WSO2 ESB: transform XML to JSON and send to endpoint - wso2

I am unable to transform an incoming SOAP Payload into JSON and send that to an Endpoint.
Did somebody ever did that?
If so, could you please share how you did?
Thank you in advance.

You can use XSLT transformation to achieve the task. Here is a sample which will guide you.

Use the payloadFactory Mediator.
https://docs.wso2.com/display/ESB481/PayloadFactory+Mediator
You have to add the below line to convert the XML payload to JSON
<property name="messageType" value="application/json" scope="axis2" />
Some sample below.
<payloadFactory media-type="json">
<format>
{
"userIdentifier": {
"id": "$1"
}
}
</format>
<args>
<arg expression="get-property('uri.var.id')"></arg>
</args>
</payloadFactory>
<property name="messageType" value="application/json" scope="axis2" />

Related

WSO2 EI 6.6.0 Class Mediator not being able to use SOAP call return content

I have the following API in EI 6.6.0:
<?xml version='1.0' encoding='UTF-8'?>
<api xmlns="http://ws.apache.org/ns/synapse" name="sample" context="/sample">
<resource methods="POST">
<inSequence>
<payloadFactory media-type="xml">
<format>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<P xmlns="http://tempuri.org/">
<P1>$1</P1>
<P2>$2</P2>
<P3>$3</P3>
</P>
</soap:Body>
</soap:Envelope>
</format>
<args>
<arg evaluator="json" expression="$.p1" />
<arg evaluator="json" expression="$.p2" />
<arg evaluator="json" expression="$.p3" />
</args>
</payloadFactory>
<log level="full" />
<property name="Content-Type" value="text/xml;charset=UTF-8" scope="axis2"/>
<header name="Accept" scope="transport" value="text/xml"/>
<call>
<endpoint>
<wsdl Action="name_of_the_action" service="name_of_the_service" port="name_of_soap_port" uri="http://<ip>/path?WSDL" />
</endpoint>
</call>
<class name="my_mediator_package"></class>
<log level="full" />
<payloadFactory media-type="xml">
<format>
<retorno xmlns="">
<msg>$1</msg>
</retorno>
</format>
<args>
<arg evaluator="xml" expression="get-property('property_set_on_mediator')" />
</args>
</payloadFactory>
<property name="messageType" value="application/xml" scope="axis2" type="STRING" />
<respond />
</inSequence>
<outSequence>
</outSequence>
<faultSequence>
<property name="text" value="An unexpected error occured"/>
<property name="message" expression="get-property('ERROR_MESSAGE')"/>
<payloadFactory media-type="xml">
<format>
<error xmlns="">
<msg>$1</msg>
</error>
</format>
<args>
<arg evaluator="xml" expression="get-property('ERROR_MESSAGE')"/>
</args>
</payloadFactory>
<property name="messageType" value="application/json" scope="axis2" type="STRING"/>
<respond/>
</faultSequence>
</resource>
</api>
my mediate method content:
public boolean mediate(MessageContext synCtx) {
org.apache.axis2.context.MessageContext axis2MessageContext = ((Axis2MessageContext) synCtx)
.getAxis2MessageContext();
try {
// Getting the json payload to string
String jsonPayloadToString = JsonUtil.jsonPayloadToString(((Axis2MessageContext) synCtx)
.getAxis2MessageContext());
System.out.println("original payload : \n" + jsonPayloadToString + "\n");
I'm not being able to use the return from my SOAP call in my mediator so I can work on it.
When I run the API I get the following from my mediator code:
original payload:
{}
Is there a way so I can obtain the SOAP call returned envelope and use it in my mediator?
The JSON payload is coming as empty because you are calling a SOAP backend and getting a SOAP payload. You can use synCtx.getEnvelope() in your mediator to get the SOAPEnvelope from the response.
1- make sure the json payload is there. So, log the json properties inside your inSequence.
2- I'm not being able to use the return from my SOAP call in my mediator so I can work on it. you can see the response payload in your outSequence which currently is doing nothing.
3- According to your scenario which is simply calling a SOAP webservice, you do not need a class mediator. In other words, when you do not need manipulating the initial payload and then pass it to the destination service, logically implementing your own class mediator benefits you nothing.
Also, there are quite number of samples in https://docs.wso2.com/display/EI611 which will help you.
Please let me know if your problem is solved.

WSO2 EI For loop through Json array

I have a below request (i am using WSO2 Enterprise integrator 6.5.0):
And I wanna get this in jsonpayload which is returned client
<ERROR_RESP>
<ERROR>
<ECODE>ST-VALS-002</ECODE>
<EDESC>Record Not Found for Branch Code-CHO:Currency 1-USD:Currency 2-MN</EDESC>
</ERROR>
<ERROR>
<ECODE>ST-SAVE-024</ECODE>
<EDESC>Failed to Query Data</EDESC>
</ERROR>
</ERROR_RESP>
It is my tried code to achieve it :
<foreach expression="json-eval($.ERROR_RESP.ERROR)">
<sequence>
<payloadFactory media-type="json">
<format>
{
"ErrorCode" : "$1",
"ErrorMessage" : "$2"
}
</format>
<args>
<arg evaluator="json" expression="$.ECODE"/>
<arg evaluator="json" expression="$.EDESC"/>
</args>
</payloadFactory>
<log level="full">
<property name="MESSAGE" value="ENDLOOP"/>
</log>
<loopback/>
</sequence>
</foreach>
enter code here
I did some search but nothings worked, I think foreach expression is not right.
Thanks
Regards,
In your sample the Loopback mediator is used. It will be used to move the message to the out flow (response path). Therefore, the Foreach mediator splits the message and sends the first message to the response path and end the flow.
You can prepare the XML payload and convert it to JSON using the messageType property with axis2 scope as follows.
<foreach expression="//ERROR">
<sequence>
<payloadFactory media-type="xml">
<format>
<ERROR xmlns="">
<ErrorCode>$1</ErrorCode>
<ErrorMessage>$2</ErrorMessage>
</ERROR>
</format>
<args>
<arg evaluator="xml" expression="//ECODE/text()"/>
<arg evaluator="xml" expression="//EDESC/text()"/>
</args>
</payloadFactory>
</sequence>
</foreach>
<property name="messageType" scope="axis2" value="application/json"/>
The final message will be like this:
{
"ERROR_RESP": {
"ERROR": [
{
"ErrorCode": "ST-VALS-002",
"ErrorMessage": "Record Not Found for Branch Code-CHO:Currency 1-USD:Currency 2-MN"
},
{
"ErrorCode": "ST-SAVE-024",
"ErrorMessage": "Failed to Query Data"
}
]
}
}
At the moment, foreach mediator in EI 6.5.0 does not support "json-eval()" expressions. This feature will be included in the upcoming versions.
As a workaround, you can use XPath inside the expression. You can use this blog as an example. https://medium.com/#Manuri/wso2-esb-foreach-mediator-example-87f041e2a912

How to make an additional http call inside api and process response?

I'm trying to create Message Mediation Policies, with which I can make an additional http call, process the response and enrich the current message. How can i do this? I use call Mediator, but I don’t understand how to handle the response.
<?xml version="1.0" encoding="UTF-8"?> <sequence name="call_out_handler" trace="disable" xmlns="http://ws.apache.org/ns/synapse">
<call blocking="true">
<endpoint>
<http method="get" uri-template="http://192.168.99.100:8888/stubFORAPIMan/ServletWithTimeout"/>
</endpoint>
</call> </sequence>
You can use the PayloadFactory Mediator [1] to handle/format the response you received by calling an endpoint inside the Call mediator.
An example would be like this. Say you want to provide a json object by populating the values from the response you received; you can define the json object format in the "format" section and populate the values by providing the arguments in the "args" section in the PayloadFactory mediator as below.
<payloadFactory media-type="json">
<format>
{
"Data": {
"PaymentSubmissionId": "$1",
"PaymentId": "$2",
"Status": "$3",
"CreationDateTime": "$4"
}
}
</format>
<args>
<arg evaluator="xml" expression="$body//PaymentSubId"/>
<arg evaluator="xml" expression="$body//PaymentId"/>
<arg evaluator="xml" value="AcceptedSettlementInProcess"/>
<arg value="2019-06-05T15:15:22+00:00"/>
</args>
</payloadFactory>
<property name="messageType" value="application/json" scope="axis2" type="STRING"/>
[1] https://docs.wso2.com/display/EI640/PayloadFactory+Mediator

How can I get the soapenv content in WSO2?

In this case, how can I get the "MyString" content in WSO2 response?
Request:
<payloadFactory media-type="json">
<format>{
"Name" : "$1",
"group": "$3"
}
</format>
<args>
<arg evaluator="xml" expression="$ctx:Name"/>
<arg evaluator="xml" expression="$ctx:group"/>
</args>
</payloadFactory>
<call>
<endpoint key="ep_Server"/>
</call>
response:
Direction: request, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><text xmlns="http://ws.apache.org/commons/ns/payload">{"MyString":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySWQiOjEsIlN5c3RlbUlkIjoyMSwiUHJvcGVydHlJZCI6OSwiSXNBZG1pbiI6ZmFsc2UsIkNyZWF0ZURhdGVUaW1lIjoiMjAxNy0xMS0wOFQxMDoyMjoxMi45MDA3MjE4KzA4OjAwIn0.k6FyUGwXOAeC63oGsPWz8ttwo1LeDG3vnTbw7dJ18GY"}</text></soapenv:Body></soapenv:Envelope>
Try this.
<log>
<property name="MyString" expression="json-eval($.MyString)"></property>
</log>
Ref: https://docs.wso2.com/display/ESB500/JSON+Support
In your case the output is not json it's xml containing a text, usually it indicate that you're using text/plain type, I think the issue is there.
Moreover your output is not matching the sample code you've
Could you try to put the following before your call:
<property name="messageType" scope="axis2" type="STRING" value="application/json"/>
What is the content type that the service you're calling is returning? Is it valid? If not it could be that wso2 ei is by default considering it's text

alter the request payload in WSO2

I am new to WSO2.
I have proxied a service. Now i am trying to alter the input request content. The backend is expecting a request like below
<input>
<newParam>
{
"id" :"8888822"
}
</newParam>
</input>
But the frontend will be sending the request as below:
{
"id" :"8888822"
}
without the starting and ending tags.
Any documents or links which will help me do this would be of great help.
Thanks in advance.
You can achieve this by using the Payload Factory mediator[1]. In the following sample, you just retrieve the value for the "id" field from the request body and attach it to your predefined payload.
<log level="custom">
<property name="IncomingMessage" expression="$body" />
</log>
<payloadFactory media-type="xml">
<format>
<input>
<newParam>
$1
</newParam>
</input>
</format>
<args>
<arg evaluator="xml" expression="fn:concat('{"id":"', //id/text(), '"}')" />
</args>
</payloadFactory>
<log level="custom">
<property name="TransformedMessage" expression="$body" />
</log>
You will see the IncomingMessage and the TransformedMessage in the wso2carbon.log.
[1] - https://docs.wso2.com/display/ESB481/PayloadFactory+Mediator