In Part-I of this article, I explained the high level use case of the integration. Also it included the implementation of data migration ballerina services which will be used in this article. Let’s recall the complete integration again.

Figure-1 : Use case high level view

We have already implemented Data Migration Services within the previous article. In this article, Let’s go through other implementations required to complete the above integration. Figure-2 shows the detailed functionality of the integration and interaction among services.

Figure-2 : Key steps within the integration

Assume that following two JSON payloads are used as input and output.

Input Payload to the integration from the Web Application:

{  
"name":"Shaun Phillips",
"age":28,
"city":"London",
"employee_id":"201",
"department_id":"ADMIN",
"record_id":100,
"created_date":"09/06/2018",
"last_updated":"09/06/2018"
}

Output Payload from the integration to the HR System:

{  
"employee":{
"name":"Shaun Phillips",
"age":28,
"city":"London",
"employeeId":"LDM043",
"departmentId":"Administration"
},
"recordId":100,
"createdDate":"09/06/2018",
"lastUpdated":"09/06/2018"
}

In the output payload, employeeId and departmentId values have been transformed into new values and also the JSON structure has been changed. Next section explains how to do this transformation and value change within the integration using Ballerina.

employee_management_services.bal is the service which accepts client requests. It has following endpoints and listener defined.

Service listens to the port 9024 and it has two endpoints to data migration services (to transform employee and department IDs into new format) and hr service which is the new HR system interface.

Once the request received to the Listener, it validates the JSON payload and extracts values of old employee and department IDs.

Then it makes two calls to data migration service endpoints to get new values. Here, the concatenated values of URLs are marked as tainted explicitly using “untaint” keyword. In real implementation, this should be validated using a proper method to make sure it does not contain unsafe data.

New values are extracted from each response.

Finally, it creates the new payload as required by target HR system and invoke the services to update details. Response is sent back to client.

To test the sample, first build and start three services.

HR System back-end service:

$ ballerina build hr_system/
$ ballerina run ./target/hr_system.balx
ballerina: initiating service(s) in ‘./target/hr_system.balx’
ballerina: started HTTP/WS endpoint 0.0.0.0:9023

Data migration service:

$ ballerina build data_migration/
$ ballerina run ./target/data_migration.balx
ballerina: initiating service(s) in ‘./target/data_migration.balx’
ballerina: started HTTP/WS endpoint 0.0.0.0:9022

Employee management service:

$ ballerina build manage_employees/
$ ballerina run ./target/manage_employees.balx
ballerina: initiating service(s) in ‘./target/manage_employees.balx’
ballerina: started HTTP/WS endpoint 0.0.0.0:9024

Invoke service running on port 9024 with the request payload mentioned at the start of this article. It will update the employee details in HR system and respond with a successful result.

$ curl -v -X POST -H “Content-Type: application/json” -d ‘{“name”:”Shaun Phillips”,”age”:28,”city”:”London”,”employee_id”:”201",”department_id”:”IT”,”record_id”:100,”created_date”:”09/06/2018",”last_updated”:”09/06/2018"}http://localhost:9024/employees
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1…
* Connected to localhost (127.0.0.1) port 9024 (#0)
> POST /employees HTTP/1.1
> User-Agent: curl/7.35.0
> Host: localhost:9024
> Accept: */*
> Content-Type: application/json
> Content-Length: 163
>
* upload completely sent off: 163 out of 163 bytes
< HTTP/1.1 200 OK
< content-type: application/json
< date: Wed, 13 Jun 2018 22:43:30 +0100
* Server ballerina/0.970.1 is not blacklisted
< server: ballerina/0.970.1
< content-length: 107
<
* Connection #0 to host localhost left intact
{“status”:”Success”,”employeeId”:”LDM043",”message”:”Employee information successfully added to the system”}

If the request contains incorrect Employee ID of Department ID, it will respond with an error result.

$ curl -v -X POST -H “Content-Type: application/json” -d ‘{“name”:”Shaun Phillips”,”age”:28,”city”:”London”,”employee_id”:”000",”department_id”:”IT”,”record_id”:100,”created_date”:”09/06/2018",”last_updated”:”09/06/2018"}’ http://localhost:9024/employees
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1…
* Connected to localhost (127.0.0.1) port 9024 (#0)
> POST /employees HTTP/1.1
> User-Agent: curl/7.35.0
> Host: localhost:9024
> Accept: */*
> Content-Type: application/json
> Content-Length: 163
>
* upload completely sent off: 163 out of 163 bytes
< HTTP/1.1 500 Internal Server Error
< content-type: application/json
< content-length: 118
* Server ballerina/0.970.1 is not blacklisted
< server: ballerina/0.970.1
< date: Wed, 13 Jun 2018 22:45:13 +0100
<
* Connection #0 to host localhost left intact
{“message”:”Error in processing request — Error occurred while processing the request — No matching Employee ID found”}

If the request contains incorrect data which fails the validation rules in back-end, the response will be an error.

For example, if the age of the employee is 0, back-end system gives an error.

$ curl -v -X POST -H “Content-Type: application/json” -d ‘{“name”:”Shaun Phillips”,”age”:0,”city”:”London”,”employee_id”:”201",”department_id”:”IT”,”record_id”:100,”created_date”:”09/06/2018",”last_updated”:”09/06/2018"}’ http://localhost:9024/employees
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1…
* Connected to localhost (127.0.0.1) port 9024 (#0)
> POST /employees HTTP/1.1
> User-Agent: curl/7.35.0
> Host: localhost:9024
> Accept: */*
> Content-Type: application/json
> Content-Length: 162
>
* upload completely sent off: 162 out of 162 bytes
< HTTP/1.1 400 Bad Request
< content-type: application/json
< date: Wed, 13 Jun 2018 22:50:02 +0100
* Server ballerina/0.970.1 is not blacklisted
< server: ballerina/0.970.1
< content-length: 73
<
* Connection #0 to host localhost left intact
{“status”:”Error”,”message”:”Incomplete information in Employee Details”}

Complete code can be found here. Next article will explain how this scenario can be integrated with JMS Queues and payload can be transformed to an XML.

--

--

Jagath Ariyarathne

Solutions Architect with 14+ years of experience in design and development, providing solutions with Enterprise Integration Technologies, specialised in WSO2.