wso2 Transform XML to Json inside sequence - json

I receive from an rabbitmq inbound an XML message and I have to send it to mongodb with restheart.
I must modify the content of the Json generate by the formatter before sending it to the mongo rest api, because I must modify a datetime format send in string to add "ISOdate ()" for mongodb.
My incomming message can be different from other messages.
For exemple, I have this from inbound :
<CONTENT><CODE_USER>100</CODE_USER><DATE>2017-12-12</DATE></CONTENT>
and I get this for the endpoint,
{"CONTENT" : {"CODE_USER":100","DATE":"2017-12-12"}}
So I want to modify the Json format before sending to the endpoint to modify the date string.
Is there a way to trigger the esb Json formatter and get the result before send it to the endpoint ?
Thanks,
Nicolas

I find an solution,
I use json-eval($.*.) function and an script mediator to modify the date format before sending to the endpoint, like this :
<property expression="json-eval($.*.)" name="location" scope="default" type="STRING"/>
<script language="js"><![CDATA[var message = new String(mc.getProperty('location'));
var reg = /\"((\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)\.(\d{1,3})Z)\"/g;
var mess=message.replace (reg,'{\"$date\" : \"\$1\"}');
mess=mess.substring (1,mess.length-1);
mc.setPayloadJSON(mess);]]></script>
<property name="ContentType" scope="axis2" type="STRING" value="application/json"/>

Yes that is possible. You can add a mediator to the in-sequence such that the transformation happens before releasing the response to mongo-db.
Please check the available mediators and if there is no any suitable one for your requirement, you can simply write your own mediator by extending org.apache.synapse.mediators.AbstractMediator
For the details on how to write a custom mediator, you can refer the blog: https://medium.com/#nirothipanram/esb-few-tips-in-writing-a-custom-class-mediator-b9a322f4eaa8

Related

filtering json fileds without conditions using wso2 esb

In WSO2 ESB,how to pass certain json fields as request?
And adding the remaining json fields with the response?
You need to use API's if you want to pass json as the request, you can frame json request and test via SOAP UI by selecting the media type as application/json.
ESB will accept this request and then by default converts it into an XML format, you can use xpath to perform different instructions and then if you want json as the output of your API you need to use the below syntax before exiting your API.<property name="messageType" scope="axis2" type="STRING" value="application/json; charset=utf-8"/>
<property name="ContentType" scope="axis2" type="STRING" value="application/json; charset=utf-8"/>

Spring integration Object transformer based on Object Type

Spring integration has transformer to convert the payload to JSON/XML.
The problem is due to different services communicating through same Messaging channel [AMQP].
I want to separate JSON type payload to one channel and XML type payload to another channel.
<amqp:inbound-channel-adapter channel="inputChannel" listener-container="messageListener"/>
<int:chain input-channel="inputChannel">
<int:object-to-json-transformer object-mapper="jsonMapper" />
<!--- based on payload type --->
<tranformer ref="xmlMarshalUnmarshal" method="doTransform" />
</int:chain>
Any idea? I am using latest Spring 4.1.x
You can achieve that with the Router.
I'm not sure that <int:payload-type-router> helps here, because I'm sure that your AMQP adapter is based on the default SimpleMessageConverter, which returns String for body like your JSON or XML.
From other side need to know how the other AMQP side works (Producer). Does it populate content-type header for those specific messages?
Having that we can use <header-value-router>:
<header-value-router input-channel="inputChannel" header-name="contentType">
<int:mapping value="text/json" channel="jsonTransformerChannel" />
<int:mapping value="text/xml" channel="xmlTransformerChannel" />
</header-value-router>
From other side you always can convert your body already with the <int-amqp:inbound-channel-adapter> injecting message-converter.

WSO2 ESB can not response json message

I have a service response is :
<Response>
<BackUrl>www.hao123.com</url>
<resultCode>0</resultCode>
</Response>
I set messageType:"application/json". The response is:
{Response:{"BackUrl":"coship.com","resultCode":"0";}}.
But I need transform this message to a json string like:
{"BackUrl":"http://www.coship.com","resultCode":"0"}
How ro remove node "Response". I tried to use script mc.setPayloadJSON in ESB 4.5.1. But errors happened.
https://wso2.org/jira/browse/ESBJAVA-1618?page=com.atlassian.jira.plugin.system.issuetabpanels%3Aall-tabpanel#issue-tabs
Anyone can help me? Thank you very much.
There is an issue reported as mentioned, and it is not resolved yet. But, you can set messgae type as
<property name="messageType" value="application/json" scope="axis2"/>
and check?
here is a post which may useful to you

stWSO2ESB OutSequence Processing

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>

Spring Restful, Post multiple formats like json/xml/domain object into same action

I am writing a Spring Restful webservices application using Spring MVC. I have used content negotiating viewer to respond multiple data formats for eg. If some one requests a URL with .xml extension an XML will be sent in response body similarly if someone requests with an .json extension, an json will be sent in response body.
Now, I want the same process inwards, say if some body wants to post a Json or xml or a simple post from a webpage form using post method to same action, it should be able to handle all these.
This way i will be able to write a Web Service+Web Application in a single Spring MVC+Restful Application.
Thanks in advance for the help :)
You can use headers attribute of #RequestMapping annotation.
#RequestMapping(value = "/pets", method = RequestMethod.POST, headers="content-type=text/*")
to narrow content-type of requests your method is going to serve.
edit:
If you want to sent different content type in request body, then the only thing you need to do is to define MessageConverter (I assume you already did that) and annotate your method parameter with
#RequestBody
Spring should deserialize the body of your request using the MessageConverter you defined.
So assuming you have something like:
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<util:list>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
</util:list>
</property>
</bean>
<bean id="contentNegotiatingViewResolver" class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="mediaTypes">
<util:map>
<entry key="json" value="application/json"/>
</util:map>
</property>
<property name="defaultViews">
<util:list>
<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"/>
</util:list>
</property>
</bean>
in your spring context.
Annotating your method like this:
#RequestMapping(method=PUT, value="/user/{user_id}")
public void putUser(#RequestBody User user, #PathVariable int user_id) {
...
}
should do the job.
You don't have to do anything. You register converts and they will in turn tell "spring" what Content-types they can handle. XStream registers application/xml and text/xml (perhaps more), jackson registers application/json and so on.
It's all available at http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-ann-responsebody
I also don't like the filename-standard, I prefer to leave that to the same converter. In that case it will look at the Accept-header. If you want json, set Accepts: application/json.