Capitalware Inc.
Original Message:
Sent: Wed May 10, 2023 04:02 AM
From: Francois Brandelik
Subject: Websphere MQ filter Support for more fields
Why is nobody talking about the message properties?
If you want to filter on specific values, make sure that value is set as a message property by the sending application.
You should then be able to create a filter with the corresponding property = value clause.
For more specific information see https://www.ibm.com/docs/en/ibm-mq/9.3?topic=messages-message-selectors-in-jms
Hope this helps
------------------------------
Francois Brandelik
Original Message:
Sent: Tue May 09, 2023 01:57 PM
From: Roger Lacroix
Subject: Websphere MQ filter Support for more fields
what is the JMS header property to filter message data? EX: for msg type header property is JMS_IBM_MsgType like this what is the property for message data?
I already answered that question in my previous response (please re-read it).
(1) If the messages you are processing have the type set in the message data then you will need to code your application to handle it or use a solution like Message Broker/IIB/ACE. i.e. The code will have to browse all messages then destructively retrieve those messages that match. Not a very good design!! Note: MQ does not select messages based on message data or values in the message data.
To be clear, there is no message selector for selecting messages from a queue based on the message data. Your code needs to do all of the work!!!
That is why options #2 and #3 in my previous post are far, far betters options to use and it keeps the design nice and simple.
If I was designing the consumer application, the first thing I would ask "is the sender application using the MQMD Correlation Id (aka CorrelId) field?". Because if not, then the simple solution that will work for both Java (non-JMS) and JMS/Java (also C/C++/C#/COBOL/etc..) is to have the sender application set a value (i.e. MANAGER, EMPLOYEE or LEAD) in the CorrelId field and then in your consuming, you have the code to match on CorrelId.
i.e.
MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.options = CMQC.MQGMO_NO_SYNCPOINT | CMQC.MQGMO_NO_WAIT | CMQC.MQGMO_CONVERT | CMQC.MQGMO_FAIL_IF_QUIESCING;
gmo.matchOptions = CMQC.MQMO_MATCH_CORREL_ID;
MQMessage receiveMsg = new MQMessage();
receiveMsg.messageId = CMQC.MQMI_NONE;
receiveMsg.correlationId = "EMPLOYEE".getBytes();
// get the message on the queue
inQ.get(receiveMsg, gmo);
------------------------------
Roger Lacroix
CTO
Capitalware Inc.
London ON Canada
https://capitalware.com
Original Message:
Sent: Tue May 09, 2023 03:53 AM
From: Ranjitha YM
Subject: Websphere MQ filter Support for more fields
Thank You for responding,
My query is, I have the following messages in my queue. I want to select messages where message data is equal to Data 01.
for the selector string, I want to pass filter condition Message Data = Data o1 and expect 2 records as output
what is the JMS header property to filter message data? EX: for msg type header property is JMS_IBM_MsgType like this what is the property for message data?
Following is the JMS response, able to see the header property for all the fields except Message Data, it is at the end without any property.
Can you please let me know how to filter message data/syntax for the message data selector?
JMSMessage class: jms_text
JMSType: null
JMSDeliveryMode: 1
JMSDeliveryDelay: 0
JMSDeliveryTime: 0
JMSExpiration: 0
JMSPriority: 0
JMSMessageID: ID:414d5120514d5f594d522020202020207c2d566402a80040
JMSTimestamp: 1683371640590
JMSCorrelationID: null
JMSDestination: null
JMSReplyTo: null
JMSRedelivered: true
JMSXAppID: MQ Explorer 9.3.1
JMSXDeliveryCount: 10
JMSXUserID: adminqa
JMS_IBM_Character_Set: UTF-8
JMS_IBM_Encoding: 546
JMS_IBM_Format: MQSTR
JMS_IBM_MQMD_AccountingToken: 16010515000000942326C4DFF13E182CD9CC38F003000000000000000000000B
JMS_IBM_MQMD_ApplIdentityData:
JMS_IBM_MQMD_ApplOriginData:
JMS_IBM_MQMD_BackoutCount: 9
JMS_IBM_MQMD_CodedCharSetId: 1208
JMS_IBM_MQMD_CorrelId: 000000000000000000000000000000000000000000000000
JMS_IBM_MQMD_Encoding: 546
JMS_IBM_MQMD_Expiry: -1
JMS_IBM_MQMD_Feedback: 0
JMS_IBM_MQMD_Format: MQSTR
JMS_IBM_MQMD_GroupId: 000000000000000000000000000000000000000000000000
JMS_IBM_MQMD_MsgFlags: 0
JMS_IBM_MQMD_MsgId: 414D5120514D5F594D522020202020207C2D566402A80040
JMS_IBM_MQMD_MsgSeqNumber: 1
JMS_IBM_MQMD_MsgType: 8
JMS_IBM_MQMD_Offset: 0
JMS_IBM_MQMD_OriginalLength: -1
JMS_IBM_MQMD_Persistence: 0
JMS_IBM_MQMD_Priority: 0
JMS_IBM_MQMD_PutApplName: MQ Explorer 9.3.1
JMS_IBM_MQMD_PutApplType: 11
JMS_IBM_MQMD_PutDate: 20230506
JMS_IBM_MQMD_PutTime: 11140059
JMS_IBM_MQMD_ReplyToQ:
JMS_IBM_MQMD_ReplyToQMgr: QM_YMR
JMS_IBM_MQMD_Report: 0
JMS_IBM_MQMD_UserIdentifier: adminqa
JMS_IBM_MsgType: 8
JMS_IBM_PutApplType: 11
JMS_IBM_PutDate: 20230506
JMS_IBM_PutTime: 11140059
Data 01
------------------------------
Ranjitha YM
Original Message:
Sent: Mon May 08, 2023 05:29 PM
From: Roger Lacroix
Subject: Websphere MQ filter Support for more fields
I'm very confused by the different questions you have asked.
> EX: we have message data, 1) Manager 2) Employee 3) Lead 4) Manager
> I want to read messages where message data equal to Manager
What does that mean?
Also, do you understand what this code does?
String selector = "JMS_IBM_MsgType =8";
consumer = session.createConsumer(queDest, selector);
You are selecting messages that have a Message Type of MQMT_DATAGRAM.
No offence intended, but you appear to be new to IBM MQ. Queues like a database table should have a single focus or data type going to it. As I always tell my customers, you should hand out queues like candy on Halloween. Having multiple-purpose queues only leads to far more complicated code.
(1) 90% of the applications set a tag or field in the message data to denote the type of data contained
(2) 10% of the applications set a Named Property (aka Message Property) to denote the type of data contained
(3) 0.001% of the applications set the message's Message Type field to have a unique value
(1) If the messages you are processing have the type set in the message data then you will need to code your application to handle it or use a solution like Message Broker/IIB/ACE. i.e. The code will have to browse all messages then destructively retrieve those messages that match. Not a very good design!! Note: MQ does not select messages based on message data or values in the message data.
(2) If the type is in a Named Property, you can use a Message Selector to retrieve those messages.
(3) Have the sending application set a unique type in the Message Type field of the message. You can define your own message types. They just have to start at 65536 or higher.
i.e.
In C you would do:
#define MT_MANAGER 65536
#define MT_EMPLOYEE 65537
#define MT_LEAD 65538
In Java you would do:
public static final int MT_MANAGER = 65536;
public static final int MT_EMPLOYEE = 65537;
public static final int MT_LEAD = 65538;
Now you can use a simple selector like this:
String selector = "JMS_IBM_MsgType ="+MT_MANAGER;
consumer = session.createConsumer(queDest, selector);
And it will retrieve just those messages matching the Message Type.
------------------------------
Roger Lacroix
CTO
Capitalware Inc.
London ON Canada
https://capitalware.com
Original Message:
Sent: Sat May 06, 2023 10:14 PM
From: Ranjitha YM
Subject: Websphere MQ filter Support for more fields
Using com.ibm.mqjms TPL I tried to implement filter, am able to filter messages based on the below properties
But I want to filter messages based on Message Data
EX: we have message data, 1) Manager 2) Employee 3) Lead 4) Manager
I want to read messages where message data equal to Manager
JMSMessage class |
JMSType |
JMSDeliveryMode |
JMSDeliveryDelay |
JMSDeliveryTime |
JMSExpiration |
JMSPriority |
JMSMessageID |
JMSTimestamp |
JMSCorrelationID |
JMSDestination |
JMSReplyTo |
JMSRedelivered |
JMSXAppID |
JMSXDeliveryCount |
JMSXUserID |
JMS_IBM_Character_Set |
JMS_IBM_Encoding |
JMS_IBM_Format |
JMS_IBM_MsgType |
JMS_IBM_PutApplType |
JMS_IBM_PutDate |
JMS_IBM_PutTime |
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.Session;
import javax.jms.TextMessage;
import com.ibm.mq.jms.MQQueueConnectionFactory;
import com.ibm.msg.client.wmq.WMQConstants;
public class IBMMQ_JMSFilter{
public static void main(String[] args) throws NumberFormatException, JMSException {
QueueConnection Queue_Con;
MessageConsumer consumer;
String host = "host";
String port = "port";
String username = "UN";
String password = "Pass";
String queueManager = "QM";
String channel = "QA.APP.SVRCONN";
// Create queue manager connection
MQQueueConnectionFactory MQ_conFact = new MQQueueConnectionFactory();
MQ_conFact.setHostName (host);
MQ_conFact.setPort (Integer.parseInt(port));
MQ_conFact.setQueueManager (queueManager);
MQ_conFact.setChannel (channel);
MQ_conFact.setTransportType (WMQConstants.WMQ_CM_CLIENT);
//Queue_Con = MQ_conFact.createQueueConnection ();
Queue_Con = (QueueConnection) MQ_conFact.createConnection(username, password);
//Create session
Session session =
Queue_Con.createSession(false, Session.CLIENT_ACKNOWLEDGE); // non-transacted session (more)
// Queue queue = session.createQueue("QA.QUEUE.1");
//Create queue connection
Destination queDest= session.createQueue("QA.QUEUE.1");
String selector = "JMS_IBM_MsgType =8";
consumer = session.createConsumer(queDest, selector);
//consumer = session.createConsumer(queDest);
Queue_Con.start(); // start the connection (more)
while (true) { // run forever
Message msg = consumer.receiveNoWait(); // blocking! (more)
// if (! (msg instanceof TextMessage))
// throw new RuntimeException("Expected a TextMessage");
TextMessage tm = (TextMessage) msg;
System.out.println(tm.getText()); // print message content
}
}
}
------------------------------
Ranjitha YM
Original Message:
Sent: Mon March 20, 2023 01:35 PM
From: Morag Hughson
Subject: Websphere MQ filter Support for more fields
Hi Ranjitha,
The fields you show us that can be matched on are not queue attributes, but message attributes.
Match Option | Message attribute |
MQMO_MATCH_MSG_SEQ_NUMBER | MQMD.MsgSeqNumber |
MQMO_MATCH_GROUP_ID | MQMD.GroupId |
MQMO_MATCH_CORREL_ID | MQMD.CorrelId |
MQMO_MATCH_MSG_ID | MQMD.MsgId |
MQMO_MATCH_MSG_TOKEN | MQGMO.MsgToken |
MQMO_MATCH_OFFSET | MQMD.Offset |
You can use an SQL selector string to match on any field in the MQMD. Some example selector strings are shown in this post. You can use the selector string using the JMS API thus:-
// Create consumer with selector String selector = "Root.MQMD.MsgType = 4"; MessageConsumer cons = session.createConsumer(queDest, selector);
Cheers,
Morag
------------------------------
Morag Hughson
MQ Technical Education Specialist
MQGem Software Limited
Website: https://www.mqgem.com
Original Message:
Sent: Sun March 19, 2023 06:28 PM
From: Ranjitha YM
Subject: Websphere MQ filter Support for more fields
Team,
with java code, we are reading Queue messages, and also reading with filter.
We are using the below function to read queue messages with a filter. this function supports only 6 fields but Queue has more than 25 fields
1) gmo.matchOptions =
MQConstants.MQMO_MATCH_MSG_SEQ_NUMBER;
2) gmo.matchOptions = MQConstants.MQMO_MATCH_GROUP_ID;
3) gmo.matchOptions =
MQConstants.MQMO_MATCH_CORREL_ID;
4) gmo.matchOptions = MQConstants.MQMO_MATCH_MSG_ID;
5) gmo.matchOptions =
MQConstants.MQMO_MATCH_MSG_TOKEN;
6) gmo.matchOptions = MQConstants.MQMO_MATCH_OFFSET;
We want to filter data with all the fields. Can you please support the filter for all the fields ?
we are using the below IBM MQ Jars
com.ibm.mq
com.ibm.mq.jmqi
com.ibm.mq.pcf
please let us know If any other method available which supports all the fields.
------------------------------
Ranjitha YM
------------------------------