Filter
The Message Filter from the EIP patterns allows you to filter messages.
How can a component avoid receiving uninteresting messages?
Use a special kind of Message Router, a Message Filter, to eliminate undesired messages from a channel based on a set of criteria.
The message filter implemented in Camel is similar to
if (predicate) { block }
in Java. The filter will
include
the message if the predicate evaluated to
true
.
EIP options
The Filter eip supports the following options which are listed below.
| Name | Description | Default | Type |
|---|---|---|---|
|
note |
The note for this node. |
String |
|
|
description |
The description for this node. |
String |
|
|
disabled |
Whether to disable this EIP from the route during build time. Once an EIP has been disabled then it cannot be enabled later at runtime. |
false |
Boolean |
|
expression |
Required The predicate expression to evaluate. Messages where the predicate returns false are filtered out and not routed further. |
ExpressionDefinition |
|
|
statusPropertyName |
Name of an exchange property to store whether the filter predicate matched or not. The value is stored as a boolean. |
String |
|
|
outputs |
Required |
List |
Example
The Camel Simple language is great to use with the Filter EIP when routing is based on the content of the message, such as checking message headers.
-
Java
-
XML
-
YAML
from("direct:a")
.filter(simple("${header.foo} == 'bar'"))
.to("direct:bar")
.end()
.to("direct:b")
<route>
<from uri="direct:a"/>
<filter>
<simple>${header.foo} == 'bar'</simple>
<to uri="direct:bar"/>
</filter>
<to uri="direct:b"/>
</route>
- route:
from:
uri: direct:a
steps:
- filter:
expression:
simple:
expression: "${header.foo} == 'bar'"
steps:
- to:
uri: direct:bar
- to:
uri: direct:b
You can use many languages as the predicate, such as XPath :
-
Java
-
XML
-
YAML
from("direct:start").
filter().xpath("/person[@name='James']").
to("mock:result");
<route>
<from uri="direct:start"/>
<filter>
<xpath>/person[@name='James']</xpath>
<to uri="mock:result"/>
</filter>
</route>
- route:
from:
uri: direct:start
steps:
- filter:
expression:
xpath:
expression: "/person[@name='James']"
steps:
- to:
uri: mock:result
Here is another example of calling a method on a bean to define the filter behavior:
-
Java
-
XML
-
YAML
from("direct:start")
.filter().method(MyBean.class, "isGoldCustomer")
.to("mock:gold")
.end()
.to("mock:all");
<route>
<from uri="direct:start"/>
<filter>
<method beanType="com.foo.MyBean" method="isGoldCustomer"/>
<to uri="mock:gold"/>
</filter>
<to uri="mock:all"/>
</route>
- route:
from:
uri: direct:start
steps:
- filter:
expression:
method:
method: isGoldCustomer
beanType: com.foo.MyBean
steps:
- to:
uri: mock:gold
- to:
uri: mock:all
The bean can have a method that returns a
boolean
as the predicate:
public static class MyBean {
public boolean isGoldCustomer(@Header("level") String level) {
return level.equals("gold");
}
}
Filtering with status property
To know whether an
Exchange
was filtered or not, then you can choose to specify a name of a property
to store on the exchange with the result (boolean), using
statusPropertyName
as shown below:
-
Java
-
XML
-
YAML
from("direct:start")
.filter().method(MyBean.class, "isGoldCustomer").statusPropertyName("gold")
.to("mock:gold")
.end()
.to("mock:all");
<route>
<from uri="direct:start"/>
<filter statusPropertyName="gold">
<method beanType="com.foo.MyBean" method="isGoldCustomer"/>
<to uri="mock:gold"/>
</filter>
<to uri="mock:all"/>
</route>
- route:
from:
uri: direct:start
steps:
- filter:
statusPropertyName: gold
expression:
method:
method: isGoldCustomer
beanType: com.foo.MyBean
steps:
- to:
uri: mock:gold
- to:
uri: mock:all
In the example above then Camel will store an exchange property with key
gold
with the result of the filtering,
whether it was
true
or
false
.
Filtering and stopping
When using the Message Filter EIP, then it only applies to its children.
For example, in the previous example then for a message that is a gold customer will be routed to both
mock:gold
and
mock:all
(predicate is true).
However, for a non-gold message (predicate is false) then the message will not be routed in the filter block,
but will be routed to mock:all.
Sometimes you may want to stop routing for messages that were filtered. To do this, you can use the Stop EIP as shown:
-
Java
-
XML
-
YAML
from("direct:start")
.filter().method(MyBean.class, "isGoldCustomer").statusPropertyName("gold")
.to("mock:gold")
.stop()
.end()
.to("mock:all");
<route>
<from uri="direct:start"/>
<filter>
<method beanType="com.foo.MyBean" method="isGoldCustomer"/>
<to uri="mock:gold"/>
<stop/>
</filter>
<to uri="mock:all"/>
</route>
- route:
from:
uri: direct:start
steps:
- filter:
expression:
method:
method: isGoldCustomer
beanType: com.foo.MyBean
steps:
- to:
uri: mock:gold
- stop: {}
- to:
uri: mock:all