Friday, July 12, 2013

Create Artifacts for WSO2 App Factory using WSO2 Developer Studio


After a couple of iterations, now the  WSO2 App Factory is released. You can experience the live version of WSO2 App Factory from here.
The Developer Studio too is compatible with creating artifacts and deploying them into App Factory.

The blog below shows how to work on App Factory seamlessly with Developer Studio.



  1. Download and install Eclipse Juno distribution - eclipse-jee-juno-SR2-linux-gtk-x86_64.tar.gz
  2. Download latest Dev Studio distribution from http://wso2.com/more-downloads/developer-studio/
  3. Start Eclipse and install the above Dev Studio distribution. This contains the latest App Factory tooling support as well.
  4. Go to Windows --> Open Perspective --> App Factory


  1. Once click on App Factory, this will prompt a window to enter the Host, Username and Password to connect to App Factory.

  1. Once provided the above, it opens up the App Factory views as below.
  1. In the Application List view, go to an app, Select an app --> version --> checkout --> Add to workspace
The particular App version will be appeared in the Project Explorer.

  1. Right click on app in project explorer --> Team --> Share Project --> in the wizard, select Git
Select the project and click Finish.

  1. Change a file in the application. The changes will be shown as below. (with a “>”)

  1. Right click changed file --> Team -->Commit.
Add a commit message --> Commit 
Right click the file --> Team --> Push to Upstream

Tuesday, May 7, 2013

I/O exception (org.apache.http.NoHttpResponseException) caught when processing request: The target server failed to respond

I was continuously getting this error when trying to try out this code.


May 6, 2013 5:53:51 PM org.apache.http.impl.client.DefaultRequestDirector execute
INFO: I/O exception (org.apache.http.NoHttpResponseException) caught when processing request: The target server failed to respond
May 6, 2013 5:53:51 PM org.apache.http.impl.client.DefaultRequestDirector execute
INFO: Retrying request
May 6, 2013 5:54:53 PM org.apache.http.impl.client.DefaultRequestDirector execute
INFO: I/O exception (org.apache.http.NoHttpResponseException) caught when processing request: The target server failed to respond
May 6, 2013 5:54:53 PM org.apache.http.impl.client.DefaultRequestDirector execute
INFO: Retrying request
May 6, 2013 5:55:54 PM org.apache.http.impl.client.DefaultRequestDirector execute
INFO: I/O exception (org.apache.http.NoHttpResponseException) caught when processing request: The target server failed to respond
May 6, 2013 5:55:54 PM org.apache.http.impl.client.DefaultRequestDirector execute
INFO: Retrying request
Exception in thread "main" org.apache.http.NoHttpResponseException: The target server failed to respond
at org.apache.http.impl.conn.DefaultResponseParser.parseHead(DefaultResponseParser.java:101)
at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:252)
at org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader(AbstractHttpClientConnection.java:281)
at org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader(DefaultClientConnection.java:227)
at org.apache.http.impl.conn.AbstractClientConnAdapter.receiveResponseHeader(AbstractClientConnAdapter.java:229)
at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:298)
at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:447)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:641)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:576)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:554)
at QuickStart.main(QuickStart.java:107)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:115)

Finally after wasting about 5-6 hours of my time, :( found that this was due to an old HTTPClient jar. I had earlier used the version 4.0 org.apache.httpcomponents.httpclient. 
When upgraded this to 4.1, the issue got fixed. (source from a mail archive)

Friday, February 22, 2013

Extract a value of an XML type attribute using WSO2 ESB

Let's say you have an XML input with some elements as below.

<SOAP-ENV:Body>
        <Publish>
            <Notification
                message="&lt;RegistraionNotificationEvent NotificationType=&quot;Place&quot;>&lt;DeviceLocPlace
                timestamp=&quot;1361210060855&quot; accuracy=&quot;344.0&quot;
                macAddress=&quot;7b:29:a8:8b:e4:f8&quot; lastSeen=&quot;7&quot;
                sourceTimestamp=&quot;1361209904211&quot; x=&quot;171.34&quot; y=&quot;104.513&quot;/>&lt;/RegistraionNotificationEvent>" />
        </Publish>
    </SOAP-ENV:Body>

 You need to extract out the macAddress which is inside the message attribute. How can we do that?


If you closely look at this input, you would see, the macAddress stays inside the value of the attribute "message". But this message attribute carries another XML element which comes as a String. 

Now what? 

This is where WSO2 ESB Script mediator comes into rescue.
With just the following piece of configuration, you can extract out the  Mac Address.

<script language="js">
      <![CDATA[mc.setPayloadXML(new XML(mc.getPayloadXML()..*::Notification.@message.toXMLString()));]]></script>

The above segment converts the value of the attribute message into XML.

<property xmlns:ns="http://org.apache.synapse/xsd" name="mac" expression="//@macAddress" scope="default" type="STRING"/>

Using this segment, from the XML obtained above, you can extract out the macAddress part easily.

As handy as that...

Tuesday, February 5, 2013

Write Data to Cassandra with UTF-8 (String) validators

Cluster cassandraCluster = HFactory.createCluster("TestCluster",
                new CassandraHostConfigurator("localhost:9161"), credentials);
        Keyspace keyspace = HFactory.createKeyspace(keyspaceName, cassandraCluster);
       
        BasicColumnFamilyDefinition columnFamilyDefinition = new BasicColumnFamilyDefinition();
        columnFamilyDefinition.setKeyspaceName(keyspaceName);
        columnFamilyDefinition.setName(columnFamily);   
      columnFamilyDefinition.setComparatorType(ComparatorType.UTF8TYPE); 
 columnFamilyDefinition.setDefaultValidationClass(ComparatorType.UTF8TYPE.getClassName());
columnFamilyDefinition.setKeyValidationClass(ComparatorType.UTF8TYPE.getClassName());
       
        ColumnFamilyDefinition cfDef = new ThriftCfDef(columnFamilyDefinition);
       
        KeyspaceDefinition keyspaceDefinition =
            HFactory.createKeyspaceDefinition(keyspaceName, "org.apache.cassandra.locator.SimpleStrategy", 1, Arrays.asList(cfDef));
        cassandraCluster.addKeyspace(keyspaceDefinition);
       
       
        KeyspaceDefinition fromCluster = cassandraCluster.describeKeyspace(keyspaceName);
        cfDef = fromCluster.getCfDefs().get(0);
       
        columnFamilyDefinition = new BasicColumnFamilyDefinition(cfDef);
       
        BasicColumnDefinition columnDefinition = new BasicColumnDefinition();
       
        columnDefinition.setName(StringSerializer.get().toByteBuffer("lat"));
        columnDefinition.setIndexType(ColumnIndexType.KEYS);
        columnDefinition.setIndexName("lat");

columnDefinition.setValidationClass(ComparatorType.UTF8TYPE.getClassName());
        columnFamilyDefinition.addColumnDefinition(columnDefinition);
       
        columnDefinition = new BasicColumnDefinition();
        columnDefinition.setName(StringSerializer.get().toByteBuffer("lon"));   
        columnDefinition.setIndexType(ColumnIndexType.KEYS);
        columnDefinition.setIndexName("lon");

 columnDefinition.setValidationClass(ComparatorType.UTF8TYPE.getClassName());
        columnFamilyDefinition.addColumnDefinition(columnDefinition);
       
        columnDefinition = new BasicColumnDefinition();
        columnDefinition.setName(StringSerializer.get().toByteBuffer("timestamp"));   
  columnDefinition.setIndexType(ColumnIndexType.KEYS);
        columnDefinition.setIndexName("timestamp");
       columnDefinition.setValidationClass(ComparatorType.UTF8TYPE.getClassName());

        columnFamilyDefinition.addColumnDefinition(columnDefinition);
       
        cassandraCluster.updateColumnFamily(new ThriftCfDef(columnFamilyDefinition));
       
        for (int i = 90; i < 100; i++) {
            Mutator<String> mutator = HFactory.createMutator(keyspace, sser);
            String dID = Integer.toString(i);
            mutator.insert(dID, columnFamily, HFactory.createStringColumn("lat", lat));
            mutator.insert(dID, columnFamily, HFactory.createStringColumn("lon", lon));
            mutator.insert(dID, columnFamily,
                    HFactory.createStringColumn("timestamp", timestamp));
            mutator.execute();
        }



 You can check whether the created CFs are in proper and according to the required validation methods, by using a Cassandra-CLI tool. How to use this tool?
Refer my previous blog post       

A Smart and Quick Cassandra Client

Recently I wanted to get the internal details of a created Column Family. Here how I did that. 
  • Download the latest Cassandra server from here.
  • Extract to a preferred location. This will be known as CASS_HOME
  • Start up the Cassandra Server. For my task, I was using the built-in cassandra support that comes with WSO2 CEP. (The Cassandra server was running in localhost:9161)
  • Navigate to CASS_HOME/bin. From there execute the command below.
 sh cassandra-cli -h localhost -p 9161 -u admin -pw admin
  • The above command will take you to the Cassandra CLI console. Type the command below to get the key spaces:
show keyspaces;
  • That would show up fine details like validation class and comparator type etc. as follows:
Keyspace: LocationKeySpaceTestDemo_25:
  Replication Strategy: org.apache.cassandra.locator.SimpleStrategy
  Durable Writes: true
    Options: [replication_factor:1]
  Column Families:
    ColumnFamily: LocationDataTestDemo_25
      Key Validation Class: org.apache.cassandra.db.marshal.UTF8Type
      Default column value validator: org.apache.cassandra.db.marshal.UTF8Type
      Columns sorted by: org.apache.cassandra.db.marshal.UTF8Type
      GC grace seconds: 0
      Compaction min/max thresholds: 4/32
      Read repair chance: 0.0
      DC Local Read repair chance: 0.0
      Replicate on write: false
      Caching: KEYS_ONLY
      Bloom Filter FP chance: default
      Column Metadata:
        Column Name: lon
          Validation Class: org.apache.cassandra.db.marshal.UTF8Type
        Column Name: lat
          Validation Class: org.apache.cassandra.db.marshal.UTF8Type
        Column Name: timestamp
          Validation Class: org.apache.cassandra.db.marshal.UTF8Type
      Compaction Strategy: org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy
      Compression Options:
        sstable_compression: org.apache.cassandra.io.compress.SnappyCompressor
WARNING: Could not connect to the JMX on localhost:7199, information won't be shown.

Thursday, December 20, 2012

Creating a custom User Store with WSO2 IS 4.0.0


Introduction

Generally, we can  configure an external LDAP with a WSO2 IS using <UserStoreManager> tag , and with the class attribute like this : 
<UserStoreManager class="org.wso2.carbon.user.core.ldap.LDAPUserStoreManager"> 
Apart from this, there are other default UserStoreManagers that are available with WSO2 IS, such as ActiveDirectoryUserStoreManager, JDBCUserStoreManager etc. You can find more from user-mgt.xml inside a WSO2 IS distribution's repository/conf directory

Similarly there we can define custom user stores as well.

Use Case

In the sample, CustomUserStoreManager reads a user credentials from an xml file (user.xml) and authenticates the user. This can be taken analogous to a CustomUserStoreManager that connects to a custom user store and authenticates users against the credentials stored there. The same CustomUserStoreManager has been extended to provide the functionality required by the STS configuration and issuing a SAML token with requested claim values.

 

Configurations

0.  Download WSO2 IS 4.0.0 and extract it to a preferred location. We will refer to that as [IS_HOME]

1. Download the sample from here and extract.

2. Place the jar file in the sample: org.wso2.carbon.userstoremanager.sample-1.0.jar in [IS_HOME]/repository/components/lib.
    eg: /home/manisha/WSO2/wso2is-4.0.0/repository/components/lib
3. Replace the user-mgt.xml in [IS_HOME]/repository/conf with the user-mgt.xml comes with this.
 
4. Make the enable EmbeddedLDAP propety "false" in embedded-ldap.xml file in [IS_HOME]/repository/components/conf.
    <EmbeddedLDAP>
            <Property name="enable">false</Property>
        ...................

5. Comment out the default CommonHybridLDAPTenantManager in tenant-mgt.xml in [IS_HOME]/repository/components/conf.

6. Uncomment the JDBCTenantManager property in tenant-mgt.xml

7. Delete the database folder in [IS_HOME]/repository if you are not using a newly extracted IS distribution.

8. Start the server with the command 'sh wso2server.sh -Dsetup' if you followed the step 3.
   Or else, if you are using a newly extracted IS distribution, start the server with 'sh.wso2server.sh' as usual.
   (Start up file changes according to the OS you are in, above commands listed for Linux environment.)

9. Login to the management console with the credentials mentioned in the user.xml that comes with this.

10. Configure the STS to use that with the related STS client.

11. Run STS client to obtain the SAML token.



PS: Courtesy goes to Hasini Gunasinghe

Wednesday, December 5, 2012

Getting NoSuchAlgorithmException when running Secure clients with WSO2 products?


Scenario: 

Secured client   _____\    Secured Proxy  ______\   Unsecured Svc
   (external)                /         (ESB)                    /        (AS)

Apply security policy 5(Sign and Encrypt) on both the client and ESB proxy. 

Problem:

You may encounter the error below. 
org.apache.axis2.AxisFault: Error in encryption
at org.apache.rampart.handler.RampartSender.invoke(RampartSender.java:117)
at org.apache.axis2.engine.Phase.invokeHandler(Phase.java:340)
at org.apache.axis2.engine.Phase.invoke(Phase.java:313)
at org.apache.axis2.engine.AxisEngine.invoke(AxisEngine.java:262)
at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:427)
at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:406)
at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:229)
at org.apache.axis2.client.OperationClient.execute(OperationClient.java:165)
at org.apache.axis2.client.ServiceClient.sendReceive(ServiceClient.java:555)
at org.apache.axis2.client.ServiceClient.sendReceive(ServiceClient.java:531)
at SecurityClient.runSecurityClient(SecurityClient.java:103)
at SecurityClient.main(SecurityClient.java:41)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:115)
Caused by: org.apache.rampart.RampartException: Error in encryption
at org.apache.rampart.builder.AsymmetricBindingBuilder.doSignBeforeEncrypt(AsymmetricBindingBuilder.java:568)
at org.apache.rampart.builder.AsymmetricBindingBuilder.build(AsymmetricBindingBuilder.java:90)
at org.apache.rampart.MessageBuilder.build(MessageBuilder.java:147)
at org.apache.rampart.handler.RampartSender.invoke(RampartSender.java:106)
... 16 more
Caused by: org.apache.ws.security.WSSecurityException: An unsupported signature or encryption algorithm was used (unsupported key transport encryption algorithm: No such algorithm: http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p); nested exception is: 
java.security.NoSuchAlgorithmException: Cannot find any provider supporting RSA/ECB/OAEPPadding
at org.apache.ws.security.util.WSSecurityUtil.getCipherInstance(WSSecurityUtil.java:785)
at org.apache.ws.security.message.WSSecEncryptedKey.prepareInternal(WSSecEncryptedKey.java:205)
at org.apache.ws.security.message.WSSecEncrypt.prepare(WSSecEncrypt.java:259)
at org.apache.rampart.builder.AsymmetricBindingBuilder.doSignBeforeEncrypt(AsymmetricBindingBuilder.java:534)
... 19 more
Caused by: java.security.NoSuchAlgorithmException: Cannot find any provider supporting RSA/ECB/OAEPPadding
at javax.crypto.Cipher.getInstance(DashoA13*..)
at org.apache.ws.security.util.WSSecurityUtil.getCipherInstance(WSSecurityUtil.java:777)
... 22 more

Solution:
Import the bcprov-jdk15.jar jar which can be found in wso2esb-4.5.0/repository/axis2/client/lib to the class path of the secured client's project.