Concept behind RefFSContextFactory
RefFSContextFactory uses a JNDI folder as the provider URL. That JNDI folder has .binding files which contains the mapping between JNDI name and actual IBM Websphere MQ objects, such as a queue manager, queue, topic, and so forth.
Configuring WebSphere MQ
The WebSphere installation directory will be reffered to as
Note: If exists, delete any earlier versions of the .bindings files from that folder.
ex: After changing your JSAdmin.config file should look like this.
# appropriate one should be uncommented.
#
#INITIAL_CONTEXT_FACTORY=com.sun.jndi.ldap.LdapCtxFactory
INITIAL_CONTEXT_FACTORY=com.sun.jndi.fscontext.RefFSContextFactory
#INITIAL_CONTEXT_FACTORY=com.ibm.ejs.ns.jndi.CNInitialContextFactory
#INITIAL_CONTEXT_FACTORY=com.ibm.websphere.naming.WsnInitialContextFactory
#INITIAL_CONTEXT_FACTORY=com.ibm.websphere.naming.WMQInitialContextFactory
#
# The following line specifies the URL of the service provider's initial
# context. It currently refers to an LDAP root context. Examples of a
# file system URL and WebSphere's JNDI namespace are also shown, commented
# out.
#
#PROVIDER_URL=ldap://polaris/o=ibm,c=us
PROVIDER_URL=file:/C:/JNDI-Directory
#PROVIDER_URL=iiop://localhost/
#PROVIDER_URL=localhost:1414/SYSTEM.DEF.SVRCONN
......
- Go to the
/Java/bin directory and open the JSAdmin.config file with a text editor. - Comment out the existing INITIAL_CONTEXT_FACTORY and add a INITIAL_CONTEXT_FACTORY named com.sun.jndi.fscontext.RefFSContextFactory
- Comment the default PROVIDER_URL and use a directory path instead. Make sure that directory is created in the file system (ex: C:/JNDI-Directory).
ex: After changing your JSAdmin.config file should look like this.
# appropriate one should be uncommented.
#
#INITIAL_CONTEXT_FACTORY=com.sun.jndi.ldap.LdapCtxFactory
INITIAL_CONTEXT_FACTORY=com.sun.jndi.fscontext.RefFSContextFactory
#INITIAL_CONTEXT_FACTORY=com.ibm.ejs.ns.jndi.CNInitialContextFactory
#INITIAL_CONTEXT_FACTORY=com.ibm.websphere.naming.WsnInitialContextFactory
#INITIAL_CONTEXT_FACTORY=com.ibm.websphere.naming.WMQInitialContextFactory
#
# The following line specifies the URL of the service provider's initial
# context. It currently refers to an LDAP root context. Examples of a
# file system URL and WebSphere's JNDI namespace are also shown, commented
# out.
#
#PROVIDER_URL=ldap://polaris/o=ibm,c=us
PROVIDER_URL=file:/C:/JNDI-Directory
#PROVIDER_URL=iiop://localhost/
#PROVIDER_URL=localhost:1414/SYSTEM.DEF.SVRCONN
......
- 4. Restart the IBM WebSphere service
Creating a queue on WebSphere MQ
- Open the WebSphere MQ explorer and right click on Queue Manager and select New >Queue Manager.
- Provide a name for the Queue Manager (myQueueManager) and Make it default. Press Next.
- Select the options to Start Queue Manager, Autostart Queue Manager and Create server connection channel. Then press on Next.
- Select the option to Create listener configuration for TCP/IP and provide a port number (1415).
- Once the Queue Manager is created, right click on the Queues icon belonging to the queue manager (myQueueManager) and select New->Local Queue.
- Provide a name for the Queue (myQueue) and press on Next. Go with the default configurations and press on Finish.
- Right click on the Channels icon under the Advanced icon and select New > Server-connection Channel. Provide a name for the channel (myChannel) and press on Next. Set the transmission protocol as TCP and press on Finish.
- Once these steps are completed, a listener will be created running on port 1415 and you should be able to view it by clicking on the listeners icon.
Generating .bindings file
- RefFSContextFactory uses a file system url as the provider url. We are going to create a .bindings file inside C:/JNDI-Directory folder using JSAdmin.config file we prepared. Navigate to
/Java/bin directory and run JMSAdmin.bat file. - create bindings as appropriate. You have to use the names of resources you have defined. You can choose JNDI names as you want.
//define a context factory. If in same machine you can use "define qcf(MYCF) //qmgr(CUSTOMER_QUEUE_MANAGER) transport(BIND)" as well.
define qcf(MYCF) qmgr(CUSTOMER_QUEUE_MANAGER) host() port() CHANNEL(SYSTEM.DEF.SVRCONN) transport(CLIENT)
//define a queue
define q(JMS_QUEUE) qmgr(CUSTOMER_QUEUE_MANAGER) queue(MY_QUEUE)
Following is an example commands that goes with configs we have made under “Creating a queue on WebSphere MQ”. You can check created objects by display ctx command.
Welcome to the Admin Tool's command-line interface
InitCtx> def qcf(MQ_JMS_MANAGER) qmgr(myQueueManager) tran(client) chan(myChannel) host(175.157.120.102) port(1415)
InitCtx> def q(JMS_QUEUE) qmgr(myQueueManager) queue(myQueue)
InitCtx> display ctx
Contents of InitCtx
.bindings java.io.File
a JMS_QUEUE com.ibm.mq.jms.MQQueue
a MQ_JMS_MANAGER com.ibm.mq.jms.MQQueueConnectionFactory
3 Object(s)
0 Context(s)
3 Binding(s), 2 Administered
InitCtx> end
Stopping Websphere MQ classes for Java(tm) Message Service Administration
C:\IBM\WebSphere MQ\Java\bin>
Now go to C:/JNDI-Directory . You should be able to view .bindings file there.
Configure an ESB instance running on a different machine
The following configuration changes were made on the ESB for it to be able to remotely
communicate with WebSphere MQ.
The ESB installation directory will be reffered to as.
<transportReceiver name="jms" class="org.apache.axis2.transport.jms.JMSListener">
<parameter name="myQueueConnectionFactory" 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:/home/user/JNDI-Directory</parameter>
<parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">MQ_JMS_MANAGER</parameter>
<parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
<parameter name="transport.jms.Destination">JMS_QUEUE</parameter>
<parameter name="transport.jms.JMSSpecVersion">1.0</parameter>
</parameter>
<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:/home/user/JNDI-Directory</parameter>
<parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">MQ_JMS_MANAGER</parameter>
<parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
<parameter name="transport.jms.Destination">JMS_QUEUE</parameter>
<parameter name="transport.jms.JMSSpecVersion">1.0</parameter>
</parameter>
</transportReceiver>
communicate with WebSphere MQ.
The ESB installation directory will be reffered to as
- Copy C:/JNDI-Directory from above machine to a suitable place in new machine. We will consider this place in Ubuntu machine as /home/user/JNDI-Directory.
- Copy all the jars found in the jar_files.zip attachment to the
/repository/ components/lib directory. In addition, you have to copy fscontext.jar file found in/Java/lib directory as well. - Add the following jms transport receiver configuration to the
/repository/ conf/axis2.xml file.
<transportReceiver name="jms" class="org.apache.axis2.transport.jms.JMSListener">
<parameter name="myQueueConnectionFactory" 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:/home/user/JNDI-Directory</parameter>
<parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">MQ_JMS_MANAGER</parameter>
<parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
<parameter name="transport.jms.Destination">JMS_QUEUE</parameter>
<parameter name="transport.jms.JMSSpecVersion">1.0</parameter>
</parameter>
<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:/home/user/JNDI-Directory</parameter>
<parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">MQ_JMS_MANAGER</parameter>
<parameter name="transport.jms.ConnectionFactoryType" locked="false">queue</parameter>
<parameter name="transport.jms.Destination">JMS_QUEUE</parameter>
<parameter name="transport.jms.JMSSpecVersion">1.0</parameter>
</parameter>
</transportReceiver>
Note the changed values.
- Enable transport sender
- Start the ESB by providing the -Duser.name=SYSTEM jvm parameter. ex: ./wso2server.sh -Duser.name=SYSTEM
- On a successful connection, an INFO level log message similar to the following is printed on the esb startup.
INFO - JMSConnectionFactory JMS ConnectionFactory : myQueueConnectionFactory initialized
Test the setup
- Copy paste the following proxy service to ESB synapse configuration. This will listen to messages coming from created queue at Websphere MQ (myQueue) then log it and drop the message.
<proxy name="SimpleStockQuoteService" transports="jms" startOnLoad="true">
<target>
<inSequence>
<property name="OUT_ONLY" value="true"/>
<log level="full"/>
<drop/>
</inSequence>
<outSequence/>
</target>
<parameter name="transport.jms.ContentType">
<rules>
<jmsProperty>contentType</jmsProperty>
<default>application/xml</default>
</rules>
</parameter>
<parameter name="transport.jms.ConnectionFactory">myQueueConnectionFactory</parameter>
<parameter name="transport.jms.DestinationType">queue</parameter>
<parameter name="transport.jms.Destination">JMS_QUEUE</parameter>
</proxy>
- Right click queue in MQ explorer and put a test message to the queue (should be a xml). At that instance you will see that your message is consumed by the queue and logged at ESB running on remote machine.
Hi
ReplyDeleteThanks for the above code, it worked really well for me have you got any examples of sending messages to IBM MQ?
Thanks again
Where I can find the jar_files.zip file?
ReplyDelete