I want to perform parallel API calls in iterate mediator then to group the responses using the aggregate mediator. The format is JSON. I am using this code:
[...code in iterate]
<script language="js">var c = mc.getProperty("account");
print("Value : "+ c );
mc.setProperty("concatValue", c);
mc.setPayloadJSON({"result":{"account" : c}});</script>
<log>
<property expression="json-eval($)" name="JSON-Payload in sequence"/>
</log>
</sequence>
</target>
</iterate>
<property name="Aggregated_Responses" scope="default" value = "{}"/>
<aggregate id="it1">
<completeCondition>
<messageCount max="-1" min="-1"/>
</completeCondition>
<onComplete expression="json-eval($)" enclosingElementProperty="Aggregated_Responses">
<log>
<property expression="json-eval($)" name="JSON-Payload in oncomplete"/>
</log>
</onComplete>
</aggregate>
<loopback/>
</sequence>
The aggregation is not working, if i add loopback isnide the on complete, it will return one json and the second one will print a message in the logs saying that the response was already sent. Can someone help me solve this issue? And an additional question: do the work inside the iterate is usually done in parallel or in series?
Final working solution with some explanation:
<payloadFactory media-type="json">
<format>
{
"payloadss": [{
"account":"99999999999"
},{
"account":"6666666666"
}]
}
</format>
<args/>
</payloadFactory>
<iterate attachPath="json-eval($.payloadss)" expression="json-eval($.payloadss)"
id="iterate-over" preservePayload="true" continueParent="false">
<target>
<sequence>
<property expression="json-eval($.payloadss.account)" name="accounte" scope="default" type="STRING"/>
<call-template target="call_template_a">
<with-param name="url" value="/getaccount"/>
<with-param name="method_type" value="get"/>
</call-template>
[.. apply error check etc .. ]
</sequence>
</target>
</iterate>
[ use same id as the iterate otherwise it wont work ]
<property name="Aggregated_Responses" scope="default">
<jsonObject/>
</property>
<aggregate description="iterate-over" id="iterate-over">
<completeCondition timeout="120">
<messageCount max="-1" min="-1"/>
</completeCondition>
[ use expression like this otherwise it wont work, you can even add at the end /
your field name if needed ]
<onComplete xmlns:ns="http://org.apache.synapse/xsd" expression="$body/*[1]"
enclosingElementProperty="Aggregated_Responses">
[ here the json will be as payload, optionnally you can have a script mediator
to map the value and change in their names, otherwise you can just return the
result and it
will be aggregated together]
<property expression="json-eval($)" name="bbbb"/>
<script language="js"><![CDATA[
var dataFull = JSON.parse(mc.getProperty('bbbb'));
var responseList = [];
var newJson = JSON.parse("{}");
for (i = 0; i < dataFull.length; i++) {
item = dataFull[i];
newJson.newAccountNumber = item.accountNumber;
responseList.push(newJson);
}
mc.setProperty("responseList", JSON.stringify(responseList));
]]></script>
<payloadFactory media-type="json">
<format>
{
"data": $2
}
</format>
<args>
<arg evaluator="xml" expression="get-property('responseList')"/>
</args>
</payloadFactory>
[ the send should be at this level, the code just after will not be executed]
<send/>
</onComplete>