OnComplete in Aggregate sequence not triggered after the Iteration sequence

193 views Asked by At

I'm building a microservice where I have a main sequence that first reads a json file and then goes into iteration sequence that is connected to an aggregator sequence with an ID. Here is the order from the main sequence:

        <property expression="json-eval($)" name="ORIGINAL_PAYLOAD" scope="default" type="STRING"/>
        <sequence key="data-iterate-seq"/>
        <property name="aggregatedResponses" scope="default">
            <batch_response/>
        </property>
        <sequence key="data-aggregate-seq"/>

The problem I'm facing is that once it goes into iterate it first triggers the code in aggregate that is outside of OnComplete, then it goes back and does the iterations and never goes to the OnComplete neither it goes back to the main sequence. I managed to make it continue with the main sequence using continueParent=true but this way it never goes into OnComplete of the aggregation sequence. I have also tried switching the onComplete expression to $body/*[1] and //jsonObject but it didn't work Edit: neither did the <send/> and <loopback/> operators.

Here is my iterator

<?xml version="1.0" encoding="UTF-8"?>
<sequence name="data-iterate-seq" trace="disable" xmlns="http://ws.apache.org/ns/synapse">
    <iterate attachPath="json-eval($)" expression="json-eval($.records)" id="requestIterator" preservePayload="true">
        <target>
            <sequence>
                <payloadFactory media-type="json">
                    <format>$1</format>
                    <args>
                        <arg evaluator="json" expression="$"/>
                    </args>
                </payloadFactory>
                <property name="messageType" scope="axis2" type="STRING" value="application/json"/>
                <log level="custom" separator="&#xa;">
                    <property expression="json-eval($)" name="BODY_INSIDE_ITERATE"/>
                </log>
                <!-- Prepare Payload -->
                <property expression="json-eval($.recordId)" name="recordId" scope="default" type="STRING"/>
                <property name="entitySetName" scope="default" type="STRING" value="accounts"/>
                <property expression="concat(get-property('msdynamics365.resource'),'/api/data/',get-property('msdynamics365.api.version'),'/')" name="patch-url" scope="axis2" type="STRING"/>
                <payloadFactory media-type="json">
                    <format>{"batch_response": "{ "relativeUrlTemplate": "{{apiUrl}}{{entitySetName}}{{entityRecordId}}",
                                               "method": "PATCH",            
                                               "entitySetName": "$1",            
                                               "entityRecordId": "$2",            
                                               "data": {
                                                    "name":"$3",
                                                    "email":"$4"
                                                }
                                            }}
                            </format>
                    <args>
                        <arg evaluator="xml" expression="$ctx:entitySetName"/>
                        <arg evaluator="xml" expression="$ctx:recordId"/>
                        <arg evaluator="json" expression="$.data.name"/>
                        <arg evaluator="json" expression="$.data.emailaddress1"/>
                    </args>
                </payloadFactory>
                <property name="messageType" scope="axis2" type="STRING" value="application/json"/>
                <log level="full"/>
                <log level="custom" separator="&#xa;">
                    <property name="Results" value="Number of iterations"/>
                </log>
            </sequence>
        </target>
    </iterate>
</sequence>

and my aggregator:

<?xml version="1.0" encoding="UTF-8"?>
<sequence name="data-aggregate-seq" onError="data-fault-seq" trace="disable" xmlns="http://ws.apache.org/ns/synapse">
    <aggregate id="requestIterator">
        <completeCondition>
            <messageCount max="-1" min="-1"/>
        </completeCondition>
        <onComplete aggregateElementType="root" enclosingElementProperty="aggregatedResponses" expression="json-eval($)" xmlns:ns="http://org.apache.synapse/xsd">
            <property expression="json-eval($)" name="aggregatedResponses" scope="default" type="STRING"/>
            <log level="full">
                <property expression="json-eval($)" name="OUT_SEQUENCE_AGGREGATED_RESPONSE"/>
            </log>
            <log level="full">
                <property expression="get-property('aggregatedResponses')" name="Responses"/>
            </log>
        </onComplete>
    </aggregate>
    <log level="custom">
        <property expression="json-eval($)" name="FINAL_PAYLOAD"/>
        <property expression="get-property('aggregatedResponses')" name="aggregated_Response"/>
    </log>
</sequence>

Any suggestions on what I'm doing wrong or anything that might help would be really appreciated! Thank you in advance!!

1

There are 1 answers

1
Arunan On BEST ANSWER

According to the documentation, you need to use a call or send mediator inside the Iterate mediator to continue the message flow.

In Iterate you need to send the split messages to an endpoint to continue the message flow.

For me, it seems you are only transforming the message payload. Hence you can use Foreach mediator to do that without Iterate mediator.