Reputation: 13
We have a use case, where we have to iterate through array of json-object and call an external endpoint based on certain key value. So we have used a iterator mediator, switch mediator(to match condition) and an aggregate mediator.
<?xml version="1.0" encoding="UTF-8"?>
<api context="/propertycheck" name="propertyCheck" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST">
<inSequence>
<iterate attachPath="json-eval($)" expression="json-eval($.main)" id="testingid" preservePayload="true" sequential="true">
<target>
<sequence>
<switch source="json-eval($.sub1)">
<case regex="a">
<log level="full" separator=","/>
<call>
<endpoint>
<http method="post" uri-template="http://localhost:3000/test">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>1</progressionFactor>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
</case>
<case regex="b">
<log level="full" separator=","/>
<call>
<endpoint>
<http method="post" uri-template="http://localhost:3000/test">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>1</progressionFactor>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
</case>
<case regex="c">
<log level="full" separator=","/>
<call>
<endpoint>
<http method="post" uri-template="http://localhost:3000/test">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>1</progressionFactor>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
</case>
<default>
<log>
<property name="default" value="defaultCase"/>
</log>
<payloadFactory media-type="json">
<format>{
"sub1":"My own Response"
}</format>
<args/>
</payloadFactory>
</default>
</switch>
</sequence>
</target>
</iterate>
<log/>
<aggregate id="testingid">
<correlateOn expression="json-eval($)"/>
<completeCondition>
<messageCount max="-1" min="-1"/>
</completeCondition>
<onComplete aggregateElementType="root" expression="json-eval($)">
<log>
<property expression="json-eval($)" name="outout"/>
</log>
</onComplete>
</aggregate>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
The Above use case works fine, when an external endpoint is called and response is returned to the aggregate mediator, but we have to build the response in the default case with out calling an endpoint, How can be this achieved? As the aggregate mediator will be triggered only after it receives response from a back end service.
We have also followed the answer that was provided in the post : WSO2 ESB, Using Aggregate mediator without send/call in iterate mediator
This also does not seems to work, below is the implementation as per the post answer
<?xml version="1.0" encoding="UTF-8"?>
<api context="/propertycheck" name="propertyCheck" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST">
<inSequence>
<iterate attachPath="json-eval($)" expression="json-eval($.main)" id="testingid" preservePayload="true" sequential="true">
<target>
<sequence>
<switch source="json-eval($.sub1)">
<case regex="a">
<log level="full" separator=","/>
<call>
<endpoint>
<http method="post" uri-template="http://localhost:3000/test">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>1</progressionFactor>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
</case>
<case regex="b">
<log level="full" separator=","/>
<call>
<endpoint>
<http method="post" uri-template="http://localhost:3000/test">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>1</progressionFactor>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
</case>
<case regex="c">
<log level="full" separator=","/>
<call>
<endpoint>
<http method="post" uri-template="http://localhost:3000/test">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>1</progressionFactor>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
</case>
<default>
<log>
<property name="default" value="defaultCase"/>
</log>
<payloadFactory media-type="json">
<format>{
"sub1":"My own Response"
}</format>
<args/>
</payloadFactory>
<property name="RESPONSE" scope="default" type="STRING" value="true"/>
<sequence key="AggregateSequence"/>
</default>
</switch>
</sequence>
</target>
</iterate>
<log/>
<aggregate id="testingid">
<correlateOn expression="json-eval($)"/>
<completeCondition>
<messageCount max="-1" min="-1"/>
</completeCondition>
<onComplete aggregateElementType="root" expression="json-eval($)">
<log>
<property expression="json-eval($)" name="outout"/>
</log>
</onComplete>
</aggregate>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
AggregateSequence
<?xml version="1.0" encoding="UTF-8"?>
<sequence name="AggregateSequence" statistics="enable" trace="enable" xmlns="http://ws.apache.org/ns/synapse">
<log>
<property expression="json-eval($)" name="request to mediator"/>
</log>
<aggregate id="testingid">
<correlateOn expression="json-eval($)"/>
<completeCondition>
<messageCount max="-1" min="-1"/>
</completeCondition>
<onComplete aggregateElementType="root" expression="json-eval($)">
<log>
<property expression="json-eval($)" name="inside Aggregator"/>
</log>
</onComplete>
</aggregate>
</sequence>
Request
{
"main":[
{
"sub1":"a"
},
{
"sub1":"b"
},
{
"sub1":"c"
},
{
"sub1":"d"
}
]
}
Any help is appreciated. Thanks
Upvotes: 0
Views: 958
Reputation: 676
Think I had exactly the same problem, when no backend is called. Not sure anymore if it was stated in the documentation, anyhow I solved it calling the local "echo" EI/ESB service" when no backend call should be done.
Here's a snippet of how I solved it.
<iterate xmlns:m0="http://ws.wso2.org/dataservice" expression="$body//m0:Entry" id="iteratorID" sequential="true">
<target>
<sequence>
<filter xpath="contains(get-property('schedulerHour'), get-property('currentHour')) and (contains($ctx:schedulerMinutes, $ctx:currentMinute))">
<then>
.... real backend should be called...
<call>
<endpoint>
<http uri-template="https://someURL"/>
</endpoint>
</call>
....
</then>
<else>
.... fake backend call...
<payloadFactory media-type="xml">
<format>
<p:echoInt xmlns:p="http://echo.services.core.carbon.wso2.org">
<in>123</in>
</p:echoInt>
</format>
<args/>
</payloadFactory>
<call>
<endpoint>
<http method="POST" uri-template="http://localhost:8280/services/echo"/>
</endpoint>
</call>
.....
</else>
</filter>
</sequence>
</target>
</iterate>
Upvotes: 0