Home > Back-end >  Spring Integration subflow depending on .handle method
Spring Integration subflow depending on .handle method

Time:03-19

I am using spring integration to change a flow after particular retry is completed. My IntegrationFlow bean for errorResponse is as follows:

@Bean
public IntegrationFlow errorMailResponse(@Qualifier(ERROR_CHANNEL) PollableChannel errorChannel) {
    return IntegrationFlows.from(errorChannel)
            .handle(MessagingException.class, (payload, headers) -> handleMessageException(payload),
                    e -> e.poller(p -> p.fixedDelay(pollerInterval)))
            .channel(NO_OUTPUT_CHANNEL)
            .get();
}

If method handleMessageException returns an object I want the flow to continue to particular channel - MAIN_EVENTS_CHANNEL if handleMessageException returns null I want to continue to NO_OUTPUT_CHANNEL.

Is that possible to achieve with Spring integration? I tried to use subflow but I am not sure if it is the way. https://docs.spring.io/spring-integration/reference/html/dsl.html#java-dsl-subflows

@Bean
public IntegrationFlow errorMailResponse(@Qualifier(ERROR_CHANNEL) PollableChannel errorChannel) {
    return IntegrationFlows.from(errorChannel)
            .handle(MessagingException.class, (payload, headers) -> handleMailMessageException(payload),
                    e -> e.poller(p -> p.fixedDelay(pollerInterval)))
            .publishSubscribeChannel(subscription -> subscription
                    .subscribe(subflow -> subflow
                            .<MailPojo>handle((payload, headers) -> {
                                // if if result handleMessageException  == null
                            })
                            .channel(NO_OUTPUT_CHANNEL))
                    .subscribe(subflow -> subflow
                            .<MailPojo>handle((payload, headers) -> {
                               // if result handleMessageException  !=null
                            })
                            .channel(MAIN_EVENTS_CHANNEL)))
            .get();
}

Any help is appreciated.

CodePudding user response:

First of all the null is not a payload. Therefore messaging does not support null in most cases. The integration flow just stops at the point where you return null: https://docs.spring.io/spring-integration/docs/current/reference/html/messaging-endpoints.html#service-activator-namespace

The service activator is one of those components that is not required to produce a reply message. If your method returns null or has a void return type, the service activator exits after the method invocation, without any signals.

So, your assumption to make a logical decision is not correct with Spring Integration. You need to think about something what could be used as a signal for such a NO_OUTPUT_CHANNEL. You can create an artificial NullType and use a PayloadTypeRouter to determine when to go next according the payload type returned from your handleMailMessageException():

.<Object, Class<?>>route(Object::getClass, m -> m
                        .channelMapping(MailPojo.class, MAIN_EVENTS_CHANNEL)
                        .channelMapping(NullType.class, NO_OUTPUT_CHANNEL))

Another way is to use an Optional and check its content in the router function. Either way you need to use a router.

  • Related