Original Message:
Sent: 8/7/2022 8:02:00 PM
From: Glenn Baddeley
Subject: RE: MQ related
>FIFO must be guaranteed.
FIFO is a delivery sequence from the MQ queue to the consumer app threads. It is NOT guaranteed to be the message order that the producer put messages into MQ, except in very specific circumstances.
If you need strict message ordering from producer to consumer, you should provide marshalling logic in the consumer app. This needs to cater for out-of-order arrival, missing messages, long delayed messages etc.
------------------------------
Glenn Baddeley
Senior Middleware Software Engineer
Coles Supermarkets Australia Pty Ltd
------------------------------
Original Message:
Sent: Wed August 03, 2022 06:21 AM
From: Balaji Patil
Subject: MQ related
Basically our requirement is bit complex, its as below:
It would be nice to specify the type of messages coming in on a specific queue and process the messages differently based on that type.
For type 1:
FIFO must be guaranteed. Those messages basically have to be processed in order from MQ into MES (may require single threaded interface or multi-threaded using a semaphore).
For type 2:
These messages do not have an order requirement so processing quickly (if multi-threading makes sense then that would be great, number of threads configurable)
------------------------------
Balaji Patil
Original Message:
Sent: Sun July 31, 2022 01:10 PM
From: Andrew Hickson
Subject: MQ related
In this case the customer doesn't need all of the messages processed in order, just some subset of messages.
I'd be tempted to suggest they try and split the messages that must be strictly ordered onto their own queue, but if that;s not possible the restriction is really that only one thread should be allowed to have an outstanding MQGET at any point in time, essentially a pipeline implementation (c.f. channel PipeLineLength). In the most trivial implementation the app would take a lock before issuing the MQGET. Once a message is retrieved the lock could be released in any case where the message did not need to be serialized with other messages on the same queue. In the case where the message does need to be serialized then the lock would be held until after the commit. A more sophisticated design, with a larger set of locks, could allow a bit more concurrency in processing the messages that do need to be serialized while still allowing some concurrency.
------------------------------
Andrew Hickson
Original Message:
Sent: Fri July 29, 2022 11:11 AM
From: Colin Paice
Subject: MQ related
If you want to ensure that messages are processed in order, then you can only have one thread getting the messages.
For example
Thread1 does MQGET, MQPUT reply1 , slight delay
Thread 2 does MQGET, MQPUT reply2
Thread 2 does Commit. Reply 2 is visible on the queue and can be processed or sent off
Thread 1 does commit . reply1 is now visible on the queue.
If no application is getting the messages then the messages will be reply1, reply2 on the queue.
Colin
------------------------------
Colin Paice
Original Message:
Sent: Fri July 29, 2022 05:47 AM
From: Shashikanth Rao Thambrahalli
Subject: MQ related
1. What do you mean by "delete manually"? I think you meant "explicitly delete message after it is processed by your application"? You can use the CLIENT_ACKNOWLEDGE mode when creating the session. In this mode, the client application has to call message.Acknowledge() method to delete message from queue.
2. Is it FIFO? The default message delivery sequence is Priority, meaning messages with higher priority are delivered first and then messages of lower priority. The delivery sequence can be changed to FIFO by changing the delivery type on the queue from which your application is consuming messages. Run "alter ql(<qname>) MSGDLVSQ(FIFO)" command in runmqsc to alter the delivery sequence.
3. There are two types of messages - Persistent and Not-Persistent. Persistent messages survive a queue manager restart while the other type does not. When there are messages in a queue and there is an application to consume them, MQ will deliver the messages, depending the delivery sequence set on the queue. You can group related messages in Message Group and process them in an order they are in the queue. The application that puts the messages to a queue must put them as a group and application must consume them as a group. You can read more here - https://www.ibm.com/docs/en/ibm-mq/9.3?topic=ordering-grouping-logical-messages.
Hope this helped.
------------------------------
Shashikanth Rao Thambrahalli
IBM
Original Message:
Sent: Fri July 29, 2022 05:04 AM
From: Balaji Patil
Subject: MQ related
Hi Shashikanth,
Thank you for your help.
I am able to read the msgs using ReadBytes method.
Furthermore I have following questions. can you please help?
1. A msg should not be deleted automatically once we read it.. based on processing condition we delete the msg maunally.
2. Is it FIFO?
3. Can we have a msg type property for msgs?
We have 3 types of msg and each should be handed differently.
1) Message must be delivered (can't be lost) and must be processed FIFO (out of order messages will cause problems)
2) Message must be delivered (can't be lost) and can be processed in any order
3) Message could be lost (but would prefer not) and can be processed in any order
Is there any documentation available for this?
------------------------------
Balaji Patil
Original Message:
Sent: Wed July 27, 2022 03:05 AM
From: Shashikanth Rao Thambrahalli
Subject: MQ related
Please read the Knowledge Center for more details on the methods provided for each of the message type classes. ReadUTF and ReadString are for ITextMessage type, not for IBytesMessage class.
------------------------------
Shashikanth Rao Thambrahalli
IBM
Original Message:
Sent: Wed July 27, 2022 02:51 AM
From: Balaji Patil
Subject: MQ related
Thank you. Yeah, the type of the msg is "IBytesMessage".
Throwing an error while I use the method ReadUTF() on IBytesMessage
IBytesMessage textMessage = (IBytesMessage)message;
string s = textMessage.ReadUTF();
CWSMQ0136I: An attempt was made to read beyond the end of the message.
An attempt was made to read beyond the end of the message. This may be a normal condition if an application has been coded to read variable length data using the JMS 1.0.2 specification.
If necessary, recode the application to use the new getBodyLength method.
------------------------------
Balaji Patil
Original Message:
Sent: Wed July 27, 2022 01:52 AM
From: Shashikanth Rao Thambrahalli
Subject: MQ related
You must determine the type of the message before attempting to cast it. Do something like
if (message is IBytesMessage) {
// Do something like calling methods of IBytesMessage class to read message body
} else if (message is ITextMessage) {
// Do something else
}
If you know the type of the incoming message in advance, then above test is not required. Typically the Sender and Receiver of messages will have an understanding of the type/format of the message being transmitted.
------------------------------
Shashikanth Rao Thambrahalli
IBM
Original Message:
Sent: Wed July 27, 2022 01:33 AM
From: Balaji Patil
Subject: MQ related
I tried to cast, but throwing an error below:
Unable to cast object of type 'IBM.XMS.Client.Impl.XmsBytesMessageImpl' to type 'IBM.XMS.ITextMessage'.
Let me see if any alternate option.
Thanks,
Balaji
------------------------------
Balaji Patil
Original Message:
Sent: Wed July 27, 2022 01:19 AM
From: Shashikanth Rao Thambrahalli
Subject: MQ related
IMessage is an interface. You will need to cast the message object to ITextMessage, IBytesMessage or other three types of message XMS supports depending on the type of the incoming message. After casting, you will need to use the methods provided to read the message contents. See here more details on ITextMessage. There are details for other message types as well.
For example:
ITextMessage txtMsg = (ITextMessage)message;
string body = txtMsg.Text;
------------------------------
Shashikanth Rao Thambrahalli
IBM
Original Message:
Sent: Wed July 27, 2022 01:01 AM
From: Balaji Patil
Subject: MQ related
Hi Shashikanth,
Thank you for your reply
After running the solution under specific user having access to the MQ, I was able to connect to MQ successfully.
How to read the input msg in .NET?
Callback event is getting called, but I am unable to read the msg content:
Can you please suggest?
// Create message listener and assign it to consumer
messageListener = new MessageListener(OnMessageCallback);
consumerAsync.MessageListener = messageListener;
static void OnMessageCallback(IMessage message)
{
string ls = message.ToString(); (returning everything)
}
Thanks.
------------------------------
Balaji Patil
Original Message:
Sent: Wed July 27, 2022 12:14 AM
From: Shashikanth Rao Thambrahalli
Subject: MQ related
For XMS .NET you should use WMQ_CM_BINDINGS (=0) or WMQ_CM_CLIENT(=1) or WMQ_CM_CLIENT_UNMANAGED (=5). A value of 2 for XMSC.WMQ_CONNECTION_MODE property means WMQ_CM_DIRECT_TCPIP which I think is not supported.
The MQRC 2035 you are getting is because the specified user does not have the authority to connect to queue manager. Ask your MQ administrator provide access to the queue manager your application wants to connect and also to queues/topics.
------------------------------
Shashikanth Rao Thambrahalli
IBM
Original Message:
Sent: Tue July 26, 2022 08:25 AM
From: Balaji Patil
Subject: MQ related
Dear Shashikanth,
Greetings of the day.
I am getting the below errors while connecting to MQ:
1. When I set cf.SetIntProperty(XMSC.WMQ_CONNECTION_MODE, 2); I am getting object reference error while creating session:
// Create connection.
connectionWMQ = cf.CreateConnection();
Console.WriteLine("Connected created");
// Create session
sessionWMQ = connectionWMQ.CreateSession(false, AcknowledgeMode.AutoAcknowledge);
Console.WriteLine("Session created");
2. When I set cf.SetIntProperty(XMSC.WMQ_CONNECTION_MODE, 1), I am getting error -
CWSMQ0006E: An exception was received during the call to the method ConnectionFactory.CreateConnection: CompCode: 2, Reason: 2035.
During execution of the specified method an exception was thrown by another component
at
connectionWMQ = cf.CreateConnection();
I set these properties for MQ connection:
cf.SetStringProperty(XMSC.WMQ_HOST_NAME, hostName);
cf.SetIntProperty(XMSC.WMQ_PORT, port);
cf.SetStringProperty(XMSC.WMQ_CHANNEL, channelName);
cf.SetIntProperty(XMSC.WMQ_CONNECTION_MODE, 1);
cf.SetStringProperty(XMSC.WMQ_QUEUE_MANAGER, queueManagerName);
cf.SetStringProperty(XMSC.WMQ_QUEUE_NAME, "somequeue");
cf.SetStringProperty(XMSC.USERID, "userid");
cf.SetStringProperty(XMSC.PASSWORD, "xxx");
Please suggest what is wrong here?
------------------------------
Balaji Patil
Original Message:
Sent: Mon June 20, 2022 02:03 AM
From: Shashikanth Rao Thambrahalli
Subject: MQ related
Sorry, I thought you were looking for Java language sample. For C#, you will need to use XMS .NET classes that supports message listener. You can either download MQ client that contains C# libraries or pull XMS .NET from NuGet repository. Here is sample for XMS .NET (The same sample is shipped with product as well).
Here is a sample that describes MessageListener in XMS .NET.
------------------------------
Shashikanth Rao Thambrahalli
IBM
Original Message:
Sent: Mon June 20, 2022 01:22 AM
From: Balaji Patil
Subject: MQ related
Dear Shashikanth,
Thank you so much for you reply. Let me try above solution.
This way we don't need to write a continues loop for fetching the msgs, right?
I am only using the client library, the installation and managing of queue is done by different etam.
I don't have samples with me, appreciate if you can provide me the C# samples for this.
Thank you so much.
------------------------------
Balaji Patil
Original Message:
Sent: Sat June 18, 2022 08:28 AM
From: Shashikanth Rao Thambrahalli
Subject: MQ related
IBM MQ client libraries support "Asynchronous Message Consumer" (a.k.a Message Listener) that exactly meets your requirements. Asynchronous message consumer is a feature where MQ client libraries invoke application specified callback method when a message becomes available for delivery. Application does not have to periodically check the queue for messages.
You can use MQ API/Java and .NET classes to write your applications. Many samples are already shipped with product that demonstrate the asynchronous message consumer function. Here is a snippet, written using MQ classes for JMS.
// Setup your connection factory before creating connection
connection = cf.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue("TESTQ");
consumer = session.createConsumer(destination);
//
Create and register a new MessageListener for this consumer
consumer.setMessageListener(new MessageListener() {
public void onMessage(Message msg) {
try {
if (msg instanceof TextMessage) {
JMSTextMessage textMesg = (JMSTextMessage)msg;
System.out.println("Text message: " + textMesg.getText());
} else if (msg instanceof BytesMessage) {
System.out.println("Bytes message");
}
}
catch (Exception e) {
System.out.println("Exception caught in onMessage():\n" + e);
}
} // end onMessage()
}); // end setMessageListener
connection.start();
Hope this helps.
------------------------------
Shashikanth Rao Thambrahalli
IBM
Original Message:
Sent: Fri June 17, 2022 01:31 AM
From: Balaji Patil
Subject: MQ related
Dear Team,
Need your support on following questions:
1. We have 1000 of msgs coming into the MQ and we want to read it one by one without using a loop.
Loop is not allowed due to some limitations.
2. We want our application to be notified when a msgs is arrived in the MQ, currently we are periodically checking the queue.
Kindly suggest on above,
Thanks,
Balaji
------------------------------
Balaji Patil
------------------------------