Retrying an operation

Sometimes the best way to fix an error that was triggered when invoking a service is to try sending it again, as the backend infrastructure may be temporarily unavailable. Camel makes it easy to specify policies that automatically retry making calls before flagging a message as an error. This recipe will show some of the ways in which you can control the retry policies for your integration routes.

Getting ready

The Java code for this recipe is located in the org.camelcookbook.error.retry package. The Spring XML files are located under src/main/resources/META-INF/spring and prefixed with retry.

How to do it...

In the XML DSL, define an errorHandler element within the camelContext element, and reference its id with the camelContext element's errorHandlerRef attribute. Within the errorHandler element, create a child redeliveryPolicy element, which provides the maximumRedeliveries and redeliveryDelay attributes, among many other options. This will set the base error handler for all routes defined within this Camel context.

<camelContext errorHandlerRef="myErrorHandler"
              xmlns="http://camel.apache.org/schema/spring">
  <errorHandler id="myErrorHandler"
                type="DefaultErrorHandler">
    <redeliveryPolicy maximumRedeliveries="2"/>
  </errorHandler>

  <route>
    <from uri="direct:start"/>
    <!-- ... -->
  </route>
</camelContext>

In the Java DSL, you can achieve the same thing within the RouteBuilder.configure() method. Here you define an errorHandler element that refers to a DefaultErrorHandler instance configured using its fluent API. You can set a number of attributes, such as maximumRedeliveries (defaults to 0, which means no redelivery attempts), and the redeliveryDelay function (defaults to 1000 ms). The following code will configure the base error handler for all routes defined within this RouteBuilder implementation.

public class RetryRouteBuilder extends RouteBuilder {
  @Override
  public void configure() throws Exception {
    errorHandler(defaultErrorHandler()
        .maximumRedeliveries(2)
    );

    from("direct:start") //...
  }
}

How it works...

Camel's redelivery error handling policy is quite powerful. When an error (Exception) is detected, Camel will automatically attempt to redeliver the same message to the endpoint that failed up to maximumRedeliveries times. The value of maximumRedeliveries affects redeliveries as follows:

  • 0 (its default value) means do not try to redeliver
  • A negative number, such as -1, means retry delivery forever
  • A positive number means that Camel will try to redeliver up to that many times. That is, it will make the initial delivery attempt plus maximumRedeliveries redelivery attempts (1 + maximumRedeliveries).

The error handler can also introduce a delay of redeliveryDelay milliseconds between each redelivery attempt to allow time for the called service to become available again.

There are many other options within the redelivery policy such as useExponentialBackOff delay that increases the redeliveryDelay element value by some backOffMultiplier for each redelivery attempt up to a specified maximumRedeliveryDelay. The Camel Error Handling documentation gives you a lot more detail on the many powerful redelivery options available to you.

If the redelivery policy does eventually become exhausted by exceeding maximumRedeliveries attempts, Camel will revert to throwing the exception caused by the last redelivery failure.

There's more...

You can also set route-specific error handlers.

In the XML DSL, you set the route elements's errorHandlerRef attribute:

<camelContext xmlns="http://camel.apache.org/schema/spring">
  <errorHandler id="myRouteSpecificErrorHandler"
                type="DefaultErrorHandler">
    <redeliveryPolicy maximumRedeliveries="2"/>
  </errorHandler>

  <route errorHandlerRef="myRouteSpecificLogging">
    <from uri="direct:start"/>
    //...
  </route>
</camelContext>

In the Java DSL, you specify the route-specific error handler after the from part of the route definition:

from("direct:start")
    .errorHandler(defaultErrorHandler()
        .maximumRedeliveries(2)
    )
  .bean(FlakyProcessor.class)
  .to("mock:result");
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.41.148