001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.camel.routepolicy.quartz;
018
019 import java.util.concurrent.TimeUnit;
020
021 import org.apache.camel.Route;
022 import org.apache.camel.ServiceStatus;
023 import org.apache.camel.impl.RoutePolicySupport;
024 import org.apache.commons.logging.Log;
025 import org.apache.commons.logging.LogFactory;
026 import org.quartz.JobDetail;
027 import org.quartz.Scheduler;
028 import org.quartz.SchedulerException;
029 import org.quartz.Trigger;
030
031 public abstract class ScheduledRoutePolicy extends RoutePolicySupport implements ScheduledRoutePolicyConstants {
032 private static final transient Log LOG = LogFactory.getLog(ScheduledRoutePolicy.class);
033 protected ScheduledRouteDetails scheduledRouteDetails;
034 private Scheduler scheduler;
035 private int routeStopGracePeriod;
036 private TimeUnit timeUnit;
037
038 protected abstract Trigger createTrigger(Action action, Route route) throws Exception;
039
040 protected void onJobExecute(Action action, Route route) throws Exception {
041 if (LOG.isDebugEnabled()) {
042 LOG.debug("Scheduled Event notification received. Performing requested operation " + action + " for route " + route.getId());
043 }
044 ServiceStatus routeStatus = route.getRouteContext().getCamelContext().getRouteStatus(route.getId());
045 if (action == Action.START) {
046 if (routeStatus == ServiceStatus.Stopped) {
047 startRoute(route);
048 } else if (routeStatus == ServiceStatus.Suspended) {
049 startConsumer(route.getConsumer());
050 }
051 } else if (action == Action.STOP) {
052 if ((routeStatus == ServiceStatus.Started) || (routeStatus == ServiceStatus.Suspended)) {
053 stopRoute(route, getRouteStopGracePeriod(), getTimeUnit());
054 }
055 } else if (action == Action.SUSPEND) {
056 if (routeStatus == ServiceStatus.Started) {
057 stopConsumer(route.getConsumer());
058 } else {
059 if (LOG.isWarnEnabled()) {
060 LOG.warn("Route is not in a started state and cannot be suspended. The current route state is " + routeStatus);
061 }
062 }
063 } else if (action == Action.RESUME) {
064 if (routeStatus == ServiceStatus.Started) {
065 startConsumer(route.getConsumer());
066 } else {
067 if (LOG.isWarnEnabled()) {
068 LOG.warn("Route is not in a started state and cannot be resumed. The current route state is " + routeStatus);
069 }
070 }
071 }
072 }
073
074 public void scheduleRoute(Action action) throws Exception {
075 Route route = scheduledRouteDetails.getRoute();
076
077 JobDetail jobDetail = createJobDetail(action, route);
078 Trigger trigger = createTrigger(action, route);
079 updateScheduledRouteDetails(action, jobDetail, trigger);
080
081 loadCallbackDataIntoSchedulerContext(action, route);
082 getScheduler().scheduleJob(jobDetail, trigger);
083
084 if (LOG.isDebugEnabled()) {
085 LOG.debug("Scheduled Trigger: " + trigger.getFullName() + " is operational");
086 }
087 }
088
089 public void pauseRouteTrigger(Action action) throws SchedulerException {
090 String triggerName = retrieveTriggerName(action);
091 String triggerGroup = retrieveTriggerGroup(action);
092
093 getScheduler().pauseTrigger(triggerName, triggerGroup);
094
095 if (LOG.isDebugEnabled()) {
096 LOG.debug("Scheduled Trigger: " + triggerGroup + "." + triggerName + " is paused");
097 }
098 }
099
100 public void resumeRouteTrigger(Action action) throws SchedulerException {
101 String triggerName = retrieveTriggerName(action);
102 String triggerGroup = retrieveTriggerGroup(action);
103
104 getScheduler().resumeTrigger(triggerName, triggerGroup);
105
106 if (LOG.isDebugEnabled()) {
107 LOG.debug("Scheduled Trigger: " + triggerGroup + "." + triggerName + " has been resumed");
108 }
109 }
110
111 public void deleteRouteJob(Action action) throws SchedulerException {
112 String jobDetailName = retrieveJobDetailName(action);
113 String jobDetailGroup = retrieveJobDetailGroup(action);
114
115 if (!getScheduler().isShutdown()) {
116 getScheduler().deleteJob(jobDetailName, jobDetailGroup);
117 }
118
119 if (LOG.isDebugEnabled()) {
120 LOG.debug("Scheduled Job: " + jobDetailGroup + "." + jobDetailName + " has been deleted");
121 }
122 }
123
124 protected JobDetail createJobDetail(Action action, Route route) throws Exception {
125 JobDetail jobDetail = null;
126
127 if (action == Action.START) {
128 jobDetail = new JobDetail(JOB_START + route.getId(), JOB_GROUP + route.getId(), ScheduledJob.class);
129 } else if (action == Action.STOP) {
130 jobDetail = new JobDetail(JOB_STOP + route.getId(), JOB_GROUP + route.getId(), ScheduledJob.class);
131 } else if (action == Action.SUSPEND) {
132 jobDetail = new JobDetail(JOB_SUSPEND + route.getId(), JOB_GROUP + route.getId(), ScheduledJob.class);
133 } else if (action == Action.RESUME) {
134 jobDetail = new JobDetail(JOB_RESUME + route.getId(), JOB_GROUP + route.getId(), ScheduledJob.class);
135 }
136
137 return jobDetail;
138 }
139
140 protected void updateScheduledRouteDetails(Action action, JobDetail jobDetail, Trigger trigger) throws Exception {
141 if (action == Action.START) {
142 scheduledRouteDetails.setStartJobDetail(jobDetail);
143 scheduledRouteDetails.setStartTrigger(trigger);
144 } else if (action == Action.STOP) {
145 scheduledRouteDetails.setStopJobDetail(jobDetail);
146 scheduledRouteDetails.setStopTrigger(trigger);
147 } else if (action == Action.SUSPEND) {
148 scheduledRouteDetails.setSuspendJobDetail(jobDetail);
149 scheduledRouteDetails.setSuspendTrigger(trigger);
150 } else if (action == Action.RESUME) {
151 scheduledRouteDetails.setResumeJobDetail(jobDetail);
152 scheduledRouteDetails.setResumeTrigger(trigger);
153 }
154 }
155
156 protected void loadCallbackDataIntoSchedulerContext(Action action, Route route) throws SchedulerException {
157 getScheduler().getContext().put(SCHEDULED_ACTION, action);
158 getScheduler().getContext().put(SCHEDULED_ROUTE, route);
159 }
160
161 public String retrieveTriggerName(Action action) {
162 String triggerName = null;
163
164 if (action == Action.START) {
165 triggerName = scheduledRouteDetails.getStartTrigger().getName();
166 } else if (action == Action.STOP) {
167 triggerName = scheduledRouteDetails.getStopTrigger().getName();
168 } else if (action == Action.SUSPEND) {
169 triggerName = scheduledRouteDetails.getSuspendTrigger().getName();
170 } else if (action == Action.RESUME) {
171 triggerName = scheduledRouteDetails.getResumeTrigger().getName();
172 }
173
174 return triggerName;
175 }
176
177 public String retrieveTriggerGroup(Action action) {
178 String triggerGroup = null;
179
180 if (action == Action.START) {
181 triggerGroup = scheduledRouteDetails.getStartTrigger().getGroup();
182 } else if (action == Action.STOP) {
183 triggerGroup = scheduledRouteDetails.getStopTrigger().getGroup();
184 } else if (action == Action.SUSPEND) {
185 triggerGroup = scheduledRouteDetails.getSuspendTrigger().getGroup();
186 } else if (action == Action.RESUME) {
187 triggerGroup = scheduledRouteDetails.getResumeTrigger().getGroup();
188 }
189
190 return triggerGroup;
191 }
192
193 public String retrieveJobDetailName(Action action) {
194 String jobDetailName = null;
195
196 if (action == Action.START) {
197 jobDetailName = scheduledRouteDetails.getStartJobDetail().getName();
198 } else if (action == Action.STOP) {
199 jobDetailName = scheduledRouteDetails.getStopJobDetail().getName();
200 } else if (action == Action.SUSPEND) {
201 jobDetailName = scheduledRouteDetails.getSuspendJobDetail().getName();
202 } else if (action == Action.RESUME) {
203 jobDetailName = scheduledRouteDetails.getResumeJobDetail().getName();
204 }
205
206 return jobDetailName;
207 }
208
209 public String retrieveJobDetailGroup(Action action) {
210 String jobDetailGroup = null;
211
212 if (action == Action.START) {
213 jobDetailGroup = scheduledRouteDetails.getStartJobDetail().getGroup();
214 } else if (action == Action.STOP) {
215 jobDetailGroup = scheduledRouteDetails.getStopJobDetail().getGroup();
216 } else if (action == Action.SUSPEND) {
217 jobDetailGroup = scheduledRouteDetails.getSuspendJobDetail().getGroup();
218 } else if (action == Action.RESUME) {
219 jobDetailGroup = scheduledRouteDetails.getResumeJobDetail().getGroup();
220 }
221
222 return jobDetailGroup;
223 }
224
225 public ScheduledRouteDetails getScheduledRouteDetails() {
226 return scheduledRouteDetails;
227 }
228
229 public void setScheduledRouteDetails(ScheduledRouteDetails scheduledRouteDetails) {
230 this.scheduledRouteDetails = scheduledRouteDetails;
231 }
232
233 public void setScheduler(Scheduler scheduler) {
234 this.scheduler = scheduler;
235 }
236
237 public Scheduler getScheduler() {
238 return scheduler;
239 }
240
241 public void setRouteStopGracePeriod(int routeStopGracePeriod) {
242 this.routeStopGracePeriod = routeStopGracePeriod;
243 }
244
245 public int getRouteStopGracePeriod() {
246 return routeStopGracePeriod;
247 }
248
249 public void setTimeUnit(TimeUnit timeUnit) {
250 this.timeUnit = timeUnit;
251 }
252
253 public TimeUnit getTimeUnit() {
254 return timeUnit;
255 }
256
257 }