TL;DR; Sequence receives an XML message and I need to build many SOAP Envelope according to the number of <product>
tags I received.
I have a sequence that receives this following XML (Message 1):
<?xml version="1.0" encoding="UTF-8"?>
<pricing>
<product>
<idFF>1</idFF>
<skuPartner>abc</skuPartner>
<original>123</original>
<new>123</new>
</product>
<product>
<idFF>2</idFF>
<skuPartner>aba</skuPartner>
<original>123</original>
<new>123</new>
</product>
<product>
<idFF>3</idFF>
<skuPartner>ae</skuPartner>
<original>123</original>
<new>123</new>
</product>
</pricing>
I would like to iterate in this message and for each <product>
node make a call to a SOAP Service using the following contract:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:tem="http://tempuri.org/">
<soap:Header/>
<soap:Body>
<tem:ProductPriceUpdate>
<!--Optional:-->
<tem:safeKey>?</tem:safeKey>
<tem:storeId>?</tem:storeId>
<tem:articleId>?</tem:articleId>
<!--Optional:-->
<tem:barcode>?</tem:barcode>
<!--Optional:-->
<tem:sku>?</tem:sku>
<tem:price>?</tem:price>
<tem:discount>?</tem:discount>
</tem:ProductPriceUpdate>
</soap:Body>
</soap:Envelope>
In this message above, I need to replace
<tem:articleId>?</tem:articleId>
<tem:sku>?</tem:sku>
<tem:price>?</tem:price>
with the values contained in the nodes from the XML message received
<idFF>1</idFF>
<skuPartner>abc</skuPartner>
<new>123</new>
So, facing the problem described I did (at least tried to):
<idFF> <skuPartner> <new>
I am pretty sure that I am little bit far from the solution. This is what I've tried.
<iterate expression="//produto" id="iterateXML" sequential="true xmlns:ns="http://org.apache.synapse/xsd">
<target>
<sequence>
<payloadFactory media-type="xml">
<format>
<ProductPriceUpdate>
<safeKey>nExd8CzMRDo=</safeKey>
<storeId>123</storeId>
<articleId>$1</articleId>
<barcode>1</barcode>
<sku>$2</sku>
<price>$3</price>
<discount>1</discount>
</ProductPriceUpdate>
</format>
<args>
<arg evaluator="xml" expression="//idFF"/>
<arg evaluator="xml" expression="//skuPartner"/>
<arg evaluator="xml" expression="//new"/>
</args>
</payloadFactory>
<callout action="ProductPriceUpdate"
initAxis2ClientOptions="false" serviceURL="http://url-url.url.info/pub/url.asmx">
<source xpath="*"/>
<target key="Result"/>
</callout>
</sequence>
</target>
</iterate>
This is the output from the console:
[2016-02-11 11:04:52,982] ERROR - SequenceMediator Expecting an implementation of SOAP Envelope as the parent. But received some other implementation
org.apache.axiom.soap.SOAPProcessingException: Expecting an implementation of SOAP Envelope as the parent. But received some other implementation
at org.apache.axiom.soap.impl.llom.SOAPHeaderImpl.checkParent(SOAPHeaderImpl.java:408)
at org.apache.axiom.soap.impl.llom.SOAPElement.setParent(SOAPElement.java:81)
at org.apache.axiom.om.impl.llom.OMElementImpl.addChild(OMElementImpl.java:296)
at org.apache.axiom.om.impl.llom.OMElementImpl.addChild(OMElementImpl.java:212)
at org.apache.axiom.soap.impl.llom.SOAPBodyImpl.addChild(SOAPBodyImpl.java:231)
at org.apache.synapse.mediators.builtin.CalloutMediator.mediate(CalloutMediator.java:161)
at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:81)
at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:48)
at org.apache.synapse.mediators.base.SequenceMediator.mediate(SequenceMediator.java:149)
at org.apache.synapse.mediators.eip.Target.mediate(Target.java:106)
at org.apache.synapse.mediators.eip.splitter.IterateMediator.mediate(IterateMediator.java:163)
at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:81)
at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:48)
at org.apache.synapse.mediators.base.SequenceMediator.mediate(SequenceMediator.java:149)
at org.apache.synapse.mediators.MediatorWorker.run(MediatorWorker.java:69)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
[2016-02-11 11:04:53,031] INFO - LogMediator To: , WSAction: urn:mediate, SOAPAction: urn:mediate, MessageID: urn:uuid:481ca0ce-8502-486a-b501-350bda23f263, Di
rection: request, MESSAGE = Executing default 'fault' sequence, ERROR_CODE = 0, ERROR_MESSAGE = Expecting an implementation of SOAP Envelope as the parent. But
received some other implementation, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body><pricing>
<product>
<idFF>1</idFF>
<skuPartner>abc</skuPartner>
<original>123</original>
<new>123</new>
</product>
<product>
<idFF>2</idFF>
<skuPartner>aba</skuPartner>
<original>123</original>
<new>123</new>
</product>
<product>
<idFF>3</idFF>
<skuPartner>ae</skuPartner>
<original>123</original>
<new>123</new>
</product>
</pricing></soapenv:Body></soapenv:Envelope>
What I am missing? Should I use another mediator like Enrich? I appreciate every tip, thank you. =)
EDIT:
As suggested by @Jean-Michel, I replaced the xpath expression in callout mediator and the error of SOAP implementation, gone. Although I am still not able to do the request. When I go to the Monitor -> SOAP trace of my WSO2 I see the following request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<text xmlns="http://ws.apache.org/commons/ns/payload">IDFF;SKUPARTNER;ORIGINAL;NEW
11035073;BOBSKU11035073;185.99;200
</text>
</soapenv:Body>
</soapenv:Envelope>
EDIT 2:
After some modification, I just realized that the message I am sending in the callout mediator is the same message inside a SOAP envelope that I receive in the begining of the sequence. As it follows (please do not consider the xpath error, it was intentional):
[2016-02-11 12:44:43,197] INFO - LogMediator To: , WSAction: urn:mediate, SOAPAction: urn:mediate, MessageID: urn:uuid:c3bda9c7-157e-46db-ae9f-f5b687d11848, Di
rection: request, MESSAGE = Executing default 'fault' sequence, ERROR_CODE = 0, ERROR_MESSAGE = The evaluation of the XPath expression : body did not result in
an OMElement, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><pricing>
<product>
<idFF>1</idFF>
<skuPartner>abc</skuPartner>
<original>123</original>
<new>123</new>
</product>
<product>
<idFF>2</idFF>
<skuPartner>aba</skuPartner>
<original>123</original>
<new>123</new>
</product>
<product>
<idFF>3</idFF>
<skuPartner>ae</skuPartner>
<original>123</original>
<new>123</new>
</product>
</pricing></soapenv:Body></soapenv:Envelope>
EDIT 3:
I changed the address of the callout to the http://localhost:1205 and this is the result using TCPMon. Seems that everything is alright.
I was able to solve the issue. Thank you @Jean-Michel for helping me through.
I did the following:
Here you can find my WSO2-Config.XML:
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://ws.apache.org/ns/synapse">
<registry provider="org.wso2.carbon.mediation.registry.WSO2Registry">
<parameter name="cachableDuration">15000</parameter>
</registry>
<taskManager provider="org.wso2.carbon.mediation.ntask.NTaskTaskManager"/>
<proxy name="smook_proxy" startOnLoad="true" trace="disable" transports="https http vfs">
<description/>
<target>
<inSequence>
<property name="FORCE_SC_ACCEPTED" scope="axis2"
type="STRING" value="true"/>
<property name="OUT_ONLY" scope="default" type="STRING" value="true"/>
<clone>
<target sequence="pricing"/>
</clone>
</inSequence>
</target>
<parameter name="transport.PollInterval">5</parameter>
<parameter name="transport.vfs.ActionAfterProcess">MOVE</parameter>
<parameter name="transport.vfs.MoveAfterProcess">file:///C:\Users\victor.viola\Desktop\out</parameter>
<parameter name="transport.vfs.FileURI">file:///C:\Users\victor.viola\Desktop\in</parameter>
<parameter name="transport.vfs.MoveAfterFailure">file:///C:\Users\victor.viola\Desktop\error</parameter>
<parameter name="transport.vfs.FileNamePattern">.*.csv</parameter>
<parameter name="transport.vfs.ContentType">text/plain</parameter>
<parameter name="transport.vfs.ActionAfterFailure">MOVE</parameter>
</proxy>
<proxy name="PS_PRICING" startOnLoad="true" trace="disable" transports="https http">
<description/>
<target>
<endpoint name="wsFF">
<address trace="disable" uri="ADRESSTOTHEBACKEND.asmx"/>
</endpoint>
<inSequence/>
<outSequence>
<send/>
</outSequence>
<faultSequence/>
</target>
</proxy>
<localEntry key="smooks-csv.xml" src="file:C:/wso2esb-4.9.0/repository/resources/smooks/smooks-csv.xml">
<description/>
</localEntry>
<endpoint name="PS_PRICING">
<address uri="http://localhost:8280/services/PS_PRICING"/>
</endpoint>
<sequence name="pricing" statistics="enable" trace="enable">
<smooks config-key="smooks-csv.xml">
<input type="text"/>
<output type="xml"/>
</smooks>
<iterate expression="//product" id="iterateXML"
sequential="true" xmlns:ns="http://org.apache.synapse/xsd">
<target>
<sequence>
<payloadFactory media-type="xml">
<format>
<ProductPriceUpdate>
<safeKey>******</safeKey>
<storeId>*****</storeId>
<articleId>$1</articleId>
<barcode/>
<sku>$2</sku>
<price>$3</price>
<discount>100</discount>
</ProductPriceUpdate>
</format>
<args>
<arg evaluator="xml" expression="//idFF"/>
<arg evaluator="xml" expression="//skuPartner"/>
<arg evaluator="xml" expression="//new"/>
</args>
</payloadFactory>
<property name="messageType" scope="axis2" value="text/xml"/>
<in>
<header name="Action" scope="default" value="http://tempuri.org/ProductPriceUpdate"/>
<send>
<endpoint key="PS_PRICING"/>
</send>
<drop/>
</in>
<out>
<send/>
</out>
</sequence>
</target>
</iterate>
</sequence>
</definitions>
Here is my smooks.xml
<?xml version="1.0" encoding="UTF-8"?><smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd" xmlns:csv="http://www.milyn.org/xsd/smooks/csv-1.2.xsd" xmlns:ftl="http://www.milyn.org/xsd/smooks/freemarker-1.1.xsd" xmlns:file="http://www.milyn.org/xsd/smooks/file-routing-1.1.xsd">
<params>
<param name="stream.filter.type">SAX</param>
<param name="default.serialization.on">true</param>
</params>
<csv:reader fields="idFF,skuPartner,original,new" separator=";" skipLines="1"/>
<ftl:freemarker applyOnElement="#document">
<ftl:template><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<pricing>
<#list .vars["csv-set"]["csv-record"] as csv_record>
<product>
<idFF>${.vars["csv_record"]["idFF"]}</idFF>
<skuPartner>${.vars["csv_record"]["skuPartner"]}</skuPartner>
<original>${.vars["csv_record"]["original"]}</original>
<new>${.vars["csv_record"]["new"]}</new>
</product>
</#list>
</pricing>]]></ftl:template>
</ftl:freemarker>
<resource-config selector="#document">
<resource>org.milyn.delivery.DomModelCreator</resource>
</resource-config>
</smooks-resource-list>
Another thing that was VERY important to solve the issue was enabling these two logs in log4j.properties (wso2home/repository/conf)
log4j.logger.org.apache.synapse.transport.http.headers=DEBUG
log4j.logger.org.apache.synapse.transport.http.wire=DEBUG