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 -
"1.0" encoding="UTF-8" xml version=
<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 -
"1.0" encoding="UTF-8" xml version=
<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 -
"1.0" encoding="UTF-8" xml version=
<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>
<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:
"1.0" encoding="UTF-8" xml version=
<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:
"1.0" encoding="UTF-8" xml version=
<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:
"1.0" encoding="UTF-8" xml version=
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
<soapenv:Body />
</soapenv:Envelope>
DEBUG - PayloadFactoryMediator #mediate. Transformed payload format>>>
DEBUG - LogMediator To: /payloadApi, MessageID: urn:uuid:d59b1afb-951d-4b17-a648-a517356fb8df, Direction: request, where? = inner sequence acting as API - END, Payload:
DEBUG - StatisticsReporter Created statistics log : StatisticsLog{id='myPayloadSeq', componentType=SEQUENCE}
DEBUG - SynapseCallbackReceiver Body :
"1.0" encoding="UTF-8" xml version=
<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:
"1.0" encoding="UTF-8" xml version=
<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:
"1.0" encoding="UTF-8" xml version=
<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:
"1.0" encoding="UTF-8" xml version=
<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>>>
"1.0" encoding="UTF-8" xml version=
<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:
"1.0" encoding="UTF-8" xml version=
<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 !
Really nice blog and impressive information you gave us.Thank you and i will expect more in future.
ReplyDeleteJAVA Training in Chennai
Best JAVA Training institute in Chennai
Python Training in Chennai
Selenium Training in Chennai
Android Training in Chennai
Big data training in chennai
JAVA Training in Chennai
Java Training in Tambaram