Search code examples
wso2aggregateclonewso2-esb

WSO2 change payload in aggregate


I'm currently trying to compute a payload in an aggregate element from a sequence template. My problem is that the payload returned by this sequence is the one generated by the aggregate, not the one build with the payload factory. Here is a sample

<clone id="TEST" sequential="true">
  <target>
    <sequence>
       <call-template key="do-soemthing"/>
    </sequence>
  </target>
  <target>
    <sequence>
       <call-template key="do-something-else"/>
    </sequence>
  </target>
</clone>
<aggregate id="TEST">
 <completeCondition>
   <messageCount max="-1" min="-1"/>
 </completeCondition>
 <onComplete expression="//status">
    <filter xpath="count(//status[text() = 'NOK']) = 0">
      <then>
        <payloadFactory media-type="xml">
          <format>
            <myPayload>
              <status>OK</status>
              <action>foo</action>
            </myPayload>
          </format>
          <args/>
        </payloadFactory>
      </then>
      <else>
        <payloadFactory media-type="xml">
          <format>
            <myPayload>
              <status>NOK</status>
              <action>bar</action>
            </myPayload>
          </format>
          <args/>
        </payloadFactory>
      </else>
    </filter>
  </onComplete>
</aggregate> 

What I would expect when calling this sequence is to get back a element but instead i get (aggregated). How could I solve this ?

Thanks


Solution

  • If you want mediators after clone to be executed, you must set attribute continueParent="true" on clone mediator.

    But this is not enough in your case because messages generated into clone's targets are lost after clone mediator : you must move your aggregate mediator in a sequence and call this sequence inside each clone's target.

    Here come a sample composed of a proxy service (that you can simply execute with your internet browser : http://localhost:8280/services/TestSOF) and a sequence used to aggregate the mock responses

    <?xml version="1.0" encoding="UTF-8"?>
    <proxy xmlns="http://ws.apache.org/ns/synapse"
           name="TestSOF"
           transports="http"
           startOnLoad="true"
           trace="disable">
       <description/>
       <target>
          <inSequence>
             <property name="messageType" value="application/xml" scope="axis2"/>
             <clone continueParent="true">
                <target>
                   <sequence>
                      <payloadFactory media-type="xml">
                         <format>
                            <resp1 xmlns="">
                               <status>OK</status>
                            </resp1>
                         </format>
                         <args/>
                      </payloadFactory>
                      <header name="To" action="remove"/>
                      <property name="RESPONSE" value="true"/>
                      <property name="NO_ENTITY_BODY" scope="axis2" action="remove"/>
                      <sequence key="TestSOFAgg"/>
                   </sequence>
                </target>
                <target>
                   <sequence>
                      <payloadFactory media-type="xml">
                         <format>
                            <resp2 xmlns="">
                               <status>OK</status>
                            </resp2>
                         </format>
                         <args/>
                      </payloadFactory>
                      <header name="To" action="remove"/>
                      <property name="RESPONSE" value="true"/>
                      <property name="NO_ENTITY_BODY" scope="axis2" action="remove"/>
                      <sequence key="TestSOFAgg"/>
                   </sequence>
                </target>
             </clone>
             <log level="full">
                <property name="DEBUG" value="after clone"/>
             </log>
          </inSequence>
       </target>
    </proxy>
    
    <sequence xmlns="http://ws.apache.org/ns/synapse" name="TestSOFAgg">
        <aggregate>
         <completeCondition>
           <messageCount max="-1" min="-1"/>
         </completeCondition>
         <onComplete expression="//status">
            <log level="full"><property name="DEBUG" value="inside onComplete"/></log>
            <filter xpath="count(//status[text() = 'NOK']) = 0">
              <then>
                <payloadFactory media-type="xml">
                  <format>
                    <myPayload>
                      <status>OK</status>
                      <action>foo</action>
                    </myPayload>
                  </format>
                  <args/>
                </payloadFactory>
              </then>
              <else>
                <payloadFactory media-type="xml">
                  <format>
                    <myPayload>
                      <status>NOK</status>
                      <action>bar</action>
                    </myPayload>
                  </format>
                  <args/>
                </payloadFactory>
              </else>
            </filter>
            <respond/>
          </onComplete>
        </aggregate> 
    </sequence>
    

    See message logged by "after clone" : soap Body is empty (if you've used a Browser to test it, or you will have the soap message you've sent with SoapUI for exemple), your aggregate can't work here

    See message logged by "inside onComplete" : you can see all the status elements inside the soap body

    Modify one of the mock responses with something else that OK and try again : the response change, it works ;-)