All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy