Uploaded image for project: 'ActiveMQ Classic'
  1. ActiveMQ Classic
  2. AMQ-5280

Incorrect handling of unknown values in selectors

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Duplicate
    • 5.8.0
    • None
    • None
    • None

    Description

      Due to JmsMessage specification :
      http://docs.oracle.com/javaee/1.4/api/javax/jms/Message.html
      There are rules how unknown Values evaluates.
      There how AND operator should handle unknown:
      UNKNOWN AND FALSE => FALSE
      FALSE AND UNKNOWN => FALSE
      And that's how it is handled in ActiveMQ:
      UNKNOWN AND FALSE => UNKNOWN (!!!)
      FALSE AND UNKNOWN => FALSE

      I've wrote test to reproduce this:

      package org.activemq.test;
      
      import org.apache.activemq.command.ActiveMQMessage;
      import org.apache.activemq.command.ActiveMQTopic;
      import org.apache.activemq.filter.BooleanExpression;
      import org.apache.activemq.filter.MessageEvaluationContext;
      import org.apache.activemq.selector.SelectorParser;
      import org.junit.Before;
      import org.junit.Test;
      
      import javax.jms.JMSException;
      import javax.jms.Message;
      
      import static org.junit.Assert.assertEquals;
      import static org.junit.Assert.assertTrue;
      
      public class SelectorUnknownHandlingTest {
      
          private Message message;
      
          @Before
          public void setUp() throws Exception {
              message = createMessage();
          }
      
          @Test
          public void testUnknown() throws Exception {
              // Some unset property with gt operator => unknown
              assertSelectorEvaluatesToUnknown(message, "(unknownProp > 0)");
      
          }
      
          @Test
          public void testUnknownAndFalse() throws Exception {
              // false and unknown => false
              assertSelectorEvaluatesToFalse(message, "(falseProp AND unknownProp > 0)");
      
              // THIS ASSERTION FAILS !! IT EVALUATES TO UNKNOWN INSTEAD
              // unknown and false => false
              assertSelectorEvaluatesToFalse(message, "(unknownProp > 0 AND falseProp)");
      
          }
      
          @Test
          public void testUnknownOrTrue() throws Exception {
      
              // unknown or true => true
              assertSelectorEvaluatesToTrue(message, "(unknownProp > 0 OR trueProp)");
      
              // true or unknown => true
              assertSelectorEvaluatesToTrue(message, "(trueProp OR unknownProp > 0)");
      
          }
      
          private void assertSelectorEvaluatesToUnknown(Message message, String selector) throws JMSException {
              assertSelector(message, selector, false);
              assertSelector(message, "not(" + selector + ")", false);
          }
      
          private void assertSelectorEvaluatesToFalse(Message message, String selector) throws JMSException {
              assertSelector(message, selector, false);
              assertSelector(message, "not(" + selector + ")", true);
          }
      
          private void assertSelectorEvaluatesToTrue(Message message, String selector) throws JMSException {
              assertSelector(message, selector, true);
              assertSelector(message, "not(" + selector + ")", false);
          }
      
      
          protected Message createMessage() throws JMSException {
              Message message = createMessage("FOO.BAR");
              message.setJMSType("selector-test");
              message.setJMSMessageID("connection:1:1:1:1");
              message.setBooleanProperty("trueProp", true);
              message.setBooleanProperty("falseProp", false);
              return message;
          }
      
          protected void assertSelector(Message message, String text, boolean expected) throws JMSException {
              BooleanExpression selector = SelectorParser.parse(text);
              assertTrue("Created a valid selector", selector != null);
              MessageEvaluationContext context = new MessageEvaluationContext();
              context.setMessageReference((org.apache.activemq.command.Message)message);
              boolean value = selector.matches(context);
              assertEquals("Selector for: " + text, expected, value);
          }
      
          protected Message createMessage(String subject) throws JMSException {
              ActiveMQMessage message = new ActiveMQMessage();
              message.setJMSDestination(new ActiveMQTopic(subject));
              return message;
          }
      }
      

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              traylz Grigroy Sobko
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: