Monday, August 25, 2008

IBM WebSphere MQ and Tomcat JNDI

IBM WebSphere MQ is not really built out of the box to provide JMS and Publish/Subscribe. Essentially the JMS implementation is achieved through a broker and a lot of system queues. There are two steps to getting Tomcat to work with MQ.

1.1 MQ Configuration

Prior to configuring the MQ Server 6.0, download the following support packs:

  • 6.0.2-WS-MQ-WinIA32-FP0004-EnUs.zip – This is the 6.0.2.4 Update and provides a bit better JMS implementation. It certainly updates the jar files for JMS.
  • ms0q.zip – This just makes it easier to see and edit the publish/subscribe topics in the MQ Explorer. It adds a Topic folder to the queue manager.

If you are using MQ 7.0, I believe it has the above and has a totally different JMS implementation and so will require confirmation of the MQ configuration.

The process below assumes some basic knowledge of WebSphere MQ, for example how to create queues. It is also important to understand the connection mode; there are two ways for an application to connect to the WebSphere MQ queue manager, the modes are:

  • Bindings mode is the native connection mode for WebSphere MQ. In bindings mode, a JMS application must run on the same host machine as the queue manager, and they will communicate using Inter-Process Communication (IPC) protocols.
  • In client mode, a JMS application establishes a network session with the queue manager's agent process, usually over TCP/IP. The agent then talks to the queue manager using bindings mode, performing API calls on behalf of the application.
1.1.1 Configure WebSphere MQ
1.1.1.1 Create a queue manager.

There are many different options available when creating queue managers, but the ones we really care about are that it is configured with a dead letter queue, and that it is configured as the default queue manager:

The dead letter queue is used by the queue manager and Java classes to hold messages that cannot be delivered to their intended destination. It is considered a best practice for each queue manager to have a dead letter queue.

When a queue manager is configured as the default queue manager, applications can access it without knowing its name.

  1. From the Windows® Start menu, navigate to All Programs => IBM WebSphere MQ => WebSphere MQ Explorer. Once the WebSphere MQ Explorer is running, right-click on the Queue Managers folder. then select New => Queue Manager to start the New Queue Manager wizard.
  2. When the wizard opens, type in the queue manager name QM and check the box to Make this the default queue manager. Next, enter the name of the default Dead Letter Queue which is SYSTEM.DEAD.LETTER.QUEUE. Be sure to enter it in all capital letters.
  3. Select Next and Next. Ensure the Create Server Connection Channel is checked and select Next.
  4. Enter the port for the Server Connection Channel (1480).
  5. Pressing the Finish button at his point will build the queue manager with all of the default settings. Among these are that:

· the queue manager will be started immediately.

· the queue manager will be set to start when the computer is rebooted.

· a new listener will be created and started on port 1480.

  1. The new queue manager should now be visible in the WebSphere MQ Explorer window.
1.1.1.2 Create a queue.

Defining queues from the WebSphere MQ Explorer is also quite easy:

  1. Click the plus sign next to the queue manager to expand the folder tree, and then click on the Queues folder. System queues are filtered out by default, and since the queue manager has just been built, there should be no queues visible in the right-hand pane.
  2. Next, right-click on the Queues folder and select New => Local Queue on the context menu to open the Local Queue wizard.
  3. In the wizard, type IncomingQueue as the name of the queue and click the Finish button. The JNDI directory entry we create later will look for this specific queue name so enter it exactly as shown.
  4. When the wizard completes, the new queue should be visible in the Queues window.
  5. Repeat the above process for the OutgoingQueue
1.1.1.3 Create a Channel
  1. From the Windows® Start menu, navigate to All Programs => IBM WebSphere MQ => WebSphere MQ Explorer.
  2. Click the plus sign next to the queue manager to expand the folder tree, click the plus sign next to the Advanced to expand the folder tree.
  3. Next, right-click on the Chanell folder and select New => Server Channel on the context menu to open the Channel wizard.
  4. Enter the name of the service, SVR_CHANNEL, Select Next and then select Finish.
1.1.1.4 Set up publish/subscribe

So far, we have defined and started a queue manager and created a queue for point-to-point messaging. There are a couple of additional steps required to set up for publish/subscribe. The broker stores its internal state in queues we will need to create before we can start it. IBM has provided all the definitions in a command script, so all we need to do is to run the script inside the runmqsc command interpreter. Once that is done, we will set up the publish/subscribe broker to start and end under control of the queue manager.

  1. Open a command window and navigate to the directory where WebSphere MQ is installed. From there, drill down into the Java/bin directory where you will find the MQJMS_PSQ.mqsc script. Execute runmqsc and redirect this script into it as input. Redirect the output to a file so you can look at it later (see Figure 11).

clip_image001[4]

· Figure 11 - RunMQSC Command

  1. Next, we need to configure the broker as a service. WebSphere MQ services are a new feature as of Version 6, and a service named SYSTEM.BROKER is provided for this purpose. You can use the method displayed in Figure 11 but it’s a lot easier to go into the WebSphere MQ Explorer and set it up.
  2. .Click the plus sign next to the queue manager to expand the folder tree, click the plus sign next to the Advanced to expand the folder tree and then click on the Services folder.
  3. Next, right-click on the Services folder and select New => Service on the context menu to open the Service wizard.
  4. Enter the name of the service, PublishSubscribeBroker and click the select button to change the service to use as an attribute template, this will open a list of service types.
  5. Select SYSTEM.BROKER and OK to close the window. Select Next.
  6. In the next screen, change the service control from Manual to Queue Manager Start.
  7. Select Finish. The Service is now created. Right mouse click the service and select start.
1.1.1.5 MQ Authorisation

Now the user needs to be authorized for the queue and the queue manager. As the security could be provided by a number of directory services, I have just supplied the command to run. It is assumed that your infrastructure/network group will know how to set the user up in the directory. AIG Australia uses the Active Directory domain.

The commands to run are:

setmqaut -t qmgr -p "test" +all

setmqaut -t qmgr –m QM -p "test" +all

setmqaut -m QM -n IncomingMessage -t queue -p "test" +all

setmqaut -m QM -n OutgoingMessage -t queue -p "test" +all

1.1.2 Tomcat Configuration

First of all, there are a lot of processes on the web for setting up MQ as a JNDI resource for Tomcat. Unfortunately all of them are wrong in some way. This is mostly due to the fact that they are either using bindings mode or are written for an older version of MQ. The IBM web site especially has a lot of articles using the WMQInitialContextFactory or the RefFSContextFactory which use bindings mode, will only work on the MQ server or are plain incorrect.

1.1.2.1 Client Install and Libraries

The Tomcat server requires the MQ client installed and the following libraries installed in the Tomcat\common\lib directory.

Libraries from MQ Client (although this should not be required if the classpath is pointed to the MQ client Java directory correctly):

  • com.ibm.mq.jar
  • com.ibm.mq.soap.jar
  • com.ibm.mqetclient.jar
  • com.ibm.mqjms.jar
  • connector.jar
  • dhbcore.jar
  • fscontext.jar
  • jms.jar
  • jndi.jar
  • postcard.jar

Libraries from the Geronimo project (this provides the underlying JMS provider). To be honest I am not sure if this is required but it doesn’t hurt.

  • geronimo-j2ee-management_1.1_spec-1.0.1.jar
  • geronimo-jms_1.1_spec-1.1.1.jar
1.1.2.2 JMS Code

The JNDI configuration below works for the following JMS code (this code also works for ActiveMQ):

// Lookup JNDI for our connection factory and topics

InitialContext initCtx = new InitialContext();

_connectionFactory = (TopicConnectionFactory) initCtx.lookup(“java:/comp/env/ConnectionFactory”);

_incomingMessageTopic = (Topic) initCtx.lookup(“java:/comp/env/IncomingMessages”);

// Establish connection (if one exists, close it first)

_connection = _connectionFactory.createTopicConnection(_username, _password);

_connection.setClientID(_clientid);

_connection.start();

The main thing to notice in the above code is that it is using topics. The JNDI configuration is also valid for queues. In either case the connection requires a username and password as well as the clientid.

1.1.2.3 JNDI Resource Configuration

The resource configuration is shown below. In this case topics are used. If queues are used the Queue classes have to be used, in which case change the word Topic to Queue (for example, MQQueueConnectionFactory).

The Reference table below provides the extra attributes which can be used. You must use the short form as some of the long forms don’t work.

<Resource name="ConnectionFactory" auth="Container" type="com.ibm.mq.jms.MQTopicConnectionFactory" factory="com.ibm.mq.jms.MQTopicConnectionFactoryFactory" description="JMS Queue Connection Factory for sending messages" HOST="localhost" PORT="1480" CHAN="SVR_CHANNEL" TRAN="1" QMGR="QM"/>

<Resource name="IncomingMessages" auth="Container" type="com.ibm.mq.jms.MQTopic" factory="com.ibm.mq.jms.MQTopicFactory" description="JMS Topic for recieved messages" TOP="IncomingMessages" BPUB="IncomingMessage" />

6.1.2.4       Reference for the resource attributes:

The following table details the attributes which can be used to setup a JNDI resource for WebSphere MQ.

Property

Short form

Valid values (defaults in bold)

BROKERCCDSUBQ

CCDSUB

SYSTEM.JMS.D.CC.SUBSCRIPTION.QUEUE

Any string

BROKERCCSUBQ

CCSUB

SYSTEM.JMS.ND.CC.SUBSCRIPTION.QUEUE

Any string

BROKERCONQ

BCON

Any string

BROKERDURSUBQ

BDSUB

SYSTEM.JMS.D.SUBSCRIPTION.QUEUE

Any string

BROKERPUBQ

BPUB

SYSTEM.BROKER.DEFAULT.STREAM

Any string

BROKERQMGR

BQM

Any string

BROKERSUBQ

BSUB

SYSTEM.JMS.ND.SUBSCRIPTION.QUEUE

Any string

BROKERVER

BVER

V1 - To use the WebSphere MQ broker. Also for use of the WebSphere MQ Integrator V2 or WebSphere MQ Event Broker brokers in compatibility mode.

V2 - To use WebSphere MQ Integrator V2 or WebSphere MQ Event Broker brokers in native mode

CCSID

CCS

Any positive integer

CHANNEL

CHAN

Any string

CLEANUP

CL

SAFE

ASPROP

NONE

STRONG

CLEANUPINT

CLINT

60000

Any positive integer

CLIENTID

CID

Any string

DESCRIPTION

DESC

Any string

EXPIRY

EXP

APP - Expiry may be defined by the JMS application.

UNLIM - No expiry occurs.

Any positive integer representing expiry in milliseconds.

HOSTNAME

HOST

Localhost/Any string

MSGBATCHSZ

MBS

10

Any positive integer

MSGRETENTION

MRET

Yes - Unwanted messages remain on the input queue

No - Unwanted messages are dealt with according to their disposition options

PERSISTENCE

PER

APP - Persistence may be defined by the JMS application.

QDEF - Persistence takes the value of the queue default.

PERS - Messages are persistent.

NON - messages are non-persistent.

POLLINGINT

PINT

5000

Any positive integer

PORT

 

1414 (for TRANSPORT set to BIND or CLIENT); 1506 (for TRANSPORT set to DIRECT)

Any positive integer

PRIORITY

PRI

APP - Priority may be defined by the JMS application.

QDEF - Priority takes the value of the queue default.

Any integer in the range 0-9.

PUBACKINT

PAI

25

Any positive integer

QMANAGER

QMGR

Any string

QUEUE

QU

Any string

RECEXIT

RCX

Any string

RECEXITINIT

RCXI

Any string

SECEXIT

SCX

Any string

SECEXITINIT

SCXI

Any string

SENDEXIT

SDX

Any string

SENDXITINIT

SDXI

Any string

STATREFRESHINT

SRI

60000

Any positive integer

SUBSTORE

SS

MIGRATE/QUEUE/BROKER

SYNCPOINTALLGETS

SPAG

Yes/No

TARGCLIENT

TC

JMS - The target of the message is a JMS application.

MQ - The target of the message is a non-JMS, traditional WebSphere MQ application.

TEMPMODEL

TM

Any string

TOPIC

TOP

Any string

TRANSPORT

TRAN

BIND - Connections use WebSphere MQ bindings.

CLIENT - For a client connection

DIRECT - For direct connection to WebSphere MQ Event Broker broker

USECONNPOOLING

UCP

Yes/No

Sunday, August 17, 2008

Jack’s 3rd Birthday or there is not enough pink in this world!

Well Jacks third birthday went off well. Thanks to all the people who came. I have uploaded lots of photos on facebook but only available to friends as there’s other peoples’ kids in there, so become one!

Of course everything that could be Dora and pink was. She had great fun running around with all her friends. Unfortunately I was totally brain-dead having spent most of the night up with the boys.

Saturday, August 9, 2008

Soap Interop

I am having fun with SOAP interop at the moment, especially SOAP with attachments (SwA). Its funny but ACORD now have this in their standard but .Net does not seem to support it. And the more I look into SwA the more it looks to be used in the Java world.

The funny thing is that this technology is so old and so seems to have been passed-by in Microsoft. So what do I do. Well it seems you have to use horrible work around's based on 2003 code or buy a component from somebody who has probably encapsulated that horrible workaround.

It seems the best methodology is to create a SOAP extension which embeds the MIME in the XML and then converts it back outgoing.

Or there is the option of going to the Java side…… “Luke,I am your father”

Alain Bourdain

I have just read Alain Bourdain’s Kitchen Confidential. It is one of those - stories from my life type of books. The book is really quite good, of course, the hype about the disgusting practices or the hidden secrets of kitchens is all bull. In my opinion it states the bleeding obvious. For example, if you go to a fish restaurant and order steak, they are going to be getting the frozen stuff from the back of the freezer because they don’t serve that. Basically order what is being sold.

Also if you go to a restaurant when they are busy its not going to be their best (time taken) job. What was interesting was the picture of practices in kitchen. Gordon Ramsay really doesn’t swear that much etc.

So overall I’d recommend it.

Love my phone

I love my HTC Cruise. Full stop nuff said.