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

cn.dceast.platform.task.quartz.SchedulerUtil Maven / Gradle / Ivy

The newest version!
package cn.dceast.platform.task.quartz;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.commons.beanutils.BeanUtils;
import org.quartz.CronScheduleBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.JobListener;
import org.quartz.Scheduler;
import org.quartz.SchedulerListener;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.matchers.GroupMatcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.dceast.platform.task.config.TaskConfig;
import cn.dceast.platform.task.quartz.data.DataFactory;
import cn.dceast.platform.task.quartz.data.OutputJobToDataBaseService;
import cn.dceast.platform.task.quartz.data.OutputJobToDataBaseService.jobAction;
import cn.dceast.platform.task.quartz.exception.SchedulerException;
import cn.dceast.platform.task.quartz.job.PlatformJob;


public class SchedulerUtil {
    private static Scheduler scheduler = null;
    public static final String JOB_DATAMAP = "platform-jobinfo";

    private static Logger logger = LoggerFactory.getLogger(SchedulerUtil.class);

    /**
     * 初始化任务调度容器
     */
    public static synchronized void init() {
        if (scheduler != null) {
            logger.warn("The Sheduler Container was Started!");
            return;
        }

        try {
            scheduler = StdSchedulerFactory.getDefaultScheduler();
        } catch (org.quartz.SchedulerException e) {
            e.printStackTrace();
            throw new SchedulerException("Can not get Scheduler instance from StdSchedulerFactory!");
        }

    }

    /**
     * 启动job容器
     */
    public static void start() {
        if (scheduler == null) {
            throw new SchedulerException("The scheduler isn't initialized!");
        }

        try {
            if (!scheduler.isStarted()) {
                scheduler.start();
            }
        } catch (org.quartz.SchedulerException e) {
            e.printStackTrace();
            throw new SchedulerException("The scheduler cannot be started!");
        }
    }

    /**
     * 停止job容器。此方法在所有job执行结束之前一直阻塞。
     */
    public static void shutdown() {
        if (scheduler == null) {
            logger.warn("The scheduler doesn't exists!");
        }

        try {
            scheduler.shutdown(true);
        } catch (org.quartz.SchedulerException e) {
            e.printStackTrace();
        }
    }

    /**
     * 新增job
     *
     * @param job job
     * @return JobDetail
     */
    public static JobDetail addJob(JobEntity job) {
        String jobClass = job.getJobClass();
        Class clz = null;
        String jobGroup = job.getJobGroup();
        String jobName = job.getJobName();
        String cronExpresstion = job.getCronExpression();
        int priority = job.getPriority();

        if (job.getCreateTime() == null) {
            job.setCreateTime(new Date());
        }

        if (job.getJobId() == null || "".equals(job.getJobId())) {
            job.setJobId(DataFactory.getOutputJobInfoExecutor().getNextJobId());
        }

        job.setAppName(TaskConfig.appName);

        try {
            clz = (Class) Class.forName(jobClass);
        } catch (Exception e) {
            throw new SchedulerException("【" + jobClass + "】JobClass dost not exits or class isn't valid!");
        }


        logger.info("add job:{}", job);

        JobDetail jd = JobBuilder.newJob(clz)
                .withIdentity(jobName, jobGroup)
                .build();

        jd.getJobDataMap().put(JOB_DATAMAP, job);

        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpresstion);

        Trigger ct = TriggerBuilder.newTrigger()
                .withIdentity(jobName, jobGroup)
                .withSchedule(scheduleBuilder)
                .withPriority(priority)
                .build();

        ct.getJobDataMap().put(JOB_DATAMAP, job);
        try {
            scheduler.scheduleJob(jd, ct);
        } catch (org.quartz.SchedulerException e) {
            e.printStackTrace();
            throw new SchedulerException("Fail to add job!Detail:" + e.getMessage());
        }

        return jd;
    }

    /**
     * 更新job
     * 更新job将会删除旧的job,重新生成新的job
     *
     * @param job job
     */
    public static void updateJob(JobEntity job) {
        job.setUpdateTime(new Date());

        JobExecutedEntity jee = DataFactory.getOutputJobInfoExecutor().getJob(job.getJobId());

        logger.info("update job:{} to {}", jee, job);
        //不能删除历史纪录
        removeJob(jee.getJobId(), jobAction.UPDATE.name());

        addJob(job);

    }

    /**
     * 检查job是否存在
     *
     * @param jobGroup job分组
     * @param jobName  job名称
     * @return true-job存在;false-job不存在;
     */
    public static boolean checkExists(String jobGroup, String jobName) {
        JobKey jobKey = new JobKey(jobName, jobGroup);
        try {
            boolean isExists = scheduler.checkExists(jobKey);
            return isExists;
        } catch (org.quartz.SchedulerException e) {
            e.printStackTrace();
            throw new SchedulerException(e.getMessage());
        }
    }

    /**
     * 根据jobId删除job
     *
     * @param jobId  jobId
     * @param action action
     */
    public static void removeJob(String jobId, String action) {
        JobExecutedEntity jee = DataFactory.getOutputJobInfoExecutor().getJob(jobId);
        removeJob(jee, action);
    }

    /**
     * 根据groupName和jobName删除job
     *
     * @param groupName groupName
     * @param jobName   jobName
     * @param action action
     */
    public static void removeJob(String groupName, String jobName, String action) {
        JobExecutedEntity jee = DataFactory.getOutputJobInfoExecutor().getJob(groupName, jobName);
        removeJob(jee, action);
    }

    private static void removeJob(JobExecutedEntity jee, String action) {
        try {

            if (jee == null) {
                logger.warn("The job is not exists!");
                return;
            }

            String jobGroup = jee.getJobGroup();
            String jobName = jee.getJobName();

            logger.info("delete jobGroup:" + jobGroup + " jobName:" + jobName + " jobAction:" + action);

            if (jee.getStatus().equals(Trigger.TriggerState.BLOCKED)) {
                throw new SchedulerException("job is executing!");
            }

            scheduler.pauseTrigger(TriggerKey.triggerKey(jobName, jobGroup));
            scheduler.unscheduleJob(TriggerKey.triggerKey(jobName, jobGroup));
            scheduler.deleteJob(JobKey.jobKey(jobName, jobGroup));

            /**
             * 此段逻辑不能使用listener来实现,应用一旦job删除,将会删除quartz、db中的所有数据。
             * 1. 保存操作历史使用需要job数据;
             * 2. 目前更新job操作通过,先删除再新增方式操作,所以如果是更新操作,不能删除历史纪录
             */
            DataFactory.getOutputJobInfoExecutor().addJobLifecycleManageLog(jee, OutputJobToDataBaseService.jobAction.DELETE.name());
            if (!jobAction.UPDATE.name().equals(action)) {
                DataFactory.getOutputJobInfoExecutor().deleteJob(jee.getJobId());
            }

        } catch (Exception e) {
            e.printStackTrace();
            throw new SchedulerException(String.format("Fail to remove Job! [jobId:%s] detail:%s", jee.getJobId(), e.getMessage()));
        }
    }

    /**
     * 删除job
     *
     * @param jobGroup jobGroup
     * @param jobName  jobName
     */
    public static void removeJobAfterAddJobFail(String jobGroup, String jobName) {
        try {
            scheduler.pauseTrigger(TriggerKey.triggerKey(jobName, jobGroup));
            scheduler.unscheduleJob(TriggerKey.triggerKey(jobName, jobGroup));
            scheduler.deleteJob(JobKey.jobKey(jobName, jobGroup));
        } catch (Exception e) {
            e.printStackTrace();
            throw new SchedulerException(String.format("Fail to remove Job! [jobGroup:%s  jobName:%s] detail:%s", jobGroup, jobName, e.getMessage()));
        }

    }

    /**
     * 暂停job执行
     *
     * @param jobId jobId
     */
    public static void pauseJob(String jobId) {
        try {
            JobExecutedEntity jee = DataFactory.getOutputJobInfoExecutor().getJob(jobId);
            if (jee == null) {
                return;
            }
            if (jee.getStatus().equals(Trigger.TriggerState.BLOCKED)) {
                throw new SchedulerException("job is executing!");
            }

            scheduler.pauseJob(JobKey.jobKey(jee.getJobName(), jee.getJobGroup()));
        } catch (Exception e) {
            e.printStackTrace();
            throw new SchedulerException(String.format("Fail to pause job! [jobId:%s] detail:%s", jobId, e.getMessage()));
        }
    }

    /**
     * 暂停所有job执行
     */
    public static void pauseAll() {
        try {
            scheduler.pauseAll();
        } catch (Exception e) {
            e.printStackTrace();
            throw new SchedulerException("Fail to pause job!");
        }

    }

    /**
     * 恢复job执行
     *
     * @param jobId jobId
     */
    public static void resumeJob(String jobId) {
        try {

            JobExecutedEntity jee = DataFactory.getOutputJobInfoExecutor().getJob(jobId);
            if (jee == null) {
                return;
            }

            if (jee.getStatus().equals(Trigger.TriggerState.BLOCKED)) {
                throw new SchedulerException("job is executing!");
            }

            JobKey jobKey = JobKey.jobKey(jee.getJobName(), jee.getJobGroup());
            if (scheduler.checkExists(jobKey)) {
                scheduler.resumeJob(jobKey);
            } else {
                if (Trigger.TriggerState.ERROR.name().equals(jee.getStatus())) {
                    jee.setStatus(Trigger.TriggerState.NORMAL.name());
                    addJob(jee);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
            throw new SchedulerException(String.format("Fail to resume job! [jobId:%s] detail:%s", jobId, e.getMessage()));
        }
    }

    /**
     * 恢复所有的job执行
     */
    public static void resumeAll() {
        try {
            scheduler.resumeAll();
        } catch (Exception e) {
            e.printStackTrace();
            throw new SchedulerException("Fail to resume job!");
        }
    }

    /**
     * 代参数执行job
     *
     * @param jobId    jobId
     * @param jobParam jobParam
     */
    public static void executeJobImmediatelyWithParams(String jobId, String jobParam) {
        logger.info("====================executeJobImmediatelyWithParams======================");
        JobExecutedEntity jee = DataFactory.getOutputJobInfoExecutor().getJob(jobId);
        if (jee == null) {
            return;
        }

        if (jee.getStatus().equals(Trigger.TriggerState.BLOCKED)) {
            throw new SchedulerException("job is executing!");
        }
        String jobName = jee.getJobName(), jobGroup = jee.getJobGroup();

        try {

            logger.info(String.format("Executing job immediately with parameters! [jobGroup:%s  jobName:%s  jobParam:%s]", jobGroup, jobName, jobParam));

            JobDetail jd = scheduler.getJobDetail(JobKey.jobKey(jobName, jobGroup));

            if (jd == null) {
                throw new SchedulerException("Job is not exists!");
            }

            Trigger oldTrigger = scheduler.getTrigger(TriggerKey.triggerKey(jobName, jobGroup));
            if (oldTrigger == null) {
                throw new SchedulerException("The trigger of job is not exists!");
            }

            JobEntity je = (JobEntity) oldTrigger.getJobDataMap().get(JOB_DATAMAP);
            JobEntity newJe = new JobEntity();
            BeanUtils.copyProperties(newJe, je);
            newJe.setJobParam(jobParam);

            //jobDetail里dataMap需要
            //jd.getJobDataMap().put(JOB_DATAMAP, newJe);

            Trigger newTrigger = TriggerBuilder.newTrigger()
                    .withIdentity(jobName + "_1", jobGroup + "_1")
                    .startNow()
                    .forJob(jd)
                    .build();
            newTrigger.getJobDataMap().put(JOB_DATAMAP, newJe);

            logger.debug("NewTrigger params toString:" + newJe.getJobParam());
            Set set = new HashSet();
            set.add(newTrigger);

            logger.debug("SchedulerUtil scheduleJob ******" + jobParam);
            scheduler.scheduleJob(jd, set, true);

        } catch (Exception e) {
            e.printStackTrace();
            throw new SchedulerException(String.format("Fail to execute job! [jobGroup:%s  jobName:%s].detail:%s", jobGroup, jobName, e.getMessage()));
        }
    }

    /**
     * 删除所有job包括job的执行数据
     */
    public static void clear() {
        try {
            scheduler.clear();
        } catch (Exception e) {
            e.printStackTrace();
            throw new SchedulerException("Fail to clear all job data!");
        }

    }

    /**
     * 获取所有的job清单
     *
     * @return List
     */
    public static List getJobs() {
        try {

            //jobGroup,jobName,jobClass,创建时间、本次执行开始时间、本次实际执行开始时间、本次执行耗时(ms)执行耗时无法获取、下次执行开始时间 状态  操作

            GroupMatcher matcher = GroupMatcher.anyJobGroup();
            Set jobKeys = scheduler.getJobKeys(matcher);

            if (jobKeys == null) {
                return null;
            }

            Iterator iter = jobKeys.iterator();

            List resultList = new ArrayList();
            while (iter.hasNext()) {
                JobKey jobKey = iter.next();
                resultList.add(getJob(jobKey.getGroup(), jobKey.getName()));
            }

            return resultList;

        } catch (Exception e) {
            e.printStackTrace();
            throw new SchedulerException("Fail to get jobs!");
        }

    }

    public static JobExecutedEntity getJob(String jobGroup, String jobName) {
        try {
            JobDetail jd = scheduler.getJobDetail(JobKey.jobKey(jobName, jobGroup));

            //立即运行是,使用子线程方式,此jobgroup与jobName不存在
            if (jd == null) {
                return null;
            }
            //job参数
            JobEntity jobEntity = (JobEntity) jd.getJobDataMap().get(JOB_DATAMAP);

            JobExecutedEntity jee = new JobExecutedEntity();
            BeanUtils.copyProperties(jee, jobEntity);

            Trigger trigger = scheduler.getTrigger(TriggerKey.triggerKey(jobName, jobGroup));

            jee.setFireTime(trigger.getPreviousFireTime());
            jee.setFinalFireTime(trigger.getFinalFireTime());
            jee.setNextFireTime(trigger.getNextFireTime());
            jee.setStartTime(trigger.getStartTime());
            jee.setEndTime(trigger.getEndTime());

            jee.setStatus(scheduler.getTriggerState(TriggerKey.triggerKey(jobName, jobGroup)).name());

            return jee;
        } catch (Exception e) {
            e.printStackTrace();
            throw new SchedulerException("Fail to get job!");
        }

    }

    public static void addSchedulerListener(SchedulerListener schedulerListener) {
        try {
            scheduler.getListenerManager().addSchedulerListener(schedulerListener);
        } catch (Exception e) {
            e.printStackTrace();
            throw new SchedulerException("Fail to add schedulerListener!");
        }
    }

    public static void addJobListener(JobListener jobListener) {
        try {
            scheduler.getListenerManager().addJobListener(jobListener);
        } catch (org.quartz.SchedulerException e) {
            e.printStackTrace();
            throw new SchedulerException("Fail to add jobListener!");
        }
    }

    public static void unSchedulerJob(String jobGroup, String jobName) {
        try {
            scheduler.unscheduleJob(TriggerKey.triggerKey(jobName, jobGroup));
        } catch (org.quartz.SchedulerException e) {
            e.printStackTrace();
            throw new SchedulerException("Fail to unSchedulerJob!");
        }
    }

    public static String getSchedulerInstanceId() {
        try {
            return scheduler.getSchedulerInstanceId();
        } catch (org.quartz.SchedulerException e) {
            e.printStackTrace();
        }

        return null;
    }


//	public static List getCurrentExecutingJobs(){
//
//		try{
//			List list=scheduler.getCurrentlyExecutingJobs();
//		}catch(Exception e){
//			e.printStackTrace();
//			throw new SchedulerException("Fail to get current executing jobs!");
//		}
//
//
//		return null;
//	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy