Chapter 2 . Developing Message Queuing Applications

This chapter describes how to develop message queuing applications that use MessageQ MQSeries Connection to exchange messages. It covers the following topics:


Using Application Programming Interfaces

You should be familiar with the MessageQ and MQSeries application development environments and follow the coding standards required by each. If you are writing the MessageQ half of an application, you must code the MessageQ application programming interfaces (API) for attaching to the bus, locating target queues, sending and receiving messages, and controlling the application message flow.

Conversely, if you are writing the MQSeries half of the application, you must code to the MQSeries message queuing interface (MQI) for connecting to a Message Queue Manager (MQM), opening and closing queues, sending and receiving messages, and controlling the message flow.

Recall that your application interacts with the local messaging system (the one that your application is attached or connected to). Forwarding messages to another messaging system is the responsibility of the Queue Message Bridge (QMB) and is not directly under your application's control.


Designing Applications to Use MessageQ MQSeries Connection

Exchanging messages between MessageQ and MQSeries applications is complex because it requires knowledge of how messages are sent and received by each system. The QMB performs the transformation of the message header data into the format required by the message queuing system running on the receiver platform, but the application developer must understand how the QMB performs the transformation to ensure the correct result. You can use the MessageQ MQSeries Connection to exchange information between both new and legacy applications. Legacy applications may require some alteration unless they use only a simple datagram or request/reply paradigm.

When designing message-driven applications, you must decide how the messages are to be sent and received. You may want to design your application so that it sends a request and receives a reply. Or, you may want it to send a datagram message only. To have your application behave in the way you want it to, you must design the following into your application:

This topic describes the key design considerations for integrating applications that exchange messages between MessageQ and MQSeries applications.

Determining Queues that Your Application Needs

When designing message-based applications, you must determine what services are needed by your application and how to access these services. In message-based applications, your application accesses target applications by sending a message to a queue that is controlled by the target. This queue must be known and accessible to the application sending the message.

Because the QMB provides communication services to both MessageQ and MQSeries applications, it must present queues to each messaging system in a way that the messaging system recognizes. MessageQ MQSeries Connection does this through the QMB Local Service Queue (LSQ). The receiving application is located on the target messaging system and is listening on a queue known as the Remote Service Queue (RSQ). The QMB manages the LSQ and maintains the LSQ to RSQ relationship.

Before a configured MQSeries or MessageQ queue can be used as a QMB LSQ or RSQ, you must configure it appropriately in the QMB queue configuration file. The entries in this file determine the LSQ to RSQ relationship.

For more information on the QMB configuration file, see the Configuring the Queue Message Bridge topic.

Defining Queues for MessageQ Clients to MQSeries Servers

To define queues for applications that send messages from MessageQ clients to MQSeries servers, follow these steps:

  1. Define the RSQ that receives the message to be processed by the MQSeries server. This queue must be defined in one of the following ways:

  2. Define the MessageQ LSQ in the QMB configuration file. Use the defined MQSeries RSQ (as defined in step 1) as the permanent RSQ to a physical MessageQ LSQ. All messages arriving on the LSQ from MessageQ clients are mapped and forwarded to this RSQ and eventually read by the MQSeries server.

  3. Define the MessageQ LSQ to the MessageQ group that the QMB is attached to. The MessageQ name of this queue must be the same name defined in the QMB configuration files as the LSQ for this service. The queue type must be a multireader queue.

  4. If the MessageQ clients that want to access this service are not on the same MessageQ group that the QMB is attached to, the appropriate MessageQ cross-group configurations must be in place to allow access from remote groups.

  5. For the MQSeries server program to successfully send a reply back to a MessageQ client, an MQSeries reply queue must also exist. See the Defining Queues for MessageQ Clients to MQSeries Servers topic for more information.

For information on defining MessageQ queues, see the MessageQ Installation and Configuration Guide for UNIX.

Defining Queues for MQSeries Clients to MessageQ Servers

To define queues for applications that send messages from MQSeries clients to MessageQ servers, follow these steps:

  1. Define the MessageQ server queue. This is the queue that the MessageQ server program reads messages from. It must be defined in the target MessageQ group. If the target group is not the same group that the QMB is attached to, the appropriate MessageQ cross-group definitions must be in place to allow the message to be forwarded to the target group for placement into the server queue. Also, there must be an RSQ (server queue name and address) entry in the local MessageQ group name table to allow the QMB programs to locate the server queue address.

  2. Define the MQSeries LSQ to the local MQM (the MQM that the QMB is connected to). The LSQ is a QLOCAL shared queue. See the Configuring MQSeries topic for more information on MQSeries queue characteristics.

  3. Add an entry to the QMB configuration file that associates the MQSeries LSQ for the service to the MessageQ RSQ that supplies the service. See the Configuring the Queue Message Bridge topic for more information.

  4. For the MessageQ server program to successfully send a reply back to the MQSeries client, a MessageQ reply queue must also exist. See the Configuring the Queue Message Bridge topic for more information.

  5. If the MQSeries client that wants to use the defined service is not on the local MQM (the same one that the QMB is connected to), then you must implement one of the MQSeries Distributed Queue Manager (DQM) queue name resolution schemes to allow the messages to be forwarded back to the remote client MQM. See the MQSeries Distributed Queuing Guide for more information on DQM.

For information on defining MQSeries queues, see the MQSeries Command Reference Manual.


Choosing Message Characteristics

When designing message queuing applications, you will have to decide the characteristics of the message that your application will send. The characteristics of the message can determine the behavior of the receiving application, so it is important that you select the correct characteristics. The following topics describe some of the message characteristics from which you can choose:

Selecting the Type for Message Exchange

You can use the QMB to exchange the following types of messages:

The QMB determines the type of message using the MessageQ message type and class fields or by using the MQSeries MsgType header.

Processing Reply Messages

An application program must give special consideration to a request type message exchange. Certain rules must be followed to allow the successful delivery of the reply to the originating application's reply queue. Applications that intend to send reply messages must adhere to the following rules:

  1. Send the reply message to the sending application's reply queue. This information was received with the request and can be determined as follows:

  2. Include the CI that was received with the request in the appropriate message header field of the reply message.

The QMB uses an internally created entity, known as a Connection Index (CI), to link a reply message to a reply target. This CI is carried in a message header field of the request and returned in the same field of the reply.

The QMB passes the CI in the appropriate message header fields. The actual data structure used in the message header fields varies depending on the direction of the request message as follows:

For the ApplIdentityData field to pass the CI, call MQOPEN to open the MQSeries queue with the MQOO_SET_ALL_CONTEXT option. Then, construct all put messages with the MQPMO_SET_ALL_CONTEXT option.

Processing Multiple Replies

MessageQ MQSeries Connection supports multiple replies from a single request. Because of the difference in the way reply messages are processed by MessageQ or MQSeries, the rules for sending multiple replies are different. These differences are explained in the following topics:

How MQSeries Applications Process Multiple Replies

The MQSeries application sending the replies formats the data of each reply, includes the ApplIdentityData, and sends the message to the ReplyToQ and ReplyToQMgr received in the request message descriptor. The MQSeries application repeats this for each reply until complete.

Listing 2-1 shows an MQSeries server code fragment, which gets messages, processes them, and sends a reply.

Listing 2-1 MQSeries Server Code Fragment to Send a Reply
/*****************************************************************/
/* MQSeries Server Code Fragment to Get messages from the */
/* message queue, process the message, and send a reply */
/* request. */
/*****************************************************************/
/* Open the message queue for shared input. */
/*****************************************************************/
memcpy(odG.ObjectName, /* Name of input queue */
QName,
MQ_Q_NAME_LENGTH);

O_options = MQOO_INPUT_SHARED /* Open queue for shared input */
+ MQOO_FAIL_IF_QUIESCING,
+ MQOO_SAVE_ALL_CONTEXT; /* Allow context passing */

MQOPEN(Hcon, /* Connection handle */
&odG, /* Object descriptor for queue */
O_options, /* Open options */
&Hobj, /* Object handle */
&CompCode, /* MQOPEN completion code */
&Reason); /* Reason code */

if(Reason != MQRC_NONE)
{
}
if(CompCode == MQCC_FAILED)
exit(Reason);
.
.
.
buflen = sizeof(buffer) - 1;
while (CompCode == MQCC_OK)
{
gmo.Options = MQGMO_ACCEPT_TRUNCATED_MSG
+ MQGMO_WAIT; /* Wait for new messages */

gmo.WaitInterval = MQWI_UNLIMITED; /* Waiting forever */
md.Encoding = MQENC_NATIVE;
md.CodedCharSetId = MQCCSI_Q_MGR;

MQGET(Hcon, /* Connection handle */
Hobj, /* Object handle */
&md, /* Message descriptor */
&gmo, /* GET options */
buflen, /* Buffer length */
buffer, /* Message buffer */
&messlen, /* Message length */
&CompCode, /* Completion code */
&Reason); /* Reason code */

if (Reason != MQRC_NONE)
printf("MQGET: ended with reason code %ld\n", Reason);

if ((CompCode == MQCC_OK) || (CompCode == MQCC_WARNING))
{ /* Check byte order ENDIAN */
if((strncmp(md.ApplOriginData,"BEND",4)) == 0)
{
}
else if((strncmp(md.ApplOriginData,"LEND",4)) == 0)
         {
}
/*******************************************************/
/* Only process REQUEST messages */
/*******************************************************/
if (md.MsgType == MQMT_REQUEST)
{
/*****************************************************************/
/* Send reply using MQPUT1 */
/*****************************************************************/
md.MsgType = MQMT_REPLY;

/*****************************************************************/
/* Copy the ReplyToQ name to the object descriptor. */
/* Copy the ReplyToQMgr name to the object descriptor. */
/*****************************************************************\
strncpy(odR.ObjectName, md.ReplyToQ, MQ_Q_NAME_LENGTH);
strncpy(odR.ObjectQMgrName, md.ReplyToQMgr,
MQ_Q_MGR_NAME_LENGTH);

md.Report = MQRO_NONE; /* No report data. */
pmo.Options = MQPMO_SET_ALL_CONTEXT + /* Allow DMQ address*/
MQPMO_FAIL_IF_QUIESCING;/* to be passed in */
pmo.Context = Hobj; /* md.ApplIdentityData*/

/*****************************************************************/
/* Because this code fragment uses the same message descriptor */
/* (md.) for both receiving and sending messages, we do not have*/
/* to save the ApplIdentityData field and copy to the output MD */
/* before we send the reply. If separate input and output */
/* message descriptors were used, a copy would be required. */
/* The ApplIdentityData field carries the DMQ client address, */
/* which is the end target for the reply data. */
/*****************************************************************/

send_reply = process_message(buffer);

while(send_reply > 0)
{
-=send_reply;

MQPUT1(Hcon, /* Connection handle */
&odR, /* Object descriptor */
&md, /* Message descriptor */
&pmo, /* Default options */
messlen, /* Message length */
buffer, /* Message buffer */
&CompCode, /* Completion code */
&Reason); /* Reason code */

if(Reason != MQRC_NONE)
printf("MQPUT1: ended with reason code %ld\n", Reason);

} /* End send_reply. */
} /* End request. */
} /* End message for reply. */
} /* End Get message loop. */

How MessageQ Applications Process Multiple Replies

Typically, when a message queuing application responds to a request, the reply may be one in a series of messages, the last in a series, or the only message. The way that a MessageQ application indicates this is to use the message header type field in the reply. If the message type field is a positive integer, the reply is the only or last message. If the message type field is negative, the reply is one in a series of messages. All MessageQ replies are mapped to the MQSeries MQMT_REPLY. It then becomes the responsibility of the MQSeries application to handle the first, last, and only replies appropriately.

This scheme of handling first, last, and only replies allows the QMB server to keep the connection active until all replies for a request have been processed. When the last or only message is processed, the CI is removed from the CI table. To make the message type field negative, the sending process subtracts the message type field from zero (0 minus message type field) before inserting it into the message type field for the reply message.

Listing 2-2 shows a code fragment for a MessageQ server to send a reply.

Listing 2-2 MessageQ Server Code Fragment to Send a Reply
/*****************************************************************/
/* This is a code fragment of a MessageQ server that listens */
/* on a queue for messages. This queue is a QMB Remote Service */
/* Queue (RSQ) that is defined in a QMB configuration file. */
/* Messages arriving on the MQSeries LSQ are forwarded by the */
/* QMB to this MessageQ RSQ for processing. */
/*****************************************************************/
while (TRUE)
{
/* Listen, process, and reply if required. */
memset(msg_area, 0, sizeof(msg_area));
status = pams_get_msgw(msg_area,
&prio,
&source,
&class,
&type,
&max_len,
&length,
&timeout,
(int32 *) sel_addr,
&lpsb,
&show_buf,
&show_buf_len,
(char *)0,
(char *) 0, /* Reserved*/
(char *) 0 ); /* Reserved*/

if(status != PAMS_SUCCESS)
{
}
else
{ /* Check the received message class and act accordingly.*/

if(class < 0) /* Neg class is a QMB range=implied request */
{
send_reply = process_request(msg_area);

/* To send a reply, you need: receive source address */
/* receive class */
/* receive type */
while(send_reply >= 0)
{
-=send_reply; /* Decrement reply count */

prio = 0; /* Regular priority */
delivery = PDEL_MODE_NN_MEM; /* No Notification */
timeout = 300; /* Wait 30 seconds */
send_uma = PDEL_UMA_DISC; /* If can't deliver */
/* it, discard. */
put_msg_size = length;

if(send_reply == 0)
s_type = type; /* Set type pos - last or only*/
else
s_type = (0 - type);/* Set type neg-reply element */
status = pams_put_msg(msg_area,
&prio,
&source, /* Reply add passed */
&class, /* Forward class back*/
&s_type, /* Forward type back */
&delivery,
&put_msg_size,
&timeout,
(struct psb *) &lpsb,
&send_uma,
(q_address *) 0,
(char *) 0,
(char *) 0,
(char *) 0 );

if(! (status & 1) )
{
}
} /* end send_reply */
}
else if(class == MSG_CLAS_QMB)
{
if(type == MSG_TYPE_DATAGRAM)
{
}
else if(type == MSG_TYPE_RTS_ERROR)
{
}
else
{
}
}
else if(class == MSG_CLAS_PAMS)
{
if(type == MSG_TYPE_AVAIL)
{
}
else if(type == MSG_TYPE_UNAVAIL)
{
}
else
{
}
}

If your MessageQ server application is required to process multiple reply messages, make sure that the CI purge interval (by using the -i parameter on the QMB startup command line) is long enough to allow all the replies to occur. (See the Starting the Queue Message Bridge topic for more information on the qmbsrv command line.)

Using Message Types and Classes

Messaging systems use message types to control the logic of a program in a message-driven environment. A message type is a specific identifier associated with a message. These types may be assigned by the messaging systems or user application and are contained in the message header portion of the message. Because it's part of the message, message types are passed in each message sent and received.

In addition to message types, MessageQ provides a message control field called a message class. In MessageQ message-driven applications, the message class and message type are usually tightly coupled with the program logic. Therefore, when designing and implementing a message-driven interface that has defined message classes and types, all participating programs must understand and follow the rules governing message classes and types.

The specific MessageQ message classes and types defined for use with the QMB allow for maximum flexibility when porting existing MessageQ applications. These applications may contain their own message class and type definitions, which must now coexist with the additional QMB definitions.

Whether porting existing applications or writing new ones, you must design the programs to obey the rules defined by the message class and message type values of the QMB, regardless of whether the application is a sending or receiving messages.

The QMB uses both specific values and ranges of values (both positive and negative) for message class and message type identifiers.

MessageQ Message Types and Classes

The message flow dialog between a QMB process and a MessageQ Client or Server is driven by a set of predefined MessageQ class and type identifiers. The actual values in these message identifiers are determined by the following factors:

The class and type fields may be specific values or ranges of values depending on the combination of the previous factors. Generally, sending applications are required to supply specific class and type values to facilitate the correct message disposition. Likewise, receiving applications (if sending back a reply) are required to return the received class and type fields with the appropriate reply processing indicator (multi or single element).

See the qmbuser.h include file for the actual class and type values. The qmbuser.h include file is found in /usr/kits/DMC32B/include (or in /usr/kits/DMC32C/include).

Table 2-1 describes the message classes that are available to a MessageQ client.
Table 2-1 MessageQ Client Message Classes

State Message Class Description

Send

MSG_CLAS_QMB

Sends a QMB class message

Other than MSG_CLAS_QMB

If your application sends a message with a message class other than MSG_CLAS_QMB, the QMB assumes the default characteristics of the request. This scheme allows you to use existing applications without having to change the class.

Receive

MSG_CLAS_QMB

Receives a QMB class message

Table 2-2 describes the message classes that are available to a MessageQ server.
Table 2-2 MessageQ Server Message Classes

State Message Class Description

Send

QMB range

Calculated as an unsigned integer. The range is from 32,768 to 65,535.

Sends a QMB class message. A MessageQ server must return the class value received with the request (QMB range) as the reply class.

MSG_CLAS_QMB_REPLY_CANCEL

The server detects that a reply is not forthcoming. This message directs the QMB to release the CI table slot.

Receive

QMB range

Calculated as an unsigned integer. The range is from 32,768 to 65,535.

Receives a QMB class message. A MessageQ server must save this value to use in the class field of the reply.

MSG_CLAS_QMB

Receives a QMB class message

Table 2-3 describes the message types that are available to a MessageQ client.
Table 2-3 MessageQ Client Message Types

State Message Type Description

Send

MSG_TYPE_DATAGRAM

Forwards to MQSeries RSQ. No reply.

MSG_TYPE_REQUEST

Forwards to MQSeries RSQ. Reply pending.

Other than MSG_TYPE_DATAGRAM or MSG_TYPE_REQUEST

If your application sends a message with a message type other than MSG_TYPE_DATAGRAM or MSG_TYPE_REQUEST, the QMB assumes the default characteristics of the request. This scheme allows you to use existing applications without having to change the message type.

Receive

MSG_TYPE_REPLY

Reply from MQSeries RSQ request

MSG_TYPE_RTS_ERROR

QMB returns the message. No target RSQ was found.

Table 2-4 describes the message types that are available to a MessageQ server.
Table 2-4 MessageQ Server Message Types

State Message Type Description

Send

Positive range 1 to 1000

Reply to a previously received type message (request). Is an ONLY or LAST message.

Negative range -1 to -1000

Reply to a previously received type message (request). One in a series of reply message elements.

Receive

Positive range 1 to 1000

Received a message (request) with a reply pending. This field must be saved and returned in the type field with the reply.

MSG_TYPE_DATAGRAM

Received message with no reply

MQSeries Message Types

The MessageQ MQSeries Connection supports the MQSeries message types described in Table 2-5. These message types are inserted or received in the MQSeries Message Descriptor (MQMD) by the MQSeries applications. The message types vary depending on the source and state of the dialog.

Table 2-5 describes the message types that are available to an MQSeries client.
Table 2-5 MQSeries Client Message Types

State Message Type Description

Send

MQMT_DATAGRAM

Forwards to the MessageQ RSQ. No reply.

MQMT_REQUEST

Forwards to the MessageQ RSQ. Reply pending.

Receive

MQMT_REPLY

Reply from MessageQ RSQ from previous request

MQMT_RTS

Return to sender. This is from the QMBMD. No remote service queue nor no client table slots were available. Implicit error reply.

In Table 2-5, MQMT_RTS is a user-defined MQSeries message type. It is defined as follows:

# define MQMT_RTS			MQMT_APPL_FIRST + 1

MQSeries client applications must be prepared to receive this message type as a valid response to a MQMT_REQUEST.

Table 2-6 describes the message types that are available to an MQSeries server.
Table 2-6 MQSeries Server Message Types

State Message Type Description

Send

MQMT_REPLY

Reply to a MessageQ client from a previous request

Receive

MQMT_DATAGRAM

Message received. No reply.

MQMT_REQUEST

Request received. Reply to MQS_REPLYQ and return ApplIdentityData (CI).

Using Recoverable Messaging

To recover messages after a system mishap, your application must have message persistence defined. Message persistence describes a message that is written to nonvolatile storage. This means that persistent messages can survive a system restart.

Messages received with MQSeries Persistence or MessageQ Message Recovery Services are forwarded by the QMB with the corresponding persistence or MRS mode.

MessageQ MQSeries Connection locksteps the MQSeries persistence mode with the MessageQ Message Recovery Services and delays the confirmation of a message until the message has been forwarded and safely stored. Persistence mode processing may affect the performance of your application. You may want to have separate persistence and nonpersistence services.

Note: MQSeries dynamic temporary queues do not support message persistence. MessageQ temporary queues do not support Message Recovery Services.

Setting Message Priority

Message priority is the priority the message assumes for delivery.

Message priority is maintained between the MessageQ and MQSeries messaging systems as follows:

MQSeries queues defined with a Message Delivery Sequence as first-in/first-out (FIFO) order ignore priority.

How Message Header Data is Mapped

Message header data is defined to be the MQSeries message descriptor (MQMD) and the MessageQ message attributes. The content of many fields is the same in meaning but quite different in format. Because of these differences in the message header formats between the two messaging systems, a limited amount of mapping of fields is performed by the QMB applications. Include a user application level header as part of the message body to allow application-specific information exchange (if required by the application design).

There is a loose coupling between a subset of MQSeries and MessageQ message header fields, which are maintained by the QMB server in a limited manner.

Table 2-7 describes coupling of MQSeries and MessageQ message header fields.
Table 2-7 Coupling of MQSeries and MessageQ Message Header Fields

MQSeries Message Header Field MessageQ Message Header Field Description

MQMD -> Priority

PUT/GET->Priority

Message priority

MQMD -> Persistence

PSB-> ConfirmRequest

Reliable message delivery

MQMD-> MsgType

PUT/GET->Type

Message type indicator

Handling Message Byte Order Differences

The content of the message buffer is forwarded as received. It is the responsibility of the receiving application to interpret the byte order and normalize it, if required. The QMB forwards byte order information as follows:

We recommend that you use string data (if possible) or user-defined fields in the message body to carry application-specific information about the message.

Character Code Conversion

Character code conversion between the QMB and MVS based MQSeries applications is supported as follows:

Guidelines for Choosing Message Characteristics

When designing message queuing applications, you choose the characteristics of the message. These characteristics indicate to the QMB how the message is to be processed and include the following:

The guidelines to choose message characteristics are as follows:


Sending a Request to an MQSeries Server

Suppose you want your MessageQ client to send a request to an MQSeries server and receive a reply. In order for the message to be sent, the proper MessageQ, MQSeries, and QMB configurations must be correct and all messaging systems and application programs must be executing.

The following example provides details about the MessageQ client and MQSeries server applications:

Table 2-8 describes the required queue definitions to send a message to an MQSeries server for the previous example.
Table 2-8 Required Queue Definitions for an MQSeries Server

Messaging System Queue Name/Queue Type Description

MessageQ

MQS_ECHO / Multireader

MQS_ECHO is the MessageQ LSQ that receives messages to be forwarded to the MQSeries RSQ named MQS_ECHO_SERVER. MQS_ECHO is a multireader queue maintained by a QMBDM process.

MQSeries

MQS_ECHO_SERVER/ Any supported MQSeries queue type

MQS_ECHO_SERVER is the MQSeries queue that the MQSeries server (also named MQS_ECHO_SERVER) is listening on for requests.

MQS_REPLYQ / Shared Permanent

MQS_REPLYQ is a required MQSeries queue that receives all MQSeries reply messages from MQSeries server programs. A QMBMD process is listening on this shared queue for replies.

The MessageQ LSQ named MQS_ECHO is associated to the MQSeries RSQ named MQS_ECHO_SERVER in a QMB configuration file. This file stores the LSQ-to-RSQ relationship that the QMB uses when forwarding messages.

Listing 2-3 shows the QMB configuration file for the MQS Series server.

Listing 2-3 MQSeries Server Queue Message Bridge Configuration File
!LSQ Name  LSQ     RSQ              RSQ
!Name Owner Name Association
!
MQS_ECHO D MQS_ECHO_SERVER S

Table 2-9 shows the contents of the QMB configuration file.
Table 2-9 Fields in the Queue Message Bridge Configuration File

Field Description

LSQ Name

Name of the Local Service Queue defined in either MessageQ or MQSeries

LSQ Owner

Owner of the Local Service Queue. A D indicates MessageQ and an M indicates MQSeries.

RSQ Name

Name of the Remote Service Queue associated with the LSQ

RSQ Association

Method of Remote Service Queue association. An S indicates static registration and a D indicates dynamic association.

Figure 2-1 shows the sending of a request to an MQSeries server.

Figure 2-1 Sending a Request to an MQSeries Server

Note the following about Figure 2-1:

  1. The MessageQ client (named DMQ_CLIENT) must either know the MessageQ queue address of the LSQ MQS_ECHO or use the MessageQ LocateQ message-based call to obtain it. Once an address is known, the client sends the request message to the MessageQ LSQ named MQS_ECHO.

  2. The QMBDM has a read posted against the MQS_ECHO. The QMB creates a CI based on the message source. It inserts the index into the ApplIdentityData field and sets the following characteristics:

    The QMB maps and forwards the message to the MQSeries RSQ named MQS_ECHO_SERVER.

  3. The MQSeries server (named MQS_ECHO_SERVER) reads the message and responds appropriately.


Sending a Reply to a MessageQ Client

Consider the following application that sends a reply from an MQSeries server to a MessageQ client:

Figure 2-2 shows the sending of a reply to a MessageQ client.

Figure 2-2 Sending a Reply to a MessageQ Client

Note the following about Figure 2-2:

  1. The MQSeries server (named MQS_ECHO_SERVER) reads the message, processes it, and sends back a reply (which must include the ApplIdentityData) to the queue designated in the ReplyToQ field MQS_REPLYQ and ReplyToQMgr.

  2. The QMBMD has a read posted against MQS_REPLYQ. When the reply message arrives in the MQS_REPLYQ, the QMBMD program performs the following tasks:

  3. The MessageQ client (named DMQ_CLIENT) reads the message.

When writing message-based applications, use MessageQ and MQSeries system functions and services, where applicable. These functions can help determine the status and state of the bridge, associated application programs, network services, and messaging systems.


Sending a Request to a MessageQ Server

Suppose that you want to send a request to an MessageQ server. In order for this to work, you must have MessageQ, MQSeries, and QMB properly configured and running.

Consider the following application that sends an MQSeries message to a MessageQ server:

Table 2-10 provides an example of the required queue definitions.
Table 2-10 Required Queue Definitions for a MessageQ Server

Messaging System Queue Name / Queue Type Description

MQSeries

DMQ_ECHO / Shared permanent

DMQ_ECHO is an MQSeries LSQ that receives messages to be forwarded to the MessageQ RSQ named DMQ_ECHO_SERVER. This is an MQSeries shared queue maintained by a QMBMD process.

MessageQ

DMQ_ECHO_SERVER / Any supported queue type

This is the MessageQ queue that the MessageQ server is listening on for requests.

DMQ_REPLYQ / Multireader

DMQ_REPLY is a required MessageQ queue that receives all MessageQ reply messages from the MessageQ server. A QMBDM process listens on this queue for reply messages.

The MQSeries LSQ (named DMQ_ECHO) is associated to the MessageQ RSQ (DMQ_ECHO_SERVER) in a QMB configuration file entry, as shown in Listing 2-4.

Listing 2-4 Example -4: DMQ_ECHO Queue Message Bridge Configuration File
!LSQ Name  LSQ     RSQ              RSQ
!Name Owner Name Association
!
DMQ_ECHO M DMQ_ECHO_SERVER S

Table 2-11 shows the key to the QMB configuration file for the DMQ_ECHO_SERVER application.
Table 2-11 Fields in the Queue Message Bridge Configuration File

Field Description

LSQ Name

Name of the Local Service Queue defined in either MessageQ or MQSeries.

LSQ Owner

Owner of the Local Service Queue. A D indicates MessageQ and an M indicates MQSeries.

RSQ Name

Name of the Remote Service Queue associated with the LSQ.

RSQ Association

Method of Remote Service Queue association. An S indicates static registration and a D indicates dynamic queue association.

Figure 2-3 shows an MQSeries client sending a request to the MessageQ server.

Figure 2-3 Sending a Request to a MessageQ Server

In Figure 2-3, note that an MQSeries client (named MQS_CLIENT) sends a request message to the MQSeries LSQ named DMQ_ECHO. The QMB performs the following functions:

  1. Creates a CI based on the ReplyToQ name, inserts it in the type field, inserts the QMB range (MSGID) in the class field, and sets the respq field to DMQ_REPLYQ.

  2. Maps and forwards the message to the MessageQ RSQ named DMQ_ECHO_SERVER.


Sending a Reply to an MQSeries Client

Consider the following application that sends a reply from a MessageQ server to the MQSeries client:

In Figure 2-4, the MessageQ server (DMQ_ECHO_SERVER) reads the message, processes it, and sends back a reply to the queue (DMQ_REPLYQ) designated in the respq field. The reply must include the request class and type.

Figure 2-4 Sending a Reply to an MQSeries Client

When the reply message arrives in the MessageQ to MQSeries (QMBDM) DMQ_REPLYQ, the QMBDM program performs the following functions:

  1. Converts the CI to the actual MQSeries client target queue name.

  2. Maps and forwards the message to the MQSeries client.


Restrictions and Limitations

MessageQ MQSeries Connection has the following restrictions and limitations: