Skip to content

Instantly share code, notes, and snippets.

@ullgren
Created June 27, 2012 13:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ullgren/3004189 to your computer and use it in GitHub Desktop.
Save ullgren/3004189 to your computer and use it in GitHub Desktop.
Test case to show a problem we see in CronScheduledRoutePolicy
/**
* 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.
*/
import java.util.concurrent.TimeUnit;
import org.apache.camel.Route;
import org.apache.camel.component.quartz.QuartzComponent;
import org.apache.camel.routepolicy.quartz.ScheduledRoutePolicy;
import org.apache.camel.routepolicy.quartz.ScheduledRoutePolicyConstants;
import org.apache.camel.util.ObjectHelper;
import org.quartz.CronTrigger;
import org.quartz.Trigger;
/**
* This is a localy modified version of CronScheduledRoutePolicy that implements the onRemove method
*/
public class CronScheduledRoutePolicy extends ScheduledRoutePolicy implements ScheduledRoutePolicyConstants {
private String routeStartTime;
private String routeStopTime;
private String routeSuspendTime;
private String routeResumeTime;
public void onInit(Route route) {
try {
doOnInit(route);
} catch (Exception e) {
throw ObjectHelper.wrapRuntimeCamelException(e);
}
}
@Override
public void onRemove(Route route) {
try {
doStop();
} catch (Exception e) {
throw ObjectHelper.wrapRuntimeCamelException(e);
}
}
protected void doOnInit(Route route) throws Exception {
QuartzComponent quartz = route.getRouteContext().getCamelContext().getComponent("quartz", QuartzComponent.class);
setScheduler(quartz.getScheduler());
// Important: do not start scheduler as QuartzComponent does that automatic
// when CamelContext has been fully initialized and started
if (getRouteStopGracePeriod() == 0) {
setRouteStopGracePeriod(10000);
}
if (getTimeUnit() == null) {
setTimeUnit(TimeUnit.MILLISECONDS);
}
// 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");
}
registerRouteToScheduledRouteDetails(route);
if (getRouteStartTime() != null) {
scheduleRoute(Action.START, route);
}
if (getRouteStopTime() != null) {
scheduleRoute(Action.STOP, route);
}
if (getRouteSuspendTime() != null) {
scheduleRoute(Action.SUSPEND, route);
}
if (getRouteResumeTime() != null) {
scheduleRoute(Action.RESUME, route);
}
}
@Override
protected Trigger createTrigger(Action action, Route route) throws Exception {
CronTrigger trigger = null;
if (action == Action.START) {
trigger = new CronTrigger(TRIGGER_START + route.getId(), TRIGGER_GROUP + route.getId(), getRouteStartTime());
} else if (action == Action.STOP) {
trigger = new CronTrigger(TRIGGER_STOP + route.getId(), TRIGGER_GROUP + route.getId(), getRouteStopTime());
} else if (action == Action.SUSPEND) {
trigger = new CronTrigger(TRIGGER_SUSPEND + route.getId(), TRIGGER_GROUP + route.getId(), getRouteSuspendTime());
} else if (action == Action.RESUME) {
trigger = new CronTrigger(TRIGGER_RESUME + route.getId(), TRIGGER_GROUP + route.getId(), getRouteResumeTime());
}
return trigger;
}
public void setRouteStartTime(String routeStartTime) {
this.routeStartTime = routeStartTime;
}
public String getRouteStartTime() {
return routeStartTime;
}
public void setRouteStopTime(String routeStopTime) {
this.routeStopTime = routeStopTime;
}
public String getRouteStopTime() {
return routeStopTime;
}
public void setRouteSuspendTime(String routeSuspendTime) {
this.routeSuspendTime = routeSuspendTime;
}
public String getRouteSuspendTime() {
return routeSuspendTime;
}
public void setRouteResumeTime(String routeResumeTime) {
this.routeResumeTime = routeResumeTime;
}
public String getRouteResumeTime() {
return routeResumeTime;
}
}
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ullgren.pontus.demo</groupId>
<artifactId>scheduledroutepolicy</artifactId>
<version>1.0</version>
<name>Testing ScheduledRoutePolicy</name>
<packaging>jar</packaging>
<dependencies>
<dependency>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
<version>1.5.6</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>2.9.0</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-quartz</artifactId>
<version>2.9.0</version>
<scope>compile</scope>
</dependency>
<!-- for testing -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>2.9.0</version>
<type>test-jar</type>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-test</artifactId>
<version>2.9.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.5.6</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
import org.apache.camel.ServiceStatus;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.test.CamelTestSupport;
import org.junit.Ignore;
import org.junit.Test;
/**
* This testcase shows a issue we have with a application
* where we dynamicly changes route configuration by "redeploying" them.
* This is done using the following steps.
* <ol>
* <li>Stop the route</li>
* <li>Remove the route (and it's endpoints) from the context</li>
* <li>(Re)add the route to the context using the same name.</li>
* </ol>
*
* For routes that uses the CronScheduledRoutePolicy the redeploy phase failes since there are
* jobs still registered in quartz.
*
* Adding a implementation of onRemove() to the CronScheduledRoutePolicy solves this problem.
*
* @author Pontus Ullgren
*
*/
public class RedeployRouteWithCronScheduledRoutePolicyTest extends CamelTestSupport {
/**
* Tests to add a route with a CronScheduledRoutePolicy then remove it
* and re-add the route again with the same name.
*/
@Test
public void testStandardCronScheduledRoutePolicy() throws Exception {
// Add the routes to the context
context.addRoutes(new MyRouteBuilder());
// Lets wait to see that the route starts.
ServiceStatus status = context.getRouteStatus("testroute1");
while( status.isStarted() ) { Thread.sleep(10); status = context.getRouteStatus("testroute1"); }
// Ok stop and remove the route
context.stopRoute("testroute1");
context.removeRoute("testroute1");
// Lets try to re-add it
context.addRoutes(new MyRouteBuilder());
}
/**
* Do the same with a locally modified CronScheduledRoutePolicy
*/
@Test
public void testModifiedCronScheduledRoutePolicy() throws Exception {
// Add the routes to the context
context.addRoutes(new MyRouteBuilder2());
// Lets wait to see that the route starts.
ServiceStatus status = context.getRouteStatus("testroute1");
while( status.isStarted() ) { Thread.sleep(10); status = context.getRouteStatus("testroute1"); }
// Ok stop and remove the route
context.stopRoute("testroute1");
context.removeRoute("testroute1");
// Lets try to re-add it
context.addRoutes(new MyRouteBuilder2());
}
private class MyRouteBuilder extends RouteBuilder {
org.apache.camel.routepolicy.quartz.CronScheduledRoutePolicy scheduledRoutePolicy;
public MyRouteBuilder() {
scheduledRoutePolicy =
new org.apache.camel.routepolicy.quartz.CronScheduledRoutePolicy();
scheduledRoutePolicy.setRouteStartTime("0 * */1 1/1 * ?");
}
@Override
public void configure() throws Exception {
from("direct:start").routeId("testroute1")
.noAutoStartup()
.routePolicy(scheduledRoutePolicy)
.to("mock:out");
}
}
private class MyRouteBuilder2 extends RouteBuilder {
CronScheduledRoutePolicy scheduledRoutePolicy;
public MyRouteBuilder2() {
scheduledRoutePolicy =
new CronScheduledRoutePolicy();
scheduledRoutePolicy.setRouteStartTime("0 * */1 1/1 * ?");
}
@Override
public void configure() throws Exception {
from("direct:start").routeId("testroute1")
.noAutoStartup()
.routePolicy(scheduledRoutePolicy)
.to("mock:out");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment