2.10. Scheduled Route Policy

2.10.1. Overview of Scheduled Route Policies

Overview

A scheduled route policy can be used to trigger events that affect a route at runtime. In particular, the implementations that are currently available enable you to start, stop, suspend, or resume a route at any time (or times) specified by the policy.

Scheduling tasks

The scheduled route policies are capable of triggering the following kinds of event:
  • Start a route—start the route at the time (or times) specified. This event only has an effect, if the route is currently in a stopped state, awaiting activation.
  • Stop a route—stop the route at the time (or times) specified. This event only has an effect, if the route is currently active.
  • Suspend a route—temporarily de-activate the consumer endpoint at the start of the route (as specified in from()). The rest of the route is still active, but clients will not be able to send new messages into the route.
  • Resume a route—re-activate the consumer endpoint at the start of the route, returning the route to a fully active state.

Quartz component

The Quartz component is a timer component based on Terracotta's Quartz, which is an open source implementation of a job scheduler. The Quartz component provides the underlying implementation for both the simple scheduled route policy and the cron scheduled route policy.

2.10.2. Simple Scheduled Route Policy

Overview

The simple scheduled route policy is a route policy that enables you to start, stop, suspend, and resume routes, where the timing of these events is defined by providing the time and date of an initial event and (optionally) by specifying a certain number of subsequent repititions. To define a simple scheduled route policy, create an instance of the following class:
org.apache.camel.routepolicy.quartz.SimpleScheduledRoutePolicy

Dependency

The simple scheduled route policy depends on the Quartz component, camel-quartz. For example, if you are using Maven as your build system, you would need to add a dependency on the camel-quartz artifact.

Java DSL example

Example 2.7, “Java DSL Example of Simple Scheduled Route” shows how to schedule a route to start up using the Java DSL. The initial start time, startTime, is defined to be 3 seconds after the current time. The policy is also configured to start the route a second time, 3 seconds after the initial start time, which is configured by setting routeStartRepeatCount to 1 and routeStartRepeatInterval to 3000 milliseconds.
In Java DSL, you attach the route policy to the route by calling the routePolicy() DSL command in the route.

Example 2.7. Java DSL Example of Simple Scheduled Route

// Java
SimpleScheduledRoutePolicy policy = new SimpleScheduledRoutePolicy();
long startTime = System.currentTimeMillis() + 3000L;
policy.setRouteStartDate(new Date(startTime));
policy.setRouteStartRepeatCount(1);
policy.setRouteStartRepeatInterval(3000);
                
from("direct:start")
   .routeId("test")
   .routePolicy(policy)
   .to("mock:success");
Note
You can specify multiple policies on the route by calling routePolicy() with multiple arguments.

XML DSL example

Example 2.8, “XML DSL Example of Simple Scheduled Route” shows how to schedule a route to start up using the XML DSL.
In XML DSL, you attach the route policy to the route by setting the routePolicyRef attribute on the route element.

Example 2.8. XML DSL Example of Simple Scheduled Route

<bean id="date" class="java.util.Data"/>

<bean id="startPolicy" class="org.apache.camel.routepolicy.quartz.SimpleScheduledRoutePolicy">
    <property name="routeStartDate" ref="date"/>
    <property name="routeStartRepeatCount" value="1"/>
    <property name="routeStartRepeatInterval" value="3000"/>    	
</bean> 
 	
<camelContext xmlns="http://camel.apache.org/schema/spring">
    <route id="myroute" routePolicyRef="startPolicy">
        <from uri="direct:start"/>
        <to uri="mock:success"/>
    </route>
</camelContext>
Note
You can specify multiple policies on the route by setting the value of routePolicyRef as a comma-separated list of bean IDs.

Defining dates and times

The initial times of the triggers used in the simple scheduled route policy are specified using the java.util.Date type.The most flexible way to define a Date instance is through the java.util.GregorianCalendar class. Use the convenient constructors and methods of the GregorianCalendar class to define a date and then obtain a Date instance by calling GregorianCalendar.getTime().
For example, to define the time and date for January 1, 2011 at noon, call a GregorianCalendar constructor as follows:
// Java
import java.util.GregorianCalendar;
import java.util.Calendar;
...
GregorianCalendar gc = new GregorianCalendar(
    2011,
    Calendar.JANUARY,
    1,
    12,  // hourOfDay
    0,   // minutes
    0    // seconds
);

java.util.Date triggerDate = gc.getTime();
The GregorianCalendar class also supports the definition of times in different time zones. By default, it uses the local time zone on your computer.

Graceful shutdown

When you configure a simple scheduled route policy to stop a route, the route stopping algorithm is automatically integrated with the graceful shutdown procedure (see Section 2.9, “Controlling Start-Up and Shutdown of Routes”). This means that the task waits until the current exchange has finished processing before shutting down the route. You can set a timeout, however, that forces the route to stop after the specified time, irrespective of whether or not the route has finished processing the exchange.

Logging Inflight Exchanges on Timeout

If a graceful shutdown fails to shutdown cleanly within the given timeout period, then Apache Camel performs more aggressive shut down. It forces routes, threadpools etc to shutdown.
After the timeout, Apache Camel logs information about the current inflight exchanges. It logs the origin of the exchange and current route of exchange.
For example, the log below shows that there is one inflight exchange, that origins from route1 and is currently on the same route1 at the delay1 node.
During graceful shutdown, If you enable the DEBUG logging level on org.apache.camel.impl.DefaultShutdownStrategy, then it logs the same inflight exchange information.
2015-01-12 13:23:23,656 [- ShutdownTask] INFO DefaultShutdownStrategy - There are 1 inflight exchanges:
InflightExchange: [exchangeId=ID-davsclaus-air-62213-1421065401253-0-3, fromRouteId=route1, routeId=route1, nodeId=delay1, elapsed=2007, duration=2017]
If you do not want to see these logs, you can turn this off by setting the option logInflightExchangesOnTimeout to false.
  context.getShutdownStrategegy().setLogInflightExchangesOnTimeout(false);

Scheduling tasks

You can use a simple scheduled route policy to define one or more of the following scheduling tasks:

Starting a route

The following table lists the parameters for scheduling one or more route starts.
ParameterTypeDefaultDescription
routeStartDate java.util.Date None Specifies the date and time when the route is started for the first time.
routeStartRepeatCount int 0 When set to a non-zero value, specifies how many times the route should be started.
routeStartRepeatInterval long 0 Specifies the time interval between starts, in units of milliseconds.

Stopping a route

The following table lists the parameters for scheduling one or more route stops.
ParameterTypeDefaultDescription
routeStopDate java.util.Date None Specifies the date and time when the route is stopped for the first time.
routeStopRepeatCount int 0 When set to a non-zero value, specifies how many times the route should be stopped.
routeStopRepeatInterval long 0 Specifies the time interval between stops, in units of milliseconds.
routeStopGracePeriod int 10000 Specifies how long to wait for the current exchange to finish processing (grace period) before forcibly stopping the route. Set to 0 for an infinite grace period.
routeStopTimeUnit long TimeUnit.MILLISECONDS Specifies the time unit of the grace period.

Suspending a route

The following table lists the parameters for scheduling the suspension of a route one or more times.
ParameterTypeDefaultDescription
routeSuspendDate java.util.Date None Specifies the date and time when the route is suspended for the first time.
routeSuspendRepeatCount int 0When set to a non-zero value, specifies how many times the route should be suspended.
routeSuspendRepeatInterval long 0Specifies the time interval between suspends, in units of milliseconds.

Resuming a route

The following table lists the parameters for scheduling the resumption of a route one or more times.
ParameterTypeDefaultDescription
routeResumeDate java.util.Date None Specifies the date and time when the route is resumed for the first time.
routeResumeRepeatCount int 0When set to a non-zero value, specifies how many times the route should be resumed.
routeResumeRepeatInterval long 0Specifies the time interval between resumes, in units of milliseconds.

2.10.3. Cron Scheduled Route Policy

Overview

The cron scheduled route policy is a route policy that enables you to start, stop, suspend, and resume routes, where the timing of these events is specified using cron expressions. To define a cron scheduled route policy, create an instance of the following class:
org.apache.camel.routepolicy.quartz.CronScheduledRoutePolicy

Dependency

The simple scheduled route policy depends on the Quartz component, camel-quartz. For example, if you are using Maven as your build system, you would need to add a dependency on the camel-quartz artifact.

Java DSL example

Example 2.9, “Java DSL Example of a Cron Scheduled Route” shows how to schedule a route to start up using the Java DSL. The policy is configured with the cron expression, */3 * * * * ?, which triggers a start event every 3 seconds.
In Java DSL, you attach the route policy to the route by calling the routePolicy() DSL command in the route.

Example 2.9. Java DSL Example of a Cron Scheduled Route

// Java
CronScheduledRoutePolicy policy = new CronScheduledRoutePolicy();
policy.setRouteStartTime("*/3 * * * * ?");
                
from("direct:start")
    .routeId("test")
    .routePolicy(policy)
    .to("mock:success");;
Note
You can specify multiple policies on the route by calling routePolicy() with multiple arguments.

XML DSL example

Example 2.10, “XML DSL Example of a Cron Scheduled Route”shows how to schedule a route to start up using the XML DSL.
In XML DSL, you attach the route policy to the route by setting the routePolicyRef attribute on the route element.

Example 2.10. XML DSL Example of a Cron Scheduled Route

<bean id="date" class="org.apache.camel.routepolicy.quartz.SimpleDate"/>

<bean id="startPolicy" class="org.apache.camel.routepolicy.quartz.CronScheduledRoutePolicy">
    <property name="routeStartTime" value="*/3 * * * * ?"/>
</bean>
    
<camelContext xmlns="http://camel.apache.org/schema/spring">
    <route id="testRoute" routePolicyRef="startPolicy">
        <from uri="direct:start"/>
        <to uri="mock:success"/>
    </route>
</camelContext>
Note
You can specify multiple policies on the route by setting the value of routePolicyRef as a comma-separated list of bean IDs.

Defining cron expressions

The cron expression syntax has its origins in the UNIX cron utility, which schedules jobs to run in the background on a UNIX system. A cron expression is effectively a syntax for wildcarding dates and times that enables you to specify either a single event or multiple events that recur periodically.
A cron expression consists of 6 or 7 fields in the following order:
Seconds Minutes Hours DayOfMonth Month DayOfWeek [Year]
The Year field is optional and usually omitted, unless you want to define an event that occurs once and once only. Each field consists of a mixture of literals and special characters. For example, the following cron expression specifies an event that fires once every day at midnight:
0 0 24 * * ?
The * character is a wildcard that matches every value of a field. Hence, the preceding expression matches every day of every month. The ? character is a dummy placeholder that means ignore this field. It always appears either in the DayOfMonth field or in the DayOfWeek field, because it is not logically consistent to specify both of these fields at the same time. For example, if you want to schedule an event that fires once a day, but only from Monday to Friday, use the following cron expression:
0 0 24 ? * MON-FRI
Where the hyphen character specifies a range, MON-FRI. You can also use the forward slash character, /, to specify increments. For example, to specify that an event fires every 5 minutes, use the following cron expression:
0 0/5 * * * ?
For a full explanation of the cron expression syntax, see the Wikipedia article on CRON expressions.

Scheduling tasks

You can use a cron scheduled route policy to define one or more of the following scheduling tasks:

Starting a route

The following table lists the parameters for scheduling one or more route starts.
ParameterTypeDefaultDescription
routeStartString String None Specifies a cron expression that triggers one or more route start events.

Stopping a route

The following table lists the parameters for scheduling one or more route stops.
ParameterTypeDefaultDescription
routeStopTime String None Specifies a cron expression that triggers one or more route stop events.
routeStopGracePeriod int 10000 Specifies how long to wait for the current exchange to finish processing (grace period) before forcibly stopping the route. Set to 0 for an infinite grace period.
routeStopTimeUnit long TimeUnit.MILLISECONDS Specifies the time unit of the grace period.

Suspending a route

The following table lists the parameters for scheduling the suspension of a route one or more times.
ParameterTypeDefaultDescription
routeSuspendTime String None Specifies a cron expression that triggers one or more route suspend events.

Resuming a route

The following table lists the parameters for scheduling the resumption of a route one or more times.
ParameterTypeDefaultDescription
routeResumeTime String None Specifies a cron expression that triggers one or more route resume events.

2.10.4. Route Policy Factory

Using Route Policy Factory

Available as of Camel 2.14
If you want to use a route policy for every route, you can use a org.apache.camel.spi.RoutePolicyFactory as a factory for creating a RoutePolicy instance for each route. This can be used when you want to use the same kind of route policy for every route. Then you need to only configure the factory once, and every route created will have the policy assigned.
There is API on CamelContext to add a factory, as shown below:
context.addRoutePolicyFactory(new MyRoutePolicyFactory());
From XML DSL you only define a <bean> with the factory
<bean id="myRoutePolicyFactory" class="com.foo.MyRoutePolicyFactory"/>
The factory contains the createRoutePolicy method for creating route policies.
/**
 * Creates a new {@link org.apache.camel.spi.RoutePolicy} which will be assigned to the given route.
 *
 * @param camelContext the camel context
 * @param routeId      the route id
 * @param route        the route definition
 * @return the created {@link org.apache.camel.spi.RoutePolicy}, or <tt>null</tt> to not use a policy for this route
 */
RoutePolicy createRoutePolicy(CamelContext camelContext, String routeId, RouteDefinition route);
Note you can have as many route policy factories as you want. Just call the addRoutePolicyFactory again, or declare the other factories as <bean> in XML.