C H A P T E R 13 |
Using the MQ-JMS Bridge |
Note - Read Chapter 12 before reading this chapter. |
The Sun MTP MQ-JMS Bridge provides a mapping between the Sun MTP MQSeries trigger mechanism and applications developed to the Java Message Service (JMS) API. The MQ-JMS Bridge is responsible for handling the MQSeries trigger message initiated by the Sun MTP unikixqm daemon and forwarding the associated application messages to a configured user application program. The JMS point-to-point model is used as the underlying JMS messaging style.
At a high level, this provides an abstraction of the transaction initiation mechanism. The target application is oblivious to the means of initiation, and it is only interested in the application message that describes the work to be performed. At a lower level, this relieves the application developer from having to manage the underlying MQSeries queue manager and application queue. The application only needs to respond to invocations to the application implementation of the JMS MessageListener.onMessage() method.
This chapter contains the following topics:
The MQ-JMS Bridge is built upon the existing MQSeries trigger framework. In this framework, the unikixqm daemon is notified whenever an MQSeries trigger message is placed on the monitored queue. unikixqm then initiates a specified Sun MTP transaction to process the associated application queue. This framework is enhanced by defining the MQ-JMS Bridge as the initial application, rather than a user application, thereby providing a level of indirection to the processing flow.
The MQ-JMS Bridge is responsible for processing the MQSeries trigger message and using the supplied information to access the application queue and obtain an instance of the user application program. The MQ-JMS Bridge then processes the application queue, reading each message and passing it on to the user JMS application through its MessageListener.onMessage method. The following figure shows the basic concept.
The elements shown in FIGURE 13-1 are:
Client Application: Creates messages on the input data queue. The client application is independent of Sun MTP.
Data Queue: Places trigger messages on the trigger queue that define Sun MTP transactions.
Trigger Queue: Receives automated messages through procedures configured in the queue manager. Trigger messages contain information used by Sun MTP to start transactions, and used by the transaction processors to find the original data messages that spawned the trigger event.
unikixqm: Monitors the trigger queue and starts the transaction based on the Application ID in the trigger message. In the case of JMS application transactions, the transaction started by unikixqm is always the MQ-JMS Bridge.
MQ-JMS Bridge: Responsible for retrieving messages from the data queue and starting the appropriate JMS application, supplying the data message upon invocation.
JMS Application: Implements the MessageListener interface and, therefore, must supply an onMessage method with one parameter of type Message. The JMS application received the original data message from the data queue through the MQ-JMS Bridge. Any further interaction with MQSeries is the responsibility of the JMS application. It can create connects to the queue manager using the same configuration information used by the MQ-JMS Bridge. See the GetAliasJMSListenerEXMQJMS sample program in the $UNIKIX/test/mq/jms directory for an example of queue manager interaction from a JMS application.
The MQ-JMS Bridge extends the MQSeries trigger configuration shown in CODE EXAMPLE 12-1 to define the target user application that will be scheduled when a new trigger message is generated.
To define the user application, use either of these methods:
The configuration shown in this example causes the unikixqm daemon to initiate the MQJV transaction. The message that starts the transaction contains the trigger properties information, which includes the USERDATA attribute specifying the target application name scouser.GetAliasJMSListenerExMQJMS.
This section describes how to configure your region to use the MQ-JMS Bridge.
Before configuring the MQ-JMS Bridge, you must:
To configure the MQ-JMS Bridge itself, you must perform these tasks:
The program associated with the MQ-JMS Bridge product is assigned to the jms group. To enable your region to access this program, you must define the jms group in the GCT.
1. In the Table Manager, open the GCT and press PF4 to insert an entry.
2. On the insert screen, type jms as the group name and $KIXSYS/jms.dir as the directory.
See FIGURE 13-2.
3. Press Enter to insert the entry and return to the GCT main screen.
4. Press PF2 to write the changes to disk.
6. Shut down and restart the region so your changes take effect.
1. Open the PPT and put your cursor on the JMQJMSB program entry.
2. Press PF9 to open the Java Class Details screen.
The fully qualified class path for the MQ-JMS Bridge application is displayed on this screen. The program JMQJMSB is associated with the Java class file named com.sun.emp.mtp.MQJMS.MQJMSBridge.
FIGURE 13-3 shows the Java Class Details screen for the JMQJMSB program.
To Associate a Transaction ID With the MQ-JMS Bridge Program |
Note - The PCT for the sample application in $UNIKIX/test/mq/jms already contains the entries described here. |
1. Open the PCT and press PF4 to insert an entry.
2. Type JMQJMSB in the Program field.
3. Type a transaction identifier in the Trans ID field.
FIGURE 13-4 shows the JMQJMSB program is assigned to the MQJV transaction. JMQJMSB must be the first program executed when the transaction ID is issued.
This transaction ID must match the Application ID in the MQSeries trigger configuration. For example, the transaction ID shown in the following figure (MQJV) matches the value set in APPLICID shown in CODE EXAMPLE 13-1.
4. Press Enter to insert the entry.
5. Press PF2 to save the table to disk.
6. Shut down and restart the region.
Now there is a relationship between the MQSeries trigger queue and the MQ-JMS Bridge application.
The MQ-JMS Bridge uses a configuration file that contains attributes for the product. The configuration file attributes that can be applied at two levels:
The attributes at the overall level are typically related to MQSeries-specific configuration, such as the queue manager location. Application attributes enable the mapping feature whereby a target application can be mapped to some other application before the MQ-JMS Bridge attempts to locate an instance.
Note - Maintaining the MQJMS.properties file in the $KIXSYS/kix_java directory enables each Sun MTP region to have a unique MQ-JMS configuration. |
1. Copy the $UNIKIX/lib/kix_java/MQJMS.properties file to your region's $KIXSYS/kix_java directory.
See Customizing the Classpath and Library Path for instructions on creating the kix_java directory.
2. Modify the file to meet your site requirements.
The configuration file follows the Java property file format, using a series of
key=value string pairs. The following table describes the overall attributes and their default values.
Fully qualified class name of user application to be loaded for this request. This value is only used if MQTM-USERDATA is not defined in the trigger message (that is, it has a value of spaces). Can be modified using the application mapping feature of the MQ-JMS Bridge. |
||
Name of the server channel to use to connect to the MQSeries queue manager. |
||
Name/address of the server where the MQSeries queue manager is executing. |
||
Specifies whether or not MQ-JMS Bridge processing events will be logged to the unikixmain.dbg file. Supported values are: See Debugging Information for information about the types of processing events that are logged. |
||
Specifies the scope of the Sun MTP unit-of-work. Supported value is message, which specifies that each message is processed within a single Sun MTP unit-of-work. That is, each successful onMessage() invocation is followed by a SYNCPOINT (Task.commit()). |
Regardless of the type of MQSeries triggering used (FIRST, EVERY, or DEPTH), the user JMS application deployed in Sun MTP (the consumer of the application messages) is unaware of the messages on the MQSeries queue. The user JMS application is invoked for each message that is retrieved from the MQSeries queue and there is no correlation between successive invocations. For the user JMS application to envelope each onMessage() invocation in a separate Sun MTP unit-of-work, the txscope attribute of the MQ-JMS Bridge properties file can be set to the value message.
Note - In this release, the only valid attribute for txscope is message. |
If the Sun MTP region and MQSeries queue manager are executing on the same host, there is a single MQSeries queue manager configured that acts as the default queue manager. In this case, if no application mapping is required, no MQ-JMS Bridge configuration file is needed. The sample application in $UNIKIX/test/mq/jms is based on this scenario.
If the Sun MTP region and MQSeries queue manager are on different hosts, the MQSeries queue manager has a special channel defined for communication between the MQSeries client applications (unikixqm and the MQ-JMS Bridge in this case) and the queue manager. The MQJMS.properties file must contain the host and channel values defined in the MQSERVER environment variable. For example, if MQSERVER=MYSVRCHNL/TCP/myserver, the MQJMS.properties file must contain the following entries:
In general, the MQ-JMS Bridge configuration file will mirror parameters defined for the unikixqm process in the unikixrc.cfg file and in the MQSERVER environment variable. Java retrieves the MQSeries configuration from this properties file, rather than from the runtime environment. See To Configure the Region to Use MQSeries for information about $MQSERVER.
Application mapping is the technique of mapping one application target to some other target. For example, it enables an application identified as MQJMSAppl_GetAlias to be replaced by one identified as scouser.GetAliasJMSListener.
When using mapping, the target user JMS application is defined in the MQJMS.properties file rather than explicitly in the MQSeries PROCESS definition by the USERDATA attribute. This enables you to change the back-end application by simply changing the single MQJMS.properties file instead of the many MQSeries PROCESS definitions that might exist.
To implement application mapping, specify a token or alias, rather than the fully qualified class name of the user application, in the USERDATA attribute of the MQSeries PROCESS definition. This token is defined in the MQJMS.properties file as a key with the target application defined as the corresponding value.
CODE EXAMPLE 13-2 shows how the MQJMSAppl_GetAlias logical token is mapped to the JMS application scouser.GetAliasJMSListener.
Note - The USERDATA attribute could contain a real application target, such as scouser.GetAliasJMSListener. See CODE EXAMPLE 13-1. |
See Processing Flow for more information about how application mapping works.
The JCICS framework uses the Sun MTP environment variable KIXPROGS to establish an application classpath attribute to the JVM. Typically, this is how user Java applications are configured in the region, and it is how the user JMS applications should be defined to the region. The MQ-JMS Bridge application is a system application and as such, is configured in Sun MTP as part of the standard Sun MTP system JAR files.
The MQSeries MQ-JMS archive files (com.ibm.mqjms.jar and com.ibm.mq.jar) and the Sun archives (jms.jar and jndi.jar) must be available for the JVM to successfully load the MQ-JMS Bridge application. The archives must be defined by using the Classpath.appends file.
The Classpath.appends file must be placed in the $KIXSYS/kix_java directory. By editing this file and adding the necessary directory files (for example, /opt/mqm/java/lib/com.ibm.mqjms.jar), the dependent archives can be accessed by the JVM. See Customizing the Classpath and Library Path for instructions on setting up the kix_java directory and its contents.
You must also place the Libpath.appends file in the $KIXSYS/kix_java directory. You must include the following path in this file:
where MQ-installdir is the directory where MQSeries is installed. You must also add the paths to any other libraries needed by the JVM.
To use the MQ-JMS Bridge, you must set the MQSERIES environment variable to:
where MQ-installdir is the directory where MQSeries is installed. This is different from the setting when you are using MQSeries without the MQ-JMS Bridge (see Chapter 12).
The high-level flow of control for each trigger message is as follows:
1. Retrieve the MQSeries trigger message.
2. Load an instance of the specified JMS application.
3. Access the specified application queue.
4. For each message in the application queue:
b. Invoke the application MessageListener.onMessage(Message) method.
If you set the debug attribute to yes in the MQJMS.properties file, logging information is written to the $KIXSYS/unikixmain.dbg file. An example of each type of event entry is shown in the following sections.
Refer to the IBM MQSeries documentation and the IBM MQ-JMS documentation for detailed information about these events.
At the start of the transaction, the MQJMS.properties arguments are listed:
07/25/2001 14:58:08 MQJMSBridge :Triggered transaction start: Check MQJMS.properties File: chan=CHANNEL1 host=nacelle port=1414 txscope=message |
This entry lists the format of the received trigger message:
This entry lists the target application to be accessed:
The following entry names the connected receiver queue:
The onMessage event entry lists details about the input message passed to the onMessage() method of the target application. Each started event entry is followed by a unit-of-work commit entry (see Unit-of-Work Commit complete Event).
The following example is a byte message:
The following example is a text message:
This entry indicates that a commit was done on behalf of the target application:
This entry indicates that the receiver queue has no more messages on it:
Because the receiver queue is empty, the MQ-JMS Bridge will close down the input queue:
The triggered transaction cycle is complete. If a new message arrives on the receiver queue, the MQSeries service will build a new trigger message and the entire sequence starts over.
The MQ-JMS Bridge sample application is located in the $UNIKIX/test/mq/jms directory. The following README.doc file contains the instructions for setting up your region and running the application.
The MQ-JMS Bridge works only with JMS Java applications. However, COBOL or other applications can exist in the same application space, placing messages on the queue or removing them. The common point of reference is the MQSeries trigger queue itself.
One version of the JMS sample application in the $UNIKIX/test/mq/jms directory places the output on an MQSeries queue named UNIKIXMQ2. Using that as an input queue, a triggered COBOL application can process the data from UNIKIXMQ2.
To Use the MQ-JMS Bridge to Trigger a COBOL Program |
1. Make the changes shown in CODE EXAMPLE 13-4 to the MQSeries configuration file (kixmqtst.mqconfig) to define the UNIKIXMQ2 queue.
These changes tell the MQSeries service that if a message is placed on UNIKIXMQ2, a trigger message is to be created, and the triggered process is the KMQ2 transaction.
2. Put the configuration into the queue manager by using the runmqsc command on the MQ Server. For example:
where TESTMQ is the queue manager name and config-file is the name of the configuration file.
3. In the PCT, add the COBOL program KIXMQ01 and associate the transaction ID KMQ2 with it.
4. In the PPT, add the COBOL program KIXMQ01.
5. Copy the COBOL program KIXMQ01.cl2 from $UNIKIX/test/mq/cobol to $UNIKIX/test/mq/jms.
6. Edit the makefile in the $UNIKIX/test/mq/jms directory to include the translation and compilation of the COBOL program.
See the makefile in the $UNIKIX/test/mq/cobol directory for an example. Re-make the entire application.
7. Start the region and run the sample application as before.
You can use the CEBR transaction to view the temporary storage queue MQTEST01. The output that used to be on UNIKIXMQ2 is now on the MQTEST01 queue.
Copyright © 2004, Sun Microsystems, Inc. All rights reserved.