Message Selectors - WSO2 Message Broker 3.x.x

A message selector allows a JMS consumer to be more selective about the messages that it receives from a particular topic or queue. A message selector uses message properties and headers as criteria in conditional expressions. These expressions use Boolean logic to declare which messages are delivered to a client. It is not possible for a message selector to filter messages on the basis of the content of the message body.

Note: Message Selectors are supported for single node for WSO2 MB from 3.1.0 onwards. Message Selectors DOES NOT work in cluster mode for MB 3.1.0.


They way selectors work depends on the destination type:

  1. Queues - 
    • Only messages that match the selector will be delivered to the subscriber. 
    • If there is at least one subscriber out of a few subscribers for a queue, message will be delivered to that subscriber. 
    • If there is more than one subscriber whose selector matches with messages, messages will be delivered in round robin manner between those subscribers. 
    • If there is no subscriber matching a message, that message will be placed in the Dead Letter Queue.

  2. Topics - 
    • Only messages that match the selector will be delivered to the subscriber. 
    • If no subscriber's selector matches with the message, message is dropped.
    • We do not evaluate selectors when messages are received by the Broker. Messages will be written anyway if there are subscribers for that topic, and upon delivery selectors are evaluated.

  3. Durable Topics - 
      • Only messages that match the selector will be delivered to the durable topic subscriber. 
      • When keeping a copy of a message coming for a topic for the particular subscription ID, selectors are not evaluated. They are evaluated upon delivery only. 
      • If a message does not match with the selector for a particular durable topic subscription, it will be routed to Dead Letter Queue. 
Use cases with messages routed to DLC
  1. If there is no subscriber matching for a message, if the message is for a durable queue or topic, message is routed to DLC. 
  2. User has options to delete the messages selectively if they are unnecessary. 
  3. If user wishes to create a new queue and route all unmatched messages to that queue, it is also possible. 
  4. If user wishes to create a new subscriber with a matching selector for some or all messages routed to DLC, he can do that and route all messages to original queue again. Then, if there are newly created matching subscriptions, those messages will be delivered accordingly. Other messages will land on to DLC queue once again. 

Example on how to use a selector JMS way 


First create a subscriber with a selector

queue subscriber

QueueSession queueSession =
        queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);

//Receive message
Queue queue =  (Queue) ctx.lookup(queueName);

MessageConsumer queueReceiver = queueSession.
        createConsumer(queue, "releaseYear < 1980");

topic subscriber

TopicSession topicSession =
        topicConnection.createTopicSession(false, QueueSession.AUTO_ACKNOWLEDGE);

Topic topic = topicSession.createTopic(topicName);

javax.jms.TopicSubscriber topicSubscriber = topicSession.
        createSubscriber(topic, "releaseYear < 1980", false); 

durable topic subscriber

TopicSession topicSession =
        topicConnection.createTopicSession(false, QueueSession.AUTO_ACKNOWLEDGE);
Topic topic = topicSession.createTopic(topicName);

javax.jms.TopicSubscriber topicSubscriber = topicSession.
        createDurableSubscriber(topic, "mySub4", "releaseYear < 1980", false);


When publishing messages you need to add JMS property 'releaseYear' and set the value as below (Following is the queue example).

javax.jms.QueueSender queueSender = queueSession.createSender(queue);
int currentMsgCount = 0;

while(currentMsgCount < this.messageCount) {
    TextMessage textMessage = queueSession.
          createTextMessage("test: (" + currentMsgCount + ")");  
textMessage.setLongProperty("releaseYear", 1990);  
queueSender.send(textMessage);  
System.out.println("Sent message: " + currentMsgCount);
currentMsgCount ++;

}



ElementDescriptionExample Selector
Header FieldsAny headers except JMSDestinationJMSExpiration andJMSReplyToJMSPriority = 9
PropertiesMessage properties that follow Java identifier namingreleaseYear = 1982
String LiteralsString literals in single quotes, duplicate to escapetitle = 'Sam''s'
Number LiteralsNumbers in Java syntax (int and double)releaseYear = 1982
Boolean LiteralsTRUE and FALSEisAvailable = TRUE
( )Brackets(releaseYear < 1980) OR (releaseYear > 1989)
ANDORNOTLogical operators(releaseYear < 1980) AND NOT (title = 'Thriller')
=, <>, <, <=, >, >=Comparison operators(releaseYear < 1980) AND (title <>'Thriller')
LIKEString comparison with wildcards '_' and '%' (more)title LIKE 'Thrill%'
INFind value in set of strings (more)title IN ('Off the wall', 'Thriller', 'Bad')
BETWEENCheck whether number is in range (both numbers inclusive) (more)releaseYear BETWEEN 1980 AND 1989
IS NULLIS NOT NULLCheck whether value is null or not null.releaseYear IS NOT NULL
*, +, -, /Arithmetic operatorsreleaseYear * 2 > 2000 - 20
Some more examples of message consumers with selectors:
Session session = ...
MessageConsumer consumer1 = session.createConsumer(queue, 
                       "(releaseYear < 1980) OR (releaseYear > 1989)");

MessageConsumer consumer2 = session.createConsumer(queue, 
                       "(releaseYear BETWEEN 1980 AND 1989) AND title LIKE 'Michael%'");

MessageConsumer consumer3 = session.createConsumer(queue, 
                       "(releaseYear = 1982) OR (title = 'Thriller')");

MessageConsumer consumer4 = session.createDurableConsumer(queue, 
                       "title IN ('Off the wall', 'Thriller', 'Bad')");

Hasitha Hiranya

No comments:

Post a Comment

Instagram