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