diff --git a/xxl-job-admin/src/main/java/com/xxl/job/controller/JobController.java b/xxl-job-admin/src/main/java/com/xxl/job/controller/JobController.java index daa227c7..2a3b9412 100644 --- a/xxl-job-admin/src/main/java/com/xxl/job/controller/JobController.java +++ b/xxl-job-admin/src/main/java/com/xxl/job/controller/JobController.java @@ -7,6 +7,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang.StringUtils; @@ -16,11 +17,15 @@ import org.quartz.SchedulerException; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import com.xxl.job.client.handler.HandlerRepository; +import com.xxl.job.client.util.JacksonUtil; import com.xxl.job.core.model.ReturnT; +import com.xxl.job.core.model.XxlJobInfo; import com.xxl.job.core.util.DynamicSchedulerUtil; +import com.xxl.job.dao.IXxlJobInfoDao; import com.xxl.job.service.job.HttpJobBean; /** @@ -31,19 +36,47 @@ import com.xxl.job.service.job.HttpJobBean; @RequestMapping("/job") public class JobController { + @Resource + private IXxlJobInfoDao xxlJobInfoDao; + @RequestMapping public String index(Model model) { - List> jobList = DynamicSchedulerUtil.getJobList(); - model.addAttribute("jobList", jobList); + //List> jobList = DynamicSchedulerUtil.getJobList(); + //model.addAttribute("jobList", jobList); return "job/index"; } + @RequestMapping("/pageList") + @ResponseBody + public Map pageList(@RequestParam(required = false, defaultValue = "0") int start, + @RequestParam(required = false, defaultValue = "10") int length, + String jobName, String filterTime) { + + // page list + List list = xxlJobInfoDao.pageList(start, length, jobName, null, null); + int list_count = xxlJobInfoDao.pageListCount(start, length, jobName, null, null); + + // fill job info + if (list!=null && list.size()>0) { + for (XxlJobInfo jobInfo : list) { + DynamicSchedulerUtil.fillJobInfo(jobInfo); + } + } + + // package result + Map maps = new HashMap(); + maps.put("recordsTotal", list_count); // 总记录数 + maps.put("recordsFiltered", list_count); // 过滤后的总记录数 + maps.put("data", list); // 分页列表 + return maps; + } + @RequestMapping("/add") @ResponseBody public ReturnT add(HttpServletRequest request) { String triggerKeyName = null; String cronExpression = null; - Map jobData = new HashMap(); + Map jobData = new HashMap(); try { request.setCharacterEncoding("utf-8"); @@ -58,7 +91,7 @@ public class JobController { } else if (param.getKey().equals("cronExpression")) { cronExpression = param.getValue()[0]; } else { - jobData.put(param.getKey(), param.getValue().length>0?param.getValue()[0]:param.getValue()); + jobData.put(param.getKey(), (String) (param.getValue().length>0?param.getValue()[0]:param.getValue())); } } @@ -90,10 +123,19 @@ public class JobController { Class jobClass = HttpJobBean.class; try { - boolean result = DynamicSchedulerUtil.addJob(triggerKeyName, cronExpression, jobClass, jobData); + // add job 2 quartz + boolean result = DynamicSchedulerUtil.addJob(triggerKeyName, cronExpression, jobClass, null); if (!result) { return new ReturnT(500, "任务ID重复,请更换确认"); } + // Backup to the database + XxlJobInfo jobInfo = new XxlJobInfo(); + jobInfo.setJobName(triggerKeyName); + jobInfo.setJobCron(cronExpression); + jobInfo.setJobClass(jobClass.getName()); + jobInfo.setJobData(JacksonUtil.writeValueAsString(jobData)); + xxlJobInfoDao.save(jobInfo); + return ReturnT.SUCCESS; } catch (SchedulerException e) { e.printStackTrace(); @@ -117,6 +159,13 @@ public class JobController { } try { DynamicSchedulerUtil.rescheduleJob(triggerKeyName, cronExpression); + + // update + XxlJobInfo jobInfo = xxlJobInfoDao.load(triggerKeyName); + if (jobInfo!=null) { + jobInfo.setJobCron(cronExpression); + xxlJobInfoDao.update(jobInfo); + } return ReturnT.SUCCESS; } catch (SchedulerException e) { e.printStackTrace(); @@ -128,12 +177,15 @@ public class JobController { @ResponseBody public ReturnT remove(String triggerKeyName) { try { - DynamicSchedulerUtil.removeJob(triggerKeyName); - return ReturnT.SUCCESS; + if (triggerKeyName!=null) { + DynamicSchedulerUtil.removeJob(triggerKeyName); + xxlJobInfoDao.delete(triggerKeyName); + return ReturnT.SUCCESS; + } } catch (SchedulerException e) { e.printStackTrace(); - return ReturnT.FAIL; } + return ReturnT.FAIL; } @RequestMapping("/pause") @@ -141,6 +193,12 @@ public class JobController { public ReturnT pause(String triggerKeyName) { try { DynamicSchedulerUtil.pauseJob(triggerKeyName); + // update + XxlJobInfo jobInfo = xxlJobInfoDao.load(triggerKeyName); + if (jobInfo!=null) { + jobInfo.setJobStatus("PAUSED"); + xxlJobInfoDao.update(jobInfo); + } return ReturnT.SUCCESS; } catch (SchedulerException e) { e.printStackTrace(); @@ -153,6 +211,12 @@ public class JobController { public ReturnT resume(String triggerKeyName) { try { DynamicSchedulerUtil.resumeJob(triggerKeyName); + // update + XxlJobInfo jobInfo = xxlJobInfoDao.load(triggerKeyName); + if (jobInfo!=null) { + jobInfo.setJobStatus("NORMAL"); + xxlJobInfoDao.update(jobInfo); + } return ReturnT.SUCCESS; } catch (SchedulerException e) { e.printStackTrace(); diff --git a/xxl-job-admin/src/main/java/com/xxl/job/core/util/DynamicSchedulerUtil.java b/xxl-job-admin/src/main/java/com/xxl/job/core/util/DynamicSchedulerUtil.java index fdd1f6a4..79526ff7 100644 --- a/xxl-job-admin/src/main/java/com/xxl/job/core/util/DynamicSchedulerUtil.java +++ b/xxl-job-admin/src/main/java/com/xxl/job/core/util/DynamicSchedulerUtil.java @@ -23,11 +23,14 @@ import org.quartz.Trigger.TriggerState; import org.quartz.TriggerBuilder; import org.quartz.TriggerKey; import org.quartz.impl.matchers.GroupMatcher; +import org.quartz.impl.triggers.CronTriggerImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.util.Assert; +import com.xxl.job.core.model.XxlJobInfo; +import com.xxl.job.dao.IXxlJobInfoDao; import com.xxl.job.dao.IXxlJobLogDao; /** @@ -43,8 +46,11 @@ public final class DynamicSchedulerUtil implements InitializingBean { public void setXxlJobLogDao(IXxlJobLogDao xxlJobLogDao) { DynamicSchedulerUtil.xxlJobLogDao = xxlJobLogDao; } - public static IXxlJobLogDao getXxlJobLogDao() { - return xxlJobLogDao; + // xxlJobInfoDao + public static IXxlJobInfoDao xxlJobInfoDao; + @Resource + public void setXxlJobInfoDao(IXxlJobInfoDao xxlJobInfoDao) { + DynamicSchedulerUtil.xxlJobInfoDao = xxlJobInfoDao; } // Scheduler @@ -90,6 +96,34 @@ public final class DynamicSchedulerUtil implements InitializingBean { } return jobList; } + + // fill job info + public static void fillJobInfo(XxlJobInfo jobInfo) { + // TriggerKey : name + group + TriggerKey triggerKey = TriggerKey.triggerKey(jobInfo.getJobName(), Scheduler.DEFAULT_GROUP); + JobKey jobKey = new JobKey(jobInfo.getJobName(), Scheduler.DEFAULT_GROUP); + try { + Trigger trigger = scheduler.getTrigger(triggerKey); + JobDetail jobDetail = scheduler.getJobDetail(jobKey); + TriggerState triggerState = scheduler.getTriggerState(triggerKey); + + // parse params + if (trigger!=null && trigger instanceof CronTriggerImpl) { + String cronExpression = ((CronTriggerImpl) trigger).getCronExpression(); + jobInfo.setJobCron(cronExpression); + } + if (jobDetail!=null) { + String jobClass = jobDetail.getJobClass().getName(); + jobInfo.setJobClass(jobClass); + } + if (triggerState!=null) { + jobInfo.setJobStatus(triggerState.name()); + } + + } catch (SchedulerException e) { + e.printStackTrace(); + } + } // addJob 新增 public static boolean addJob(String triggerKeyName, String cronExpression, Class jobClass, Map jobData) throws SchedulerException { diff --git a/xxl-job-admin/src/main/java/com/xxl/job/dao/IXxlJobLogDao.java b/xxl-job-admin/src/main/java/com/xxl/job/dao/IXxlJobLogDao.java index 3efc5795..40394dc4 100644 --- a/xxl-job-admin/src/main/java/com/xxl/job/dao/IXxlJobLogDao.java +++ b/xxl-job-admin/src/main/java/com/xxl/job/dao/IXxlJobLogDao.java @@ -6,6 +6,10 @@ import java.util.List; import com.xxl.job.core.model.XxlJobLog; +/** + * job log + * @author xuxueli 2016-1-12 18:03:06 + */ public interface IXxlJobLogDao { public int save(XxlJobLog xxlJobLog); diff --git a/xxl-job-admin/src/main/java/com/xxl/job/dao/impl/XxlJobLogDaoImpl.java b/xxl-job-admin/src/main/java/com/xxl/job/dao/impl/XxlJobLogDaoImpl.java index 2ec15b97..a3185a3e 100644 --- a/xxl-job-admin/src/main/java/com/xxl/job/dao/impl/XxlJobLogDaoImpl.java +++ b/xxl-job-admin/src/main/java/com/xxl/job/dao/impl/XxlJobLogDaoImpl.java @@ -12,6 +12,10 @@ import org.springframework.stereotype.Repository; import com.xxl.job.core.model.XxlJobLog; import com.xxl.job.dao.IXxlJobLogDao; +/** + * job log + * @author xuxueli 2016-1-12 18:03:06 + */ @Repository public class XxlJobLogDaoImpl implements IXxlJobLogDao { diff --git a/xxl-job-admin/src/main/java/com/xxl/job/service/job/HttpJobBean.java b/xxl-job-admin/src/main/java/com/xxl/job/service/job/HttpJobBean.java index d90e33ff..51210d39 100644 --- a/xxl-job-admin/src/main/java/com/xxl/job/service/job/HttpJobBean.java +++ b/xxl-job-admin/src/main/java/com/xxl/job/service/job/HttpJobBean.java @@ -3,7 +3,6 @@ package com.xxl.job.service.job; import java.util.Date; import java.util.HashMap; import java.util.Map; -import java.util.Map.Entry; import org.apache.commons.lang.StringUtils; import org.quartz.JobExecutionContext; @@ -16,6 +15,7 @@ import org.springframework.scheduling.quartz.QuartzJobBean; import com.xxl.job.client.handler.HandlerRepository; import com.xxl.job.client.util.HttpUtil; import com.xxl.job.client.util.JacksonUtil; +import com.xxl.job.core.model.XxlJobInfo; import com.xxl.job.core.model.XxlJobLog; import com.xxl.job.core.util.DynamicSchedulerUtil; import com.xxl.job.core.util.PropertiesUtil; @@ -27,18 +27,17 @@ import com.xxl.job.core.util.PropertiesUtil; public class HttpJobBean extends QuartzJobBean { private static Logger logger = LoggerFactory.getLogger(HttpJobBean.class); + @SuppressWarnings("unchecked") @Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException { - String triggerKey = context.getTrigger().getJobKey().getName(); + // jobDataMap 2 params - Map jobDataMap = context.getMergedJobDataMap().getWrappedMap(); Map params = new HashMap(); - if (jobDataMap!=null && jobDataMap.size()>0) { - for (Entry item : jobDataMap.entrySet()) { - params.put(item.getKey(), String.valueOf(item.getValue())); - } + XxlJobInfo jobInfo = DynamicSchedulerUtil.xxlJobInfoDao.load(triggerKey); + if (jobInfo!=null && jobInfo.getJobData()!=null) { + params = JacksonUtil.readValue(jobInfo.getJobData(), Map.class); } // corn @@ -53,7 +52,7 @@ public class HttpJobBean extends QuartzJobBean { jobLog.setJobName(triggerKey); jobLog.setJobCron(cornExp); jobLog.setJobClass(HttpJobBean.class.getName()); - jobLog.setJobData(JacksonUtil.writeValueAsString(params)); + jobLog.setJobData(jobInfo.getJobData()); DynamicSchedulerUtil.xxlJobLogDao.save(jobLog); logger.info(">>>>>>>>>>> xxl-job trigger start, jobLog:{}", jobLog); @@ -70,8 +69,7 @@ public class HttpJobBean extends QuartzJobBean { jobLog.setTriggerTime(new Date()); jobLog.setTriggerStatus(HttpUtil.FAIL); jobLog.setTriggerMsg("[responseMsg]:"+responseMsg+"
[exceptionMsg]:"+exceptionMsg); - if (StringUtils.isNotBlank(responseMsg)) { - @SuppressWarnings("unchecked") + if (StringUtils.isNotBlank(responseMsg) && responseMsg.indexOf("{")>-1 ) { Map responseMap = JacksonUtil.readValue(responseMsg, Map.class); if (responseMap!=null && StringUtils.isNotBlank(responseMap.get(HttpUtil.status))) { jobLog.setTriggerStatus(responseMap.get(HttpUtil.status)); diff --git a/xxl-job-admin/src/main/resources/applicationcontext-database.xml b/xxl-job-admin/src/main/resources/applicationcontext-database.xml index 96874386..2a8bd8a3 100644 --- a/xxl-job-admin/src/main/resources/applicationcontext-database.xml +++ b/xxl-job-admin/src/main/resources/applicationcontext-database.xml @@ -31,7 +31,7 @@ - + diff --git a/xxl-job-admin/src/main/java/com/xxl/job/core/model/mapper/XxlJobLogMapper.xml b/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobLogMapper.xml similarity index 100% rename from xxl-job-admin/src/main/java/com/xxl/job/core/model/mapper/XxlJobLogMapper.xml rename to xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobLogMapper.xml diff --git a/xxl-job-admin/src/main/webapp/WEB-INF/template/help.ftl b/xxl-job-admin/src/main/webapp/WEB-INF/template/help.ftl index 9ce7eaf6..e489f5d5 100644 --- a/xxl-job-admin/src/main/webapp/WEB-INF/template/help.ftl +++ b/xxl-job-admin/src/main/webapp/WEB-INF/template/help.ftl @@ -68,8 +68,6 @@ <@netCommon.commonFooter /> - - <@netCommon.commonControl /> <@netCommon.commonScript /> diff --git a/xxl-job-admin/src/main/webapp/WEB-INF/template/job/index.ftl b/xxl-job-admin/src/main/webapp/WEB-INF/template/job/index.ftl index 7a37c29b..6aaf3b3f 100644 --- a/xxl-job-admin/src/main/webapp/WEB-INF/template/job/index.ftl +++ b/xxl-job-admin/src/main/webapp/WEB-INF/template/job/index.ftl @@ -28,32 +28,53 @@
+ +
+
+
+ + jobName + + +
+
+
+ +
+
+ +
+
+

调度列表

-
- - - + + + + + - + + + <#-- <#if jobList?exists && jobList?size gt 0> <#list jobList as item> - + + + --> - - - - - - - - - - +
调度keycronid任务Key任务Cron任务Class状态Status 参数状态addTimeupdateTime 操作
${item['TriggerKey'].name} ${item['Trigger'].cronExpression}${item['JobDetail'].jobClass} <#assign jobDataMap = item['JobDetail'].jobDataMap /> <#if jobDataMap?exists && jobDataMap?keys?size gt 0> @@ -89,17 +110,10 @@
调度keycron参数状态操作
@@ -110,8 +124,6 @@ <@netCommon.commonFooter /> - - <@netCommon.commonControl />
@@ -129,19 +141,19 @@
-
+
-
+
-
+
-
+
@@ -166,12 +178,24 @@