benz
benz

Reputation: 725

Apache Camel: compound conditions by using the predicateBuilder and access them from the when() function

I am trying to compound conditions with the PredicateBuilder and saving it to the header to access the predicate from the when() function. At the beginning I set the body to Hello World. Also the body is not null or not equal to AUTHENTICATE failed but I getting into the when block and process_no_mail_or_failed is being logged. I do not understand what I am doing wrong. How can I compound predicates in Apache Camel and use them in the when() function? In case I have to check the body at some step. Therefore I did it in the way.

I apreciate any help!

Apache Camel route:

import org.apache.camel.Exchange;
import org.apache.camel.Message;
import org.apache.camel.Predicate;
import org.apache.camel.Processor;
import org.apache.camel.builder.PredicateBuilder;
import org.apache.camel.builder.RouteBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Component
public class TestRoute  extends RouteBuilder {
    
    static final Logger LOGGER = LoggerFactory.getLogger(EmailPollingRoute.class);
    static final String AUTHENTICATE_FAILED = "AUTHENTICATE failed.";
    
    @Override
    public void configure() throws Exception {

        from("quartz://emailTimer?cron=0/30+*+*+*+*+?+*")
        .log("TestRoute - Before calling transform")
        .process(new Processor() {
            @Override
            public void process(Exchange exchange) throws Exception {
                Message message = exchange.getIn();
                message.setBody("Hello World");
                String body = message.getBody(String.class);
                LOGGER.info("body: \n" + body);
                
                Predicate p1 = body().isNull();
                Predicate p2 = body().isEqualTo(AUTHENTICATE_FAILED);
                Predicate predicate_result12 = PredicateBuilder.or(p1, p2);
                message.setHeader("process_no_mail_or_failed", predicate_result12);
                
            }   
        })
        .choice()
        .when(header("process_no_mail_or_failed").convertTo(Predicate.class)) 
        //.when(simple("${body} == null || ${body} == 'AUTHENTICATE failed.'")) //This works for me. I am getting into the otherwise block
           .log("when: ${body}")
           
        .otherwise()
           .log("otherwise: ${body}");
    
    }
}
    

Upvotes: 0

Views: 2320

Answers (1)

Pasi Österman
Pasi Österman

Reputation: 2197

Predicates have matches method which you can use to evaluate the predicate with

If you want to get the result for Predicate you can use the matches-method to evaluate the predicate.

from("direct:example")
    .routeId("example")
    .process(exchange -> {

        Predicate bodyNotNullOrEmpty = PredicateBuilder.and(
            body().isNotEqualTo(null), 
            body().isNotEqualTo("")
        );
        Boolean result = bodyNotNullOrEmpty.matches(exchange);
        exchange.getMessage().setHeader("bodyNotNullOrEmpty", result);
    })
    .choice().when(header("bodyNotNullOrEmpty"))
        .log("body: ${body}")
    .otherwise()
        .log("Body is null or empty")
    .end()
    .to("mock:result");

You could also just import static methods from the Predicate builder and use them within choice without having to store the result to exchange property.

This trick of importing the static methods from Predicate builder can be easy to miss due to it being only mentioned in negate predicates section of the documentation.

import static org.apache.camel.builder.PredicateBuilder.not;
import static org.apache.camel.builder.PredicateBuilder.and;

...

from("direct:example")
    .routeId("example")
    .choice()
        .when(and(body().isNotNull(), body().isNotEqualTo("")))
            .log("body: ${body}")
        .otherwise()
            .log("Body is null or empty")
    .end()
    .to("mock:result");

Upvotes: 1

Related Questions