Search code examples
xmlapiwso2esbei

WSO2 EI send objects responded from an endpoint to another endpoint one by one


I'm new with WSO2 EI and am trying to get data from an endpoint and sending each object of responded objects to another endpoint. For next step, if it could be done, I want to show a progress bar to user to find out how process is doing.

After reading and searching in WSO2 documents and samples over github and stackoverflow, couldn't find any complete sample to show how to do this process completely.

As a working sample I have done with Integration Studio, here is an API which calls an endpoint to get data from server1 and then calls second endpoint to send responded data to server2, and it's working fine.

<?xml version="1.0" encoding="UTF-8"?>
<api context="/Product/UpdatePrice" name="ProductUpdatePrice" xmlns="http://ws.apache.org/ns/synapse">
    <resource methods="GET" url-mapping="/All">
        <inSequence>
            <call>
                <endpoint name="HTTPEndpoint">
                    <http method="get" uri-template="https://server1/api/Goods/GetPrices">
                        <suspendOnFailure>
                            <initialDuration>-1</initialDuration>
                            <progressionFactor>1</progressionFactor>
                        </suspendOnFailure>
                        <markForSuspension>
                            <retriesBeforeSuspension>0</retriesBeforeSuspension>
                        </markForSuspension>
                    </http>
                </endpoint>
            </call>
            <log level="custom">
                <property expression="json-eval($.message)" name="test"/>
            </log>
            <script language="nashornJs"><![CDATA[payload = mc.getPayloadJSON();
                var res = payload.response;
                mc.setPayloadJSON(res);]]></script>
            <call>
                <endpoint name="HTTPEndpoint">
                    <http method="post" uri-template="https://server2/api/Product/UpdateAllPrices">
                        <suspendOnFailure>
                            <initialDuration>-1</initialDuration>
                            <progressionFactor>1</progressionFactor>
                        </suspendOnFailure>
                        <markForSuspension>
                            <retriesBeforeSuspension>0</retriesBeforeSuspension>
                        </markForSuspension>
                    </http>
                </endpoint>
            </call>
            <respond/>
        </inSequence>
        <outSequence/>
        <faultSequence/>
    </resource>
</api>

In this sample, prices of products responded from server1 will send to server2 to update database there.

What I want to is using iteration to call server2 API to send server1 responded objects one by one.

As I found out in my searches, it seems I have to use iterate such as below, but don't know where in my sample I have to use it.

    <iterate attachPath="json-eval($.categories)" expression="json-eval($.categories)" id="iterate-over-cats" preservePayload="true">
        <target>
            <sequence>
                <send>
                    <endpoint>
                        <http method="post" uri-template="https://server2/api/Product/UpdatePrice">
                            <suspendOnFailure>
                                <initialDuration>-1</initialDuration>
                                <progressionFactor>1</progressionFactor>
                            </suspendOnFailure>
                            <markForSuspension>
                                <retriesBeforeSuspension>0</retriesBeforeSuspension>
                            </markForSuspension>
                        </http>
                    </endpoint>
                </send>
            </sequence>
        </target>
    </iterate>

Any idea will be appreciated.


Solution

  • Assuming Server1 returns a list of objects your solution is already complete with the proposed iterator, you can place it right where you currently you have the call in the example. Depending on whether you want the flow to continue after the iterate you will have to add an aggregate mediator after it. [1] I replaced the send with a call since otherwise the iterator responses will end up in the outSequence.

    <?xml version="1.0" encoding="UTF-8"?>
    <api context="/Product/UpdatePrice" name="ProductUpdatePrice" xmlns="http://ws.apache.org/ns/synapse">
        <resource methods="GET" url-mapping="/All">
            <inSequence>
                <call>
                    <endpoint name="HTTPEndpoint">
                        <http method="get" uri-template="https://server1/api/Goods/GetPrices">
                            <suspendOnFailure>
                                <initialDuration>-1</initialDuration>
                                <progressionFactor>1</progressionFactor>
                            </suspendOnFailure>
                            <markForSuspension>
                                <retriesBeforeSuspension>0</retriesBeforeSuspension>
                            </markForSuspension>
                        </http>
                    </endpoint>
                </call>
                <log level="custom">
                    <property expression="json-eval($.message)" name="test"/>
                </log>
                <script language="nashornJs"><![CDATA[payload = mc.getPayloadJSON();
                    var res = payload.response;
                    mc.setPayloadJSON(res);]]></script>
           <iterate attachPath="json-eval($.categories)" expression="json-eval($.categories)" id="iterate-over-cats" preservePayload="true">
            <target>
                <sequence>
                    <call>
                        <endpoint>
                            <http method="post" uri-template="https://server2/api/Product/UpdatePrice">
                                <suspendOnFailure>
                                    <initialDuration>-1</initialDuration>
                                    <progressionFactor>1</progressionFactor>
                                </suspendOnFailure>
                                <markForSuspension>
                                    <retriesBeforeSuspension>0</retriesBeforeSuspension>
                                </markForSuspension>
                            </http>
                        </endpoint>
                    </call>
                </sequence>
            </target>
        </iterate>
    <!-- Basic aggregate here to correctly exit the iterate mediator --> 
                <respond/>
            </inSequence>
            <outSequence/>
            <faultSequence/>
        </resource>
    </api>
    
    

    [1]https://docs.wso2.com/display/EI660/Iterate+Mediator