I have been busy refactoring my sequences and proxy ( see WSO2 Aggregate Mediator premature/incomplete/unknown completion ). After I had gotten it working as per previous question , it has produced some unwanted behaviour. I only changed the names of the sequences , nothing else.
Now after my second aggregator :
<sequence xmlns="http://ws.apache.org/ns/synapse">
<log level="custom">
<property name="pocSearchRsHandlerSeq reached" value="++++++++++++++=========Aggregating now========+++++++++++++++++=="></property>
</log>
<aggregate id="iT">
<completeCondition>
<messageCount min="-1" max="-1"></messageCount>
</completeCondition>
<onComplete xmlns:ns="http://org.apache.synapse/xsd" expression="//productDetails">
<log level="custom" separator=",">
<property name="::::" value="======================= Formatting the Aggregated Responses. ==============="></property>
</log>
<log level="full"></log>
</onComplete>
</aggregate>
<aggregate>
<completeCondition>
<messageCount min="-1" max="-1"></messageCount>
</completeCondition>
<onComplete xmlns:ns="http://org.apache.synapse/xsd" expression="//productDetails">
<payloadFactory media-type="xml">
<format>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:prod="http://za.co.pepkor/product_service/">
<soapenv:Body>
<prod:productSearchResp> $1 </prod:productSearchResp>
</soapenv:Body>
</soapenv:Envelope>
</format>
<args>
<arg expression="//productDetails" evaluator="xml"></arg>
</args>
</payloadFactory>
<respond></respond>
</onComplete>
</aggregate>
</sequence>
Now ,it is dropping(or forgetting) that aggregated message (which previously looked like this for example) :
?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<productDetails>
<productID>1452168</productID>
<productName>PUMPS</productName>
<productSize>7</productSize>
<productColour>ORANGE</productColour>
<productType>SHOE</productType>
<sourceID>SHC</sourceID>
</productDetails>
<productDetails>
<productID>1124596</productID>
<productName>REEBOK_SNEAKERS</productName>
<productSize>7</productSize>
<productColour>BROWN</productColour>
<productType>SHOES</productType>
<sourceID>SHC</sourceID>
</productDetails>
<productDetails>
<productID>1123456</productID>
<productName>NIKE_SHIRTS</productName>
<productSize>7</productSize>
<productColour>RED</productColour>
<productType>SHIRT</productType>
<sourceID>SHC</sourceID>
</productDetails>
</soapenv:Body>
</soapenv:Envelope>
And sending in this to be secondarily aggregated instead :
<?xml version="1.0" encoding="utf-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body></soapenv:Body></soapenv:Envelope>
I am getting a lot of these empty messages back into my proxies outSequence for some reason :
TID: [0] [ESB] [2015-02-25 16:22:01,023] DEBUG {org.apache.synapse.core.axis2.SynapseCallbackReceiver} - Synapse received an asynchronous response message {org.apache.synapse.core.axis2.SynapseCallbackReceiver}
TID: [0] [ESB] [2015-02-25 16:22:01,023] DEBUG {org.apache.synapse.mediators.base.SequenceMediator} - Start : Sequence <ackServiceSearchSeqRs> {org.apache.synapse.mediators.base.SequenceMediator}
TID: [0] [ESB] [2015-02-25 16:22:01,023] DEBUG {org.apache.synapse.core.axis2.SynapseCallbackReceiver} - Received To: null {org.apache.synapse.core.axis2.SynapseCallbackReceiver}
TID: [0] [ESB] [2015-02-25 16:22:01,024] DEBUG {org.apache.synapse.mediators.base.SequenceMediator} - Sequence <SequenceMediator> :: mediate() {org.apache.synapse.mediators.base.SequenceMediator}
TID: [0] [ESB] [2015-02-25 16:22:01,024] DEBUG {org.apache.synapse.core.axis2.SynapseCallbackReceiver} - SOAPAction: {org.apache.synapse.core.axis2.SynapseCallbackReceiver}
TID: [0] [ESB] [2015-02-25 16:22:01,024] DEBUG {org.apache.synapse.mediators.base.SequenceMediator} - Mediation started from mediator position : 0 {org.apache.synapse.mediators.base.SequenceMediator}
TID: [0] [ESB] [2015-02-25 16:22:01,024] DEBUG {org.apache.synapse.core.axis2.SynapseCallbackReceiver} - WSA-Action: {org.apache.synapse.core.axis2.SynapseCallbackReceiver}
TID: [0] [ESB] [2015-02-25 16:22:01,025] DEBUG {org.apache.synapse.core.axis2.SynapseCallbackReceiver} - Body :
<?xml version="1.0" encoding="utf-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body></soapenv:Body></soapenv:Envelope> {org.apache.synapse.core.axis2.SynapseCallbackReceiver}
At least 2 everytime. I have disabled continueParent.
EDIT
Check out WSO2 ESB : Aggregate node droppping message after aggregation for more background info
In the onComplete of <aggregate id="iT"> , you will have the aggregated
productDetails as follow
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:prod="http://za.co.pepkor/product_service/">
<soapenv:Body>
<productDetails>
----
</productDetails>
<productDetails>
----
</productDetails>
</soapenv:Body>
</soapenv:Envelope>
so you can add the root element <prod:productSearchResp> to soap body with payload factory mediator.
<payloadFactory media-type="xml">
<format>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:prod="http://za.co.pepkor/product_service/">
<soapenv:Body>
<prod:productSearchResp> $1 </prod:productSearchResp>
</soapenv:Body>
</soapenv:Envelope>
</format>
<args>
<arg xmlns:ns="http://org.apache.synapse/xsd" evaluator="xml" expression="//productDetails"/>
</args>
</payloadFactory>
No need for second aggregate and having payload factory mediator within that.
Related
I'm send soap reqest to microservice and in respond I get this.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<soapenv:Fault>
<faultcode xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">SOAP-ENV:Client</faultcode>
<faultstring>An error was detected in the Web Service request. (10894)</faultstring>
<detail>
<ns1:FaultDetail xmlns:ns1="urn:soap-fault:details">
<errorMessage>Error in SOAP Envelope: Content length must be specified. (10913)</errorMessage>
<requestID>----</requestID>
</ns1:FaultDetail>
</detail>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
I create my soap envelope in payloadFactory.
<payloadFactory description="Set ARGS for CALL" media-type="xml">
<format>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:xyz:zyz">
<soapenv:Header/>
<soapenv:Body>
...
</soapenv:Body>
</soapenv:Envelope>
</format>
<args>
...
</args>
</payloadFactory>
Next I send this to microservice. Micro service work on SOAP 1.1. I'm don't attach content lenght because I do not know how.
After the PL factory and before sending the request try setting the following properties.
<property name="DISABLE_CHUNKING" value="true" scope="axis2" />
<property name="messageType" value="text/xml" scope="axis2" type="STRING"/>
I've tried several ways to get The Property from OnComplete AggregateMediator and used it in Expression prop of ForEach Mediator, but none of these is suceed.
I've searched in google too, but no luck at all.
Here is my RESTful API (in short mode):
This is inSequence section
<api xmlns="http://ws.apache.org/ns/synapse" context="/path/to/context" name="NamedAPI">
<resource methods="POST" protocol="http">
<inSequence>
<property expression="count(//parameter/objects)" name="count" scope="default" type="STRING"/>
<iterate expression="//parameter/objects" id="iterate1" sequential="true">
<target>
<sequence>
<property expression="//objects/text()" name="element1" scope="default" type="STRING"/>
<sequence key="getIdOfElement1"/>
<property expression="json-eval($.result.id)" name="el1id" scope="default" type="STRING"/>
<payloadFactory media-type="xml">
<format>
<ids xmlns="">
<id>$1</id>
</ids>
</format>
<args>
<arg evaluator="xml" expression="get-property('el1id')"/>
</args>
</payloadFactory>
</sequence>
</target>
</iterate>
<aggregate id="iterate1">
<completeCondition timeout="10">
<messageCount max="-1" min="{get-property('count')}"/>
</completeCondition>
<onComplete expression="//ids">
<property expression="$body" name="message" scope="operation" type="OM"/>
</onComplete>
</aggregate>
<payloadFactory media-type="xml">
<format>
<result xmlns="">$1</result>
</format>
<args>
<arg evaluator="xml" expression="get-property('operation','message')"/>
</args>
</payloadFactory>
<send>
<endpoint key="NamedEP"/>
</send>
</inSequence>
This is OutSequence section:
<outSequence>
<property expression="get-property('operation', 'message')" name="IDs"/>
<log level="custom">
<property expression="//ids" name="========== LIST IDs =========="/>
</log>
<foreach expression="//ids" id="foreach1">
<sequence>
<log level="custom">
<property expression="//id" name="========== ID =========="/>
</log>
<log level="full"/>
<dbreport>
<connection>
<pool>
<dsName>A_DS</dsName>
</pool>
</connection>
<statement>
<sql>INSERT INTO "table" ("field1", "id") VALUES (?,?)</sql>
<parameter expression="get-property('field1')" type="VARCHAR"/>
<parameter expression="//id" type="INTEGER"/>
</statement>
</dbreport>
</sequence>
</foreach>
<payloadFactory media-type="json">
<format>
[{ "field1" : "$1" }]
</format>
<args>
<arg evaluator="xml" expression="get-property('field1')"/>
</args>
</payloadFactory>
<property name="messageType" scope="axis2" type="STRING" value="application/json"/>
<property expression="json-eval($.)" name="response" scope="default" type="STRING"/>
<send/>
</outSequence>
This is FaultSequence Section
<faultSequence>
<payloadFactory media-type="json">
<format>
[{ "fault" : { "responsecode" : "999", "responsedesc" : "General error", "errordetails" : "$1" } }]
</format>
<args>
<arg evaluator="xml" expression="$ctx:ERROR_MESSAGE"/>
</args>
</payloadFactory>
<respond/>
<send/>
</faultSequence>
</resource>
</api>
I've Tried this:
<foreach expression="//ids" id="foreach1">
it does not work. The DBReport not executed in ForEach Mediator, so does the Log Mediator
I've Tried this:
<foreach expression="get-property('operation', 'message')" id="foreach1">
The WSO2EI showed me an error
I've tried to move all of the Mediator (ForEach and DBReport) in OutSequence Section to the InSequence Section but it's not worked too.
Please, help me.
Any help will be appreciated.
Thanks in advance.
Here is the log as per #Arunan's Comment
TID: [-1234] [] [2019-08-21 10:00:06,176] INFO {org.apache.synapse.mediators.builtin.LogMediator} - ========== START COUNTER ========== = 1 {org.apache.synapse.mediators.builtin.LogMediator}
TID: [-1234] [] [2019-08-21 10:00:06,176] INFO {org.apache.synapse.mediators.builtin.LogMediator} - ========== START ITERATE NO : = 2.0 {org.apache.synapse.mediators.builtin.LogMediator}
TID: [-1234] [] [2019-08-21 10:00:06,177] INFO {org.apache.synapse.mediators.builtin.LogMediator} - ========== NIP FROM ITERATE : = 198910202001020001 {org.apache.synapse.mediators.builtin.LogMediator}
TID: [-1234] [] [2019-08-21 10:00:06,180] INFO {org.apache.synapse.mediators.builtin.LogMediator} - ========== START ITERATE NO : = 2.0 {org.apache.synapse.mediators.builtin.LogMediator}
TID: [-1234] [] [2019-08-21 10:00:06,181] INFO {org.apache.synapse.mediators.builtin.LogMediator} - ========== NIP FROM ITERATE : = 199509142005010001 {org.apache.synapse.mediators.builtin.LogMediator}
TID: [-1234] [] [2019-08-21 10:00:06,230] INFO {org.apache.synapse.mediators.builtin.LogMediator} - ========== RPID FROM SEQUENCE IN ITERATE ========== = 3 {org.apache.synapse.mediators.builtin.LogMediator}
TID: [-1234] [] [2019-08-21 10:00:06,230] INFO {org.apache.synapse.mediators.builtin.LogMediator} - ========== RPID FROM SEQUENCE IN ITERATE ========== = 1 {org.apache.synapse.mediators.builtin.LogMediator}
TID: [-1234] [] [2019-08-21 10:00:06,262] INFO {org.apache.synapse.mediators.builtin.LogMediator} - ========== EXIST RICE DOCUMENT ========== = 0 {org.apache.synapse.mediators.builtin.LogMediator}
TID: [-1234] [] [2019-08-21 10:00:06,348] INFO {org.apache.synapse.mediators.builtin.LogMediator} - ========== LIST RPIDs ========== = {org.apache.synapse.mediators.builtin.LogMediator}
Alhamdulillah, I've tried my best, and It's worked Perfectly.
How to share the messaging between InSequence and OutSequence (in my case: from Aggregate Mediator inside inSequence section to Expression ForEach Mediator inside OutSequence section).
You must declare new property, and get the value from message property, like:
<property expression="get-property('operation', 'message')" name="rpidList" scope="default" type="OM"/>
And, in the ForEach Expression, you give a code below
<foreach expression="$ctx:rpidList//rpids" id="foreach1">
Thanks for all.
And Thank you StackOverflow.com
Foreach is not working properly under AggregateMediator's scope in response flow
Input request :
[
{
"name" : "Home"
},
{
"name" : "Car"
},
{
"name" : "Mobile"
}
]
I am using iterate, to send each element of above array as a request to a pass-through service( In my actual project this is not pass through. For better understanding of issue I kept it like this ).
The responses of the pass through service are aggregated in one soap xml by AggregateMediator.
Below is response from AggregateMediator
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<Information>
<jsonObject>
<name>Mobile</name>
</jsonObject>
<jsonObject>
<name>Car</name>
</jsonObject>
<jsonObject>
<name>Home</name>
</jsonObject>
</Information>
</soapenv:Body>
</soapenv:Envelope>
Using foreach to modify each response depending on some parameters coming in response.
But the Foreach is not working properly under Aggregator scope in response flow . Its response is weird.
For-each response :
[2017-07-11 14:07:44,696] INFO - LogMediator msg4 = "Inside Foreach"
[2017-07-11 14:07:44,697] INFO - LogMediator To: http://www.w3.org/2005/08/addressing/anonymous, WSAction: , SOAPAction: , MessageID: urn:uuid:3e1fd827-12ab-413c-824d-c9daf7b6df7c, Direction: response, Envelope: <?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<jsonObject>
<name>Home</name>
</jsonObject>
</soapenv:Body>
</soapenv:Envelope>
[2017-07-11 14:07:44,697] INFO - LogMediator msg4 = "Inside Foreach"
[2017-07-11 14:07:44,697] INFO - LogMediator To: http://www.w3.org/2005/08/addressing/anonymous, WSAction: , SOAPAction: , MessageID: urn:uuid:3e1fd827-12ab-413c-824d-c9daf7b6df7c, Direction: response, Payload: {"name":"Home"}
[2017-07-11 14:07:44,697] INFO - LogMediator msg4 = "Inside Foreach"
[2017-07-11 14:07:44,698] INFO - LogMediator To: http://www.w3.org/2005/08/addressing/anonymous, WSAction: , SOAPAction: , MessageID: urn:uuid:3e1fd827-12ab-413c-824d-c9daf7b6df7c, Direction: response, Payload: {"name":"Home"}
--------------------------------------------------------------------------------
The second and third iterate of foreach should have been like below :
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<jsonObject>
<name>Mobile</name>
</jsonObject>
</soapenv:Body>
</soapenv:Envelope>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<jsonObject>
<name>Car</name>
</jsonObject>
</soapenv:Body>
</soapenv:Envelope>
Instead of :
Payload: {"name":"Home"}
Payload: {"name":"Home"}
Please find below flow xml's.
forEachTest.xml :
<?xml version="1.0" encoding="UTF-8"?>
<api context="/foreschTest" name="foreachTest" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST GET" uri-template="/hi">
<inSequence>
<log level="full"/>
<log level="custom">
<property expression="//jsonArray" name="message"/>
</log>
<iterate expression="//jsonArray/jsonElement" id="1">
<target>
<sequence>
<log level="custom">
<property name="msg2" value=""Inside Foreach""/>
</log>
<log level="full"/>
<send>
<endpoint key="modifyAgrRespEP"/>
</send>
</sequence>
</target>
</iterate>
</inSequence>
<outSequence>
<property name="info" scope="default">
<Information xmlns=""/>
</property>
<aggregate id="1">
<completeCondition>
<messageCount max="-1" min="-1"/>
</completeCondition>
<onComplete enclosingElementProperty="info" expression="//jsonObject">
<log level="custom">
<property name="msg3" value=""Inside Aggr""/>
</log>
<log level="full"/>
<foreach expression="//Information/jsonObject">
<sequence>
<log level="custom">
<property name="msg4" value=""Inside Foreach""/>
</log>
<log level="full"/>
</sequence>
</foreach>
</onComplete>
</aggregate>
</outSequence>
<faultSequence/>
</resource>
</api>
modifyAgrRes (Passthrough flow) :
<?xml version="1.0" encoding="UTF-8"?>
<api context="/mod" name="modifyAgrRes" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST GET" uri-template="/aggr">
<inSequence>
<log level="custom">
<property name="message" value=""Inside Modify Service *************************""/>
</log>
<log level="custom">
<property expression="//jsonObject" name="location"/>
</log>
<respond/>
</inSequence>
<outSequence>
<send/>
</outSequence>
<faultSequence/>
</resource>
</api>
I have a requirement to invoke an external webservice(s) via the Middleware, with one of the tags in my payload containing embedded XML. Sample payload and sequence snippet below. I encounter the following issues.
Scenario 1 : (line 24) expression="get-property('PayloadXML')" - Upon issuing a send command, the webservice method is not recognized.
Scenario 2 : (line 24) expression="get-property('lPayload')" - Upon issuing a send command, the webservice method is successfully invoked. However, for the target system to successfully process the message, it would need to handle the CDATA element(wrapping).
When trying to invoke Scenario 2 via soapUI, the process is successful. From what I've researched (Passing CDATA in WSO2), soapUI seems to internally handle the CDATA element, before forwarding the message.
Now, I understand the way I'm setting scenario 2 is not ideal(more of a hack), but I'm unaware of any other ways to achieve this. I've read numerous blogs/posts and tried transforming(developing) the Payload via the XSLT mediator with no luck. I've also come across the following post http://www.yenlo.com/en/how-to-preserve-a-cdata-in-xml-that-is-circulating-in-a-wso2-enterprise-service-bus/ , but I can't seem to find the patch that is being referred to.
So my questions are as follows:
1. Are there any other ways/mechanisms for me to achieve my requirements?
2. Will the WSO2 ESB 4.9.0 release resolve the issues mentioned above?
Sample Payload :
<sample><test>MyData</test></sample>
Sequence Snippet :
<property xmlns:ns1="http://ws.wso2.org/dataservice"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
name="PayloadXML"
expression="$body/data-services-event/content/ns1:return/ns1:return/ns1:PayLoadXML"/>
<property xmlns:ns="http://org.apache.synapse/xsd"
name="lPayload"
expression="fn:concat(fn:concat('<![CDATA[',get-property('PayloadXML')), ']]>')"/>
<payloadFactory media-type="xml">
<format>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:log="http://mynamespace">
<soapenv:Header/>
<soapenv:Body>
<log:publishMessage>
<Payload xmlns="">$1</Payload>
</log:publishMessage>
</soapenv:Body>
</soapenv:Envelope>
</format>
<args>
<arg xmlns:ns2="http://org.apache.synapse/xsd"
xmlns:ns="http://org.apache.synapse/xsd"
evaluator="xml"
expression="get-property('lPayload')"/>
</args>
</payloadFactory>
Here is a sample proxy service that receive XML data and send back a new XML message with a sub part of the input content in a CDATA section.
Send it :
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<PayloadXML>
<sample><test>MyData</test></sample>
</PayloadXML>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
You receive :
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<log:publishMessage xmlns:log="http://mynamespace">
<Payload><![CDATA[<sample><test>MyData</test></sample>]]></Payload>
</log:publishMessage>
</soapenv:Body>
</soapenv:Envelope>
The proxy def :
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="TestSOF" transports="http" statistics="disable" trace="disable" startOnLoad="true">
<target>
<inSequence>
<!-- extract xml content from the input message -->
<property name="xmlContent" expression="$body/PayloadXML/*[1]" type="OM"/>
<!-- compose a new message -->
<enrich>
<source type="inline" clone="true">
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<log:publishMessage xmlns:log="http://mynamespace">
<Payload xmlns=""/>
</log:publishMessage>
</soapenv:Body>
</soapenv:Envelope>
</source>
<target type="envelope"/>
</enrich>
<!-- create a CDATA section for 'Payload' node -->
<script language="js">
importPackage(Packages.org.apache.axiom.om);
var payloadElmt = mc.getEnvelope().getBody().getFirstElement().getFirstElement();
var omText = payloadElmt.getOMFactory().createOMText(payloadElmt, mc.getProperty("xmlContent"), OMNode.CDATA_SECTION_NODE);
payloadElmt.addChild(omText)
</script>
<!-- send back this new message as a response for the caller -->
<header name="To" action="remove"/>
<property name="RESPONSE" value="true"/>
<property name="NO_ENTITY_BODY" scope="axis2" action="remove"/>
<send/>
</inSequence>
</target>
<description/>
</proxy>
If your basic requirement is to pass xml data within a tag, Here is an example for that.
Here I am using wso2 ESB 4.9.0. Basic thing is, you need to store the payload factory format in registry and use it in the payload factory configuration as bellow.
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="foo"
transports="https,http"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<property xmlns:ns="http://org.apache.synapse/xsd"
name="Request"
expression="$body/child::*[fn:position()=1]"
scope="default"
type="STRING"/>
<payloadFactory media-type="xml">
<format key="conf:/repository/esb/myPF"/>
<args>
<arg evaluator="xml" expression="$ctx:Request"/>
<arg value="1"/>
</args>
</payloadFactory>
<send>
<endpoint>
<address uri="http://127.0.0.1:9763/services/Hello"/>
</endpoint>
</send>
</inSequence>
<outSequence>
<send/>
</outSequence>
</target>
<description/>
Above is my proxy service. I am getting the first child from the request ESB gets from the client and use it as the input for the payload factory mediator.
Content of the registry resource looks like bellow.
<ns:testMethod xmlns:ns="http://example.com">
<xs:xmlBody xmlns:xs="http://example.com"><![CDATA[$1]]></xs:xmlBody>
<xs:sessionId xmlns:xs="http://example.com">$2</xs:sessionId>
</ns:testMethod>
You can test the scenario by enabling wirelogs for ESB[2].
Here I have hosted a simple axis2 service in WSO2 AS for testing. Here is the wirelog output.
[2016-02-24 19:02:24,696] DEBUG - wire << "POST /services/Hello HTTP/1.1[\r][\n]"
[2016-02-24 19:02:24,696] DEBUG - wire << "Content-Type: application/soap+xml; charset=UTF-8; action="urn:mediate"[\r][\n]"
[2016-02-24 19:02:24,696] DEBUG - wire << "Transfer-Encoding: chunked[\r][\n]"
[2016-02-24 19:02:24,696] DEBUG - wire << "Host: 127.0.0.1:9763[\r][\n]"
[2016-02-24 19:02:24,697] DEBUG - wire << "Connection: Keep-Alive[\r][\n]"
[2016-02-24 19:02:24,697] DEBUG - wire << "User-Agent: Synapse-PT-HttpComponents-NIO[\r][\n]"
[2016-02-24 19:02:24,697] DEBUG - wire << "[\r][\n]"
[2016-02-24 19:02:24,697] DEBUG - wire << "180[\r][\n]"
[2016-02-24 19:02:24,697] DEBUG - wire << "<?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"><soapenv:Body><ns:testMethod xmlns:ns="http://example.com"><xs:xmlBody xmlns:xs="http://example.com"><![CDATA[<sample><test>MyData</test></sample>]]></xs:xmlBody><xs:sessionId xmlns:xs="http://example.com">1</xs:sessionId></ns:testMethod></soapenv:Body></soapenv:Envelope>[\r][\n]"
[2016-02-24 19:02:24,697] DEBUG - wire << "0[\r][\n]"
[2016-02-24 19:02:24,697] DEBUG - wire << "[\r][\n]"
Here you can find the defined registry resource with content type as text/xml registry resource
[2] https://docs.wso2.com/display/ESB490/Setting+Up+Logging
I'm having a confusing issue with my aggregate mediator inside an out Sequence of a proxy.
Configuration :
A sequence implementing the iterate mediator Iterated the following message :
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<productSearchRs xmlns="SHC">
<productDetails>
<Product_ID>1487326</Product_ID>
<Product_Name>SECRET</Product_Name>
<Product_Size>M</Product_Size>
<Product_Colour>BLACK</Product_Colour>
<Product_Type>SOCKS</Product_Type>
<Source>SHC</Source>
</productDetails>
<productDetails>
<Product_ID>1985211</Product_ID>
<Product_Name>SECRET</Product_Name>
<Product_Size>M</Product_Size>
<Product_Colour>BLACK</Product_Colour>
<Product_Type>SOCKS</Product_Type>
<Source>SHC</Source>
</productDetails>
</productSearchRs>
</soapenv:Body>
</soapenv:Envelope>
Into these (after a payloadFactory):
<pfPadding>
<productDetails>
<productID>1487326</productID>
<productName>SECRET</productName>
<productSize>M</productSize>
<productColour>BLACK</productColour>
<productType>SOCKS</productType>
<sourceID>SHC</sourceID>
</productDetails>
</pfPadding>
and
<pfPadding>
<productDetails>
<productID>1985211</productID>
<productName>SECRET</productName>
<productSize>M</productSize>
<productColour>BLACK</productColour>
<productType>SOCKS</productType>
<sourceID>SHC</sourceID>
</productDetails>
</pfPadding>
Full sequence:
<sequence xmlns="http://ws.apache.org/ns/synapse" name="shcServiceSearchSeqRs">
<log level="custom">
<property name="Below response recieved from Shc-DS" value="=================="></property>
</log>
<log level="full"></log>
<log level="custom">
<property name="Splitting product_Detail/s up" value="=================="></property>
</log>
<property xmlns:ns1="SHC" xmlns:ns="http://org.apache.synapse/xsd" name="Product_ID" expression="//ns1:productDetails/ns1:Product_ID/text()" scope="default" type="STRING"></property>
<filter xmlns:ns="http://org.apache.synapse/xsd" xpath="boolean(get-property('Product_ID'))">
<then>
<iterate xmlns:ns1="SHC" expression="//ns1:productDetails">
<target>
<sequence>
<property name="Product_ID" expression="//ns1:productDetails/ns1:Product_ID/text()" scope="default" type="STRING"></property>
<property name="Product_Name" expression="//ns1:productDetails/ns1:Product_Name/text()" scope="default" type="STRING"></property>
<property name="Product_Size" expression="//ns1:productDetails/ns1:Product_Size/text()" scope="default" type="STRING"></property>
<property name="Product_Colour" expression="//ns1:productDetails/ns1:Product_Colour/text()" scope="default" type="STRING"></property>
<property name="Product_Type" expression="//ns1:productDetails/ns1:Product_Type/text()" scope="default" type="STRING"></property>
<property name="Source" expression="//ns1:productDetails/ns1:Source/text()" scope="default" type="STRING"></property>
<log level="full"></log>
<log level="custom">
<property name="shcRs : P_ID : " expression="$ctx:Product_ID"></property>
<property name="shcRs : P_Name : " expression="$ctx:Product_Name"></property>
<property name="shcRs : P_Size : " expression="$ctx:Product_Size"></property>
<property name="shcRs : P_Colour : " expression="$ctx:Product_Colour"></property>
<property name="shcRs : P_Type : " expression="$ctx:Product_Type"></property>
<property name="shcRs : P_Source : " expression="$ctx:Source"></property>
</log>
<payloadFactory media-type="xml">
<format>
<productDetails xmlns="">
<productID>$1</productID>
<productName>$2</productName>
<productSize>$3</productSize>
<productColour>$4</productColour>
<productType>$5</productType>
<sourceID>$6</sourceID>
</productDetails>
</format>
<args>
<arg expression="$ctx:Product_ID" evaluator="xml"></arg>
<arg expression="$ctx:Product_Name" evaluator="xml"></arg>
<arg expression="$ctx:Product_Size" evaluator="xml"></arg>
<arg expression="$ctx:Product_Colour" evaluator="xml"></arg>
<arg expression="$ctx:Product_Type" evaluator="xml"></arg>
<arg expression="$ctx:Source" evaluator="xml"></arg>
</args>
</payloadFactory>
<log level="custom">
<property name="Iterated Message : : :" value="++++++++++++++===================================================+++++++++++++++++=="></property>
</log>
<log level="full"></log>
<sequence key="conf:/pocSearchRsHandlerSeq"></sequence>
</sequence>
</target>
</iterate>
</then>
<else>
<payloadFactory media-type="xml">
<format>
<productDetails xmlns="">
<noItemFound>No item in ShoeCity</noItemFound>
</productDetails>
</format>
</payloadFactory>
<sequence key="conf:/pocSearchRsHandlerSeq"></sequence>
</else>
</filter>
</sequence>
Here's my Response handler :
<?xml version="1.0" encoding="UTF-8"?>
<sequence xmlns="http://ws.apache.org/ns/synapse" name="pocSearchRsHandlerSeq">
<log level="custom">
<property name="pocSearchRsHandlerSeq reached" value="++++++++++++++=========Aggregating now========+++++++++++++++++=="/>
</log>
<aggregate>
<completeCondition>
<messageCount min="-1" max="-1"/>
</completeCondition>
<onComplete xmlns:ns="http://org.apache.synapse/xsd" expression="//productDetails">
<log level="custom" separator=",">
<property name="::::" value="======================= Formatting the Aggregated Responses. ==============="/>
</log>
<log level="full"/>
</onComplete>
</aggregate>
<payloadFactory media-type="xml">
<format>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:prod="http://za.co.pepkor/product_service/">
<soapenv:Body>
<prod:productSearchResp> $1 </prod:productSearchResp>
</soapenv:Body>
</soapenv:Envelope>
</format>
<args>
<arg xmlns:ns="http://org.apache.synapse/xsd" evaluator="xml" expression="//productDetails"/>
</args>
</payloadFactory>
<log level="custom">
<property name="Full Rs Message : : : " value="++++++++++++++===================================================+++++++++++++++++=="/>
</log>
<respond/>
</sequence>
This sequence also receives another message from a different sequence which it does aggregate (sometimes)
Here are some responses (all from same request)
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:prod="http://za.co.pepkor/product_service/">
<soapenv:Body>
<prod:productSearchResp>
<productDetails>
<productID>2145627</productID>
<productName>NIKE_SHIRTS</productName>
<productSize>7</productSize>
<productColour>RED</productColour>
<productType>SHIRT</productType>
<sourceID>ACK</sourceID>
</productDetails>
<productDetails>
<productID>1452168</productID>
<productName>PUMPS</productName>
<productSize>7</productSize>
<productColour>ORANGE</productColour>
<productType>SHOE</productType>
<sourceID>SHC</sourceID>
</productDetails>
</prod:productSearchResp>
</soapenv:Body>
</soapenv:Envelope>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:prod="http://za.co.pepkor/product_service/">
<soapenv:Body>
<prod:productSearchResp></prod:productSearchResp>
</soapenv:Body>
</soapenv:Envelope>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:prod="http://za.co.pepkor/product_service/">
<soapenv:Body>
<prod:productSearchResp>
<productDetails>
<productID>1452168</productID>
<productName>PUMPS</productName>
<productSize>7</productSize>
<productColour>ORANGE</productColour>
<productType>SHOE</productType>
<sourceID>SHC</sourceID>
</productDetails>
<productDetails>
<productID>2145627</productID>
<productName>NIKE_SHIRTS</productName>
<productSize>7</productSize>
<productColour>RED</productColour>
<productType>SHIRT</productType>
<sourceID>ACK</sourceID>
</productDetails>
<productDetails>
<productID>1124596</productID>
<productName>REEBOK_SNEAKERS</productName>
<productSize>7</productSize>
<productColour>BROWN</productColour>
<productType>SHOES</productType>
<sourceID>SHC</sourceID>
</productDetails>
</prod:productSearchResp>
</soapenv:Body>
</soapenv:Envelope>
I mainly get the empty response back , I noticed in the logs that these have the following line in the log where the others(non-empty) don't:
TID: [0] [ESB] [2015-01-16 16:00:15,770] DEBUG {org.apache.synapse.registry.AbstractRegistry} - Cached object has expired for key : conf:/ackServiceSearchSeqRs {org.apache.synapse.registry.AbstractRegistry}
TID: [0] [ESB] [2015-01-16 16:00:15,770] DEBUG {org.apache.synapse.registry.AbstractRegistry} - Expired version number is same as current version in registry {org.apache.synapse.registry.AbstractRegistry}
EDIT :
What is the difference between using a "send" mediator with a sequence key and a "sequence" mediator?
Also , can I use a single "aggregate" node to aggregate responses from an "iterate" in one sequnece AND responses from a different sequence , reliably? It seems my aggregate node is prematurely "completing" before collecting all of my responses , and therefore executing my send/respond(any difference here?) mediator. Because I noticed this in the documentation :
Note that when the Iterate mediator is used to split the requests and produces only an n number of fragmented messages, the Aggregate mediator will terminate as soon as it receives n responses, even if you have specified a higher minimum limit.
Enabling reliable messaging gives me all sorts of other problems.
I solved it like such :
Turns out I needed a specific aggregator to agg my iterated messages (linked through the id attribute on the iterate/aggregate nodes respectively), then another to aggregate the other response as well as the above (already aggregated responses)
My Response handler:
<sequence xmlns="http://ws.apache.org/ns/synapse">
<log level="custom">
<property name="pocSearchRsHandlerSeq reached" value="++++++++++++++=========Aggregating now========+++++++++++++++++=="></property>
</log>
<aggregate id="iT">
<completeCondition>
<messageCount min="-1" max="-1"></messageCount>
</completeCondition>
<onComplete xmlns:ns="http://org.apache.synapse/xsd" expression="//productDetails">
<log level="custom" separator=",">
<property name="::::" value="======================= Formatting the Aggregated Responses. ==============="></property>
</log>
<log level="full"></log>
</onComplete>
</aggregate>
<aggregate>
<completeCondition>
<messageCount min="-1" max="-1"></messageCount>
</completeCondition>
<onComplete xmlns:ns="http://org.apache.synapse/xsd" expression="//productDetails">
<payloadFactory media-type="xml">
<format>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:prod="http://za.co.pepkor/product_service/">
<soapenv:Body>
<prod:productSearchResp> $1 </prod:productSearchResp>
</soapenv:Body>
</soapenv:Envelope>
</format>
<args>
<arg expression="//productDetails" evaluator="xml"></arg>
</args>
</payloadFactory>
<respond></respond>
</onComplete>
</aggregate>
</sequence>
In your sequence "pocSearchRsHandlerSeq", you should send back your aggregated response inside the aggregate's onComplete node :
<?xml version="1.0" encoding="UTF-8"?>
<sequence xmlns="http://ws.apache.org/ns/synapse" name="pocSearchRsHandlerSeq">
<aggregate>
<completeCondition>
<messageCount min="-1" max="-1"/>
</completeCondition>
<onComplete xmlns:ns="http://org.apache.synapse/xsd" expression="//productDetails">
<payloadFactory media-type="xml">
<format>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:prod="http://za.co.pepkor/product_service/">
<soapenv:Body>
<prod:productSearchResp>$1</prod:productSearchResp>
</soapenv:Body>
</soapenv:Envelope>
</format>
<args>
<arg xmlns:ns="http://org.apache.synapse/xsd" evaluator="xml" expression="//productDetails"/>
</args>
</payloadFactory>
<send/>
</onComplete>
</aggregate>
</sequence>