package org.ovirt.engine.core.utils.timer;
import static org.quartz.TriggerBuilder.newTrigger;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.apache.commons.lang.StringUtils;
import org.ovirt.engine.core.common.config.Config;
import org.ovirt.engine.core.common.config.ConfigValues;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobListener;
import org.quartz.SchedulerException;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.TriggerKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The FixedDelayJobListener is a JobListener implementation to turn a job into
* a fixed delay job. A fixed delay job means that the delay is fixed between
* any 2 successive executions of the job.
*
*/
public class FixedDelayJobListener implements JobListener {
Logger logger = LoggerFactory.getLogger(FixedDelayJobListener.class);
// const
public static final String FIXED_JOB_LISTENER_NAME = "fixedJobListenerName";
public SchedulerUtil sched;
/**
* create a new Job Listener.
*
* @param scheduler
* - the scheduler used rescheduling the next job
*/
public FixedDelayJobListener(SchedulerUtil scheduler) {
sched = scheduler;
}
/**
* @return the jobListener constant name
*/
@Override
public String getName() {
return FIXED_JOB_LISTENER_NAME;
}
/**
* reschedule the job with a new trigger. The new trigger will fire within a
* fixed time from the method execution.
*
* @see org.quartz.JobListener#jobWasExecuted(JobExecutionContext,
* JobExecutionException)
*/
@Override
public void jobWasExecuted(JobExecutionContext context, JobExecutionException exception) {
// Get the details of the job:
JobDetail jobdetail = context.getJobDetail();
JobDataMap data = jobdetail.getJobDataMap();
// This is being called for all our jobs, so first check if this is a fixed delay
// job and if not just exit:
if (!data.containsKey(SchedulerUtilBaseImpl.FIXED_DELAY_VALUE)) {
return;
}
// This Job might already have an unused trigger in place, use it
List<? extends Trigger> triggersOfJob = null;
try {
triggersOfJob = context.getScheduler().getTriggersOfJob(context.getJobDetail().getKey());
} catch (SchedulerException e) {
// ignore
}
if (triggersOfJob != null
&& triggersOfJob.stream()
.filter(t -> t instanceof SimpleTrigger)
.anyMatch(t -> ((SimpleTrigger) t).getTimesTriggered() == 0)) {
logger.debug("Not scheduling {} again as there is still an unfired trigger.", context.getJobDetail().getKey());
return;
} else {
logger.debug("Rescheduling {} as there is no unfired trigger.", context.getJobDetail().getKey());
}
// generate the new trigger time
String configValueName = data.getString(SchedulerUtilBaseImpl.CONFIGURABLE_DELAY_KEY_NAME);
long delay;
if (StringUtils.isEmpty(configValueName)) {
delay = data.getLongValue(SchedulerUtilBaseImpl.FIXED_DELAY_VALUE);
} else {
ConfigValues configDelay = ConfigValues.valueOf(configValueName);
delay = Config.<Integer> getValue(configDelay).longValue();
}
TimeUnit delayUnit = (TimeUnit) data.getWrappedMap().get(SchedulerUtilBaseImpl.FIXED_DELAY_TIME_UNIT);
Date runTime = SchedulerUtilQuartzImpl.getFutureDate(delay, delayUnit);
// generate the new trigger
Trigger oldTrigger = context.getTrigger();
TriggerKey oldTriggerKey = oldTrigger.getKey();
Trigger newTrigger = newTrigger()
.withIdentity(oldTriggerKey)
.startAt(runTime)
.build();
// schedule the new trigger
sched.rescheduleAJob(oldTriggerKey.getName(), oldTriggerKey.getGroup(), newTrigger);
// SchedulerUtilQuartzImpl.getInstance().rescheduleAJob(oldTriggerName,
// oldTriggerGroup, newTrigger);
}
@Override
public void jobExecutionVetoed(JobExecutionContext arg0) {
// empty implementation
}
@Override
public void jobToBeExecuted(JobExecutionContext arg0) {
// empty implementation
}
}