MQ

 View Only
Expand all | Collapse all

MQ related

  • 1.  MQ related

    Posted Fri June 17, 2022 10:23 AM

    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
    ------------------------------


  • 2.  RE: MQ related

    Posted Sat June 18, 2022 08:28 AM
    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
    ------------------------------



  • 3.  RE: MQ related

    Posted Mon June 20, 2022 01:23 AM

    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
    ------------------------------



  • 4.  RE: MQ related

    Posted Mon June 20, 2022 02:04 AM
    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
    ------------------------------



  • 5.  RE: MQ related

    Posted Mon June 20, 2022 02:53 AM
    Edited by Balaji Patil Mon June 20, 2022 02:54 AM

    Sorry that I missed to mention the language in my original post.

    Thank you so much for your quick reply.

    Let me refer the code sample and will update here if any roadblocks. 



    ------------------------------
    Balaji Patil
    ------------------------------



  • 6.  RE: MQ related

    Posted Tue July 26, 2022 10:13 AM

    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
    ------------------------------



  • 7.  RE: MQ related

    Posted Wed July 27, 2022 12:14 AM
    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
    ------------------------------



  • 8.  RE: MQ related

    Posted Wed July 27, 2022 01:01 AM

    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
    ------------------------------



  • 9.  RE: MQ related

    Posted Wed July 27, 2022 01:20 AM
    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
    ------------------------------



  • 10.  RE: MQ related

    Posted Wed July 27, 2022 01:33 AM

    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
    ------------------------------



  • 11.  RE: MQ related

    Posted Wed July 27, 2022 01:53 AM
    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
    ------------------------------



  • 12.  RE: MQ related

    Posted Wed July 27, 2022 02:52 AM

    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
    ------------------------------



  • 13.  RE: MQ related

    Posted Wed July 27, 2022 03:06 AM
    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
    ------------------------------



  • 14.  RE: MQ related

    IBM Champion
    Posted Wed July 27, 2022 03:31 AM
    Furthermore ReadUTF should only be used if the producer used WriteUTF.

    ------------------------------
    Francois Brandelik
    ------------------------------



  • 15.  RE: MQ related

    Posted Fri July 29, 2022 05:05 AM
    Edited by Balaji Patil Fri July 29, 2022 05:06 AM

    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
    ------------------------------



  • 16.  RE: MQ related

    Posted Fri July 29, 2022 05:47 AM

    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
    ------------------------------



  • 17.  RE: MQ related

    IBM Champion
    Posted Fri July 29, 2022 11:12 AM

    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
    ------------------------------



  • 18.  RE: MQ related

    Posted Sun July 31, 2022 01:10 PM
    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
    ------------------------------



  • 19.  RE: MQ related

    Posted Mon August 01, 2022 06:05 AM
    Thank you so much for your inputs Shashikanth, Colin, Andrew.

    ------------------------------
    Balaji Patil
    ------------------------------



  • 20.  RE: MQ related

    Posted Wed August 03, 2022 06:22 AM
    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
    ------------------------------



  • 21.  RE: MQ related

    Posted Sun August 07, 2022 08:02 PM
    >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
    ------------------------------



  • 22.  RE: MQ related

    Posted Tue August 09, 2022 01:56 PM

    See "Message groups"

    Bob Gibson
    Advisory Software Engineer - MQ Technical Support
    bgibson@us.ibm.com

    IBM Software

     

     






  • 23.  RE: MQ related

    Posted Tue August 09, 2022 08:42 PM
    Hi Bob,
    I am aware of MQ message groups, and usage of groups to segment very large payloads into multiple MQ messages.
    Disadvantages are that a group must contain a finite number of messages and producer / consumer both need to be under UOW.
    This is of no use if transactions are in a continuous sequential ordered stream.
    If the transactions are in sets or batches, I would combine them into one message (if they fit in 100MB), rather than using message groups.
    Cheers,

    ------------------------------
    Glenn Baddeley
    Senior Middleware Software Engineer
    Coles Supermarkets Australia Pty Ltd
    ------------------------------



  • 24.  RE: MQ related

    Posted Wed August 10, 2022 10:54 AM
    MQ grouped and segmented messages provide you with a plethora of options. There's a relatively "simple" interface where you use MQ to split and reassemble messages into segments which would have minor UOW implications (MQPMO_SEGMENTATION_ALLOWED/MQGMO_COMPLETE_MSG) which the queue manager would manage for you. MQPMO_LOGICAL_ORDER and MQGMO_LOGICAL_ORDER allow a single producer to steam messages to a single consumer in a strict order (even then the error handling implications are significant) with no defined UOW restrictions or requirements.
    Then there's a "roll your own" set of options where the applications explicitly build groups and segments supplying all of the group/segment attributes explicitly and are responsible for getting this 100% correct (I'd strongly suggest NOT attempting this).
    Even if you only had one producer and one consumer, and you got the (non trivial) error handling correct you'd still have to be concerned at the 999,999,999 limit on the message sequence number. In short a message group isn't really suitable for any sort of global serialization between multiple producers and multiple consumers.
    I've heard many statements about the need to globally serialize messages, but in practice it's usually that subsets of messages between single producers and single consumers need to be processed in strict sequence. Multiple message groups could be used if the boundaries where serialization is required can be identified, with a new message group used for each such subset.
    Don't forget that if one of the messages in the group is put to a DLQ (for example due to queue full) then it would need to be restored and forwarded before subsequent messages in the group could be seen.

    As with most serialization issues, the key here is to accurately identify the MINIMUM serialization required for correct behaviour.

    ------------------------------
    Andrew Hickson
    ------------------------------



  • 25.  RE: MQ related

    Posted Thu August 11, 2022 03:23 AM
    Hi Andrew.
    MQ message groups has many options and certainly fits many messaging design scenarios. However, as you point out, there are error handling and DLQ implications.

    We have hundreds of MQ interfaces across our enterprise systems with a wide mix of transaction types and payload sizes. MQ message groups and serialization / sequencing / segmentation are not used. I feel that serialization is an application problem, not a transport problem.  As an example, Purchase Order transaction messages are put to MQ in sequence. The consumer app does a reconciliation of order numbers (independent of consumed sequence), and goes back to the producer if any are missing.

    ------------------------------
    Glenn Baddeley
    Senior Middleware Software Engineer
    Coles Supermarkets Australia Pty Ltd
    ------------------------------



  • 26.  RE: MQ related

    Posted Wed August 10, 2022 03:01 AM

    Apart from message.Acknowledge(), is there any other way to delete msg from MQ.

    In the the callback method we are only reading the message and processing it.

    After successful processing of the msg, a response will be sent to a different method...

    We have to send the response to OutBound MQ and delete the messge from Inbound MQ.

    Please see if you can help.



    ------------------------------
    Balaji Patil
    ------------------------------



  • 27.  RE: MQ related

    IBM Champion
    Posted Thu August 11, 2022 03:08 AM
    Edited by Francois Brandelik Thu August 11, 2022 03:10 AM
    Have you thought about using a transacted session with  Session.AUTO_AKNOWLEDGE ?
    You will then have to issue a session.rollback or session.commit to rollback or consume the message(s) in the Unit Of Work (UOW).

    ------------------------------
    Francois Brandelik
    ------------------------------