How to change camel redelivery attempts as per exception
Environment
- JBoss Fuse
- 6.x
Issue
- I have a simple camel route. When an exception occurs I need to find out exact root exception (e.g. JMSException) nested in a generic exception 'GenericHandlerException'. After that I need to make redelivery of the message for certain number of attempts depending on the root exception.
For instance, If I catch a HandlerException but with a JMSException wrapped as a root exception, I need to re-deliver it 3 times. For any other exceptions caught within the HandlerException as a root exception, I would like to re-deliver it 5 times.
Any idea how to achieve it?
- We have some custom route policy classes that handles suspending/resuming of the routes in case there are any exception in routes. We also do not have any exception handling block at individual route level.
Resolution
The solution is to use "retryWhile". For more details, please take a look at section "Using fine grained retry using retryWhile predicate" from this link:
http://camel.apache.org/exception-clause.html
Basically you will need to create a ruleset bean class to configure rule sets for variable retry attempts based on different exception that is embedded in the GenericHandlerException. You can configure multiple sets of the rules to combine number of retry attempts with particular type of exceptions:
public class MyRetryRuleset {
...
public boolean shouldRetry(
@Header(Exchange.REDELIVERY_COUNTER) Integer counter,
Exception causedBy) {
if (causedBy instanceof GenericHandlerException) {
Exception rootEx = ((GenericHandlerException)causedBy).getRootException();
if (rootEx.getClass().equals(ThreeRetryException.class) && counter < 3) {
return true;
} else if (rootEx.getClass().equals(FiveRetryException.class) && counter < 5) {
return true;
} else {
// add other exceptions and retry attempts
}
}
return false;
}
...
}
Then in your camel route, you just simply do:
@Override
public void configure() throws Exception {
onException(GenericHandlerException.class)
.retryWhile(bean(MyRetryRuleset.class));
from("activemq:queue:foo")
.convertBodyTo(String.class)
.bean(TesterBean.class)
.log("received body: ${body}");
}
Please find attached demo for more details.
Attachments
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.
Welcome! Check out the Getting Started with Red Hat page for quick tours and guides for common tasks.
