|
@@ -0,0 +1,308 @@
|
|
|
+package cn.com.qmth.task.base;
|
|
|
+
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Set;
|
|
|
+
|
|
|
+import org.quartz.CronScheduleBuilder;
|
|
|
+import org.quartz.CronTrigger;
|
|
|
+import org.quartz.Job;
|
|
|
+import org.quartz.JobBuilder;
|
|
|
+import org.quartz.JobDetail;
|
|
|
+import org.quartz.JobExecutionContext;
|
|
|
+import org.quartz.JobKey;
|
|
|
+import org.quartz.Scheduler;
|
|
|
+import org.quartz.SchedulerException;
|
|
|
+import org.quartz.Trigger;
|
|
|
+import org.quartz.TriggerBuilder;
|
|
|
+import org.quartz.TriggerKey;
|
|
|
+import org.quartz.impl.matchers.GroupMatcher;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.scheduling.quartz.SchedulerFactoryBean;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+
|
|
|
+import cn.com.qmth.examcloud.commons.base.exception.ExamCloudRuntimeException;
|
|
|
+import cn.com.qmth.examcloud.commons.base.logging.ExamCloudLog;
|
|
|
+import cn.com.qmth.examcloud.commons.base.logging.ExamCloudLogFactory;
|
|
|
+import cn.com.qmth.examcloud.commons.base.util.JsonUtil;
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ * Quartz 管理器
|
|
|
+ *
|
|
|
+ * @author WANGWEI
|
|
|
+ * @date 2018年3月7日
|
|
|
+ * @Copyright (c) 2018-2020 WANGWEI [QQ:522080330] All Rights Reserved.
|
|
|
+ */
|
|
|
+@Component
|
|
|
+public class QuartzManager
|
|
|
+{
|
|
|
+ private static final ExamCloudLog TASK_LOG = ExamCloudLogFactory.getLog("TASK_LOGGER");
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private SchedulerFactoryBean schedulerFactoryBean;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 添加任务
|
|
|
+ *
|
|
|
+ * @author WANGWEI
|
|
|
+ * @param job
|
|
|
+ */
|
|
|
+ public void addJob(ScheduleJob job)
|
|
|
+ {
|
|
|
+ if (TASK_LOG.isDebugEnabled())
|
|
|
+ {
|
|
|
+ TASK_LOG.debug("add a job. job detail: " + JsonUtil.toJson(job));
|
|
|
+ }
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ Scheduler scheduler = schedulerFactoryBean.getScheduler();
|
|
|
+ TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());
|
|
|
+
|
|
|
+ CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
|
|
|
+
|
|
|
+ if (null == trigger)
|
|
|
+ {
|
|
|
+ Class<? extends Job> jobClass = job.isStateful()
|
|
|
+ ? StatefulDistributionJob.class
|
|
|
+ : DistributionJob.class;
|
|
|
+ JobDetail jobDetail = JobBuilder.newJob(jobClass)
|
|
|
+ .withIdentity(job.getJobName(), job.getJobGroup()).build();
|
|
|
+
|
|
|
+ jobDetail.getJobDataMap().put("scheduleJob", job);
|
|
|
+
|
|
|
+ CronScheduleBuilder scheduleBuilder = CronScheduleBuilder
|
|
|
+ .cronSchedule(job.getCronExpression());
|
|
|
+
|
|
|
+ trigger = TriggerBuilder.newTrigger()
|
|
|
+ .withIdentity(job.getJobName(), job.getJobGroup())
|
|
|
+ .withSchedule(scheduleBuilder).build();
|
|
|
+
|
|
|
+ scheduler.scheduleJob(jobDetail, trigger);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ CronScheduleBuilder scheduleBuilder = CronScheduleBuilder
|
|
|
+ .cronSchedule(job.getCronExpression());
|
|
|
+
|
|
|
+ trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
|
|
|
+ .withSchedule(scheduleBuilder).build();
|
|
|
+
|
|
|
+ scheduler.rescheduleJob(triggerKey, trigger);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (SchedulerException e)
|
|
|
+ {
|
|
|
+ TASK_LOG.error("Fail to add a job. job detail: " + JsonUtil.toJson(job), e);
|
|
|
+ throw new ExamCloudRuntimeException(e);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (TASK_LOG.isDebugEnabled())
|
|
|
+ {
|
|
|
+ TASK_LOG.debug("add a job successfully. job detail: " + JsonUtil.toJson(job));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取所有计划中的任务列表
|
|
|
+ *
|
|
|
+ * @author WANGWEI
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public List<ScheduleJob> getAllJobs()
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ Scheduler scheduler = schedulerFactoryBean.getScheduler();
|
|
|
+ GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
|
|
|
+ Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
|
|
|
+ List<ScheduleJob> jobList = new ArrayList<ScheduleJob>();
|
|
|
+ for (JobKey jobKey : jobKeys)
|
|
|
+ {
|
|
|
+ List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
|
|
|
+ for (Trigger trigger : triggers)
|
|
|
+ {
|
|
|
+ ScheduleJob job = new ScheduleJob();
|
|
|
+ job.setJobName(jobKey.getName());
|
|
|
+ job.setJobGroup(jobKey.getGroup());
|
|
|
+ job.setDescription("触发器:" + trigger.getKey());
|
|
|
+ Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
|
|
|
+ job.setJobStatus(triggerState.name());
|
|
|
+ if (trigger instanceof CronTrigger)
|
|
|
+ {
|
|
|
+ CronTrigger cronTrigger = (CronTrigger) trigger;
|
|
|
+ String cronExpression = cronTrigger.getCronExpression();
|
|
|
+ job.setCronExpression(cronExpression);
|
|
|
+ }
|
|
|
+ jobList.add(job);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return jobList;
|
|
|
+ }
|
|
|
+ catch (SchedulerException e)
|
|
|
+ {
|
|
|
+ TASK_LOG.error("Fail to get all jobs.", e);
|
|
|
+ throw new ExamCloudRuntimeException(e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 所有正在运行的job
|
|
|
+ *
|
|
|
+ * @author WANGWEI
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public List<ScheduleJob> getRunningJobs()
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ Scheduler scheduler = schedulerFactoryBean.getScheduler();
|
|
|
+ List<JobExecutionContext> executingJobs = scheduler.getCurrentlyExecutingJobs();
|
|
|
+ List<ScheduleJob> jobList = new ArrayList<ScheduleJob>(executingJobs.size());
|
|
|
+ for (JobExecutionContext executingJob : executingJobs)
|
|
|
+ {
|
|
|
+ ScheduleJob job = new ScheduleJob();
|
|
|
+ JobDetail jobDetail = executingJob.getJobDetail();
|
|
|
+ JobKey jobKey = jobDetail.getKey();
|
|
|
+ Trigger trigger = executingJob.getTrigger();
|
|
|
+ job.setJobName(jobKey.getName());
|
|
|
+ job.setJobGroup(jobKey.getGroup());
|
|
|
+ job.setDescription("触发器:" + trigger.getKey());
|
|
|
+ Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
|
|
|
+ job.setJobStatus(triggerState.name());
|
|
|
+ if (trigger instanceof CronTrigger)
|
|
|
+ {
|
|
|
+ CronTrigger cronTrigger = (CronTrigger) trigger;
|
|
|
+ String cronExpression = cronTrigger.getCronExpression();
|
|
|
+ job.setCronExpression(cronExpression);
|
|
|
+ }
|
|
|
+ jobList.add(job);
|
|
|
+ }
|
|
|
+ return jobList;
|
|
|
+ }
|
|
|
+ catch (Exception e)
|
|
|
+ {
|
|
|
+ TASK_LOG.error("Fail to get running jobs.", e);
|
|
|
+ throw new ExamCloudRuntimeException(e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 暂停一个job
|
|
|
+ *
|
|
|
+ * @author WANGWEI
|
|
|
+ * @param scheduleJob
|
|
|
+ */
|
|
|
+ public void pauseJob(ScheduleJob scheduleJob)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ Scheduler scheduler = schedulerFactoryBean.getScheduler();
|
|
|
+ JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
|
|
|
+ scheduler.pauseJob(jobKey);
|
|
|
+ }
|
|
|
+ catch (SchedulerException e)
|
|
|
+ {
|
|
|
+ TASK_LOG.error("Fail to pause Job. job detail: " + JsonUtil.toJson(scheduleJob), e);
|
|
|
+ throw new ExamCloudRuntimeException(e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 恢复一个job
|
|
|
+ *
|
|
|
+ * @author WANGWEI
|
|
|
+ * @param scheduleJob
|
|
|
+ */
|
|
|
+ public void resumeJob(ScheduleJob scheduleJob)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ Scheduler scheduler = schedulerFactoryBean.getScheduler();
|
|
|
+ JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
|
|
|
+ scheduler.resumeJob(jobKey);
|
|
|
+ }
|
|
|
+ catch (SchedulerException e)
|
|
|
+ {
|
|
|
+ TASK_LOG.error("Fail to resume job. job detail: " + JsonUtil.toJson(scheduleJob), e);
|
|
|
+ throw new ExamCloudRuntimeException(e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 删除一个job
|
|
|
+ *
|
|
|
+ * @author WANGWEI
|
|
|
+ * @param scheduleJob
|
|
|
+ */
|
|
|
+ public void deleteJob(ScheduleJob scheduleJob)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ Scheduler scheduler = schedulerFactoryBean.getScheduler();
|
|
|
+ JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
|
|
|
+ scheduler.deleteJob(jobKey);
|
|
|
+ }
|
|
|
+ catch (SchedulerException e)
|
|
|
+ {
|
|
|
+ TASK_LOG.error("Fail to delete job. job detail: " + JsonUtil.toJson(scheduleJob), e);
|
|
|
+ throw new ExamCloudRuntimeException(e);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 执行job
|
|
|
+ *
|
|
|
+ * @author WANGWEI
|
|
|
+ * @param scheduleJob
|
|
|
+ */
|
|
|
+ public void runJob(ScheduleJob scheduleJob)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ Scheduler scheduler = schedulerFactoryBean.getScheduler();
|
|
|
+ JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
|
|
|
+ scheduler.triggerJob(jobKey);
|
|
|
+ }
|
|
|
+ catch (SchedulerException e)
|
|
|
+ {
|
|
|
+ TASK_LOG.error("Fail to run job. job detail: " + JsonUtil.toJson(scheduleJob), e);
|
|
|
+ throw new ExamCloudRuntimeException(e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 更新job时间表达式
|
|
|
+ *
|
|
|
+ * @author WANGWEI
|
|
|
+ * @param scheduleJob
|
|
|
+ */
|
|
|
+ public void updateJobCronExpression(ScheduleJob scheduleJob)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ Scheduler scheduler = schedulerFactoryBean.getScheduler();
|
|
|
+
|
|
|
+ TriggerKey triggerKey = TriggerKey.triggerKey(scheduleJob.getJobName(),
|
|
|
+ scheduleJob.getJobGroup());
|
|
|
+
|
|
|
+ CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
|
|
|
+
|
|
|
+ CronScheduleBuilder scheduleBuilder = CronScheduleBuilder
|
|
|
+ .cronSchedule(scheduleJob.getCronExpression());
|
|
|
+
|
|
|
+ trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
|
|
|
+ .withSchedule(scheduleBuilder).build();
|
|
|
+
|
|
|
+ scheduler.rescheduleJob(triggerKey, trigger);
|
|
|
+ }
|
|
|
+ catch (SchedulerException e)
|
|
|
+ {
|
|
|
+ TASK_LOG.error("Fail to update job cron expression. job detail :"
|
|
|
+ + JsonUtil.toJson(scheduleJob), e);
|
|
|
+ throw new ExamCloudRuntimeException(e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|