Thursday, April 7, 2016

In this post I'm going to create a proxy service using WSO2 ESB to Pull a message from ActiveMQ and to push that Message to IBM MQ (WebSphere MQ). If you need to configure IBM MQ you can follow this Post. And to configure ESB with ActiveMQ you can follow this post.

After configuring ActiveMQ and IBM MQ you need to add the following transports. (If you have already added this do not add).

The issue here is, for both ActiveMQ and IBMMQ you need two different transport configurations. So you can achieve this by referring the following axis2 configurations.

Transport Receivers


<!-- This is for IBM MQ -->
<transportReceiver name="jmsin" class="org.apache.axis2.transport.jms.JMSListener">
  <parameter name="default" locked="false">
    <parameter name="java.naming.factory.initial" locked="false">com.sun.jndi.fscontext.RefFSContextFactory</parameter>
    <parameter name="java.naming.provider.url" locked="false">file:/C:/jndi-dir</parameter>
    <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">MyQueueConnectionFactory</parameter>
    <parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
    <parameter name="transport.jms.UserName" locked="false">admin</parameter>
    <parameter name="transport.jms.Password" locked="false">admin</parameter>
  </parameter>

  <parameter name="myQueueConnectionFactory1" locked="false">
    <parameter name="java.naming.factory.initial" locked="false">com.sun.jndi.fscontext.RefFSContextFactory</parameter>
    <parameter name="java.naming.provider.url" locked="false">file:/C:/jndi-dir</parameter>
    <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">MyQueueConnectionFactory</parameter>
    <parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
    <parameter name="transport.jms.UserName" locked="false">admin</parameter>
    <parameter name="transport.jms.Password" locked="false">admin</parameter>
  </parameter>
</transportReceiver>

<!-- This is for ActiveMQ -->

<transportReceiver name="jmsamq" class="org.apache.axis2.transport.jms.JMSListener">
       <parameter name="myTopicConnectionFactory" locked="false">
           <parameter name="java.naming.factory.initial" locked="false">org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter>
           <parameter name="java.naming.provider.url" locked="false">tcp://localhost:61616</parameter>
           <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">TopicConnectionFactory</parameter>
            <parameter name="transport.jms.ConnectionFactoryType" locked="false">topic</parameter>
       </parameter>
  
       <parameter name="myQueueConnectionFactory" locked="false">
           <parameter name="java.naming.factory.initial" locked="false">org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter>
           <parameter name="java.naming.provider.url" locked="false">tcp://localhost:61616</parameter>
           <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">QueueConnectionFactory</parameter>
            <parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
       </parameter>
  
       <parameter name="default" locked="false">
           <parameter name="java.naming.factory.initial" locked="false">org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter>
           <parameter name="java.naming.provider.url" locked="false">tcp://localhost:61616</parameter>
           <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">QueueConnectionFactory</parameter>
            <parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
       </parameter>
   </transportReceiver>



Transport Senders


<!-- For IBM MQ -->
<transportSender name="jms" class="org.apache.axis2.transport.jms.JMSSender">
  <parameter name="default" locked="false">
    <parameter name="java.naming.factory.initial" locked="false">com.sun.jndi.fscontext.RefFSContextFactory</parameter>
    <parameter name="java.naming.provider.url" locked="false">file:/C:/jndi-dir</parameter>
    <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">MyQueueConnectionFactory</parameter>
    <parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
    <parameter name="transport.jms.UserName" locked="false">admin</parameter>
    <parameter name="transport.jms.Password" locked="false">admin</parameter>
  </parameter>

  <parameter name="myQueueConnectionFactory1" locked="false">
    <parameter name="java.naming.factory.initial" locked="false">com.sun.jndi.fscontext.RefFSContextFactory</parameter>
    <parameter name="java.naming.provider.url" locked="false">file:/C:/jndi-dir</parameter>
    <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">MyQueueConnectionFactory</parameter>
    <parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
    <parameter name="transport.jms.UserName" locked="false">admin</parameter>
    <parameter name="transport.jms.Password" locked="false">admin</parameter>
  </parameter>
</transportSender>


Now when you are creating a proxy the transports you defined will be listed under the transport section.

Now create the following proxy service

<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="LocalQueue1"
       transports="jmsamq"
       statistics="disable"
       trace="disable"
       startOnLoad="true">
   <target>
      <inSequence>
         <property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
         <property name="OUT_ONLY" value="true" scope="default" type="STRING"/>
         <property name="JMS_COORELATION_ID"
                   value="12345"
                   scope="axis2"
                   type="STRING"/>
         <property name="JMS_DESTINATION" scope="transport" action="remove"/>
         <property name="JMS_REDELIVERED" scope="transport" action="remove"/>
         <property name="JMS_TYPE" scope="transport" action="remove"/>
         <property name="Accept-Encoding" scope="transport" action="remove"/>
         <property name="Content-Length" scope="transport" action="remove"/>
         <property name="Content-Type" scope="transport" action="remove"/>
         <property name="User-Agent" scope="transport" action="remove"/>
         <property name="Transfer-Encoding" scope="transport" action="remove"/>
         <property name="X-Forwarded-For" scope="transport" action="remove"/>
         <property name="X-Forwarded-Host" scope="transport" action="remove"/>
         <property name="X-Forwarded-Server" scope="transport" action="remove"/>
         <log level="full"/>
      </inSequence>
      <endpoint>
         <address uri="jms:/LocalQueue1?transport.jms.ConnectionFactoryJNDIName=MyQueueConnectionFactory&amp;java.naming.factory.initial=com.sun.jndi.fscontext.RefFSContextFactory&amp;java.naming.provider.url=file:/C:/jndi-dir/&amp;transport.jms.DestinationType=queue&amp;"/>
      </endpoint>
   </target>
   <description/>
</proxy>

                             
In the above proxy I have enabled jmsamq transport so it will Poll the queue specified for ActiveMQ and push the message to endpoint which is a queue in IBM MQ.

Also note all the header properties I have set and removed, In IBMMQ some header properties that are sent with the message may not be supported. You can refer this to get a better understanding of supported properties. So we need to specifically remove any unsupported headers if any. Or else you will come across the following error.


[2015-12-28 14:41:58,817] INFO - ProxyServiceDeployer ProxyService named 'EsbMQMtmOutbound' has been update from file :
C:\apps\wso2\wso2esb-4.8.1\repository\deployment\server\synapse-configs\default\proxy-services\EsbMQMtmOutbound.xml
[2015-12-28 14:42:26,233] ERROR - JMSSender Error creating a JMS message from the message context
com.ibm.msg.client.jms.DetailedMessageFormatException: JMSCC0049: The property name 'Content-Type' is not a valid Java(t
m) identifier.
The supplied property name does not conform to the allowed format described in the JMS specification.
Check the characters used in the property name and modify as necessary.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at com.ibm.msg.client.commonservices.j2se.NLSServices.createException(NLSServices.java:319)
at com.ibm.msg.client.commonservices.nls.NLSServices.createException(NLSServices.java:233)
at com.ibm.msg.client.jms.internal.JmsErrorUtils.createException(JmsErrorUtils.java:109)
at com.ibm.msg.client.jms.internal.JmsMessageImpl.checkPropName(JmsMessageImpl.java:2033)
at com.ibm.msg.client.jms.internal.JmsMessageImpl.setStringProperty(JmsMessageImpl.java:1559)
at com.ibm.jms.JMSMessage.setStringProperty(JMSMessage.java:1496)
at org.apache.axis2.transport.jms.JMSUtils.setTransportHeaders(JMSUtils.java:316)
at org.apache.axis2.transport.jms.JMSSender.createJMSMessage(JMSSender.java:449)
at org.apache.axis2.transport.jms.JMSSender.sendOverJMS(JMSSender.java:175)
at org.apache.axis2.transport.jms.JMSSender.sendMessage(JMSSender.java:157)
at org.apache.axis2.transport.base.AbstractTransportSender.invoke(AbstractTransportSender.java:112)
at org.apache.axis2.engine.AxisEngine$TransportNonBlockingInvocationWorker.run(AxisEngine.java:626)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
[2015-12-28 14:42:26,324] INFO - AxisEngine [MessageContext: logID=3283eebc6424ae00536a3adb43db8bf0cf6e3c456624e6fc] Er
ror creating a JMS message from the message context
[2015-12-28 14:42:26,326] ERROR - AsyncCallback Error creating a JMS message from the message context
org.apache.axis2.AxisFault: Error creating a JMS message from the message context
at org.apache.axis2.transport.base.AbstractTransportSender.handleException(AbstractTransportSender.java:226)
at org.apache.axis2.transport.jms.JMSSender.sendOverJMS(JMSSender.java:177)
at org.apache.axis2.transport.jms.JMSSender.sendMessage(JMSSender.java:157)
at org.apache.axis2.transport.base.AbstractTransportSender.invoke(AbstractTransportSender.java:112)
at org.apache.axis2.engine.AxisEngine$TransportNonBlockingInvocationWorker.run(AxisEngine.java:626)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
Caused by: com.ibm.msg.client.jms.DetailedMessageFormatException: JMSCC0049: The property name 'Content-Type' is not a v
alid Java(tm) identifier.
The supplied property name does not conform to the allowed format described in the JMS specification.
Check the characters used in the property name and modify as necessary.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at com.ibm.msg.client.commonservices.j2se.NLSServices.createException(NLSServices.java:319)
at com.ibm.msg.client.commonservices.nls.NLSServices.createException(NLSServices.java:233)
at com.ibm.msg.client.jms.internal.JmsErrorUtils.createException(JmsErrorUtils.java:109)
at com.ibm.msg.client.jms.internal.JmsMessageImpl.checkPropName(JmsMessageImpl.java:2033)
at com.ibm.msg.client.jms.internal.JmsMessageImpl.setStringProperty(JmsMessageImpl.java:1559)
at com.ibm.jms.JMSMessage.setStringProperty(JMSMessage.java:1496)
at org.apache.axis2.transport.jms.JMSUtils.setTransportHeaders(JMSUtils.java:316)
at org.apache.axis2.transport.jms.JMSSender.createJMSMessage(JMSSender.java:449)
at org.apache.axis2.transport.jms.JMSSender.sendOverJMS(JMSSender.java:175)
... 6 more
[2015-12-28 14:42:26,336] WARN - AsyncCallback Executing fault handler due to exception encountered
[2015-12-28 14:42:26,339] WARN - EndpointContext Endpoint : AnonymousEndpoint will be marked SUSPENDED as it failed
[2015-12-28 14:42:26,340] WARN - EndpointContext Suspending endpoint : AnonymousEndpoint - current suspend duration is
: 30000ms - Next retry after : Mon Dec 28 14:42:56 PST 2015


Hope this will help someone interested and please drop a comment if you have any queries.


Tuesday, April 5, 2016

In this post I'll explain how we can redirect all HTTP traffic to HTTPS. Here I'm using Apache2 and its rewrite module to achieve this.

You can refer the following configuration from apache.

RewriteEngine on

RewriteCond %{HTTPS} !=on
# This checks to make sure the connection is not already HTTPS
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]

In the above configurations I'm rewriting all HTTP traffic to its HTTPS URL.

http://yenlo.com/t  ==> https://yenlo.com/t

Full Apache configs will look like following.

<VirtualHost mod_rewrite.c *:80>
        ServerName yenlo.com
        ServerAlias yenlo.com

RewriteEngine on

RewriteCond %{HTTPS} !=on
# This checks to make sure the connection is not already HTTPS
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]

</VirtualHost>

<Virtualhost *:443>
ServerName yenlo.com
ServerAlias yenlo.com
ProxyPreserveHost On
# ProxyRequests On
SSLEngine On
SSLProxyEngine On
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLCertificateFile /etc/apache2/ssl/apache.crt
SSLCertificateKeyFile /etc/apache2/ssl/apache.key

ProxyPass /t https://10.100.5.112:9443/t
ProxyPassReverse /t https://10.100.5.112:9443/t

</Virtualhost>


Thanks for reading and please drop a comment if you have any queries.

Monday, April 4, 2016


When I was trying to call a service via HTTPS I observed the below issue.

FATAL: Error verifying developer key: Failed to read server's response: handshake alert:  unrecognized_name
br.eti.kinoshita.testlinkjavaapi.util.TestLinkAPIException: Error verifying developer key: Failed to read server's response: handshake alert:  unrecognized_name
 at br.eti.kinoshita.testlinkjavaapi.MiscService.checkDevKey(MiscService.java:63)
 at br.eti.kinoshita.testlinkjavaapi.TestLinkAPI.<init>(TestLinkAPI.java:144)
 at hudson.plugins.testlink.TestLinkBuilder.getTestLinkSite(TestLinkBuilder.java:318)
 at hudson.plugins.testlink.TestLinkBuilder.perform(TestLinkBuilder.java:197)
 at hudson.tasks.BuildStepMonitor$1.perform(BuildStepMonitor.java:20)
 at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:782)
 at hudson.maven.MavenModuleSetBuild$MavenModuleSetBuildExecution.build(MavenModuleSetBuild.java:906)
 at hudson.maven.MavenModuleSetBuild$MavenModuleSetBuildExecution.doRun(MavenModuleSetBuild.java:857)
 at hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:534)
 at hudson.model.Run.execute(Run.java:1738)
 at hudson.maven.MavenModuleSetBuild.run(MavenModuleSetBuild.java:529)
 at hudson.model.ResourceController.execute(ResourceController.java:98)
 at hudson.model.Executor.run(Executor.java:410)
Caused by: org.apache.xmlrpc.XmlRpcException: Failed to read server's response: handshake alert:  unrecognized_name
 at org.apache.xmlrpc.client.XmlRpcStreamTransport.sendRequest(XmlRpcStreamTransport.java:161)
 at org.apache.xmlrpc.client.XmlRpcHttpTransport.sendRequest(XmlRpcHttpTransport.java:143)
 at org.apache.xmlrpc.client.XmlRpcSunHttpTransport.sendRequest(XmlRpcSunHttpTransport.java:69)
 at org.apache.xmlrpc.client.XmlRpcClientWorker.execute(XmlRpcClientWorker.java:56)
 at org.apache.xmlrpc.client.XmlRpcClient.execute(XmlRpcClient.java:167)
 at org.apache.xmlrpc.client.XmlRpcClient.execute(XmlRpcClient.java:158)
 at org.apache.xmlrpc.client.XmlRpcClient.execute(XmlRpcClient.java:147)
 at br.eti.kinoshita.testlinkjavaapi.BaseService.executeXmlRpcCall(BaseService.java:90)
 at br.eti.kinoshita.testlinkjavaapi.MiscService.checkDevKey(MiscService.java:60)
 ... 12 more
Caused by: javax.net.ssl.SSLProtocolException: handshake alert:  unrecognized_name
 at sun.security.ssl.ClientHandshaker.handshakeAlert(ClientHandshaker.java:1292)
 at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1952)
 at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1077)
 at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
 at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339)
 at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323)
 at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:563)
 at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
 at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1091)
 at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:250)
 at org.apache.xmlrpc.client.XmlRpcSunHttpTransport.writeRequest(XmlRpcSunHttpTransport.java:104)
 at org.apache.xmlrpc.client.XmlRpcStreamTransport.sendRequest(XmlRpcStreamTransport.java:151)
 ... 20 more
ERROR: Error communicating with TestLink. Check your TestLink configuration.
Finished: FAILURE

The reason for this issue is the server sends an unrecognized host in the time of handshake. And java client fails due to this. Most other clients will ignore this alert and proceed but from JAVA 7 this doesn't work like that.

This can happen due to misconfigurations in the servers. If you come across the above issue there are several ways to get this resolved. You can use the method 1 if you do not have accesses to the remote server.


1. By disabling SNI verification.

This is one of the workarounds you can follow, you can simply set the following JVM property at the client side.
-Djsse.enableSNIExtension=false

e.g : In the below example I have set this property to TomCat run-time. So SNI will be disabled globally. You can do this in class level as well.
export CATALINA_OPTS="-Djsse.enableSNIExtension=false"

2. By modifying Apche2 configurations. 

In Apache2 server configurations make sure you have set the following parameters

ServerName testlinkstaging.wso2.com
ServerAlias testlinkstaging.wso2.com

Full configs will look like following.
<VirtualHost testlinkstaging.wso2.com:443>
    ServerName testlinkstaging.wso2.com
    ServerAlias testlinkstaging.wso2.com
    SSLEngine on
    SSLCertificateFile  /etc/apache2/ssl/apache.crt
    SSLCertificateKeyFile /etc/apache2/ssl/apache.key

    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html/testlink

</VirtualHost>


That's it, If everything is set properly you should be able to access the SSL endpoint.

Please drop a comment if you have any queries.

Sunday, April 3, 2016

In this post I will explain how to enable SSL for jenkins testlink plugin. When you try to access testlink via SSL from Jenkins you might come across the following error.


Archiving /home/ubuntu/.jenkins/jobs/TestSample/workspace/pom.xml to org.wso2.carbon/testng-test/1.0.0/testng-test-1.0.0.pom
channel stopped
Preparing TestLink client API.
Using TestLink URL: https://192.168.48.112/lib/api/xmlrpc/v1/xmlrpc.php

FATAL: Error verifying developer key: Failed to read server's response: java.security.cert.CertificateException: No subject alternative names present
br.eti.kinoshita.testlinkjavaapi.util.TestLinkAPIException: Error verifying developer key: Failed to read server's response: java.security.cert.CertificateException: No subject alternative names present
 at br.eti.kinoshita.testlinkjavaapi.MiscService.checkDevKey(MiscService.java:63)
 at br.eti.kinoshita.testlinkjavaapi.TestLinkAPI.<init>(TestLinkAPI.java:144)
 at hudson.plugins.testlink.TestLinkBuilder.getTestLinkSite(TestLinkBuilder.java:320)
 at hudson.plugins.testlink.TestLinkBuilder.perform(TestLinkBuilder.java:199)
 at hudson.tasks.BuildStepMonitor$1.perform(BuildStepMonitor.java:20)
 at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:782)
 at hudson.maven.MavenModuleSetBuild$MavenModuleSetBuildExecution.build(MavenModuleSetBuild.java:906)
 at hudson.maven.MavenModuleSetBuild$MavenModuleSetBuildExecution.doRun(MavenModuleSetBuild.java:857)
 at hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:534)
 at hudson.model.Run.execute(Run.java:1738)
 at hudson.maven.MavenModuleSetBuild.run(MavenModuleSetBuild.java:529)
 at hudson.model.ResourceController.execute(ResourceController.java:98)
 at hudson.model.Executor.run(Executor.java:410)
Caused by: org.apache.xmlrpc.XmlRpcException: Failed to read server's response: java.security.cert.CertificateException: No subject alternative names present
 at org.apache.xmlrpc.client.XmlRpcStreamTransport.sendRequest(XmlRpcStreamTransport.java:161)
 at org.apache.xmlrpc.client.XmlRpcHttpTransport.sendRequest(XmlRpcHttpTransport.java:143)
 at org.apache.xmlrpc.client.XmlRpcSunHttpTransport.sendRequest(XmlRpcSunHttpTransport.java:69)
 at org.apache.xmlrpc.client.XmlRpcClientWorker.execute(XmlRpcClientWorker.java:56)
 at org.apache.xmlrpc.client.XmlRpcClient.execute(XmlRpcClient.java:167)
 at org.apache.xmlrpc.client.XmlRpcClient.execute(XmlRpcClient.java:158)
 at org.apache.xmlrpc.client.XmlRpcClient.execute(XmlRpcClient.java:147)
 at br.eti.kinoshita.testlinkjavaapi.BaseService.executeXmlRpcCall(BaseService.java:90)
 at br.eti.kinoshita.testlinkjavaapi.MiscService.checkDevKey(MiscService.java:60)
 ... 12 more
Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names present
 at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
 at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1884)
 at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276)
 at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:270)
 at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1341)
 at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:153)
 at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868)
 at sun.security.ssl.Handshaker.process_record(Handshaker.java:804)
 at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016)
 at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
 at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339)
 at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323)
 at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:563)
 at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
 at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1091)
 at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:250)
 at org.apache.xmlrpc.client.XmlRpcSunHttpTransport.writeRequest(XmlRpcSunHttpTransport.java:104)
 at org.apache.xmlrpc.client.XmlRpcStreamTransport.sendRequest(XmlRpcStreamTransport.java:151)
 ... 20 more
Caused by: java.security.cert.CertificateException: No subject alternative names present
 at sun.security.util.HostnameChecker.matchIP(HostnameChecker.java:142)
 at sun.security.util.HostnameChecker.match(HostnameChecker.java:91)
 at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:347)
 at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:203)
 at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:126)
 at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1323)
 ... 33 more
ERROR: Error communicating with TestLink. Check your TestLink configuration.
Finished: FAILURE


Since the test-link plugin doesn't support SSL connections directly, you have to set SSL configurations from JVM level and get it to work.

In my case Jenkins is running on Tomcat and Test link is hosted in Apache2. The SSL layer is handled by Apache it self. So first we need to create a certificate with a proper hostname for Apache to access testlink. You can follow this tutorial to create a certificate and enable SSL for Apache2.

 After creating a proper certificate. Lets configure and add this to tomcat.

Download the created .crt file. You can do this via your browser as well. Go to certificate settings page and import the certificate through the browser.

Now lets create a new keystore with the certificate. Execute the following commands for this.

1. Login to the server where you have hosted jenkins.

2. Create a directory called ssl with the following command.


mkdir /home/ubuntu/jenkins/ssl

3. Now navigate to the created directory.

cd /home/ubuntu/jenkins/ssl

4. Copy the downloaded .crt to the above directory and execute the following command. This will create new trust store with the specified certificate.

keytool -importcert -keystore jssecacerts -trustcacerts -alias wso2qa -file apache.crt
Note : Make sure to give information that's relevant to your setup. e.g : file name, alias etc.

5. Now we need to tell tomcat where to look for the keystore. So execute the following command.


export CATALINA_OPTS="-Djavax.net.ssl.keyStoreType=jks -Djavax.net.ssl.keyStore=/home/ubuntu/jenkins/ssl/jssecacerts -Djavax.net.ssl.keyStorePassword=wso2qa123 -Djavax.net.ssl.trustStore=/home/ubuntu/jenkins/ssl/jssecacerts -Djavax.net.ssl.trustStorePassword=wso2qa123 -Djsse.enableSNIExtension=false"
CATALINA_OPTS is what tomcat refers when its started.

Note : Make sure you give the correct information in the above command (File paths/ password etc.). Also you can add the above line to bashrc or environments so it gets set on server startup.

Now restart tomcat. If everything is set properly you should be able to communicate with testlink via the https endpoint.

Note : Also if you get the above error even after following the above steps, make sure that you have defined the test-link endpoint with the host name provided in certificate you created.



In this post I will explain how we can set dynamic properties within a Jenkins build. I will append the current Date for the build name to demonstrate how we can achieve this.


First you need to install Groovy Script plugin. (This is just one way of doing this)

You can go to plugin manager and Install the groovy plugin.




After Installing it will look like following.



Now got to the build you configured and add a Pre-Build Steps and select "Execute system Groovy script."


Now add the following script as the body.


import hudson.model.*
  
def build = Thread.currentThread().executable
def today = new Date()
def pa = new ParametersAction([new StringParameterValue("DATE",today.toString())])
build.addAction(pa)


With the above code snippet I have added the system date to a variable called "DATE". After setting this should be accessible within the job context with the following syntax.

$DATE
${DATE}queries.

Hope this will help someone interested and please drop a comment if you have any queries.



Friday, March 11, 2016



In some cases you might want to read the system date and get it into the ESB and perform an action based on the time. The easiest way to do this is by using the property mediator and using default synapse properties.

You can do this in the following manner.


<property name="StrigVal"
                   expression="get-property('SYSTEM_DATE')"
                   scope="default"
                   type="STRING"/>


A full proxy service that uses the default SYSTEM_DATE.



<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="Proxy"
       transports="http,https"
       statistics="enable"
       trace="enable"
       startOnLoad="true">
   <target>
      <inSequence>
         <property name="StrigVal"
                   expression="get-property('SYSTEM_DATE')"
                   scope="default"
                   type="STRING"/>
         <log level="custom">
            <property name="StrigVal ==" expression="$ctx:StrigVal"/>
         </log>
      </inSequence>
      <outSequence>
         <log level="custom">
            <property name="StrigVal-out SEQ ==" expression="$ctx:StrigVal"/>
         </log>
      </outSequence>
      <endpoint>
         <address uri="http://www.mocky.io/v2/56e2821f2600003c35eaa2f8"/>
      </endpoint>
   </target>
   <description/>
</proxy>
                                

The Above Proxy will log the following.


INFO - LogMediator StrigVal-out SEQ == = 3/11/16 3:06 PM

Sunday, February 14, 2016

In this post I'll explain you how to save a request body to a file using WSO2 ESB. Here the approach I'm using is File connector. I'm using ESB 4.9 and File connector 2.0.

Note the File connector version I'm using because the syntax/key words differ from connector version to version.

The message flow is depicted as shown below.



To achieve the above use case we can use two approaces.

1. Using VFS transport.

a. Fist you need to enable VFS transport in ESB. To do this follow this.

b. Now create the following API.

<api xmlns="http://ws.apache.org/ns/synapse" name="Api01" context="/api01">
   <resource methods="POST" uri-template="/write-file-system">
      <inSequence>
         <log level="full">
            <property name="====== WRITING THE " value=" FILE ========"/>
         </log>
         <property name="FORCE_SC_ACCEPTED" value="true" scope="axis2" type="STRING"/>
         <property name="REST_URL_POSTFIX" value="" scope="axis2"/>
         <property name="OUT_ONLY" value="true" scope="default" type="STRING"/>
         <property name="transport.vfs.ReplyFileName" value="Hello55.txt" scope="transport" type="STRING"/>
         <log level="custom" separator=",">
            <property name="Output file" expression="$trp:transport.vfs.ReplyFileName"/>
         </log>
         <send>
            <endpoint>
               <address uri="vfs:ftp://ftpuser:ftpuser@localhost/files/in"/>
            </endpoint>
         </send>
      </inSequence>
      <outSequence/>
      <faultSequence/>
   </resource>
</api>

Note : In the above API I'm using a uri-template, If you use a uri-template the context will be appended to the end of the endpoint. So the ESB will try to access a location with the attached context which might cause issues. So to avoid this I'm using the following property to nullify the appending context.

<property name="REST_URL_POSTFIX" value="" scope="axis2"/>

2. You can achieve the same with file connector as well.  Inorder to use file connector you need to install the file connector first. You can refer [1] for more details.

a. After installing the connector and enabling it you can create the following API to achieve the requirement.

<api xmlns="http://ws.apache.org/ns/synapse" name="Api01" context="/api01">
   <resource methods="POST" uri-template="/write-file-system">
      <inSequence>
         <log level="full">
            <property name="In The API ==============" value="==================="/>
         </log>
         <property name="FORCE_SC_ACCEPTED" value="true" scope="axis2" type="STRING"/>
         <property name="OUT_ONLY" value="true" scope="default" type="STRING"/>
         <property name="transport.vfs.ReplyFileName" value="HelloConnector.txt" scope="transport" type="STRING"/>
         <property name="uri" value="ftp://ftpuser:ftpuser@192.168.48.119/files/in/" type="STRING"/>
         <log level="custom" separator=",">
            <property name="Output file" expression="$trp:transport.vfs.ReplyFileName"/>
         </log>
         <fileconnector.create>
            <source>{fn:concat($ctx:uri,$trp:transport.vfs.ReplyFileName)}</source>
            <inputContent>{$body}</inputContent>
         </fileconnector.create>
      </inSequence>
      <outSequence/>
      <faultSequence/>
   </resource>
</api>

Please drop a comment if you have any queries

[1] - https://store.wso2.com/store/assets/esbconnector/aec1554a-29ea-4dbb-b8c5-5d529a853aa2




Tuesday, January 19, 2016



In this post I will reveal how you can easily setup multiple java environments and switch between them easily.

This is a simple method I use, sharing in case anyone is interested. Please follow the steps below.

1. Download and extract the java version you require in your PC. I will be using Java 1.7 and Java 1.8 for the demonstration purpose. I have extracted java 1.7 and 1.8 to following locations.

e.g : /home/yasassri/soft/java/jdk1.8.0_05
        /home/yasassri/soft/java/jdk1.7.0_65

2. Now Open the bachrc file using your favorite text editor. You can use the following commands to do this.


vim ~/.bashrc

3. Now Add the following two alias at the end of the file.


# Setting Java 8
alias setjava18='export JAVA_HOME='/home/yasassri/soft/java/jdk1.8.0_05' && export PATH=$JAVA_HOME/bin:$PATH && source ~/.bashrc'

#Setting Java 7
alias setjava17='export JAVA_HOME='/home/yasassri/soft/java/jdk1.7.0_65' && export PATH=$JAVA_HOME/bin:$PATH && source ~/.bashrc'

Note : You need to replace '/home/yasassri/soft/java/jdk1.8.0_05' and '/home/yasassri/soft/java/jdk1.7.0_65' with the file location of extracted Java folders in your PC.

4. Save and exit the file.

5. Execute the following command.


source ~/.bashrc

6. Everything is set now. Now execute the following command in your terminal.


setjava18

Now check the Java version that is set with java -version, Java 8 will be set.

7. Now execute following 


setjava17

Now Java 1.7 will be set.

Thanks for reading and please drop a comment if you have any issues. 

Tuesday, December 15, 2015

In this Post I'll explain you how to Send a message to a ESB proxy service, Store the message in a messaging queue and respond the client with a custom respone.

The message flow is depicted as below.


As per the above diagram, A request is sent to the ESB and ESB will send out the message to ActiveMQ as a OUT_ONLY message, where ESB will not expect a response from ActiveMQ, at the same time the ESB will send a response to the client.

To achieve this first you need to enable JMS transport senders and listeners in the ESB in-order to receive and send JMS messages. You can do this by following this.

After configuring the ESB create the following Proxy service. Now when you send a request to the following proxy it will send store a message in the JMS queue and send a response to the client.

<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="TestJMS"
       transports="http,jms"
       statistics="disable"
       trace="disable"
       startOnLoad="true">
   <target>
      <inSequence>
         <property name="OUT_ONLY" value="true" scope="default" type="STRING"/>
         <log>
            <property name="==" value="============== In the In Sequence ================"/>
         </log>
         <call>
            <endpoint>
               <address uri="jms:/TESTQUEUE?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>
         </call>
         <payloadFactory media-type="xml">
            <format>
               <Response xmlns="">CUSTOM RESPONSE!!!</Response>
            </format>
            <args/>
         </payloadFactory>
         <respond/>
      </inSequence>
      <outSequence>
         <send/>
      </outSequence>
   </target>
   <description/>
</proxy>

In the above proxy please note the OUT_ONLY property which tells the ESB to send the message out and ignore any response.

Hope this post is useful to someone, Feel free to drop a comment if you have any queries. :)

Monday, August 31, 2015


In this Post I'll explain you how to send a GZIPed post body using CURL commands. Its pretty straight forward, noting down if anyone come accross a similar requirement.

First you need to create the body you need to send, In my case I'm sending a XML content. So create a valid xml file, then zip the created file in gzip format, In ubuntu you can just right click on the file and compress it. After compressing the file will have a .gz extension.

e.g : test.xml.gz

Now navigate to the file location in terminal and execute the following command.

curl -v -s --trace-ascii http_trace.log --data-binary @test.xml.gz -H "Content-Type: text/xml" -H "Content-Encoding: gzip" -X POST http://10.100.5.112:8280/api01

After invoking everything will be recorded in the specified log file.

== Info:   Trying 10.100.5.112...
== Info: Connected to 10.100.5.112 (10.100.5.112) port 8280 (#0)
=> Send header, 155 bytes (0x9b)
0000: POST /api01 HTTP/1.1
0016: User-Agent: curl/7.35.0
002f: Host: 10.100.5.112:8280
0048: Accept: */*
0055: Content-Type: text/xml
006d: Content-Encoding: gzip
0085: Content-Length: 42
0099: 
=> Send data, 42 bytes (0x2a)
0000: .......U..test.xml..)I-.....6.`&..-..J....
== Info: upload completely sent off: 42 out of 42 bytes
<= Recv header, 17 bytes (0x11)
0000: HTTP/1.1 200 OK
<= Recv header, 24 bytes (0x18)
0000: Content-Type: text/xml
<= Recv header, 37 bytes (0x25)
0000: Date: Tue, 01 Sep 2015 06:40:03 GMT
<= Recv header, 28 bytes (0x1c)
0000: Transfer-Encoding: chunked
<= Recv header, 2 bytes (0x2)
0000: 
<= Recv data, 34 bytes (0x22)
0000: 17
0004: <abc>Created !!!!</abc>
001d: 0
0020: 
== Info: Connection #0 to host 10.100.5.112 left intact


In this post I'll explain how to monitor WSO2 products remotely using Jconsole. Jconsoles comes by default with Java in linux you can type Jconsole to start Jconsole.

WSO2 Product Configurations

Main JMX ports related configs are located at <Product_Home>/repository/conf/carbon.xml Open <CARBON_HOME>/repository/conf/carbon.xml and specify the ports if you need to change the default ports. Change the following section.

        <!-- The JMX Ports -->
        <JMX>
            <!--The port RMI registry is exposed-->
            <RMIRegistryPort>9999</RMIRegistryPort>
            <!--The port RMI server should be exposed-->
            <RMIServerPort>11111</RMIServerPort>
        </JMX>

Now open <CARBON_HOME>/repository/conf/etc/jmx.xml and make sure the configs are changed as follows, You need to specify the machine IP as the HostName.


<JMX xmlns="http://wso2.org/projects/carbon/jmx.xml">
    <StartRMIServer>true</StartRMIServer>

    <!-- HostName, or Network interface to which this RMI server should be bound -->
    <HostName>192.168.48.49</HostName>

    <!--  ${Ports.JMX.RMIRegistryPort} is defined in the Ports section of the carbon.xml-->
    <RMIRegistryPort>${Ports.JMX.RMIRegistryPort}</RMIRegistryPort>

    <!--  ${Ports.JMX.RMIRegistryPort} is defined in the Ports section of the carbon.xml-->
    <RMIServerPort>${Ports.JMX.RMIServerPort}</RMIServerPort>
</JMX>

Now open <CARBON_HOME>/bin.wso2server.sh and add the following line as a JAVA parameter.

 -Djava.rmi.server.hostname="192.168.48.49"

You should add the above as shown below. Note: I'm using ESB 4.9 to demonstrate this, so your parameters may differ from what I have mentioned.


while [ "$status" = "$START_EXIT_STATUS" ]
do
    $JAVACMD \
    -Xbootclasspath/a:"$CARBON_XBOOTCLASSPATH" \
    -Xms256m -Xmx1024m -XX:MaxPermSize=256m \
    -XX:+HeapDumpOnOutOfMemoryError \
    -XX:HeapDumpPath="$CARBON_HOME/repository/logs/heap-dump.hprof" \
    $JAVA_OPTS \
    -Dcom.sun.management.jmxremote \
    -classpath "$CARBON_CLASSPATH" \
    -Djava.endorsed.dirs="$JAVA_ENDORSED_DIRS" \
    -Djava.io.tmpdir="$CARBON_HOME/tmp" \
    -Dcatalina.base="$CARBON_HOME/lib/tomcat" \
    -Dwso2.server.standalone=true \
    -Dcarbon.registry.root=/ \
    -Djava.command="$JAVACMD" \
    -Dcarbon.home="$CARBON_HOME" \
    -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager \
    -Dcarbon.config.dir.path="$CARBON_HOME/repository/conf" \
    -Djava.util.logging.config.file="$CARBON_HOME/repository/conf/etc/logging-bridge.properties" \
    -Dcomponents.repo="$CARBON_HOME/repository/components/plugins" \
    -Dconf.location="$CARBON_HOME/repository/conf"\
    -Dcom.atomikos.icatch.file="$CARBON_HOME/lib/transactions.properties" \
    -Dcom.atomikos.icatch.hide_init_file_path=true \
    -Dorg.apache.jasper.compiler.Parser.STRICT_QUOTE_ESCAPING=false \
    -Dorg.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER=true \
    -Dcom.sun.jndi.ldap.connect.pool.authentication=simple  \
    -Dcom.sun.jndi.ldap.connect.pool.timeout=3000  \
    -Dorg.terracotta.quartz.skipUpdateCheck=true \
    -Djava.security.egd=file:/dev/./urandom \
    -Dfile.encoding=UTF8 \
    -Djava.net.preferIPv4Stack=true \
    -Dcom.ibm.cacheLocalHost=true \
    -DworkerNode=true \
    -Djava.rmi.server.hostname="192.168.48.49" \
    org.wso2.carbon.bootstrap.Bootstrap $*
    status=$?
done

Thats all from the WSO2 side, after the configurations are done you need to restart the server. If the RMI servers are started successfully you will see the following logs on server startup.

TID: [-1234] [] [2015-08-31 14:27:18,854]  INFO {org.wso2.carbon.core.init.JMXServerManager} -  JMX Service URL  : service:jmx:rmi://192.168.48.49:11111/jndi/rmi://192.168.48.49:9999/jmxrmi {org.wso2.carbon.core.init.JMXServerManager}

Connecting Via JConsole.

There are two ways to connect via JConsole remotely, using the IP and port [1] or using JMX service URL [2].

After starting Jconsole Select  Remote process. And add one of the following URLs

[1]    192.168.48.49:9999

[2]    service:jmx:rmi://192.168.48.49:11111/jndi/rmi://192.168.48.49:9999/jmxrmi


For the username and the password, enter the super user name and the password of the WSO2 server. The default username and password is admin/admin. The final configs will look like following.


Now click on connect, When clicked on connect it will give you and error saying secured connection failed, So you need to select insecure connection when this error pops up. If you need to securely connect to JConsole you need add necessary keystores etc.


If everything goes well you should connect to the RMI server and relevant graphs will be generated as shown below.


So that's it please drop a comment if you have any queries.

Subscribe to RSS Feed Follow me on Twitter!