What are WebSphere MQ Everyplace messages?

Messages are simply collections of data sent by one application and intended for another application. WebSphere MQ Everyplace messages contain application-defined content. When stored, they are held in a queue and such messages may be moved across a WebSphere MQ Everyplace network.

WebSphere MQ Everyplace messages are a special type of MQeFields items, as described in MQeFields. Therefore, you can use methods that are applicable to MQeFields with messages.

Therefore, messages are Fields objects with the addition of some special fields. Java provides a subclass of MQeFields, MQeMsgObject which provides methods to manage these fields. The C codebase does not provide such a subclass. Instead, there are a number of mqeFieldsHelper_operation functions. The following fields form the Unique ID of a WebSphere MQ Everyplace message:

The Unique ID identifies a message within a WebSphere MQ Everyplace network provided all queue managers within the WebSphere MQ Everyplace network are named uniquely. However, WebSphere MQ Everyplace does not check or enforce the uniqueness of queue manager names.

In Java, the message is created when an instance of MQeMsgObject is created. In C, the Message is "created", that is UniqueID fields are added, when the message is put to a queue.

The getMsgUIDFields()method or mqeFieldsHelpers_getMsgUidFields() function accesses the UniqueID of a message, for example:

Java code
MQeFields msgUID = msgObj.getMsgUIDFields();
C code
rc = mqeFieldsHelpers_getMsgUidFields(hMgsObj, 
								&exceptBlock,&hUIDFields);

WebSphere MQ Everyplace adds property related information to a message (and subsequently removes it) in order to implement messaging and queuing operations. When sending a message between queue managers, you can add resend information to indicate that data is being retransmitted.

Typical application-based messages have additional properties in accordance with their purpose. Some of these additional properties are generic and common to many applications, such as the name of the reply-to queue manager. Therefore, WebSphere MQ Everyplace supports the following message properties:

Table 1. Message properties
Property name Java type C type Description
Action int MQEINT32 Used by administration to indicate actions such as inquire, create, and delete
Correlation ID byte[] MQEBYTE[] Byte string typically used to correlate a reply with the original message
Errors MQeFields MQeFieldsHndl Used by administration to return error information
Expire time int or long MQEINT32 or MQEINT64 Time after which the message can be deleted (even if it is not delivered)
Lock ID long MQEINT64 The key necessary to unlock a message
Message ID byte[] MQEBYTE[] A unique identifier for a message
Originating queue manager string MQeStringHndl The name of the queue manager that sent the message
Parameters MQeFields MQeFieldsHndl Used by administration to pass administration details
Priority byte MQEBYTE Relative order of priority for message transmission
Reason string MQeStringHndl Used by administration to return error information
Reply-to queue string MQeStringHndl Name of the queue to which a message reply should be addressed
Reply-to queue manager string MQeStringHndl Name of the queue manager to which a message reply should be addressed
Resend boolean MQEBOOL Indicates that the message is a resend of a previous message
Return code byte MQEBYTE Used by administration to return the status of an administration operation
Style byte MQEBYTE Distinguishes commands from request/reply for example
Wrap message byte[] MQEBYTE[] Message wrapped to ensure data protection

For the symbolic names corresponding to the message properties in the previous table, refer to the WebSphere MQ Everyplace Java Programming Reference and the WebSphere MQ Everyplace C Programming Reference.

In all cases, a defined constant allows the property name to be carried in a single byte. For example, priority (if present) affects the order in which messages are transmitted, correlation ID triggers indexing of a queue for fast retrieval of information, expire time triggers the expiry of the message, and so on. Also, the default message dump command minimizes the size of the generated byte string for more efficient message storage and transmission.

The WebSphere MQ Everyplace Message ID and Correlation ID allow the application to provide an identity for a message. These are also used in interactions with the rest of the WebSphere MQ family:

Java
MQeMsgObject msgObj = new MQeMsgObject;
msgObj.putArrayOfByte( MQe.Msg_ID, MQe.asciiToByte( "1234" ));
C
rc = mqeFields_putArrayOfByte(hMsg,&exceptBlock, 
						MQE_MSG_MSGID,pByteArray,sizeByteArray);

Priority contains message priority values. Message priority is defined as in other members of the WebSphere MQ family. It ranges from 9 (highest) to 0 (lowest):

Java
MQeMsgObject msgObj = new MQeMsgObject();
msgObj.putByte( MQe.Msg_Priority, (byte)8 );
C
rc = mqeFields_putByte(hsg,&exceptBlock, MQE_MSG_PRIORITY, (MQEBYTE)8);

Applications can create fields for their own data within messages:

Java
MQeMsgObject msgObj = new MQeMsgObject();
msgObj.putAscii( "PartNo", "Z301" );
msgObj.putAscii( "Colour", "Blue" );
msgObj.putInt( "Size", 350 );
C
MQeFieldsHndl hPartMsg;
MQeStringHndl hSize_FieldLabel;
rc = mqeFields_new(&exceptBlock,&hPartMsg);
rc = mqeString_newUtf8(&exceptBlock, 
									&hSize_FieldLabel,"Size");

rc = mqeFields_putInt32(hPartMsg, 
								&exceptBlock,hSize_FieldLabel,350);

The priority of the message is used, in part, to control the order in which messages are removed from the queue. If the message does not specify any, then the queue default priority is used . This, unless changed, is 4. However, the application must interpret the different levels of priority.

In Java, you can extend the MQeMsgObject to include some methods that assist in creating messages, as shown in the following example:

package messages.order;
import com.ibm.mqe.*;

/*** This class defines the Order Request format */
public class OrderRequestMsg extends MQeMsgObject
{

  public OrderRequestMsg() throws Exception
  {
  }

 /*** This method sets the client number */
  public void setClientNo(long aClientNo) throws Exception
  {
    putLong("ClientNo", aClientNo);
  }

 /*** This method returns the client number */
  public long getClientNo() throws Exception
  {
    return getLong("ClientNo");
  }

To find out the length of a message, you can enumerate on the message as each data type has methods for getting its length.

Message Filters

Filters allow WebSphere MQ Everyplace to perform powerful message searches. Most of the major queue manager operations support the use of filters. You can create filters using MQeFields.

Using a filter, for example in a getMessage() call, causes an application to return the first available message that contains the same fields and values as the filter. The following examples create a filter that obtains the first message with a message id of "1234":

Java
MQeFields filter = new MQeFields();
filter.putArrayOfByte( MQe.Msg_MsgID, 
				MQe.AsciiToByte( "1234" ) );
C
rc = mqeFields_putArrayOfByte(hMsg,,
&exceptBlock, MQE_MSG_MSGID,
pByteArray, sizeByteArray);

You can use this filter as an input parameter to various API calls, for example getMessage.

Message Expiry

Queues can be defined with an expiry interval. If a message has remained on a queue for a period of time longer than this interval then the message is automatically deleted. When a message is deleted, a queue rule is called. Refer to Chapter 3, Rules, of the WebSphere MQ Everyplace System Programming Guide for information on queue rules. This rule cannot affect the deletion of the message, but it does provide an opportunity to create a copy of the message.

Messages can also have an expiry interval that overrides the queue expiry interval. You can define this by adding a C MQE_MSG_EXPIRETIME or Java MQe.Msg_ExpireTime field to the message. The expiry time is either relative (expire 2 days after the message was created), or absolute (expire on November 25th 2000, at 08:00 hours). Relative expiry times are fields of type Int or MQEINT32, and absolute expiry times are fields of type Long or MQEINT64.

In the example below, the message expires 60 seconds after it is created (60000 milliseconds = 60 seconds).

/* create a new message					*/
MQeMsgObject msgObj = new MQeMsgObject();
msgObj.putAscii( "MsgData", getMsgData() );
/* expiry time of sixty seconds after message was created		*/
msgObj.putInt( MQe.Msg_ExpireTime, 60000 );

In the example below, the message expires on 15th May 2001, at 15:25 hours.

/* create a new message					*/
MQeMsgObject msgObj = new MQeMsgObject();
msgObj.putAscii( "MsgData", getMsgData() );
/* create a Date object for 15th May 2001, 15:25 hours			*/
Calendar calendar = Calendar.getInstance();
calendar.set( 2001, 04, 15, 15, 25 );
Date expiryTime = calendar.getTime();
/* add expiry time to message				*/
msgObj.putLong( MQe.Msg_ExpireTime, expiryTime.getTime() );
/* put message onto queue				*/
qmgr.putMessage( null, "MyQueue", msgObj, null, 0 );