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

io.robe.quartz.QuartzBundle Maven / Gradle / Ivy

There is a newer version: 0.5.0.0-1039
Show newest version
package io.robe.quartz;

import io.dropwizard.Configuration;
import io.dropwizard.ConfiguredBundle;
import io.dropwizard.setup.Bootstrap;
import io.dropwizard.setup.Environment;
import io.robe.quartz.common.JobInfo;
import io.robe.quartz.common.JobProvider;
import io.robe.quartz.common.TriggerInfo;
import io.robe.quartz.configuration.HasQuartzConfiguration;
import io.robe.quartz.configuration.QuartzConfiguration;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.reflections.Reflections;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 * Configures  Quartz.
 * Collect {@link io.robe.quartz.common.JobProvider} classes
 * Initializes scheduler
 * Collects all subtypes of {@link org.quartz.Job} annotated with {@link io.robe.quartz.job.schedule.QJob} including {@link @QTrigger}'s
 * * Collects additional triggers from providers
 * * Registers them all for future control.
 * Holds application start and end triggered jobs for managed access.
 * Provides Job & Trigger Registery
 */
public class QuartzBundle implements ConfiguredBundle {
    private static final Logger LOGGER = LoggerFactory.getLogger(QuartzBundle.class);
    private List providers = null;
    private Set onStartJobs = null;
    private Set onStopJobs = null;


    public QuartzBundle() {
    }


    /**
     * Initializes the environment. Forwards the configuration to Quartz.
     * Collect {@link io.robe.quartz.common.JobProvider} classes
     * Initializes scheduler
     * Collects all subtypes of {@link org.quartz.Job} annotated with {@link io.robe.quartz.job.schedule.QJob} including {@link @QTrigger}'s
     * * Collects additional triggers from providers
     * * Registers them all for future control.
     *
     * @param configuration the configuration object
     * @param environment   the service's {@link io.dropwizard.setup.Environment}
     * @throws Exception if something goes wrong
     */
    @Override
    public void run(T configuration, Environment environment) {
        QuartzConfiguration qConf = configuration.getQuartzConfiguration();
        try {

            initializeScheduler(extractProperties(qConf));
            collectProviders(qConf.getProviders());
            collectAndScheduleJobs(qConf.getScanPackages());

            environment.lifecycle().manage(new ManagedQuartz(getOnStartJobs(),getOnStopJobs()));

        } catch (SchedulerException e) {
            LOGGER.error("SchedulerException:", e);
        }
    }

    /**
     * Just sets necessary properties for quartz.
     *
     * @param quartzConfiguration
     * @return
     */
    private Properties extractProperties(QuartzConfiguration quartzConfiguration) {
        Properties properties = new Properties();
        properties.setProperty("org.quartz.scheduler.instanceName", quartzConfiguration.getInstanceName());
        properties.setProperty("org.quartz.threadPool.threadCount", String.valueOf(quartzConfiguration.getThreadCount()));
        properties.setProperty("org.quartz.threadPool.threadPriority", String.valueOf(quartzConfiguration.getThreadPriority()));
        properties.setProperty("org.quartz.scheduler.skipUpdateCheck", quartzConfiguration.getSkipUpdateCheck());
        //Set jobstore properties.
        properties.setProperty("org.quartz.jobStore.class", quartzConfiguration.getJobStore().getClassName());
        //Forward jobstore properties directly
        if (quartzConfiguration.getJobStore().getProperties() != null) {
            properties.putAll(quartzConfiguration.getJobStore().getProperties());
        }
        return properties;
    }

    /**
     * Initialize scheduler and start JobManager
     * @param properties
     * @throws SchedulerException
     */
    private void initializeScheduler(Properties properties) throws SchedulerException {
        SchedulerFactory factory = new StdSchedulerFactory(properties);
        Scheduler scheduler = factory.getScheduler();
        scheduler.start();
        JobManager.initialize(scheduler);
    }

    private void collectAndScheduleJobs(String[] packages) throws SchedulerException {
        Set> quartzJobs;

        onStartJobs = new HashSet<>();
        onStopJobs = new HashSet<>();

        for (String pkg : packages) {
            LOGGER.info("Scanning Jobs package : " + pkg);
            Reflections reflections = new Reflections(pkg);
            quartzJobs = reflections.getSubTypesOf(Job.class);

            for (Class clazz : quartzJobs) {
                //Collect all provided triggers
                Set triggers = new HashSet<>();

                for (JobProvider provider : providers) {
                    JobInfo jInfo = provider.getJob(clazz);
                    if (jInfo == null)
                        continue;

                    LOGGER.info("\nJob " + jInfo.getClass().getName() + "\n\tName: " + jInfo.getName() + "\n\tDesc: " + jInfo.getDescription());

                    JobDetail jobDetail = JobProvider.convert2JobDetail(jInfo);

                    //Collect all triggers
                    for (TriggerInfo tInfo : jInfo.getTriggers()) {

                        LOGGER.info("Trigger " + clazz.getName() + "\n\tName: " + tInfo.getName() + "\n\tType: " + tInfo.getType().name());

                        if (tInfo.getType().equals(TriggerInfo.Type.ON_APP_START)) {
                            onStartJobs.add(jobDetail);
                        } else if (tInfo.getType().equals(TriggerInfo.Type.ON_APP_STOP)) {
                            onStopJobs.add(jobDetail);
                        } else {
                            triggers.add(JobProvider.convert2Trigger(tInfo));
                        }
                    }

                    JobManager.getInstance().scheduleJob(jobDetail, triggers, true);

                }

                //TODO: Register Triggers for future access.


            }
        }
    }

    /**
     * Collects all custom providers at scan packages.
     * Creates instances and stores for usage.
     *
     * @param packages
     */
    private void collectProviders(String[] packages) {
        providers = new LinkedList<>();
        for (String pkg : packages) {
            LOGGER.info("Scanning Provider package : " + pkg);
            Reflections reflections = new Reflections(pkg);
            Set> classses = reflections.getSubTypesOf(JobProvider.class);
            for (Class clazz : classses) {
                try {
                    JobProvider provider = clazz.newInstance();
                    LOGGER.info("Provider found : " + clazz.getName());
                    providers.add(provider);
                } catch (Exception e) {
                    LOGGER.error(clazz.getName(), e);
                }
            }
        }
    }


    /**
     * Initializes the service bootstrap.
     *
     * @param bootstrap the service bootstrap
     */
    @Override
    public void initialize(Bootstrap bootstrap) {
        LOGGER.info("Initializing QuartzBundle");
    }

    public Set getOnStartJobs() {
        return onStartJobs;
    }

    public Set getOnStopJobs() {
        return onStopJobs;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy