Monday, August 17, 2015

How to use XQuery in WSO2 ESB

To transfer the message in WSO2 ESB XQuery can also be used like Script, XSLT and payload mediator. XQuery provides the facility to query like database within the xml. We can filter xml response with xml query so based on the requirement we have to use transform mediator.

We can define XQuery in the synapse with below syntax.

<xquery key="string" [target="xpath"]>
    <variable name="string" type="string" [key="string"] [expression="xpath"] [value="string"]/>?
</xquery>

In above syntax we have to provide some parameter as mentioned below.

  • In key we have to provide a unique String name of it which can be used in service logic to call XQuery. It specifies the registry of the XQuery file.
  • Target is an attribute which specifies the node of the SOAP message that should be transformed. By default the first child of the SOAP body is selected.
  • In variable we can pass an attribute or variable value like in java function which can be retrieved in XQuery file to process further.


Console UI:

XQuery comes in the category of transformation, so if you select transform menu, you can see XQuery option in it.


You can fill the required details like Key Type, Key and its Target. Once you click Apply and save, it will be added in your service.


Example:

In this example we are trying to find the details of an employee which belongs to IT department through XQuery mediator.

Define XQuery:

I am giving the XQuery key name is “GetEmployeeDetail_XQ” and also giving its path resides in conf directory.

<localEntry key="GetEmployeeDetail_XQ" src="file:repository/conf/employee/resources/xquery/GetEmployeeDetail.xq"/>

Call XQuery in Synapse:

<xquery key="GetEmployeeDetail_XQ">
<variable name="Department" action="set" value="IT"/>
</xquery>

In this XQuery we are also passing one variable and value of this variable is “IT”.

XQuery:

xquery version "1.0";
declare namespace swj="http://shriwithjava.blogspot.co.nz/";
declare variable $Department as xs:string external;

declare variable $EmployeeName := $EmployeeDetailsResponse/swj:EmployeeDetails[swj:DepartmentNumber=$Department]/swj:EmployeeName/text();
declare variable $EmployeeDesignation := $EmployeeDetailsResponse/swj:EmployeeDetails[swj:DepartmentNumber=$Department]/swj:EmployeeDesignation/text();
declare variable $EmployeeAddress := $EmployeeDetailsResponse/swj:EmployeeDetails[swj:DepartmentNumber=$Department]/swj:EmployeeAddress/text();
declare variable $EmployeePhone := $EmployeeDetailsResponse/swj:EmployeeDetails[swj:DepartmentNumber=$Department]/swj:EmployeePhone/text();

<EMPLOYEE_DETAILS_RESPONSE>
  <EMP_NAME>{$EmployeeName}</EMP_NAME>
  <EMP_DESG>{$EmployeeDesignation}</EMP_DESG>
  <EMP_ADD>{$EmployeeAddress}</EMP_ADD>
  <EMP_PHONE>{$EmployeePhone}</EMP_PHONE>
</EMPLOYEE_DETAILS_RESPONSE>


Retrieve details in Synapse:

From the below Xpath expression we can get the value of Employee belongs to IT department from the XQuery, we have transformed.

<property name="EmployeeName" action="set" expression="//EMPLOYEE_DETAILS_RESPONSE/EMP_NAME/text()"/>
<property name="EmployeeDesignation" action="set" expression="//EMPLOYEE_DETAILS_RESPONSE/EMP_DESG/text()"/>       
<property name="EmployeeAddress" action="set" expression="//EMPLOYEE_DETAILS_RESPONSE/EMP_ADD/text()"/>
<property name="EmployeePhone" action="set" expression="//EMPLOYEE_DETAILS_RESPONSE/EMP_PHONE/text()"/>

Thursday, August 13, 2015

How to use XSLT Mediator in WSO2 ESB

XSLT mediator is used to transform the message as we do in script and payload factory mediator. We can create a structure of xml as required to send or receive in request or response.


To add an xslt mediator go to the IN sequence of the service then add child --àtransform ---à XSLT



You will see the below screen.



Add the details as required then click Apply and finish to add xslt mediator.
To use it direct in synapse file follow the syntax.

<syn:localEntry key="<KEY_NAME>" src="<FILE_PATH>"/>

  • In Key, you have to give a name by which XSLT can be referred in synapse.
  • In source, you have to provide the XSLT file name with its complete path.


Now to call the XSLT in the service, define below syntax, you can also pass some variable in it which will be picked up in XSLT as required.

<syn:xslt key="<KEY_NAME>">
<syn:property name="<PROPERTY_NAME>" expression="<EXPRESSION_VALUE>" type="<DATA_TYPE>"/>
</syn:xslt>       

Write above code to use XSLT, there are some values you have to provide as below.

  • In key, you have to pass the name of the value which has been defined in in “localEntry
  • In property, you can pass variable which will be picked up in XSLT.
  • In expression, you can pass dynamic variable value which we have got from other source.
  • In type, we have to pass data type like String or Integer etc.


XSLT Structure:

<xsl:stylesheet version="2.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:xs="http://www.w3.org/2001/XMLSchema"
     xmlns:fn="http://www.w3.org/2005/xpath-functions"
     exclude-result-prefixes="xs fn xsl">
<!--<xsl:param name="<PASSED PARAMETER FROM SYNAPSE>"/> ->
<xsl:template match="/">
<!-—STRUCTURE OF XML ->
</xsl:template>
</xsl:stylesheet>

Example:

In example we are trying to get employee details through XSLT in desired structure.

Here we are defining the XSLT to be used.

<localEntry key="EmplyeeDetails_XSLT" src="file:repository/conf/EMP/resources/xslt/EmplyeeDetails.xslt"/>

To call this XSLT we are defining below code and also passing two parameters.

<xslt key="EmplyeeDetails_XSLT">
<property name="EmpAddress" expression="get-property('EmpAddress')" type="STRING"/>
<property name="EmpName" expression="get-property('EmpName')" type="STRING"/>
</xslt>         

This is the XSLT we have created to transform the message.

XSLT:

<xsl:stylesheet version="2.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:xs="http://www.w3.org/2001/XMLSchema"
     xmlns:fn="http://www.w3.org/2005/xpath-functions"
       xmlns:emp="http://shriwithjava.blogspot.co.nz/empdetails/"
     exclude-result-prefixes="xs fn xsl">

<xsl:param name="EmpAddress"/>
<xsl:param name="EmpName"/>
<xsl:template match="/">
<emp:GetEmployeeDetails xmlns:emp="http://shriwithjava.blogspot.co.nz/empdetails/">
<emp:empName><xsl:value-of select="$EmpName"></emp:empName>
 <emp:empAddress><xsl:value-of select="$EmpAddress"></emp:empAddress>
    </emp:GetEmployeeDetails>
</xsl:template>
</xsl:stylesheet>

In synapse if we want to get data from this XSLT we can extract value by below property.

<syn:property name="EmpName" expression="//emp:empName"  xmlns:emp="http://shriwithjava.blogspot.co.nz/empdetails/" type="STRING"/>

By the property mediator we can get the transformed value from the XSLT mediator.

Tuesday, August 11, 2015

Exception/Error Handling in WSO2 ESB Endpoint

When we create a service in ESB this needs to be send to a particular end point, in transport layer it might be possible that any error can come so it is necessary to handle this situation wherever an error occurred.

If the end point is not available or due to any firewall issue by which connection time out may occur then your message will be lost. Therefore to overcome from this situation error handling is required.

In endpoint configure for error handling can have below three states.

  • Active: End point is up and ready to handle request.
  • Timeout: An error has come but still message is received. It will keep on receiving message until maximum retries. If it keeps on failing then it will go to suspended state.
  • Suspended: In this state message can’t be received or sent and endpoint result will go in fault. ESB waits until the initial duration to be passed by default it is 30 second. In between if any request gets succeeded then it will go to Active state else in timeout error. ESB waits before retrying messages using the following formula:
Min(current suspension duration * progressionFactor, maximumDuration)


Example:

<endpoint name="EmployyeDetails_EPR">
<address uri="http://XXXX:9773/services/getEmployeeDetails">
<timeout>
<duration>30000</duration>
</timeout>
<markForSuspension>
<errorCodes>101504, 101505</errorCodes>
<retriesBeforeSuspension>3</retriesBeforeSuspension>
<retryDelay>1</retryDelay>
</markForSuspension>
<suspendOnFailure>
<errorCodes>101500, 101501, 101506, 101507, 101508</errorCodes>
<initialDuration>3000</initialDuration>
<progressionFactor>1.0</progressionFactor>
</suspendOnFailure>
</address>
</endpoint>



Timeout Setting

Name
Values
Default
Description
duration
Miliseconds
60000
If within 60 second response does not come then it will go to timeout state
responseAction
discard, fault, none
none
On failure It checks whether message needs to be discarded or need to go in exception handling state
MarkForSuspension State


Name
Values
Default
Description
errorCodes
Comma separated list of error codes
101504, 101505
101504: shows the connection timeout error 101505: connection closed
retriesBeforeSuspension
Integer
0
It shows how many time it can retry to send message
retryDelay
milliseconds
0
wait time between the last retry  and the next retry.

SuspensionOnFailure State

Name
Values
Default
Description
errorCodes
Comma separated error codes
All the errors except the errors specified inmarkForSuspension
Errors that send the endpoint into the "Suspended" state.
initialDuration
milliseconds
30000
This is the default time after this time retry will occur
progressionFactor
Integer
1
The endpoint will try to send the messages after the initialDuration. If it still fails, the next duration is calculated as:
Min(current suspension duration * progressionFactor, maximumDuration)
maximumDuration
milliseconds
Long.MAX_VALUE
Upper bound of retry duration.

Sunday, August 9, 2015

How to change default port number of WSO2 ESB, DSS and BPS

WSO2 product ESB, DSS and BPS by default runs on 9443 port. It is fine if all servers are hosted in different machine but if you have to run locally in one system then port number change is required.

For this Example we are using below versions:

  • ESB: 4.0.3
  • BPS: 2.1.2
  • DSS: 2.5.1

 To change port number in ESB go to wso2esb-4.0.3\repository\conf\carbon.xml under the “ServletTransports” tag you can change your setting.

  <!-- Override the ports defined in mgt-transports.xml -->
        <ServletTransports>
            <HTTPS>9443</HTTPS>
            <HTTP>9773</HTTP>
        </ServletTransports>


When you start the server the port number shows 9443.
Now change port number in “carbon.xml” file with new 9453 port number and again restart your server.

<!-- Override the ports defined in mgt-transports.xml -->
        <ServletTransports>
            <HTTPS>9453</HTTPS>
            <HTTP>9773</HTTP>
        </ServletTransports>

You can see this in logs as well.


Now if you open this highlighted URL in browser the below screen will come and showing that ESB is now running in 9453 port number.



Change port in BPS:

Change in “carbon.xml” file, located in wso2bps-2.1.2\repository\conf\mgt-transports.xml

   <!-- ${Ports.ServletTransports.HTTPS} is defined in the Ports section of the carbon.xml -->
        <parameter name="port">9453</parameter>



Change port in DSS:

Change in “mgt-transports.xml” file located in wso2dataservices-2.5.1\repository\conf folder.

<transport name="https" class="org.wso2.carbon.server.transports.http.HttpsTransport">
        <parameter name="port">9453</parameter>



If there is any requirement like you have to run above 3 servers at a time in your local machine then port number should be different like 9443, 9453 and 9463 or any port number you like.

Saturday, August 8, 2015

How to fetch multiple rows from database in WSO2 ESB using DBLookup or DBReport Mediator

There is no such a way to fetch multiple rows in ESB using DBReport or DBLookup mediator. In ESB these mediator only gives you one row even if you write query to fetch multiple rows. It will give you only the first row from the database.

To fetch multiple rows from Database in ESB you have to use DSS or also you can create your own custom mediator.

You can create dataservice in DSS and call its end point in ESB, this is the simplest way to get multiple rows from database in ESB. To create data service in DSS you can see this blog http://shriwithjava.blogspot.co.nz/2013/08/creating-my-first-data-service-wso2.html.

OR

If you don’t want to use DSS then create your own logic in custom mediator and use in ESB. To create a custom mediator you can follow this blog http://shriwithjava.blogspot.co.nz/2015/08/how-to-write-custom-mediator-in-wso2-esb.html

How to use custom mediator in WSO2 ESB

To use custom mediator you need to first write a mediator, to do so click http://shriwithjava.blogspot.co.nz/2015/08/how-to-write-custom-mediator-in-wso2-esb.html to write custom mediator.
We have already created a mediator in previous blog now we have to use this in ESB. After writing class mediator export it as jar file and put this in below folder.

Folder to put Custom Mediator Jar File

wso2esb-4.0.3\repository\components\lib\MyCustomMediator.jar

We have created jar file from the java class file with the name of ‘MyCustomMediator.jar’ and put this in above folder.
In the synapse file I have created a proxy named “myCustom” in which we will invoke custom mediator.

Synapse Code:

 <proxy name="myCustom" transports="https http" startOnLoad="true" trace="disable" statistics="enable">
<target inSequence="myCustom_IN" />

</proxy>
<sequence name="myCustom_IN">
<log level="full"/>
<property name="email" action="set" value="abc"/>
<property name="pass" action="set" value="pass"/>
<class name="java.is.easy.MyCustomMediator"/>

<property name="email_id" action="set" expression="//p:EmployeeDetails" xmlns:p="http://java.is.easy/custommediator"/>

<log level="full"/>
<send/>
<drop/>
</sequence>


In this above code I have not written proper code or any error handling which can be put in your logic but this is just to call custom mediator.

Now if you call this service you can see that in logs it is showing the details as expected. This mediator is fetching the record from the database and showing this to ESB. Now you can use this data as required in your logic.