You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by bv...@apache.org on 2013/09/20 19:49:20 UTC
git commit: CAMEL-6773: The scheduled route policies of camel-quartz2
now support clustered jobs (like as it's done for camel-quartz through
CAMEL-6686). Also polished the codebase a bit.
Updated Branches:
refs/heads/master 0e69a1c0b -> 07bc39c29
CAMEL-6773: The scheduled route policies of camel-quartz2 now support clustered jobs (like as it's done for camel-quartz through CAMEL-6686). Also polished the codebase a bit.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/07bc39c2
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/07bc39c2
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/07bc39c2
Branch: refs/heads/master
Commit: 07bc39c29c6649899f8f375ba02c6eabf97a0564
Parents: 0e69a1c
Author: Babak Vahdat <bv...@apache.org>
Authored: Fri Sep 20 19:49:14 2013 +0200
Committer: Babak Vahdat <bv...@apache.org>
Committed: Fri Sep 20 19:49:14 2013 +0200
----------------------------------------------------------------------
.../component/quartz2/QuartzComponent.java | 7 ++
.../quartz2/CronScheduledRoutePolicy.java | 2 +-
.../quartz2/ScheduledRoutePolicy.java | 17 ++++
.../quartz2/SimpleScheduledRoutePolicy.java | 2 +-
...ringQuartzPersistentStoreRestartAppTest.java | 6 +-
...ngQuartzPersistentStoreClusteredAppTest.java | 85 ++++++++++++++++++++
.../SpringQuartzPersistentStoreRestartTest.xml | 3 +-
.../quartz2/SpringQuartzPersistentStoreTest.xml | 3 +-
.../quartz2/SpringQuartzClusteredAppOneTest.xml | 75 +++++++++++++++++
.../quartz2/SpringQuartzClusteredAppTwoTest.xml | 75 +++++++++++++++++
10 files changed, 267 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/07bc39c2/components/camel-quartz2/src/main/java/org/apache/camel/component/quartz2/QuartzComponent.java
----------------------------------------------------------------------
diff --git a/components/camel-quartz2/src/main/java/org/apache/camel/component/quartz2/QuartzComponent.java b/components/camel-quartz2/src/main/java/org/apache/camel/component/quartz2/QuartzComponent.java
index 65d98fc..8215ec2 100644
--- a/components/camel-quartz2/src/main/java/org/apache/camel/component/quartz2/QuartzComponent.java
+++ b/components/camel-quartz2/src/main/java/org/apache/camel/component/quartz2/QuartzComponent.java
@@ -154,6 +154,13 @@ public class QuartzComponent extends DefaultComponent implements StartupListener
return answer;
}
+ /**
+ * Is the quartz scheduler clustered?
+ */
+ public boolean isClustered() throws SchedulerException {
+ return getScheduler().getMetaData().isJobStoreClustered();
+ }
+
private Properties loadProperties() throws SchedulerException {
Properties answer = getProperties();
if (answer == null && getPropertiesFile() != null) {
http://git-wip-us.apache.org/repos/asf/camel/blob/07bc39c2/components/camel-quartz2/src/main/java/org/apache/camel/routepolicy/quartz2/CronScheduledRoutePolicy.java
----------------------------------------------------------------------
diff --git a/components/camel-quartz2/src/main/java/org/apache/camel/routepolicy/quartz2/CronScheduledRoutePolicy.java b/components/camel-quartz2/src/main/java/org/apache/camel/routepolicy/quartz2/CronScheduledRoutePolicy.java
index 19ecef4..205f113 100644
--- a/components/camel-quartz2/src/main/java/org/apache/camel/routepolicy/quartz2/CronScheduledRoutePolicy.java
+++ b/components/camel-quartz2/src/main/java/org/apache/camel/routepolicy/quartz2/CronScheduledRoutePolicy.java
@@ -57,7 +57,7 @@ public class CronScheduledRoutePolicy extends ScheduledRoutePolicy implements Sc
// validate time options has been configured
if ((getRouteStartTime() == null) && (getRouteStopTime() == null) && (getRouteSuspendTime() == null) && (getRouteResumeTime() == null)) {
- throw new IllegalArgumentException("Scheduled Route Policy for route {} has no stop/stop/suspend/resume times specified");
+ throw new IllegalArgumentException("Scheduled Route Policy for route {} has no start/stop/suspend/resume times specified");
}
registerRouteToScheduledRouteDetails(route);
http://git-wip-us.apache.org/repos/asf/camel/blob/07bc39c2/components/camel-quartz2/src/main/java/org/apache/camel/routepolicy/quartz2/ScheduledRoutePolicy.java
----------------------------------------------------------------------
diff --git a/components/camel-quartz2/src/main/java/org/apache/camel/routepolicy/quartz2/ScheduledRoutePolicy.java b/components/camel-quartz2/src/main/java/org/apache/camel/routepolicy/quartz2/ScheduledRoutePolicy.java
index 45db16e..788b7c1 100644
--- a/components/camel-quartz2/src/main/java/org/apache/camel/routepolicy/quartz2/ScheduledRoutePolicy.java
+++ b/components/camel-quartz2/src/main/java/org/apache/camel/routepolicy/quartz2/ScheduledRoutePolicy.java
@@ -22,6 +22,7 @@ import java.util.concurrent.TimeUnit;
import org.apache.camel.Route;
import org.apache.camel.ServiceStatus;
+import org.apache.camel.component.quartz2.QuartzComponent;
import org.apache.camel.impl.RoutePolicySupport;
import org.apache.camel.util.ServiceHelper;
import org.quartz.JobBuilder;
@@ -96,6 +97,22 @@ public abstract class ScheduledRoutePolicy extends RoutePolicySupport implements
updateScheduledRouteDetails(action, jobDetail, trigger, route);
loadCallbackDataIntoSchedulerContext(jobDetail, action, route);
+
+ boolean isClustered = route.getRouteContext().getCamelContext().getComponent("quartz2", QuartzComponent.class).isClustered();
+ if (isClustered) {
+ // check to see if the same job has already been setup through another node of the cluster
+ JobDetail existingJobDetail = getScheduler().getJobDetail(jobDetail.getKey());
+ if (jobDetail.equals(existingJobDetail)) {
+ if (LOG.isInfoEnabled()) {
+ LOG.info("Skipping to schedule the job: {} for action: {} on route {} as the job: {} already existing!",
+ new Object[] {jobDetail.getKey(), action, route.getId(), existingJobDetail.getKey()});
+ }
+
+ // skip scheduling the same job as one is already available for the same route and action
+ return;
+ }
+ }
+
getScheduler().scheduleJob(jobDetail, trigger);
if (LOG.isInfoEnabled()) {
http://git-wip-us.apache.org/repos/asf/camel/blob/07bc39c2/components/camel-quartz2/src/main/java/org/apache/camel/routepolicy/quartz2/SimpleScheduledRoutePolicy.java
----------------------------------------------------------------------
diff --git a/components/camel-quartz2/src/main/java/org/apache/camel/routepolicy/quartz2/SimpleScheduledRoutePolicy.java b/components/camel-quartz2/src/main/java/org/apache/camel/routepolicy/quartz2/SimpleScheduledRoutePolicy.java
index 2e84d4a..95f135e 100644
--- a/components/camel-quartz2/src/main/java/org/apache/camel/routepolicy/quartz2/SimpleScheduledRoutePolicy.java
+++ b/components/camel-quartz2/src/main/java/org/apache/camel/routepolicy/quartz2/SimpleScheduledRoutePolicy.java
@@ -66,7 +66,7 @@ public class SimpleScheduledRoutePolicy extends ScheduledRoutePolicy {
// validate time options has been configured
if ((getRouteStartDate() == null) && (getRouteStopDate() == null) && (getRouteSuspendDate() == null) && (getRouteResumeDate() == null)) {
- throw new IllegalArgumentException("Scheduled Route Policy for route {} has no stop/stop/suspend/resume times specified");
+ throw new IllegalArgumentException("Scheduled Route Policy for route {} has no start/stop/suspend/resume times specified");
}
registerRouteToScheduledRouteDetails(route);
http://git-wip-us.apache.org/repos/asf/camel/blob/07bc39c2/components/camel-quartz2/src/test/java/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartAppTest.java
----------------------------------------------------------------------
diff --git a/components/camel-quartz2/src/test/java/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartAppTest.java b/components/camel-quartz2/src/test/java/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartAppTest.java
index f493b7a..18af3a0 100644
--- a/components/camel-quartz2/src/test/java/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartAppTest.java
+++ b/components/camel-quartz2/src/test/java/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartAppTest.java
@@ -71,9 +71,11 @@ public class SpringQuartzPersistentStoreRestartAppTest extends TestSupport {
app2.stop();
- // we're done so let's properly close the application contexts
- app.close();
+ // we're done so let's properly close the application contexts, but stop
+ // the second app before the first one so that the quartz scheduler running
+ // inside it can properly be shutdown
app2.close();
+ app.close();
}
}
http://git-wip-us.apache.org/repos/asf/camel/blob/07bc39c2/components/camel-quartz2/src/test/java/org/apache/camel/routepolicy/quartz2/SpringQuartzPersistentStoreClusteredAppTest.java
----------------------------------------------------------------------
diff --git a/components/camel-quartz2/src/test/java/org/apache/camel/routepolicy/quartz2/SpringQuartzPersistentStoreClusteredAppTest.java b/components/camel-quartz2/src/test/java/org/apache/camel/routepolicy/quartz2/SpringQuartzPersistentStoreClusteredAppTest.java
new file mode 100644
index 0000000..86f9cb5
--- /dev/null
+++ b/components/camel-quartz2/src/test/java/org/apache/camel/routepolicy/quartz2/SpringQuartzPersistentStoreClusteredAppTest.java
@@ -0,0 +1,85 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.routepolicy.quartz2;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelExecutionException;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.component.direct.DirectConsumerNotAvailableException;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.junit4.TestSupport;
+
+import org.junit.Test;
+
+import org.springframework.context.support.AbstractXmlApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+/**
+ * @version
+ */
+public class SpringQuartzPersistentStoreClusteredAppTest extends TestSupport {
+
+ @Test
+ public void testQuartzPersistentStoreClusteredApp() throws Exception {
+ // boot up the first clustered app which also launches an embedded database
+ AbstractXmlApplicationContext app = new ClassPathXmlApplicationContext("org/apache/camel/routepolicy/quartz2/SpringQuartzClusteredAppOneTest.xml");
+ app.start();
+
+ // and now the second one
+ AbstractXmlApplicationContext app2 = new ClassPathXmlApplicationContext("org/apache/camel/routepolicy/quartz2/SpringQuartzClusteredAppTwoTest.xml");
+ app2.start();
+
+ CamelContext camel = app.getBean("camelContext", CamelContext.class);
+ assertNotNull(camel);
+
+ MockEndpoint mock = camel.getEndpoint("mock:result", MockEndpoint.class);
+ mock.expectedMessageCount(1);
+ mock.expectedBodiesReceived("clustering pings!");
+
+ // wait a bit to make sure the route has been properly started through
+ // the given route policy
+ Thread.sleep(5000);
+
+ app.getBean("template", ProducerTemplate.class).sendBody("direct:start", "clustering");
+
+ mock.assertIsSatisfied();
+
+ CamelContext camel2 = app2.getBean("camelContext", CamelContext.class);
+ assertNotNull(camel2);
+
+ MockEndpoint mock2 = camel2.getEndpoint("mock:result", MockEndpoint.class);
+ mock.expectedMessageCount(0);
+
+ // expect no consumer being started as the seconds app is expected to
+ // run in standby modus
+ try {
+ app2.getBean("template", ProducerTemplate.class).sendBody("direct:start", "clustering");
+ fail("Should have thrown exception");
+ } catch (CamelExecutionException cee) {
+ assertIsInstanceOf(DirectConsumerNotAvailableException.class, cee.getCause());
+ }
+
+ mock2.assertIsSatisfied();
+
+ // we're done so let's properly close the application contexts, but stop
+ // the second app before the first one so that the quartz scheduler running
+ // inside it can properly be shutdown
+ app2.close();
+ app.close();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/07bc39c2/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartTest.xml
----------------------------------------------------------------------
diff --git a/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartTest.xml b/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartTest.xml
index 26f18fd..6f498aa 100644
--- a/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartTest.xml
+++ b/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartTest.xml
@@ -31,10 +31,9 @@
<bean id="quartz" class="org.apache.camel.component.quartz2.QuartzComponent">
<property name="scheduler" ref="scheduler"/>
- <property name="autoStartScheduler" value="true"/>
</bean>
- <!-- jdbc:initialize-database must come before this so the job store exists -->
+ <!-- jdbc:embedded-database must come before this so the job store exists -->
<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="dataSource" ref="camel_quartz"/>
<property name="autoStartup" value="false"/>
http://git-wip-us.apache.org/repos/asf/camel/blob/07bc39c2/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreTest.xml
----------------------------------------------------------------------
diff --git a/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreTest.xml b/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreTest.xml
index 3b055fd..851f3c5 100644
--- a/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreTest.xml
+++ b/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreTest.xml
@@ -31,10 +31,9 @@
<bean id="quartz" class="org.apache.camel.component.quartz2.QuartzComponent">
<property name="scheduler" ref="scheduler"/>
- <property name="autoStartScheduler" value="true"/>
</bean>
- <!-- jdbc:initialize-database must come before this so the job store exists -->
+ <!-- jdbc:embedded-database must come before this so the job store exists -->
<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="dataSource" ref="camel_quartz"/>
<property name="autoStartup" value="false"/>
http://git-wip-us.apache.org/repos/asf/camel/blob/07bc39c2/components/camel-quartz2/src/test/resources/org/apache/camel/routepolicy/quartz2/SpringQuartzClusteredAppOneTest.xml
----------------------------------------------------------------------
diff --git a/components/camel-quartz2/src/test/resources/org/apache/camel/routepolicy/quartz2/SpringQuartzClusteredAppOneTest.xml b/components/camel-quartz2/src/test/resources/org/apache/camel/routepolicy/quartz2/SpringQuartzClusteredAppOneTest.xml
new file mode 100644
index 0000000..991523d
--- /dev/null
+++ b/components/camel-quartz2/src/test/resources/org/apache/camel/routepolicy/quartz2/SpringQuartzClusteredAppOneTest.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:jdbc="http://www.springframework.org/schema/jdbc"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
+ http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
+ ">
+
+ <!-- the persistent store for quartz -->
+ <jdbc:embedded-database id="camel_quartz" type="DERBY">
+ <jdbc:script location="classpath:tables_derby.sql"/>
+ </jdbc:embedded-database>
+
+ <bean id="quartz2" class="org.apache.camel.component.quartz2.QuartzComponent">
+ <property name="scheduler" ref="scheduler"/>
+ </bean>
+
+ <!-- jdbc:embedded-database must come before this so the job store exists -->
+ <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
+ <property name="dataSource" ref="camel_quartz"/>
+ <property name="autoStartup" value="false"/>
+ <!-- let Camel start -->
+ <property name="schedulerContextAsMap">
+ <!-- hook Camel into Quartz -->
+ <map>
+ <entry key="CamelQuartzCamelContext" value-ref="camelContext"/>
+ </map>
+ </property>
+ <property name="quartzProperties">
+ <props>
+ <prop key="org.quartz.scheduler.instanceName">myscheduler</prop>
+ <prop key="org.quartz.scheduler.instanceId">AUTO</prop>
+ <prop key="org.quartz.scheduler.skipUpdateCheck">true</prop>
+ <prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.StdJDBCDelegate</prop>
+ <prop key="org.quartz.jobStore.isClustered">true</prop>
+ <prop key="org.quartz.jobStore.clusterCheckinInterval">1000</prop>
+ </props>
+ </property>
+ </bean>
+
+ <bean id="startPolicy" class="org.apache.camel.routepolicy.quartz2.CronScheduledRoutePolicy">
+ <property name="routeStartTime" value="0/3 * * * * ?" />
+ </bean>
+
+ <camelContext id="camelContext" managementNamePattern="#name#-#counter#" xmlns="http://camel.apache.org/schema/spring">
+ <template id="template" />
+ <route id="myRoute" routePolicyRef="startPolicy" autoStartup="false">
+ <from uri="direct:start" />
+ <to uri="log:triggered" />
+ <transform>
+ <simple>${in.body} pings!</simple>
+ </transform>
+ <to uri="mock:result" />
+ </route>
+ </camelContext>
+
+</beans>
http://git-wip-us.apache.org/repos/asf/camel/blob/07bc39c2/components/camel-quartz2/src/test/resources/org/apache/camel/routepolicy/quartz2/SpringQuartzClusteredAppTwoTest.xml
----------------------------------------------------------------------
diff --git a/components/camel-quartz2/src/test/resources/org/apache/camel/routepolicy/quartz2/SpringQuartzClusteredAppTwoTest.xml b/components/camel-quartz2/src/test/resources/org/apache/camel/routepolicy/quartz2/SpringQuartzClusteredAppTwoTest.xml
new file mode 100644
index 0000000..3ccd7e3
--- /dev/null
+++ b/components/camel-quartz2/src/test/resources/org/apache/camel/routepolicy/quartz2/SpringQuartzClusteredAppTwoTest.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:jdbc="http://www.springframework.org/schema/jdbc"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
+ http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
+ ">
+
+ <!-- the persistent store for quartz -->
+ <jdbc:embedded-database id="camel_quartz" type="DERBY">
+ <!-- do not load script as database alreaady exists -->
+ </jdbc:embedded-database>
+
+ <bean id="quartz2" class="org.apache.camel.component.quartz2.QuartzComponent">
+ <property name="scheduler" ref="scheduler"/>
+ </bean>
+
+ <!-- jdbc:embedded-database must come before this so the job store exists -->
+ <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
+ <property name="dataSource" ref="camel_quartz"/>
+ <property name="autoStartup" value="false"/>
+ <!-- let Camel start -->
+ <property name="schedulerContextAsMap">
+ <!-- hook Camel into Quartz -->
+ <map>
+ <entry key="CamelQuartzCamelContext" value-ref="camelContext"/>
+ </map>
+ </property>
+ <property name="quartzProperties">
+ <props>
+ <prop key="org.quartz.scheduler.instanceName">myscheduler</prop>
+ <prop key="org.quartz.scheduler.instanceId">AUTO</prop>
+ <prop key="org.quartz.scheduler.skipUpdateCheck">true</prop>
+ <prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.StdJDBCDelegate</prop>
+ <prop key="org.quartz.jobStore.isClustered">true</prop>
+ <prop key="org.quartz.jobStore.clusterCheckinInterval">1000</prop>
+ </props>
+ </property>
+ </bean>
+
+ <bean id="startPolicy" class="org.apache.camel.routepolicy.quartz2.CronScheduledRoutePolicy">
+ <property name="routeStartTime" value="0/3 * * * * ?" />
+ </bean>
+
+ <camelContext id="camelContext" managementNamePattern="#name#-#counter#" xmlns="http://camel.apache.org/schema/spring">
+ <template id="template" />
+ <route id="myRoute" routePolicyRef="startPolicy" autoStartup="false">
+ <from uri="direct:start" />
+ <to uri="log:triggered" />
+ <transform>
+ <simple>${in.body} pongs!</simple>
+ </transform>
+ <to uri="mock:result" />
+ </route>
+ </camelContext>
+
+</beans>