Endpoint Template—to resolve endpoints dynamically with WSO2 ESB (devOps)

This is a parallel iteration of an article written explaining the deployment automation process of WSO2 middleware based solutions in general. Therefore, I would like to encourage you to go through that blog-post first, in order to gain some background knowledge on what we are trying to accomplish here. With this post, we wish to narrow the scope into a particular challenge identified and highlighted in the other article, which is related to certain part of the automation process. With this article we would be discussing about the problem in detail, and discuss on how to address the same using existing capabilities of the platform. Since this a very specific use-case, also note that we are narrowing the scope to WSO2 Enterprise Service Bus, rather than discussing about WSO2 middleware products in general.

Recap—the problem use-case

Let's assume that we wish to expose a SOAP based web service in the form of a RESTful web service. For our example, we can use the most popular WSO2 sample web service called the SimpleStockQuoteService. This is a SOAP based web service, and we can use WSO2 Enterprise Service Bus (ESB), effectively to perform a SOAP to REST conversion and make the same capabilities available to the clients in the form of a RESTful web service or an API. ( If you are wondering how to perform that, please refer to this GitHub repository and follow the README in order to get something similar up and running within a few seconds. )

If we exposed this particular web service with a RESTful wrapper through the ESB, we probably should have used a proper context URL like /stocks to invoke this service, similar to how we have depicted the use-case in figure-1.0


Figure 1.0
  1. A developer doesn't know of hostnames, ports or URIs of a particular back-end service deployed on,
    • Development environment
    • Testing/OA enviroment or
    • Production environment
  2. But he develops integration artifacts, that should be deployed on ESB installations of,
    • Development environment
    • Testing/OA enviroment and
    • Production environment
  3. When the same archive of integration artifacts is moved...
  4. from one environment to another,
  5. the artifacts should adapt to each environment...
  6. by updating the back-end service endpoints dynamically, similar to what is depicted in figure-3.0.

In the development environment, the application developer would use /stocks context path to invoke the StockQuoteService instance deployed on deployment environment. Similarly, the same context path /stocks would be used by QA staff with testing utility tools which should route the invocation traffic into some other instance of StockQuoteService hosted on a different VM. When it comes to the production environment, the same context path /stocks should route the production traffic into the StockQuoteService cluster deployed in production.

But the integration artifacts developer is not aware of the host-names, ports or URLs of these instances of the StockQuoteService by the time he/she develops the artifacts. Even if he/she were provided with such environment specific information in advance by the operational engineers; hard coding of such information would hardly scale!

If the integration artifact developer has a way to define these service endpoint parameters so that they would be resolved dynamically on run-time, we can consider this particular problem is resolved. This exactly is what we are trying to perform, with the use of an existing integration artifact type called Endpoint Templates.

The typical build automation practice


Figure 2.0

With figure-2.0 above, I have explained how the integration artifacts are developed and packaged so that those would be available for deployment. The developers would use the eclipse based IDE tool called the WSO2 Developer Studio to compose the WSO2 ESB integration artifacts (with source code edit and visual modeling support). These will ultimately generate a few XML files which consists of all integration and mediation logic which are understood and interpreted by the mediation engine of the WSO2 ESB. These source code files are then pushed in to the source code repository which may be based on some technology such as Subversion or Git.

A build automation tool or a build server such as Jenkins or Bamboo can be used to package these source files according to the logic defined using Maven.

Typically, all types of WSO2 deployment artifacts (including but not limited to integration artifacts) are packaged using a common archive type called WSO2 Composite Application Archive (identified with file extension *.car). Also we typically use the term CAR file for verbal reference to identify such archive files.

A CAR file may consist of many different types of projects such as ESB projects, Application Server projects, Data Services projects and Governance Registry projects those are only applicable to and supported by different WSO2 products. However, the CAR file provides you a way to package all of those projects in a single and a universally deploy-able archive. Once such a CAR file with many different project types was deployed in different WSO2 servers, each server (product instance) has the intelligence to extract only the relevant parts from the archive.

Which means, if you chose WSO2 ESB server instance/cluster to deploy a particular CAR file with ESB projects, Application Server projects, Data Services projects and Governance Registry projects in it; the ESB instance(s) will only extract the ESB projects from the CAR file, having ignored rest of the projects.

I can literally see a bright smile on the operational engineers face now, once he/she read the above paragraph; because he/she definitely understands the value delivered by the above described packaging approach. This provides the freedom for the operation engineer to copy the same file into all the WSO2 product instances that they may have within their solution. They do not have to handle the stress of being careful on selecting any relevant product instances/cluster to deploy each artifact type. Rather they would copy the same archive (CAR file) into all the locations. Therefore, you can notice that this obviously minimizes the deployment automation effort as well.

Walk-through the source code

The REST API

The following code segment presents the integration logic of the above discussed /stocks API. This performs a SOAP to REST conversion, exposing the same capability delivered by the SOAP based StockQuoteService, in the form of a REST API.


<api context="/stocks" name="StockExchangeAPI" xmlns="http://ws.apache.org/ns/synapse">
  <resource methods="GET" protocol="http" uri-template="/quote/{symbol}">
    <inSequence>
      <payloadFactory description="make StockQuote Payload" media-type="xml">
        <format>
          <ser:getQuote xmlns:ser="http://services.samples" xmlns:xsd="http://services.samples/xsd">
            <ser:request>
              <xsd:symbol>$1</xsd:symbol>
            </ser:request>
          </ser:getQuote>
        </format>
        <args>
          <arg evaluator="xml" expression="get-property('uri.var.symbol')"/>
        </args>
      </payloadFactory>
      <property description="set SOAPAction header" name="SOAPAction" scope="transport" type="STRING" value="urn:getQuote"/>
      <call>
        <endpoint>
          <address uri="http://devl.example.com:9000/services/SimpleStockQuoteService" format="soap11"/>
        </endpoint>
      </call>
      <respond/>
    </inSequence>
    <outSequence/>
    <faultSequence/>
  </resource>
</api>

The Service Endpoint

Note the <endpoint> and <address> elements in the above code; especially the attribute called uri. There, we typically do hard code the host-name and the port of the back-end service. Let's assume that we composed the mediation logic of the REST API artifact like this by directly hard coding the back-end service URI. In that case, the CAR file which consists of this API could only be deployed on the development environment setup, but not on other environments. Otherwise, when we move the CAR file from development environment to another, we need to extract this logic, modify it accordingly by replacing the host name and port to match that particular environment and then re-package everything into a CAR file before deployment (which sounds troublesome). Therefore, we need to look for an alternative approach.

The Endpoint Template

Like already mentioned, WSO2 ESB comes with an artifact type called Endpoint Template, which we can use effectively to address the above mentioned scenario. Please observe the code segment provided below.


<template xmlns="http://ws.apache.org/ns/synapse" name="address-endpoint-template">
  <endpoint name="$name">
    <address uri="$uri"/>
  </endpoint>
</template>

You can use either the WSO2 Developer Studio or WSO2 ESB admin management console (web based) to define a template like this. ( In the admin management console follow the path Templates > Add Endpoint Template > Address Endpoint Template )

Once you have this kind of a Template created, you can use this within your mediation logic so that the values for $name and $uri placeholders could be passed dynamically during run-time. In that case, you need to modify the <endpoint> element of the API source code accordingly to use this template instead of the hard coded endpoint parameters (host-name and port).

Updated Endpoint Reference


<endpoint template="address-endpoint-template" uri="http://{system.prop.host}:{system.prop.port}/services/SimpleStockQuoteService" name="stock-quote-endpoint"/>

Updated REST API source code


<api context="/stocks" name="StockExchangeAPI" xmlns="http://ws.apache.org/ns/synapse">
  <resource methods="GET" protocol="http" uri-template="/quote/{symbol}">
    <inSequence>
      <payloadFactory description="make StockQuote Payload" media-type="xml">
        <format>
          <ser:getQuote xmlns:ser="http://services.samples" xmlns:xsd="http://services.samples/xsd">
            <ser:request>
              <xsd:symbol>$1</xsd:symbol>
            </ser:request>
          </ser:getQuote>
        </format>
        <args>
          <arg evaluator="xml" expression="get-property('uri.var.symbol')"/>
        </args>
      </payloadFactory>
      <property description="set SOAPAction header" name="SOAPAction" scope="transport" type="STRING" value="urn:getQuote"/>
      <call>
        <endpoint template="address-endpoint-template" uri="http://{system.prop.host}:{system.prop.port}/services/SimpleStockQuoteService" name="stock-quote-endpoint"/>
      </call>
      <respond/>
    </inSequence>
    <outSequence/>
    <faultSequence/>
  </resource>
</api>

Note the {system.prop.host} and {system.prop.port} in the uri. With these expressions, the WSO2 ESB has the capability of reading two JVM parameters called host and port passed at the startup. Therefore, we can pass the environment specific host-names and the ports when we start a particular WSO2 ESB instance.

Typically we start an instance of WSO2 ESB by running the startup script located in its /bin directory as,

  
  ./wso2server.sh
  

Instead, we can simply execute the same by providing two additional JVM parameters as below, in order to provide the host-name and the port of the relevant service endpoint (according to the environment)

Development environment ESB

  
  ./wso2server.sh -Dhost=devl.example.com -Dport=9000
  

Testing environment ESB

  
  ./wso2server.sh -Dhost=test.example.com -Dport=9000
  

Production environment ESB

  
  ./wso2server.sh -Dhost=prod.example.com -Dport=443
  

Now look at figure-3.0 and re-visit figure-1.0 which depict the entire deployment process and this particular issue we addressed using the endpoint-templates. Then try to make references with what you studied by reading these two articles.


Figure 3.0

At this point, we are done with our study. As a few additional points to keep in mind, please note that these JVM parameters following two basic approaches.

  1. With Deployment Automation Channel
    • Here you can compose your deployment automation scripts to pass these JVM parameters dynamically, similar to the above.
  2. With Configuration Automation Channel
    • Here you can manipulate the startup script file (wso2server.sh) by adding those JVM parameters.
    • Also note that this is possible, since the operational engineers directly involve at this stage (they have the knowledge of deployment topology and environment specifics).

Summary

With this blog-post, we mainly discussed on how to use Endpoint Templates and the integration code level, to address a particular issue; rather than discussion things at the solution level. Here we mainly targeted the builds automation part of the entire automation process, and studied how to keep the development staff independent-of or away-from the deployment / operational concerns. I hope that the knowledge that you gathered by reading this post and the other parallel iteration which describes the entire (end-to-end) automation process, would be helpful enough to understand the basics—allowing you to implement the same, similar or an own approach of automation of WSO2 middleware based solutions which probably is inspired by these basics.

If you believe that the above mentioned capabilities would address some requirements you have, or WSO2 middleware platform has the potential of helping you build your future solutions providing the capability of expansion and extension; you can go to the next level by exploring WSO2 official documentation, articles and other resources such as videos and webinars to gather more knowledge on specifics.

Comments

  1. Awesome post Chathura! This was really helpful.

    ReplyDelete
  2. this blog is very helpful and informative. thank you for sharing this. please add more inputs for working.

    devops training in chennai

    ReplyDelete
  3. RealTime example with awesome explanation.

    ReplyDelete
  4. Casino App | Download APK and Install on Your Mobile
    Casino App App App APK Download 경주 출장샵 and Install 인천광역 출장안마 on Your Mobile. It has 김포 출장샵 several popular themes: video slots, 목포 출장마사지 table games, video 화성 출장샵 poker,

    ReplyDelete
  5. 6E754Maritza5FBC74/14/2024 11:35 am

    40723
    matadorbet
    ----
    ----
    ----
    ----
    ----
    ----
    ----
    ----

    ReplyDelete
  6. D9CF4Esperanza586AC4/15/2024 11:40 am

    10EDA
    ----
    ----
    ----
    ----
    matadorbet
    ----
    ----
    ----
    ----

    ReplyDelete

Post a Comment