Thursday, June 28, 2012
UNIX History
Unix is a multitasking, multi-user computer operating system originally developed in 1969 by a group of AT&T employees at Bell Labs, including Ken Thompson, Dennis Ritchie, Brian Kernighan, Douglas McIlroy, Michael Lesk and Joe Ossanna. The Unix operating system was first developed in assembly language, but by 1973 had been almost entirely recoded in C, greatly facilitating its further
Friday, May 18, 2012
Managing SOA artifacts in different environments using WSO2 Governance Registry
NOTE:
Please note that the instructions given in this blog post are applicable ONLY for ESB-4.0.X and G-reg-4.1.X, G-reg-4.5.0 versions. The deployment approach of the latest ESB versions has been changed and the recommended deployment synchronization approach has been switched to SVN based synchronizer. Because of that the following set of instructions cannot be applied to the latest WSO2 ESB and G-reg product versions.
Managing artifacts of a service oriented solution is one of the most important features expected from any SOA middleware platform. In a typical service oriented project, SOA artifacts are subjected to move through multiple phases. Usually, separate environments are maintained for the activities associated with those phases.
e.g:-
- Development environment
- QA environment
When the service oriented solution becomes complex and there are large number of SOA artifacts, automated artifact governance mechanism is required to ensure smooth transition between various environments. In this post, I will take you through a simplified SOA artifact governance process using WSO2 SOA middleware stack. We will explore a use case similar to the following.
Separate development and QA environments are used to maintain the SOA artifacts. For example, solution developers implement various configuration artifacts in ESB development node. After completing those development tasks, solution developers move those artifacts in to QA environment which allows the testers to carryout QA activities in an independent environment. The moving of artifacts will be done automatically using the features provided by central SOA governance solution.
In this example, we will use WSO2 ESB as the enterprise service bus middleware, WSO2 Governance Registry as the SOA governance solution.
Lets go through each of the steps in detail. We need to have 2 WSO2 ESB instances and 1 WSO2 G-reg instance which runs on mySQL. All these instances will be deployed in single host.
Setting up G-reg and ESB products
Step 1
Download the latest versions of WSO2 ESB and WSO2 G-reg from here. First we will configure WSO2 G-reg instance. Extract wso2greg-4.x.x.zip into your file system. We will refer to the extracted location as GREG_HOME.
By default, WSO2 products run on the file based embedded H2 database. Since we need two ESB instances connect to the database used by G-reg instance, we will configure G-reg to run on a mySQL database. Enter the following commands to create a database and grant permission to a user.
mysql> create database greg_db;
Query OK, 1 row affected (0.00 sec)
mysql> use greg_db;
Database changed
mysql> grant all on greg_db.* to regadmin@localhost identified by "regadmin";
Query OK, 0 rows affected (0.05 sec)
Step 2
Now, we need to change the default database configuration in G-reg instance through registry.xml configuration file. Open GREG_HOME/repository/conf/registry.xml and update dbConfig element as shown below.
<dbConfig name="wso2registry">Copy mysql jdbc driver to GREG_HOME/repository/components/lib and start G-reg server by running wso2server.sh
<url>jdbc:mysql://localhost:3306/greg_db</url>
<userName>regadmin</userName>
<password>regadmin</password>
<driverName>com.mysql.jdbc.Driver</driverName>
<maxActive>50</maxActive>
<maxWait>60000</maxWait>
<minIdle>5</minIdle>
</dbConfig>
Step 3
We have completed the configurations of WSO2 Governance Registry instance. Lets move forward with setting up ESB instance in development environment.
Extract the downloaded wso2esb-4.x.x.zip into a directory in your file system. We will refer to this directory as ESBDEV_HOME. Since we are running all product instances in a single machine, we need to start them up in different ports. Therefore, change port offset parameter in ESBDEV_HOME/repository/conf/carbon.xml as follows.
<Offset>1</Offset>Step 4
As shown in the above diagram, we will mount /_system/config collection, where the ESB artifacts are stored in to /_system/dev collection of G-reg instance. ESBDEV_HOME/repository/conf/registry.xml is used to configure that.
<dbConfig name="configgovregistry">Start ESB dev instance. If you log in to management console of the ESB instance (https://localhost:9444/carbon) and access registry browser, you will notice the config and governance collections are mounted (See the arrow icons) to the remote G-reg database.
<url>jdbc:mysql://localhost:3306/greg_db</url>
<userName>regadmin</userName>
<password>regadmin</password>
<driverName>com.mysql.jdbc.Driver</driverName>
<maxActive>50</maxActive>
<maxWait>60000</maxWait>
<minIdle>5</minIdle>
</dbConfig>
<remoteInstance url="https://localhost:9443/registry">
<id>configgov</id>
<dbConfig>configgovregistry</dbConfig>
<readOnly>false</readOnly>
<enableCache>true</enableCache>
<registryRoot>/</registryRoot>
</remoteInstance>
<mount path="/_system/config" overwrite="true">
<instanceId>configgov</instanceId>
<targetPath>/_system/dev</targetPath>
</mount>
<mount path="/_system/governance" overwrite="true">
<instanceId>configgov</instanceId>
<targetPath>/_system/governance</targetPath>
</mount>
Step 5
Repeat step 3 and 4 with another copy of wso2esb-4.x.x.zip. Lets call it ESBQA instance. (The root directory of ESBQA instance will be referred to as ESBQA_HOME). Make sure to specify a different offset value in carbon.xml. In this instance, we will mount /_system/config collection to /_system/qa collection of G-reg instance. Update registry.xml of ESBQA node as follows.
<dbConfig name="configgovregistry">
<url>jdbc:mysql://localhost:3306/greg_db</url>
<userName>regadmin</userName>
<password>regadmin</password>
<driverName>com.mysql.jdbc.Driver</driverName>
<maxActive>50</maxActive>
<maxWait>60000</maxWait>
<minIdle>5</minIdle>
</dbConfig>
<remoteInstance url="https://localhost:9443/registry">
<id>configgov</id>
<dbConfig>configgovregistry</dbConfig>
<readOnly>false</readOnly>
<enableCache>true</enableCache>
<registryRoot>/</registryRoot>
</remoteInstance>
<mount path="/_system/config" overwrite="true">
<instanceId>configgov</instanceId>
<targetPath>/_system/qa</targetPath>
</mount>
<mount path="/_system/governance" overwrite="true">
<instanceId>configgov</instanceId>
<targetPath>/_system/governance</targetPath>
</mount>
Start the server. We are done with the product configurations. However, we have not done any artifact governance configuration yet. In the next steps, we will look into moving artifacts between the two ESB instances.
Using WSO2 Governance Registry to move artifacts between environments
As I explained at the beginning, we use central governance registry instance to manage the artifacts produced by each of DEV and QA environments. The ESB artifacts produced by development environment are stored under /_system/dev collection of governance registry where as the artifacts used in QA environment are stored in /_system/qa collection. When the development tasks are compelte and ready for QA, we can manually copy the artifacts into the relevant locations and configure the QA environment. Obviously it will be a painful task to copy large number of artifacts into various locations of ESB QA environment by hand. Therefore, we need some kind of automated artifact copying mechanism.
WSO2 Governance Registry provides us with registry extension features to extend the core functionality of G-reg to use in these types of situations. The lifecycle management feature is such a useful extension provided by WSO2 Governance Registry which can be used to manage life cycle of a resource stored in registry.
The standard WSO2 G-reg distribution is shipped with a default ServiceLifeCycle which can be used to move service artifacts among different environments. We will modify the default ServiceLifeCycle to copy artifacts stored under /_system/dev collection to /_system/qa when promoting from development stage to testing.
Log in to G-reg management console and navigate to Extensions --> Configure --> Lifecycles. Click on Add New LifeCycle and add the following life cycle.
<aspect name="ESBLifeCycle" class="org.wso2.carbon.governance.registry.extensions.aspects.DefaultLifeCycle">You can see that we have used org.wso2.carbon.governance.registry.extensions.executors.CopyExecutor class to copy one or more resources from one environment to another. Executors are custom extensions to G-reg which used to trigger a custom execution logic at the time of state transition (e.g:- Dev to QA, QA to Production). When artifacts are promoted to Testing state from Development, the CopyExecutor is triggered and the events defined under transitionExecution element are carried out. In this lifecycle, CopyExecutor copies any resource which is at currentEnvironment to targetEnvironment
<configuration type="literal">
<lifecycle>
<scxml xmlns="http://www.w3.org/2005/07/scxml"
version="1.0"
initialstate="Development">
<state id="Development">
<datamodel>
<data name="checkItems">
<item name="Configurations Completed" forEvent="">
</item>
<item name="Transform Rules Done" forEvent="">
</item>
<item name="Routing Rules Completed" forEvent="">
</item>
</data>
<data name="transitionExecution">
<execution forEvent="Promote" class="org.wso2.carbon.governance.registry.extensions.executors.CopyExecutor">
<parameter name="currentEnvironment" value="/_system/dev"/>
<parameter name="targetEnvironment" value="/_system/qa"/>
</execution>
</data>
<data name="transitionUI">
<ui forEvent="Promote" href="../lifecycles/pre_invoke_aspect_ajaxprocessor.jsp?currentEnvironment=/_system/dev/"/>
</data>
</datamodel>
<transition event="Promote" target="Testing"/>
</state>
<state id="Testing">
<transition event="Demote" target="Development"/>
</state>
</scxml>
</lifecycle>
</configuration>
</aspect>
Note that, CopyExecutor has not been shipped by default in WSO2 G-reg-4.1.X versions. Hence, you need to implement org.wso2.carbon.governance.registry.extensions.interfaces.Execution interface. However, in current trunk based versions (which will be released within few months), this executor is included by default and you can use it out-of-the-box.
Once the life cycle is created and saved, we can apply it to the relevant collection in registry. In this example, we need to move the artifacts stored at /_system/dev to /_system/qa. Hence, we must apply ESBLifecycle to /_system/dev collection.
Navigate to /_system/dev collection in registry browser. Click on Lifecycle in the left pane. Select Add Lifecycle and choose ESBLifeCycle from the dropdown list. Click on Add to add ESBLifeCycle to /_system/dev collection.
We do not have any artifacts in /_system/dev collection yet. Therefore, lets add some ESB artifacts through ESB management console. Log in to the management console of ESB DEV instance and add a sequence. (say it is "devsequence). This will create a new sequence in ESB and it will be stored under /_system/dev in G-reg
Now, go back to G-reg management console and navigate to /_system/dev collection. Select the check-list items such as Configurations Completed, Transform Rules Defined etc.. and click on Promote.
After promotion, click on Search --> metadata in left menu in G-reg management console and search for the resource which has just been added ("devsequence"). The resource will be copied to /_system/qa collection.
We have just completed automatic promotion of resources which have been created from ESB DEV environment to ESB QA environment. However, you will notice that the ESB sequence artifact which has just been added, is not "deployed" in ESB QA instance. Because of that, you will not see "devsequence" in sequence list of ESB QA instance. The artifact is added to the relevant registry location but in order for deployment of the resource, ESB needs to check-out the resource from /_system/qa/repository/deployment/server/synapse-configs/default/sequences location in registry to the corresponding deployment directory of file system of ESB QA server.
DeploymentSynchronizer comes into action in this situation. As I have explained in a previous blog post, DeploymentSynchronizer can be used to synchronize deployment artifacts among cluster nodes.
Lets enable registry based deployment synchronizer for ESB DEV and ESB QA instances.
- Shutdown both ESB DEV and ESB QA servers
- From WSO2 Carbon-4.0.0 release onwards, we need to enable Tribes based clustering in order for deployment synchronizer to communicate with cluster nodes. Open ESBDEV_HOME/repository/conf/axis2/axis2.xml and enable clustering and specify a unique domain name.
<clustering class="org.apache.axis2.clustering.tribes.TribesClusteringAgent" enable="true"><parameter name="domain">wso2.charitha.domain</parameter>
Repeat the same with ESBQA_HOME/repository/conf/axis2/axis2.xml as well.
- Enable deployment synchronizer configuration in ESBDEV_HOME/repository/conf/carbon.xml
<DeploymentSynchronizer>
<Enabled>true</Enabled>
<AutoCommit>true</AutoCommit>
<AutoCheckout>true</AutoCheckout>
</DeploymentSynchronizer>
- Similarly, Enable deployment synchronizer configuration in ESBQA_HOME/repository/conf/carbon.xml. ESB QA instance automatically checks out the resources from /_system/qa collection of G-reg. Therefore, we just enable AutoCheckout in that node.
<DeploymentSynchronizer>
<Enabled>true</Enabled>
<AutoCommit>false</AutoCommit>
<AutoCheckout>true</AutoCheckout>
</DeploymentSynchronizer>
We have completed enabling deployment synchronizer for both ESB development and QA servers. Now, try out adding another sequence from ESB DEV instance (say it is "devsequence2"). Once the sequence is added, access G-reg management console and browse /_system/dev collection. Promote the lifecycle again. This time, you will notice that devsequence2 is deployed in ESB QA instance upon successful promotion
In this post, I took you through the steps of moving artifacts between different environments using WSO2 ESB and WSO2 G-reg. We created artifacts in ESB using management console. However, the recommended best practice is to build SOA artifacts using a tool like WSO2 Carbon Studio and upload the CAR artifacts to ESB. We will look into CAR based SOA governance mechanism in a future post.
Wednesday, February 22, 2012
QA role in SOA projects
The traditional roles and responsibilities are being redefined and expanded in the context of SOA projects. We can observe a new project life cycle model and the roles associated with various life cycle stages in an SOA project.
We can identify a set of common life cycle stages of a SOA project, such as SOA feasibility study, service oriented analysis, service oriented design, service development, service testing, service deployment etc.. In his book, SOA governance, Thomas Erl describes organizational roles which are associated with one or more of those SOA project life cycle stages. Thomas Erl specifically defines SOA Quality Assurance Specialist role who is primarily involved in the testing stage of a SOA project. He also states the importance of possessing expertise in both business domain and technology.
While agreeing with Thomas, I would expect much more contribution than mere testing of solutions from SOA QA specialist in a SOA project.
SOA governance specialist is primarily responsible for the execution of governance process in a SOA project. However, as defined by Ian Sommerville in his book on Software engineering, quality assurance is an umbrella activity which spreads through out the projects from inception to delivery. Therefore, ideally, the SOA QA specialist should be able to play the governance specialist role.
SOA QA specialist should actively be involved in all service analysis, design phases and gather data about possible failures of the solutions, testing requirements, security requirements etc.. Also, the QA specialist should identify consumer applications in advance, the nature of the production environment and be prepared with simulating complex application integrations.
As I explained in Quality The key to successful SOA presentation, early testing will be most important aspect of SOA testing effort. SOA QA role should use mock services to simulate the services which are not implemented yet or not available for testing instead of waiting till they are ready for testing.
Test automation is a must-have condition for SOA projects due to the likelihood of frequent requirement changes and rapid release cycles. It will be always important to have a comprehensive automation plan which will be driven by everyone involved in project, not limited to testers.
Since SOA has gone from nice-to-have to have-to-have, we would expect a greater involvement of QA in SOA projects.
We can identify a set of common life cycle stages of a SOA project, such as SOA feasibility study, service oriented analysis, service oriented design, service development, service testing, service deployment etc.. In his book, SOA governance, Thomas Erl describes organizational roles which are associated with one or more of those SOA project life cycle stages. Thomas Erl specifically defines SOA Quality Assurance Specialist role who is primarily involved in the testing stage of a SOA project. He also states the importance of possessing expertise in both business domain and technology.
While agreeing with Thomas, I would expect much more contribution than mere testing of solutions from SOA QA specialist in a SOA project.
- SOA life cycle governance
SOA governance specialist is primarily responsible for the execution of governance process in a SOA project. However, as defined by Ian Sommerville in his book on Software engineering, quality assurance is an umbrella activity which spreads through out the projects from inception to delivery. Therefore, ideally, the SOA QA specialist should be able to play the governance specialist role.
- Service oriented test analysis
SOA QA specialist should actively be involved in all service analysis, design phases and gather data about possible failures of the solutions, testing requirements, security requirements etc.. Also, the QA specialist should identify consumer applications in advance, the nature of the production environment and be prepared with simulating complex application integrations.
- Service testing at the early stages of the project
As I explained in Quality The key to successful SOA presentation, early testing will be most important aspect of SOA testing effort. SOA QA role should use mock services to simulate the services which are not implemented yet or not available for testing instead of waiting till they are ready for testing.
- Test automation
Test automation is a must-have condition for SOA projects due to the likelihood of frequent requirement changes and rapid release cycles. It will be always important to have a comprehensive automation plan which will be driven by everyone involved in project, not limited to testers.
Since SOA has gone from nice-to-have to have-to-have, we would expect a greater involvement of QA in SOA projects.
Friday, January 27, 2012
SOAP message correlation with JMeter Beanshell pre-processor
When testing service oriented solutions, it is often required to correlate SOAP or POX messages with each other. For example, first you may need to talk to one particular web service and get the response back. Then you will need to extract some properties from the response and include them in subsequent requests. In these situations, you cannot just send the SOAP messages to the web service. In other words, you should do some preprocessing before doing the second service call.
Apache Jmeter provides you with Pre-Processor elements to handle these types of requirements. In this post, we will look into one of the useful pre-processor element, Bean Shell PreProcessor
We will do a simple echo web service call first and extract the response value to a user defined variable. Then, we will use Bean Shell PreProcessor to modify the second SOAP request.
Step 1
Start Jmeter and create a new test plan. Add two SOAP/XML-RPC request samplers. Add the following request for one sampler. Name the sampler as "echoStringRequest"
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://service.carbon.wso2.org">
<soapenv:Body>
<ser:echoString>
<ser:s>MSFT</ser:s>
</ser:echoString>
</soapenv:Body>
</soapenv:Envelope>
For the second SOAP/XML-RPC request sampler, add the following request. Name it as "StockQuoteRequest"
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<p:getQuote xmlns:p="http://services.samples/xsd">
<p:request>
<p:symbol></p:symbol>
</p:request>
</p:getQuote>
</s:Body>
</s:Envelope>
Note that there is no relationship between these two web service calls. I use these just for the demonstration purposes only.
Step 2:
The above two requests will be sent to two web services hosted in Apache Axis2 (or WSO2 Application Server). Therefore, download Axis2Service.aar and SimpleStockQuoteService.aar deploy the services.
Step 3:
Now, Send the above echoStringRequest to Axis2Service and check the response. You will see something like below.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns:echoStringResponse xmlns:ns="http://service.carbon.wso2.org"><ns:return>MSFT</ns:return>
</ns:echoStringResponse>
</soapenv:Body>
</soapenv:Envelope>
We are going to extract the value of <echoStringResponse> element and assign it to a variable so that we can use the value later. For that, we need to add the User Defined Variables config element to the thread group. Right click on thread group and select Add --> Config Elements ---> User Defined Variables
Name: echoResponse
Value: empty

Step 4:
We need to extract the echoStringResponse from the above SOAP response. For that, we will use XPAth extractor post-processor element.
Right click on the echoStringRequest SOAP/XML-RPC sampler and add XPath Extractor.

Specify "//echoStringResponse/return" as the Xpath query and "echoResponse" (the user defined variable) as the reference name.
Step 5
In the previous two steps, we extracted echoStringResponse value from the SOAP response message and assign it to a user defined variable. Now, we need to insert the extracted string into the second SOAP request.
As I mentioned at the beginning, we use BeanShell preprocessor to modify the SOAP request before submission.
BeanShell is a simple scripting language which dynamically executes standard java syntax.
Lets add the beanshell preprocessor as a child of our second SOAP sampler, StockQuoteRequest.
Right click on StockQuoteRequest SOAP/XML-RPC sampler and select Add --> Pre Processors --> BeanShell Pre Processor
You can include the processing script inside script pane. Here, first we read the StockQuoteRequest to a String and replace the <symbol> element with the echoResponse value which has been placed under the user defined variable.
Here, sampler is a variable provided by jmeter which refers to the parent SOAP request.

Step 6
We have completed adding all the necessary elements to our Jmeter test plan. Now, add a listener to visualize the results and run the test.
You will see that the response of the echoStringRequest will be used for the StockQuoteRequest by extracting the echoStringResponse value from the first request.
Apache Jmeter provides you with Pre-Processor elements to handle these types of requirements. In this post, we will look into one of the useful pre-processor element, Bean Shell PreProcessor
We will do a simple echo web service call first and extract the response value to a user defined variable. Then, we will use Bean Shell PreProcessor to modify the second SOAP request.
Step 1
Start Jmeter and create a new test plan. Add two SOAP/XML-RPC request samplers. Add the following request for one sampler. Name the sampler as "echoStringRequest"
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://service.carbon.wso2.org">
<soapenv:Body>
<ser:echoString>
<ser:s>MSFT</ser:s>
</ser:echoString>
</soapenv:Body>
</soapenv:Envelope>
For the second SOAP/XML-RPC request sampler, add the following request. Name it as "StockQuoteRequest"
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<p:getQuote xmlns:p="http://services.samples/xsd">
<p:request>
<p:symbol></p:symbol>
</p:request>
</p:getQuote>
</s:Body>
</s:Envelope>
Note that there is no relationship between these two web service calls. I use these just for the demonstration purposes only.
Step 2:
The above two requests will be sent to two web services hosted in Apache Axis2 (or WSO2 Application Server). Therefore, download Axis2Service.aar and SimpleStockQuoteService.aar deploy the services.
Step 3:
Now, Send the above echoStringRequest to Axis2Service and check the response. You will see something like below.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns:echoStringResponse xmlns:ns="http://service.carbon.wso2.org"><ns:return>MSFT</ns:return>
</ns:echoStringResponse>
</soapenv:Body>
</soapenv:Envelope>
We are going to extract the value of <echoStringResponse> element and assign it to a variable so that we can use the value later. For that, we need to add the User Defined Variables config element to the thread group. Right click on thread group and select Add --> Config Elements ---> User Defined Variables
Name: echoResponse
Value: empty

Step 4:
We need to extract the echoStringResponse from the above SOAP response. For that, we will use XPAth extractor post-processor element.
Right click on the echoStringRequest SOAP/XML-RPC sampler and add XPath Extractor.

Specify "//echoStringResponse/return" as the Xpath query and "echoResponse" (the user defined variable) as the reference name.
Step 5
In the previous two steps, we extracted echoStringResponse value from the SOAP response message and assign it to a user defined variable. Now, we need to insert the extracted string into the second SOAP request.
As I mentioned at the beginning, we use BeanShell preprocessor to modify the SOAP request before submission.
BeanShell is a simple scripting language which dynamically executes standard java syntax.
Lets add the beanshell preprocessor as a child of our second SOAP sampler, StockQuoteRequest.
Right click on StockQuoteRequest SOAP/XML-RPC sampler and select Add --> Pre Processors --> BeanShell Pre Processor
You can include the processing script inside script pane. Here, first we read the StockQuoteRequest to a String and replace the <symbol> element with the echoResponse value which has been placed under the user defined variable.
import org.apache.jmeter.protocol.http.sampler.SoapSampler;
SoapSampler soapSampler = (SoapSampler) sampler;
String stockRequest = soapSampler.getXmlData().replaceFirst("#symbol#", vars.get("echoResponse"));
soapSampler.setXmlData(stockRequest);
SoapSampler class can be used to manipulate a lot of operations of SOAP/XML-RPC request such as read XML data, modify data and set SOAPAction etc..Here, sampler is a variable provided by jmeter which refers to the parent SOAP request.

Step 6
We have completed adding all the necessary elements to our Jmeter test plan. Now, add a listener to visualize the results and run the test.
You will see that the response of the echoStringRequest will be used for the StockQuoteRequest by extracting the echoStringResponse value from the first request.
Thursday, January 26, 2012
Testing Perspective of API management
API(Application programming interface) is not new, it has been a commonly used term in computing for decades. But what is management of APIs?
When a set of entities become larger and grow in exponential manner, there is alway a need of management. You can have your own shop and you are able to look after each and every aspect of its operations till it grows to some level. Once, you have a chain of shops, you, by your own cannot do the same which you did with one shop. You should have some kind of management to govern and control your business operations.
Similarly, management is a common requirement for most of the entities around us. DBMS systems were built to manage pools of data.
If you expose the computing assets of your organization to external parties so that they can build applications to integrate with your systems, it can be considered as an API offering. With the widespread adoption of mobile devices and service oriented computing, business organizations began to open application and services to external developers. These third party developers built applications to integrate with the systems of API provider allowing the provider to extend the capabilities of their business as well as helping the third party developers to earn by their own.
Today, there is a enormous set of applications build by third party developers based on the APIs exposed by large vendors. For example, how many new android, iPad, iPhone apps out there for download? how many facebook, twitter apps?
With this demand of APIs, there is a necessity of adopting a proper API management if you are a Internet application vendor who expose the business APIs for third party developers. Similar to database management software, API management software is used primarily to help API publishers to expose the APIs and third party developers to build applications in simple and efficient manner. Mashery is considered as the first known API management solution. An API management software should be capable of governing and controlling access to the APIs, securing APIs, metering and monitoring usage of APIs etc..
With large amount of APIs offered by many vendors as well as the adoption of API management solutions, should we expect a radical change in software testing space? Should there be a totally different approach for API testing?
Since there is a close relationship with services in service oriented architecture (SOA) and web APIs, I believe the approach which I suggested for SOA testing will still be applicable for APIs.
Similar to web services, the APIs which are exposed to outside, for various application development and integration efforts, must be tested end-to-end to verify both functional and non-functional needs. In API development, everyone (both QA and Development) should equally be responsible for quality. You should not even think of exposing your APIs for public use if you do not have automated tests to verify regressions. Think about the performance impacts, think about security concerns, think about usage patterns of your APIs and derive a comprehensive test plan.
Open source tools such as soapUI which we use for web services testing can also be used for API testing out of the box. Specially, soapUI can easily be used for REST API testing.
I do not think there will be a completely different set of tools for API testing since API testing has been there for years and most of the tools as well as the constructs provided by programming languages such as Junit, Nunit etc.. have been used in API testing in all these years.
However, I believe, the API management vendors should think more about the testing and quality assurance aspects. Quality is as important as the govern, control, monitoring aspects of web APIs. Therefore, it will be important for API management solutions, at least to include a set of tools for testing the APIs managed by them.
When a set of entities become larger and grow in exponential manner, there is alway a need of management. You can have your own shop and you are able to look after each and every aspect of its operations till it grows to some level. Once, you have a chain of shops, you, by your own cannot do the same which you did with one shop. You should have some kind of management to govern and control your business operations.
Similarly, management is a common requirement for most of the entities around us. DBMS systems were built to manage pools of data.
If you expose the computing assets of your organization to external parties so that they can build applications to integrate with your systems, it can be considered as an API offering. With the widespread adoption of mobile devices and service oriented computing, business organizations began to open application and services to external developers. These third party developers built applications to integrate with the systems of API provider allowing the provider to extend the capabilities of their business as well as helping the third party developers to earn by their own.
Today, there is a enormous set of applications build by third party developers based on the APIs exposed by large vendors. For example, how many new android, iPad, iPhone apps out there for download? how many facebook, twitter apps?
With this demand of APIs, there is a necessity of adopting a proper API management if you are a Internet application vendor who expose the business APIs for third party developers. Similar to database management software, API management software is used primarily to help API publishers to expose the APIs and third party developers to build applications in simple and efficient manner. Mashery is considered as the first known API management solution. An API management software should be capable of governing and controlling access to the APIs, securing APIs, metering and monitoring usage of APIs etc..
With large amount of APIs offered by many vendors as well as the adoption of API management solutions, should we expect a radical change in software testing space? Should there be a totally different approach for API testing?
Since there is a close relationship with services in service oriented architecture (SOA) and web APIs, I believe the approach which I suggested for SOA testing will still be applicable for APIs.
Similar to web services, the APIs which are exposed to outside, for various application development and integration efforts, must be tested end-to-end to verify both functional and non-functional needs. In API development, everyone (both QA and Development) should equally be responsible for quality. You should not even think of exposing your APIs for public use if you do not have automated tests to verify regressions. Think about the performance impacts, think about security concerns, think about usage patterns of your APIs and derive a comprehensive test plan.
Open source tools such as soapUI which we use for web services testing can also be used for API testing out of the box. Specially, soapUI can easily be used for REST API testing.
I do not think there will be a completely different set of tools for API testing since API testing has been there for years and most of the tools as well as the constructs provided by programming languages such as Junit, Nunit etc.. have been used in API testing in all these years.
However, I believe, the API management vendors should think more about the testing and quality assurance aspects. Quality is as important as the govern, control, monitoring aspects of web APIs. Therefore, it will be important for API management solutions, at least to include a set of tools for testing the APIs managed by them.
Saturday, January 21, 2012
Truly RESTful Services using Apache Wink and WSO2 Application Server


Apache Wink is a complete implementation of JAX-RS v-1.1 specification. JAX-RS is a java API which supports creating web services in RESTful manner.
WSO2 Application Server is the enterprise-ready, scalable web services and web app hosting platform powered by Apache Axis2 and Apache Tomcat.
In this post, we are going to create a RESTful web service using Apache wink libraries and deploy it in WSO2 Application Server. If we summarize the steps that we are going to do in this example;
1. Create a JDBC data source (mySQL)
2. Create the web service with JAX-RS annotations which makes use of the above database
3. Create a web application (war) with apache wink libraries
4. Deploy the web app in WSO2 Application Server
WSO2 provides application developers with a complete middleware platform in cloud. Therefore, we makes use of WSO2 StratosLive PaaS (Platform as a Service) as our development platform. In other words, we are NOT even going to install mySQL or WSO2 Application server in our machines to try this sample out. We will create the database in cloud and host web application in the cloud.
Without discussing further. lets start our journey.
Step 1
We are going to create a primitive customer registration application which consists of a mySQL database with one table called customer. We need to create the DB schema.
WSO2 Stratos middleware platform in cloud allows us to have our own data storage in cloud within seconds. As I explained in this post, all we have to do is;
- Register a new tenant
- Log into https://stratoslive.wso2.com
- Access DataServices Server
- Create a database and a table
CREATE TABLE CUSTOMER_T(customerID int, customerName varchar(100), customerAge int, customerAddress varchar(200));
Once the database and table is created, note the DB connection URL. In my case, it is,
jdbc:mysql://rss1.stratoslive.wso2.com/wink_superqa_com
Step 2
Now, our application data source is ready for use. As I have explained before, we are going to create a customer registration web service which includes all CRUD operations associated with above DB schema. In other words, we can add, delete, read and update customers using the web service. We will implement our webservice in completely RESTful manner so that we makes use of HTTP verbs to invoke service.
Therefore, lets create the Customer bean first. Open your favorite Java IDE and add Customer class with the following properties and associated getters and setters. The complete class can be found at https://wso2.org/repos/wso2/trunk/commons/qa/qa-artifacts/app-server/rest/jaxrs-sample/src/com/beans/Customer.java
public class Customer {
private int customerID;
private String customerName;
private String customerAddress;
private int customerAge;
Step 3
We will use a separate class to handle all communication with the database which we created above. Lets name the class as Storage.java and implement all CRUD operations.
public class Storage {
Connection connection = null;
Statement statement = null;
ResultSet rs = null;
private Connection getConnection() {
String driverName = "com.mysql.jdbc.Driver";
String conectionURI = "jdbc:mysql://rss1.stratoslive.wso2.com/wink_superqa_com";
String userName = "ck_l96225fe";
String password = "ck";
try {
Class.forName(driverName);
try {
connection = DriverManager.getConnection(conectionURI, userName, password);
} catch (SQLException e) {
e.printStackTrace();
}
try {
connection.setAutoCommit(true);
} catch (SQLException e) {
e.printStackTrace();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return connection;
}
//CREATE operation
public void addCustomer(Customer customer) {
try {
connection = getConnection();
statement = connection.createStatement();
String sqlStatement = "INSERT INTO CUSTOMER_T VALUES (" + customer.getCustomerID()
+ ",'" + customer.getCustomerName() + "', " + customer.getCustomerAge() + ",'" + customer.getCustomerAddress() + "')";
statement.execute(sqlStatement);
} catch (SQLException e) {
} finally {
if (statement != null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
Similarly, add the other methods to UPDATE, DELETE and READ operations. The complete Storage.java class can be found here.
Step 4
Now, we can implement our web service. We are going to use JAX-RS annotations to make our web service completely RESTful. Download Apache wink distribution from here and add WINK_HOME/dist and WINK_HOME/lib to class path of your IDE.
We will have four methods to demonstrate the basic HTTP methods.
- addCustomer() method is used to add a new customer to the system. We use a HTTP POST request to send the customer details to the web service method.
- getCustomerName() is just a HTTP GET operation which reads the CUSTOMER_T table and send back the name of the customer associated with given customer ID.
- updateCustomer() method updates the customer address of the given customer
- deleteCustomer() method removes a customer record from the table
@Path("/qa")
public class CustomerService {}
Now, we need to implement the methods associated with CRUD operations. First lets look at addCustomer method. As we defined the root resource at the class declaration level, we can define subresource methods to handle the common HTTP methods. Here, addCustomer is a subresource method and we annotate it with @POST to direct POST requests which are targeted to '/qa' root resource. @Path annotation at the sub resource level resolves the URL path which is targeted to the method. In otherwords, if the request URL is, /qa/customer and the HTTP method is POST, the request is dispatched to addCustomer() method.
@POST
@Consumes("application/x-www-form-urlencoded")
@Path("/customer")
public void addCustomer(@FormParam("customerid") int customerID, @FormParam("customername") String customerName, @FormParam("customerage") int customerAge, @FormParam("customeraddress") String customerAddress){
Storage storage = new Storage();
Customer customer = new Customer();
customer.setCustomerID(customerID);
customer.setCustomerName(customerName);
customer.setCustomerAge(customerAge);
customer.setCustomerAddress(customerAddress);
storage.addCustomer(customer);
}
Also, make a note of the @Consumes annotation, here we define the Content-Type which must be included in the HTTP POST request. In our example, if a POST request to '/qa/customer' is issued with "application/x-www-form-urlencoded" Content-Type, the addCustomer() method will be invoked. If we send any other content in the POST request, this method will not get invoked.
We also use annotated parameters to pass some additional information with a request. For example we can use query parameters, path parameters etc and process them accordingly. In our example, we use @FormParm parameter to extract parameter values from the form posts.
Similarly, we can implement the other methods in our service implementation class.
@GET
@Path("/customer/{customerid}")
@Produces("text/plain")
public String getCustomerName(@PathParam("customerid") int customerID) {
Storage storage = new Storage();
Customer customer = null;
try {
customer = storage.getCustomerDetails(customerID);
} catch (SQLException e) {
e.printStackTrace();
}
return customer.getCustomerName();
}
@PUT
@Consumes("application/x-www-form-urlencoded")
@Path("/customer")
public void updateCustomer(@FormParam("customername") String customerName, @FormParam("customeraddress") String customerAddress){
Storage storage = new Storage();
storage.updateCustomer(customerName, customerAddress);
}
@DELETE
@Path("/customer/{customerid}")
public void deleteUser(@PathParam("customerid") int customerID) {
Storage storage = new Storage();
storage.deleteCustomer(customerID);
}
Step 5
We have completed the implementation of our web service class with JAX-RS annotations. Apache wink needs us to create a sub-class of javax.ws.rs.core.Application if we deploy deploy our application on non-JAX-RS aware containers. At the time of writing, WSO2 Application Server is not JAX-RS aware hence we need to create this particular subclass. This class basically returns the root resource(s).
public class CustomerResourceApplication extends Application {
@Override
public Set> getClasses() {
Set> classes = new HashSet>();
classes.add(CustomerService.class);
return classes;
}
}
Step 6
Next, we need to create the web.xml file for our web application. In addition to the standard constructs in web.xml, we should define that the Apache wink JAX-RS servlet should be initialized with an instance of the above CustomerResourceApplication.
We also define that the requests begin with '/rest/' will be handled by Apache Wink JAX-RS servlet.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Restful service Test Web Application</display-name>
<servlet>
<servlet-name>CustomerServlet</servlet-name>
<servlet-class>org.apache.wink.server.internal.servlet.RestServlet</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.sample.CustomerResourceApplication</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CustomerServlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
Step 7
We are done with our web application now. Create a war with the above classes as well as apache wink libraries. Make sure to place all jars included in WINK_HOME/dist and WINK_HOME/lib in WEB-INF/lib of the web application. You can use the ant build script given here to do all these stuff.
Step 8
Once the web application (CustomerService.war) is ready, log in to https://appserver.stratoslive.wso2.com with your tenant credentials and upload the web application. (Please read my blog post on Apache Tomcat As a Service if you want to know how WSO2 application Server can be used in web app deployment)
Step 9
Finally, we can invoke each of the operations of our web service in truly RESTful manner using a client application such as curl.
HTTP POST:
curl --data "customerid=1&customername=charitha&customerage=33&customeraddress=piliyandala" -X POST -H "Content-Type: application/x-www-form-urlencoded"http://appserver.stratoslive.wso2.com/t/superqa.com/webapps/CustomerService/rest/qa/customer
HTTP GET:
curl -X GET http://appserver.stratoslive.wso2.com/t/superqa.com/webapps/CustomerService/rest/qa/customer/1
HTTP PUT:
curl --data "customername=charitha&customeraddress=colombo" -X PUT -H "Content-Type: application/x-www-form-urlencoded" http://appserver.stratoslive.wso2.com/t/superqa.com/webapps/CustomerService/rest/qa/customer
HTTP DELETE:
curl -X DELETE http://appserver.stratoslive.wso2.com/t/superqa.com/webapps/CustomerService/rest/qa/customer/1
SOAP with HTTP basic auth using Apache JMeter
SOAP/XML-RPC request sampler of Apache Jmeter can be used to send SOAP requests to a web service. We looked into the details of SOAP/XML-RPC sampler in a previous blog post.
If the web service is secured, we cannot directly send messages using the above sampler. This post will help you to use Jmeter in web service testing if the service is secured using HTTP basic authorization.
If a web service is secured using HTTP basic authorization, the authorization credentials are carried over HTTP headers of the message. The security information is not coupled with the SOAP envelope. Therefore, the same procedure which we are going to discuss below can be applied to any other sampler in Jmeter.
Step 1:
Have a web service secured with HTTP basic authentication. I use Apache Axis2 as the web service container and deploy it on Apache Tomcat. Then use the tomcat authorization to secure any service hosted in Axis2 As explained by Prabath in here.
If the service is secured with HTTP basic auth, the service can only be invoked if you send the request with Authorization header as follows.
Authorization: Basic Y2hhcml0aGE6Y2hhcml0aGE=
Step 2:
We need to insert this header into SOAP messages which transmits over HTTP channel. In other words, we need Jmeter to add this header for all requests which are sent to the above web service. Lets see how we can do this.
Start to create a new Jmeter test plan. Add a thread group and add SOAP/XML-RPC request sampler. Add SOAP envelope and specify the endpoint URL.

Step 3
We need to insert authorization HTTP header to each SOAP request. Therefore, we need to use one of the Config Elements included in Jmeter. HTTP Authorization Manager config element comes in handy in this situation. Authorization manager can be used to specify login information when you access websites, web services or any other HTTP accessible resource which secured with basic authorization.
Select the thread group and select Config Element --> Authorization Manager
HTTP authorization manager config element will be added to your thread group as shown below.

Step 4
Specify the following properties in HTTP Authorization manager.
Base URL = http://localhost:8080/axis2
username = charitha
password = charitha
Here, Base URL is a part or complete URL of the web service you are going to access.
User name and password are the credentials which we specified in tomcat-users.xml file
Step 5
Add a listener and run the test. You will see the SOAP request with the following HTTP headers.
Content-Type: text/xml
SOAPAction: "urn:echoString"
Connection: close
Authorization: Basic Y2hhcml0aGE6Y2hhcml0aGE=
User-Agent: Jakarta Commons-HttpClient/3.1
Host: localhost:8080
Content-Length: 268
If the web service is secured, we cannot directly send messages using the above sampler. This post will help you to use Jmeter in web service testing if the service is secured using HTTP basic authorization.
If a web service is secured using HTTP basic authorization, the authorization credentials are carried over HTTP headers of the message. The security information is not coupled with the SOAP envelope. Therefore, the same procedure which we are going to discuss below can be applied to any other sampler in Jmeter.
Step 1:
Have a web service secured with HTTP basic authentication. I use Apache Axis2 as the web service container and deploy it on Apache Tomcat. Then use the tomcat authorization to secure any service hosted in Axis2 As explained by Prabath in here.
If the service is secured with HTTP basic auth, the service can only be invoked if you send the request with Authorization header as follows.
Authorization: Basic Y2hhcml0aGE6Y2hhcml0aGE=
Step 2:
We need to insert this header into SOAP messages which transmits over HTTP channel. In other words, we need Jmeter to add this header for all requests which are sent to the above web service. Lets see how we can do this.
Start to create a new Jmeter test plan. Add a thread group and add SOAP/XML-RPC request sampler. Add SOAP envelope and specify the endpoint URL.

Step 3
We need to insert authorization HTTP header to each SOAP request. Therefore, we need to use one of the Config Elements included in Jmeter. HTTP Authorization Manager config element comes in handy in this situation. Authorization manager can be used to specify login information when you access websites, web services or any other HTTP accessible resource which secured with basic authorization.
Select the thread group and select Config Element --> Authorization Manager
HTTP authorization manager config element will be added to your thread group as shown below.

Step 4
Specify the following properties in HTTP Authorization manager.
Base URL = http://localhost:8080/axis2
username = charitha
password = charitha
Here, Base URL is a part or complete URL of the web service you are going to access.
User name and password are the credentials which we specified in tomcat-users.xml file
Step 5
Add a listener and run the test. You will see the SOAP request with the following HTTP headers.
Content-Type: text/xml
SOAPAction: "urn:echoString"
Connection: close
Authorization: Basic Y2hhcml0aGE6Y2hhcml0aGE=
User-Agent: Jakarta Commons-HttpClient/3.1
Host: localhost:8080
Content-Length: 268
Subscribe to:
Posts (Atom)


