I have an endpoint in wso2 integrator, wich receive some parameters, call some rest apis, and produce a new response.
I created a sequence for each rest api call, wich will get the properties and make the specific call. Then with a script mediator, i'm creating a new payload with the response, and putting it in a property. Example: myResponseA, myResponseB, myResponseC.
My main endpoint have an IN sequence with only a clone mediator and a loopback tag. The clone mediator have a target for each sequence described above, like:
<clone continueParent="false" sequential="true">
<target sequence="mySequenceA">
</target>
<target sequence="mySequenceB">
</target>
</clone>
<loopback />
My main endpoint have an OUT sequence with a payloadFactory and a send tag, like:
<payloadFactory media-type="json">
<format>
<![CDATA[
{
"myResponseA": $1,
"myResponseB": $2
}
]]>
</format>
<args>
<arg expression="get-property('myResponseA')"/>
<arg expression="get-property('myResponseB')"/>
</args>
</payloadFactory>
<property name="HTTP_SC" scope="axis2" type="STRING" value="200"/>
<send/>
The problem is, the OUT sequence is called multiple times, one for each sequence in Clone mediator.
I tried to use the Aggregate mediator with no luck, 'coz my apis is restful and i don't know how to use the aggregate expression. I dont even need it, because i put the responses in different properties and read it in my payloadFactory.
How to execute my OUT sequence only one single time when all my sequences return in clone mediator? or there is another mediator i should use?
Obs.: I have to call those apis in parallel, because each one will take some time, and i will call 5~10 each time.
Can you try this as a startup :-D
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="PoCCloneAggregate"
transports="http"
startOnLoad="true"
statistics="enable"
trace="enable">
<description/>
<target>
<inSequence>
<property name="enclosing_element" scope="default">
<result xmlns=""/>
</property>
<clone continueParent="false" sequential="true">
<target>
<sequence>
<log level="custom">
<property name="CLON" value="clon 1"/>
</log>
<payloadFactory media-type="json">
<format>
{"data":
{"temperatura":"10",
"id":"1"}}
</format>
<args>
</args>
</payloadFactory>
<loopback/>
</sequence>
</target>
<target>
<sequence>
<log level="custom">
<property name="CLON" value="clon 2"/>
</log>
<payloadFactory media-type="json">
<format>
{"data":
{"temperatura":"20",
"id":"2"}}
</format>
<args>
</args>
</payloadFactory>
<loopback/>
</sequence>
</target>
<target>
<sequence>
<log level="custom">
<property name="CLON" value="clon 3"/>
</log>
<payloadFactory media-type="json">
<format>
{"data":
{"temperatura":"30",
"id":"3"}}
</format>
<args>
</args>
</payloadFactory>
<loopback/>
</sequence>
</target>
</clone>
</inSequence>
<outSequence>
<log level="full"/>
<aggregate>
<completeCondition>
<messageCount min="-1" max="-1"/>
</completeCondition>
<onComplete expression="$body/jsonObject" xmlns:s12="http://www.w3.org/2003/05/soap-envelope"
xmlns:s11="http://schemas.xmlsoap.org/soap/envelope/" enclosingElementProperty="enclosing_element">
<log level="custom" separator=",">
<property name="MessageFlow" value="======================= Respuestas Agregadas. ==============="/>
</log>
<log level="full" separator=","/>
<send/>
</onComplete>
</aggregate>
</outSequence>
<faultSequence/>
</target>
</proxy>
You have to use aggragate mediator, the goal is to route each response to a single sequence containing this aggregate.
For example, if you use send mediator inside mySequenceA and mySequenceB, define the "receive" attribute to route the response in a dedicated sequence with <send receive="myResponseSequence"> (the same "myResponseSequence" must be used in mySequenceA and B).
If you use call mediator, then call a dedicated sequence with <sequence key="myResponseSequence"> (the same "myResponseSequence" must be used in mySequenceA and B)
inside myResponseSequence, use aggregate mediator :
the completeCondition can be let to default, the ESB will wait to receive the same number of response than the number of targets in your clone mediator. It gives you someting like :
<completeCondition>
<messageCount min="-1" max="-1"/>
</completeCondition>
the onComplete contains the mediation sequence that will be executed as soon as all the responses will be there : this sequence must contain the send mediator that will send a single response to the caller. The "expression" attribute on this "onComplete" node will contain an xpath that tell which node from the response must arrive inside the onComplete sequence.
inside the onComplete sequence, you can use payloadMediator to compose your single response
<onComplete xmlns:ns="http://org.apache.synapse/xsd" expression="//values">
<payloadFactory media-type="xml">
<format>
<myCustomResponse>
<result>$1</result>
</myCustomResponse>
</format>
<args>
<arg evaluator="xml" expression="//values"/>
</args>
</payloadFactory>
<send/>
</onComplete>
The fact that your api is restful should not be a problem with aggregate mediator. Perhaps the format is json and not xml : use json-eval if you want for the xpath or media-type=json" inside payloadFactory
Related
I have created a REST API using WSO2 API Manager (StockQuoteService) and configured a back end SOAP based web service (converting REST to SOAP) from where it will be getting the data based on the URL template.
In the "In Sequence", I have used a Switch mediator to send the request to different back end endpoints based on incoming data whereas in the default scenario (when no case match), I want to send the error message back to the client that the "Input message is invalid".
I have tried using the Send mediator, Respond Mediator, Sequence Mediator but still no success (may be doing something wrong) as still I am getting "no response from server" error when I try to invoke the URL which doesn't match any case of Switch and goes to Default.
How can I send the Error/Fault message back to the client from In Sequence of WSO2 API Manager?
In my scenario, the input sequence I used the switch mediator and I invoke an operation or another, in the default option I create my failure response
<inSequence>
<switch xmlns:xsd="http://pharmacy.arce.org/xsd"
description=""
source="//xsd:desc">
<case regex="NATURAL">
<log description="Search Pharmacy" level="custom" separator=",">
<property name="STATUS" value="Search Pharmacy"/>
</log>
<payloadFactory media-type="xml">
<format>
<p:searchpharmacy xmlns:p="http://pharmacy.arce.org">
<ax22:pharmacy xmlns:ax22="http://pharmacy.arce.org">
<xs:desc xmlns:xs="http://pharmacy.arce.org/xsd">$1</xs:desc>
<xs:id xmlns:xs="http://pharmacy.arce.org/xsd">$2</xs:id>
<xs:latitude xmlns:xs="http://pharmacy.arce.org/xsd">$3</xs:latitude>
<xs:longitude xmlns:xs="http://pharmacy.arce.org/xsd">$4</xs:longitude>
</ax22:pharmacy>
</p:searchpharmacy>
</format>
<args>
<arg evaluator="xml" expression="//xsd:desc"/>
<arg evaluator="xml" expression="//xsd:id"/>
<arg evaluator="xml" expression="//xsd:latitude"/>
<arg evaluator="xml" expression="//xsd:longitude"/>
</args>
</payloadFactory>
<header name="To" scope="default" value="urn:searchpharmacy"/>
<log level="full" separator=",">
<property name="Mensaje" value="Cuerpo"/>
</log>
</case>
<case regex="EXPERIMENTAL">
<log description="Search Pharmacy Direction" level="custom" separator=",">
<property name="STATUS" value="Search Pharmacy Direction Request"/>
</log>
<payloadFactory media-type="xml">
<format>
<p:searchPhone xmlns:p="http://pharmacy.arce.org">
<ax22:pharmacy xmlns:ax22="http://pharmacy.arce.org">
<xs:desc xmlns:xs="http://pharmacy.arce.org/xsd">$1</xs:desc>
<xs:id xmlns:xs="http://pharmacy.arce.org/xsd">$2</xs:id>
<xs:latitude xmlns:xs="http://pharmacy.arce.org/xsd">$3</xs:latitude>
<xs:longitude xmlns:xs="http://pharmacy.arce.org/xsd">$4</xs:longitude>
</ax22:pharmacy>
</p:searchPhone>
</format>
<args>
<arg evaluator="xml" expression="//xsd:desc"/>
<arg evaluator="xml" expression="//xsd:id"/>
<arg evaluator="xml" expression="//xsd:latitude"/>
<arg evaluator="xml" expression="//xsd:longitude"/>
</args>
</payloadFactory>
<header name="Action" scope="default" value="urn:searchPhone"/>
<property name="SOAPAction" scope="transport" type="STRING" value=""/>
<log level="full" separator=",">
<property name="Data" value="Body"/>
</log>
</case>
<default>
<log description="Fault" level="custom" separator=",">
<property name="STATUS" value="Invoke fault "/>
</log>
<payloadFactory media-type="xml">
<format>
<rs:fault xmlns:rs="http://pharmacy.arce.org">
<rs:code>-1</rs:code>
<rs:type>Invocation error</rs:type>
<rs:message>No operation has been invoked</rs:message>
<rs:description>The value of the input parameter is not valid</rs:description>
</rs:fault>
</format>
<args/>
</payloadFactory>
<respond/>
</default>
</switch>
</inSequence>
Here is the default section
<default>
<log description="Fault" level="custom" separator=",">
<property name="STATUS" value="Invoke fault "/>
</log>
<payloadFactory media-type="xml">
<format>
<rs:fault xmlns:rs="http://pharmacy.arce.org">
<rs:code>-1</rs:code>
<rs:type>Invocation error</rs:type>
<rs:message>No operation has been invoked</rs:message>
<rs:description>The value of the input parameter is not valid</rs:description>
</rs:fault>
</format>
<args/>
</payloadFactory>
<respond/>
</default>
And the fault response
{"fault":{"code":-1,"type":"Invocation error","message":"No operation has been invoked","description":"The value of the input parameter is not valid"}}
You can find other scenarios here
http://harshcreationz.blogspot.com/2016/02/common-and-error-handling-sequences.html
This should work.
<payloadFactory media-type="json">
<format>
{
"error":"true",
"message":"error case"
}
</format>
</payloadFactory>
<property name="messageType" value="application/json" scope="axis2"/>
<respond/>
Nits
The error response as comments "no response from server", I receive it when I call the api from the test console that has the API Manager.
You can see this link
API Console Issue
To validate the response you expect.
Try calling from another tool such as SOAP UI or Postman, in my case I receive a fault response message with the structure defined.
This is the call from the console API
curl -X GET --header 'Accept: application/xml' --header 'Authorization: Bearer 465f1385-a120-3c19-ad22-c3057e744a3b' 'https://169.254.193.10:8252/getById/1.0.0/getEmployeeXML?Id=5'
For the call from another client in the header pass these values you have in the api call
Accept: application/json
Authorization: Bearer 465f1385-a120-3c19-ad22-c3057e744a3b'
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?
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>
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.
I'am evaluating WSO2 esb and try this simple use case :
jms -> (esb) -> WebService (HelloService on WSO2 Application Server)
Send ws response to jms queue (end point EPQ_ESB_OUT)
Send fault to jms queue (end point EPQ_ESB_ERR)
When I stop WSO2 Application Server, the fault sequence is called and a message is sent to EPQ_ESB_ERR but the message is always empty...
I've tried to use makefault and buildfactory mediators but it fails in both case (empty message in both case).
My Proxy :
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="Test04Proxy02" transports="jms" startOnLoad="true" trace="enable">
<target>
<endpoint key="EPW_HelloService"/>
<inSequence>
<log>
<property name="STEP" value="==== INseq"/>
</log>
</inSequence>
<outSequence>
<property name="OUT_ONLY" value="true"/>
<log>
<property name="STEP" value="==== OUTseq"/>
</log>
<send>
<endpoint key="EPQ_ESB_OUT"/>
</send>
</outSequence>
<faultSequence>
<property name="OUT_ONLY" value="true" scope="default" type="STRING"/>
<log level="full">
<property name="STEP" value="==== FAULTseq"/>
<property name="ERROR_CODE" expression="get-property('ERROR_CODE')"/>
<property name="ERROR_MESSAGE" expression="get-property('ERROR_MESSAGE')"/>
<property name="ERROR_DETAIL" expression="get-property('ERROR_DETAIL')"/>
</log>
<payloadFactory>
<format>
<ns:text xmlns:ns="http://myns">$1</ns:text>
</format>
<args>
<arg xmlns:ns="http://myns"
evaluator="xml"
expression="get-property('ERROR_MESSAGE')"/>
</args>
</payloadFactory>
<send>
<endpoint key="EPQ_ESB_ERR"/>
</send>
</faultSequence>
</target>
</proxy>
Any help would be appreciate. Thanks.
Just a guess:
Maybe you are having some issues with namesspaces. WSO seems to use the ns namespace itself extensively, so I would try using a different namespace in your payload factory, eg
<payloadFactory>
<format>
<myns:text xmlns:myns="http://myns">$1</myns:text>
</format>
<args>
<arg evaluator="xml" expression="get-property('ERROR_MESSAGE')"/>
</args>
</payloadFactory>
(you shouldn't actually need a namespace definition in the <arg> element)
problem solved :
Replaced ... by
<makefault version="soap11">
<code expression="get-property('ERROR_CODE')"/>
<reason expression="get-property('ERROR_MESSAGE')"/>
</makefault>
and added
<parameter name="transport.jms.ContentType">
<rules>
<jmsProperty>contentType</jmsProperty>
<default>application/xml</default>
</rules>
</parameter>
just before the end tag.
Don't really know why it works now with this parameter...
I am using iterate mediater and aggregate mediator.
My request is:
<p:GetPersonDataOperation xmlns:p="http://tempuri.org">
<!--1 or more occurrences-->
<xs:ID xmlns:xs="http://tempuri.org">1</xs:ID>
</p:GetPersonDataOperation>
and response is :
<GetPersonDataCollection xmlns="http://tempuri.org">
<GetPersonData>
<AppInstanceID>1</AppInstanceID>
<RecordID>349</RecordID>
<ID>1</ID>
<Name>name</Name>
<LastName>lastname</LastName>
<Descr>description</Descr>
<Address>Park Street</Address>
</GetPersonData>
</GetPersonDataCollection>
If i don't use Aggregate mediator then i get the above response, But if i use Aggregate mediator i get request timeOut Exception
My in Sequence is :
<sequence xmlns="http://ws.apache.org/ns/synapse" name="GetPersonDataOperationSeq">
<iterate xmlns:xs="http://tempuri.org" xmlns:ns="http://org.apache.synapse/xsd" xmlns:p="http://tempuri.org" preservePayload="true" attachPath="//p:GetPersonData" expression="//p:GetPersonData/xs:ID" id="Iterator1">
<target>
<sequence>
<property name="ID" expression="//xs:ID" scope="default" type="STRING"/>
<payloadFactory>
<format>
<p:GetPersonData>
<xs:ID>$1</xs:ID>
</p:GetPersonData>
</format>
<args>
<arg expression="get-property('ID')"/>
</args>
</payloadFactory>
<send receive="AggregatorSeq">
<endpoint key="GetPersonDataEP"/>
</send>
</sequence>
</target>
</iterate>
</sequence>
And From The above in sequence i am redirecting to another Sequence called AggregatorSeq and my AggregatorSeq is:
<sequence xmlns="http://ws.apache.org/ns/synapse" name="AggregatorSeq">
<log level="custom">
<property name="CamHereProp" value="*******************Yes??????????????**********************************************"/>
</log>
<aggregate>
<completeCondition>
<messageCount min="-1" max="-1"/>
</completeCondition>
<onComplete xmlns:ns="http://org.apache.synapse/xsd" xmlns:p="http://tempuri.org" expression="//p:GetPersonDataCollection">
<send/>
</onComplete>
</aggregate>
</sequence>
What am i doing wrong.Looking forward to your answers.Thanks in advance
Try adding the ID of the iterator to your aggregator. In your case it should be like,
<aggregate id="Iterator1">
Also, if each of your response body starts with <GetPersonData> then you need to add that to the expression in onComplete.
<onComplete xmlns:ns="http://org.apache.synapse/xsd" xmlns:p="http://tempuri.org" expression="//p:GetPersonData">
Can you specify the issue with the code you have given. You can use <log level="full"/> to debug till what level is your configuration gets executed.
I am invoking a wso2 DSS service which returns me data like:
<IdentifierCollection xmlns="http://tempuri.org/">
<Identifier>
<One>1</One>
<Two>2</Two>
<Three>3</Three>
</Identifier>
</IdentifierCollection>
To invoke Dss my esb code is:
<payloadFactory>
<format>
<p:GetIdentifier xmlns:p="http://tempuri.org/">
<xs:ID xmlns:xs="http://tempuri.org/">$1</xs:ID>
</p:GetIdentifier >
</format>
<args>
<arg expression="get-property('ID')"/>
</args>
</payloadFactory>
<send receive="ResponseOfGetIdentifier">
<endpoint key="IdentifierEP"/>
</send>
Now in my ResponseOfGetIdentifier Sequence i am capturing all data in properties
<sequence xmlns="http://ws.apache.org/ns/synapse" name="ResponseOfGetIdentifier">
<iterate xmlns:ns="http://org.apache.synapse/xsd" xmlns:p="http://tempuri.org/" preservePayload="true" attachPath="//p:EntriesCollection" expression="//p:EntriesCollection/p:Entries" id="IterateForResponse">
<target>
<sequence>
<property xmlns:ns="http://org.apache.synapse/xsd" xmlns:p="http://tempuri.org" name="ResponseOne" expression="//p:Identifier/p:one" scope="default" type="STRING"/>
<property xmlns:ns="http://org.apache.synapse/xsd" xmlns:p="http://tempuri.org" name="ResponseTwo" expression="//p:Identifier/p:Two" scope="default" type="STRING"/>
<property xmlns:ns="http://org.apache.synapse/xsd" xmlns:p="http://tempuri.org" name="ResponseThree" expression="//p:Identifier/p:Three" scope="default" type="STRING"/>
<payloadFactory>
<format>
<tns:ProductIdentifier xmlns:tns="http://globalArther.products.com">
<IdentifierProducts>
<Product1>$1</Product1>
<Product2>$2</Product>
<Product3>$3</Product3>
</IdentifierProducts>
</tns:ProductIdentifier>
</format>
<args>
<arg expression="get-property('ResponseOne')"/>
<arg expression="get-property(''ResponseTwo)"/>
<arg expression="get-property('ResponseThree')"/>
</args>
</payloadFactory>
</sequence>
</target>
</iterate>
</sequence>
Since my dss response contains only one iteration of Identifier node hence above code is working but when my identifier node count is more than one i.e
<IdentifierCollection xmlns="http://tempuri.org/">
<Identifier>
<One>1</One>
<Two>2</Two>
<Three>3</Three>
</Identifier>
<Identifier>
<One>a</One>
<Two>b</Two>
<Three>c</Three>
</Identifier>
</IdentifierCollection>
, since my payload can take only one data it takes the second iteration data and shows me only single result as:
<tns:ProductIdentifier xmlns:tns="http://globalArther.products.com">
<IdentifierProducts>
<Product1>a</Product1>
<Product2>b</Product>
<Product3>c</Product3>
</IdentifierProducts>
</tns:ProductIdentifier>
But i want my response as :
<tns:ProductIdentifier xmlns:tns="http://globalArther.products.com">
<IdentifierProducts>
<Product1>1</Product1>
<Product2>2</Product>
<Product3>3</Product3>
</IdentifierProducts>
<IdentifierProducts>
<Product1>a</Product1>
<Product2>b</Product>
<Product3>c</Product3>
</IdentifierProducts>
</tns:ProductIdentifier>
So now my question is how can i do that i.e how can i make my payload dynamic i.e. i want to add every iteration in my payload.
Looking forward to your answers.Thanks in advance
Payload is kind of static. You need to use XSLT mediator to achieve this .That is, you have to write XSLT script to make the iteration logic.