ASG
IBM
Zystems
Cressida
Icon
Netflexity
 
  MQSeries.net
Search  Search       Tech Exchange      Education      Certifications      Library      Info Center      SupportPacs      LinkedIn  Search  Search                                                                   FAQ  FAQ   Usergroups  Usergroups
 
Register  ::  Log in Log in to check your private messages
 
RSS Feed - WebSphere MQ Support RSS Feed - Message Broker Support

MQSeries.net Forum Index » IBM MQ Java / JMS » Dynamic message selection within EJB container

Post new topic  Reply to topic
 Dynamic message selection within EJB container « View previous topic :: View next topic » 
Author Message
johnson
PostPosted: Wed Nov 23, 2011 8:07 am    Post subject: Dynamic message selection within EJB container Reply with quote

Newbie

Joined: 23 Nov 2011
Posts: 6

Hi there,

I need to retrieve two types of messages of the same queue, grouped
and non-grouped messages, using an MDB message selector.


I can successfully retrieve the grouped messages using the following
MDB message selector:
<message-selector>JMS_IBM_Last_Msg_In_Group=TRUE</message-selector>
but for non-grouped messages I can’t seem to get this to work.
I have tried the following
<message-selector>JMSXGroupID IS NULL</message-selector>.
However, the strange thing is if I try the above in my client test
app as shown below:
Code:
MessageConsumer consumer = session.createConsumer(queue, "JMSXGroupID
IS NULL");

This seems to work just fine. Any ideas on how I can resolve this
using the MDB message selector ?


Thanks in advance.
Back to top
View user's profile Send private message
mqjeff
PostPosted: Wed Nov 23, 2011 9:12 am    Post subject: Reply with quote

Grand Master

Joined: 25 Jun 2008
Posts: 17447

Your understanding of the problem is wrong.

Your MDB should be configured to read all the messages on the queue.

If it gets a a message that does not belong to a group, you merely need to process it.


If it is a message that belongs to a group, then in your MDB, you should create a consumer and read the rest of the messages in the group, and use a JMS Selector to ensure that you only get messages that belong to the current group.

You check to see if the message you have just received is the last message in the group to see if you should stop consuming messages and exit the MDB and process the next message.
Back to top
View user's profile Send private message
fjb_saper
PostPosted: Wed Nov 23, 2011 11:05 am    Post subject: Reply with quote

Grand High Poobah

Joined: 18 Nov 2003
Posts: 20756
Location: LI,NY


_________________
MQ & Broker admin
Back to top
View user's profile Send private message Send e-mail
johnson
PostPosted: Wed Nov 23, 2011 3:12 pm    Post subject: Reply with quote

Newbie

Joined: 23 Nov 2011
Posts: 6

Thanks for your response mqjeff. I initially considered your idea but then realised this will not work in a (MDB) clustered environment. Do you agree ?
The message-selector seems to simplify the solution, especially that the filter:JMS_IBM_Last_Msg_In_Group ensures that the MDB doesn’t get any of the grouped messages
until the last message of the group is on the queue.

Is it not possible to determine if a message belongs to a group or not using the JAVA API?
Back to top
View user's profile Send private message
fjb_saper
PostPosted: Wed Nov 23, 2011 6:31 pm    Post subject: Reply with quote

Grand High Poobah

Joined: 18 Nov 2003
Posts: 20756
Location: LI,NY

You're still not thinking right.
Reread mqjeff's post VERY CAREFULLY.
Make sure you UNDERSTAND it.

Think over the way you need to code your MDB.
Try it and let us know.

Have fun
_________________
MQ & Broker admin
Back to top
View user's profile Send private message Send e-mail
johnson
PostPosted: Thu Nov 24, 2011 9:25 am    Post subject: Reply with quote

Newbie

Joined: 23 Nov 2011
Posts: 6

Guys tnx for the response so far…. pls see the following snippet – are we on the same page yet?
Go easy ….. 


Code:
public void onMessage(Message msg) {
      // TODO Auto-generated method stub
      boolean noMoreMsgs=false;
      try {
      if(msg instanceof BytesMessage)
      {
      
            String groupId = msg.getStringProperty("JMSXGroupID");
            Map<Integer, byte[]>  map = new HashMap<Integer, byte[]>();
            if(groupId!=null) // this is a grouped msg, get the rest of the grouped msg
            {
                InitialContext ctx = new InitialContext();
                QueueConnectionFactory conFactory = (QueueConnectionFactory) ctx.lookup("queueMgr");
                Destination consumerQueue = (Destination) ctx.lookup("queue");
                Connection connection = conFactory.createQueueConnection();
                Session session = connection.createSession(false,  Session.AUTO_ACKNOWLEDGE);
                connection.start();
                while(noMoreMsgs)
                {
                   MessageConsumer consumer = session.createConsumer(consumerQueue,
                            "JMSXGroupID='" + groupId + "'");
                   BytesMessage message = (BytesMessage) consumer.receiveNoWait();
                   if(message !=null)
                   {
                      int seq = message.getIntProperty("JMSXGroupSeq");
                      byte parts[] = new byte[(int) ((BytesMessage) message)
                                           .getBodyLength()];
                           ((BytesMessage) message).readBytes(parts);
                            map.put(seq, parts);
                            consumer.close();
                           
                   }
                   else
                   {
                      noMoreMsgs = true;
                   }
                  
                }
                connection.close();
            }
            else
            {
                 //processNoneGroupedMsg();
            }
         
      }

Assuming we are:
If the MDB is clustered to receive all messages: then consider the following scenario.
3 Grouped (Seq 1, 2 & 3) msgs on the Queue, Msg Seq 1 is picked up by MDB instance 1. While MDB instance 1is trying to consume the rest of the msgs that belong to the Group, MDB instance 2 consumes (OnMessage) Msg Seq 2This means MDB instance 1 will never get the rest of the msgs that belong to the group. And this is what I see as problematic, or am I still missing
something here ….?
Back to top
View user's profile Send private message
fjb_saper
PostPosted: Thu Nov 24, 2011 12:24 pm    Post subject: Reply with quote

Grand High Poobah

Joined: 18 Nov 2003
Posts: 20756
Location: LI,NY

1st thing you are missing is that it applies to any message, not just to Bytes message.

The MDB would have a selector that makes it only pick up the last message from any group.

If the last message is the first message, process it.

If the last message is not the first message, create a receiver for the other group members with a group selector and process the group as a whole.

Have fun
_________________
MQ & Broker admin
Back to top
View user's profile Send private message Send e-mail
johnson
PostPosted: Thu Nov 24, 2011 3:55 pm    Post subject: Reply with quote

Newbie

Joined: 23 Nov 2011
Posts: 6

Quote:
1st thing you are missing is that it applies to any message, not just to Bytes message.

Yes, this is taken care off.... actually textMessages are not allowed as the data expected are actually images (whether grouped or not).

Ok now regarding the follwing important comments:
Quote:
The MDB would have a selector that makes it only pick up the last message from any group.

The following selector is been used:
Code:
<message-selector>JMS_IBM_Last_Msg_In_Group=TRUE</message-selector>

This works great but ofcourse with a change to code logic, but the problem here is that the above selector only works for messages that are grouped (grouped Messages). None grouped messages are left on the queue. This is my current problem.

Quote:
If the last message is the first message, process it.
If the last message is not the first message, create a receiver for the other group members with a group selector and process the group as a whole.

This is not currently possible as the selector above ignores non-grouped messages on the queue.
So this brings me back to the question of how can I filter using the message selector for non-grouped messages ? (if this is possible I can create an addtional MDB with a msg-selector to get non-grouped messages.



btwn:Thanks for all the help on this so far, hoping there's some kind of solution to this.
Back to top
View user's profile Send private message
fjb_saper
PostPosted: Thu Nov 24, 2011 5:43 pm    Post subject: Reply with quote

Grand High Poobah

Joined: 18 Nov 2003
Posts: 20756
Location: LI,NY

I expect non grouped messages would have the group field filled with hex 0 and you could certainly check on that... , but I thought they'd also have the last in group indicator set to true...
_________________
MQ & Broker admin
Back to top
View user's profile Send private message Send e-mail
johnson
PostPosted: Fri Nov 25, 2011 4:58 am    Post subject: Reply with quote

Newbie

Joined: 23 Nov 2011
Posts: 6

Quote:
I expect non grouped messages would have the group field filled with hex 0 and you could certainly check on that... , but I thought they'd also have the last in group indicator set to true...


is the group field the equivalent of JMSXGroupID, if it is - based on my findings: is that the JMSXGroupID property is not present in the message if it's a non group message
Code:
 (i.e. if i do msg.getStringProperty("JMSXGroupID  ").
And this could possibly explain why this is not working in the MDB message selector.
However, if I programmatically use the following message selector filter:
Code:
MessageConsumer consumer = session.createConsumer(
               queue, "JMS_IBM_Last_Msg_In_Group=false and JMSXGroupID  is NULL"); 

outside of the Application server, it fetches the non group messages correctly.

Re the last group indicator, this is not the case for non grouped messages.[/quote]
Back to top
View user's profile Send private message
mqjeff
PostPosted: Fri Nov 25, 2011 7:20 am    Post subject: Reply with quote

Grand Master

Joined: 25 Jun 2008
Posts: 17447

You either need to single-thread this, as you have mentioned, or you need to gracefully exit if your MDB is given a message that is A member of a Group and is not the FIRST message in the group.

I.e. either single thread it to ensure that you are never given message 2 of 3, or code it to gracefully handle the fact that you were given message 2 of 3 instead of message 1.
Back to top
View user's profile Send private message
johnson
PostPosted: Fri Nov 25, 2011 1:15 pm    Post subject: Reply with quote

Newbie

Joined: 23 Nov 2011
Posts: 6

Many tnx for the follow-ups. I'm going to ask for an additional queue to used solely for the grouped messages. I think this is the easiest and safest solution......
Cheers….
Back to top
View user's profile Send private message
fjb_saper
PostPosted: Fri Nov 25, 2011 6:41 pm    Post subject: Reply with quote

Grand High Poobah

Joined: 18 Nov 2003
Posts: 20756
Location: LI,NY

To avoid any changes in the upstream applications, have 2 queues defined downstream, one for the grouped messages and one for the single messages, then have one MDB on the initial queue that does nothing but triage and move to the downstream queues.

Have fun
_________________
MQ & Broker admin
Back to top
View user's profile Send private message Send e-mail
Display posts from previous:   
Post new topic  Reply to topic Page 1 of 1

MQSeries.net Forum Index » IBM MQ Java / JMS » Dynamic message selection within EJB container
Jump to:  



You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Protected by Anti-Spam ACP
 
 


Theme by Dustin Baccetti
Powered by phpBB © 2001, 2002 phpBB Group

Copyright © MQSeries.net. All rights reserved.