blob: fd9c149559241a7e0b0693578ad8f15bc3231c4b [file] [log] [blame]
[[HowdoIretryprocessingamessagefromacertainpointbackoranentireroute-HowdoIretryprocessingamessagefromacertainpointbackoranentireroute]]
= How do I retry processing a message from a certain point back or an entire route
By default Apache Camel will perform any redelivery (retry) attempts
from the point of failure. So if you want to retry from a point before
this, you would need to split up your route.
In the example above we have 2 routes (`direct:start`, `direct:sub`). In
case of a failure anywhere in the `direct:sub` route, then the entire
route is retried. This happens because we have instructed the `direct:sub`
route to not use any error handler (eg the no error handler). Then we
link the routes using the xref:components::direct-component.adoc[Direct] component by calling
the sub route from the 1st route.
[source,java]
----
// in case of io exception then try to redeliver up till 2 times
// (do not use any delay due faster unit testing)
onException(IOException.class)
.maximumRedeliveries(2).redeliveryDelay(0);
from("direct:start")
.to("mock:a")
// call sub route (using direct)
.to("direct:sub")
.to("mock:c");
from("direct:sub")
// disable error handler, so the entire route can be retried in case of redelivery
.errorHandler(noErrorHandler())
.to("mock:b")
.process(new MyProcessor());
----
The code above is based on an unit test, and as you can see the
processor below is configured to fail the first 2 attempts.
So that means the entire `direct:sub` route is redeliveried, meaning that
the `mock:b` endpoint receives the incoming message again.
[source,java]
----
public static class MyProcessor implements Processor {
private int counter;
@Override
public void process(Exchange exchange) throws Exception {
// use a processor to simulate error in the first 2 calls
if (counter++ < 2) {
throw new IOException("Forced");
}
exchange.getIn().setBody("Bye World");
}
}
----
The same example is shown below using the XML DSL:
[source,xml]
----
<!-- this is the processor that will fail the first 2 attempts -->
<bean id="myProcessor" class="org.apache.camel.processor.RedeliverToSubRouteTest.MyProcessor"/>
<camelContext xmlns="http://camel.apache.org/schema/spring">
<!-- setup no error handler with an id, we refer to from the 2nd route -->
<errorHandler id="noErrorHandler" type="NoErrorHandler"/>
<!-- configure on exception to redelivery at most 2 times when an IOException was thrown
do not use redelivery delay to run unit test faster -->
<onException>
<exception>java.io.IOException</exception>
<redeliveryPolicy maximumRedeliveries="2" redeliveryDelay="0"/>
</onException>
<!-- 1st route, no need to setup error handler, as it will use the default error handler -->
<route>
<from uri="direct:start"/>
<to uri="mock:a"/>
<to uri="direct:sub"/>
<to uri="mock:c"/>
</route>
<!-- disable error handler on this route, so the entire route can be redelivered
when called from the 1st route -->
<route errorHandlerRef="noErrorHandler">
<from uri="direct:sub"/>
<to uri="mock:b"/>
<process ref="myProcessor"/>
</route>
</camelContext>
----