diff --git a/db/tables_xxl_job.sql b/db/tables_xxl_job.sql index 823e2ef6..6f4f61c0 100644 --- a/db/tables_xxl_job.sql +++ b/db/tables_xxl_job.sql @@ -161,6 +161,7 @@ CREATE TABLE `XXL_JOB_QRTZ_TRIGGER_INFO` ( `glue_switch` int(11) DEFAULT '0' COMMENT 'GLUE模式开关:0-否,1-是', `glue_source` text COMMENT 'GLUE源代码', `glue_remark` varchar(128) DEFAULT NULL COMMENT 'GLUE备注', + `child_jobkey` varchar(255) DEFAULT NULL COMMENT '子任务Key', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobInfoController.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobInfoController.java index a076d11a..e733e2a9 100644 --- a/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobInfoController.java +++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobInfoController.java @@ -41,19 +41,20 @@ public class JobInfoController { @RequestMapping("/add") @ResponseBody public ReturnT add(String jobGroup, String jobCron, String jobDesc, String author, String alarmEmail, - String executorAddress, String executorHandler, String executorParam, int glueSwitch, String glueSource, String glueRemark) { + String executorAddress, String executorHandler, String executorParam, int glueSwitch, String glueSource, String glueRemark, + String childJobKey) { return xxlJobService.add(jobGroup, jobCron, jobDesc, author, alarmEmail, - executorAddress, executorHandler, executorParam, glueSwitch, glueSource, glueRemark); + executorAddress, executorHandler, executorParam, glueSwitch, glueSource, glueRemark, childJobKey); } @RequestMapping("/reschedule") @ResponseBody public ReturnT reschedule(String jobGroup, String jobName, String jobCron, String jobDesc, String author, String alarmEmail, - String executorAddress, String executorHandler, String executorParam, int glueSwitch) { + String executorAddress, String executorHandler, String executorParam, int glueSwitch, String childJobKey) { return xxlJobService.reschedule(jobGroup, jobName, jobCron, jobDesc, author, alarmEmail, - executorAddress, executorHandler, executorParam, glueSwitch); + executorAddress, executorHandler, executorParam, glueSwitch, childJobKey); } @RequestMapping("/remove") diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/callback/XxlJobLogCallbackServerHandler.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/callback/XxlJobLogCallbackServerHandler.java index 7a35710c..112efdd7 100644 --- a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/callback/XxlJobLogCallbackServerHandler.java +++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/callback/XxlJobLogCallbackServerHandler.java @@ -1,23 +1,31 @@ package com.xxl.job.admin.core.callback; +import com.xxl.job.admin.core.model.ReturnT; +import com.xxl.job.admin.core.model.XxlJobInfo; import com.xxl.job.admin.core.model.XxlJobLog; import com.xxl.job.admin.core.util.DynamicSchedulerUtil; import com.xxl.job.core.router.model.RequestModel; import com.xxl.job.core.router.model.ResponseModel; import com.xxl.job.core.util.XxlJobNetCommUtil; +import org.apache.commons.lang.StringUtils; import org.eclipse.jetty.server.Request; import org.eclipse.jetty.server.handler.AbstractHandler; +import org.quartz.SchedulerException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; +import java.text.MessageFormat; import java.util.Date; /** * Created by xuxueli on 2016-5-22 11:15:42 */ public class XxlJobLogCallbackServerHandler extends AbstractHandler { + private static Logger logger = LoggerFactory.getLogger(XxlJobLogCallbackServerHandler.class); @Override public void handle(String s, Request baseRequest, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws IOException, ServletException { @@ -33,6 +41,31 @@ public class XxlJobLogCallbackServerHandler extends AbstractHandler { ResponseModel responseModel = null; XxlJobLog log = DynamicSchedulerUtil.xxlJobLogDao.load(requestModel.getLogId()); if (log!=null) { + + // trigger success, to trigger child job, and avoid repeat trigger child job + if (!ResponseModel.SUCCESS.equals(log.getHandleStatus())) { + XxlJobInfo xxlJobInfo = DynamicSchedulerUtil.xxlJobInfoDao.load(log.getJobGroup(), log.getJobName()); + if (xxlJobInfo!=null && StringUtils.isNotBlank(xxlJobInfo.getChildJobKey())) { + String[] jobKeyArr = xxlJobInfo.getChildJobKey().split("_"); + if (jobKeyArr!=null && jobKeyArr.length==2) { + XxlJobInfo childJobInfo = DynamicSchedulerUtil.xxlJobInfoDao.load(jobKeyArr[0], jobKeyArr[1]); + if (childJobInfo!=null) { + try { + boolean ret = DynamicSchedulerUtil.triggerJob(childJobInfo.getJobName(), childJobInfo.getJobGroup()); + + // add msg + String msg = requestModel.getMsg(); + msg += MessageFormat.format("
触发子任务执行, jobKey:{0}, status:{1}, 描述:{2}", xxlJobInfo.getChildJobKey(), ret, childJobInfo.getJobDesc()); + requestModel.setMsg(msg); + } catch (SchedulerException e) { + logger.error("", e); + } + } + } + } + } + + // save log log.setHandleTime(new Date()); log.setHandleStatus(requestModel.getStatus()); log.setHandleMsg(requestModel.getMsg()); diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobInfo.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobInfo.java index 91a7f070..04db4c36 100644 --- a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobInfo.java +++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobInfo.java @@ -28,6 +28,8 @@ public class XxlJobInfo { private int glueSwitch; // GLUE模式开关:0-否,1-是 private String glueSource; // GLUE源代码 private String glueRemark; // GLUE备注 + + private String childJobKey; // 子任务Key // copy from quartz private String jobStatus; // 任务状态 【base on quartz】 @@ -152,6 +154,14 @@ public class XxlJobInfo { this.glueRemark = glueRemark; } + public String getChildJobKey() { + return childJobKey; + } + + public void setChildJobKey(String childJobKey) { + this.childJobKey = childJobKey; + } + public String getJobStatus() { return jobStatus; } diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/service/IXxlJobService.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/service/IXxlJobService.java index ccca803c..d4f41fa9 100644 --- a/xxl-job-admin/src/main/java/com/xxl/job/admin/service/IXxlJobService.java +++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/service/IXxlJobService.java @@ -14,10 +14,11 @@ public interface IXxlJobService { public Map pageList(int start, int length, String jobGroup, String executorHandler, String filterTime); public ReturnT add(String jobGroup, String jobCron, String jobDesc,String author, String alarmEmail, - String executorAddress, String executorHandler, String executorParam, int glueSwitch, String glueSource, String glueRemark); + String executorAddress, String executorHandler, String executorParam, int glueSwitch, String glueSource, String glueRemark, + String childJobKey); public ReturnT reschedule(String jobGroup, String jobName, String jobCron, String jobDesc, String author, String alarmEmail, - String executorAddress, String executorHandler, String executorParam, int glueSwitch); + String executorAddress, String executorHandler, String executorParam, int glueSwitch, String childJobKey); public ReturnT remove(String jobGroup, String jobName); diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java index e86452ac..24eec955 100644 --- a/xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java +++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java @@ -61,7 +61,8 @@ public class XxlJobServiceImpl implements IXxlJobService { @Override public ReturnT add(String jobGroup, String jobCron, String jobDesc, String author, String alarmEmail, - String executorAddress, String executorHandler, String executorParam, int glueSwitch, String glueSource, String glueRemark) { + String executorAddress, String executorHandler, String executorParam, int glueSwitch, String glueSource, String glueRemark, + String childJobKey) { // valid if (JobGroupEnum.match(jobGroup) == null) { return new ReturnT(500, "请选择“任务组”"); @@ -110,6 +111,7 @@ public class XxlJobServiceImpl implements IXxlJobService { jobInfo.setGlueSwitch(glueSwitch); jobInfo.setGlueSource(glueSource); jobInfo.setGlueRemark(glueRemark); + jobInfo.setChildJobKey(childJobKey); try { // add job 2 quartz @@ -128,7 +130,7 @@ public class XxlJobServiceImpl implements IXxlJobService { @Override public ReturnT reschedule(String jobGroup, String jobName, String jobCron, String jobDesc, String author, String alarmEmail, - String executorAddress, String executorHandler, String executorParam, int glueSwitch) { + String executorAddress, String executorHandler, String executorParam, int glueSwitch, String childJobKey) { // valid if (JobGroupEnum.match(jobGroup) == null) { @@ -166,6 +168,7 @@ public class XxlJobServiceImpl implements IXxlJobService { jobInfo.setExecutorHandler(executorHandler); jobInfo.setExecutorParam(executorParam); jobInfo.setGlueSwitch(glueSwitch); + jobInfo.setChildJobKey(childJobKey); try { // fresh quartz diff --git a/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml b/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml index 0a8b1915..abc0ea51 100644 --- a/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml +++ b/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml @@ -24,6 +24,8 @@ + + @@ -41,7 +43,8 @@ t.executor_param, t.glue_switch, t.glue_source, - t.glue_remark + t.glue_remark, + t.child_jobkey +
+ +
+

@@ -219,13 +224,16 @@ public class DemoJobHandler extends IJobHandler {
-
+
+ +
+

diff --git a/xxl-job-admin/src/main/webapp/static/js/jobinfo.index.1.js b/xxl-job-admin/src/main/webapp/static/js/jobinfo.index.1.js index 87545561..ccbff0a9 100644 --- a/xxl-job-admin/src/main/webapp/static/js/jobinfo.index.1.js +++ b/xxl-job-admin/src/main/webapp/static/js/jobinfo.index.1.js @@ -35,6 +35,14 @@ $(function() { } }, { "data": 'jobName', "visible" : false}, + { + "data": 'childJobKey', + "visible" : true, + "render": function ( data, type, row ) { + var jobKey = row.jobGroup + "_" + row.jobName; + return jobKey; + } + }, { "data": 'jobDesc', "visible" : true}, { "data": 'jobCron', "visible" : true}, { "data": 'executorAddress', "visible" : false}, @@ -103,6 +111,7 @@ $(function() { ' executorHandler="'+row.executorHandler +'" '+ ' executorParam="'+ row.executorParam +'" '+ ' glueSwitch="'+ row.glueSwitch +'" '+ + ' childJobKey="'+ row.childJobKey +'" '+ '>'+ ' '+ pause_resume + @@ -284,6 +293,8 @@ $(function() { addModalValidate.resetForm(); $("#addModal .form .form-group").removeClass("has-error"); $(".remote_panel").show(); // remote + + $("#addModal .form input[name='executorHandler']").removeAttr("readonly"); }); // GLUE模式开启 @@ -314,6 +325,7 @@ $(function() { $("#updateModal .form input[name='executorAddress']").val($(this).parent('p').attr("executorAddress")); $("#updateModal .form input[name='executorHandler']").val($(this).parent('p').attr("executorHandler")); $("#updateModal .form input[name='executorParam']").val($(this).parent('p').attr("executorParam")); + $("#updateModal .form input[name='childJobKey']").val($(this).parent('p').attr("childJobKey")); // jobGroupTitle var jobGroupTitle = $("#addModal .form select[name='jobGroup']").find("option[value='" + $(this).parent('p').attr("jobGroup") + "']").text();