[
https://issues.apache.org/jira/browse/AMQ-5281?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Grigroy Sobko updated AMQ-5281:
-------------------------------
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:
{code}
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;
}
}
{code}
was:
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:
{code}
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;
}
}
{code}
> Incorrect handling of unknown values in selectors
> -------------------------------------------------
>
> Key: AMQ-5281
> URL: https://issues.apache.org/jira/browse/AMQ-5281
> Project: ActiveMQ
> Issue Type: Bug
> Affects Versions: 5.8.0
> Reporter: Grigroy Sobko
>
> 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:
> {code}
> 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;
> }
> }
> {code}
--
This message was sent by Atlassian JIRA
(v6.2#6252)