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:
Code Block | ||||
---|---|---|---|---|
| ||||
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:
Code Block | ||||
---|---|---|---|---|
| ||||
Predicate isWidget = header("type").isEqualTo("widget"); |
And then you can refer to it in the route as:
Code Block | ||||
---|---|---|---|---|
| ||||
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:
Code Block |
---|
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:
Wiki Markup |
---|
{snippet:id=e1|lang=java|url=camel/trunk/camel-core/src/test/java/org/apache/camel/processor/ChoiceWhenNotPredicateTest.java} |
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.:
Code Block |
---|
PredicateBuilder.and(XPathBuilder.xpath("/bookings/flights"), simple("${property.country = 'Spain'}")) |
The sample below demonstrates further use cases:
Wiki Markup |
---|
{snippet:id=e1|lang=java|url=camel/trunk/camel-core/src/test/java/org/apache/camel/processor/ChoiceCompoundPredicateTest.java} |
Extensible Predicates
Camel supports extensible Predicates using multiple Languages; the following languages are supported out of the box
Include Page | ||||
---|---|---|---|---|
|
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
Include Page | ||||
---|---|---|---|---|
|