WSO2 ESB array with single element json to json conversion brackets missing - json

I'm using wso2 esb 4.9 and created a proxy with payloadFactory element and call it with REST to start my BPMN process, but the problem is esb cannot convert single element json array , and esb drops json array's brackets. here is my proxy :
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="InformationIncome"
transports="https,http"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<log level="full"/>
<property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
<property name="OUT_ONLY" value="true"/>
<payloadFactory media-type="json">
<format>
{
"processDefinitionId":"myProcess:6:25188",
"variables": [
{
"name":"text",
"value":"$1"
}
]
}
</format>
<args>
<arg evaluator="json" expression="$.text"/>
</args>
</payloadFactory>
<header name="Authorization"
scope="transport"
expression="fn:concat('Basic ', base64Encode('admin:admin'))"/>
<log level="full"/>
<store messageStore="InformationIncomeMS"/>
</inSequence>
</target>
<description/>
</proxy>
And Here is the content of my request from soapUI :
{
"text" : "Hello"
}
And I found out my json becomes like this after payloadFactory:
{
"processDefinitionId":"myProcess:6:25188",
"variables": {
{
"name":"text",
"value":"Hello"
}
}
}
it seems esb json converter drops brackets of arrays with single element. Any ideas?

I tested above scenario with Postman, and it works properly. Please find steps as follows;
Add proxy and remove message store. (Because adding null message to message store giving following error)
[2016-07-11 13:46:53,291] 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)
at org.apache.synapse.commons.staxon.core.json.stream.impl.JsonScanner.nextSymbol(JsonScanner.java:310)
at org.apache.synapse.commons.staxon.core.json.stream.impl.JsonStreamSourceImpl.next(JsonStreamSourceImpl.java:149)
at org.apache.synapse.commons.staxon.core.json.stream.impl.JsonStreamSourceImpl.peek(JsonStreamSourceImpl.java:272)
at org.apache.synapse.commons.staxon.core.json.JsonXMLStreamReader.consume(JsonXMLStreamReader.java:129)
at org.apache.synapse.commons.staxon.core.json.JsonXMLStreamReader.consume(JsonXMLStreamReader.java:132)
at org.apache.synapse.commons.staxon.core.base.AbstractXMLStreamReader.hasNext(AbstractXMLStreamReader.java:446)
at org.apache.synapse.commons.staxon.core.base.AbstractXMLStreamReader.next(AbstractXMLStreamReader.java:456)
at javax.xml.stream.util.StreamReaderDelegate.next(StreamReaderDelegate.java:88)
at org.apache.axiom.om.impl.builder.StAXOMBuilder.parserNext(StAXOMBuilder.java:681)
at org.apache.axiom.om.impl.builder.StAXOMBuilder.next(StAXOMBuilder.java:214)
at org.apache.axiom.om.impl.llom.OMElementImpl.getNextOMSibling(OMElementImpl.java:336)
at org.apache.axiom.om.impl.OMNavigator._getFirstChild(OMNavigator.java:199)
at org.apache.axiom.om.impl.OMNavigator.updateNextNode(OMNavigator.java:140)
at org.apache.axiom.om.impl.OMNavigator.getNext(OMNavigator.java:112)
at org.apache.axiom.om.impl.SwitchingWrapper.updateNextNode(SwitchingWrapper.java:1113)
at org.apache.axiom.om.impl.SwitchingWrapper.(SwitchingWrapper.java:235)
at org.apache.axiom.om.impl.OMStAXWrapper.(OMStAXWrapper.java:74)
at org.apache.axiom.om.impl.llom.OMStAXWrapper.(OMStAXWrapper.java:52)
at org.apache.axiom.om.impl.llom.OMContainerHelper.getXMLStreamReader(OMContainerHelper.java:51)
at org.apache.axiom.om.impl.llom.OMElementImpl.getXMLStreamReader(OMElementImpl.java
Use Postman and invoke proxy service with "POST" command
Add json content in to body
Send it. ESB will print the message correctly with brackets.

As DilshaniS said :
Looks like this is a bug in WSO2 ESB 4.9.0 and reported an jira this link

Related

WSO2 Couldn't save JSON payload

I use WSO2 EI 6.6.0 and Micro Integrator 4.0.0. I have an api to get data, but for this I need to authenticate and get a token to use in a further request. for authentication I use separately created api and call it from first flow. For authentication I need to create a payload and send it in the request body to the server, but I get an error. The problem is repeated on different servers and I do not understand what is the reason.
My Auth API looks like this:
<api context="/auth" name="AuthGateway" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="GET" uri-template="/gateway">
<inSequence>
<payloadFactory media-type="json">
<format>{"username": "adm", "password": "admin"}</format>
<args/>
</payloadFactory>
<call>
<endpoint>
<http method="post" uri-template="https://1537-212-90-188-166.ngrok.io/auth/login">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>-1</progressionFactor>
<maximumDuration>0</maximumDuration>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
<log separator="
">
<property expression="json-eval($)" name="log_auth"/>
</log>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
My Data API looks like this:
<resource methods="GET" uri-template="/fieldCard?*">
<inSequence>
<propertyGroup>
<property name="uri.var.version" expression="$url:version" scope="default" type="STRING"/>
<property name="uri.var.size" expression="$url:size" scope="default" type="STRING"/>
<property name="uri.var.page" expression="$url:page" scope="default" type="STRING"/>
</propertyGroup>
<log level="full" separator="
">
<property name="version" expression="$ctx:uri.var.version"/>
<property name="size" expression="$ctx:uri.var.size"/>
<property name="page" expression="$ctx:uri.var.page"/>
</log>
<call>
<endpoint>
<http method="GET" uri-template="http://localhost:8290/auth/gateway"/>
</endpoint>
</call> .......
In the console I get messages:
[2022-05-02 19:16:12,962] ERROR {JsonStreamBuilder} - Error occurred while processing document for application/json java.lang.reflect.InvocationTargetException
Caused by: org.apache.axis2.AxisFault: #Can not parse stream. MessageID: urn:uuid:7ac6a4c9-0ed1-4973-87d4-69dad6d4a950. Error>>> #getNewJsonPayload. Could not save JSON payload. Invalid input stream found. Payload is not a JSON string.
org.apache.synapse.commons.json.JsonStreamBuilder.processDocument(JsonStreamBuilder.java:43)
... 21 more
Caused by: org.apache.axis2.AxisFault: #getNewJsonPayload. Could not save JSON payload. Invalid input stream found. Payload is not a JSON string.
[2022-05-02 19:16:12,963] ERROR {DeferredMessageBuilder} - Error building message org.apache.axis2.AxisFault
[2022-05-02 19:16:12,964] ERROR {RelayUtils} - Error while building Passthrough stream org.apache.axis2.AxisFault
[2022-05-02 19:16:12,964] ERROR {SequenceMediator} - {api:AuthGateway} Error while building message. Error while building Passthrough stream org.apache.axis2.AxisFault: Error while building Passthrough stream
I removed the detailed stack trace. If it is needed to understand the problem - I can add it.
P.S. When calling the auth API directly I get the token and the response is correct.
[2022-05-02 19:20:17,560] INFO {org.apache.synapse.mediators.builtin.LogMediator} - To: http://www.w3.org/2005/08/addressing/anonymous
WSAction:
SOAPAction:
MessageID: urn:uuid:817185a7-39a4-4418-a696-72473672997d
Direction: request
log_auth = {"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiMyIsInVzZXJfbmFtZSI6Im...
Payload: {"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiMyIsInVzZXJfbmFtZSI6Im...
Please help me understand the problem.
UPD: I reinstalled the server because I thought the error might be there or I broke the config files. created a new project and wrote a new same thread, but the error still repeats.
Good. The problem was that Postman has a Header Accept-Encoding option. When this parameter was disabled, the request became correct and the response began to come without errors!

WS02 can't parse json with colon in key

Using WSO2, I'm having problems parsing Json with a colon in one of the keys. The value also has commas
For example,
{
"foo:bar" : "a,b,c"
}
I have this json in a property. I'm using a payloadFactory like this:
<payloadFactory media-type="json">
<format>
{
"data" : $1
}
</format>
<args>
<arg evaluator="xml" expression="get-property('json')"/>
</args>
</payloadFactory>
I get error:
[2021-03-19 08:54:31,213] ERROR {org.apache.synapse.commons.json.JsonUtil} - #writeAsJson. Could not convert OMElement to JSON. Invalid XML payload. Error>>> Undeclared namespace prefix "foo"
at [row,col {unknown-source}]: [1,447]
[2021-03-19 08:54:31,216] ERROR {org.wso2.carbon.integrator.core.json.JsonStreamFormatter} - Error occurred while writing to application/json java.lang.reflect.InvocationTargetException
If I try to put the value in quotes (which is not really the result I want)
<payloadFactory media-type="json">
<format>
{
"data" : "$1"
}
</format>
<args>
<arg evaluator="xml" expression="get-property('json')"/>
</args>
</payloadFactory>
This time I get the error
[2021-03-19 09:06:09,045] ERROR {org.apache.axiom.om.impl.llom.OMSourcedElementImpl} - Could not get parser from data source for element jsonObject javax.xml.stream.XMLStreamException: java.io.IOException: Illegal character: <f>
at org.apache.synapse.commons.staxon.core.base.AbstractXMLStreamReader.initialize(AbstractXMLStreamReader.java:245)
Tried specifying evaluator="json". When using "data" : $1 (without double-quotes), I get this weird error:
[2021-03-19 09:40:52,525] ERROR {org.apache.synapse.mediators.base.SequenceMediator} - javax.xml.stream.XMLStreamException: ParseError at [row,col]:[8,23]
Message: Unexpected symbol: COMMA org.apache.axiom.om.OMException: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[8,23]
Message: Unexpected symbol: COMMA
at org.apache.axiom.om.impl.builder.StAXOMBuilder.next(StAXOMBuilder.java:296)
which I assume is complaining about the commas in the Json value
Is there any way to do this?
Update: I cannot reproduce this using this test sequence
<?xml version="1.0" encoding="UTF-8"?>
<api context="/testMeta" name="TestMeta" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="PUT">
<inSequence>
<property expression="json-eval($)" name="test" scope="default" type="STRING"/>
<payloadFactory media-type="json">
<format>
{
"data" : $1
}
</format>
<args>
<arg evaluator="xml" expression="get-property('test')"/>
</args>
</payloadFactory>
<property description="JSONIFY" name="messageType" scope="axis2" type="STRING" value="application/json"/>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
However, in my actual code, I faked out the JSON and tried various values.
{
"foo:bar" : "a,b,c"
}
worked, but one of the actual values,
{
"pdf:unmappedUnicodeCharsPerPage":"[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]"
}
does not. I don't know exactly what triggers it. Also tried
{
"foo:unmappedUnicodeCharsPerPage":"[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]"
}
to ensure there was nothing special about the string pdf
The way I'm faking it out is just hard-coding the value:
<payloadFactory description="BuildFinalPayload" media-type="json">
<format>
{
"metadata" : {"foo:unmappedUnicodeCharsPerPage":"[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]"
}
</format>
<args/>
</payloadFactory>
So it doesn't seem to have anything to do with how the value is being loaded into the property
UPDATE #2
So I realized that the error is happening right at the end of the sequence, when it's about to exit. My whole sequence looks something like this
<iterate>
<payloadFactory/>
<aggregate/>
</iterate>
failure occurs here
<respond/>
I can log json-eval($) after the payloadFactory and it looks fine
I've got the statement
<property name="messageType" scope="axis2" type="STRING" value="application/json" />
at the end, but even if I comment that out, I get the error
I tried to replicate your issue but with the following code but found no errors, I reckon something is off with either your messageType[1] before you put the data into the property or the property is set to be "OM" which will turn it into an XML object. But as this isn't included in your example I can't be sure.
<property expression="json-eval($)" name="test"/>
<payloadFactory media-type="json">
<format>
{
"data" : $1
}
</format>
<args>
<arg evaluator="xml" expression="get-property('test')"/>
</args>
</payloadFactory>
As input I used:
{
"foo:bar" : "a,b,c"
}
[1]https://docs.wso2.com/display/EI611/Generic+Properties#GenericProperties-messageType
[2]https://docs.wso2.com/display/EI610/Property+Mediator (Part about TYPE = OM)

WSO2 PayloadFactory mediator

I am facing issue while converting xml to json by using payloadfactory mediator.
the xml structure is containing
<base>tyuä</base>
and it should be transformed into
"base":"tyuä"
here is the snippet of my code :::
<payloadFactory media-type="json">
<format>
{
"base": ""
}
</format>
<args>
<arg evaluator="xml" expression="//base/text()"/>
</args>
</payloadFactory>
But it is giving me as "base":"tyuä".
What should be done to resolve it??
Try adding messageType (with charset=UTF-8) like this, after the payload factory mediator.
<property name="messageType" value="application/json;charset=UTF-8" scope="axis2"/>

xml to json conversion in wso2

When I am trying to convert XML to Json using XSLT mediator in wso2 I am getting "Payload could not be written as JSON." error. Can anyone help to me resolve this.
Thanks in advance
Why you do not use payload factory? this is a best way for converting xml to Json.
for example:
<payloadFactory media-type="json">
<format>{ "error": "0", "message": "$1", "data": $2 }</format>
<args>
<arg evaluator="json" expression="$.USER.description"/>
<arg evaluator="json" expression="$.USER"/>
</args>
</payloadFactory>
<property name="ContentType" value="application/json" scope="axis2"/>
Or use this property for send message:
<property name="messageType" value="application/json" scope="axis2"/>
The media-type attribute specifies whether to format the message in XML or JSON.
In this example i use JSON to convert this xml:
<USER>
<description>some Notes</description>
<others></others>
</USER>
and the ESB result:
{
"error" : "0",
"message" : "Some notes",
"data" : {
"description" : "Some notes",
"others" : ""
}
}
for more information about payload factory please see this link:
https://docs.wso2.com/display/ESB490/PayloadFactory+Mediator
Update:
you must use switch case or filter mediator.
for example this is a switch case sample. you must complete regex:
<switch source="//body">
<case regex="">
<payloadFactory media-type="json">
</payloadFactory>
</case>
</switch>
or you can use filter. In this example, the Filter match your given regular expression or XPath. If this evaluation returns true, it will send the true json. If the evaluation returns false, it will return empty json.
<filter (source="[XPath|json-eval(JSONPath)]" regex="string") | xpath="[XPath|json-eval(JSONPath)]">
<then>
<payloadFactory media-type="json">
<format>{josn:"body"}</format>
<args>your args<args/>
</payloadFactory>
</then>
<else>
<payloadFactory media-type="json">
<format>{}</format>
<args/>
</payloadFactory>
</else>
</filter>
This link should help you:
https://docs.wso2.com/display/ESB490/Filter+Mediator
If you are trying to convert a soap service to rest, you can do it by specifying message type as (in a rest api):
<property name="messageType" value="application/json" scope="axis2"/>

How to config WSO2 API to access rails REST json web service

I have a rails app exposed an rest json interface like: http://foo.com/agency/:name.json
I have written a wso2 esb api config to access the api
<api name="agency" context="/agency">
<resource methods="GET" uri-template="/view/{name}">
<inSequence>
<property name="REST_URL_POSTFIX"
expression="fn:concat('/',get-property('uri.var.name'), '.json')"
scope="axis2"/>
<send>
<endpoint>
<address uri="http://foo.com/agency/" format="pox"/>
</endpoint>
</send>
</inSequence>
<outSequence>
<send/>
</outSequence>
</resource>
</api>
when I tested the wso2 esb api using curl, I get
\dev\curl-w32>curl http://192.168.181.132:8280/agency/view/blah-blah
curl: (52) Empty reply from server
And the ESB log write
[2013-11-14 16:17:49,047] INFO - LogMediator To: /agency/view/blah-blah, MessageID: urn:uuid:d0a4c4ec-7600-430d-bb52-e580b
6ec2516, Direction: request, MESSAGE = Executing default 'fault' sequence, ERROR
_CODE = 101500, ERROR_MESSAGE = Error in Sender, Envelope: <?xml version='1.0' e
ncoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap
-envelope"><soapenv:Body/></soapenv:Envelope>
[2013-11-14 16:18:49,063] WARN - SourceHandler Connection time out after reques
t is read: http-incoming-48
seems endpoint url translate is not work.
How to correct my API config to make it work? Thx
Try changing the scope="axis2" to scope="transport" and removing format="pox" from the address endpoint.