Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Apache Camel Developer's Cookbook

You're reading from   Apache Camel Developer's Cookbook For Apache Camel developers, this is the book you'll always want to have handy. It's stuffed full of great recipes that are designed for quick practical application. Expands your Apache Camel abilities immediately.

Arrow left icon
Product type Paperback
Published in Dec 2013
Publisher Packt
ISBN-13 9781782170303
Length 424 pages
Edition 1st Edition
Languages
Tools
Arrow right icon
Toc

Table of Contents (14) Chapters Close

Preface 1. Structuring Routes 2. Message Routing FREE CHAPTER 3. Routing to Your Code 4. Transformation 5. Splitting and Aggregating 6. Parallel Processing 7. Error Handling and Compensation 8. Transactions and Idempotency 9. Testing 10. Monitoring and Debugging 11. Security 12. Web Services Index

Controlling route startup and shutdown

When integration logic is composed of routes depending on other routes via direct:, it is important that they start up in such a way that dependencies are available before exchanges start flowing. If not, you are likely to see this sort of exception being thrown:

org.apache.camel.CamelExchangeException: No consumers available on endpoint: Endpoint[direct://someMissingEndpoint]

Conversely, on application shutdown, messages should complete processing gracefully rather than fail because a dependent route is no longer available. Camel provides a mechanism to define an order for startup and shutdown that addresses both of these issues at the same time.

This recipe will show you how to control the startup and shutdown order of your routes.

Getting ready

Define your desired routing logic as described in either the Using Camel in a Java application recipe, or the Embedding Camel in a Spring application recipe.

The Java code for this recipe is located in the org.camelcookbook.structuringroutes.routecontrol package.

How to do it...

Set the startupOrder property associated with the route.

In the XML DSL, add a startupOrder attribute to the route element:

<route startupOrder="20">
  <from uri="jms:queue:orders"/>
  <to uri="direct:processOrder"/>
</route>

<route startupOrder="10">
  <from uri="direct:processOrder"/>
  <process ref="orderProcessor"/>
</route>

In the Java DSL, call the startupOrder(..) method after the from statement:

from("jms:queue:orders").startupOrder(20)
  .to("direct:processOrder");

from("direct:processOrder").startupOrder(10)
  .process(new OrderProcessor());

How it works...

Routes are started in ascending startupOrder. In the preceding examples, the direct: route will be started before the main entry point to the integration, which consumes from JMS.

You can assign any integer greater than 0 and less than 1,000 to the startupOrder. You cannot assign the same value more than once in a Camel context, otherwise it will refuse to start up. Camel will automatically assign values greater than 1,000 to any routes that do not specifically have one defined.

Tip

Drawing inspiration from BASIC programming (for those old enough to remember it), it is useful to assign startupOrder values in increments of 10. As your integration grows and you find yourself breaking routes down for reuse, it pays to have numbers available so that you do not have to renumber every route.

When you shut down the application, Camel will turn off the routes in the reverse order to that in which it started them. Routes are turned off in descending order.

When a route shuts down, the endpoint consumer is first turned off, and any messages that are flowing through the route ("in-flight") are allowed to complete before the route itself is shut down. Any messages that remain in-flight will be discarded after a timeout of 300 seconds. The timeout is configurable on the Camel context's associated ShutdownStrategy.

There's more...

Routes can be started and shut down programmatically through the CamelContext startRoute() and stopRoute() methods. Since the context is accessible through an Exchange it is possible to perform custom route control logic. Take, as an example, the following class that stops a route whose name is specified by the body of the exchange:

public class RouteStoppingProcessor implements Processor {
  @Override
  public void process(Exchange exchange) throws Exception {
    final String routeName = 
        exchange.getIn().getBody(String.class);
    final CamelContext context = exchange.getContext();
    new Thread(new Runnable() {
      @Override
      public void run() {
        try {
          context.stopRoute(routeName);
        } catch (Exception e) {
          throw new RuntimeException(e);
        }
      }
    }).start();
  }
}

Note

It is best practice to manually shut down routes in Camel in a separate thread than in the one that is processing the exchange. The reason behind this is that Camel waits for all exchanges that are flowing through a route to complete before it stops the route. If a thread processing an exchange attempts to shut down the route through which that exchange is flowing, this results in a deadlock.

See the following for more details: http://camel.apache.org/how-can-i-stop-a-route-from-a-route.html.

Routes can also be stopped and started through the use of a Control Bus endpoint:

from("direct:in").id("mainRoute")
  .log("Stopping route")
  .to("controlbus:route?routeId=mainRoute&action=stop&async=true")
  .log("Signalled to stop route")
  .to("mock:out");

Tip

Note the use of async=true to shut down the route in a background thread and thereby prevent a deadlock.

Manual route control does not take into account the startupOrder, so you must take care when performing it that any routes that you start up or shut down are controlled in an orderly manner.

Routes can be turned off at startup by setting the autoStartup attribute to false.

In the XML DSL, add an autoStartup attribute to the route element:

<route autoStartup="false">
  <from uri="jms:queue:orders"/>
  <!-- ... -->
</route>

In the Java DSL, call the autoStartup(..) method after the from statement:

from("jms:queue:orders").autoStartup(false)...

You would use this feature if you want to control route availability manually, or through a route policy.

A RoutePolicy is an interface that you can build upon to determine whether routes should be running or not. Camel provides route policies out of the box for throttling routes (ThrottlingInflightRoutePolicy), defining uptime through a timer (SimpleScheduledRoutePolicy), and cron expressions (CronScheduledRoutePolicy).

lock icon The rest of the chapter is locked
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €18.99/month. Cancel anytime