activemq-artemis/docs/user-manual/filter-expressions.adoc

110 lines
5.2 KiB
Plaintext
Raw Normal View History

ARTEMIS-4383 migrate user docs to AsciiDoc Markdown, which is currently used for user-facing documentation, is good for a lot of things. However, it's not great for the kind of complex documentation we have and our need to produce both multi-page HTML and single-page PDF output via Maven. Markdown lacks features which would make the documentation easier to read, easier to navigate, and just look better overall. The current tool-chain uses honkit and a tool called Calibre. Honkit is written in TypeScript and is installed via NPM. Calibre is a native tool so it must be installed via an OS-specific package manager. All this complexity makes building, releasing, uploading, etc. a pain. AsciiDoc is relatively simple like Markdown, but it has more features for presentation and navigation not to mention Java-based Maven tooling to generate both HTML and PDF. Migrating will improve both the appearance of the documentation as well as the processes to generate and upload it. This commit contains the following changes: - Convert all the Markdown for the User Manual, Migration Guide, and Hacking guide to AsciiDoc via kramdown [1]. - Update the `artemis-website` build to use AsciiDoctor Maven tooling. - Update `RELEASING.md` with simplified instructions. - Update Hacking Guide with simplified instructions. - Use AsciiDoc link syntax in Artemis Maven doc plugin. - Drop EPUB & MOBI docs for User Manual as well as PDF for the Hacking Guide. All docs will be HTML only except for the User Manual which will have PDF. - Move all docs up out of their respective "en" directory. This was a hold-over from when we had docs in different languages. - Migration & Hacking Guides are now single-page HTML since they are relatively short. - Refactor README.md to simplify and remove redundant content. Benefits of the change: - Much simplified tooling. No more NPM packages or native tools. - Auto-generated table of contents for every chapter. - Auto-generated anchor links for every sub-section. - Overall more appealing presentation. - All docs will use the ActiveMQ favicon. - No more manual line-wrapping! AsciiDoc recommends one sentence per line and paragraphs are separated by a blank line. - AsciiDoctor plugins for IDEA are quite good. - Resulting HTML is less than *half* of the previous size. All previous links/bookmarks should continue to work. [1] https://github.com/asciidoctor/kramdown-asciidoc
2023-07-27 23:45:17 -04:00
= Filter Expressions
:idprefix:
:idseparator: -
Apache ActiveMQ Artemis provides a powerful filter language based on a subset of the SQL 92 expression syntax.
It is the same as the syntax used for JMS & Jakarta Messaging selectors, but the predefined identifiers are different.
For documentation on JMS selector syntax please the JavaDoc for https://docs.oracle.com/javaee/7/api/javax/jms/Message.html[`javax.jms.Message`].
For the corresponding Jakarta Messaging JavaDoc see https://jakarta.ee/specifications/messaging/3.0/apidocs/jakarta/jms/message[`jakarta.jms.Message`]
Filter expressions are used in several places in Apache ActiveMQ Artemis
* Predefined Queues.
When pre-defining a queue, in `broker.xml` 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.
* Core bridges can be defined with an optional filter expression, only matching messages will be bridged (see xref:core-bridges.adoc#core-bridges[Core Bridges]).
* Diverts can be defined with an optional filter expression, only matching messages will be diverted (see xref:diverts.adoc#diverting-and-splitting-message-flows[Diverts]).
* Filter are also used programmatically when creating consumers, queues and in several places as described in xref:management.adoc#management[management].
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.
The following identifiers can be used in a core filter expressions to refer to attributes of the core message in an expression:
AMQUserID::
The ID set by the user when the message is sent.
This is analogous to the `JMSMessageID` for JMS-based clients.
AMQAddress::
The address to which the message was sent.
AMQGroupID::
The group ID used when sending the message.
AMQPriority::
To refer to the priority of a message.
Message priorities are integers with valid values from `0 - 9`.
`0` is the lowest priority and `9` is the highest.
e.g. `AMQPriority = 3 AND animal = 'aardvark'`
AMQExpiration::
To refer to the expiration time of a message.
The value is a long integer.
AMQDurable::
To refer to whether a message is durable or not.
The value is a string with valid values: `DURABLE` or `NON_DURABLE`.
AMQTimestamp::
The timestamp of when the message was created.
The value is a long integer.
AMQSize::
The size of a message in bytes.
The value is an integer.
Any other identifiers used in core filter expressions will be assumed to be properties of the message.
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 `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 to 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 and Jakarta Messaging specs also state 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.
== XPath
Apache ActiveMQ Artemis also supports special https://en.wikipedia.org/wiki/XPath[XPath] filters which operate on the _body_ of a message.
The body must be XML.
To use an XPath filter use this syntax:
----
XPATH '<xpath-expression>'
----
XPath filters are supported with and between producers and consumers using the following protocols:
* OpenWire JMS
* Core (and Core JMS)
* STOMP
* AMQP
Since XPath applies to the body of the message and requires parsing of XML *it may be significantly slower* than normal filters.
Large messages are *not* supported.
The XML parser used for XPath is configured with these default "features":
* `+http://xml.org/sax/features/external-general-entities+`: `false`
* `+http://xml.org/sax/features/external-parameter-entities+`: `false`
* `+http://apache.org/xml/features/disallow-doctype-decl+`: `true`
However, in order to deal with any implementation-specific issues the features can be customized by using system properties starting with the `org.apache.activemq.documentBuilderFactory.feature:` prefix, e.g.:
----
-Dorg.apache.activemq.documentBuilderFactory.feature:http://xml.org/sax/features/external-general-entities=true
----