Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom Transform REST to SOAP to REST using Apache Camel

We are building an utility which will :

  1. Accept JSON through a RESTful service
  2. Map it to a POJO
  3. Transform it to an Object which can be used to call a remote SOAP service (JSON is not identical as SOAP-XML, for example a few fields are missing, so we got to map entities instead of doing automation.)
  4. Make a SOAP API call, and fetch the result.
  5. Transform this result to JSON and send it back to client. (Process are synchronous to avoid complexity initially).

Plan A: We successfully tried Mulesoft Anypoint studio to build the flow. It provides Data Mapping, where we can easily map members from JSON to SOAP stub, and transform results again to JSON.

Plan B: Due to licensing constraint in Plan A, I am planning to do it using Camel. I am quite new to it, but could successfully build POC web app, which exposes a servlet accepting JSON. But now I am stuck as I don't know how to transform and call a remote soap. (WSDL is available).

Intended Flow

Client -> (Camel starts here) RESTful service -> Transform data -> Remote SOAP -> Accept response and transform to JSON -> Send back to client.

Any pointer into the right direction will be helpful.

like image 738
navaltiger Avatar asked Nov 11 '22 00:11

navaltiger


1 Answers

It seems your main problem is JSON<->SOAP transformation. You can use **freemarker** component as producer and write transformation logic in freemarker template language. Below is a sample JSON to SOAP transformation using FTL

<#ftl encoding="utf-8">
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:iser="http://example.com/service" xmlns:das="http://example.com/service">
   <soapenv:Header>
      <iser:header>
         <iser:username></iser:username>
         <iser:password></iser:password>
         <iser:agency>${body.customer.name}</iser:agency>
      </iser:header>
   </soapenv:Header>
   <soapenv:Body>
      <iser:readCompositeAddressByAddressNum>
         <iser:arg1 addressNum="${body.customer.addressNum}" buildingCode="0" cityCode="0" districtCode="0" quarterCode="0" streetCode="0" streetTypeCode="0" townshipCode="0" villageCode="0">
         </iser:arg1>
      </iser:readCompositeAddressByAddressNum>
   </soapenv:Body>
</soapenv:Envelope>

save above as inputTransformer.ftl. Create your output transfomer ftl (SOAP to JSON) and use both in your interface like below

from("direct-vm:getCustomerDetail")
.routeId("getCustomerDetail")
..
..
.to("freemarker:inputTransformer.ftl")
.log('{$body}')
.to(<Your SOAP Service>)
..
..
.to("freemarker:outputTransformer.ftl")
.log('${body}')

Send the transformed json back to your rest caller.

Hope it helped.

like image 59
Balaji Kannan Avatar answered Nov 15 '22 07:11

Balaji Kannan