Содержание:
1. Что такое “мосты” в интеграции?
2. Async-Sync Bridge. Познакомьтесь – RequestResponseBean и ResponseOnewayBean.
2.1 Асинхронно-синхронный мост с модулями в Sender Communication Channel
2.2 Пример асинхронно-синхронного моста с модулями в Sender Communication Channel.
2.3 Асинхронно-синхронный мост с модулями в Receiver Communication Channel.
2.4 Пример: Асинхронно-синхронный мост с модулями в Receiver Communication Channel
1. Что такое “мосты” в интеграции?
В практике разработки интерфейсов на SAP Process Integration достаточно часто встречается задача по связыванию систем, работающих в разных режимах. Предположим, необходимо принять файл (асинхронный режим), передать его при помощи RFC-вызова в SAP ERP (синхронный режим), а ответ, в свою очередь, выгрузить на FTP в виде файла (асинхронный режим).
Или другая задача: из системы ERP запросить у внешней системы дополнительную информацию (синхронный режим), вызвать web-сервис (в асинхронном режиме), затем предоставить web-сервис для ответа (то есть ждать асинхронного вызова от внешней системы) и вернуть ответ в ERP ожидающей программе.
В общем виде эти задачи можно представить следующим образом:
В SAP Process Integration есть два способа решить такого рода задачу:
- Использовать ccBPM. Для этого нужно создать интеграционный процесс в SAP PI и использовать его элементы для построения моста.
Плюсы – мост можно использовать в сложном процессе, связывающем множество систем.
Минусы – время разработки и тестирования, сложность мониторинга и отладки, невозможность использования ccBPM на Single Stack инсталляции. Данный способ я рекомендую использовать только в том случае, если нужно включить мост в более сложный процесс ccBPM.
Подробнее о ссBPM Bridge можно почитать на help.sap.com: “Example: Sync/Async Communication”. - Использование стандартных модулей адаптеров.
Плюсы – скорость разработки сопоставима с обычным интерфейсом, используются стандартные элементы разработки, простая отладка и мониторинг.
Минусы – нужна аккуратность при заполнении параметров модулей, трудно для новичков, закрытый код модулей, путанная (и иногда противоречивая) информация в интернете.
Давайте рассмотрим поближе второй способ построения мостов.
2. Async-Sync Bridge. Познакомьтесь – RequestResponseBean и ResponseOnewayBean.
Начнем с асинхронно-синхронного моста. Напомню, это случай, когда исходная система работает в асинхронном режиме, то есть отправкой запроса и ожиданием ответа занимаются разные (условно-независимые) ее части. Целевая система, в свою очередь, синхронизирует запрос и ответ, и отправляет ответ в тот же канал, по которому пришел запрос (Рис.1).
Я сознательно буду по минимуму затрагивать процесс создания самих интерфейсов и программ мэппинга в Integration Builder, возможные затруднения разобраны в примерах.
В работе этого варианта моста принимают участие два модуля:
- RequestResponseBean отвечает за преобразование асинхронного сообщения в синхронное и передачу его либо далее по цепочке модулей, либо в подсистему обработки сообщений PI.
- ResponseOnewayBean – модуль, преобразующий синхронное сообщение-ответ в асинхронное и перенаправляющий его получателю.
Модули могут быть использованы как в канале-отправителе (sender communication channel), так и в канале-получателе (receiver communication channel).
Дополнительная информация: модули в адаптере выполняются один за другим, в порядке размещения (сверху-вниз) на вкладке “Module” в настройках канала связи. Выходные данные вышестоящего модуля являются входными для следующего. В списке модулей всегда присутствует собственный модуль адаптера, CallSAPAdapter.
Параметры модулей задаются там же, на вкладе “Module” в разделе “Module Configuration”.
Для включения модулей в канал связи нужно перейти на вкладку “Module” и внести следующие значения:
Module Name | Type | Module Key |
---|---|---|
AF_Modules/RequestResponseBean | Local Enterprise Bean | RqResp |
CallSAPAdapter | Local Enterprise Bean | sap |
AF_Modules/ResponseOnewayBean | Local Enterprise Bean | RespOneW |
“Module Key” может быть любым – главное, чтобы он был уникальным и ключи было бы сложно перепутать – это поможет нам впоследствии при определении параметров модулей.
Дальнейшие настройки зависят от того, где мы разместили наши модули – в канале-отправителе (sender communication channel) или канале-получателе (receiver communication channel).
2.1 Асинхронно-синхронный мост с модулями в Sender Communication Channel
Логика работы модулей в Sender Channel следующая:
- Прием асинхронного сообщения по каналу связи с внешней системой, передача его модулю RequestResponseBean. Модуль меняет тип сообщения с асинхронного на синхронный, прописывая это в техническом заголовке сообщения.
- В зависимости от параметра passThrough либо передаем сообщение дальше по цепочке модулей, либо напрямую в подсистему обработки PI (пропуская п.3).
- Обработка сообщения стандартным модулем адаптера, передача его в подсистему обработки сообщений PI.
- Отправка запроса через синхронный канал связи.
- Синхронный вызов внешней системы, получение результата.
- Прием ответа из синхронного канала связи.
- Возврат ответа в модуль ResponseOnewayBean, который, в свою очередь, меняет тип сообщения с синхронного на асинхронный и, используя параметры настройки, определяет – в какую систему отдать ответ.
- Передача сообщения в выбранный канал связи.
- Доставка сообщения во внешнюю систему по асинхронному каналу связи.
Параметры модуля RequestResponseBean при размещении его в Sender Communication Channel:
Параметр | Назначение | Возможные значения |
Значения по умолчанию |
---|---|---|---|
passThrough | Определяет, куда модуль должен передать обработанное сообщение: – подсистеме обработки сообщений PI – false; – следующему модулю в цепочке – true |
true/false | false |
timeout | Время ожидания ответа модулями моста, начиная с момента окончания работы модуля RequestResponseBean. | Задается в миллисекундах | 300000 |
Не забывайте, что параметры в Java – контекстно-зависимые и никакой проверки при сохранении канала для этих параметров не проводится!
Ошибки в написании и регистрах букв всплывут только при тестировании, причем порой очень сложно понять причину ошибки.
Параметры модуля ResponseOnewayBean при размещении его в Sender Communication Channel:
Параметр | Назначение | Возможные значения | Значения по умолчанию | |
---|---|---|---|---|
receiverParty | Наименование Communication Component и Party(если есть) для системы – получателя. | Необязательный* | Если не задано – система пользуется данными из технического заголовка сообщения. | |
receiverService | Необязательный* | |||
receiverChannel | Имя канала связи получателя. | Необязательный.* | Если не задано – система ищет подходящий receiver agreement, основываясь на информации в техническом заголовке сообщения. | |
adapterType | Параметры канала связи – тип и пространство имен адаптера канала связи получателя. | Необязательный* | Значения можно взять из канала связи в Integration Builder – поле Adapter Type. Пример значений: File, http://sap.com/xi/XI/System | |
adapterNamespace | Необязательный* | |||
При желании можно также обрабатывать сообщения об ошибках: | ||||
Параметр | Назначение | Возможные значения | ||
receiverChannelOnFault | Имя канала связи получателя для сообщений об ошибках. | |||
replaceInterfaceOnFault | true – заменить интерфейс и пространство имен сообщения об ошибке приложения на собственные; false – не трогать заголовок сообщения |
true/false | ||
interfaceOnFault | Имя интерфейса для замены в заголовке | |||
interfaceNamespaceOnFault | Пространство имен интерфейса для замены в заголовке сообщения |
* – теоретически, можно не задавать параметров вообще. Нужно будет только создать “искусственный” receiver agreement, где будут заданы:
система отправитель = синхронная система,
получатель = конечная асинхронная система,
интерфейс = исходный интерфейс-запрос.
“Искусственный” – потому как PI не даст выбрать такой набор параметров в agreement – их придется прописывать в полях объекта вручную (copy-paste). Именно такая “каша” образуется в заголовке возвращаемого от синхронной системы сообщения в результате работы моста.
Если типы адаптеров исходной асинхронной системы и конечного получателя не совпадают – придется все же задать adapterType и adapterNamespace конечного канала связи.
На практике – проще аккуратно задать все необходимые параметры в настройках модуля.
После того, как мы установили необходимые модули в Sender Communication Channel, нам остается лишь создать правила маршрутизации, связывающие исходную асинхронную систему с синхронной системой.
Это можно сделать двумя способами:
- создать связку Receiver Determination -> Interface Determination -> Receiver Agreement
- создать Integrated Configuration
Маршрутизация ответа от синхронной системы будет автоматической, до конечной точки сообщение направит модуль моста.
2.2 Пример асинхронно-синхронного моста с модулями в Sender Communication Channel.
Давайте посмотрим, как это выглядит на практике.
Схематично мост выглядит следующим образом:
Исходная система запрашивает дополнительную информацию о персоне/партнере по некоторому ID. Передача запроса осуществляется посредством вызова асинхронного web-сервиса.
Информация храниться в ERP (в данном конкретном примере – это ABAP часть инсталляции PI). Получение информации возможно путем синхронного вызова функционального модуля, доступного по RFC.
Ответ должен быть выгружен в файловую систему (в данном случае – папка на сервере PI) в виде XML-файла, откуда, “по легенде”, он будет забран внешней системой.
Для реализации этого интерфейса нам понадобятся следующие объекты разработки:
Все объекты создаются стандартным образом (см. рис. 6-8):
Исключением является Operation Mapping:
Дело в том, что система не даст создать двусторонний синхронный мэппинг, так как исходный интерфейс SI_ExtSystem_Request_Async у нас асинхронный. Хотя, на этапе выполнения интерфейса, модули моста “создадут видимость” синхронной работы и мэппинг будет выполнен в обе стороны.
Алгоритм создания объекта OM_ExtSystem_Request_to_RFC следующий:
- Создаем Message Mapping MM_ExtSystem_Request_to_RFC для интерфейсов SI_ExtSystem_Request_Async и ZZ_EXT_REQUEST
- Создаем Message Mapping MM_RFC_to_ExtSystem_Response для интерфейсов ZZ_EXT_REQUEST.Response и SI_ExtSystem_Request_Async
- Внимание: редактируем исходный интерфейс SI_ExtSystem_Request_Async: меняем его тип на синхронный, добавляем в качестве ответа message type из интерфейса SI_ExtSystem_Response. Сохраняем, но НЕ АКТИВИРУЕМ.
- Создаем Operation Mapping, исходный интерфейс – SI_ExtSystem_Request_Async(он у нас сейчас синхронный), целевой – RFC. Подставляем мэппинги из пунктов 1 и 2 во вкладки request и response соответственно.
- Отменяем изменения интерфейса (возвращаем его в прежний, асинхронный вид).
- Активируем все изменения.
Таким способом мы получили мэппинг OM_ExtSystem_Request_to_RFC, который будет выполнять все преобразования в нашем интерфейсе.
Теперь переходим к настройке интерфейса, запускаем Integration Builder и создаем следующие объекты:
Каналы связи CC_IntegrationServer_RFC_Receiver и CC_ExtSystem_File_Receiver не имеют каких-либо особенностей, тип адаптера виден из названия.
Самое главное – это аккуратно и правильно настроить SOAP Sender Communication Channel CC_ExtSystem_SOAP_Sender и подключить модули моста:
Настраиваем модули RequestResponseBean и ResponseOnewayBean:
Затем строим маршрутизацию от исходной системы к ERP. Я сделал это через Receiver Determination + Interface Determination + Receiver Agreement (можно также использовать Integrated Configuration):
Не забудьте в Interface Determination подключить наш мэппинг – OM_ExtSystem_Request_to_RFC:
Теперь проверяем наш мост. В Sender Agreement, в меню выбираем пункт “Display WSDL”, затем нажимаем “Save” и сохраняем WSDL нашего сервиса-запроса на локальный диск.
Затем, используя любой инструмент отправки SOAP-запроса (я использовал freeware инструмент SOAPUI) и сохраненный WSDL, формируем запрос к PI.
Если все было настроено правильно – в целевой директории наблюдаем файл с ответом:
Итак, мы настроили пример асинхронно-синхронного моста с модулями в канале связи системы отправителя.
Поздравляю Вас, можно немного передохнуть, а затем переходить к следующему варианту моста.
2.3 Асинхронно-синхронный мост с модулями в Receiver Communication Channel.
Предположим, что мы не хотим (или не можем) затрагивать Sender Communication Channel. Существует возможность разместить те же модули в синхронном канале связи системы-получателя.
Логика работы асинхронно-синхронного моста с модулями в канале получателя следующая:
- Прием асинхронного сообщения по каналу связи с внешней системой
- Передача сообщения в PI.
- Обработка сообщения в PI, передача его в синхронный канал связи на вход модуля RequestResponseBean.
- RequestResponseBean переводит тип сообщения из асинхронного в синхронный, затем, используя параметры настройки, определяет – в какую систему вернуть ответ. В зависимости от параметра passThrough, сообщение либо передается далее по цепочке модулей до стандартного адаптера, либо напрямую в модуль ResponseOnewayBean (пропуская пп.4-6).
- Синхронный вызов внешней системы, получение результата.
- Возврат ответа в модуль ResponseOnewayBean, который меняет тип сообщения с синхронного на асинхронный.
- Возврат ответа в подсистему обработки сообщений, которая проводит маршрутизацию на базе заголовка сообщения. Параметры в заголовке сообщения изменены модулем RequestResponseBean на шаге 4.
- Передача сообщения в выбранный канал связи.
- Доставка сообщения во внешнюю систему по асинхронному каналу связи.
Мост строиться с использованием все тех же модулей RequestResponseBean и ResponseOnewayBean.
Параметры модуля RequestResponseBean:
Параметр | Назначение | Возможные значения | Значения по умолчанию |
---|---|---|---|
passThrough | Определяет, куда модуль должен передать обработанное сообщение: – следующему модулю в цепочке – true; – напрямую в модуль ResponseOnewayBean – false; |
true/false | false |
timeout | Время ожидания ответа модулем, начиная с момента отправки сообщения далее. | Задается в миллисекундах | 300000 |
Для модуля ResponseOnewayBean, включенного в Receiver Communication Channel, возможных параметров немного – мы, при необходимости, можем только при получении сообщения об ошибке заменить в заголовке интерфейс на свой (например, с целью изменить дальнейшую маршрутизацию).
Параметр | Назначение | Возможные значения | ||
---|---|---|---|---|
replaceInterface | true – подменить интерфейс-отправитель и его пространство имен в сообщении; false – не трогать заголовок сообщения |
true/false | ||
interface | Имя интерфейса для замены в заголовке. Заменяется интерфейс-отправитель. | |||
interfaceNamespace | Пространство имен интерфейса для замены в заголовке сообщения | |||
replaceInterfaceOnFault | true – заменить интерфейс сообщения об ошибке и его пространство имен сообщения на собственные; false – не трогать заголовок сообщения |
true/false | ||
interfaceOnFault | Имя интерфейса сообщения об ошибке для замены в заголовке | |||
interfaceNamespaceOnFault | Пространство имен интерфейса сообщения об ошибке для замены в заголовке сообщения |
ВНИМАНИЕ: документация (официальная с help.sap.com и неофициальная c sdn.sap.com) по настройкам модулей Async-Sync Bridge в варианте с каналом-получателем дает ПРОТИВОРЕЧИВУЮ информацию!
Пример: глава “Configuring the Async/Sync Bridge Using the JMS Adapter” описывает одни параметры модуля ResponseOnewayBean, а ее подглава “Adding ResponseOnewayBean in the Module Processor” – другие.
Коллеги с SDN, в основном, описывают частные примеры на базе “Configuring the Async/Sync Bridge Using the JMS Adapter”. Достаточно часто встречаются комментарии к статьям, что с одним адаптером это работает, а с другим (при таких же настройках) – нет.
Действительно, при использовании, к примеру, RFC-адаптера в качестве синхронного получателя, подмена интерфейса (параметр replaceInterface) в ResponseOnewayBean не работает! Однако, та же подмена отлично работает при использовании синхронного запроса через SOAP-адаптер.
Будьте внимательны, и при возникновении ошибок анализируйте все возможные источники информации.
После настройки каналов связи нам осталось только создать два пути маршрутизации:
- Внешняя система -> Sender Agreement (если нужен) -> Reciever Determination -> Interface Determination -> Receiver Agreement -> Синхронный канал связи с модулями
- Синхронная система -> Sender Agreement (если нужен) -> Reciever Determination -> Interface Determination -> Receiver Agreement -> Асинхронный канал связи
Оба пути можно настроить и через Integrated Configuration.
2.4 Пример: Асинхронно-синхронный мост с модулями в Receiver Communication Channel
От теории – к практике! Давайте разберемся, как построить мост, если добавить модули в канал связи получателя.
Схема интерфейса выглядит следующим образом:
Нам потребуется небольшая подготовительная работа, не относящаяся непосредственно к настройке моста. В этот раз в качестве получателя будет выступать синхронный SOAP-сервис. Для простоты создадим его на базе функционального модуля из предыдущего примера (используя транзакции SE80 -> Enterprise Service и SOAMANAGER).
Выгружаем и импортируем в репозитарий PI WSDL нашего сервиса, получаем объект External Definition DOC_3I_ZZ_SOAP_EXT_REQUEST.
Далее создаем синхронный интерфейс SI_SOAP_ADDINFO_Sync, используя типы сообщений из предыдущего импорта:
На этом синхронная часть моста готова.
Для всего остального нам понадобятся следующие объекты разработки:
Итого:
- Два асинхронных интерфейса для асинхронной системы (запрос и ответ): SI_ExtSystem_Request_Async и SI_ExtSystem_Response
- Синхронный интерфейс SI_SOAP_ADDINFO_Sync.
- Асинхронный интерфейс SI_ERP_SOAP_Response_Async (передает сообщение ZZ_SOAP_EXT_REQUEST.Response от синхронного SI_SOAP_ADDINFO_Sync).
- Асинхронный Operations Mapping для запроса OM_ExtSystemRequest_to_SOAP_Request
- Асинхронный Operations Mapping для ответа OM_ERP_SOAPResp_to_ExtSystem_Response
Объекты создаются стандартным способом, никаких особенностей или технических хитростей тут нет. Единственное, при активации мэппинга OM_ExtSystemRequest_to_SOAP_Request система выдаст предупреждение о несоответствии типов интерфейсов, но активации объекта это не помешает.
Теперь, когда все объекты разработки у нас готовы – переходим к настройке в Integration Directory.
На этот раз (в отличии от п.2.2) попробуем построить маршрутизацию на Integrated Configuration. Создаем объект для передачи запроса:
Создадим синхронный канал связи с SOAP-сервисом CC_IntegrationServer_SOAP_Receiver:
Настроим модули в канале связи:
Параметры модуля ResponseOnewayBean задают имя и пространство имен интерфейса для замены в заголовке сообщения. В результате работы модуля сообщение-ответ от SOAP меняет заголовок и становиться асинхронным, отправленным с интерфейса SI_ERP_SOAP_Response_Async.
ВНИМАНИЕ: с синхронным вызовом адаптера RFC такая подмена НЕ РАБОТАЕТ! Для организации моста с синхронным RFC нужно использовать прием с синхронным мэппингом и Receiver Determination (или Integrated Configuration), как в примере 2.2.
Для создания Integrated Configuration обязательно наличие двух каналов связи – отправителя и получателя. Но канал SOAP у нас определен как получатель, и использовать его для маршрутизации ответа не получится. Выход – создать псевдо-канал, который займет место в Integrated Configuration на вкладке Inbound Processing. Тип адаптера для этого канала не важен, я выбрал SOAP:
Далее настраиваем обратную маршрутизацию обычным образом:
Ну вот и все. Активируем все объекты настройки, тестируем с помощью SOAPUI, как в примере 2.2.
Результат радует нас XML-файлом с запрошенной информацией:
………………………………
Буду благодарен за комментарии и конструктивную критику!
Продолжение – в следующей статье: Наводим мосты – 2: Синхронно – Асинхронный вариант
Спасибо за подробное описание! Первый раз такое встречаю.
Да не за что, Юлия.
Попробую восполнить этот пробел, в меру сил и времени. )
А еще есть возможность сделать LookUp из меппинга. Она самая простая, но почему-то не описана..
Женя, спасибо за дополнение!
LookUp – да, можно попробовать. Поставлю это в следующую статью, в раздел “Экзотика”. )
Насчет “самая простая” – не соглашусь, есть ньюансы: нужно хотя бы минимально знать java и при разработке учитывать производительность lookup.
Да, не уверен еще, что на все адаптеры можно настроить lookup (RFC, JDBC, SOAP – точно можно, остальные – надо смотреть).
Фактически, нужно будет сделать собственную разработку.
Мост на модулях – это стандарт. Не очень “прямой” :), но стандарт.
Замечательная статья! Вот только один момент остается непонятным: как обрабатывать ошибки передачи данных (async-sync bridge, вариант 2 с модулями в receiver)? Например, если принимающий SOAP-сервер встал. В этом случае “ответное” сообщение от него не генерится, хотя в канале четко видна ошибка уровня адаптера. Если нужно использовать параметр interfaceOnFault модуля, то какое сообщение надо использовать? Хотя, скорее всего, ошибку “физики” этим способом не поймать.
Спасибо, Николай!
Если сервер встал – то вернется техническая ошибка адаптера SOAP по тайм-ауту. А дальше нужно будет один раз “поймать” эту ошибку и посмотреть – что за сообщение вернулось от адаптера, его и обрабатывать.
Сам параметр interfaceOnFault не влияет на обработку – он лишь подменяет в заголовке этого обратного сообщения имя интерфейса на другое (если это нам нужно).
Да, но она видна только в мониторинге канала. Сообщение при этом помечается как успешное и никакие алерты не срабатывают. Вот если бы ее можно было как-нибудь вытащить оттуда в сообщение…
А ведь точно! Спасибо за наводку, даже статью поправил – в документации, оказывается, говорится только об application error, я сходу не заметил. Попробовал – действительно, технические ошибки связи по тайм-ауту видны только в мониторе каналов.
Надо думать.
Со своей стороны пока не придумал ничего, кроме написания собственного модуля, который бы доставал ошибку из лога адаптера и правил бы соответствующим образом исходное/ответное сообщение.
Привет! Пытаюсь сделать сценарий FILE-SOAP-FILE с модулями в Receiver Communication Channel.
Веб сервис исполняется успешно, но потом ошибка получается: “Message processing failed. Cause: com.sap.aii.adapter.xi.routing.RoutingException: InterfaceDetermination did not yield any actual interface”
Пожалуйста помогите 🙂
Привет!
Скорее всего – что-то с маршрутизацией на обратной дороге или с подменой имени интерфейса.
Проверьте настройки модуля еще раз – возможно, что подмена не произвелась.
Через что маршрутизацию делаете – “классически” или через Integrated Configuration?
На момент ошибки какой интерфейс в заголовке сообщения указан в разделе sender?
Есть в Integration Directory Interface Determination для этого интерфейса?
Привет,
Я думаю что ошибка получается в AF_Modules/ResponseOnewayBean. Это часть лога обработки сообщения:
3/28/2014 10:33:27 AM Information SOAP: completed the processing
3/28/2014 10:33:27 AM Information SOAP: continuing to response message ed2abb59-b685-11e3-c959-0000008297d6
3/28/2014 10:33:27 AM Information MP: processing local module localejbs/AF_Modules/ResponseOnewayBean
3/28/2014 10:33:27 AM Error MP: exception caught with cause com.sap.aii.adapter.xi.routing.RoutingException: InterfaceDetermination did not yield any actual interface
Другие тоже получают тоже самую ошибку: http://scn.sap.com/thread/3477551
Если можете помочь буду благодарен 🙂
Привет,
не похоже, скорее всего – ошибка правил маршрутизации.
На SCN таких ошибок много, причем иногда – интерфейс вообще модули не использует.
Модуль ResponseOnewayBean начинает свои сообщения об ошибке с “ROB:”. 🙂
Еще раз – проверьте обратную маршрутизацию, алгоритм поиска такой (если Вы используете Integrated Configuration – то искать на соответствующей вкладке):
– посмотреть внимательно, совпадает ли имя интерфейса в параметрах модуля ResponseOneWayBean с именем интерфейса-отправителя в Receiver Determination – может быть банальная опечатка в настройках модуля.
– проверить Interface Determination – есть ли условия на маршрутизацию (если ни одно не выполняется – то будет как раз такая ошибка) .
– посмотрите в тексте сообщения – сменился ли интерфейс по итогам работы ResponseOneWayBean – в заголовке SOAP-XML, в разделе Sender.
По итогам – будем дальше смотреть. 🙂
Привет,
Я посмотрел опять – имя и пространство имен в модуле ResponseOneWayBean совпадает с то что указано в Sender моего Integrated Configuration. У меня нет условий на маршрутизацию. А текст сообщения ошибки совпадает с сообщением запроса, ответ от вебсервиса не виден (хотя я уверен вебсервис выполняется.
Я еще попробовал задать Stateless (XI30-compatible) на интерфейсе file sender как предлагают здесь: http://scn.sap.com/thread/3205324
Ошибка поменялась на:
Transmitting the message to endpoint using connection AFW failed, due to: com.sap.engine.interfaces.messaging.api.exception.ConfigException: No sender agreement configured that matches the message’s header fields (sender party: “”, sender service: “BC_BR_WEB”, interface: “http://webservicesyncsync SI_4”, receiver party: “”, receiver service: “BC_BR_WEB”)
Мне не совсем ясно – почему для Receiver service ожидает то же самое как для Sender service. И нужно ли в версии 7.31 ползьзовать опцию Stateless (XI30-compatible)?
Что-то не так. )
Явно, ошибка где-то в маршрутизации. Ни модули, ни XI30-compartible тут не при чем.
Можете полный XI-SOAP ответ с ошибкой прислать на почту (адрес – внизу страницы)? Namespace, если секретные, можно заменить. 🙂
Спасибо, очень познавательно!
ждем с нетерпением “А в следующей статье я расскажу о синхронно-асинхронном мосте и его видах.”=)
Николай подымал вопрос по поводу обработки ошибок на Receiver SOAP адаптере, на сколько я понимаю, в sxmb_moni не отображаются эти ошибки только если мост сделан без средств ccBPM? Потому что, если в подобном сценарии (sync\async ссBPM) специально валю канал, то в sxmb_moni выходит ошибка типа “XIAdapterFramework”.
“””подобном сценарии (async\sync ссBPM)
Добрый день!
Так я уже выложил 2ю и 3ю части:
http://sap.pitroff.ru/sap-netweaver/sap-xi-pi/sync-async-bridge-ili-chto-nam-stoit-most-postroit-chast-vtoraya/
http://sap.pitroff.ru/navodim-mostyi-3-ekzotika-i-rekomendatsii/
По ошибке – да, ccBPM сам генерирует ошибку, не дождавшись ответа от адаптера. Модули же такую ошибку не обрабатывают.
отличная статья, подробно с примерами
однако, у меня на практике что-то не сложилось…
пробовал оба варианта с модулями в отправителе и в получателе, и получал похожие ошибки в обоих случаях:
cause: com.sap.engine.services.jndi.persistent.exceptions720.NameNotFoundException: Object not found in lookup of RequestResponseBean
с чем может быть связано такое сообщение?
направьте меня на путь истинный, пожалуйста 😉
Мне необходимо реализовать асинхронно/синхронный мост в PI 7.40:
источник – плоский файл (служит исключительно для того, чтобы дернуть JDBC-receiver)
JDBC-receiver (а не sender) использую, т.к. параметры SQL-запроса формируются динамически
далее синхронный интерфейс по каналу JDBC c БД PostgreSQL
и результат надо вернуть асинхронно в ERP по RFC-каналу
в мониторе адаптера наблюдаю указанную ошибку и, соответственно, в мониторе XML-сообщений ничего не появляется
подробнее, в сценарии с модулями в sender, такие сообщения об ошибках:
Module Exception ‘com.sap.aii.af.lib.mp.module.ModuleException: Error during processing local bean: localejbs/RequestResponseBean’ found, cause: com.sap.engine.services.jndi.persistent.exceptions720.NameNotFoundException: Object not found in lookup of RequestResponseBean
категория: com.sap.aii.adapter.file.File2XI
местоположение: com.sap.aii.adapter.file.File2XI.processFileList
Сообщение:Channel CC_File_sender_4_start_process_mod: Sending file failed with com.sap.engine.services.jndi.persistent.exceptions720.NameNotFoundException: Object not found in lookup of RequestResponseBean. – continue processing
Категория:/Applications/ExchangeInfrastructure/AdapterFramework/Services/ADAPTER/ADMIN/File
Местоположение: com.sap.aii.adapter.file.File2XI.processFileList()
Сообщение:FILE_ERR_211
Категория:/Applications/ExchangeInfrastructure/AdapterFramework/Services/ADAPTER/ADMIN/File
Местоположение: com.sap.aii.adapter.file.util.AuditLog.addAuditLog(PublicMessageKey,String,AuditLogStatus,String,String,Object[])
PS. в сценарии с модулями в канале получателя были такие сообщения:
Информация Сообщение успешно вызвано из очереди получения
Информация Статус сообщения установлен на DLNG
Ошибка MP: exception caught with cause com.sap.engine.services.jndi.persistent.exceptions720.NameNotFoundException: Object not found in lookup of RequestResponseBean.
Информация Доставка в канал: CC_jdbc_receiver_SP_sap_test_sync
Информация MP: processing local module localejbs/RequestResponseBean
Ошибка В архитектуре адаптера возникла особая ситуация: Object not found in lookup of RequestResponseBean.
Ошибка Не удалось доставить сообщение приложению с помощью соединения JDBC_http://sap.com/xi/XI/System из-за: com.sap.engine.interfaces.messaging.api.exception.MessagingException: com.sap.engine.services.jndi.persistent.exceptions720.NameNotFoundException: Object not found in lookup of RequestResponseBean.
Добрый день, Виталий!
Судя по ошибке – неверно указано имя модуля, проверьте наименование модуля на вкладке Modules.
Там должно быть “AF_Modules/RequestResponseBean”, без кавычек.
С уважением,
Алексей
Алексей, огромное спасибо
Вы были абсолютно правы
Столько раз говорилось о необходимости ТОЧНО указывать имя модуля, что я зациклился на сверке регистров, копировал из текста статьи название RequestResponseBean, но забыл про путь (префикс AF_Modules/)
Спасибо.
Сценарий работает.
Добрый день!
Еще небольшой вопросик. Интерсно, а зачем нужен параметр replaceInterface в модуле ResponseOnewayBean (вариант “Мост с модулями в Receiver Communication Channel”)? Если поставить его в false, то система в процессе маршрутизации обратного сообщения потребует receiver agreemenr’а для от , интерфейс . В то же время, я не нашел способа создать Interface mapping, в котором бы в качестве и Source Interface выступал бы . При этом, чтобы бралось его response-сообщение и маппилось бы на сообщение асинхронного интерфейса системы .
И еще одно замечание, касающееся создания асинхронно-синхронного моста с модулями в канале Sender’а. Рассмотрим пример, в частности, строки:
4.Создаем Operation Mapping, исходный интерфейс — SI_ExtSystem_Request_Async(он у нас сейчас синхронный), целевой — RFC. Подставляем мэппинги из пунктов 1 и 2 во вкладки request и response соответственно.
5.Отменяем изменения интерфейса (возвращаем его в прежний, асинхронный вид).
6.Активируем все изменения.
Не получится активировать. Нельзя активировать OperationMapping, у которого с одной стороны асинхронный, а с другой – синхронный интерфейс. На выходе получается ошибка:
Interface modi are different. Source interface | is asynchronous, target interface Operation . | is synchronous и активация не происходит.
Приветствую, Николай,
Опечатка, спасибо.
В п.4 оба интерфейса – синхронные. После этого нужно активировать Operation Mapping и перейти к п.5.
UPD: Хотя нет, пересмотрел еще раз – у меня работало именно так, как в статье.
К сожалению, сейчас нет системы под рукой – проверить.
Синхронными оба быть не могут, тогда весь смысл теряется и модуль RequestResponseBean вроде не нужен 🙂
У меня 7.40, там н работает (текст ошибки присылал). К тому же есть вариант, когда схема с модулями в Sender’е не сработает точно – когда входят IDoc’и. Поверх IDOC’а не нужно строить интерфейс, а синхронным его не сделаешь по-определению.
Я пример проходил “руками” именно на 7.4 – работает.
Синхронные оба интерфейса только на момент активации мэппинга. Затем сразу же нужно сменить тип исходящего интерфейса на асинхронный и активировать только сам интерфейс.
После активации в кэш появляется активный объект мэппинга, который в момент работы не проверяет тип интерфейса.
Про IDOC – пожалуй соглашусь, схема с модулями в Sender не сработает.
Хотя – можно было бы с “бубном” потанцевать вокруг, если бы время было. 🙂
Я пробовал по всякому. Если поверх IDOC’а сделать интерфейс, даже асинхронный, то IDOC в AAE-adapter на PI уже не попадает.
Да там и пробовать не нужно – IDoc-адаптер в Dual Stack сделан “топорно”. 🙂
При приходе Idoc он отправляется в ABAP на вход функционального модуля, который проверяет настройки (“это Integration Engine или нет?”) – и в зависимости от настроек либо отправляет на вход стандартной процедуры, либо в прямиком в pipeline.
Добрый день!
Нашел еще один момент. Настройка асинхронно-синхронного моста с модулями в receiver’е, рис . 24 (Integrated configuration – request). На вкладке Receiver Interfaces у Вас указан асинхронный operation mapping OM_ExtSystemRequest_to_SOAP_Request и синхронный интерфейс SI_SOAP_ADDINFO_Sync. Такое невозможно, при попытке создать выдается:
Interface | is not a target interface of Operation Mapping | |
Если же попытаться переделать мапинг так, чтобы target интерфейс был синхронным, то активировать его не удастся (см. вчерашний вопрос).
Добрый день,
подскажите, пожалуйста, для случая Асинхронно-синхронный моста с модулями в Receiver Communication Channel, как можно сохранить значение каког-либо поля из сообщения системы-источника, чтобы потом его использовать в конечной системе, которая принимает ответ? В сихронном сообщении можно было использовать динамическую конфигурацию, а с мостом она не работает.
Пример: АсихрФайл->ПиАй->СихронВебсервис->ПиАй->SAP ABAP proxy
файл сожержит уникальный номер, который отправляется в вебсервис но ответ уже юез номер. А номер надо использовать в конце для записи в SAP. Как можно этот номер в PI сохранить и в добавить в конце в меппинге?
Спасибо
Попробуйте использовать GetPayloadValueBean и PutPayloadValueBean
Приветствую, Кирилл!
Юлия абсолютно права – можно использовать эти два модуля.
Пример от индийского коллеги:
http://scn.sap.com/community/pi-and-soa-middleware/blog/2013/03/20/insert-value-from-request-message-to-response-using-getpayloadvaluebean-and-putpayloadvaluebean
Добрый день! Спасибо за вашу работу, настольные ссылки для меня.
Не могли бы вы пояснить такую проблему.
Сценарий асинх-синх, IDOC->SOAP->IDOC т.е. IDOC отправляется в SOAP и обратно возвращается сообщение, которое меппится в IDOC(ALEAUD). Сделала все по примеру 2.4 Пример: Асинхронно-синхронный мост с модулями в Receiver Communication Channel, только не ICO, а классический сценарий. Ошибка выходит следующая:
MP: exception caught with cause java.lang.NullPointerException: while trying to invoke the method com.sap.engine.interfaces.messaging.api.Message.getMessageId() of a null object loaded from local variable ‘message1’
Adapter Framework caught exception: while trying to invoke the method com.sap.engine.interfaces.messaging.api.Message.getMessageId() of a null object loaded from local variable ‘message1’
Есть такой момент, пока доступа к реальному сервису нет, использую SoapUI Mock для тестирования. SoapUI Mock находится на виртуальном рабочем столе, может в этом причина появления такой ошибки.
Заранее благодарю.
Юлия,
удаленная отладка сродни посадке самолета по телефону. 🙂
На каком этапе возникает ошибка – прием IDOC, мэппинг или отправка SOAP?
В SOAPUI видно вызов?
Очень похоже на ошибку технического мэппинга из IDoc в XML – нужно в технический заголовок XML смотреть.
Hi pitroff,
I am facing the same issue like the one mentioned by Yuliya and this seems to be something related to the correlationID. Can I please know the solution for the same?
Hi Shruthi,
it’s really hard to point the exact solution.
getMessageId() must return unique technical GUID of the message, settled by messaging system.
The problem can be in SOAP xml format, or in the mapping (I saw some discussion connected to this error and an xslt mapping on SDN)
My suggestion would be to analyse trace of the message and searching for the step, where this error occurs.
Здравствуйте, Алексей!
Настроил сценарий: IDoc – SOAP – IDOC по статье из блога Вильяма Ли.
Хотел бы спросить Вашего совета: Вильям в блоге обращает внимание на то, что во втором объекте ICo (асинхронный ответ) должен быть включен параметр “Sender uses virtual receiver”. Когда я первоначально сделал все без этого параметра, то в ответ получил ошибку на ответном сообщении: No sender agreement configured that matches the message’s header fields (sender party: “”, sender service: “BS2”, interface: “urn:my_urn SI_SOAP_Async_Out”, receiver party: “”, receiver service: “BS1”). Причем, во втором ICo все было настроено именно по данным, что указаны в ошибке. Как только включил признак – все заработало.
Вот не совсем понимаю, каким образом этот признак на логику работы влияет.
Алексей, добрый день!
Спасибо за ваши чёткие статьи.
В этой статье для создания синхронного веб-сервиса в SAP вы используете транзакции se80 (для создания веб-сервиса) и SOAMANAGER (для настройки).
Не совсем понятно, что за настройки необходимо выполнить в SOAMANAGER? Почему нельзя просто взять url WSDL из se80 и направить его внешней системе для использования?
Александр, добрый день!
В SAP такая логика заложена: SE80 – это определение(definition), а SOAMANAGER – это его конфигурация (runtime configuration).
wsdl разные будут.
Алексей, спасибо, теперь понятнее стало (чувствуется аналогия с XI/PI)!
1. Т.е. wsdl в SE80 – это вроде как xsd-схема, а wsdl в SOAMANAGER – это уже сам xml?
2. в SOAMANAGER к сервису можно сделать привязку (bind) и у неё также есть свой отдельный wsdl, а он для чего используется?
3. Какой в итоге из трёх wsdl необходимо использовать для вызова сервиса из внешней системы?
Александр, добрый день,
1) Скорее SE80 – это WSDL со структурой данных, а SOAMANAGER – wsdl с привязкой к конкретной системе.
2) Bind – это указание внешней системе – по какому url вызывать данный сервис.
3) wsdl в SOAMANAGER.
Алексей, спасибо за быстрый ответ.
Настроил, даже тест проходит, но в SOAMANAGER на вкладке “мониторинг” нет никаких xml-сообщений…
Мониторинг надо как-то отдельно настраивать?
Да, там своя процедура настройки логов и трассировки.
http://help.sap.com/erp2005_ehp_04/helpdata/en/af/7591e6b48944ba884cd2eb800789d1/content.htm
Ок, спасибо, буду пробовать!
А если не в SOAMANAGER, то как в SAP ERP можно промониторить передачу сообщений через веб-сервис?
Про payload сходу не скажу, а сам факт и процесс вызова сервиса можно в SMICM (http trace) посмотреть.
Алексей, спасибо за наводку!
Горизонты данной статьи существенно расширились:)
Алексей, здравствуйте.
Спасибо вам за эти статьи.
Сделал у себя асинхронно-синхронный мост FTP -> JDBC (синхронно) -> FTP.
Модули в канале-сендере.
Можно было и двумя асинхронными взаимодействиями обойтись, но нужно максимально быстро получать ответный файл, и заодно это повод опробовать описанное вами решение.
Всё работает. Использую 7.4 Single Stack.
Смущает один нюанс. Если ошибка на стороне получателя (JDBC), то сообщение сразу падает в статус Cancelled и не подлежит переотправке.
Учитывая, что отправитель работает в асинхронном режиме (и не висит в ожидании ответа), идеологически ничего не мешает попытаться повторить сообщение.
Можно ли это как-то сделать?
Андрей, добрый день!
Посмотрите настройки JDBC Receiver, в частности “Number of Retries of Database Transaction on SQL Error” в блоке Advanced mode.
https://help.sap.com/saphelp_nw73/helpdata/en/48/465581929734d9e10000000a42189d/content.htm?frameset=/en/22/b4d13b633f7748b4d34f3191529946/frameset.htm¤t_toc=/en/ca/b977f1c7814201954f20bb87ad7aab/plain.htm&node_id=65&show_children=false
Спасибо. Забыл про такую возможность.