Rama Kesara
Rama Kesara

Reputation: 94

Iterate Mediator sends duplicate payload almost always

We are trying out a scenario where we want to iterate over a list of nodes and make a POST call to some service with each individual request payload. We are seeing the iterate mediator actually sends two elements in that call and that causes issues on the API end.

I have a mock service deployed locally that returns response say :

<result>
   <row>
      <product_id>8351</product_id>
      <event_key>17708</event_key>
      <event_code>AEONBM</event_code>
      <show_title>Some Show</show_title>
      <venue_name>Eugene ONeill Theatre</venue_name>
      <area>ORCHC</area>
      <row>C</row>
      <seat_num>103</seat_num>
      <seat_increment>1</seat_increment>
      <marketing_code>PREMIUM</marketing_code>
      <Cost>352.0000</Cost>
   </row>
   <row>
      <product_id>8351</product_id>
      <event_key>17708</event_key>
      <event_code>AEONBM</event_code>
      <show_title>Some Show</show_title>
      <venue_name>Eugene ONeill Theatre</venue_name>
      <area>ORCHC</area>
      <row>C</row>
      <seat_num>104</seat_num>
      <seat_increment>1</seat_increment>
      <marketing_code>PREMIUM</marketing_code>
      <Cost>352.0000</Cost>
   </row
</result>

Here is how my proxy service looks like:

<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="CreateListingFromGetLocation"
       transports="https,http"
       statistics="disable"
       trace="disable"
       startOnLoad="true">
   <target>
      <inSequence>
         <log level="full">
            <property name="text" value="Triggering getLocation API call.."/>
         </log>
         <send receive="createListingsFromGetLocationResponseSequence">
            <endpoint>
               <http method="get" uri-template="http://localhost:8989/GetLocation/"/>
            </endpoint>
         </send>
         <property name="OUT_ONLY" value="true"/>
      </inSequence>
      <outSequence>
        <send/>
      </outSequence>
      <faultSequence/>
   </target>
   <description/>
</proxy>

Here is my receiving sequence that is using the iterate mediator:

<sequence xmlns="http://ws.apache.org/ns/synapse" name="createListingsFromGetLocationResponseSequence">
   <iterate xmlns:tem="http://tempuri.org" xmlns:ns="http://org.apache.synapse/xsd" expression="//result/row">
      <target>
         <sequence>
            <log level="full">
               <property name="LocationRow" value="Row element from GetLocationResponse"></property>
            </log>
            <payloadFactory media-type="xml">
               <format>
                  <listing xmlns="">
                     <eventId>$1</eventId>
                     <eventDescription>$2</eventDescription>
                     <pricePerTicket>
                        <amount>$3</amount>
                        <currency>USD</currency>
                     </pricePerTicket>
                     <quantity>$4</quantity>
                     <section>$5</section>
                     <rows>$6</rows>
                     <seats>$7</seats>
                     <splitOption>NONE</splitOption>
                  </listing>
               </format>
               <args>
                  <arg expression="//event_key" evaluator="xml"></arg>
                  <arg expression="//show_title" evaluator="xml"></arg>
                  <arg expression="//Cost" evaluator="xml"></arg>
                  <arg expression="//seat_increment" evaluator="xml"></arg>
                  <arg expression="//area" evaluator="xml"></arg>
                  <arg expression="//row/row" evaluator="xml"></arg>
                  <arg expression="//seat_num" evaluator="xml"></arg>
               </args>
            </payloadFactory>
            <log level="full">
               <property name="ListingRequest" value="Listing request xml"></property>
            </log>
            <property name="Content-Type" value="application/xml" scope="transport" type="STRING"></property>
            <property name="messageType" value="application/xml" scope="transport" type="STRING"></property>
            <property name="TARGET_HOST" value="srwd30" scope="transport" type="STRING"></property>
            <property name="HTTP_METHOD" value="POST" scope="transport" type="STRING"></property>
            <send>
               <endpoint>
                  <http format="pox" method="post" uri-template="http://www.srwd30.com/listings/v1/"></http>
               </endpoint>
            </send>
         </sequence>
      </target>
   </iterate>
</sequence>

Firstly, I see that it is iterating over each xml node properly, here are some logs indicating that:

[2014-04-22 13:29:42,020]  INFO - LogMediator To: http://www.w3.org/2005/08/addressing/anonymous, WSAction: , SOAPAction: , MessageID: urn:uuid:3bc14a33-3a7a-478e-bdbf-720f1ec855a5, Direction: response, LocationRow = Row element from GetLocationResponse, Envelope: <?xml version="1.0" encoding="utf-8
"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><row>
      <product_id>8351</product_id>
      <event_key>17708</event_key>
      <event_code>AEONBM</event_code>
      <show_title>Some Show</show_title>
      <venue_name>Eugene ONeill Theatre</venue_name>
      <area>ORCHC</area>
      <row>D</row>
      <seat_num>103</seat_num>
      <seat_increment>1</seat_increment>
      <marketing_code>PREMIUM</marketing_code>
      <Cost>352.0000</Cost>
   </row></soapenv:Body></soapenv:Envelope>
[2014-04-22 13:29:42,021]  INFO - LogMediator To: http://www.w3.org/2005/08/addressing/anonymous, WSAction: , SOAPAction: , MessageID: urn:uuid:0e04ac15-a0bf-41a3-a7d7-80a1401d3efc, Direction: response, ListingRequest = Listing request xml, Envelope: <?xml version="1.0" encoding="utf-8"?><soapenv:En
velope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><listing><eventId>17708</eventId><eventDescription>Some Show</eventDescription><pricePerTicket><amount>352.0000</amount><currency>USD</currency></pricePerTicket><quantity>1</quantity><section>ORCHC</section><rows
>C</rows><seats>103</seats><splitOption>NONE</splitOption></listing></soapenv:Body></soapenv:Envelope>

But on my API I see that we are receiving duplicate or two root nodes:

Content-Type: application/xml
Headers: {cache-control=[no-cache], connection=[Keep-Alive],
content-type=[application/xml], host=[www.srwd30.com], http_method=[POST], messagetype=[application/xml], target_host=[srwd30], transfer-encoding=
[chunked], user-agent=[Synapse-PT-HttpComponents-NIO]}
Payload: <listing><eventId>17708</eventId><eventDescription>Some Show</eventDescription><pricePerTicket><amount>352.0000</amount><currency>USD</currenc
y></pricePerTicket><quantity>1</quantity><section>ORCHC</section><rows>C</rows><seats>103</seats><splitOption>NONE</splitOption></listing><listing><eventId>1770
8</eventId><eventDescription>Some Show</eventDescription><pricePerTicket><amount>352.0000</amount><currency>USD</currency></pricePerTicket><quantity>1<
/quantity><section>ORCHC</section><rows>D</rows><seats>104</seats><splitOption>NONE</splitOption></listing>
--------------------------------------
2014-04-22 19:01:51,468 [e14f#fbf/http://www.srwd30.com/listings/v1/] priority=WARN  app_name=shared-stubhubjobs thread=http-0.0.0.0-
8080-8 location=AbstractJAXBProvider line=112 javax.xml.bind.UnmarshalException
 - with linked exception:
[com.ctc.wstx.exc.WstxParsingException: Illegal to have multiple roots (start tag in epilog?).
 at [row,col {unknown-source}]: [1,291]]

From the looks of it, iterator is sending two elements when I make that send call. Am i missing something or doing something wrong? How can make each call independent from other?

Upvotes: 3

Views: 1573

Answers (2)

Rama Kesara
Rama Kesara

Reputation: 94

I got the issue resolved by adding a Action header using urn:test value for that header. I realized that this was causing that duplicate requests to be sent and sometimes only one request being sent even if the iterator has about 10 records.

    <proxy name="PushInventory"
      transports="https http"
      startOnLoad="true"
      trace="disable">
  <description/>
  <target>
     <inSequence>
        <log level="full">
           <property name="STATUS"
                     value="+++++++++++++++++ Inside PushInventory Proxy Service ++++++++++++++++++"/>
        </log>
        <iterate xmlns:tem="http://tempuri.org"
                 xmlns:ns="http://org.apache.synapse/xsd"
                 id="pushInventoryIterator"
                 expression="//result/row"
                 sequential="true">
           <target>
              <sequence>
                 <payloadFactory media-type="xml">
                    <format>
                       <listing xmlns="">
                          <eventId>$1</eventId>
                          <eventDescription>$2</eventDescription>
                          <pricePerTicket>
                             <amount>$3</amount>
                             <currency>USD</currency>
                          </pricePerTicket>
                          <quantity>$4</quantity>
                          <section>$5</section>
                          <rows>$6</rows>
                          <seats>$7</seats>
                          <splitOption>NONE</splitOption>
                       </listing>
                    </format>
                    <args>
                       <arg evaluator="xml" expression="//event_key"/>
                       <arg evaluator="xml" expression="//show_title"/>
                       <arg evaluator="xml" expression="//Cost"/>
                       <arg evaluator="xml" expression="//seat_increment"/>
                       <arg evaluator="xml" expression="//area"/>
                       <arg evaluator="xml" expression="//row_desc"/>
                       <arg evaluator="xml" expression="//seat_num"/>
                    </args>
                 </payloadFactory>
                 <log level="full">
                    <property name="STATUS"
                              value="++++++++++++ Invoking Listing EndPoint ++++++++++++++"/>
                 </log>
                 <property name="Authorization"
                           value="Basic dafdsfadsfdsafdsfdsafdsafsdfadsf"
                           scope="transport"
                           type="STRING"/>
                 <property name="Content-Type"
                           value="application/xml"
                           scope="transport"
                           type="STRING"/>
                 <property name="messageType"
                           value="application/xml"
                           scope="axis2"
                           type="STRING"/>
                 <property name="HTTP_METHOD" value="POST" scope="transport" type="STRING"/>
                 <header name="Action" scope="default" value="urn:test"/>
                 <send>
                    <endpoint key="ListingEndPoint"/>
                 </send>
              </sequence>
           </target>
        </iterate>
     </inSequence>
     <outSequence>
        <log level="full">
           <property name="STATUS"
                     value="+++++++++++++++++ Inside OutSequence of PushInventory ++++++++++++++++++"/>
        </log>
        <aggregate>
           <completeCondition>
              <messageCount min="10" max="10"/>
           </completeCondition>
           <onComplete xmlns:ns2="com.blah.blah" expression="//listing">
              <log level="full" separator=",">
                 <property name="STATUS"
                           value="+++++++++++++++++ Aggregating responses back ++++++++++++++++++"/>
              </log>
              <enrich>
                 <source type="envelope" clone="true"/>
                 <target type="body"/>
              </enrich>
              <send/>
           </onComplete>
        </aggregate>
     </outSequence>
  </target>
    </proxy>

Upvotes: 1

Ratha
Ratha

Reputation: 9702

You put your log before the iterator mediator and see what you're receiving from the endpoint. It may contain duplicate entries. Then within iterate you have another log mediator. Check for records are right.

Upvotes: 0

Related Questions