How can I create a JSON payload with text containing XML in it? - json

I try to create an automatic JIRA problem reporting (in some FAULT sequences.
I make a JSON payload for JIRA APIs what works just fine for text.
I would like to however report to JIRA a SOAP request and response whereby I could investigate on the issue.
my question is how can I create a JSON payload with text containing XML in it?
I get this exception in WSO2 ESB
[2016-09-18 21:46:31,774] ERROR - NativeWorkerPool Uncaught exception
java.lang.Error: Error: could not match input
at org.apache.synapse.commons.staxon.core.json.stream.impl.JsonScanner.zzScanError(JsonScanner.java:530)
at org.apache.synapse.commons.staxon.core.json.stream.impl.JsonScanner.yylex(JsonScanner.java:941)
payload which I want to generate
<payloadFactory description="" media-type="json">
<format>
{
"fields": {
"project":
{
"key": "$1"
},
"summary": "$2",
"description": "$3",
"issuetype": { "name": "$4" }
}
}
</format>
<args>
<arg evaluator="xml" expression="$func:projectKey"/>
<arg evaluator="xml" expression="$func:summary"/>
<arg evaluator="xml" expression="$func:description"/>
<arg evaluator="xml" expression="$func:issueType"/>
</args>
</payloadFactory>
and I want to send some text containing XML into the parameter $func:description. When I sent only poor XML into the $func:description, the payload Factory transferred into into JSON what is not needed in this case, the the XML is supposed to be a text - the message
for the completeness to get the XML message I used
<property expression="$body" name="request"
scope="default" type="STRING"/>
call the end-point
<property expression="$body" name="response"
scope="default" type="STRING"/>
and I need to know bind "request" + "response" into $func:description

If the XML is well-formed you can simply set messageType property to application/json and do the conversion automatically. Refer this for more details.
Or else you can use the payload Factory mediator or Enrich mediator to custom build your Json.

create the payload with the XML structure you like.
use JS script mediator to modify one node as CDATA.
change the content type.
My proxy config, please do the change you need for your requirement:
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="XMLinsideJSON"
transports="http https"
startOnLoad="true">
<target>
<inSequence>
<property name="BOK" expression="//*[1]" type="OM" scope="default"/>
<enrich>
<source type="inline" clone="true">
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<fields xmlns="">
<summary xmlns=""/>
<project xmlns=""/>
<description xmlns=""/>
<issuetype xmlns="">
<name xmlns=""/>
</issuetype>
</fields>
</soapenv:Body>
</soapenv:Envelope>
</source>
<target type="envelope"/>
</enrich>
<script language="js">
importPackage(Packages.org.apache.axiom.om);
var elem= mc.getEnvelope().getBody().getFirstElement().getFirstElement();
var myText = elem.getOMFactory().createOMText(elem, mc.getProperty("BOK"), OMNode.CDATA_SECTION_NODE);
elem.addChild(myText)
</script>
<property name="messageType" scope="axis2" value="application/json"/>
<respond/>
</inSequence>
<outSequence>
<send/>
</outSequence>
</target>
</proxy>
My request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<payload>
<response>
<data>AAA</data>
</response>
</payload>
</soapenv:Body>
</soapenv:Envelope>
My response:
{"fields":{"summary":"<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"><soapenv:Body>\n <payload>\n <response>\n <data>AAA</data>\n </response>\n </payload>\n </soapenv:Body></soapenv:Envelope>","project":null,"description":null,"issuetype":{"name":null}}}

Related

Dynamically add new element to json payload in WSO2 EI by using enrich mediator

I need to enrich existing json payload with new elements which is dynamically passed to existing payload instead of static value. Can anyone please help me?
Existing payload:
{
"Type":"CAR",
"Identifier":"2db23c39-9d3f-4e61-b3c5-e8725a2f1b90",
"ListingType":"New",
"SaleStatus":"For Sale"
}
Expected :
{
"Type":"CAR",
"Identifier":"2db23c39-9d3f-4e61-b3c5-e8725a2f1b90",
"ListingType":"New",
"SaleStatus":"For Sale",
"messageId":"urn:uuid:ccdafb72-c4"
}
Here messageId is ESB generated MessageID automatically.
<!-- ************API Request set to incomingRequest property************ -->
<property description="incomingRequest" expression="json-eval($.)" name="incomingRequest"
scope="default" type="STRING"/>
<payloadFactory media-type="json">
<format>$1</format>
<args>
<arg evaluator="xml" expression="get-property('incomingRequest')"/>
</args>
</payloadFactory>
<enrich description="">
<source type="inline" clone="true">
<messageId xmlns="">evaluate(get-property('operation','messageId'))
</messageId>
</source>
<target action="child" xpath="//jsonObject" />
</enrich>
<enrich>
<source clone="true" xpath="//jsonObject" />
<target type="body" />
</enrich>
<log level="full"/>
**Getting Wrong output**
{
"Type":"CAR",
"Identifier":"2db23c39-9d3f-4e61-b3c5-e8725a2f1b90",
"ListingType":"New",
"SaleStatus":"For Sale",
"messageId": "evaluate(get-property('operation','messageId'))"
}
Note:
I have followed this
Inline content on the enrich mediator is not evaluated. (considered as string)
So, we can use the property mediator to evaluate the expression.
<property name="prop1" expression="get-property('operation','messageId')"/>
Then we can use the above property in enrich mediator.
<enrich description="">
<source type="property" property="prop1"></source>
<target action="child" xpath="//jsonObject" />
</enrich>
BTW, In latest product versions, the Enrich mediator has the native JSON support.
More details in Here
I had similar scenario where i wanted to append some elements to a received json response:
First i got the response received into a property:
property expression="json-eval($)" name="RESPONSE" scope="default"
type="STRING"
Then i created a payload and added the new properties:
<payloadFactory media-type="json">
<format>
{"details": $1,
"timestamp":"$2",
"value":"$3"}
</format>
<args>
<arg evaluator="xml"
expression="get-property('RESPONSE')" />
<arg evaluator="xml"
expression="get-property('REQUEST_TIMESTAMP')" />
<arg evaluator="xml"
expression="get-property('VALUE')" />
</args>
</payloadFactory>
Then I returned the response using loopback. Note that REQUEST_TIMESTAMP and VALUE are defined as properties.

WSO2 API Manager Tool: Unable to convert JSONtoSOAP and then SOAPtoJSON to communicate between mock backend and API

Following the guidelines from WSO2 Documentation at: https://docs.wso2.com/display/AM260/Convert+a+JSON+Message+to+SOAP+and+SOAP+to+JSON
The intended response was
I revised it a couple times but keep getting "400: bad request error"
my curl and the error
EDIT¹: After running tests I found out that the issue is just with the SOAPtoJSON conversion. When I POST without the OUT (SOAPtoJSON) sequence, I get the XML answer exactly as intended as shown here
Thats my JSONtoSOAP.xml:
<?xml version="1.0" encoding="UTF-8"?>
<sequence name="JSONtoSOAP" trace="disable" xmlns="http://ws.apache.org/ns/synapse">
<payloadFactory media-type="xml">
<format>
<soap12:Envelope xmlns:soap12="http://www.w3.org/2003/05/soap-envelope" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap12:Body>
<CheckPhoneNumber xmlns="http://ws.cdyne.com/PhoneVerify/query">
<PhoneNumber>$1</PhoneNumber>
<LicenseKey>$2</LicenseKey>
</CheckPhoneNumber>
</soap12:Body>
</soap12:Envelope>
</format>
<args>
<arg evaluator="xml" expression="//request/PhoneNumber" literal="true"/>
<arg evaluator="xml" expression="//request/LicenseKey" literal="true"/>
</args>
</payloadFactory>
<property name="messageType" scope="axis2" type="STRING" value="application/soap+xml"/>
</sequence>
Thats my SOAPtoJSON.xml:
<?xml version="1.0" encoding="UTF-8"?>
<sequence name="SOAPtoJSON" trace="disable" xmlns="http://ws.apache.org/ns/synapse">
<log level="custom" separator=",">
<property name="TRACE" value="Global Mediation Extension"/>
</log>
<payloadFactory media-type="xml">
<format>
<CheckPhoneNumber xmlns="http://ws.cdyne.com/PhoneVerify/query">
<PhoneNumber>$1</PhoneNumber>
<LicenseKey>$2</LicenseKey>
</CheckPhoneNumber>
</format>
<args>
<arg evaluator="xml" expression="//request/PhoneNumber"/>
<arg evaluator="xml" expression="//request/LicenseKey"/>
</args>
</payloadFactory>
<property name="messageType" scope="axis2" type="STRING" value="application/json"/>
</sequence>
I'm really new to the technology. And I just followed the steps from the documentation as mentioned. Maybe is was just a silly mistake (even though I revised it several times)
Maybe someone got the same problem and can help me out.
Thanks in advance.
Here is a new feature which generates a REST interface for your SOAP service. Try that. It supports SOAP-REST conversion automatically.
https://docs.wso2.com/display/AM260/Generate+REST+APIs+from+SOAP+Backends

Converting input XML to JSON format in WSO2 ESB

I want to convert the input XML to JSON format in WSO2 ESB.
I have tried using the property mediator but it is not working,
<property name="messageType" value="application/json" scope="axis2" type="STRING"></property>
<property name="Content-Type" value="application/json" scope="transport" type="STRING"></property>
Try this configuration:
<inSequence>
...
</inSequence>
<outSequence>
<property name="messageType" value="application/json" scope="axis2"></property>
<respond/>
</outSequence>
You just need to add formatter (which is define by messageType property) to format out going message.
<property name="messageType" value="application/json" scope="axis2" type="STRING"></property>
Content-Type property is used to build incoming message to the format of the SOAP, which is used inside the ESB. If incoming message is XML you can use the following builder. Adding this property is not compulsory, if the "Content-Type" is sent with the incoming message headers ESB automatically pic it and build the message.
<property name="Content-Type" value="application/xml" scope="transport" type="STRING"></property>
Also make sure you have enable the "application/json" message formatters inside the axis2.xml file. this can be found inside the repository/conf/axis2 folder.
Let's assume your xml input is,
<name>abc</name>
<id>123</id>
Then you need to convert it to Json format as,
{
"name" : "abc",
"id" : "123"
}
You can use PayloadFactory mediator to convert XML to JSON format
<payloadFactory media-type="json">
<format>
{
"name" : "$1",
"id" : "$2"
}
</format>
<args>
<arg evaluator="xml" expression="//name"/>
<arg evaluator="xml" expression="//id"/>
</args>
</payloadFactory>
Hope this helps!!

Iterate Mediator over json arrays

I'd like to iterate the results array of a json message
{
"results":[
{
"category":"mdl",
"subcategory":"ip",
"ip":"103.14.120.121",
"subtype":"IP-MDL",
"date":"1405074556",
"longitude":"75.3333",
"latitude":"19.8833",
"country":"India",
"city":"Aurangabad",
"organization":"Good Domain Registry Private Limited",
"isp":"Good Domain Registry Private Limited"
},
{
"category":"mdl",
"subcategory":"ip",
"ip":"108.162.198.96",
"subtype":"IP-MDL",
"date":"1405074556",
"longitude":"-122.3933",
"latitude":"37.7697",
"country":"United States",
"city":"San Francisco",
"organization":"CloudFlare",
"isp":"CloudFlare"
}
]
}
unfortunately iteration mediator doesn't seem to accept non xpath expression
anyone knows how to iterate over the previous message json results the same way i do it in xml ?
I'd like to use ESB json-native support but doesn't seem to be able to break down json messages as with XML (i've tried iterate mediator, json payload factory and script mediator without any success)
<iterate expression="json-eval(results)">
<target>
<sequence>
<property name="messageType" value="application/json" scope="axis2"/>
<payloadFactory media-type="json">
<format>
{
"event":{
"providerName":"$1",
"providerSource":"$2",
"providerClassification":"$3",
"providerVersion":"$4",
"body":{
"results":{$5}
}
}
}
</format>
<args>
<arg value="bdigital"/>
<arg evaluator="json" expression="$.results.category"/>
<arg evaluator="json" expression="$.results.subcategory"/>
<arg value="1.0"/>
<arg evaluator="json" expression="$.results"/>
</args>
</payloadFactory>
<call>
<endpoint>
<http method="post"
uri-template="http://BD-VM-PP-CIC01:8280/services/CICQueue"/>
</endpoint>
</call>
</sequence>
</target>
</iterate>
thanks in advance,
You could do the following?
<property name="messageType" value="application/xml" scope="axis2" type="STRING"></property>
<iterate xmlns:ns="http://org.apache.synapse/xsd" continueParent="true" expression="//jsonObject/results" id="MyIterator">
<target>
<sequence>
<property name="cat" expression="json-eval($.results.category)" type="STRING"></property>
etc.
There is a new version in WSO2 EI in which you can iterate over JSON using JSON Path. You can do something like below.
<iterate id="iterate-over-users" preservePayload="true" attachPath="json-eval($.results)" expression="json-eval($.results)">
<target>
<sequence>
<send>
<endpoint>
<http method="POST" uri-template="http://backend.com"/>
</endpoint>
</send>
</sequence>
</target>
</iterate>
Refer to the following blog for more info. https://medium.com/#arunans23/iterate-over-json-payload-with-wso2-enterprise-integrator-8ccb9cdd2c70

JSON format in WSO2 ESB PayloadFactory mediator

PayloadFactory mediator I’m using JSON format string. The Problem is, when I enable the following lines in /repository/conf/axis2/axis2.xml, POST request works fine, but GET request produce error message.
<!--messageFormatter contentType="application/json"
class="org.apache.axis2.json.JSONStreamFormatter"/-->
<!--messageBuilder contentType="application/json"
class="org.apache.axis2.json.JSONStreamBuilder"/-->
Here is the ESB template for paypal List all Payment Resources:
<template name="listPaymentResources" xmlns="http://ws.apache.org/ns/synapse">
<sequence class="sequence">
<payloadFactory media-type="json">
<format>
{}
</format>
</payloadFactory>
<property name="messageType" scope="axis2" value="application/json" />
<call>
<endpoint>
<http method="get" uri-template="{uri.var.paypalUrl}/v1/payments/payment"/>
</endpoint>
</call>
</sequence>
</template>
Proxy service:
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="listPaymentResources"
transports="https,http"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<property xmlns:ns="uri.var.payment"
name="ppurl"
expression="//ns:paypalurl/text()"/>
<PayPal.config>
<appUri>{$ctx:ppurl}</appUri>
</PayPal.config>
<PayPal.listPaymentResources/>
<respond/>
</inSequence>
<outSequence>
<log/>
<send/>
</outSequence>
</target>
<description/>
</proxy>
The Error log:
[2013-12-11 17:25:10,971] ERROR - TargetHandler Unexpected error: Cannot get a J
SON writer
java.lang.UnsupportedOperationException: Cannot get a JSON writer
at org.apache.axis2.json.JSONStreamFormatter.getJSONWriter(JSONStreamFor
matter.java:63)
at org.apache.axis2.json.AbstractJSONMessageFormatter.getTargetAddress(A
bstractJSONMessageFormatter.java:228)
at org.apache.synapse.transport.passthru.TargetRequest.start(TargetReque
st.java:152)
at org.apache.synapse.transport.passthru.TargetHandler.requestReady(Targ
etHandler.java:136)
at org.apache.http.impl.nio.DefaultNHttpClientConnection.produceOutput(D
efaultNHttpClientConnection.java:244)
at org.apache.synapse.transport.http.conn.LoggingNHttpClientConnection.p
roduceOutput(LoggingNHttpClientConnection.java:112)
at org.apache.synapse.transport.passthru.ClientIODispatch.onOutputReady(
ClientIODispatch.java:88)
at org.apache.synapse.transport.passthru.ClientIODispatch.onOutputReady(
ClientIODispatch.java:41)
at org.apache.http.impl.nio.reactor.AbstractIODispatch.outputReady(Abstr
actIODispatch.java:148)
I have done some testing on the subject on latest release of the WSO2 ESB and i could not able to reproduce this given issue.