WSO2 PayloadFactory is sending json wrapped with jsonObject - api

I am using WSO2 API Manager 1.7.0 and am doing a simple payloadfactory attempting to convert a call from a GET to a POST passing in a json payload.
However when I look at the log files it appears that WSO2 is sending the json wrapped with {"jsonObject": [myjson] }
I am new to WSO2 and am not sure what cofiguration setting I need to use to stop this. I assume it is a config setting since in no examples or documentation that I have found does anyone else mention this.
My api looks like this:
"POST http://localhost:81/Service/ProcessRequest HTTP/1.1[\r][\n]"
"Authorization: Basic asdfadfadfadfadfadfadfa=[\r][\n]"
"Accept-Encoding: gzip,deflate[\r][\n]"
"Content-Type: application/json[\r][\n]"
"activityID: 2342342342342342342342342[\r][\n]"
"Transfer-Encoding: chunked[\r][\n]"
"Host: localhost:81[\r][\n]"
"Connection: Keep-Alive[\r][\n]"
"User-Agent: Synapse-PT-HttpComponents-NIO[\r][\n]"
"[\r][\n]"
I/O session http-outgoing-2-3 11.11.11.11:12345<->192.168.1.1:8080[ACTIVE][rw:w]: 0 bytes written
http-outgoing-2: Produce output
I/O session http-outgoing-2-3 11.11.11.11:12345<->192.168.1.1:8080[ACTIVE][rw:w]: 230 bytes written
"db[\r][\n]"
"{"jsonObject":{"UserType":"User"}}[\r][\n]"
"0[\r][\n]"
"[\r][\n]"
The log file part that seems to apply to the service call looks like this:
<api name="admin--JJJJJ" context="/jjjjj" version="v1.0" version-type="url">
<resource methods="GET" url-mapping="/documents">
<inSequence>
<payloadFactory media-type="json">
<format>{"UserType":"User"}</format>
<args/>
</payloadFactory>
<property name="Authorization" expression="fn:concat('Basic ', base64Encode('user:password'))" scope="transport"/>
<property name="HTTP_METHOD" value="POST" scope="axis2" type="STRING"/>
<property name="messageType" value="application/json" scope="axis2"/>
<property name="REST_URL_POSTFIX" scope="axis2" action="remove"/>
<log>
<property name="JSON-Payload" expression="json-eval($.)"/>
</log>
<send>
<endpoint name="admin--JJJJJ_APIproductionEndpoint_0">
<http trace="enable" method="post" uri-template="http://localhost:81/Service/ProcessRequest"></http>
</endpoint>
</send>
</inSequence>
<outSequence>
<send/>
</outSequence>
</resource>
<handlers>
...
</handlers>
</api>
I'm not sure where the db and 0 come from in the transmission but the error I get back from my service appears to be caused by the wrapping jsonObject.
Does anyone have any hints or ideas on how I can either prevent this wrapping or modify the payload just prior to sending it to remove it. Or I guess a better or even different way of transforming a GET request to a POST with a json payload.
Thank you for any hints on what I'm doing wrong.

change the messageformater in axi2.xml (/repository/conf/axis2/axis2.xml)file as
<messageFormatter contentType="application/json" class="org.apache.synapse.commons.json.JsonStreamFormatter"/>
and comment the default message formatter for json
<!--messageFormatter contentType="application/json" class="org.apache.axis2.json.JSONMessageFormatter"/-->
learn more on json support here[1]
https://docs.wso2.com/display/ESB480/JSON+Support

You can add an enrich mediator to api before send mediator to remove jsonObject wrapper from body like below.
<enrich>
<source clone="true" xpath="$body//jsonObject//UserType"/>
<target type="body"/>
</enrich>
You can add a log mediator after enrich mediator and check the changed body.
Hope this will help you.

Related

WSO2 Iterate and send messages to a message store

I'm on Enterprise Integrator 6.5.
My proxy receives a payload with a file's content and the metadata associated with it.
Said metadata may be sent into 1 or more pieces.
I need to respond to the frontend with the uploading success and then set the metadata asynchronously.
So I figured out this solution:
Upload the file to the backend
Iterate the metadata node from the payload sending messages to a message store
Respond to the frontend
The file uploads, the metada is set BUT I can't get the code after the Iterate mediator to execute (which is just setting a payload and going to outsequence).
I read on the documentation that "You need to always accompany an Iterate with an Aggregate mediator." but apparently that is meant to be when you use the Send mediator inside the Iterate.
My case doesn't seem to fit neither on the ForEach mediator, since documentation says "Use the ForEach mediator only for message transformations. If you need to make back-end calls from each iteration, then use the iterate mediator."
Also, the Iterate mediator works perfectly in my case, I find extremely useful attachPath and preservePayload atributes.
Can you please help me solve this?
Weird thing: I set a log inside the iterate mediator and I can't see it in the logs :/
This is my code:
[...]
<log level="full">
<property name="status" value="outside iterate mediator"/>
</log>
<iterate attachPath="//nm:upload" expression="//nm:upload/metadata"
preservePayload="true"
xmlns:nm="http://www.i.com/uploadFileSAPProxy/" xmlns:ns="http://org.apache.synapse/xsd">
<target>
<sequence>
<log level="full">
<property name="status" value="inside iterate mediator"/>
</log>
<payloadFactory media-type="xml">
<format>
<nm:upload
xmlns:b="http://ws.wso2.org/dataservice" xmlns:prx="urn:sap.com:proxy:Q01:/1SAI/TASF285B85AB4507D6C358B:702">
<id_group>$1</id_group>
<section>$2</section>
$3
</nm:upload>
</format>
<args>
<arg evaluator="xml" expression="$ctx:id_group" literal="false"/>
<arg evaluator="xml"
expression="//nm:upload/metadata/section" literal="false"/>
<arg evaluator="xml"
expression="//nm:upload/metadata/values" literal="false"/>
</args>
</payloadFactory>
<property name="messageType" scope="axis2" type="STRING" value="application/json"/>
<property expression="json-eval($.upload)" name="result"
scope="default" type="STRING"/>
<payloadFactory media-type="json">
<format>$1</format>
<args>
<arg evaluator="xml" expression="$ctx:result" literal="false"/>
</args>
</payloadFactory>
<axis2ns29:store
messageStore="uploadFileSAP_v1_putMetadata_ms" xmlns:axis2ns29="http://ws.apache.org/ns/synapse"/>
</sequence>
</target>
</iterate>[...]
Thanks in advance!
I forgot to set continueParent="true"

WSO2 API Manager 1.10 issue

We are running into an issue where a call to a WSO2 API REST endpoint fails with a "412 Precondition Failed" when the Content-Length exceeds 1068. Just adding a space to the request (increasing size to 1069) causes this failure. This issue can also happen when content length is less than 1069, if the API is called fast enough (using SOAPUI for testing). We have a theory that the header and body are split between packets and confuses the request. We tried turning off chunking and that didn't affect things. When the back end REST service is called directly it works fine.
You can turn off the chunking as below by using the property mediator if you are calling the SOAP endpoint. But you have to make sure that the SOAP endpoint is also expecting a non-chunked request.
<property name=”DISABLE_CHUNKING” value=”true” scope=”axis2″/>
But if you are using REST endpoint above property may not work sometimes. In that kind of situation, we need to make sure the Content-Length header is appended to the request. We can use below two properties to append the Content-Length header.
<property name="FORCE_HTTP_CONTENT_LENGTH" value="true" scope="axis2"></property>
<property name="COPY_CONTENT_LENGTH_FROM_INCOMING" value="true" scope="axis2"></property>
Sample proxy inSequence
<inSequence>
<log level="custom">
<property name="msg" value="Executing IN sequence"></property>
</log>
<property name="FORCE_HTTP_CONTENT_LENGTH" value="true" scope="axis2"></property>
<property name="COPY_CONTENT_LENGTH_FROM_INCOMING" value="true" scope="axis2"></property>
<send>
<endpoint>
<address uri="https://www.google.com" format="rest"></address>
</endpoint>
</send>
</inSequence>

About messageType and JIRA connector

I have two proxy services for testing purpose that connects with JIRA using JIRA Connector. First one, accepting "application/json" payload:
<proxy name="PruebaJIRA_01" startOnLoad="true" trace="disable" transports="https http">
<description/>
<target>
<inSequence>
<log level="full"/>
<jira.init>
<username>xxxxxx</username>
<password>xxxxxx</password>
<uri>http://gea-jira.its.ute.com/jiragea</uri>
</jira.init>
<property expression="json-eval($.consulta)" name="query"/>
<jira.searchJira>
<query>{$ctx:query}</query>
</jira.searchJira>
<log level="full"/>
<respond/>
</inSequence>
</target>
</proxy>
The second one, accepting "text/xml" payload:
<proxy name="PruebaJIRA_02" startOnLoad="true" trace="disable" transports="https http">
<description/>
<target>
<inSequence>
<property name="messageType" scope="axis2" value="application/json"/>
<log level="full"/>
<jira.init>
<username>xxxxxx</username>
<password>xxxxxx</password>
<uri>http://gea-jira.its.ute.com/jiragea</uri>
</jira.init>
<property expression="//root/consulta" name="query"/>
<jira.searchJira>
<query>{$ctx:query}</query>
</jira.searchJira>
<log level="full"/>
<respond/>
</inSequence>
</target>
</proxy>
It seems that JIRA connector only accept JSON incoming data, so in the second one I have a "messageType" conversion at the top of the sequence.
Both services run OK, but the question is: Why is the second proxy working if I am using an xpath expression?
I am using wso2 ESB 4.9.0.
Thanks in advance.
ESB receives disparate message formats from different clients and systems, because of this ESB required a canonical message format inside the ESB to do all the message mediation tasks. Because of this the message builder used to convert the incoming messages into a canonical format. The canonical format using inside the ESB is SOAP. So surely your XPATH expression works with the soap message.
MessageType property used to select correct message formatter and the message formatter is used to build the outgoing stream from the proxy.
More Info - demystifying-wso2-esb-pass-through-transport /
Working with Message Builders and Formatters

WSO2 ESB REST Post request empty response

I'm trying to call test Rest Api via Post request but ESB returns always empty response. For GET request response is sent correctly by ESB.
I have tried almost everything but still cannot make this work. My ultimate goal is to store message sent by client via Post request (large requests) and sent XML structured response to user that message is queued. Here's simple example what I have tried but for Post request empty response is sent by ESB.
<inSequence xmlns="http://ws.apache.org/ns/synapse">
<log>
<property name="text" value="IN Sequence"></property>
</log>
<header name="To" scope="default" action="remove"></header>
<property name="RESPONSE" value="true" scope="default" type="STRING"></property>
<payloadFactory media-type="xml">
<format>
<response xmlns="">Hello world</response>
</format>
</payloadFactory>
<send></send>
</inSequence>
Is this BUG In WSO2 ESB 4.0.8 or am I missing something ?
Thanks,
Kari
This is now resolved. Actually problem was that in Rest client I didn't specify Content-type. After adding Content-Type application/xml -header. The XML response worked fine for POST request. For GET Request this was working all the time.

Why do I get transport error in WSO2 ESB if I remove the filter?

I have the following proxy:
<proxy name="expedientes" transports="https http" startOnLoad="true" trace="enable" statistics="enable">
<target inSequence="main" outSequence="main" faultSequence="main">
<endpoint>
<address uri="https://someweb/somepath/"/>
<property name="Authorization" expression="fn:concat('Basic ', base64Encode('user:password'))" scope="transport"/>
</endpoint>
</target>
</proxy>
with the this default main sequence:
<sequence name="main">
<in>
<log level="full"/>
<filter source="get-property('To')" regex="http://localhost:9000.*">
<send/>
</filter>
</in>
<out>
<send/>
</out>
</sequence>
When I remove the filter and leave it as:
<sequence name="main">
<in>
<log level="full"/>
<send/>
</in>
<out>
<send/>
</out>
</sequence>
I get the following error "Unexpected error during sending message out: org.apache.axis2.AxisFault: The system cannot infer the transport information from the /services/expedientes/indice.xml":
TID: [] [WSO2 ESB] [2013-02-15 12:42:05,531] ERROR
{org.apache.synapse.core.axis2.Axis2Sender} - Unexpected error during sending message out
{org.apache.synapse.core.axis2.Axis2Sender}org.apache.axis2.AxisFault: The system cannot infer the transport information from the /services/expedientes/indice.xml URL. at
...
The out message should (obviously) use the same transport to answer the request (HTTP GET). But what has this to do with "filter"?
Basically in the segment of configuration above (the one with filter mediator) it checks the "TO" header property of your message weather it is equals to "http://localhost:9000.*" or not.
If that condition fired, it simply send your message to the destination. Else the message send inside the "out" mediator.
When you remove the expression what happened is, it trying to send the all messages which are coming inside "in" mediator without knowing weather there is a "To" property or not.
In your case the incoming messages aren't containing a valid "To" property.
The default mediator inside main sequence to send message out is the "out" mediator. The "in" mediator doesn't know the message is expected to send as a response otherwise you did not say it is a resonance message explicitly.You can do it by using configuration like this
<header action="remove" name="To"/>
<property action="set" name="RESPONSE" scope="default" type="STRING" value="true"/>
But It strongly depend on your usecase though
I suggest you to go through some references regarding message mediation with WSO2 ESB.
Following are good references which I found hope you can find more
Configuring the ESB to Perform Message Mediation
Message Mediation
Thanks,