Learner
Learner

Reputation: 287

Output and Error Channel after any/all service activator is done

I would like to execute something after service any/all service activator is done executing. The flow is defined as follows:

@Bean
public IntegrationFlow myFlow(MessageSource<Object> someMessageSource) {
    return IntegrationFlows.from(someMessageSource,
            c -> c.poller(Pollers.fixedRate(1, SECONDS)
                    .maxMessagesPerPoll(10)))
            .channel(mySourceChannel())
            .get();
}

@Bean
public MessageChannel mySourceChannel() {
    return new ExecutorChannel(executor());
}

The two service activators are defined as

public static class MyFooActivator {  
    @ServiceActivator(inputChannel = "mySourceChannel")
    public void doSomething(FooTask event) {
      //handle foo task
    }
}

public static class MyBarActivator { 
    @ServiceActivator(inputChannel = "mySourceChannel")
    public void doSomething(BarTask event) {
        // handle bar task
    }
}

As you can see, the service activators are not defined as part of integration flow but through annotations. The goal is to execute some piece of code when 1) service activator execution was successful 2) when service activator execution was not successful.

If service executor are known/defined with flow, this can be achieved by defining another flow and add an output channel and error. Not sure, how to achieve the same in my case.

Upvotes: 2

Views: 471

Answers (1)

Artem Bilan
Artem Bilan

Reputation: 121427

First of all you need to understand that having to subscribers to that mySourceChannel, you'll end up with the round-robin balancing between them, when the first message is going to the first service activator and the next one to the second. And so on odd-even manner. So, you should be sure that this is exactly what you except from such a configuration.

To make some analyze for the execution result of the service activator you need to use an ExpressionEvaluatingRequestHandlerAdvice . It has successChannel and failureChannel options alongside with appropriate expressions if that necessary.

You can inject the reference to its bean into the adviceChain attribute of the @ServiceActivator. Something like this:

    @Bean
    @ServiceActivator(inputChannel = "myHandlerChannel", adviceChain = "myHandlerAdvice")
    public MessageHandler myHandler() {
        return message -> { };
    }

    @Bean
    public Advice myHandlerAdvice() {
        ExpressionEvaluatingRequestHandlerAdvice advice = new ExpressionEvaluatingRequestHandlerAdvice();
        advice.setOnSuccessExpressionString("payload");
        advice.setSuccessChannel(myHandlerSuccessChannel());
        return advice;
    }

More info is in the Reference Manual: https://docs.spring.io/spring-integration/reference/html/messaging-endpoints-chapter.html#expression-advice

Upvotes: 2

Related Questions