Sunday, 5 October 2014

Implementing JMS communication at WMB

MQ
Message queues provide an asynchronous communications protocol, meaning that the sender and receiver of the message do not need to interact with the message queue at the same time.
JMS
JMS is a API which helps java applications to interact with other applications through JMS Api.JMS API helps java programs to connect to Enterprise systems like MQ world.
JMS is similar to JDBC.Like the JDBC API used to connect to different relational databases,the JMS API provides vendor independent access to Enterprise messaging system like JBOSS Messaging,Websphere MQ,BEA Weblogic. Same JMS code can be used to connect to Enterprise messaging system like JBOSS Messaging,Websphere MQ,BEA Weblogic.
JMS is a standard.
Still not getting clear idea on why JMS?Read further…
Now-a-days,the messaging World has expanded a lot.We not only have IBM MQ.There are other MQ products such as Sonic MQ,Apache MQ,MSMQ,etc.
You have your application with you handling only the application level logic and Integration layer is completely in Integration layer and out of Application layer.In such case,Application should not bother about which type of Integration MQ you are going to connect.This should not  be tightly coupled.Your application should be able to connect to any type of Integration .Any type of MQ.
If your application is java based ,then it will support JMS.And if the MQ product also supports JMS.Then done.All set.
Your application can act as JMS consumer/provider and the Messaging MQ can also act as JMS producer/consumer so that they both can start communicating with each other.So,this seems to be like a thin layer in between Application and the Messaging MQ product.
Hope now you can understand why JMS..

Now,my Messaging product is IBM MQ.Lets check whether IBM MQ can support JMS.Check whether JMS related files are present in the below path.If there,then your MQ product can support JMS.
C:\Program Files (x86)\IBM\WebSphere MQ\java\bin

JMS client is the Application.And JMS Server is the Message Product which supports JMS.
While communication is in place,client can act as both Consumer/Producer and similar way Server can also act as Producer/Consumer.

Two Models of JMS communication are available:
1)Point to Point 2)Publish/Subscribe Topics
Why we may need Message broker or other Integration Transformer/Mediator in the JMS communication paradigm?
Suppose your application has to communicate with multiple JMS providers of different Messaging MQ products,then the target applications which are connecting to those JMS provider would require messages in their compatible format.
But  you have one application in which you would have to write many messaging transformation logic to support each target application.
Here comes the product like WMB.
Any JMS client use JNDI to lookup JMS connection factories and destinations.All JMS nodes act as JMS clients and hence all the JMS nodes have to configured with Connection Factories and Destinations.
So,now  the Workflow will be as below,
à Your Application acts as  JMS client
  àLooks for JNDI objects to connect to JMS Provider and put message in Destination Queue
     à Integration product like  WMB JMS Input node which is  JMS Consumer ,acts as JMS client to connect to that Destination Queue and receives the message to transform
          à WMB flow (To do the transformation of message)
              à JMSOutput node acts as JMS Provider  to put message in Destination Output queue.Again this                   acts as JMS client to connect to JMS Provider
            à Target Application connect to this Destination Output queue as JMS client to receive the message
What are the components we need to establish connection in JMS?
To create Connection factory:
·         For the clients communicate with JMS Provider(Messaging system),they lookup for Connection factories in JNDI.To configure the Connection Factories in JNDI,follow the below steps

Create Initial Context Factory which specifies whether it is LDAP or FileSystem for JNDI and also the Provider URL
I have used MQQueueConnectionFactory to use purely Point-To-Point communication.And used Client mode.
So,below are the properties configured for Connection Factory

Creating Destination Queue-Finally its an MQ product after crossing JMS.So,as final destination JMS queues should be present for the clients to communicate.These should be local queues present in the queue manager.
I am creating here two local queues for the Destination Queues
2)Now Application is built in WMB as below,
JMSInput node:
JMSOutput node:
3)JMS client can be using Java code or using JMETER as given  below
Ensure that you have below jars in the JMETER lib folder to test JMS,
Testing
As the clients connect through SYSTEM.DEF.SVRCONN,the client user may not have permission to connect to QueueManager.By default in MQ7.5 has Security enabled for client connections.Hence the below error was thrown when trying to connect from JMS client.

So,Disabling for Client Authentication to ease the explaination of JMS flow here
Now,by placing message from JMS client,it works….
Below picture shows the JMS headers getting populated at the JMSInput node
Output Message at the JMS Destination Target Queue
Q&A
Question?
"This provider url (EG: F:/JMS) seems to be the path of .bindings file present in JMS Provider system." 

So,how does the client system resolves/recognises the F drive present in the Server system.Does it automatically resolves after it establishes connection to JMS provider via Server Connection Channel? 


An Application would like to communicate via JMS so that it can connect to any Messaging providers such as IBM MQ,TIBCO,SAP Netweaver PI etc...Having said that,why do we need ServerConnectionChannel which is more specific for an MQ Client to be used at Application side?Does it not fall back to the category of MQClient instead of acting as JMSClient?

Answer:

The provider URL points you with the JNDI to the .bindings file which contains the implementation information for the connection. 
The client system does not resolve anything at this point. 
The client system's OS knows the location of the .bindings file because the Provider URL told it where it was. 
Inside the .bindings file you have bound a JMS ConnectionFactory. There is an Implementation Class name behind it. So when you retrieve the JMS ConnectionFactory from the JNDI it already knows the relevant implementation parameters "decorating" it. 
I.E. all your JMS program needs to do is create a connection off of it. 

If you did create the JMS ConnectionFactory, instead of retrieving it from JNDI, you will have to decorate it with all the information it needs in order to be able to build the connection....

Read up on the basic JMS model. The JMS client knows nothing about the MQ Channel. The JMS client knows about the JMS ConnectionFactory. The connection factory in turn knows about the MQ channel and hostname / port etc.. and any other information needed to build the connection. 

So yes your JMS code is agnostic to the implementation. Your JNDI however is not. It is the JNDI that builds the glue between the JMS generic set up (program) and its practical implementation (MQ). 

So if you want to access MQ, Tibco, SAP PI or any other JMS implementation, all you need to do is correctly bind a "decorated" JMS ConnectionFactory for each of those providers into your JNDI. 
Retrieve from the JNDI the ConnectionFactory corresponding to the implementation you desire. 

Needless to say the same thing goes for the JMS Destinations bound in your JNDI. And no your code is not allowed to mix and match destinations with connection factories, or sessions.

The preferred thing is to define your destinations in the URI form and instantiate them from the session created off the connection (created off the connection factory). This gives you more flexibility than retrieving the queue from JNDI as you can have the URI retrieved from a resource bundle or properties file... 

The URI form of the destination should be as much implementation agnostic as possible. The following example ("queue://qmgr/qname?property=value&property=value...") is the MQ URI form for a queue. 
You may notice the qmgr/queue pair which could be considered as implementation specific... 

Your generic form is ("destinationtype://implementation naming?property=value&property=value..."). The property value pairs are mostly generic but can also be implementation specific. 

REF:
Very good website for JMS concepts
http://www.ibm.com/developerworks/websphere/techjournal/0610_woolf/0610_woolf.html-For knowing more about standing Java application communicating with JMS Provider Messaging system