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