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:
from("direct:start"
)
.choice()
.when(not(header("username"
).regex("goofy|pluto"
))).to("mock:people"
)
.otherwise().to("mock:animals"
)
.end();
Compound Predicates
You can also create compound predicates using boolean operators such as and, or, not and many others.
The sample below demonstrates this:
// We define 3 predicates based on some user roles
// we have static
imported and/or from org.apache.camel.builder.PredicateBuilder
// First we have a regular user that is just identified having a username header
Predicate user = header("username"
).isNotNull();
// The admin user must be a user AND have a admin header as true
Predicate admin = and(user, header("admin"
).isEqualTo("true
"
));
// And God must be an admin and (either have type god or a special message containing Camel Rider)
Predicate god = and(admin, or(body().contains("Camel Rider"
), header("type"
).isEqualTo("god"
)));
// As you can see with the predicates above we can stack them to build compound predicates
// In our route below we can create a nice content based router based on the predicates we
// have defined. Then the route is easy to read and understand.
// We encourage you to define complex predicates outside the fluent router builder as
// it will just get a bit complex for
humans to read
from("direct:start"
).choice()
.when(god).to("mock:god"
)
.when(admin).to("mock:admin"
)
.when(user).to("mock:user"
)
.otherwise().to("mock:guest"
)
.end();
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
- JXPath
- Mvel
- OGNL
- Property
- Scala DSL
- Scripting Languages such as
- Simple
- SQL
- XPath
- XQuery
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 | org.apache.camel.builder.script.ScriptBuilder |
SQL | org.apache.camel.builder.josql.SqlBuilder |
XPath | org.apache.camel.builder.xml.XPathBuilder |
XQuery | org.apache.camel.builder.saxon.XQueryBuilder |