@Component
@Scope("singleton")
@Slf4j
public class QuartzManager implements ApplicationListener<ApplicationPreparedEvent> {
private static SchedulerFactory schedulerFactory = new StdSchedulerFactory();
private Scheduler scheduler;
@Autowired
private EquipmentPlanRepository equipmentPlanRepository;
/**
* 啓動所有任務
*/
public void startAllPlan() {
try {
this.scheduler = schedulerFactory.getScheduler();
List<EquipmentPlan> equipmentPlan = equipmentPlanRepository.findByPlanningState();
equipmentPlan.forEach(this::addPlan);
} catch (SchedulerException e) {
log.error(e.getMessage(), e);
throw new RuntimeException("任務註冊失敗");
}
}
/**
* 添加任務
*/
public void addPlan(EquipmentPlan plan) {
if (DateTimeUtils.todayIn(plan.getStartTime(), plan.getEndTime()) && plan.getPlanningState().equals(PlanTypeOrState.START_USING.getState())) {
if (!CronExpression.isValidExpression(plan.getPollingTime())) {
log.error("時間表達式錯誤,請重新設置!");
return;
}
JobDetail jobDetail = JobBuilder.newJob()
.withIdentity(new JobKey(plan.getId().toString()))
.usingJobData("equipmentPlan", JSON.toJSONString(plan))
.ofType(PlanMakeTask.class)
.withDescription(plan.getPlanName())
.build();
CronScheduleBuilder csb = CronScheduleBuilder.cronSchedule(plan.getPollingTime());
csb.withMisfireHandlingInstructionDoNothing();
Trigger trigger = TriggerBuilder.newTrigger()
.forJob(jobDetail)
.withSchedule(csb)
.withIdentity(new TriggerKey(plan.getId().toString()))
.build();
//判斷任務在定時器中是否已經存在,若存在將不再添加,避免重複添加任務
try {
if (!scheduler.checkExists(jobDetail.getKey())) {
scheduler.scheduleJob(jobDetail, trigger);
scheduler.start();
}
} catch (SchedulerException se) {
log.error(se.getMessage() + ":" + plan.toString());
}
}
}
/**
* 更新任務
*
* @param jobName 任務名稱
* @param cronExp 時間表達式
* @return 返回操作結果
*/
public boolean updateJob(String jobName, String cronExp) {
boolean result = false;
if (!CronExpression.isValidExpression(cronExp)) {
log.error("時間表達式錯誤{}", cronExp);
return result;
}
JobKey jobKey = new JobKey(jobName);
TriggerKey triggerKey = new TriggerKey(jobName);
try {
if (scheduler.checkExists(jobKey) && scheduler.checkExists(triggerKey)) {
JobDetail jobDetail = scheduler.getJobDetail(jobKey);
Trigger newTrigger = TriggerBuilder.newTrigger()
.forJob(jobDetail)
.withSchedule(CronScheduleBuilder.cronSchedule(cronExp))
.withIdentity(new TriggerKey(jobName))
.build();
scheduler.rescheduleJob(triggerKey, newTrigger);
result = true;
} else {
log.error("更新任務:{},任務組:{} 或者時間:{},任務組:{} 不存在",
jobKey.getName(), jobKey.getGroup(), triggerKey.getName(), triggerKey.getGroup());
}
} catch (SchedulerException e) {
log.error(e.getMessage(), e);
log.error("更新任務:{},任務組:{} 失敗!", jobKey.getName(), jobKey.getGroup());
}
return result;
}
/**
* 刪除任務
*
* @param jobName 任務名稱
* @return 返回操作結果
*/
public boolean deleteJob(String jobName) {
boolean result = false;
JobKey jobKey = new JobKey(jobName);
try {
if (scheduler.checkExists(jobKey)) {
result = scheduler.deleteJob(jobKey);
} else {
log.error("刪除 任務:{},任務組:{} 不存在.", jobKey.getName(), jobKey.getGroup());
}
} catch (SchedulerException e) {
log.error(e.getMessage(), e);
log.error("刪除 任務:{},任務組:{} 失敗!", jobKey.getName(), jobKey.getGroup());
}
return result;
}
/**
* 暫停指定任務
*/
public void pauseJob(String jobName) {
JobKey jobKey = new JobKey(jobName);
try {
if (scheduler.checkExists(jobKey)) {
scheduler.pauseJob(jobKey);
} else {
log.error("delete job name:{},group name:{} not exists.", jobKey.getName(), jobKey.getGroup());
}
} catch (SchedulerException e) {
log.error(e.getMessage(), e);
}
}
/**
* 重啓指定的任務
*/
public void resumeJob(String jobName) {
JobKey jobKey = new JobKey(jobName);
try {
if (scheduler.checkExists(jobKey)) {
scheduler.resumeJob(jobKey);
} else {
log.error("delete job name:{},group name:{} not exists.", jobKey.getName(), jobKey.getGroup());
}
} catch (SchedulerException e) {
log.error(e.getMessage(), e);
}
}
/**
* Handle an application event.
*
* @param event the event to respond to
*/
@Override
public void onApplicationEvent(ApplicationPreparedEvent event) {
startAllPlan();
}
}