ARTEMIS-573 clarify filter documentation
This commit is contained in:
parent
d7edf06689
commit
8a66d5f485
|
@ -49,3 +49,25 @@ refer to attributes of the core message in an expression:
|
|||
|
||||
Any other identifiers used in core filter expressions will be assumed to
|
||||
be properties of the message.
|
||||
|
||||
The JMS spec states that a String property should not get converted to a
|
||||
numeric when used in a selector. So for example, if a message has the `age`
|
||||
property set to String `21` then the following selector should not match
|
||||
it: `age > 18`. Since Apache ActiveMQ Artemis supports STOMP clients which
|
||||
can only send messages with string properties, that restriction is a bit
|
||||
limiting. Therefore, if you want your filter expressions to auto-convert String
|
||||
properties the the appropriate number type, just prefix it with
|
||||
`convert_string_expressions:`. If you changed the filter expression in the
|
||||
previous example to be `convert_string_expressions:age > 18`, then it would
|
||||
match the aforementioned message.
|
||||
|
||||
The JMS spec also states that property identifiers (and therefore the
|
||||
identifiers which are valid for use in a filter expression) are an,
|
||||
"unlimited-length sequence of letters and digits, the first of which must be
|
||||
a letter. A letter is any character for which the method
|
||||
`Character.isJavaLetter` returns `true`. This includes `_` and `$`. A letter
|
||||
or digit is any character for which the method `Character.isJavaLetterOrDigit`
|
||||
returns `true`." This constraint means that hyphens (i.e. `-`) cannot be used.
|
||||
However, this constraint can be overcome by using the `hyphenated_props:`
|
||||
prefix. For example, if a message had the `foo-bar` property set to `0` then
|
||||
the filter expression `hyphenated_props:foo-bar = 0` would match it.
|
|
@ -311,6 +311,13 @@ seconds.
|
|||
> users can use heart-beats to maintain the life cycle of stomp
|
||||
> connections.
|
||||
|
||||
### Selector/Filter expressions
|
||||
|
||||
Stomp subscribers can specify an expression used to select or filter
|
||||
what the subscriber receives using the `selector` header. The filter
|
||||
expression syntax follows the *core filter syntax* described in the
|
||||
[Filter Expressions](filter-expressions.md) documentation.
|
||||
|
||||
### Stomp and JMS interoperability
|
||||
|
||||
#### Using JMS destinations
|
||||
|
|
|
@ -31,6 +31,12 @@ import java.util.regex.Matcher;
|
|||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.activemq.artemis.api.core.SimpleString;
|
||||
import org.apache.activemq.artemis.api.core.client.ActiveMQClient;
|
||||
import org.apache.activemq.artemis.api.core.client.ClientMessage;
|
||||
import org.apache.activemq.artemis.api.core.client.ClientProducer;
|
||||
import org.apache.activemq.artemis.api.core.client.ClientSession;
|
||||
import org.apache.activemq.artemis.api.core.client.ClientSessionFactory;
|
||||
import org.apache.activemq.artemis.api.core.client.ServerLocator;
|
||||
import org.apache.activemq.artemis.api.core.management.ResourceNames;
|
||||
import org.apache.activemq.artemis.api.jms.ActiveMQJMSClient;
|
||||
import org.apache.activemq.artemis.core.protocol.stomp.Stomp;
|
||||
|
@ -435,6 +441,35 @@ public class StompTest extends StompTestBase {
|
|||
Assert.assertEquals("bar", "123", message.getStringProperty("bar"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendMessageWithCustomHeadersAndHyphenatedSelector() throws Exception {
|
||||
|
||||
MessageConsumer consumer = session.createConsumer(queue, "hyphenated_props:b-ar = '123'");
|
||||
|
||||
String frame = "CONNECT\n" + "login: brianm\n" + "passcode: wombats\n\n" + Stomp.NULL;
|
||||
sendFrame(frame);
|
||||
|
||||
frame = receiveFrame(10000);
|
||||
Assert.assertTrue(frame.startsWith("CONNECTED"));
|
||||
|
||||
frame = "SEND\n" + "foo:abc\n" +
|
||||
"b-ar:123\n" +
|
||||
"destination:" +
|
||||
getQueuePrefix() +
|
||||
getQueueName() +
|
||||
"\n\n" +
|
||||
"Hello World" +
|
||||
Stomp.NULL;
|
||||
|
||||
sendFrame(frame);
|
||||
|
||||
TextMessage message = (TextMessage) consumer.receive(1000);
|
||||
Assert.assertNotNull(message);
|
||||
Assert.assertEquals("Hello World", message.getText());
|
||||
Assert.assertEquals("foo", "abc", message.getStringProperty("foo"));
|
||||
Assert.assertEquals("b-ar", "123", message.getStringProperty("b-ar"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendMessageWithStandardHeaders() throws Exception {
|
||||
|
||||
|
@ -755,6 +790,49 @@ public class StompTest extends StompTestBase {
|
|||
sendFrame(frame);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSubscribeWithAutoAckAndHyphenatedSelector() throws Exception {
|
||||
|
||||
String frame = "CONNECT\n" + "login: brianm\n" + "passcode: wombats\n\n" + Stomp.NULL;
|
||||
sendFrame(frame);
|
||||
|
||||
frame = receiveFrame(100000);
|
||||
Assert.assertTrue(frame.startsWith("CONNECTED"));
|
||||
|
||||
frame = "SUBSCRIBE\n" + "destination:" +
|
||||
getQueuePrefix() +
|
||||
getQueueName() +
|
||||
"\n" +
|
||||
"selector: hyphenated_props:foo-bar = 'zzz'\n" +
|
||||
"ack:auto\n\n" +
|
||||
Stomp.NULL;
|
||||
sendFrame(frame);
|
||||
|
||||
ServerLocator serverLocator = addServerLocator(ActiveMQClient.createServerLocator("vm://0"));
|
||||
ClientSessionFactory clientSessionFactory = serverLocator.createSessionFactory();
|
||||
ClientSession clientSession = clientSessionFactory.createSession(true, true);
|
||||
ClientProducer producer = clientSession.createProducer(getQueuePrefix() + getQueueName());
|
||||
|
||||
ClientMessage ignoredMessage = clientSession.createMessage(false);
|
||||
ignoredMessage.putStringProperty("foo-bar", "1234");
|
||||
ignoredMessage.getBodyBuffer().writeNullableSimpleString(SimpleString.toSimpleString("Ignored message"));
|
||||
|
||||
ClientMessage realMessage = clientSession.createMessage(false);
|
||||
realMessage.putStringProperty("foo-bar", "zzz");
|
||||
realMessage.getBodyBuffer().writeNullableSimpleString(SimpleString.toSimpleString("Real message"));
|
||||
|
||||
producer.send(ignoredMessage);
|
||||
producer.send(realMessage);
|
||||
|
||||
frame = receiveFrame(10000);
|
||||
Assert.assertTrue(frame.startsWith("MESSAGE"));
|
||||
Assert.assertTrue("Should have received the real message but got: " + frame, frame.indexOf("Real message") > 0);
|
||||
|
||||
frame = "DISCONNECT\n" + "\n\n" + Stomp.NULL;
|
||||
sendFrame(frame);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSubscribeWithClientAck() throws Exception {
|
||||
|
||||
|
|
Loading…
Reference in New Issue