wso2esb повторяется через результат wso2dss
Я хочу написать следующую целевую последовательность действий: 1. вызвать DSS, чтобы получить список клиентов 2. обогатить каждого клиента отдельным вызовом другой службой DSS.
Итак, я подумал, что должен вызвать медиатор обратного вызова, а затем повторить его результат, используя итератор. Но я не могу понять, что я должен написать в итераторе.
И еще один вопрос - я прав, что результат каждой итерации будет прикреплен к тегу customer?
Подробности:
XML, который возвращается из DSS, следующий:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<customers xmlns="crm.crm.crm">
<customer>
<customerId>1</customerId>
<name>Customer #1</name>
<birthdate>2017-01-15T14:54:12.000+03:00</birthdate>
</customer>
</customers>
</soapenv:Body>
</soapenv:Envelope>
Последовательность:
<?xml version="1.0" encoding="UTF-8"?>
<sequence name="BatchSequence" statistics="enable" trace="disable" xmlns="http://ws.apache.org/ns/synapse">
<log description="">
<property name="text" value="Start batch seq"/>
</log>
<payloadFactory description="create dss request" media-type="xml">
<format>
<soapenv:Envelope xmlns:crm="crm.crm.crm" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<crm:getCustomers>
<crm:batchSize>3</crm:batchSize>
</crm:getCustomers>
</soapenv:Body>
</soapenv:Envelope>
</format>
<args/>
</payloadFactory>
<callout action="urn:getCustomers" description="dss: main object" initAxis2ClientOptions="false" serviceURL="http://192.168.3.32:9765/services/CrmDataService?wsdl">
<source type="envelope"/>
<target key="customers"/>
</callout>
<log description="">
<property expression="get-property('customers')" name="text"/>
</log>
<iterate description="Enrich customers" expression="/soapenv:Envelope/soapenv:Body/customers/customer" id="iterateId" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<target>
<sequence>
<property description="customerId" expression="/customerId" name="customerID" scope="default" type="STRING"/>
<log description="">
<property expression="get-property('customerID')" name="text"/>
</log>
</sequence>
</target>
</iterate>
<log description="">
<property name="text" value="End batch seq"/>
</log>
</sequence>
выход:
[2017-01-27 10: 17: 17,371] ИНФОРМАЦИЯ - LogMediator To:, MessageID: urn:uuid:d628e361-beb8-4c26-b06d-3901227ad76a, Направление: запрос, текст = Запуск пакета seq [2017-01-27 10:17:18,558] ИНФОРМАЦИЯ - LogMediator To:, MessageID: urn:uuid:d628e361-beb8-4c26-b06d-3901227ad76a, Направление: запрос, текст = 1 Клиент № 12017-01-15T14:54:12.000+03:002 Клиент № 22016-12-16T14:54:20.000+03:003Клиент #32016-10-27T14:54:21.000+03:00 [2017-01-27 10:17:18,559] ПРЕДУПРЕЖДЕНИЕ - RuntimeStatisticCollector События происходят после завершения сбора события, событие - urn_uuid_d628e361-beb8-4c26-b06d-3901227ad7 6a231160071781262
Обновление 1 Некоторый рабочий код. Не уверен, что это правильно, потому что я немного запутался для PayloadFactory здесь..
<payloadFactory description="" media-type="xml">
<format>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>$1</soapenv:Body>
</soapenv:Envelope>
</format>
<args>
<arg evaluator="xml" expression="get-property('customers')"/>
</args>
</payloadFactory>
<iterate continueParent="true" description="" expression="$body/crm:customers/crm:customer" sequential="true" xmlns:crm="crm.crm.crm">
<target>
<sequence>
<property expression="//crm:customerId" name="customerID" scope="default" type="STRING"/>
<log>
<property expression="get-property('customerID')" name="text"/>
</log>
</sequence>
</target>
</iterate>
Обновление 2 Я понял, что главная проблема - посредник выноски не помещает ответ в контекст конверта (если я правильно понимаю). Итак, мы не можем использовать просто свойство, чтобы связать его с итератором, поэтому в этом случае мы должны связать их, используя что-то вроде фабрики полезной нагрузки. Не очень полезно Если smbdy знает, как сделать это более просто (прямая передача свойства итератору) - пожалуйста, напишите мне. Решение - воспользоваться Call medator. Работает отлично.
Спасибо всем!
2 ответа
Вы можете использовать вложенные запросы. Пожалуйста, проверьте этот пост https://docs.wso2.com/display/DSS351/Nested+Query+Sample
XML-узлы в ответе dss принадлежат пространству имен "crm.crm.crm", и вы должны ссылаться на него в своем xpath
С помощью итерации mediatior, если вы хотите сохранить исходную полезную нагрузку, вы должны использовать атрибут с именем preservePayload="true" и сообщить, где фрагменты xml должны быть присоединены с атрибутом attachPath, иначе в последовательности interate у вас будет только ваш фрагмент xml в мыльное тело
Это пример, который работает без сохранения полезной нагрузки источника:
<iterate xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:crm="crm.crm.crm" expression="$body/crm:customers/crm:customer" id="iterateId">
<target>
<sequence>
<property expression="$body/crm:customer/crm:customerId" name="customerID" scope="default" type="STRING"/>
<log>
<property expression="get-property('customerID')" name="text"/>
</log>
</sequence>
</target>
</iterate>
По умолчанию посредники после повторения не будут выполняться. Если вы хотите продолжить посредничество, используйте атрибут continueParent="true"