Isuru Gunawardana

Enterprise Integration Patterns with Ballerina: Content Based Router

Ballerina is a general purpose, concurrent and strongly typed programming language with both textual and graphical syntaxes, optimized for integration. In this technical guide, we share some of our experiences in using the Content Based Router feature in Ballerina.

Ballerina is a general purpose, concurrent and strongly typed programming language with both textual and graphical syntaxes, optimized for integration. If you happen to be someone who shares the same interests we have in Enterprise Application Integration, we are quite sure you have already heard of Ballerina. In this technical guide, we share some of our experiences in using the Content Based Router feature in Ballerina.

 

Understanding Enterprise Integration Patterns (EIP)

Enterprise Integration Patterns are a catalogue of design patterns that are specifically designed for integration practices. EIPs are used in the systems development process when integrate new and existing software within a business environment.

As explained by Enterprise Integration Patterns, ‘enterprise integration is too complex to be solved with a simple ‘cookbook’ approach. Instead, patterns can provide guidance by documenting the kind of experience that usually lives only in architects’ heads: they are accepted solutions to recurring problems within a given context.’




Understanding a Content Based Router

A Content Based Router (CBR) is an EIP which is used in a scenario where each message is required to be routed to a specific recipient based on its content.

Special caution should be taken to making the routing function easy to maintain as the router can become a point of frequent maintenance in this pattern. The below code snippet provides an example of how to implement this EIP using Ballerina with a simple routing function.

Version: Ballerina 0.964.0

GIT Project: content-based-routing

package com.ignwrdn.cbr;

import ballerina.net.http;
import ballerina.io;
import com.ignwrdn.rule;

@http:configuration {basePath:”/ims”, port:8890}
service<http> inventoryUpdate {

   @http:resourceConfig {
       methods:[“POST”],
       path:”/update”
   }
   resource inventoryUpdateResource (http:Connection con, http:InRequest req) {
       endpoint<http:HttpClient> imsEndpoint {
           create http:HttpClient(“http://localhost:8891/ims-service”, {});
       }

       json request = req.getJsonPayload();

       string brand;
       error castErr;

       try {
           brand, castErr = (string)request[“brand”];
       } catch (error e) {
           e.message = “Request error. No brand found”;
           io:println(e);
           throw e;
       }

       io:println(“Brand: ” + brand);

       http:InResponse imsResp;
       http:HttpConnectorError conErr;

       http:OutResponse res = {};

       imsResp, conErr = imsEndpoint.post(rule:route(brand), {});

       if (conErr == null) {
           io:println(“Backend call success..!”);
           io:println(imsResp);
           _ = con.forward(imsResp);
       } else {
           io:print(“Error in connecting to backend”);
           io:println(conErr);
           res.statusCode = 500;
           res.setStringPayload(conErr.message);
           _ = con.respond(res);
       }
   }
}

Since the routing logic is externalised above, it can be even enhanced to use a rule engine later. And furthermore, the logic or mapping of the rule can easily be maintained with some enhancements to the below function.

public function route (string brand) (string context) {
   if (brand == “mbt”) {
       io:println(“Rule found for: ” + brand);
       context = “/mbt/update”;
       return;
   } else {
       io:println(“Rule found for: ” + brand);
       context = “/dlg/update”;
       return;
   }
}

Thank you for reading this Tech Guide. We hope you will also read our next tutorial so that we can help you solve some more interesting problems.

Further reading: https://ballerinalang.org/docs/by-example/content-based-routing

 

Isuru-profile

Isuru Gunawardana

Technical Lead | Mitra Innovation