An interesting discussion on the use of client connection wildcards came up on mqseries.net today. This is documented in the Application Programming Reference and Clients manuals, but I’ve not seen it used very often and it can help to see how it works with a practical example.

In this post, I’ll go through an example of why you might want to use a wildcard in an MQCONN call and show the effect that it has.

Background

Imagine you had two queue managers called DALE in your network, one on a machine with IP address 9.9.9.9 and one on a machine with the IP address 8.8.8.8. And you want to define the connection from your client to queue managers with a Client channel definition table.

The obvious channel definitions to make in the channel table might be:

1 : define channel(IN.SVRCONN.x) chltype(CLNTCONN) conname(9.9.9.9) qmname(DALE)
2 : define channel(IN.SVRCONN.y) chltype(CLNTCONN) conname(8.8.8.8) qmname(DALE)

In your client application, if you tried MQCONN to DALE this would pick up the first definition which matches the QMNAME parameter (e.g. – 1), and try to connect to it. On successful connection, it will negotiate, and part of this is to get the queue manager name of the remote end (in this case “DALE”). If this doesnt match the name in the MQCONN, then the connection fails.

If the connection fails for any reason (e.g. the first destination is unavailable, invalid queue manager name at the remote end etc.) then we retry the MQCONN with the next matching definition (e.g. – 2). This ability provides a very basic level of failover when a node is unavailable.

This does mean that there is no way to select which “DALE” you want to connect to when using client channel definition tables. (One way to programatically choose one would be to code the whole channel definition yourself rather than relying on a lookup in a definition table). This is one of a number of reasons why it is not generally recommended to have multiple queue managers with the same name in a single network.

Using the wildcard in MQCONN

This is where a workaround using the “*” option on the MQCONN can come in. Imagine that we still have the same two queue managers called “DALE” on 9.9.9.9 and 8.8.8.8. But now, our client channel definition table contains:

1 : define channel(IN.SVRCONN.x) chltype(CLNTCONN) conname(9.9.9.9) qmname(FRED)
2 : define channel(IN.SVRCONN.y) chltype(CLNTCONN) conname(8.8.8.8) qmname(BARNEY)

This gives us a number of options…

MQCONN(*FRED)
This will look up FRED in the QMNAME of the channel table. It will find a matching entry (1) and connect to it. On successful negotiation, we ignore the fact that the returned qmgr name (DALE) is different from what we connected to because of the ‘*’ prefix.

MQCONN(FRED)
This will look up FRED in the QMNAME of the channel table. It will find a matching entry (1) and connect to it. On successful negotiation, we see the fact that the returned qmgr name (DALE) is different from what we connected to and reject the connection.

MQCONN(*BARNEY)
This will look up BARNEY in the QMNAME of the channel table. It will find a matching entry (2) and connect to it. On successful negotiation, we ignore the fact that the returned qmgr name (DALE) is different from what we connected to because of the ‘*’ prefix.

MQCONN(BARNEY)
This will look up BARNEY in the QMNAME of the channel table. It will find a matching entry (2) and connect to it. On successful negotiation, we see the fact that the returned qmgr name (DALE) is different from what we connected to and reject the connection.

MQCONN(DALE)
This will look up DALE in the QMNAME of the channel table, find no matching entry and fail.

MQCONN("") or MQCONN(*)
This will look in the channel table for a QMNAME entry that is blank, find no matching entry and fail.

Note that these are all client bindings specific options (MQCONN will fail if a non-client application specifies a queue-manager name beginning with an asterisk).

Why you might want to use this

It has a number of uses, including the ability to solve the problem described above. It is not queue manager aliasing (that is something else), but it does have a similar sort of effect which the manuals refer to as “client queue manager groups”. Uses include where you have a client application which is only putting messages to any one of a group of queue managers, and it is not important to which queue manager a message is put.

For example, if you have a group of queue managers – all with different names and hosted on machines with different IP addresses – you can use QMNAME in the definitions of the client channels to identify them as being part of a single group:

define channel(IN.SVRCONN1) chltype(CLNTCONN) conname(9.9.9.1) qmname(MYQMGROUP)
define channel(IN.SVRCONN2) chltype(CLNTCONN) conname(9.9.9.2) qmname(MYQMGROUP)
define channel(IN.SVRCONN3) chltype(CLNTCONN) conname(9.9.9.3) qmname(MYQMGROUP)
define channel(IN.SVRCONN4) chltype(CLNTCONN) conname(9.9.9.4) qmname(MYQMGROUP)
define channel(IN.SVRCONN5) chltype(CLNTCONN) conname(9.9.9.5) qmname(MYQMGROUP)
define channel(IN.SVRCONN6) chltype(CLNTCONN) conname(9.9.9.6) qmname(MYQMGROUP)

If you want to connect to any queue manager in this group (regardless of what any of them are called), you can MQCONN to *MYQMGROUP.

Advertisements