How to set property of XML Object payload's to arguments () to call Wso2 ds using CLOB
Below is my payload which calling WSO2 DS :
<property name="messageType" scope="axis2" value="application/xml"/>
<property expression="$body/*" name="acclist" scope="default" type="OM"/>
<payloadFactory media-type="xml">
<format>
<Body>
<p_cif>$1</p_cif>
<p_acclist>$2</p_acclist>
</Body>
</format>
<args>
<arg evaluator="xml" expression="$ctx:cif"/>
<arg evaluator="xml" expression="$ctx:acclist"/>
</args>
</payloadFactory>
Error message of WSO2 DS :
Default Namespace: http://ws.wso2.org/dataservice
Current Request Name: _post_getacclist
Current Params: {p_acclist=, p_cif=00021118}
Nested Exception:-
DS Fault Message: Error in 'createProcessedPreparedStatement'
DS Code: UNKNOWN_ERROR
Nested Exception:-
java.sql.SQLRecoverableException: IO Error: 0 char of CLOB data cannot be read
I think Input Clob parameter(p_acclist) is null or empty,
When i convert $ctx:acclist to JSON, it is set upin arguments, But XML is not working
I can pass whole $body// it prints properly too, But i need inside element of this XML.
Basically i'am calling Data service using Clob(XML object) from Proxy service
Your problem is twofold:
the p_acclist element does not contain any kind of value, but more
xml. This needs to be in a CDATA block
A CDATA block in your payload factory won't work like that because the config is also XML. So the CDATA block in your payloadfactory/proxy will be ignored.
You can solve this by building the message using xslt, within the XSLT you can add the CDATA block as follows:
<xsl:text disable-output-escaping="yes"><![CDATA[</xsl:text>
<xsl:copy-of select="*"/>
<xsl:text disable-output-escaping="yes">]]></xsl:text>
You could even pass on your property to the xslt like so:
<xslt key="xlsfilereference">
<property expression="$ctx:acclist" name="acclist">
</property>
</xslt>
And then use it in the xslt as follows:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="acclist"></xsl:param>
...
<Body>
<p_cif><xsl:value-of select="[path_to_cif_value]"/></p_cif>
<p_acclist>
<xsl:text disable-output-escaping="yes"><![CDATA[</xsl:text>
<xsl:value-of select="$acclist"/>
<xsl:text disable-output-escaping="yes">]]></xsl:text>
</p_acclist>
</Body>
...
</xsl:stylesheet>
You might have to use copy-of instead of value-of in the above example.
Since the content of the acclist is not a valid XML can you try to enclose the elements with the CDATA tags? Please note that we will not be able to use the CDATA tags directly with the payload factory mediator due to its limitations. You can follow the steps below in order to add the CDATA tags.
Create a registry resource with the following elements(conf:/test/format.xml).
<Body>
<p_cif>$1</p_cif>
<p_acclist><![CDATA[$2]]></p_acclist>
</Body>
Modify the payload factory mediator as follows.
<payloadFactory media-type="xml">
<format key="conf:/test/format.xml"/>
<args>
<arg evaluator="xml" expression="$ctx:cif"/>
<arg evaluator="xml" expression="$ctx:acclist"/>
</args>
</payloadFactory>
create a file called XMLInputFactory.properties inside <EI_HOME>
Add the following content into the file
javax.xml.stream.isCoalescing=false
Related
I need to create Soap Operation GetFile to respond with file content and additional tags using MTOM (reponse Content-Type multipart/related):
<Response>
<file>
<id>1</id>
<name>Filename.pdf</name>
<content>
<xop:Include href="cid:test" xmlns:xop="http://www.w3.org/2004/08/xop/include"/>
</content>
</file>
</Response>
I have proxy which calls external service to get file content and then I generate payload using PayloadFactory mediator ($body/* in this case is file binary content from external service, id and name are hardcoded for simplicity):
<payloadFactory media-type="xml">
<format>
<Response>
<file>
<id>$1</id>
<name>$2</name>
<content>$3</content>
</file>
</Response>
</format>
<args>
<arg value="1"/>
<arg value="fileName.pdf"/>
<arg evaluator="xml"
expression="$body/*"/>
</args>
</payloadFactory>
<property name="enableMTOM" scope="axis2" type="STRING" value="true"/>
<respond/>
In response I get:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<Response xmlns="http://ws.apache.org/ns/synapse">
<file>
<id>1</id>
<name>fileName.pdf</name>
<content>base64content</content>
</file>
</Response>
</soapenv:Body>
</soapenv:Envelope>
If I remove that payloadFactory then I get correct multipart/related response, so enableMTOM property works (but I need additional custom tags):
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns:binary xmlns:ns="http://ws.apache.org/commons/ns/payload">
<xop:Include href="cid:1" xmlns:xop="http://www.w3.org/2004/08/xop/include"/>
</ns:binary>
</soapenv:Body>
</soapenv:Envelope>
Is custom mediator with messageContext.addAttachment only solution in this case? And whats best practice in such case - save received file content locally on server and then use it as attachment?
If you are constructing the message payload using a Payload factory mediator, and expecting to send the response as "multipart/form-data", you need to set the message type of the response after the Payload factory mediator. You can use the following property to set the message type of the response.
<property name="messageType" value="multipart/form-data" scope="axis2"/>
Furthermore, when we manipulate the file content using the Payload factory mediator, the message context gets built inside the Payload factory mediator and returned as a base64 encoded value. In order to decode the content, you need to add the following property to your proxy configuration.
<property name="DECODE_MULTIPART_DATA" value="true" scope="axis2" action="set" type="BOOLEAN"/>
Please refer to the latest WSO2 documentation on MTOM and SwA Optimizations and Request/Response Correlation for more details on this.
In a content-aware mediation scenario (where the message gets built), you can use the following property to decode the multipart message that is being sent to the backend. Otherwise, the outgoing message will be in encoded form.
I am transforming xml message into csv using xslt mediator. Transforming is happening fine but in the output message
is getting added on its own. Output message shown below
<text xmlns="http://ws.apache.org/commons/ns/payload">E5cjHWs_9N5ZiSWuvMHg_7Bhlxka|admin#xyz.super|admin|Test_API/|3.0|time|time|time|time|time|time|time|time|2018-09-25 11:51|time|time|time
</text>
Can some one please let me know how to remove them from the output file. Though in the log file the message looks good but actual message do have this added.
Any help pls...
Finally it worked.
I had to put payloadFactory after xslt mapping to remove the xmlns
Below code I added
<property name="messageType" scope="axis2" type="STRING"
value="text/plain"/>
<payloadFactory media-type="text">
<format>$1</format>
<args>
<arg evaluator="xml" expression="$body//*"
xmlns:ns="http://org.apache.synapse/xsd"/>
</args>
</payloadFactory>
I'm integrating wso2dss 3.5 and wso2esb 4.9. In DSS, I created a DataService to get data from a database. Following the WSO2 Dashboard into DSS, I used the endpoint in my eclipse project (Developer Studio). The xml gerated by DSS is:
<elements xmlns="http://ws.wso2.org/dataservice">
<row>
<name>nome1</name>
<address>rua xalala das xalalas</address>
</row>
<row>
<name>nome2</name>
<address>ruas rms did sa</address>
</row>
<row>
<name>nome3</name>
<address>aldoas daso dasodsa</address>
</row>
</elements>
So, in my ESB project I have this gerated code:
<foreach expression="//elements/row">
<sequence>
<payloadFactory media-type="xml">
<format>
<p:Insert xmlns:p="http://ws.wso2.org/dataservice">
<xs:nome xmlns:xs="http://ws.wso2.org/dataservice">$1</xs:nome>
<xs:endereco xmlns:xs="http://ws.wso2.org/dataservice">$2</xs:endereco>
</p:Insert>
</format>
<args>
<arg evaluator="xml" expression="/row/name"/>
<arg evaluator="xml" expression="/row/address"/>
</args>
</payloadFactory>
<log>
<property name="xalela" value="xalxalxlalxal"/>
</log>
</sequence>
</foreach>
The problem is that it isn't loggin into foreach, in other words, it isn't accessing inside the foreach mediator. What's wrong?
xpath //elements/row return nothing because node "elements" belong to namespace http://ws.wso2.org/dataservice
try with //ds:element/ds:row and define ds as xmlns:ds="http://ws.wso2.org/dataservice"
Good day!
I only recently began to study the ESB bus. I need to convert the incoming SOAP message in the HTTP request with Content-Type: application/x-www-form-urlencoded.
I have created a Proxy Service, Custom Mediator 1 in Java, transformed message, how do I pass it to the endpoint and get the answer in Custom Mediator 2?
In the picture I have drawn an example of how to transform the message.
You don't need to write custom mediators, you can transform SOAP to rest calls, sample with a rest service waiting for 2 parameters like
param1=value1¶m2=value2
<!-- prepare data for org.apache.axis2.transport.http.XFormURLEncodedFormatter message formatter -->
<payloadFactory media-type="xml">
<format>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<root>
<param1>$1</param1>
<param2>$2</param2>
</root>
</soapenv:Body>
</soapenv:Envelope>
</format>
<args>
<arg evaluator="xml" expression="$body/node1/node11/text()"/>
<arg evaluator="xml" expression="$body/node1/node12/text()"/>
</args>
</payloadFactory>
<!-- set output format -->
<property name="messageType" value="application/x-www-form-urlencoded" scope="axis2" type="STRING"/>
<property name="DISABLE_CHUNKING" value="true" scope="axis2" type="STRING"/>
<!-- call the REST endpoint with synch call : response is received in this sequence -->
<call>
<endpoint key="conf:endpoints/MyServiceEndpoint.xml"/>
</call>
<!-- the response is here, transform it has needed -->
<xslt key="myxsl"/>
<!-- send this response to the client -->
<property name="messageType" value="application/soap+xml" scope="axis2" type="STRING"/>
<!-- or test/xml and in this case, don't forget to specify a SOAP Action, below, a sample to specify a blank soapAction : -->
<header name="Action" value=""""/>
<send/>
Sample endpoint conf (with this sample, you need to define a property uri.var.ServiceURL in your sequence) :
<endpoint>
<http method="POST" uri-template="{uri.var.ServiceURL}/Path/2011-10-01"/>
</endpoint>
But if you really need your custom mediators, just replace payloadFactory and xslt mediators with them
Thanks for the reply, I still have to write custom mediator, just a very complex transformation messages
I will give an example how should I transform the message
SOAP message in my Proxy Service, send in custrom mediator
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<AddPay xmlns="http://MyTestService">
<!--input dynamic data-->
<fields>
<Items>
<Data>
<Name>Field1</Name>
<Value>11</Value>
</Data>
<Data>
<Name>Field2</Name>
<Value>22</Value>
</Data>
</Items>
</fields>
</AddPay>
</soap:Body>
</soap:Envelope>
The result of the transformation of the mediator
0000035401SM000000970000009700000121
api99 00000990
00000000
BEGIN // <!--input dynamic data-->
FIELD1=11 // Soap data
FIELD2=22 // Soap data
END
BEGIN SIGNATURE
iQBRAwkBAAAD3j2r2NwBAeevAf4nvAG4rGAyAePHkyVKTt7wffzURhOckd3ctgmG
yQkKWkXh3CLpsbrExsllVUBlO6ih8qHozk2uttXApzHXQXoO
=+pch
END SIGNATURE
Request to the HTTP Server
POST /cgi-bin/es/es_pay_check.cgi HTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 498
inputmessage=0000035401SM000000970000009700000121%0D%0Aapi99+
+++++++++++00000990%0D%0A++++++++++++++++++++00000000%0ABEGIN%0D%
0FIELD1%11%0FIELD2%220AEND%0D%0ABEGIN+SIGNATURE%0AiQBRAwkBAABCiUs
00dQBATG5AgDHdZ6RYHykL46QBaAvnHYaY4p0pDjgjO4K1Iyj%0D%0AfSBSvCRpS%2
F0EYO9NspuyLeANEQQkkGE%2F37gUxiPqzAgStXjpsAHH%0D%0A%3DvSgb%0AEND+
SIGNATURE
The response from the HTTP Server, pass in custrom mediator to transform into SOAP
0000030301SM000000460000004600000121
0J0005 00064182
00000000
BEGIN
DATE=04.10.2014 12:34:12
ERROR=0
ERRMSG=
FIELD3=33
FIELD4=44
FIELD5=55
END
BEGIN SIGNATURE
iQBRAwkBAAD6tj1BJ10BAYKxAfsHlQsEFnO2k6ry++W8O8AiJuv4gT+ZVCfZHsKk
c0CbZpP/W3vkljG3xNzMLiqjbwkNuIdwR9Dq7gHmH+ZQMhbT
=LOnP
END SIGNATURE
The result in the Proxy service
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<AddPayResponse xmlns="http://MyTestService">
<AddPayResult xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Data>
<Items>
<!--output dynamic data-->
<Data>
<Name>Field3</Name>
<Value>33</Value>
</Data>
<Data>
<Name>Field4</Name>
<Value>44</Value>
</Data>
<Data>
<Name>Field5</Name>
<Value>55</Value>
</Data>
</Items>
</Data>
<ErrCode>0</ErrCode>
<ErrMsg>Ok</ErrMsg>
</AddPayResult>
</AddPayResponse>
</s:Body>
</s:Envelope>
I am new to the WSO2 and ActiveMQ, and I have been trying to achieve a seemingly simple message transformation, but without success.
I need to expose a web service on WSO2 which will take the value of only one particular input argument (out of three),
and forward that value as a plain text string on to the ActiveMQ queue. So, there is no backend service, no response to process,
only a simple one-way forwarding operation is required with value extraction and a transformation to plain text before posting to the queue.
I've been through the proxy samples and a lot of google-ing, yet, the most I have managed is to get that required value on the queue,
but as a POX, and that is not satisfactory.
Actually I have doubts whether WSO2 is capable of posting a plain text string at all,
and yet, there are articles where people swore that it can do almost anything imaginable, only they do not explain exactly how.
What I do is that I extract the required value "arg2" using the PayloadFactory mediator,
into an <xdr> element (because the PayloadFactory insists on either the XML or the JSON format, no plain text allowed).
Then I send that element to the queue. Question #1 is whether WSO2 can somehow convert that xml into plain text automatically?
Currently I think not.
So, before sending, I have tried many things to get that value out without any xml tags,
mostly using the Enrich mediator and even Javascript, but at one point or another, the thing would fail - either the WSO2 wouldn't let me define such mediation,
or it would simply not perform as expected/required, or fail at runtime.
The Enrich mediator is also not really clearly explained - what does "source" mean,
and what is the "target", with all those options - whatever options I chose, I've neever seen any change done to my message by the Enrich mediator.
What am I doing wrong, please? :)
Below is my current WSO2 proxy definition, which now contains pretty much everything I've compiled from the net so far,
but it still only posts the value format to the queue - so this is merely an illustration of what I've tried so far:
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="VomsXdrPlain"
transports="http"
statistics="disable"
trace="enable"
startOnLoad="true">
<target>
<inSequence>
<!-- first, the extraction -->
<payloadFactory media-type="xml">
<format>
<xdr xmlns="">$1</xdr>
</format>
<args>
<arg xmlns:xsd="http://api.service.com/"
evaluator="xml"
expression="//xsd:arg2"/>
</args>
</payloadFactory>
<!-- the following was added out of desperation -->
<property name="OUT_ONLY" value="true"/>
<property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
<property name="FORCE_POST_PUT_NOBODY"
value="true"
scope="axis2"
type="BOOLEAN"/>
<!-- here the idea was to put the value into a property, so it might be used in the Enrich mediator -->
<property name="xdrTicket"
expression="//xdr/text()"
scope="default"
type="STRING"/>
<!-- how to use the Enrich mediator properly for this purpose? -->
<enrich>
<source type="property" clone="true" property="xdrTicket"/>
<target type="body"/>
</enrich>
<!-- then I tried scripting... but the setPayLoadXML method also insists on tags so I've put "abc" -->
<script language="js">
var xmlPayload = mc.getPayloadXML();
var xdrTick = xmlPayload.substr(0,36);
mc.setPayloadXML(<abc>{xdrTick}</abc> );
</script>
<!-- this is posting to the queue and it works, but again, allowed formats are only POX, SOAP, REST, or AS-IS... but no PLAIN TEXT -->
<send>
<endpoint>
<address uri="jms:/VomsXdrService?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&java.naming.provider.url=tcp://localhost:61616&transport.jms.DestinationType=queue"
format="pox"/>
</endpoint>
</send>
</inSequence>
</target>
<parameter name="transport.jms.ContentType">
<rules xmlns="">
<jmsProperty>contentType</jmsProperty>
<default>text/plain; charset=ISO-8859-1</default>
</rules>
</parameter>
<parameter name="ContentType" value="text/plain"/>
<parameter name="transports">jms</parameter>
<description/>
</proxy>
The request is like the following:
<body>
<p:writeXDRRequest xmlns:p="http://api.service.com/">
<xsd:arg0 xmlns:xsd="http://api.service.com/">VOMS</xsd:arg0>
<xsd:arg1 xmlns:xsd="http://api.service.com/">SDR</xsd:arg1>
<xsd:arg2 xmlns:xsd="http://api.service.com/">1.0|321|2014-09-24T13:25:19.183+0000</xsd:arg2>
</p:writeXDRRequest>
</body>
On the queue, only the value of arg2 is expected, in plain text, without any tags:
1.0|321|2014-09-24T13:25:19.183+0000
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="VomsXdrPlain"
transports="http"
statistics="disable"
trace="enable"
startOnLoad="true">
<target>
<inSequence>
<payloadFactory media-type="xml">
<format>
<text xmlns="http://ws.apache.org/commons/ns/payload">$1</text>
</format>
<args>
<arg xmlns:xsd="http://api.service.com/"
evaluator="xml"
expression="//xsd:arg2"/>
</args>
</payloadFactory>
<property name="OUT_ONLY" value="true"/>
<property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
<property name="messageType" value="text/plain; charset=windows-1252" scope="axis2"/>
<!-- this is posting to the queue and it works, but again, allowed formats are only POX, SOAP, REST, or AS-IS... but no PLAIN TEXT -->
<send>
<endpoint>
<address uri="jms:/dynamicQueues/TestQueue?transport.jms.ConnectionFactory=myQueueConnectionFactory"/>
</endpoint>
</send>
</inSequence>
</target>
<description/>
</proxy>
see https://docs.wso2.com/display/ESB481/Converting+the+SOAP+Messages+to+Plain+Text+Mail