Lately, I was working on some transformations in AmberPoint (a SOA Management tool for web services governance and a lightweight ESB because we can do lot of transformations and other ESB related tasks apart from Web Service Management). These transformations requires to manipulate dateTime from 2009-06-23T00:00:00Z pattern to 2009-06-23T00:00:00Z+X minutes. We were trying to integrate with a trading partner who has .NET and requires timestamp signed and as part of timestamp, creation datetime and expiration datetime which is typically creation datetime + X minutes needed.
Any system that supports XPath 2.0, this can be achieved very easily with built-in functions. Ex: Adding minutes/hours/days..etc to existing dateTime is as simple as "add-dayTimeDuration-to-dateTime($arg1 as xs:dateTime, $arg2 as xs:dayTimeDuration)" (it is just one way). Believe it or not the similar thing in XPath 1.0 takes more than hundred lines of code. While XPath 2.0 supports rich set of time, datetime manipulation features, XPath 1.0 just ignores these functions but supports string manipulation functions. Since the barebones string manipulation is allowed, though it will be cumbersome, one can write such functionality.
The following example takes the input in the format "2009-12-31T00:00:59-06:00" and then converts it to "2009-12-31T06:00:59Z" after that it adds "5" minutes to the time to make it "2009-12-31T06:05:59Z"
Here is the XSL (XSLT-DateTime.xsl)
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<xsl:for-each select="sales/summary">
old time <xsl:value-of select="date" />
<xsl:variable name="dt">
<xsl:call-template name="makeGMTTime">
<xsl:with-param name="DateTime" select="date"/>
</xsl:call-template>
</xsl:variable>
gmt time <xsl:value-of select="$dt"/>
exp time <xsl:call-template name="addMinutes">
<xsl:with-param name="DateTime" select="$dt"/>
<xsl:with-param name="deltaMinutes" select="number(5)"/>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<xsl:template name="makeGMTTime">
<xsl:param name="DateTime"/>
<xsl:variable name="year">
<xsl:value-of select="substring($DateTime,1,4)"/>
</xsl:variable>
<xsl:variable name="month">
<xsl:value-of select="substring($DateTime,6,2)"/>
</xsl:variable>
<xsl:variable name="day">
<xsl:value-of select="substring($DateTime,9,2)"/>
</xsl:variable>
<xsl:variable name="hours">
<xsl:value-of select="substring($DateTime,12,2)"/>
</xsl:variable>
<xsl:variable name="minutes">
<xsl:value-of select="substring($DateTime,15,2)"/>
</xsl:variable>
<xsl:variable name="seconds">
<xsl:value-of select="substring($DateTime,18,2)"/>
</xsl:variable>
<xsl:variable name="deltahours">
<xsl:value-of select="substring($DateTime,21,2)"/>
</xsl:variable>
<xsl:variable name="thours">
<xsl:value-of select="$hours + $deltahours"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="$thours > 23">
<xsl:variable name="nhours">
<xsl:call-template name="resetHours">
<xsl:with-param name="hours" select="$thours"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="ldayofmonth">
<xsl:call-template name="last-day-of-month">
<xsl:with-param name="month" select="$month"/>
<xsl:with-param name="year" select="$year"/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$day = $ldayofmonth">
<xsl:variable name="nday">
<xsl:value-of select="concat('0','1')"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="$month + 1 > 12">
<xsl:variable name="nmonth">
<xsl:value-of select="concat('0','1')"/>
</xsl:variable>
<xsl:variable name="nyear">
<xsl:value-of select="$year + 1"/>
</xsl:variable>
<xsl:value-of
select="concat($nyear,'-',$nmonth,'-',$nday,'T',$nhours,':',$minutes,':',$seconds,'Z')"/>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="nmonth">
<xsl:call-template name="resetMonths">
<xsl:with-param name="months" select="$month+1"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="nyear">
<xsl:value-of select="$year"/>
</xsl:variable>
<xsl:value-of
select="concat($nyear,'-',$nmonth,'-',$nday,'T',$nhours,':',$minutes,':',$seconds,'Z')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="nday">
<xsl:call-template name="resetDays">
<xsl:with-param name="days" select="$day+1"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="nmonth">
<xsl:value-of select="$month"/>
</xsl:variable>
<xsl:variable name="nyear">
<xsl:value-of select="$year"/>
</xsl:variable>
<xsl:value-of
select="concat($nyear,'-',$nmonth,'-',$nday,'T',$nhours,':',$minutes,':',$seconds,'Z')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="nhours">
<xsl:call-template name="resetHours">
<xsl:with-param name="hours" select="$thours"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="nday">
<xsl:value-of select="$day"/>
</xsl:variable>
<xsl:variable name="nmonth">
<xsl:value-of select="$month"/>
</xsl:variable>
<xsl:variable name="nyear">
<xsl:value-of select="$year"/>
</xsl:variable>
<xsl:value-of
select="concat($nyear,'-',$nmonth,'-',$nday,'T',$nhours,':',$minutes,':',$seconds,'Z')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="addMinutes">
<xsl:param name="DateTime" />
<xsl:param name="deltaMinutes" />
<xsl:variable name="year">
<xsl:value-of select="substring($DateTime,1,4)" />
</xsl:variable>
<xsl:variable name="month">
<xsl:value-of select="substring($DateTime,6,2)" />
</xsl:variable>
<xsl:variable name="day">
<xsl:value-of select="substring($DateTime,9,2)" />
</xsl:variable>
<xsl:variable name="hours">
<xsl:value-of select="substring($DateTime,12,2)" />
</xsl:variable>
<xsl:variable name="minutes">
<xsl:value-of select="substring($DateTime,15,2)" />
</xsl:variable>
<xsl:variable name="seconds">
<xsl:value-of select="substring($DateTime,18,2)" />
</xsl:variable>
<xsl:variable name="adjhours">
<xsl:value-of select="substring($DateTime,21,2)" />
</xsl:variable>
<xsl:choose>
<xsl:when test="$minutes + $deltaMinutes > 59">
<xsl:variable name="tmins">
<xsl:value-of select="$minutes + $deltaMinutes - 60" />
</xsl:variable>
<xsl:variable name="nmins">
<xsl:value-of select="concat('0',string($tmins))" />
</xsl:variable>
<xsl:choose>
<xsl:when test="$hours = 23">
<xsl:variable name="nhours">
<xsl:value-of select="concat('0','0')" />
</xsl:variable>
<xsl:variable name="ldayofmonth">
<xsl:call-template name="last-day-of-month">
<xsl:with-param name="month" select="$month"/>
<xsl:with-param name="year" select="$year"/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$day = $ldayofmonth">
<xsl:variable name="nday">
<xsl:value-of select="concat('0','1')" />
</xsl:variable>
<xsl:choose>
<xsl:when test="$month + 1 > 12">
<xsl:variable name="nmonth">
<xsl:value-of select="concat('0','1')" />
</xsl:variable>
<xsl:variable name="nyear">
<xsl:value-of select="$year + 1" />
</xsl:variable>
<xsl:value-of select="concat($nyear,'-',$nmonth,'-',$nday,'T',$nhours,':',$nmins,':',$seconds,'Z')"/>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="nmonth">
<xsl:call-template name="resetMonths">
<xsl:with-param name="months" select="$month + 1"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="nyear">
<xsl:value-of select="$year" />
</xsl:variable>
<xsl:value-of select="concat($nyear,'-',$nmonth,'-',$nday,'T',$nhours,':',$nmins,':',$seconds,'Z')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="nday">
<xsl:value-of select="$day + 1" />
</xsl:variable>
<xsl:variable name="nmonth">
<xsl:value-of select="$month" />
</xsl:variable>
<xsl:variable name="nyear">
<xsl:value-of select="$year" />
</xsl:variable>
<xsl:value-of select="concat($nyear,'-',$nmonth,'-',$nday,'T',$nhours,':',$nmins,':',$seconds,'Z')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$hours < 8">
<xsl:variable name="nhours">
<xsl:value-of select="concat('0',string($hours + 1))" />
</xsl:variable>
<xsl:variable name="nday">
<xsl:value-of select="$day" />
</xsl:variable>
<xsl:variable name="nmonth">
<xsl:value-of select="$month" />
</xsl:variable>
<xsl:variable name="nyear">
<xsl:value-of select="$year" />
</xsl:variable>
<xsl:value-of select="concat($nyear,'-',$nmonth,'-',$nday,'T',$nhours,':',$nmins,':',$seconds,'Z')"/>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="nhours">
<xsl:value-of select="$hours + 1" />
</xsl:variable>
<xsl:variable name="nday">
<xsl:value-of select="$day" />
</xsl:variable>
<xsl:variable name="nmonth">
<xsl:value-of select="$month" />
</xsl:variable>
<xsl:variable name="nyear">
<xsl:value-of select="$year" />
</xsl:variable>
<xsl:value-of select="concat($nyear,'-',$nmonth,'-',$nday,'T',$nhours,':',$nmins,':',$seconds,'Z')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="nmins">
<xsl:call-template name="resetMinutes">
<xsl:with-param name="minutes" select="$minutes + $deltaMinutes"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="nhours">
<xsl:value-of select="$hours" />
</xsl:variable>
<xsl:variable name="nday">
<xsl:value-of select="$day" />
</xsl:variable>
<xsl:variable name="nmonth">
<xsl:value-of select="$month" />
</xsl:variable>
<xsl:variable name="nyear">
<xsl:value-of select="$year" />
</xsl:variable>
<xsl:value-of select="concat($nyear,'-',$nmonth,'-',$nday,'T',$nhours,':',$nmins,':',$seconds,'Z')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="last-day-of-month">
<xsl:param name="month"/>
<xsl:param name="year"/>
<xsl:choose>
<xsl:when test="$month = 2 and
not($year mod 4) and
($year mod 100 or not($year mod 400))">
<xsl:value-of select="29"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of
select="substring('312831303130313130313031',
2 * $month - 1,2)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="resetHours">
<xsl:param name="hours"/>
<xsl:choose>
<xsl:when test="$hours = 24">
<xsl:value-of select="concat('0','0')"/>
</xsl:when>
<xsl:when test="$hours > 24">
<xsl:value-of select="concat('0',string($hours - 24))"/>
</xsl:when>
<xsl:when test="$hours < 10">
<xsl:value-of select="concat('0',string($hours))"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$hours"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="resetDays">
<xsl:param name="days"/>
<xsl:choose>
<xsl:when test="$days < 10">
<xsl:value-of select="concat('0',string($days))"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$days"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="resetMinutes">
<xsl:param name="minutes"/>
<xsl:choose>
<xsl:when test="$minutes < 10">
<xsl:value-of select="concat('0',string($minutes))"/>
</xsl:when>
<xsl:when test="$minutes > 60 ">
<xsl:value-of select="concat('0',string($minutes - 60))"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$minutes"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="resetMonths">
<xsl:param name="months"/>
<xsl:choose>
<xsl:when test="$months > 12">
<xsl:value-of select="concat('0',string($months - 12))"/>
</xsl:when>
<xsl:when test="$months < 10">
<xsl:value-of select="concat('0',string($months))"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$months"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Here is the XML for testing it
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="XSLT-DateTime.xsl"?>
<sales>
<summary>
<date>2009-12-31T00:00:59-06:00</date>
</summary>
<summary>
<date>2009-12-31T18:00:59-06:00</date>
</summary>
<summary>
<date>2009-12-31T00:10:59-04:00</date>
</summary>
<summary>
<date>2009-12-31T00:08:59-05:00</date>
</summary>
<summary>
<date>2009-12-31T01:01:59-04:00</date>
</summary>
<summary>
<date>2009-12-31T07:01:59-04:00</date>
</summary>
<summary>
<date>2009-12-31T05:56:59-04:00</date>
</summary>
<summary>
<date>2009-12-31T23:55:59-04:00</date>
</summary>
<summary>
<date>2012-02-28T23:55:59-04:00</date>
</summary>
<summary>
<date>2009-12-31T19:55:59-04:00</date>
</summary>
<summary>
<date>2012-02-28T07:06:59-04:00</date>
</summary>
<summary>
<date>2012-02-28T19:57:59-04:00</date>
</summary>
<summary>
<date>2012-02-29T19:57:59-04:00</date>
</summary>
<summary>
<date>2012-01-31T19:57:59-04:00</date>
</summary>
<summary>
<date>2012-03-31T19:57:59-04:00</date>
</summary>
<summary>
<date>2012-04-30T19:57:59-04:00</date>
</summary>
<summary>
<date>2012-05-31T19:57:59-04:00</date>
</summary>
<summary>
<date>2012-06-30T19:57:59-04:00</date>
</summary>
<summary>
<date>2012-07-31T19:57:59-04:00</date>
</summary>
<summary>
<date>2012-08-31T19:57:59-04:00</date>
</summary>
<summary>
<date>2012-09-30T19:57:59-04:00</date>
</summary>
<summary>
<date>2012-10-31T19:57:59-04:00</date>
</summary>
<summary>
<date>2012-11-30T19:57:59-04:00</date>
</summary>
<summary>
<date>2012-12-31T19:57:59-04:00</date>
</summary>
</sales>
You are free to use, refactor, distribute the above code without any limitations.
References:
Determining the Last Day of the Month: http://my.safaribooksonline.com/0596009747/xsltckbk2-CHP-4-SECT-4#X2ludGVybmFsX1NlY3Rpb25Db250ZW50P3htbGlkPTA1OTYwMDk3NDcveHNsdGNrYmsyLUNIUC00LVNFQ1QtMg==
Tuesday, June 23, 2009
Tuesday, October 14, 2008
Mashups and SOA
The recent buzz in the IT industry apart from SOA is "Mashups". While SOA mainly focus on Web Services, Mashups deal with bringing data from various systems together.
Wikipedia defines Mashup as a web application that combines data from more than one source into a single integrated tool. RSS, Web Pages, Databases, Web Services, and even custom code can be sources for Mashups. Data can be made available using different protocols like Web Services (SOAP), REST, or RSS.
Based on the type of activities that are done with the mashups, mashups can be categorized as data mashups, consumer mashups, and business mashups, etc. While there is no clear separation among the mashups the underlying concepts or technologies are the same.
We can classify mahsups as next generation Portals as there are many similarities in the functionality and concepts. At present there are no specific standards (just for the mashups) like portals which have JSR 168, JSR 286 etc. but follow some of the XML, Web Services and REST standards.
Some of the aspects or focuses of SOA are governance and service reuse or service composition. With some of the commercial Mashup tools both of these things can be easily done and infact service composition is the goal of mashups. Lately Data Services are also focus of rapid development and SOA and these data services are focus of Mashups also.
Some of the known mashup tools in the market/industry are WSO2 Mashup Server (open source), JackBe Presto, Serena Business Mashups, Nexaweb Enterprise Web Suite, RSSBus, Apatar (open source), Kapow's Web Harvesting Tools, Backbase, etc. Most of these tools focus on bringing RIA usage to the users apart from mashups.
If properly used in SOA for the service composition and to feed the data for portals or to serve as portals these can be potential candidates for good ROI.
Wikipedia defines Mashup as a web application that combines data from more than one source into a single integrated tool. RSS, Web Pages, Databases, Web Services, and even custom code can be sources for Mashups. Data can be made available using different protocols like Web Services (SOAP), REST, or RSS.
Based on the type of activities that are done with the mashups, mashups can be categorized as data mashups, consumer mashups, and business mashups, etc. While there is no clear separation among the mashups the underlying concepts or technologies are the same.
We can classify mahsups as next generation Portals as there are many similarities in the functionality and concepts. At present there are no specific standards (just for the mashups) like portals which have JSR 168, JSR 286 etc. but follow some of the XML, Web Services and REST standards.
Some of the aspects or focuses of SOA are governance and service reuse or service composition. With some of the commercial Mashup tools both of these things can be easily done and infact service composition is the goal of mashups. Lately Data Services are also focus of rapid development and SOA and these data services are focus of Mashups also.
Some of the known mashup tools in the market/industry are WSO2 Mashup Server (open source), JackBe Presto, Serena Business Mashups, Nexaweb Enterprise Web Suite, RSSBus, Apatar (open source), Kapow's Web Harvesting Tools, Backbase, etc. Most of these tools focus on bringing RIA usage to the users apart from mashups.
If properly used in SOA for the service composition and to feed the data for portals or to serve as portals these can be potential candidates for good ROI.
Tuesday, September 30, 2008
Mock Web Services with WSO2-ESB
Mock Web Services are not actual web services but behave like real web services. In general these services have interfaces defined but the implementation (business logic and coding) is not yet done. Mock Web Services (will use Mock Services for simplicity) are helpful for the service consumers or for the developers who are developing services based on some other web services. If the depending services are not yet available this will delay their development. With the help of Mock Services one can start coding/developing or consuming the services. Also when the actual services can not be accessed for any reason then mock services are helpful.
For the demo of Mock Services, I am considering Amazon Web Services particularly AlexaWebSearch service listed at http://wsearch.amazonaws.com/doc/2007-03-15/AlexaWebSearch.wsdl. Let us say that, Amazon has published the interface at that given url but the service is not yet ready. It is known how the request and response look like. Now with the help of Mock Services, the users that are interested in can start developing their application and can simulate some test cases.
Using Mock Services encourage some of best practices (1) Contract First Design (2) Decouples the dependency of deliverables (Initially).
In this post, I will explain how to develop Mock Services using WSO2-ESB.
(1) Download and install latest WSO2-ESB (1.7.1 today) from here.
We will download binaries, after download extract the zip file to c:\. It will create the following structure.
From now on wards C:\wso2esb-1.7.1 is referred as %ESB_HOME%
The default ports & passwords used by ESB are mentioned below:
You can change any of the above ports or userid/passwords by changing the %ESB_HOME%
\webapp\WEB-INF\classes\conf\server.xml
ESB Management Console port (default) is 9444 which can be changed by changing %ESB_HOME%\tomcat\conf\tomcat.properties file.
(2) You can start the ESB by running the windows batch file %ESB_HOME%\bin\wso2-esb.bat.
Access the managment console by opening the page at https://localhost:9444/esb
After successful logging, it will take us to the following screen where the left side has links for proxies, sequences, endpoints, tasks, registry, configuration, statistics..etc most of them are self explanatory (at least for the folks in SOA or trying to be in SOA)
Adding Mock Service is a three step procedure. (a) Determine the response for the mock service operations and prepare xslt (b) Define the sequence (c) Create Proxy Service and apply the xslt and sequences. We can combine these steps into one step if we start with creating proxy. In this example we will create mock service in three steps.
(3) Access the WSDL from http://wsearch.amazonaws.com/doc/2007-03-15/AlexaWebSearch.wsdl and save the contents to a file(ex: AlexaWebSearch.wsdl). Sample services request and responses are provided here http://docs.amazonwebservices.com/AlexaWebSearch/2007-03-15/SOAP_SoapAuthenticationArticle.html. Save the request and responses to AlexaWebSearch-Request.xml and AlexaWebSearch-Response.xml files, we are going to use this sample response for our Mock Service.
We have the following soap response in the AlexaWebSearch-Response.xml
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<ns1:SearchResponse xmlns:ns1="http://wsearch.amazonaws.com/doc/2007-03-15/">
<ns1:SearchResult>
<ns1:SearchTerms>java</ns1:SearchTerms>
<ns1:EstimatedNumberOfDocuments>87568000</ns1:EstimatedNumberOfDocuments>
<ns1:Documents>
<ns1:Document>
<ns1:Url>http://java.com/en/download/index.jsp</ns1:Url>
<ns1:Title>Download Free Java Software</ns1:Title>
<ns1:Bytes>11360</ns1:Bytes>
<ns1:Checksum>AAAAAAABAkY=</ns1:Checksum>
</ns1:Document>
</ns1:Documents>
</ns1:SearchResult>
<ns1:ResponseMetaData>
<ns1:RequestId>09b4accb-ff51-4145-9988-25d38dfcb705</ns1:RequestId>
</ns1:ResponseMetaData>
</ns1:SearchResponse>
</soapenv:Body>
</soapenv:Envelope>
Modify it as followed to make it xsl transformation which we will use for sending the custom response from the mock service.
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:template match="/">
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<ns1:SearchResponse xmlns:ns1="http://wsearch.amazonaws.com/doc/2007-03-15/">
<ns1:SearchResult>
<ns1:SearchTerms>java</ns1:SearchTerms>
<ns1:EstimatedNumberOfDocuments>87568000</ns1:EstimatedNumberOfDocuments>
<ns1:Documents>
<ns1:Document>
<ns1:Url>http://java.com/en/download/index.jsp</ns1:Url>
<ns1:Title>Download Free Java Software</ns1:Title>
<ns1:Bytes>11360</ns1:Bytes>
<ns1:Checksum>AAAAAAABAkY=</ns1:Checksum>
</ns1:Document>
</ns1:Documents>
</ns1:SearchResult>
<ns1:ResponseMetaData>
<ns1:RequestId>09b4accb-ff51-4145-9988-25d38dfcb705</ns1:RequestId>
</ns1:ResponseMetaData>
</ns1:SearchResponse>
</soapenv:Body>
</soapenv:Envelope>
</xsl:template>
</xsl:stylesheet>
Add the contents of the above xslt file to integrated registry by clikcing "Integrated Registry" followed by "XSLT", then provide a name (SnowBoard) and click create to save the xslt in the registry as shown below
Follow similar steps for creating WSDL called AlexaWebSearch inside registry.
(4) Now it is time to define what to do with the Mock Service request. Once a request to ESB comes, we need to take the request and ignore where it should be routed and then send the previously built custom response back.
To add a sequence to the registry click "Sequences" and then "Add" button in the management console.
After that click "Add Mediator" and select "Filters"-->"In" and again add "Filters"-->"Out" as shown below.
After that, click "Add Mediator" inside "In Mediator" and then select "Transform"-->"XSLT"
Click the "Registry Browser" button next to "Key" form value field and then browse "XSLT", pick "AlexaWebSearch" and then click "updated" as shown below:
Now we have defined the outgoing message structure in the sequence. We need to indicate that we are going to send the response and we will strip down the "header" (if any in the request) from the outgoing message and then we are going to send out the message.
To indicate that we are sending response back, add the property named "RESPONSE" and set its value to "true" as shown below
To remove the header from the response follow as shown below.
Finally to send the response back add the "send" sequence as shown below and then click "Save As" and save the sequence.
This whole sequence is represented in the Apache Synapse (which is used in the WSO2-ESB) in the sequences as below, which you can find it in the configuration:
<syn:sequence statistics="enable" name="AlexaWebSearch" trace="enable">
<syn:in>
<syn:xslt key="XSLT/AlexaWebSearch"/>
<syn:property name="RESPONSE" value="true"/>
<syn:header name="To" action="remove"/>
<syn:send/>
</syn:in>
<syn:out/>
</syn:sequence>
(You can avoid creating the whole sequnce manually, isntead you can copy paste the above sequnecne text inside the configuration and then hit "update" button which will create the sequence and after that save the configuration.)
Now we have the mock response and the behavior that is required to act like a mock service. We are ready to define the proxy service (mock service) and attache the above defined behavior and response objects to it.
(5) Create a new proxy from the ESB Management console by clicking "Proxy Services" and after that "Add" as shown below.
This will lead to the form for defining and creating a proxy service as shown below:
Enter the proxy service name as "AlexaWebSearch" and then click select the drop down for the "Incoming Messages" and choose "AlexaWebSearch" sequence from the declared sequnces as shown below
After that click advanced and disable unwated protocols and then click "Next" and "Next". Click the Registry Browser and browse the registry and pick the "WSDL" and then click finish.
You can verify the newly created Mock Service (proxy) by cliking "Proxy Services" on the left.
Enable the logs and statistics as shown below for this newly created service.
Congrats...now we have created a mock service successfully using WSO2-ESB. Irrespective of the request message, we will be getting only one response back as per our "xslt". One can configure various responses based on the user needs or based on the incoming requests.
(6) I have used SoapUI for testing this Mock Service and below are the request and responses.
For the demo of Mock Services, I am considering Amazon Web Services particularly AlexaWebSearch service listed at http://wsearch.amazonaws.com/doc/2007-03-15/AlexaWebSearch.wsdl. Let us say that, Amazon has published the interface at that given url but the service is not yet ready. It is known how the request and response look like. Now with the help of Mock Services, the users that are interested in can start developing their application and can simulate some test cases.
Using Mock Services encourage some of best practices (1) Contract First Design (2) Decouples the dependency of deliverables (Initially).
In this post, I will explain how to develop Mock Services using WSO2-ESB.
(1) Download and install latest WSO2-ESB (1.7.1 today) from here.
We will download binaries, after download extract the zip file to c:\. It will create the following structure.
From now on wards C:\wso2esb-1.7.1 is referred as %ESB_HOME%
The default ports & passwords used by ESB are mentioned below:
RMIRegistryPort: 1099 RMI Registry port used for JMX
HTTPPort: 8280 HTTP port used by the underlying
Axis2/Synapse
HTTPSPort: 8243 HTTPS port used by the
underlying Axis2/Synapse
DerbyPort: 1528 Internal Derby Database port
userid/password: admin/admin
esb/esb
You can change any of the above ports or userid/passwords by changing the %ESB_HOME%
\webapp\WEB-INF\classes\conf\server.xml
ESB Management Console port (default) is 9444 which can be changed by changing %ESB_HOME%\tomcat\conf\tomcat.properties file.
(2) You can start the ESB by running the windows batch file %ESB_HOME%\bin\wso2-esb.bat.
Access the managment console by opening the page at https://localhost:9444/esb
After successful logging, it will take us to the following screen where the left side has links for proxies, sequences, endpoints, tasks, registry, configuration, statistics..etc most of them are self explanatory (at least for the folks in SOA or trying to be in SOA)
Adding Mock Service is a three step procedure. (a) Determine the response for the mock service operations and prepare xslt (b) Define the sequence (c) Create Proxy Service and apply the xslt and sequences. We can combine these steps into one step if we start with creating proxy. In this example we will create mock service in three steps.
(3) Access the WSDL from http://wsearch.amazonaws.com/doc/2007-03-15/AlexaWebSearch.wsdl and save the contents to a file(ex: AlexaWebSearch.wsdl). Sample services request and responses are provided here http://docs.amazonwebservices.com/AlexaWebSearch/2007-03-15/SOAP_SoapAuthenticationArticle.html. Save the request and responses to AlexaWebSearch-Request.xml and AlexaWebSearch-Response.xml files, we are going to use this sample response for our Mock Service.
We have the following soap response in the AlexaWebSearch-Response.xml
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<ns1:SearchResponse xmlns:ns1="http://wsearch.amazonaws.com/doc/2007-03-15/">
<ns1:SearchResult>
<ns1:SearchTerms>java</ns1:SearchTerms>
<ns1:EstimatedNumberOfDocuments>87568000</ns1:EstimatedNumberOfDocuments>
<ns1:Documents>
<ns1:Document>
<ns1:Url>http://java.com/en/download/index.jsp</ns1:Url>
<ns1:Title>Download Free Java Software</ns1:Title>
<ns1:Bytes>11360</ns1:Bytes>
<ns1:Checksum>AAAAAAABAkY=</ns1:Checksum>
</ns1:Document>
</ns1:Documents>
</ns1:SearchResult>
<ns1:ResponseMetaData>
<ns1:RequestId>09b4accb-ff51-4145-9988-25d38dfcb705</ns1:RequestId>
</ns1:ResponseMetaData>
</ns1:SearchResponse>
</soapenv:Body>
</soapenv:Envelope>
Modify it as followed to make it xsl transformation which we will use for sending the custom response from the mock service.
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:template match="/">
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<ns1:SearchResponse xmlns:ns1="http://wsearch.amazonaws.com/doc/2007-03-15/">
<ns1:SearchResult>
<ns1:SearchTerms>java</ns1:SearchTerms>
<ns1:EstimatedNumberOfDocuments>87568000</ns1:EstimatedNumberOfDocuments>
<ns1:Documents>
<ns1:Document>
<ns1:Url>http://java.com/en/download/index.jsp</ns1:Url>
<ns1:Title>Download Free Java Software</ns1:Title>
<ns1:Bytes>11360</ns1:Bytes>
<ns1:Checksum>AAAAAAABAkY=</ns1:Checksum>
</ns1:Document>
</ns1:Documents>
</ns1:SearchResult>
<ns1:ResponseMetaData>
<ns1:RequestId>09b4accb-ff51-4145-9988-25d38dfcb705</ns1:RequestId>
</ns1:ResponseMetaData>
</ns1:SearchResponse>
</soapenv:Body>
</soapenv:Envelope>
</xsl:template>
</xsl:stylesheet>
Follow similar steps for creating WSDL called AlexaWebSearch inside registry.
(4) Now it is time to define what to do with the Mock Service request. Once a request to ESB comes, we need to take the request and ignore where it should be routed and then send the previously built custom response back.
To add a sequence to the registry click "Sequences" and then "Add" button in the management console.
After that click "Add Mediator" and select "Filters"-->"In" and again add "Filters"-->"Out" as shown below.
After that, click "Add Mediator" inside "In Mediator" and then select "Transform"-->"XSLT"
Click the "Registry Browser" button next to "Key" form value field and then browse "XSLT", pick "AlexaWebSearch" and then click "updated" as shown below:
Now we have defined the outgoing message structure in the sequence. We need to indicate that we are going to send the response and we will strip down the "header" (if any in the request) from the outgoing message and then we are going to send out the message.
To indicate that we are sending response back, add the property named "RESPONSE" and set its value to "true" as shown below
To remove the header from the response follow as shown below.
Finally to send the response back add the "send" sequence as shown below and then click "Save As" and save the sequence.
This whole sequence is represented in the Apache Synapse (which is used in the WSO2-ESB) in the sequences as below, which you can find it in the configuration:
<syn:sequence statistics="enable" name="AlexaWebSearch" trace="enable">
<syn:in>
<syn:xslt key="XSLT/AlexaWebSearch"/>
<syn:property name="RESPONSE" value="true"/>
<syn:header name="To" action="remove"/>
<syn:send/>
</syn:in>
<syn:out/>
</syn:sequence>
(You can avoid creating the whole sequnce manually, isntead you can copy paste the above sequnecne text inside the configuration and then hit "update" button which will create the sequence and after that save the configuration.)
Now we have the mock response and the behavior that is required to act like a mock service. We are ready to define the proxy service (mock service) and attache the above defined behavior and response objects to it.
(5) Create a new proxy from the ESB Management console by clicking "Proxy Services" and after that "Add" as shown below.
This will lead to the form for defining and creating a proxy service as shown below:
Enter the proxy service name as "AlexaWebSearch" and then click select the drop down for the "Incoming Messages" and choose "AlexaWebSearch" sequence from the declared sequnces as shown below
After that click advanced and disable unwated protocols and then click "Next" and "Next". Click the Registry Browser and browse the registry and pick the "WSDL" and then click finish.
You can verify the newly created Mock Service (proxy) by cliking "Proxy Services" on the left.
Enable the logs and statistics as shown below for this newly created service.
Congrats...now we have created a mock service successfully using WSO2-ESB. Irrespective of the request message, we will be getting only one response back as per our "xslt". One can configure various responses based on the user needs or based on the incoming requests.
(6) I have used SoapUI for testing this Mock Service and below are the request and responses.
Wednesday, September 10, 2008
SOA Management Systems
The goal of this post is to introduce SOA Management Systems and some of their capabilities.
Service Oriented Architecture (SOA) is now-a-days an important buzz word for most of the moderately big organizations. While most of the organizations are trying to achieve it through "Web Services" there can be other implementations as well. With the increasing popularity of SOA and its inception via Web Services, web service management or SOA Management is a key step for success.
There are many products in the industry which are providing such solutions, Amberpoint, Progress Actional, Tibco ActiveMatrix, Oracle ClearApp, etc. With the help of these tools one can separate the security concerns to an extent and can focus primarily on deliverables (developing code for business logic rather than for security). Some of the other features are logging, security (authorization, authentication, SAML, etc), transaction control/management, service level agreement (SLA) based policies and various custom policies.
Based on the deployment architecture, application/web servers used and hardware/software some of the tools can provide visibility inside the web services by instrumenting the class loaders. While it is totally based on the requirements whether to go for this additional visibility or not, going for this will create lot of information which may cause adverse performance issues.
Most of the products enforce policies based on Proxy mechanism. While proxies gives power also comes with the tightly coupling architecture with them.
In summary there are many SOA Management Systems out there in the market and most of them separate the concerns for logging, security, and policies there by helping in delivarables and return on investment (ROI).
Note: Amberpoint, Progress Actional, Tibco ActiveMatrix, Oracle ClearApp are registered trademarks of respective companies.
Service Oriented Architecture (SOA) is now-a-days an important buzz word for most of the moderately big organizations. While most of the organizations are trying to achieve it through "Web Services" there can be other implementations as well. With the increasing popularity of SOA and its inception via Web Services, web service management or SOA Management is a key step for success.
There are many products in the industry which are providing such solutions, Amberpoint, Progress Actional, Tibco ActiveMatrix, Oracle ClearApp, etc. With the help of these tools one can separate the security concerns to an extent and can focus primarily on deliverables (developing code for business logic rather than for security). Some of the other features are logging, security (authorization, authentication, SAML, etc), transaction control/management, service level agreement (SLA) based policies and various custom policies.
Based on the deployment architecture, application/web servers used and hardware/software some of the tools can provide visibility inside the web services by instrumenting the class loaders. While it is totally based on the requirements whether to go for this additional visibility or not, going for this will create lot of information which may cause adverse performance issues.
Most of the products enforce policies based on Proxy mechanism. While proxies gives power also comes with the tightly coupling architecture with them.
In summary there are many SOA Management Systems out there in the market and most of them separate the concerns for logging, security, and policies there by helping in delivarables and return on investment (ROI).
Note: Amberpoint, Progress Actional, Tibco ActiveMatrix, Oracle ClearApp are registered trademarks of respective companies.
Subscribe to:
Posts (Atom)