IBM MQ Little Gem #20: Picking CCDT entry by Channel Name

This is part of a series of small blog posts which will cover some of the smaller, perhaps less likely to be noticed, features of IBM MQ. Read other posts in this series.

CCDT.jpgA Client Channel Definition Table (CCDT) is a way to supply all the required details for connecting to a queue manager, without hard-coding them in your application. More than that, these details can be maintained by the system administrator, and updated as required, without needing to know how the application was written, and without requiring differences depending on the language used to write the application.

It has always been the case that to use a CCDT, you make a connection to a queue manager name, which may be a real queue manager name, or may be a logical queue manager name, and that name is used to look up the CCDT for an entry marked with that queue manager name.

Example 1: Real queue manager name

For example, when making an MQCONN call like this:-

MQLONG  CompCode, Reason;
MQHCONN hConn  = MQHC_UNUSABLE_HCONN;
char  * QMName = "MQG1";
MQCONN(QMName,
       &hConn,
       &CompCode,
       &Reason);

and looking up a CCDT created like this:-

DEFINE CHANNEL(MQG1.SVRCONN) CHLTYPE(CLNTCONN)
       TRPTYPE(TCP) CONNAME('aix2.mqgem.com(1501)')
       QMNAME(MQG1)
DEFINE CHANNEL(MQG2.SVRCONN) CHLTYPE(CLNTCONN)
       TRPTYPE(TCP) CONNAME('win12.mqgem.com(1502)')
       QMNAME(MQG2)

it would choose the record for the channel named MQG1.SVRCONN, since that is the only record for queue manager MQG1.

Example 2: Logical queue manager name

Taking another example, this time with a logical queue manager name, provided on an MQCONN call like this:-

MQLONG  CompCode, Reason;
MQHCONN hConn  = MQHC_UNUSABLE_HCONN;
char  * QMName = "*MQGEM";
MQCONN(QMName,
       &hConn,
       &CompCode,
       &Reason);

and looking up a CCDT created like this:-

DEFINE CHANNEL(MQG1.SVRCONN) CHLTYPE(CLNTCONN)
       TRPTYPE(TCP) CONNAME('aix2.mqgem.com(1501)')
       QMNAME(MQGEM) CLNTWGHT(20) AFFINITY(NONE)
DEFINE CHANNEL(MQG2.SVRCONN) CHLTYPE(CLNTCONN)
       TRPTYPE(TCP) CONNAME('win12.mqgem.com(1502)')
       QMNAME(MQGEM) CLNTWGHT(20) AFFINITY(NONE)
DEFINE CHANNEL(MQG3.SVRCONN) CHLTYPE(CLNTCONN)
       TRPTYPE(TCP) CONNAME('mvs1.mqgem.com(1503)')
       QMNAME(MQGEM) CLNTWGHT(20) AFFINITY(NONE)

it would randomly choose one of the three records with queue manager name MQGEM because they are all equally good. If connection to the one it picked failed, it would try another until it was successful, or it ran out of entries to try. The asterisk used on the queue manager name provided on the MQCONN call means that it knows this is not the real queue manager name and not to raise an error when the client code finds out that the queue manager name at the end of the connection doesn't match the one supplied on the MQCONN call.

Example 3: Using a CCDT for multiple connections

In WebSphere MQ V7, a feature was introduced to help applications which wanted to use the CCDT to make a connection, but needed to make more than one connection, and wanted all the connections to use the same entry from the CCDT. This is useful for, but not limited to, JMS Connections and JMS Sessions. In short this feature said, pick the first connection from the CCDT and return to me what you chose, and then for the second and subsequent connections, I will use what you told me you chose.

Here's how that is coded:-

MQLONG  CompCode, Reason;
MQHCONN hConn1, hConn2;
MQCNO   cno    = {MQCNO_DEFAULT};
MQCD    cd     = {MQCD_CLIENT_CONN_DEFAULT};
char  * QMName = "*MQGEM";
cno.Version       = MQCNO_VERSION_2;
cno.ClientConnPtr = &cd;
cno.Options       = MQCNO_CD_FOR_OUTPUT_ONLY;
MQCONNX(QMName,
        &cno,
        &hConn1,
        &CompCode,
        &Reason);
if (CompCode != MQCC_NONE) ...
cno.Options = MQCNO_USE_CD_SELECTION; MQCONNX(QMName, &cno, &hConn2, &CompCode, &Reason);

CCDT ChlName.jpgYou have to use MQCONNX rather than MQCONN this time in order to provide the MQCD for the channel to be returned to you. The option MQCNO_CD_FOR_OUTPUT_ONLY informs the client code that it doesn't have to look at the MQCD from the perspective of using it as a channel definition, but should do it's usual look up as if there wasn't an MQCD provided, but then to copy the channel name into the MQCD to return to the application. On the second MQCONNX, the same MQCD is then reused with the option MQCNO_USE_CD_SELECTION telling the client code to use the channel name in the MQCD as well as the queue manager name, to look up the CCDT.

Example 4: Using a channel name to look up CCDT

The feature shown above means that you can also make a specific choice of channel name to use from a CCDT. This used to be a common error new folks would make when using a CCDT. They'd provide the channel name and expect that to be the look-up key in the CCDT to get all the other information. Well, now you can do that so long as you use the correct option.

MQLONG  CompCode, Reason;
MQHCONN hConn = MQHC_UNUSABLE_HCONN;
MQCNO   cno    = {MQCNO_DEFAULT};
MQCD    cd     = {MQCD_CLIENT_CONN_DEFAULT};
char  * QMName = "*MQGEM";
cno.Version       = MQCNO_VERSION_2;
cno.ClientConnPtr = &cd;
cno.Options       = MQCNO_USE_CD_SELECTION;
memcpy(cd.ChannelName, "MQG2.SVRCONN", MQ_CHANNEL_NAME_LENGTH);
MQCONNX(QMName,
        &cno,
        &hConn,
        &CompCode,
        &Reason);

Both the queue manager name and the channel name must match for an entry in the CCDT to be chosen.

So with this technique you have even more flexibility on how to use your CCDT.


Morag Hughson is an MQ expert. She spent 18 years in the MQ Devt organisation before taking on her current job writing MQ Technical education courses with MQGem. She also blogs for MQGem. You can connect with her here on IMWUC or on Twitter and LinkedIn.
0 Comments
2 Likes
Recent Stories
IBM MQ Little Gem #27: strmqtrc

IBM MQ Little Gem #26: Publish Delivery Options

IBM MQ Little Gem #25: MCAUSER(*)