Reputation: 57
I have a requirement to invoke an external webservice(s) via the Middleware, with one of the tags in my payload containing embedded XML. Sample payload and sequence snippet below. I encounter the following issues.
Scenario 1 : (line 24) expression="get-property('PayloadXML')" - Upon issuing a send command, the webservice method is not recognized.
Scenario 2 : (line 24) expression="get-property('lPayload')" - Upon issuing a send command, the webservice method is successfully invoked. However, for the target system to successfully process the message, it would need to handle the CDATA element(wrapping).
When trying to invoke Scenario 2 via soapUI, the process is successful. From what I've researched (Passing CDATA in WSO2), soapUI seems to internally handle the CDATA element, before forwarding the message.
Now, I understand the way I'm setting scenario 2 is not ideal(more of a hack), but I'm unaware of any other ways to achieve this. I've read numerous blogs/posts and tried transforming(developing) the Payload via the XSLT mediator with no luck. I've also come across the following post http://www.yenlo.com/en/how-to-preserve-a-cdata-in-xml-that-is-circulating-in-a-wso2-enterprise-service-bus/ , but I can't seem to find the patch that is being referred to.
So my questions are as follows: 1. Are there any other ways/mechanisms for me to achieve my requirements? 2. Will the WSO2 ESB 4.9.0 release resolve the issues mentioned above?
Sample Payload :
<sample><test>MyData</test></sample>
Sequence Snippet :
<property xmlns:ns1="http://ws.wso2.org/dataservice"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
name="PayloadXML"
expression="$body/data-services-event/content/ns1:return/ns1:return/ns1:PayLoadXML"/>
<property xmlns:ns="http://org.apache.synapse/xsd"
name="lPayload"
expression="fn:concat(fn:concat('<![CDATA[',get-property('PayloadXML')), ']]>')"/>
<payloadFactory media-type="xml">
<format>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:log="http://mynamespace">
<soapenv:Header/>
<soapenv:Body>
<log:publishMessage>
<Payload xmlns="">$1</Payload>
</log:publishMessage>
</soapenv:Body>
</soapenv:Envelope>
</format>
<args>
<arg xmlns:ns2="http://org.apache.synapse/xsd"
xmlns:ns="http://org.apache.synapse/xsd"
evaluator="xml"
expression="get-property('lPayload')"/>
</args>
</payloadFactory>
Upvotes: 2
Views: 2035
Reputation: 81
If your basic requirement is to pass xml data within a tag, Here is an example for that.
Here I am using wso2 ESB 4.9.0. Basic thing is, you need to store the payload factory format in registry and use it in the payload factory configuration as bellow.
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="foo"
transports="https,http"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<property xmlns:ns="http://org.apache.synapse/xsd"
name="Request"
expression="$body/child::*[fn:position()=1]"
scope="default"
type="STRING"/>
<payloadFactory media-type="xml">
<format key="conf:/repository/esb/myPF"/>
<args>
<arg evaluator="xml" expression="$ctx:Request"/>
<arg value="1"/>
</args>
</payloadFactory>
<send>
<endpoint>
<address uri="http://127.0.0.1:9763/services/Hello"/>
</endpoint>
</send>
</inSequence>
<outSequence>
<send/>
</outSequence>
</target>
<description/>
Above is my proxy service. I am getting the first child from the request ESB gets from the client and use it as the input for the payload factory mediator.
Content of the registry resource looks like bellow.
<ns:testMethod xmlns:ns="http://example.com">
<xs:xmlBody xmlns:xs="http://example.com"><![CDATA[$1]]></xs:xmlBody>
<xs:sessionId xmlns:xs="http://example.com">$2</xs:sessionId>
</ns:testMethod>
You can test the scenario by enabling wirelogs for ESB[2].
Here I have hosted a simple axis2 service in WSO2 AS for testing. Here is the wirelog output.
[2016-02-24 19:02:24,696] DEBUG - wire << "POST /services/Hello HTTP/1.1[\r][\n]"
[2016-02-24 19:02:24,696] DEBUG - wire << "Content-Type: application/soap+xml; charset=UTF-8; action="urn:mediate"[\r][\n]"
[2016-02-24 19:02:24,696] DEBUG - wire << "Transfer-Encoding: chunked[\r][\n]"
[2016-02-24 19:02:24,696] DEBUG - wire << "Host: 127.0.0.1:9763[\r][\n]"
[2016-02-24 19:02:24,697] DEBUG - wire << "Connection: Keep-Alive[\r][\n]"
[2016-02-24 19:02:24,697] DEBUG - wire << "User-Agent: Synapse-PT-HttpComponents-NIO[\r][\n]"
[2016-02-24 19:02:24,697] DEBUG - wire << "[\r][\n]"
[2016-02-24 19:02:24,697] DEBUG - wire << "180[\r][\n]"
[2016-02-24 19:02:24,697] DEBUG - wire << "<?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"><soapenv:Body><ns:testMethod xmlns:ns="http://example.com"><xs:xmlBody xmlns:xs="http://example.com"><![CDATA[<sample><test>MyData</test></sample>]]></xs:xmlBody><xs:sessionId xmlns:xs="http://example.com">1</xs:sessionId></ns:testMethod></soapenv:Body></soapenv:Envelope>[\r][\n]"
[2016-02-24 19:02:24,697] DEBUG - wire << "0[\r][\n]"
[2016-02-24 19:02:24,697] DEBUG - wire << "[\r][\n]"
Here you can find the defined registry resource with content type as text/xml
registry resource
[2] https://docs.wso2.com/display/ESB490/Setting+Up+Logging
Upvotes: 1
Reputation: 5946
Here is a sample proxy service that receive XML data and send back a new XML message with a sub part of the input content in a CDATA section.
Send it :
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<PayloadXML>
<sample><test>MyData</test></sample>
</PayloadXML>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
You receive :
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<log:publishMessage xmlns:log="http://mynamespace">
<Payload><![CDATA[<sample><test>MyData</test></sample>]]></Payload>
</log:publishMessage>
</soapenv:Body>
</soapenv:Envelope>
The proxy def :
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="TestSOF" transports="http" statistics="disable" trace="disable" startOnLoad="true">
<target>
<inSequence>
<!-- extract xml content from the input message -->
<property name="xmlContent" expression="$body/PayloadXML/*[1]" type="OM"/>
<!-- compose a new message -->
<enrich>
<source type="inline" clone="true">
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<log:publishMessage xmlns:log="http://mynamespace">
<Payload xmlns=""/>
</log:publishMessage>
</soapenv:Body>
</soapenv:Envelope>
</source>
<target type="envelope"/>
</enrich>
<!-- create a CDATA section for 'Payload' node -->
<script language="js">
importPackage(Packages.org.apache.axiom.om);
var payloadElmt = mc.getEnvelope().getBody().getFirstElement().getFirstElement();
var omText = payloadElmt.getOMFactory().createOMText(payloadElmt, mc.getProperty("xmlContent"), OMNode.CDATA_SECTION_NODE);
payloadElmt.addChild(omText)
</script>
<!-- send back this new message as a response for the caller -->
<header name="To" action="remove"/>
<property name="RESPONSE" value="true"/>
<property name="NO_ENTITY_BODY" scope="axis2" action="remove"/>
<send/>
</inSequence>
</target>
<description/>
</proxy>
Upvotes: 2