Based on WSO2 documentation, we can use Aggregate mediator to collect responses from Iterate mediator and send back the aggregated data to as response to client, but for some reason, I can't use Aggregate mediator out side the Iterate to get the expected results, the following code stucks in Iterate mediator for ever
<api context="/test" name="test" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST GET">
<inSequence>
<iterate description="Students Loop" expression="json-eval($.students)" id="create_students" sequential="true">
<target>
<sequence>
<call blocking="true">
<endpoint key="CreateStudent"/>
</call>
</sequence>
</target>
</iterate>
<aggregate id="create_students">
<completeCondition>
<messageCount max="-1" min="-1"/>
</completeCondition>
<onComplete aggregateElementType="root" expression="json-eval($)"/>
</aggregate>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
but the following code is working fine:
<api context="/test" name="test" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST GET">
<inSequence>
<iterate description="Students Loop" expression="json-eval($.students)" id="create_students" sequential="true">
<target>
<sequence>
<call blocking="true">
<endpoint key="CreateStudent"/>
</call>
<property name="RESULTS" scope="default">
<students xmlns=""/>
</property>
<aggregate id="create_students">
<completeCondition>
<messageCount max="-1" min="-1"/>
</completeCondition>
<onComplete aggregateElementType="root" enclosingElementProperty="RESULTS" expression="json-eval($)">
<log level="full"/>
</onComplete>
</aggregate>
<respond/>
</sequence>
</target>
</iterate>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
Is that means, I have to put Aggregate inside Iterate?
The first approach is correct, but as I know, the calls should be non-blocking, while we use the aggregate mediator. Otherwise the aggregation does not proceed.
Related
Please, I have this error with my WSO2EI API definitions, it worked for me many times but no I don't know what is happening.
My Configuration is as following :
<resource methods="PUT DELETE GET" uri-template="/{appointmentId}">
<inSequence>
<log description="" level="custom">
<property expression="uri.var.appointmentId" name="property_name"/>
</log>
<switch description="" source="$axis2:HTTP_METHOD">
<case regex="GET">
<sequence key="appointmentGet"/>
</case>
<default>
<sequence key="errorSequence"/>
</default>
</switch>
<respond/>
</inSequence>
<outSequence/>
<faultSequence>
<sequence key="errorSequence"/>
<send/>
</faultSequence>
</resource>
Thank you very much
I forgot to use get-property('uri.var.appointmentId')
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)
<?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"/>
I have taken an example from DZONE blog for the clone mediator but looks like I am making some mistake and unable to return in outsequece to process further.
Can anyone help in this?
<proxy name="DSS_TrainDetailsProxy" transports="http" startOnLoad="true" trace="disable" statistics="enable">
<target inSequence="DSS_TrainDetails_IN" outSequence="DSS_TrainDetails_OUT" faultSequence="CommonFaultHandler"/>
<publishWSDL key="DSS_TrainDetails_wsdl"/>
</proxy>
<localEntry key="DSS_TrainDetails_wsdl" src="file:repository/conf/train/wsdl/TrainDetails.wsdl"/>
<sequence name="DSS_TrainDetails_IN">
<clone>
<target>
<send>
<endpoint key="DSS_TrainDetails_EPR"/>
</send>
</target>
<target>
<send>
<endpoint key="DSS_TrainDetails_EPR"/>
</send>
</target>
<target>
<send>
<endpoint key="DSS_TrainDetails_EPR"/>
</send>
</target>
</clone>
<sequence name="DSS_TrainDetails_OUT">
<aggregate>
<completeCondition>
<messageCount min="-1" max="-1"/>
</completeCondition>
<onComplete xmlns:tra="traindetails.co.nz" expression="//tra:TrainDetails">
<log level="custom" separator=",">
<property name="MessageFlow" value="======================= Sending Back the Aggregated Responses. ==============="/>
</log>
<log level="full" separator=","/>
<enrich>
<source xmlns:tra="traindetails.co.nz" clone="true" xpath="//tra:TrainDetails/tra:TrainsDetails"/>
<target type="body" action="child"/>
</enrich>
<send/>
</onComplete>
</aggregate>
</sequence>
Hi just wanted to let you know that Clone mediator worked for me :) I have made changes in IN sequence by below code I have removed "send" keyword from IN sequence :
<sequence name="DSS_TrainDetails_IN">
<clone>
<target>
<endpoint key="DSS_TrainDetails_EPR"/>
</target>
<target>
<endpoint key="DSS_TrainDetails_EPR1"/>
</target>
<target>
<endpoint key="DSS_TrainDetails_EPR2"/>
</target>
</clone>
Try that : remove your outSequence="DSS_TrainDetails_OUT" in your proxy def and inside your clone targets, change <send> to <send receive="DSS_TrainDetails_OUT">
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.