PCF comand to set authorities (revisited)

Asked by jeff mcdowell

Hi Darren--

There was a question a few months ago about an error being received when trying to execute: MQCMD_SET_AUTH_REC

Attempting to run this gets the following error:
pymqi.MQMIError: MQI Error. Comp: 2, Reason 2321: FAILED: MQRC_PARAMETER_MISSING

I was trying to run this with the following params:
pcf.MQCMD_SET_AUTH_REC ({
      CMQCFC.MQCACF_AUTH_PROFILE_NAME: "MYQUEUE.2",
      CMQCFC.MQIACF_OBJECT_TYPE: "MQOT_Q",
      CMQCFC.MQIACF_AUTH_ADD_AUTHS: "MQAUTH_BROWSE",
      CMQCFC.MQCACF_GROUP_ENTITY_NAMES: "swww02"
    })

I reached out to IBM and found that the variables above are all actually different PCF structure types:

MQCMD_SET_AUTH_REC
- CMQCFC.MQCACF_AUTH_PROFILE_NAME: MQCFST - PCF string parameter
- CMQCFC.MQIACF_OBJECT_TYPE: MQCFIN - PCF integer parameter
- CMQCFC.MQIACF_AUTH_ADD_AUTHS: MQCFIL - PCF integer list parameter
- CMQCFC.MQCACF_GROUP_ENTITY_NAMES: MQCFSL - PCF string list parameter

In all of your pymqi examples provided, and even unfortunately in data returned by the MQCMD_INQUIRE_AUTH_RECS command, all variables are either MQCFST (strings) or MQCFIN (integers).

I can't find an example of how a MQCFIL (integer list) or MQCFSL (string list) should actually look if I was attempting to create and initiate a SET_AUTH_REC

Can you help track this down?
Thank you so much for all of your work with this wonderful tool!!

Question information

Language:
English Edit question
Status:
Answered
For:
PyMQI Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Revision history for this message
jeff mcdowell (mcdowellstl) said :
#1

A little more info on the MQCFSL (string list)and MQCFIL (integer list) params:

It looks like the MQCMD_INQUIRE_CHANNEL_NAMES command actually returns both of these, in the format of channel name and channel type. The returned output looks like this when I pass in a "*" to return all channels on a queue manager. This is the data that was returned:

[{3512L: ['NOSSL.SVRCONN ', 'SYSTEM.AUTO.RECEIVER', 'SYSTEM.AUTO.SVRCONN ', 'SYSTEM.DEF.CLUSRCVR ', 'SYSTEM.DEF.CLUSSDR ', 'SYSTEM.DEF.RECEIVER ', 'SYSTEM.DEF.REQUESTER', 'SYSTEM.DEF.SENDER ', 'SYSTEM.DEF.SERVER ', 'SYSTEM.DEF.SVRCONN ', 'TEST.SVRCONN ', 'TESTQM.TESTQM2 '], 1582L: [7L, 3L, 7L, 8L, 9L, 3L, 4L, 1L, 2L, 7L, 7L, 1L]}]

Notice the "string length header" in front of the string list and integer list, for both of these types (3512L & 1582L). It is certainly easy enough to create a list of strings in python, but I can't get figure out how to put in a length indentifier in the same format that is returned by the data.

Revision history for this message
Dariusz Suchojad (dsuch) said :
#3

Just to confirm - this is MQ 7.5, right?

Revision history for this message
jeff mcdowell (mcdowellstl) said :
#4

MQ 7.1 actually, Dariusz

Revision history for this message
jeff mcdowell (mcdowellstl) said :
#5

Doing more research on this, Dariusz.. And I am worried that pymqi may not support what I need here:

If I build a python dictionary that includes a long value, followed by an array of strings or integers,
I can match the format returned by other PCF functions that utilize this same data structure.

I did this with the following:
====================================================
groupEntity ={128L: ['swww02']}
authEntity = {128L: [CMQCFC.MQAUTH_BROWSE]}

args = {CMQCFC.MQCACF_AUTH_PROFILE_NAME: 'MYQUEUE.2',
... CMQCFC.MQIACF_OBJECT_TYPE: CMQC.MQOT_Q,
... CMQCFC.MQIACF_AUTH_ADD_AUTHS: authEntity,
... CMQCFC.MQCACF_GROUP_ENTITY_NAMES: groupEntity}

>>> print args
{1016: 1, 3066: {128L: ['swww02']}, 3067: 'MYQUEUE.2', 1116: {128L: [2]}}
====================================================

However, when I attempt to use this to set an authority:
result = pcf.MQCMD_SET_AUTH_REC(args)

I get the following error:
====================================================
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/site/lib/python/pymqi.py", line 2085, in __call__
    rv = pymqe.mqaiExecute(qmHandle, CMQCFC.__dict__[self.__name], args[0])
pymqe.error: Value [2] for key 1116 is not a long, string nor a pymqi.ByteString instance
====================================================

If the PCF commands require a dictionary data type,
Is there workaround to the restriction above that limits these values to long, string, or ByteString.

Would the ByteString be a potential usecase for what I am trying to accomplish?

Revision history for this message
Dariusz Suchojad (dsuch) said :
#6

Jeff,

the not so good news is that PyMQI won't currently support it. Like you've discovered, parameters to PCFExecute need to be plain ints, strings or ByteStrings.

The latter is what I've come up with for situations when you need to pass an MQBYTE from Python to C. A similar thing should be done with integer lists here, MQCFIL defined in cmqcfc.h.

The deal is, there are no usage examples and it would be really helpful if there were. Do you think you can open a PMR with IBM asking for an MQCMD_SET_AUTH_REC usage example with MQCFIL in C?

I'm sure they should be able to find something and I could take it up from there.

Many thanks!

Revision history for this message
jeff mcdowell (mcdowellstl) said :
#7

Thanks Dariusz-

I think that it will need to support Integer Lists (MQCFIL) and String Lists (MQCFSL) as well.
I will ask IBM for C examples for both of those from within the MQCMD_SET_AUTH_REC calls.

In the meantime,
Here are some generic C struct typedefs for each of those types:

typedef struct tagMQCFSL {
  MQLONG Type; /* Structure type */
  MQLONG StrucLength; /* Structure length */
  MQLONG Parameter; /* Parameter identifier */
  MQLONG CodedCharSetId; /* Coded character set identifier */
  MQLONG Count; /* Count of parameter values */
  MQLONG StringLength; /* Length of one string */
  MQCHAR Strings[1]; /* String values - first
                              character */
 } MQCFSL;

typedef struct tagMQCFIL {
  MQLONG Type; /* Structure type */
  MQLONG StrucLength; /* Structure length */
  MQLONG Parameter; /* Parameter identifier */
  MQLONG Count; /* Count of parameter values */
  MQLONG Values[1]; /* Parameter values - first element */
 } MQCFIL;

Revision history for this message
jeff mcdowell (mcdowellstl) said :
#8

Here is what IBM came back to me with:

Below is a link to the only pcf sample (from IBM) that I know of. This is the code for the support pac MS03 (Saveqmgr) and the source code I used for the snippets I reference below:
http://publib.boulder.ibm.com/infocenter/wmqv6/v6r0/index.jsp?topic=%2Fcom.ibm.mq.csqzac.doc%2Fpc15430_.htm
.
You can't use your own definitions for parameter lists. I have no idea what that syntax is ({3512L: [2]}). You have to use the datatypes defined in the mq header files. PCF programing is a bit complicated and requires a good understanding of programming techniques (in particular buffer manipulation). Below are some snippets from the sample (saveqmgr) that I think you need to understand:
.
.
They have definitions for pointers to the various data types:
.
MQBYTE *pAdminMsg; /* Ptr to outbound data buffer */
MQLONG AdminMsgLen /* lenght of user message buffer */
MQCFH *pPCFHeader; /* Ptr to PCF header structure */
MQCFST *pPCFString; /* Ptr to PCF string parm block */
MQCFIN *pPCFInteger; /* Ptr to PCF integer parm block */
.
So you need to include one for MQCFIL:
MQCFIL *pPCFIntegerList;
.
Here is where they set up the data in the allocated memory block that will be put into the msg which goes to the sys command queue:
.
/* Setup request header */
pPCFHeader->Type = MQCFT_COMMAND;
pPCFHeader->StrucLength = MQCFH_STRUC_LENGTH;
pPCFHeader->Version = MQCFH_VERSION_1;
pPCFHeader->Command = MQCMD_INQUIRE_Q;
/** NOTE: I think the 'Command' for you should be MQCMD_SET_AUTH_REC **/
pPCFHeader->MsgSeqNumber = MQCFC_LAST;
pPCFHeader->Control = MQCFC_LAST;
pPCFHeader->ParameterCount = 2;
.
/* Setup parameter block */
pPCFString->Type = MQCFT_STRING;
pPCFString->StrucLength = MQCFST_STRUC_LENGTH_FIXED + MQ_Q_NAME_LENGTH;
pPCFString->Parameter = MQCA_Q_NAME;
pPCFString->CodedCharSetId = MQCCSI_DEFAULT;
pPCFString->StringLength = MQ_Q_NAME_LENGTH;
memset( pPCFString->String, ' ', MQ_Q_NAME_LENGTH );
memcpy( pPCFString->String, "*", 1 );
.
/* Setup parameter block */
pPCFInteger->Type = MQCFT_INTEGER;
pPCFInteger->StrucLength = MQCFIN_STRUC_LENGTH;
pPCFInteger->Parameter = MQIA_Q_TYPE;
pPCFInteger->Value = MQQT_LOCAL;
****************
.
So here is the struct def from the cmqcfc.h file that you need to fill in:
struct tagMQCFIL {
MQLONG Type; /* Structure type */
MQLONG StrucLength; /* Structure length */
MQLONG Parameter; /* Parameter identifier */
MQLONG Count; /* Count of parameter values */
MQLONG Values[1]; /* Parameter values -- first element */
};
.
You should set this up something like this:
.
pPCFIntegerList->Type = MQCFT_INTEGER_LIST;
pPCFIntegerList->StructLength = MQCFIL_STRUC_LENGTH_FIXED + (2 * sizeof (MQLONG));;
pPCFIntegerList->Parameter = MQIACF_AUTH_ADD_AUTHS;
pPCFIntegerList->Count = 2;
pPCFIntegerList->Values[0] = MQAUTH_BROWSE;
pPCFIntegerList->Values[1] = MQAUTH_INQUIRE;

Revision history for this message
Dariusz Suchojad (dsuch) said :
#9

Thanks Jeff, I'll see if this is helpful.

Agreed that PCF 'is a bit complicated ', aka as a mess, hence IBM themselves simplified the API by introducing MQAI, another API on top of PCF. Because what you've just posted is raw PCF, this isn't exactly what PyMQI uses, it needs to go through the layer of MQAI. Let me just see what I can do with it.

Thanks again!

Revision history for this message
Dariusz Suchojad (dsuch) said :
#10

OK Jeff, can you ask IBM the following question?

"""
How can we pass integer lists (MQCFIL) and string lists (MQCFSL) into MQAI?

When using string, integer or byte string parameters, MQAI offers, respectively, mqAddString, mqAddInteger and mqAddByteString.

One of the parameters to MQCMD_SET_AUTH_REC is an MQCFIL yet there is no hypothetical 'mqAddIntegerList' in the MQAI.

How one should use such an MQCFIL parameter with MQAI? Is it possible at all?
"""

Revision history for this message
jeff mcdowell (mcdowellstl) said :
#11

L3 from IBM just got back to us and the news isn't good:

According to the v7.1 MQAI manual, topic pc15550, the only data items that can be used are:
When you have created a data bag, you can populate it with integer or character-string items.
You can inquire about all three types of item.

The data item can either be integer or character-string items. Here are the types of data item available within the MQAI:
Integer
64-bit integer
Integer filter
Character-string
String filter
Byte string
Byte string filter
Bag handle

It appears that there is no way to use either an MQCFIL or MQCFSL PCF type in MQAI. To add these PCF types to the MQAI would require a DCR to be raised and approved.

==========

Without this available, do you have any recommendations on how one might go about tackling this problem?
Should I try to skip the API layer and use Java or C to create the PCF command ourselves?

Revision history for this message
Dariusz Suchojad (dsuch) said :
#12

> It appears that there is no way to use either an MQCFIL or MQCFSL PCF
> type in MQAI. To add these PCF types to the MQAI would require a DCR to
> be raised and approved.

Hmm.. I'm not sure what a DCR is but this seems an oversight on IBM's part.

And I'm really sorry Jeff, but without MQCFIL and MQCFSL in MQAI PyMQI
won't be able to do what you need :-(

Revision history for this message
Dariusz Suchojad (dsuch) said :
#13

I've just released PyMQI 1.3 and the development effort has moved to GitHub - https://github.com/dsuch/pymqi

Can you help with this problem?

Provide an answer of your own, or ask jeff mcdowell for more information if necessary.

To post a message you must log in.