Implement Iterate in parrelel execution with aggregate in a single sequence WSO2 ESB5 - wso2

What I want to do is implement Iterate in parrelel execution with aggregate in a single sequence (without using call/send medior within it).
When I implement the Aggregate in the out sequence this works fine as mentioned below.
<inSequence>
<property name="it_count" scope="operation" type="STRING" value="0"/>
<iterate expression="//symbols/symbol">
<target>
<sequence>
<log level="custom">
<property name="ITERATING..." expression="$body"/>
</log>
<enrich>
<source type="inline">
<out xmlns="">TEST</out>
</source>
<target xpath="//symbol"/>
</enrich>
<log level="custom">
<property name="ITERATING..." expression="$body"/>
</log>
<loopback/>
</sequence>
</target>
</iterate>
</inSequence>
<outSequence>
<property name="response" scope="default">
<response xmlns=""/>
</property>
<aggregate>
<completeCondition>
<messageCount max="-1" min="-1"/>
</completeCondition>
<onComplete enclosingElementProperty="response" expression="//out">
<log level="custom">
<property name="AGGREGATING..." expression="$body"/>
</log>
</onComplete>
</aggregate>
<send/>
</outSequence>
But I'm facing a difficulty of doing it in the same seqence as like below. It doesn't come even to the Aggegate log. I tried various ways but still faced.
<inSequence>
<property name="it_count" scope="operation" type="STRING" value="0"/>
<iterate expression="//symbols/symbol">
<target>
<sequence>
<log level="custom">
<property name="ITERATING..." expression="$body"/>
</log>
<enrich>
<source type="inline">
<out xmlns="">TEST</out>
</source>
<target xpath="//symbol"/>
</enrich>
<log level="custom">
<property name="ITERATING..." expression="$body"/>
</log>
<loopback/>
</sequence>
</target>
</iterate>
<property name="response" scope="default">
<response xmlns=""/>
</property>
<aggregate>
<completeCondition>
<messageCount max="-1" min="-1"/>
</completeCondition>
<onComplete enclosingElementProperty="response" expression="//symbol">
<log level="custom">
<property name="AGGREGATING..." expression="$body"/>
</log>
</onComplete>
</aggregate>
<respond/>
</inSequence>
<outSequence/>
I know if I use Call/Send mediator within the Iterate I can do this in one sequence. But in my case I don't use one in there.
Can anyone give a clue for this.

In the 2nd case, add attribute continueParent="true" on iterate mediator (you don't want this mediation to stop after iterate mediator) and remove loopback mediator (you don't want to send anything to an out sequence)

Related

What is the best way to iterate inside WSO2 EI?

After reading of WSO2 EI References, I still confuse about how use iterators inside a EI sequence.
In my case I have a payload like this....
{
...
"array": [
{"cpf": "12345678911"},
{"cnpj":"12345678912346"}
]
}
So I have to iterate to check if those guys exist using another web services. in order to achieve that flow, I am using the iterate mediator to split the message and then building the logic to make those validations as follows..
The code that implements this image is following:
<iterate description="" expression="//jsonObject/array" id="myid">
<target>
<sequence>
<property expression="json-eval($.array.cpf)" name="tipoCPF" scope="default" type="STRING"/>
<filter description="" xpath="boolean(get-property('tipoCPF'))">
<then>
<property expression="json-eval($.array.cpf)" name="uri.var.cpf" scope="default" type="STRING"/>
<call>
<endpoint>
<http method="get" uri-template="http://endpoint/service/{uri.var.cpf}"/>
</endpoint>
</call>
<filter regex="200" source="get-property('axis2','HTTP_SC')">
<then/>
<else>
<payloadFactory description="" media-type="json">
<format>{
"code":"400",
"error":"CPF inexistente"
}</format>
<args/>
</payloadFactory>
<property name="HTTP_SC" scope="axis2" type="STRING" value="400"/>
<respond/>
</else>
</filter>
</then>
<else>
<property expression="json-eval($.array.cnpj)" name="tipoCNPJ" scope="default" type="STRING"/>
<filter xpath="boolean(get-property('tipoCNPJ'))">
<then>
<property expression="json-eval($.array.cnpj)" name="uri.var.cnpj" scope="default" type="STRING"/>
<header name="Authorization" scope="transport" value="Basic Y29yZS5jb25zdWx0aW5nOm8xNXRyZWI="/>
<call>
<endpoint>
<http method="get" uri-template="http://endpoint/service/cnpj/{uri.var.cnpj}"/>
</endpoint>
</call>
<filter regex="200" source="get-property('axis2','HTTP_SC')">
<then/>
<else>
<payloadFactory media-type="json">
<format>{
"code":"400",
"error":"CNPJ inexistente"
}</format>
<args/>
</payloadFactory>
<property name="HTTP_SC" scope="axis2" type="STRING" value="400"/>
<respond/>
</else>
</filter>
</then>
<else>
<call>
<endpoint>
<http method="get" uri-template="http://endpoint/service/info"/>
</endpoint>
</call>
</else>
</filter>
</else>
</filter>
</sequence>
</target>
</iterate>
This iterator work as part inside of the an 'insequence'. The 'Insequence' is deigned to allow to insert new contracts information inside the Database.
Problem: after add this iterator, the service starts to make duplicated insertions inside Database. It´s looks like the iteration don´t finish in the edge of tags 'iterator'. It´s like the iteration continues to the rest of insequence.
Try: In order to solve this problem i try to add an aggregator mediator after the iterator. But or doesn't have any effect end the duplicated insert persist, or I receive an error message.
So What is the correct whey to make this iterations inside WSO2 EI?
As you have mentioned, Iteration will occur even outside the iterate tag, until the Aggregate mediator is used. To resolve this issue, you need to add the aggregate mediator inside the iterate mediator. This will stop the iteration within the iterator tag itself.
For your use case, you may need to set continueParent="true" in the IterateMediator, so that the mediation will continue after the iterate mediator for the insertion Operation in database.
Thanks for the helping Arunan!
After your answer I try to add the Aggregator as follows
The config of aggregator is following:
...
<aggregate id="NIRO">
<completeCondition>
<messageCount max="-1" min="-1"/>
</completeCondition>
<onComplete expression="//jsonObject">
<log description="" level="full" separator=";">
<property expression="json-eval($.)" name="jsonObject"/>
</log>
</onComplete>
</aggregate>
</sequence>
</target>
</iterate>
As you sad I change the iterator property 'Continue Parent' to 'true'. But the problem persists....
As proposed in the other answer, you need to
use an Aggregate mediator to close the iteration
If and only if the Iterator is set to continueParent="true"
However, I am not sure that putting it inside the <iterate> works. Here is a working solution using an Aggregate mediator right after your Iterator.
<sequence>
<iterate continueParent="true" description="" expression="//jsonObject/array" id="myid">
<target>
<your_sequence />
</target>
</iterate>
<aggregate>
<completeCondition>
<messageCount max="-1" min="-1" />
</completeCondition>
<onComplete enclosingElementProperty="//jsonObject/array" expression="/whatever/you/want"/>
</aggregate>
</sequence>
Notice expression="//jsonObject/array" you used in your Iteration, you'll need to use it in the Aggregator's enclosingElementProperty. This is how your EI will know from which iterator it should aggregate from (not 100% sure about this point, more of an empirical consideration).

Can I invoke a web service using call mediator in wso2 esb?

<?xml version="1.0" encoding="UTF-8"?>
<sequence name=SEQUENCE trace="disable" xmlns="http://ws.apache.org/ns/synapse">
<iterate expression=EXPRESSION sequential="true" xmlns:ns="http://org.apache.synapse/xsd">
<target>
<sequence>
<log level="full">
<property expression="$body/*" name="Test within iterate"/>
</log>
<call>
<endpoint>
<http method="POST" uri-template=URI TEMPLATE
</endpoint>
</call>
<log>
<property name="After CALL" value="response"/>
</log>
</sequence>
</target>
</iterate>
<aggregate>
<completeCondition>
<messageCount max="-1" min="-1"/>
</completeCondition>
<onComplete expression="$body/*" sequence="OutSequenceforData"
xmlns:ns="http://org.apache.synapse/xsd"
xmlns:s11="http://schemas.xmlsoap.org/soap/envelope/" xmlns:s12="http://www.w3.org/2003/05/soap-envelope"/>
</aggregate>
<send/>
<log level="full">
<property expression="$body/*" name="After Aggregate" xmlns:ns="http://org.apache.synapse/xsd"/>
</log>
</sequence>
I am trying to invoke a web service using call mediator. But I do not see any log about the call in the wso2 logs. The goal is to display the data from a file in the web service.
Yes you can, after the Call mediator put a Log mediator.
<log level="full" xmlns="http://ws.apache.org/ns/synapse"/>

local entry as filter criteria in wso2 esb mediation

I have a sequence as part of proxy service which filters based on "Source and Regular Expression". I have defined source as element value coming as part of SOAP request and regular expression as "local entry defined in ESB". However, result is not what I am expecting.
Local Entry is defined as Inline Text (myFields) - FIELD1|FIELD2|FIELD3
Mediation sequence is defined as -
<sequence xmlns="http://ws.apache.org/ns/synapse" name="007">
<property xmlns:ns="http://org.apache.synapse/xsd" name="fieldName" expression="$body/fieldName/text()" scope="default" type="STRING"/>
<filter xmlns:ns="http://org.apache.synapse/xsd" source="get-property('fieldName')" regex="get-property('myFields')">
<then>
<log level="full" separator="*****YES*********">
<property name="myFields" expression="get-property('myFields')"/>
</log>
</then>
<else>
<log level="full" separator="*********NO**************">
<property name="myFields" expression="get-property('myFields')"/>
</log>
</else>
</filter>
</sequence>
When I am sending SOAP request as -
<body>
<fieldName>FIELD1</fieldName>
</body>
execution is always going to else part. Any suggestion ?
With filter mediator, regex attribute must be a string, not an expression.
You can use XPATH2 "matches"
Sample :
<inSequence>
<property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
<property name="fieldName" expression="$body/fieldName/text()"/>
<property xmlns:fn="http://www.w3.org/2005/xpath-functions" name="match" expression="fn:matches(syn:get-property('fieldName'),syn:get-property('myFields'))"/>
<filter source="get-property('match')" regex="true">
<then>
<log level="full" separator="*****YES*********">
<property name="myFields" expression="get-property('myFields')"/>
</log>
</then>
<else>
<log level="full" separator="*********NO**************">
<property name="myFields" expression="get-property('myFields')"/>
</log>
</else>
</filter>
<log level="full"/>
</inSequence>

Getting error in Aggregate Mediator?

I am using iterate mediater and aggregate mediator.
My request is:
<p:GetPersonDataOperation xmlns:p="http://tempuri.org">
<!--1 or more occurrences-->
<xs:ID xmlns:xs="http://tempuri.org">1</xs:ID>
</p:GetPersonDataOperation>
and response is :
<GetPersonDataCollection xmlns="http://tempuri.org">
<GetPersonData>
<AppInstanceID>1</AppInstanceID>
<RecordID>349</RecordID>
<ID>1</ID>
<Name>name</Name>
<LastName>lastname</LastName>
<Descr>description</Descr>
<Address>Park Street</Address>
</GetPersonData>
</GetPersonDataCollection>
If i don't use Aggregate mediator then i get the above response, But if i use Aggregate mediator i get request timeOut Exception
My in Sequence is :
<sequence xmlns="http://ws.apache.org/ns/synapse" name="GetPersonDataOperationSeq">
<iterate xmlns:xs="http://tempuri.org" xmlns:ns="http://org.apache.synapse/xsd" xmlns:p="http://tempuri.org" preservePayload="true" attachPath="//p:GetPersonData" expression="//p:GetPersonData/xs:ID" id="Iterator1">
<target>
<sequence>
<property name="ID" expression="//xs:ID" scope="default" type="STRING"/>
<payloadFactory>
<format>
<p:GetPersonData>
<xs:ID>$1</xs:ID>
</p:GetPersonData>
</format>
<args>
<arg expression="get-property('ID')"/>
</args>
</payloadFactory>
<send receive="AggregatorSeq">
<endpoint key="GetPersonDataEP"/>
</send>
</sequence>
</target>
</iterate>
</sequence>
And From The above in sequence i am redirecting to another Sequence called AggregatorSeq and my AggregatorSeq is:
<sequence xmlns="http://ws.apache.org/ns/synapse" name="AggregatorSeq">
<log level="custom">
<property name="CamHereProp" value="*******************Yes??????????????**********************************************"/>
</log>
<aggregate>
<completeCondition>
<messageCount min="-1" max="-1"/>
</completeCondition>
<onComplete xmlns:ns="http://org.apache.synapse/xsd" xmlns:p="http://tempuri.org" expression="//p:GetPersonDataCollection">
<send/>
</onComplete>
</aggregate>
</sequence>
What am i doing wrong.Looking forward to your answers.Thanks in advance
Try adding the ID of the iterator to your aggregator. In your case it should be like,
<aggregate id="Iterator1">
Also, if each of your response body starts with <GetPersonData> then you need to add that to the expression in onComplete.
<onComplete xmlns:ns="http://org.apache.synapse/xsd" xmlns:p="http://tempuri.org" expression="//p:GetPersonData">
Can you specify the issue with the code you have given. You can use <log level="full"/> to debug till what level is your configuration gets executed.

wso2esb - aggregate mediator is not being detected

I am using WSO2 4.0.3 on Mac OSX 10.6 I have Data Services Server feature enabled(3.2.2
working in wso2esb 4.0.3 on aggregate mediator.
Below is the code, where the iterate mediator worked perfectly, but the aggregate mediator does not seem to get recognized, as the log in it is not getting printed .The response from the endpoint is getting printed in the log level=full of outsequence, but the flow is not getting continued in aggregate.
Could anyone from wso2team please confirm whether aggregate behaves as expected in wso2 esb 4.0.3?
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="test" transports="http https" startOnLoad="true" trace="disable" statistics="enable">
<target>
<inSequence >
<log level="full" separator=",">
<property name="InSequence-EntryMessage" value="test - Entering InSequence."/>
</log>
<iterate preservePayload="true" attachPath="//REQ" expression="//REQ/MODULE">
<target>
<sequence>
<payloadFactory>
<format>
<MODULE>
<party_id>$1</party_id>
</MODULE>
</format>
<args>
<arg expression="//REQ/MODULE/party_id"/>
</args>
</payloadFactory>
<log level="full" separator=",">
<property name="InSequence-iterate" value="formed after iterate"/>
</log>
<send>
<endpoint key="conf:/test/ds_endpoint.xml"/>
</send>
</sequence>
</target>
</iterate>
<log level="custom" separator=",">
<property name="InSequence-ExitMessage" value="test - Exiting InSequence."/>
</log>
</inSequence>
<outSequence >
<log level="full" separator=",">
<property name="ValidResponse" value="test Sending the Response Back."/>
</log>
<aggregate>
<log level="full" separator=",">
<property name="ValidResponse" value="TEST ---------------- Sending the Response Back."/>
</log>
<correlateOn expression="//TEST"/>
<completeCondition>
<messageCount min="-1" max="-1"/>
</completeCondition>
<onComplete expression="//TESTALL">
<log level="full" separator=",">
<property name="ValidResponse" value="TEST 1 ---------------- Sending the Response Back."/>
</log>
<send/>
</onComplete>
</aggregate>
<log level="full" separator=",">
<property name="OutSequence-ExitMessage" value="test - Exiting OutSequence."/>
</log>
</outSequence>
</target>
</proxy>
Appreciate a response on this!
Log mediator is only applicable inside "onComplete" tag in Aggregate mediator. So following log will not recognized and it is an expected behavior,
<log level="full" separator=",">
<property name="ValidResponse" value="TEST ---------------- Sending the Response Back."/>
</log>
but the following log which you have added within "onComplete" tag should work,
<log level="full" separator=",">
<property name="ValidResponse" value="TEST 1 ---------------- Sending the Response Back."/>
</log>