/** * 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.apache.aurora.scheduler.cron.quartz; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import javax.inject.Inject; import com.google.common.util.concurrent.AbstractIdleService; import org.apache.aurora.common.stats.Stats; import org.apache.aurora.scheduler.configuration.SanitizedConfiguration; import org.apache.aurora.scheduler.cron.CronException; import org.apache.aurora.scheduler.cron.SanitizedCronJob; import org.apache.aurora.scheduler.storage.Storage; import org.apache.aurora.scheduler.storage.entities.IJobConfiguration; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import static java.util.Objects.requireNonNull; /** * Manager for startup and teardown of Quartz scheduler. */ class CronLifecycle extends AbstractIdleService { private static final Logger LOG = LoggerFactory.getLogger(CronLifecycle.class); private static final AtomicInteger RUNNING_FLAG = Stats.exportInt("quartz_scheduler_running"); private static final AtomicInteger LOADED_FLAG = Stats.exportInt("cron_jobs_loaded"); private static final AtomicLong LAUNCH_FAILURES = Stats.exportLong("cron_job_launch_failures"); private final Scheduler scheduler; private final CronJobManagerImpl cronJobManager; private final Storage storage; @Inject CronLifecycle( Scheduler scheduler, CronJobManagerImpl cronJobManager, Storage storage) { this.scheduler = requireNonNull(scheduler); this.cronJobManager = requireNonNull(cronJobManager); this.storage = requireNonNull(storage); } @Override protected void startUp() throws SchedulerException { LOG.info("Starting Quartz cron scheduler" + scheduler.getSchedulerName() + "."); scheduler.start(); RUNNING_FLAG.set(1); for (IJobConfiguration job : Storage.Util.fetchCronJobs(storage)) { try { SanitizedCronJob cronJob = SanitizedCronJob.from(new SanitizedConfiguration(job)); cronJobManager.scheduleJob( cronJob.getCrontabEntry(), cronJob.getSanitizedConfig().getJobConfig().getKey()); } catch (CronException e) { logLaunchFailure(job, e); } } LOADED_FLAG.set(1); } private void logLaunchFailure(IJobConfiguration job, Exception e) { LAUNCH_FAILURES.incrementAndGet(); LOG.error("Scheduling failed for recovered job " + job, e); } @Override protected void shutDown() throws SchedulerException { LOG.info("Shutting down Quartz cron scheduler."); scheduler.shutdown(); RUNNING_FLAG.set(0); } }