Predicates
Camel supports a pluggable interface called Predicate which can be used to integrate a dynamic predicate into Enterprise Integration Patterns such as when using the Message Filter or Content Based Router.
A Predicate is being evaluated to a boolean value so the result is either true
or false
. This makes Predicate so powerful as it is often used to control the routing of message in which path they should be routed.
A simple example is to route an Exchange based on a header value:
from("jms:queue:order") .choice() .when(header("type").isEqualTo("widget")).to("bean:widgetOrder") .when(header("type").isEqualTo("wombat")).to("bean:wombatOrder") .otherwise() .to("bean:miscOrder") .end();
In the route above the Predicate is the header("type").isEqualTo("widget")
as its constructed as an Expression that is evaluated as a Predicate. To do this the various Builder classes helps us here to create a nice and fluent syntax. isEqualTo
is a builder method that returns a Predicate based on the input.
Sometimes the fluent builders can get long and a bit complex to read, then you can just define your predicate outside the route and then just refer to the predicate in the route:
Predicate isWidget = header("type").isEqualTo("widget");
And then you can refer to it in the route as:
from("jms:queue:order") .choice() .when(isWidget).to("bean:widgetOrder") .when(isWombat).to("bean:wombatOrder") .otherwise() .to("bean:miscOrder") .end();
Negating a Predicate
You can use the not method on the PredicateBuilder
to negate a predicate.
First we import the not static, so it makes our route nice and easy to read:
import static org.apache.camel.builder.PredicateBuilder.not
And then we can use it to enclose an existing predicate and negate it as the example shows:
Compound Predicates
You can also create compound predicates using boolean operators such as and, or, not
and many others.
Currently this feature is only available in the Java-based DSLs, but not in the Spring nor Blueprint DSLs.
Using the PredicateBuilder
class, you can combine predicates from different Expression Languages based on logical operators and comparison operators:
not
,and
,or
isNull
,isNotNull
isEqualTo
,isGreaterThan
,isLessThan
startsWith
,endsWith
in
("any of X predicates stands true")
Additionally, with PredicateBuilder
you can create Regular Expressions and use them as predicates, applying them to the result of an expression, e.g. PredicateBuilder.regex(header("foo"), "\d{4}")
applies the regular expression to the header = foo.
Combining different Expression Languages is also possible, e.g.:
PredicateBuilder.and(XPathBuilder.xpath("/bookings/flights"), simple("${property.country = 'Spain'}"))
The sample below demonstrates further use cases:
Extensible Predicates
Camel supports extensible Predicates using multiple Languages; the following languages are supported out of the box
- Bean Language for using Java for expressions
- Constant
- the unified EL from JSP and JSF
- Header
- JSonPath
- JXPath
- Mvel
- OGNL
- Ref Language
- ExchangeProperty / Property
- Scripting Languages such as
- Simple
- Spring Expression Language
- SQL
- Tokenizer
- XPath
- XQuery
- VTD-XML
Most of these languages is also supported used as Annotation Based Expression Language.
You can easily write your own plugin predicate by implementing the Predicate interface.
There are also a number of helper builders available such as the PredicateBuilder class
Using Predicates in your IDE
To use different expression and predicates in your IDE you need to perform a static import of the builder class for the language(s) you wish to use.Language(s) |
Builder class to import |
---|---|
Scripting Languages such as BeanShell, JavaScript, Groovy, PHP, Python and Ruby |
|