Sunday, December 13, 2020

Working with WSO2 ESB sequence

What is Apache Synapse?


Apache Synapse is a lightweight and high-performance Enterprise Service Bus (ESB) which acts as a bridge between several applications. It uses Apache Axis2 as its underlying web services engine. Synapse is configured using a simple, XML-based configuration language.




Apache Synapse supports standard XPath functions and variables through its underlying XPath engine. These functions can deal with the  message context at the given scope. There are 5 scopes as follows and they include the following properties. 


  • Default  

    • The properties which directly set on the Synapse MessageContext instance 

  • Axis2 

    • The properties which  set on the underlying Axis2 MessageContext object

  • Transport 

    •  The transport headers  which set on the MessageContext

  • Registry 

    •  The properties which reside  in the registry 

  • System 

    • The Java system properties 


What is WSO2 ESB?


WSO2 ESB is a 100% open source, lightweight, enterprise-ready ESB. It is built on the Apache Synapse.  So you can configure the  WSO2 ESB using XML-based configuration language the same as configuring Apache Synapse.


Rest of the article describes what are the functions that may be used when you are configuring WSO2 ESB using XML-based configuration language.


1. Variable defining and use

1.1 Create a new variable giving a value

You can create a variable named ORDER_ID by giving ORDER123 as its value as follows.

<property 
    name="ORDER_ID" 
    value="ORDER123" 
    type="STRING" 
     scope="default"
/>

1.2 Create variable using request header

Assume request header name is service-id and its data type is String. Then you can define a new variable named SERVICE_ID as follows.

<property 
    name="SERVICE_ID" 
    expression="$trp:service-id" 
    type="STRING"
    scope="default"
/>

1.3 Create variable using json request body content

Assume request body is a JSON type as follows.


{
"brand": "Samsung"
"Order" : {
"OrderId":"Sam2020103" 
}
}


Then you can define a new variable named BRAND using the response payload's brand key as follows.

<property 
    name="BRAND" 
    expression="json-eval($.brand)" 
    type="STRING" 
    scope="default"
/>

And also you can define a new variable named ORDER_ID using the response payload's Order and OrderId keys as follows.

<property 
    name="ORDER_ID" 
    expression="json-eval($.Order.OrderId)" 
    type="STRING" 
    scope="default"
/>

1.4 Create variable using XML request body content


Assume SOAP request body as follows

<?xml version="1.0" encoding="utf-8" ?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<soapenv:Fault>
<errorcode>ABC0901</errorcode>
<errorstring>Order id is not accepted!</errorstring>
<detail>
<ns1:ServiceException xmlns:ns1="http://www.abc.org/schema/common/v2_1">
<messageId>ABC0901</messageId>
<text>Order ID is invalid</text>
</ns1:ServiceException>
</detail>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>

You can define a new variable named RESPONSE_ERROR_MESSAGE using the SOAP request payload's faultstring key as follows.

<property
    xmlns:ns1="http://www.abc.org/schema/common/v2_1"
    name="RESPONSE_ERROR_MESSAGE"
    expression="$body//errorstring"
    scope="default"
    type="STRING"
/>

2. String Manipulation


2.1 Manipulate string content using variables


You can use xpath replace function which is available from XPath 2.0. First, you need to enable xpath 2.0 on ESB 5.0. For that set the following property on


<ESB_HOME>/repository/conf/synapse.properties file


      synapse.xpath.dom.failover.enabled=true  


Suppose you have to create a string by changing its content using parameters. Here, what I am going to do is replace the values inside curly brackets using parameters.

  <property 

name="OriginalString"

            value="Well done, you have subscribed to the {ServiceName} service. Your account will be debited from {Amount}. Free unsubscription the service by sending  STOP {KeyWord} to {Shortcode}"

      scope="default"

      type="STRING" />


Followings are the values of the parameters.


 <property name="serviceName" value="Hela Derana News"/>

 <property name="amount" value="Rs.10"  type="STRING" />

 <property name="keyword" value="HDN"/>

 <property name="shortcode" value="1122"/>


Now I am going to change 'OriginalString' content using the above parameters and fn:replace() function.


 <property 

name="ReplacedString"  expression="fn:replace(fn:replace(fn:replace((fn:replace($ctx:OriginalString,'\{ServiceName\}',$ctx:serviceName)), '\{Amount\}',$ctx:amount), '\{KeyWord\}', $ctx:keyword),'\{Shortcode\}',$ctx:shortcode)"

   scope="default" 

   type="STRING" 

   xmlns:fn="http://www.w3.org/2005/xpath-functions" />


After the execution,  a new variable named ‘ReplacedString’ in default scope has new String value as follows.


" Well done, you have subscribed to the Hela Derana News service. Your account will be debited from Rs.10. Free unsubscription the service by sending  STOP HDN to 1122 ". 


2.2 String Concatenation

We can concatenate several strings as follows using fn:concat() .


<property name="string_1" scope="default" type="STRING" value="Example_One "/>

<property name="string_2" scope="default" type="STRING" value="Example_Two "/>

<property name="string_3" scope="default" type="STRING" value="Example_Three "/>  

<property name="concatString"

              expression="fn:concat($ctx:string_1, $ctx:string_2, $ctx:string_3)"

              scope="default" type="STRING"/>


The result is same to 


<property

    name=”concatString”

    value=”Example_One Example_Two Example_Three ”

    scope="default"

    type="STRING"

/>


2.3 String Dividing

2.3.1 Getting string content  after the first occurrence of the given argument 


Suppose there is a string property named 'tele_number' in default scope which value is ‘+9411729729’. Now you need to get only the string value without ‘+94’ prefix and assign its value to new property named 'local_tele_number'. That can be done as follows. 


 <property

 name="'local_tele_number'"

 expression="fn:substring-after(get-property(''tele_number''), '+94')"

 scope="default"

 type="STRING"

/>


2.3.2 Getting string content  before the first occurrence of the given argument


Suppose there is a string property named 'order_item' in default scope which value is ‘Sorny Headset’. Now you need to get only the string value without ‘Headset’’ suffix and assign its value to a new property named 'brand'. That can be done as follows. 


 <property

 name="brand"

 expression="fn:substring-before(get-property(‘order_item’), ' Headset')"

 scope="default"

 type="STRING"

/>


I will discuss more on how to do logging, cloning and filtering in WSO2 ESB sequence in the next article. Thank You.



No comments:

Post a Comment

How to send Slack notification using a Python script?

 In this article,  I am focussing on sending Slack notifications periodically based on the records in the database. Suppose we have to monit...