Wednesday, 15 March 2017

WSO2 ESB - How to use PayloadFactory Mediator




As per the WSO2-ESB documentation of PayloadFactory Mediator, it is stated that this mediator can be used to transform/ replace the contents of a message at the runtime.


To experience how it works, lets have a working demo.
For the same, as discussed in earlier tutorials, have the local setup of WSO2-ESB up and running.


For reference, feel free to drop by @ 


Our plan of action will be something like this -

  1. One working url that can return as something when invoked

  2. An API, that works in 2 parts -

      a. Inbound: Invokes the above mentioned url

      b. Outbound: Transforms the message received using PayloadFactory

So, the plan sounds simple, and the coding will sound simpler too.

Let’s begin -


1. We need a URL/ Restful API that provides us a json data.

Why not create one instead of depending on any 3rd party?

Here is the mechanism, and it will make you more comfortable with ESB -

Create a sequence, to use PayloadFactory, to create JSON data.

Note – As a good practice, use Log mediator, so that you can trace your code flow in the console.
I generally prefer using values as shown below, in logging. It’s up to you what you prefer.

Moving on, once you create your sequence, it will look somewhat like this -






The XML view for the above is -

<?xml version="1.0" encoding="UTF-8"?> <sequence xmlns="http://ws.apache.org/ns/synapse" name="myPayloadSeq" trace="enable"> <log category="DEBUG" level="full"> <property name="where?" value="inner sequence acting as API - START" /> </log> <payloadFactory media-type="json"> <format>{"id": "201", "fname": "Ramlal", "lname": "Gabbar"}</format> </payloadFactory> <log category="DEBUG" level="full"> <property name="where?" value="inner sequence acting as API - END" /> </log> <respond /> </sequence>

Behind the scenes -

What we have done here is using PayloadFactory to create a JSON data, that will be returned whenever the enclosing API is invoked. We can use this in an API so that it can be treated as an endpoint URL that provides us data.


The APIs once created should look like this - 'MyPayloadApi'




The XML for the above is as follows -

<?xml version="1.0" encoding="UTF-8"?> <api xmlns="http://ws.apache.org/ns/synapse" name="myPayloadApi" context="/payloadApi"> <resource methods="DELETE POST PUT GET"> <inSequence> <sequence key="myPayloadSeq" /> <respond /> </inSequence> </resource> </api>

Behind the scenes -

We have invoked the sequence, and ended the invocation using Respond mediator.



2. Now the big task is here -

Coming to the main task, we have to implement one API, that will get the message from the so called remote url (created above), and will modify it using the PayloadFactory mediator.

If we succeed, our mission is accomplished.

Let’s try this.

Design the API, and it should look like - 'InvokePayloadApi'




The XML view -

<?xml version="1.0" encoding="UTF-8"?> <api xmlns="http://ws.apache.org/ns/synapse" name="invokePayloadApi" context="/invoke"> <resource methods="DELETE POST PUT GET">
<inSequence> <log level="full" category="DEBUG"> <property name="where?" value="Inside In Sequence that invokes API" /> </log> <send> <endpoint> <http uri-template="http://192.168.122.1:8280/payloadApi" /> </endpoint> </send> <log level="full" category="DEBUG"> <property name="where?" value="Exiting In Sequence that invokes API" /> </log> </inSequence>
<outSequence> <log level="full" category="DEBUG"> <property name="where?" value="Beginning payload transformation in out sequence" /> </log> <payloadFactory media-type="xml"> <format> <hello xmlns=""> <hello1>$1</hello1> <hello2>$2</hello2> <hello3>$3</hello3> </hello> </format> <args> <arg evaluator="json" expression="$.id" /> <arg evaluator="json" expression="$.fname" /> <arg evaluator="json" expression="$.lname" /> </args> </payloadFactory> <log level="full" category="DEBUG"> <property name="where?" value="Ending payload transformation in out sequence" /> </log> <respond /> </outSequence>
</resource> </api>


Behind the scenes -

Let’s take a moment to understand what we have done here.

a. Divided the API in 2 parts – Insequence and OutSequence

b. Insequence -

Using Send mediator, invoked the above url (using HTTP endpoint)

Note – If you get your localhost changed, like at the restarting of local WSO2 ESB server, make sure you change the IP here too. We are talking about the highlighted part in the XML.

You are free to choose any other working option to invoke the URL, for now I selected this.

For other readers, you can share your experiences in the comments, so that we all can ponder on new stuffs.

c. Outsequence -

We are trying to convert the incoming json into xml, so we have mapped the values as $.X of ‘X’ key from the json to the value of custom tags of XML here. Please not how <args> section is responsibly doing this task, and how <format> section takes care of the output format.

d. And as usual we have Log mediators for easy tracing in logs.



Here are a few highlights of my local logs -


DEBUG - RESTRequestHandler Located specific API: invokePayloadApi for processing message

DEBUG - LogMediator To: /invoke, MessageID: urn:uuid:91624339-3f31-466b-8985-8287cfa1bd2a, Direction: request, where? = Inside In Sequence that invokes API, Envelope:

<?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"> <soapenv:Body /> </soapenv:Envelope>

DEBUG - HTTPEndpoint Sending message through endpoint : null resolving to address = http://192.168.122.1:8280/payloadApi

DEBUG - LogMediator To: http://192.168.122.1:8280/payloadApi, MessageID: urn:uuid:91624339-3f31-466b-8985-8287cfa1bd2a, Direction: request, where? = Exiting In Sequence that invokes API, Envelope:

<?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"> <soapenv:Body /> </soapenv:Envelope>

DEBUG - LogMediator To: /payloadApi, MessageID: urn:uuid:d59b1afb-951d-4b17-a648-a517356fb8df, Direction: request, where? = inner sequence acting as API - START, Envelope:

<?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"> <soapenv:Body /> </soapenv:Envelope>

DEBUG - PayloadFactoryMediator #mediate. Transformed payload format>>>
 
   "id":"201",
   "fname":"Ramlal",
   "lname":"Gabbar"
}

DEBUG - LogMediator To: /payloadApi, MessageID: urn:uuid:d59b1afb-951d-4b17-a648-a517356fb8df, Direction: request, where? = inner sequence acting as API - END, Payload:
 
   "id":"201",
   "fname":"Ramlal",
   "lname":"Gabbar"
}

DEBUG - StatisticsReporter Created statistics log : StatisticsLog{id='myPayloadSeq', componentType=SEQUENCE}

DEBUG - SynapseCallbackReceiver Body : 

<?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Body /> </soapenv:Envelope>


DEBUG - LogMediator To: http://www.w3.org/2005/08/addressing/anonymous, WSAction: , SOAPAction: , MessageID: urn:uuid:1e15723a-514b-428e-81d8-7c0bb25fc1a3, Direction: response, where? = Beginning payload transformation in out sequence, Envelope:

<?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Body> <jsonObject> <id>201</id> <fname>Ramlal</fname> <lname>Gabbar</lname> </jsonObject> </soapenv:Body> </soapenv:Envelope>

DEBUG - LogMediator End : Log mediator

DEBUG - JsonUtil #transformElement. Transformed OMElement. Result:

<?xml version="1.0" encoding="UTF-8"?> <jsonObject> <id>201</id> <fname>Ramlal</fname> <lname>Gabbar</lname> </jsonObject>

DEBUG - SynapseJsonPath #stringValueOf. Evaluated JSON path 
<$.id> : <201>

DEBUG - JsonUtil #transformElement. Transformed OMElement. Result:

 <?xml version="1.0" encoding="UTF-8"?>
<jsonObject> <id>201</id> <fname>Ramlal</fname> <lname>Gabbar</lname> </jsonObject>

DEBUG - SynapseJsonPath #stringValueOf. Evaluated JSON path 
<$.fname> : <Ramlal>

DEBUG - JsonUtil #transformElement. Transformed OMElement. Result: 

<?xml version="1.0" encoding="UTF-8"?> <jsonObject> <id>201</id> <fname>Ramlal</fname> <lname>Gabbar</lname> </jsonObject>

DEBUG - SynapseJsonPath #stringValueOf. Evaluated JSON path 
<$.lname> : <Gabbar>


DEBUG - PayloadFactoryMediator #mediate. Transformed payload format>>>

<?xml version="1.0" encoding="UTF-8"?> <pfPadding> <hello> <hello1>201</hello1> <hello2>Ramlal</hello2> <hello3>Gabbar</hello3> </hello> </pfPadding>

DEBUG - LogMediator Start : Log mediator
DEBUG - LogMediator To: http://www.w3.org/2005/08/addressing/anonymous, WSAction: , SOAPAction: , MessageID: urn:uuid:1e15723a-514b-428e-81d8-7c0bb25fc1a3, Direction: response, where? = Ending payload transformation in out sequence, Envelope:

<?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Body> <hello> <hello1>201</hello1> <hello2>Ramlal</hello2> <hello3>Gabbar</hello3> </hello> </soapenv:Body> </soapenv:Envelope>

DEBUG - LogMediator End : Log mediator
DEBUG - RespondMediator Start : Respond Mediator
DEBUG - RespondMediator End : Respond Mediator
DEBUG - SequenceMediator End : Sequence <anonymous>



Here is my output, checked using Mr. Postman :P





Hope you enjoyed this one.

Happy Coding !

Featured post

JAVA based project, that can be used to hit DB using JDBC, from WSO2 ESB

Hi Buddies, Here is a small project that will enable you to hit MySQL DB using WSO2 ESB - https://github.com/namitsharma99/customM...

Popular Posts