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:
if WriteInt then ReadInt
etc..)if SetBooleanProperty(Name) then GetBooleanProperty(Name)
)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.
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.