/* * Copyright 2016 KairosDB Authors * * Licensed 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. */ package org.kairosdb.core.scheduler; import com.google.inject.Inject; import com.google.inject.Injector; import com.google.inject.Key; import org.kairosdb.core.KairosDBService; import org.kairosdb.core.exception.KairosDBException; import org.quartz.*; import org.quartz.impl.StdSchedulerFactory; import org.quartz.impl.matchers.GroupMatcher; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.*; import static com.google.common.base.Preconditions.checkNotNull; import static org.quartz.JobBuilder.newJob; public class KairosDBSchedulerImpl implements KairosDBService, KairosDBScheduler { private static final Logger log = LoggerFactory.getLogger(KairosDBSchedulerImpl.class); private final Scheduler scheduler; private final Injector guice; @Inject public KairosDBSchedulerImpl(Injector guice) throws SchedulerException { this.guice = guice; Properties props = new Properties(); props.setProperty("org.quartz.threadPool.threadCount", "4"); props.setProperty(StdSchedulerFactory.PROP_SCHED_SKIP_UPDATE_CHECK, "true"); StdSchedulerFactory factory = new StdSchedulerFactory(props); scheduler = factory.getScheduler(); scheduler.setJobFactory(new KairosDBJobFactory(guice)); } @SuppressWarnings("unchecked") @Override public void start() throws KairosDBException { try { scheduler.start(); for (Key<?> key : guice.getAllBindings().keySet()) { Class bindingClass = key.getTypeLiteral().getRawType(); if (KairosDBJob.class.isAssignableFrom(bindingClass)) { KairosDBJob job = (KairosDBJob) guice.getInstance(bindingClass); JobDetail jobDetail = newJob(job.getClass()) .withIdentity(job.getClass().getName()).build(); scheduler.scheduleJob(jobDetail, job.getTrigger()); } } for (String groupName : scheduler.getJobGroupNames()) { for (JobKey jobKey : scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName))) { String jobName = jobKey.getName(); List<Trigger> triggers = (List<Trigger>) scheduler.getTriggersOfJob(jobKey); Date nextFireTime = triggers.get(0).getNextFireTime(); log.info("*** Scheduled job " + jobName + " to execute next on " + nextFireTime); } } } catch (SchedulerException e) { throw new KairosDBException("Failed to start " + getClass().getName(), e); } } @Override public void stop() { try { scheduler.shutdown(true); } catch (SchedulerException e) { log.error("Failed to start " + getClass().getName(), e); } } @Override public void schedule(JobDetail jobDetail, Trigger trigger) throws KairosDBException { checkNotNull(jobDetail); checkNotNull(trigger); try { scheduler.scheduleJob(jobDetail, trigger); } catch (SchedulerException e) { throw new KairosDBException("Failed to schedule trigger " + jobDetail, e); } } @Override public void cancel(JobKey jobKey) throws KairosDBException { checkNotNull(jobKey); try { scheduler.deleteJob(jobKey); } catch (SchedulerException e) { throw new KairosDBException("Failed to delete job " + jobKey, e); } } @Override @SuppressWarnings("unchecked") public Set<String> getScheduledJobIds() throws KairosDBException { Set<String> scheduledJobs = new HashSet<String>(); try { for (String groupName : scheduler.getJobGroupNames()) { for (JobKey jobKey : scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName))) { scheduledJobs.add(jobKey.getName()); } } } catch (SchedulerException e) { throw new KairosDBException("Could not get scheduled jobs." + e); } return scheduledJobs; } }