|
@@ -0,0 +1,219 @@
|
|
|
|
+package com.bosshand.virgo.api.service;
|
|
|
|
+
|
|
|
|
+import com.alibaba.fastjson.JSONArray;
|
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
|
+import com.bosshand.virgo.api.model.JobInfo;
|
|
|
|
+import com.bosshand.virgo.api.model.Project;
|
|
|
|
+import org.quartz.*;
|
|
|
|
+import org.quartz.impl.matchers.GroupMatcher;
|
|
|
|
+import org.slf4j.Logger;
|
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
|
+
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
+import java.util.HashMap;
|
|
|
|
+import java.util.List;
|
|
|
|
+import java.util.Map;
|
|
|
|
+
|
|
|
|
+@Service
|
|
|
|
+public class QuartzService {
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ private Scheduler scheduler;
|
|
|
|
+
|
|
|
|
+ private static final String DEFAULT_JOB_GROUP = "default_job_group";
|
|
|
|
+
|
|
|
|
+ private static final String DEFAULT_TRIGGER_GROUP = "default_trigger_group";
|
|
|
|
+
|
|
|
|
+ private static final String TRIGGER_PRE = "Trigger_";
|
|
|
|
+
|
|
|
|
+ private static Map<Integer, String> CRON_MAP = new HashMap<>();
|
|
|
|
+
|
|
|
|
+ // cron 每周几0点1分执行
|
|
|
|
+ static {
|
|
|
|
+ CRON_MAP.put(1, "0 1 0 ? * 2");
|
|
|
|
+ CRON_MAP.put(2, "0 1 0 ? * 3");
|
|
|
|
+ CRON_MAP.put(3, "0 1 0 ? * 4");
|
|
|
|
+ CRON_MAP.put(4, "0 1 0 ? * 5");
|
|
|
|
+ CRON_MAP.put(5, "0 1 0 ? * 6");
|
|
|
|
+ CRON_MAP.put(6, "0 1 0 ? * 7");
|
|
|
|
+ CRON_MAP.put(7, "0 1 0 ? * 1");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ static Logger log = LoggerFactory.getLogger(QuartzService.class);
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 定时保存项目所在城市天气
|
|
|
|
+ */
|
|
|
|
+ public void executeJobCityWeatherQuartz(Project project) {
|
|
|
|
+ long projectId = project.getId();
|
|
|
|
+ JSONArray jsonArray = JSONArray.parseArray(project.getAddress());
|
|
|
|
+ String city = jsonArray.getString(2);
|
|
|
|
+
|
|
|
|
+ JSONObject js = new JSONObject();
|
|
|
|
+ js.put("projectId", projectId);
|
|
|
|
+ js.put("city", city);
|
|
|
|
+
|
|
|
|
+ // 执行保存项目所在城市天气任务,任务名称(projectId_city)
|
|
|
|
+ String jobName = projectId + "_" + city;
|
|
|
|
+ String jobClassName = "com.bosshand.virgo.api.job.JobCityWeatherQuartz";
|
|
|
|
+ addCronJob(jobName, "0 0 0 * * ?", jobClassName, js);
|
|
|
|
+ // 首次执行一次保存任务
|
|
|
|
+ executeImmediately(jobName + "_" + projectId, jobClassName, js);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 定时生成项目周报
|
|
|
|
+ */
|
|
|
|
+ public void executeJobProjectWeeklyQuartz(Project project) {
|
|
|
|
+ Integer generateWeeklyDate = project.getGenerateWeeklyDate();
|
|
|
|
+ JSONObject js = new JSONObject();
|
|
|
|
+ js.put("projectId", project.getId());
|
|
|
|
+ js.put("createDate", project.getCreateDate());
|
|
|
|
+ // 执行生成周报任务,任务名称(projectId_projectName)
|
|
|
|
+ String s = addCronJob(project.getId() + "_" + project.getName(), CRON_MAP.get(generateWeeklyDate), "com.bosshand.virgo.api.job.JobProjectWeeklyQuartz", js);
|
|
|
|
+ log.info(project.getId() + "_" + project.getName()+"周报定时任务启动:{}", s);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 删除项目定时任务
|
|
|
|
+ */
|
|
|
|
+ public void deleteJobQuartz(Project project) {
|
|
|
|
+ JSONArray jsonArray = JSONArray.parseArray(project.getAddress());
|
|
|
|
+ String city = jsonArray.getString(2);
|
|
|
|
+ // 天气
|
|
|
|
+ deleteCronJob(project.getId() + "_" + city, DEFAULT_JOB_GROUP, TRIGGER_PRE + project.getId() + "_" + city, DEFAULT_TRIGGER_GROUP);
|
|
|
|
+ // 周报
|
|
|
|
+ deleteCronJob(project.getId() + "_" + project.getName(), DEFAULT_JOB_GROUP, TRIGGER_PRE + project.getId() + "_" + project.getName(), DEFAULT_TRIGGER_GROUP);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public String addCronJob(String jobName, String cron, String jobClassName, JSONObject data) {
|
|
|
|
+ try {
|
|
|
|
+ // 当前任务不存在才进行添加
|
|
|
|
+ JobKey jobKey = JobKey.jobKey(jobName, DEFAULT_JOB_GROUP);
|
|
|
|
+ if (scheduler.checkExists(jobKey)) {
|
|
|
|
+ log.info("[添加定时任务]已存在该作业,jobkey为:{}", jobKey);
|
|
|
|
+ return "已存在该作业";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 构建 Job
|
|
|
|
+ JobDetail job = JobBuilder.newJob(getClass(jobClassName).getClass())
|
|
|
|
+ .withIdentity(jobKey).build();
|
|
|
|
+
|
|
|
|
+ job.getJobDataMap().put("data", data.toJSONString());
|
|
|
|
+
|
|
|
|
+ // cron表达式定时构造器
|
|
|
|
+ CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
|
|
|
|
+
|
|
|
|
+ // 构建 Trigger
|
|
|
|
+ Trigger trigger = TriggerBuilder.newTrigger()
|
|
|
|
+ .withIdentity(TriggerKey.triggerKey(TRIGGER_PRE + jobName, DEFAULT_TRIGGER_GROUP))
|
|
|
|
+ .withSchedule(cronScheduleBuilder).build();
|
|
|
|
+
|
|
|
|
+ // 启动调度器
|
|
|
|
+ scheduler.scheduleJob(job, trigger);
|
|
|
|
+ scheduler.start();
|
|
|
|
+ return "SUCCESS";
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.error("[新增定时任务]失败,报错:", e);
|
|
|
|
+ return "FAIL";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public String deleteCronJob(String jobName, String jobGroup, String triggerName, String triggerGroup) {
|
|
|
|
+ try {
|
|
|
|
+
|
|
|
|
+ JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
|
|
|
|
+
|
|
|
|
+ TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroup);
|
|
|
|
+
|
|
|
|
+ Trigger trigger = scheduler.getTrigger(triggerKey);
|
|
|
|
+
|
|
|
|
+ if (null == trigger) {
|
|
|
|
+ log.info("[停止定时任务]根据triggerName:{}和triggerGroup:{}未查询到相应的trigger!");
|
|
|
|
+ return "SUCCESS";
|
|
|
|
+ }
|
|
|
|
+ // 暂停触发器
|
|
|
|
+ scheduler.pauseTrigger(triggerKey);
|
|
|
|
+ // 移除触发器
|
|
|
|
+ scheduler.unscheduleJob(triggerKey);
|
|
|
|
+ // 删除任务
|
|
|
|
+ scheduler.deleteJob(jobKey);
|
|
|
|
+
|
|
|
|
+ log.info("[停止定时任务]jobName:{},jobGroup:{}, triggerName:{}, triggerGroup:{},停止--------------", jobName, jobGroup, triggerName, triggerGroup);
|
|
|
|
+
|
|
|
|
+ return "SUCCESS";
|
|
|
|
+
|
|
|
|
+ } catch (SchedulerException e) {
|
|
|
|
+ log.error("[停止定时任务]失败,报错:", e);
|
|
|
|
+ return "FAIL";
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public static Job getClass(String className) throws Exception {
|
|
|
|
+ Class<?> classTemp = Class.forName(className);
|
|
|
|
+ return (Job) classTemp.newInstance();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public String executeImmediately(String jobName, String jobClassName, JSONObject data) {
|
|
|
|
+ try {
|
|
|
|
+ JobKey jobKey = JobKey.jobKey(jobName, DEFAULT_JOB_GROUP);
|
|
|
|
+ JobDetail job = JobBuilder.newJob(getClass(jobClassName).getClass())
|
|
|
|
+ .withIdentity(jobKey).build();
|
|
|
|
+
|
|
|
|
+ job.getJobDataMap().put("data", data.toJSONString());
|
|
|
|
+
|
|
|
|
+ Trigger trigger = TriggerBuilder.newTrigger()
|
|
|
|
+ .withIdentity(TriggerKey.triggerKey(TRIGGER_PRE + jobName, DEFAULT_TRIGGER_GROUP))
|
|
|
|
+ .build();
|
|
|
|
+
|
|
|
|
+ // 启动调度器
|
|
|
|
+ scheduler.scheduleJob(job, trigger);
|
|
|
|
+ scheduler.start();
|
|
|
|
+ return "SUCCESS";
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.error("[立即执行一次任务,不定时]失败,报错:", e);
|
|
|
|
+ return "FAIL";
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 查询定时任务列表
|
|
|
|
+ */
|
|
|
|
+ public List<JobInfo> getScheduleJobList() {
|
|
|
|
+ List<JobInfo> list = new ArrayList<>();
|
|
|
|
+ try {
|
|
|
|
+ for (String groupJob : scheduler.getJobGroupNames()) {
|
|
|
|
+ for (JobKey jobKey : scheduler.getJobKeys(GroupMatcher.<JobKey>groupEquals(groupJob))) {
|
|
|
|
+ List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
|
|
|
|
+ for (Trigger trigger : triggers) {
|
|
|
|
+ JobInfo jobInfo = new JobInfo();
|
|
|
|
+ Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
|
|
|
|
+ JobDetail jobDetail = scheduler.getJobDetail(jobKey);
|
|
|
|
+ String cronExpression = "";
|
|
|
|
+ if (trigger instanceof CronTrigger) {
|
|
|
|
+ CronTrigger cronTrigger = (CronTrigger) trigger;
|
|
|
|
+ cronExpression = cronTrigger.getCronExpression();
|
|
|
|
+ jobInfo.setCron(cronExpression);
|
|
|
|
+ }
|
|
|
|
+ jobInfo.setJobName(jobKey.getName());
|
|
|
|
+ jobInfo.setJobGroup(jobKey.getGroup());
|
|
|
|
+ jobInfo.setTriggerGroup(trigger.getKey().getGroup());
|
|
|
|
+ jobInfo.setTriggerName(trigger.getKey().getName());
|
|
|
|
+ jobInfo.setJobStatus(triggerState.name());
|
|
|
|
+ jobInfo.setJobClassName(jobDetail.getJobClass().toGenericString());
|
|
|
|
+ jobInfo.setJobDataMap(jobDetail.getJobDataMap());
|
|
|
|
+ list.add(jobInfo);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } catch (SchedulerException e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ return list;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+}
|