My usecase is to receive Kafka messages, make multiple attempts at a rest call and upon exhaustion dump the failed mesage onto Kafka DLQ topic.
@StreamListener(EventSource.SOME_CHANNEL)
public void processMessage(Message<?> unsolicitedMessage) {
String aString = .....
oneService.act(aString);
}
@Retryable
is working perfectly in terms of handing logic for multiple attempts.
@Retryable(value = {OneException.class, TwoException}, maxAttempts = 3,
backoff = @Backoff(delay = 1000))
public boolean act(String message, String endPoint) {
//do stuff
}
For the Spring Cloud Stream inbuilt Kafka DLQ publishing to kick in (enableDlq: true
) , the exception needs to bubble-up to the @StreamListener
annotated method for the Kafka binder to do the needful.
However, in doing so, I am not able to leverage the @Recover
annotated method, where the flow perfectly lands after retrying:
@Recover
public boolean recoverOnToDLQ(OneException ex, String message, String
endPoint) {
throw ex; //Required for StreamListener Kafka DLQ to kick in!
}
Question: Is there a way to trigger Kakfa DLQ publishing from within the @Recover
method without re-throwing the exception?
Because if I use it only to rethrow, I believe I won't be making efficient use of the tighter control obtained therein. This will also simplify unit test cases, and better capture the logic at code-level? Are there any thoughts on how to handle this better?
I am on all the latest versions for spring-cloud, spring-cloud-stream and spring-retry as of this date.