com.turbospaces.quartz.QuartzFactoryBean Maven / Gradle / Ivy
package com.turbospaces.quartz;
import java.util.Objects;
import java.util.Properties;
import org.apache.commons.lang3.time.StopWatch;
import org.quartz.Job;
import org.quartz.JobKey;
import org.quartz.JobPersistenceException;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.matchers.GroupMatcher;
import org.quartz.plugins.history.LoggingJobHistoryPlugin;
import org.quartz.plugins.history.LoggingTriggerHistoryPlugin;
import org.quartz.simpl.SimpleJobFactory;
import org.quartz.spi.JobFactory;
import org.quartz.spi.TriggerFiredBundle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.AbstractFactoryBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import com.turbospaces.cfg.ApplicationProperties;
public class QuartzFactoryBean extends AbstractFactoryBean implements JobFactory, ApplicationContextAware {
protected final Logger log = LoggerFactory.getLogger(getClass());
protected ApplicationProperties props;
protected QuartzConfigurer configurer;
protected ApplicationContext applicationContext;
public QuartzFactoryBean(ApplicationProperties props) {
this.props = Objects.requireNonNull(props);
}
public QuartzFactoryBean(ApplicationProperties props, QuartzConfigurer configurer) {
this(props);
this.configurer = Objects.requireNonNull(configurer);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Override
public Job newJob(TriggerFiredBundle bundle, Scheduler schd) throws SchedulerException {
try {
JobFactory factory = new SimpleJobFactory();
return factory.newJob(bundle, getObject());
} catch (Exception err) {
throw new SchedulerException(err);
}
}
@Override
public Class> getObjectType() {
return Scheduler.class;
}
@Override
protected Scheduler createInstance() throws Exception {
Properties map = new Properties();
map.put("org.quartz.threadPool.threadCount", props.QUARTZ_WORKER_POOL_COUNT.get().toString());
map.put("org.quartz.scheduler.instanceName", props.CLOUD_APP_ID.get());
map.put("org.quartz.scheduler.instanceId", props.QUARTZ_SCHEDULER_ID.get());
map.put("org.quartz.scheduler.makeSchedulerThreadDaemon", Boolean.TRUE.toString());
map.put("org.quartz.scheduler.skipUpdateCheck", Boolean.TRUE.toString());
map.put("org.quartz.plugin.triggerHistory.class", LoggingTriggerHistoryPlugin.class.getName());
map.put("org.quartz.plugin.jobHistory.class", LoggingJobHistoryPlugin.class.getName());
StdSchedulerFactory schedulerFactory = new StdSchedulerFactory();
configurer.configureQuartz(map, schedulerFactory);
schedulerFactory.initialize(map);
Scheduler scheduler = schedulerFactory.getScheduler();
scheduler.setJobFactory(this);
if (props.QUARTZ_AUTO_REMOVE_JOBS_WITH_MISSING_CLASSES_ENABLED.get()) {
autoRemoveJobsWithMissingJobClasses(scheduler);
}
return scheduler;
}
private void autoRemoveJobsWithMissingJobClasses(Scheduler scheduler) throws SchedulerException {
log.debug("Looking for jobs with missing classes...");
for (JobKey jobKey : scheduler.getJobKeys(GroupMatcher.anyGroup())) {
log.trace("Checking job key: {}", jobKey);
try {
if (scheduler.getJobDetail(jobKey) != null) {
scheduler.getJobDetail(jobKey).getJobClass();
}
} catch (JobPersistenceException e) {
if (e.getCause() instanceof ClassNotFoundException classNotFoundEx) {
log.warn("Failed to load Java class ({}) for job key '{}'. Job is about to be automatically deleted",
classNotFoundEx.getMessage(), jobKey);
scheduler.deleteJob(jobKey);
}
}
}
}
@Override
protected void destroyInstance(Scheduler instance) throws Exception {
if (instance != null) {
StopWatch stopWatch = StopWatch.createStarted();
boolean waitForCompletion = props.QUARTZ_SHUTDOWN_WAIT_FOR_JOBS_COMPLETION.orElse(props.isDevMode()).get();
log.info("about to shutdown quartz now ...");
instance.shutdown(waitForCompletion);
stopWatch.stop();
log.info("shut down quartz in {}", stopWatch);
}
}
}