Skip to main content

     
  TPF : Library : Newsletters

About TPF MQSeries Support

Allan Feldman, IBM TPF Development

The IBM MQSeries product is one of the fastest growing message-oriented middleware products in the industry. Today, MQSeries is supported by well over 17 platforms and has a growing customer base of over 5000 customers. The ability to guarantee delivery of messages to a diverse and heterogeneous set of systems within and between customers with a single set of application programming interfaces (APIs) is an attractive model for TPF customers.

TPF MQSeries Local Queue Manager and TPF MQSeries Client Support

On TPF program update tape (PUT) 5, IBM delivered a Message Queue Interface (MQI) client on the TPF system. With this support, the complete MQSeries API was enabled for TPF applications. When an application connects to the queue manager (using the MQCONN API), a connection is established with a remote MQSeries server (on OS/390 or AIX, for example). Each MQSeries API, in turn, is delivered to a remote MQSeries server over LU 6.2 communication links and then processed by the MQSeries server. The queues themselves reside on the server, not on the TPF system. The API available to the application is determined by the API available on the remote server.

With our client support, the application must be prepared to handle communication failures and system managers must be prepared to install and maintain remote MQSeries server systems.

On TPF PUT 9, IBM delivered local queue manager support on TPF. When an application connects to the queue manager, it can connect to the local queue manager running on TPF. This is accomplished by specifying the name of the local queue manager in the MQCONN API. All subsequent MQSeries API requests will be serviced by the local TPF queue manager. The APIs available to the local queue manager are more restrictive than most remote servers. See the TPF C/C++ Language Support User's Guide for specific details about the API available.

The application can also still connect to a remote MQSeries server using TPF MQI client support. If the application specifies the name of a remote server queue manager in the MQCONN request, MQCONN and all subsequent API requests will be sent to the remote server for processing.

APIs

Nine MQSeries APIs are provided with TPF MQSeries local queue manager support: MQCONN, MQOPEN, MQPUT, MQPUT1, MQGET, MQCLOSE, MQDISC, MQINQ, and MQSET (MQINQ and MQSET are provided on TPF PUT10). The options supported for each API are documented in the TPF C/C++ Language Support User's Guide. Because the APIs supported locally are generally more restrictive than those on other platforms, applications that require unsupported functions should consider using the TPF MQI client where a remote server can satisfy the request.

Supported Queue Types

The TPF local queue manager supports three different queue types, which are defined using the ZMQSC DEFINE Qx...... functional message. These queue types are:

  • Local
  • Remote
  • Alias (available with TPF PUT 10).

There are two types of local queues: normal and transmission (xmitq). Normal local queues physically reside in the TPF system and messages on local queues are retrieved (MQGET) by applications. Applications can put (MQPUT) messages to local queues for processing by a TPF application. Transmission queues contain messages that are destined for a remote system. In fact, the transmission queue is also physically located in TPF, but applications do not normally get and put messages directly to them. When an application puts a message to a remote queue, the TPF queue manager, in turn, figures out on which transmission queue to put the message. At some point, the channel associated with that transmission queue takes the messages from that queue and sends them to the remote system.

With alias queues, the system administrator can define an alias queue that is opened by an application. However, unknown to the application, the queue that is actually opened is some other (target of the alias queue) local queue or local definition of a remote queue. In this way, the administrator manages the queues that are processed by applications. The application code never has to change to satisfy changes in queue names.

Empty Queue Trigger User Exit

TPF does not support the normal set of event and trigger queues provided in other MQSeries platforms. We do, however, provide a user exit that is invoked when an MQGET request is attempted from an empty queue that subsequently has a message put on to it. The trigger is not set unless an application attempts to read (MQGET) a message from the queue when it is empty. When the queue becomes nonempty, the user exit is invoked with a trigger message on data level 0 of the entry control block (ECB) that indicates which queue was triggered. The user exit can interpret this data and pass control to the appropriate application for processing the message.

Message Routing

TPF supports several different methodologies when resolving remote queue names:

Local Definition of Remote Queues

To remove the burden from the application of determining the queue manager and queue to receive its message, the MQSeries administrator can define a local definition of a remote queue that specifies the actual destination queue manager and destination queue name. The application opens a local name for the queue, and the TPF queue manager will substitute the specified queue manager and queue name and put the message on the specified transmission queue. To define a local definition of a remote queue, use the ZMQSC DEF QR- functional message and specify RQMNAME and RNAME and XMITQ.

So if the administrator had defined:

ZMQSC DEF QR-RQ1 RQMNAME-QMGR1 RNAME-Q1 XMITQ-XQ1

and the application issues an MQOPEN for RQ1, the message will be put on transmission queue XQ1 with a destination queue manager of QMGR1 and queue Q1 specified in the transmission queue header.

Queue Manager Aliasing

TPF also supports queue manager aliasing. Here, the name of the remote queue is known, but not the name of the remote queue manager. When the application opens a queue specifying a queue manager, the TPF system will look up the name of the queue manager and substitute the queue manager specified. Queue manager aliasing is accomplished by leaving the QNAME field blank in the ZMQSC DEF QR functional message.

So if the administrator had defined:

ZMQSC DEF QR-RQMGR RQMNAME-RQMGR2 XMITQ-XQ1

and the application issues an MQOPEN with a queue manager name of RQMGR and queue name of Q1, the TPF system will put the message on transmission queue XQ1 with a destination queue manager of RQMGR2 and a destination queue of Q1 specified in the transmission queue header.

Queue Manager Name As Transmission Queue Name

In addition to a local definition of remote queues and queue manager aliasing, the system administrator can send a message to an adjacent queue manager if the name of the queue manager opened by the application is the same as a transmission queue.

So if the administrator had defined transmission queue:

ZMQSC DEF QL-QMGR1 USAGE-XMITQ

and the application opens a queue with a queue manager name of QMGR1 and a queue name of Q1, the TPF system will put the message on transmission queue QMGR1 and send the message to queue manager QMGR1.

Middle Hop Routing

Messages received by TPF MQSeries local queue manager channels may not be destined for the TPF queue manager. The TPF receiver channel will invoke the local TPF queue manager to resolve the name of the destination queue manager and queue name for each message it receives. The queue manager and queue name are resolved according to the rules previously stated and the message is put on the appropriate transmission queue.

Message Types

Persistent and nonpersistent messages are supported. Applications specify the message type in the message descriptor (MQMD). However, the TPF implementation is slightly different from other platforms when it comes to transmitting and receiving nonpersistent messages over fast channels. See the description of fast and normal channels that follows.

Channels

The TPF MQSeries local queue manager supports two channel types, which connect to remote MQSeries systems:

  • A sender (SDR) channel, which must connect only to a remote receiver channel
  • A receiver (RCVR) channel, which accepts connection requests only from remote sender channels.

Receiver channels make use of the latest TPF Internet daemon (INETD). When a remote sender channel first connects to the TPF system over Transmission Control Protocol/Internet Protocol (TCP/IP), it sends a connection request to port 1414, the standard MQSeries port. System administrators must set up an INETD listener on that port that, once the connection request is received, passes control to the TPF MQSeries receiver channel session initiation program (CMQL). The TCP/IP model used is activate_on_receipt, which means that a TPF entry control block (ECB) to process the session initiation request is only created when the connection request is received. To set up the INETD listener for MQSeries, you must add an MQSeries server using the following functional message:

ZINETD ADD S-MQS P-TCPIP MODEL-AOR PORT-1414 PGM-CMQL AORL-8

This is required before establishing a connection between remote sender channels and TPF receiver channels. It is possible to change the TCP/IP port used for these connections. If you establish an INETD listener on a different port for the MQSeries server, you need to specify the same port in the CONNAME parameter when defining the sender channel on the remote MQSeries system.

Two channel "speeds" are supported for both sender and receiver channels: normal and fast.

When sending persistent messages over normal speed sender channels, the messages are included in batches and receipt confirmation is required before the messages are deleted from our transmission queue. Persistent messages are never sent over fast channels. This is a restriction that is not found on other platforms.

When sending nonpersistent messages over fast channels, the messages are immediately sent over the channel. They are not included in batches and receipt confirmation is not required.

When receiving both persistent and nonpersistent messages over normal receiver channels, the messages are processed as part of a batch and receipt confirmation is sent for the entire batch of messages. The messages are filed using TPF collection support (TPFCS). Once the confirmation is sent, the messages appear on local TPF MQSeries queues or are put on transmission queues destined for another queue manager if the TPF queue manager is not the target queue manager. The nonpersistent messages have an indicator in the message descriptor saying that it is nonpersistent. Applications must get messages from the local queues using the MQGET function.

When receiving nonpersistent messages over a fast receiver channel, the message is not filed and, although it is considered part of a batch of messages, the message is assumed to be destined for a traditional non-MQSeries application. To achieve significant performance throughput for these messages, they are given directly to TPF applications using the TPF-unique MQSeries ROUTC Bridge function. The messages never appear on a queue.

MQSeries ROUTC Bridge

TPF local queue manager support includes a TPF-unique mechanism for passing nonpersistent messages received over fast channels directly to traditional TPF applications. In this way, TPF customers can take advantage of MQSeries-oriented networks for delivering older traditional, high-speed TPF-style messages to TPF applications.

The MQSeries message is converted into TPF AM0SG format and given to TPF message router program COA4 for routing the message to an application. A user exit is provided that gives customers the opportunity to assign a line number, interchange address, and terminal address (LNIATA) to the message before giving it to the application. In addition, the terminal address table (WGTA) for that LNIATA is marked with an MQSeries indicator so when the application responds to the message using the ROUTC bridge, the message is intercepted and converted back to an MQSeries message format.

Swinging Transmission Queues

The TPF local queue manager provides a unique feature that redirects messages originally destined for a transmission queue to an alternate transmission queue. If, for example, a channel is hung or the remote receiver channel is down, messages can be moved to a transmission queue that has an active channel. All of the messages that were previously on the original transmission queue are moved to the new transmission queue, and all new messages put to the original transmission queue are actually added to the new transmission queue. The ZMQSC SWQ functional message is used to perform this function.

Monitoring Transmission Queue Depth

The TPF system provides a transmission queue depth monitor. When the queue depth on a transmission queue, which is set by an administrator, is reached (QDEPTHHI on ZMQSC DEF QL-xxxx USAGE-XMITQ or ZMQSC DEF MQP), a warning message will be sent to the operator console. This could mean that the transmission queue is hung and may need operator intervention. The warning message is sent to the console every xx seconds until the queue goes below the QDEPTHHI value (where xx is the interval that is determined by the administrator via the QDT keyword on the ZMQSC DEF MQP functional message).

Debugging TPF MQSeries

Because the TPF MQSeries implementation uses TPFCS for its database, there are several named collections that you can browse using the TPFCS browser. You can display the named collections using the ZBROW NAME DISPLAY ALL functional message. Don't forget to set the browser qualifier to MQSeries data store MQSCxxxx, where xxxx is the subsystem name (for example, MQSCBSS).

Trace

Included in TPF MQSeries support is communications and function trace. Communications trace was provided on PUT 9. Function trace is being added for PUT 10.

With communications trace, the data sent and received over channels is included in a trace block attached to the channel definition. Much of the data will not be formatted because the contents of the message flows are considered proprietary and confidential.

With function trace, you can trace function calls in the three different areas of MQSeries:

  • Administrative (ZMQSC functional messages)
  • Queue manager
  • Communications.

Each function that is called and returned creates an entry in a trace block that is attached to the ECB. The trace data can be used for problem determination. You can function trace individual channels or queues, or all channels or all queues.

Trace data can be sent to either the console, the RTA tape, both the RTA tape and console, or neither. It is strongly recommended that sending trace data to the console be restricted to test system environments only.

Packaging

Most of MQSeries is contained in a dynamic link library (DLL) called CMQS. CMQS contains the entry points for the MQSeries APIs as well as the entry points for the MQSeries dynamic link modules (DLMs): CMQL, CMQR, CUIU, CUIE, CUIF, CUIK, CUIM, CUIR, CUIX, and CUSC. The C linkage into the CMQS entry points requires a side-deck, which is produced when CMQS is link-edited. The side-deck is then imported into any DLM that requires those entry points, including the MQSeries DLMs. In addition, any customer application that issues an MQSeries API must also import the CMQS side-deck.

Header file CMQC.H contains the prototypes for the function calls to the MQSeries APIs. Any customer application that is currently using MQI client support links into the MQI client C library called CMQI. With delivery of local queue manager support on PUT 9, the prototypes defined in CMQC.H for the MQSeries APIs have changed. Each function name has been redefined with a prefix of zst. Therefore, MQCONN is defined as zstMQCONN and MQOPEN is now zstMQOPEN. While applications still code MQCONN and MQOPEN, they are turned into zstMQCONN and zstMQOPEN at compile time. The linkage to zstMQCONN (because it is included in the CMQS side-deck, not in the CMQI transfer vector) goes into CMQS, which now determines whether MQCONN is for the local queue manager or for a client queue manager. If the name of the queue manager in MQCONN is the same as the name of the local TPF queue manager, CMQS will then process the local request. If the name of the queue manager in MQCONN is not the name of the local queue manager, CMQS will then pass control to CMQI to process a client request.

Because there is only one copy of CMQC.H for both client and local queue manager MQSeries applications, any existing MQI client application should be recompiled to pick up the new linkage. In addition, some of the fields in CMQC.H have changed. Of course, if you do not recompile your client application, the linkage into CMQI will not change and the code should work as before, but this is not recommended.

The CMQS DLL is quite large and contains several object code only (OCO) modules. Customers must compile the non-OCO MQSeries modules using a C++ compiler and link-edit them using the CMQSBS build script. The OCO modules shipped by IBM have been compiled using the OS/390 Version 2 Release 4 (2.4) C++ compiler. It is strongly recommended that customers compile the non-OCO modules using the C++ compiler and linkage editor shipped with OS/390 2.4. Attempting to link-edit some modules compiled with an older version of the compiler and linkage editor and link-editing them with the OCO modules compiled with OS/390 2.4 may produce linkage editor errors.

Important: When compiling, use the OPTIMIZATION (0) compiler option. However, the known OS/390 2.4 C++ compiler bug with optimization level 1 has since been fixed by APAR PQ24612.

Offline program CMQMPP is used to postprocess trace data from an RTA tape. CMQMPP is also shipped as OCO, but was compiled using the C compiler (not C++) and does not require prelinking because it was compiled with the NORENT and NOLONGNAME options. Therefore, the linkage editor job control language (JCL) produced by the system initialization program (SIP) calls CEEWL, which does not invoke the prelinker. The original JCL produced by SIP (PUT 9) called EDCL, which is a PROC that is only available on older versions of OS/390. With PUT 10, the GENSIP macro was changed to produce JCL that calls CEEWL.

What Is New on TPF PUT 10?

Alias Queue

Applications can specify an alias queue name when opening queues. The real queue name is not known to the application. The real queue can be a local queue or a local definition of a remote queue. A new functional message (ZMQSC DEF QA-) is available to the MQSeries administrator for defining alias queues.

Function Trace

Previously, TPF local queue manager support included channel trace where data sent and received over channels was dumped to an RTA tape and postprocessed in an offline environment. With PUT 10, a function trace is available that shows the logic flow of function entry and exit for channels, queue manager functions, and administrative functions. Trace output can be sent to the RTA tape, to the console, to both, or to neither. Of course, sending trace output to a console in a production system is dangerous and should be avoided.

MQSET/MQINQ

Two new MQSeries APIs are now supported in the local queue manager. These APIs let applications inquire about queue and queue manager attributes or set queue attributes.

Disable Receiver Channel

Receiver channels on the TPF local queue manager can be disabled by issuing a ZMQSC STOP CHL functional message. This function prevents remote sender channels, which may be looping or generating erroneous messages, from establishing a connection with the TPF MQSeries system.

Tips for Administering Your Local Queue Manager

The administrative functions in the TPF implementation of an MQSeries local queue manager are similar to, but not exactly the same as, other platforms. Some of the functions are unique because of the loosely coupled nature of TPF systems, while other differences result from the fact that TPF maintains some of the MQSeries object definitions in system heap for performance.

Defining the MQSeries Profile

When you define the MQSeries profile (ZMQSC DEF MQP...) for the first time, you must specify how many queues and channels you need via the MAXQUE and MAXMCA parameters. Because the queue definitions and channel definitions are loaded into system heap memory for performance, these parameters determine how much system heap will be needed for these definitions. So if you set MAXMCA to 20, the channel definition table will contain 20 entries. If you decide you need more, you can always alter the MQSeries profile (ZMQSC ALT MQP...), but you will need to stop and start the queue manager so the system can reallocate the system heap for the new tables.

Also, when you define the MQSeries profile, the TPF system automatically provides a system queue called dead-letter queue. This is the only default queue provided. Other platforms provide several other default queues. Any message that arrives at the TPF system whose destination queue name cannot be resolved is put on the dead-letter queue. All customers are expected to create a monitor for the dead-letter queue that determines what to do with messages that arrive there.

Common-Yes for Local Queues

In a loosely coupled environment, normal local queues can be shared between processors or they can be processor unique. When you define a local queue (ZMQSC DEF QL-xxx USAGE-NORMAL), you can specify that you want all processors to see the queue by specifying COMMON-YES. When COMMON-YES is coded, a single TPFCS persistent identifier (PID) (yes, we used collection support for our queues!) is then used for the queue that all of the processors can see. Messages put on the queue from processor A can be retrieved from processor B. When COMMON-NO is coded, each processor in the complex will be allocated a different TPFCS PID and each processor will, in effect, have its own copy of the queue. Messages that are put on the queue from processor A will only be visible to processor A.

Note also that if you define a COMMON-NO queue, the queue definition will exist on all processors. So even though you define a queue on processor A, the queue name will exist on processor B; it will just have its own copy of the queue.

Obviously, if you can live with the I/O contention for a shared queue, that is the way to go. If you cannot, you should then specify COMMON-NO. Of course, either way, the application may need to be aware of whether the queue is available on all processors.

You should also be aware that once you have specified whether the queue is shared or not, you cannot alter this attribute. To change it, you will need to delete the queue and redefine it with the new attribute.

Finally, transmission queues are all processor unique because they are all associated with channels that are also, by definition, processor unique. Remote queues are really virtual and actually get resolved to physical transmission queues.

CPU Parameter for Channel Definitions

Channels, by nature, are processor unique. Each processor establishes an MQSeries channel connection to an adjacent MQSeries system. As a matter of convenience, the TPF system provides a CPU parameter for the functional messages that define and alter channel definitions. In this way, an operator on processor A can define or alter channels on processor B even while processor B is down.

Altering Definitions

Because our channel and queue definitions reside in memory, and because we do not want to lock the tables for each access, changes to these definitions do not always occur immediately. For changes to channel definitions, the channel must be stopped and restarted. For queue definition changes and queue manager definition changes, the queue manager must be stopped and restarted.