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