Saturday, June 11, 2016

Apache Camel: Integrating Weblogic Queue with Jboss Fuse ESB

This is article is about to integrate the Weblogic Message broker with Jboss Fuse using Apche Camel integration framework. For this I assume that you already have a weblogic server in place with JMS queue. I'm not going in detail to explain more about Weblogic message broker, Apache Camel, Jboss fuse, OSGi.

The requirement for this integrations,
  1. Jboss Fuse ESB 6.1
  2. Apache Camel
  3. Eclipse
  4. Weblogic Server with Queue Configuration
  5. wlthint3client.jar [Download from official page of Weblogic server]
Now we required below details of your WL server,
  1. Weblogic broker URL with port
  2. Credentials for this URL to connect (username, password)
  3. Weblogic JNDI Name exposed for communication with queue
  4. Weblogic queue name
Here, for this integration I have used as per below,

WL broker URL -->  t3://localhost:8090
Credentials -->  Username : wl_admin, password : wl_pass
WL JNDI Name -->  jms/TestJndiName
WL Queue Name -->  testqueue

We are done with the configuration related requirement. So, let's do camel riding for this integration.

To send and received data with WL queue we need to create one camel component which will do our job. This component will be responsible for exchange data with WL queue. To create this component we required object of jndiTemplate, jndiObjectFactoryBean, jndiDestinationResolver and jmsConfiguration. Each of this object we can refer respective java docs. Will explain each of the required object in the next section. 

jndiTemplate

This is the helper class which specify JNDI operations. It provides methods to lookup and bind objects, and allows implementations of the JndiCallback interface to perform any operation they like with a JNDI naming context provided. Here we have specified all the required properties which is required to lookup exposed JNDI object.

 Ref: Spring Docs


jndiObjectFactoryBean

This exposes the singleton object found in JNDI for bean references in a application context. The default behavior of this object is to lookup the object on startup and cache it. We can change its behavior to lazy initialization by setting lookupOnStartup=false and setting proxyInterface=javax.jms.ConnectionFactory. You can have more detail on this by referring spring docs. The simple code snippet is like this,


jndiDestinationResolver

This allows for customizing the JNDI environment if necessary, for example specifying appropriate JNDI environment properties. Dynamic queues and topics get cached by destination name. As a consequence, you need to use unique destination names across both queues and topics. You can have more detail on this by referring spring docs. The simple code snippet is like this,


jmsConfiguration
This object holds all the configuration and required object which are needed to create the camel weblogic component which exchanges the data between fuse and WL. The simple code snippet is like this,
wlqueue

This is the camel component with which we will access the queue/topic to send or receive the messages to/from WL.

Full context file is as per below,

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:camel="http://camel.apache.org/schema/spring"
  
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans.xsd
  http://camel.apache.org/schema/spring 
  http://camel.apache.org/schema/spring/camel-spring.xsd">

<!-- JNDITemplate object which holds basic property for JNDI lookup -->
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
   <property name="environment">
       <props>
           <prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop>
           <prop key="java.naming.provider.url">t3://localhost:8090</prop>
           <prop key="java.naming.security.principal">wl_admin</prop>
           <prop key="java.naming.security.credentials">wl_pass</prop>
       </props>
   </property>
</bean>
<!-- jndiObjectFactoryBean object -->
<bean id="jndiObjectFactoryBean" class="org.springframework.jndi.JndiObjectFactoryBean">
   <property name="jndiName" value="jms/TestJndiName"/>
   <property name="jndiTemplate" ref="jndiTemplate"/>
   <property name="lookupOnStartup" value="false"/> <!--  -->
   <property name="proxyInterface" value="javax.jms.ConnectionFactory"/>
</bean>
<!-- jndiDestinationResolver object -->
<bean id="jndiDestinationResolver" class="org.springframework.jms.support.destination.JndiDestinationResolver">
   <property name="jndiTemplate" ref="jndiTemplate"/>
</bean>
<!-- jmsConfiguration object -->
<bean id="jmsConfiguration" class="org.apache.camel.component.jms.JmsConfiguration">
<property name="connectionFactory" ref="jndiObjectFactoryBean"/>
<property name="destinationResolver" ref="jndiDestinationResolver"/>
</bean>
<!-- wlqueue object -->
<bean id="wlqueue" class="org.apache.camel.component.jms.JmsComponent">
<property name="configuration" ref="jmsConfiguration" />
</bean>
<camel:routeContext id="main-weblogic-consumer-producer-route-context">
<!-- This route will process by consuming weblogic queue  -->
<camel:route id="simple-weblogic-consumer-route">
<camel:from uri="wlqueue:queue:testqueue" />
<log loggingLevel="DEBUG" logName="simple-weblogic-consumer-route" 
message="Consumed message from weblogic queue:testqueue :: ${body}" />
<camel:to uri="direct:consumer-message-process-route" />
</camel:route>

<camel:route id="consumer-message-process-route">
<camel:from uri="direct:consumer-message-process-route" />
<log loggingLevel="DEBUG" logName="consumer-message-process-route" 
message="Processing initiated for consumed message :: ${body}" />
</camel:route>
<camel:route id="message-creater-for-wl-producer-route">
<camel:from uri="file://some-dir/file/input" />
<log loggingLevel="DEBUG" logName="message-creater-for-wl-producer-route" 
message="Message for web logic queue :: ${body}" />
<camel:to uri="direct:simple-weblogic-producer-route" />
</camel:route>
<!-- This route will push message in weblogic queue  -->
<camel:route id="simple-weblogic-producer-route">
<camel:from uri="direct:simple-weblogic-producer-route" />
<log loggingLevel="DEBUG" logName="simple-weblogic-consumer-route" 
message="Message to be push in weblogic queue:testqueue :: ${body}" />
<camel:to uri="wlqueue:queue:testqueue" />
</camel:route>
</camel:routeContext>
</beans>

Here, I have created route which consume message from WL queue and to push the message in the WL queue.

Now, our module is ready to exchange messages between web logic and jboss fuse esb. Generate OSGi using maven. Before deploying your bundle you have to install wlthint3client.jar in fuse server. To install this jar file you to convert it into OSGi bundle. Don't worry for this conversion. Below command will convert your jar into OSGi and will deploy into fuse esb.

Start your jboss fuse server and login to karaf console. fire below command to install wlthint3client.jar in fuse server. 

$osgi:install -s wrap:file:///<absolute-path>/wlthint3client.jar

Once you deployed this now you need to deploy you osgi module in jboss fuse. 


We are done now. That's it. Try to push message in WL queue and observe fuse server log.

Don't forget to share your feedback to make this article more helpful.

Cheers,
Ashish Mishra

1 comment:

  1. Hi Ashish,

    I have been stuck with the installation of wlthint3client.jar on JBoss fuse 6.2 (I have tried both 6.2.0 and 6.2.1) but it seems it's not possible to use weblogic client jar with JBoss anymore. If you have experienced such scenario can you please guide.

    Error is Caused by: javax.naming.NoInitialContextException: Cannot instantiate class: weblogic.jndi.WLInitialContextFactory [Root exception is java.lang.ClassNotFoundException: weblogic.jndi.WLInitialContextFactory in classloader xbean]


    I can see that with JBoss Fuse 6.1 it's possible to use felix.threading.disable=false but 6.2 onward it's not possible anymore. Kindly advise.

    ReplyDelete