You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2011/01/07 15:22:09 UTC
svn commit: r1056333 - in /camel/trunk/components/camel-quartz/src:
main/java/org/apache/camel/component/quartz/
test/java/org/apache/camel/component/quartz/
Author: davsclaus
Date: Fri Jan 7 14:22:08 2011
New Revision: 1056333
URL: http://svn.apache.org/viewvc?rev=1056333&view=rev
Log:
CAMEL-3239: quartz component now enforces trigger name/group being unique. This does not apply for clustered. Thanks to Tracy Snell for patch.
Added:
camel/trunk/components/camel-quartz/src/test/java/org/apache/camel/component/quartz/QuartzNameCollisionTest.java
Modified:
camel/trunk/components/camel-quartz/src/main/java/org/apache/camel/component/quartz/QuartzComponent.java
camel/trunk/components/camel-quartz/src/main/java/org/apache/camel/component/quartz/QuartzEndpoint.java
Modified: camel/trunk/components/camel-quartz/src/main/java/org/apache/camel/component/quartz/QuartzComponent.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-quartz/src/main/java/org/apache/camel/component/quartz/QuartzComponent.java?rev=1056333&r1=1056332&r2=1056333&view=diff
==============================================================================
--- camel/trunk/components/camel-quartz/src/main/java/org/apache/camel/component/quartz/QuartzComponent.java (original)
+++ camel/trunk/components/camel-quartz/src/main/java/org/apache/camel/component/quartz/QuartzComponent.java Fri Jan 7 14:22:08 2011
@@ -111,8 +111,19 @@ public class QuartzComponent extends Def
Map<String, Object> triggerParameters = IntrospectionSupport.extractProperties(parameters, "trigger.");
Map<String, Object> jobParameters = IntrospectionSupport.extractProperties(parameters, "job.");
- // create the trigger either cron or simple
Trigger trigger;
+
+ // if we're starting up and not running in Quartz clustered mode then check for a name conflict.
+ if (!isClustered()) {
+ // check to see if this trigger already exists
+ trigger = getScheduler().getTrigger(name, group);
+ if (trigger != null) {
+ String msg = "A Quartz job already exists with the name/group: " + name + "/" + group;
+ throw new IllegalArgumentException(msg);
+ }
+ }
+
+ // create the trigger either cron or simple
if (ObjectHelper.isNotEmpty(cron)) {
trigger = createCronTrigger(cron);
} else {
@@ -232,29 +243,37 @@ public class QuartzComponent extends Def
}
}
- public void removeJob(JobDetail job, Trigger trigger) throws SchedulerException {
+ public void pauseJob(Trigger trigger) throws SchedulerException {
JOBS.decrementAndGet();
if (isClustered()) {
- // do not remove jobs which are clustered, as we want the jobs to continue running on the other nodes
+ // do not pause jobs which are clustered, as we want the jobs to continue running on the other nodes
if (LOG.isDebugEnabled()) {
- LOG.debug("Cannot removing job using trigger: " + trigger.getGroup() + "/" + trigger.getName() + " as the JobStore is clustered.");
+ LOG.debug("Cannot pause job using trigger: " + trigger.getGroup() + "/" + trigger.getName() + " as the JobStore is clustered.");
}
- return;
+ } else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Pausing job using trigger: " + trigger.getGroup() + "/" + trigger.getName());
+ }
+ getScheduler().pauseTrigger(trigger.getName(), trigger.getGroup());
+ getScheduler().pauseJob(trigger.getName(), trigger.getGroup());
}
+ }
- // only unschedule volatile jobs
- if (job.isVolatile()) {
+ public void deleteJob(String name, String group) throws SchedulerException {
+ if (isClustered()) {
+ // do not pause jobs which are clustered, as we want the jobs to continue running on the other nodes
if (LOG.isDebugEnabled()) {
- LOG.debug("Removing job using trigger: " + trigger.getGroup() + "/" + trigger.getName());
+ LOG.debug("Cannot delete job using trigger: " + group + "/" + name + " as the JobStore is clustered.");
}
- getScheduler().unscheduleJob(trigger.getName(), trigger.getGroup());
} else {
- // but pause jobs so we can resume them if the application restarts
- if (LOG.isDebugEnabled()) {
- LOG.debug("Pausing job using trigger: " + trigger.getGroup() + "/" + trigger.getName());
+ Trigger trigger = getScheduler().getTrigger(name, group);
+ if (trigger != null) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Deleting job using trigger: " + group + "/" + name);
+ }
+ getScheduler().unscheduleJob(name, group);
}
- getScheduler().pauseTrigger(trigger.getName(), trigger.getGroup());
}
}
Modified: camel/trunk/components/camel-quartz/src/main/java/org/apache/camel/component/quartz/QuartzEndpoint.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-quartz/src/main/java/org/apache/camel/component/quartz/QuartzEndpoint.java?rev=1056333&r1=1056332&r2=1056333&view=diff
==============================================================================
--- camel/trunk/components/camel-quartz/src/main/java/org/apache/camel/component/quartz/QuartzEndpoint.java (original)
+++ camel/trunk/components/camel-quartz/src/main/java/org/apache/camel/component/quartz/QuartzEndpoint.java Fri Jan 7 14:22:08 2011
@@ -21,7 +21,7 @@ import java.util.Date;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.Producer;
-import org.apache.camel.Service;
+import org.apache.camel.ShutdownableService;
import org.apache.camel.impl.DefaultEndpoint;
import org.apache.camel.impl.ServiceSupport;
import org.apache.camel.processor.loadbalancer.LoadBalancer;
@@ -42,7 +42,7 @@ import org.quartz.Trigger;
*
* @version $Revision:520964 $
*/
-public class QuartzEndpoint extends DefaultEndpoint implements Service {
+public class QuartzEndpoint extends DefaultEndpoint implements ShutdownableService {
private static final transient Log LOG = LogFactory.getLog(QuartzEndpoint.class);
private LoadBalancer loadBalancer;
@@ -80,8 +80,12 @@ public class QuartzEndpoint extends Defa
getComponent().addJob(detail, trigger);
}
- public void removeTrigger(final Trigger trigger, final JobDetail detail) throws SchedulerException {
- getComponent().removeJob(detail, trigger);
+ public void pauseTrigger(final Trigger trigger) throws SchedulerException {
+ getComponent().pauseJob(trigger);
+ }
+
+ public void deleteTrigger(final Trigger trigger) throws SchedulerException {
+ getComponent().deleteJob(trigger.getName(), trigger.getGroup());
}
/**
@@ -218,7 +222,7 @@ public class QuartzEndpoint extends Defa
public synchronized void consumerStopped(final QuartzConsumer consumer) throws SchedulerException {
ObjectHelper.notNull(trigger, "trigger");
if (started) {
- removeTrigger(getTrigger(), getJobDetail());
+ pauseTrigger(getTrigger());
started = false;
}
@@ -245,4 +249,8 @@ public class QuartzEndpoint extends Defa
ServiceHelper.stopService(loadBalancer);
}
+ public void shutdown() throws Exception {
+ ObjectHelper.notNull(trigger, "trigger");
+ deleteTrigger(getTrigger());
+ }
}
Added: camel/trunk/components/camel-quartz/src/test/java/org/apache/camel/component/quartz/QuartzNameCollisionTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-quartz/src/test/java/org/apache/camel/component/quartz/QuartzNameCollisionTest.java?rev=1056333&view=auto
==============================================================================
--- camel/trunk/components/camel-quartz/src/test/java/org/apache/camel/component/quartz/QuartzNameCollisionTest.java (added)
+++ camel/trunk/components/camel-quartz/src/test/java/org/apache/camel/component/quartz/QuartzNameCollisionTest.java Fri Jan 7 14:22:08 2011
@@ -0,0 +1,138 @@
+/**
+ * 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.builder.RouteBuilder;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Test;
+import org.quartz.Scheduler;
+import org.quartz.Trigger;
+
+/**
+ * Check for duplicate name/group collision.
+ */
+public class QuartzNameCollisionTest {
+ private DefaultCamelContext camel1;
+ private DefaultCamelContext camel2;
+
+ @Test
+ public void testDupeName() throws Exception {
+ camel1 = new DefaultCamelContext();
+ camel1.setName("camel-1");
+ camel1.addRoutes(new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ from("quartz://myGroup/myTimerName?cron=0/1+*+*+*+*+?").to("log:one", "mock:one");
+ }
+ });
+ camel1.start();
+
+ camel2 = new DefaultCamelContext();
+ QuartzComponent component2 = new QuartzComponent(camel2);
+
+ try {
+ component2.createEndpoint("quartz://myGroup/myTimerName");
+ Assert.fail("Should have thrown an exception");
+ } catch (IllegalArgumentException e) {
+ Assert.assertEquals("A Quartz job already exists with the name/group: myTimerName/myGroup", e.getMessage());
+ }
+ }
+
+
+ /**
+ * Make sure a resume doesn't trigger a dupe name error.
+ */
+ @Test
+ public void testRestart() throws Exception {
+ DefaultCamelContext camel = new DefaultCamelContext();
+
+ camel.addRoutes(new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ from("quartz://myGroup/myTimerName?cron=0/1+*+*+*+*+?").to("log:one", "mock:one");
+ }
+ });
+
+ // traverse a litany of states
+ camel.start();
+ Thread.sleep(100);
+ camel.suspend();
+ Thread.sleep(100);
+ camel.resume();
+ Thread.sleep(100);
+ camel.stop();
+ Thread.sleep(100);
+ camel.start();
+ Thread.sleep(100);
+ camel.stop();
+ }
+
+
+ /**
+ * Confirm the quartz trigger is removed on route stop.
+ */
+ @Test
+ public void testRemoveJob() throws Exception {
+ camel1 = new DefaultCamelContext();
+ camel1.setName("camel-1");
+ camel1.addRoutes(new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ from("quartz://myGroup/myTimerName?cron=0/1+*+*+*+*+?").to("log:one", "mock:one");
+ }
+ });
+ camel1.start();
+
+ camel2 = new DefaultCamelContext();
+ camel2.setName("camel-2");
+ camel2.addRoutes(new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ from("quartz://myGroup2/myTimerName?cron=0/1+*+*+*+*+?").to("log:one", "mock:one");
+ }
+ });
+ camel2.start();
+
+ QuartzComponent component = (QuartzComponent) camel1.getComponent("quartz");
+ Scheduler scheduler = component.getScheduler();
+ Trigger trigger = scheduler.getTrigger("myTimerName", "myGroup");
+ Assert.assertNotNull(trigger);
+
+ camel1.stop();
+
+ trigger = scheduler.getTrigger("myTimerName", "myGroup");
+ Assert.assertNull(trigger);
+
+ camel2.stop();
+ }
+
+ @After
+ public void cleanUp() throws Exception {
+ if (camel1 != null) {
+ camel1.stop();
+ camel1 = null;
+ }
+
+ if (camel2 != null) {
+ camel2.stop();
+ camel2 = null;
+ }
+ }
+
+}