getting cognito acces_token with wso2 esb - wso2

I'm trying to get access token through AWS Cognito with client credentials but getting something else.
I'm doing this in wso2 Enterprise integrator 6.1.0
<payloadFactory media-type="xml">
<format>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/1999/XMLSchema/instance">
<soapenv:Header>
<Content-Type xmlns="">$1</Content-Type>
<Authorization xmlns="">$2</Authorization>
</soapenv:Header>
<soapenv:Body/>
</soapenv:Envelope>
</format>
<args>
<arg evaluator="xml" value="application/x-www-form-urlencoded"/>
<arg value="Basic 2354sdfmdtrerkdfdgkeryryrtwdasr345345twsdfwsedtr34"/>
</args>
</payloadFactory>
<log level="full"/>
<property name="DISABLE_CHUNKING" scope="axis2" type="STRING" value="true"/>
<endpoint key="validateUser-ext-ep"/>
</call>
<log level="full"/>
after this the response i'm getting is like this :
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
<soapenv:Body>
<ns:binary xmlns:ns="http://ws.apache.org/commons/ns/payload">PCFET0NUWVBFIGh0bWw+CjxodG1sIGxhbiYWNrZ3JvdW5kLWN1c3RvbWl6YWJsZSBtb2RhbC1jb250ZW50LW1vYmlsZSI+CiAgICAgICAgICAgICAgICA8ZGl2PgogICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9ImJhbm5lci1jdXN0b21pemFibGUiPgogICAgICAgICAgICAgICAgICAgICAgICA8Y2VudGVyPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgIDwvY2VudGVyPgogICAgICAgICAgICAgICAgICAgIDwvZGl2PgogICAgICAgICAgICAgICAgPC9kaXY+CiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPSJtb2RhbC1ib2R5Ij4KICAgICAgICAgICAgICAgICAgICA8cCBhbGlnbj0iY2VudGVyIj5BbiBlcnJvciB3YXMgZW5jb3VudGVyZWQgd2l0aCB0aGUgcmVxdWVzdGVkIHBhZ2UuPC9wPgogICAgICAgICAgICAgICAgICAgIDxicj4KICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIDwvZGl2PgogICAgICAgICAgICA8L2Rpdj4KICAgICAgICA8L2Rpdj4KICAgIDwvZGl2Pgo8L2JvZHk+Cgo8L2h0bWw+Cg==</ns:binary>l
</soapenv:Body>
</soapenv:Envelope>
I don't know if I'm doing something wrong as in postman I sent the data same way I was getting the token there I passed the Authrization as Basic dfudne4r49859dfnw34598sdfs base64 endcoded(client:client_secret) and Content-Type : application/x-www-form-urlencoded in header and in params I passed grant_type: client_credential for this I was able to get the token but when I tried in wso2 esb I got the above error
the endpoint looks like :https://xxxxxxxxxx.us-east-1.amazoncognito.com/oauth2/token?grant_type=client_credentials

this is the API to get the Access token and it returns the access token
<?xml version="1.0" encoding="UTF-8"?>
<api context="/api/myService" name="my-service-api" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST" uri-template="/getToken">
<inSequence>
<script language="js"><![CDATA[var payload = mc.getPayloadXML();
var log = mc.getServiceLog();
var client_id = payload..*::client_id.toString();
var client_secret = payload..*::client_secret.toString();
mc.setProperty("client_id", client_id);
mc.setProperty("client_secret", client_secret);]]>
</script>
<payloadFactory media-type="json">
<format/>
<args/>
</payloadFactory>
<property name="ContentType" scope="axis2" type="STRING" value="application/x-www-form-urlencoded"/>
<property expression="fn:concat($ctx:client_id,':',$ctx:client_secret)" name="credentials" scope="default" type="STRING"/>
<property expression="fn:concat('Basic ', base64Encode($ctx:credentials))" name="Authorization" scope="transport" type="STRING" xmlns:ns="http://org.apache.synapse/xsd"/>
<property name="FORCE_POST_PUT_NOBODY" scope="axis2" type="BOOLEAN" value="true"/>
<property name="DISABLE_CHUNKING" scope="axis2" type="STRING" value="true"/>
<call>
<endpoint>
<http method="post" uri-template="https://xxxxxxxxxxx.amazoncognito.com/oauth2/token?grant_type=client_credentials"/>
</endpoint>
</call>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
Call the above API like this :
<payloadFactory media-type="xml">
<format>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<root>
<client_id>$1</client_id>
<client_secret>$2</client_secret>
</root>
</soapenv:Body>
</soapenv:Envelope>
</format>
<args>
<arg evaluator="xml" expression="get-property('client_id')"/>
<arg evaluator="xml" expression="get-property('client_secret')"/>
</args>
</payloadFactory>
<property name="ContentType" scope="default" type="STRING" value="application/xml"/>
<property action="remove" name="REST_URL_POSTFIX" scope="axis2"/>
<call>
<endpoint>
<http method="post" uri-template="http://localhost:8280/api/myService/getToken"/>
</endpoint>
</call>
<script language="js">
<![CDATA[ var tokenContainer = mc.getPayloadJSON();
var log = mc.getServiceLog();
mc.setProperty("Authorization_header", tokenContainer.access_token);]]>
</script>
The Response will be
{"access_token":"LzSq94JoaUT2LwJlkEl35CXX0MdwqtUKIL8Wvi7dm4SqcSofR4xF5xBZre83MZXpHOr-Hg","expires_in":360,"token_type":"Bearer"}
In last script mediator you can access the token Access token throught getting it by mc.getPayloadJSON() this will give the same response as shwon above

Related

WSO2 EI 6.6.0 Class Mediator not being able to use SOAP call return content

I have the following API in EI 6.6.0:
<?xml version='1.0' encoding='UTF-8'?>
<api xmlns="http://ws.apache.org/ns/synapse" name="sample" context="/sample">
<resource methods="POST">
<inSequence>
<payloadFactory media-type="xml">
<format>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<P xmlns="http://tempuri.org/">
<P1>$1</P1>
<P2>$2</P2>
<P3>$3</P3>
</P>
</soap:Body>
</soap:Envelope>
</format>
<args>
<arg evaluator="json" expression="$.p1" />
<arg evaluator="json" expression="$.p2" />
<arg evaluator="json" expression="$.p3" />
</args>
</payloadFactory>
<log level="full" />
<property name="Content-Type" value="text/xml;charset=UTF-8" scope="axis2"/>
<header name="Accept" scope="transport" value="text/xml"/>
<call>
<endpoint>
<wsdl Action="name_of_the_action" service="name_of_the_service" port="name_of_soap_port" uri="http://<ip>/path?WSDL" />
</endpoint>
</call>
<class name="my_mediator_package"></class>
<log level="full" />
<payloadFactory media-type="xml">
<format>
<retorno xmlns="">
<msg>$1</msg>
</retorno>
</format>
<args>
<arg evaluator="xml" expression="get-property('property_set_on_mediator')" />
</args>
</payloadFactory>
<property name="messageType" value="application/xml" scope="axis2" type="STRING" />
<respond />
</inSequence>
<outSequence>
</outSequence>
<faultSequence>
<property name="text" value="An unexpected error occured"/>
<property name="message" expression="get-property('ERROR_MESSAGE')"/>
<payloadFactory media-type="xml">
<format>
<error xmlns="">
<msg>$1</msg>
</error>
</format>
<args>
<arg evaluator="xml" expression="get-property('ERROR_MESSAGE')"/>
</args>
</payloadFactory>
<property name="messageType" value="application/json" scope="axis2" type="STRING"/>
<respond/>
</faultSequence>
</resource>
</api>
my mediate method content:
public boolean mediate(MessageContext synCtx) {
org.apache.axis2.context.MessageContext axis2MessageContext = ((Axis2MessageContext) synCtx)
.getAxis2MessageContext();
try {
// Getting the json payload to string
String jsonPayloadToString = JsonUtil.jsonPayloadToString(((Axis2MessageContext) synCtx)
.getAxis2MessageContext());
System.out.println("original payload : \n" + jsonPayloadToString + "\n");
I'm not being able to use the return from my SOAP call in my mediator so I can work on it.
When I run the API I get the following from my mediator code:
original payload:
{}
Is there a way so I can obtain the SOAP call returned envelope and use it in my mediator?
The JSON payload is coming as empty because you are calling a SOAP backend and getting a SOAP payload. You can use synCtx.getEnvelope() in your mediator to get the SOAPEnvelope from the response.
1- make sure the json payload is there. So, log the json properties inside your inSequence.
2- I'm not being able to use the return from my SOAP call in my mediator so I can work on it. you can see the response payload in your outSequence which currently is doing nothing.
3- According to your scenario which is simply calling a SOAP webservice, you do not need a class mediator. In other words, when you do not need manipulating the initial payload and then pass it to the destination service, logically implementing your own class mediator benefits you nothing.
Also, there are quite number of samples in https://docs.wso2.com/display/EI611 which will help you.
Please let me know if your problem is solved.

SOAPProcessingException occurred when execute the artifact in WSO2 ESB

I used WSO2 ESB 5.0. I used two soap endpoints to get the response. Below mention the proxy service code.
<?xml version="1.0" encoding="UTF-8"?>
<inSequence xmlns="http://ws.apache.org/ns/synapse">
<log/>
<property expression="//sam:getCertificateID/sam:vehicleNumber"
name="getVehicleNo" scope="default" type="STRING" xmlns:sam="http://sample.esb.org"/>
<log>
<property expression="get-property('default','getVehicleNo')" name="VehicleNo"/>
</log>
<call>
<endpoint>
<wsdl port="EmissionTestServiceHttpSoap11Endpoint"
service="EmissionTestService" uri="http://172.17.0.1:9763/services/EmissionTestService?wsdl"/>
</endpoint>
</call>
<property expression="//ns:getCertificateIDResponse/ns:return"
name="getCertificateIDResponse" scope="default" type="STRING" xmlns:ns="http://sample.esb.org"/>
<log>
<property
expression="get-property('default','getCertificateIDResponse')" name="CertificateID"/>
</log>
<payloadFactory media-type="xml">
<format>
<soapenv:Envelope xmlns:sam="http://sample.esb.org" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<sam:getPolicyID>
<sam:vehicleNumber>$1</sam:vehicleNumber>
</sam:getPolicyID>
</soapenv:Body>
</soapenv:Envelope>
</format>
<args>
<arg evaluator="xml" expression="get-property('default','getVehicleNo')"/>
</args>
</payloadFactory>
<log/>
<property name="messageType" scope="axis2" type="STRING" value="application/soap+xml"/>
<call>
<endpoint>
<wsdl port="InsuranceServiceHttpSoap11Endpoint"
service="InsuranceService" uri="http://172.17.0.1:9763/services/InsuranceService?wsdl"/>
</endpoint>
</call>
<property expression="//ns:getPolicyIDResponse/ns:return"
name="getPolicyIDResponse" scope="default" type="STRING" xmlns:ns="http://sample.esb.org"/>
<log>
<property
expression="get-property('default','getPolicyIDResponse')" name="PolicyID"/>
</log>
</inSequence>
First endpoint is working fine and gave the specific log messages. But when going to call second endpoint, below error message is occurred.
Caused by: org.apache.axiom.soap.SOAPProcessingException: First Element must contain the local name, Envelope , but found faultstring
at org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder.constructNode(StAXSOAPModelBuilder.java:305)
at org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder.createOMElement(StAXSOAPModelBuilder.java:252)
at org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder.createNextOMElement(StAXSOAPModelBuilder.java:234)
at org.apache.axiom.om.impl.builder.StAXOMBuilder.next(StAXOMBuilder.java:249)
at org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder.getSOAPEnvelope(StAXSOAPModelBuilder.java:204)
at org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder.<init>(StAXSOAPModelBuilder.java:154)
at org.apache.axiom.om.impl.AbstractOMMetaFactory.createStAXSOAPModelBuilder(AbstractOMMetaFactory.java:73)
at org.apache.axiom.om.impl.AbstractOMMetaFactory.createSOAPModelBuilder(AbstractOMMetaFactory.java:79)
at org.apache.axiom.om.OMXMLBuilderFactory.createSOAPModelBuilder(OMXMLBuilderFactory.java:196)
at org.apache.axis2.builder.SOAPBuilder.processDocument(SOAPBuilder.java:65)
at org.apache.synapse.transport.passthru.util.DeferredMessageBuilder.getDocument(DeferredMessageBuilder.java:148)
at org.apache.synapse.transport.passthru.util.RelayUtils.builldMessage(RelayUtils.java:137)
... 14 more
Can you help me to solve this issue. Any help or workarounds are really appreciated.
Your endpoint is not returning an soap Envelope. You can see what's happening if you set 'configure->logging->apache.synapse.tranport.http.wire' to 'debug'.
Because the endpoint is not returning SOAP, but likely plain old XML you can try setting
<property name="messageType" value="application/xml" scope="axis2"/>
<property name="ContentType" value="application/xml" scope="axis2"/>
before sending the message.

WSO2 ESB - Error Response when Post-Request - Content-Type application/x-www-form-urlencoded

I'm using WSO2 EI 6.3v.I want to pass application/x-www-form-urlencoded data to the rezlive hotel Supplier. In hear i put my code and response.
CODE
<inSequence>
<log category="WARN" level="full">
<property name="API BEGIN" value="Test_Supplier API"/>
</log>
<payloadFactory media-type="xml">
<format>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<HotelFindRequest xmlns="">
$1
</HotelFindRequest>
</soapenv:Body>
</soapenv:Envelope>
</format>
<args>
<arg evaluator="xml" expression="$env/*[local-name()='Body']/*[local-name()='HotelFindRequest']/*"/>
</args>
</payloadFactory>
<property expression="$env/*[local-name()='Body']/*" name="xmlbody" scope="default" type="STRING"/>
<log>
<property expression="$ctx:xmlbody" name="Body======="/>
</log>
<property name="messageType" scope="axis2" type="STRING" value="application/x-www-form-urlencoded"/>
<property expression="$body" name="payload" scope="default" type="STRING"/>
<property name="uri.var.url" scope="default" type="STRING" value="http://test.xmlhub.com/testpanel.php/action/findhotel"/>
<call>
<endpoint>
<address format="pox" uri="http://test.xmlhub.com/testpanel.php/action/findhotel?XML={xmlbody}"/>
</endpoint>
</call>
<respond/>
</inSequence>
Body Log
<HotelFindRequest>
<Authentication>
<AgentCode>xxxxxxx</AgentCode>
<UserName>xxxxx</UserName>
<Password>xxxxxx</Password>
</Authentication>
<Booking>
<ArrivalDate>22/05/2019</ArrivalDate>
<DepartureDate>25/05/2019</DepartureDate>
<CountryCode>AE</CountryCode>
<City>968</City>
<GuestNationality>LK</GuestNationality>
<HotelRatings>
<HotelRating>1</HotelRating><HotelRating>2</HotelRating>
<HotelRating>3</HotelRating><HotelRating>4</HotelRating>
<HotelRating>5</HotelRating>
</HotelRatings>
<Rooms>
<Room>
<Type>Room-1</Type>
<NoOfAdults>2</NoOfAdults>
<NoOfChilds>0</NoOfChilds>
</Room>
<Room>
<Type>Room-2</Type>
<NoOfAdults>1</NoOfAdults>
<NoOfChilds>0</NoOfChilds>
</Room>
<Room>
<Type>Room-3</Type>
<NoOfAdults>2</NoOfAdults>
<NoOfChilds>0</NoOfChilds>
</Room>
<Room>
<Type>Room-4</Type>
<NoOfAdults>3</NoOfAdults>
<NoOfChilds>0</NoOfChilds>
</Room>
</Rooms>
</Booking>
Response comming as
<HotelFindResponse>
<error>Please provide agentcode.</error>
<error>Please provide username.</error>
<error>Please provide password.</error></HotelFindResponse>
But I pass same configuration in POSTMAN, give me the correct response.
I put the same configuration in Postman. I tried so meny ways to get response.All are failed.
What is wrong with that code?.
Please help.
Can you try with HTTP endpoint (https://docs.wso2.com/display/EI640/HTTP+Endpoint) using post?
Payload factory already sets the body, so it should work right away as it will try to post it.
Try using "uri.var.xmlBody" property name instead of simple "xmlBody":
<property expression="$env/*[local-name()='Body']/*" name="uri.var.xmlBody" scope="default" type="STRING"/>
<call>
<endpoint>
<address format="pox" uri="http://test.xmlhub.com/testpanel.php/action/findhotel?XML={uri.var.xmlBody}"/>
</endpoint>
</call>
Can you try this? from here
<payloadFactory media-type="xml">
<format>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<root xmlns="">
<XML>$1</XML>
</root>
</soapenv:Body>
</soapenv:Envelope>
</format>
<args>
<arg evaluator="xml" expression="$ctx:xmlbody"></arg>
</args>
</payloadFactory>
<property name="messageType" value="application/x-www-form-urlencoded" scope="axis2" type="STRING"></property>
<property name="DISABLE_CHUNKING" value="true" scope="axis2" type="STRING"></property>
<call>
<http method="post" uri-template="test.xmlhub.com/testpanel.php/action/findhotel"/>
</call>

WSO2 ESB does not sent a clinicId param to WSO2 DSS

In WSO2 configured proxy service, does not send the clinicId param to DSS. In logs from DSS gives exception :
Default Namespace: https://bur.test.ru/dss/services/tfoms
Current Request Name: get_single_inserted_branch_by_id
Current Params: {clinicID=}
Nested Exception:-
java.lang.NumberFormatException: For input string: ""
In logs from ESB:
Nested Exception:-
javax.xml.stream.XMLStreamException: DS Fault Message: Error in 'SQLQuery.processPreNormalQuery': For input string: ""
DS Code: DATABASE_ERROR
Source Data Service:-
Name: TEST
Location: \TEST.dbs
Description: Service generates hospitalisation&
Default Namespace: https://bur.TEST.ru/dss/services/tfoms
Current Request Name: get_single_inserted_branch_by_id
Current Params: {clinicID=}
Nested Exception:-
java.lang.NumberFormatException: For input string: ""
On WSO2 DSS it works good and it takes info from postgres.
Here is a code of proxy servise from WSO2 ESB:
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="BurProxy"
transports="http,https"
statistics="disable"
trace="enable"
startOnLoad="true">
<target>
<inSequence>
<property name="CLINIC_ID"
expression="//clinicID/text()"
scope="axis2"
type="STRING"/>
<log level="full">
<property name="CLINIC_ID" expression="clinicID"/>
</log>
<payloadFactory media-type="xml">
<format>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:tfom="https://bur.cdmarf.ru/dss/services/tfoms">
<soapenv:Header/>
<soapenv:Body>
<tfom:get_single_inserted_branch_by_id>
<tfom:clinicID>$1</tfom:clinicID>
</tfom:get_single_inserted_branch_by_id>
</soapenv:Body>
</soapenv:Envelope>
</format>
<args>
<arg evaluator="xml" expression="$axis2:CLINIC_ID"/>
</args>
</payloadFactory>
<log>
<property name="PAYLOAD" expression="$body"/>
</log>
<call blocking="true">
<endpoint key="dss"/>
</call>
<xslt key="xslt-remove-namespace"/>
<property name="messageType" value="text/xml" scope="axis2"/>
<property name="contentType" value="text/xml" scope="axis2"/>
<property name="rabbitmq.attributes.app.id"
value="RMIS"
scope="axis2"
type="STRING"/>
<property name="rabbitmq.attributes.type"
value="BRANCH"
scope="axis2"
type="STRING"/>
<property name="rabbitmq.attributes.user.id"
value="rmis"
scope="axis2"
type="STRING"/>
<property name="MESSAGE_ID" expression="get-property('MessageID')"/>
<script language="js">var messageID = mc.getProperty('MESSAGE_ID').substring(9,45);
mc.setProperty("RABBIT_MESSAGE_ID", messageID);</script>
<property name="rabbitmq.attributes.custom.message.id"
expression="get-property('RABBIT_MESSAGE_ID')"
scope="axis2"/>
<clone continueParent="true">
<target sequence="writeToFile"/>
</clone>
<send>
<endpoint key="rabbit"/>
</send>
<payloadFactory media-type="xml">
<format>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:tfom="https://bur.cdmarf.ru/dss/services/tfoms">
<soapenv:Header/>
<soapenv:Body>
<tfom:get_inserted_divisions_of_clinic>
<tfom:clinicID>$1</tfom:clinicID>
</tfom:get_inserted_divisions_of_clinic>
</soapenv:Body>
</soapenv:Envelope>
</format>
<args>
<arg evaluator="xml" expression="$axis2:CLINIC_ID"/>
</args>
</payloadFactory>
<call blocking="true">
<endpoint key="dss"/>
</call>
<iterate xmlns:tfoms="https://bur.cdmarf.ru/dss/services/tfoms"
continueParent="true"
expression="//tfoms:DIVISION"
sequential="true">
<target>
<sequence>
<property name="rabbitmq.attributes.type"
value="DIVISION"
scope="axis2"
type="STRING"/>
<property name="messageType" value="xml" scope="axis2"/>
<property name="contentType" value="xml" scope="axis2"/>
<property name="MESSAGE_ID" expression="get-property('MessageID')"/>
<script language="js">var messageID = mc.getProperty('MESSAGE_ID').substring(9,45);
mc.setProperty("RABBIT_MESSAGE_ID", messageID);</script>
<property name="rabbitmq.attributes.custom.message.id"
expression="get-property('RABBIT_MESSAGE_ID')"
scope="axis2"/>
<xslt key="xslt-remove-namespace"/>
<clone continueParent="true">
<target sequence="writeToFile"/>
</clone>
<send>
<endpoint key="rabbit"/>
</send>
</sequence>
</target>
</iterate>
<payloadFactory media-type="xml">
<format>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:tfom="https://bur.cdmarf.ru/dss/services/tfoms">
<soapenv:Body>
<tfom:get_inserted_liks_division_to_bed>
<tfom:clinicID>$1</tfom:clinicID>
</tfom:get_inserted_liks_division_to_bed>
</soapenv:Body>
</soapenv:Envelope>
</format>
<args>
<arg evaluator="xml" expression="$axis2:CLINIC_ID"/>
</args>
</payloadFactory>
<call blocking="true">
<endpoint key="dss"/>
</call>
<iterate xmlns:tfoms="https://bur.cdmarf.ru/dss/services/tfoms"
continueParent="true"
expression="//tfoms:DIVISION_LINK_STRUCTURE_BED"
sequential="true">
<target>
<sequence>
<property name="rabbitmq.attributes.type"
value="DIVISION_LINK_STRUCTURE_BED"
scope="axis2"
type="STRING"/>
<property name="messageType" value="xml" scope="axis2"/>
<property name="contentType" value="xml" scope="axis2"/>
<property name="MESSAGE_ID" expression="get-property('MessageID')"/>
<script language="js">var messageID = mc.getProperty('MESSAGE_ID').substring(9,45);
mc.setProperty("RABBIT_MESSAGE_ID", messageID);</script>
<property name="rabbitmq.attributes.custom.message.id"
expression="get-property('RABBIT_MESSAGE_ID')"
scope="axis2"/>
<xslt key="xslt-remove-namespace"/>
<clone continueParent="true">
<target sequence="writeToFile"/>
</clone>
<send>
<endpoint key="rabbit"/>
</send>
</sequence>
</target>
</iterate>
<payloadFactory media-type="xml">
<format>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:tfom="https://bur.cdmarf.ru/dss/services/tfoms">
<soapenv:Body>
<tfom:get_inserted_amound_bed>
<tfom:clinicID>$1</tfom:clinicID>
</tfom:get_inserted_amound_bed>
</soapenv:Body>
</soapenv:Envelope>
</format>
<args>
<arg evaluator="xml" expression="$axis2:CLINIC_ID"/>
</args>
</payloadFactory>
<call blocking="true">
<endpoint key="dss"/>
</call>
<iterate xmlns:tfoms="https://bur.cdmarf.ru/dss/services/tfoms"
continueParent="true"
expression="//tfoms:AMOUNT_BED"
sequential="true">
<target>
<sequence>
<property name="rabbitmq.attributes.type"
value="AMOUNT_BED"
scope="axis2"
type="STRING"/>
<property name="messageType" value="xml" scope="axis2"/>
<property name="contentType" value="xml" scope="axis2"/>
<property name="MESSAGE_ID" expression="get-property('MessageID')"/>
<script language="js">var messageID = mc.getProperty('MESSAGE_ID').substring(9,45);
mc.setProperty("RABBIT_MESSAGE_ID", messageID);</script>
<property name="rabbitmq.attributes.custom.message.id"
expression="get-property('RABBIT_MESSAGE_ID')"
scope="axis2"/>
<xslt key="xslt-remove-namespace"/>
<clone continueParent="true">
<target sequence="writeToFile"/>
</clone>
<send>
<endpoint key="rabbit"/>
</send>
</sequence>
</target>
</iterate>
<respond/>
</inSequence>
</target>
<description/>
</proxy>
For a request like this:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:tfom="bur.cdmarf.ru/dss/services/tfoms">
<soapenv:Header/>
<soapenv:Body>
<tfom:get_inserted_amound_bed>
<tfom:clinicID>6048820</tfom:clinicID>
</tfom:get_inserted_amound_bed>
</soapenv:Body>
</soapenv:Envelope>
Yo can use this mediators to capture and log the clinic_id value:
<property name="CLINIC_ID" xmlns:tfom="bur.cdmarf.ru/dss/services/tfoms"
expression="//tfom:get_inserted_amound_bed/tfom:clinicID"
scope="default"
type="STRING"/>
<log level="custom">
<property name="CLINIC_ID_PROPERTY_VALUE" expression="get-property('CLINIC_ID')"/>
</log>
<log>
<property name="PAYLOAD" expression="$body"/>
</log>
In the payload factory mediator use the same expression to capture the clinic id value:
<args>
<arg evaluator="xml" expression="get-property('CLINIC_ID')"/>
</args>

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?
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.