Search This Blog

Thursday, November 21, 2013

CQL 3 commands for Cassandra 1.2

I used apache-cassandra-1.2.4 cqlsh client with WSO2 Storage Server 1.1.0

Connection:
 $ ./cqlsh -3 node3 9160 -u admin -p admin  
 Connected to SSCluster at node3:9160.  
 [cqlsh 2.3.0 | Cassandra 1.2.10 | CQL spec 3.0.0 | Thrift protocol 19.36.0]  
 Use HELP for help.  
 cqlsh>

Create Keyspace:
 cqlsh> CREATE KEYSPACE ks215 WITH REPLICATION = {'class' : 'SimpleStrategy', 'replication_factor': 3};  

Use Keyspace:
cqlsh> use ks215;

Alter Keyspace
cqlsh:ks215> ALTER KEYSPACE ks215 WITH REPLICATION = {'class' : 'SimpleStrategy', 'replication_factor': 2};

Create Table (Column Family)
 cqlsh:ks215> CREATE TABLE company ( empID int, nationalID int, first_name varchar, last_name varchar, possition varchar, PRIMARY KEY (empID, nationalID));  

Insert into table:
 cqlsh:ks215> INSERT INTO company (empID, nationalID, first_name, last_name, possition) VALUES (101, 900810543, 'Chamara', 'Ariyarathne', 'SSE');  

Select:
 cqlsh:ks215> SELECT * FROM company;  

Monday, September 9, 2013

How to create a patch


1. Checkout the code

I checked out the WSO2 JAX-RS Starbucks service from here;

 http://svn.wso2.org/repos/wso2/carbon/platform/branches/4.2.0/products/as/5.2.0/modules/samples/product/Jaxws-Jaxrs/jaxrs_starbucks_service  

2. Make the change

I wanted this service to work as Non-SOAP for HTTP POST requests; So I changed the code as;

From here;
 @Consumes(MediaType.TEXT_XML)  // consumes text/xml  

To this;
 @Consumes(MediaType.APPLICATION_XML)  // consumes application/xml  

3. Create the diff

Now use the following svn command to create the patch diff
 $ svn diff > patch.diff  

4. Patch diff will look like this

 Index: src/main/java/demo/jaxrs/server/StarbucksOutletService.java  
 ===================================================================  
 --- src/main/java/demo/jaxrs/server/StarbucksOutletService.java (revision 184754)  
 +++ src/main/java/demo/jaxrs/server/StarbucksOutletService.java (working copy)  
 @@ -21,7 +21,7 @@  
    @Path("/orders/")  
  //  @Produces(MediaType.TEXT_PLAIN)  
    @Produces(MediaType.APPLICATION_JSON)  // produces application/json  
 -  @Consumes(MediaType.TEXT_XML)  // consumes text/xml  
 +  @Consumes(MediaType.APPLICATION_XML)  // consumes application/xml  
    public Response addOrder (Order orderBean);  
    /**  

Wednesday, September 4, 2013

Clustering WSO2 Identity Server and Load balancing it with WSO2 ELB

The WSO2 Identity server 4.5.0 and WSO2 Enterprise Load Balancer 2.1.0 is now released. So with this post I'm going to guide you with each and every and complete set of steps on how to cluster Identity server with two nodes and loadbalance it with ELB. And this setup is going to be in one Ubuntu machine.

Prerequisites:
1. Ubuntu 12.04 or a Linux similar platform
2. Java 1.6 or above (I'm using 1.7.0_25 64-bit)
3. Mysql (I'm using Ver 14.14 Distrib 5.5.32)

Let's go through the steps on how to cluster IS

1. Pointing to same User store and User Management db.

Being a cluster of IS, every node need to share the same User Store and User Management databases. So that every request come through load balancer will be served by any node similarly.

For User Store you can use any LDAP as Active Directory, Apache DS, OpenLDAP etc. Here I'm using the JDBC userstore which is supported by Identity Server to use a relational database as the user store.

I'm using mysql database for this.

Create a new database
 $ mysql -uroot -proot  

 mysql> create database is_user_store;  

Populate the tables needed. For that you can use the db scripts in the dbscripts directory in Identity Server home.
 ${IS_HOME}/dbscripts/mysql.sql  
 ${IS_HOME}/dbscripts/identity/mysql.sql  
 ${IS_HOME}/dbscripts/service-provider/mysql.sql  

 mysql> source mysql.sql;  
 mysql> source identity/mysql.sql;  
 mysql> source service-provider/mysql.sql;  

Now you have to use this database in the configurations. For the User Store you have to add the following configurations;

In the;
 ${IS_HOME}/repository/conf/datasources/master-datasources.xml  

Have the configuration
     <datasource>  
       <name>WSO2_USERSTORE_DB</name>  
       <description>The datasource used for registry and user manager</description>  
       <jndiConfig>  
         <name>jdbc/WSO2UserStoreDB</name>  
       </jndiConfig>  
       <definition type="RDBMS">  
         <configuration>  
           <url>jdbc:mysql://localhost:3306/is_user_store</url>  
           <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>  

And that jndi database reference have to be used in the user-mgt.xml as to use it as the userstore
${IS_HOME}/repository/conf/user-mgt.xml

     <UserStoreManager class="org.wso2.carbon.user.core.jdbc.JDBCUserStoreManager">  
       <Property name="TenantManager">org.wso2.carbon.user.core.tenant.JDBCTenantManager</Property>  
       <Property name="ReadOnly">false</Property>  
       <Property name="MaxUserNameListLength">100</Property>  
       <Property name="IsEmailUserName">false</Property>  
       <Property name="DomainCalculation">default</Property>  
       <Property name="PasswordDigest">SHA-256</Property>  
       <Property name="StoreSaltedPassword">true</Property>  
       <Property name="ReadGroups">true</Property>  
       <Property name="WriteGroups">true</Property>  
       <Property name="UserNameUniqueAcrossTenants">false</Property>  
       <Property name="PasswordJavaRegEx">^[\S]{5,30}$</Property>  
       <Property name="PasswordJavaScriptRegEx">^[\S]{5,30}$</Property>  
       <Property name="UsernameJavaRegEx">^[^~!#$;%^*+={}\\|\\\\&lt;&gt;,\'\"]{3,30}$</Property>  
       <Property name="UsernameJavaScriptRegEx">^[\S]{3,30}$</Property>  
       <Property name="RolenameJavaRegEx">^[^~!#$;%^*+={}\\|\\\\&lt;&gt;,\'\"]{3,30}$</Property>  
       <Property name="RolenameJavaScriptRegEx">^[\S]{3,30}$</Property>  
       <Property name="UserRolesCacheEnabled">true</Property>  
       <Property name="MaxRoleNameListLength">100</Property>  
       <Property name="MaxUserNameListLength">100</Property>  
       <Property name="SharedGroupEnabled">false</Property>  
       <Property name="SCIMEnabled">false</Property>  
       <Property name="dataSource">jdbc/WSO2UserStoreDB</Property>  
     </UserStoreManager>  

And for that to be the Primary userstore of the IS that need to be on top in the user-mgt.xml as the first mentioned userstore configuration. Every other userstore configuration you specify will be secondary userstores with a domain name.

and this has to be done in both of the IS nodes.

Now lets create another db and set it as the User Management db. Run the scripts to populate tables and refer it in the master-datasources.xml as following.

     <datasource>  
       <name>WSO2_UM_DB</name>  
       <description>The datasource used for registry and user manager</description>  
       <jndiConfig>  
         <name>jdbc/WSO2UserMgtDB</name>  
       </jndiConfig>  
       <definition type="RDBMS">  
         <configuration>  
           <url>jdbc:mysql://localhost:3306/is_user_mgt</url>  
           <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>  

You have to refer this in the user-mgt.xml as in following.
     <Configuration>  
         <AddAdmin>true</AddAdmin>  
         <AdminRole>admin</AdminRole>  
         <AdminUser>  
            <UserName>admin</UserName>  
            <Password>admin</Password>  
         </AdminUser>  
       <EveryOneRoleName>everyone</EveryOneRoleName> <!-- By default users in this role sees the registry root -->  
       <Property name="dataSource">jdbc/WSO2UserMgtDB</Property>  
     </Configuration>  

Now the User management related configurations are done. The next step is sharing the config and governance registries among each IS nodes. That is called Registry Mounting.

2. Registry Mounting

Let's create a database to be used in the mount configurations so that it will be the same repository for both IS nodes to share as the Config and Governance collections. That will be called the Mounted db. However for each IS node, the local registry will still be pointed to each and every node's H2 database. That configuration is already there in the master-datasources.xml. That need not to be changed.

You'll have to create a database in mysql and populate the tables. Let's see how it will be refered in the configurations.

First in the;
${IS_HOME}/repository/conf/datasources/master-datasources.xml  

     <datasource>  
       <name>WSO2_MOUNT_DB</name>  
       <description>The datasource used for registry and user manager</description>  
       <jndiConfig>  
         <name>jdbc/WSO2ISMountDB</name>  
       </jndiConfig>  
       <definition type="RDBMS">  
         <configuration>  
           <url>jdbc:mysql://localhost:3306/is_mount_db</url>  
           <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>  

And now this jndi database reference will be used in both nodes as in;
${IS_HOME}/repository/conf/registry.xml

   <currentDBConfig>wso2registry</currentDBConfig>  
   <readOnly>false</readOnly>  
   <enableCache>true</enableCache>  
   <registryRoot>/</registryRoot>  
   <dbConfig name="wso2registry">  
     <dataSource>jdbc/WSO2CarbonDB</dataSource>  
   </dbConfig>  
   <dbConfig name="mounted_registry">  
     <dataSource>jdbc/WSO2ISMountDB</dataSource>  
   </dbConfig>  
   <handler class="org.wso2.carbon.identity.entitlement.policy.finder.registry.RegistryPolicyHandler">  
     <filter class="org.wso2.carbon.identity.entitlement.policy.finder.registry.RegistryPolicyMediaTypeMatcher">  
       <property name="mediaType">application/xacml-policy+xml</property>  
     </filter>  
   </handler>  

   <remoteInstance url="https://localhost:9443/registry">  
     <id>instanceid</id>  
     <dbConfig>mounted_registry</dbConfig>  
     <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>  

Now let's look at the clustering configurations.

3. Clustering of IS nodes

We need to cluster two IS nodes as management nodes, and load balance it with WSO2 ELB.

First let's look at Identity Server configurations.

This is for the IS node 1.

${IS_HOME}/repository/conf/axis2/axis2.xml

There is a section as "clustering". You have to find the place and edit as following.
 <clustering class="org.wso2.carbon.core.clustering.hazelcast.HazelcastClusteringAgent"  
         enable="true">  

 <parameter name="membershipScheme">wka</parameter>  

We have to specify a domain for Identity Server cluster. And this domain name need to be unique from other WSO2 product clusters. Even from ELB domain.
 <parameter name="domain">wso2.is.chamara.domain</parameter>  

 <parameter name="localMemberPort">4001</parameter>  

 <parameter name="properties">  
       <property name="backendServerURL" value="https://${hostName}:${httpsPort}/services/"/>  
       <property name="mgtConsoleURL" value="https://${hostName}:${httpsPort}/"/>  
       <property name="subDomain" value="mgt"/>  
 </parameter>  

The next step is to define the well known member for IS nodes. (this will be kept as default)

         <members>
            <member>
                <hostName>127.0.0.1</hostName>
                <port>4000</port>
            </member>
        </members>


Here the well known member is WSO2 ELB. In the ELB in the file
${ELB_HOME}/repository/conf/axis2/axis2.xml

the property of localMemberHost will be kept as default.
<parameter name="localMemberHost">127.0.0.1</parameter>

and in the file
${ELB_HOME}/repository/conf/loadbalancer.conf

I will define group management port as 4000. This Hostname and the Port are the socket which each IS node will search for, as the well known member. 



In the carbon.xml
${IS_HOME}/repository/conf/carbon.xml

 <Offset>1</Offset>

 <HostName>wso2.is.chamara.com</HostName>  

 <MgtHostName>wso2.is.chamara.com</MgtHostName>

This hostname will be the one that is used by IS cluster and the ELB. It need to be specified in the;
 /etc/hosts  
as;
 127.0.0.1 wso2.is.chamara.com  

In the carbon.xml we are specifying the deployment synchronizer configuration as well. The deployment synchronizer will be enabled for, each IS nodes to share the secondary user store configurations.

Here I'm using svn based deployment synchronizer. So you'll have to find your own svn server and specify a location. Or else you can use Registry Based Deployment Synchronizer
   <DeploymentSynchronizer>  
     <Enabled>true</Enabled>  
     <AutoCommit>true</AutoCommit>  
     <AutoCheckout>true</AutoCheckout>  
     <RepositoryType>svn</RepositoryType>  
     <SvnUrl>http://svnexample.wso2.com/svn/chamara450</SvnUrl>  
     <SvnUser>wso2</SvnUser>  
     <SvnPassword>wso2123</SvnPassword>  
     <SvnUrlAppendTenantId>true</SvnUrlAppendTenantId>  
   </DeploymentSynchronizer>  

I'm going to run ELB on default HTTP/HTTPS ports which are 80/443.
So we have to specify those as proxy ports in the
${IS_HOME}/repository/conf/tomcat/catalina-server.xml

 <Connector protocol="org.apache.coyote.http11.Http11NioProtocol"  
         port="9763"  
         proxyPort="80"  

 <Connector protocol="org.apache.coyote.http11.Http11NioProtocol"  
         port="9443"  
         proxyPort="443"  

In the IS node 2 the configurations are almost same as for node1. The only differences that need to be changed are; in;
${IS_HOME}/repository/conf/axis2/axis2.xml

 <parameter name="localMemberPort">4002</parameter>  

and in;
${IS_HOME}/repository/conf/carbon.xml

 <Offset>2</Offset>

4. Sharing of same keystores in IS cluster and ELB

In this step I'm going to explain how to use the same keystore in three servers and having certificates in the truststores. We can always use the default keystore wso2carbon.jks and it's public certificates. But in this case since we are using ELB in default ports, the servers need to have same keystore with the Common Name as the domain name (CN=wso2.is.chamara.com). So here are the steps to generate your own keystore.

 $ keytool -genkey -alias iscarbon -keyalg RSA -keysize 1024 -keypass iscarbon -keystore iscarbon.jks -storepass iscarbon  
 What is your first and last name?  
  [Unknown]: wso2.is.chamara.com  
 What is the name of your organizational unit?  
  [Unknown]: users.wso2  
 What is the name of your organization?  
  [Unknown]: wso2  
 What is the name of your City or Locality?  
  [Unknown]: Colombo  
 What is the name of your State or Province?  
  [Unknown]: Western  
 What is the two-letter country code for this unit?  
  [Unknown]: 94  
 Is CN=wso2.is.chamara.com, OU=users.wso2, O=wso2, L=Colombo, ST=Western, C=94 correct?  
  [no]: yes  

Here for local testing purposes it is ok to use self signed certificate. If this is going to be used in production the public certificate need to be signed by Certificate Authority.

Now export the public certificate and import it to the server trust store. Here it need to be imported in two IS nodes and the ELB.
 $ keytool -export -alias iscarbon -keystore iscarbon.jks -storepass iscarbon -file iscarbon.pem  

 $ keytool -import -alias iscarbon -file iscarbon.pem -keystore client-truststore.jks -storepass wso2carbon  

Now we need to change the configuration files to use this new keystore as the server keystore. For that following locations needs to be updated accordingly.

 identity.xml: <Location>${carbon.home}/repository/resources/security/iscarbon.jks</Location>  
 identity.xml: <Password>iscarbon</Password>  
 security/cipher-text.properties: Carbon.Security.KeyStore.Password=[iscarbon]  
 security/cipher-text.properties: Carbon.Security.KeyStore.KeyPassword=[iscarbon]  
 carbon.xml: <Location>${carbon.home}/repository/resources/security/iscarbon.jks</Location>  
 carbon.xml: <Password>iscarbon</Password>  
 carbon.xml: <KeyAlias>iscarbon</KeyAlias>  
 carbon.xml: <KeyPassword>iscarbon</KeyPassword>  
 axis2/axis2.xml: <Location>repository/resources/security/iscarbon.jks</Location>  
 axis2/axis2.xml: <Password>iscarbon</Password>  
 axis2/axis2.xml: <KeyPassword>iscarbon</KeyPassword>  
 axis2/axis2.xml: <Password>iscarbon</Password>  
 axis2/axis2.xml: <Location>repository/resources/security/iscarbon.jks</Location>  
 axis2/axis2.xml: <Password>iscarbon</Password>  
 axis2/axis2.xml: <KeyPassword>iscarbon</KeyPassword>  
 axis2/axis2.xml: <Password>iscarbon</Password>  

5. Configuring the Elastic Load Balancer

We are done with configuring the IS nodes. Lets look at how to configure the ELB

${ELB_HOME}/repository/conf/axis2/axis2.xml

 <clustering class="org.wso2.carbon.core.clustering.hazelcast.HazelcastClusteringAgent" enable="true">  

 <parameter name="domain">wso2.chamara.lb.domain</parameter>  

this is a individual port unique from is nodes' localMemberPort
 <parameter name="localMemberPort">4100</parameter>  

For changing Transport ports (Proxy ports in IS nodes)

 <transportReceiver name="http" class="org.apache.synapse.transport.passthru.PassThroughHttpListener">  
    <parameter name="port">80</parameter>  

 <transportReceiver name="https" class="org.apache.synapse.transport.passthru.PassThroughHttpSSLListener">  
     <parameter name="port" locked="false">443</parameter>  

In the file
${ELB_HOME}/repository/conf/loadbalancer.conf

Remove all the services entries and add the following.

   identity {  
     domains  {  
       wso2.is.chamara.domain {  
         tenant_range  *;  
         group_mgt_port 4000;  
         mgt {  
           hosts wso2.is.chamara.com;  
         }  
       }  
     }  
   }  

In the ELB also you need to specify keystore configurations as above, in order to use the iscarbon.jks. Here you don't have add configure or add any identity.xml.

6. Running the cluster

Now we have come to the last part. First run the ELB. For run that you need to be the superuser of that computer since we are running ELB on default ports.

 {ELB_HOME}# ./bin/wso2server.sh  

Then run two IS servers.

 {IS_HOME}$ ./bin/wso2server.sh  

You will see the following logs in ELB while IS nodes joining ELB.

 [2013-09-04 08:21:15,211] INFO - HazelcastGroupManagementAgent Member joined [ad2e310c-bf27-4bf3-9e03-afbe2117b6dd]: /127.0.0.1:4001  
 [2013-09-04 08:21:18,275] INFO - MemberUtils Added member: Host:127.0.0.1, Remote Host:null, Port: 4001, HTTP:9764, HTTPS:9444, Domain: wso2.is.chamara.domain, Sub-domain:mgt, Active:true  
 [2013-09-04 08:21:18,276] INFO - HazelcastGroupManagementAgent Application member Host:127.0.0.1, Remote Host:null, Port: 4001, HTTP:9764, HTTPS:9444, Domain: wso2.is.chamara.domain, Sub-domain:mgt, Active:true joined application cluster  

 [2013-09-04 08:24:59,428] INFO - HazelcastGroupManagementAgent Member joined [3db96e0f-d4e9-4c45-bbdf-6331682a61cd]: /127.0.0.1:4002  
 [2013-09-04 08:25:02,493] INFO - MemberUtils Added member: Host:127.0.0.1, Remote Host:null, Port: 4002, HTTP:9765, HTTPS:9445, Domain: wso2.is.chamara.domain, Sub-domain:mgt, Active:true  
 [2013-09-04 08:25:02,494] INFO - HazelcastGroupManagementAgent Application member Host:127.0.0.1, Remote Host:null, Port: 4002, HTTP:9765, HTTPS:9445, Domain: wso2.is.chamara.domain, Sub-domain:mgt, Active:true joined application cluster  

And also while IS node joins each other following log will be appeared.

Node 1

 [2013-09-04 08:22:15,083] INFO {org.wso2.carbon.core.clustering.hazelcast.util.MemberUtils} - Added member: Host:127.0.0.1, Remote Host:null, Port: 4000, HTTP:-1, HTTPS:-1, Domain: null, Sub-domain:null, Active:true  
 [2013-09-04 08:22:23,314] INFO {org.wso2.carbon.core.clustering.hazelcast.HazelcastClusteringAgent} - Hazelcast initialized in 8228ms  
 [2013-09-04 08:22:23,365] INFO {org.wso2.carbon.core.clustering.hazelcast.HazelcastClusteringAgent} - Local member: [bb0a0482-aea0-4895-a2f1-68ee721a38a5] - Host:127.0.0.1, Remote Host:null, Port: 4001, HTTP:9764, HTTPS:9444, Domain: wso2.is.chamara.domain, Sub-domain:mgt, Active:true  
 [2013-09-04 08:22:23,374] INFO {org.wso2.carbon.core.clustering.hazelcast.util.MemberUtils} - Added member: Host:127.0.0.1, Remote Host:null, Port: 4001, HTTP:9764, HTTPS:9444, Domain: wso2.is.chamara.domain, Sub-domain:mgt, Active:true  

 [2013-09-04 08:24:59,430] INFO {org.wso2.carbon.core.clustering.hazelcast.wka.WKABasedMembershipScheme} - Member joined [3db96e0f-d4e9-4c45-bbdf-6331682a61cd]: /127.0.0.1:4002  
 [2013-09-04 08:25:01,494] INFO {org.wso2.carbon.core.clustering.hazelcast.util.MemberUtils} - Added member: Host:127.0.0.1, Remote Host:null, Port: 4002, HTTP:9765, HTTPS:9445, Domain: wso2.is.chamara.domain, Sub-domain:mgt, Active:true  

Node 2

 [2013-09-04 08:24:53,226] INFO {org.wso2.carbon.core.clustering.hazelcast.util.MemberUtils} - Added member: Host:127.0.0.1, Remote Host:null, Port: 4000, HTTP:-1, HTTPS:-1, Domain: null, Sub-domain:null, Active:true  
 [2013-09-04 08:25:01,451] INFO {org.wso2.carbon.core.clustering.hazelcast.HazelcastClusteringAgent} - Hazelcast initialized in 8223ms  
 [2013-09-04 08:25:01,481] INFO {org.wso2.carbon.core.clustering.hazelcast.util.MemberUtils} - Added member: Host:127.0.0.1, Remote Host:null, Port: 4001, HTTP:9764, HTTPS:9444, Domain: wso2.is.chamara.domain, Sub-domain:mgt, Active:true  
 [2013-09-04 08:25:01,481] INFO {org.wso2.carbon.core.clustering.hazelcast.HazelcastClusteringAgent} - Local member: [3db96e0f-d4e9-4c45-bbdf-6331682a61cd] - Host:127.0.0.1, Remote Host:null, Port: 4002, HTTP:9765, HTTPS:9445, Domain: wso2.is.chamara.domain, Sub-domain:mgt, Active:true  
 [2013-09-04 08:25:01,492] INFO {org.wso2.carbon.core.clustering.hazelcast.util.MemberUtils} - Added member: Host:127.0.0.1, Remote Host:null, Port: 4002, HTTP:9765, HTTPS:9445, Domain: wso2.is.chamara.domain, Sub-domain:mgt, Active:true  

Now you can access the IS cluster Management Consoles using following url;

 https://wso2.is.chamara.com/carbon/  

Login using the default admin user {admin:admin}


Saturday, August 31, 2013

WSO2 Appserver 5.2.0 JAX-RS Starbucks Sample

Checkout the sample from
 http://svn.wso2.org/repos/wso2/carbon/platform/branches/4.2.0/products/as/5.2.0/modules/samples/product/Jaxws-Jaxrs/jaxrs_starbucks_service  
and build with
 mvn clean install  

Or download the pre built app from here

Deploy the sample app in WSO2 Appserver 5.2.0.

Now let's look at the RESTful Invocations using curl.

1. Retrieve
 curl -v -X GET http://localhost:9763/jaxrs_starbucks_service/services/Starbucks_Outlet_Service/orders/123
 * About to connect() to localhost port 9764 (#0)  
 *  Trying 127.0.0.1... connected  
 > GET /jaxrs_starbucks_service/services/Starbucks_Outlet_Service/orders/123 HTTP/1.1  
 > User-Agent: curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3  
 > Host: localhost:9764  
 > Accept: */*  
 >   
 < HTTP/1.1 200 OK  
 < Date: Sat, 31 Aug 2013 19:07:42 GMT  
 < Content-Type: application/json  
 < Transfer-Encoding: chunked  
 < Server: WSO2 Carbon Server  
 <   
 * Connection #0 to host localhost left intact  
 * Closing connection #0  
 {"Order":{"additions":"Milk","drinkName":"Vanilla Flavored Coffee","locked":false,"orderId":123}}  


2. Create
 <Order> 
   <drinkName>Mocha Coffee</drinkName> 
   <additions>Caramel</additions> 
 </Order> 

 curl -v -X POST -H "Content-Type: text/xml" -d @starbucks_order.xml http://localhost:9763/jaxrs_starbucks_service/services/Starbucks_Outlet_Service/orders
 * About to connect() to localhost port 9764 (#0)  
 *  Trying 127.0.0.1... connected  
 > POST /jaxrs_starbucks_service/services/Starbucks_Outlet_Service/orders HTTP/1.1  
 > User-Agent: curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3  
 > Host: localhost:9764  
 > Accept: */*  
 > Content-Type: text/xml  
 > Content-Length: 86  
 >   
 * upload completely sent off: 86out of 86 bytes  
 < HTTP/1.1 200 OK  
 < Date: Sat, 31 Aug 2013 19:10:09 GMT  
 < Content-Type: application/json  
 < Transfer-Encoding: chunked  
 < Server: WSO2 Carbon Server  
 <   
 * Connection #0 to host localhost left intact  
 * Closing connection #0  
 {"Order":{"additions":"Caramel","drinkName":"Mocha Coffee","locked":false,"orderId":"55a7a380-e852-44f6-b2d6-c40bd9d70be0"}}  


3. Update
 {  
  "Order": {  
   "orderId": "55a7a380-e852-44f6-b2d6-c40bd9d70be0",  
   "additions": "Chocolate Chip Cookies"  
  }  
 }  
 curl -v -X PUT -H "Content-Type: application/json" -d @starbucks_update.json http://localhost:9763/jaxrs_starbucks_service/services/Starbucks_Outlet_Service/orders  
 * About to connect() to localhost port 9764 (#0)  
 *  Trying 127.0.0.1... connected  
 > PUT /jaxrs_starbucks_service/services/Starbucks_Outlet_Service/orders HTTP/1.1  
 > User-Agent: curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3  
 > Host: localhost:9764  
 > Accept: */*  
 > Content-Type: application/json  
 > Content-Length: 112  
 >   
 * upload completely sent off: 112out of 112 bytes  
 < HTTP/1.1 200 OK  
 < Date: Sat, 31 Aug 2013 19:14:11 GMT  
 < Content-Type: application/json  
 < Transfer-Encoding: chunked  
 < Server: WSO2 Carbon Server  
 <   
 * Connection #0 to host localhost left intact  
 * Closing connection #0  
 {"Order":{"additions":"Chocolate Chip Cookies","drinkName":"Mocha Coffee","locked":false,"orderId":"55a7a380-e852-44f6-b2d6-c40bd9d70be0"}}  

4. Delete
 curl -v -X DELETE http://localhost:9763/jaxrs_starbucks_service/services/Starbucks_Outlet_Service/orders/55a7a380-e852-44f6-b2d6-c40bd9d70be0  
 * About to connect() to localhost port 9764 (#0)  
 *  Trying 127.0.0.1... connected  
 > DELETE /jaxrs_starbucks_service/services/Starbucks_Outlet_Service/orders/55a7a380-e852-44f6-b2d6-c40bd9d70be0 HTTP/1.1  
 > User-Agent: curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3  
 > Host: localhost:9764  
 > Accept: */*  
 >   
 < HTTP/1.1 200 OK  
 < Date: Sat, 31 Aug 2013 19:16:41 GMT  
 < Content-Type: application/json  
 < Transfer-Encoding: chunked  
 < Server: WSO2 Carbon Server  
 <   
 * Connection #0 to host localhost left intact  
 * Closing connection #0  




Friday, August 16, 2013

SAML OAuth Grant Type with OpenID Connect

This is an extenstion on the blog provided by Johann at
http://nallaa.wordpress.com/2013/04/04/saml2-bearer-assertion-profile-for-oauth-2-0-with-wso2-identity-server/

on how to use the SAML OAuth grant type with OpenID Connect

1. Create SAML2 assertion

Download the java client here. 
But use this jar which is modifed to send claim attributes.
https://svn.wso2.org/repos/wso2/people/chamaraa/SAML2AssertionCreator.jar SAML2AssertionCreator.jar

The command to use the client is

 java -jar SAML2AssertionCreator.jar SAML2AssertionCreator admin https://localhost:9443/oauth2/token https://localhost:9443/oauth2/token /home/chamara/isrelease/14082013/wso2is-4.5.0-SNAPSHOT-AD/repository/resources/security/wso2carbon.jks wso2carbon wso2carbon wso2carbon  

The result will be

 SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".  
 SLF4J: Defaulting to no-operation (NOP) logger implementation  
 SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.  
 Assertion String: <?xml version="1.0" encoding="UTF-8"?><saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="opgehlkjdppnfmpjpgolbekkghdjkpbjhpjggbbl" IssueInstant="2013-08-16T11:26:19.710Z" Version="2.0"><saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">SAML2AssertionCreator</saml: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:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>  
 <ds:Reference URI="#opgehlkjdppnfmpjpgolbekkghdjkpbjhpjggbbl">  
 <ds:Transforms>  
 <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>  
 <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="ds saml xs xsi"/></ds:Transform>  
 </ds:Transforms>  
 <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>  
 <ds:DigestValue>Yu1RAlCuatR035v/zsy1jbJaa2g=</ds:DigestValue>  
 </ds:Reference>  
 </ds:SignedInfo>  
 <ds:SignatureValue>  
 Bom3LNNumJhwdB/grQqsDIRB17mMLFouoYc7JLce9yQNiagres4bmkyAWBq74uFxitMJJbgdnTUK  
 PQ5NoDMp3Zw0tjo+cjXZNhHXbEJY8uGvSDC/dI6QOhzCWSPvvb4rwG1JKYSFtNCfuCricFH6Y0JQ  
 xRr3KtwD7ehMpWxU/pY=  
 </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><saml:Subject><saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">admin</saml:NameID><saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml:SubjectConfirmationData InResponseTo="0" NotOnOrAfter="2013-08-16T11:31:19.710Z" Recipient="https://localhost:9443/oauth2/token"/></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore="2013-08-16T11:26:19.710Z" NotOnOrAfter="2013-08-16T11:31:19.710Z"><saml:AudienceRestriction><saml:Audience>https://localhost:9443/oauth2/token</saml:Audience></saml:AudienceRestriction></saml:Conditions><saml:AuthnStatement AuthnInstant="2013-08-16T11:26:19.869Z"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement><saml:AttributeStatement><saml:Attribute><saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">/</saml:AttributeValue></saml:Attribute></saml:AttributeStatement></saml:Assertion>  
 base64-url Encoded Assertion String: PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c2FtbDpBc3NlcnRpb24geG1s%0AbnM6c2FtbD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiIgSUQ9Im9wZ2Vo%0AbGtqZHBwbmZtcGpwZ29sYmVra2doZGprcGJqaHBqZ2diYmwiIElzc3VlSW5zdGFudD0iMjAxMy0w%0AOC0xNlQxMToyNjoxOS43MTBaIiBWZXJzaW9uPSIyLjAiPjxzYW1sOklzc3VlciBGb3JtYXQ9InVy%0AbjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpuYW1laWQtZm9ybWF0OmVudGl0eSI%2BU0FNTDJBc3Nl%0AcnRpb25DcmVhdG9yPC9zYW1sOklzc3Vlcj48ZHM6U2lnbmF0dXJlIHhtbG5zOmRzPSJodHRwOi8v%0Ad3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjIj4KPGRzOlNpZ25lZEluZm8%2BCjxkczpDYW5vbmlj%0AYWxpemF0aW9uTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwt%0AZXhjLWMxNG4jIi8%2BCjxkczpTaWduYXR1cmVNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3Lncz%0ALm9yZy8yMDAwLzA5L3htbGRzaWcjcnNhLXNoYTEiLz4KPGRzOlJlZmVyZW5jZSBVUkk9IiNvcGdl%0AaGxramRwcG5mbXBqcGdvbGJla2tnaGRqa3BiamhwamdnYmJsIj4KPGRzOlRyYW5zZm9ybXM%2BCjxk%0AczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcj%0AZW52ZWxvcGVkLXNpZ25hdHVyZSIvPgo8ZHM6VHJhbnNmb3JtIEFsZ29yaXRobT0iaHR0cDovL3d3%0Ady53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIj48ZWM6SW5jbHVzaXZlTmFtZXNwYWNlcyB4%0AbWxuczplYz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8xMC94bWwtZXhjLWMxNG4jIiBQcmVmaXhM%0AaXN0PSJkcyBzYW1sIHhzIHhzaSIvPjwvZHM6VHJhbnNmb3JtPgo8L2RzOlRyYW5zZm9ybXM%2BCjxk%0AczpEaWdlc3RNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRz%0AaWcjc2hhMSIvPgo8ZHM6RGlnZXN0VmFsdWU%2BWXUxUkFsQ3VhdFIwMzV2L3pzeTFqYkphYTJnPTwv%0AZHM6RGlnZXN0VmFsdWU%2BCjwvZHM6UmVmZXJlbmNlPgo8L2RzOlNpZ25lZEluZm8%2BCjxkczpTaWdu%0AYXR1cmVWYWx1ZT4KQm9tM0xOTnVtSmh3ZEIvZ3JRcXNESVJCMTdtTUxGb3VvWWM3SkxjZTl5UU5p%0AYWdyZXM0Ym1reUFXQnE3NHVGeGl0TUpKYmdkblRVSwpQUTVOb0RNcDNadzB0am8rY2pYWk5oSFhi%0ARUpZOHVHdlNEQy9kSTZRT2h6Q1dTUHZ2YjRyd0cxSktZU0Z0TkNmdUNyaWNGSDZZMEpRCnhScjNL%0AdHdEN2VoTXBXeFUvcFk9CjwvZHM6U2lnbmF0dXJlVmFsdWU%2BCjxkczpLZXlJbmZvPjxkczpYNTA5%0ARGF0YT48ZHM6WDUwOUNlcnRpZmljYXRlPk1JSUNOVENDQVo2Z0F3SUJBZ0lFUzM0M2dqQU5CZ2tx%0AaGtpRzl3MEJBUVVGQURCVk1Rc3dDUVlEVlFRR0V3SlZVekVMTUFrR0ExVUUKQ0F3Q1EwRXhGakFV%0AQmdOVkJBY01EVTF2ZFc1MFlXbHVJRlpwWlhjeERUQUxCZ05WQkFvTUJGZFRUekl4RWpBUUJnTlZC%0AQU1NQ1d4dgpZMkZzYUc5emREQWVGdzB4TURBeU1Ua3dOekF5TWpaYUZ3MHpOVEF5TVRNd056QXlN%0AalphTUZVeEN6QUpCZ05WQkFZVEFsVlRNUXN3CkNRWURWUVFJREFKRFFURVdNQlFHQTFVRUJ3d05U%0AVzkxYm5SaGFXNGdWbWxsZHpFTk1Bc0dBMVVFQ2d3RVYxTlBNakVTTUJBR0ExVUUKQXd3SmJHOWpZ%0AV3hvYjNOME1JR2ZNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0R05BRENCaVFLQmdRQ1VwL29WMXZXYzgv%0AVGtRU2lBdlRvdQpzTXpPTTRhc0IyaWx0cjJRS296bmk1YVZGdTgxOE1wT0xaSXI4TE1uVHpXbGxK%0AdnZhQTVSQUFkcGJFQ2IrNDhGamJCZTBoc2VVZE41Ckhwd3ZuSC9EVzhaY2NHdms1M0k2T3JxN2hM%0AQ3YxWkh0dU9Db2tnaHovQVRyaHlQcStRa3RNZlhuUlM0SHJLR0pUenhhQ2NVN09RSUQKQVFBQm94%0ASXdFREFPQmdOVkhROEJBZjhFQkFNQ0JQQXdEUVlKS29aSWh2Y05BUUVGQlFBRGdZRUFXNXdQUjdj%0AcjFMQWRxK0lyUjQ0aQpRbFJHNUlUQ1pYWTloSTBQeWdMUDJySEFOaCtQWWZUbXhidU9ueWtOR3lo%0ATTZGakZMYlcydVpIUVRZMWpNclBwcmpPcm15SzVzakpSCk80ZDFEZUdIVC9ZbklqczlKb2dSS3Y0%0AWEhFQ3dMdElWZEFiSWRXSEV0VlpKeU1Ta3RjeXlzRmN2dWhQUUs4UWMvRS9XcTh1SFNDbz08L2Rz%0AOlg1MDlDZXJ0aWZpY2F0ZT48L2RzOlg1MDlEYXRhPjwvZHM6S2V5SW5mbz48L2RzOlNpZ25hdHVy%0AZT48c2FtbDpTdWJqZWN0PjxzYW1sOk5hbWVJRCBGb3JtYXQ9InVybjpvYXNpczpuYW1lczp0YzpT%0AQU1MOjEuMTpuYW1laWQtZm9ybWF0OmVtYWlsQWRkcmVzcyI%2BYWRtaW48L3NhbWw6TmFtZUlEPjxz%0AYW1sOlN1YmplY3RDb25maXJtYXRpb24gTWV0aG9kPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoy%0ALjA6Y206YmVhcmVyIj48c2FtbDpTdWJqZWN0Q29uZmlybWF0aW9uRGF0YSBJblJlc3BvbnNlVG89%0AIjAiIE5vdE9uT3JBZnRlcj0iMjAxMy0wOC0xNlQxMTozMToxOS43MTBaIiBSZWNpcGllbnQ9Imh0%0AdHBzOi8vbG9jYWxob3N0Ojk0NDMvb2F1dGgyL3Rva2VuIi8%2BPC9zYW1sOlN1YmplY3RDb25maXJt%0AYXRpb24%2BPC9zYW1sOlN1YmplY3Q%2BPHNhbWw6Q29uZGl0aW9ucyBOb3RCZWZvcmU9IjIwMTMtMDgt%0AMTZUMTE6MjY6MTkuNzEwWiIgTm90T25PckFmdGVyPSIyMDEzLTA4LTE2VDExOjMxOjE5LjcxMFoi%0APjxzYW1sOkF1ZGllbmNlUmVzdHJpY3Rpb24%2BPHNhbWw6QXVkaWVuY2U%2BaHR0cHM6Ly9sb2NhbGhv%0Ac3Q6OTQ0My9vYXV0aDIvdG9rZW48L3NhbWw6QXVkaWVuY2U%2BPC9zYW1sOkF1ZGllbmNlUmVzdHJp%0AY3Rpb24%2BPC9zYW1sOkNvbmRpdGlvbnM%2BPHNhbWw6QXV0aG5TdGF0ZW1lbnQgQXV0aG5JbnN0YW50%0APSIyMDEzLTA4LTE2VDExOjI2OjE5Ljg2OVoiPjxzYW1sOkF1dGhuQ29udGV4dD48c2FtbDpBdXRo%0AbkNvbnRleHRDbGFzc1JlZj51cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YWM6Y2xhc3NlczpQ%0AYXNzd29yZDwvc2FtbDpBdXRobkNvbnRleHRDbGFzc1JlZj48L3NhbWw6QXV0aG5Db250ZXh0Pjwv%0Ac2FtbDpBdXRoblN0YXRlbWVudD48c2FtbDpBdHRyaWJ1dGVTdGF0ZW1lbnQ%2BPHNhbWw6QXR0cmli%0AdXRlPjxzYW1sOkF0dHJpYnV0ZVZhbHVlIHhtbG5zOnhzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAx%0AL1hNTFNjaGVtYSIgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1p%0AbnN0YW5jZSIgeHNpOnR5cGU9InhzOnN0cmluZyI%2BLzwvc2FtbDpBdHRyaWJ1dGVWYWx1ZT48L3Nh%0AbWw6QXR0cmlidXRlPjwvc2FtbDpBdHRyaWJ1dGVTdGF0ZW1lbnQ%2BPC9zYW1sOkFzc2VydGlvbj4%3D  


You have to extract the base64-url Encoded Assertion String and use it in a http POST request;

Jmeter script is attached here

For this POST request to work you have to add the Trusted Identity Provider to IS.
For that first export the trusted certificate from the wso2carbon.jks

 wso2is-4.5.0/repository/resources/security$ keytool -export -alias wso2carbon -keystore wso2carbon.jks -storepass wso2carbon -file mycert.pem  

Add this certificate in the IS -> Configure -> Trusted Idps -> Add New Trusted Identity Provider ->

Identity Provider Name: test
Identity Provider Issuer: SAML2AssertionCreator
Identity Provider Public Certificate: attach the certificate
 Identity Provider Audience: https://localhost:9443/oauth2/token 

The Jmeter response will be your access token and refresh token

 {"token_type":"bearer","expires_in":2947,"refresh_token":"74a77731f314f641f98c2470af1b879","id_token":"eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0=\r\n.eyJleHAiOi01MzEzNjg4MDQsImF6cCI6IkNqZ2dmaW1yNWNneFFSOFpQNkRseEZmTlVpY2EiLCJz\r\ndWIiOiJhZG1pbiIsImVtYWlsIjoiY2hhbWFyYUB3c28yLmNvbSIsImF1ZCI6IkNqZ2dmaW1yNWNn\r\neFFSOFpQNkRseEZmTlVpY2EiLCJpc3MiOiJodHRwczpcL1wvbG9jYWxob3N0Ojk0NDNcL29hdXRo\r\nMmVuZHBvaW50c1wvdG9rZW4iLCJ0ZWxlcGhvbmUiOiIrOTQ3NTUwMTIwNjAiLCJpYXQiOi01MzQ5\r\nNjg4MDQsImNvdW50cnkiOiJTcmkgTGFua2EifQ==\r\n.","access_token":"edec914a3decfbfcf32d2573dc540c0"}  

In that response you can extract the id_token which is

 eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0=\r\n.eyJleHAiOi01MzEzNjg4MDQsImF6cCI6IkNqZ2dmaW1yNWNneFFSOFpQNkRseEZmTlVpY2EiLCJz\r\ndWIiOiJhZG1pbiIsImVtYWlsIjoiY2hhbWFyYUB3c28yLmNvbSIsImF1ZCI6IkNqZ2dmaW1yNWNn\r\neFFSOFpQNkRseEZmTlVpY2EiLCJpc3MiOiJodHRwczpcL1wvbG9jYWxob3N0Ojk0NDNcL29hdXRo\r\nMmVuZHBvaW50c1wvdG9rZW4iLCJ0ZWxlcGhvbmUiOiIrOTQ3NTUwMTIwNjAiLCJpYXQiOi01MzQ5\r\nNjg4MDQsImNvdW50cnkiOiJTcmkgTGFua2EifQ==\r\n.  

And if you decode this with a base64 decoder, You will get the result as

 {"alg":"none","typ":"JWT"}  
 {"exp":-531368804,"azp":"Cjggfimr5cgxQR8ZP6DlxFfNUica","sub":"admin","email":"chamara@wso2.com","aud":"Cjggfimr5cgxQR8ZP6DlxFfNUica","iss":"https:\/\/localhost:9443\/oauth2endpoints\/token","telephone":"+94755012060","iat":-534968804,"country":"Sri Lanka"}  


Thursday, July 11, 2013

An Axis2 Service to Log the incoming message

Java class is:

 package org.wso2.logservice;  
 import org.apache.commons.logging.Log;  
 import org.apache.commons.logging.LogFactory;  
 public class LogService{  
   private static final Log log = LogFactory.getLog(LogService.class);  
   public void LogAndDrop (String incoming) {     
     log.info("The message is: "+ incoming);  
   }  
   public String LogAndAck (String incoming) {  
     log.info("The message is: "+ incoming);  
     return "Logged: "+ incoming;  
   }  
 }  

Use this class and build an axis2 service.
Then you can deploy the service in WSO2 Application Server and invoke.

While invoking with a String value you will be able to notice that the message you sent will be logged in the wso2carbon.log as

 TID: [0] [AS] [2013-07-11 10:42:23,686] INFO {org.wso2.logservice.LogService} - The message is: Logging is what? Good ! {org.wso2.logservice.LogService}  
 TID: [0] [AS] [2013-07-11 10:42:37,993] INFO {org.wso2.logservice.LogService} - The message is: Logging and getting a response is what? Goood ! {org.wso2.logservice.LogService}  

Wednesday, July 10, 2013

WSO2 ESB, MB integration to serve a backend axis2service with more than one JMS queues to ensure the speed and the integrity

WSO2 ESB's JMS Message Store implementation can be used to store incoming messages in a queue and serve a backend service without having to worry about the integrity of the messages.

In a simple scenario it is possible to implement a Proxy service which the client sees and calls to, a message store which stores those messages in a JMS queue and a message processor which fetches those messages and send to the defined endpoint.

We can implement a scenario which uses more than one queues and more than one message stores to put messages into those queues and more than one message processors to fetch from queues and serves one backend endpoint. Here we will have to use more than one proxy service in ESB and the requests coming in can be load balanced to which proxy it should go and which ESB node it should go.

Here I'm using three proxy services in two ESB nodes. The load balancing to each proxy needs to be done from the client side. But the load balancing to each ESB node will be happened by the ELB.

First you have to configure a ESB Cluster load balanced by a WSO2 ELB and with JMS transport enabled with a WSO2 MB. After that you can use the following synapse configurations to implement the scenario.

One set of Proxy, Store, Processor, Endpoint configuration of ESB node 1;

Proxy; 

 <?xml version="1.0" encoding="UTF-8"?>  
 <proxy xmlns="http://ws.apache.org/ns/synapse"  
     name="Proxy1"  
     transports="https http"  
     startOnLoad="true"  
     trace="disable">  
   <description/>  
   <target>  
    <inSequence>  
      <property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>  
      <property name="OUT_ONLY" value="true"/>  
      <property name="target.endpoint" value="logndrop"/>  
      <store messageStore="JMSMS"/>  
    </inSequence>  
   </target>  
 </proxy>  


Endpoint;

 <?xml version="1.0" encoding="UTF-8"?>  
 <endpoint xmlns="http://ws.apache.org/ns/synapse" name="logndrop">  
   <address uri="http://localhost:9773/as/services/LognDrop"/>  
 </endpoint>  


Message Store;
 
 <?xml version="1.0" encoding="UTF-8"?>  
 <messageStore xmlns="http://ws.apache.org/ns/synapse"  
        class="org.wso2.carbon.message.store.persistence.jms.JMSMessageStore"  
        name="JMSMS">  
   <parameter name="java.naming.factory.initial">org.wso2.andes.jndi.PropertiesFileInitialContextFactory</parameter>  
   <parameter name="store.jms.cache.connection">false</parameter>  
   <parameter name="java.naming.provider.url">repository/conf/jndi.properties</parameter>  
   <parameter name="store.jms.destination">JMSMS</parameter>  
   <parameter name="store.jms.JMSSpecVersion">1.1</parameter>  
 </messageStore>  


Message Processor;

 <?xml version="1.0" encoding="UTF-8"?>  
 <messageProcessor xmlns="http://ws.apache.org/ns/synapse"  
          class="org.apache.synapse.message.processors.forward.ScheduledMessageForwardingProcessor"  
          name="Processor1"  
          messageStore="JMSMS">  
   <parameter name="max.delivery.attempts">4</parameter>  
   <parameter name="interval">4000</parameter>  
 </messageProcessor>  



The other set of Proxy, Store, Processor, Endpoint configuration of ESB node 1;

Proxy;

 <?xml version="1.0" encoding="UTF-8"?>  
 <proxy xmlns="http://ws.apache.org/ns/synapse"  
     name="Proxy2"  
     transports="https http"  
     startOnLoad="true"  
     trace="disable">  
   <description/>  
   <target>  
    <inSequence>  
      <property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>  
      <property name="OUT_ONLY" value="true"/>  
      <property name="target.endpoint" value="logndrop"/>  
      <store messageStore="JMSMS2"/>  
    </inSequence>  
   </target>  
 </proxy>  


Endpoint; 

 <?xml version="1.0" encoding="UTF-8"?>  
 <endpoint xmlns="http://ws.apache.org/ns/synapse" name="logndrop">  
   <address uri="http://localhost:9773/as/services/LognDrop"/>  
 </endpoint>  


Message Store; 

 <?xml version="1.0" encoding="UTF-8"?>  
 <messageStore xmlns="http://ws.apache.org/ns/synapse"  
        class="org.wso2.carbon.message.store.persistence.jms.JMSMessageStore"  
        name="JMSMS2">  
   <parameter name="java.naming.factory.initial">org.wso2.andes.jndi.PropertiesFileInitialContextFactory</parameter>  
   <parameter name="store.jms.cache.connection">false</parameter>  
   <parameter name="java.naming.provider.url">repository/conf/jndi.properties</parameter>  
   <parameter name="store.jms.JMSSpecVersion">1.1</parameter>  
   <parameter name="store.jms.destination">JMSMS2</parameter>  
 </messageStore>  


Message Processor;

 <?xml version="1.0" encoding="UTF-8"?>  
 <messageProcessor xmlns="http://ws.apache.org/ns/synapse"  
          class="org.apache.synapse.message.processors.forward.ScheduledMessageForwardingProcessor"  
          name="Processor2"  
          messageStore="JMSMS2">  
   <parameter name="max.delivery.attempts">4</parameter>  
   <parameter name="interval">4000</parameter>  
 </messageProcessor>  


This configuration needs to be synced with one other esb node in a esb cluster. The requests needs to be load balanced to each proxies by the client. And each of these messages will be load balanced to each ESB node in the cluster by the ELB. In my implementation I haven't used a ELB so that I had to load balance the requests to each esb nodes too by the client. Also I used three Proxy services, three Message Stores and Three Message Processors which talks to the same backend. Here only two are mentioned.

The backend service is a Axis2 Service which prints the incoming message and forget it.

 public class LognDrop {  
         public void logndrop(String value) {  
             System.out.println("Value is:" + value);  
         }  
 }   


Service can be found at;

https://svn.wso2.org/repos/wso2/trunk/commons/qa/qa-artifacts/app-server/LognDrop.aar

An Apache Jmeter project is the client which sends a string value to the proxy services. So that finally we can see how the requests are processed.
The Jmeter script can be found at;
https://svn.wso2.org/repos/wso2/trunk/commons/qa/qa-artifacts/app-server/jmeter-tests/InvokeLognDrop.jmx



Results;
  
 You can enable DEBUG logs for ESB JMS Message Processors by putting the following entry in {ESB_HOME}/repository/conf/log4j.properties

 #JMS Message Processor log  
 log4j.logger.org.wso2.carbon.jmsms.MSMPLog=DEBUG  


 so that you can see the execution in the ESB side as following;

 [2013-07-10 12:39:42,416] DEBUG - MSMPLog [JMSMS] Storing[1] MessageID:urn:uuid:d3e97693-9b07-46e4-a7c9-4b108965a188  
 [2013-07-10 12:39:42,439] DEBUG - MSMPLog [JMSMS] Storing[2] MessageID:urn:uuid:e9e391cb-3778-4e9e-8490-99d68dea4a9d  
 [2013-07-10 12:39:42,492] DEBUG - MSMPLog [JMSMS2] Storing[1] MessageID:urn:uuid:d0b76a30-9107-4db9-b159-8b70b707d29b  
 [2013-07-10 12:39:42,510] DEBUG - MSMPLog [JMSMS2] Storing[2] MessageID:urn:uuid:7c4579bf-cdb5-4173-a961-36c7cbeb2299  
 [2013-07-10 12:39:42,567] DEBUG - MSMPLog [JMSMS3] Storing[1] MessageID:urn:uuid:289e4073-1199-4805-9c32-46d689902059  
 [2013-07-10 12:39:42,584] DEBUG - MSMPLog [JMSMS3] Storing[2] MessageID:urn:uuid:f942d2c1-14b1-4867-8727-f745af147a6b  
 [2013-07-10 12:39:42,590] DEBUG - MSMPLog [JMSMS] Storing[3] MessageID:urn:uuid:32aa8ac0-470c-4293-8d36-1682df482a2a  
 [2013-07-10 12:39:42,658] DEBUG - MSMPLog [JMSMS] Storing[4] MessageID:urn:uuid:962808ff-19bf-4d86-a4b1-2e7e0b4363ec  
 [2013-07-10 12:39:42,672] DEBUG - MSMPLog [JMSMS2] Storing[3] MessageID:urn:uuid:62b3cfe6-f947-49e2-a43f-a39d09970147  
 [2013-07-10 12:39:42,716] DEBUG - MSMPLog [JMSMS2] Storing[4] MessageID:urn:uuid:d463555f-6955-450a-9b84-d2d2a6749712  
 [2013-07-10 12:39:42,731] DEBUG - MSMPLog [JMSMS3] Storing[3] MessageID:urn:uuid:56221673-e159-4604-8baf-31193fb0536e  
 [2013-07-10 12:39:42,747] DEBUG - MSMPLog [JMSMS] Storing[5] MessageID:urn:uuid:76ad4a31-91f4-4372-a851-2189723c485c  
 [2013-07-10 12:39:42,783] DEBUG - MSMPLog [JMSMS3] Storing[4] MessageID:urn:uuid:087fba00-7d6f-4138-8fa8-06c1549b508a  
 [2013-07-10 12:39:42,845] DEBUG - MSMPLog [JMSMS] Storing[6] MessageID:urn:uuid:5ba9bdba-9ada-48ae-ac33-41bcd22d4b73  
 [2013-07-10 12:39:42,848] DEBUG - MSMPLog [JMSMS2] Storing[5] MessageID:urn:uuid:7af16cc1-ee29-4f16-addc-0d9ae4b51f9b  
 [2013-07-10 12:39:42,921] DEBUG - MSMPLog [JMSMS2] Storing[6] MessageID:urn:uuid:3d802cb7-a029-4a59-b8b3-4c1b1074d4ab  
 [2013-07-10 12:39:42,971] DEBUG - MSMPLog [JMSMS] Storing[7] MessageID:urn:uuid:0dbd1ff5-071f-4d4e-b9df-ede65146cd20  
 [2013-07-10 12:39:42,999] DEBUG - MSMPLog [JMSMS3] Storing[5] MessageID:urn:uuid:19f02a23-6149-4c82-be32-9ec69986a45e  
 [2013-07-10 12:39:43,058] DEBUG - MSMPLog [JMSMS] Storing[8] MessageID:urn:uuid:3307251f-31cb-4690-bb23-224c4fd8d480  
 [2013-07-10 12:39:43,075] DEBUG - MSMPLog [JMSMS3] Storing[6] MessageID:urn:uuid:ba76517e-f4f2-4a5d-81eb-ed6c4f260783  
 [2013-07-10 12:39:43,078] DEBUG - MSMPLog [JMSMS2] Storing[7] MessageID:urn:uuid:3c5aa2fb-ad8c-4f9e-8c4d-222a21d2892f  
 [2013-07-10 12:39:43,150] DEBUG - MSMPLog [JMSMS] Storing[9] MessageID:urn:uuid:a08658be-a5b4-4cc4-a485-b53b86a2d871  
 [2013-07-10 12:39:43,161] DEBUG - MSMPLog [JMSMS3] Storing[7] MessageID:urn:uuid:3a487564-41ff-464a-bca7-6bc83030f03b  
 [2013-07-10 12:39:43,170] DEBUG - MSMPLog [JMSMS2] Storing[8] MessageID:urn:uuid:773b675f-f96f-48b1-a1f9-be31b102a933  
 [2013-07-10 12:39:43,177] DEBUG - MSMPLog [Processor2] Fetched[1] MessageID:urn:uuid:d0b76a30-9107-4db9-b159-8b70b707d29b  
 [2013-07-10 12:39:43,199] DEBUG - MSMPLog [Processor2] Fetched[2] MessageID:urn:uuid:3c121aab-ca24-45ba-a3bb-c727ecfda28a  
 [2013-07-10 12:39:43,227] DEBUG - MSMPLog [JMSMS2] Storing[7] MessageID:urn:uuid:82f95665-c758-4c8e-ae8d-a0db3c389a32  
 [2013-07-10 12:39:43,236] DEBUG - MSMPLog [Processor2] Fetched[3] MessageID:urn:uuid:62b3cfe6-f947-49e2-a43f-a39d09970147  
 [2013-07-10 12:39:43,246] DEBUG - MSMPLog [JMSMS] Storing[10] MessageID:urn:uuid:be8c177b-2483-4db4-8a39-fcf6f6b4793e  
 [2013-07-10 12:39:43,255] DEBUG - MSMPLog [Processor2] Fetched[4] MessageID:urn:uuid:d463555f-6955-450a-9b84-d2d2a6749712  
 [2013-07-10 12:39:43,303] DEBUG - MSMPLog [JMSMS3] Storing[8] MessageID:urn:uuid:91fef3e9-1146-4903-a790-02fee3685f26  
 [2013-07-10 12:39:43,337] DEBUG - MSMPLog [JMSMS2] Storing[6] MessageID:urn:uuid:2b4a76a8-2c6d-4e99-9da7-be5cf207aee1  
 [2013-07-10 12:39:43,348] DEBUG - MSMPLog [JMSMS3] Storing[9] MessageID:urn:uuid:cc754b66-11bf-40f0-b9d8-7ec72ac7397a  
 [2013-07-10 12:39:43,379] DEBUG - MSMPLog [JMSMS3] Storing[10] MessageID:urn:uuid:06bf808e-f35f-4724-ad34-d723d39b7131  
 [2013-07-10 12:39:43,412] DEBUG - MSMPLog [Processor2] Fetched[5] MessageID:urn:uuid:7af16cc1-ee29-4f16-addc-0d9ae4b51f9b  
 [2013-07-10 12:39:43,436] DEBUG - MSMPLog [Processor2] Fetched[6] MessageID:urn:uuid:3d802cb7-a029-4a59-b8b3-4c1b1074d4ab  
 [2013-07-10 12:39:43,455] DEBUG - MSMPLog [Processor2] Fetched[7] MessageID:urn:uuid:3c5aa2fb-ad8c-4f9e-8c4d-222a21d2892f  
 [2013-07-10 12:39:43,835] DEBUG - MSMPLog [Processor1] Fetched[1] MessageID:urn:uuid:1f50e3f1-46aa-470c-bf77-feea4088f32b  
 [2013-07-10 12:39:43,852] DEBUG - MSMPLog [Processor1] Fetched[2] MessageID:urn:uuid:32aa8ac0-470c-4293-8d36-1682df482a2a  
 [2013-07-10 12:39:43,867] DEBUG - MSMPLog [Processor1] Fetched[3] MessageID:urn:uuid:8bb300cb-faa9-45b4-bbd9-1d1e83f5aea7  
 [2013-07-10 12:39:43,878] DEBUG - MSMPLog [Processor1] Fetched[4] MessageID:urn:uuid:2103ba47-77e8-4518-8050-e18b81be62dd  
 [2013-07-10 12:39:43,890] DEBUG - MSMPLog [Processor3] Fetched[1] MessageID:urn:uuid:289e4073-1199-4805-9c32-46d689902059  
 [2013-07-10 12:39:43,893] DEBUG - MSMPLog [Processor1] Fetched[5] MessageID:urn:uuid:ee2b3c05-8a68-40ef-a2f1-be8c12a2a788  
 [2013-07-10 12:39:43,916] DEBUG - MSMPLog [Processor2] Fetched[8] MessageID:urn:uuid:773b675f-f96f-48b1-a1f9-be31b102a933  
 [2013-07-10 12:39:43,938] DEBUG - MSMPLog [Processor3] Fetched[2] MessageID:urn:uuid:b6fdf8eb-24eb-4ff4-8d49-5b58ae4fd38a  
 [2013-07-10 12:39:43,943] DEBUG - MSMPLog [Processor2] Fetched[9] MessageID:urn:uuid:82f95665-c758-4c8e-ae8d-a0db3c389a32  
 [2013-07-10 12:39:43,947] DEBUG - MSMPLog [Processor1] Fetched[6] MessageID:urn:uuid:e24eb516-c99c-4051-af0c-6120e9c9cd01  
 [2013-07-10 12:39:43,960] DEBUG - MSMPLog [Processor3] Fetched[3] MessageID:urn:uuid:56221673-e159-4604-8baf-31193fb0536e  
 [2013-07-10 12:39:43,961] DEBUG - MSMPLog [Processor2] Fetched[10] MessageID:urn:uuid:2b4a76a8-2c6d-4e99-9da7-be5cf207aee1  
 [2013-07-10 12:39:43,967] DEBUG - MSMPLog [Processor1] Fetched[7] MessageID:urn:uuid:909f69a0-44d9-462c-a8f8-1065fe81232d  
 [2013-07-10 12:39:43,974] DEBUG - MSMPLog [Processor3] Fetched[4] MessageID:urn:uuid:087fba00-7d6f-4138-8fa8-06c1549b508a  
 [2013-07-10 12:39:43,979] DEBUG - MSMPLog [Processor1] Fetched[8] MessageID:urn:uuid:54b99480-9976-436f-8aa2-f80d70602433  
 [2013-07-10 12:39:43,985] DEBUG - MSMPLog [Processor3] Fetched[5] MessageID:urn:uuid:19f02a23-6149-4c82-be32-9ec69986a45e  
 [2013-07-10 12:39:43,995] DEBUG - MSMPLog [Processor3] Fetched[6] MessageID:urn:uuid:ba76517e-f4f2-4a5d-81eb-ed6c4f260783  
 [2013-07-10 12:39:44,006] DEBUG - MSMPLog [Processor3] Fetched[7] MessageID:urn:uuid:3a487564-41ff-464a-bca7-6bc83030f03b  
 [2013-07-10 12:39:44,016] DEBUG - MSMPLog [Processor3] Fetched[8] MessageID:urn:uuid:91fef3e9-1146-4903-a790-02fee3685f26  
 [2013-07-10 12:39:44,031] DEBUG - MSMPLog [Processor3] Fetched[9] MessageID:urn:uuid:cc754b66-11bf-40f0-b9d8-7ec72ac7397a  
 [2013-07-10 12:39:44,045] DEBUG - MSMPLog [Processor3] Fetched[10] MessageID:urn:uuid:06bf808e-f35f-4724-ad34-d723d39b7131  
 [2013-07-10 12:40:38,572] DEBUG - MSMPLog [Processor1] Fetched[9] MessageID:urn:uuid:962808ff-19bf-4d86-a4b1-2e7e0b4363ec  
 [2013-07-10 12:40:38,587] DEBUG - MSMPLog [Processor1] Fetched[10] MessageID:urn:uuid:76ad4a31-91f4-4372-a851-2189723c485c  


 This log is same in the other ESB node as well. But since both of the ESBs servce one backend service the log there will be like this;

 Value is:2  
 Value is:2  
 Value is:2  
 Value is:1  
 Value is:3  
 Value is:2  
 Value is:1  
 Value is:4  
 Value is:3  
 Value is:1  
 Value is:1  
 Value is:3  
 Value is:4  
 Value is:5  
 Value is:3  
 Value is:5  
 Value is:6  
 Value is:4  
 Value is:6  
 Value is:6  
 Value is:5  
 Value is:7  
 Value is:7  
 Value is:7  
 Value is:6  
 Value is:8  
 Value is:1  
 Value is:3  
 Value is:5  
 Value is:6  
 Value is:2  
 Value is:7  
 Value is:7  
 Value is:8  
 Value is:9  
 Value is:8  
 Value is:9  
 Value is:10  
 Value is:2  
 Value is:10  
 Value is:8  
 Value is:9  
 Value is:8  
 Value is:9  
 Value is:3  
 Value is:10  
 Value is:9  
 Value is:10  
 Value is:4  
 Value is:10  
 Value is:5  
 Value is:6  
 Value is:7  
 Value is:8  
 Value is:9  
 Value is:10  
 Value is:1  
 Value is:4  
 Value is:4  
 Value is:5