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

xyz.erupt.job.service.EruptJobService Maven / Gradle / Ivy

The newest version!
package xyz.erupt.job.service;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.quartz.*;
import org.quartz.impl.JobDetailImpl;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.quartz.simpl.SimpleThreadPool;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.stereotype.Service;
import xyz.erupt.job.model.EruptJob;
import xyz.erupt.job.model.EruptJobLog;
import xyz.erupt.jpa.dao.EruptDao;

import javax.annotation.Resource;
import java.text.ParseException;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author YuePeng
 * date 2019-12-26
 */
@Service
public class EruptJobService implements DisposableBean {

    /**
     * 执行任务线程.
     */
    private static final String PROP_THREAD_COUNT = "org.quartz.threadPool.threadCount";
    /**
     * 执行任务线程数.
     */
    private static final int DEFAULT_THREAD_COUNT = 1;

    @Resource
    private EruptDao eruptDao;

    @Autowired(required = false)
    private JavaMailSenderImpl javaMailSender;

    @Resource
    @Getter
    StringRedisTemplate stringRedisTemplate;

    public static final String MAIL_SENDER_KEY = "mailSensor";

    private final Map schedulerFactoryMap = new ConcurrentHashMap<>();

    public void triggerJob(EruptJob eruptJob) {
        new EruptJobAction().trigger(eruptJob, javaMailSender);
    }

    public synchronized void addJob(EruptJob eruptJob) throws SchedulerException, ParseException {
        String code = eruptJob.getCode();
        if (!schedulerFactoryMap.containsKey(code)) {
            if (eruptJob.getStatus()) {
                StdSchedulerFactory ssf = new StdSchedulerFactory();
                ssf.initialize(getSchedulerProp(code));
                Scheduler scheduler = ssf.getScheduler();
                // job
                JobDetailImpl job = new JobDetailImpl();
                JobDataMap jobDataMap = new JobDataMap();
                jobDataMap.put(code, eruptJob);
                jobDataMap.put(MAIL_SENDER_KEY, javaMailSender);
                job.setJobDataMap(jobDataMap);
                job.setName(code);
                job.setJobClass(EruptJobAction.class);
                // trigger
                CronTriggerImpl trigger = new CronTriggerImpl();
                trigger.setName(code);
                trigger.setCronExpression(eruptJob.getCron());
                scheduler.scheduleJob(job, trigger);
                scheduler.start();
                schedulerFactoryMap.put(code, new EruptJobStdSchedulerFactory(eruptJob, ssf));
            }
        }
    }

    public synchronized void modifyJob(EruptJob eruptJob) throws SchedulerException, ParseException {
        if (schedulerFactoryMap.containsKey(eruptJob.getCode())) {
            if (eruptJob.equals(schedulerFactoryMap.get(eruptJob.getCode()).getEruptJob())) {
                return;
            } else {
                this.deleteJob(eruptJob);
            }
        }
        this.addJob(eruptJob);
    }

    public synchronized void deleteJob(EruptJob eruptJob) throws SchedulerException {
        EruptJobStdSchedulerFactory sf = schedulerFactoryMap.get(eruptJob.getCode());
        if (null != sf) {
            Scheduler scheduler = sf.getStdSchedulerFactory().getScheduler();
            scheduler.deleteJob(new JobKey(eruptJob.getCode()));
            if (!scheduler.isShutdown()) scheduler.shutdown();
            schedulerFactoryMap.remove(eruptJob.getCode());
        }
    }

    private Properties getSchedulerProp(String schedulerName) {
        Properties props = new Properties();
        props.setProperty(StdSchedulerFactory.PROP_SCHED_MAKE_SCHEDULER_THREAD_DAEMON, "true");
        props.setProperty(StdSchedulerFactory.PROP_SCHED_INTERRUPT_JOBS_ON_SHUTDOWN_WITH_WAIT, "true");
        props.setProperty(StdSchedulerFactory.PROP_SCHED_INTERRUPT_JOBS_ON_SHUTDOWN, "true");
        props.setProperty(StdSchedulerFactory.PROP_SCHED_INSTANCE_ID, "AUTO");
        props.setProperty(StdSchedulerFactory.PROP_SCHED_INSTANCE_NAME, schedulerName);
        props.setProperty(StdSchedulerFactory.PROP_THREAD_POOL_CLASS, SimpleThreadPool.class.getName());
        props.setProperty(PROP_THREAD_COUNT, Integer.toString(DEFAULT_THREAD_COUNT));
        return props;
    }

    public void saveJobLog(EruptJobLog eruptJobLog) {
        eruptDao.persistAndFlush(eruptJobLog);
    }

    @Override
    public void destroy() throws SchedulerException {
        for (EruptJobStdSchedulerFactory value : schedulerFactoryMap.values()) {
            value.getStdSchedulerFactory().getScheduler().shutdown();
        }
    }


    @Getter
    @Setter
    @NoArgsConstructor
    private static class EruptJobStdSchedulerFactory {

        private EruptJob eruptJob;

        private StdSchedulerFactory stdSchedulerFactory;

        public EruptJobStdSchedulerFactory(EruptJob eruptJob, StdSchedulerFactory stdSchedulerFactory) {
            this.eruptJob = eruptJob;
            this.stdSchedulerFactory = stdSchedulerFactory;
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy