/** * The contents of this file are subject to the Mozilla Public License * Version 1.1 (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.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations under * the License. * * The Original Code is OpenELIS code. * * Copyright (C) CIRG, University of Washington, Seattle WA. All Rights Reserved. * */ package us.mn.state.health.lims.scheduler; import org.quartz.*; import org.quartz.impl.StdSchedulerFactory; import us.mn.state.health.lims.common.util.DateUtil; import us.mn.state.health.lims.dataexchange.MalariaSurveilance.MalariaSurveilanceJob; import us.mn.state.health.lims.dataexchange.aggregatereporting.AggregateReportJob; import us.mn.state.health.lims.scheduler.daoimpl.CronSchedulerDAOImpl; import us.mn.state.health.lims.scheduler.valueholder.CronScheduler; import java.text.ParseException; import java.util.HashMap; import java.util.List; import java.util.Map; import static org.quartz.CronScheduleBuilder.cronSchedule; import static org.quartz.JobBuilder.newJob; import static org.quartz.TriggerBuilder.newTrigger; public class LateStartScheduler { private static final String NEVER = "never"; private static Map<String, Class<? extends Job>> scheduleJobMap; private Scheduler scheduler; static { scheduleJobMap = new HashMap<String, Class<? extends Job>>(); scheduleJobMap.put("sendSiteIndicators", AggregateReportJob.class); scheduleJobMap.put("sendMalariaSurviellanceReport", MalariaSurveilanceJob.class); } public void restartSchedules() { new Restarter().start(); } public class Restarter extends Thread { public void run() { try { scheduler = StdSchedulerFactory.getDefaultScheduler(); scheduler.shutdown(); checkAndStartScheduler(); } catch (SchedulerException e) { e.printStackTrace(); } } } public void checkAndStartScheduler() { try { scheduler = StdSchedulerFactory.getDefaultScheduler(); List<CronScheduler> schedulers = new CronSchedulerDAOImpl().getAllCronSchedules(); for (CronScheduler schedule : schedulers) { addOrRunSchedule(scheduler, schedule); } scheduler.start(); } catch (SchedulerException se) { se.printStackTrace(); } catch (ParseException pe) { pe.printStackTrace(); } } private void addOrRunSchedule(Scheduler scheduler, CronScheduler schedule) throws SchedulerException, ParseException { int currentHour = DateUtil.getCurrentHour(); int currentMin = DateUtil.getCurrentMinute(); if (!schedule.getActive() || NEVER.equals(schedule.getCronStatement())) { return; } String jobName = schedule.getJobName(); System.out.println("Adding cron job: " + jobName); Class<? extends Job> targetJob = scheduleJobMap.get(jobName); if (targetJob == null) { return; } JobDetail job = newJob(targetJob).withIdentity(jobName + "Job", jobName).build(); Trigger trigger = newTrigger().withIdentity(jobName + "Trigger", jobName).withSchedule(cronSchedule(schedule.getCronStatement())) .forJob(jobName + "Job", jobName).build(); scheduler.scheduleJob(job, trigger); String[] cronParts = schedule.getCronStatement().split(" "); try { int cronHour = Integer.parseInt(cronParts[2]); if (cronHour < currentHour || (cronHour == currentHour && Integer.parseInt(cronParts[1]) < currentMin)) { new ImmediateRunner(scheduler, jobName).start(); } } catch (NumberFormatException e) { System.out.println("Malformed cron statement." + schedule.getCronStatement()); } } public void shutdown() throws SchedulerException { scheduler.shutdown(); } class ImmediateRunner extends Thread { private Scheduler scheduler; private String jobName; public ImmediateRunner(Scheduler scheduler, String jobName) { this.scheduler = scheduler; this.jobName = jobName; } @Override public void run() { try { // so everything doesn't happen at once long delay = 2000L * (Long) Math.round(Math.random() * 10); sleep(delay); synchronized (scheduler) { if (!scheduler.isShutdown()) { scheduler.triggerJob(new JobKey(jobName + "Job", jobName)); } } } catch (InterruptedException e) { e.printStackTrace(); } catch (SchedulerException e) { e.printStackTrace(); } } } }