Using a Java method as a Predicate

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.

Getting ready

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.

How to do it...

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");
    }
  }
}

How it works...

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:

  1. Select which method on an object to call, if not explicitly specified or if there are overloaded methods.
  2. Map the exchange contents into one or more of the method parameters.
  3. Convert the result data type to a 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
  }

Tip

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").

There's more...

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");
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.143.5.15