package com.constellio.data.threads; import org.apache.commons.collections.CollectionUtils; import org.joda.time.DateTime; import org.quartz.CronExpression; import org.quartz.CronScheduleBuilder; import org.quartz.DisallowConcurrentExecution; import org.quartz.Job; import org.quartz.JobBuilder; import org.quartz.JobDetail; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.quartz.JobKey; import org.quartz.Scheduler; import org.quartz.SimpleScheduleBuilder; import org.quartz.Trigger; import org.quartz.TriggerBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.text.ParseException; import java.util.Date; import java.util.HashSet; import java.util.Set; import java.util.TreeSet; /** * */ @DisallowConcurrentExecution public abstract class ConstellioJob implements Job { private final Logger LOGGER = LoggerFactory.getLogger(getClass()); @Override public final void execute(JobExecutionContext context) throws JobExecutionException { final JobKey jobKey = context.getJobDetail().getKey(); try { LOGGER.info("job fired"); action().run(); LOGGER.info("job finished"); } catch (final Throwable t) { final JobExecutionException jobExecutionException = new JobExecutionException(t); jobExecutionException.setUnscheduleFiringTrigger(unscheduleOnException()); throw jobExecutionException; } } protected abstract String name(); protected abstract Runnable action(); protected abstract boolean unscheduleOnException(); protected abstract Set<Integer> intervals(); protected abstract Set<String> cronExpressions(); protected Date startTime() { return null; } JobDetail buildJobDetail() { return JobBuilder. newJob(getClass()). withIdentity(name(), Scheduler.DEFAULT_GROUP). build(); } Set<Trigger> buildIntervalTriggers() { final Set<Trigger> triggers = new HashSet<>(); Set<Integer> intervals = intervals(); if (CollectionUtils.isNotEmpty(intervals)) { intervals = new TreeSet<>(intervals); for (final int interval : intervals) { final TriggerBuilder triggerBuilder = TriggerBuilder. newTrigger(). withIdentity(name() + "-Trigger-" + interval, Scheduler.DEFAULT_GROUP). withSchedule(SimpleScheduleBuilder. simpleSchedule(). withIntervalInSeconds(interval). repeatForever()); if (startTime() == null) { triggerBuilder.startAt(DateTime.now().plusSeconds(interval).toDate()); } else { triggerBuilder.startAt(startTime()); } triggers.add(triggerBuilder.build()); } } return triggers; } Set<Trigger> buildCronTriggers() { final Set<Trigger> triggers = new HashSet<>(); Set<String> cronExpressions = cronExpressions(); if (CollectionUtils.isNotEmpty(cronExpressions)) { cronExpressions = new TreeSet<>(cronExpressions); for (final String cronExpression : cronExpressions) { try { final TriggerBuilder triggerBuilder = TriggerBuilder. newTrigger(). withIdentity(name() + "-Trigger-" + cronExpression, Scheduler.DEFAULT_GROUP). withSchedule(CronScheduleBuilder. cronSchedule(cronExpression)); ; if (startTime() == null) { triggerBuilder.startAt( new CronExpression(cronExpression).getNextValidTimeAfter(new Date())); } else { triggerBuilder.startAt(startTime()); } triggers.add(triggerBuilder.build()); } catch (final ParseException e) { LOGGER.error("invalid cron expression " + cronExpression , e); } } } return triggers; } }