0

I want to trigger an email, after RabbitMQ Listener retrials are over and still if the process of handle failed.

retry logic is working with below code. But how to trigger the functionality (email trigger) once the max retrial attempts are over.

@Bean
public SimpleMessageListenerContainer container() {
    SimpleMessageListenerContainer container =
            new SimpleMessageListenerContainer(connectionFactory());
    container.setQueues(myQueue());
    container.setDefaultRequeueRejected(false);
    Advice[] adviceArray = new Advice[]{interceptor()};
    container.setAdviceChain(adviceArray);
    return container;
}

@Bean
public IntegrationFlow inboundFlow() {
    return IntegrationFlows.from(
            Amqp.inboundAdapter(container()))
            .log()
            .handle(listenerBeanName, listenerMethodName)
            .get();
}

@Bean
RetryOperationsInterceptor interceptor() {
    return RetryInterceptorBuilder.stateless()
            .maxAttempts(retryMaxAttempts)
            .backOffOptions(initialInterval, multiplier, maxInterval)
             //.recoverer(new RejectAndDontRequeueRecoverer()) 
            .recoverer(new CustomRejectAndRecoverer())
            .build();
}

Adding with code of CustomeRecover

@Service
public class CustomRejectAndRecoverer implements MessageRecoverer {
@Autowired
private EmailGateway emailgateway;

@Override
public void recover(Message message, Throwable cause) {
    // INSERT CODE HERE.... HOW TO CALL GATEWAY
    // emailgateway.sendMail(cause);
    throw new ListenerExecutionFailedException("Retry Policy Exhausted",
            new AmqpRejectAndDontRequeueException(cause), message);
} }
Harish Menda
  • 71
  • 1
  • 2
  • 13
  • Could you clean this up a bit to narrow it down to the exact question? It looks like you got to an answer, but I don think the question is as useful to other readers as it could be. – theMayer Jun 30 '18 at 13:05

1 Answers1

1

That's exactly what a .recoverer() in that RetryInterceptorBuilder is for.

You use there now a RejectAndDontRequeueRecoverer, but no body stops you to implement your own MessageRecoverer with the delegation to the RejectAndDontRequeueRecoverer and sending a message to some MessageChannel with a sending emails logic.

Artem Bilan
  • 113,505
  • 11
  • 91
  • 118
  • If I use below code, I am getting nullpointerexception at gateway. Can you help in finding out the right way @Artem: Service public class CustomRejectAndRecoverer implements MessageRecoverer { Autowired private EmailGateway emailgateway; Override public void recover(Message message, Throwable cause) { //INSERT CODE HERE.... HOW TO CALL GATEWAY //emailgateway.sendMail(message); throw new ListenerExecutionFailedException("Retry Policy Exhausted", new AmqpRejectAndDontRequeueException(cause), message); } } – Harish Menda Jun 27 '18 at 18:39
  • Please, edit your question with that code. However it sounds like you are missing the fact that your `CustomRejectAndRecoverer` has to be declared as a `@Bean`, otherwise `EmailGateway` is not going to be injected. – Artem Bilan Jun 27 '18 at 18:45
  • Do I need to add '@Bean' at recover method? – Harish Menda Jun 27 '18 at 18:54
  • I don't know what you mean, but since I see a `RetryOperationsInterceptor` declared as a `@Bean`, I didn't think that it is going to be problem for your to declare a `@Bean` similar way for the `CustomRejectAndRecoverer`. More over you didn't show your current state of the code... – Artem Bilan Jun 27 '18 at 18:55
  • Added the code. can you please check. @Artem. In the added code, I am getting emailgateway as null – Harish Menda Jun 27 '18 at 18:59
  • Looks good. How do you use it? If that is not injection, but just `new CustomRejectAndRecoverer()` that is really not going to work but `NPE`. – Artem Bilan Jun 27 '18 at 19:00
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/173913/discussion-between-harish-menda-and-artem-bilan). – Harish Menda Jun 27 '18 at 19:04
  • No, I don't use chat here on SO. We are still good to comment here – Artem Bilan Jun 27 '18 at 19:05
  • Any idea, how to make it work? Sorry, if I am asking very basic questions. Autowired doesn't works here? – Harish Menda Jun 27 '18 at 19:08
  • How do you use your `CustomRejectAndRecoverer`? You show only class. If you really have there a `@ComponentScan`, then it is going to be a bean, indeed. But that still doesn't matter that you use it properly. So, how, please? What is your current `.recoverer()` situation? – Artem Bilan Jun 27 '18 at 19:10
  • Cuurent code: `.recoverer(new CustomRejectAndRecoverer())`. Please see, I have edited the code. And Yes I am using `@IntegrationComponentScan` in the configuration class – Harish Menda Jun 27 '18 at 19:14
  • I told you: that must not be `new CustomRejectAndRecoverer()`, if you are going to rely in the dependency injection. The `@IntegrationComponentScan` is not for regular `@Service` also. Please, read more about Spring container: https://docs.spring.io/spring/docs/5.0.7.RELEASE/spring-framework-reference/core.html#beans-java. – Artem Bilan Jun 27 '18 at 19:17
  • Thank you for your valueble time. It is working, when I injected through bean like this: `@Bean public CustomRejectAndRecoverer customRejectAndRecoverer(){ return new CustomRejectAndRecoverer(); }` – Harish Menda Jun 27 '18 at 19:35