Camel makes it very easy to call out to some existing Java code to act as a predicate when you are using an Enterprise Integration Pattern (EIP) such as Content Based Router or Filter. Any EIPs that require a Camel Predicate can use the Bean Expression Language to call any Java method that evaluates to a boolean
value. Remember that a Camel Predicate is any Camel Expression that evaluates to a boolean
value (true
or false
). This allows you to integrate complex decision making from your existing Java code into your routing logic.
This recipe shows you how to use any of your Java methods that returns a boolean
value wherever Camel expects a predicate.
The Java code for this recipe is located in the org.camelcookbook.extend.predicate
package. The Spring XML files are located under src/main/resources/META-INF/spring
and prefixed with predicate
.
Given an existing Java method that evaluates to a boolean
value, such as:
public class MyPredicate { public boolean isWhatIWant(String body) { // evaluate message body and return true or false } }
This method can be evaluated for use by any EIP that requires a predicate:
In the XML DSL, this is written as:
<beans xmlns="http://www.springframework.org/schema/beans"... > <bean id="myPredicate" class="org.camelcookbook.extend.predicate.MyPredicate"/> <camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/> <filter> <method ref="myPredicate" method="isWhatIWant"/> <to uri="mock:boston"/> </filter> </route> </camelContext> </beans>
In the Java DSL, the same route is expressed as:
public class MyPredicateRouteBuilder extends RouteBuilder {
@Override
public void configure() throws Exception {
MyPredicate predicate = new MyPredicate();
from("direct:start")
.filter().method(predicate, "isWhatIWant")
.to("mock:boston");
}
}
}
Behind the scenes, Camel uses a class called PredicateBuilder
to convert any expression, in our case a Bean Expression Language expression bound using the method
statement, into a predicate that will pass the contents of an exchange (message, headers, and properties) into a method returning a boolean
value.
Camel uses a very sophisticated algorithm known as Bean Binding to perform the following steps:
boolean
value.There are a number of Java annotations you can use to influence how Camel interacts with your Java objects. For example, if you wanted the first parameter to be mapped to a header, and the second parameter to the body of the message, you could perform the following:
public void doSomething( @Header("JMSCorrelationID") String correlationID, @Body String body) { // process the message here }
More details can be found in the Camel documentation on Parameter Binding Annotations (http://camel.apache.org/parameter-binding-annotations.html).
The preceding method
statement is an Expression variant of the bean
statement and the Bean Component, all of which allow you to call a Java method on the referenced Java class instance that is a POJO. The method
statement requires a reference to an existing bean instance contained in the Camel context's Registry, and a method name. The bean
statement takes either a reference name or a Java type (Camel will instantiate a singleton instance of that type), and an optional method name (Camel will use its Bean Binding algorithm to determine which method to call if none is provided). The Bean Component lets you specify a reference anywhere you can specify an endpoint URI, that is .to("bean:myBean?method=foo")
.
Camel supports the ability to combine one or more expressions into a compound predicate. This allows you to logically combine (and
, or
, not
) multiple expressions together, even if they are in multiple expression languages. For example, you could create a compound predicate that first evaluates an XPath expression, and then evaluates a Java method.
import static org.apache.camel.builder.PredicateBuilder.and; from("direct:start") .filter(and(xpath("/someXml/city = 'Boston'"), method(predicate, "isWhatIWant"))) .to("mock:boston");
3.138.124.194