wso2 ESB: шаблон разделения / сбора - одиночный ответ
Это не вопрос, а скорее ответ. Я совершенно новичок в wso2 ESB и хотел сделать тестовый запуск, реализующий EIP с разделением / сборкой как часть POC. Я последовал примерам, которые нашел, и сразу же получил рабочую конфигурацию, которая возвращала единственный ответ. Однако чтобы получить ответы на все вопросы, потребовалось некоторое время, чтобы выяснить это. Большинство данных образцов, казалось, дали тот же неожиданный результат. Я надеюсь, что если вы столкнетесь с такой же проблемой, эти строки будут вам полезны.
Настроить
Я использовал пример службы soapUI (операция поиска) в качестве бэкэнда службы. Я отправил комбинированное сообщение в поисках двух элементов на прокси-сервер (см. Артефакт ниже). Посредник итерации разделяет сообщение и перенаправляет его в конечную точку, которая вызывает макет soapUI. Агрегирующий посредник ожидает всех ответов и пытается поместить их в одно сообщение о результате.
проблема
Хотя сплиттер работал правильно, агрегатор возвратил только один элемент результата, а не список элементов, как ожидалось. Все журналы показали, что все было в порядке, несколько запросов было отправлено на соответствующие конечные точки, но все же только первый ответ, который был возвращен, был виден в конечном ответе.
Решение
После установки уровня журнала прокси TRACE я понял, что агрегатор работает просто отлично, только он создает сообщение, которое на самом деле не соответствует SOAP. Все агрегированные элементы были добавлены непосредственно под мыльным телом. Поэтому вопрос заключался в том, как добавить один корневой элемент между тегами body и result. Сначала я попробовал XSLT, но он также мог читать только первый дочерний элемент тела. Наконец, я нашел какой-то глубоко скрытый намек на использование посредника обогащения (или, вернее, серии этого), и это помогло. Следующий список объясняет ту часть конфигурации (код показан ниже), которую нет в большинстве примеров.
- Сначала используйте Enrich для захвата всех соответствующих предметов в собственность
- Забудьте о текущем сообщении - перепишите полный конверт с телом, содержащим только новый корневой элемент полезной нагрузки
- Присоедините элементы, хранящиеся в свойстве, к новому корню полезной нагрузки.
- Если необходимо, захватите заголовок мыла в свойстве и присоедините его к новому сообщению (не в конфигурации ниже)
Артефакты
Демо-запрос
<body>
<sam:multisearch xmlns:sam="http://www.example.org/sample/">
<sam:search>
<sessionid>123</sessionid>
<searchstring>Item 1</searchstring>
</sam:search>
<sam:search>
<sessionid>123</sessionid>
<searchstring>Item 2</searchstring>
</sam:search>
</sam:multisearch>
</body>
конфиг
<proxy xmlns="http://ws.apache.org/ns/synapse" name="test.multisearch" transports="https,http" statistics="enable" trace="enable" startOnLoad="true">
<target>
<inSequence>
<iterate xmlns:sam="http://www.example.org/sample/" expression="//sam:multisearch/sam:search">
<target>
<sequence>
<send>
<endpoint key="soapUI_Mockup"/>
</send>
</sequence>
</target>
</iterate>
</inSequence>
<outSequence>
<aggregate>
<completeCondition>
<messageCount min="-1" max="-1"/>
</completeCondition>
<onComplete xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sam="http://www.example.org/sample/" expression="//sam:searchResponse">
<enrich>
<source clone="true" xpath="$body//item"/>
<target type="property" property="ResultItems"/>
</enrich>
<log level="custom">
<property name="ResultItems" expression="get-property('ResultItems')"/>
</log>
<enrich>
<source type="inline" clone="true">
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<sam:GenericDataResponse/>
</soapenv:Body>
</soapenv:Envelope>
</source>
<target type="envelope"/>
</enrich>
<enrich>
<source type="property" clone="true" property="ResultItems"/>
<target action="child" xpath="//sam:GenericDataResponse"/>
</enrich>
<send/>
</onComplete>
</aggregate>
</outSequence>
</target>
<description></description>
</proxy>
Наконец вопрос
Если бы кто-то мог намекнуть мне на какую-то документацию или дать мне какой-нибудь рабочий конфиг для атрибута correlateOn агрегатного посредника, я был бы очень благодарен.
2 ответа
Вам нужно указать любой идентификатор в посреднике итератора (см. Документацию посредника итератора) и указать тот же идентификатор в посреднике агрегатора, что и идентификатор корреляции. Вот и все. -
Агрегаторный посредник поддерживает атрибут enclosingElementProperty, который окружает ответы одним родительским элементом. Это упрощает ваш трюк с обогащением:
<property name="ROOT" scope="default">
<root:rootelement xmlns:root="www.wso2esb.com"/>
</property>
<aggregate>
<completeCondition>
<messageCount min="-1" max="-1"/>
</completeCondition>
<onComplete expression="//dummy" enclosingElementProperty="ROOT">
</onComplete>
</aggregate>