SAP PI Async-Sync Bridge. Наводим мосты или как связать между собой асинхронный и синхронный интерфейсы без помощи ccBPM.


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 ожидающей программе.

В общем виде эти задачи можно представить следующим образом:

Асинхронно - Синхронный мост

Рис.1: Асинхронно – синхронный мост

Синхронно - Асинхронный мост

Рис.2: Синхронно – асинхронный мост

В 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 следующая:
Рис.3: Логика работы асинхронно-синхронного моста при размещении адаптеров в канале связи отправителя.

Рис.3: Логика работы асинхронно-синхронного моста при размещении адаптеров в канале связи отправителя.

  1. Прием асинхронного сообщения по каналу связи с внешней системой, передача его модулю RequestResponseBean. Модуль меняет тип сообщения с асинхронного на синхронный, прописывая это в техническом заголовке сообщения.
  2. В зависимости от параметра passThrough либо передаем сообщение дальше по цепочке модулей, либо напрямую в подсистему обработки PI (пропуская п.3).
  3. Обработка сообщения стандартным модулем адаптера, передача его в подсистему обработки сообщений PI.
  4. Отправка запроса через синхронный канал связи.
  5. Синхронный вызов внешней системы, получение результата.
  6. Прием ответа из синхронного канала связи.
  7. Возврат ответа в модуль ResponseOnewayBean, который, в свою очередь, меняет тип сообщения с синхронного на асинхронный и, используя параметры настройки, определяет – в какую систему отдать ответ.
  8. Передача сообщения в выбранный канал связи.
  9. Доставка сообщения во внешнюю систему по асинхронному каналу связи.

Параметры модуля 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.


Давайте посмотрим, как это выглядит на практике.

Схематично мост выглядит следующим образом:

Рис.4: Схема примера асинхронно-синхронного моста SOAP-RFC-File

Рис.4: Схема примера асинхронно-синхронного моста SOAP-RFC-File

Исходная система запрашивает дополнительную информацию о персоне/партнере по некоторому ID. Передача запроса осуществляется посредством вызова асинхронного web-сервиса.
Информация храниться в ERP (в данном конкретном примере – это ABAP часть инсталляции PI). Получение информации возможно путем синхронного вызова функционального модуля, доступного по RFC.
Ответ должен быть выгружен в файловую систему (в данном случае – папка на сервере PI) в виде XML-файла, откуда, “по легенде”, он будет забран внешней системой.

Для реализации этого интерфейса нам понадобятся следующие объекты разработки:

Рис.5: Объекты разработки в Integration Repository

Рис.5: Объекты разработки в Integration Repository

Все объекты создаются стандартным образом (см. рис. 6-8):

Рис.6: Асинхронный интерфейс - запрос

Рис.6: Асинхронный интерфейс – запрос


Рис.7: Асинхронный интерфейс - ответ

Рис.7: Асинхронный интерфейс – ответ


Рис.8:  модуль RFC, импортирован из ABAP

Рис.8: модуль RFC, импортирован из ABAP


Исключением является Operation Mapping:
Рис.9:  Синхронный Operation Mapping между двумя асинхронными интерфейсами и RFC

Рис.9: Синхронный Operation Mapping между двумя асинхронными интерфейсами и RFC

Дело в том, что система не даст создать двусторонний синхронный мэппинг, так как исходный интерфейс SI_ExtSystem_Request_Async у нас асинхронный. Хотя, на этапе выполнения интерфейса, модули моста “создадут видимость” синхронной работы и мэппинг будет выполнен в обе стороны.

Алгоритм создания объекта OM_ExtSystem_Request_to_RFC следующий:

  1. Создаем Message Mapping MM_ExtSystem_Request_to_RFC для интерфейсов SI_ExtSystem_Request_Async и ZZ_EXT_REQUEST
  2. Создаем Message Mapping MM_RFC_to_ExtSystem_Response для интерфейсов ZZ_EXT_REQUEST.Response и SI_ExtSystem_Request_Async
  3. Внимание: редактируем исходный интерфейс SI_ExtSystem_Request_Async: меняем его тип на синхронный, добавляем в качестве ответа message type из интерфейса SI_ExtSystem_Response. Сохраняем, но НЕ АКТИВИРУЕМ.
  4. Создаем Operation Mapping, исходный интерфейс – SI_ExtSystem_Request_Async(он у нас сейчас синхронный), целевой – RFC. Подставляем мэппинги из пунктов 1 и 2 во вкладки request и response соответственно.
  5. Отменяем изменения интерфейса (возвращаем его в прежний, асинхронный вид).
  6. Активируем все изменения.

Таким способом мы получили мэппинг OM_ExtSystem_Request_to_RFC, который будет выполнять все преобразования в нашем интерфейсе.

Теперь переходим к настройке интерфейса, запускаем Integration Builder и создаем следующие объекты:

Рис.:10: Объекты настройки

Рис.:10: Объекты настройки

Каналы связи CC_IntegrationServer_RFC_Receiver и CC_ExtSystem_File_Receiver не имеют каких-либо особенностей, тип адаптера виден из названия.
Самое главное – это аккуратно и правильно настроить SOAP Sender Communication Channel CC_ExtSystem_SOAP_Sender и подключить модули моста:

Рис.11: Канал связи SOAP Sender

Рис.11: Канал связи SOAP Sender


Настраиваем модули RequestResponseBean и ResponseOnewayBean:
Рис.12: Канал связи SOAP Sender - модули

Рис.12: Канал связи SOAP Sender – модули

Затем строим маршрутизацию от исходной системы к ERP. Я сделал это через Receiver Determination + Interface Determination + Receiver Agreement (можно также использовать Integrated Configuration):

Рис.13: Receiver Determination и другие объекты маршрутизации

Рис.13: Receiver Determination и другие объекты маршрутизации

Не забудьте в Interface Determination подключить наш мэппинг – OM_ExtSystem_Request_to_RFC:

Рис.14: Interface Determination и Operations Mapping

Рис.14: Interface Determination и Operations Mapping

Вот и все.

Теперь проверяем наш мост. В Sender Agreement, в меню выбираем пункт “Display WSDL”, затем нажимаем “Save” и сохраняем WSDL нашего сервиса-запроса на локальный диск.

Рис.15: Выгрузка WSDL для Sender SOAP Comm. Channel

Рис.15: Выгрузка WSDL для Sender SOAP Comm. Channel


Затем, используя любой инструмент отправки SOAP-запроса (я использовал freeware инструмент SOAPUI) и сохраненный WSDL, формируем запрос к PI.
Рис.16: Отправка SOAP-запроса из SOAPUI в PI

Рис.16: Отправка SOAP-запроса из SOAPUI в PI

Если все было настроено правильно – в целевой директории наблюдаем файл с ответом:

Рис.16: Файл с дополнительной информацией из ERP

Рис.16: Файл с дополнительной информацией из ERP

Итак, мы настроили пример асинхронно-синхронного моста с модулями в канале связи системы отправителя.
Поздравляю Вас, можно немного передохнуть, а затем переходить к следующему варианту моста.

2.3 Асинхронно-синхронный мост с модулями в Receiver Communication Channel.


Предположим, что мы не хотим (или не можем) затрагивать Sender Communication Channel. Существует возможность разместить те же модули в синхронном канале связи системы-получателя.

Логика работы асинхронно-синхронного моста с модулями в канале получателя следующая:

Рис.17: Логика работы асинхронно-синхронного моста при размещении адаптеров в канале связи получателя.

Рис.17: Логика работы асинхронно-синхронного моста при размещении адаптеров в канале связи получателя.

  1. Прием асинхронного сообщения по каналу связи с внешней системой
  2. Передача сообщения в PI.
  3. Обработка сообщения в PI, передача его в синхронный канал связи на вход модуля RequestResponseBean.
  4. RequestResponseBean переводит тип сообщения из асинхронного в синхронный, затем, используя параметры настройки, определяет – в какую систему вернуть ответ. В зависимости от параметра passThrough, сообщение либо передается далее по цепочке модулей до стандартного адаптера, либо напрямую в модуль ResponseOnewayBean (пропуская пп.4-6).
  5. Синхронный вызов внешней системы, получение результата.
  6. Возврат ответа в модуль ResponseOnewayBean, который меняет тип сообщения с синхронного на асинхронный.
  7. Возврат ответа в подсистему обработки сообщений, которая проводит маршрутизацию на базе заголовка сообщения. Параметры в заголовке сообщения изменены модулем RequestResponseBean на шаге 4.
  8. Передача сообщения в выбранный канал связи.
  9. Доставка сообщения во внешнюю систему по асинхронному каналу связи.

Мост строиться с использованием все тех же модулей 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-адаптер.
Будьте внимательны, и при возникновении ошибок анализируйте все возможные источники информации.

После настройки каналов связи нам осталось только создать два пути маршрутизации:

  1. Внешняя система -> Sender Agreement (если нужен) -> Reciever Determination -> Interface Determination -> Receiver Agreement -> Синхронный канал связи с модулями
  2. Синхронная система -> Sender Agreement (если нужен) -> Reciever Determination -> Interface Determination -> Receiver Agreement -> Асинхронный канал связи

Оба пути можно настроить и через Integrated Configuration.

2.4 Пример: Асинхронно-синхронный мост с модулями в Receiver Communication Channel


От теории – к практике! Давайте разберемся, как построить мост, если добавить модули в канал связи получателя.

Схема интерфейса выглядит следующим образом:

Рис.18: Схема примера асинхронно-синхронного моста SOAP-RFC-File

Рис.18: Схема примера асинхронно-синхронного моста SOAP-RFC-File

Нам потребуется небольшая подготовительная работа, не относящаяся непосредственно к настройке моста. В этот раз в качестве получателя будет выступать синхронный SOAP-сервис. Для простоты создадим его на базе функционального модуля из предыдущего примера (используя транзакции SE80 -> Enterprise Service и SOAMANAGER).

Рис.19: Создание SOAP-сервиса в транзакции SE80

Рис.19: Создание SOAP-сервиса в транзакции SE80

Рис.20: Настройка SOAP-сервиса в транзакции SOAMANGER

Рис.20: Настройка SOAP-сервиса в транзакции SOAMANGER

Рис.21: Настройка SOAP-сервиса в транзакции SOAMANGER

Рис.21: Настройка SOAP-сервиса в транзакции SOAMANGER

Выгружаем и импортируем в репозитарий PI WSDL нашего сервиса, получаем объект External Definition DOC_3I_ZZ_SOAP_EXT_REQUEST.
Далее создаем синхронный интерфейс SI_SOAP_ADDINFO_Sync, используя типы сообщений из предыдущего импорта:

Рис.22: Синхронный интерфейс на базе внешней WSDL

Рис.22: Синхронный интерфейс на базе внешней WSDL

На этом синхронная часть моста готова.
Для всего остального нам понадобятся следующие объекты разработки:

Рис.23: Объекты разработки в Integration Repository

Рис.23: Объекты разработки в Integration Repository


Итого:

  • Два асинхронных интерфейса для асинхронной системы (запрос и ответ): 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.

Рис.:24: Объекты настройки

Рис.:24: Объекты настройки

На этот раз (в отличии от п.2.2) попробуем построить маршрутизацию на Integrated Configuration. Создаем объект для передачи запроса:

Рис.:24: Integrated Configuration - Request

Рис.:24: Integrated Configuration – Request

Создадим синхронный канал связи с SOAP-сервисом CC_IntegrationServer_SOAP_Receiver:

Рис.25: Канал связи SOAP Receiver

Рис.25: Канал связи SOAP Receiver


Настроим модули в канале связи:
Рис.26: Канал связи SOAP Receiver - настройка модулей

Рис.26: Канал связи 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:

Рис.27:  Канал связи SOAP как placeholder в Integrated Configuration

Рис.27: Канал связи SOAP как placeholder в Integrated Configuration

Далее настраиваем обратную маршрутизацию обычным образом:

Рис.28:  Integrated Configuration - Reciever

Рис.28: Integrated Configuration – Reciever

Рис.29:  Integrated Configuration - Reciever Interface

Рис.29: Integrated Configuration – Reciever Interface

Рис.30:  Integrated Configuration - Outbound Processing

Рис.30: Integrated Configuration – Outbound Processing

Ну вот и все. Активируем все объекты настройки, тестируем с помощью SOAPUI, как в примере 2.2.

Результат радует нас XML-файлом с запрошенной информацией:

Рис.31: Файл с дополнительной информацией от SOAP-сервиса

Рис.31: Файл с дополнительной информацией от SOAP-сервиса

………………………………
Буду благодарен за комментарии и конструктивную критику!

Продолжение – в следующей статье: Наводим мосты – 2: Синхронно – Асинхронный вариант

50 thoughts on “SAP PI Async-Sync Bridge. Наводим мосты или как связать между собой асинхронный и синхронный интерфейсы без помощи ccBPM.

    1. pitroff.ru Post author

      Да не за что, Юлия.
      Попробую восполнить этот пробел, в меру сил и времени. )

      Reply
  1. Женя

    А еще есть возможность сделать LookUp из меппинга. Она самая простая, но почему-то не описана..

    Reply
    1. pitroff.ru Post author

      Женя, спасибо за дополнение!
      LookUp – да, можно попробовать. Поставлю это в следующую статью, в раздел “Экзотика”. )
      Насчет “самая простая” – не соглашусь, есть ньюансы: нужно хотя бы минимально знать java и при разработке учитывать производительность lookup.
      Да, не уверен еще, что на все адаптеры можно настроить lookup (RFC, JDBC, SOAP – точно можно, остальные – надо смотреть).
      Фактически, нужно будет сделать собственную разработку.
      Мост на модулях – это стандарт. Не очень “прямой” :), но стандарт.

      Reply
  2. Николай

    Замечательная статья! Вот только один момент остается непонятным: как обрабатывать ошибки передачи данных (async-sync bridge, вариант 2 с модулями в receiver)? Например, если принимающий SOAP-сервер встал. В этом случае “ответное” сообщение от него не генерится, хотя в канале четко видна ошибка уровня адаптера. Если нужно использовать параметр interfaceOnFault модуля, то какое сообщение надо использовать? Хотя, скорее всего, ошибку “физики” этим способом не поймать.

    Reply
    1. pitroff.ru Post author

      Спасибо, Николай!

      Если сервер встал – то вернется техническая ошибка адаптера SOAP по тайм-ауту. А дальше нужно будет один раз “поймать” эту ошибку и посмотреть – что за сообщение вернулось от адаптера, его и обрабатывать.
      Сам параметр interfaceOnFault не влияет на обработку – он лишь подменяет в заголовке этого обратного сообщения имя интерфейса на другое (если это нам нужно).

      Reply
      1. Николай

        Да, но она видна только в мониторинге канала. Сообщение при этом помечается как успешное и никакие алерты не срабатывают. Вот если бы ее можно было как-нибудь вытащить оттуда в сообщение…

        Reply
        1. pitroff.ru Post author

          А ведь точно! Спасибо за наводку, даже статью поправил – в документации, оказывается, говорится только об application error, я сходу не заметил. Попробовал – действительно, технические ошибки связи по тайм-ауту видны только в мониторе каналов.

          Надо думать.

          Reply
          1. Николай

            Со своей стороны пока не придумал ничего, кроме написания собственного модуля, который бы доставал ошибку из лога адаптера и правил бы соответствующим образом исходное/ответное сообщение.

            Reply
  3. Райчо

    Привет! Пытаюсь сделать сценарий FILE-SOAP-FILE с модулями в Receiver Communication Channel.
    Веб сервис исполняется успешно, но потом ошибка получается: “Message processing failed. Cause: com.sap.aii.adapter.xi.routing.RoutingException: InterfaceDetermination did not yield any actual interface”
    Пожалуйста помогите 🙂

    Reply
    1. pitroff.ru Post author

      Привет!

      Скорее всего – что-то с маршрутизацией на обратной дороге или с подменой имени интерфейса.

      Проверьте настройки модуля еще раз – возможно, что подмена не произвелась.
      Через что маршрутизацию делаете – “классически” или через Integrated Configuration?
      На момент ошибки какой интерфейс в заголовке сообщения указан в разделе sender?
      Есть в Integration Directory Interface Determination для этого интерфейса?

      Reply
  4. Райчо

    Привет,

    Я думаю что ошибка получается в 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

    Если можете помочь буду благодарен 🙂

    Reply
    1. pitroff.ru Post author

      Привет,

      не похоже, скорее всего – ошибка правил маршрутизации.
      На SCN таких ошибок много, причем иногда – интерфейс вообще модули не использует.

      Модуль ResponseOnewayBean начинает свои сообщения об ошибке с “ROB:”. 🙂

      Еще раз – проверьте обратную маршрутизацию, алгоритм поиска такой (если Вы используете Integrated Configuration – то искать на соответствующей вкладке):
      – посмотреть внимательно, совпадает ли имя интерфейса в параметрах модуля ResponseOneWayBean с именем интерфейса-отправителя в Receiver Determination – может быть банальная опечатка в настройках модуля.
      – проверить Interface Determination – есть ли условия на маршрутизацию (если ни одно не выполняется – то будет как раз такая ошибка) .
      – посмотрите в тексте сообщения – сменился ли интерфейс по итогам работы ResponseOneWayBean – в заголовке SOAP-XML, в разделе Sender.

      По итогам – будем дальше смотреть. 🙂

      Reply
  5. Райчо

    Привет,

    Я посмотрел опять – имя и пространство имен в модуле 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)?

    Reply
    1. pitroff.ru Post author

      Что-то не так. )

      Явно, ошибка где-то в маршрутизации. Ни модули, ни XI30-compartible тут не при чем.
      Можете полный XI-SOAP ответ с ошибкой прислать на почту (адрес – внизу страницы)? Namespace, если секретные, можно заменить. 🙂

      Reply
  6. black

    Спасибо, очень познавательно!
    ждем с нетерпением “А в следующей статье я расскажу о синхронно-асинхронном мосте и его видах.”=)

    Николай подымал вопрос по поводу обработки ошибок на Receiver SOAP адаптере, на сколько я понимаю, в sxmb_moni не отображаются эти ошибки только если мост сделан без средств ccBPM? Потому что, если в подобном сценарии (sync\async ссBPM) специально валю канал, то в sxmb_moni выходит ошибка типа “XIAdapterFramework”.

    Reply
    1. pitroff.ru Post author

      Добрый день!

      Так я уже выложил 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 сам генерирует ошибку, не дождавшись ответа от адаптера. Модули же такую ошибку не обрабатывают.

      Reply
  7. Виталий

    отличная статья, подробно с примерами

    однако, у меня на практике что-то не сложилось…
    пробовал оба варианта с модулями в отправителе и в получателе, и получал похожие ошибки в обоих случаях:
    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.

    Reply
    1. pitroff.ru Post author

      Добрый день, Виталий!

      Судя по ошибке – неверно указано имя модуля, проверьте наименование модуля на вкладке Modules.
      Там должно быть “AF_Modules/RequestResponseBean”, без кавычек.

      С уважением,
      Алексей

      Reply
  8. Виталий

    Алексей, огромное спасибо
    Вы были абсолютно правы

    Столько раз говорилось о необходимости ТОЧНО указывать имя модуля, что я зациклился на сверке регистров, копировал из текста статьи название RequestResponseBean, но забыл про путь (префикс AF_Modules/)

    Спасибо.
    Сценарий работает.

    Reply
  9. Николай

    Добрый день!
    Еще небольшой вопросик. Интерсно, а зачем нужен параметр replaceInterface в модуле ResponseOnewayBean (вариант “Мост с модулями в Receiver Communication Channel”)? Если поставить его в false, то система в процессе маршрутизации обратного сообщения потребует receiver agreemenr’а для от , интерфейс . В то же время, я не нашел способа создать Interface mapping, в котором бы в качестве и Source Interface выступал бы . При этом, чтобы бралось его response-сообщение и маппилось бы на сообщение асинхронного интерфейса системы .

    Reply
  10. Николай

    И еще одно замечание, касающееся создания асинхронно-синхронного моста с модулями в канале 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 и активация не происходит.

    Reply
    1. pitroff.ru Post author

      Приветствую, Николай,

      Опечатка, спасибо.
      В п.4 оба интерфейса – синхронные. После этого нужно активировать Operation Mapping и перейти к п.5.

      UPD: Хотя нет, пересмотрел еще раз – у меня работало именно так, как в статье.
      К сожалению, сейчас нет системы под рукой – проверить.

      Reply
      1. Николай

        Синхронными оба быть не могут, тогда весь смысл теряется и модуль RequestResponseBean вроде не нужен 🙂
        У меня 7.40, там н работает (текст ошибки присылал). К тому же есть вариант, когда схема с модулями в Sender’е не сработает точно – когда входят IDoc’и. Поверх IDOC’а не нужно строить интерфейс, а синхронным его не сделаешь по-определению.

        Reply
        1. pitroff.ru Post author

          Я пример проходил “руками” именно на 7.4 – работает.

          Синхронные оба интерфейса только на момент активации мэппинга. Затем сразу же нужно сменить тип исходящего интерфейса на асинхронный и активировать только сам интерфейс.
          После активации в кэш появляется активный объект мэппинга, который в момент работы не проверяет тип интерфейса.

          Reply
        2. pitroff.ru Post author

          Про IDOC – пожалуй соглашусь, схема с модулями в Sender не сработает.
          Хотя – можно было бы с “бубном” потанцевать вокруг, если бы время было. 🙂

          Reply
          1. Николай

            Я пробовал по всякому. Если поверх IDOC’а сделать интерфейс, даже асинхронный, то IDOC в AAE-adapter на PI уже не попадает.

            Reply
            1. pitroff.ru Post author

              Да там и пробовать не нужно – IDoc-адаптер в Dual Stack сделан “топорно”. 🙂

              При приходе Idoc он отправляется в ABAP на вход функционального модуля, который проверяет настройки (“это Integration Engine или нет?”) – и в зависимости от настроек либо отправляет на вход стандартной процедуры, либо в прямиком в pipeline.

              Reply
  11. Николай

    Добрый день!
    Нашел еще один момент. Настройка асинхронно-синхронного моста с модулями в 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 интерфейс был синхронным, то активировать его не удастся (см. вчерашний вопрос).

    Reply
  12. Кирилл

    Добрый день,

    подскажите, пожалуйста, для случая Асинхронно-синхронный моста с модулями в Receiver Communication Channel, как можно сохранить значение каког-либо поля из сообщения системы-источника, чтобы потом его использовать в конечной системе, которая принимает ответ? В сихронном сообщении можно было использовать динамическую конфигурацию, а с мостом она не работает.
    Пример: АсихрФайл->ПиАй->СихронВебсервис->ПиАй->SAP ABAP proxy
    файл сожержит уникальный номер, который отправляется в вебсервис но ответ уже юез номер. А номер надо использовать в конце для записи в SAP. Как можно этот номер в PI сохранить и в добавить в конце в меппинге?

    Спасибо

    Reply
  13. Юлия

    Добрый день! Спасибо за вашу работу, настольные ссылки для меня.
    Не могли бы вы пояснить такую проблему.
    Сценарий асинх-синх, 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 находится на виртуальном рабочем столе, может в этом причина появления такой ошибки.
    Заранее благодарю.

    Reply
    1. pitroff.ru Post author

      Юлия,

      удаленная отладка сродни посадке самолета по телефону. 🙂

      На каком этапе возникает ошибка – прием IDOC, мэппинг или отправка SOAP?
      В SOAPUI видно вызов?
      Очень похоже на ошибку технического мэппинга из IDoc в XML – нужно в технический заголовок XML смотреть.

      Reply
      1. Shruthi

        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?

        Reply
        1. pitroff.ru Post author

          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.

          Reply
  14. Евгений

    Здравствуйте, Алексей!

    Настроил сценарий: 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 все было настроено именно по данным, что указаны в ошибке. Как только включил признак – все заработало.
    Вот не совсем понимаю, каким образом этот признак на логику работы влияет.

    Reply
  15. Александр

    Алексей, добрый день!

    Спасибо за ваши чёткие статьи.
    В этой статье для создания синхронного веб-сервиса в SAP вы используете транзакции se80 (для создания веб-сервиса) и SOAMANAGER (для настройки).
    Не совсем понятно, что за настройки необходимо выполнить в SOAMANAGER? Почему нельзя просто взять url WSDL из se80 и направить его внешней системе для использования?

    Reply
    1. pitroff.ru Post author

      Александр, добрый день!

      В SAP такая логика заложена: SE80 – это определение(definition), а SOAMANAGER – это его конфигурация (runtime configuration).
      wsdl разные будут.

      Reply
      1. Александр

        Алексей, спасибо, теперь понятнее стало (чувствуется аналогия с XI/PI)!
        1. Т.е. wsdl в SE80 – это вроде как xsd-схема, а wsdl в SOAMANAGER – это уже сам xml?
        2. в SOAMANAGER к сервису можно сделать привязку (bind) и у неё также есть свой отдельный wsdl, а он для чего используется?
        3. Какой в итоге из трёх wsdl необходимо использовать для вызова сервиса из внешней системы?

        Reply
        1. pitroff.ru Post author

          Александр, добрый день,

          1) Скорее SE80 – это WSDL со структурой данных, а SOAMANAGER – wsdl с привязкой к конкретной системе.
          2) Bind – это указание внешней системе – по какому url вызывать данный сервис.
          3) wsdl в SOAMANAGER.

          Reply
          1. Александр

            Алексей, спасибо за быстрый ответ.

            Настроил, даже тест проходит, но в SOAMANAGER на вкладке “мониторинг” нет никаких xml-сообщений…
            Мониторинг надо как-то отдельно настраивать?

            Reply
              1. Александр

                Ок, спасибо, буду пробовать!
                А если не в SOAMANAGER, то как в SAP ERP можно промониторить передачу сообщений через веб-сервис?

                Reply
                1. pitroff.ru Post author

                  Про payload сходу не скажу, а сам факт и процесс вызова сервиса можно в SMICM (http trace) посмотреть.

                  Reply
                  1. Александр

                    Алексей, спасибо за наводку!
                    Горизонты данной статьи существенно расширились:)

                    Reply
  16. Андрей Петин

    Алексей, здравствуйте.

    Спасибо вам за эти статьи.
    Сделал у себя асинхронно-синхронный мост FTP -> JDBC (синхронно) -> FTP.
    Модули в канале-сендере.
    Можно было и двумя асинхронными взаимодействиями обойтись, но нужно максимально быстро получать ответный файл, и заодно это повод опробовать описанное вами решение.
    Всё работает. Использую 7.4 Single Stack.

    Смущает один нюанс. Если ошибка на стороне получателя (JDBC), то сообщение сразу падает в статус Cancelled и не подлежит переотправке.
    Учитывая, что отправитель работает в асинхронном режиме (и не висит в ожидании ответа), идеологически ничего не мешает попытаться повторить сообщение.
    Можно ли это как-то сделать?

    Reply
    1. pitroff.ru Post author

      Андрей, добрый день!

      Посмотрите настройки 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&current_toc=/en/ca/b977f1c7814201954f20bb87ad7aab/plain.htm&node_id=65&show_children=false

      Reply

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *