.netwebsphereibm-mqmq

MQMessage exploring (using WebSphere MQ .NET API)


I'm really new to WebSphere MQ, but I have one question regarding the MQMessage API. It seems that a receiver of MQMessage should know in advance:

It make no sense to me. Since if I'm not familiar with the message structure should I explore all options until I retrieve the data in it?

Help will be appreciated.


Solution

  • Yes, you are absolutely correct that if the message is structured data such as a fixed-length record format, you must know in advance the format of the message in order to parse it. On the other hand, if the message payload is tagged data structure (such as valid XML) then you would use normal parsing to access it. For example, you might use XPath to access an XML payload without first knowing the exact structure.

    The methods that you mention (WriteInt, ReadInt, etc.) would ordinarily be used to extract data from a known format and advance the buffer pointer to the next field. However, there are also methods to read and write UTF strings. If for some reason your application must process a variety of message types, then you can inquire on the message format and message type by querying the message descriptor. The method for doing this is documented in Message descriptor fields as properties. In this way you can distinguish between different types and formats of message and parse them appropriately.

    Note that the docs I have linked above are to the v7 .Net classes. Since v6 end-of-life is September 2011, it is hoped that new development is all with the v7 classes, and preferably connecting to a v7 QMgr.

    Edit - Response to comments

    Example of checking the message format:
    As per the page linked above, check the C header file cmqc.h for the fields in the MQMD. This will tell you the field name as well as the field type. In a default Windows installation, this file lives at C:\Program Files\IBM\WebSphere MQ\tools\c\include\cmqc.h

    So for example, message.getStringProperty('Root.MQMD.Format') returns the message format. Near the top of cmqc.h you will find a list of macros named MQFMT_ with the possible values for the MQMD Format field. As of v7.01 they look like this:

     /* Formats */
     #define MQFMT_NONE               "        "
     #define MQFMT_ADMIN              "MQADMIN "
     #define MQFMT_CHANNEL_COMPLETED  "MQCHCOM "
     #define MQFMT_CICS               "MQCICS  "
     #define MQFMT_COMMAND_1          "MQCMD1  "
     #define MQFMT_COMMAND_2          "MQCMD2  "
     #define MQFMT_DEAD_LETTER_HEADER "MQDEAD  "
     #define MQFMT_DIST_HEADER        "MQHDIST "
     #define MQFMT_EMBEDDED_PCF       "MQHEPCF "
     #define MQFMT_EVENT              "MQEVENT "
     #define MQFMT_IMS                "MQIMS   "
     #define MQFMT_IMS_VAR_STRING     "MQIMSVS "
     #define MQFMT_MD_EXTENSION       "MQHMDE  "
     #define MQFMT_PCF                "MQPCF   "
     #define MQFMT_REF_MSG_HEADER     "MQHREF  "
     #define MQFMT_RF_HEADER          "MQHRF   "
     #define MQFMT_RF_HEADER_1        "MQHRF   "
     #define MQFMT_RF_HEADER_2        "MQHRF2  "
     #define MQFMT_STRING             "MQSTR   "
     #define MQFMT_TRIGGER            "MQTRIG  "
     #define MQFMT_WORK_INFO_HEADER   "MQHWIH  "
     #define MQFMT_XMIT_Q_HEADER      "MQXMIT  "
    

    The actual MQMD structure is defined near the bottom of cmqc.h. As of v7.0.1 it looks like this:

     /****************************************************************/
     /*  MQMD2 Structure -- Version-2 Message Descriptor             */
     /****************************************************************/
    
    
     typedef struct tagMQMD2 MQMD2;
     typedef MQMD2 MQPOINTER PMQMD2;
    
     struct tagMQMD2 {
       MQCHAR4   StrucId;           /* Structure identifier */
       MQLONG    Version;           /* Structure version number */
       MQLONG    Report;            /* Report options */
       MQLONG    MsgType;           /* Message type */
       MQLONG    Expiry;            /* Expiry time */
       MQLONG    Feedback;          /* Feedback or reason code */
       MQLONG    Encoding;          /* Numeric encoding of message data */
       MQLONG    CodedCharSetId;    /* Character set identifier of message
                                       data */
       MQCHAR8   Format;            /* Format name of message data */
       MQLONG    Priority;          /* Message priority */
       MQLONG    Persistence;       /* Message persistence */
       MQBYTE24  MsgId;             /* Message identifier */
       MQBYTE24  CorrelId;          /* Correlation identifier */
       MQLONG    BackoutCount;      /* Backout counter */
       MQCHAR48  ReplyToQ;          /* Name of reply-to queue */
       MQCHAR48  ReplyToQMgr;       /* Name of reply queue manager */
       MQCHAR12  UserIdentifier;    /* User identifier */
       MQBYTE32  AccountingToken;   /* Accounting token */
       MQCHAR32  ApplIdentityData;  /* Application data relating to
                                       identity */
       MQLONG    PutApplType;       /* Type of application that put the
                                       message */
       MQCHAR28  PutApplName;       /* Name of application that put the
                                       message */
       MQCHAR8   PutDate;           /* Date when message was put */
       MQCHAR8   PutTime;           /* Time when message was put */
       MQCHAR4   ApplOriginData;    /* Application data relating to
                                       origin */
       MQBYTE24  GroupId;           /* Group identifier */
       MQLONG    MsgSeqNumber;      /* Sequence number of logical message
                                       within group */
       MQLONG    Offset;            /* Offset of data in physical message
                                       from start of logical message */
       MQLONG    MsgFlags;          /* Message flags */
       MQLONG    OriginalLength;    /* Length of original message */
     };
    

    The cmqc.h file defines macros for each of the fields shown and these will contain the possible values. These macros are also defined in the .Net classes as the MQC object. MQC is described here but since it has no methods, the page just refers you to the list of WMQ constants which it defines. That page is here.