Pages

Subscribe:

Ads 468x60px

Wednesday, January 13, 2016

WSO2 ESB : Consume JMS Messages From HornetQ embedded JBOSS EAP

In this post we are going to explore some JMS transport capabilities in WSO2 ESB. We are going to learn on how to create a message queues in JBOSS EAP, Publish sample messages to that queue. And finally using WSO2 ESB to listen to that queue and fetch the messages from the queue. Following are the per-requisites for this tutorial.
  1. WSO2 ESB 4.9.0 Download From Here
  2. JBOSS EAP Download From Here 
  3. Maven to build and run the helloworld-jms sample client
Setting up JBOSS EAP

First lets install the JBOSS EAP to your local machine. Follow the below instructions to install.
1. Start the installer using the following command.

java -jar jboss-eap-6.2.0-installer.jar

2. Continue the installer with appropriate values (mostly default configurations). Select yes to install samples. Since we are using the helloworld-jms sample to publish messages to the queue. Otherwise you can write your own sample client to publish messages.

3. After that fill out the details with default values as it is, and finish the installation.
Now you have installed JBoss EAP successfully, Now lets create a new application user and a new message queue.

Adding a new application user. 

Move to the JBOSS-EAP installation folder and execute the following command.

EAP_HOME/bin/add-user.sh -a -u 'SampleUser' -p 'SamplePwd1!' -g 'guest'

Create a new message queue.

You can add a message queue directly editing the EAP_HOME/standalone/configuration/standalone-full.xml configuration file. Follow the below steps to add the new message queue.

Open up the the standalone-full.xml file and locate the <hornetq-server>
2. Add the following content inside the  <hornetq-server> element.

1
2
3
4
5
6
<jms-destinations>
      <jms-queue name="sampleQueue">
          <entry name="queue/test"/>
          <entry name="java:jboss/exported/jms/queue/test"/>
      </jms-queue>
  </jms-destinations>

Now Start the JBoss server with following command and login to the management console.

EAP_HOME/bin/standalone.sh -c standalone-full.xml

Now after logging to the management console, we can see the newly added user and the message queue. Default admin console url is http://127.0.0.1:9990

After logging navigate to Profile -> Messaging -> Destinations. And you'll be able to see the added sampleQueue.


And if you move to Security Settings section in the same page, you'll able to see the Role with guest has the permission to consume and produce messages to the queue.

Now the configuration part of the JBOSS EAP is done. Lets configure the WSO2 ESB. In this sample we are going to consume messages from the queue. So we are going to configure only the JMS Transport Receiving part in the ESB side.

1. Open up the WSO2-ESB/repository/conf/axis2/axis2.xml file and add  the following configuration.

<transportReceiver name="jms" class="org.apache.axis2.transport.jms.JMSListener">
 <parameter name="sampleQueueConnectionFactory" locked="false">
  <parameter name="java.naming.factory.initial" locked="false">org.jboss.naming.remote.client.InitialContextFactory</parameter>
  <parameter name="java.naming.provider.url" locked="false">remote://localhost:4447</parameter>
  <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">jms/RemoteConnectionFactory</parameter>
  <parameter name="transport.jms.UserName" locked="false">SampleUser</parameter>
  <parameter name="transport.jms.Password" locked="false">SamplePwd1!</parameter>
  <parameter name="java.naming.security.principal" locked="false">SampleUser</parameter> 
  <parameter name="java.naming.security.credentials" locked="false">SamplePwd1!</parameter>
  <parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
 </parameter>
    </transportReceiver>

For the username and password add the user details we have created in JBOSS side for both transport.jms and java.naming.security parameters.

2. Copy the jboss-client.jar to WSO2-ESB/repository/components/lib folder.
IMPORTANT After copying we have to remove the javax.jms package inside the javax.


Now Start the esb server by executing the ./ESB-HOME/bin/wso2server.sh command. Login to the ESB Management console and create the following sample Proxy. 

Note that in the below proxy transport.jms.destination value should be equal to the sampleQueue we have created earlier. transport.jms.ConnectionFactory value should be eqaul to the transportReceiver element calue we have added to the axis.xml


<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="JBossToESB"
       transports="jms"
       startOnLoad="true"
       trace="disable">
   <description/>
   <target>
      <inSequence>
         <log level="full">
            <property name="MESSAGE" value="New message from JBoss"/>
         </log>
      </inSequence>
   </target>
   <parameter name="transport.jms.Destination">sampleQueue</parameter>
   <parameter name="transport.jms.ContentType">
      <rules>
         <jmsProperty>contentType</jmsProperty>
         <default>text/plain</default>
      </rules>
   </parameter>
   <parameter name="transport.jms.ConnectionFactory">sampleQueueConnectionFactory</parameter>
</proxy>

If the deployment of the proxy is successful you'll see something similar to the following log.

[2016-01-13 12:47:33,623]  INFO - ProxyService Building Axis service for Proxy service : JBossToESB
[2016-01-13 12:47:33,625]  INFO - ProxyService Adding service JBossToESB to the Axis2 configuration
[2016-01-13 12:47:33,635]  INFO - DeploymentInterceptor Deploying Axis2 service: JBossToESB {super-tenant}
[2016-01-13 12:47:33,712]  INFO - JMSListener Connection attempt: 1 for JMS Provider for service: JBossToESB was successful!
[2016-01-13 12:47:33,713]  INFO - ServiceTaskManager Task manager for service : JBossToESB [re-]initialized
[2016-01-13 12:47:34,714]  INFO - JMSListener Started to listen on destination : sampleQueue of type queue for service JBossToESB
[2016-01-13 12:47:34,714]  INFO - ProxyService Successfully created the Axis2 service for Proxy service : JBossToESB
[2016-01-13 12:47:34,714]  INFO - ProxyServiceDeployer ProxyService named 'JBossToESB' has been deployed from file : /home/aruna/Desktop/doc/wso2esb-4.9.0/repository/deployment/server/synapse-configs/default/proxy-services/JBossToESB.xml

Test the Scenario

To test this JBOSS ESB integration is working we are going to use the helloworld-jms sample client which comes with the JBoss installation.

Navigate to the following folder EAP-Home/jboss-eap-6.2.0.GA-quickstarts/helloworld-jms. Then comment out the following code block from the src/main/java/org/jboss/as/quickstarts/jms/HelloWorldJMSClient.java file. Since we don't need the consume part of the sample. ESB will consume the message.

// Then receive the same number of messages that were sent
//            for (int i = 0; i < count; i++) { 
//              message = (TextMessage) consumer.receive(5000);
//              log.info("Received message with content " + message.getText());
//        }

Execute the following command to run the sample.

mvn clean compile exec:java -Dusername=SampleUser -Dpassword=SamplePwd1! -Dmessage.content="Hellow WSO2 ESB From JBoss EAP"

If the above command fails to execute due to dependency issue. You may have to add following profile to Maven-Home/conf/settings.xml.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/xsd/settings-1.0.0.xsd">
    <localRepository/>
    <profiles>
        <profile>
            <id>redhat-techpreview-all-repository</id>
            <repositories>
                <repository>
                    <id>redhat-techpreview-all-repository</id>
                    <name>Red Hat Tech Preview repository (all)</name>
                    <url>http://maven.repository.redhat.com/techpreview/all/</url>
                    <layout>default</layout>
                    <releases>
                        <enabled>true</enabled>
                        <updatePolicy>never</updatePolicy>
                    </releases>
                    <snapshots>
                        <enabled>false</enabled>
                        <updatePolicy>never</updatePolicy>
                    </snapshots>
                </repository>
            </repositories>
            <pluginRepositories>
                <pluginRepository>
                    <id>redhat-techpreview-all-repository</id>
                    <name>Red Hat Tech Preview repository (all)</name>
                    <url>http://maven.repository.redhat.com/techpreview/all/</url>
                    <layout>default</layout>
                    <releases>
                        <enabled>true</enabled>
                        <updatePolicy>never</updatePolicy>
                    </releases>
                    <snapshots>
                        <enabled>false</enabled>
                        <updatePolicy>never</updatePolicy>
                    </snapshots>
                </pluginRepository>
            </pluginRepositories>
        </profile>
    </profiles>
    <activeProfiles>
        <activeProfile>redhat-techpreview-all-repository</activeProfile>
    </activeProfiles>
</settings>

Or else you can add the above repository to the sample's pom.xml.

Explanation

helloworld-jms sample client will add a sample message to the sampleQueue after running the above command. And now if you check the ESB Console, You'll see something similar to the following log, proving that the ESB has consumed the message from the JBoss JMS queue.

[2016-01-13 14:10:28,888]  INFO - LogMediator To: , WSAction: urn:mediate, SOAPAction: urn:mediate, MessageID: ID:4c942aa5-b9d1-11e5-b7c9-c18d59e6d603, Direction: request, MESSAGE = New message from JBoss, Envelope: 
<?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<axis2ns3:text xmlns:axis2ns3="http://ws.apache.org/commons/ns/payload">Hellow WSO2 ESB From JBoss EAP</axis2ns3:text>
</soapenv:Body>
</soapenv:Envelope>

Possible Issues and How to troubleshoot them.

1. Address already in use when starting ESB Server.

[2016-01-13 11:56:43,966] ERROR - JMXServerManager Could not create the RMI local registry
java.rmi.server.ExportException: Port already in use: 9999; nested exception is: 
 java.net.BindException: Address already in use
 at sun.rmi.transport.tcp.TCPTransport.listen(TCPTransport.java:330)
 at sun.rmi.transport.tcp.TCPTransport.exportObject(TCPTransport.java:238)
 at sun.rmi.transport.tcp.TCPEndpoint.exportObject(TCPEndpoint.java:411)
 at sun.rmi.transport.LiveRef.exportObject(LiveRef.java:147)
 at sun.rmi.server.UnicastServerRef.exportObject(UnicastServerRef.java:208)

Start the ESB server with -DportOffset=1 flag

2. ListenerManager Couldn't initialize the jmstransport listener

[2016-01-13 15:07:52,246]  INFO - PassThroughHttpSSLSender Pass-through HTTPS Sender started...
[2016-01-13 15:07:53,176] ERROR - BaseUtils JNDI lookup of name jms/RemoteConnectionFactory returned a org.hornetq.jms.client.HornetQJMSConnectionFactory while a interface javax.jms.ConnectionFactory was expected
[2016-01-13 15:07:53,178] ERROR - ListenerManager Couldn't initialize the jmstransport listener
org.apache.axis2.transport.base.BaseTransportException: JNDI lookup of name jms/RemoteConnectionFactory returned a org.hornetq.jms.client.HornetQJMSConnectionFactory while a interface javax.jms.ConnectionFactory was expected
 at org.apache.axis2.transport.base.BaseUtils.handleException(BaseUtils.java:168)
 at org.apache.axis2.transport.jms.JMSUtils.lookup(JMSUtils.java:656)
 at org.apache.axis2.transport.jms.JMSConnectionFactory.<init>(JMSConnectionFactory.java:93)
 at org.apache.axis2.transport.jms.JMSConnectionFactoryManager.loadConnectionFactoryDefinitions(JMSConnectionFactoryManager.java:58)
 at org.apache.axis2.transport.jms.JMSConnectionFactoryManager.<init>(JMSConnectionFactoryManager.java:45)
 at org.apache.axis2.transport.jms.JMSListener.doInit(JMSListener.java:65)
 at org.apache.axis2.transport.base.AbstractTransportListenerEx.init(AbstractTransportListenerEx.java:62)
 at org.apache.axis2.engine.ListenerManager.init(ListenerManager.java:84)
 at org.wso2.carbon.core.init.CarbonServerManager.initializeCarbon(CarbonServerManager.java:411)
 at org.wso2.carbon.core.init.CarbonServerManager.start(CarbonServerManager.java:219)
 at org.wso2.carbon.core.internal.CarbonCoreServiceComponent.activate(CarbonCoreServiceComponent.java:91)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:483)
 at org.eclipse.equinox.internal.ds.model.ServiceComponent.activate(ServiceComponent.java:260)
 at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.activate(ServiceComponentProp.java:146)
 at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.build(ServiceComponentProp.java:345)
 at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponent(InstanceProcess.java:620)
 at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponents(InstanceProcess.java:197)
 at org.eclipse.equinox.internal.ds.Resolver.getEligible(Resolver.java:343)
 at org.eclipse.equinox.internal.ds.SCRManager.serviceChanged(SCRManager.java:222)
 at org.eclipse.osgi.internal.serviceregistry.FilteredServiceListener.serviceChanged(FilteredServiceListener.java:107)
 at org.eclipse.osgi.framework.internal.core.BundleContextImpl.dispatchEvent(BundleContextImpl.java:861)
 at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
 at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148)
 at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEventPrivileged(ServiceRegistry.java:819)
 at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEvent(ServiceRegistry.java:771)
 at org.eclipse.osgi.internal.serviceregistry.ServiceRegistrationImpl.register(ServiceRegistrationImpl.java:130)
 at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.registerService(ServiceRegistry.java:214)
 at org.eclipse.osgi.framework.internal.core.BundleContextImpl.registerService(BundleContextImpl.java:433)
 at org.eclipse.equinox.http.servlet.internal.Activator.registerHttpService(Activator.java:81)
 at org.eclipse.equinox.http.servlet.internal.Activator.addProxyServlet(Activator.java:60)
 at org.eclipse.equinox.http.servlet.internal.ProxyServlet.init(ProxyServlet.java:40)
 at org.wso2.carbon.tomcat.ext.servlet.DelegationServlet.init(DelegationServlet.java:38)
 at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1284)
 at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1197)
 at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1087)
 at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5262)
 at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5550)
 at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
 at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1575)
 at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1565)
 at java.util.concurrent.FutureTask.run(FutureTask.java:266)
 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
 at java.lang.Thread.run(Thread.java:745)

Remove the jms package from the jboss-client.jar

3. JMSConnectionFactoryManager Error setting up connection factory


[2016-01-13 15:14:57,357] ERROR - JMSConnectionFactoryManager Error setting up connection factory : sampleQueueConnectionFactory
org.apache.axis2.transport.jms.AxisJMSException: Cannot acquire JNDI context, JMS Connection factory : jms/RemoteConnectionFactory or default destination : null for JMS CF : sampleQueueConnectionFactory using : {transport.jms.Password=SamplePwd1!, java.naming.provider.url=remote://localhost:4447, java.naming.factory.initial=org.jboss.naming.remote.client.InitialContextFactory, transport.jms.ConnectionFactoryType=queue, transport.jms.UserName=SampleUser, java.naming.security.principal=SampleUser, transport.jms.ConnectionFactoryJNDIName=jms/RemoteConnectionFactory, java.naming.security.credentials=SamplePwd1!}
 at org.apache.axis2.transport.jms.JMSConnectionFactory.<init>(JMSConnectionFactory.java:102)
 at org.apache.axis2.transport.jms.JMSConnectionFactoryManager.loadConnectionFactoryDefinitions(JMSConnectionFactoryManager.java:58)
 at org.apache.axis2.transport.jms.JMSConnectionFactoryManager.<init>(JMSConnectionFactoryManager.java:45)
 at org.apache.axis2.transport.jms.JMSListener.doInit(JMSListener.java:65)
 at org.apache.axis2.transport.base.AbstractTransportListenerEx.init(AbstractTransportListenerEx.java:62)
 at org.apache.axis2.engine.ListenerManager.init(ListenerManager.java:84)
 at org.wso2.carbon.core.init.CarbonServerManager.initializeCarbon(CarbonServerManager.java:411)
 at org.wso2.carbon.core.init.CarbonServerManager.start(CarbonServerManager.java:219)
 at org.wso2.carbon.core.internal.CarbonCoreServiceComponent.activate(CarbonCoreServiceComponent.java:91)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:483)
 at org.eclipse.equinox.internal.ds.model.ServiceComponent.activate(ServiceComponent.java:260)
 at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.activate(ServiceComponentProp.java:146)
 at org.eclipse.equinox.internal.ds.model.ServiceComponentProp.build(ServiceComponentProp.java:345)
 at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponent(InstanceProcess.java:620)
 at org.eclipse.equinox.internal.ds.InstanceProcess.buildComponents(InstanceProcess.java:197)
 at org.eclipse.equinox.internal.ds.Resolver.getEligible(Resolver.java:343)
 at org.eclipse.equinox.internal.ds.SCRManager.serviceChanged(SCRManager.java:222)
 at org.eclipse.osgi.internal.serviceregistry.FilteredServiceListener.serviceChanged(FilteredServiceListener.java:107)
 at org.eclipse.osgi.framework.internal.core.BundleContextImpl.dispatchEvent(BundleContextImpl.java:861)
 at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
 at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148)
 at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEventPrivileged(ServiceRegistry.java:819)
 at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.publishServiceEvent(ServiceRegistry.java:771)
 at org.eclipse.osgi.internal.serviceregistry.ServiceRegistrationImpl.register(ServiceRegistrationImpl.java:130)
 at org.eclipse.osgi.internal.serviceregistry.ServiceRegistry.registerService(ServiceRegistry.java:214)
 at org.eclipse.osgi.framework.internal.core.BundleContextImpl.registerService(BundleContextImpl.java:433)
 at org.eclipse.equinox.http.servlet.internal.Activator.registerHttpService(Activator.java:81)
 at org.eclipse.equinox.http.servlet.internal.Activator.addProxyServlet(Activator.java:60)
 at org.eclipse.equinox.http.servlet.internal.ProxyServlet.init(ProxyServlet.java:40)
 at org.wso2.carbon.tomcat.ext.servlet.DelegationServlet.init(DelegationServlet.java:38)
 at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1284)
 at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1197)
 at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1087)
 at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5262)
 at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5550)
 at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
 at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1575)
 at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1565)
 at java.util.concurrent.FutureTask.run(FutureTask.java:266)
 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
 at java.lang.Thread.run(Thread.java:745)
Caused by: javax.naming.NamingException: Failed to connect to any server. Servers tried: [remote://localhost:4447]
 at org.jboss.naming.remote.client.HaRemoteNamingStore.failOverSequence(HaRemoteNamingStore.java:213)
 at org.jboss.naming.remote.client.HaRemoteNamingStore.namingStore(HaRemoteNamingStore.java:144)
 at org.jboss.naming.remote.client.HaRemoteNamingStore.namingOperation(HaRemoteNamingStore.java:125)
 at org.jboss.naming.remote.client.HaRemoteNamingStore.lookup(HaRemoteNamingStore.java:241)
 at org.jboss.naming.remote.client.RemoteContext.lookup(RemoteContext.java:79)
 at org.jboss.naming.remote.client.RemoteContext.lookup(RemoteContext.java:83)
 at javax.naming.InitialContext.lookup(InitialContext.java:417)
 at org.apache.axis2.transport.jms.JMSUtils.lookup(JMSUtils.java:643)
 at org.apache.axis2.transport.jms.JMSConnectionFactory.<init>(JMSConnectionFactory.java:93)
 ... 44 more

Check the java.naming.provider.url is correct in the axis2.xml transportReceiver Parameters.
Check the JBOSS EAP is up and running and reachable to WSO2 ESB.