Real World Examples with Ballerina — Part I

Jagath Ariyarathne
5 min readJun 5, 2018

--

The integration world is rapidly moving from Service Oriented Architecture to the latest, cloud based, micro-services architecture. Ballerina is a cloud native programming language which is specifically built for this type of micro-services integrations. More details about the background and its architecture can be found in Ballerina home page;

Step by step instructions to setup ballerina run-time can be found here. Good collection of basic ballerina sample scenarios are available here. Try it out and get yourself familiar on setting up development environment, building and running ballerina samples with services and functions.

In this series of articles, the aim is to provide an understanding on real-world examples, where Ballerina can be used. Take the below high level use case as the first example;

Figure-1: High Level use case of the integration

Assume that an organization moves to cloud based HR system and it needs to integrate with existing web application. The web application sends information as JSON messages and some information has to be changed at the integration layer as per the requirement by new HR system. For example, Employee ID and Department ID should be translated from old format to the new format at the integration layer using external services.

Figure-2 provides the high level view of the system with the use of ballerina for the integration and additional data migration services.

Figure-2: Integration in high level view with Ballerina

As the first step, lets build two services required for Employee ID and Department ID translation from old format to new format. Figure-3 shows the interactions between data migration services and how the data is transformed.

Figure-3: Data Migration Services

Client sends a request with an Employee ID used in an old system. Data Migration service convert it to a new Employee ID matching with target HR System. Same happens for Department ID as well. Both requests are GET requests with Employee ID and Department ID are passed as path parameters.

Employee Migration Service:

Method: 
GET
Resource Path:
/data-migration/employees/{employeeId}
Response: {
"translateResponse": {
"informationType": "employee",
"sourceId": "201",
"targetId": "LDM043"
}
}

Department Migration Service:

Method: 
GET
Resource Path:
/data-migration/departments/{departmentId}
Response:{
"translateResponse": {
"informationType": "department",
"sourceId": "ADMIN",
"targetId": "Administration"
}
}

These services have been implemented as two different resources in data-migration ballerina service.

Ballerina functions are implemented in a different .bal file within the same package. This ballerina file contains two maps related to employee and department ID transformation which include old and new IDs. Also it contains functions to generate JSON response for successful as well as error scenarios.

Complete source code can be found in this git repository. To run the above service, clone the git repository and execute following ballerina commands (in UNIX) within the ballerina-playground directory.

$ ballerina init
Ballerina project initialized
$ ballerina build
$ 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

This will start services in data_migration package. In this scenario, there is only one ballerina service i.e. data_migration_service on port 9022.

Log level is set to DEBUG in ballerina.conf file which is there in the root directory.

b7a.log.level="DEBUG"

Send requests using curl to test the functionality with few valid and invalid IDs.

Employee ID migration examples:

$ curl -v http://127.0.0.1:9022/data-migration/employees/201
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 9022 (#0)
> GET /data-migration/employee/201 HTTP/1.1
> User-Agent: curl/7.35.0
> Host: 127.0.0.1:9022
> Accept: */*
>
< HTTP/1.1 200 OK
< content-type: application/json
< content-length: 89
* Server ballerina/0.970.1 is not blacklisted
< server: ballerina/0.970.1
< date: Sun, 3 Jun 2018 12:35:44 +0100
<
* Connection #0 to host 127.0.0.1 left intact
{"translateResponse":{"informationType":"employee","sourceId":"201","targetId":"LDM043"}}
$ curl -v http://127.0.0.1:9022/data-migration/employees/202
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 9022 (#0)
> GET /data-migration/employees/202 HTTP/1.1
> User-Agent: curl/7.35.0
> Host: 127.0.0.1:9022
> Accept: */*
>
< HTTP/1.1 404 Not Found
< content-length: 0
* Server ballerina/0.970.1 is not blacklisted
< server: ballerina/0.970.1
< date: Sun, 3 Jun 2018 12:59:41 +0100
<
* Connection #0 to host 127.0.0.1 left intact

Department ID migration examples:

$ curl -v http://127.0.0.1:9022/data-migration/departments/ADMIN
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1…
* Connected to 127.0.0.1 (127.0.0.1) port 9022 (#0)
> GET /data-migration/departments/ADMIN HTTP/1.1
> User-Agent: curl/7.35.0
> Host: 127.0.0.1:9022
> Accept: */*
>
< HTTP/1.1 200 OK
< content-type: application/json
< content-length: 101
* Server ballerina/0.970.1 is not blacklisted
< server: ballerina/0.970.1
< date: Sun, 3 Jun 2018 12:39:09 +0100
<
* Connection #0 to host 127.0.0.1 left intact
{“translateResponse”:{“informationType”:”department”,”sourceId”:”ADMIN”,”targetId”:”Administration”}}
$ curl -v http://127.0.0.1:9022/data-migration/departments/FINANCE
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 9022 (#0)
> GET /data-migration/departments/FINANCE HTTP/1.1
> User-Agent: curl/7.35.0
> Host: 127.0.0.1:9022
> Accept: */*
>
< HTTP/1.1 404 Not Found
< content-length: 0
* Server ballerina/0.970.1 is not blacklisted
< server: ballerina/0.970.1
< date: Sun, 3 Jun 2018 13:03:38 +0100
<
* Connection #0 to host 127.0.0.1 left intact

Debug and error Logs related to above requests can be found in the console;

$ 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
2018–06–05 22:30:06,978 DEBUG [data_migration] — Employee ID migration : 201 to LDM043
2018–06–05 22:30:09,827 ERROR [data_migration] — Old employee ID not found in the system : 202
2018–06–05 22:30:14,198 DEBUG [data_migration] — Department ID migration : ADMIN to Administration
2018–06–05 22:30:18,359 DEBUG [data_migration] — Old department ID not found in the system : FINANCE

Next article will explain, how these services can be integrated to enrich the requests received from client with new data, before sending those to the back-end.

--

--

Jagath Ariyarathne

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