Tuesday, March 28, 2017

Message transformation using Iterate and Aggregate pattern without using the send/call

Iterate mediator will always have to be accompanied by an Aggregate mediator. Iterate will be used for situations where split messages will be sent to a target and collected by aggregate in a different flow. The current implementation is expecting to send the iterated requests to the back end service and aggregate will trigger only after the response received from the back end.
However following sample illustrate how to use iterate/aggregate pattern without sending the iterated messages to the backend service.

To get this work, we need to follow the below steps inside the iterate mediator in each iteration.

1) Apply any needed transformations to your message.
2) Define it as a response message (set property RESPONSE to true)

 <property name="RESPONSE" value="true"/>  

3) Define the aggregate mediator in a sequence and invoke that at the end of each iteration.


 <sequence key="AggregateSequence"/>  


Applied the above changes to the "AggregateProxy" and Created a new sequence "AggregateSequence" containing the Aggregate mediator logic.

AggregateProxy.xml
 <?xml version="1.0" encoding="UTF-8"?>  
 <proxy xmlns="http://ws.apache.org/ns/synapse"  
     name="AggregateProxy"  
     transports="https,http"  
     statistics="disable"  
     trace="disable"  
     startOnLoad="true">  
   <target>  
    <inSequence>  
      <iterate xmlns:abc="http://abc.com" id="iteratorId" expression="//abc:Request">  
       <target>  
         <sequence>  
          <payloadFactory media-type="xml">  
            <format>  
             <abc:Result>$1</abc:Result>  
            </format>  
            <args>  
             <arg evaluator="xml" expression="//abc:Request"/>  
            </args>  
          </payloadFactory>  
          <log level="full"/>  
          <property name="RESPONSE" value="true"/>  
          <sequence key="AggregateSequence"/>  
         </sequence>  
       </target>  
      </iterate>  
    </inSequence>  
   </target>  
   <description/>  
 </proxy>  



AggregateSequence.xml
 <sequence xmlns="http://ws.apache.org/ns/synapse" name="AggregateSequence">  
   <property name="ResultTag" scope="default">  
    <test:result xmlns:test="http://test.com"></test:result>  
   </property>  
   <aggregate id="iteratorId">  
    <completeCondition>  
      <messageCount></messageCount>  
    </completeCondition>  
    <onComplete xmlns:abc="http://abc.com" xmlns:ns="http://org.apache.synapse/xsd" expression="//abc:Result" enclosingElementProperty="ResultTag">  
      <log level="full"></log>  
      <respond></respond>  
    </onComplete>  
   </aggregate>  
 </sequence>  


Invoked the "AggregateProxy.xml" with the below request.

 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">  
   <soapenv:Header/>  
   <soapenv:Body>  
 <ns0:getDBGateDataRequest xmlns:ns0="http://abc.com">  
 <ns0:Request>1</ns0:Request>   
 <ns0:Request>2</ns0:Request>   
 <ns0:Request>3</ns0:Request>   
 </ns0:getDBGateDataRequest>  
 </soapenv:Body>  
 </soapenv:Envelope>  


Observed the transformed aggregated message.

 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">  
   <soapenv:Body>  
    <test:result xmlns:test="http://test.com">  
      <abc:Result xmlns:abc="http://abc.com">1</abc:Result>  
      <abc:Result xmlns:abc="http://abc.com">2</abc:Result>  
      <abc:Result xmlns:abc="http://abc.com">3</abc:Result>  
    </test:result>  
   </soapenv:Body>  
 </soapenv:Envelope>