Flink-ESB Message Gateway Tutorials
Original situation: there are services, posting data to the application server (for example to store the data in the database), and services, reading data from the application server.
Objective: encrypt data before it is sent to the application server. For example, you do not want your customer data to be stored on remote server (cloud CRM) in clear text.
Getting data back from remote server, Flink-ESB Message Gateway should decrypt response data and present to the caller in clear text.
Neither client applications, nor application server offering the services should be modified, or even aware about this modification. Encryption and decryption is done by Flink-ESB Message Gateway in a transparent for both client and server way.
Estimated costs:
Programming efforts: 0
Administrator efforts: 30 minutes
For this tutorial 2 applications are used, created with Flink-ESB Editor.
First Flink-ESB application is called "customer-api". It offers 4 services via 4 HTTP methods GET, POST, PUT and DELETE to read, insert, update and delete customer data in the database in table called CUSTOMER. With every insert a new CUSTID is generated and assigned to the entry. HTTP GET, PUT and DELETE use that CUSTID to read or modify customer data. Data is exchanged in XML format. >> Check tutorial on creating "customer-api" application with Flink-ESB Editor.
Second Flink-ESB application offers 2 services to encrypt and to decrypt XML data. These services will be used by Flink-ESB Message Gateway to encrypt request XML before sending it to the server, and to decrypt response from the server. >> Check tutorial on creating OSGI services to encrypt/decrypt XML nodes with Flink-ESB Editor.
Open Flink-ESB Message Gateway Config Console in the browser. Default URL: https://localhost:8082. Login with default username/password: admin/admin.
Click on "Destinations" tab and press "Add Entry" button. Enter data as on the picture below: "Destination Id" : 1002 (or any unique Id), "Protocol" : HTTP, "Method" : GET, "Destination Expression" : 'http://192.168.2.105:4444/customer'+(property['http.queryString']!='' ? '?'+property['http.queryString'] : '') (adjust IP accordingly).
Click on added row to hide details panel. Now click on "Add Entry" again and type the data for the second destination as on picture below: "Destination Id" : 1003 (or any unique Id), "Protocol" : HTTP, "Method" : POST, "Destination Expression" : 'http://192.168.2.105:4444/customer' (adjust IP accordingly).
Click "Save Modifications" to save 2 new destinations.
Click on "Gateway Config" tab and press "Add Entry" button. Enter data as on the picture below: "Config Id" : 1002 (or any unique Id), "Method" : GET, "URI" : /customer:
Click on "Edit Destination Rules" link, select "Show all rules" checkbox and select a checkbox on the left side of rule with Id 1002 (or whatever Id you've assigned to a HTTP GET destination in the previous step).
The data should look like on picture below:
Click on new façade entry row to hide details panel. Press "Add Entry" again and enter data for the second façade entry: "Config Id" : 1003 (or any unique Id), "Method" : POST, "URI" : /customer.
Click on "Edit Destination Rules" link, select "Show all rules" checkbox and select a checkbox on the left side of rule with Id 1003 (or whatever Id you've assigned to a HTTP POST destination in the previous step).
Now click "Save Modifications" to save changes.
Click on "Gateway Config" tab if not there already, and click "Trigger Instances" button. Confirm a message box by pressing "OK"
Customer data should be stored on remote server in the table called "CUSTOMER". Structure of tha table is like on picture below:
Currently the table is empty. Go to the browser any try this URL: https://192.168.2.105:8081/customer (adjust IP and port to the machine where your Flink-ESB Message Gateway is running). You should get following error:
Now try this URL: https://192.168.2.105:8081/customer?id=1. This time you should get:
Now let's create a customer by calling HTTP POST https://192.168.2.105:8081/customer and sending this body message:
<InsertCustomer> <name>Darth Vader</name> <city>Cloud City</city> <zip>12345</zip> </InsertCustomer>
You should get response like below:
<InsertCustomerResult> <custid>1</custid> <name>Darth Vader</name> <city>Cloud City</city> <zip>12345</zip> <status>OK</status> </InsertCustomerResult>
Try https://192.168.2.105:8081/customer?id=1 in the browser again. You should get now customer data:
As of now, you've created 2 new façade entries for HTTP POST and GET to insert customer data and to read customer data.
Let us now add encryption/decryption functionality. The aim is: to send all the data during insert to the server encrypted, and to read data decrypted.
Go to Config Console in the browser and click "Transformation Rules" tab, then click "Add Entry" button and enter data as on picture below: "Rule Id" : 1005 (or any unique Id), "Rule Type" : OSGI, "Interface" : net.liuk.esb.components.Route, "Filter" : (route.name=encrypt-xml), "Method" : processMessage, "Param. Types" : { 'java.lang.String' }, "Parameters" : { property['request'] }:
Hide details panel. Click "Add Entry" and enter data for the second transformation rule: "Rule Id" : 1006 (or any unique Id), "Rule Type" : OSGI, "Interface" : net.liuk.esb.components.Route, "Filter" : (route.name=decrypt-xml), "Method" : processMessage, "Param. Types" : { 'java.lang.String' }, "Parameters" : { property['response'] }.
Now click "Save Modifications" to save changes.
Let us explain the meaning of all those parameters we've used for creating transformation rules.
"Rule Type"=OSGI - means, we will use OSGI service to perform a message transformation. Every java class implementing one or multiple java interfaces can be registered as OSGI service. Then any application can call this service without knowing where this java class is running. It can be within the same Flink-ESB application, or it can be a part of some other application running within the same JVM, or it could be on some remote machine. As soon as this class registers itself by its local service registry as OSGI service, all cluster instances should be able to call this service.
"Interface"=net.liuk.esb.components.Route, "Filter"=(route.name=encrypt-xml) are used to find the right OSGI service within service repository.
The other parameters define what exactly should be called on the object representing OSGI service: name of the method, types of parameters this method expects, and the values of parameters.
In other words, we want to call here Flink-ESB route (all routes implement net.liuk.esb.components.Route interface) with name "encrypt-xml" (routes always register a service property with "route.name" name). We want to call a method called "processMessage" (which is the main route's method), and we pass one parameter of type "java.lang.String" to the method, and the value we take from the "request" message property.
To decrypt response we call route with the name "decrypt-xml" and pass a value of "response" message property to its "processMessage" method.
Now click "Save Modifications" to save transformation rules.
Go to Flink-ESB Message Gateway Config Console on the browser and click on "Gateway Config" tab and click on the row with "Config Id" 1002 (or whatever Id you've assigned to HTTP GET façade entry in step 2) to unhide details panel.
Click on "Edit Response Transformation Rules" link and unselect a checkbox on the left side of rule with Id 1006 (or whatever Id you've assigned to OSGI rule with filter route.name=decrypt-xml):
Click on façade entry to hide its details panel. Now click on façade entry with "Config Id" 1003 (or whatever Id you've assigned to HTTP POST façade entry in step 2) to unhide details panel.
Click on "Edit Request Transformation Rules" link and unselect a checkbox on the left side of rule with Id 1005 (or whatever Id you've assigned to OSGI rule with filter route.name=encrypt-xml):
Click on "Edit Request Transformation Rules" link again to hide its details, now click "Edit Response Transformation Rules" link and assign decryption rule with Id 1006 (or whatever Id you've assigned to OSGI rule with filter route.name=decrypt-xml).
Now click "Save Modifications" to save changes and after that click "Trigger Instances" to activate configuration changes.
Let's create another customer by calling HTTP POST https://192.168.2.105:8081/customer and sending this body message:
<InsertCustomer> <name>Luke Skywalker</name> <city>Cloud City</city> <zip>12345</zip> </InsertCustomer>
You should get response like below:
<InsertCustomerResult> <custid>2</custid> <name>Luke Skywalker</name> <city>Cloud City</city> <zip>12345</zip> <status>OK</status> </InsertCustomerResult>
Try https://192.168.2.105:8081/customer?id=1 in the browser. You should get a data for the customer you've created in step 4 of this tutorial:
Now try this URL: https://192.168.2.105:8081/customer?id=2 in the browser. You should get the data of the customer with CUSTID=2:
Nothing exciting so far. HTTP GET service delivers the data of the customer with CUSTID=2. But let us now check the data in the database:
As you can see, the data of the customer with CUSTID=2 is stored in the database encrypted !!!
Go ahead and create several more customers with HTP POST service and read customer data with HTTP GET service. As you can see, neither client application (browser in our case), nor the application server were modified, but the data is now exchanged between client and Flink-ESB Message Gateway in clear text, and encrypted between Gateway and application server. In other words no data in clear text leaves your network.
This approach is pretty secure, because encryption keys are stored on Flink-ESB side. Application server has no access to the keys, and therefore cannot decrypt the data. Clients also do not have access to the keys, they might not even know, that the data is encrypted/decrypted on the fly.