Bläddra i källkod

任务地址支持配置多个,进行failover

xueli.xue 9 år sedan
förälder
incheckning
71e12272c3
23 ändrade filer med 620 tillägg och 449 borttagningar
  1. 10 5
      db/tables_xxl_job.sql
  2. 13 196
      xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobInfoController.java
  3. 20 27
      xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobLogController.java
  4. 58 27
      xxl-job-admin/src/main/java/com/xxl/job/admin/core/jobbean/RemoteHttpJobBean.java
  5. 31 20
      xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobInfo.java
  6. 21 13
      xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobLog.java
  7. 7 9
      xxl-job-admin/src/main/java/com/xxl/job/admin/core/util/DynamicSchedulerUtil.java
  8. 2 5
      xxl-job-admin/src/main/java/com/xxl/job/admin/dao/impl/XxlJobLogDaoImpl.java
  9. 33 0
      xxl-job-admin/src/main/java/com/xxl/job/admin/service/IXxlJobService.java
  10. 241 0
      xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java
  11. 1 1
      xxl-job-admin/src/main/resources/applicationcontext-base.xml
  12. 1 3
      xxl-job-admin/src/main/resources/applicationcontext-database.xml
  13. 16 5
      xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml
  14. 18 5
      xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobLogMapper.xml
  15. 9 7
      xxl-job-admin/src/main/webapp/WEB-INF/template/jobinfo/jobinfo.index.ftl
  16. 3 1
      xxl-job-admin/src/main/webapp/WEB-INF/template/joblog/joblog.index.ftl
  17. 21 32
      xxl-job-admin/src/main/webapp/static/js/jobinfo.index.1.js
  18. 5 19
      xxl-job-admin/src/main/webapp/static/js/joblog.index.1.js
  19. 0 2
      xxl-job-admin/src/test/java/com/xxl/job/dao/impl/XxlJobInfoTest.java
  20. 0 1
      xxl-job-admin/src/test/java/com/xxl/job/dao/impl/XxlJobLogTest.java
  21. 102 63
      xxl-job-core/src/main/java/com/xxl/job/core/handler/HandlerRepository.java
  22. 5 4
      xxl-job-core/src/main/java/com/xxl/job/core/handler/HandlerThread.java
  23. 3 4
      xxl-job-core/src/main/java/com/xxl/job/core/util/HttpUtil.java

+ 10 - 5
db/tables_xxl_job.sql Visa fil

@@ -150,17 +150,19 @@ CREATE TABLE `xxl_job_qrtz_trigger_info` (
150 150
   `job_cron` varchar(128) NOT NULL COMMENT '任务执行CORN',
151 151
   `job_desc` varchar(255) NOT NULL,
152 152
   `job_class` varchar(255) NOT NULL COMMENT '任务执行JobBean',
153
-  `job_data` varchar(512) DEFAULT NULL COMMENT '任务执行数据',
154 153
   `add_time` datetime DEFAULT NULL,
155 154
   `update_time` datetime DEFAULT NULL,
156 155
   `author` varchar(64) DEFAULT NULL COMMENT '作者',
157 156
   `alarm_email` varchar(255) DEFAULT NULL COMMENT '报警邮件',
158 157
   `alarm_threshold` int(11) DEFAULT NULL COMMENT '报警阀值(连续失败次数)',
158
+  `executor_address` varchar(255) DEFAULT NULL COMMENT '执行器地址,有多个则逗号分隔',
159
+  `executor_handler` varchar(255) DEFAULT NULL COMMENT '执行器任务handler',
160
+  `executor_param` varchar(255) DEFAULT NULL COMMENT '执行器任务参数',
159 161
   `glue_switch` int(11) DEFAULT '0' COMMENT 'GLUE模式开关:0-否,1-是',
160 162
   `glue_source` text COMMENT 'GLUE源代码',
161 163
   `glue_remark` varchar(128) DEFAULT NULL COMMENT 'GLUE备注',
162 164
   PRIMARY KEY (`id`)
163
-);
165
+) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
164 166
 
165 167
 CREATE TABLE `xxl_job_qrtz_trigger_log` (
166 168
   `id` int(11) NOT NULL AUTO_INCREMENT,
@@ -169,7 +171,9 @@ CREATE TABLE `xxl_job_qrtz_trigger_log` (
169 171
   `job_cron` varchar(128) NOT NULL COMMENT '任务执行CORN表达式',
170 172
   `job_desc` varchar(255) NOT NULL,
171 173
   `job_class` varchar(255) NOT NULL COMMENT '任务执行JobBean',
172
-  `job_data` varchar(512) DEFAULT NULL COMMENT '任务执行数据',
174
+  `executor_address` varchar(255) DEFAULT NULL COMMENT '执行器地址,本次执行的地址',
175
+  `executor_handler` varchar(255) DEFAULT NULL COMMENT '执行器任务handler',
176
+  `executor_param` varchar(255) DEFAULT NULL COMMENT 'executor_param',
173 177
   `trigger_time` datetime DEFAULT NULL COMMENT '调度-时间',
174 178
   `trigger_status` varchar(255) DEFAULT NULL COMMENT '调度-结果',
175 179
   `trigger_msg` varchar(2048) DEFAULT NULL COMMENT '调度-日志',
@@ -177,7 +181,7 @@ CREATE TABLE `xxl_job_qrtz_trigger_log` (
177 181
   `handle_status` varchar(255) DEFAULT NULL COMMENT '执行-状态',
178 182
   `handle_msg` varchar(2048) DEFAULT NULL COMMENT '执行-日志',
179 183
   PRIMARY KEY (`id`)
180
-);
184
+) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8;
181 185
 
182 186
 CREATE TABLE `xxl_job_qrtz_trigger_logglue` (
183 187
   `id` int(11) NOT NULL AUTO_INCREMENT,
@@ -188,7 +192,8 @@ CREATE TABLE `xxl_job_qrtz_trigger_logglue` (
188 192
   `add_time` timestamp NULL DEFAULT NULL,
189 193
   `update_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
190 194
   PRIMARY KEY (`id`)
191
-) ;
195
+) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
196
+
192 197
 
193 198
 
194 199
 commit;

+ 13 - 196
xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobInfoController.java Visa fil

@@ -1,14 +1,9 @@
1 1
 package com.xxl.job.admin.controller;
2 2
 
3
-import java.util.HashMap;
4
-import java.util.List;
5 3
 import java.util.Map;
6 4
 
7 5
 import javax.annotation.Resource;
8 6
 
9
-import org.apache.commons.lang.StringUtils;
10
-import org.quartz.CronExpression;
11
-import org.quartz.SchedulerException;
12 7
 import org.springframework.stereotype.Controller;
13 8
 import org.springframework.ui.Model;
14 9
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -16,15 +11,8 @@ import org.springframework.web.bind.annotation.RequestParam;
16 11
 import org.springframework.web.bind.annotation.ResponseBody;
17 12
 
18 13
 import com.xxl.job.admin.core.constant.Constants.JobGroupEnum;
19
-import com.xxl.job.admin.core.jobbean.RemoteHttpJobBean;
20 14
 import com.xxl.job.admin.core.model.ReturnT;
21
-import com.xxl.job.admin.core.model.XxlJobInfo;
22
-import com.xxl.job.admin.core.util.DynamicSchedulerUtil;
23
-import com.xxl.job.admin.dao.IXxlJobInfoDao;
24
-import com.xxl.job.admin.dao.IXxlJobLogDao;
25
-import com.xxl.job.admin.dao.IXxlJobLogGlueDao;
26
-import com.xxl.job.core.handler.HandlerRepository;
27
-import com.xxl.job.core.util.JacksonUtil;
15
+import com.xxl.job.admin.service.IXxlJobService;
28 16
 
29 17
 /**
30 18
  * index controller
@@ -35,11 +23,7 @@ import com.xxl.job.core.util.JacksonUtil;
35 23
 public class JobInfoController {
36 24
 	
37 25
 	@Resource
38
-	private IXxlJobInfoDao xxlJobInfoDao;
39
-	@Resource
40
-	public IXxlJobLogDao xxlJobLogDao;
41
-	@Resource
42
-	private IXxlJobLogGlueDao xxlJobLogGlueDao;
26
+	private IXxlJobService xxlJobService;
43 27
 	
44 28
 	@RequestMapping
45 29
 	public String index(Model model) {
@@ -53,219 +37,52 @@ public class JobInfoController {
53 37
 			@RequestParam(required = false, defaultValue = "10") int length,
54 38
 			String jobGroup, String jobName, String filterTime) {
55 39
 		
56
-		// page list
57
-		List<XxlJobInfo> list = xxlJobInfoDao.pageList(start, length, jobGroup, jobName);
58
-		int list_count = xxlJobInfoDao.pageListCount(start, length, jobGroup, jobName);
59
-		
60
-		// fill job info
61
-		if (list!=null && list.size()>0) {
62
-			for (XxlJobInfo jobInfo : list) {
63
-				DynamicSchedulerUtil.fillJobInfo(jobInfo);
64
-			}
65
-		}
66
-		
67
-		// package result
68
-		Map<String, Object> maps = new HashMap<String, Object>();
69
-	    maps.put("recordsTotal", list_count);		// 总记录数
70
-	    maps.put("recordsFiltered", list_count);	// 过滤后的总记录数
71
-	    maps.put("data", list);  					// 分页列表
72
-		return maps;
40
+		return xxlJobService.pageList(start, length, jobGroup, jobName, filterTime);
73 41
 	}
74 42
 	
75 43
 	@RequestMapping("/add")
76 44
 	@ResponseBody
77 45
 	public ReturnT<String> add(String jobGroup, String jobName, String jobCron, String jobDesc,
78
-			String handler_address, String handler_name, String handler_params, 
46
+			String executorAddress, String executorHandler, String executorParam, 
79 47
 			String author, String alarmEmail, int alarmThreshold, 
80 48
 			int glueSwitch, String glueSource, String glueRemark) {
81 49
 		
82
-		// valid
83
-		if (JobGroupEnum.match(jobGroup) == null) {
84
-			return new ReturnT<String>(500, "请选择“任务组”");
85
-		}
86
-		if (StringUtils.isBlank(jobName)) {
87
-			return new ReturnT<String>(500, "请输入“任务名”");
88
-		}
89
-		if (!CronExpression.isValidExpression(jobCron)) {
90
-			return new ReturnT<String>(500, "“corn”不合法");
91
-		}
92
-		if (StringUtils.isBlank(jobDesc)) {
93
-			return new ReturnT<String>(500, "请输入“任务描述”");
94
-		}
95
-		if (StringUtils.isBlank(handler_address)) {
96
-			return new ReturnT<String>(500, "请输入“执行器地址”");
97
-		}
98
-		if (glueSwitch==0 && StringUtils.isBlank(handler_name)) {
99
-			return new ReturnT<String>(500, "请输入“jobHandler”");
100
-		}
101
-		if (StringUtils.isBlank(author)) {
102
-			return new ReturnT<String>(500, "请输入“负责人”");
103
-		}
104
-		if (StringUtils.isBlank(alarmEmail)) {
105
-			return new ReturnT<String>(500, "请输入“报警邮件”");
106
-		}
107
-		if (alarmThreshold < 0) {
108
-			alarmThreshold = 0;
109
-		}
110
-		
111
-		try {
112
-			if (DynamicSchedulerUtil.checkExists(jobName, jobGroup)) {
113
-				return new ReturnT<String>(500, "此任务已存在,请更换任务组或任务名");
114
-			}
115
-		} catch (SchedulerException e1) {
116
-			e1.printStackTrace();
117
-			return new ReturnT<String>(500, "此任务已存在,请更换任务组或任务名");
118
-		}
119
-		
120
-		// parse jobDataMap
121
-		HashMap<String, String> jobDataMap = new HashMap<String, String>();
122
-		jobDataMap.put(HandlerRepository.HANDLER_ADDRESS, handler_address);
123
-		jobDataMap.put(HandlerRepository.HANDLER_NAME, handler_name);
124
-		jobDataMap.put(HandlerRepository.HANDLER_PARAMS, handler_params);
125
-		
126
-		// Backup to the database
127
-		XxlJobInfo jobInfo = new XxlJobInfo();
128
-		jobInfo.setJobGroup(jobGroup);
129
-		jobInfo.setJobName(jobName);
130
-		jobInfo.setJobCron(jobCron);
131
-		jobInfo.setJobDesc(jobDesc);
132
-		jobInfo.setJobClass(RemoteHttpJobBean.class.getName());
133
-		jobInfo.setJobData(JacksonUtil.writeValueAsString(jobDataMap));
134
-		jobInfo.setAuthor(author);
135
-		jobInfo.setAlarmEmail(alarmEmail);
136
-		jobInfo.setAlarmThreshold(alarmThreshold);
137
-		jobInfo.setGlueSwitch(glueSwitch);
138
-		jobInfo.setGlueSource(glueSource);
139
-		jobInfo.setGlueRemark(glueRemark);
140
-		xxlJobInfoDao.save(jobInfo);
141
-		
142
-		try {
143
-			// add job 2 quartz
144
-			boolean result = DynamicSchedulerUtil.addJob(jobInfo);
145
-			if (result) {
146
-				return ReturnT.SUCCESS;
147
-			} else {
148
-				xxlJobInfoDao.delete(jobGroup, jobName);
149
-				return new ReturnT<String>(500, "新增任务失败");
150
-			}
151
-		} catch (SchedulerException e) {
152
-			e.printStackTrace();
153
-		}
154
-		return ReturnT.FAIL;
50
+		return xxlJobService.add(jobGroup, jobName, jobCron, jobDesc, executorAddress, executorHandler, executorParam,
51
+				author, alarmEmail, alarmThreshold, glueSwitch, glueSource, glueRemark);
155 52
 	}
156 53
 	
157 54
 	@RequestMapping("/reschedule")
158 55
 	@ResponseBody
159 56
 	public ReturnT<String> reschedule(String jobGroup, String jobName, String jobCron, String jobDesc,
160
-			String handler_address, String handler_name, String handler_params, 
57
+			String executorAddress, String executorHandler, String executorParam, 
161 58
 			String author, String alarmEmail, int alarmThreshold, int glueSwitch) {
162 59
 		
163
-		// valid
164
-		if (JobGroupEnum.match(jobGroup) == null) {
165
-			return new ReturnT<String>(500, "请选择“任务组”");
166
-		}
167
-		if (StringUtils.isBlank(jobName)) {
168
-			return new ReturnT<String>(500, "请输入“任务名”");
169
-		}
170
-		if (!CronExpression.isValidExpression(jobCron)) {
171
-			return new ReturnT<String>(500, "“corn”不合法");
172
-		}
173
-		if (StringUtils.isBlank(jobDesc)) {
174
-			return new ReturnT<String>(500, "请输入“任务描述”");
175
-		}
176
-		if (StringUtils.isBlank(handler_address)) {
177
-			return new ReturnT<String>(500, "请输入“执行器地址”");
178
-		}
179
-		if (glueSwitch==0 && StringUtils.isBlank(handler_name)) {
180
-			return new ReturnT<String>(500, "请输入“jobHandler”");
181
-		}
182
-		if (StringUtils.isBlank(author)) {
183
-			return new ReturnT<String>(500, "请输入“负责人”");
184
-		}
185
-		if (StringUtils.isBlank(alarmEmail)) {
186
-			return new ReturnT<String>(500, "请输入“报警邮件”");
187
-		}
188
-		if (alarmThreshold < 0) {
189
-			alarmThreshold = 0;
190
-		}
191
-		
192
-		// parse jobDataMap
193
-		HashMap<String, String> jobDataMap = new HashMap<String, String>();
194
-		jobDataMap.put(HandlerRepository.HANDLER_ADDRESS, handler_address);
195
-		jobDataMap.put(HandlerRepository.HANDLER_NAME, handler_name);
196
-		jobDataMap.put(HandlerRepository.HANDLER_PARAMS, handler_params);
197
-		
198
-		XxlJobInfo jobInfo = xxlJobInfoDao.load(jobGroup, jobName);
199
-		jobInfo.setJobCron(jobCron);
200
-		jobInfo.setJobDesc(jobDesc);
201
-		jobInfo.setJobData(JacksonUtil.writeValueAsString(jobDataMap));
202
-		jobInfo.setAuthor(author);
203
-		jobInfo.setAlarmEmail(alarmEmail);
204
-		jobInfo.setAlarmThreshold(alarmThreshold);
205
-		jobInfo.setGlueSwitch(glueSwitch);
206
-		
207
-		try {
208
-			// fresh quartz
209
-			DynamicSchedulerUtil.rescheduleJob(jobInfo);
210
-			
211
-			// fresh db
212
-			xxlJobInfoDao.update(jobInfo);
213
-			return ReturnT.SUCCESS;
214
-		} catch (SchedulerException e) {
215
-			e.printStackTrace();
216
-		}
217
-		return ReturnT.FAIL;
60
+		return xxlJobService.reschedule(jobGroup, jobName, jobCron, jobDesc, executorAddress, executorHandler, executorParam, author,
61
+				alarmEmail, alarmThreshold, glueSwitch);
218 62
 	}
219 63
 	
220 64
 	@RequestMapping("/remove")
221 65
 	@ResponseBody
222 66
 	public ReturnT<String> remove(String jobGroup, String jobName) {
223
-		try {
224
-			DynamicSchedulerUtil.removeJob(jobName, jobGroup);
225
-			xxlJobInfoDao.delete(jobGroup, jobName);
226
-			xxlJobLogDao.delete(jobGroup, jobName);
227
-			xxlJobLogGlueDao.delete(jobGroup, jobName);
228
-			return ReturnT.SUCCESS;
229
-		} catch (SchedulerException e) {
230
-			e.printStackTrace();
231
-		}
232
-		return ReturnT.FAIL;
67
+		return xxlJobService.remove(jobGroup, jobName);
233 68
 	}
234 69
 	
235 70
 	@RequestMapping("/pause")
236 71
 	@ResponseBody
237 72
 	public ReturnT<String> pause(String jobGroup, String jobName) {
238
-		try {
239
-			DynamicSchedulerUtil.pauseJob(jobName, jobGroup);	// jobStatus do not store
240
-			return ReturnT.SUCCESS;
241
-		} catch (SchedulerException e) {
242
-			e.printStackTrace();
243
-			return ReturnT.FAIL;
244
-		}
73
+		return xxlJobService.pause(jobGroup, jobName);
245 74
 	}
246 75
 	
247 76
 	@RequestMapping("/resume")
248 77
 	@ResponseBody
249 78
 	public ReturnT<String> resume(String jobGroup, String jobName) {
250
-		try {
251
-			DynamicSchedulerUtil.resumeJob(jobName, jobGroup);
252
-			return ReturnT.SUCCESS;
253
-		} catch (SchedulerException e) {
254
-			e.printStackTrace();
255
-			return ReturnT.FAIL;
256
-		}
79
+		return xxlJobService.resume(jobGroup, jobName);
257 80
 	}
258 81
 	
259 82
 	@RequestMapping("/trigger")
260 83
 	@ResponseBody
261 84
 	public ReturnT<String> triggerJob(String jobGroup, String jobName) {
262
-		try {
263
-			DynamicSchedulerUtil.triggerJob(jobName, jobGroup);
264
-			return ReturnT.SUCCESS;
265
-		} catch (SchedulerException e) {
266
-			e.printStackTrace();
267
-			return ReturnT.FAIL;
268
-		}
85
+		return xxlJobService.triggerJob(jobGroup, jobName);
269 86
 	}
270 87
 	
271 88
 }

+ 20 - 27
xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobLogController.java Visa fil

@@ -20,10 +20,10 @@ import com.xxl.job.admin.core.constant.Constants.JobGroupEnum;
20 20
 import com.xxl.job.admin.core.model.ReturnT;
21 21
 import com.xxl.job.admin.core.model.XxlJobLog;
22 22
 import com.xxl.job.admin.dao.IXxlJobLogDao;
23
-import com.xxl.job.core.handler.HandlerRepository;
23
+import com.xxl.job.core.handler.HandlerRepository.ActionEnum;
24
+import com.xxl.job.core.handler.HandlerRepository.HandlerParamEnum;
24 25
 import com.xxl.job.core.util.HttpUtil;
25 26
 import com.xxl.job.core.util.HttpUtil.RemoteCallBack;
26
-import com.xxl.job.core.util.JacksonUtil;
27 27
 
28 28
 /**
29 29
  * index controller
@@ -41,7 +41,7 @@ public class JobLogController {
41 41
 		model.addAttribute("jobGroup", jobGroup);
42 42
 		model.addAttribute("jobName", jobName);
43 43
 		model.addAttribute("JobGroupList", JobGroupEnum.values());
44
-		return "joblog/index";
44
+		return "joblog/joblog.index";
45 45
 	}
46 46
 	
47 47
 	@RequestMapping("/pageList")
@@ -101,21 +101,18 @@ public class JobLogController {
101 101
 		if (log == null) {
102 102
 			return new ReturnT<String>(500, "参数异常");
103 103
 		}
104
-		
105
-		// server address
106
-		@SuppressWarnings("unchecked")
107
-		Map<String, String> jobDataMap = JacksonUtil.readValue(log.getJobData(), Map.class);
108
-		String handler_address = jobDataMap.get(HandlerRepository.HANDLER_ADDRESS);
109
-		if (!handler_address.startsWith("http")){
110
-			handler_address = "http://" + handler_address + "/";
104
+		if (!RemoteCallBack.SUCCESS.equals(log.getTriggerStatus())) {
105
+			return new ReturnT<String>(500, "调度失败,无法查看执行日志");
111 106
 		}
107
+		
112 108
 		// trigger id, trigger time
113 109
 		Map<String, String> reqMap = new HashMap<String, String>();
114
-		reqMap.put(HandlerRepository.NAMESPACE, HandlerRepository.NameSpaceEnum.LOG.name());
115
-		reqMap.put(HandlerRepository.TRIGGER_LOG_ID, String.valueOf(id));
116
-		reqMap.put(HandlerRepository.TRIGGER_TIMESTAMP, String.valueOf(log.getTriggerTime().getTime()));
110
+		reqMap.put(HandlerParamEnum.TIMESTAMP.name(), String.valueOf(System.currentTimeMillis()));
111
+		reqMap.put(HandlerParamEnum.ACTION.name(), ActionEnum.LOG.name());
112
+		reqMap.put(HandlerParamEnum.LOG_ID.name(), String.valueOf(id));
113
+		reqMap.put(HandlerParamEnum.LOG_DATE.name(), String.valueOf(log.getTriggerTime().getTime()));
117 114
 		
118
-		RemoteCallBack callBack = HttpUtil.post(handler_address, reqMap);
115
+		RemoteCallBack callBack = HttpUtil.post(HttpUtil.addressToUrl(log.getExecutorAddress()), reqMap);
119 116
 		if (HttpUtil.RemoteCallBack.SUCCESS.equals(callBack.getStatus())) {
120 117
 			return new ReturnT<String>(callBack.getMsg());
121 118
 		} else {
@@ -138,23 +135,19 @@ public class JobLogController {
138 135
 		if (log == null) {
139 136
 			return new ReturnT<String>(500, "参数异常");
140 137
 		}
141
-		
142
-		// server address
143
-		@SuppressWarnings("unchecked")
144
-		Map<String, String> jobDataMap = JacksonUtil.readValue(log.getJobData(), Map.class);
145
-		String handler_address = jobDataMap.get(HandlerRepository.HANDLER_ADDRESS);
146
-		if (!handler_address.startsWith("http")){
147
-			handler_address = "http://" + handler_address + "/";
138
+		if (!RemoteCallBack.SUCCESS.equals(log.getTriggerStatus())) {
139
+			return new ReturnT<String>(500, "调度失败,无法终止日志");
148 140
 		}
149
-		String handler_name = jobDataMap.get(HandlerRepository.HANDLER_NAME);
150 141
 		
151
-		// trigger id, trigger time
142
+		// request
152 143
 		Map<String, String> reqMap = new HashMap<String, String>();
153
-		reqMap.put(HandlerRepository.NAMESPACE, HandlerRepository.NameSpaceEnum.KILL.name());
154
-		reqMap.put(HandlerRepository.HANDLER_NAME, handler_name);
155
-		reqMap.put(HandlerRepository.TRIGGER_TIMESTAMP, String.valueOf(System.currentTimeMillis()));
144
+		reqMap.put(HandlerParamEnum.TIMESTAMP.name(), String.valueOf(System.currentTimeMillis()));
145
+		reqMap.put(HandlerParamEnum.ACTION.name(), ActionEnum.KILL.name());
146
+		reqMap.put(HandlerParamEnum.EXECUTOR_HANDLER.name(), log.getExecutorHandler());
147
+		reqMap.put(HandlerParamEnum.JOB_GROUP.name(), log.getJobGroup());
148
+		reqMap.put(HandlerParamEnum.JOB_NAME.name(), log.getJobName());
156 149
 		
157
-		RemoteCallBack callBack = HttpUtil.post(handler_address, reqMap);
150
+		RemoteCallBack callBack = HttpUtil.post(HttpUtil.addressToUrl(log.getExecutorAddress()), reqMap);
158 151
 		if (HttpUtil.RemoteCallBack.SUCCESS.equals(callBack.getStatus())) {
159 152
 			log.setHandleStatus(HttpUtil.RemoteCallBack.FAIL);
160 153
 			log.setHandleMsg("人为操作主动终止");

+ 58 - 27
xxl-job-admin/src/main/java/com/xxl/job/admin/core/jobbean/RemoteHttpJobBean.java Visa fil

@@ -1,8 +1,8 @@
1 1
 package com.xxl.job.admin.core.jobbean;
2 2
 
3
+import java.text.MessageFormat;
3 4
 import java.util.Date;
4 5
 import java.util.HashMap;
5
-import java.util.Map;
6 6
 
7 7
 import org.quartz.JobExecutionContext;
8 8
 import org.quartz.JobExecutionException;
@@ -16,10 +16,10 @@ import com.xxl.job.admin.core.model.XxlJobInfo;
16 16
 import com.xxl.job.admin.core.model.XxlJobLog;
17 17
 import com.xxl.job.admin.core.thread.JobMonitorHelper;
18 18
 import com.xxl.job.admin.core.util.DynamicSchedulerUtil;
19
-import com.xxl.job.core.handler.HandlerRepository;
19
+import com.xxl.job.core.handler.HandlerRepository.ActionEnum;
20
+import com.xxl.job.core.handler.HandlerRepository.HandlerParamEnum;
20 21
 import com.xxl.job.core.util.HttpUtil;
21 22
 import com.xxl.job.core.util.HttpUtil.RemoteCallBack;
22
-import com.xxl.job.core.util.JacksonUtil;
23 23
 
24 24
 /**
25 25
  * http job bean
@@ -30,14 +30,12 @@ import com.xxl.job.core.util.JacksonUtil;
30 30
 public class RemoteHttpJobBean extends QuartzJobBean {
31 31
 	private static Logger logger = LoggerFactory.getLogger(RemoteHttpJobBean.class);
32 32
 	
33
-	@SuppressWarnings("unchecked")
34 33
 	@Override
35 34
 	protected void executeInternal(JobExecutionContext context)
36 35
 			throws JobExecutionException {
37 36
 		JobKey jobKey = context.getTrigger().getJobKey();
38 37
 		
39 38
 		XxlJobInfo jobInfo = DynamicSchedulerUtil.xxlJobInfoDao.load(jobKey.getGroup(), jobKey.getName());
40
-		HashMap<String, String> jobDataMap = (HashMap<String, String>) JacksonUtil.readValueRefer(jobInfo.getJobData(), Map.class);
41 39
 		// save log
42 40
 		XxlJobLog jobLog = new XxlJobLog();
43 41
 		jobLog.setJobGroup(jobInfo.getJobGroup());
@@ -45,35 +43,30 @@ public class RemoteHttpJobBean extends QuartzJobBean {
45 43
 		jobLog.setJobCron(jobInfo.getJobCron());
46 44
 		jobLog.setJobDesc(jobInfo.getJobDesc());
47 45
 		jobLog.setJobClass(jobInfo.getJobClass());
48
-		jobLog.setJobData(jobInfo.getJobData());
49
-		
50
-		jobLog.setJobClass(RemoteHttpJobBean.class.getName());
51
-		jobLog.setJobData(jobInfo.getJobData());
52 46
 		DynamicSchedulerUtil.xxlJobLogDao.save(jobLog);
53
-		logger.info(">>>>>>>>>>> xxl-job trigger start, jobLog:{}", jobLog);
47
+		logger.info(">>>>>>>>>>> xxl-job trigger start, jobId:{}", jobLog.getId());
54 48
 		
55 49
 		// trigger request
56 50
 		HashMap<String, String> params = new HashMap<String, String>();
57
-		params.put(HandlerRepository.TRIGGER_TIMESTAMP, String.valueOf(System.currentTimeMillis()));
58
-		params.put(HandlerRepository.NAMESPACE, HandlerRepository.NameSpaceEnum.RUN.name());
59
-		
60
-		params.put(HandlerRepository.TRIGGER_LOG_ID, String.valueOf(jobLog.getId()));
61
-		params.put(HandlerRepository.TRIGGER_LOG_ADDRESS, XxlJobLogCallbackServer.getTrigger_log_address());
51
+		params.put(HandlerParamEnum.TIMESTAMP.name(), String.valueOf(System.currentTimeMillis()));
52
+		params.put(HandlerParamEnum.ACTION.name(), ActionEnum.RUN.name());
62 53
 		
63
-		params.put(HandlerRepository.HANDLER_NAME, jobDataMap.get(HandlerRepository.HANDLER_NAME));
64
-		params.put(HandlerRepository.HANDLER_PARAMS, jobDataMap.get(HandlerRepository.HANDLER_PARAMS));
54
+		params.put(HandlerParamEnum.LOG_ADDRESS.name(), XxlJobLogCallbackServer.getTrigger_log_address());
55
+		params.put(HandlerParamEnum.LOG_ID.name(), String.valueOf(jobLog.getId()));
65 56
 		
66
-		params.put(HandlerRepository.HANDLER_GLUE_SWITCH, String.valueOf(jobInfo.getGlueSwitch()));
67
-		params.put(HandlerRepository.HANDLER_JOB_GROUP, jobInfo.getJobGroup());
68
-		params.put(HandlerRepository.HANDLER_JOB_NAME, jobInfo.getJobName());
57
+		params.put(HandlerParamEnum.EXECUTOR_HANDLER.name(), jobInfo.getExecutorHandler());
58
+		params.put(HandlerParamEnum.EXECUTOR_PARAMS.name(), jobInfo.getExecutorParam());
69 59
 		
60
+		params.put(HandlerParamEnum.GLUE_SWITCH.name(), String.valueOf(jobInfo.getGlueSwitch()));
61
+		params.put(HandlerParamEnum.JOB_GROUP.name(), jobInfo.getJobGroup());
62
+		params.put(HandlerParamEnum.JOB_NAME.name(), jobInfo.getJobName());
70 63
 
71
-		// handler address, jetty (servlet dead)
72
-		String handler_address = jobDataMap.get(HandlerRepository.HANDLER_ADDRESS);
73
-
74
-		RemoteCallBack callback = HttpUtil.post(HttpUtil.addressToUrl(handler_address), params);
75
-		logger.info(">>>>>>>>>>> xxl-job trigger http response, jobLog.id:{}, jobLog:{}, callback:{}", jobLog.getId(), jobLog, callback);
76
-
64
+		// failover trigger
65
+		RemoteCallBack callback = failoverTrigger(jobInfo.getExecutorAddress(), params, jobLog);
66
+		jobLog.setExecutorHandler(jobInfo.getGlueSwitch()==0?jobInfo.getExecutorHandler():"GLUE任务");
67
+		jobLog.setExecutorParam(jobInfo.getExecutorParam());
68
+		logger.info(">>>>>>>>>>> xxl-job failoverTrigger response, jobId:{}, callback:{}", jobLog.getId(), callback);
69
+		
77 70
 		// update trigger info
78 71
 		jobLog.setTriggerTime(new Date());
79 72
 		jobLog.setTriggerStatus(callback.getStatus());
@@ -83,7 +76,45 @@ public class RemoteHttpJobBean extends QuartzJobBean {
83 76
 		// monitor triger
84 77
 		JobMonitorHelper.monitor(jobLog.getId());
85 78
 		
86
-		logger.info(">>>>>>>>>>> xxl-job trigger end, jobLog.id:{}, jobLog:{}", jobLog.getId(), jobLog);
79
+		logger.info(">>>>>>>>>>> xxl-job trigger end, jobId:{}", jobLog.getId());
87 80
     }
88 81
 	
82
+	
83
+	/**
84
+	 * failover for trigger remote address
85
+	 * @param addressArr
86
+	 * @return
87
+	 */
88
+	public RemoteCallBack failoverTrigger(String handler_address, HashMap<String, String> handler_params, XxlJobLog jobLog){
89
+		if (handler_address.split(",").length > 1) {
90
+			String failoverMessage = "";
91
+			for (String address : handler_address.split(",")) {
92
+				HashMap<String, String> params = new HashMap<String, String>();
93
+				params.put(HandlerParamEnum.TIMESTAMP.name(), String.valueOf(System.currentTimeMillis()));
94
+				params.put(HandlerParamEnum.ACTION.name(), ActionEnum.BEAT.name());
95
+				RemoteCallBack beatResult = HttpUtil.post(HttpUtil.addressToUrl(address), params);
96
+				failoverMessage += MessageFormat.format("BEAT running, <br>>>>[address] : {0}, <br>>>>[status] : {1}, <br>>>>[msg] : {2} <br><hr>", address, beatResult.getStatus(), beatResult.getMsg());
97
+				if (RemoteCallBack.SUCCESS.equals(beatResult.getStatus())) {
98
+					jobLog.setExecutorAddress(address);
99
+					RemoteCallBack triggerCallback = HttpUtil.post(HttpUtil.addressToUrl(address), handler_params);
100
+					triggerCallback.setStatus(RemoteCallBack.SUCCESS);
101
+					failoverMessage += MessageFormat.format("Trigger running, <br>>>>[address] : {0}, <br>>>>[status] : {1}, <br>>>>[msg] : {2} <br><hr>", address, triggerCallback.getStatus(), triggerCallback.getMsg());
102
+					triggerCallback.setMsg(failoverMessage);
103
+					return triggerCallback;
104
+				}
105
+			}
106
+			
107
+			RemoteCallBack result = new RemoteCallBack();
108
+			result.setStatus(RemoteCallBack.FAIL);
109
+			result.setMsg(failoverMessage);
110
+			return result;
111
+		} else {
112
+			jobLog.setExecutorAddress(handler_address);
113
+			RemoteCallBack triggerCallback = HttpUtil.post(HttpUtil.addressToUrl(handler_address), handler_params);
114
+			String failoverMessage = MessageFormat.format("Trigger running, <br>>>>[address] : {0}, <br>>>>[status] : {1}, <br>>>>[msg] : {2} <br><hr>", handler_address, triggerCallback.getStatus(), triggerCallback.getMsg());
115
+			triggerCallback.setMsg(failoverMessage);
116
+			return triggerCallback;
117
+		}
118
+	}
119
+	
89 120
 }

+ 31 - 20
xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobInfo.java Visa fil

@@ -15,7 +15,7 @@ public class XxlJobInfo {
15 15
 	private String jobCron;		// 任务执行CRON表达式 【base on quartz】
16 16
 	private String jobDesc;
17 17
 	private String jobClass;	// 任务执行JobBean 【base on quartz】
18
-	private String jobData;		// 任务执行数据 Map-JSON-String
18
+	//private String jobData;		// 任务执行数据 Map-JSON-String
19 19
 	
20 20
 	private Date addTime;
21 21
 	private Date updateTime;
@@ -24,6 +24,10 @@ public class XxlJobInfo {
24 24
 	private String alarmEmail;	// 报警邮件
25 25
 	private int alarmThreshold;	// 报警阀值
26 26
 	
27
+	private String executorAddress;	// 执行器地址,有多个则逗号分隔
28
+	private String executorHandler;	// 执行器,任务Handler名称
29
+	private String executorParam;	// 执行器,任务参数
30
+	
27 31
 	private int glueSwitch;		// GLUE模式开关:0-否,1-是
28 32
 	private String glueSource;	// GLUE源代码
29 33
 	private String glueRemark;	// GLUE备注
@@ -79,14 +83,6 @@ public class XxlJobInfo {
79 83
 		this.jobClass = jobClass;
80 84
 	}
81 85
 
82
-	public String getJobData() {
83
-		return jobData;
84
-	}
85
-
86
-	public void setJobData(String jobData) {
87
-		this.jobData = jobData;
88
-	}
89
-
90 86
 	public Date getAddTime() {
91 87
 		return addTime;
92 88
 	}
@@ -127,12 +123,28 @@ public class XxlJobInfo {
127 123
 		this.alarmThreshold = alarmThreshold;
128 124
 	}
129 125
 
130
-	public String getJobStatus() {
131
-		return jobStatus;
126
+	public String getExecutorAddress() {
127
+		return executorAddress;
132 128
 	}
133 129
 
134
-	public void setJobStatus(String jobStatus) {
135
-		this.jobStatus = jobStatus;
130
+	public void setExecutorAddress(String executorAddress) {
131
+		this.executorAddress = executorAddress;
132
+	}
133
+
134
+	public String getExecutorHandler() {
135
+		return executorHandler;
136
+	}
137
+
138
+	public void setExecutorHandler(String executorHandler) {
139
+		this.executorHandler = executorHandler;
140
+	}
141
+
142
+	public String getExecutorParam() {
143
+		return executorParam;
144
+	}
145
+
146
+	public void setExecutorParam(String executorParam) {
147
+		this.executorParam = executorParam;
136 148
 	}
137 149
 
138 150
 	public int getGlueSwitch() {
@@ -159,13 +171,12 @@ public class XxlJobInfo {
159 171
 		this.glueRemark = glueRemark;
160 172
 	}
161 173
 
162
-	@Override
163
-	public String toString() {
164
-		return "XxlJobInfo [id=" + id + ", jobGroup=" + jobGroup + ", jobName=" + jobName + ", jobCron=" + jobCron
165
-				+ ", jobDesc=" + jobDesc + ", jobClass=" + jobClass + ", jobData=" + jobData + ", addTime=" + addTime
166
-				+ ", updateTime=" + updateTime + ", author=" + author + ", alarmEmail=" + alarmEmail
167
-				+ ", alarmThreshold=" + alarmThreshold + ", glueSwitch=" + glueSwitch + ", glueSource=" + glueSource
168
-				+ ", glueRemark=" + glueRemark + ", jobStatus=" + jobStatus + "]";
174
+	public String getJobStatus() {
175
+		return jobStatus;
176
+	}
177
+
178
+	public void setJobStatus(String jobStatus) {
179
+		this.jobStatus = jobStatus;
169 180
 	}
170 181
 	
171 182
 }

+ 21 - 13
xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobLog.java Visa fil

@@ -16,7 +16,10 @@ public class XxlJobLog {
16 16
 	private String jobCron;
17 17
 	private String jobDesc;
18 18
 	private String jobClass;
19
-	private String jobData;
19
+	
20
+	private String executorAddress;	// 执行器地址,有多个则逗号分隔
21
+	private String executorHandler;	// 执行器,任务Handler名称
22
+	private String executorParam;	// 执行器,任务参数
20 23
 	
21 24
 	// trigger info
22 25
 	private Date triggerTime;
@@ -27,6 +30,7 @@ public class XxlJobLog {
27 30
 	private Date handleTime;
28 31
 	private String handleStatus;
29 32
 	private String handleMsg;
33
+	
30 34
 	public int getId() {
31 35
 		return id;
32 36
 	}
@@ -63,11 +67,23 @@ public class XxlJobLog {
63 67
 	public void setJobClass(String jobClass) {
64 68
 		this.jobClass = jobClass;
65 69
 	}
66
-	public String getJobData() {
67
-		return jobData;
70
+	public String getExecutorAddress() {
71
+		return executorAddress;
72
+	}
73
+	public void setExecutorAddress(String executorAddress) {
74
+		this.executorAddress = executorAddress;
75
+	}
76
+	public String getExecutorHandler() {
77
+		return executorHandler;
68 78
 	}
69
-	public void setJobData(String jobData) {
70
-		this.jobData = jobData;
79
+	public void setExecutorHandler(String executorHandler) {
80
+		this.executorHandler = executorHandler;
81
+	}
82
+	public String getExecutorParam() {
83
+		return executorParam;
84
+	}
85
+	public void setExecutorParam(String executorParam) {
86
+		this.executorParam = executorParam;
71 87
 	}
72 88
 	public Date getTriggerTime() {
73 89
 		return triggerTime;
@@ -106,12 +122,4 @@ public class XxlJobLog {
106 122
 		this.handleMsg = handleMsg;
107 123
 	}
108 124
 	
109
-	@Override
110
-	public String toString() {
111
-		return "XxlJobLog [id=" + id + ", jobGroup=" + jobGroup + ", jobName=" + jobName + ", jobCron=" + jobCron
112
-				+ ", jobDesc=" + jobDesc + ", jobClass=" + jobClass + ", jobData=" + jobData + ", triggerTime="
113
-				+ triggerTime + ", triggerStatus=" + triggerStatus + ", triggerMsg=" + triggerMsg + ", handleTime="
114
-				+ handleTime + ", handleStatus=" + handleStatus + ", handleMsg=" + handleMsg + "]";
115
-	}
116
-	
117 125
 }

+ 7 - 9
xxl-job-admin/src/main/java/com/xxl/job/admin/core/util/DynamicSchedulerUtil.java Visa fil

@@ -12,7 +12,6 @@ import org.quartz.CronScheduleBuilder;
12 12
 import org.quartz.CronTrigger;
13 13
 import org.quartz.Job;
14 14
 import org.quartz.JobBuilder;
15
-import org.quartz.JobDataMap;
16 15
 import org.quartz.JobDetail;
17 16
 import org.quartz.JobKey;
18 17
 import org.quartz.Scheduler;
@@ -35,7 +34,6 @@ import com.xxl.job.admin.core.callback.XxlJobLogCallbackServer;
35 34
 import com.xxl.job.admin.core.model.XxlJobInfo;
36 35
 import com.xxl.job.admin.dao.IXxlJobInfoDao;
37 36
 import com.xxl.job.admin.dao.IXxlJobLogDao;
38
-import com.xxl.job.core.util.JacksonUtil;
39 37
 
40 38
 /**
41 39
  * base quartz scheduler util
@@ -151,7 +149,7 @@ public final class DynamicSchedulerUtil implements ApplicationContextAware, Init
151 149
 	}
152 150
 
153 151
 	// addJob 新增
154
-    @SuppressWarnings("unchecked")
152
+	@SuppressWarnings("unchecked")
155 153
 	public static boolean addJob(XxlJobInfo jobInfo) throws SchedulerException {
156 154
     	// TriggerKey : name + group
157 155
         TriggerKey triggerKey = TriggerKey.triggerKey(jobInfo.getJobName(), jobInfo.getJobGroup());
@@ -176,10 +174,11 @@ public final class DynamicSchedulerUtil implements ApplicationContextAware, Init
176 174
 		}
177 175
         
178 176
 		JobDetail jobDetail = JobBuilder.newJob(jobClass_).withIdentity(jobKey).build();
179
-        if (jobInfo.getJobData()!=null) {
177
+        /*if (jobInfo.getJobData()!=null) {
180 178
         	JobDataMap jobDataMap = jobDetail.getJobDataMap();
181
-        	jobDataMap.putAll(JacksonUtil.readValue(jobInfo.getJobData(), Map.class));	// JobExecutionContext context.getMergedJobDataMap().get("mailGuid");
182
-		}
179
+        	jobDataMap.putAll(JacksonUtil.readValue(jobInfo.getJobData(), Map.class));	
180
+        	// JobExecutionContext context.getMergedJobDataMap().get("mailGuid");
181
+		}*/
183 182
         
184 183
         // schedule : jobDetail + cronTrigger
185 184
         Date date = scheduler.scheduleJob(jobDetail, cronTrigger);
@@ -189,7 +188,6 @@ public final class DynamicSchedulerUtil implements ApplicationContextAware, Init
189 188
     }
190 189
     
191 190
     // reschedule
192
-    @SuppressWarnings("unchecked")
193 191
 	public static boolean rescheduleJob(XxlJobInfo jobInfo) throws SchedulerException {
194 192
     	
195 193
     	// TriggerKey valid if_exists
@@ -210,9 +208,9 @@ public final class DynamicSchedulerUtil implements ApplicationContextAware, Init
210 208
         
211 209
         // JobDetail-JobDataMap fresh
212 210
         JobDetail jobDetail = scheduler.getJobDetail(jobKey);
213
-    	JobDataMap jobDataMap = jobDetail.getJobDataMap();
211
+    	/*JobDataMap jobDataMap = jobDetail.getJobDataMap();
214 212
     	jobDataMap.clear();
215
-    	jobDataMap.putAll(JacksonUtil.readValue(jobInfo.getJobData(), Map.class));
213
+    	jobDataMap.putAll(JacksonUtil.readValue(jobInfo.getJobData(), Map.class));*/
216 214
     	
217 215
     	// Trigger fresh
218 216
     	HashSet<Trigger> triggerSet = new HashSet<Trigger>();

+ 2 - 5
xxl-job-admin/src/main/java/com/xxl/job/admin/dao/impl/XxlJobLogDaoImpl.java Visa fil

@@ -63,15 +63,12 @@ public class XxlJobLogDaoImpl implements IXxlJobLogDao {
63 63
 
64 64
 	@Override
65 65
 	public int save(XxlJobLog xxlJobLog) {
66
-		if (xxlJobLog!=null && xxlJobLog.getJobData().length()>2000) {
67
-			xxlJobLog.setJobData(xxlJobLog.getJobData().substring(0, 2000));
68
-		}
69 66
 		return sqlSessionTemplate.insert("XxlJobLogMapper.save", xxlJobLog);
70 67
 	}
71 68
 	
72 69
 	@Override
73 70
 	public int updateTriggerInfo(XxlJobLog xxlJobLog) {
74
-		if (xxlJobLog!=null && xxlJobLog.getTriggerMsg()!=null && xxlJobLog.getTriggerMsg().length()>2000) {
71
+		if (xxlJobLog.getTriggerMsg()!=null && xxlJobLog.getTriggerMsg().length()>2000) {
75 72
 			xxlJobLog.setTriggerMsg(xxlJobLog.getTriggerMsg().substring(0, 2000));
76 73
 		}
77 74
 		return sqlSessionTemplate.update("XxlJobLogMapper.updateTriggerInfo", xxlJobLog);
@@ -79,7 +76,7 @@ public class XxlJobLogDaoImpl implements IXxlJobLogDao {
79 76
 
80 77
 	@Override
81 78
 	public int updateHandleInfo(XxlJobLog xxlJobLog) {
82
-		if (xxlJobLog!=null && xxlJobLog.getHandleMsg()!=null && xxlJobLog.getHandleMsg().length()>2000) {
79
+		if (xxlJobLog.getHandleMsg()!=null && xxlJobLog.getHandleMsg().length()>2000) {
83 80
 			xxlJobLog.setHandleMsg(xxlJobLog.getHandleMsg().substring(0, 2000));
84 81
 		}
85 82
 		return sqlSessionTemplate.update("XxlJobLogMapper.updateHandleInfo", xxlJobLog);

+ 33 - 0
xxl-job-admin/src/main/java/com/xxl/job/admin/service/IXxlJobService.java Visa fil

@@ -0,0 +1,33 @@
1
+package com.xxl.job.admin.service;
2
+
3
+import java.util.Map;
4
+
5
+import com.xxl.job.admin.core.model.ReturnT;
6
+
7
+/**
8
+ * core job service for xxl-job
9
+ * 
10
+ * @author xuxueli 2016-5-28 15:30:33
11
+ */
12
+public interface IXxlJobService {
13
+	
14
+	public Map<String, Object> pageList(int start, int length, String jobGroup, String jobName, String filterTime);
15
+	
16
+	public ReturnT<String> add(String jobGroup, String jobName, String jobCron, String jobDesc, 
17
+			String executorAddress,	String executorHandler, String executorParam, 
18
+			String author, String alarmEmail, int alarmThreshold,
19
+			int glueSwitch, String glueSource, String glueRemark);
20
+	
21
+	public ReturnT<String> reschedule(String jobGroup, String jobName, String jobCron, String jobDesc,
22
+			String handler_address, String handler_name, String handler_params, 
23
+			String author, String alarmEmail, int alarmThreshold, int glueSwitch);
24
+	
25
+	public ReturnT<String> remove(String jobGroup, String jobName);
26
+	
27
+	public ReturnT<String> pause(String jobGroup, String jobName);
28
+	
29
+	public ReturnT<String> resume(String jobGroup, String jobName);
30
+	
31
+	public ReturnT<String> triggerJob(String jobGroup, String jobName);
32
+	
33
+}

+ 241 - 0
xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java Visa fil

@@ -0,0 +1,241 @@
1
+package com.xxl.job.admin.service.impl;
2
+
3
+import java.util.HashMap;
4
+import java.util.List;
5
+import java.util.Map;
6
+
7
+import javax.annotation.Resource;
8
+
9
+import org.apache.commons.lang.StringUtils;
10
+import org.quartz.CronExpression;
11
+import org.quartz.SchedulerException;
12
+import org.springframework.stereotype.Service;
13
+
14
+import com.xxl.job.admin.core.constant.Constants.JobGroupEnum;
15
+import com.xxl.job.admin.core.jobbean.RemoteHttpJobBean;
16
+import com.xxl.job.admin.core.model.ReturnT;
17
+import com.xxl.job.admin.core.model.XxlJobInfo;
18
+import com.xxl.job.admin.core.util.DynamicSchedulerUtil;
19
+import com.xxl.job.admin.dao.IXxlJobInfoDao;
20
+import com.xxl.job.admin.dao.IXxlJobLogDao;
21
+import com.xxl.job.admin.dao.IXxlJobLogGlueDao;
22
+import com.xxl.job.admin.service.IXxlJobService;
23
+
24
+/**
25
+ * core job service for xxl-job
26
+ * @author xuxueli 2016-5-28 15:30:33
27
+ */
28
+@Service
29
+public class XxlJobServiceImpl implements IXxlJobService {
30
+
31
+	@Resource
32
+	private IXxlJobInfoDao xxlJobInfoDao;
33
+	@Resource
34
+	public IXxlJobLogDao xxlJobLogDao;
35
+	@Resource
36
+	private IXxlJobLogGlueDao xxlJobLogGlueDao;
37
+	
38
+	@Override
39
+	public Map<String, Object> pageList(int start, int length, String jobGroup, String jobName, String filterTime) {
40
+		
41
+		// page list
42
+		List<XxlJobInfo> list = xxlJobInfoDao.pageList(start, length, jobGroup, jobName);
43
+		int list_count = xxlJobInfoDao.pageListCount(start, length, jobGroup, jobName);
44
+		
45
+		// fill job info
46
+		if (list!=null && list.size()>0) {
47
+			for (XxlJobInfo jobInfo : list) {
48
+				DynamicSchedulerUtil.fillJobInfo(jobInfo);
49
+			}
50
+		}
51
+		
52
+		// package result
53
+		Map<String, Object> maps = new HashMap<String, Object>();
54
+	    maps.put("recordsTotal", list_count);		// 总记录数
55
+	    maps.put("recordsFiltered", list_count);	// 过滤后的总记录数
56
+	    maps.put("data", list);  					// 分页列表
57
+		return maps;
58
+	}
59
+
60
+	@Override
61
+	public ReturnT<String> add(String jobGroup, String jobName, String jobCron, String jobDesc, 
62
+			String executorAddress,	String executorHandler, String executorParam, 
63
+			String author, String alarmEmail, int alarmThreshold,
64
+			int glueSwitch, String glueSource, String glueRemark) {
65
+		// valid
66
+		if (JobGroupEnum.match(jobGroup) == null) {
67
+			return new ReturnT<String>(500, "请选择“任务组”");
68
+		}
69
+		if (StringUtils.isBlank(jobName)) {
70
+			return new ReturnT<String>(500, "请输入“任务名”");
71
+		}
72
+		if (!CronExpression.isValidExpression(jobCron)) {
73
+			return new ReturnT<String>(500, "请输入格式正确的“corn”");
74
+		}
75
+		if (StringUtils.isBlank(jobDesc)) {
76
+			return new ReturnT<String>(500, "请输入“任务描述”");
77
+		}
78
+		if (StringUtils.isBlank(executorAddress)) {
79
+			return new ReturnT<String>(500, "请输入“执行器地址”");
80
+		}
81
+		if (glueSwitch==0 && StringUtils.isBlank(executorHandler)) {
82
+			return new ReturnT<String>(500, "请输入“jobHandler”");
83
+		}
84
+		if (StringUtils.isBlank(author)) {
85
+			return new ReturnT<String>(500, "请输入“负责人”");
86
+		}
87
+		if (StringUtils.isBlank(alarmEmail)) {
88
+			return new ReturnT<String>(500, "请输入“报警邮件”");
89
+		}
90
+		if (alarmThreshold < 0) {
91
+			alarmThreshold = 0;
92
+		}
93
+		
94
+		try {
95
+			if (DynamicSchedulerUtil.checkExists(jobName, jobGroup)) {
96
+				return new ReturnT<String>(500, "此任务已存在,请更换任务组或任务名");
97
+			}
98
+		} catch (SchedulerException e1) {
99
+			e1.printStackTrace();
100
+			return new ReturnT<String>(500, "此任务已存在,请更换任务组或任务名");
101
+		}
102
+		
103
+		// Backup to the database
104
+		XxlJobInfo jobInfo = new XxlJobInfo();
105
+		jobInfo.setJobGroup(jobGroup);
106
+		jobInfo.setJobName(jobName);
107
+		jobInfo.setJobCron(jobCron);
108
+		jobInfo.setJobDesc(jobDesc);
109
+		jobInfo.setJobClass(RemoteHttpJobBean.class.getName());
110
+		jobInfo.setAuthor(author);
111
+		jobInfo.setAlarmEmail(alarmEmail);
112
+		jobInfo.setAlarmThreshold(alarmThreshold);
113
+		jobInfo.setGlueSwitch(glueSwitch);
114
+		jobInfo.setGlueSource(glueSource);
115
+		jobInfo.setGlueRemark(glueRemark);
116
+		jobInfo.setExecutorAddress(executorAddress);
117
+		jobInfo.setExecutorHandler(executorHandler);
118
+		jobInfo.setExecutorParam(executorParam);
119
+		xxlJobInfoDao.save(jobInfo);
120
+		
121
+		try {
122
+			// add job 2 quartz
123
+			boolean result = DynamicSchedulerUtil.addJob(jobInfo);
124
+			if (result) {
125
+				return ReturnT.SUCCESS;
126
+			} else {
127
+				xxlJobInfoDao.delete(jobGroup, jobName);
128
+				return new ReturnT<String>(500, "新增任务失败");
129
+			}
130
+		} catch (SchedulerException e) {
131
+			e.printStackTrace();
132
+		}
133
+		return ReturnT.FAIL;
134
+	}
135
+
136
+	@Override
137
+	public ReturnT<String> reschedule(String jobGroup, String jobName, String jobCron, String jobDesc,
138
+			String executorAddress,	String executorHandler, String executorParam, 
139
+			String author, String alarmEmail, int alarmThreshold, int glueSwitch) {
140
+		
141
+		// valid
142
+		if (JobGroupEnum.match(jobGroup) == null) {
143
+			return new ReturnT<String>(500, "请选择“任务组”");
144
+		}
145
+		if (StringUtils.isBlank(jobName)) {
146
+			return new ReturnT<String>(500, "请输入“任务名”");
147
+		}
148
+		if (!CronExpression.isValidExpression(jobCron)) {
149
+			return new ReturnT<String>(500, "请输入格式正确的“corn”");
150
+		}
151
+		if (StringUtils.isBlank(jobDesc)) {
152
+			return new ReturnT<String>(500, "请输入“任务描述”");
153
+		}
154
+		if (StringUtils.isBlank(executorAddress)) {
155
+			return new ReturnT<String>(500, "请输入“执行器地址”");
156
+		}
157
+		if (glueSwitch==0 && StringUtils.isBlank(executorHandler)) {
158
+			return new ReturnT<String>(500, "请输入“jobHandler”");
159
+		}
160
+		if (StringUtils.isBlank(author)) {
161
+			return new ReturnT<String>(500, "请输入“负责人”");
162
+		}
163
+		if (StringUtils.isBlank(alarmEmail)) {
164
+			return new ReturnT<String>(500, "请输入“报警邮件”");
165
+		}
166
+		if (alarmThreshold < 0) {
167
+			alarmThreshold = 0;
168
+		}
169
+		
170
+		XxlJobInfo jobInfo = xxlJobInfoDao.load(jobGroup, jobName);
171
+		jobInfo.setJobCron(jobCron);
172
+		jobInfo.setJobDesc(jobDesc);
173
+		jobInfo.setAuthor(author);
174
+		jobInfo.setAlarmEmail(alarmEmail);
175
+		jobInfo.setAlarmThreshold(alarmThreshold);
176
+		jobInfo.setGlueSwitch(glueSwitch);
177
+		jobInfo.setExecutorAddress(executorAddress);
178
+		jobInfo.setExecutorHandler(executorHandler);
179
+		jobInfo.setExecutorParam(executorParam);
180
+		
181
+		try {
182
+			// fresh quartz
183
+			DynamicSchedulerUtil.rescheduleJob(jobInfo);
184
+			
185
+			// fresh db
186
+			xxlJobInfoDao.update(jobInfo);
187
+			return ReturnT.SUCCESS;
188
+		} catch (SchedulerException e) {
189
+			e.printStackTrace();
190
+		}
191
+		return ReturnT.FAIL;
192
+	}
193
+
194
+	@Override
195
+	public ReturnT<String> remove(String jobGroup, String jobName) {
196
+		try {
197
+			DynamicSchedulerUtil.removeJob(jobName, jobGroup);
198
+			xxlJobInfoDao.delete(jobGroup, jobName);
199
+			xxlJobLogDao.delete(jobGroup, jobName);
200
+			xxlJobLogGlueDao.delete(jobGroup, jobName);
201
+			return ReturnT.SUCCESS;
202
+		} catch (SchedulerException e) {
203
+			e.printStackTrace();
204
+		}
205
+		return ReturnT.FAIL;
206
+	}
207
+
208
+	@Override
209
+	public ReturnT<String> pause(String jobGroup, String jobName) {
210
+		try {
211
+			DynamicSchedulerUtil.pauseJob(jobName, jobGroup);	// jobStatus do not store
212
+			return ReturnT.SUCCESS;
213
+		} catch (SchedulerException e) {
214
+			e.printStackTrace();
215
+			return ReturnT.FAIL;
216
+		}
217
+	}
218
+
219
+	@Override
220
+	public ReturnT<String> resume(String jobGroup, String jobName) {
221
+		try {
222
+			DynamicSchedulerUtil.resumeJob(jobName, jobGroup);
223
+			return ReturnT.SUCCESS;
224
+		} catch (SchedulerException e) {
225
+			e.printStackTrace();
226
+			return ReturnT.FAIL;
227
+		}
228
+	}
229
+
230
+	@Override
231
+	public ReturnT<String> triggerJob(String jobGroup, String jobName) {
232
+		try {
233
+			DynamicSchedulerUtil.triggerJob(jobName, jobGroup);
234
+			return ReturnT.SUCCESS;
235
+		} catch (SchedulerException e) {
236
+			e.printStackTrace();
237
+			return ReturnT.FAIL;
238
+		}
239
+	}
240
+	
241
+}

+ 1 - 1
xxl-job-admin/src/main/resources/applicationcontext-base.xml Visa fil

@@ -9,7 +9,7 @@
9 9
            http://www.springframework.org/schema/util 
10 10
            http://www.springframework.org/schema/util/spring-util.xsd">
11 11
 
12
-	<context:component-scan base-package="com.xxl.job.admin.dao" />
12
+	<context:component-scan base-package="com.xxl.job.admin.service, com.xxl.job.admin.dao" />
13 13
 
14 14
 	<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
15 15
 		<property name="templateLoaderPath" value="/WEB-INF/template/" />

+ 1 - 3
xxl-job-admin/src/main/resources/applicationcontext-database.xml Visa fil

@@ -48,7 +48,6 @@
48 48
     </bean> 
49 49
     
50 50
     <!-- part 2 :for tx -->
51
-    <!--
52 51
     <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
53 52
 		<property name="dataSource" ref="dataSource" />
54 53
 	</bean>
@@ -68,9 +67,8 @@
68 67
 	</tx:advice>
69 68
 
70 69
 	<aop:config>
71
-		<aop:pointcut id="txoperation" expression="execution(* com.xxl.job.admin.service.imp.*.*(..))" />
70
+		<aop:pointcut id="txoperation" expression="execution(* com.xxl.job.admin.service.impl.*.*(..))" />
72 71
 		<aop:advisor pointcut-ref="txoperation" advice-ref="txAdvice" />
73 72
 	</aop:config>
74
-	-->
75 73
 	
76 74
 </beans>

+ 16 - 5
xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml Visa fil

@@ -11,7 +11,6 @@
11 11
 	    <result column="job_cron" property="jobCron" />
12 12
 	    <result column="job_desc" property="jobDesc" />
13 13
 	    <result column="job_class" property="jobClass" />
14
-	    <result column="job_data" property="jobData" />
15 14
 	    
16 15
 	    <result column="add_time" property="addTime" />
17 16
 	    <result column="update_time" property="updateTime" />
@@ -20,6 +19,10 @@
20 19
 	    <result column="alarm_email" property="alarmEmail" />
21 20
 	    <result column="alarm_threshold" property="alarmThreshold" />
22 21
 	    
22
+	    <result column="executor_address" property="executorAddress" />
23
+	    <result column="executor_handler" property="executorHandler" />
24
+	    <result column="executor_param" property="executorParam" />
25
+	    
23 26
 	    <result column="glue_switch" property="glueSwitch" />
24 27
 	    <result column="glue_source" property="glueSource" />
25 28
 	    <result column="glue_remark" property="glueRemark" />
@@ -32,12 +35,14 @@
32 35
 		t.job_cron,
33 36
 		t.job_desc,
34 37
 		t.job_class,
35
-		t.job_data,
36 38
 		t.add_time,
37 39
 		t.update_time,
38 40
 		t.author,
39 41
 		t.alarm_email,
40 42
 		t.alarm_threshold,
43
+		t.executor_address,
44
+		t.executor_handler,
45
+		t.executor_param,
41 46
 		t.glue_switch,
42 47
 		t.glue_source,
43 48
 		t.glue_remark
@@ -78,12 +83,14 @@
78 83
 			job_cron,
79 84
 			job_desc,
80 85
 			job_class,
81
-			job_data,
82 86
 			add_time,
83 87
 			update_time,
84 88
 			author,
85 89
 			alarm_email,
86 90
 			alarm_threshold,
91
+			executor_address,
92
+			executor_handler,
93
+			executor_param,
87 94
 			glue_switch,
88 95
 			glue_source,
89 96
 			glue_remark
@@ -93,12 +100,14 @@
93 100
 			#{jobCron}, 
94 101
 			#{jobDesc}, 
95 102
 			#{jobClass}, 
96
-			#{jobData},
97 103
 			NOW(),
98 104
 			NOW(),
99 105
 			#{author},
100 106
 			#{alarmEmail},
101 107
 			#{alarmThreshold},
108
+			#{executorAddress},
109
+			#{executorHandler},
110
+			#{executorParam},
102 111
 			#{glueSwitch},
103 112
 			#{glueSource},
104 113
 			#{glueRemark}
@@ -120,11 +129,13 @@
120 129
 		SET 
121 130
 			job_cron = #{jobCron},
122 131
 			job_desc = #{jobDesc},
123
-			job_data = #{jobData},
124 132
 			update_time = NOW(),
125 133
 			author = #{author},
126 134
 			alarm_email = #{alarmEmail},
127 135
 			alarm_threshold = #{alarmThreshold},
136
+			executor_address = #{executorAddress},
137
+			executor_handler = #{executorHandler},
138
+			executor_param = #{executorParam},
128 139
 			glue_switch = #{glueSwitch},
129 140
 			glue_source = #{glueSource},
130 141
 			glue_remark = #{glueRemark}

+ 18 - 5
xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobLogMapper.xml Visa fil

@@ -11,7 +11,10 @@
11 11
 	    <result column="job_cron" property="jobCron" />
12 12
 	    <result column="job_desc" property="jobDesc" />
13 13
 	    <result column="job_class" property="jobClass" />
14
-	    <result column="job_data" property="jobData" />
14
+	    
15
+	    <result column="executor_address" property="executorAddress" />
16
+	    <result column="executor_handler" property="executorHandler" />
17
+	    <result column="executor_param" property="executorParam" />
15 18
 	    
16 19
 	    <result column="trigger_time" property="triggerTime" />
17 20
 	    <result column="trigger_status" property="triggerStatus" />
@@ -20,6 +23,7 @@
20 23
 	    <result column="handle_time" property="handleTime" />
21 24
 	    <result column="handle_status" property="handleStatus" />
22 25
 	    <result column="handle_msg" property="handleMsg" />
26
+	    
23 27
 	</resultMap>
24 28
 
25 29
 	<sql id="Base_Column_List">
@@ -29,7 +33,9 @@
29 33
 		t.job_cron,
30 34
 		t.job_desc,
31 35
 		t.job_class,
32
-		t.job_data,
36
+		t.executor_address,
37
+		t.executor_handler,
38
+		t.executor_param,
33 39
 		t.trigger_time,
34 40
 		t.trigger_status,
35 41
 		t.trigger_msg,
@@ -98,14 +104,18 @@
98 104
 			`job_cron`, 
99 105
 			`job_desc`,
100 106
 			`job_class`, 
101
-			`job_data`
107
+			`executor_address`,
108
+			`executor_handler`,
109
+			`executor_param`
102 110
 		) VALUES (
103 111
 			#{jobGroup}, 
104 112
 			#{jobName},
105 113
 			#{jobCron},
106 114
 			#{jobDesc},
107 115
 			#{jobClass},
108
-			#{jobData}
116
+			#{executorAddress},
117
+			#{executorHandler},
118
+			#{executorParam}
109 119
 		);
110 120
 		<selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id"> 
111 121
 			SELECT LAST_INSERT_ID() 
@@ -117,7 +127,10 @@
117 127
 		SET 
118 128
 			`trigger_time`= #{triggerTime}, 
119 129
 			`trigger_status`= #{triggerStatus}, 
120
-			`trigger_msg`= #{triggerMsg}
130
+			`trigger_msg`= #{triggerMsg},
131
+			`executor_address`= #{executorAddress},
132
+			`executor_handler`= #{executorHandler},
133
+			`executor_param`= #{executorParam}
121 134
 		WHERE `id`= #{id}
122 135
 	</update>
123 136
 	

+ 9 - 7
xxl-job-admin/src/main/webapp/WEB-INF/template/jobinfo/jobinfo.index.ftl Visa fil

@@ -72,7 +72,9 @@
72 72
 					                  	<th name="jobDesc" >描述</th>
73 73
 					                  	<th name="jobCron" >Cron</th>
74 74
 					                  	<th name="jobClass" >JobBean</th>
75
-					                  	<th name="jobData" >任务数据</th>
75
+					                  	<th name="executorAddress" >执行器地址</th>
76
+					                  	<th name="executorHandler" >JobHandler</th>
77
+					                  	<th name="executorParam" >任务参数</th>
76 78
 					                  	<th name="addTime" >新增时间</th>
77 79
 					                  	<th name="updateTime" >更新时间</th>
78 80
 					                  	<th name="author" >负责人</th>
@@ -126,13 +128,13 @@
126 128
 					</div>
127 129
 					<div class="form-group">
128 130
 						<label for="lastname" class="col-sm-2 control-label">执行器地址<font color="red">*</font></label>
129
-						<div class="col-sm-4"><input type="text" class="form-control" name="handler_address" placeholder="请输入“执行器地址”" maxlength="200" ></div>
131
+						<div class="col-sm-4"><input type="text" class="form-control" name="executorAddress" placeholder="请输入“执行器地址”,多个地址逗号分隔" maxlength="200" ></div>
130 132
 						<label for="lastname" class="col-sm-2 control-label">jobHandler<font color="red">*</font></label>
131
-						<div class="col-sm-4"><input type="text" class="form-control" name="handler_name" placeholder="请输入“jobHandler”" maxlength="200" ></div>
133
+						<div class="col-sm-4"><input type="text" class="form-control" name="executorHandler" placeholder="请输入“jobHandler”" maxlength="200" ></div>
132 134
 					</div>
133 135
 					<div class="form-group">
134 136
 						<label for="firstname" class="col-sm-2 control-label">执行参数<font color="black">*</font></label>
135
-						<div class="col-sm-4"><input type="text" class="form-control" name="handler_params" placeholder="请输入“执行参数”" maxlength="100" ></div>
137
+						<div class="col-sm-4"><input type="text" class="form-control" name="executorParam" placeholder="请输入“执行参数”" maxlength="100" ></div>
136 138
 						<label for="lastname" class="col-sm-2 control-label">负责人<font color="red">*</font></label>
137 139
 						<div class="col-sm-4"><input type="text" class="form-control" name="author" placeholder="请输入“负责人”" maxlength="200" ></div>
138 140
 					</div>
@@ -207,13 +209,13 @@ public class DemoJobHandler extends IJobHandler {
207 209
 					
208 210
 					<div class="form-group">
209 211
 						<label for="lastname" class="col-sm-2 control-label">执行器地址<font color="red">*</font></label>
210
-						<div class="col-sm-4"><input type="text" class="form-control" name="handler_address" placeholder="请输入“执行器地址”" maxlength="200" ></div>
212
+						<div class="col-sm-4"><input type="text" class="form-control" name="executorAddress" placeholder="请输入“执行器地址”,多个地址逗号分隔" maxlength="200" ></div>
211 213
 						<label for="lastname" class="col-sm-2 control-label">jobHandler<font color="red">*</font></label>
212
-						<div class="col-sm-4"><input type="text" class="form-control" name="handler_name" placeholder="请输入“jobHandler”" maxlength="200" ></div>
214
+						<div class="col-sm-4"><input type="text" class="form-control" name="executorHandler" placeholder="请输入“jobHandler”" maxlength="200" ></div>
213 215
 					</div>
214 216
 					<div class="form-group">
215 217
 						<label for="firstname" class="col-sm-2 control-label">执行参数<font color="black">*</font></label>
216
-						<div class="col-sm-4"><input type="text" class="form-control" name="handler_params" placeholder="请输入“执行参数”" maxlength="100" ></div>
218
+						<div class="col-sm-4"><input type="text" class="form-control" name="executorParam" placeholder="请输入“执行参数”" maxlength="100" ></div>
217 219
 						<label for="lastname" class="col-sm-2 control-label">负责人<font color="red">*</font></label>
218 220
 						<div class="col-sm-4"><input type="text" class="form-control" name="author" placeholder="请输入“负责人”" maxlength="200" ></div>
219 221
 					</div>

xxl-job-admin/src/main/webapp/WEB-INF/template/joblog/index.ftl → xxl-job-admin/src/main/webapp/WEB-INF/template/joblog/joblog.index.ftl Visa fil

@@ -78,7 +78,9 @@
78 78
 					                  	<th name="jobCron" >Cron</th>
79 79
 					                  	<th name="jobDesc" >描述</th>
80 80
 					                  	<th name="jobClass" >JobBean</th>
81
-					                  	<th name="jobData" >任务数据</th>
81
+					                  	<th name="executorAddress" >执行器地址</th>
82
+					                  	<th name="executorHandler" >JobHandler</th>
83
+					                  	<th name="executorParam" >任务参数</th>
82 84
 					                  	<th name="triggerTime" >调度时间</th>
83 85
 					                  	<th name="triggerStatus" >调度结果</th>
84 86
 					                  	<th name="triggerMsg" >调度日志</th>

+ 21 - 32
xxl-job-admin/src/main/webapp/static/js/jobinfo.index.1.js Visa fil

@@ -33,17 +33,9 @@ $(function() {
33 33
 	                { "data": 'jobDesc', "visible" : true},
34 34
 	                { "data": 'jobCron', "visible" : true},
35 35
 	                { "data": 'jobClass', "visible" : false},
36
-	                { 
37
-	                	"data": 'jobData',
38
-	                	"visible" : true,
39
-	                	"render": function ( data, type, row ) {
40
-	                		var _jobData = eval('(' + data + ')');	// row.jobData
41
-	                		var html = "<p title='" + data + "'>执行器:" + _jobData.handler_name +
42
-	                			"<br>执行参数:" + _jobData.handler_params + 
43
-	                			"<br>执行器地址:" + _jobData.handler_address + "</p>";
44
-	                		return html;
45
-	                	}
46
-	                },
36
+	                { "data": 'executorAddress', "visible" : false},
37
+	                { "data": 'executorHandler', "visible" : false},
38
+	                { "data": 'executorParam', "visible" : false},
47 39
 	                { 
48 40
 	                	"data": 'addTime', 
49 41
 	                	"visible" : false, 
@@ -90,15 +82,12 @@ $(function() {
90 82
 	                			var logUrl = base_url +'/joblog?jobGroup='+ row.jobGroup +'&jobName='+ row.jobName;
91 83
 	                			
92 84
 	                			// log url
93
-	                			var codeHtml = "";
94
-	                			if(row.glueSwitch != 0){
85
+	                			var codeBtn = "";
86
+	                			if(row.glueSwitch > 0){
95 87
 	                				var codeUrl = base_url +'/jobcode?jobGroup='+ row.jobGroup +'&jobName='+ row.jobName;
96
-	                				codeHtml = '<button class="btn btn-warning btn-xs" type="button" onclick="javascript:window.open(\'' + codeUrl + '\')" >GLUE</button>  '
88
+	                				codeBtn = '<button class="btn btn-warning btn-xs" type="button" onclick="javascript:window.open(\'' + codeUrl + '\')" >GLUE</button>  '
97 89
 	                			}
98 90
 	                			
99
-	                			// job data
100
-	                			var jobDataMap = eval('(' + row.jobData + ')');
101
-	                			
102 91
 	                			var html = '<p id="'+ row.id +'" '+
103 92
 	                							' jobGroup="'+ row.jobGroup +'" '+
104 93
 	                							' jobName="'+ row.jobName +'" '+
@@ -106,9 +95,9 @@ $(function() {
106 95
 	                							' jobDesc="'+ row.jobDesc +'" '+
107 96
 	                							' jobClass="'+ row.jobClass +'" '+
108 97
 	                							' jobData="'+ row.jobData +'" '+
109
-	                							' handler_params="'+jobDataMap.handler_params +'" '+
110
-	                							' handler_address="'+ jobDataMap.handler_address +'" '+
111
-	                							' handler_name="'+ jobDataMap.handler_name +'" '+
98
+	                							' executorAddress="'+row.executorAddress +'" '+
99
+	                							' executorHandler="'+ row.executorHandler +'" '+
100
+	                							' executorParam="'+ row.executorParam +'" '+
112 101
 	                							' author="'+ row.author +'" '+
113 102
 	                							' alarmEmail="'+ row.alarmEmail +'" '+
114 103
 	                							' alarmThreshold="'+ row.alarmThreshold +'" '+
@@ -118,7 +107,7 @@ $(function() {
118 107
 										pause_resume +
119 108
 										'<button class="btn btn-primary btn-xs" type="job_del" type="button" onclick="javascript:window.open(\'' + logUrl + '\')" >日志</button><br>  '+
120 109
 										'<button class="btn btn-warning btn-xs update" type="button">编辑</button>  '+
121
-										codeHtml +
110
+										codeBtn +
122 111
 								  		'<button class="btn btn-danger btn-xs job_operate" type="job_del" type="button">删除</button>  '+
123 112
 									'</p>';
124 113
 									
@@ -236,11 +225,11 @@ $(function() {
236 225
             	required : true ,
237 226
                 maxlength: 200
238 227
             },
239
-            handler_address : {
228
+            executorAddress : {
240 229
             	required : true ,
241 230
                 maxlength: 200
242 231
             },
243
-            handler_name : {
232
+            executorHandler : {
244 233
             	required : true ,
245 234
                 maxlength: 200
246 235
             },
@@ -271,11 +260,11 @@ $(function() {
271 260
             	required :"请输入“任务描述”."  ,
272 261
                 maxlength:"“任务描述”长度不应超过200位"
273 262
             },  
274
-            handler_address : {
263
+            executorAddress : {
275 264
             	required :"请输入“执行器地址”."  ,
276 265
                 maxlength:"“执行器地址”长度不应超过200位"
277 266
             },
278
-            handler_name : {
267
+            executorHandler : {
279 268
             	required : "请输入“jobHandler”."  ,
280 269
                 maxlength: "“jobHandler”长度不应超过200位"
281 270
             },
@@ -359,9 +348,9 @@ $(function() {
359 348
 		$("#updateModal .form input[name='jobName']").val($(this).parent('p').attr("jobName"));
360 349
 		$("#updateModal .form input[name='jobCron']").val($(this).parent('p').attr("jobCron"));
361 350
 		$("#updateModal .form input[name='jobDesc']").val($(this).parent('p').attr("jobDesc"));
362
-		$("#updateModal .form input[name='handler_address']").val($(this).parent('p').attr("handler_address"));
363
-		$("#updateModal .form input[name='handler_name']").val($(this).parent('p').attr("handler_name"));
364
-		$("#updateModal .form input[name='handler_params']").val($(this).parent('p').attr("handler_params"));
351
+		$("#updateModal .form input[name='executorAddress']").val($(this).parent('p').attr("executorAddress"));
352
+		$("#updateModal .form input[name='executorHandler']").val($(this).parent('p').attr("executorHandler"));
353
+		$("#updateModal .form input[name='executorParam']").val($(this).parent('p').attr("executorParam"));
365 354
 		$("#updateModal .form input[name='author']").val($(this).parent('p').attr("author"));
366 355
 		$("#updateModal .form input[name='alarmEmail']").val($(this).parent('p').attr("alarmEmail"));
367 356
 		$("#updateModal .form input[name='alarmThreshold']").val($(this).parent('p').attr("alarmThreshold"));
@@ -393,11 +382,11 @@ $(function() {
393 382
             	required : true ,
394 383
                 maxlength: 200
395 384
             },
396
-            handler_address : {
385
+            executorAddress : {
397 386
             	required : true ,
398 387
                 maxlength: 200
399 388
             },
400
-            handler_name : {
389
+            executorHandler : {
401 390
             	required : true ,
402 391
                 maxlength: 200
403 392
             },
@@ -423,11 +412,11 @@ $(function() {
423 412
             	required :"请输入“任务描述”."  ,
424 413
                 maxlength:"“任务描述”长度不应超过200位"
425 414
             },  
426
-            handler_address : {
415
+            executorAddress : {
427 416
             	required :"请输入“执行器地址”."  ,
428 417
                 maxlength:"“执行器地址”长度不应超过200位"
429 418
             },
430
-            handler_name : {
419
+            executorHandler : {
431 420
             	required : "请输入“jobHandler”."  ,
432 421
                 maxlength: "“jobHandler”长度不应超过200位"
433 422
             },

+ 5 - 19
xxl-job-admin/src/main/webapp/static/js/joblog.index.1.js Visa fil

@@ -60,22 +60,14 @@ $(function() {
60 60
 	            			return data;
61 61
 	            		}
62 62
             		},
63
-	                { "data": 'jobName'},
63
+	                { "data": 'jobName', "visible" : false},
64 64
 	                { "data": 'jobCron', "visible" : false},
65 65
 	                { "data": 'jobDesc', "visible" : false},
66 66
 	                { "data": 'jobClass', "visible" : false},
67
-	                { 
68
-	                	"data": 'jobData',
69
-	                	"visible" : true,
70
-	                	"render": function ( data, type, row ) {
71
-	                		var _jobData = eval('(' + data + ')');	// row.jobData
72
-	                		var html = "<p title='" + data + "'>JobHandler:" + _jobData.handler_name +
73
-	                			"<br>执行参数:" + _jobData.handler_params + 
74
-	                			"<br>执行器地址:" + _jobData.handler_address + "</p>";
75
-	                		
76
-	                		return data?'<a class="logMsg" href="javascript:;" >查看<span style="display:none;">'+ html +'</span></a>':"无";
77
-	                	}
78
-	                },
67
+	                
68
+	                { "data": 'executorAddress', "visible" : true},
69
+	                { "data": 'executorHandler', "visible" : true},
70
+	                { "data": 'executorParam', "visible" : true},
79 71
 	                { 
80 72
 	                	"data": 'triggerTime', 
81 73
 	                	"render": function ( data, type, row ) {
@@ -106,12 +98,6 @@ $(function() {
106 98
 	                	"render": function ( data, type, row ) {
107 99
 	                		// better support expression or string, not function
108 100
 	                		return function () {
109
-	                			// local job do not support trigger detail log, now
110
-		                		var _jobData = eval('(' + row.jobData + ')'); 
111
-		                		if (!_jobData.handler_address) {
112
-		                			return;
113
-		                		}
114
-		                		
115 101
 		                		if (row.triggerStatus == 'SUCCESS'){
116 102
 		                			var temp = '<a href="javascript:;" class="logDetail" _id="'+ row.id +'">执行日志</a>';
117 103
 		                			if(!row.handleStatus){

+ 0 - 2
xxl-job-admin/src/test/java/com/xxl/job/dao/impl/XxlJobInfoTest.java Visa fil

@@ -34,7 +34,6 @@ public class XxlJobInfoTest {
34 34
 		info.setJobName("job_name");
35 35
 		info.setJobCron("jobCron");
36 36
 		info.setJobClass("jobClass");
37
-		info.setJobData("jobData");
38 37
 		int count = xxlJobInfoDao.save(info);
39 38
 		System.out.println(count);
40 39
 		System.out.println(info.getId());
@@ -48,7 +47,6 @@ public class XxlJobInfoTest {
48 47
 		XxlJobInfo item = xxlJobInfoDao.load(null ,"job_name");
49 48
 		
50 49
 		item.setJobCron("jobCron2");
51
-		item.setJobData("jobData2");
52 50
 		xxlJobInfoDao.update(item);
53 51
 	}
54 52
 	

+ 0 - 1
xxl-job-admin/src/test/java/com/xxl/job/dao/impl/XxlJobLogTest.java Visa fil

@@ -28,7 +28,6 @@ public class XxlJobLogTest {
28 28
 		xxlJobLog.setJobName("job_name");
29 29
 		xxlJobLog.setJobCron("jobCron");
30 30
 		xxlJobLog.setJobClass("jobClass");
31
-		xxlJobLog.setJobData("jobData");
32 31
 		int count = xxlJobLogDao.save(xxlJobLog);
33 32
 		System.out.println(count);
34 33
 		System.out.println(xxlJobLog.getId());

+ 102 - 63
xxl-job-core/src/main/java/com/xxl/job/core/handler/HandlerRepository.java Visa fil

@@ -19,20 +19,49 @@ import com.xxl.job.core.util.JacksonUtil;
19 19
 public class HandlerRepository {
20 20
 	private static Logger logger = LoggerFactory.getLogger(HandlerRepository.class);
21 21
 	
22
-	public static final String NAMESPACE = "namespace";
23
-	public enum NameSpaceEnum{RUN, KILL, LOG}
24
-	
25
-	public static final String HANDLER_ADDRESS = "handler_address";
26
-	public static final String HANDLER_PARAMS = "handler_params";
27
-	
28
-	public static final String HANDLER_GLUE_SWITCH = "handler_glue_switch";
29
-	public static final String HANDLER_NAME = "handler_name";
30
-	public static final String HANDLER_JOB_GROUP = "handler_job_group";
31
-	public static final String HANDLER_JOB_NAME = "handler_job_name";
32
-	
33
-	public static final String TRIGGER_LOG_ID = "trigger_log_id";
34
-	public static final String TRIGGER_LOG_ADDRESS = "trigger_log_address";
35
-	public static final String TRIGGER_TIMESTAMP = "trigger_timestamp";
22
+	public enum HandlerParamEnum{
23
+		/**
24
+		 * trigger timestamp
25
+		 */
26
+		TIMESTAMP,
27
+		/**
28
+		 * trigger action
29
+		 */
30
+		ACTION,
31
+		/**
32
+		 * remote executor jobhandler
33
+		 */
34
+		EXECUTOR_HANDLER,
35
+		/**
36
+		 * params of jobhandler
37
+		 */
38
+		EXECUTOR_PARAMS,
39
+		/**
40
+		 * switch of job, if open glue model
41
+		 */
42
+		GLUE_SWITCH,
43
+		/**
44
+		 * job group
45
+		 */
46
+		JOB_GROUP,
47
+		/**
48
+		 * job name
49
+		 */
50
+		JOB_NAME,
51
+		/**
52
+		 * address for callback log
53
+		 */
54
+		LOG_ADDRESS,
55
+		/**
56
+		 * log id
57
+		 */
58
+		LOG_ID,
59
+		/**
60
+		 * log date
61
+		 */
62
+		LOG_DATE
63
+	}
64
+	public enum ActionEnum{RUN, KILL, LOG, BEAT}
36 65
 	
37 66
 	public static ConcurrentHashMap<String, HandlerThread> handlerTreadMap = new ConcurrentHashMap<String, HandlerThread>();
38 67
 	
@@ -53,27 +82,26 @@ public class HandlerRepository {
53 82
 		callback.setStatus(RemoteCallBack.FAIL);
54 83
 
55 84
 		// check namespace
56
-		String namespace = _param.get(HandlerRepository.NAMESPACE);
85
+		String namespace = _param.get(HandlerParamEnum.ACTION.name());
57 86
 		if (namespace==null || namespace.trim().length()==0) {
58 87
 			callback.setMsg("param[NAMESPACE] can not be null.");
59 88
 			return JacksonUtil.writeValueAsString(callback);
60 89
 		}
61
-		
62
-		// parse namespace
63
-		if (namespace.equals(HandlerRepository.NameSpaceEnum.RUN.name())) {
64
-			// encryption check
65
-			long timestamp = _param.get(HandlerRepository.TRIGGER_TIMESTAMP)!=null?Long.valueOf(_param.get(HandlerRepository.TRIGGER_TIMESTAMP)):-1;
66
-			if (System.currentTimeMillis() - timestamp > 60000) {
67
-				callback.setMsg("Timestamp check failed.");
68
-				return JacksonUtil.writeValueAsString(callback);
69
-			}
90
+		// encryption check
91
+		long timestamp = _param.get(HandlerParamEnum.TIMESTAMP.name())!=null?Long.valueOf(_param.get(HandlerParamEnum.TIMESTAMP.name())):-1;
92
+		if (System.currentTimeMillis() - timestamp > 60000) {
93
+			callback.setMsg("Timestamp check failed.");
94
+			return JacksonUtil.writeValueAsString(callback);
95
+		}
70 96
 					
97
+		// parse namespace
98
+		if (namespace.equals(ActionEnum.RUN.name())) {
71 99
 			// push data to queue
72
-			String handler_glue_switch = _param.get(HandlerRepository.HANDLER_GLUE_SWITCH);
100
+			String handler_glue_switch = _param.get(HandlerParamEnum.GLUE_SWITCH.name());
73 101
 			HandlerThread handlerThread = null;
74 102
 			if ("0".equals(handler_glue_switch)) {
75 103
 				// bean model
76
-				String handler_name = _param.get(HandlerRepository.HANDLER_NAME);
104
+				String handler_name = _param.get(HandlerParamEnum.EXECUTOR_HANDLER.name());
77 105
 				if (handler_name == null || handler_name.trim().length()==0) {
78 106
 					callback.setMsg("bean model handler[HANDLER_NAME] not found.");
79 107
 					return JacksonUtil.writeValueAsString(callback);
@@ -85,70 +113,81 @@ public class HandlerRepository {
85 113
 				}
86 114
 			} else {
87 115
 				// glue
88
-				String handler_job_group = _param.get(HandlerRepository.HANDLER_JOB_GROUP);
89
-				String handler_job_name = _param.get(HandlerRepository.HANDLER_JOB_NAME);
90
-				if (handler_job_group == null || handler_job_group.trim().length()==0 || handler_job_name == null || handler_job_name.trim().length()==0) {
116
+				String job_group = _param.get(HandlerParamEnum.JOB_GROUP.name());
117
+				String job_name = _param.get(HandlerParamEnum.JOB_NAME.name());
118
+				if (job_group == null || job_group.trim().length()==0 || job_name == null || job_name.trim().length()==0) {
91 119
 					callback.setMsg("glue model handler[job group or name] is null.");
92 120
 					return JacksonUtil.writeValueAsString(callback);
93 121
 				}
94
-				String glueHandleName = "glue_".concat(handler_job_group).concat("_").concat(handler_job_name);
122
+				String glueHandleName = "glue_".concat(job_group).concat("_").concat(job_name);
95 123
 				handlerThread = handlerTreadMap.get(glueHandleName);
96 124
 				if (handlerThread==null) {
97
-					HandlerRepository.regist(glueHandleName, new GlueJobHandler(handler_job_group, handler_job_name));
125
+					HandlerRepository.regist(glueHandleName, new GlueJobHandler(job_group, job_name));
98 126
 				}
99 127
 				handlerThread = handlerTreadMap.get(glueHandleName);
100 128
 			}
101 129
 			
102 130
 			handlerThread.pushData(_param);
103 131
 			callback.setStatus(RemoteCallBack.SUCCESS);
104
-		} else if (namespace.equals(HandlerRepository.NameSpaceEnum.LOG.name())) {
105
-			String trigger_log_id = _param.get(HandlerRepository.TRIGGER_LOG_ID);
106
-			String trigger_timestamp = _param.get(HandlerRepository.TRIGGER_TIMESTAMP);
107
-			if (trigger_log_id==null || trigger_timestamp==null) {
108
-				callback.setMsg("trigger_log_id | trigger_timestamp can not be null.");
132
+		} else if (namespace.equals(ActionEnum.LOG.name())) {
133
+			String log_id = _param.get(HandlerParamEnum.LOG_ID.name());
134
+			String log_date = _param.get(HandlerParamEnum.LOG_DATE.name());
135
+			if (log_id==null || log_date==null) {
136
+				callback.setMsg("LOG_ID | LOG_DATE can not be null.");
109 137
 				return JacksonUtil.writeValueAsString(callback);
110 138
 			}
111 139
 			int logId = -1;
112 140
 			Date triggerDate = null;
113 141
 			try {
114
-				logId = Integer.valueOf(trigger_log_id);
115
-				triggerDate = new Date(Long.valueOf(trigger_timestamp));
142
+				logId = Integer.valueOf(log_id);
143
+				triggerDate = new Date(Long.valueOf(log_date));
116 144
 			} catch (Exception e) {
117 145
 			}
118 146
 			if (logId<=0 || triggerDate==null) {
119
-				callback.setMsg("trigger_log_id | trigger_timestamp is not parsed valid.");
147
+				callback.setMsg("LOG_ID | LOG_DATE parse error.");
120 148
 				return JacksonUtil.writeValueAsString(callback);
121 149
 			}
122
-			String logConteng = XxlJobFileAppender.readLog(triggerDate, trigger_log_id);
150
+			String logConteng = XxlJobFileAppender.readLog(triggerDate, log_id);
123 151
 			callback.setStatus(RemoteCallBack.SUCCESS);
124 152
 			callback.setMsg(logConteng);
125
-		} else if (namespace.equals(HandlerRepository.NameSpaceEnum.KILL.name())) {
126
-			// encryption check
127
-			long timestamp = _param.get(HandlerRepository.TRIGGER_TIMESTAMP)!=null?Long.valueOf(_param.get(HandlerRepository.TRIGGER_TIMESTAMP)):-1;
128
-			if (System.currentTimeMillis() - timestamp > 60000) {
129
-				callback.setMsg("Timestamp check failed.");
130
-				return JacksonUtil.writeValueAsString(callback);
131
-			}
132
-			
153
+		} else if (namespace.equals(ActionEnum.KILL.name())) {
133 154
 			// kill handlerThread, and create new one
134
-			String handler_name = _param.get(HandlerRepository.HANDLER_NAME);
135
-			if (handler_name!=null && handler_name.trim().length()>0) {
136
-				HandlerThread handlerThread = handlerTreadMap.get(handler_name);
137
-				if (handlerThread != null) {
138
-					IJobHandler handler = handlerThread.getHandler();
139
-					handlerThread.toStop();
140
-					handlerThread.interrupt();
141
-					regist(handler_name, handler);
142
-					callback.setStatus(RemoteCallBack.SUCCESS);
143
-				} else {
144
-					callback.setMsg("handler[" + handler_name + "] not found.");
155
+			String handler_glue_switch = _param.get(HandlerParamEnum.GLUE_SWITCH.name());
156
+			String handlerName = null;
157
+			if ("0".equals(handler_glue_switch)) {
158
+				String executor_handler = _param.get(HandlerParamEnum.EXECUTOR_HANDLER.name());
159
+				if (executor_handler==null) {
160
+					callback.setMsg("bean job , param[EXECUTOR_HANDLER] is null");
161
+					return JacksonUtil.writeValueAsString(callback);
162
+				}
163
+				handlerName = executor_handler;
164
+			} else {
165
+				// glue
166
+				String job_group = _param.get(HandlerParamEnum.JOB_GROUP.name());
167
+				String job_name = _param.get(HandlerParamEnum.JOB_NAME.name());
168
+				if (job_group==null || job_group.trim().length()==0 || job_name==null || job_name.trim().length()==0) {
169
+					callback.setMsg("glue job , param[JOB_GROUP or JOB_NAME] is null");
170
+					return JacksonUtil.writeValueAsString(callback);
145 171
 				}
146
-			}else{
147
-				callback.setMsg("param[HANDLER_NAME] can not be null.");
172
+				handlerName = "glue_".concat(job_group).concat("_").concat(job_name);
173
+			}
174
+			
175
+			HandlerThread handlerThread = handlerTreadMap.get(handlerName);
176
+			if (handlerThread != null) {
177
+				IJobHandler handler = handlerThread.getHandler();
178
+				handlerThread.toStop();
179
+				handlerThread.interrupt();
180
+				regist(handlerName, handler);
181
+				callback.setStatus(RemoteCallBack.SUCCESS);
182
+			} else {
183
+				callback.setMsg("job handler[" + handlerName + "] not found.");
148 184
 			}
149
-						
185
+				
186
+		} else if (namespace.equals(ActionEnum.BEAT.name())) {
187
+			callback.setStatus(RemoteCallBack.SUCCESS);
188
+			callback.setMsg(null);
150 189
 		} else {
151
-			callback.setMsg("param[NAMESPACE] is not valid.");
190
+			callback.setMsg("param[Action] is not valid.");
152 191
 			return JacksonUtil.writeValueAsString(callback);
153 192
 		}
154 193
 		

+ 5 - 4
xxl-job-core/src/main/java/com/xxl/job/core/handler/HandlerThread.java Visa fil

@@ -11,6 +11,7 @@ import org.eclipse.jetty.util.ConcurrentHashSet;
11 11
 import org.slf4j.Logger;
12 12
 import org.slf4j.LoggerFactory;
13 13
 
14
+import com.xxl.job.core.handler.HandlerRepository.HandlerParamEnum;
14 15
 import com.xxl.job.core.handler.IJobHandler.JobHandleStatus;
15 16
 import com.xxl.job.core.log.XxlJobFileAppender;
16 17
 import com.xxl.job.core.util.HttpUtil;
@@ -47,7 +48,7 @@ public class HandlerThread extends Thread{
47 48
 	}
48 49
 	
49 50
 	public void pushData(Map<String, String> param) {
50
-		if (param.get(HandlerRepository.TRIGGER_LOG_ID)!=null && !logIdSet.contains(param.get(HandlerRepository.TRIGGER_LOG_ID))) {
51
+		if (param.get(HandlerParamEnum.LOG_ID.name())!=null && !logIdSet.contains(param.get(HandlerParamEnum.LOG_ID.name()))) {
51 52
 			handlerDataQueue.offer(param);
52 53
 		}
53 54
 	}
@@ -60,9 +61,9 @@ public class HandlerThread extends Thread{
60 61
 				Map<String, String> handlerData = handlerDataQueue.poll();
61 62
 				if (handlerData!=null) {
62 63
 					i= 0;
63
-					String trigger_log_address = handlerData.get(HandlerRepository.TRIGGER_LOG_ADDRESS);
64
-					String trigger_log_id = handlerData.get(HandlerRepository.TRIGGER_LOG_ID);
65
-					String handler_params = handlerData.get(HandlerRepository.HANDLER_PARAMS);
64
+					String trigger_log_address = handlerData.get(HandlerParamEnum.LOG_ADDRESS.name());
65
+					String trigger_log_id = handlerData.get(HandlerParamEnum.LOG_ID.name());
66
+					String handler_params = handlerData.get(HandlerParamEnum.EXECUTOR_PARAMS.name());
66 67
 					logIdSet.remove(trigger_log_id);
67 68
 					
68 69
 					// parse param

+ 3 - 4
xxl-job-core/src/main/java/com/xxl/job/core/util/HttpUtil.java Visa fil

@@ -1,8 +1,6 @@
1 1
 package com.xxl.job.core.util;
2 2
 
3 3
 import java.io.IOException;
4
-import java.io.PrintWriter;
5
-import java.io.StringWriter;
6 4
 import java.util.ArrayList;
7 5
 import java.util.List;
8 6
 import java.util.Map;
@@ -98,9 +96,10 @@ public class HttpUtil {
98 96
 			}
99 97
 		} catch (Exception e) {
100 98
 			e.printStackTrace();
101
-			StringWriter out = new StringWriter();
99
+			/*StringWriter out = new StringWriter();
102 100
 			e.printStackTrace(new PrintWriter(out));
103
-			callback.setMsg(out.toString());
101
+			callback.setMsg(out.toString());*/
102
+			callback.setMsg(e.getMessage());
104 103
 		} finally{
105 104
 			if (httpPost!=null) {
106 105
 				httpPost.releaseConnection();