tag:blogger.com,1999:blog-59498961386316438462024-03-13T10:35:48.793-07:00Charitha's Web LogUnlocking the Power of Engineering Management: Insights and Strategies for Leading Technical Teams to Success.Charithahttp://www.blogger.com/profile/00209392844529688942noreply@blogger.comBlogger159125tag:blogger.com,1999:blog-5949896138631643846.post-33216970200002752082023-03-11T17:58:00.001-08:002023-03-11T17:58:13.315-08:00Revamping My Tech Blog<p>After nearly a decade of inactivity, I thought to revive my blog. I created this blog in 2006 while I was a core contributor to Apache open source projects. In those days when social channels like YouTube and Stack overflow were not readily available for software developers to assist in technical subject matters, bloggers like me became reference materials for open source software troubleshooting. Some posts in this blog generated 1k+ daily hits and tech enthusiasts reached me via various channels and engaged in productive discussions. </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3VuvDS4F4kuDU-IPtQ9oN0ymYdJfkAiUJCn55NX7CoE6dsfHppwhpmr9Sr3TRjHD_VMrbPfmhimsznmjWHvJ8ukt181Z_65AlMNH9XvNpHwyHHgs_Bp4MUjoDrTsc3sHtGrhFLBsdiE3Higx0NpNhiR_92jKGyQPbdyKQJ1cAaGj2sHuYAe1rOUlJ_Q/s512/5d11c82a-cfc0-47b1-a51e-fa0112490659.jpeg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="512" data-original-width="512" height="278" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3VuvDS4F4kuDU-IPtQ9oN0ymYdJfkAiUJCn55NX7CoE6dsfHppwhpmr9Sr3TRjHD_VMrbPfmhimsznmjWHvJ8ukt181Z_65AlMNH9XvNpHwyHHgs_Bp4MUjoDrTsc3sHtGrhFLBsdiE3Higx0NpNhiR_92jKGyQPbdyKQJ1cAaGj2sHuYAe1rOUlJ_Q/w413-h278/5d11c82a-cfc0-47b1-a51e-fa0112490659.jpeg" width="413" /></a></div><p>I quit contributing to open source software since I joined Amazon in 2014. Since then, I was not active in the blogosphere primarily because of the proprietary technologies that I have been using at Amazon and the restrictions on sharing confidential information. Over the last 8 years, I advanced my career at Amazon by transitioning from an individual contributor to Engineering Management role. In this process, I gained a wealth of experience in working in 7 different organizations across Retail, Alexa, Amazon Ads and People Experience and Technology (PxT). This has given me a unique opportunity to share my learnings, opinions and engage with the wider tech community while also being careful about not disclosing confidential/proprietary materials. </p><p>This time around, I will focus more on topics in software engineering management, system design and operational excellence . I have witnessed firsthand how effective management can make a significant difference in delivering successful software products. As technology continues to advance rapidly, the demand for software engineering management has never been higher. By focusing on software engineering management in my blog, I hope to provide valuable insights and guidance to those seeking to improve their management skills. Stay tuned! </p>Charithahttp://www.blogger.com/profile/00209392844529688942noreply@blogger.com0tag:blogger.com,1999:blog-5949896138631643846.post-56008926514738255562014-07-12T08:59:00.003-07:002014-07-12T09:02:05.527-07:00How to enforce a default HTTP Content-Type for requests in WSO2 ESB<div dir="ltr" style="text-align: left;" trbidi="on">
Occasionally, you will get requests from legacy client applications that do not include HTTP Content-Type header. WSO2 ESB proceeds with the mediation flow only after building the relevant SOAP infoset using the message builders registered against the Content-Type of the incoming request. In case the Content-Type is blank, you will experience an error similar to the following in the log.<br />
<br />
<div class="p1">
<i><b>ERROR - RelayUtils Error while building Passthrough stream</b></i></div>
<i><b>java.lang.StringIndexOutOfBoundsException: String index out of range: -1 </b></i><br />
<i><b><br /></b></i>
If modification of client applications to include the mandatory Content-Type HTTP header in POST requests is out of your control, we should be able to set a default content type for such incoming requests. In WSO2 ESB, you can use the following property to set a default Content-Type for the incoming requests in case the HTTP request does not have Content-Type header.<br />
<br />
i.e:-<br />
<br />
<div class="p1">
<br />
<div class="p1">
<parameter name="DEFAULT_REQUEST_CONTENT_TYPE" locked="false">application/json</parameter></div>
</div>
<div class="p1">
<br /></div>
<div class="p1">
Set this property in ESB_HOME/repository/conf/axis2/axis2.xml and restart the server. Here, we have configured application/json as the default content type. So that, when a request similar to the following reaches ESB, the default JSON builder registered for application/json content (org.apache.synapse.commons.json.JsonStreamBuilder in WSO2 ESB-4.8.1) takes care of building the message and hands it over to mediation engine to proceed with the mediation flow.</div>
<div class="p1">
<br /></div>
<div class="p1">
<br /></div>
<div class="p1">
<b><i>POST http://host:8280/services/ContentTest HTTP/1.1</i></b></div>
<div class="p1">
<b><i>Accept-Encoding: gzip,deflate</i></b></div>
<div class="p1">
<b><i>Content-Length: 30</i></b></div>
<div class="p1">
<b><i>Host: host:8280</i></b></div>
<div class="p1">
<b><i>Connection: Keep-Alive</i></b></div>
<div class="p1">
<b><i>User-Agent: Apache-HttpClient/4.1.1 (java 1.5)</i></b></div>
<div class="p1">
<b><i><br /></i></b></div>
<div class="p1">
<b><i>{</i></b></div>
<div class="p1">
<b><i> "in": { "test": "wso2" }</i></b></div>
<div class="p1">
<b><i>}</i></b></div>
</div>
Charithahttp://www.blogger.com/profile/00209392844529688942noreply@blogger.com1tag:blogger.com,1999:blog-5949896138631643846.post-67990572687230889942014-05-25T10:41:00.001-07:002014-05-25T10:41:37.091-07:00Handling JSON responses in Apache JMeter<div dir="ltr" style="text-align: left;" trbidi="on">
There are various types of <a href="http://jmeter.apache.org/usermanual/component_reference.html#postprocessors" target="_blank">post processor elements</a> that we can use out of the box when handling responses in a JMeter test plan. For example, <a href="http://jmeter.apache.org/usermanual/regular_expressions.html" target="_blank">Regular Expression Extractor</a> can be used to capture a specific value or set of values from a XML, HTML or JSON response.<br />
However, handling JSON responses through the default regular expression extractor will be a daunting task when the JSON response becomes complex. When handling complex XML responses, Xpath extractor is the obvious choice in JMeter. Similarly, it will be quite efficient to have a similar post processor element to handle complex JSON responses.<br />
<a href="https://code.google.com/p/json-path/" target="_blank">JSONPath</a> is a way to extract parts of a given JSON document and is now available in many programming languages. In this simple post, we will look at how we can use JSONPath expressions to extract values from JSON responses in JMeter.<br />
<br />
<h4 style="text-align: left;">
Pre-Requisites:</h4>
Download and install JMeter version 2.8 or later<br />
<br />
<h4 style="text-align: left;">
Step 1</h4>
Download <a href="http://jmeter-plugins.org/downloads/file/JMeterPlugins-ExtrasLibs-1.1.3.zip" target="_blank">this</a> JMeter plugin library and unzip JMeterPlugins-ExtrasLibs-1.1.3.zip<br />
Copy the content under lib/ directory to JMETER_HOME/lib (this will merge with the existing content)<br />
<br />
<h4 style="text-align: left;">
Step 2</h4>
Restart JMeter and start to create a new test plan. Add a new thread group. Then add a <b>HTTP Request</b> sampler. Enter the following values.<br />
Server name : ip.jsontest.com<br />
Method : GET<br />
<br />
Leave the other attribute values as they are.<br />
<br />
<h4 style="text-align: left;">
Step 3</h4>
Right-click on the above HTTP Request Sampler and select <b>Add --> Post Processors --> jp@gc - JSON Path Extractor</b><br />
Enter the following values.<br />
<br />
<b>Variable name:</b> ip_address (this is just a reference)<br />
<b>JSON Path:</b> $.ip<br />
<b>Default value:</b> NO_VALUE<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAu5Io0ab65WgCZzry0AB59NRYVlviCL8I51T00OUCg-ewjDFa63sphfHOGLL_-DlQJg64_STD9mk4w9OqzzZI2Vsa7uaQBn_eLQne1_ruyvf3d9eVSQs8re5eG8Axtf4pZFOOZmm3nqBT/s1600/json-path-extractor.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAu5Io0ab65WgCZzry0AB59NRYVlviCL8I51T00OUCg-ewjDFa63sphfHOGLL_-DlQJg64_STD9mk4w9OqzzZI2Vsa7uaQBn_eLQne1_ruyvf3d9eVSQs8re5eG8Axtf4pZFOOZmm3nqBT/s1600/json-path-extractor.png" height="242" width="400" /></a></div>
<br />
<b><br /></b>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<h4 style="text-align: left;">
<br /></h4>
<h4 style="text-align: left;">
Step 4</h4>
Add a Debug sampler so that we can check the extracted value. You can add Debug sampler by right clicking on the thread group and selecting <b>Add --> Sampler --> Debug Sampler</b><br />
<b><br /></b>
<h4 style="text-align: left;">
Step 5</h4>
<br />
Add View Results Tree listener and save the test plan. Then run the test. You will see the following response.<br />
<br />
<i>{"ip": "50.151.197.63"}</i><br />
<br />
<h4 style="text-align: left;">
Step 6</h4>
The above simple JSONPath expression ($.ip) should return the ip address value from the JSON response. Check the Debug sampler output. It will look similar to the following.<br />
<br />
<i>JMeterVariables:</i><br />
<i>JMeterThread.last_sample_ok=true</i><br />
<i>JMeterThread.pack=org.apache.jmeter.threads.SamplePackage@61191c78</i><br />
<i>START.HMS=222538</i><br />
<i>START.MS=1401036938959</i><br />
<i>START.YMD=20140525</i><br />
<i>TESTSTART.MS=1401039015874</i><br />
<i>ip_address=50.151.197.63</i><br />
<br />
The ip address value was extracted from theSON response and assigned to ip_address variable which we have specified in the JSON Path Extractor definition.<br />
<br />
We can now use this variable down in our JMeter test plan to use in various other samplers. </div>
Charithahttp://www.blogger.com/profile/00209392844529688942noreply@blogger.com1tag:blogger.com,1999:blog-5949896138631643846.post-33892705919996457592014-03-27T14:38:00.001-07:002014-03-27T14:38:12.235-07:00Common mistakes to avoid in WSO2 API Manager - "ERROR - APIAuthenticationHandler API authentication failure" for a API call with valid access token<div dir="ltr" style="text-align: left;" trbidi="on">
In the third post of the <b>common mistakes to avoid in WSO2 Carbon platform</b> blog series, I'm going to look at another frequently raised question. I have been struggling to get rid of this issue for few hours recently and figured out the fix by consulting one of my colleagues, <a href="http://nuwanzone.blogspot.com/" target="_blank">Nuwan</a><br />
Let's look at the problem in detail. <br />
<br />
<h4 style="text-align: left;">
Problem</h4>
<br />
Suppose I'm calling a REST API hosted in <a href="http://wso2.com/products/api-manager/" target="_blank">WSO2 API Manager</a> with a set of query parameters as shown below.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>GET http://192.168.1.10:8280/qa/1.0/GetData?name=charitha&city=colombo HTTP/1.1
</code></pre>
<br />
In order to match with the GET URL/query parameters, I define the url-pattern in API publisher as shown below.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivPFzRoDUOE6cp6tn-I7qgnarI_Sda9J8pxc9YFrnOPQnb2Lg2NCgUsqk0mfzDf0hw6KLxWXfm-Z3_jxef6HaKWL2D_Hk-b5YoeHGVkwsl1FTb2VwHE9cvlLSAO0ogqOTTHIOlGUuzPt3G/s1600/blog1.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivPFzRoDUOE6cp6tn-I7qgnarI_Sda9J8pxc9YFrnOPQnb2Lg2NCgUsqk0mfzDf0hw6KLxWXfm-Z3_jxef6HaKWL2D_Hk-b5YoeHGVkwsl1FTb2VwHE9cvlLSAO0ogqOTTHIOlGUuzPt3G/s1600/blog1.png" height="88" width="320" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<b>Note****</b><br />
<i><b>We cannot define a uri-template in API publisher UI in the latest version of API Manager (At the time of writing, it is API Manager 1.6.0).</b></i><br />
<br />
However, the specified url-pattern, /GetData/* does not match with the request URL since my API call contains a set of query parameters.<br />
<br />
Thus, I open the API configuration file which is stored in repository/deployment/server/synapse-configs/default/api directory in API Manager distribution and modify the resource definition as follows.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code> <resource methods="GET" uri-template="/GetData?*">
</code></pre>
<br />
I simply modified url-mapping into uri-template and changed its value to "/GetData?*" so that my request will be accepted by the API resource definition.<br />
<br />
After saving the configuration in file system, I subscribe to the API in store and send a GET request.<br />
I expect everything is correct since the API definition matches with the request perfectly. But I get a HTTP 403 response with the following error in log!<br />
<br />
<i><b>ERROR - APIAuthenticationHandler API authentication failure</b></i><br />
<i><b>org.wso2.carbon.apimgt.gateway.handlers.security.APISecurityException: Access failure for API: /qa, version: 1.0 with key: _Zj7PHU1pvw16lWGq0JHCDSFoE8a<br /> at org.wso2.carbon.apimgt.gateway.handlers.security.oauth.OAuthAuthenticator.authenticate(OAuthAuthenticator.java:139)<br /> at org.wso2.carbon.apimgt.gateway.handlers.security.APIAuthenticationHandler.handleRequest(APIAuthenticationHandler.java:92)<br /> at org.apache.synapse.rest.API.process(API.java:285)<br /> at org.apache.synapse.rest.RESTRequestHandler.dispatchToAPI(RESTRequestHandler.java:76)<br /> at org.apache.synapse.rest.RESTRequestHandler.process(RESTRequestHandler.java:63)</b></i><br />
<br />
This confuses me a lot. I double check my access token. It is valid. I try again generating a new token. No luck. Still getting the same authentication failure. Why??<br />
<br />
<h4 style="text-align: left;">
What is wrong here?</h4>
<br />
When you publish an API through the API publisher UI, the corresponding api config artifact is created in file system. But that is not the only reference. AM_API_URL_MAPPING table, which is in API Manager database (WSO2AM_DB by default in H2)) is also updated with the specified url-pattern value. So in our example, it will be written to that table as "/GetData/*" (this is what we have specified when publishing API in API Publisher UI)<br />
Even though we have changed the API definition in file system as mentioned above, this value in database is not changed. Also, when matching a particular url-pattern, API manager does it at two levels. It validates the auth type of the resource against token using url-mapping (in the above table) and then proceed with the url-pattern validation using the corresponding API definition (file system).<br />
<br />
In our example, though we have changed the API resource definition in API configuration file, the database still contains "/GetData/*" as the url-mapping value. Hence, the first level of validation of the request (matching auth type of the resource against token using url-mapping in AM_API_URL_MAPPING table) fails and returns the above error.<br />
<br />
<h4 style="text-align: left;">
How can we fix this?</h4>
<br />
The fix is simple. Go to API publisher UI and select the published API. Then click on Edit to update the API.<br />
Modify the URL pattern as "/*".<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhy8D9VcXJR0suZ4wTfsrTOJ7GX9sZcOpMIXAsEvJqeuGJ-mJTs3fHW_-_MTelx3jK5uOeRKW4VAV1qFgz7ieNYHb1QL4B9F7kzHFxCsbeLOudk1_-oxRv17fVoxj_LujsDakgCdCAhNs9J/s1600/blog2.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhy8D9VcXJR0suZ4wTfsrTOJ7GX9sZcOpMIXAsEvJqeuGJ-mJTs3fHW_-_MTelx3jK5uOeRKW4VAV1qFgz7ieNYHb1QL4B9F7kzHFxCsbeLOudk1_-oxRv17fVoxj_LujsDakgCdCAhNs9J/s1600/blog2.png" height="109" width="320" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Next, you have to do the same resource modification in API configuration file in repository/deployment/server/synapse-configs/default/api<br />
<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code> <resource methods="GET" uri-template="/GetData?*">
</code></pre>
<br />
Save everything and send a request again. It will be successful. <br />
<br />
<br /></div>
Charithahttp://www.blogger.com/profile/00209392844529688942noreply@blogger.com1tag:blogger.com,1999:blog-5949896138631643846.post-17134727945191826742014-02-28T17:59:00.002-08:002014-02-28T17:59:29.356-08:00Common mistakes to avoid in WSO2 Carbon - 2 - "java.sql.SQLException: Total number of available connections are less than the total number of closed connections"<div dir="ltr" style="text-align: left;" trbidi="on">
This is the second post of common mistakes blog series which I'm planning to share with you. In this post, we are looking into another common mistake which we do when working with WSO2 Carbon platform.<br />
<br />
<a href="https://docs.wso2.org/display/Governance453/Remote+Instance+and+Mount+Configuration+Details" target="_blank">Registry mounting</a> is a way of federating the registry space across multiple servers in a product cluster. For example, if you have a WSO2 ESB cluster, you can use a single registry space to store all configuration data common to cluster nodes.<br />
There are 3 different registry spaces provided by each WSO2 Carbon product; local, configuration and governance. You can find more details about these spaces in <a href="http://wso2.com/library/tutorials/2010/04/sharing-registry-space-across-multiple-product-instances/" target="_blank">here</a>.<br />
<br />
We have to keep in mind a few important concepts when building a shared registry setup. You cannot share the local registry space among multiple cluster nodes. The local registry space is used to store node-specific data hence it should not be shared among other nodes in the cluster. However, we mistakenly do this when configuring shared registry setups and experience many unexpected issues. The following weird startup error is one such occurrence due to incorrect mounting configurations (I removed some part of the complete stack trace for clarity).<br />
<br />
<i><b>ERROR - RegistryCoreServiceComponent Failed to activate Registry Core bundle <br />org.wso2.carbon.registry.core.exceptions.RegistryException: Failed to close transaction.<br /> at org.wso2.carbon.registry.core.jdbc.dataaccess.JDBCTransactionManager.endTransaction(JDBCTransactionManager.java:183)<br />-- </b></i><br />
<i><b>Caused by: java.sql.SQLException: Total number of available connections are less than the total number of closed connections<br /> at org.wso2.carbon.registry.core.jdbc.dataaccess.JDBCDatabaseTransaction$ManagedRegistryConnection.close(JDBCDatabaseTransaction.java:1349)<br /> at org.wso2.carbon.registry.core.jdbc.dataaccess.JDBCTransactionManager.endTransaction(JDBCTransactionManager.java:178)</b></i><br />
<br />
This error does not give any clue about a problem related to mounting. You may have spent many hours unnecessarily to tune up your DBMS since the error says about DB connections! <br />
<br />
Let's explore this error in detail.<br />
<h4 style="text-align: left;">
Step 1</h4>
<h4 style="text-align: left;">
</h4>
We are going to have a shared registry database (which is used as configuration and governance registry spaces in a ESB cluster). I will use mySQL and create a database first.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>mysql> create database sharedreg_db;
</code></pre>
<br />
Next, create the registry DB schema using mySQL database scripts available in CARBON_HOME/dbscripts directory.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>mysql> use sharedreg_db;
mysql> source /home/charitha/products/esb/tmp/wso2esb-4.8.1/dbscripts/mysql.sql;
</code></pre>
<br />
<h4 style="text-align: left;">
Step 2</h4>
<h4 style="text-align: left;">
</h4>
We will register this new database in master-datasources.xml which can be found at<br />
CARBON_HOME/repository/conf/datasources directory<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><datasource>
<name>WSO2_SHARED_REGISTRY_DB</name>
<description>The datasource used for shared registry</description>
<jndiConfig>
<b> <name>jdbc/WSO2SharedRegDB</name></b>
</jndiConfig>
<definition type="RDBMS">
<configuration>
<b> <url>jdbc:mysql://localhost:3306/sharedreg_db</url></b>
<username>root</username>
<password>root</password>
<driverClassName>com.mysql.jdbc.Driver</driverClassName>
<maxActive>50</maxActive>
<maxWait>60000</maxWait>
<testOnBorrow>true</testOnBorrow>
<validationQuery>SELECT 1</validationQuery>
<validationInterval>30000</validationInterval>
</configuration>
</definition>
</datasource>
</code></pre>
<br />
<h4 style="text-align: left;">
Step 3</h4>
<h4 style="text-align: left;">
</h4>
<br />
Now, we have a shared registry database. We need to mount the registry collections to this remote database. There are 3 mounting mechanisms; JDBC, Atom and WS. The commonly used pattern is JDBC mounting. Hence I will use the same.<br />
Mounting configuration can be done in CARBON_HOME/repository/conf/registry.xml as shown below.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><remoteInstance url="https://localhost:9443/registry">
<id>instanceid</id>
<b> <dbConfig>wso2registry</dbConfig></b>
<readOnly>false</readOnly>
<enableCache>true</enableCache>
<registryRoot>/</registryRoot>
</remoteInstance>
<mount path="/_system/config" overwrite="true">
<instanceId>instanceid</instanceId>
<targetPath>/_system/nodes</targetPath>
</mount>
<mount path="/_system/governance" overwrite="true">
<instanceId>instanceid</instanceId>
<targetPath>/_system/governance</targetPath>
</mount>
</code></pre>
<br />
Make a note of the highlighted configuration parameter.<br />
<br />
Now, the database configuration referred by the mount is defined at the top of registry.xml as follows.<br />
We simply change the JNDI name of the default db config;<b> jdbc/WSO2CarbonDB</b> to the JNDI name of our shared registry database; <b>jdbc/WSO2SharedRegDB</b><br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code> <b><currentDBConfig>wso2registry</currentDBConfig></b>
<readOnly>false</readOnly>
<enableCache>true</enableCache>
<registryRoot>/</registryRoot>
<dbConfig name="wso2registry">
<b> <dataSource>jdbc/WSO2SharedRegDB</dataSource></b>
</dbConfig>
</code></pre>
<br />
<br />
<br />
OK. Assuming everything is configured correctly, we start Carbon server. Unfortunately, you will get the above meaningless error at the server startup.<br />
<br />
<h4 style="text-align: left;">
What is wrong here?</h4>
<h4 style="text-align: left;">
</h4>
<br />
By defining a common data source for mount configuration as well as local registry definition (under currentDBConfig element), we have done a big mistake. This will eventually leads to share local registry space among heterogeneous product cluster nodes which is theoretically incorrect. <br />
<h4 style="text-align: left;">
</h4>
<h4 style="text-align: left;">
How can we fix this?</h4>
<h4 style="text-align: left;">
</h4>
Simple. You can define a separate, unique database configuration for the shared registry db.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><b><dbConfig name="sharedregistry"></b>
<dataSource>jdbc/WSO2SharedRegDB</dataSource>
</dbConfig>
</code></pre>
<br />
<br />
Then, that will be referenced by the remote mounting configuration.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><remoteInstance url="https://localhost:9443/registry">
<id>instanceid</id>
<b><dbConfig>sharedregistry</dbConfig></b>
<readOnly>false</readOnly>
<enableCache>true</enableCache>
<registryRoot>/</registryRoot>
</remoteInstance>
</code></pre>
<br />
Finally, make sure to change the local registry definition back to its default so that it will use the WSO2 Carbon DB (usually H2).<br />
<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><dbConfig name="wso2registry">
<dataSource>jdbc/WSO2CarbonDB</dataSource>
</dbConfig>
</code></pre>
<br />
Restart the server. The error will disappear!<br />
<br /></div>
Charithahttp://www.blogger.com/profile/00209392844529688942noreply@blogger.com5tag:blogger.com,1999:blog-5949896138631643846.post-30325390371470020232014-02-22T08:33:00.001-08:002014-02-22T08:37:00.865-08:00Common mistakes to avoid in WSO2 ESB - 1 - "org.apache.axis2.AxisFault: The system cannot infer the transport information from the URL"<div dir="ltr" style="text-align: left;" trbidi="on">
In the next few weeks, you could expect a series of blog posts from me which explain the remedies to avoid some common mistakes which we do when working with <a href="http://wso2.com/products/enterprise-service-bus/" target="_blank"><b>WSO2 ESB</b></a>. This is the first of many.<br />
<br />
During the initial rounds of testing your integration solution or even in production systems, you may have come across the following error.<br />
<br />
<b><i>org.apache.axis2.AxisFault: The system cannot infer the transport information from the URL ....</i></b><br />
<br />
Some of you may have struggled hours figuring out a solution to address this issue. Let me explain this error in detail and possible causes of this. So, next time when you see this error in your WSO2 ESB setup, you will not have to spend time unnecessarily googling everywhere.<br />
<br />
There can be many different causes of this error. I have observed four main reasons.<br />
<br />
<h4 style="text-align: left;">
<b>Cause 1</b></h4>
<br />
This is the simplest cause. Suppose, you have a proxy service similar to the following.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><proxy xmlns="http://ws.apache.org/ns/synapse"
name="MistakesTest"
transports="https,http"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<b> <send/></b>
</inSequence>
<outSequence>
<send/>
</outSequence>
</target>
<description/>
</proxy>
</code></pre>
<br />
Look at the inSequence of the above proxy. We have defined send mediator without address information. Now, when you send a typical SOAP request over HTTP to this proxy service, ESB does have no way to find where to route the request. The HTTP transport sender which is supposed to route the HTTP request clueless where to forward the request and fails with the following error.<br />
<br />
<i><b>ERROR - ClientUtils The system cannot infer the transport information from the /services/MistakesTest URL.ERROR - Axis2Sender Unexpected error during sending message out<br />org.apache.axis2.AxisFault: The system cannot infer the transport information from the /services/MistakesTest URL.<br /> at org.apache.axis2.description.ClientUtils.inferOutTransport(ClientUtils.java:81)</b></i><br />
<br />
<b>How can we fix this? There are many approaches.</b><br />
<br />
First, you can simply associate address information to the send mediator by defining an endpoint.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code> <send>
<b><endpoint>
<address uri="http://localhost:8088/mockaxis2service"/>
</endpoint></b>
</send>
</code></pre>
<br />
Or else, you can seek help of WS-Addressing framework. You can fix your client application to send your request with WS-Addressing To header as shown below. Then, Axis2 transport sender in WSO2 ESB, extracts the wsa:To header value of the request and forwards the message to back-end service.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://service.carbon.wso2.org">
<soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing"><wsa:Action>urn:echoString</wsa:Action><wsa:MessageID>uuid:86b1f69b-f4a2-4f4c-b5c9-54fea095972e</wsa:MessageID><b><wsa:To>http://localhost:8088/mockaxis2service</wsa:To></b></soapenv:Header>
<soapenv:Body>
<ser:echoString>
<ser:s>charitha</ser:s>
</ser:echoString>
</soapenv:Body>
</soapenv:Envelope>
</code></pre>
<br />
We have discussed about the simplest cause for the error which we are trying to solve. Next, let's try to understand another common reason.<br />
<h3 style="text-align: left;">
</h3>
<h4 style="text-align: left;">
<b>Cause 2</b></h4>
<br />
Suppose, you have a proxy service similar to the following.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><proxy xmlns="http://ws.apache.org/ns/synapse"
name="MistakesTest"
transports="https,http"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<b><send>
<endpoint>
<default/>
</endpoint>
</send></b>
</inSequence>
<outSequence>
<send/>
</outSequence>
</target>
<description/>
</proxy>
</code></pre>
<br />
Here, we have defined a <a href="http://docs.wso2.org/display/ESB481/Default+Endpoint" target="_blank">default</a> endpoint, which does not have an address URI associated with it and the address information is resolved through wsa:To header of the incoming request. <br />
Now, if you send a SOAP request, without wsa:To header, you will get the above error.<br />
<br />
<b>How can we fix this?</b><br />
<br />
Obviously, we can include wsa:To addressing header in the request (as explained before).<br />
Or else, you can add an <a href="http://docs.wso2.org/display/ESB481/Header+Mediator" target="_blank">header</a> mediator before send mediator in the above configuration which will set wsa:To header of the request.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><header name="To" value="http://localhost:9090/mockaxis2service"/>
</code></pre>
<br />
<h4 style="text-align: left;">
Cause 3</h4>
<br />
As I explained above, axis2 transport sender, defined at axis2.xml is responsible for forwarding the incoming request.<br />
<br />
e.g:-<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code> <transportSender name="http" class="org.apache.synapse.transport.passthru.PassThroughHttpSender">
</code></pre>
<br />
HTTP and HTTPS transport senders are enabled by default in axis2.xml. Think about a use case similar to the following.<br />
You need to do a transport protocol switching through WSO2 ESB, which is a quite common use case in any ESB. In that case, suppose you have a proxy service similar to the following.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="MistakesTest"
transports="https,http"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<send>
<endpoint>
<address uri="jms:/queue1?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&amp;java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&amp;java.naming.provider.url=tcp://localhost:61616&amp;transport.jms.DestinationType=queue"/>
</endpoint>
</send>
</inSequence>
<outSequence>
<send/>
</outSequence>
</target>
<description/>
</proxy>
</code></pre>
<br />
In this proxy configuration, the proxy service acts as a JMS producer and forwards the request coming through HTTP channel to a JMS queue (queue1). If you try this scenario, in vanilla version of WSO2 ESB without any modification, you will get the following error.<br />
<br />
<i><b>ERROR - Axis2Sender Unexpected error during sending message out<br />org.apache.axis2.AxisFault: The system cannot infer the transport information from the jms:/queue1?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory& java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&java.naming.provider.url=tcp://localhost:61616&transport.jms.DestinationType=queue URL</b></i><br />
<br />
<b>How can we fix this?</b><br />
<br />
In the default axis2 configuration, the HTTP transport senders are only enabled. Thus, when you we are trying to forward a message through non-HTTP transport such as JMS (or VFS, SAP, FiX, mail etc), ESB cannot finds the transport sender registered against the transport protocol define in endpoint url (in this example, "jms:/")<br />
Thus, you need to stop ESB and enable the relevant transport sender in ESB_HOME/repository/conf/axis2/axis2.xml as shown below.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><transportSender name="jms" class="org.apache.axis2.transport.jms.JMSSender"/>
</code></pre>
<br />
<h4 style="text-align: left;">
Cause 4</h4>
<br />
Let's conclude our discussion by looking at another common reason for "The system cannot infer transport..." error.<br />
<br />
When you are working with scenarios related to blocking transport senders, for example, <a href="http://docs.wso2.org/display/ESB481/Callout+Mediator" target="_blank"><b>Callout mediator</b></a> or <b><a href="http://docs.wso2.org/display/ESB481/Message+Processors" target="_blank">message processors</a></b>, you may have come across the same error. These elements use blocking transports to call the external services hence they cannot make use of the default axis configuration defined in ESB_HOME/repository/conf/axis2/axis2.xml.<br />
Think about a scenario, where you use message processor to query a queue and forward the message to an external file server through VFS transport or route to a SAP endpoint.<br />
In this case, even if you enabled, the relevant transportSenders in the default axis2.xml, message processor or Callout mediator is not aware of that. They read the axis configuration from the following locations by default.<br />
<br />
In ESB-4.8.0 or above:<br />
<b>ESB_HOME/repository/conf/axis2/axis2_blocking_client.xml</b><br />
<br />
In ESB-4.7.0 or below:<br />
<b>ESB_HOME/samples/axis2Client/client_repo/conf/axis2.xml</b><br />
<br />
Thus, if you do not enable transport senders in those locations, you get the same error. <br />
<br />
<br /></div>
Charithahttp://www.blogger.com/profile/00209392844529688942noreply@blogger.com1tag:blogger.com,1999:blog-5949896138631643846.post-14304832430254036212014-02-22T06:46:00.001-08:002014-02-22T06:46:06.582-08:00Back in blogosphere<div dir="ltr" style="text-align: left;" trbidi="on">
I have been away from blogging for more than 2 months. Many of the readers of this blog, asked me if I stopped writing or what. The last few months were hectic due to a many reasons. First, I moved to <a href="http://en.wikipedia.org/wiki/Bloomington,_Indiana" target="_blank">Bloomington</a>, a beautiful small town in Indiana, USA from my home country, <a href="http://en.wikipedia.org/wiki/Sri_Lanka" target="_blank">Sri Lanka</a>. Thus, I had to focus on many initial settlement stuff which allowed me very little time to scan through my blog. Next, I had to spend time on adjusting to the totally new environment specially crazy coldness in here.<br />
I believe I'm back in business now. As the tag line of this blog says, "no nonsense", only SOA and testing. Therefore, I'm not going to write about what is happening around me. I will continue sticking to the objective of this blog. Helping at least one person who is stuck figuring out an answer for a problem related to Service-Oriented architecture, enterprise integration or software testing. </div>
Charithahttp://www.blogger.com/profile/00209392844529688942noreply@blogger.com0tag:blogger.com,1999:blog-5949896138631643846.post-831353356685877572013-11-25T20:07:00.001-08:002013-11-25T20:07:13.713-08:00Simulating RESTful services with soapUI<div dir="ltr" style="text-align: left;" trbidi="on">
I have discussed about the mock services which simulate SOAP back-ends in chapter 6 of <a href="http://www.amazon.com/Services-Testing-soapUI-Kankanamge-Charitha/dp/1849515662" target="_blank">Web Services Testing with soapUI book</a>. For the past few years, service orientation has been shifting towards RESTful web services from SOAP which demands the necessity of mocking various types of RESTful services. Being the one-stop tool kit of SOA developers/testers, soapUI provides users with different options to simulate RESTful services. In this post, I will discuss one of such a simple mechanisms to create RESTful mock services in soapUI.<br />
<br />
<b>Pre-requisites:</b><br />
<br />
soapUI-4.5.2 or later<br />
<br />
<h4 style="text-align: left;">
Simulating POX (Plain-Old-XML) with soapUI</h4>
<div style="text-align: left;">
Suppose you have a web service which returns XML response. Usually, the HTTP Content-Type of such a message is application/xml or text/xml.</div>
<ol style="text-align: left;">
<li>Create a new MOCK Service in soapUI. You can either create a Mock service from a new WSDL (ouch! we are dealing with RESTful services. Why do we need WSDL?? Does not matter. We just want to have a mock service regardless of where it originated from. We will tweak the response to be RESTy. Trust me!) or add a new mock service by right-clicking on an interface of an existing SOAP based service.</li>
<li>Either way, you will have a mock service similar to the following.<br /><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguPjL7GoqKDYsZBREcrdOyyaLUPrn_MZMvHtrqGX6h6pH4fgFIcW0Ja5JzZpyi2hpEKUMWQwDOdPkOaAyKDJsdWkEgADbAFHkSxHIkaFJsvTb6T287lgYfC9adv8qBEfo4KL_jF0fCtuFg/s1600/soapui1.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="160" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguPjL7GoqKDYsZBREcrdOyyaLUPrn_MZMvHtrqGX6h6pH4fgFIcW0Ja5JzZpyi2hpEKUMWQwDOdPkOaAyKDJsdWkEgADbAFHkSxHIkaFJsvTb6T287lgYfC9adv8qBEfo4KL_jF0fCtuFg/s320/soapui1.png" width="320" /></a><br />Note that, our mock service will be exposed at <i><b>http://localhost:8088/restMockService</b></i></li>
<li>We are going to simulate a response with text/xml content. Create an XML file in your file system. i.e:-<br /><br />
<pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><root>
<child>value</child>
<root>
</code></pre>
<br />Save the file as xmlresponse.xml.</li>
<li>Once a HTTP request (regardless of the content of incoming message) hits the mock service, it will return XML response. We can execute a groovy script at this time and respond back with XML output. This can be achieved by having a <b>OnRequest Script</b> in soapUI mock service interface. Click on <b>OnRequest Script </b>tab at the bottom pane of mock service editor.</li>
<li>In the <b>OnRequest Script</b> editor, add the following script. <br /><br />
<pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>//To output text/xml
mockRunner.returnFile(mockRequest.httpResponse, new File("/home/charitha/Desktop/xmlresponse.xml"))
return new com.eviware.soapui.impl.wsdl.mock.WsdlMockResult(mockRequest)
</code></pre>
</li>
<li>Start the mock service by clicking on green arrow icon at the top left corner of mock service editor. </li>
<li>Send any HTTP request to <i><b>http://localhost:8088/restMockService. </b></i>You will observe the following output.<br /><br />
<pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>HTTP/1.1 200 OK
Content-Length: 35
Content-Type: text/xml
Connection: close
Server: Jetty(6.1.26)
<root>
<child>value</child>
<root>
</code></pre>
<br /><h4>
Simulating JSON output with soapUI</h4>
This is quite similar to the above procedure but a few tweaks are required to format the JSON response to be a valid JSON with application/json content-type.<br />
<br />
<ol>
<li>In the same mock service which we created above (or a different one), we will add a new OnRequest script. First, create a file in your local file system with the following content.<br /><br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>{
"getQuote": {
"request": { "symbol": "WSO2" }
}
}
</code></pre>
<br />Save the file as jsonresponse.json.</li>
<li>Now, add the following script as <b>OnRequest Script</b>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>import javax.servlet.http.HttpServletResponse
import com.eviware.soapui.support.Tools
def response = mockRequest.httpResponse
File file = new File("/home/charitha/Desktop/jsonresponse.json")
FileInputStream fin = new FileInputStream(file)
response.setStatus( HttpServletResponse.SC_OK )
long length = file.length();
response.setContentLength( ( int )length );
response.setContentType("application/json;charset=utf-8" );
Tools.readAndWrite( fin, length, response.getOutputStream() );
fin.close();
return new com.eviware.soapui.impl.wsdl.mock.WsdlMockResult(mockRequest)
</code></pre>
<br />You will question why we cannot just return the output of jsonresponse.json straight-away as we did with text/xml content. As explained by <a href="http://smartbear.com/speakers/ole-lensmar/" target="_blank">Ole Lensmar</a> (The creator of soapUI) in <a href="http://forum.loadui.org/viewtopic.php?f=2&t=15020&p=36012">http://forum.loadui.org/viewtopic.php?f=2&t=15020&p=36012</a> , this is a hack to respond back with application/json content-type. If you just return the file, the content-type will be delivered as application/javascript.</li>
<li>Now, restart the mock service and send a HTTP request to above mock service endpoint. You will get a response similar to the following.<br /><br /><br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>HTTP/1.1 200 OK
Content-Length: 60
Content-Type: application/json;charset=utf-8
Connection: close
Server: Jetty(6.1.26)
{
"getQuote": {
"request": { "symbol": "WSO2" }
}
}
</code></pre>
<br />Similarly, you can simulate what ever RESTful back-end you want with soapUI. For example, if you want to return<b> text/html</b>, create a simple HTML in your file system and add the following script.<br /><br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>//To output text/html
mockRunner.returnFile(mockRequest.httpResponse, new File("/home/charitha/Desktop/htmlresponse.html"))
return new com.eviware.soapui.impl.wsdl.mock.WsdlMockResult(mockRequest)
</code></pre>
<br />To return <b>text/plain</b> response, create a text file in file system and add the following script. <br /><br /><br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>//to output text/plain
mockRunner.returnFile(mockRequest.httpResponse, new File("/home/charitha/Desktop/plaintextresponse.txt"))
return new com.eviware.soapui.impl.wsdl.mock.WsdlMockResult(mockRequest)
</code></pre>
<br /><br />
</li>
</ol>
</li>
</ol>
</div>
Charithahttp://www.blogger.com/profile/00209392844529688942noreply@blogger.com2tag:blogger.com,1999:blog-5949896138631643846.post-92043719882265577672013-10-25T15:29:00.004-07:002013-10-25T15:29:51.252-07:00The difference between JSON streaming builder and the default JSON builder in WSO2 ESB<div dir="ltr" style="text-align: left;" trbidi="on">
When a request/response is received by ESB, the message will initially be converted into XML infoset. This process is known as message building and the builders are responsible to do this transformation based on the HTTP Content-Type of the incoming message. The default JSONBuilder<b> (org.apache.axis2.json.JSONBuilder) </b>converts the JSON into corresponding XML representation. If I explain this through an example, suppose your incoming JSON response/request is similar to the following. <br />
<br />
{ <br />
"getQuote": { <br />
"request": { "symbol": "charitha" } <br />
} <br />
} <br />
<br />
If you log this message inside inSequence of your message flow (using log mediator), you will observe an output similar to the following.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>LogMediator To: http://www.w3.org/2005/08/addressing/anonymous, </code></pre>
<pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>WSAction: , SOAPAction: , MessageID: urn:uuid:f37b8466-7cb3-41d6-9187-b5a0a7648f16, </code></pre>
<pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); color: black; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>Direction: response, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"><soapenv:Body><getQuote><request><symbol>charitha</symbol></request></getQuote></soapenv:Body></soapenv:Envelope>
</code></pre>
<br />
<br />
<br />
Look at the Body of the SOAP envelope. You may notice the JSON to XML mapping clearly in there. <br />
<br />
The message formatters do the complete opposite of builders. They are responsible for formatting the message into the relevant wire format. So, the default JSONMessageFormatter converts XML back into JSON. <br />
Obviously this JSON <--> XML conversion may lead to a certain degree of information loss. <br /><br />In order to avoid that, we have introduced the JSON streaming builder <b>(org.apache.axis2.json.JSONStreamBuilder)</b> which does not covert JSON message to intermediate XML format. If you conduct the same test which I explained above with streaming JSON builder, you will see a message similar to the following when you use log mediator within the message flow. <br /><br /><b><i>LogMediator To: http://www.w3.org/2005/08/addressing/anonymous, WSAction: , SOAPAction: , MessageID: urn:uuid:33d9ad3f-83bc-46ee-adb9-1cafd7e5a9cc, Direction: response, Envelope: <soapenv:envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"><soapenv:body></soapenv:body></soapenv:envelope></i></b> <br /><br />In the above message, there is no XML representation of the JSON message. The Body element is empty. <br /><br />Therefore, if you use streaming JSON builder/formatter, you will not be able to access the message payload. If you want to access/modify the payload, that can only be achieved using script mediator. To access/modify JSON paylaod, you can use mc.getPayloadJSON() or mc.setPayloadJSON() methods as explained in http://docs.wso2.org/display/ESB470/Sample+441:+Exposing+a+SOAP+Service+Over+JSON<!------></--></div>
Charithahttp://www.blogger.com/profile/00209392844529688942noreply@blogger.com2tag:blogger.com,1999:blog-5949896138631643846.post-56749042112526680302013-09-22T08:56:00.001-07:002013-09-22T09:00:07.132-07:00QA mind-set<div dir="ltr" style="text-align: left;" trbidi="on">
In the agile world of software development, quality assurance function is embedded into the main stream development process and it is not considered as an activity managed by a separate QA team. <br />
Even with following many agile testing principles, why do some teams still fail to deliver products/projects with acceptable quality?<br />
According to my experience, I believe the issues with <strong><em>adopting the QA mindset</em></strong> can be considered as the primary reason for many software quality concerns. <br />
So, what is QA mindset and why is it a critical factor in software testing? <br />
<br />
If you are a software developer, your primary objective is to complete the implementation of the feature/module which you have been assigned to do without schedule slippages. But, you are obliged to deliver it with best quality. So, you follow good agile testing principles, may be follow TDD (Test driven development), code reviews, write automation tests, do manual tests for the scenarios which you cannot automate, run performance tests etc.. <br />
However, when your "well-tested" feature is in UAT at your client's environment or verified by another person, the bug tracking system is filled up with many bugs. <br />
What went wrong in your testing? Why did you miss all these bugs?<br />
<br />
Software development has become more and more complex with all kinds of heterogeneous platform integrations which we use in today's applications. You are no longer expected to have the luxury of testing the traditional 3-tier applications. Instead, you need to think about large array of integration scenarios. The complexity multiplies by many factors when you are developing middleware. For example, what are the implications when your app runs on a cloud provider? what can be the behavior when the application is integrated into various DBMSs? what kind of changes can be expected in feature X of your app when it integrates with a third party enterprise application? <br />
How will the application behave when different message types are processed? Will the feature X provide the same functionality with each message type under various platforms?<br />
There can be endless questions! <br />
<br />
You should not even think about a process without comprehensive test automation methodology to address such a complex matrix of test combinations. However, you can never replace human brain by a test automation tool. The test scenarios, which are the inputs for your test automation tool, have to be derived by you. Thus, it is really important to adopt QA mindset in any testing activity regardless of its nature (automated or manual).<br />
<br />
QA mindset is all about the approach of looking at the problem at hand. When you develop a feature, you are mostly optimistic about its functionality since your mind forces you to believe that your creation is correct. You are biased towards your own work. <br />
If you seriously want to avoid a third eye complaining about your creation, always use QA mindset in testing. There is a tester inside all of us. Get him out when you start testing!<br />
<br />
<ul style="text-align: left;">
<li>Avoid pre-mature feature completion announcements. Do not judge the functionality by just observing the positive work flow. </li>
<li>Think about all possible integration scenarios. Write them down and execute each very carefully</li>
<li>If your component consists of feature X, Y and Z, test every attribute of each feature. Do not leave out anything obvious for a third eye to try and complain</li>
<li>Conduct more and more exploratory tests. Research on similar features implemented by others and look for missing use-cases. </li>
<li>If you are enhancing an existing feature, collect the issues reported by your customers on the old implementation and assess each of them against the new implementation. </li>
<li>Maintain a record of what you have tested so that a separate tester will not be repeating the same test scenarios which you have already tried out</li>
<li>Do not be fooled by code coverage figures. Try to break your implementation. </li>
</ul>
A lot of work.. huh? yes.. but at the end of the day, your work has to be part of a production system. So, quality is not something to compromise. Start to love software testing. That is the only way to deliver quality! </div>
Charithahttp://www.blogger.com/profile/00209392844529688942noreply@blogger.com1tag:blogger.com,1999:blog-5949896138631643846.post-46809354983871470472013-07-21T23:43:00.003-07:002013-07-21T23:43:24.275-07:00Working with HTTP multipart requests in soapUI<div dir="ltr" style="text-align: left;" trbidi="on">
You can use <i><b>HTTP request</b></i> test step in <a href="http://www.soapui.org/" target="_blank">soapUI</a> to submit messages with various Content-Types. In this post, we will have a quick look into the multipart/form-data requests in soapUI.<br />
<br />
multipart/form-data requests usually come into action when you do HTML form submissions with file attachments. For example, have a look at the following HTML form post.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><form action="http://localhost:8090/CKFileUploadApp/UploadServlet" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="text" name="paramName">
<input type="submit" name="Submit" value="Upload File">
</form>
</code></pre>
<br />
In the forms like above, we have file upload option as a form input where we can upload a file along with the form submission. In that case, the request's HTTP content type will be multipart/form-data. How can we simulate such a request using soapUI?<br />
<br />
<b>Pre-requisite:</b><br />
You can have your own file upload servlet as the backend. But in order to demonstrate the scenario, I have hosted a sample webapp, CKFileUploadApp.war from <a href="https://sourceforge.net/projects/charithablogsam/files/" target="_blank">here</a>. Make sure to change the following context parameter value in WEB-INF/web.xml directory before deploying the web application in Apache tomcat.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><param-name>file-upload</param-name>
<b><param-value>/home/charitha/</param-value></b>
</code></pre>
<br />
<h4 style="text-align: left;">
Step 1</h4>
Start to create a new soapUI project. Specify a name and select <b>Create Web TestCase</b> option.<br />
<br />
<b>Add Web TestCase</b> dialog will be displayed. Enter <i><b>http://localhost:8080/CKFileUploadApp/UploadServlet</b></i> as the Web Address. Clear <b>Start Recoding Immediately</b> option and click on OK.<br />
<br />
<h4 style="text-align: left;">
Step 2</h4>
Once the new HTTP request is added as explained in the first step, change the HTTP method to POST. The request editor should look like the following.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg93uao2f5b-HLXGtnk9prRCGemmubb1cHELj_ZDg6CELhKIShMKTBfTPnIF07zu1RqGi-JJkdMolqo7nYlGn41MX5IYC_qhC3cpKUV3vP_zhuLYZMS8nAGzrjtZtBlQt2wSu6ewMkvAPzE/s1600/soapui1.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="106" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg93uao2f5b-HLXGtnk9prRCGemmubb1cHELj_ZDg6CELhKIShMKTBfTPnIF07zu1RqGi-JJkdMolqo7nYlGn41MX5IYC_qhC3cpKUV3vP_zhuLYZMS8nAGzrjtZtBlQt2wSu6ewMkvAPzE/s400/soapui1.png" width="400" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<h4 style="text-align: left;">
Step 3</h4>
<br />
Choose <b><i>multipart/form-data</i></b> from the <b>Media Type</b> drop down. Now, click on <b>Attachments</b> tab at the bottom of the request editor (see below).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBAEVHr9qEBqAm9E3qG3LcztRCeEK4pQop_8mbmF5J5x76WIHtoU8qSNulB_zzjyhoCUc6hJ_asqUijcQBtwsqmFhx3-JXtnKfnmZuPanbbdq0E4UYPqadx7YTYe9d0PJ8jqnXvcTW-nEL/s1600/soapui2.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="268" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBAEVHr9qEBqAm9E3qG3LcztRCeEK4pQop_8mbmF5J5x76WIHtoU8qSNulB_zzjyhoCUc6hJ_asqUijcQBtwsqmFhx3-JXtnKfnmZuPanbbdq0E4UYPqadx7YTYe9d0PJ8jqnXvcTW-nEL/s400/soapui2.png" width="400" /></a></div>
<br />
<br />
<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<br />
Click on + icon at the top left corner of the attachment window to browse and attach a file to request. Browse for a file in your local file system and add it as an attachment. Now, the attachment editor will be similar to the following.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-B7kpUs9f1R-7PqQU67cVf6r0M6mhwTMSDp87bHBSVak3fVGRzQfH0O07xBUvzjID5MGCBbmTWWbLo6_1j9JAFT2Bsy4h2x9-8o2Db-nbeAK63cQl1Vv8qRX67RCfgZ5P24wZoPBIrurx/s1600/soapui3.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="38" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-B7kpUs9f1R-7PqQU67cVf6r0M6mhwTMSDp87bHBSVak3fVGRzQfH0O07xBUvzjID5MGCBbmTWWbLo6_1j9JAFT2Bsy4h2x9-8o2Db-nbeAK63cQl1Vv8qRX67RCfgZ5P24wZoPBIrurx/s400/soapui3.png" width="400" /></a></div>
<br />
<br />
<br />
<br />
<h4 style="text-align: left;">
<span style="font-weight: normal;"><br /></span></h4>
<h4 style="text-align: left;">
<span style="font-weight: normal;"><br /></span></h4>
<h4 style="text-align: left;">
<span style="font-weight: normal;">Step 4</span></h4>
<br />
We have everything ready to send the request with a file attachment. Click on submit button to send the request. You will get a HTTP 200 response with the message "Uploaded Filename: <filename>" message. Click on the raw view of the request. You will see the Content-Type of the request is set to multipart/form-data. You will also notice the relevant MIME boundaries of the request.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRmpqvLwmJbAsMxWuYVBn9etp2BB5r5imutsvZBKPWts56fgXeumg7l7zTjj5aApTGSaA97zkHd_xEctT9MxOwxEmNom9cMkSgaELcBqJ75eJ-sWHpGbIOtomKv2oqQaLq2GL_taJEUKhH/s1600/soapui5.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="185" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRmpqvLwmJbAsMxWuYVBn9etp2BB5r5imutsvZBKPWts56fgXeumg7l7zTjj5aApTGSaA97zkHd_xEctT9MxOwxEmNom9cMkSgaELcBqJ75eJ-sWHpGbIOtomKv2oqQaLq2GL_taJEUKhH/s400/soapui5.png" width="400" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Since I have attached an xml file to the request, you can observe the Content-Type of the attachment part of the message as text/xml.<br />
<br />
<br />
<b><i>------=_Part_17_31084605.1374474723633</i></b><br />
<b><i>Content-Type: text/xml; charset=UTF-8; name=registry.xml</i></b><br />
<div>
<br /></div>
</div>
Charithahttp://www.blogger.com/profile/00209392844529688942noreply@blogger.com1tag:blogger.com,1999:blog-5949896138631643846.post-42185650036167246622013-07-16T01:55:00.000-07:002013-07-16T01:55:37.611-07:00OAuth 2.0 grant types with WSO2 API Manager - II - Implicit<div dir="ltr" style="text-align: left;" trbidi="on">
This is the second of a series of posts related to OAuth-2.0 grant types in WSO2 API Manager (WSO2 Carbon platform). Therfore, I strongly suggest you to read and work on the examples described in <a href="http://charithaka.blogspot.com/2013/07/oauth-20-grant-types-with-wso2-api.html" target="_blank">the first post</a> before proceeding with this.<br />
<br />
In this post, we will go through Implicit grant type which is the recommended practice if your application (client) is a mobile application or a browser based app such as a JavaScript client. The key difference of implicit grant when comparing to the Authorization Code is, the client receives access token as the result of the authorization request. In our previous post, which was about Authorization Code grant, client had to make separate requests for authorization and access token. Also note that, the implicit grant does not include client authentication because it does not make use of client secret.<br />
<br />
Before attempting to work on the sample, let's have a look at the steps involved in implicit grant type.<br />
<br />
<div style="text-align: left;">
<span style="font-weight: normal;">1.
Application (client) does a token request from the
authorization server by sending a HTTP GET request with the following
query parameters.</span></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<b><i><span style="font-weight: normal;">response_type = token</span></i></b></div>
<div style="text-align: left;">
<b><i><span style="font-weight: normal;">client_id = VALUE_OF_CONSUMER_KEY</span></i></b></div>
<div style="text-align: left;">
<b><i><span style="font-weight: normal;">redirect_uri = REDIRECT_URL_OF_THE_APPLICATION</span></i></b></div>
<div style="text-align: left;">
<b><i><span style="font-weight: normal;">scope = SCOPE_OF_THE_ACCESS_REQUEST</span></i></b></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<span style="font-weight: normal;">The first two are mandatory parameters where as the last two can be optional. </span></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<span style="font-weight: normal;">2.
Upon receiving the request, the authorization server must return a 302 redirection back to the
client with an <b>Location</b> header pointing to the URL of user consent page.
(e.g:- Location:
https://localhost:9443/carbon/oauth/oauth2_authn_ajaxprocessor.jsp)</span></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<span style="font-weight: normal;">3. User (resource owner) confirms the authorization requested by client (application) by specifying his credentials.</span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<span style="font-weight: normal;">4. Authorization server redirects user back to the application (to the callback url which has been specified at the first step) with the access token. </span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<span style="font-weight: normal;">Let's
explore more on the above steps, using our sample web application (acts
as the client/application) and WSO2 API Manager (acts as the
authorization server).</span><br />
<br />
<span style="font-weight: normal;"></span><br />
<div style="text-align: left;">
<h4 style="text-align: left;">
<b><span style="font-weight: normal;">Step 1</span></b></h4>
</div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<span style="font-weight: normal;">Access
the OAuth playground application as instructed in "Setting up client"
section in the <a href="http://charithaka.blogspot.com/2013/07/oauth-20-grant-types-with-wso2-api.html" target="_blank">previous post</a>. Once you click on "Import Photos" icon, you will be landed in a
page where you will find a form with various options such as
Authorization Grant Type, Client Id etc..</span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<h4 style="text-align: left;">
<span style="font-weight: normal;">Step 2</span></h4>
</div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<span style="font-weight: normal;">Select <b>Implicit</b> as the Authorization Grant Type. </span></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<span style="font-weight: normal;">Copy
the consumer key value from the application you have subscribed in WSO2
API Manager (see above) and enter it in <b>Client Id</b> text box.</span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<span style="font-weight: normal;">Specify any string value as scope. We do not really worry about scope attribute in this example. </span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<span style="font-weight: normal;">Enter
callback URL which must be identical to the value you have specified at
the time of creating the new application in WSO2 API Manager. </span></div>
<div style="text-align: left;">
<span style="font-weight: normal;">e.g:- http://localhost:8090/playground2.0/oauth2client</span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<span style="font-weight: normal;">Enter
Authorize endpoint. This should be the endpoint of authorization server
where it accepts the authorization requests. In WSO2 API Manager, there
is an API to handle all authorization requests and it can be accessed
through http://localhost:8280/authorize.</span><br />
<br />
<span style="font-weight: normal;">Once you completed adding all values in the form in the playground app, click on Authorize.</span><br />
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<span style="font-weight: normal;">This
will generate HTTP GET request similar to the following. You can see it
contains all mandatory URL parameters which we have discussed in point 1
under the general introduction of "Implicit grant type".</span><br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>GET /authorize?scope=api_scope&response_type=token&redirect_uri=http%3A%2F%2Flocalhost%3A8090%2Fplayground2.0%2Foauth2client&client_id=ePCzEHajPOZRKus4XS3pva_Ec5Ua HTTP/1.1
Host: 127.0.0.1:8281
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:7.0.1) Gecko/20100101 Firefox/7.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,es;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Referer: http://127.0.0.1:8090/playground2.0/oauth2.jsp?reset=true
Cookie: i18next=en-US; region1_configure_menu=none; region3_registry_menu=none; region4_monitor_menu=none; region5_tools_menu=none
</code></pre>
</div>
</div>
</div>
<br />
<br />
<div style="text-align: left;">
<h4 style="text-align: left;">
<span style="font-weight: normal;">Step 3</span></h4>
</div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<span style="font-weight: normal;">When
you click on "authorize" with all required parameters, the application
generates the above HTTP GET call and you will be redirected to the user
consent screen as shown below. </span><br />
<span style="font-weight: normal;"><br /></span>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWAgNP-xxtiYAHGP0Cr31JvF3rMc-Z6okegmfPdzyZuhOXG3DlouFPcoypGIcT1gCT_Dj-dDKJYpLzBYMQ0lEWrchu-0It9J5K4oWetqD0HbI3ZCm91O6gHoHR2Jz7jQn3RSDQOw8aZB7D/s1600/user_consent2.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="71" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWAgNP-xxtiYAHGP0Cr31JvF3rMc-Z6okegmfPdzyZuhOXG3DlouFPcoypGIcT1gCT_Dj-dDKJYpLzBYMQ0lEWrchu-0It9J5K4oWetqD0HbI3ZCm91O6gHoHR2Jz7jQn3RSDQOw8aZB7D/s400/user_consent2.png" width="400" /></a></div>
<span style="font-weight: normal;"><br /></span>
<span style="font-weight: normal;"><br /></span>
<span style="font-weight: normal;"><br /></span>
<span style="font-weight: normal;"><br /></span>
<span style="font-weight: normal;"><br /></span>
<span style="font-weight: normal;"><br /></span>
<span style="font-weight: normal;"><br /></span>
<span style="font-weight: normal;">Click on Authorize. You will be
provided with options to enter user name and password (username and
password of the resource owner/end user).</span><br />
<br />
<span style="font-weight: normal;">Type admin/admin as user name and passeword respectively and click on login.</span><br />
<br />
<h4 style="text-align: left;">
<span style="font-weight: normal;">Step 4</span></h4>
<br />
<span style="font-weight: normal;">You will receive the <b>Access Token </b>as shown below.<b><br /></b></span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjX_z2W3FEwcy-pjM0jRWlBnSijtX16Dz9ZyiLZrdpVeOb2LhRfw60RRnpOZPklnTPfuzwcpequ81-d9b8atxELahUd7OexvpSRAkaSEEcaxvxrB4IHz6S9SiP-qBNrgpSyBNN3taIlMy1n/s1600/implicit_token.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="137" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjX_z2W3FEwcy-pjM0jRWlBnSijtX16Dz9ZyiLZrdpVeOb2LhRfw60RRnpOZPklnTPfuzwcpequ81-d9b8atxELahUd7OexvpSRAkaSEEcaxvxrB4IHz6S9SiP-qBNrgpSyBNN3taIlMy1n/s400/implicit_token.png" width="400" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<span style="font-weight: normal;">Now, we can use this access token to do the actual API call.</span><br />
<br />
<span style="font-weight: normal;">We will explore <b>Client Credentials</b> OAuth-2.0 grant type in our next post. </span><span style="font-weight: normal;"><br /></span></div>
Charithahttp://www.blogger.com/profile/00209392844529688942noreply@blogger.com0tag:blogger.com,1999:blog-5949896138631643846.post-50757397368833072542013-07-15T22:44:00.000-07:002013-07-15T22:44:24.539-07:00OAuth 2.0 grant types with WSO2 API Manager - I - Authorization Code<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: left;">
<a href="http://wso2.com/products/api-manager/" target="_blank">WSO2 API Manager</a> is a complete open source solution to manage APIs. It provides authorization and authentication for APIs using OAuth 2.0 standard. According to the OAuth specification, the client needs to get authorization from the resource owner when requesting an <b>access token</b>. The authorization is expressed in the form of an <b>authorization grant</b>, which the client uses to request the access token. There are 4 grant types defined in the OAuth spec.</div>
<br />
<ul style="text-align: left;">
<li>Authorization code</li>
<li>Implicit</li>
<li>Resource owner password credentials</li>
<li>Client credentials</li>
</ul>
<br />
Almost all scenarios explained in the online documentations written on WSO2 API Manager, make use of the <b>Resource owner password credentials</b> grant type. In there, we exchanges access token for user credentials and client_id and client_secret.<br />
<br />
I'm going to explain the use of all 4 OAuth grant types using WSO2 API Manager through a serious of blog posts. In this post, I will explain how we can use <b>Authorization Code</b> grant type with WSO2 API Manager. <br />
<br />
Pre-requisites:<br />
==============<br />
1. Download and install WSO2 API Manager-1.4.0<br />
2. Install Apache Tomcat<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8h2fPmVspvAKloj7YlAJMUut2qrgk5fF1HqnnxCRQstcNbVmn2iUJgDGm5H6TNnf9beXk87aOeHPXtboNvAzkfwdYrslomdobqUPH3ZMmRimhoC8niVFVAy7QX28gpUkx3T5YG0K0EJCu/s1600/api.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="218" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8h2fPmVspvAKloj7YlAJMUut2qrgk5fF1HqnnxCRQstcNbVmn2iUJgDGm5H6TNnf9beXk87aOeHPXtboNvAzkfwdYrslomdobqUPH3ZMmRimhoC8niVFVAy7QX28gpUkx3T5YG0K0EJCu/s400/api.png" width="400" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
When calling an API hosted in WSO2 API Manager, we need to associate an OAuth access token as part of the requests HTTP header to authenticate the caller.<br />
<br />
<i>POST http://localhost:8280/myapi/1.0.0 HTTP/1.1
<br />Accept-Encoding: gzip,deflate
<br />Content-Type: text/xml;charset=UTF-8
<br />SOAPAction: "urn:echoInt"
<br /><b>Authorization: Bearer 21737b20a287fb4e207bf08bf3b17924</b></i>
<br />
<br />
WSO2 API manager consists of multiple components to provide unique functionalities required to manage APIs hosted in it. Authorization server, which is one of such components, responsible for issuing tokens which are needed to authenticate API consumers. Therefore, before making a API call, the application user should possess the relevant access token with him.<br />
<br />
Obtaining access token can be done in multiple ways. In other words, the four of the above OAuth grant types can be used to obtain access token from the authorization server. <br />
Let's see how we can obtain access tokens from each of the OAuth 2 grant types.<br />
<br />
<br />
<h4 style="text-align: left;">
Setting up Client (Third party application) </h4>
<br />
As shown in the above picture, we will use a web application hosted in Apache Tomcat as the client.<br />
Download playground2.0.war from <a href="https://sourceforge.net/projects/charithablogsam/files/" target="_blank">here</a> and copy it to TOMCAT_HOME/webapps directory. Make sure to update the following parameters in WEB-INF/web.xml <br />
<br />
<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><servlet>
<servlet-name>oAuth2ClientServlet</servlet-name>
<servlet-class>com.wso2.identity.oauth.sample.OAuth2ClientServlet</servlet-class>
<init-param>
<description>serverUrl</description>
<param-name>serverUrl</param-name>
<b><param-value>https://localhost:9443/services/</param-value></b>
</code></pre>
<br />
localhost is the server where we host WSO2 API Manager and 9443 is the default SSL port of it.<br />
Also, make sure to update param-value of setup to <b>AM</b> as shown below.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><servlet>
<servlet-name>oAuth2AccessResourcePage</servlet-name>
<jsp-file>/oauth2-access-resource.jsp</jsp-file>
<init-param>
<description>setup</description>
<param-name>setup</param-name>
<b><param-value>AM</param-value></b>
</init-param>
</code></pre>
<br />
Restart tomcat and access <i><b>http://localhost:8080/playground2.0/</b></i> (assuming tomcat is running on HTTP port 8080). You will be directed to the landing page of our sample application. Click on Import Photos and you will be shown the following page.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxc7HR3lQi2S8DHmDfHJafCGoAYAXAzeKF-5ATIO5VzNOrJtuWOlNduUxS5fSmryhpgh_G7_O50dXD1Nyam4R9oNWUF5qE7YIZ7KeULl1fsSrHH19nGEgHplyUUV3iAWHU0PQLC5YPEudH/s1600/playground.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="188" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxc7HR3lQi2S8DHmDfHJafCGoAYAXAzeKF-5ATIO5VzNOrJtuWOlNduUxS5fSmryhpgh_G7_O50dXD1Nyam4R9oNWUF5qE7YIZ7KeULl1fsSrHH19nGEgHplyUUV3iAWHU0PQLC5YPEudH/s400/playground.png" width="400" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
We can use this application to request access tokens using the four OAuth2 grant types.<br />
<br />
<h4 style="text-align: left;">
Create and subscribe to a new API in WSO2 API Manager </h4>
<div style="text-align: left;">
<br />
Before exploring OAuth grant types supported by WSO2 API Manager, we need to add an API using the API publisher web app in WSO2 API Manager, publish it to the API gateway component and finally subscribe to the API through API store web app. I'm not going to repeat those steps in this post since I have already explained them in one of <a href="http://wso2.com/library/blog-post/2012/07/consuming-soap-service-using-wso2-api-manager" target="_blank">my previous posts</a>. You will also find the <a href="http://docs.wso2.org/wiki/display/AM140/WSO2+API+Manager+Documentation" target="_blank">WSO2 API Manager official documentation</a> useful. However, I will explain one modification which will be important to continue with our example.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
In WSO2 API Manager, an application user subscribes to an API or multiple APIs through an application. The OAuth keys are generated per application. Once you have access token in a particular application, you can call any APIs associated with it using the same key. </div>
<div style="text-align: left;">
When you add a new application, you will notice an option to include a <b>Callback URL</b> with the application (see below).</div>
<div style="text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiLwLYnUOhEvOWf0I13BnAS3MVBsyIodpoLE9RqgbG8yNoJ5qni9RX0BV8GevUk4R9J4oLn-AoxU_r7OIuQTPT3Gjxof6ToEQP19GebUdjHOl77CeVn0in9Lcy6yRBsQ8LiurejQSBRxOl/s1600/oauthapp.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="116" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiLwLYnUOhEvOWf0I13BnAS3MVBsyIodpoLE9RqgbG8yNoJ5qni9RX0BV8GevUk4R9J4oLn-AoxU_r7OIuQTPT3Gjxof6ToEQP19GebUdjHOl77CeVn0in9Lcy6yRBsQ8LiurejQSBRxOl/s400/oauthapp.png" width="400" /></a></div>
<div style="text-align: left;">
<br /></div>
<h4 style="text-align: left;">
</h4>
<h4 style="text-align: left;">
</h4>
<h4 style="text-align: left;">
</h4>
<h4 style="text-align: left;">
</h4>
<div style="text-align: left;">
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<b>Callback URL</b> <span style="font-weight: normal;">is a redirection URI in the client application which is used by the authorization server to send the client's user-agent (usually web browser) back after granting access. In our example, we will use <i><b>http://localhost:8090/playground2.0/oauth2client</b></i> as the Callback URL.</span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<span style="font-weight: normal;">Once you create the application, you can subscribe to one or more APIs using the new application. </span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOFBVt_DiwzddVW7NnvUGlEbM_qXdleiM_qYbdiALTPzrT5LPqujs0w5RMz1ARS8m2YZ6h99fqzPGOJYiZnqZ8zF6meHeQ9LVkpOjUkhsgbDSZ2vrGvFdrxb2_kvltZUnfVQ1tAZ_EbDwx/s1600/keys.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="157" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOFBVt_DiwzddVW7NnvUGlEbM_qXdleiM_qYbdiALTPzrT5LPqujs0w5RMz1ARS8m2YZ6h99fqzPGOJYiZnqZ8zF6meHeQ9LVkpOjUkhsgbDSZ2vrGvFdrxb2_kvltZUnfVQ1tAZ_EbDwx/s400/keys.png" width="400" /></a></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<br />
<span style="font-weight: normal;">Make a note of <i><b>access token</b></i>, <i><b>consumer key</b></i> and <i><b>consumer secret</b></i> specific to your application. </span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<h4 style="text-align: left;">
<span style="font-weight: normal;">Authorization code grant type with API Manager</span></h4>
<h4 style="text-align: left;">
<span style="font-weight: normal;"> </span></h4>
<div style="text-align: left;">
<span style="font-weight: normal;">Authorization code grant type is the recommended approach if the client is a web server based application such as a servlet, JSP etc. The authorization code grant type can simply be explained using the following steps. </span></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<span style="font-weight: normal;">1. Application (client) requests an authorization code from the authorization server by sending a HTTP GET request with the following query parameters.</span></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<b><i><span style="font-weight: normal;">response_type = code</span></i></b></div>
<div style="text-align: left;">
<b><i><span style="font-weight: normal;">client_id = VALUE_OF_CONSUMER_KEY</span></i></b></div>
<div style="text-align: left;">
<b><i><span style="font-weight: normal;">redirect_uri = REDIRECT_URL_OF_THE_APPLICATION</span></i></b></div>
<div style="text-align: left;">
<b><i><span style="font-weight: normal;">scope = SCOPE_OF_THE_ACCESS_REQUEST</span></i></b></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<span style="font-weight: normal;">The first two are mandatory parameters where as the last two can be optional. </span></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<span style="font-weight: normal;">2. The authorization server must return a 302 redirection back to the client with an Location header pointing to the URL of user consent page. (e.g:- Location: https://localhost:9443/carbon/oauth/oauth2_authn_ajaxprocessor.jsp)</span></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<span style="font-weight: normal;">3. User (resource owner) confirms the authorization requested by client (application) by specifying his credentials.</span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<span style="font-weight: normal;">4. Authorization server responds back to the callback URL specified at the first step with an Authorization Code.</span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<span style="font-weight: normal;">5. Application makes a HTTP POST request to get <b>access token</b> with the following POST parameters</span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<span style="font-weight: normal;">grant_type = </span><span style="font-weight: normal;"> authorization_code</span></div>
<div style="text-align: left;">
<span style="font-weight: normal;">code = authorization_code_value_obtained_from_step_4</span></div>
<div style="text-align: left;">
<span style="font-weight: normal;">redirect_url = redirect_url_of_the_application</span><br />
<span style="font-weight: normal;">client_id = value_of_consumer_id </span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"></span></div>
<div style="text-align: left;">
<span style="font-weight: normal;">client_secret = value_of_consumer_secret</span></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<span style="font-weight: normal;">6. Finally, the authorization server returns an access token optionally with a refresh token</span></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<span style="font-weight: normal;">Let's explore more on the above steps, using our sample web application (act as the client/application) and WSO2 API Manager (act as the authorization server).</span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<h4 style="text-align: left;">
<b><span style="font-weight: normal;">Step 1</span></b></h4>
</div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<span style="font-weight: normal;">Access the OAuth playground application as instructed in "Setting up client" section. Once you click on "Import Photos" icon, you will be landed in a page where you will find a form with various options such as Authorization Grant Type, Client Id etc..</span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<h4 style="text-align: left;">
<span style="font-weight: normal;">Step 2</span></h4>
</div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<span style="font-weight: normal;">Select <b>Authorization Code</b> as the Authorization Grant Type. </span></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<span style="font-weight: normal;">Copy the consumer key value from the application you have subscribed in WSO2 API Manager (see above) and enter it in Client Id text box.</span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<span style="font-weight: normal;">Specify any string value as scope. We do not really worry about scope attribute in this example. </span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<span style="font-weight: normal;">Enter callback URL which must be identical to the value you have specified at the time of creating the new application in WSO2 API Manager. </span></div>
<div style="text-align: left;">
<span style="font-weight: normal;">e.g:- http://localhost:8090/playground2.0/oauth2client</span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<span style="font-weight: normal;">Enter Authorize endpoint. This should be the endpoint of authorization server where it accepts the authorization requests. In WSO2 API Manager, there is an API to handle all authorization requests and it can be accessed through http://localhost:8280/authorize.</span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<span style="font-weight: normal;">These APIs can be found in "Deployed APIs" page in API Manager management console (gateway) as shown below.</span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcBvBbILxCy8zh1buEccNJArlXLwiaqN_hBZgqyN3XeGV494FetvDSbsk2D17-HSmeHjpo5-zR8DwWTDyH7dzaCB1CiQMXlmJt03HoBr7wEbHW-tzxUm79vmnFTEaAgFHdKu3v6u5uWASk/s1600/apimlist.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="76" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjcBvBbILxCy8zh1buEccNJArlXLwiaqN_hBZgqyN3XeGV494FetvDSbsk2D17-HSmeHjpo5-zR8DwWTDyH7dzaCB1CiQMXlmJt03HoBr7wEbHW-tzxUm79vmnFTEaAgFHdKu3v6u5uWASk/s400/apimlist.png" width="400" /></a></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<br />
<br />
<span style="font-weight: normal;">Once you completed adding all values in the form in the playground app, click on Authorize.</span></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<span style="font-weight: normal;">This will generate HTTP GET request similar to the following. You can see it contains all mandatory URL parameters which we have discussed in point 1 under "Authorization Code grant type".</span></div>
<div style="text-align: left;">
<br /></div>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>GET /authorize?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A8090%2Fplayground2.0%2Foauth2client&client_id=ePCzEHajPOZRKus4XS3pva_Ec5Ua%20&scope=my_scope HTTP/1.1
Connection: keep-alive
User-Agent: Jakarta Commons-HttpClient/3.1
Host: 127.0.0.1:8281
</code></pre>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<h4 style="text-align: left;">
<span style="font-weight: normal;">Step 3</span></h4>
</div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<span style="font-weight: normal;">When you click on "authorize" with all required parameters, the application generates the above HTTP GET call and you will be redirected to the user consent screen as shown below. </span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5WEURDadVHuTfPznjH7pnRzpiAY3WA_lLBtJGQtJhnfRnfsX4UWXwZB53IxHhoZ_kd2kVIpdS92-W7VkwUahkcNzK5eEq3RlwO7osB9hwvow9kBjS2ZhZf5N8A6hqPaDHDznVGh_tqQpx/s1600/consent.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5WEURDadVHuTfPznjH7pnRzpiAY3WA_lLBtJGQtJhnfRnfsX4UWXwZB53IxHhoZ_kd2kVIpdS92-W7VkwUahkcNzK5eEq3RlwO7osB9hwvow9kBjS2ZhZf5N8A6hqPaDHDznVGh_tqQpx/s1600/consent.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="98" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5WEURDadVHuTfPznjH7pnRzpiAY3WA_lLBtJGQtJhnfRnfsX4UWXwZB53IxHhoZ_kd2kVIpdS92-W7VkwUahkcNzK5eEq3RlwO7osB9hwvow9kBjS2ZhZf5N8A6hqPaDHDznVGh_tqQpx/s400/consent.png" width="400" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<span style="font-weight: normal;">Click on Authorize. You will be provided with options to enter user name and password (username and password of the resource owner/end user).</span><br />
<br />
<span style="font-weight: normal;">Type admin/admin as user name and passeword respectively and click on login.</span><br />
<br />
<h4 style="text-align: left;">
<span style="font-weight: normal;">Step 4</span></h4>
<br />
<span style="font-weight: normal;">You will be directed to a new form with an <b>Authorization Code</b>. (see below)</span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJpqlUhxKp6dA_zbM3-4ZCy6ZAXMTVWJsK_yfkPm7hTUsy-6tbhz0ixpii4gKLcnMurGksYi4wdswlyB0vRsQCQvsHp7pAH8lVE50MS5nxGhNf7U3yILAIyc3QGiQWmaHybxtWJn5jEc6H/s1600/authscreen.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="168" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJpqlUhxKp6dA_zbM3-4ZCy6ZAXMTVWJsK_yfkPm7hTUsy-6tbhz0ixpii4gKLcnMurGksYi4wdswlyB0vRsQCQvsHp7pAH8lVE50MS5nxGhNf7U3yILAIyc3QGiQWmaHybxtWJn5jEc6H/s400/authscreen.png" width="400" /></a></div>
<br />
<br /></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span></div>
<h4 style="text-align: left;">
<span style="font-weight: normal;"><br /></span></h4>
<h4 style="text-align: left;">
<span style="font-weight: normal;"><br /></span></h4>
<div style="text-align: left;">
<span style="font-weight: normal;"><br /></span>
<span style="font-weight: normal;"></span><br />
<br />
<br />
<br />
<span style="font-weight: normal;">Specify the same call back url which you have entered in step 2. (http://localhost:8090/playground2.0/oauth2client)</span><br />
<br />
<span style="font-weight: normal;">We are going to obtain an access token from the authorization server. Thus, we need to specify the endpoint URL of the API which returns access tokens. You can find it in the same way as we got the authorize endpoint from </span><span style="font-weight: normal;"> "Deployed APIs" page in API Manager management console (gateway). It will be similar to </span>http://localhost:8280/token<span style="font-weight: normal;">. </span><br />
<br />
<span style="font-weight: normal;">Specify client secret (consumer secret) value which can be found in the relevant application in the API store of WSO2 API manager (see above).</span><br />
<br />
<span style="font-weight: normal;"> Click on Get Access Token. This will generate a HTTP POST request similar to the following.</span><br />
<span style="font-weight: normal;"><br /></span>
<span style="font-weight: normal;"><br /></span>
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>POST /token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache
Pragma: no-cache
User-Agent: Java/1.6.0_29
Host: 127.0.0.1:8281
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Content-Length: 223
client_secret=fasxsVxJkTNzYtIAXxly8fR8s8ga+&grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalhost%3A8090%2Fplayground2.0%2Foauth2client&code=7dea8b1258febe471f2dad424dad6fd&client_id=ePCzEHajPOZRKus4XS3pva_Ec5Ua
</code></pre>
<span style="font-weight: normal;"> </span><br />
Compare this with the mandatory parameters which we have explained under point number 5 in authorization code grant type. <br />
<br />
<h4 style="text-align: left;">
<b><span style="font-weight: normal;">Step 5</span></b></h4>
<span style="font-weight: normal;"><br /></span>
<span style="font-weight: normal;">You will get an access token (typically a JSON response) which can be used to do the actual API call. </span><br />
<span style="font-weight: normal;"><br /></span></div>
<div style="text-align: left;">
<span style="font-weight: normal;">We will discuss the usage of implicit OAuth grant type in the next post. Stay tuned!!!</span></div>
</div>
Charithahttp://www.blogger.com/profile/00209392844529688942noreply@blogger.com2tag:blogger.com,1999:blog-5949896138631643846.post-1642613618354810322013-07-05T21:12:00.003-07:002013-07-05T21:12:54.458-07:00Broker trust relationships with WSO2 Identity Server<div dir="ltr" style="text-align: left;" trbidi="on">
WS-Trust can be considered as an extension to WS-Security specification which primarily provides methods for managing security tokens and ways to broker the trust relationships. The web services trust model explained under the <a href="http://docs.oasis-open.org/ws-sx/ws-trust/v1.4/ws-trust.html" target="_blank">WS-trust specification</a> defines three key participants. <br />
<br />
<ul style="text-align: left;">
<li>Security token service</li>
</ul>
<ul style="text-align: left;">
<li>Service Consumer</li>
</ul>
<ul style="text-align: left;">
<li>Service provider (Relying party)</li>
</ul>
<div style="text-align: left;">
<br />
<b>Security token service (STS)</b> is a web service that issues security tokens based on requesters needs. The <b>consumer</b> sends token requests to the STS as well as append tokens into the actual service request and submits them to the provider. The <b>service provider</b> makes the authentication decison on the service based on the token provided by STS. The service provider may also request token validations from the STS. <br />
<br />
This post is not yet another detailed explanation about WS-trust and the associated frameworks. You can find many references just by googling the term,<i> ws-trust</i>. Instead, I'm going to take you through a set of step-by-step instructions on how WS-trust concepts can be used with WSO2 SOA middleware. Hope this post will be a starting point for your journey towards learning WS-trust.</div>
<div style="text-align: left;">
<br /></div>
<h4 style="text-align: left;">
Use Case</h4>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
We are going to work on the basic trust establishment use case in the context of WS-trust specifiction. A SOAP web service consumer requests security token from a STS. We will make use of WSO2 Identity Server as the token provider. WSO2 Identity Server includes a Security Token Service (STS) which is capable of generating security tokens to build trust relationships. </div>
<div style="text-align: left;">
Once the consumer possesses the necesary security tokens, he presents those tokens to authenticate to a web service deployed in WSO2 Application Server.</div>
<div style="text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-WqtgLw-eePM/UdbQ-BxXXUI/AAAAAAAAAuw/Y6Vp7q6KOGk/s1600/sts.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="287" src="http://3.bp.blogspot.com/-WqtgLw-eePM/UdbQ-BxXXUI/AAAAAAAAAuw/Y6Vp7q6KOGk/s400/sts.png" width="400" /></a></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<b>Pre-requisites:</b></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
1. Download and install WSO2 Identity Server 4.1.0 or later version</div>
<div style="text-align: left;">
2. Download and install WSO2 Application Server 5.0.1 or later version</div>
<div style="text-align: left;">
3. Any Java IDE (Eclipse, Idea)</div>
<div style="text-align: left;">
4. soapUI (optional)</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
First, we need to figure out how we can start the end-to-end process. Obviously, the consumer initiates the process. But, how does the consumer know that he first needs to talk to a STS in order to consume the web service which is deployed in WSO2 application server? </div>
<div style="text-align: left;">
The service provider needs to advertise those requirements through a WS-Policy. So, the starting point of our use case is to configure a policy in the web service. </div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Then, we need to look into the token provider, WSO2 Identity Server. As I have explained before, WSO2 IS comes with a Security Token Service. We need to configure it to issue tokens to the provider web service and secure STS using a WS-Security policy because the consumers should authenticate themselves to the STS when requesting tokens.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Finally, we will write a client/consumer (or just use a service invocation tool such as soapUI) to request a security token from STS and append it to the actual web service request message to authenticate to the web service which is deployed in WSO2 Application Server.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<h4 style="text-align: left;">
Step 1 </h4>
</div>
<div style="text-align: left;">
Start WSO2 Application Server and log in to the management console as default admin user. Go to Manage --> Services --> Add --> AAR Service and deploy Axis2Service.aar which can be downloaded from <a href="https://svn.wso2.org/repos/wso2/trunk/commons/qa/qa-artifacts/app-server/Axis2Service.aar" target="_blank">here</a>.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Once the service is deployed, we need to associate a security policy for our service. You will find a set of default web service security policies in security configuration wizard. However, we cannot use any of them for our use case. Why?</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Our web service should be associated with a trust based security policy. A Security token which is offered by STS represents <b>a set of claims</b>. A claim defines a specific information about a particular user. For example, firstname or email address of the user. </div>
<div style="text-align: left;">
In our example, Axis2Service (the web service deployed in service provider, wso2 application server) needs to be made as a claim-aware web service. So that, the users who are going to consume the service should present the claims defined in WS-Security policy. </div>
<div style="text-align: left;">
Thus, we need to secure Axis2Service using a custom policy. You can download the complete policy from <a href="https://sourceforge.net/p/charithablogsam/code/ci/master/tree/resources/policies/axis2service.policy.xml" target="_blank">here</a>. You might specially be interested in looking into the following element in the custom security policy.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code> <sp:SupportingTokens xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:IssuedToken
sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
<sp:Issuer>
<Address xmlns="http://www.w3.org/2005/08/addressing">https://localhost:9444/services/wso2carbon-sts</Address>
</sp:Issuer>
<sp:RequestSecurityTokenTemplate>
<t:TokenType xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust">urn:oasis:names:tc:SAML:2.0:assertion</t:TokenType>
<t:KeyType xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust">http://schemas.xmlsoap.org/ws/2005/02/trust/Bearer</t:KeyType>
<t:KeySize xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust">256</t:KeySize>
<t:Claims Dialect="http://wso2.org/claims"
xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust"
xmlns:ic="http://schemas.xmlsoap.org/ws/2005/05/identity">
<ic:ClaimType Uri="http://wso2.org/claims/givenname"/>
<ic:ClaimType Uri="http://wso2.org/claims/emailaddress"/>
</t:Claims>
</sp:RequestSecurityTokenTemplate>
<wsp:Policy>
<sp:RequireInternalReference/>
</wsp:Policy>
</sp:IssuedToken>
</wsp:Policy>
</sp:SupportingTokens>
</code></pre>
<br />
<i><b>SupportingTokens</b></i> are used to provide additional claims for a requester (client). We will use SupportingToken policy assertion to describe claims which should be given by a consumer to access this particular web service. <br />
<br />
The <i><b>sp:IssuedToken</b></i> element defines that the requester must talk to an STS to obtain the token.<br />
<br /></div>
<div style="text-align: left;">
<br />
The <i><b>sp:IncludeToken</b></i> attribute value is defined as ../AlwaysToRecipient, which says the token must be included as part of all messages sent from the initiator (service consumer) to the recipient.<br />
<br />
The <i><b>Address</b></i> attribute of <i><b>sp:Issuer</b></i> element defines the token issuer whom the consumer must be contacted to get the security token. In other words, the endpoint address of the Security Token Service. In our case, it must be the STS url of IS.<br />
<i>[Note: I'm running WSO2 IS with port-offset 1, hence the https port is 9444] </i><br />
<br />
The <i><b>sp:RequestSecurityTokenTemplate</b></i> element specifies the structure/type of the token which has to be issued by the STS. Later, you will observe the children of this element will be included as the part of <i><b>RequestSecurityToken (RST)</b></i> message which will be sent to the STS by consumer. <br />
<br />
The <b><i>t:TokenType</i></b> element represents the type of the token such as UserNameToken, SAML-1.1, SAML-2.0. In our example, we ask STS To generate SAML-2.0 token by specifying SAML-2.0 token type URL.<br />
<br />
<i><b>t:KeyType</b></i> represents the type of the key desired in security token, can be either public key, symmetric key or bearer. We will ask STS to generate the relatively simple key, <b>bearer</b> token. Bearer token does not require a proof of possession hence it is quite easy to dealt with.<br />
<br />
<i><b>t:Claims</b></i> element defines the claims that must be included in the security token. We will request <b>First Name</b> and <b>email address</b> claims from the consumer.<br />
<br />
You may raise the question why the <i>First Name</i> claim has been mapped to "http://wso2.org/claims/givenname" URI. We will be able to clear ourselves once we configure the token provider in the next step. <br />
<br />
OK, now we understood all elements of the SupportingToken assertion of our custom web service policy. Let's upload the policy to embedded registry in WSO2 Application Service.<br />
<br />
Locate /_system/config collection in registry browser and click on <b>Add Resource</b>.<br />
Then, browse the <b>axis2service.policy.xml</b> which you have downloaded from the above location and click on <b>Add</b>.<br />
<br />
Now, we have our custom policy in WSO2 Application Server. We can associate the policy to Axis2Service.<br />
<br />
Click on <b>Unsecured</b> link in Axis2Service in <b>Deployed Services</b> page. You will be directed to <b>Security for the service</b> page. Find <b>Policy From Registry</b> section which is at the bottom of the page. Click on Configuration Registry icon and select the axis2service.policy.xml from /_system/config collection. <br />
Click on next to proceed with the wizard. You will be at the <b>Activate Security</b> page where you can specify a trusted key store for the web service.<br />
We will select wso2carbon.jks as the trusted key store. We have already discussed that STS is responsible for issuing tokens. Therefore, the STS is trusted by both consumer as well as the service provider. In order to do so, the public key certificate of STS should be imported to the trusted key store defined here. We will not explicitly do key exchanges in this example because we are using the same wso2carbon.jks keystore in both WSO2 Application Server and WSO2 Identity Server. <br />
<br />
Now, we have our web service secured with a claim-aware security policy. Let's move in to the STS configurations.<br />
<br />
<h4 style="text-align: left;">
Step 2 </h4>
<div style="text-align: left;">
Start WSO2 Identity Server and log in to the management console using the default admin credentials. Select <b>Secure Token Service</b> from the left menu under the <b>Manage</b> section.</div>
<div style="text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-MlkzZj746wY/Udb3jH3KPgI/AAAAAAAAAvE/ddjri5qDafg/s1600/STS2.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="113" src="http://1.bp.blogspot.com/-MlkzZj746wY/Udb3jH3KPgI/AAAAAAAAAvE/ddjri5qDafg/s320/STS2.png" width="320" /></a></div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
<br /></div>
<h4 style="text-align: left;">
</h4>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
First, we should secure the STS. There are multiple ways to authenticate to the Secure Token Service. The consumer can just present his username and password as UserNameTokens or X509 certificates to the STS. In this example, we will configure the STS using UserNameToken Authentication policy so that the clients should talk to STS by presenting their credentials.<br />
<br />
Click on <b>Apply Security Policy</b> in the above screen. Select UsernameToken from the list of default security policies in the<b> Security for the service</b> page. Click on <b>Next</b>.<br />
Now, we need to select a user group to which the service consumer belongs. We will incorporate our consumer into the admin group and request tokens from STS by presenting the default admin user credentials. Therefore, select <b>admin</b> as the user group and click on finish. <br />
<br />
Next, we need to configure STS to add Axis2Service as a trusted service. In the above screen, enter the http endpoint url of the Axis2Service.<br />
<br />
Endpoint Address = http://localhost:9765/services/Axis2Service/<br />
<br />
Usually, the security token is signed by STS. Thus, we need to select a certificate alias to sign the token. We will select the default <b>wso2carbon</b> certificate alias. <br />
<br />
Now, let's look at the user profile of admin user who is going to authenticate to the STS. Click on <b>My Profiles</b> at the left menu. Update Profile form will be displayed where you can enter various user attributes such as First Name, Last Name etc.<br />
Make sure to add some values to First Name and Email address fields since we are going to use those as the required claims.<br />
<br />
Click on <b>Configure</b> in the left menu and select Claim Management. You will find a set of claim dialects associated with the internal user store in IS. Click on the default claim dialect, http://wso2.org/claims. Click on <b>First Name</b> claim mapping.<br />
As you can see in the following screen shot, First Name is mapped to givenName attribute.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-XmH9NZOUFcI/UdeASqiCPYI/AAAAAAAAAvY/Q9XNZtdlty8/s1600/sts3.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="253" src="http://1.bp.blogspot.com/-XmH9NZOUFcI/UdeASqiCPYI/AAAAAAAAAvY/Q9XNZtdlty8/s320/sts3.png" width="320" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Now, you should be able to understand why we have specified http://wso2.org/claims/givenName as the claimuri for First Name attribute in the service policy.<br />
<br />
<h4 style="text-align: left;">
Step 3</h4>
<br />
Now, all what left is to work on the service consumer. Basically, we need to generate the <b><i>RequestSecurityToken</i></b> programatically using a client, insert into the web service request and send to Axis2Service. <br />
The wst:RequestSecurityToken element is used to request a security token from STS. </div>
<div style="text-align: left;">
It will be a child of SOAP body. At the minumum level, the RequestSecurityToken element will be similar to the following. </div>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
</div>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><wst:RequestSecurityToken xmlns:wst="http://schemas.xmlsoap.org/ws/2005/02/trust">
<wst:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</wst:RequestType>
<wst:TokenType>http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0
</wst:TokenType>
<wst:KeyType>http://schemas.xmlsoap.org/ws/2005/02/trust/Bearer</wst:KeyType>
<wst:Claims xmlns:wsp="http://schemas.xmlsoap.org/ws/2005/02/trust"
wsp:Dialect="http://wso2.org">
<wsid:ClaimType xmlns:wsid="http://schemas.xmlsoap.org/ws/2005/05/identity"
Uri="http://wso2.org/claims/givenname"/>
<wsid:ClaimType xmlns:wsid="http://schemas.xmlsoap.org/ws/2005/05/identity"
Uri="http://wso2.org/claims/emailaddress"/>
</wst:Claims>
</wst:RequestSecurityToken>
</code></pre>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
<br />
You would like to compare this with the SupportingToken policy assertion which we defined in step 1. In this, we will request a SAML2 token from STS (see wst:TokenType element) and indicate that the keytype is bearer. We also define the two claims we would present to the web service, givenname and emailaddress.<br />
<br />
You can include RequestSecurityToken element into a SOAP message body and send to STS. You can use soapUI SOAP request editor as shown below.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/--UMFOrVDMKk/UdeIKWP2lyI/AAAAAAAAAvs/ApNGvBYPrjw/s1600/sts4.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="153" src="http://1.bp.blogspot.com/--UMFOrVDMKk/UdeIKWP2lyI/AAAAAAAAAvs/ApNGvBYPrjw/s320/sts4.png" width="320" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Since we are using usernametoken authentication when submitting token request to STS, specify username and password under "Aut" tab in soapUI. Also specify WSS-passwordType as plaintext and WSS timeto live to some integer value. You can find more information about securing requests with username token with soapUI in <a href="http://charithaka.blogspot.com/2010/11/invoking-secure-web-services-using.html" target="_blank">one of my blog posts</a>. Also, make sure to enable WS-Addressing for the token request as explained in <a href="http://charithaka.blogspot.com/2011/01/ws-addressing-with-soapui.html" target="_blank">another blog post of mine</a>.<br />
With all these, when you submit the request to STS endpoint (in our case, https://localhost:9444/services/wso2carbon-sts), you will get a response with the generated token (<i><b>RequestSecurityTokenResponse</b></i>). You will notice it in the response view of the above screen shot.<br />
Now, you can extract the <i><b>saml2:Assertion</b></i> element from the response and embed it with the actual web service request message. For that, you can try adding SAML WSS entry for soapUI request and copy the extracted saml2:Assertion element into the Enter SAML Assertion text area as shown in the following screen shot. However, I was unsuccessful sending a message with bearer confirmation method with soapUI-4.5.2. It seems soapUI still supports <i><b>sender vouches</b></i> confirmation method only. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-ZrLgX1FnDrc/UdeM40oIjdI/AAAAAAAAAwA/PlBCioicAU8/s1600/sts5.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="180" src="http://1.bp.blogspot.com/-ZrLgX1FnDrc/UdeM40oIjdI/AAAAAAAAAwA/PlBCioicAU8/s320/sts5.png" width="320" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Because of this limitation, we need to follow a programmatic approach to insert the token into the web service request and forward to Axis2Service.<br />
You can find the complete working client in <a href="https://sourceforge.net/p/charithablogsam/code/ci/master/tree/" target="_blank">this sourceforge account</a><br />
<br />
<u><b>Steps to run the client</b></u><br />
<br />
1. Check out the complete source from <a href="https://sourceforge.net/p/charithablogsam/code/ci/master/tree/">https://sourceforge.net/p/charithablogsam/code/ci/master/tree/</a> and import the source into your IDE<br />
2. Go to IS_HOME/bin and type ant. This will copy the necessary client libraries in to IS_HOME/repository/lib directory<br />
3. Add IS_HOME/repository/lib directory to your IDE class path<br />
4. Also add IS_HOME/repository/components/lib/bcprov-jdk15-132.jar to the class path<br />
5. Modify Axis2ServiceClient according to the file paths in your system wherever necessary.<br />
e.g:-<br />
<i>Policy stsPolicy = loadSTSPolicy("/resources/policies/sts.ut.policy.xml");</i><br />
6. Run the client<br />
<br />
<br />
You should see the output similar to the following.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:xs="http://www.w3.org/2001/XMLSchema" ID="urn:uuid:D6511FA799FD47AC4D1373081003469" IssueInstant="2013-07-06T03:23:23.465Z" Version="2.0"><saml2:Issuer>localhost</saml2:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod>
<ds:Reference URI="#urn:uuid:D6511FA799FD47AC4D1373081003469">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="xs"></ec:InclusiveNamespaces></ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod>
<ds:DigestValue>MO6PnDsz+lbXsvuFRmMBwa7r0j4=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
i8S8BFxLJ59DpYUF8s8/Glt8x0n2plGPgCJKigB6eopRt7Y52LLnSqRimkWTWx57wdwjOFENMTPa
ZsYgBJ3AlxKRDQoy23OBOjrRA+S0WQ4Pq3EGcmM5XGKxU9pTNnh/xEhT4lDN9QE12Z1rttFz6RkU
AgFt3nmvqNqZvbNMga4=
</ds:SignatureValue>
<ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIICNTCCAZ6gAwIBAgIES343gjANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJVUzELMAkGA1UE
CAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxDTALBgNVBAoMBFdTTzIxEjAQBgNVBAMMCWxv
Y2FsaG9zdDAeFw0xMDAyMTkwNzAyMjZaFw0zNTAyMTMwNzAyMjZaMFUxCzAJBgNVBAYTAlVTMQsw
CQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzENMAsGA1UECgwEV1NPMjESMBAGA1UE
AwwJbG9jYWxob3N0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCUp/oV1vWc8/TkQSiAvTou
sMzOM4asB2iltr2QKozni5aVFu818MpOLZIr8LMnTzWllJvvaA5RAAdpbECb+48FjbBe0hseUdN5
HpwvnH/DW8ZccGvk53I6Orq7hLCv1ZHtuOCokghz/ATrhyPq+QktMfXnRS4HrKGJTzxaCcU7OQID
AQABoxIwEDAOBgNVHQ8BAf8EBAMCBPAwDQYJKoZIhvcNAQEFBQADgYEAW5wPR7cr1LAdq+IrR44i
QlRG5ITCZXY9hI0PygLP2rHANh+PYfTmxbuOnykNGyhM6FjFLbW2uZHQTY1jMrPprjOrmyK5sjJR
O4d1DeGHT/YnIjs9JogRKv4XHECwLtIVdAbIdWHEtVZJyMSktcyysFcvuhPQK8Qc/E/Wq8uHSCo=</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature><saml2:Subject><saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">admin</saml2:NameID><saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"></saml2:SubjectConfirmation></saml2:Subject><saml2:Conditions NotBefore="2013-07-06T03:23:23.465Z" NotOnOrAfter="2013-07-06T03:28:23.465Z"></saml2:Conditions><saml2:AuthnStatement AuthnInstant="2013-07-06T03:23:23.465Z"><saml2:AuthnContext><saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml2:AuthnContextClassRef></saml2:AuthnContext></saml2:AuthnStatement><saml2:AttributeStatement><saml2:Attribute Name="http://wso2.org/claims/emailaddress" NameFormat="http://wso2.org/claims/emailaddress"><saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">charitha@wso2.com</saml2:AttributeValue></saml2:Attribute><saml2:Attribute Name="http://wso2.org/claims/givenname" NameFormat="http://wso2.org/claims/givenname"><saml2:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">charitha</saml2:AttributeValue></saml2:Attribute></saml2:AttributeStatement></saml2:Assertion>
Response : <ns:echoStringResponse xmlns:ns="http://service.carbon.wso2.org"><ns:return>Hello world1</ns:return></ns:echoStringResponse>
</code></pre>
<br />
<br />
Comment on or contact me directly at uoccharitha@gmail.com if this does not work for you!</div>
</div>
Charithahttp://www.blogger.com/profile/00209392844529688942noreply@blogger.com2tag:blogger.com,1999:blog-5949896138631643846.post-22460812756232538842013-06-30T09:03:00.000-07:002013-06-30T09:03:00.513-07:00Helping hands in the world of enterprise middleware - Technical Support<div dir="ltr" style="text-align: left;" trbidi="on">
Recently, I got an opportunity to work on a domain which is bit different from my subject matter specialization, software testing and quality assurance. I started to work as a lead of technical support team at WSO2 since November 2012. I thought to put together some key observations I made in technical support career in general and how I position it in terms of my beliefs.<br />
<br />
<div style="text-align: left;">
<span style="font-size: large;"><b>Willingness to help - the most important characteristic of a support engineer</b></span></div>
<br />
Are you really a helping hand regardless of your profession? How can I understand my willingness in helping others. I would simply list down some questions to evaluate your likelihood to help others.<br />
<br />
Do you get frustrated when someone requests your help? If someone asks a question, what is your initial reaction?<br />
In our life, we have seen people who do not even look at the person who requested help. Some people just route the request to some other party without even understanding what kind of help is required.<br />
<br />
If you are really a helping hand, you just do not do it because of your professional obligations. You do it simply because you like to help others. You enjoy by observing how your help solves some other's problems.<br />
<br />
If you are generously help people in need without hesitation, you possess one of the fundamental characteristics expected from a good technical support engineer.<br />
<br />
<div style="text-align: left;">
<span style="font-size: large;"><b>Listening to others and clear in communication</b></span></div>
<br />
A good support engineer always listen to others very carefully. She raises many follow-up queries to get the question clarified. She does not attempt to solve the problem blindly without completely understanding the issue at hand. She also communicates very clearly with the clients as well as the other stake holders to help in providing the the best answer.<br />
<br />
<div style="text-align: left;">
<span style="font-size: large;"><b>Expertise in user perspective</b></span></div>
<br />
Support engineers are clients advocates who should look at the problem through customer point of view. How painful is this issue to my clients? How does it affect their business transactions? When you approach problem from the customer point of view, you first look at what needs to be done before considering how you are going to address the concerns.<br />
<br />
<b><span style="font-size: large;">Enthusiastic in learning new technologies</span></b><br />
<br />
To help needy people, you must have a good understanding about the relevant subject matter. You will be clueless if you do not know the problem domain. This is one of the most important attributes especially in middleware technical support. You will not at least understand a basic question, if you do not step in to learn the technology. The technical support engineer should eager to learn various technologies and find out various solutions to address common problems that can occur.<br />
At WSO2, technology becomes obsolete quite frequently. The technical support engineer must stay up-to-date with the latest features and enhancements introduced to the product platform. <br />
<br />
<span style="font-size: large;"><b>Focus on SLA</b></span><br />
<span style="font-size: large;"><b><br /></b></span>
Generally, technical support contracts are based on different Service Level Agreements (SLA). There can be various levels of SLA policies. A good support engineer always consider his SLA is now and act fast to find the best resolution for client's issue. <br />
<br />
<i>More experiences on technical support, specially related to WSO2 product platform are to be followed....</i><br />
<br />
<br /></div>
Charithahttp://www.blogger.com/profile/00209392844529688942noreply@blogger.com0tag:blogger.com,1999:blog-5949896138631643846.post-66367270319735012062013-06-28T03:51:00.002-07:002013-06-28T03:51:27.849-07:00Invoking WSO2 Carbon admin services with soapUI<div dir="ltr" style="text-align: left;" trbidi="on">
The management aspects of WSO2 Carbon platform are primarily achieved through SOAP web services interface known as admin services. All Carbon products ship with a management console (front-end user interface) which communicates with these web services and provides users with various administration capabilities. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9-OOW2EjhIx-DjidD4uyUU478hUnLeeJm5VZ-VQfFAS7EiyiA9YpwE7_agGVY7QkgZUtfapro2EhaFc7CZ8c3V8L-njQIfCPF1lLL_PTGdJUEAEM4JuJPz5jCN5pTJvf7eI3o9ODK5m1q/s422/image.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="186" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9-OOW2EjhIx-DjidD4uyUU478hUnLeeJm5VZ-VQfFAS7EiyiA9YpwE7_agGVY7QkgZUtfapro2EhaFc7CZ8c3V8L-njQIfCPF1lLL_PTGdJUEAEM4JuJPz5jCN5pTJvf7eI3o9ODK5m1q/s320/image.png" width="320" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
In some situations, we need to by-pass the management UI and call the backend web services directly. Specially, in test automation, it is important to minimize the risk of frequent UI changes hence focusing on admin service interactions can be considered as a viable solution. WSO2 test automation framework is built upon this approach which programatically calls the backend web services to manage deployment, configuration and various other tasks.<br />
<br />
These backend web services are secured to prevent anonymous invocations. WSO2 Carbon server secures these services through multiple methodologies. For example; <br />
<br />
<ul style="text-align: left;">
<li>HTTP Basic Authentication over SSL</li>
</ul>
<ul style="text-align: left;">
<li>WS-Security username token</li>
</ul>
<ul style="text-align: left;">
<li>Session based authentication</li>
</ul>
You can use any SOAP client and communicates with the admin services by authenticating through above security protocols. <br />
<br />
In this post, I will take you through consuming an admin service using <a href="http://www.soapui.org/" target="_blank">soapUI</a> since soapUI is the most user-friendly service testing tool out there to test SOAP or RESTful web services.<br />
<br />
We will use HTTP basic auth authentication mechanism out of the auth options described above. If you like to use a different approach such as carbon session based authentication, you may refer to <a href="http://nandikajayawardana.blogspot.com/2012/10/how-to-invoke-admin-services-with-soapui.html" target="_blank">Nandika's blog post</a>.<br />
<br />
<b>Pre-requisite:</b><br />
soapUI 4.5.1 or later<br />
WSO2 Carbon 4.X version (You can use any member product of WSO2 Carbon family)<br />
<br />
<h4 style="text-align: left;">
Step 1</h4>
<br />
By default, the WSDLs of admin web services are hidden from consumers. Therefore, we need to enable them first to import admin service WSDL into a soapUI project.<br />
<br />
Open CARBON_HOME/repository/conf/carbon.xml and set <i><b>HideAdminServiceWSDLs</b></i> property to false.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><HideAdminServiceWSDLs>false</HideAdminServiceWSDLs>
</code></pre>
<br />
<br />
Start WSO2 Carbon server. <br />
<br />
<h4 style="text-align: left;">
Step 2</h4>
<h4 style="text-align: left;">
</h4>
There are large number of admin services which serve many administration and management functionalities such as ServiceAdmin, StatisticsAdmin, ProxyAdmin etc.. However, I will use a simplest admin service, <b>UserAdmin</b> for this example.<br />
<br />
Open https://localhost:9443/services/UserAdmin?wsdl in your browser and check whether it is accessible. <br />
<br />
<h4 style="text-align: left;">
Step 3</h4>
<br />
Create a SOAP web service project in soapUI using the above WSDL<br />
<br />
<h4 style="text-align: left;">
Step 4</h4>
<br />
We are going to invoke one of the web services operations exposed through UserAdmin web service. Select listAllUsers operation under UserAdminSoap11Binding interface and click on SOAP request.<br />
<br />
<h4 style="text-align: left;">
Step 5</h4>
<br />
We are going to submit listAllUsers SOAP request using HTTP basic authentication headers. Therefore, click on Aut tab under the bottom of the request editor and specify the admin user name and password of carbon server.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVcRYHuUZ4q7eq7sEY0LAjzTEhFxX0OTop9rnYPCFSvCpHA5lrixssT1Qg_09-wb9GVQgBhfRQxhvJQkP8L2xFDMJBLcEPjkFNl2qezA6L2WLw4h0W-cnD_RuWS1VV6-9qF326L38mNkzf/s817/soapuiadmin.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="237" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVcRYHuUZ4q7eq7sEY0LAjzTEhFxX0OTop9rnYPCFSvCpHA5lrixssT1Qg_09-wb9GVQgBhfRQxhvJQkP8L2xFDMJBLcEPjkFNl2qezA6L2WLw4h0W-cnD_RuWS1VV6-9qF326L38mNkzf/s320/soapuiadmin.png" width="320" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Enter the following values for the required parameters of the SOAP request.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><xsd:filter>*</xsd:filter>
<xsd:limit>100</xsd:limit>
</code></pre>
<br />
<br />
<h4 style="text-align: left;">
Step 6</h4>
Now, we can submit the request to UserAdmin web service.You will get a SOAP response with all users available in the user store of Carbon server.</div>
Charithahttp://www.blogger.com/profile/00209392844529688942noreply@blogger.com8tag:blogger.com,1999:blog-5949896138631643846.post-90259224452815116292013-06-21T10:03:00.001-07:002013-09-19T23:04:58.007-07:00How to use SecureVault when WSO2 Carbon servers are started as background processes<div dir="ltr" style="text-align: left;" trbidi="on">
<a href="http://wso2.org/project/carbon/3.2.0/docs/secure_vault.html" target="_blank"><b>SecureVault</b></a> can be used to encrypt the plain-text passwords specified in various configurations files in WSO2 Carbon products. You can find more information about how to secure plain-text passwords using securevault in <a href="http://www.soasecurity.org/2012/08/secure-plain-text-passwords-in-wso2.html" target="_blank">this blog</a> written by <a href="http://wso2.com/about/team/asela-pathberiya/" target="_blank">Asela</a>.<br />
<br />
When you use SecureVault to encrypt the passwords as explained there, you are supposed to specify the primary keystore password at the server startup. However, this is not possible when you start the server as a background process.<br />
<br />
This post summarizes the complete procedure of securing plain text passwords using secure vault and additional configurations when you start the server as a background process.<br />
<br />
Suppose, we need to encrypt the LDAP <b>ConnectionPassword</b> value in CARBON_HOME/repository/conf/user-mgt.xml <br />
<br />
<ol style="text-align: left;">
<li>Locate cipher-text.properties which can be found at CARBON_HOME/repository/conf/security directory</li>
<li> Keep a back up of the cipher-text.properties file</li>
<li> Now, remove all key-value pairs which have there by default in cipher-text.properties file.(In this example, we just need to encrypt ConnectionPassword value)</li>
<li>Add the following line. Make sure to include your plain_text LDAP connection password in [plain_text_ldap_password]<br /><br /><i><b>UserStoreManager.Property.ConnectionPassword=[plain_text_ldap_password]</b></i></li>
<li> Locate ciphertool.sh script which can be found at CARBON_HOME/bin directory</li>
<li> Run ciphertool.sh as follows<br /> ciphertool.sh -Dconfigure<br /><br />This will prompt "[Please Enter Primary KeyStore Password of Carbon
Server : ]" message. Enter "wso2carbon" as the primary keystore password</li>
<li> If the script execution completed successfully, you will see the following message.<br />"Secret Configurations are written to the property file successfully"</li>
<li> Now, go back and look at the cipher-text.properties file. The plain text LDAP password will be replaced by a cipher value. </li>
<li> You will also look at CARBON_HOME/repository/conf/user-mgt.xml where we have specified the connection password for LDAP user. <br />You will notice that it will be modified by the ciphertool script as follows. <br /><i><b><Property name="ConnectionPassword"
svns:secretAlias="UserStoreManager.Property.ConnectionPassword">password</Property></b></i></li>
<li>Now, you can start the server. <br />e.g:- sh wso2server.sh </li>
<li>This will prompt "[Enter KeyStore and Private Key Password :]" at the
server startup because we need to decrypt the encrypted passwords to
connect to LDAP.<br />You can enter "wso2carbon" and the server will be started successfully. <br /><br />But you will not be able to provide this password value if you start
WSO2 Carbon server as a background process. <br />i.e:- ./wso2server.sh
start<br />In that case, you can follow a simple set of additional steps as explained below</li>
<li>Have a file named "password-tmp" in CARBON_HOME/ directory. Add
"wso2carbon" (the primary keystore password) to this file and save</li>
<li>Now, start the server as a background process. <br /><i><b>./wso2server.sh start</b></i></li>
<li>Keystore password will be picked up from password-tmp file. Once the
server is started, this fill will automatically be deleted from the file
system. Make sure to add this temporary file back whenever you start the sever as a background process. </li>
</ol>
<strong><em> NOTE : If you make the name of the password file as "password-persist" instead of "password-tmp" then the fie will not be deleted after reading. Then you don't need to provide the password in subsequent startups.</em></strong><br />
<br /><br /><br />
<ol style="text-align: left;">
</ol>
<br />
<br /></div>
Charithahttp://www.blogger.com/profile/00209392844529688942noreply@blogger.com3tag:blogger.com,1999:blog-5949896138631643846.post-70191721125293880512013-05-11T06:22:00.002-07:002013-05-11T06:24:29.068-07:00The simplest possible way to simulate a backend service delay<div dir="ltr" style="text-align: left;" trbidi="on">
When testing service integrations, we usually want to simulate the delayed responses from backend web services. For example, if you want to test how <a href="http://wso2.com/products/enterprise-service-bus/" target="_blank"><b>WSO2 ESB</b></a> or <a href="http://synapse.apache.org/" target="_blank"><b>Apache Synapse</b></a> reacts when the backend service takes large amount of time for responding, there are many approaches to introduce delay to backend web service. I have observed that, most of the people modify the backend web services to add Thread.sleep() when they need to introduce a delay in service invocation.<br />
<br />
If you are not testing the backend web service and just want to test the integration (e.g:- outgoing calls from ESB), I cannot think of a better solution than using <a href="http://www.soapui.org/" target="_blank"><b>soapUI </b></a>mock services. <br />
<br />
<h4 style="text-align: left;">
Step 1</h4>
<h4 style="text-align: left;">
</h4>
Add a new<b> mock service</b> to soapUI project. This can be done at the time of creating the project or by selecting a particular interface (binding) of a wsdl based project.<br />
<br />
<h4 style="text-align: left;">
Step 2</h4>
<h4 style="text-align: left;">
</h4>
Select the mock service in soapUI navigator and open the mock service editor. In the mock service editor, select OnRequest script.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRG9bMiZUmJWnG8TOpvDyEVCHOwSMNrfCtRA1zVANmeoUH4kLB_ywopKV4pXzB6JIUCXmhdjh4i7wGB3Y8XOlkmSsHKRCY49lCA6UZrAIBK-5OHzNRzJfjaIOrmZCPmUsz0O6IbaN_ATPw/s1600/soapui1.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="152" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRG9bMiZUmJWnG8TOpvDyEVCHOwSMNrfCtRA1zVANmeoUH4kLB_ywopKV4pXzB6JIUCXmhdjh4i7wGB3Y8XOlkmSsHKRCY49lCA6UZrAIBK-5OHzNRzJfjaIOrmZCPmUsz0O6IbaN_ATPw/s400/soapui1.png" width="400" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<h4 style="text-align: left;">
Step 3</h4>
<h4 style="text-align: left;">
</h4>
<br />
Add the following groovy script inside the OnRequest Script editor to introduce 1 minute delay.<br />
<br />
<b><i>sleep(60000)</i></b><br />
<br />
Now, send a request to the mock service. You will notice that all requests will respond back to the caller after 1 minute of delay.<br />
<br />
Read chapter 6 (Web service simulation with soapUI) and 11 (Extending soapUI with Scripting) of <a href="http://www.amazon.com/Services-Testing-soapUI-Kankanamge-Charitha/dp/1849515662" target="_blank">Web Services Testing with soapUI</a> book for more information about soapUI scripting capabilities.<br />
<br />
<br />
<br />
<br /></div>
Charithahttp://www.blogger.com/profile/00209392844529688942noreply@blogger.com0tag:blogger.com,1999:blog-5949896138631643846.post-48176000443807788962013-05-05T00:50:00.001-07:002013-05-05T00:50:27.609-07:00Testing one-way operations which do not return HTTP 202 responses<div dir="ltr" style="text-align: left;" trbidi="on">
When you invoke a one-way (in-Only) operation of a web service over HTTP, it responds with HTTP 202 accepted message. Many web service clients such as soapUI or Jmeter waits till they receive a response from the web service.<br />
Waiting for HTTP 202 response is always not desirable since there are situations where you do not even get a 202 response. For example, if you invoke one-way JMS operation, it does not send a reply back to the client.<br />
Look at a scenario similar to the following.<br />
<br />
A client sends a message over HTTP to a proxy service in <a href="http://wso2.com/products/enterprise-service-bus/" target="_blank">WSO2 ESB</a>. The proxy service places the message in a JMS queue and does not expect a response back. In this case, client does not even get a HTTP 202 response hence it waits and eventually timed out. This prevents you using the tools like <a href="http://www.soapui.org/" target="_blank">soapUI</a>, <a href="http://jmeter.apache.org/" target="_blank">Apache Jmeter</a> in these scenarios. How can we fix this so that the client always get a HTTP 202 response back?<br />
<br />
Let's go through the procedure in detail.<br />
<br />
<h4 style="text-align: left;">
Step 1:</h4>
Configure <b>Apache ActiveMQ</b> JMS broker with WSO2 ESB as explained <a href="http://docs.wso2.org/wiki/display/ESB460/Configure+with+ActiveMQ" target="_blank">here</a>.<br />
<br />
<h4 style="text-align: left;">
Step 2: </h4>
Create a queue in ActiveMQ. You could access ActiveMQ console application through http://localhost:8161/admin and create a new queue. Name it as "onewaytest".<br />
<br />
<h4 style="text-align: left;">
Step 3: </h4>
Create a simple proxy service in WSO2 ESB as shown below. This proxy service just forwards the incoming SOAP messages into the "onewaytest" JMS queue which we have created in the previous step.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><proxy xmlns="http://ws.apache.org/ns/synapse" name="onewayProxy" transports="http" statistics="disable" trace="disable" startOnLoad="true">
<target>
<inSequence>
<property name="OUT_ONLY" value="true"/>
<send>
<endpoint>
<address uri="jms:/onewaytest?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&java.naming.provider.url=tcp://localhost:61616"/>
</endpoint>
</send>
</inSequence>
<outSequence>
<send/>
</outSequence>
</target>
<description></description>
</proxy>
</code></pre>
<br />
<h4 style="text-align: left;">
Step 4:</h4>
<br />
Use soapUI (or SOAP/XML-RPC sampler in Apache Jmeter) and send a SOAP request to the above proxy service. You will get "java.net.SocketTimeoutException: Read timed out" in soapUI log. This explains the behavior of HTTP client waiting for HTTP 202 response.<br />
<br />
<h4 style="text-align: left;">
Step 5:</h4>
<br />
There is an useful property, <b>FORCE_SC_ACCEPTED</b> which can be used inside the inSequence of the proxy service to send HTTP 202 Accepted response back to the client in case of one-way JMS operations.<br />
<br />
Add this property to the inSequence of the above proxy service.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><b><property name="FORCE_SC_ACCEPTED" value="true" scope="axis2" /></b>
</code></pre>
<br />
<h4 style="text-align: left;">
Step 6:</h4>
<br />
Re-send a SOAP message to the proxy service using soapUI. You will get a HTTP 202 response.<br />
<br />
<br />
<b><i>HTTP/1.1 202 Accepted</i></b><br />
<b><i>Content-Type: text/xml; charset=UTF-8</i></b><br />
<b><i>Date: Sun, 05 May 2013 07:42:27 GMT</i></b><br />
<b><i>Server: WSO2-PassThrough-HTTP</i></b><br />
<b><i>Transfer-Encoding: chunked</i></b><br />
<div>
<br /></div>
<br />
<br /></div>
Charithahttp://www.blogger.com/profile/00209392844529688942noreply@blogger.com2tag:blogger.com,1999:blog-5949896138631643846.post-25792068095503923352013-02-26T18:22:00.001-08:002013-02-26T18:22:37.643-08:00How to configure soapUI to send HTTP chunked encoded requests <div dir="ltr" style="text-align: left;" trbidi="on">
soapUI makes use of <b><a href="http://hc.apache.org/httpcomponents-client-ga/index.html" target="_blank">Apache HttpClient</a></b> (based on HTTPComponents project) as the client side HTTP implementation. When submitting requests using soapUI, you may have noticed that, the requests always send <b>Content-Length</b> HTTP header. You can find it out in the Raw View of the request editor.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>POST http://localhost:9000/services/SimpleStockQuoteService HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: "urn:getQuote"
User-Agent: Jakarta Commons-HttpClient/3.1
Host: localhost:9000
<b style="background-color: cyan;">Content-Length: 416</b>
</code></pre>
<br />
In functional and non-functional testing, we usually need to test the servers by sending HTTP requests with both Content-Length as well as chunked transfer encoding. How can we configure soapUI to send chunked encoded requests instead of Content-Length?<br />
<br />
<span style="font-size: large;"><b>Step 1</b></span><br />
<br />
Click on <b>Global soapUI Preferences</b> icon in the main tool bar (Or else, click on File --> Preferences)<br />
<br />
<span style="font-size: large;"><b>Step 2</b></span><br />
<br />
HTTP Settings tab will be selected by default. You will notice <b>Chunking Threshold</b> option. By default this is set to empty so that the chunking is disabled for any HTTP request.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh93itr0TZ96cnSu3MyMMwfJtaCy_fK-xPyCD5qTsZHEXdeg6npV3X3JZoJAZu_v85hq2EBjL0N1h-KkwMb18ZVGP2kvhVZ6NMCtjhj5e5fdt-XNFoTsu1i4lBo_AwHAvwkWmdGO6LDWdPf/s1600/soapui.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="231" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh93itr0TZ96cnSu3MyMMwfJtaCy_fK-xPyCD5qTsZHEXdeg6npV3X3JZoJAZu_v85hq2EBjL0N1h-KkwMb18ZVGP2kvhVZ6NMCtjhj5e5fdt-XNFoTsu1i4lBo_AwHAvwkWmdGO6LDWdPf/s320/soapui.png" width="320" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Update this field with non negative integer value (e.g:- 1) and resubmit your request. You will notice chunked encoded request as shown below.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>POST http://localhost:9000/services/SimpleStockQuoteService HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: "urn:getQuote"
User-Agent: Jakarta Commons-HttpClient/3.1
Host: localhost:9000
<b style="background-color: cyan;">Transfer-Encoding: chunked</b>
</code></pre>
<br />
For more information about various soapUI tips and tricks, read <a href="http://www.packtpub.com/web-services-testing-with-soapui/book" target="_blank">Web services Testing with soapUI book</a>. </div>
Charithahttp://www.blogger.com/profile/00209392844529688942noreply@blogger.com2tag:blogger.com,1999:blog-5949896138631643846.post-72968417060140270562013-02-16T23:40:00.000-08:002013-02-16T23:40:36.248-08:00How to connect WSO2 ESB to Apache ActiveMQ using simple authentication<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
There are different types of pluggable authentication mechanisms provided by <a href="http://activemq.apache.org/" target="_blank">Apache ActiveMQ</a> message broker. One of the quickest and easiest mechanisms is to use <a href="http://activemq.apache.org/security.html" target="_blank">simple authentication</a>. As the name implies, it is as simple as adding authentication details to ACTIVEMQ_HOME/conf/activemq-security.xml<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> <span style="color: #007000;"><plugins></span>
<span style="color: grey;"><!-- Configure authentication; Username, passwords and groups --></span>
<span style="color: #007000;"><simpleAuthenticationPlugin></span>
<span style="color: #007000;"><users></span>
<span style="color: #007000;"><authenticationUser</span> <span style="color: #0000c0;">username=</span><span style="background-color: #fff0f0;">"system"</span> <span style="color: #0000c0;">password=</span><span style="background-color: #fff0f0;">"${activemq.password}"</span>
<span style="color: #0000c0;">groups=</span><span style="background-color: #fff0f0;">"users,admins"</span><span style="color: #007000;">/></span>
<span style="color: #007000;"><authenticationUser</span> <span style="color: #0000c0;">username=</span><span style="background-color: #fff0f0;">"user"</span> <span style="color: #0000c0;">password=</span><span style="background-color: #fff0f0;">"${guest.password}"</span>
<span style="color: #0000c0;">groups=</span><span style="background-color: #fff0f0;">"users"</span><span style="color: #007000;">/></span>
<span style="color: #007000;"><authenticationUser</span> <span style="color: #0000c0;">username=</span><span style="background-color: #fff0f0;">"guest"</span> <span style="color: #0000c0;">password=</span><span style="background-color: #fff0f0;">"${guest.password}"</span> <span style="color: #0000c0;">groups=</span><span style="background-color: #fff0f0;">"guests"</span><span style="color: #007000;">/></span>
<span style="color: #007000;"></users></span>
<span style="color: #007000;"></simpleAuthenticationPlugin></span>
</pre>
</div>
<br />
<br />
In this simple configuration, passwords of each user is defined in ACTIVEMQ_HOME/apache-activemq-5.7.0/conf/credential.properties file.<br />
<br />
<br />
You can find more details about ActiveMQ simple authentication plugin in <a href="http://bhou.wordpress.com/2012/08/05/activemq-simple-authentication-configuration/" target="_blank">this blog</a>.<br />
<br />
Suppose, you have started Apache ActiveMQ with simple authentication. Then, any consumer of the destinations defined in your ActiveMQ broker should connect using the credentials defined under simple authentication plugin.<br />
<br />
If <a href="http://wso2.com/products/enterprise-service-bus/" target="_blank"><b>WSO2 ESB</b></a> needs to connect to ActiveMQ configured with simple authentication, we can simply update the broker configuration details in ESB_HOME/repository/conf/axis2/axis2.xml as shown below.</div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; background: white; border-width: .1em .1em .1em .8em; border: solid gray; color: black; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> <span style="color: #007000;"><transportReceiver</span> <span style="color: #0000c0;">name=</span><span style="background-color: #fff0f0;">"jms"</span> <span style="color: #0000c0;">class=</span><span style="background-color: #fff0f0;">"org.apache.axis2.transport.jms.JMSListener"</span><span style="color: #007000;">></span>
<span style="color: #007000;"><parameter</span> <span style="color: #0000c0;">name=</span><span style="background-color: #fff0f0;">"myTopicConnectionFactory"</span> <span style="color: #0000c0;">locked=</span><span style="background-color: #fff0f0;">"false"</span><span style="color: #007000;">></span>
<span style="color: #007000;"><parameter</span> <span style="color: #0000c0;">name=</span><span style="background-color: #fff0f0;">"java.naming.factory.initial"</span> <span style="color: #0000c0;">locked=</span><span style="background-color: #fff0f0;">"false"</span><span style="color: #007000;">></span>org.apache.activemq.jndi.ActiveMQInitialContextFactory<span style="color: #007000;"></parameter></span>
<span style="color: #007000;"><parameter</span> <span style="color: #0000c0;">name=</span><span style="background-color: #fff0f0;">"java.naming.provider.url"</span> <span style="color: #0000c0;">locked=</span><span style="background-color: #fff0f0;">"false"</span><span style="color: #007000;">></span>tcp://localhost:61616<span style="color: #007000;"></parameter></span>
<b> <span style="color: #007000;"><parameter</span> <span style="color: #0000c0;">name=</span><span style="background-color: #fff0f0;">"transport.jms.UserName"</span><span style="color: #007000;">></span>system<span style="color: #007000;"></parameter></span>
<span style="color: #007000;"><parameter</span> <span style="color: #0000c0;">name=</span><span style="background-color: #fff0f0;">"transport.jms.Password"</span><span style="color: #007000;">></span>manager<span style="color: #007000;"></parameter></span></b>
<span style="color: #007000;"><parameter</span> <span style="color: #0000c0;">name=</span><span style="background-color: #fff0f0;">"transport.jms.ConnectionFactoryJNDIName"</span> <span style="color: #0000c0;">locked=</span><span style="background-color: #fff0f0;">"false"</span><span style="color: #007000;">></span>TopicConnectionFactory<span style="color: #007000;"></parameter></span>
<span style="color: #007000;"><parameter</span> <span style="color: #0000c0;">name=</span><span style="background-color: #fff0f0;">"transport.jms.ConnectionFactoryType"</span> <span style="color: #0000c0;">locked=</span><span style="background-color: #fff0f0;">"false"</span><span style="color: #007000;">></span>topic<span style="color: #007000;"></parameter></span>
<span style="color: #007000;"></parameter></span>
<span style="color: #007000;"><parameter</span> <span style="color: #0000c0;">name=</span><span style="background-color: #fff0f0;">"myQueueConnectionFactory"</span> <span style="color: #0000c0;">locked=</span><span style="background-color: #fff0f0;">"false"</span><span style="color: #007000;">></span>
<span style="color: #007000;"><parameter</span> <span style="color: #0000c0;">name=</span><span style="background-color: #fff0f0;">"java.naming.factory.initial"</span> <span style="color: #0000c0;">locked=</span><span style="background-color: #fff0f0;">"false"</span><span style="color: #007000;">></span>org.apache.activemq.jndi.ActiveMQInitialContextFactory<span style="color: #007000;"></parameter></span>
<span style="color: #007000;"><parameter</span> <span style="color: #0000c0;">name=</span><span style="background-color: #fff0f0;">"java.naming.provider.url"</span> <span style="color: #0000c0;">locked=</span><span style="background-color: #fff0f0;">"false"</span><span style="color: #007000;">></span>tcp://localhost:61616<span style="color: #007000;"></parameter></span>
<b><span style="color: #007000;"><parameter</span> <span style="color: #0000c0;">name=</span><span style="background-color: #fff0f0;">"transport.jms.UserName"</span><span style="color: #007000;">></span>system<span style="color: #007000;"></parameter></span>
<span style="color: #007000;"><parameter</span> <span style="color: #0000c0;">name=</span><span style="background-color: #fff0f0;">"transport.jms.Password"</span><span style="color: #007000;">></span>manager<span style="color: #007000;"></parameter></span></b>
<span style="color: #007000;"><parameter</span> <span style="color: #0000c0;">name=</span><span style="background-color: #fff0f0;">"transport.jms.ConnectionFactoryJNDIName"</span> <span style="color: #0000c0;">locked=</span><span style="background-color: #fff0f0;">"false"</span><span style="color: #007000;">></span>QueueConnectionFactory<span style="color: #007000;"></parameter></span>
<span style="color: #007000;"><parameter</span> <span style="color: #0000c0;">name=</span><span style="background-color: #fff0f0;">"transport.jms.ConnectionFactoryType"</span> <span style="color: #0000c0;">locked=</span><span style="background-color: #fff0f0;">"false"</span><span style="color: #007000;">></span>queue<span style="color: #007000;"></parameter></span>
<span style="color: #007000;"></parameter></span>
<span style="color: #007000;"><parameter</span> <span style="color: #0000c0;">name=</span><span style="background-color: #fff0f0;">"default"</span> <span style="color: #0000c0;">locked=</span><span style="background-color: #fff0f0;">"false"</span><span style="color: #007000;">></span>
<span style="color: #007000;"><parameter</span> <span style="color: #0000c0;">name=</span><span style="background-color: #fff0f0;">"java.naming.factory.initial"</span> <span style="color: #0000c0;">locked=</span><span style="background-color: #fff0f0;">"false"</span><span style="color: #007000;">></span>org.apache.activemq.jndi.ActiveMQInitialContextFactory<span style="color: #007000;"></parameter></span>
<span style="color: #007000;"><parameter</span> <span style="color: #0000c0;">name=</span><span style="background-color: #fff0f0;">"java.naming.provider.url"</span> <span style="color: #0000c0;">locked=</span><span style="background-color: #fff0f0;">"false"</span><span style="color: #007000;">></span>tcp://localhost:61616<span style="color: #007000;"></parameter></span>
<b> <span style="color: #007000;"><parameter</span> <span style="color: #0000c0;">name=</span><span style="background-color: #fff0f0;">"transport.jms.UserName"</span><span style="color: #007000;">></span>system<span style="color: #007000;"></parameter></span>
<span style="color: #007000;"><parameter</span> <span style="color: #0000c0;">name=</span><span style="background-color: #fff0f0;">"transport.jms.Password"</span><span style="color: #007000;">></span>manager<span style="color: #007000;"></parameter></span></b>
<span style="color: #007000;"><parameter</span> <span style="color: #0000c0;">name=</span><span style="background-color: #fff0f0;">"transport.jms.ConnectionFactoryJNDIName"</span> <span style="color: #0000c0;">locked=</span><span style="background-color: #fff0f0;">"false"</span><span style="color: #007000;">></span>QueueConnectionFactory<span style="color: #007000;"></parameter></span>
<span style="color: #007000;"><parameter</span> <span style="color: #0000c0;">name=</span><span style="background-color: #fff0f0;">"transport.jms.ConnectionFactoryType"</span> <span style="color: #0000c0;">locked=</span><span style="background-color: #fff0f0;">"false"</span><span style="color: #007000;">></span>queue<span style="color: #007000;"></parameter></span>
<span style="color: #007000;"></parameter></span>
<span style="color: #007000;"></transportReceiver></span>
</pre>
</div>
<br />
Note that highlighted parameters (transport.jms.UserName and transport.jms.Password) which are used to connect to the broker using simple authentication.<br />
<br />
The above configuration can be used to connect any Apache Axis2 based server (Apache Axis2, WSO2 Application Server etc..) to ActiveMQ using simple authentication. </div>
Charithahttp://www.blogger.com/profile/00209392844529688942noreply@blogger.com0tag:blogger.com,1999:blog-5949896138631643846.post-44928557661136556022013-02-08T06:40:00.000-08:002013-02-08T06:40:35.035-08:00How to preserve User-Agent HTTP header when messages passing through WSO2 ESB<div dir="ltr" style="text-align: left;" trbidi="on">
When <b>WSO2 ESB</b> forwards a request to the back-end web service, ESB alters the <b>User-Agent</b> of the incoming request and sets it to <b>Synapse-HttpComponent-NIO</b>.<br />
<br />
Suppose, you want to avoid this and preserve User-Agent header sent by client. You can simply do it using the following method.<br />
<br />
<b>Step 1</b><br />
<br />
Open ESB_HOME/repository/conf/nhttp.properties file<br />
<br />
<b>Step 2</b><br />
<br />
Add the following property and save nhttp.properties file.<br />
<br />
<pre style="background: #ffffff; color: black;"><span style="font-size: large;">http.user.agent.preserve=true</span>
</pre>
<br />
<br />
<b>Step 3</b><br />
<br />
Restart ESB and send a HTTP request to ESB. Monitor the HTTP traffic between ESB and the back-end web service. You will see the <b>User-Agent</b> value is not altered by ESB.<br />
<b><br /></b>
<b>HTTP headers of the inbound request (client to ESB)</b><br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>POST http://localhost:8280/services/Axis2Proxy HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: "urn:echoString"
User-Agent: Jakarta Commons-HttpClient/3.1
Host: localhost:8280
Content-Length: 299
</code></pre>
<br />
<b>HTTP headers of the outbound request (ESB to back-end service)</b><br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>POST /services/Axis2Service HTTP/1.1
Content-Type: text/xml; charset=UTF-8
Accept-Encoding: gzip,deflate
User-Agent: Jakarta Commons-HttpClient/3.1
SOAPAction: "urn:echoString"
Transfer-Encoding: chunked
Host: 127.0.0.1:9765
Connection: Keep-Alive
</code></pre>
<br />
<br />
<br />
<br />
<br /></div>
Charithahttp://www.blogger.com/profile/00209392844529688942noreply@blogger.com0tag:blogger.com,1999:blog-5949896138631643846.post-57841677153893300262013-01-25T10:08:00.000-08:002013-01-25T10:08:04.404-08:00How to disable HTTP Keep-Alive connections for all out-going requests in WSO2 ESB<div dir="ltr" style="text-align: left;" trbidi="on">
By default, WSO2 ESB establishes HTTP Keep-Alive connection with the back-end web service. However, in some cases, we want to close connections just after using them specially when back-end server does not properly support Keep-Alive connections .<br />
At individual proxy service or sequence level, you can add <a href="http://wso2.org/project/esb/java/4.0.0/docs/properties_guide.html" target="_blank">NO_KEEPALIVE property</a> to disable Keep-Alive connection between ESB and backend web services.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><property name="NO_KEEPALIVE" value="true"
scope="axis2"/>
</code></pre>
<br />
However, if you want to disable Keep-Alive connections globally for all message mediations, the above property will not be the solution.<br />
<br />
In such cases, you can add the following parameter to <i><b>ESB_HOME/repository/conf/nhttp.properties</b></i> file.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>http.connection.disable.keepalive=1
</code></pre>
<br /></div>
Charithahttp://www.blogger.com/profile/00209392844529688942noreply@blogger.com0tag:blogger.com,1999:blog-5949896138631643846.post-90907316680022853042013-01-12T05:47:00.001-08:002013-01-12T05:47:10.266-08:00JSON pass-through in WSO2 ESB<div dir="ltr" style="text-align: left;" trbidi="on">
<a href="http://www.json.org/" target="_blank">JSON</a> is a lightweight data exchange format used in many web applications. <b>WSO2 ESB</b> supports sending and receiving JSON messages out-of-the-box. Exposing a SOAP web service over JSON is explained under <a href="http://docs.wso2.org/wiki/display/ESB451/Sample+440%3A+Exposing+a+SOAP+Service+Over+JSON" target="_blank">sample 440</a> in WSO2 ESB official documentation. This post is to summarize steps of invoking a pass-through proxy service which accepts JSON request, forwards it to a RESTful service and reply back with JSON response (JSON-in, JSON-out).<br />
<br />
<h4 style="text-align: left;">
<b>Pre-requisite:</b></h4>
<ul style="text-align: left;">
<li>Download and extract the binary distribution of <a href="http://wso2.com/products/enterprise-service-bus/" target="_blank">WSO2 ESB-4.5.1</a></li>
<li>I will use <a href="http://wso2.com/products/application-server/" target="_blank">WSO2 Application Server-5.0.1</a> to deploy RESTful backend web service. You can use any server as the backend. However, in order to follow the steps mentioned in this post, you should use WSO2 Application server.</li>
</ul>
<h4 style="text-align: left;">
<b>Step 1:</b></h4>
First, we need to setup the backend web service. We will deploy a <a href="http://jax-rs-spec.java.net/" target="_blank">JAX-RS</a> based restful service which consumes and produces JSON messages. You can download this RESTful web service(jaxrs_basic.war) from <a href="https://svn.wso2.org/repos/wso2/trunk/commons/qa/qa-artifacts/esb/esb450/json-resources/jaxrs_basic.war" target="_blank">here</a>.<br />
<br />
<h4 style="text-align: left;">
Step 2:</h4>
Start WSO2 Application Server, log in to management console and navigate to <b>Manage --> Applications --> List</b>.<br />
You will notice the web applications which are deployed by default in WSO2 Application Server. Since we already have a JAX-RS web app with the name jaxrs_basic, delete the default jaxrs_basic web application.<br />
<br />
Now, we can deploy our jaxrs_basic web application (Note that, jaxrs_basic is a modified version of default sample jax-rs web application which has been customized to consume and produce JSON messages).<br />
<br />
Go to <b>Manage --> Applications -->Add --> JAX-WS/JAX-RS.</b><br />
<b>Upload JAX-WS/JAX-RS Applications </b>page will be shown. Browse the downloaded jaxrs_basic.war and click on upload. New JAX-RS web service will be deployed in WSO2 Application Server.<br />
<br />
<h4 style="text-align: left;">
Step 3:</h4>
The auto-generated WADL of the RESTful web service can be obtained by accessing http://<wso2_application_server_hostname><wso2_application_server_hostname>:<wso2_application_server_port><wso2_application_server_port>/jaxrs_basic/services/customers?_wadl</wso2_application_server_port></wso2_application_server_hostname><br />
From there, you will identify the POST URL of 'customer' resource;<br />
<br />
<i><b>http://<wso2_application_server_hostname><wso2_application_server_hostname>:<wso2_application_server_port><wso2_application_server_port>/jaxrs_basic/services/customers/customerservice/customers </wso2_application_server_port></wso2_application_server_hostname></b></i><br />
<br />
We will forward a message to the above URL from WSO2 ESB.<br />
<br />
<h4 style="text-align: left;">
Step 4:</h4>
Now we have the backend web service, ready to process messages. Let's create a pass-through proxy service in ESB. Obviously, the endpoint URL will be the one mentioned above.<br />
<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><proxy xmlns="http://ws.apache.org/ns/synapse" name="jsonproxy" transports="https,http" statistics="disable" trace="disable" startOnLoad="true">
<target>
<outSequence>
<send/>
</outSequence>
<endpoint>
<address uri="http://localhost:9764/jaxrs_basic/services/customers/customerservice/customers"/>
</endpoint>
</target>
<description></description>
</proxy>
</code></pre>
<br />
Either using Pass Through Proxy template in WSO2 ESB management console or using file system, deploy the above proxy service.<br />
<br />
<h4 style="text-align: left;">
Step 5:</h4>
Let's send a JSON request to our proxy service. I will use soapUI as usual since it is the best tool out there to invoke web services.<br />
<br />
Open soapUI project and add a HTTP request test step to any existing test suite. Change the default method as POST. Enter the proxy service endpoint URL (http://<esb_host_name>:8280/services/jsonproxy) as the <b>Request URL</b>. <br />
Set the media type as application/json and add the following JSON request to POST body text area.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>{
"Customer": { "name": "charitha" }
}
</code></pre>
<br />
Finally, your soapUI request editor will look like the following.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_OdHLMq3d-lHbMfhuWZYLVQUC7TdBYIEuXWeDKV5ysJ07gBJhqHoEAyiuOdZapZ9XU9o33yKPCAvuORMYnX0yvp-MtVF72O2Txl-piKWqn0UdcDfel8DNmTfQF02GLvUEzc51NqJ4jOlL/s1600/sc1.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="230" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_OdHLMq3d-lHbMfhuWZYLVQUC7TdBYIEuXWeDKV5ysJ07gBJhqHoEAyiuOdZapZ9XU9o33yKPCAvuORMYnX0yvp-MtVF72O2Txl-piKWqn0UdcDfel8DNmTfQF02GLvUEzc51NqJ4jOlL/s320/sc1.png" width="320" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Submit the request. You will get a JSON response back as shown below. WSO2 ESB will seamlessly forward JSON request to RESTful web service and forward the JSON response to soapUI.<br />
<br />
<i><b>HTTP/1.1 200 OK
<br />Content-Type: application/json; charset=UTF-8
<br />Server: WSO2 Carbon Server
<br />Date: Sat, 12 Jan 2013 13:34:31 GMT
<br />Transfer-Encoding: chunked
<br /><br />{"Customer":{"id":"125","name":"charitha"}} </b></i><br />
<br />
<b>NOTE:</b><br />
In the previous versions of ESB (4.0.3 etc), you should add JSON message builders and formatters to ESB_HOME/repository/conf/axis2.xml in order to enable JSON message processing capabilities in ESB. (See <a href="http://docs.wso2.org/wiki/display/ESB403/ESB+and+JSON">http://docs.wso2.org/wiki/display/ESB403/ESB+and+JSON)</a><br />
However, these builder and formatters are enabled by default in WSO2 ESB version 4.5.1 and later. In addition to that, you may need to set the following property in IN and OUT paths of proxy services and sequences in previous ESB versions.<br />
<br />
<span style="-webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: white; color: #222222; display: inline !important; float: none; font-family: arial, sans-serif; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><property name="messageType" value="application/json" scope="axis2" /><span class="Apple-converted-space"> </span></span><br />
<br />
<br /></div>
Charithahttp://www.blogger.com/profile/00209392844529688942noreply@blogger.com1tag:blogger.com,1999:blog-5949896138631643846.post-14341861920470416702013-01-04T04:12:00.000-08:002013-01-04T04:12:25.474-08:00TIP: How to view log statements generated by WSO2 ESB log mediator in System Logs UI? <div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
When you use log mediator inside sequences and proxy services in WSO2 ESB , the logs are shown by default in wso2carbon.file which can be found in CARBON_HOME/repository/logs directory. The same logs are viewable from "System Logs" page in ESB management console.<br />
However, from ESB-4.5.X releases, you should do the following simple change in order to see these logs in "System Logs" UI in management console.<br />
<br />
<b>Step 1</b><br />
Open CARBON_HOME/repository/conf/axis2/axis2.xml<br />
<br />
<b>Step 2</b><br />
Uncomment the following element.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code> <handler class="org.wso2.carbon.utils.logging.handler.TenantDomainSetter" name="TenantDomainSetter">
</code></pre>
</div>
<br />
Now, restart the server. Send a request to ESB and see the logs in "System Logs" UI in management console.</div>
Charithahttp://www.blogger.com/profile/00209392844529688942noreply@blogger.com0