I would to publish a SOAP service as REST(json) API . The service operation I want to expose has a xml sequence element in the WSDL/XSD definition:
<xs:complexType name="hellolist">
<xs:sequence>
<xs:element name="name" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="hellolistResponse">
<xs:sequence>
<xs:element name="return" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
I don't know how to map a JSON array to a xml sequence using PayloadFactory. All the samples I found deal only with simple json and SOAP messages like this sample WSO2 transformation.
I would like to transform this json message:
{"hellolist":{"name":["Peter","Mary","Ann","James"]}}
To this soap message:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:dum="http://dummyservice2.com/">
<soapenv:Header/>
<soapenv:Body>
<dum:hellolist>
<name>Peter</name>
<name>Mary</name>
<name>Ann</name>
<name>James</name>
</dum:hellolist>
</soapenv:Body>
</soapenv:Envelope>
You can use payload factory mediator to do this. It can be used to transform or replace message content in between the client and the back-end server. In the case of your scenario you can configure a proxy service as below.
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="json_to_xml_factory"
transports="https,http"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<payloadFactory media-type="xml">
<format>
<dum:hellolist xmlns:dum="http://dummyservice2.com/">
<name xmlns="">$1</name>
<name xmlns="">$2</name>
<name xmlns="">$3</name>
<name xmlns="">$4</name>
</dum:hellolist>
</format>
<args>
<arg evaluator="json" expression="$.hellolist.name[0]"/>
<arg evaluator="json" expression="$.hellolist.name[1]"/>
<arg evaluator="json" expression="$.hellolist.name[2]"/>
<arg evaluator="json" expression="$.hellolist.name[3]"/>
</args>
</payloadFactory>
<log level="full"/>
</inSequence>
<outSequence/>
</target>
<description/>
</proxy>
Please refer below links for more information on this.
https://docs.wso2.com/display/ESB490/PayloadFactory+Mediator
http://christinetechtips.blogspot.com/2014/02/payload-factory-mediators-to-work-with.html
http://madhukaudantha.blogspot.com/2013/05/wso2-esb-payload-mediator-tutorial.html
If you have a non-static payload (your case), payload-factory-mediator will not be the solution (only for static payload). The best way for your kind of a problem is using xslt mediator + enrich mediator in WSO2 ESB. You can try out this example, https://docs.wso2.com/display/ESB481/Sample+440%3A+Converting+JSON+to+XML+Using+XSLT
Or you can use script mediator in case, as explained in this example.https://docs.wso2.com/display/ESB481/Sample+350%3A+Introduction+to+the+Script+Mediator+Using+JavaScript . Yet not the most preffered way.
I have done your kind of conversions using WSO2 ESB as I described above. But I don't know whether those mediator tools are also available with WSO2 APIM (I couldn't find any example when I googled for your problem).
Try the steps mention below
Steps to Convert a SOAP Test service in SoapUI with assertions into JSON service with assertions
Copy the project xml file of SOAP UI project
Open the copied xml file
Find the format for all assertion types in JSON that is equal in SOAP call assertion
Now convert all the soap assertions in the config node of the test step node to JSON assertion config node format as found in the previous step
Convert the SOAP call request into JSON call by changing all the fields as below
• Add the output_format node
• Add the Rest call – service name
• Remove the nodes without value and convert the others into JSON format like {“node name” : “value”} etc.,
In the test step node type attribute – it will be “request” change it to “httprequest”
Save the file and open it in SOAP UI
Now you can see all the services in the newly opened project will be in JSON format and all assertions will be available that were in SOAP call previously.
also refer the link which helps to convert the request completely including the assertions
please reply if it is not helpful
Related
I have REST API URL defined as
https://hostname/[version]/[service]/[operation]
and I would like to transform JSON payload in WSO2 API Manager in order to put version and operation inside.
So the WSO2 will send it to backend in the following form:
POST https://backend/[service]
{
“version”: [version],
“operation”: [operation]
}
So I need to put version and operation from URL to JSON payload. How to do it?
As I understand you want to create a new payload and POST with values from the resource URI definition (not API context).
Lets assume:
you don't want to change the method (the resource is having POST method).
the original request posted is JSON as well
You may want to create a (synapse) mediation flow as for ESB building such a message.
Plugging in the mediation is described in the documentation Adding Mediation Extensions. This mediation will be executed for every request of the API
Having resource https://hostname/[version]/[service]/[operation]
In the mediation, you may build the JSON payload
<payloadFactory media-type="json">
<format>{
"version":"$1",
"service": "$2",
"some_original_data": "$3"
}</format>
<args>
<arg expression="get-property('uri.var.version')"/>
<arg expression="get-property('uri.var.service')"/>
<arg expression="$.person.name" evaluator="json" />
</args>
</payloadFactory>
I'm using wso2 esb 4.8.1 version for SOAP to rest conversion with as API. I have a soap request with xsi values. After I generate the proper soap request with script mediator and um getting an expected response. But I have an issue with response. Because I need t convert the soap response into json. When I tried with following out sequence um not getting the proper json response with axis2. How can I convert this soap response into json properly?
This it the soap response.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns1:easyDownloadResponse xmlns:ns1="http://usermanage.ivas.huawei.com" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<easyDownloadReturn href="#id0"/>
</ns1:easyDownloadResponse>
<multiRef xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns2="http://response.usermanage.ivas.huawei.com" id="id0" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns2:EasyDownloadResp">
<eventClassName xsi:type="xsd:string" xsi:nil="true"/>
<failedResources xsi:type="soapenc:Array" xsi:nil="true"/>
<operationID xsi:type="xsd:long">0</operationID>
<resultCode xsi:type="xsd:int">0</resultCode>
<resultInfo xsi:type="xsd:string" xsi:nil="true"/>
<returnCode xsi:type="xsd:string">000000</returnCode>
<toneTransactionID xsi:type="soapenc:Array" xsi:nil="true"/>
<transactionID xsi:type="xsd:string" xsi:nil="true"/>
</multiRef>
</soapenv:Body>
</soapenv:Envelope>
This is the response which i'm getting
{"easyDownloadResponse":{"#encodingStyle":"http://schemas.xmlsoap.org/soap/encoding/","easyDownloadReturn":{"#href":"#id0"}}}
This is my out sequence
<outSequence xmlns="http://ws.apache.org/ns/synapse">
<property name="messageType" value="application/json" scope="axis2" type="STRING"></property>
<send></send>
</outSequence>
All your answers are highly welcome.
Finally I found the solution for the issue. In the normal case we use
<property name="messageType" value="application/json" scope="axis2" type="STRING"></property>
But this axis2 property cannot convert the complex soap response into json such as with xsi.
For that need to use the following axis2 property. Then it converts the entire soap response into Json as we expected.
<property name="messageType" value="application/json/badgerfish" scope="axis2" type="STRING"></property>
This is my full outsequence.
<outSequence xmlns="http://ws.apache.org/ns/synapse">
<property name="messageType" value="application/json/badgerfish" scope="axis2" type="STRING"></property>
<send></send>
</outSequence>
You can try payload mediator to get exact json format 1. But still you may have to uncomment the following lines in
$ESB_HOME/repository/conf/axis2/axis2.xml
<!--messageFormatter contentType="application/json"
class="org.apache.axis2.json.JSONStreamFormatter"/-->
<!--messageBuilder contentType="application/json"
class="org.apache.axis2.json.JSONStreamBuilder"/-->
By default, JSON messages are converted to XML when they are received by the PayloadFactor mediator. However, if you enable the JSON stream formatter and builder, incoming JSON messages are left in JSON format.
And also you can use script mediator again (In outsequence) to modify your json response. Refer this sample
There are numerous examples of using the mailto transport in WSO2 ESB to send emails (based on filter mediator, fault sequence etc.). However, I have attempted this a number of ways all with the same result i.e. that the proxy service never terminates. I am testing this using SOAPUi.
This is my proxy service
<proxy xmlns="http://ws.apache.org/ns/synapse" name="TMCService" transports="https,http" statistics="enable" trace="enable" startOnLoad="true">
<target inSequence="gov:/trunk/sequences/seqGetTMCData">
<outSequence>
<filter xmlns:trac="http://mynamespaceuri" xpath="//trac:SaveIncidentsResponse">
<then>
<log level="full"/>
<property name="Subject" value="CEP Event" scope="transport"/>
<property name="OUT_ONLY" value="true"/>
<send>
<endpoint>
<address uri="mailto:conrad.crampton#gmail.com"/>
</endpoint>
</send>
</then>
<else>
<send/>
</else>
</filter>
</outSequence>
</target>
<description></description>
</proxy>
the email sends no problem with the response from the inSequence - no problem, it just never terminates. I have to manually stop it in SOAPUi to stop.
I've tried putting drop after the send in the then element, that doesn't work either.
I guess I am missing something fundamental in how I am understanding the out sequence to work, but this is pretty much lifted from the many examples out there and no one else appears to be having the same issue as me.
Any suggestions/ pointers??
WSO2 ESB v4.5.1
I have resolved this by cloning the response message, sending one to the mailto transport and sending the other one as a default send (no endpoint) which returns back to the client.
Kind of makes sense as the OUT_ONLY property is explicitly saying there will be no response, so have ensure that the client receives one by cloning the message.
Still welcome any other comments if there is another way of doing this without clone mediator.
So why doesn't the examples show this!
I am trying to pass my JSON as a object to a WSO2 ESB.
I am getting JSON like this:
'{FIELDNAME":"NAME",FIELDVALUE:"KISHORE"}'
This JSON I need to pass my ESB as a dynamic column. But Its accepting like JSON {"NAME":"KISHORE"}. How can I convert from above JSON to below one in WSO2 ESB. If I get above one I am unable to pass to proxy. If I get below one I will pass like this (//name/child::text()) then I will get value as "KISHORE" I was tried with ENRICH mediator but its not working.
<proxy xmlns="http://ws.apache.org/ns/synapse" name="test_dynamic" transports="https,http" statistics="disable" trace="disable" startOnLoad="true">
<target>
<inSequence>
<enrich>
<source type="body" clone="true"/>
<target type="property" property="RM"/>
</enrich>
<property name="RM" expression="//fieldname/child::text()" scope="default" type="STRING"/>
<log level="custom">
<property name="r_no" expression="get-property('R_no')"/>
<property name="r_value" expression="get-property('R_value')"/>
<property name="emp_d" expression="get-property('emp')"/>
<property name="RM" expression="get-property('RM')"/>
</log>
<log level="full"/>
</inSequence>
</target>
<description></description>
</proxy>
ANS: request, Envelope:
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
<soapenv:Body><fieldname>e_no</fieldname><fieldvalue>5</fieldvalue></soapenv:Body>
</soapenv:Envelope>
I think you should send the JSON message like this:
'{"RECORD":{FIELDNAME":"NAME",FIELDVALUE:"KISHORE"}}'
then get the value by the "Property" mediator in WSO2 ESB, like
<property name="FIELDNAME" expression="//FIELDNAME/text()" scope="default" type="STRING"/>
<property name="FIELDVALUE" expression="//FIELDVALUE/text()" scope="default" type="STRING"/>
The link provided below by WSO2 explains the exact usecase which you are interested in solving
Steps:
Convert JSON to XML using the XSLT mediator
Use the Enrich mediator to replace the Body of the SOAP message
Follow this link for detailed info and actual proxy configuration
https://docs.wso2.com/display/ESB480/Sample+440%3A+Converting+JSON+to+XML+Using+XSLT
I'm transforming XML request to SOAP via XSLT in WSO2ESB, just wondering is it possible to make request parameter available to be used in response?
E.g.
<request>
<test>123</test>
<param1>testing</param1>
</request>
-> converted to SOAP
<?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">#S:Body><ns2:testrequest xmlns:ns2="http://xml.testing.com/test"><teststring>testing</teststring></ns2:testrequest></S:Body></S:Envelope></soapenv:Body></soapenv:Envelope>
In the response
<?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><ns2:testresponse xmlns:ns2="http://xml.testing.com/test"><responsestring>success</responsestring></ns2:testresponse></S:Body></S:Envelope></soapenv:Body></soapenv:Envelope>
I want to return in XML
<responsestring>
<test>123</test>
<return1>success</return1>
</responsestring>
As you see, 123 isn't send to the server and has not received from the server. However, client is sending this parameter and i would like to just use this parameter in request and send back in response, is this possible? By how? I'm very new to synapse and very new to WSO2ESB, could anyone please enlighten me?
Thanks.
Yes it is possible. You can use property mediator in the Insequence to set the required value as a property and then add it in the outsequence to response using enrich mediator.
Got it working now.
Simply by adding the property mediator in both insequence and outsequence together with the XSLT, where the xslt is trying to get the value from test property. That's it!
Insequence
<property xmlns:ns="http://org.apache.synapse/xsd" name="TEST" expression="//request/*[local-name()=test]" scope="default"/>
outsequence
<xslt key="xxxx.xslt">
<property name="test" expression="get-property('TEST')"/>
</xslt>