blob: db666c4fbc9782ff5fc6df4cf4200e5413924cd3 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 2.0.18">
<link rel="icon" type="image/png" href="images/favicon.png">
<title>Filter Expressions</title>
<link rel="stylesheet" href="css/asciidoctor.css">
<link rel="stylesheet" href="css/font-awesome.css">
</head>
<body class="book toc2 toc-left">
<div id="header">
<h1>Filter Expressions</h1>
<div id="toc" class="toc2">
<div id="toctitle"><a href="index.html">User Manual for 2.32.0</a></div>
<ul class="sectlevel1">
<li><a href="#xpath">1. XPath</a></li>
</ul>
</div>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Apache ActiveMQ Artemis provides a powerful filter language based on a subset of the SQL 92 expression syntax.</p>
</div>
<div class="paragraph">
<p>It is the same as the syntax used for JMS &amp; Jakarta Messaging selectors, but the predefined identifiers are different.
For documentation on JMS selector syntax please the JavaDoc for <a href="https://docs.oracle.com/javaee/7/api/javax/jms/Message.html"><code>javax.jms.Message</code></a>.
For the corresponding Jakarta Messaging JavaDoc see <a href="https://jakarta.ee/specifications/messaging/3.0/apidocs/jakarta/jms/message"><code>jakarta.jms.Message</code></a></p>
</div>
<div class="paragraph">
<p>Filter expressions are used in several places in Apache ActiveMQ Artemis</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Predefined Queues.
When pre-defining a queue, in <code>broker.xml</code> in either the core or jms configuration a filter expression can be defined for a queue.
Only messages that match the filter expression will enter the queue.</p>
</li>
<li>
<p>Core bridges can be defined with an optional filter expression, only matching messages will be bridged (see <a href="core-bridges.html#core-bridges">Core Bridges</a>).</p>
</li>
<li>
<p>Diverts can be defined with an optional filter expression, only matching messages will be diverted (see <a href="diverts.html#diverting-and-splitting-message-flows">Diverts</a>).</p>
</li>
<li>
<p>Filter are also used programmatically when creating consumers, queues and in several places as described in <a href="management.html#management">management</a>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>There are some differences between JMS selector expressions and Apache ActiveMQ Artemis core filter expressions.
Whereas JMS selector expressions operate on a JMS message, Apache ActiveMQ Artemis core filter expressions operate on a core message.</p>
</div>
<div class="paragraph">
<p>The following identifiers can be used in a core filter expressions to refer to attributes of the core message in an expression:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">AMQUserID</dt>
<dd>
<p>The ID set by the user when the message is sent.
This is analogous to the <code>JMSMessageID</code> for JMS-based clients.</p>
</dd>
<dt class="hdlist1">AMQAddress</dt>
<dd>
<p>The address to which the message was sent.</p>
</dd>
<dt class="hdlist1">AMQGroupID</dt>
<dd>
<p>The group ID used when sending the message.</p>
</dd>
<dt class="hdlist1">AMQPriority</dt>
<dd>
<p>To refer to the priority of a message.
Message priorities are integers with valid values from <code>0 - 9</code>.
<code>0</code> is the lowest priority and <code>9</code> is the highest.
e.g. <code>AMQPriority = 3 AND animal = 'aardvark'</code></p>
</dd>
<dt class="hdlist1">AMQExpiration</dt>
<dd>
<p>To refer to the expiration time of a message.
The value is a long integer.</p>
</dd>
<dt class="hdlist1">AMQDurable</dt>
<dd>
<p>To refer to whether a message is durable or not.
The value is a string with valid values: <code>DURABLE</code> or <code>NON_DURABLE</code>.</p>
</dd>
<dt class="hdlist1">AMQTimestamp</dt>
<dd>
<p>The timestamp of when the message was created.
The value is a long integer.</p>
</dd>
<dt class="hdlist1">AMQSize</dt>
<dd>
<p>The size of a message in bytes.
The value is an integer.</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>Any other identifiers used in core filter expressions will be assumed to be properties of the message.</p>
</div>
<div class="paragraph">
<p>The JMS and Jakarta Messaging specs state that a String property should not get converted to a numeric when used in a selector.
So for example, if a message has the <code>age</code> property set to <code>String</code> <code>21</code> then the following selector should not match it: <code>age &gt; 18</code>.
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 <code>String</code> properties to the appropriate number type, just prefix it with <code>convert_string_expressions:</code>.
If you changed the filter expression in the previous example to be <code>convert_string_expressions:age &gt; 18</code>, then it would match the aforementioned message.</p>
</div>
<div class="paragraph">
<p>The JMS and Jakarta Messaging specs also state that property identifiers (and therefore the identifiers which are valid for use in a filter expression) are an:</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="paragraph">
<p>unlimited-length sequence of letters and digits, the first of which must be a letter.
A letter is any character for which the method <code>Character.isJavaLetter</code> returns <code>true</code>.
This includes <code>_</code> and <code>$</code>.
A letter or digit is any character for which the method <code>Character.isJavaLetterOrDigit</code> returns <code>true</code>.</p>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>This constraint means that hyphens (i.e. <code>-</code>) cannot be used.
However, this constraint can be overcome by using the <code>hyphenated_props:</code> prefix.
For example, if a message had the <code>foo-bar</code> property set to <code>0</code> then the filter expression <code>hyphenated_props:foo-bar = 0</code> would match it.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="xpath"><a class="anchor" href="#xpath"></a><a class="link" href="#xpath">1. XPath</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>Apache ActiveMQ Artemis also supports special <a href="https://en.wikipedia.org/wiki/XPath">XPath</a> filters which operate on the <em>body</em> of a message.
The body must be XML.
To use an XPath filter use this syntax:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="nowrap">XPATH '&lt;xpath-expression&gt;'</pre>
</div>
</div>
<div class="paragraph">
<p>XPath filters are supported with and between producers and consumers using the following protocols:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>OpenWire JMS</p>
</li>
<li>
<p>Core (and Core JMS)</p>
</li>
<li>
<p>STOMP</p>
</li>
<li>
<p>AMQP</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Since XPath applies to the body of the message and requires parsing of XML <strong>it may be significantly slower</strong> than normal filters.</p>
</div>
<div class="paragraph">
<p>Large messages are <strong>not</strong> supported.</p>
</div>
<div class="paragraph">
<p>The XML parser used for XPath is configured with these default "features":</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>http://xml.org/sax/features/external-general-entities</code>: <code>false</code></p>
</li>
<li>
<p><code>http://xml.org/sax/features/external-parameter-entities</code>: <code>false</code></p>
</li>
<li>
<p><code>http://apache.org/xml/features/disallow-doctype-decl</code>: <code>true</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>However, in order to deal with any implementation-specific issues the features can be customized by using system properties starting with the <code>org.apache.activemq.documentBuilderFactory.feature:</code> prefix, e.g.:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="nowrap">-Dorg.apache.activemq.documentBuilderFactory.feature:http://xml.org/sax/features/external-general-entities=true</pre>
</div>
</div>
</div>
</div>
</div>
</body>
</html>