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.spring.pollingconsumer;
018
019 import java.util.TimeZone;
020 import java.util.concurrent.ScheduledFuture;
021
022 import org.apache.camel.CamelContext;
023 import org.apache.camel.Consumer;
024 import org.apache.camel.spi.ScheduledPollConsumerScheduler;
025 import org.apache.camel.spring.util.CamelThreadPoolTaskScheduler;
026 import org.apache.camel.support.ServiceSupport;
027 import org.apache.camel.util.ObjectHelper;
028 import org.slf4j.Logger;
029 import org.slf4j.LoggerFactory;
030 import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
031 import org.springframework.scheduling.support.CronTrigger;
032
033 /**
034 * A Spring based {@link ScheduledPollConsumerScheduler} which uses a {@link CronTrigger} to define when the
035 * poll should be triggered.
036 */
037 public class SpringScheduledPollConsumerScheduler extends ServiceSupport implements ScheduledPollConsumerScheduler {
038
039 private static final Logger LOG = LoggerFactory.getLogger(SpringScheduledPollConsumerScheduler.class);
040 private CamelContext camelContext;
041 private Consumer consumer;
042 private Runnable runnable;
043 private String cron;
044 private TimeZone timeZone = TimeZone.getDefault();
045 private volatile CronTrigger trigger;
046 private volatile ThreadPoolTaskScheduler taskScheduler;
047 private boolean destroyTaskScheduler;
048 private volatile ScheduledFuture<?> future;
049
050 @Override
051 public void onInit(Consumer consumer) {
052 this.consumer = consumer;
053 }
054
055 @Override
056 public void scheduleTask(Runnable runnable) {
057 this.runnable = runnable;
058 }
059
060 @Override
061 public void unscheduleTask() {
062 if (future != null) {
063 future.cancel(false);
064 future = null;
065 }
066 }
067
068 @Override
069 public void startScheduler() {
070 // we start the scheduler in doStart
071 }
072
073 @Override
074 public boolean isSchedulerStarted() {
075 return taskScheduler != null && !taskScheduler.getScheduledExecutor().isShutdown();
076 }
077
078 @Override
079 public void setCamelContext(CamelContext camelContext) {
080 this.camelContext = camelContext;
081 }
082
083 @Override
084 public CamelContext getCamelContext() {
085 return camelContext;
086 }
087
088 public String getCron() {
089 return cron;
090 }
091
092 public void setCron(String cron) {
093 this.cron = cron;
094 }
095
096 public TimeZone getTimeZone() {
097 return timeZone;
098 }
099
100 public void setTimeZone(TimeZone timeZone) {
101 this.timeZone = timeZone;
102 }
103
104 public ThreadPoolTaskScheduler getTaskScheduler() {
105 return taskScheduler;
106 }
107
108 public void setTaskScheduler(ThreadPoolTaskScheduler taskScheduler) {
109 this.taskScheduler = taskScheduler;
110 }
111
112 @Override
113 protected void doStart() throws Exception {
114 ObjectHelper.notEmpty(cron, "cron", this);
115
116 trigger = new CronTrigger(getCron(), getTimeZone());
117
118 if (taskScheduler == null) {
119 taskScheduler = new CamelThreadPoolTaskScheduler(getCamelContext(), consumer, consumer.getEndpoint().getEndpointUri());
120 taskScheduler.afterPropertiesSet();
121 destroyTaskScheduler = true;
122 }
123
124 LOG.debug("Scheduling cron trigger {}", getCron());
125 future = taskScheduler.schedule(runnable, trigger);
126 }
127
128 @Override
129 protected void doStop() throws Exception {
130 if (future != null) {
131 future.cancel(false);
132 future = null;
133 }
134
135 if (destroyTaskScheduler) {
136 taskScheduler.destroy();
137 taskScheduler = null;
138 }
139 }
140 }