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 0 options, which are listed below.
| Name | Description | Default | Type |
|---|---|---|---|
note | Sets the note of this node. | String | |
description | Sets the description of this node. | String | |
disabled | Disables this EIP from the route. | false | Boolean |
expression | Required Expression to determine if the message should be filtered or not. If the expression returns an empty value or false then the message is filtered (dropped), otherwise the message is continued being routed. | ExpressionDefinition | |
statusPropertyName | Name of exchange property to use for storing the status of the filtering. Setting this allows to know if the filter predicate evaluated as true or false. | 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:
from("direct:start")
.filter().method(MyBean.class, "isGoldCustomer")
.to("mock:gold")
.end()
.to("mock:all"); And then 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");
}
} And in XML we can call the bean in <method> where we can specify the FQN class name of the bean as shown:
<route>
<from uri="direct:start"/>
<filter>
<method beanType="com.foo.MyBean" method="isGoldCustomer"/>
<to uri="mock:gold"/>
</filter>
<to uri="mock:all"/>
</route> And similar in YAML DSL:
- route:
from:
uri: direct:start
steps:
- filter:
expression:
method:
method: isGoldCustomer
beanType: com.foo.MyBean
steps:
- to:
uri: mock:gold
- to:
uri: mock:all 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