Ver código fonte

1、任务属性新增"路由策略"并设计交互;
2、GLUE源码底层结构调整;

xueli.xue 8 anos atrás
pai
commit
f3573c8643

+ 2 - 2
README.md

@@ -88,10 +88,10 @@ XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是
 ![输入图片说明](https://static.oschina.net/uploads/img/201703/07162326_L3VB.png "在这里输入图片标题")
 
 #### 1.5 环境
+- Servlet/JSP Spec:3.0/2.2
 - JDK:1.7+
-- Tomcat:7+
+- Tomcat:7+/Jetty8+
 - Mysql:5.6+
-- Servlet/JSP Spec:3.0/2.2
 - Maven:3+
 
 

+ 19 - 25
xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobCodeController.java

@@ -5,7 +5,6 @@ import com.xxl.job.admin.core.model.XxlJobLogGlue;
 import com.xxl.job.admin.dao.IXxlJobInfoDao;
 import com.xxl.job.admin.dao.IXxlJobLogGlueDao;
 import com.xxl.job.core.biz.model.ReturnT;
-import org.apache.commons.lang.StringUtils;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -28,9 +27,9 @@ public class JobCodeController {
 	private IXxlJobLogGlueDao xxlJobLogGlueDao;
 
 	@RequestMapping
-	public String index(Model model, int jobGroup, String jobName) {
-		XxlJobInfo jobInfo = xxlJobInfoDao.load(jobGroup, jobName);
-		List<XxlJobLogGlue> jobLogGlues = xxlJobLogGlueDao.selectList(jobGroup, jobName);
+	public String index(Model model, int jobId) {
+		XxlJobInfo jobInfo = xxlJobInfoDao.loadById(jobId);
+		List<XxlJobLogGlue> jobLogGlues = xxlJobLogGlueDao.findByJobId(jobId);
 		model.addAttribute("jobInfo", jobInfo);
 		model.addAttribute("jobLogGlues", jobLogGlues);
 		return "jobcode/jobcode.index";
@@ -38,7 +37,7 @@ public class JobCodeController {
 	
 	@RequestMapping("/save")
 	@ResponseBody
-	public ReturnT<String> save(Model model, int jobGroup, String jobName, String glueSource, String glueRemark) {
+	public ReturnT<String> save(Model model, int id, String glueSource, String glueRemark) {
 		// valid
 		if (glueRemark==null) {
 			return new ReturnT<String>(500, "请输入备注");
@@ -46,31 +45,26 @@ public class JobCodeController {
 		if (glueRemark.length()<6 || glueRemark.length()>100) {
 			return new ReturnT<String>(500, "备注长度应该在6至100之间");
 		}
-		XxlJobInfo jobInfoOld = xxlJobInfoDao.load(jobGroup, jobName);
-		if (jobInfoOld == null) {
-			return new ReturnT<String>(500, "任务不存在");
+		XxlJobInfo exists_jobInfo = xxlJobInfoDao.loadById(id);
+		if (exists_jobInfo == null) {
+			return new ReturnT<String>(500, "参数异常");
 		}
 		
 		// log old code
 		XxlJobLogGlue xxlJobLogGlue = new XxlJobLogGlue();
-		xxlJobLogGlue.setJobGroup(jobInfoOld.getJobGroup());
-		xxlJobLogGlue.setJobName(jobInfoOld.getJobName());
-		xxlJobLogGlue.setGlueSource(jobInfoOld.getGlueSource());
-		xxlJobLogGlue.setGlueRemark(jobInfoOld.getGlueRemark());
-		
-		// init new code
-		jobInfoOld.setGlueSource(glueSource);
-		jobInfoOld.setGlueRemark(glueRemark);
-		
-		// update new code ,and log old code
-		xxlJobInfoDao.update(jobInfoOld);
-		if (StringUtils.isNotBlank(xxlJobLogGlue.getGlueSource()) && StringUtils.isNotBlank(xxlJobLogGlue.getGlueRemark())) {
-			xxlJobLogGlueDao.save(xxlJobLogGlue);
-			// remove code backup more than 30
-			xxlJobLogGlueDao.removeOld(xxlJobLogGlue.getJobGroup(), xxlJobLogGlue.getJobName(), 30);
-		}
-		
+		xxlJobLogGlue.setJobId(exists_jobInfo.getId());
+		xxlJobLogGlue.setGlueSource(exists_jobInfo.getGlueSource());
+		xxlJobLogGlue.setGlueRemark(exists_jobInfo.getGlueRemark());
+		xxlJobLogGlueDao.save(xxlJobLogGlue);
 		
+		// update new code
+		exists_jobInfo.setGlueSource(glueSource);
+		exists_jobInfo.setGlueRemark(glueRemark);
+		xxlJobInfoDao.update(exists_jobInfo);
+
+		// remove code backup more than 30
+		xxlJobLogGlueDao.removeOld(exists_jobInfo.getId(), 3);
+
 		return ReturnT.SUCCESS;
 	}
 	

+ 9 - 12
xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobInfoController.java

@@ -1,6 +1,8 @@
 package com.xxl.job.admin.controller;
 
 import com.xxl.job.admin.core.model.XxlJobGroup;
+import com.xxl.job.admin.core.model.XxlJobInfo;
+import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum;
 import com.xxl.job.admin.dao.IXxlJobGroupDao;
 import com.xxl.job.admin.service.IXxlJobService;
 import com.xxl.job.core.biz.model.ReturnT;
@@ -30,9 +32,11 @@ public class JobInfoController {
 	@RequestMapping
 	public String index(Model model) {
 
+		// 路由策略-列表
+		model.addAttribute("ExecutorRouteStrategyEnum", ExecutorRouteStrategyEnum.values());
+
 		// 任务组
 		List<XxlJobGroup> jobGroupList =  xxlJobGroupDao.findAll();
-
 		model.addAttribute("JobGroupList", jobGroupList);
 		return "jobinfo/jobinfo.index";
 	}
@@ -48,21 +52,14 @@ public class JobInfoController {
 	
 	@RequestMapping("/add")
 	@ResponseBody
-	public ReturnT<String> add(int jobGroup, String jobCron, String jobDesc, String author, String alarmEmail,
-							   String executorHandler, String executorParam, int glueSwitch, String glueSource, String glueRemark, String childJobKey) {
-		
-		return xxlJobService.add(jobGroup, jobCron, jobDesc, author, alarmEmail,
-				executorHandler, executorParam,
-				glueSwitch, glueSource, glueRemark, childJobKey);
+	public ReturnT<String> add(XxlJobInfo jobInfo) {
+		return xxlJobService.add(jobInfo);
 	}
 	
 	@RequestMapping("/reschedule")
 	@ResponseBody
-	public ReturnT<String> reschedule(int jobGroup, String jobName, String jobCron, String jobDesc, String author, String alarmEmail,
-			String executorHandler, String executorParam, int glueSwitch, String childJobKey) {
-
-		return xxlJobService.reschedule(jobGroup, jobName, jobCron, jobDesc, author, alarmEmail,
-				executorHandler, executorParam, glueSwitch, childJobKey);
+	public ReturnT<String> reschedule(XxlJobInfo jobInfo) {
+		return xxlJobService.reschedule(jobInfo);
 	}
 	
 	@RequestMapping("/remove")

+ 26 - 20
xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobLogGlue.java

@@ -7,63 +7,69 @@ package com.xxl.job.admin.core.model;
 public class XxlJobLogGlue {
 	
 	private int id;
-	
-	private int jobGroup;
-	private String jobName;
-	
+	private int jobId;
 	private String glueSource;
 	private String glueRemark;
 	private String addTime;
 	private String updateTime;
-	
+
 	public int getId() {
 		return id;
 	}
+
 	public void setId(int id) {
 		this.id = id;
 	}
-	public int getJobGroup() {
-		return jobGroup;
-	}
-	public void setJobGroup(int jobGroup) {
-		this.jobGroup = jobGroup;
-	}
-	public String getJobName() {
-		return jobName;
+
+	public int getJobId() {
+		return jobId;
 	}
-	public void setJobName(String jobName) {
-		this.jobName = jobName;
+
+	public void setJobId(int jobId) {
+		this.jobId = jobId;
 	}
+
 	public String getGlueSource() {
 		return glueSource;
 	}
+
 	public void setGlueSource(String glueSource) {
 		this.glueSource = glueSource;
 	}
+
 	public String getGlueRemark() {
 		return glueRemark;
 	}
+
 	public void setGlueRemark(String glueRemark) {
 		this.glueRemark = glueRemark;
 	}
+
 	public String getAddTime() {
 		return addTime;
 	}
+
 	public void setAddTime(String addTime) {
 		this.addTime = addTime;
 	}
+
 	public String getUpdateTime() {
 		return updateTime;
 	}
+
 	public void setUpdateTime(String updateTime) {
 		this.updateTime = updateTime;
 	}
-	
+
 	@Override
 	public String toString() {
-		return "XxlJobLogGlue [id=" + id + ", jobGroup=" + jobGroup + ", jobName=" + jobName + ", glueSource="
-				+ glueSource + ", glueRemark=" + glueRemark + ", addTime=" + addTime + ", updateTime=" + updateTime
-				+ "]";
+		return "XxlJobLogGlue{" +
+				"id=" + id +
+				", jobId=" + jobId +
+				", glueSource='" + glueSource + '\'' +
+				", glueRemark='" + glueRemark + '\'' +
+				", addTime='" + addTime + '\'' +
+				", updateTime='" + updateTime + '\'' +
+				'}';
 	}
-	
 }

+ 5 - 3
xxl-job-admin/src/main/java/com/xxl/job/admin/core/route/ExecutorRouteStrategyEnum.java

@@ -32,9 +32,11 @@ public enum ExecutorRouteStrategyEnum {
     }
 
     public static ExecutorRouteStrategyEnum match(String name, ExecutorRouteStrategyEnum defaultItem){
-        for (ExecutorRouteStrategyEnum item: ExecutorRouteStrategyEnum.values()) {
-            if (item.name().equals(name)) {
-                return item;
+        if (name != null) {
+            for (ExecutorRouteStrategyEnum item: ExecutorRouteStrategyEnum.values()) {
+                if (item.name().equals(name)) {
+                    return item;
+                }
             }
         }
         return defaultItem;

+ 2 - 1
xxl-job-admin/src/main/java/com/xxl/job/admin/dao/IXxlJobInfoDao.java

@@ -16,7 +16,8 @@ public interface IXxlJobInfoDao {
 	public int pageListCount(int offset, int pagesize, int jobGroup, String executorHandler);
 	
 	public int save(XxlJobInfo info);
-	
+
+	public XxlJobInfo loadById(int id);
 	public XxlJobInfo load(int jobGroup, String jobName);
 	
 	public int update(XxlJobInfo item);

+ 3 - 3
xxl-job-admin/src/main/java/com/xxl/job/admin/dao/IXxlJobLogGlueDao.java

@@ -12,10 +12,10 @@ public interface IXxlJobLogGlueDao {
 	
 	public int save(XxlJobLogGlue xxlJobLogGlue);
 	
-	public List<XxlJobLogGlue> selectList(int jobGroup, String jobName);
+	public List<XxlJobLogGlue> findByJobId(int jobId);
 
-	public int removeOld(int jobGroup, String jobName, int limit);
+	public int removeOld(int jobId, int limit);
 
-	public int delete(int jobGroup, String jobName);
+	public int deleteByJobId(int jobId);
 	
 }

+ 5 - 0
xxl-job-admin/src/main/java/com/xxl/job/admin/dao/impl/XxlJobInfoDaoImpl.java

@@ -48,6 +48,11 @@ public class XxlJobInfoDaoImpl implements IXxlJobInfoDao {
 	}
 
 	@Override
+	public XxlJobInfo loadById(int id) {
+		return sqlSessionTemplate.selectOne("XxlJobInfoMapper.loadById", id);
+	}
+
+	@Override
 	public XxlJobInfo load(int jobGroup, String jobName) {
 		HashMap<String, Object> params = new HashMap<String, Object>();
 		params.put("jobGroup", jobGroup);

+ 6 - 13
xxl-job-admin/src/main/java/com/xxl/job/admin/dao/impl/XxlJobLogGlueDaoImpl.java

@@ -25,28 +25,21 @@ public class XxlJobLogGlueDaoImpl implements IXxlJobLogGlueDao {
 	}
 
 	@Override
-	public List<XxlJobLogGlue> selectList(int jobGroup, String jobName) {
-		HashMap<String, Object> params = new HashMap<String, Object>();
-		params.put("jobGroup", jobGroup);
-		params.put("jobName", jobName);
-		return sqlSessionTemplate.selectList("XxlJobLogGlueMapper.selectList", params);
+	public List<XxlJobLogGlue> findByJobId(int jobId) {
+		return sqlSessionTemplate.selectList("XxlJobLogGlueMapper.findByJobId", jobId);
 	}
 
 	@Override
-	public int removeOld(int jobGroup, String jobName, int limit) {
+	public int removeOld(int jobId, int limit) {
 		HashMap<String, Object> params = new HashMap<String, Object>();
-		params.put("jobGroup", jobGroup);
-		params.put("jobName", jobName);
+		params.put("jobId", jobId);
 		params.put("limit", limit);
 		return sqlSessionTemplate.delete("XxlJobLogGlueMapper.removeOld", params);
 	}
 
 	@Override
-	public int delete(int jobGroup, String jobName) {
-		HashMap<String, Object> params = new HashMap<String, Object>();
-		params.put("jobGroup", jobGroup);
-		params.put("jobName", jobName);
-		return sqlSessionTemplate.delete("XxlJobLogGlueMapper.delete", params);
+	public int deleteByJobId(int jobId) {
+		return sqlSessionTemplate.delete("XxlJobLogGlueMapper.deleteByJobId", jobId);
 	}
 	
 }

+ 3 - 4
xxl-job-admin/src/main/java/com/xxl/job/admin/service/IXxlJobService.java

@@ -1,6 +1,7 @@
 package com.xxl.job.admin.service;
 
 
+import com.xxl.job.admin.core.model.XxlJobInfo;
 import com.xxl.job.core.biz.model.ReturnT;
 
 import java.util.Map;
@@ -14,11 +15,9 @@ public interface IXxlJobService {
 	
 	public Map<String, Object> pageList(int start, int length, int jobGroup, String executorHandler, String filterTime);
 	
-	public ReturnT<String> add(int jobGroup, String jobCron, String jobDesc, String author, String alarmEmail,
-			String executorHandler, String executorParam, int glueSwitch, String glueSource, String glueRemark, String childJobKey);
+	public ReturnT<String> add(XxlJobInfo jobInfo);
 	
-	public ReturnT<String> reschedule(int jobGroup, String jobName, String jobCron, String jobDesc, String author, String alarmEmail,
-			String executorHandler, String executorParam, int glueSwitch, String childJobKey);
+	public ReturnT<String> reschedule(XxlJobInfo jobInfo);
 	
 	public ReturnT<String> remove(int jobGroup, String jobName);
 	

+ 48 - 43
xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java

@@ -2,6 +2,7 @@ package com.xxl.job.admin.service.impl;
 
 import com.xxl.job.admin.core.model.XxlJobGroup;
 import com.xxl.job.admin.core.model.XxlJobInfo;
+import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum;
 import com.xxl.job.admin.core.schedule.XxlJobDynamicScheduler;
 import com.xxl.job.admin.dao.IXxlJobGroupDao;
 import com.xxl.job.admin.dao.IXxlJobInfoDao;
@@ -64,33 +65,34 @@ public class XxlJobServiceImpl implements IXxlJobService {
 	}
 
 	@Override
-	public ReturnT<String> add(int jobGroup, String jobCron, String jobDesc, String author, String alarmEmail,
-							   String executorHandler, String executorParam,
-							   int glueSwitch, String glueSource, String glueRemark, String childJobKey) {
+	public ReturnT<String> add(XxlJobInfo jobInfo) {
 		// valid
-		XxlJobGroup group = xxlJobGroupDao.load(jobGroup);
+		XxlJobGroup group = xxlJobGroupDao.load(jobInfo.getJobGroup());
 		if (group == null) {
 			return new ReturnT<String>(500, "请选择“执行器”");
 		}
-		if (!CronExpression.isValidExpression(jobCron)) {
+		if (!CronExpression.isValidExpression(jobInfo.getJobCron())) {
 			return new ReturnT<String>(500, "请输入格式正确的“Cron”");
 		}
-		if (StringUtils.isBlank(jobDesc)) {
+		if (StringUtils.isBlank(jobInfo.getJobDesc())) {
 			return new ReturnT<String>(500, "请输入“任务描述”");
 		}
-		if (StringUtils.isBlank(author)) {
+		if (StringUtils.isBlank(jobInfo.getAuthor())) {
 			return new ReturnT<String>(500, "请输入“负责人”");
 		}
-		if (StringUtils.isBlank(alarmEmail)) {
+		if (StringUtils.isBlank(jobInfo.getAlarmEmail())) {
 			return new ReturnT<String>(500, "请输入“报警邮件”");
 		}
-		if (glueSwitch==0 && StringUtils.isBlank(executorHandler)) {
+		if (ExecutorRouteStrategyEnum.match(jobInfo.getExecutorRouteStrategy(), null) == null) {
+			return new ReturnT<String>(500, "路由策略非法");
+		}
+		if (jobInfo.getGlueSwitch()==0 && StringUtils.isBlank(jobInfo.getExecutorHandler())) {
 			return new ReturnT<String>(500, "请输入“JobHandler”");
 		}
 
 		// childJobKey valid
-		if (StringUtils.isNotBlank(childJobKey)) {
-			String[] childJobKeys = childJobKey.split(",");
+		if (StringUtils.isNotBlank(jobInfo.getChildJobKey())) {
+			String[] childJobKeys = jobInfo.getChildJobKey().split(",");
 			for (String childJobKeyItem: childJobKeys) {
 				String[] childJobKeyArr = childJobKeyItem.split("_");
 				if (childJobKeyArr.length!=2) {
@@ -105,8 +107,9 @@ public class XxlJobServiceImpl implements IXxlJobService {
 
 		// generate jobName
 		String jobName = FastDateFormat.getInstance("yyyyMMddHHmmssSSSS").format(new Date());
+		jobInfo.setJobName(jobName);
 		try {
-			if (XxlJobDynamicScheduler.checkExists(jobName, String.valueOf(jobGroup))) {
+			if (XxlJobDynamicScheduler.checkExists(jobName, String.valueOf(jobInfo.getJobGroup()))) {
 				return new ReturnT<String>(500, "系统繁忙,请稍后重试");
 			}
 		} catch (SchedulerException e1) {
@@ -115,7 +118,7 @@ public class XxlJobServiceImpl implements IXxlJobService {
 		}
 
 		// Backup to the database
-		XxlJobInfo jobInfo = new XxlJobInfo();
+		/*XxlJobInfo jobInfo = new XxlJobInfo();
 		jobInfo.setJobGroup(jobGroup);
 		jobInfo.setJobName(jobName);
 		jobInfo.setJobCron(jobCron);
@@ -127,11 +130,11 @@ public class XxlJobServiceImpl implements IXxlJobService {
 		jobInfo.setGlueSwitch(glueSwitch);
 		jobInfo.setGlueSource(glueSource);
 		jobInfo.setGlueRemark(glueRemark);
-		jobInfo.setChildJobKey(childJobKey);
+		jobInfo.setChildJobKey(childJobKey);*/
 
 		try {
 			// add job 2 quartz
-			boolean result = XxlJobDynamicScheduler.addJob(String.valueOf(jobGroup), jobName, jobCron);
+			boolean result = XxlJobDynamicScheduler.addJob(String.valueOf(jobInfo.getJobGroup()), jobName, jobInfo.getJobCron());
 			if (result) {
 				xxlJobInfoDao.save(jobInfo);
 				return ReturnT.SUCCESS;
@@ -145,36 +148,31 @@ public class XxlJobServiceImpl implements IXxlJobService {
 	}
 
 	@Override
-	public ReturnT<String> reschedule(int jobGroup, String jobName, String jobCron, String jobDesc, String author, String alarmEmail,
-			String executorHandler, String executorParam, int glueSwitch, String childJobKey) {
+	public ReturnT<String> reschedule(XxlJobInfo jobInfo) {
 
 		// valid
-		XxlJobGroup group = xxlJobGroupDao.load(jobGroup);
-		if (group == null) {
-			return new ReturnT<String>(500, "请选择“执行器”");
-		}
-		if (StringUtils.isBlank(jobName)) {
-			return new ReturnT<String>(500, "请输入“任务名”");
-		}
-		if (!CronExpression.isValidExpression(jobCron)) {
+		if (!CronExpression.isValidExpression(jobInfo.getJobCron())) {
 			return new ReturnT<String>(500, "请输入格式正确的“Cron”");
 		}
-		if (StringUtils.isBlank(jobDesc)) {
+		if (StringUtils.isBlank(jobInfo.getJobDesc())) {
 			return new ReturnT<String>(500, "请输入“任务描述”");
 		}
-		if (StringUtils.isBlank(author)) {
+		if (StringUtils.isBlank(jobInfo.getAuthor())) {
 			return new ReturnT<String>(500, "请输入“负责人”");
 		}
-		if (StringUtils.isBlank(alarmEmail)) {
+		if (StringUtils.isBlank(jobInfo.getAlarmEmail())) {
 			return new ReturnT<String>(500, "请输入“报警邮件”");
 		}
-		if (glueSwitch==0 && StringUtils.isBlank(executorHandler)) {
+		if (ExecutorRouteStrategyEnum.match(jobInfo.getExecutorRouteStrategy(), null) == null) {
+			return new ReturnT<String>(500, "路由策略非法");
+		}
+		if (jobInfo.getGlueSwitch()==0 && StringUtils.isBlank(jobInfo.getExecutorHandler())) {
 			return new ReturnT<String>(500, "请输入“JobHandler”");
 		}
 
 		// childJobKey valid
-		if (StringUtils.isNotBlank(childJobKey)) {
-			String[] childJobKeys = childJobKey.split(",");
+		if (StringUtils.isNotBlank(jobInfo.getChildJobKey())) {
+			String[] childJobKeys = jobInfo.getChildJobKey().split(",");
 			for (String childJobKeyItem: childJobKeys) {
 				String[] childJobKeyArr = childJobKeyItem.split("_");
 				if (childJobKeyArr.length!=2) {
@@ -188,21 +186,26 @@ public class XxlJobServiceImpl implements IXxlJobService {
 		}
 
 		// stage job info
-		XxlJobInfo jobInfo = xxlJobInfoDao.load(jobGroup, jobName);
-		jobInfo.setJobCron(jobCron);
-		jobInfo.setJobDesc(jobDesc);
-		jobInfo.setAuthor(author);
-		jobInfo.setAlarmEmail(alarmEmail);
-		jobInfo.setExecutorHandler(executorHandler);
-		jobInfo.setExecutorParam(executorParam);
-		jobInfo.setGlueSwitch(glueSwitch);
-		jobInfo.setChildJobKey(childJobKey);
+		XxlJobInfo exists_jobInfo = xxlJobInfoDao.loadById(jobInfo.getId());
+		if (exists_jobInfo == null) {
+			return new ReturnT<String>(500, "参数异常");
+		}
+
+		exists_jobInfo.setJobCron(jobInfo.getJobCron());
+		exists_jobInfo.setJobDesc(jobInfo.getJobDesc());
+		exists_jobInfo.setAuthor(jobInfo.getAuthor());
+		exists_jobInfo.setAlarmEmail(jobInfo.getAlarmEmail());
+		exists_jobInfo.setExecutorRouteStrategy(jobInfo.getExecutorRouteStrategy());
+		exists_jobInfo.setExecutorHandler(jobInfo.getExecutorHandler());
+		exists_jobInfo.setExecutorParam(jobInfo.getExecutorParam());
+		exists_jobInfo.setGlueSwitch(jobInfo.getGlueSwitch());
+		exists_jobInfo.setChildJobKey(jobInfo.getChildJobKey());
 		
 		try {
 			// fresh quartz
-			boolean ret = XxlJobDynamicScheduler.rescheduleJob(String.valueOf(jobGroup), jobName, jobCron);
+			boolean ret = XxlJobDynamicScheduler.rescheduleJob(String.valueOf(exists_jobInfo.getJobGroup()), exists_jobInfo.getJobName(), exists_jobInfo.getJobCron());
 			if (ret) {
-				xxlJobInfoDao.update(jobInfo);
+				xxlJobInfoDao.update(exists_jobInfo);
 				return ReturnT.SUCCESS;
 			} else {
 				return new ReturnT<String>(500, "更新任务失败");
@@ -215,11 +218,13 @@ public class XxlJobServiceImpl implements IXxlJobService {
 
 	@Override
 	public ReturnT<String> remove(int jobGroup, String jobName) {
+		XxlJobInfo xxlJobInfo = xxlJobInfoDao.load(jobGroup, jobName);
+
 		try {
 			XxlJobDynamicScheduler.removeJob(jobName, String.valueOf(jobGroup));
 			xxlJobInfoDao.delete(jobGroup, jobName);
 			xxlJobLogDao.delete(jobGroup, jobName);
-			xxlJobLogGlueDao.delete(jobGroup, jobName);
+			xxlJobLogGlueDao.deleteByJobId(xxlJobInfo.getId());
 			return ReturnT.SUCCESS;
 		} catch (SchedulerException e) {
 			e.printStackTrace();

+ 7 - 1
xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml

@@ -113,7 +113,13 @@
 			SELECT LAST_INSERT_ID() 
 		</selectKey> 
 	</insert>
-	
+
+	<select id="loadById" parameterType="java.util.HashMap" resultMap="XxlJobInfo">
+		SELECT <include refid="Base_Column_List" />
+		FROM XXL_JOB_QRTZ_TRIGGER_INFO AS t
+		WHERE t.id = #{id}
+	</select>
+
 	<select id="load" parameterType="java.util.HashMap" resultMap="XxlJobInfo">
 		SELECT <include refid="Base_Column_List" />
 		FROM XXL_JOB_QRTZ_TRIGGER_INFO AS t

+ 11 - 22
xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobLogGlueMapper.xml

@@ -5,8 +5,7 @@
 	
 	<resultMap id="XxlJobLogGlue" type="com.xxl.job.admin.core.model.XxlJobLogGlue" >
 		<result column="id" property="id" />
-	    <result column="job_group" property="jobGroup" />
-	    <result column="job_name" property="jobName" />
+	    <result column="job_id" property="jobId" />
 	    <result column="glue_source" property="glueSource" />
 	    <result column="glue_remark" property="glueRemark" />
 	    <result column="add_time" property="addTime" />
@@ -15,8 +14,7 @@
 
 	<sql id="Base_Column_List">
 		t.id,
-		t.job_group,
-		t.job_name,
+		t.job_id,
 		t.glue_source,
 		t.glue_remark,
 		t.add_time,
@@ -25,15 +23,13 @@
 	
 	<insert id="save" parameterType="com.xxl.job.admin.core.model.XxlJobLogGlue" useGeneratedKeys="true" keyProperty="id" >
 		INSERT INTO XXL_JOB_QRTZ_TRIGGER_LOGGLUE (
-			`job_group`,
-			`job_name`,
-			`glue_source`, 
+			`job_id`,
+			`glue_source`,
 			`glue_remark`,
 			`add_time`, 
 			`update_time`
 		) VALUES (
-			#{jobGroup}, 
-			#{jobName},
+			#{jobId},
 			#{glueSource},
 			#{glueRemark},
 			now(),
@@ -44,17 +40,10 @@
 		</selectKey> 
 	</insert>
 	
-	<select id="selectList" parameterType="java.util.HashMap" resultMap="XxlJobLogGlue">
+	<select id="findByJobId" parameterType="java.lang.Integer" resultMap="XxlJobLogGlue">
 		SELECT <include refid="Base_Column_List" />
 		FROM XXL_JOB_QRTZ_TRIGGER_LOGGLUE AS t
-		<trim prefix="WHERE" prefixOverrides="AND | OR" >
-			<if test="jobGroup gt 0">
-				AND t.job_group = #{jobGroup}
-			</if>
-			<if test="jobName != null and jobName != ''">
-				AND t.job_name = #{jobName}
-			</if>
-		</trim>
+		WHERE t.job_id = #{jobId}
 		ORDER BY id DESC
 	</select>
 	
@@ -63,16 +52,16 @@
 		WHERE id NOT in(
 			SELECT id FROM(
 				SELECT id FROM XXL_JOB_QRTZ_TRIGGER_LOGGLUE
-				WHERE `job_group` = #{jobGroup} and `job_name` = #{jobName}
+				WHERE `job_id` = #{jobId}
 				ORDER BY update_time desc
 				LIMIT 0, #{limit}
 			) t1
-		) AND `job_group` = #{jobGroup} and `job_name` = #{jobName}
+		) AND `job_id` = #{jobId}
 	</delete>
 	
-	<delete id="delete" parameterType="java.util.HashMap" >
+	<delete id="deleteByJobId" parameterType="java.lang.Integer" >
 		DELETE FROM XXL_JOB_QRTZ_TRIGGER_LOGGLUE
-		WHERE job_group = #{jobGroup} and job_name = #{jobName}
+		WHERE `job_id` = #{jobId}
 	</delete>
 	
 </mapper>

+ 1 - 2
xxl-job-admin/src/main/webapp/WEB-INF/template/jobcode/jobcode.index.ftl

@@ -94,8 +94,7 @@
 <script src="${request.contextPath}/static/plugins/codemirror/addon/hint/show-hint.js"></script>
 <script src="${request.contextPath}/static/plugins/codemirror/addon/hint/anyword-hint.js"></script>
 <script>
-var jobGroup = '${jobInfo.jobGroup}';
-var jobName = '${jobInfo.jobName}';
+var id = '${jobInfo.id}';
 </script>
 <script src="${request.contextPath}/static/js/jobcode.index.1.js"></script>
 

+ 48 - 25
xxl-job-admin/src/main/webapp/WEB-INF/template/jobinfo/jobinfo.index.ftl

@@ -124,23 +124,29 @@
                         <label for="lastname" class="col-sm-2 control-label">任务描述<font color="red">*</font></label>
                         <div class="col-sm-4"><input type="text" class="form-control" name="jobDesc" placeholder="请输入“描述”" maxlength="50" ></div>
 					</div>
-					<div class="form-group">
+                    <div class="form-group">
+                        <label for="firstname" class="col-sm-2 control-label">路由策略<font color="red">*</font></label>
+                        <div class="col-sm-4">
+                            <select class="form-control" name="executorRouteStrategy" >
+							<#list ExecutorRouteStrategyEnum as item>
+                                <option value="${item}" >${item.title}</option>
+							</#list>
+                            </select>
+                        </div>
+                        <label for="lastname" class="col-sm-2 control-label">Cron<font color="red">*</font></label>
+                        <div class="col-sm-4"><input type="text" class="form-control" name="jobCron" placeholder="请输入“Cron”" maxlength="20" ></div>
+                    </div>
+                    <div class="form-group">
                         <label for="firstname" class="col-sm-2 control-label">JobHandler<font color="red">*</font></label>
                         <div class="col-sm-4">
                             <div class="input-group">
-								<input type="text" class="form-control" name="executorHandler" placeholder="请输入“JobHandler”" maxlength="100" >
-								<span class="input-group-addon"><b>GLUE</b>&nbsp;<input type="checkbox" class="ifGLUE" ></span>
+                                <input type="text" class="form-control" name="executorHandler" placeholder="请输入“JobHandler”" maxlength="100" >
+                                <span class="input-group-addon"><b>GLUE</b>&nbsp;<input type="checkbox" class="ifGLUE" ></span>
                                 <input type="hidden" name="glueSwitch" value="0" >
                             </div>
-						</div>
-						<label for="firstname" class="col-sm-2 control-label">执行参数<font color="black">*</font></label>
+                        </div>
+                        <label for="firstname" class="col-sm-2 control-label">执行参数<font color="black">*</font></label>
                         <div class="col-sm-4"><input type="text" class="form-control" name="executorParam" placeholder="请输入“执行参数”" maxlength="100" ></div>
-					</div>
-                    <div class="form-group">
-                        <label for="lastname" class="col-sm-2 control-label">Cron<font color="red">*</font></label>
-                        <div class="col-sm-4"><input type="text" class="form-control" name="jobCron" placeholder="请输入“Cron”" maxlength="20" ></div>
-                        <label for="lastname" class="col-sm-2 control-label">子任务Key<font color="black">*</font></label>
-                        <div class="col-sm-4"><input type="text" class="form-control" name="childJobKey" placeholder="请输入子任务的任务Key,如存在多个逗号分隔" maxlength="100" ></div>
                     </div>
 					<div class="form-group">
 						<label for="lastname" class="col-sm-2 control-label">报警邮件<font color="red">*</font></label>
@@ -148,6 +154,10 @@
                         <label for="lastname" class="col-sm-2 control-label">负责人<font color="red">*</font></label>
                         <div class="col-sm-4"><input type="text" class="form-control" name="author" placeholder="请输入“负责人”" maxlength="50" ></div>
 					</div>
+                    <div class="form-group">
+                        <label for="lastname" class="col-sm-2 control-label">子任务Key<font color="black">*</font></label>
+                        <div class="col-sm-4"><input type="text" class="form-control" name="childJobKey" placeholder="请输入子任务的任务Key,如存在多个逗号分隔" maxlength="100" ></div>
+                    </div>
                     <hr>
 					<div class="form-group">
 						<div class="col-sm-offset-3 col-sm-6">
@@ -191,14 +201,30 @@ public class DemoGlueJobHandler extends IJobHandler {
          	</div>
          	<div class="modal-body">
 				<form class="form-horizontal form" role="form" >
-					<div class="form-group">
+                    <div class="form-group">
                         <label for="firstname" class="col-sm-2 control-label">执行器<font color="red">*</font></label>
                         <div class="col-sm-4">
-							<input type="text" class="form-control jobGroupTitle" maxlength="50" readonly >
-						</div>
+                            <select class="form-control" name="jobGroup" disabled >
+							<#list JobGroupList as group>
+                                <option value="${group.id}" >${group.title}</option>
+							</#list>
+                            </select>
+                        </div>
                         <label for="lastname" class="col-sm-2 control-label">任务描述<font color="red">*</font></label>
                         <div class="col-sm-4"><input type="text" class="form-control" name="jobDesc" placeholder="请输入“描述”" maxlength="50" ></div>
-					</div>
+                    </div>
+                    <div class="form-group">
+                        <label for="firstname" class="col-sm-2 control-label">路由策略<font color="red">*</font></label>
+                        <div class="col-sm-4">
+                            <select class="form-control" name="executorRouteStrategy" >
+							<#list ExecutorRouteStrategyEnum as item>
+                                <option value="${item}" >${item.title}</option>
+							</#list>
+                            </select>
+                        </div>
+                        <label for="lastname" class="col-sm-2 control-label">Cron<font color="red">*</font></label>
+                        <div class="col-sm-4"><input type="text" class="form-control" name="jobCron" placeholder="请输入“Cron”" maxlength="20" ></div>
+                    </div>
                     <div class="form-group">
                         <label for="firstname" class="col-sm-2 control-label">JobHandler<font color="red">*</font></label>
                         <div class="col-sm-4">
@@ -212,24 +238,21 @@ public class DemoGlueJobHandler extends IJobHandler {
                         <div class="col-sm-4"><input type="text" class="form-control" name="executorParam" placeholder="请输入“执行参数”" maxlength="100" ></div>
                     </div>
                     <div class="form-group">
-                        <label for="lastname" class="col-sm-2 control-label">Cron<font color="red">*</font></label>
-                        <div class="col-sm-4"><input type="text" class="form-control" name="jobCron" placeholder="请输入“Cron”" maxlength="20" ></div>
+                        <label for="lastname" class="col-sm-2 control-label">报警邮件<font color="red">*</font></label>
+                        <div class="col-sm-4"><input type="text" class="form-control" name="alarmEmail" placeholder="请输入“报警邮件”,多个邮件地址逗号分隔" maxlength="100" ></div>
+                        <label for="lastname" class="col-sm-2 control-label">负责人<font color="red">*</font></label>
+                        <div class="col-sm-4"><input type="text" class="form-control" name="author" placeholder="请输入“负责人”" maxlength="50" ></div>
+                    </div>
+                    <div class="form-group">
                         <label for="lastname" class="col-sm-2 control-label">子任务Key<font color="black">*</font></label>
                         <div class="col-sm-4"><input type="text" class="form-control" name="childJobKey" placeholder="请输入子任务的任务Key,如存在多个逗号分隔" maxlength="100" ></div>
                     </div>
-					<div class="form-group">
-						<label for="lastname" class="col-sm-2 control-label">报警邮件<font color="red">*</font></label>
-						<div class="col-sm-4"><input type="text" class="form-control" name="alarmEmail" placeholder="请输入“报警邮件”,多个邮件地址逗号分隔" maxlength="100" ></div>
-                        <label for="lastname" class="col-sm-2 control-label">负责人<font color="red">*</font></label>
-                        <div class="col-sm-4"><input type="text" class="form-control" name="author" placeholder="请输入“负责人”" maxlength="50" ></div>
-					</div>
 					<hr>
 					<div class="form-group">
                         <div class="col-sm-offset-3 col-sm-6">
 							<button type="submit" class="btn btn-primary"  >保存</button>
 							<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
-                            <input type="hidden" name="jobGroup" >
-                            <input type="hidden" name="jobName" >
+                            <input type="hidden" name="id" >
 						</div>
 					</div>
 				</form>

+ 1 - 2
xxl-job-admin/src/main/webapp/static/js/jobcode.index.1.js

@@ -37,8 +37,7 @@ $(function() {
 				type : 'POST',
 				url : base_url + '/jobcode/save',
 				data : {
-					'jobGroup' : jobGroup,
-					'jobName' : jobName,
+					'id' : id,
 					'glueSource' : glueSource,
 					'glueRemark' : glueRemark
 				},

+ 5 - 7
xxl-job-admin/src/main/webapp/static/js/jobinfo.index.1.js

@@ -100,7 +100,7 @@ $(function() {
 	                			// log url
 	                			var codeBtn = "";
 	                			if(row.glueSwitch > 0){
-									var codeUrl = base_url +'/jobcode?jobGroup='+ row.jobGroup +'&jobName='+ row.jobName;
+									var codeUrl = base_url +'/jobcode?jobId='+ row.id;
 									codeBtn = '<button class="btn btn-warning btn-xs" type="button" onclick="javascript:window.open(\'' + codeUrl + '\')" >GLUE</button>  '
 								}
 
@@ -112,6 +112,7 @@ $(function() {
 									' jobDesc="'+ row.jobDesc +'" '+
 									' author="'+ row.author +'" '+
 									' alarmEmail="'+ row.alarmEmail +'" '+
+									' executorRouteStrategy="'+row.executorRouteStrategy +'" '+
 									' executorHandler="'+row.executorHandler +'" '+
 									' executorParam="'+ row.executorParam +'" '+
 									' glueSwitch="'+ row.glueSwitch +'" '+
@@ -323,20 +324,17 @@ $(function() {
 	$("#job_list").on('click', '.update',function() {
 
 		// base data
-		$("#updateModal .form input[name='jobGroup']").val($(this).parent('p').attr("jobGroup"));
-		$("#updateModal .form input[name='jobName']").val($(this).parent('p').attr("jobName"));
+		$("#updateModal .form input[name='id']").val($(this).parent('p').attr("id"));
+		$('#updateModal .form select[name=jobGroup] option[value='+ $(this).parent('p').attr("jobGroup") +']').prop('selected', true);
 		$("#updateModal .form input[name='jobDesc']").val($(this).parent('p').attr("jobDesc"));
 		$("#updateModal .form input[name='jobCron']").val($(this).parent('p').attr("jobCron"));
 		$("#updateModal .form input[name='author']").val($(this).parent('p').attr("author"));
 		$("#updateModal .form input[name='alarmEmail']").val($(this).parent('p').attr("alarmEmail"));
+		$('#updateModal .form select[name=executorRouteStrategy] option[value='+ $(this).parent('p').attr("executorRouteStrategy") +']').prop('selected', true);
 		$("#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();
-		$("#updateModal .form .jobGroupTitle").val(jobGroupTitle);
-
         // glueSwitch
 		var glueSwitch = $(this).parent('p').attr("glueSwitch");
 		$("#updateModal .form input[name='glueSwitch']").val(glueSwitch);