Search code examples
javaspring-integration

Spring Integration Java DSL Filter w/ Routing


Spring Integration 5.x here (Java DSL). I am interested in implementing a filter as part of my IntegrationFlow that has the following logic:

  • if the inbound message has a header of "fruit", then I want it routed to the "fruit-channel" (regardless of the fruit header's value)
  • otherwise I want the message sent to a discard channel/dead letter queue

My best attempt at the filter itself:

public class FruitFilter {

    @Filter
    public boolean fruitsOnly(Message<?> message) {
        return message.getHeaders().containsKey("fruit");
    }

}

And my best attempt at using this filter in a flow:

@Bean
public IntegrationFlow fruitFlow() {

    return IntegrationFlows.from(ingressChannel())

        .filter(fruitFilter)

        // TODO #1: how to route messages (containing the fruit header) on to the "fruit-channel"?
        // TODO #2: how to process messages that were filtered and sent to the discard/DLQ channel?
        .get();

}

I think the Java code and use of Spring Integration's API is OK above, but I'm not understanding where/how I place the actual filter-based routing. Can anyone spot where I'm going awry here? Thanks in advance!


Solution

  • Your @Filter impl is OK, although it could be just made as an in-line lambda. The fruit-channel should be just an output of this filter() endpoint. The error-channel must be configured as a discardChannel option of that filter(). So, the solution for your task might look like this:

    @Bean
    public IntegrationFlow fruitFlow() {
    
        return IntegrationFlows.from(ingressChannel())
                .filter(fruitFilter, "fruitsOnly", e -> e.discardChannel("error-channel"))
                .channel("fruit-channel")
                .get();
    
    }
    

    That's if you stick with your FruitFilter bean. However this one would let you to avoid that one as well:

     .filter(Message.class, message -> message.getHeaders().containsKey("fruit"), e -> e.discardChannel("error-channel"))