You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ja...@apache.org on 2014/11/13 16:21:12 UTC
[2/4] camel git commit: CAMEL-7627 - Quartz/Quartz2 in cluster mode
doesn't apply changed trigger settings
CAMEL-7627 - Quartz/Quartz2 in cluster mode doesn't apply changed trigger settings
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/4134f18d
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/4134f18d
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/4134f18d
Branch: refs/heads/camel-2.14.x
Commit: 4134f18d42e1f2c6b318424960b7aa76054072d6
Parents: 4416b0f
Author: Jonathan Anstey <ja...@gmail.com>
Authored: Thu Nov 13 11:17:42 2014 -0330
Committer: Jonathan Anstey <ja...@gmail.com>
Committed: Thu Nov 13 11:18:37 2014 -0330
----------------------------------------------------------------------
.../camel/component/quartz/QuartzComponent.java | 15 +-
...sistentStoreRestartAppChangeOptionsTest.java | 161 ++++++++++++++++++
...StoreRestartAppChangeCronExpressionTest1.xml | 70 ++++++++
...StoreRestartAppChangeCronExpressionTest2.xml | 70 ++++++++
...sistentStoreRestartAppChangeOptionsTest1.xml | 70 ++++++++
...sistentStoreRestartAppChangeOptionsTest2.xml | 70 ++++++++
.../camel/component/quartz2/QuartzEndpoint.java | 51 ++++--
...sistentStoreRestartAppChangeOptionsTest.java | 164 +++++++++++++++++++
...StoreRestartAppChangeCronExpressionTest1.xml | 70 ++++++++
...StoreRestartAppChangeCronExpressionTest2.xml | 70 ++++++++
...sistentStoreRestartAppChangeOptionsTest1.xml | 70 ++++++++
...sistentStoreRestartAppChangeOptionsTest2.xml | 70 ++++++++
12 files changed, 933 insertions(+), 18 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/4134f18d/components/camel-quartz/src/main/java/org/apache/camel/component/quartz/QuartzComponent.java
----------------------------------------------------------------------
diff --git a/components/camel-quartz/src/main/java/org/apache/camel/component/quartz/QuartzComponent.java b/components/camel-quartz/src/main/java/org/apache/camel/component/quartz/QuartzComponent.java
index 99287e2..86e471a 100644
--- a/components/camel-quartz/src/main/java/org/apache/camel/component/quartz/QuartzComponent.java
+++ b/components/camel-quartz/src/main/java/org/apache/camel/component/quartz/QuartzComponent.java
@@ -290,13 +290,18 @@ public class QuartzComponent extends UriEndpointComponent implements StartupList
incrementJobCounter(getScheduler());
}
- private boolean hasTriggerChanged(Trigger oldTrigger, Trigger newTrigger) {
- if (oldTrigger instanceof CronTrigger && oldTrigger.equals(newTrigger)) {
- CronTrigger oldCron = (CronTrigger) oldTrigger;
+ private static boolean hasTriggerChanged(Trigger oldTrigger, Trigger newTrigger) {
+ if (newTrigger instanceof CronTrigger && oldTrigger instanceof CronTrigger) {
CronTrigger newCron = (CronTrigger) newTrigger;
- return !oldCron.getCronExpression().equals(newCron.getCronExpression());
+ CronTrigger oldCron = (CronTrigger) oldTrigger;
+ return !newCron.getCronExpression().equals(oldCron.getCronExpression());
+ } else if (newTrigger instanceof SimpleTrigger && oldTrigger instanceof SimpleTrigger) {
+ SimpleTrigger newSimple = (SimpleTrigger) newTrigger;
+ SimpleTrigger oldSimple = (SimpleTrigger) oldTrigger;
+ return newSimple.getRepeatInterval() != oldSimple.getRepeatInterval()
+ || newSimple.getRepeatCount() != oldSimple.getRepeatCount();
} else {
- return !newTrigger.equals(oldTrigger);
+ return !newTrigger.getClass().equals(oldTrigger.getClass()) || !newTrigger.equals(oldTrigger);
}
}
http://git-wip-us.apache.org/repos/asf/camel/blob/4134f18d/components/camel-quartz/src/test/java/org/apache/camel/component/quartz/SpringQuartzPersistentStoreRestartAppChangeOptionsTest.java
----------------------------------------------------------------------
diff --git a/components/camel-quartz/src/test/java/org/apache/camel/component/quartz/SpringQuartzPersistentStoreRestartAppChangeOptionsTest.java b/components/camel-quartz/src/test/java/org/apache/camel/component/quartz/SpringQuartzPersistentStoreRestartAppChangeOptionsTest.java
new file mode 100644
index 0000000..8ec91fd
--- /dev/null
+++ b/components/camel-quartz/src/test/java/org/apache/camel/component/quartz/SpringQuartzPersistentStoreRestartAppChangeOptionsTest.java
@@ -0,0 +1,161 @@
+/**
+ * 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.component.quartz;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.test.junit4.TestSupport;
+import org.apache.camel.util.IOHelper;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.quartz.CronTrigger;
+import org.quartz.Scheduler;
+import org.quartz.SchedulerException;
+import org.quartz.SimpleTrigger;
+import org.quartz.Trigger;
+import org.springframework.context.support.AbstractXmlApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+public class SpringQuartzPersistentStoreRestartAppChangeOptionsTest extends TestSupport {
+
+ private AbstractXmlApplicationContext db;
+ private AbstractXmlApplicationContext app;
+ private AbstractXmlApplicationContext app2;
+
+ @Before
+ public void prepareDB() {
+ // boot up the database the two invocations are going to share inside a clustered quartz setup
+ db = new ClassPathXmlApplicationContext("org/apache/camel/component/quartz/SpringQuartzConsumerClusteredAppDatabase.xml");
+ db.start();
+ }
+
+ @After
+ public void closeApps() {
+ // we're done so let's properly close the application contexts, but close
+ // the second app before the first one so that the quartz scheduler running
+ // inside it can be properly shutdown
+ IOHelper.close(app2, app, db);
+ }
+
+
+ @Test
+ public void testRestartAppChangeCronExpression() throws Exception {
+
+ // Test creates application context twice with different cron expressions in configuration xml.
+ // Both times it retrieves back the cron expression, accessing it via trigger (so, using value stored in DB).
+ // After that it asserts that two cron expressions are not equal.
+
+ // load spring app
+ app = new ClassPathXmlApplicationContext("org/apache/camel/component/quartz/SpringQuartzPersistentStoreRestartAppChangeCronExpressionTest1.xml");
+ app.start();
+ CamelContext camel = app.getBean("camelContext", CamelContext.class);
+ assertNotNull(camel);
+ String cronExpression = ((CronTrigger) getTrigger(camel, "quartzRoute")).getCronExpression();
+ app.stop();
+
+ log.info("Restarting ...");
+ log.info("Restarting ...");
+ log.info("Restarting ...");
+
+ // load spring app
+ app2 = new ClassPathXmlApplicationContext("org/apache/camel/component/quartz/SpringQuartzPersistentStoreRestartAppChangeCronExpressionTest2.xml");
+ app2.start();
+ CamelContext camel2 = app2.getBean("camelContext", CamelContext.class);
+ assertNotNull(camel2);
+ String cronExpression2 = ((CronTrigger) getTrigger(camel2, "quartzRoute")).getCronExpression();
+ app2.stop();
+
+ assertNotEquals(cronExpression, cronExpression2);
+ }
+
+ @Test
+ public void testRestartAppChangeTriggerOptions() throws Exception {
+
+ // Test creates application context twice with different simple trigger options in configuration xml.
+ // Both times it retrieves back the option, accessing it via trigger (so, using value stored in DB).
+ // After that it asserts that two options are not equal.
+
+ // load spring app
+ AbstractXmlApplicationContext app = new ClassPathXmlApplicationContext("org/apache/camel/component/quartz/SpringQuartzPersistentStoreRestartAppChangeOptionsTest1.xml");
+ app.start();
+ CamelContext camel = app.getBean("camelContext", CamelContext.class);
+ assertNotNull(camel);
+ SimpleTrigger trigger = (SimpleTrigger) getTrigger(camel, "quartzRoute");
+ long repeatInterval = trigger.getRepeatInterval();
+ app.stop();
+
+ log.info("Restarting ...");
+ log.info("Restarting ...");
+ log.info("Restarting ...");
+
+ // load spring app
+ AbstractXmlApplicationContext app2 = new ClassPathXmlApplicationContext("org/apache/camel/component/quartz/SpringQuartzPersistentStoreRestartAppChangeOptionsTest2.xml");
+ app2.start();
+ CamelContext camel2 = app2.getBean("camelContext", CamelContext.class);
+ assertNotNull(camel2);
+ SimpleTrigger trigger2 = (SimpleTrigger) getTrigger(camel2, "quartzRoute");
+ long repeatInterval2 = trigger2.getRepeatInterval();
+ app2.stop();
+
+ // we're done so let's properly close the application contexts, but close
+ // the second app before the first one so that the quartz scheduler running
+ // inside it can be properly shutdown
+ IOHelper.close(app2, app);
+
+ assertNotEquals(repeatInterval, repeatInterval2);
+ }
+
+ @Test
+ public void testRestartAppChangeTriggerType() throws Exception {
+
+ // Test creates application context twice with different simple trigger options in configuration xml.
+ // Both times it retrieves back the option, accessing it via trigger (so, using value stored in DB).
+ // After that it asserts that two options are not equal.
+
+ // load spring app
+ app = new ClassPathXmlApplicationContext("org/apache/camel/component/quartz/SpringQuartzPersistentStoreRestartAppChangeCronExpressionTest1.xml");
+ app.start();
+ CamelContext camel = app.getBean("camelContext", CamelContext.class);
+ assertNotNull(camel);
+ assertTrue(getTrigger(camel, "quartzRoute") instanceof CronTrigger);
+ app.stop();
+
+ log.info("Restarting ...");
+ log.info("Restarting ...");
+ log.info("Restarting ...");
+
+ // load spring app
+ AbstractXmlApplicationContext app2 = new ClassPathXmlApplicationContext("org/apache/camel/component/quartz/SpringQuartzPersistentStoreRestartAppChangeOptionsTest2.xml");
+ app2.start();
+ CamelContext camel2 = app2.getBean("camelContext", CamelContext.class);
+ assertNotNull(camel2);
+ assertTrue(getTrigger(camel2, "quartzRoute") instanceof SimpleTrigger);
+ app2.stop();
+
+ // we're done so let's properly close the application contexts, but close
+ // the second app before the first one so that the quartz scheduler running
+ // inside it can be properly shutdown
+ IOHelper.close(app2, app);
+ }
+
+ private Trigger getTrigger(CamelContext camel, String routeId) throws SchedulerException {
+ QuartzEndpoint endpoint = (QuartzEndpoint) (camel.getRoute(routeId).getEndpoint());
+ QuartzComponent component = endpoint.getComponent();
+ Scheduler scheduler = component.getScheduler();
+ return scheduler.getTrigger(endpoint.getTrigger().getName(), endpoint.getTrigger().getGroup());
+ }
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/4134f18d/components/camel-quartz/src/test/resources/org/apache/camel/component/quartz/SpringQuartzPersistentStoreRestartAppChangeCronExpressionTest1.xml
----------------------------------------------------------------------
diff --git a/components/camel-quartz/src/test/resources/org/apache/camel/component/quartz/SpringQuartzPersistentStoreRestartAppChangeCronExpressionTest1.xml b/components/camel-quartz/src/test/resources/org/apache/camel/component/quartz/SpringQuartzPersistentStoreRestartAppChangeCronExpressionTest1.xml
new file mode 100644
index 0000000..94e1e02
--- /dev/null
+++ b/components/camel-quartz/src/test/resources/org/apache/camel/component/quartz/SpringQuartzPersistentStoreRestartAppChangeCronExpressionTest1.xml
@@ -0,0 +1,70 @@
+<?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">
+
+ <bean id="quartzDataSource" class="org.apache.commons.dbcp.BasicDataSource">
+ <property name="driverClassName" value="org.apache.derby.jdbc.EmbeddedDriver" />
+ <!-- refer the embedded database we setup inside SpringQuartzConsumerClusteredAppDatabase.xml -->
+ <property name="url" value="jdbc:derby:memory:quartz-db" />
+ <property name="username" value="sa" />
+ <property name="password" value="" />
+ </bean>
+
+ <bean id="quartzBean" class="org.apache.camel.component.quartz.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="quartzDataSource"/>
+ <property name="autoStartup" value="false"/>
+ <!-- let Camel start -->
+ <property name="schedulerContextAsMap">
+ <!-- hook Camel into Quartz -->
+ <map>
+ <entry key="CamelQuartzCamelContext-camelContext" 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.terracotta.quartz.skipUpdateCheck">true</prop>
+ <prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
+ <prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.StdJDBCDelegate</prop>
+ <prop key="org.quartz.jobStore.isClustered">true</prop>
+ </props>
+ </property>
+ </bean>
+
+ <camelContext id="camelContext" managementNamePattern="#name#" xmlns="http://camel.apache.org/schema/spring">
+ <route id="quartzRoute">
+ <from uri="quartzBean://app/test?cron=0+0/1+*+1/1+*+?+*"/>
+ <to uri="log:trigger"/>
+ <to uri="mock:result"/>
+ </route>
+ </camelContext>
+
+</beans>
http://git-wip-us.apache.org/repos/asf/camel/blob/4134f18d/components/camel-quartz/src/test/resources/org/apache/camel/component/quartz/SpringQuartzPersistentStoreRestartAppChangeCronExpressionTest2.xml
----------------------------------------------------------------------
diff --git a/components/camel-quartz/src/test/resources/org/apache/camel/component/quartz/SpringQuartzPersistentStoreRestartAppChangeCronExpressionTest2.xml b/components/camel-quartz/src/test/resources/org/apache/camel/component/quartz/SpringQuartzPersistentStoreRestartAppChangeCronExpressionTest2.xml
new file mode 100644
index 0000000..e782d53
--- /dev/null
+++ b/components/camel-quartz/src/test/resources/org/apache/camel/component/quartz/SpringQuartzPersistentStoreRestartAppChangeCronExpressionTest2.xml
@@ -0,0 +1,70 @@
+<?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">
+
+ <bean id="quartzDataSource" class="org.apache.commons.dbcp.BasicDataSource">
+ <property name="driverClassName" value="org.apache.derby.jdbc.EmbeddedDriver" />
+ <!-- refer the embedded database we setup inside SpringQuartzConsumerClusteredAppDatabase.xml -->
+ <property name="url" value="jdbc:derby:memory:quartz-db" />
+ <property name="username" value="sa" />
+ <property name="password" value="" />
+ </bean>
+
+ <bean id="quartzBean" class="org.apache.camel.component.quartz.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="quartzDataSource"/>
+ <property name="autoStartup" value="false"/>
+ <!-- let Camel start -->
+ <property name="schedulerContextAsMap">
+ <!-- hook Camel into Quartz -->
+ <map>
+ <entry key="CamelQuartzCamelContext-camelContext" 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.terracotta.quartz.skipUpdateCheck">true</prop>
+ <prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
+ <prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.StdJDBCDelegate</prop>
+ <prop key="org.quartz.jobStore.isClustered">true</prop>
+ </props>
+ </property>
+ </bean>
+
+ <camelContext id="camelContext" managementNamePattern="#name#" xmlns="http://camel.apache.org/schema/spring">
+ <route id="quartzRoute">
+ <from uri="quartzBean://app/test?cron=0+0/2+*+1/1+*+?+*"/>
+ <to uri="log:trigger"/>
+ <to uri="mock:result"/>
+ </route>
+ </camelContext>
+
+</beans>
http://git-wip-us.apache.org/repos/asf/camel/blob/4134f18d/components/camel-quartz/src/test/resources/org/apache/camel/component/quartz/SpringQuartzPersistentStoreRestartAppChangeOptionsTest1.xml
----------------------------------------------------------------------
diff --git a/components/camel-quartz/src/test/resources/org/apache/camel/component/quartz/SpringQuartzPersistentStoreRestartAppChangeOptionsTest1.xml b/components/camel-quartz/src/test/resources/org/apache/camel/component/quartz/SpringQuartzPersistentStoreRestartAppChangeOptionsTest1.xml
new file mode 100644
index 0000000..3610042
--- /dev/null
+++ b/components/camel-quartz/src/test/resources/org/apache/camel/component/quartz/SpringQuartzPersistentStoreRestartAppChangeOptionsTest1.xml
@@ -0,0 +1,70 @@
+<?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">
+
+ <bean id="quartzDataSource" class="org.apache.commons.dbcp.BasicDataSource">
+ <property name="driverClassName" value="org.apache.derby.jdbc.EmbeddedDriver" />
+ <!-- refer the embedded database we setup inside SpringQuartzConsumerClusteredAppDatabase.xml -->
+ <property name="url" value="jdbc:derby:memory:quartz-db" />
+ <property name="username" value="sa" />
+ <property name="password" value="" />
+ </bean>
+
+ <bean id="quartzBean" class="org.apache.camel.component.quartz.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="quartzDataSource"/>
+ <property name="autoStartup" value="false"/>
+ <!-- let Camel start -->
+ <property name="schedulerContextAsMap">
+ <!-- hook Camel into Quartz -->
+ <map>
+ <entry key="CamelQuartzCamelContext-camelContext" 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.terracotta.quartz.skipUpdateCheck">true</prop>
+ <prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
+ <prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.StdJDBCDelegate</prop>
+ <prop key="org.quartz.jobStore.isClustered">true</prop>
+ </props>
+ </property>
+ </bean>
+
+ <camelContext id="camelContext" managementNamePattern="#name#" xmlns="http://camel.apache.org/schema/spring">
+ <route id="quartzRoute">
+ <from uri="quartzBean://app/test?trigger.repeatInterval=10&trigger.repeatCount=1"/>
+ <to uri="log:trigger"/>
+ <to uri="mock:result"/>
+ </route>
+ </camelContext>
+
+</beans>
http://git-wip-us.apache.org/repos/asf/camel/blob/4134f18d/components/camel-quartz/src/test/resources/org/apache/camel/component/quartz/SpringQuartzPersistentStoreRestartAppChangeOptionsTest2.xml
----------------------------------------------------------------------
diff --git a/components/camel-quartz/src/test/resources/org/apache/camel/component/quartz/SpringQuartzPersistentStoreRestartAppChangeOptionsTest2.xml b/components/camel-quartz/src/test/resources/org/apache/camel/component/quartz/SpringQuartzPersistentStoreRestartAppChangeOptionsTest2.xml
new file mode 100644
index 0000000..19d89eb
--- /dev/null
+++ b/components/camel-quartz/src/test/resources/org/apache/camel/component/quartz/SpringQuartzPersistentStoreRestartAppChangeOptionsTest2.xml
@@ -0,0 +1,70 @@
+<?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">
+
+ <bean id="quartzDataSource" class="org.apache.commons.dbcp.BasicDataSource">
+ <property name="driverClassName" value="org.apache.derby.jdbc.EmbeddedDriver" />
+ <!-- refer the embedded database we setup inside SpringQuartzConsumerClusteredAppDatabase.xml -->
+ <property name="url" value="jdbc:derby:memory:quartz-db" />
+ <property name="username" value="sa" />
+ <property name="password" value="" />
+ </bean>
+
+ <bean id="quartzBean" class="org.apache.camel.component.quartz.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="quartzDataSource"/>
+ <property name="autoStartup" value="false"/>
+ <!-- let Camel start -->
+ <property name="schedulerContextAsMap">
+ <!-- hook Camel into Quartz -->
+ <map>
+ <entry key="CamelQuartzCamelContext-camelContext" 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.terracotta.quartz.skipUpdateCheck">true</prop>
+ <prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
+ <prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.StdJDBCDelegate</prop>
+ <prop key="org.quartz.jobStore.isClustered">true</prop>
+ </props>
+ </property>
+ </bean>
+
+ <camelContext id="camelContext" managementNamePattern="#name#" xmlns="http://camel.apache.org/schema/spring">
+ <route id="quartzRoute">
+ <from uri="quartzBean://app/test?trigger.repeatInterval=20&trigger.repeatCount=2"/>
+ <to uri="log:trigger"/>
+ <to uri="mock:result"/>
+ </route>
+ </camelContext>
+
+</beans>
http://git-wip-us.apache.org/repos/asf/camel/blob/4134f18d/components/camel-quartz2/src/main/java/org/apache/camel/component/quartz2/QuartzEndpoint.java
----------------------------------------------------------------------
diff --git a/components/camel-quartz2/src/main/java/org/apache/camel/component/quartz2/QuartzEndpoint.java b/components/camel-quartz2/src/main/java/org/apache/camel/component/quartz2/QuartzEndpoint.java
index 4dd9e23..5a6f65f 100644
--- a/components/camel-quartz2/src/main/java/org/apache/camel/component/quartz2/QuartzEndpoint.java
+++ b/components/camel-quartz2/src/main/java/org/apache/camel/component/quartz2/QuartzEndpoint.java
@@ -32,9 +32,9 @@ import org.apache.camel.processor.loadbalancer.RoundRobinLoadBalancer;
import org.apache.camel.spi.UriEndpoint;
import org.apache.camel.spi.UriParam;
import org.apache.camel.util.EndpointHelper;
+import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobBuilder;
-import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SimpleTrigger;
@@ -43,6 +43,7 @@ import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
import static org.quartz.CronScheduleBuilder.cronSchedule;
import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
@@ -236,22 +237,31 @@ public class QuartzEndpoint extends DefaultEndpoint {
// Add or use existing trigger to/from scheduler
Scheduler scheduler = getComponent().getScheduler();
JobDetail jobDetail;
- Trigger trigger = scheduler.getTrigger(triggerKey);
- if (trigger == null) {
- jobDetail = createJobDetail();
- trigger = createTrigger(jobDetail);
+ Trigger oldTrigger = scheduler.getTrigger(triggerKey);
+ boolean triggerExisted = oldTrigger != null;
+ if (triggerExisted) {
+ ensureNoDupTriggerKey();
+ }
- QuartzHelper.updateJobDataMap(getCamelContext(), jobDetail, getEndpointUri());
+ jobDetail = createJobDetail();
+ Trigger trigger = createTrigger(jobDetail);
- // Schedule it now. Remember that scheduler might not be started it, but we can schedule now.
- Date nextFireDate = scheduler.scheduleJob(jobDetail, trigger);
- if (LOG.isInfoEnabled()) {
- LOG.info("Job {} (triggerType={}, jobClass={}) is scheduled. Next fire date is {}",
- new Object[] {trigger.getKey(), trigger.getClass().getSimpleName(),
- jobDetail.getJobClass().getSimpleName(), nextFireDate});
+ QuartzHelper.updateJobDataMap(getCamelContext(), jobDetail, getEndpointUri());
+
+ if (triggerExisted) {
+ // Reschedule job if trigger settings were changed
+ if (hasTriggerChanged(oldTrigger, trigger)) {
+ scheduler.rescheduleJob(triggerKey, trigger);
}
} else {
- ensureNoDupTriggerKey();
+ // Schedule it now. Remember that scheduler might not be started it, but we can schedule now.
+ scheduler.scheduleJob(jobDetail, trigger);
+ }
+
+ if (LOG.isInfoEnabled()) {
+ LOG.info("Job {} (triggerType={}, jobClass={}) is scheduled. Next fire date is {}",
+ new Object[] {trigger.getKey(), trigger.getClass().getSimpleName(),
+ jobDetail.getJobClass().getSimpleName(), trigger.getNextFireTime()});
}
// Increase camel job count for this endpoint
@@ -263,6 +273,21 @@ public class QuartzEndpoint extends DefaultEndpoint {
jobAdded.set(true);
}
+ private boolean hasTriggerChanged(Trigger oldTrigger, Trigger newTrigger) {
+ if (newTrigger instanceof CronTrigger && oldTrigger instanceof CronTrigger) {
+ CronTrigger newCron = (CronTrigger) newTrigger;
+ CronTrigger oldCron = (CronTrigger) oldTrigger;
+ return !newCron.getCronExpression().equals(oldCron.getCronExpression());
+ } else if (newTrigger instanceof SimpleTrigger && oldTrigger instanceof SimpleTrigger) {
+ SimpleTrigger newSimple = (SimpleTrigger) newTrigger;
+ SimpleTrigger oldSimple = (SimpleTrigger) oldTrigger;
+ return newSimple.getRepeatInterval() != oldSimple.getRepeatInterval()
+ || newSimple.getRepeatCount() != oldSimple.getRepeatCount();
+ } else {
+ return !newTrigger.getClass().equals(oldTrigger.getClass()) || !newTrigger.equals(oldTrigger);
+ }
+ }
+
private void ensureNoDupTriggerKey() {
for (Route route : getCamelContext().getRoutes()) {
if (route.getEndpoint() instanceof QuartzEndpoint) {
http://git-wip-us.apache.org/repos/asf/camel/blob/4134f18d/components/camel-quartz2/src/test/java/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartAppChangeOptionsTest.java
----------------------------------------------------------------------
diff --git a/components/camel-quartz2/src/test/java/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartAppChangeOptionsTest.java b/components/camel-quartz2/src/test/java/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartAppChangeOptionsTest.java
new file mode 100644
index 0000000..125c8bc
--- /dev/null
+++ b/components/camel-quartz2/src/test/java/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartAppChangeOptionsTest.java
@@ -0,0 +1,164 @@
+/**
+ * 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.component.quartz2;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.test.junit4.TestSupport;
+import org.apache.camel.util.IOHelper;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.quartz.CronTrigger;
+import org.quartz.Scheduler;
+import org.quartz.SchedulerException;
+import org.quartz.SimpleTrigger;
+import org.quartz.Trigger;
+import org.springframework.context.support.AbstractXmlApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+/**
+ */
+public class SpringQuartzPersistentStoreRestartAppChangeOptionsTest extends TestSupport {
+
+ private AbstractXmlApplicationContext db;
+ private AbstractXmlApplicationContext app;
+ private AbstractXmlApplicationContext app2;
+
+ @Before
+ public void prepareDB() {
+ // boot up the database the two invocations are going to share inside a clustered quartz setup
+ db = new ClassPathXmlApplicationContext("org/apache/camel/component/quartz2/SpringQuartzConsumerClusteredAppDatabase.xml");
+ db.start();
+ }
+
+ @After
+ public void closeApps() {
+ // we're done so let's properly close the application contexts, but close
+ // the second app before the first one so that the quartz scheduler running
+ // inside it can be properly shutdown
+ IOHelper.close(app2, app, db);
+ }
+
+
+ @Test
+ public void testRestartAppChangeCronExpression() throws Exception {
+
+ // Test creates application context twice with different cron expressions in configuration xml.
+ // Both times it retrieves back the cron expression, accessing it via trigger (so, using value stored in DB).
+ // After that it asserts that two cron expressions are not equal.
+
+ // load spring app
+ app = new ClassPathXmlApplicationContext("org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartAppChangeCronExpressionTest1.xml");
+ app.start();
+ CamelContext camel = app.getBean("camelContext", CamelContext.class);
+ assertNotNull(camel);
+ String cronExpression = ((CronTrigger) getTrigger(camel, "quartzRoute")).getCronExpression();
+ app.stop();
+
+ log.info("Restarting ...");
+ log.info("Restarting ...");
+ log.info("Restarting ...");
+
+ // load spring app
+ app2 = new ClassPathXmlApplicationContext("org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartAppChangeCronExpressionTest2.xml");
+ app2.start();
+ CamelContext camel2 = app2.getBean("camelContext", CamelContext.class);
+ assertNotNull(camel2);
+ String cronExpression2 = ((CronTrigger) getTrigger(camel2, "quartzRoute")).getCronExpression();
+ app2.stop();
+
+ assertNotEquals(cronExpression, cronExpression2);
+ }
+
+ @Test
+ public void testRestartAppChangeTriggerOptions() throws Exception {
+
+ // Test creates application context twice with different simple trigger options in configuration xml.
+ // Both times it retrieves back the option, accessing it via trigger (so, using value stored in DB).
+ // After that it asserts that two options are not equal.
+
+ // load spring app
+ AbstractXmlApplicationContext app = new ClassPathXmlApplicationContext("org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartAppChangeOptionsTest1.xml");
+ app.start();
+ CamelContext camel = app.getBean("camelContext", CamelContext.class);
+ assertNotNull(camel);
+ SimpleTrigger trigger = (SimpleTrigger) getTrigger(camel, "quartzRoute");
+ long repeatInterval = trigger.getRepeatInterval();
+ app.stop();
+
+ log.info("Restarting ...");
+ log.info("Restarting ...");
+ log.info("Restarting ...");
+
+ // load spring app
+ AbstractXmlApplicationContext app2 = new ClassPathXmlApplicationContext("org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartAppChangeOptionsTest2.xml");
+ app2.start();
+ CamelContext camel2 = app2.getBean("camelContext", CamelContext.class);
+ assertNotNull(camel2);
+ SimpleTrigger trigger2 = (SimpleTrigger) getTrigger(camel2, "quartzRoute");
+ long repeatInterval2 = trigger2.getRepeatInterval();
+ app2.stop();
+
+ // we're done so let's properly close the application contexts, but close
+ // the second app before the first one so that the quartz scheduler running
+ // inside it can be properly shutdown
+ IOHelper.close(app2, app);
+
+ assertNotEquals(repeatInterval, repeatInterval2);
+ }
+
+ @Test
+ public void testRestartAppChangeTriggerType() throws Exception {
+
+ // Test creates application context twice with different simple trigger options in configuration xml.
+ // Both times it retrieves back the option, accessing it via trigger (so, using value stored in DB).
+ // After that it asserts that two options are not equal.
+
+ // load spring app
+ app = new ClassPathXmlApplicationContext("org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartAppChangeCronExpressionTest1.xml");
+ app.start();
+ CamelContext camel = app.getBean("camelContext", CamelContext.class);
+ assertNotNull(camel);
+ assertTrue(getTrigger(camel, "quartzRoute") instanceof CronTrigger);
+ app.stop();
+
+ log.info("Restarting ...");
+ log.info("Restarting ...");
+ log.info("Restarting ...");
+
+ // load spring app
+ AbstractXmlApplicationContext app2 = new ClassPathXmlApplicationContext("org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartAppChangeOptionsTest2.xml");
+ app2.start();
+ CamelContext camel2 = app2.getBean("camelContext", CamelContext.class);
+ assertNotNull(camel2);
+ assertTrue(getTrigger(camel2, "quartzRoute") instanceof SimpleTrigger);
+ app2.stop();
+
+ // we're done so let's properly close the application contexts, but close
+ // the second app before the first one so that the quartz scheduler running
+ // inside it can be properly shutdown
+ IOHelper.close(app2, app);
+ }
+
+ private Trigger getTrigger(CamelContext camel, String routeId) throws SchedulerException {
+ QuartzEndpoint endpoint = (QuartzEndpoint) (camel.getRoute(routeId).getEndpoint());
+ QuartzComponent component = endpoint.getComponent();
+ Scheduler scheduler = component.getScheduler();
+ return scheduler.getTrigger(endpoint.getTriggerKey());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/4134f18d/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartAppChangeCronExpressionTest1.xml
----------------------------------------------------------------------
diff --git a/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartAppChangeCronExpressionTest1.xml b/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartAppChangeCronExpressionTest1.xml
new file mode 100644
index 0000000..58967fb
--- /dev/null
+++ b/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartAppChangeCronExpressionTest1.xml
@@ -0,0 +1,70 @@
+<?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">
+
+ <bean id="quartzDataSource" class="org.apache.commons.dbcp.BasicDataSource">
+ <property name="driverClassName" value="org.apache.derby.jdbc.EmbeddedDriver" />
+ <!-- refer the embedded database we setup inside SpringQuartzConsumerClusteredAppDatabase.xml -->
+ <property name="url" value="jdbc:derby:memory:quartz-db" />
+ <property name="username" value="sa" />
+ <property name="password" value="" />
+ </bean>
+
+ <bean id="quartzBean" 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="quartzDataSource"/>
+ <property name="autoStartup" value="false"/>
+ <!-- let Camel start -->
+ <property name="schedulerContextAsMap">
+ <!-- hook Camel into Quartz -->
+ <map>
+ <entry key="CamelQuartzCamelContext-camelContext" 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.terracotta.quartz.skipUpdateCheck">true</prop>
+ <prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
+ <prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.StdJDBCDelegate</prop>
+ <prop key="org.quartz.jobStore.isClustered">true</prop>
+ </props>
+ </property>
+ </bean>
+
+ <camelContext id="camelContext" managementNamePattern="#name#" xmlns="http://camel.apache.org/schema/spring">
+ <route id="quartzRoute">
+ <from uri="quartzBean://app/test?cron=0+0/1+*+1/1+*+?+*"/>
+ <to uri="log:trigger"/>
+ <to uri="mock:result"/>
+ </route>
+ </camelContext>
+
+</beans>
http://git-wip-us.apache.org/repos/asf/camel/blob/4134f18d/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartAppChangeCronExpressionTest2.xml
----------------------------------------------------------------------
diff --git a/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartAppChangeCronExpressionTest2.xml b/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartAppChangeCronExpressionTest2.xml
new file mode 100644
index 0000000..e8ce79d
--- /dev/null
+++ b/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartAppChangeCronExpressionTest2.xml
@@ -0,0 +1,70 @@
+<?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">
+
+ <bean id="quartzDataSource" class="org.apache.commons.dbcp.BasicDataSource">
+ <property name="driverClassName" value="org.apache.derby.jdbc.EmbeddedDriver" />
+ <!-- refer the embedded database we setup inside SpringQuartzConsumerClusteredAppDatabase.xml -->
+ <property name="url" value="jdbc:derby:memory:quartz-db" />
+ <property name="username" value="sa" />
+ <property name="password" value="" />
+ </bean>
+
+ <bean id="quartzBean" 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="quartzDataSource"/>
+ <property name="autoStartup" value="false"/>
+ <!-- let Camel start -->
+ <property name="schedulerContextAsMap">
+ <!-- hook Camel into Quartz -->
+ <map>
+ <entry key="CamelQuartzCamelContext-camelContext" 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.terracotta.quartz.skipUpdateCheck">true</prop>
+ <prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
+ <prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.StdJDBCDelegate</prop>
+ <prop key="org.quartz.jobStore.isClustered">true</prop>
+ </props>
+ </property>
+ </bean>
+
+ <camelContext id="camelContext" managementNamePattern="#name#" xmlns="http://camel.apache.org/schema/spring">
+ <route id="quartzRoute">
+ <from uri="quartzBean://app/test?cron=0+0/2+*+1/1+*+?+*"/>
+ <to uri="log:trigger"/>
+ <to uri="mock:result"/>
+ </route>
+ </camelContext>
+
+</beans>
http://git-wip-us.apache.org/repos/asf/camel/blob/4134f18d/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartAppChangeOptionsTest1.xml
----------------------------------------------------------------------
diff --git a/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartAppChangeOptionsTest1.xml b/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartAppChangeOptionsTest1.xml
new file mode 100644
index 0000000..cb6daf6
--- /dev/null
+++ b/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartAppChangeOptionsTest1.xml
@@ -0,0 +1,70 @@
+<?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">
+
+ <bean id="quartzDataSource" class="org.apache.commons.dbcp.BasicDataSource">
+ <property name="driverClassName" value="org.apache.derby.jdbc.EmbeddedDriver" />
+ <!-- refer the embedded database we setup inside SpringQuartzConsumerClusteredAppDatabase.xml -->
+ <property name="url" value="jdbc:derby:memory:quartz-db" />
+ <property name="username" value="sa" />
+ <property name="password" value="" />
+ </bean>
+
+ <bean id="quartzBean" 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="quartzDataSource"/>
+ <property name="autoStartup" value="false"/>
+ <!-- let Camel start -->
+ <property name="schedulerContextAsMap">
+ <!-- hook Camel into Quartz -->
+ <map>
+ <entry key="CamelQuartzCamelContext-camelContext" 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.terracotta.quartz.skipUpdateCheck">true</prop>
+ <prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
+ <prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.StdJDBCDelegate</prop>
+ <prop key="org.quartz.jobStore.isClustered">true</prop>
+ </props>
+ </property>
+ </bean>
+
+ <camelContext id="camelContext" managementNamePattern="#name#" xmlns="http://camel.apache.org/schema/spring">
+ <route id="quartzRoute">
+ <from uri="quartzBean://app/test?trigger.repeatInterval=10&trigger.repeatCount=1"/>
+ <to uri="log:trigger"/>
+ <to uri="mock:result"/>
+ </route>
+ </camelContext>
+
+</beans>
http://git-wip-us.apache.org/repos/asf/camel/blob/4134f18d/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartAppChangeOptionsTest2.xml
----------------------------------------------------------------------
diff --git a/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartAppChangeOptionsTest2.xml b/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartAppChangeOptionsTest2.xml
new file mode 100644
index 0000000..e414860
--- /dev/null
+++ b/components/camel-quartz2/src/test/resources/org/apache/camel/component/quartz2/SpringQuartzPersistentStoreRestartAppChangeOptionsTest2.xml
@@ -0,0 +1,70 @@
+<?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">
+
+ <bean id="quartzDataSource" class="org.apache.commons.dbcp.BasicDataSource">
+ <property name="driverClassName" value="org.apache.derby.jdbc.EmbeddedDriver" />
+ <!-- refer the embedded database we setup inside SpringQuartzConsumerClusteredAppDatabase.xml -->
+ <property name="url" value="jdbc:derby:memory:quartz-db" />
+ <property name="username" value="sa" />
+ <property name="password" value="" />
+ </bean>
+
+ <bean id="quartzBean" 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="quartzDataSource"/>
+ <property name="autoStartup" value="false"/>
+ <!-- let Camel start -->
+ <property name="schedulerContextAsMap">
+ <!-- hook Camel into Quartz -->
+ <map>
+ <entry key="CamelQuartzCamelContext-camelContext" 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.terracotta.quartz.skipUpdateCheck">true</prop>
+ <prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
+ <prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.StdJDBCDelegate</prop>
+ <prop key="org.quartz.jobStore.isClustered">true</prop>
+ </props>
+ </property>
+ </bean>
+
+ <camelContext id="camelContext" managementNamePattern="#name#" xmlns="http://camel.apache.org/schema/spring">
+ <route id="quartzRoute">
+ <from uri="quartzBean://app/test?trigger.repeatInterval=20&trigger.repeatCount=2"/>
+ <to uri="log:trigger"/>
+ <to uri="mock:result"/>
+ </route>
+ </camelContext>
+
+</beans>