xueli.xue 9 år sedan
förälder
incheckning
8b71e2cec4
34 ändrade filer med 988 tillägg och 674 borttagningar
  1. 27 28
      xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobLogController.java
  2. 27 29
      xxl-job-admin/src/main/java/com/xxl/job/admin/core/callback/XxlJobLogCallbackServerHandler.java
  3. 5 5
      xxl-job-admin/src/main/java/com/xxl/job/admin/core/jobbean/LocalNomalJobBean.java
  4. 44 34
      xxl-job-admin/src/main/java/com/xxl/job/admin/core/jobbean/RemoteHttpJobBean.java
  5. 2 2
      xxl-job-admin/src/main/java/com/xxl/job/admin/core/jobbean/impl/DemoConcurrentJobBean.java
  6. 2 2
      xxl-job-admin/src/main/java/com/xxl/job/admin/core/jobbean/impl/DemoNomalJobBean.java
  7. 4 4
      xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobMonitorHelper.java
  8. 1 1
      xxl-job-admin/src/main/java/com/xxl/job/admin/service/IXxlJobService.java
  9. 1 1
      xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java
  10. 6 2
      xxl-job-admin/src/main/webapp/static/js/jobinfo.index.1.js
  11. 1 0
      xxl-job-admin/src/main/webapp/static/js/joblog.index.1.js
  12. 4 6
      xxl-job-admin/src/test/java/com/xxl/job/dao/impl/XxlJobInfoTest.java
  13. 8 10
      xxl-job-admin/src/test/java/com/xxl/job/dao/impl/XxlJobLogTest.java
  14. 3 3
      xxl-job-core/src/main/java/com/xxl/job/core/executor/jetty/XxlJobExecutor.java
  15. 30 17
      xxl-job-core/src/main/java/com/xxl/job/core/executor/jetty/XxlJobExecutorHandler.java
  16. 2 2
      xxl-job-core/src/main/java/com/xxl/job/core/executor/servlet/XxlJobServlet.java
  17. 1 1
      xxl-job-core/src/main/java/com/xxl/job/core/glue/GlueFactory.java
  18. 0 247
      xxl-job-core/src/main/java/com/xxl/job/core/handler/HandlerRepository.java
  19. 0 129
      xxl-job-core/src/main/java/com/xxl/job/core/handler/HandlerThread.java
  20. 4 6
      xxl-job-core/src/main/java/com/xxl/job/core/handler/IJobHandler.java
  21. 8 15
      xxl-job-core/src/main/java/com/xxl/job/core/log/XxlJobFileAppender.java
  22. 99 0
      xxl-job-core/src/main/java/com/xxl/job/core/router/HandlerRouter.java
  23. 13 0
      xxl-job-core/src/main/java/com/xxl/job/core/router/IAction.java
  24. 17 0
      xxl-job-core/src/main/java/com/xxl/job/core/router/action/BeatAction.java
  25. 35 0
      xxl-job-core/src/main/java/com/xxl/job/core/router/action/KillAction.java
  26. 21 0
      xxl-job-core/src/main/java/com/xxl/job/core/router/action/LogAction.java
  27. 66 0
      xxl-job-core/src/main/java/com/xxl/job/core/router/action/RunAction.java
  28. 140 0
      xxl-job-core/src/main/java/com/xxl/job/core/router/model/RequestModel.java
  29. 45 0
      xxl-job-core/src/main/java/com/xxl/job/core/router/model/ResponseModel.java
  30. 128 0
      xxl-job-core/src/main/java/com/xxl/job/core/router/thread/JobThread.java
  31. 44 0
      xxl-job-core/src/main/java/com/xxl/job/core/router/thread/TriggerCallbackThread.java
  32. 59 0
      xxl-job-core/src/main/java/com/xxl/job/core/util/ByteHexConverter.java
  33. 0 130
      xxl-job-core/src/main/java/com/xxl/job/core/util/HttpUtil.java
  34. 141 0
      xxl-job-core/src/main/java/com/xxl/job/core/util/XxlJobNetCommUtil.java

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

@@ -6,10 +6,10 @@ import com.xxl.job.admin.core.model.XxlJobInfo;
6 6
 import com.xxl.job.admin.core.model.XxlJobLog;
7 7
 import com.xxl.job.admin.dao.IXxlJobInfoDao;
8 8
 import com.xxl.job.admin.dao.IXxlJobLogDao;
9
-import com.xxl.job.core.handler.HandlerRepository.ActionEnum;
10
-import com.xxl.job.core.handler.HandlerRepository.HandlerParamEnum;
11
-import com.xxl.job.core.util.HttpUtil;
12
-import com.xxl.job.core.util.HttpUtil.RemoteCallBack;
9
+import com.xxl.job.core.router.HandlerRouter.ActionRepository;
10
+import com.xxl.job.core.router.model.RequestModel;
11
+import com.xxl.job.core.router.model.ResponseModel;
12
+import com.xxl.job.core.util.XxlJobNetCommUtil;
13 13
 import org.apache.commons.lang.StringUtils;
14 14
 import org.apache.commons.lang.time.DateUtils;
15 15
 import org.springframework.stereotype.Controller;
@@ -110,22 +110,22 @@ public class JobLogController {
110 110
 		if (log == null) {
111 111
 			return new ReturnT<String>(500, "参数异常");
112 112
 		}
113
-		if (!RemoteCallBack.SUCCESS.equals(log.getTriggerStatus())) {
113
+		if (!ResponseModel.SUCCESS.equals(log.getTriggerStatus())) {
114 114
 			return new ReturnT<String>(500, "调度失败,无法查看执行日志");
115 115
 		}
116 116
 		
117 117
 		// trigger id, trigger time
118
-		Map<String, String> reqMap = new HashMap<String, String>();
119
-		reqMap.put(HandlerParamEnum.TIMESTAMP.name(), String.valueOf(System.currentTimeMillis()));
120
-		reqMap.put(HandlerParamEnum.ACTION.name(), ActionEnum.LOG.name());
121
-		reqMap.put(HandlerParamEnum.LOG_ID.name(), String.valueOf(id));
122
-		reqMap.put(HandlerParamEnum.LOG_DATE.name(), String.valueOf(log.getTriggerTime().getTime()));
123
-		
124
-		RemoteCallBack callBack = HttpUtil.post(HttpUtil.addressToUrl(log.getExecutorAddress()), reqMap);
125
-		if (HttpUtil.RemoteCallBack.SUCCESS.equals(callBack.getStatus())) {
126
-			return new ReturnT<String>(callBack.getMsg());
118
+		RequestModel requestModel = new RequestModel();
119
+		requestModel.setTimestamp(System.currentTimeMillis());
120
+		requestModel.setAction(ActionRepository.LOG.name());
121
+		requestModel.setLogId(id);
122
+		requestModel.setLogDateTim(log.getTriggerTime().getTime());
123
+
124
+		ResponseModel responseModel = XxlJobNetCommUtil.postHex(XxlJobNetCommUtil.addressToUrl(log.getExecutorAddress()), requestModel);
125
+		if (ResponseModel.SUCCESS.equals(responseModel.getStatus())) {
126
+			return new ReturnT<String>(responseModel.getMsg());
127 127
 		} else {
128
-			return new ReturnT<String>(500, callBack.getMsg());
128
+			return new ReturnT<String>(500, responseModel.getMsg());
129 129
 		}
130 130
 	}
131 131
 	
@@ -145,27 +145,26 @@ public class JobLogController {
145 145
 		if (log == null || jobInfo==null) {
146 146
 			return new ReturnT<String>(500, "参数异常");
147 147
 		}
148
-		if (!RemoteCallBack.SUCCESS.equals(log.getTriggerStatus())) {
148
+		if (!ResponseModel.SUCCESS.equals(log.getTriggerStatus())) {
149 149
 			return new ReturnT<String>(500, "调度失败,无法终止日志");
150 150
 		}
151 151
 		
152
-		// request
153
-		Map<String, String> reqMap = new HashMap<String, String>();
154
-		reqMap.put(HandlerParamEnum.TIMESTAMP.name(), String.valueOf(System.currentTimeMillis()));
155
-		reqMap.put(HandlerParamEnum.ACTION.name(), ActionEnum.KILL.name());
156
-		reqMap.put(HandlerParamEnum.JOB_GROUP.name(), log.getJobGroup());
157
-		reqMap.put(HandlerParamEnum.JOB_NAME.name(), log.getJobName());
158
-		reqMap.put(HandlerParamEnum.GLUE_SWITCH.name(), String.valueOf(jobInfo.getGlueSwitch()));
152
+		// request of kill
153
+		RequestModel requestModel = new RequestModel();
154
+		requestModel.setTimestamp(System.currentTimeMillis());
155
+		requestModel.setAction(ActionRepository.KILL.name());
156
+		requestModel.setJobGroup(log.getJobGroup());
157
+		requestModel.setJobName(log.getJobName());
159 158
 
160
-		RemoteCallBack callBack = HttpUtil.post(HttpUtil.addressToUrl(log.getExecutorAddress()), reqMap);
161
-		if (HttpUtil.RemoteCallBack.SUCCESS.equals(callBack.getStatus())) {
162
-			log.setHandleStatus(HttpUtil.RemoteCallBack.FAIL);
159
+		ResponseModel responseModel = XxlJobNetCommUtil.postHex(XxlJobNetCommUtil.addressToUrl(log.getExecutorAddress()), requestModel);
160
+		if (ResponseModel.SUCCESS.equals(responseModel.getStatus())) {
161
+			log.setHandleStatus(ResponseModel.FAIL);
163 162
 			log.setHandleMsg("人为操作主动终止");
164 163
 			log.setHandleTime(new Date());
165 164
 			xxlJobLogDao.updateHandleInfo(log);
166
-			return new ReturnT<String>(callBack.getMsg());
165
+			return new ReturnT<String>(responseModel.getMsg());
167 166
 		} else {
168
-			return new ReturnT<String>(500, callBack.getMsg());
167
+			return new ReturnT<String>(500, responseModel.getMsg());
169 168
 		}
170 169
 	}
171 170
 }

+ 27 - 29
xxl-job-admin/src/main/java/com/xxl/job/admin/core/callback/XxlJobLogCallbackServerHandler.java Visa fil

@@ -1,20 +1,18 @@
1 1
 package com.xxl.job.admin.core.callback;
2 2
 
3
-import java.io.IOException;
4
-import java.util.Date;
3
+import com.xxl.job.admin.core.model.XxlJobLog;
4
+import com.xxl.job.admin.core.util.DynamicSchedulerUtil;
5
+import com.xxl.job.core.router.model.RequestModel;
6
+import com.xxl.job.core.router.model.ResponseModel;
7
+import com.xxl.job.core.util.XxlJobNetCommUtil;
8
+import org.eclipse.jetty.server.Request;
9
+import org.eclipse.jetty.server.handler.AbstractHandler;
5 10
 
6 11
 import javax.servlet.ServletException;
7 12
 import javax.servlet.http.HttpServletRequest;
8 13
 import javax.servlet.http.HttpServletResponse;
9
-
10
-import org.apache.commons.lang.StringUtils;
11
-import org.eclipse.jetty.server.Request;
12
-import org.eclipse.jetty.server.handler.AbstractHandler;
13
-
14
-import com.xxl.job.admin.core.model.XxlJobLog;
15
-import com.xxl.job.admin.core.util.DynamicSchedulerUtil;
16
-import com.xxl.job.core.util.HttpUtil.RemoteCallBack;
17
-import com.xxl.job.core.util.JacksonUtil;
14
+import java.io.IOException;
15
+import java.util.Date;
18 16
 
19 17
 /**
20 18
  * Created by xuxueli on 2016-5-22 11:15:42
@@ -27,31 +25,31 @@ public class XxlJobLogCallbackServerHandler extends AbstractHandler {
27 25
 		httpServletRequest.setCharacterEncoding("UTF-8");
28 26
 		httpServletResponse.setCharacterEncoding("UTF-8");
29 27
 
30
-		// parse param
31
-		String log_id = httpServletRequest.getParameter("log_id");
32
-		String status = httpServletRequest.getParameter("status");
33
-		String msg = httpServletRequest.getParameter("msg");
34
-		
28
+		// parse hex-json to request model
29
+		String requestHex = httpServletRequest.getParameter(XxlJobNetCommUtil.HEX);
30
+		RequestModel requestModel = XxlJobNetCommUtil.parseHexJson2Obj(requestHex, RequestModel.class);
31
+
35 32
 		// process
36
-		RemoteCallBack callBack = new RemoteCallBack();
37
-		callBack.setStatus(RemoteCallBack.FAIL);
38
-		if (StringUtils.isNumeric(log_id) && StringUtils.isNotBlank(status)) {
39
-			XxlJobLog log = DynamicSchedulerUtil.xxlJobLogDao.load(Integer.valueOf(log_id));
40
-			if (log!=null) {
41
-				log.setHandleTime(new Date());
42
-				log.setHandleStatus(status);
43
-				log.setHandleMsg(msg);
44
-				DynamicSchedulerUtil.xxlJobLogDao.updateHandleInfo(log);
45
-				callBack.setStatus(RemoteCallBack.SUCCESS);
46
-			}
33
+		ResponseModel responseModel = null;
34
+		XxlJobLog log = DynamicSchedulerUtil.xxlJobLogDao.load(requestModel.getLogId());
35
+		if (log!=null) {
36
+			log.setHandleTime(new Date());
37
+			log.setHandleStatus(requestModel.getStatus());
38
+			log.setHandleMsg(requestModel.getMsg());
39
+			DynamicSchedulerUtil.xxlJobLogDao.updateHandleInfo(log);
40
+			responseModel = new ResponseModel(ResponseModel.SUCCESS, null);
41
+		} else {
42
+			responseModel = new ResponseModel(ResponseModel.FAIL, "log item not found.");
47 43
 		}
48
-		String resp = JacksonUtil.writeValueAsString(callBack);
44
+
45
+		// format response model to hex-json
46
+		String responseHex = XxlJobNetCommUtil.formatObj2HexJson(responseModel);
49 47
 
50 48
 		// response
51 49
 		httpServletResponse.setContentType("text/html;charset=utf-8");
52 50
 		httpServletResponse.setStatus(HttpServletResponse.SC_OK);
53 51
 		baseRequest.setHandled(true);
54
-		httpServletResponse.getWriter().println(resp);
52
+		httpServletResponse.getWriter().println(responseHex);
55 53
 	}
56 54
 
57 55
 }

+ 5 - 5
xxl-job-admin/src/main/java/com/xxl/job/admin/core/jobbean/LocalNomalJobBean.java Visa fil

@@ -1,5 +1,5 @@
1 1
 package com.xxl.job.admin.core.jobbean;
2
-//package com.xxl.job.service.job;
2
+//package com.xxl.job.action.job;
3 3
 //
4 4
 //import java.io.PrintWriter;
5 5
 //import java.io.StringWriter;
@@ -15,8 +15,8 @@ package com.xxl.job.admin.core.jobbean;
15 15
 //import org.slf4j.LoggerFactory;
16 16
 //import org.springframework.scheduling.quartz.QuartzJobBean;
17 17
 //
18
-//import com.xxl.job.client.handler.HandlerRepository;
19
-//import com.xxl.job.client.util.HttpUtil.RemoteCallBack;
18
+//import com.xxl.job.client.handler.HandlerRouter;
19
+//import com.xxl.job.client.util.XxlJobNetCommUtil.RemoteCallBack;
20 20
 //import com.xxl.job.client.util.JacksonUtil;
21 21
 //import com.xxl.job.core.model.XxlJobInfo;
22 22
 //import com.xxl.job.core.model.XxlJobLog;
@@ -55,7 +55,7 @@ package com.xxl.job.admin.core.jobbean;
55 55
 //		logger.info(">>>>>>>>>>> xxl-job trigger start, jobLog:{}", jobLog);
56 56
 //		
57 57
 //		// trigger request
58
-//		String handler_params = jobDataMap.get(HandlerRepository.HANDLER_PARAMS);
58
+//		String handler_params = jobDataMap.get(HandlerRouter.HANDLER_PARAMS);
59 59
 //		String[] handlerParams = null;
60 60
 //		if (StringUtils.isNotBlank(handler_params)) {
61 61
 //			handlerParams = handler_params.split(",");
@@ -72,7 +72,7 @@ package com.xxl.job.admin.core.jobbean;
72 72
 //			jobLog.setHandleStatus(RemoteCallBack.SUCCESS);
73 73
 //			jobLog.setHandleMsg(JacksonUtil.writeValueAsString(responseMsg));
74 74
 //		} catch (Exception e) {
75
-//			logger.info("HandlerThread Exception:", e);
75
+//			logger.info("JobThread Exception:", e);
76 76
 //			StringWriter out = new StringWriter();
77 77
 //			e.printStackTrace(new PrintWriter(out));
78 78
 //			

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

@@ -5,10 +5,10 @@ import com.xxl.job.admin.core.model.XxlJobInfo;
5 5
 import com.xxl.job.admin.core.model.XxlJobLog;
6 6
 import com.xxl.job.admin.core.thread.JobMonitorHelper;
7 7
 import com.xxl.job.admin.core.util.DynamicSchedulerUtil;
8
-import com.xxl.job.core.handler.HandlerRepository.ActionEnum;
9
-import com.xxl.job.core.handler.HandlerRepository.HandlerParamEnum;
10
-import com.xxl.job.core.util.HttpUtil;
11
-import com.xxl.job.core.util.HttpUtil.RemoteCallBack;
8
+import com.xxl.job.core.router.HandlerRouter.ActionRepository;
9
+import com.xxl.job.core.router.model.RequestModel;
10
+import com.xxl.job.core.router.model.ResponseModel;
11
+import com.xxl.job.core.util.XxlJobNetCommUtil;
12 12
 import org.apache.commons.lang.StringUtils;
13 13
 import org.quartz.JobExecutionContext;
14 14
 import org.quartz.JobExecutionException;
@@ -18,7 +18,10 @@ import org.slf4j.LoggerFactory;
18 18
 import org.springframework.scheduling.quartz.QuartzJobBean;
19 19
 
20 20
 import java.text.MessageFormat;
21
-import java.util.*;
21
+import java.util.Arrays;
22
+import java.util.Collections;
23
+import java.util.Date;
24
+import java.util.List;
22 25
 
23 26
 /**
24 27
  * http job bean
@@ -43,30 +46,27 @@ public class RemoteHttpJobBean extends QuartzJobBean {
43 46
 		logger.info(">>>>>>>>>>> xxl-job trigger start, jobId:{}", jobLog.getId());
44 47
 		
45 48
 		// trigger request
46
-		HashMap<String, String> params = new HashMap<String, String>();
47
-		params.put(HandlerParamEnum.TIMESTAMP.name(), String.valueOf(System.currentTimeMillis()));
48
-		params.put(HandlerParamEnum.ACTION.name(), ActionEnum.RUN.name());
49
-		
50
-		params.put(HandlerParamEnum.LOG_ADDRESS.name(), XxlJobLogCallbackServer.getTrigger_log_address());
51
-		params.put(HandlerParamEnum.LOG_ID.name(), String.valueOf(jobLog.getId()));
52
-
53
-		params.put(HandlerParamEnum.JOB_GROUP.name(), jobInfo.getJobGroup());
54
-		params.put(HandlerParamEnum.JOB_NAME.name(), jobInfo.getJobName());
55
-		params.put(HandlerParamEnum.EXECUTOR_HANDLER.name(), jobInfo.getExecutorHandler());
56
-		params.put(HandlerParamEnum.EXECUTOR_PARAMS.name(), jobInfo.getExecutorParam());
57
-
58
-		params.put(HandlerParamEnum.GLUE_SWITCH.name(), String.valueOf(jobInfo.getGlueSwitch()));
49
+		RequestModel requestModel = new RequestModel();
50
+		requestModel.setTimestamp(System.currentTimeMillis());
51
+		requestModel.setAction(ActionRepository.RUN.name());
52
+		requestModel.setJobGroup(jobInfo.getJobGroup());
53
+		requestModel.setJobName(jobInfo.getJobName());
54
+		requestModel.setExecutorHandler(jobInfo.getExecutorHandler());
55
+		requestModel.setExecutorParams(jobInfo.getExecutorParam());
56
+		requestModel.setGlueSwitch((jobInfo.getGlueSwitch()==0)?false:true);
57
+		requestModel.setLogAddress(XxlJobLogCallbackServer.getTrigger_log_address());
58
+		requestModel.setLogId(jobLog.getId());
59 59
 
60 60
 		// failover trigger
61
-		RemoteCallBack callback = failoverTrigger(jobInfo.getExecutorAddress(), params, jobLog);
61
+		ResponseModel responseModel = failoverTrigger(jobInfo.getExecutorAddress(), requestModel, jobLog);
62 62
 		jobLog.setExecutorHandler(jobInfo.getExecutorHandler());
63 63
 		jobLog.setExecutorParam(jobInfo.getExecutorParam());
64
-		logger.info(">>>>>>>>>>> xxl-job failoverTrigger response, jobId:{}, callback:{}", jobLog.getId(), callback);
64
+		logger.info(">>>>>>>>>>> xxl-job failoverTrigger response, jobId:{}, responseModel:{}", jobLog.getId(), responseModel.toString());
65 65
 		
66 66
 		// update trigger info
67 67
 		jobLog.setTriggerTime(new Date());
68
-		jobLog.setTriggerStatus(callback.getStatus());
69
-		jobLog.setTriggerMsg(callback.getMsg());
68
+		jobLog.setTriggerStatus(responseModel.getStatus());
69
+		jobLog.setTriggerMsg(responseModel.getMsg());
70 70
 		DynamicSchedulerUtil.xxlJobLogDao.updateTriggerInfo(jobLog);
71 71
 
72 72
 		// monitor triger
@@ -81,7 +81,7 @@ public class RemoteHttpJobBean extends QuartzJobBean {
81 81
 	 * @param handler_address
82 82
 	 * @return
83 83
 	 */
84
-	public RemoteCallBack failoverTrigger(String handler_address, HashMap<String, String> handler_params, XxlJobLog jobLog){
84
+	public ResponseModel failoverTrigger(String handler_address, RequestModel requestModel, XxlJobLog jobLog){
85 85
 		if (handler_address.split(",").length > 1) {
86 86
 			
87 87
 			// for ha
@@ -92,33 +92,43 @@ public class RemoteHttpJobBean extends QuartzJobBean {
92 92
 			String failoverMessage = "";
93 93
 			for (String address : addressList) {
94 94
 				if (StringUtils.isNotBlank(address)) {
95
-					HashMap<String, String> params = new HashMap<String, String>();
96
-					params.put(HandlerParamEnum.TIMESTAMP.name(), String.valueOf(System.currentTimeMillis()));
97
-					params.put(HandlerParamEnum.ACTION.name(), ActionEnum.BEAT.name());
98
-					RemoteCallBack beatResult = HttpUtil.post(HttpUtil.addressToUrl(address), params);
95
+
96
+					// beat check
97
+					RequestModel beatRequest = new RequestModel();
98
+					beatRequest.setTimestamp(System.currentTimeMillis());
99
+					beatRequest.setAction(ActionRepository.BEAT.name());
100
+					ResponseModel beatResult = XxlJobNetCommUtil.postHex(XxlJobNetCommUtil.addressToUrl(address), beatRequest);
99 101
 					failoverMessage += MessageFormat.format("BEAT running, <br>>>>[address] : {0}, <br>>>>[status] : {1}, <br>>>>[msg] : {2} <br><hr>", address, beatResult.getStatus(), beatResult.getMsg());
100
-					if (RemoteCallBack.SUCCESS.equals(beatResult.getStatus())) {
102
+
103
+					// beat success, trigger do
104
+					if (beatResult.SUCCESS.equals(beatResult.getStatus())) {
105
+						// store real address
101 106
 						jobLog.setExecutorAddress(address);
102
-						RemoteCallBack triggerCallback = HttpUtil.post(HttpUtil.addressToUrl(address), handler_params);
103
-						triggerCallback.setStatus(RemoteCallBack.SUCCESS);
107
+
108
+						// real trigger
109
+						ResponseModel triggerCallback = XxlJobNetCommUtil.postHex(XxlJobNetCommUtil.addressToUrl(address), requestModel);
104 110
 						failoverMessage += MessageFormat.format("Trigger running, <br>>>>[address] : {0}, <br>>>>[status] : {1}, <br>>>>[msg] : {2} <br><hr>", address, triggerCallback.getStatus(), triggerCallback.getMsg());
105 111
 						triggerCallback.setMsg(failoverMessage);
106 112
 						return triggerCallback;
107 113
 					}
114
+
108 115
 				}
109 116
 			}
110
-			
111
-			RemoteCallBack result = new RemoteCallBack();
112
-			result.setStatus(RemoteCallBack.FAIL);
117
+
118
+			ResponseModel result = new ResponseModel();
119
+			result.setStatus(ResponseModel.FAIL);
113 120
 			result.setMsg(failoverMessage);
114 121
 			return result;
115 122
 		} else {
123
+			// store real address
116 124
 			jobLog.setExecutorAddress(handler_address);
117
-			RemoteCallBack triggerCallback = HttpUtil.post(HttpUtil.addressToUrl(handler_address), handler_params);
125
+
126
+			ResponseModel triggerCallback = XxlJobNetCommUtil.postHex(XxlJobNetCommUtil.addressToUrl(handler_address), requestModel);
118 127
 			String failoverMessage = MessageFormat.format("Trigger running, <br>>>>[address] : {0}, <br>>>>[status] : {1}, <br>>>>[msg] : {2} <br><hr>", handler_address, triggerCallback.getStatus(), triggerCallback.getMsg());
119 128
 			triggerCallback.setMsg(failoverMessage);
120 129
 			return triggerCallback;
121 130
 		}
122 131
 	}
132
+
123 133
 	
124 134
 }

+ 2 - 2
xxl-job-admin/src/main/java/com/xxl/job/admin/core/jobbean/impl/DemoConcurrentJobBean.java Visa fil

@@ -1,11 +1,11 @@
1 1
 package com.xxl.job.admin.core.jobbean.impl;
2
-//package com.xxl.job.service.job.impl;
2
+//package com.xxl.job.action.job.impl;
3 3
 //
4 4
 //import java.util.concurrent.TimeUnit;
5 5
 //
6 6
 //import org.quartz.DisallowConcurrentExecution;
7 7
 //
8
-//import com.xxl.job.service.job.LocalNomalJobBean;
8
+//import com.xxl.job.action.job.LocalNomalJobBean;
9 9
 //
10 10
 ///**
11 11
 // * demo job bean for no-concurrent

+ 2 - 2
xxl-job-admin/src/main/java/com/xxl/job/admin/core/jobbean/impl/DemoNomalJobBean.java Visa fil

@@ -1,12 +1,12 @@
1 1
 package com.xxl.job.admin.core.jobbean.impl;
2
-//package com.xxl.job.service.job.impl;
2
+//package com.xxl.job.action.job.impl;
3 3
 //
4 4
 //import java.util.concurrent.TimeUnit;
5 5
 //
6 6
 //import org.slf4j.Logger;
7 7
 //import org.slf4j.LoggerFactory;
8 8
 //
9
-//import com.xxl.job.service.job.LocalNomalJobBean;
9
+//import com.xxl.job.action.job.LocalNomalJobBean;
10 10
 //
11 11
 ///**
12 12
 // * demo job bean for concurrent

+ 4 - 4
xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobMonitorHelper.java Visa fil

@@ -4,7 +4,7 @@ import com.xxl.job.admin.core.model.XxlJobInfo;
4 4
 import com.xxl.job.admin.core.model.XxlJobLog;
5 5
 import com.xxl.job.admin.core.util.DynamicSchedulerUtil;
6 6
 import com.xxl.job.admin.core.util.MailUtil;
7
-import com.xxl.job.core.util.HttpUtil.RemoteCallBack;
7
+import com.xxl.job.core.router.model.ResponseModel;
8 8
 import org.apache.commons.lang.StringUtils;
9 9
 import org.slf4j.Logger;
10 10
 import org.slf4j.LoggerFactory;
@@ -40,7 +40,7 @@ public class JobMonitorHelper {
40 40
 							logger.info(">>>>>>>>>>> job monitor heat success, JobLogId:{}", jobLogId);
41 41
 							XxlJobLog log = DynamicSchedulerUtil.xxlJobLogDao.load(jobLogId);
42 42
 							if (log!=null) {
43
-								if (RemoteCallBack.SUCCESS.equals(log.getTriggerStatus()) && StringUtils.isBlank(log.getHandleStatus())) {
43
+								if (ResponseModel.SUCCESS.equals(log.getTriggerStatus()) && StringUtils.isBlank(log.getHandleStatus())) {
44 44
 									try {
45 45
 										TimeUnit.SECONDS.sleep(10);
46 46
 									} catch (InterruptedException e) {
@@ -48,10 +48,10 @@ public class JobMonitorHelper {
48 48
 									}
49 49
 									JobMonitorHelper.monitor(jobLogId);
50 50
 								}
51
-								if (RemoteCallBack.SUCCESS.equals(log.getTriggerStatus()) && RemoteCallBack.SUCCESS.equals(log.getHandleStatus())) {
51
+								if (ResponseModel.SUCCESS.equals(log.getTriggerStatus()) && ResponseModel.SUCCESS.equals(log.getHandleStatus())) {
52 52
 									// pass
53 53
 								}
54
-								if (RemoteCallBack.FAIL.equals(log.getTriggerStatus()) || RemoteCallBack.FAIL.equals(log.getHandleStatus())) {
54
+								if (ResponseModel.FAIL.equals(log.getTriggerStatus()) || ResponseModel.FAIL.equals(log.getHandleStatus())) {
55 55
 									XxlJobInfo info = DynamicSchedulerUtil.xxlJobInfoDao.load(log.getJobGroup(), log.getJobName());
56 56
 									if (info!=null && info.getAlarmEmail()!=null && info.getAlarmEmail().trim().length()>0) {
57 57
 

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

@@ -5,7 +5,7 @@ import java.util.Map;
5 5
 import com.xxl.job.admin.core.model.ReturnT;
6 6
 
7 7
 /**
8
- * core job service for xxl-job
8
+ * core job action for xxl-job
9 9
  * 
10 10
  * @author xuxueli 2016-5-28 15:30:33
11 11
  */

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

@@ -23,7 +23,7 @@ import java.util.List;
23 23
 import java.util.Map;
24 24
 
25 25
 /**
26
- * core job service for xxl-job
26
+ * core job action for xxl-job
27 27
  * @author xuxueli 2016-5-28 15:30:33
28 28
  */
29 29
 @Service

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

@@ -265,7 +265,9 @@ $(function() {
265 265
         	$.post(base_url + "/jobinfo/add",  $("#addModal .form").serialize(), function(data, status) {
266 266
     			if (data.code == "200") {
267 267
     				ComAlert.show(1, "新增任务成功", function(){
268
-    					window.location.reload();
268
+    					//window.location.reload();
269
+						$('#addModal').modal('hide');
270
+						jobTable.fnDraw();
269 271
     				});
270 272
     			} else {
271 273
     				if (data.msg) {
@@ -395,7 +397,9 @@ $(function() {
395 397
     		$.post(base_url + "/jobinfo/reschedule", $("#updateModal .form").serialize(), function(data, status) {
396 398
     			if (data.code == "200") {
397 399
     				ComAlert.show(1, "更新成功", function(){
398
-    					window.location.reload();
400
+    					//window.location.reload();
401
+						$('#updateModal').modal('hide');
402
+						jobTable.fnDraw();
399 403
     				});
400 404
     			} else {
401 405
     				if (data.msg) {

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

@@ -71,6 +71,7 @@ $(function() {
71 71
 	        	var obj = {};
72 72
 	        	obj.jobGroup = $('#jobGroup').val();
73 73
 	        	obj.jobName = $('#jobName').val();
74
+				obj.filterTime = $('#filterTime').val();
74 75
 	        	obj.start = d.start;
75 76
 	        	obj.length = d.length;
76 77
                 return obj;

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

@@ -1,16 +1,14 @@
1 1
 package com.xxl.job.dao.impl;
2 2
 
3
-import java.util.List;
4
-
5
-import javax.annotation.Resource;
6
-
3
+import com.xxl.job.admin.core.model.XxlJobInfo;
4
+import com.xxl.job.admin.dao.IXxlJobInfoDao;
7 5
 import org.junit.Test;
8 6
 import org.junit.runner.RunWith;
9 7
 import org.springframework.test.context.ContextConfiguration;
10 8
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
11 9
 
12
-import com.xxl.job.admin.core.model.XxlJobInfo;
13
-import com.xxl.job.admin.dao.IXxlJobInfoDao;
10
+import javax.annotation.Resource;
11
+import java.util.List;
14 12
 
15 13
 @RunWith(SpringJUnit4ClassRunner.class)
16 14
 @ContextConfiguration(locations = "classpath*:applicationcontext-*.xml")

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

@@ -1,19 +1,17 @@
1 1
 package com.xxl.job.dao.impl;
2 2
 
3
-import java.util.Date;
4
-import java.util.List;
5
-
6
-import javax.annotation.Resource;
7
-
3
+import com.xxl.job.admin.core.model.XxlJobLog;
4
+import com.xxl.job.admin.dao.IXxlJobLogDao;
5
+import com.xxl.job.core.handler.IJobHandler;
6
+import com.xxl.job.core.router.model.ResponseModel;
8 7
 import org.junit.Test;
9 8
 import org.junit.runner.RunWith;
10 9
 import org.springframework.test.context.ContextConfiguration;
11 10
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
12 11
 
13
-import com.xxl.job.admin.core.model.XxlJobLog;
14
-import com.xxl.job.admin.dao.IXxlJobLogDao;
15
-import com.xxl.job.core.handler.IJobHandler;
16
-import com.xxl.job.core.util.HttpUtil.RemoteCallBack;
12
+import javax.annotation.Resource;
13
+import java.util.Date;
14
+import java.util.List;
17 15
 
18 16
 @RunWith(SpringJUnit4ClassRunner.class)
19 17
 @ContextConfiguration(locations = "classpath*:applicationcontext-*.xml")
@@ -38,7 +36,7 @@ public class XxlJobLogTest {
38 36
 	public void updateTriggerInfo(){
39 37
 		XxlJobLog xxlJobLog = xxlJobLogDao.load(29);
40 38
 		xxlJobLog.setTriggerTime(new Date());
41
-		xxlJobLog.setTriggerStatus(RemoteCallBack.SUCCESS);
39
+		xxlJobLog.setTriggerStatus(ResponseModel.SUCCESS);
42 40
 		xxlJobLog.setTriggerMsg("trigger msg");
43 41
 		xxlJobLogDao.updateTriggerInfo(xxlJobLog);
44 42
 	}

+ 3 - 3
xxl-job-core/src/main/java/com/xxl/job/core/executor/jetty/XxlJobExecutor.java Visa fil

@@ -1,6 +1,6 @@
1 1
 package com.xxl.job.core.executor.jetty;
2 2
 
3
-import com.xxl.job.core.handler.HandlerRepository;
3
+import com.xxl.job.core.router.HandlerRouter;
4 4
 import com.xxl.job.core.handler.IJobHandler;
5 5
 import com.xxl.job.core.handler.annotation.JobHander;
6 6
 import org.eclipse.jetty.server.Connector;
@@ -81,7 +81,7 @@ public class XxlJobExecutor implements ApplicationContextAware {
81 81
 	}
82 82
 	
83 83
 	/**
84
-	 * init job handler service
84
+	 * init job handler action
85 85
 	 */
86 86
 	public void initJobHandler(){
87 87
 		Map<String, Object> serviceBeanMap = XxlJobExecutor.applicationContext.getBeansWithAnnotation(JobHander.class);
@@ -90,7 +90,7 @@ public class XxlJobExecutor implements ApplicationContextAware {
90 90
                 if (serviceBean instanceof IJobHandler){
91 91
                     String name = serviceBean.getClass().getAnnotation(JobHander.class).value();
92 92
                     IJobHandler handler = (IJobHandler) serviceBean;
93
-                    HandlerRepository.registJobHandler(name, handler);
93
+                    HandlerRouter.registJobHandler(name, handler);
94 94
                 }
95 95
             }
96 96
         }

+ 30 - 17
xxl-job-core/src/main/java/com/xxl/job/core/executor/jetty/XxlJobExecutorHandler.java Visa fil

@@ -1,20 +1,24 @@
1 1
 package com.xxl.job.core.executor.jetty;
2 2
 
3
-import com.xxl.job.core.handler.HandlerRepository;
3
+import com.xxl.job.core.router.HandlerRouter;
4
+import com.xxl.job.core.router.model.RequestModel;
5
+import com.xxl.job.core.router.model.ResponseModel;
6
+import com.xxl.job.core.util.XxlJobNetCommUtil;
4 7
 import org.eclipse.jetty.server.Request;
5 8
 import org.eclipse.jetty.server.handler.AbstractHandler;
9
+import org.slf4j.Logger;
10
+import org.slf4j.LoggerFactory;
6 11
 
7 12
 import javax.servlet.ServletException;
8 13
 import javax.servlet.http.HttpServletRequest;
9 14
 import javax.servlet.http.HttpServletResponse;
10 15
 import java.io.IOException;
11
-import java.util.HashMap;
12
-import java.util.Map;
13 16
 
14 17
 /**
15 18
  * Created by xuxueli on 2016/3/2 21:23.
16 19
  */
17 20
 public class XxlJobExecutorHandler extends AbstractHandler {
21
+    private static Logger logger = LoggerFactory.getLogger(XxlJobExecutorHandler.class);
18 22
 
19 23
 	@Override
20 24
 	public void handle(String s, Request baseRequest, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws IOException, ServletException {
@@ -22,22 +26,31 @@ public class XxlJobExecutorHandler extends AbstractHandler {
22 26
 		httpServletRequest.setCharacterEncoding("UTF-8");
23 27
 		httpServletResponse.setCharacterEncoding("UTF-8");
24 28
 
25
-		Map<String, String> _param = new HashMap<String, String>();
26
-		if (httpServletRequest.getParameterMap()!=null && httpServletRequest.getParameterMap().size()>0) {
27
-			for (Object paramKey : httpServletRequest.getParameterMap().keySet()) {
28
-				if (paramKey!=null) {
29
-					String paramKeyStr = paramKey.toString();
30
-					_param.put(paramKeyStr, httpServletRequest.getParameter(paramKeyStr));
31
-				}
32
-			}
33
-		}
34
-
35
-		String resp = HandlerRepository.service(_param);
36
-
37
-		httpServletResponse.setContentType("text/html;charset=utf-8");
29
+        // parse hex-json to request model
30
+        String requestHex = httpServletRequest.getParameter(XxlJobNetCommUtil.HEX);
31
+        ResponseModel responseModel = null;
32
+        if (requestHex!=null && requestHex.trim().length()>0) {
33
+            try {
34
+                // route trigger
35
+                RequestModel requestModel = XxlJobNetCommUtil.parseHexJson2Obj(requestHex, RequestModel.class);
36
+                responseModel = HandlerRouter.route(requestModel);
37
+            } catch (Exception e) {
38
+                logger.error("", e);
39
+                responseModel = new ResponseModel(ResponseModel.SUCCESS, e.getMessage());
40
+            }
41
+        }
42
+        if (responseModel == null) {
43
+            responseModel = new ResponseModel(ResponseModel.SUCCESS, "系统异常");
44
+        }
45
+
46
+        // format response model to hex-json
47
+        String responseHex = XxlJobNetCommUtil.formatObj2HexJson(responseModel);
48
+
49
+        // return
50
+		httpServletResponse.setContentType("text/plain;charset=utf-8");
38 51
 		httpServletResponse.setStatus(HttpServletResponse.SC_OK);
39 52
 		baseRequest.setHandled(true);
40
-		httpServletResponse.getWriter().println(resp);
53
+		httpServletResponse.getWriter().println(responseHex);
41 54
 	}
42 55
 
43 56
 }

+ 2 - 2
xxl-job-core/src/main/java/com/xxl/job/core/executor/servlet/XxlJobServlet.java Visa fil

@@ -10,7 +10,7 @@
10 10
 //import javax.servlet.http.HttpServletRequest;
11 11
 //import javax.servlet.http.HttpServletResponse;
12 12
 //
13
-//import com.xxl.job.client.handler.HandlerRepository;
13
+//import com.xxl.job.client.handler.HandlerRouter;
14 14
 //
15 15
 //
16 16
 ///**
@@ -45,7 +45,7 @@
45 45
 //			}
46 46
 //		}
47 47
 //		
48
-//		String resp = HandlerRepository.service(_param);
48
+//		String resp = HandlerRouter.action(_param);
49 49
 //		response.getWriter().append(resp);
50 50
 //		return;
51 51
 //	}

+ 1 - 1
xxl-job-core/src/main/java/com/xxl/job/core/glue/GlueFactory.java Visa fil

@@ -59,7 +59,7 @@ public class GlueFactory implements ApplicationContextAware {
59 59
 	}
60 60
 	
61 61
 	/**
62
-	 * inject service of spring
62
+	 * inject action of spring
63 63
 	 * @param instance
64 64
 	 */
65 65
 	public void injectService(Object instance){

+ 0 - 247
xxl-job-core/src/main/java/com/xxl/job/core/handler/HandlerRepository.java Visa fil

@@ -1,247 +0,0 @@
1
-package com.xxl.job.core.handler;
2
-
3
-import com.xxl.job.core.handler.impl.GlueJobHandler;
4
-import com.xxl.job.core.log.XxlJobFileAppender;
5
-import com.xxl.job.core.util.HttpUtil;
6
-import com.xxl.job.core.util.HttpUtil.RemoteCallBack;
7
-import com.xxl.job.core.util.JacksonUtil;
8
-import org.slf4j.Logger;
9
-import org.slf4j.LoggerFactory;
10
-
11
-import java.util.Date;
12
-import java.util.HashMap;
13
-import java.util.Map;
14
-import java.util.concurrent.ConcurrentHashMap;
15
-import java.util.concurrent.LinkedBlockingQueue;
16
-
17
-/**
18
- * handler repository
19
- * @author xuxueli 2015-12-19 19:28:44
20
- */
21
-public class HandlerRepository {
22
-	private static Logger logger = LoggerFactory.getLogger(HandlerRepository.class);
23
-	
24
-	public enum HandlerParamEnum{
25
-		/**
26
-		 * trigger timestamp
27
-		 */
28
-		TIMESTAMP,
29
-		/**
30
-		 * trigger action
31
-		 */
32
-		ACTION,
33
-		/**
34
-		 * job group
35
-		 */
36
-		JOB_GROUP,
37
-		/**
38
-		 * job name
39
-		 */
40
-		JOB_NAME,
41
-		/**
42
-		 * params of jobhandler
43
-		 */
44
-		EXECUTOR_HANDLER,
45
-		/**
46
-		 * params of jobhandler
47
-		 */
48
-		EXECUTOR_PARAMS,
49
-		/**
50
-		 * switch of glue job: 0-no,1-yes
51
-		 */
52
-		GLUE_SWITCH,
53
-		/**
54
-		 * address for callback log
55
-		 */
56
-		LOG_ADDRESS,
57
-		/**
58
-		 * log id
59
-		 */
60
-		LOG_ID,
61
-		/**
62
-		 * log date
63
-		 */
64
-		LOG_DATE
65
-	}
66
-	public enum ActionEnum{RUN, KILL, LOG, BEAT}
67
-
68
-	// jobhandler repository
69
-	private static ConcurrentHashMap<String, IJobHandler> handlerRepository = new ConcurrentHashMap<String, IJobHandler>();
70
-	public static void registJobHandler(String name, IJobHandler jobHandler){
71
-		handlerRepository.put(name, jobHandler);
72
-		logger.info("xxl-job register jobhandler success, name:{}, jobHandler:{}", name, jobHandler);
73
-	}
74
-
75
-	// thread repository of jobhandler
76
-	public static ConcurrentHashMap<String, HandlerThread> handlerTreadMap = new ConcurrentHashMap<String, HandlerThread>();
77
-	public static HandlerThread registJobHandlerThread(String jobkey, IJobHandler handler){
78
-		HandlerThread handlerThread = new HandlerThread(handler);
79
-		handlerThread.start();
80
-		logger.info(">>>>>>>>>>> xxl-job regist handler success, jobkey:{}, handler:{}", new Object[]{jobkey, handler});
81
-		return handlerTreadMap.put(jobkey, handlerThread);	// putIfAbsent
82
-	}
83
-
84
-	// handler push to queue
85
-	public static String service(Map<String, String> _param) {
86
-		logger.debug(">>>>>>>>>>> xxl-job service start, _param:{}", new Object[]{_param});
87
-
88
-		// callback
89
-		RemoteCallBack callback = new RemoteCallBack();
90
-		callback.setStatus(RemoteCallBack.FAIL);
91
-
92
-		// check namespace
93
-		String namespace = _param.get(HandlerParamEnum.ACTION.name());
94
-		if (namespace==null || namespace.trim().length()==0) {
95
-			callback.setMsg("param[NAMESPACE] can not be null.");
96
-			return JacksonUtil.writeValueAsString(callback);
97
-		}
98
-		// encryption check
99
-		long timestamp = _param.get(HandlerParamEnum.TIMESTAMP.name())!=null?Long.valueOf(_param.get(HandlerParamEnum.TIMESTAMP.name())):-1;
100
-		if (System.currentTimeMillis() - timestamp > 60000) {
101
-			callback.setMsg("Timestamp check failed.");
102
-			return JacksonUtil.writeValueAsString(callback);
103
-		}
104
-
105
-		// parse namespace
106
-		if (namespace.equals(ActionEnum.RUN.name())) {
107
-
108
-			// generate jobKey
109
-			String job_group = _param.get(HandlerParamEnum.JOB_GROUP.name());
110
-			String job_name = _param.get(HandlerParamEnum.JOB_NAME.name());
111
-			if (job_group == null || job_group.trim().length()==0 || job_name == null || job_name.trim().length()==0) {
112
-				callback.setMsg("JOB_GROUP or JOB_NAME is null.");
113
-				return JacksonUtil.writeValueAsString(callback);
114
-			}
115
-
116
-			// glue switch
117
-			String handler_glue_switch = _param.get(HandlerParamEnum.GLUE_SWITCH.name());
118
-			if (handler_glue_switch==null || handler_glue_switch.trim().length()==0){
119
-				callback.setMsg("GLUE_SWITCH is null.");
120
-				return JacksonUtil.writeValueAsString(callback);
121
-			}
122
-
123
-			// load old thread
124
-			String jobKey = job_group.concat("_").concat(job_name);
125
-			HandlerThread handlerThread = handlerTreadMap.get(jobKey);
126
-
127
-			if ("0".equals(handler_glue_switch)) {
128
-				// bean model
129
-
130
-				// handler name
131
-				String executor_handler = _param.get(HandlerParamEnum.EXECUTOR_HANDLER.name());
132
-				if (executor_handler==null || executor_handler.trim().length()==0){
133
-					callback.setMsg("EXECUTOR_HANDLER is null.");
134
-					return JacksonUtil.writeValueAsString(callback);
135
-				}
136
-
137
-				// handler instance
138
-				IJobHandler jobHandler = handlerRepository.get(executor_handler);
139
-
140
-				if (handlerThread == null) {
141
-					// jobhandler match
142
-					if (jobHandler==null) {
143
-						callback.setMsg("handler for jobKey=[" + jobKey + "] not found.");
144
-						return JacksonUtil.writeValueAsString(callback);
145
-					}
146
-					handlerThread = HandlerRepository.registJobHandlerThread(jobKey, jobHandler);
147
-				} else {
148
-					if (handlerThread.getHandler() != jobHandler) {
149
-						handlerThread = HandlerRepository.registJobHandlerThread(jobKey, jobHandler);
150
-					}
151
-				}
152
-			} else {
153
-				// glue
154
-				if (handlerThread == null) {
155
-					handlerThread = HandlerRepository.registJobHandlerThread(jobKey, new GlueJobHandler(job_group, job_name));
156
-				}
157
-			}
158
-
159
-			// push data to queue
160
-			handlerThread.pushData(_param);
161
-			callback.setStatus(RemoteCallBack.SUCCESS);
162
-		} else if (namespace.equals(ActionEnum.KILL.name())) {
163
-			// generate jobKey
164
-			String job_group = _param.get(HandlerParamEnum.JOB_GROUP.name());
165
-			String job_name = _param.get(HandlerParamEnum.JOB_NAME.name());
166
-			if (job_group == null || job_group.trim().length()==0 || job_name == null || job_name.trim().length()==0) {
167
-				callback.setMsg("JOB_GROUP or JOB_NAME is null.");
168
-				return JacksonUtil.writeValueAsString(callback);
169
-			}
170
-			String jobKey = job_group.concat("_").concat(job_name);
171
-
172
-			// kill handlerThread, and create new one
173
-			HandlerThread handlerThread = handlerTreadMap.get(jobKey);
174
-			if (handlerThread != null) {
175
-				IJobHandler handler = handlerThread.getHandler();
176
-				handlerThread.toStop();
177
-				handlerThread.interrupt();
178
-				HandlerRepository.registJobHandlerThread(jobKey, handler);
179
-				callback.setStatus(RemoteCallBack.SUCCESS);
180
-			} else {
181
-				callback.setMsg("handler for jobKey=[" + jobKey + "] not found.");
182
-			}
183
-
184
-		} else if (namespace.equals(ActionEnum.LOG.name())) {
185
-			String log_id = _param.get(HandlerParamEnum.LOG_ID.name());
186
-			String log_date = _param.get(HandlerParamEnum.LOG_DATE.name());
187
-			if (log_id==null || log_date==null) {
188
-				callback.setMsg("LOG_ID | LOG_DATE can not be null.");
189
-				return JacksonUtil.writeValueAsString(callback);
190
-			}
191
-			int logId = -1;
192
-			Date triggerDate = null;
193
-			try {
194
-				logId = Integer.valueOf(log_id);
195
-				triggerDate = new Date(Long.valueOf(log_date));
196
-			} catch (Exception e) {
197
-			}
198
-			if (logId<=0 || triggerDate==null) {
199
-				callback.setMsg("LOG_ID | LOG_DATE parse error.");
200
-				return JacksonUtil.writeValueAsString(callback);
201
-			}
202
-			String logConteng = XxlJobFileAppender.readLog(triggerDate, log_id);
203
-			callback.setStatus(RemoteCallBack.SUCCESS);
204
-			callback.setMsg(logConteng);
205
-		} else if (namespace.equals(ActionEnum.BEAT.name())) {
206
-			callback.setStatus(RemoteCallBack.SUCCESS);
207
-			callback.setMsg(null);
208
-		} else {
209
-			callback.setMsg("param[Action] is not valid.");
210
-			return JacksonUtil.writeValueAsString(callback);
211
-		}
212
-
213
-		logger.debug(">>>>>>>>>>> xxl-job service end, triggerData:{}");
214
-		return JacksonUtil.writeValueAsString(callback);
215
-	}
216
-
217
-	// ----------------------- for callback log -----------------------
218
-	private static LinkedBlockingQueue<HashMap<String, String>> callBackQueue = new LinkedBlockingQueue<HashMap<String, String>>();
219
-	static {
220
-		new Thread(new Runnable() {
221
-			@Override
222
-			public void run() {
223
-				while(true){
224
-					try {
225
-						HashMap<String, String> item = callBackQueue.take();
226
-						if (item != null) {
227
-							RemoteCallBack callback = null;
228
-							try {
229
-								callback = HttpUtil.post(item.get("_address"), item);
230
-							} catch (Exception e) {
231
-								logger.info("HandlerThread Exception:", e);
232
-							}
233
-							logger.info(">>>>>>>>>>> xxl-job callback , params:{}, result:{}", new Object[]{item, callback});
234
-						}
235
-					} catch (Exception e) {
236
-						e.printStackTrace();
237
-					}
238
-				}
239
-			}
240
-		}).start();
241
-	}
242
-	public static void pushCallBack(String address, HashMap<String, String> params){
243
-		params.put("_address", address);
244
-		callBackQueue.add(params);
245
-	}
246
-	
247
-}

+ 0 - 129
xxl-job-core/src/main/java/com/xxl/job/core/handler/HandlerThread.java Visa fil

@@ -1,129 +0,0 @@
1
-package com.xxl.job.core.handler;
2
-
3
-import com.xxl.job.core.handler.HandlerRepository.HandlerParamEnum;
4
-import com.xxl.job.core.handler.IJobHandler.JobHandleStatus;
5
-import com.xxl.job.core.log.XxlJobFileAppender;
6
-import com.xxl.job.core.util.HttpUtil;
7
-import org.eclipse.jetty.util.ConcurrentHashSet;
8
-import org.slf4j.Logger;
9
-import org.slf4j.LoggerFactory;
10
-
11
-import java.io.PrintWriter;
12
-import java.io.StringWriter;
13
-import java.util.HashMap;
14
-import java.util.Map;
15
-import java.util.concurrent.LinkedBlockingQueue;
16
-import java.util.concurrent.TimeUnit;
17
-
18
-/**
19
- * handler thread
20
- * @author xuxueli 2016-1-16 19:52:47
21
- */
22
-public class HandlerThread extends Thread{
23
-	private static Logger logger = LoggerFactory.getLogger(HandlerThread.class);
24
-	
25
-	private IJobHandler handler;
26
-	private LinkedBlockingQueue<Map<String, String>> handlerDataQueue;
27
-	private ConcurrentHashSet<String> logIdSet;		// avoid repeat trigger for the same TRIGGER_LOG_ID
28
-	private boolean toStop = false;
29
-	
30
-	public HandlerThread(IJobHandler handler) {
31
-		this.handler = handler;
32
-		handlerDataQueue = new LinkedBlockingQueue<Map<String,String>>();
33
-		logIdSet = new ConcurrentHashSet<String>();
34
-	}
35
-	
36
-	public IJobHandler getHandler() {
37
-		return handler;
38
-	}
39
-	public void toStop() {
40
-		/**
41
-		 * Thread.interrupt只支持终止线程的阻塞状态(wait、join、sleep),
42
-		 * 在阻塞出抛出InterruptedException异常,但是并不会终止运行的线程本身;
43
-		 * 所以需要注意,此处彻底销毁本线程,需要通过共享变量方式;
44
-		 */
45
-		this.toStop = true;
46
-	}
47
-	
48
-	public void pushData(Map<String, String> param) {
49
-		if (param.get(HandlerParamEnum.LOG_ID.name())!=null && !logIdSet.contains(param.get(HandlerParamEnum.LOG_ID.name()))) {
50
-			handlerDataQueue.offer(param);
51
-		}
52
-	}
53
-	
54
-	int i = 1;
55
-	@Override
56
-	public void run() {
57
-		while(!toStop){
58
-			try {
59
-				// to check toStop signal, we need cycle, so wo cannot use queue.take(), instand of poll(timeout)
60
-				Map<String, String> handlerData = handlerDataQueue.poll(3L, TimeUnit.SECONDS);
61
-				if (handlerData!=null) {
62
-					i= 0;
63
-					String log_address = handlerData.get(HandlerParamEnum.LOG_ADDRESS.name());
64
-					String log_id = handlerData.get(HandlerParamEnum.LOG_ID.name());
65
-					String handler_params = handlerData.get(HandlerParamEnum.EXECUTOR_PARAMS.name());
66
-					logIdSet.remove(log_id);
67
-					
68
-					// parse param
69
-					String[] handlerParams = null; 
70
-					if (handler_params!=null && handler_params.trim().length()>0) {
71
-						handlerParams = handler_params.split(",");
72
-					} else {
73
-						handlerParams = new String[0];
74
-					}
75
-					
76
-					// handle job
77
-					JobHandleStatus _status = JobHandleStatus.FAIL;
78
-					String _msg = null;
79
-					try {
80
-						XxlJobFileAppender.contextHolder.set(log_id);
81
-						logger.info(">>>>>>>>>>> xxl-job handle start.");
82
-						_status = handler.execute(handlerParams);
83
-					} catch (Exception e) {
84
-						logger.info("HandlerThread Exception:", e);
85
-						StringWriter out = new StringWriter();
86
-						e.printStackTrace(new PrintWriter(out));
87
-						_msg = out.toString();
88
-					}
89
-					logger.info(">>>>>>>>>>> xxl-job handle end, handlerParams:{}, _status:{}, _msg:{}", 
90
-							new Object[]{handlerParams, _status, _msg});
91
-					
92
-					// callback handler info
93
-					if (!toStop) {
94
-						HashMap<String, String> params = new HashMap<String, String>();
95
-						params.put("log_id", log_id);
96
-						params.put("status", _status.name());
97
-						params.put("msg", _msg);
98
-						HandlerRepository.pushCallBack(HttpUtil.addressToUrl(log_address), params);
99
-					} else {
100
-						HashMap<String, String> params = new HashMap<String, String>();
101
-						params.put("log_id", log_id);
102
-						params.put("status", JobHandleStatus.FAIL.name());
103
-						params.put("msg", "人工手动终止[业务运行中,被强制终止]");
104
-						HandlerRepository.pushCallBack(HttpUtil.addressToUrl(log_address), params);
105
-					}
106
-				}
107
-			} catch (Exception e) {
108
-				logger.info("HandlerThread Exception:", e);
109
-			}
110
-		}
111
-		
112
-		// callback trigger request in queue
113
-		while(handlerDataQueue!=null && handlerDataQueue.size()>0){
114
-			Map<String, String> handlerData = handlerDataQueue.poll();
115
-			if (handlerData!=null) {
116
-				String log_address = handlerData.get(HandlerParamEnum.LOG_ADDRESS.name());
117
-				String log_id = handlerData.get(HandlerParamEnum.LOG_ID.name());
118
-				
119
-				HashMap<String, String> params = new HashMap<String, String>();
120
-				params.put("log_id", log_id);
121
-				params.put("status", JobHandleStatus.FAIL.name());
122
-				params.put("msg", "人工手动终止[任务尚未执行,在调度队列中被终止]");
123
-				HandlerRepository.pushCallBack(HttpUtil.addressToUrl(log_address), params);
124
-			}
125
-		}
126
-		
127
-		logger.info(">>>>>>>>>>>> xxl-job handlerThrad stoped, hashCode:{}", Thread.currentThread());
128
-	}
129
-}

+ 4 - 6
xxl-job-core/src/main/java/com/xxl/job/core/handler/IJobHandler.java Visa fil

@@ -1,10 +1,12 @@
1 1
 package com.xxl.job.core.handler;
2 2
 
3
+import com.xxl.job.core.router.HandlerRouter;
4
+
3 5
 /**
4 6
  * remote job handler
5 7
  * @author xuxueli 2015-12-19 19:06:38
6 8
  */
7
-public abstract class IJobHandler extends HandlerRepository{
9
+public abstract class IJobHandler extends HandlerRouter {
8 10
 	
9 11
 	/**
10 12
 	 * job handler <br><br>
@@ -23,11 +25,7 @@ public abstract class IJobHandler extends HandlerRepository{
23 25
 		/**
24 26
 		 * handle fail
25 27
 		 */
26
-		FAIL, 
27
-		/**
28
-		 * handle not found
29
-		 */
30
-		NOT_FOUND;
28
+		FAIL;
31 29
 	}
32 30
 	
33 31
 }

+ 8 - 15
xxl-job-core/src/main/java/com/xxl/job/core/log/XxlJobFileAppender.java Visa fil

@@ -1,27 +1,20 @@
1 1
 package com.xxl.job.core.log;
2 2
 
3
-import java.io.BufferedReader;
4
-import java.io.File;
5
-import java.io.FileInputStream;
6
-import java.io.FileOutputStream;
7
-import java.io.FileReader;
8
-import java.io.IOException;
9
-import java.io.InputStreamReader;
10
-import java.io.LineNumberReader;
11
-import java.text.SimpleDateFormat;
12
-import java.util.Date;
13
-
14 3
 import org.apache.log4j.AppenderSkeleton;
15 4
 import org.apache.log4j.Layout;
16 5
 import org.apache.log4j.spi.LoggingEvent;
17 6
 
7
+import java.io.*;
8
+import java.text.SimpleDateFormat;
9
+import java.util.Date;
10
+
18 11
 /**
19 12
  * store trigger log in each log-file
20 13
  * @author xuxueli 2016-3-12 19:25:12
21 14
  */
22 15
 public class XxlJobFileAppender extends AppenderSkeleton {
23 16
 	
24
-	// for HandlerThread
17
+	// for JobThread
25 18
 	public static ThreadLocal<String> contextHolder = new ThreadLocal<String>();
26 19
 	public static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
27 20
 	
@@ -112,8 +105,8 @@ public class XxlJobFileAppender extends AppenderSkeleton {
112 105
 	 * @param trigger_log_id
113 106
 	 * @return
114 107
 	 */
115
-	public static String readLog(Date triggerDate, String trigger_log_id ){
116
-		if (triggerDate==null || trigger_log_id==null || trigger_log_id.trim().length()==0) {
108
+	public static String readLog(Date triggerDate, int trigger_log_id ){
109
+		if (triggerDate==null || trigger_log_id<=0) {
117 110
 			return null;
118 111
 		}
119 112
 		
@@ -131,7 +124,7 @@ public class XxlJobFileAppender extends AppenderSkeleton {
131 124
 		}
132 125
 		
133 126
 		// filePath/yyyy-MM-dd/9999.log
134
-		String logFileName = trigger_log_id.concat(".log");
127
+		String logFileName = String.valueOf(trigger_log_id).concat(".log");
135 128
 		File logFile = new File(filePathDateDir, logFileName);	
136 129
 		if (!logFile.exists()) {
137 130
 			return null;

+ 99 - 0
xxl-job-core/src/main/java/com/xxl/job/core/router/HandlerRouter.java Visa fil

@@ -0,0 +1,99 @@
1
+package com.xxl.job.core.router;
2
+
3
+import com.xxl.job.core.handler.IJobHandler;
4
+import com.xxl.job.core.router.action.BeatAction;
5
+import com.xxl.job.core.router.action.KillAction;
6
+import com.xxl.job.core.router.action.LogAction;
7
+import com.xxl.job.core.router.action.RunAction;
8
+import com.xxl.job.core.router.model.RequestModel;
9
+import com.xxl.job.core.router.model.ResponseModel;
10
+import com.xxl.job.core.router.thread.JobThread;
11
+import org.slf4j.Logger;
12
+import org.slf4j.LoggerFactory;
13
+
14
+import java.util.concurrent.ConcurrentHashMap;
15
+
16
+/**
17
+ * handler repository
18
+ * @author xuxueli 2015-12-19 19:28:44
19
+ */
20
+public class HandlerRouter {
21
+	private static Logger logger = LoggerFactory.getLogger(HandlerRouter.class);
22
+
23
+	/**
24
+	 * job handler repository
25
+     */
26
+	private static ConcurrentHashMap<String, IJobHandler> jobHandlerRepository = new ConcurrentHashMap<String, IJobHandler>();
27
+	public static IJobHandler registJobHandler(String name, IJobHandler jobHandler){
28
+		logger.info("xxl-job register jobhandler success, name:{}, jobHandler:{}", name, jobHandler);
29
+		return HandlerRouter.jobHandlerRepository.put(name, jobHandler);
30
+	}
31
+	public static IJobHandler loadJobHandler(String name){
32
+		return HandlerRouter.jobHandlerRepository.get(name);
33
+	}
34
+
35
+	/**
36
+	 * job thread repository
37
+     */
38
+	private static ConcurrentHashMap<String, JobThread> JobThreadRepository = new ConcurrentHashMap<String, JobThread>();
39
+	public static JobThread registJobThread(String jobkey, IJobHandler handler){
40
+		JobThread handlerThread = new JobThread(handler);
41
+		handlerThread.start();
42
+		logger.info(">>>>>>>>>>> xxl-job regist handler success, jobkey:{}, handler:{}", new Object[]{jobkey, handler});
43
+		return HandlerRouter.JobThreadRepository.put(jobkey, handlerThread);	// putIfAbsent
44
+	}
45
+	public static JobThread loadJobThread(String jobKey){
46
+		return HandlerRouter.JobThreadRepository.get(jobKey);
47
+	}
48
+
49
+	/**
50
+	 * route action repository
51
+	 */
52
+	public enum ActionRepository {
53
+		RUN(new RunAction()),
54
+		KILL(new KillAction()),
55
+		LOG(new LogAction()),
56
+		BEAT(new BeatAction());
57
+
58
+		private IAction action;
59
+		private ActionRepository(IAction action){
60
+			this.action = action;
61
+		}
62
+
63
+		/**
64
+		 * match Action by enum name
65
+		 * @param name
66
+         * @return
67
+         */
68
+		public static IAction matchAction(String name){
69
+			if (name!=null && name.trim().length()>0) {
70
+				for (ActionRepository item : ActionRepository.values()) {
71
+					if (item.name().equals(name)) {
72
+						return item.action;
73
+					}
74
+				}
75
+			}
76
+			return null;
77
+		}
78
+
79
+	}
80
+
81
+	// handler push to queue
82
+	public static ResponseModel route(RequestModel requestModel) {
83
+		logger.debug(">>>>>>>>>>> xxl-job route, RequestModel:{}", new Object[]{requestModel.toString()});
84
+
85
+		// timestamp check
86
+		if (System.currentTimeMillis() - requestModel.getTimestamp() > 60000) {
87
+			return new ResponseModel(ResponseModel.SUCCESS, "Timestamp Timeout.");
88
+		}
89
+
90
+		// match action
91
+		IAction action = ActionRepository.matchAction(requestModel.getAction());
92
+		if (action == null) {
93
+			return new ResponseModel(ResponseModel.SUCCESS, "Action match fail.");
94
+		}
95
+
96
+		return action.execute(requestModel);
97
+	}
98
+
99
+}

+ 13 - 0
xxl-job-core/src/main/java/com/xxl/job/core/router/IAction.java Visa fil

@@ -0,0 +1,13 @@
1
+package com.xxl.job.core.router;
2
+
3
+import com.xxl.job.core.router.model.RequestModel;
4
+import com.xxl.job.core.router.model.ResponseModel;
5
+
6
+/**
7
+ * Created by xuxueli on 16/7/22.
8
+ */
9
+public abstract class IAction {
10
+
11
+    public abstract ResponseModel execute(RequestModel requestModel);
12
+
13
+}

+ 17 - 0
xxl-job-core/src/main/java/com/xxl/job/core/router/action/BeatAction.java Visa fil

@@ -0,0 +1,17 @@
1
+package com.xxl.job.core.router.action;
2
+
3
+import com.xxl.job.core.router.IAction;
4
+import com.xxl.job.core.router.model.RequestModel;
5
+import com.xxl.job.core.router.model.ResponseModel;
6
+
7
+/**
8
+ * Created by xuxueli on 16/7/22.
9
+ */
10
+public class BeatAction extends IAction {
11
+
12
+    @Override
13
+    public ResponseModel execute(RequestModel requestModel) {
14
+        return new ResponseModel(ResponseModel.SUCCESS, "i am alive.");
15
+    }
16
+
17
+}

+ 35 - 0
xxl-job-core/src/main/java/com/xxl/job/core/router/action/KillAction.java Visa fil

@@ -0,0 +1,35 @@
1
+package com.xxl.job.core.router.action;
2
+
3
+import com.xxl.job.core.handler.IJobHandler;
4
+import com.xxl.job.core.router.HandlerRouter;
5
+import com.xxl.job.core.router.IAction;
6
+import com.xxl.job.core.router.model.RequestModel;
7
+import com.xxl.job.core.router.model.ResponseModel;
8
+import com.xxl.job.core.router.thread.JobThread;
9
+
10
+/**
11
+ * Created by xuxueli on 16/7/22.
12
+ */
13
+public class KillAction extends IAction {
14
+
15
+    @Override
16
+    public ResponseModel execute(RequestModel requestModel) {
17
+
18
+        // generate jobKey
19
+        String jobKey = requestModel.getJobGroup().concat("_").concat(requestModel.getJobName());
20
+
21
+        // kill handlerThread, and create new one
22
+        JobThread jobThread = HandlerRouter.loadJobThread(jobKey);
23
+
24
+        if (jobThread != null) {
25
+            IJobHandler handler = jobThread.getHandler();
26
+            jobThread.toStop("人工手动终止");
27
+            jobThread.interrupt();
28
+            HandlerRouter.registJobThread(jobKey, handler);
29
+            return new ResponseModel(ResponseModel.SUCCESS, "job thread kull success.");
30
+        }
31
+
32
+        return new ResponseModel(ResponseModel.FAIL, "job thread not found.");
33
+    }
34
+
35
+}

+ 21 - 0
xxl-job-core/src/main/java/com/xxl/job/core/router/action/LogAction.java Visa fil

@@ -0,0 +1,21 @@
1
+package com.xxl.job.core.router.action;
2
+
3
+import com.xxl.job.core.log.XxlJobFileAppender;
4
+import com.xxl.job.core.router.IAction;
5
+import com.xxl.job.core.router.model.RequestModel;
6
+import com.xxl.job.core.router.model.ResponseModel;
7
+
8
+import java.util.Date;
9
+
10
+/**
11
+ * Created by xuxueli on 16/7/22.
12
+ */
13
+public class LogAction extends IAction {
14
+
15
+    @Override
16
+    public ResponseModel execute(RequestModel requestModel) {
17
+        String logConteng = XxlJobFileAppender.readLog(new Date(requestModel.getLogDateTim()), requestModel.getLogId());
18
+        return new ResponseModel(ResponseModel.SUCCESS, logConteng);
19
+    }
20
+
21
+}

+ 66 - 0
xxl-job-core/src/main/java/com/xxl/job/core/router/action/RunAction.java Visa fil

@@ -0,0 +1,66 @@
1
+package com.xxl.job.core.router.action;
2
+
3
+import com.xxl.job.core.handler.IJobHandler;
4
+import com.xxl.job.core.handler.impl.GlueJobHandler;
5
+import com.xxl.job.core.router.HandlerRouter;
6
+import com.xxl.job.core.router.IAction;
7
+import com.xxl.job.core.router.model.RequestModel;
8
+import com.xxl.job.core.router.model.ResponseModel;
9
+import com.xxl.job.core.router.thread.JobThread;
10
+
11
+/**
12
+ * Created by xuxueli on 16/7/22.
13
+ */
14
+public class RunAction extends IAction {
15
+
16
+    @Override
17
+    public ResponseModel execute(RequestModel requestModel) {
18
+
19
+        // generate jobKey
20
+        String jobKey = requestModel.getJobGroup().concat("_").concat(requestModel.getJobName());
21
+
22
+        // load old thread
23
+        JobThread jobThread = HandlerRouter.loadJobThread(jobKey);
24
+
25
+        if (!requestModel.isGlueSwitch()) {
26
+            // bean model
27
+
28
+            // handler instance
29
+            IJobHandler jobHandler = HandlerRouter.loadJobHandler(requestModel.getExecutorHandler());
30
+
31
+            if (jobThread == null) {
32
+                // jobhandler match
33
+                if (jobHandler==null) {
34
+                    return new ResponseModel(ResponseModel.FAIL, "job handler for jobKey=[" + jobKey + "] not found.");
35
+                }
36
+                jobThread = HandlerRouter.registJobThread(jobKey, jobHandler);
37
+            } else {
38
+
39
+                // job handler update, kill old job thread
40
+                if (jobThread.getHandler() != jobHandler) {
41
+
42
+                    // kill old job thread
43
+                    jobThread.toStop("人工手动终止");
44
+                    jobThread.interrupt();
45
+
46
+                    // new thread, with new job handler
47
+                    jobThread = HandlerRouter.registJobThread(jobKey, jobHandler);
48
+                }
49
+            }
50
+        } else {
51
+            // glue model
52
+
53
+            if (jobThread == null) {
54
+                jobThread = HandlerRouter.registJobThread(jobKey, new GlueJobHandler(requestModel.getJobGroup(), requestModel.getJobName()));
55
+            }
56
+        }
57
+
58
+        // sometime, cmap.get can not return given value, i do not know why
59
+        jobThread = HandlerRouter.loadJobThread(jobKey);
60
+
61
+        // push data to queue
62
+        jobThread.pushTriggerQueue(requestModel);
63
+        return new ResponseModel(ResponseModel.SUCCESS, null);
64
+    }
65
+
66
+}

+ 140 - 0
xxl-job-core/src/main/java/com/xxl/job/core/router/model/RequestModel.java Visa fil

@@ -0,0 +1,140 @@
1
+package com.xxl.job.core.router.model;
2
+
3
+/**
4
+ * Created by xuxueli on 16/7/22.
5
+ */
6
+public class RequestModel {
7
+
8
+    private long timestamp;
9
+    private String action;
10
+
11
+    private String jobGroup;
12
+    private String jobName;
13
+
14
+    private String executorHandler;
15
+    private String executorParams;
16
+
17
+    private boolean glueSwitch;
18
+
19
+    private String logAddress;
20
+    private int logId;
21
+    private long logDateTim;
22
+
23
+    private String status;
24
+    private String msg;
25
+
26
+    public long getTimestamp() {
27
+        return timestamp;
28
+    }
29
+
30
+    public void setTimestamp(long timestamp) {
31
+        this.timestamp = timestamp;
32
+    }
33
+
34
+    public String getAction() {
35
+        return action;
36
+    }
37
+
38
+    public void setAction(String action) {
39
+        this.action = action;
40
+    }
41
+
42
+    public String getJobGroup() {
43
+        return jobGroup;
44
+    }
45
+
46
+    public void setJobGroup(String jobGroup) {
47
+        this.jobGroup = jobGroup;
48
+    }
49
+
50
+    public String getJobName() {
51
+        return jobName;
52
+    }
53
+
54
+    public void setJobName(String jobName) {
55
+        this.jobName = jobName;
56
+    }
57
+
58
+    public String getExecutorHandler() {
59
+        return executorHandler;
60
+    }
61
+
62
+    public void setExecutorHandler(String executorHandler) {
63
+        this.executorHandler = executorHandler;
64
+    }
65
+
66
+    public String getExecutorParams() {
67
+        return executorParams;
68
+    }
69
+
70
+    public void setExecutorParams(String executorParams) {
71
+        this.executorParams = executorParams;
72
+    }
73
+
74
+    public boolean isGlueSwitch() {
75
+        return glueSwitch;
76
+    }
77
+
78
+    public void setGlueSwitch(boolean glueSwitch) {
79
+        this.glueSwitch = glueSwitch;
80
+    }
81
+
82
+    public String getLogAddress() {
83
+        return logAddress;
84
+    }
85
+
86
+    public void setLogAddress(String logAddress) {
87
+        this.logAddress = logAddress;
88
+    }
89
+
90
+    public int getLogId() {
91
+        return logId;
92
+    }
93
+
94
+    public void setLogId(int logId) {
95
+        this.logId = logId;
96
+    }
97
+
98
+    public long getLogDateTim() {
99
+        return logDateTim;
100
+    }
101
+
102
+    public void setLogDateTim(long logDateTim) {
103
+        this.logDateTim = logDateTim;
104
+    }
105
+
106
+    public String getStatus() {
107
+        return status;
108
+    }
109
+
110
+    public void setStatus(String status) {
111
+        this.status = status;
112
+    }
113
+
114
+    public String getMsg() {
115
+        return msg;
116
+    }
117
+
118
+    public void setMsg(String msg) {
119
+        this.msg = msg;
120
+    }
121
+
122
+    @Override
123
+    public String toString() {
124
+        return "RequestModel{" +
125
+                "timestamp=" + timestamp +
126
+                ", action='" + action + '\'' +
127
+                ", jobGroup='" + jobGroup + '\'' +
128
+                ", jobName='" + jobName + '\'' +
129
+                ", executorHandler='" + executorHandler + '\'' +
130
+                ", executorParams='" + executorParams + '\'' +
131
+                ", glueSwitch=" + glueSwitch +
132
+                ", logAddress='" + logAddress + '\'' +
133
+                ", logId=" + logId +
134
+                ", logDateTim=" + logDateTim +
135
+                ", status='" + status + '\'' +
136
+                ", msg='" + msg + '\'' +
137
+                '}';
138
+    }
139
+
140
+}

+ 45 - 0
xxl-job-core/src/main/java/com/xxl/job/core/router/model/ResponseModel.java Visa fil

@@ -0,0 +1,45 @@
1
+package com.xxl.job.core.router.model;
2
+
3
+/**
4
+ * Created by xuxueli on 16/7/22.
5
+ */
6
+public class ResponseModel {
7
+    public static final String SUCCESS = "SUCCESS";
8
+    public static final String FAIL = "FAIL";
9
+
10
+    private String status;
11
+    private String msg;
12
+
13
+    public ResponseModel() {
14
+    }
15
+
16
+    public ResponseModel(String status, String msg) {
17
+        this.status = status;
18
+        this.msg = msg;
19
+    }
20
+
21
+    public String getStatus() {
22
+        return status;
23
+    }
24
+
25
+    public void setStatus(String status) {
26
+        this.status = status;
27
+    }
28
+
29
+    public String getMsg() {
30
+        return msg;
31
+    }
32
+
33
+    public void setMsg(String msg) {
34
+        this.msg = msg;
35
+    }
36
+
37
+    @Override
38
+    public String toString() {
39
+        return "ResponseModel{" +
40
+                "status='" + status + '\'' +
41
+                ", msg='" + msg + '\'' +
42
+                '}';
43
+    }
44
+
45
+}

+ 128 - 0
xxl-job-core/src/main/java/com/xxl/job/core/router/thread/JobThread.java Visa fil

@@ -0,0 +1,128 @@
1
+package com.xxl.job.core.router.thread;
2
+
3
+import com.xxl.job.core.handler.IJobHandler;
4
+import com.xxl.job.core.handler.IJobHandler.JobHandleStatus;
5
+import com.xxl.job.core.log.XxlJobFileAppender;
6
+import com.xxl.job.core.router.model.RequestModel;
7
+import com.xxl.job.core.util.XxlJobNetCommUtil;
8
+import org.eclipse.jetty.util.ConcurrentHashSet;
9
+import org.slf4j.Logger;
10
+import org.slf4j.LoggerFactory;
11
+
12
+import java.io.PrintWriter;
13
+import java.io.StringWriter;
14
+import java.util.Arrays;
15
+import java.util.concurrent.LinkedBlockingQueue;
16
+import java.util.concurrent.TimeUnit;
17
+
18
+/**
19
+ * handler thread
20
+ * @author xuxueli 2016-1-16 19:52:47
21
+ */
22
+public class JobThread extends Thread{
23
+	private static Logger logger = LoggerFactory.getLogger(JobThread.class);
24
+	
25
+	private IJobHandler handler;
26
+	private LinkedBlockingQueue<RequestModel> triggerQueue;
27
+	private ConcurrentHashSet<Integer> triggerLogIdSet;		// avoid repeat trigger for the same TRIGGER_LOG_ID
28
+
29
+	private boolean toStop = false;
30
+	private String stopReason;
31
+
32
+	public JobThread(IJobHandler handler) {
33
+		this.handler = handler;
34
+		triggerQueue = new LinkedBlockingQueue<RequestModel>();
35
+		triggerLogIdSet = new ConcurrentHashSet<Integer>();
36
+	}
37
+	public IJobHandler getHandler() {
38
+		return handler;
39
+	}
40
+
41
+	public void pushTriggerQueue(RequestModel requestModel) {
42
+		if (triggerLogIdSet.contains(requestModel.getLogId())) {
43
+			logger.info("repeate trigger job, logId:{}", requestModel.getLogId());
44
+			return;
45
+		}
46
+
47
+		triggerLogIdSet.add(requestModel.getLogId());
48
+		triggerQueue.add(requestModel);
49
+	}
50
+
51
+	public void toStop(String stopReason) {
52
+		/**
53
+		 * Thread.interrupt只支持终止线程的阻塞状态(wait、join、sleep),
54
+		 * 在阻塞出抛出InterruptedException异常,但是并不会终止运行的线程本身;
55
+		 * 所以需要注意,此处彻底销毁本线程,需要通过共享变量方式;
56
+		 */
57
+		this.toStop = true;
58
+		this.stopReason = stopReason;
59
+	}
60
+	
61
+
62
+	
63
+	int i = 1;
64
+	@Override
65
+	public void run() {
66
+		while(!toStop){
67
+			try {
68
+				// to check toStop signal, we need cycle, so wo cannot use queue.take(), instand of poll(timeout)
69
+				RequestModel triggerDate = triggerQueue.poll(3L, TimeUnit.SECONDS);
70
+				if (triggerDate!=null) {
71
+					triggerLogIdSet.remove(triggerDate.getLogId());
72
+					
73
+					// parse param
74
+					String[] handlerParams = (triggerDate.getExecutorParams()!=null && triggerDate.getExecutorParams().trim().length()>0)
75
+							? (String[])(Arrays.asList(triggerDate.getExecutorParams().split(",")).toArray()) : null;
76
+					
77
+					// handle job
78
+					JobHandleStatus _status = JobHandleStatus.FAIL;
79
+					String _msg = null;
80
+
81
+					try {
82
+						XxlJobFileAppender.contextHolder.set(String.valueOf(triggerDate.getLogId()));
83
+						logger.info("----------- xxl-job job handle start -----------");
84
+						_status = handler.execute(handlerParams);
85
+					} catch (Exception e) {
86
+						logger.info("JobThread Exception:", e);
87
+						StringWriter out = new StringWriter();
88
+						e.printStackTrace(new PrintWriter(out));
89
+						_msg = out.toString();
90
+					}
91
+					logger.info("----------- xxl-job job handle end ----------- <br>: ExecutorParams:{}, Status:{}, Msg:{}",
92
+							new Object[]{handlerParams, _status, _msg});
93
+					
94
+					// callback handler info
95
+					if (!toStop) {
96
+						// commonm
97
+						triggerDate.setStatus(_status.name());
98
+						triggerDate.setMsg(_msg);
99
+						TriggerCallbackThread.pushCallBack(triggerDate);
100
+					} else {
101
+						// is killed
102
+						triggerDate.setStatus(JobHandleStatus.FAIL.name());
103
+						triggerDate.setMsg(stopReason + "人工手动终止[业务运行中,被强制终止]");
104
+						TriggerCallbackThread.pushCallBack(triggerDate);
105
+					}
106
+				}
107
+			} catch (Exception e) {
108
+				logger.info("JobThread Exception:", e);
109
+			}
110
+		}
111
+		
112
+		// callback trigger request in queue
113
+		while(triggerQueue !=null && triggerQueue.size()>0){
114
+			RequestModel triggerDate = triggerQueue.poll();
115
+			if (triggerDate!=null) {
116
+				// is killed
117
+				RequestModel callback = new RequestModel();
118
+				callback.setLogAddress(XxlJobNetCommUtil.addressToUrl(triggerDate.getLogAddress()));
119
+				callback.setLogId(triggerDate.getLogId());
120
+				callback.setStatus(JobHandleStatus.FAIL.name());
121
+				callback.setMsg(stopReason + "[任务尚未执行,在调度队列中被终止]");
122
+				TriggerCallbackThread.pushCallBack(callback);
123
+			}
124
+		}
125
+		
126
+		logger.info(">>>>>>>>>>>> xxl-job handlerThrad stoped, hashCode:{}", Thread.currentThread());
127
+	}
128
+}

+ 44 - 0
xxl-job-core/src/main/java/com/xxl/job/core/router/thread/TriggerCallbackThread.java Visa fil

@@ -0,0 +1,44 @@
1
+package com.xxl.job.core.router.thread;
2
+
3
+import com.xxl.job.core.router.model.RequestModel;
4
+import com.xxl.job.core.router.model.ResponseModel;
5
+import com.xxl.job.core.util.XxlJobNetCommUtil;
6
+import org.slf4j.Logger;
7
+import org.slf4j.LoggerFactory;
8
+
9
+import java.util.concurrent.LinkedBlockingQueue;
10
+
11
+/**
12
+ * Created by xuxueli on 16/7/22.
13
+ */
14
+public class TriggerCallbackThread {
15
+    private static Logger logger = LoggerFactory.getLogger(TriggerCallbackThread.class);
16
+
17
+    private static LinkedBlockingQueue<RequestModel> callBackQueue = new LinkedBlockingQueue<RequestModel>();
18
+    static {
19
+        new Thread(new Runnable() {
20
+            @Override
21
+            public void run() {
22
+                while(true){
23
+                    try {
24
+                        RequestModel callback = callBackQueue.take();
25
+                        if (callback != null) {
26
+                            try {
27
+                                ResponseModel responseModel = XxlJobNetCommUtil.postHex(XxlJobNetCommUtil.addressToUrl(callback.getLogAddress()), callback);
28
+                                logger.info(">>>>>>>>>>> xxl-job callback , RequestModel:{}, ResponseModel:{}", new Object[]{callback.toString(), responseModel.toString()});
29
+                            } catch (Exception e) {
30
+                                logger.info("JobThread Exception:", e);
31
+                            }
32
+                        }
33
+                    } catch (Exception e) {
34
+                        logger.error("", e);
35
+                    }
36
+                }
37
+            }
38
+        }).start();
39
+    }
40
+    public static void pushCallBack(RequestModel callback){
41
+        callBackQueue.add(callback);
42
+    }
43
+
44
+}

+ 59 - 0
xxl-job-core/src/main/java/com/xxl/job/core/util/ByteHexConverter.java Visa fil

@@ -0,0 +1,59 @@
1
+package com.xxl.job.core.util;
2
+
3
+import java.math.BigInteger;
4
+
5
+/**
6
+ * hex/byte util
7
+ * @author xuxueli 2015-11-14 22:47:28
8
+ */
9
+public class ByteHexConverter {
10
+	
11
+	/**
12
+	 * byte - to - radix, use BigInteger
13
+	 */
14
+	private static final String hex_tables = "0123456789ABCDEF";
15
+	public static String byte2hex (byte[] iBytes) {
16
+		StringBuilder hex = new StringBuilder(iBytes.length * 2);
17
+		for (int index = 0; index < iBytes.length; index++) {
18
+			hex.append(hex_tables.charAt((iBytes[index] & 0xf0) >> 4));
19
+			hex.append(hex_tables.charAt((iBytes[index] & 0x0f) >> 0));
20
+		}		
21
+		return hex.toString();
22
+	}
23
+	public static byte[] hex2Byte(String hexString) {
24
+		if (hexString == null || hexString.equals("")) {  
25
+	        return null;  
26
+	    }
27
+		byte[] res = new byte[hexString.length() / 2];
28
+		char[] chs = hexString.toCharArray();
29
+		for (int i = 0, c = 0; i < chs.length; i += 2, c++) {
30
+			res[c] = (byte) (Integer.parseInt(new String(chs, i, 2), 16));
31
+		}
32
+		return res;
33
+	}
34
+	
35
+	/**
36
+	 * byte - to - radix, use BigInteger
37
+	 */
38
+	public static final int HEX = 16;
39
+	public static String byte2radix(byte[] iBytes, int radix){
40
+		return new BigInteger(1, iBytes).toString(radix);
41
+	}
42
+	public static byte[] radix2byte(String val, int radix){
43
+		return new BigInteger(val, radix).toByteArray();
44
+	}
45
+	 
46
+	public static void main(String[] args) {
47
+		// hex - byte[] 方案A:位移
48
+		String temp = "1111111111113d1f3a51sd3f1a32sd1f32as1df2a13sd21f3a2s1df32a13sd2f123s2a3d13fa13sd9999999999";
49
+		System.out.println("明文:" + new String(temp.getBytes()));
50
+		System.out.println("编码:" + byte2hex(temp.getBytes()));
51
+		System.out.println("解码:" + new String(hex2Byte(byte2hex(temp.getBytes()))));
52
+		
53
+		// hex - byte[] 方案B:BigInteger
54
+		System.out.println("编码:" + byte2radix(temp.getBytes(), HEX));
55
+		System.out.println("解码:" + new String(radix2byte(byte2radix(temp.getBytes(), HEX), HEX)));
56
+
57
+	}
58
+	
59
+}

+ 0 - 130
xxl-job-core/src/main/java/com/xxl/job/core/util/HttpUtil.java Visa fil

@@ -1,130 +0,0 @@
1
-package com.xxl.job.core.util;
2
-
3
-import java.io.IOException;
4
-import java.util.ArrayList;
5
-import java.util.List;
6
-import java.util.Map;
7
-
8
-import org.apache.http.HttpEntity;
9
-import org.apache.http.HttpResponse;
10
-import org.apache.http.NameValuePair;
11
-import org.apache.http.client.config.RequestConfig;
12
-import org.apache.http.client.entity.UrlEncodedFormEntity;
13
-import org.apache.http.client.methods.HttpPost;
14
-import org.apache.http.impl.client.CloseableHttpClient;
15
-import org.apache.http.impl.client.HttpClients;
16
-import org.apache.http.message.BasicNameValuePair;
17
-import org.apache.http.util.EntityUtils;
18
-
19
-/**
20
- * http util to send data
21
- * @author xuxueli
22
- * @version  2015-11-28 15:30:59
23
- */
24
-public class HttpUtil {
25
-	
26
-	/**
27
-	 * http remote callback
28
-	 */
29
-	public static class RemoteCallBack{
30
-		public static final String SUCCESS = "SUCCESS";
31
-		public static final String FAIL = "FAIL";
32
-		
33
-		private String status;
34
-		private String msg;
35
-		public void setStatus(String status) {
36
-			this.status = status;
37
-		}
38
-		public String getStatus() {
39
-			return status;
40
-		}
41
-		public void setMsg(String msg) {
42
-			this.msg = msg;
43
-		}
44
-		public String getMsg() {
45
-			return msg;
46
-		}
47
-		
48
-		@Override
49
-		public String toString() {
50
-			return "RemoteCallBack [status=" + status + ", msg=" + msg + "]";
51
-		}
52
-		
53
-	}
54
-	
55
-	/**
56
-	 * http post request
57
-	 * @param reqURL
58
-	 * @param params
59
-	 * @return	[0]=responseMsg, [1]=exceptionMsg
60
-	 */
61
-	public static RemoteCallBack post(String reqURL, Map<String, String> params){
62
-		RemoteCallBack callback = new RemoteCallBack();
63
-		callback.setStatus(RemoteCallBack.FAIL);
64
-		
65
-		// do post
66
-		HttpPost httpPost = null;
67
-		CloseableHttpClient httpClient = null;
68
-		try{
69
-			httpPost = new HttpPost(reqURL);
70
-			if (params != null && !params.isEmpty()) {
71
-				List<NameValuePair> formParams = new ArrayList<NameValuePair>();
72
-				for(Map.Entry<String,String> entry : params.entrySet()){
73
-					formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
74
-				}
75
-				httpPost.setEntity(new UrlEncodedFormEntity(formParams, "UTF-8"));
76
-			}
77
-			RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(5000).setConnectTimeout(5000).build();
78
-			httpPost.setConfig(requestConfig);
79
-			
80
-			//httpClient = HttpClients.createDefault();	// default retry 3 times
81
-			httpClient = HttpClients.custom().disableAutomaticRetries().build();
82
-			
83
-			HttpResponse response = httpClient.execute(httpPost);
84
-			HttpEntity entity = response.getEntity();
85
-			if (response.getStatusLine().getStatusCode() == 200) {
86
-				if (null != entity) {
87
-					String responseMsg = EntityUtils.toString(entity, "UTF-8");
88
-					callback = JacksonUtil.readValue(responseMsg, RemoteCallBack.class);
89
-					if (callback == null) {
90
-						callback = new RemoteCallBack();
91
-						callback.setStatus(RemoteCallBack.FAIL);
92
-						callback.setMsg("responseMsg parse json fail, responseMsg:" + responseMsg);
93
-					}
94
-					EntityUtils.consume(entity);
95
-				}
96
-			} else {
97
-				callback.setMsg("http statusCode error, statusCode:" + response.getStatusLine().getStatusCode());
98
-			}
99
-		} catch (Exception e) {
100
-			e.printStackTrace();
101
-			/*StringWriter out = new StringWriter();
102
-			e.printStackTrace(new PrintWriter(out));
103
-			callback.setMsg(out.toString());*/
104
-			callback.setMsg(e.getMessage());
105
-		} finally{
106
-			if (httpPost!=null) {
107
-				httpPost.releaseConnection();
108
-			}
109
-			if (httpClient!=null) {
110
-				try {
111
-					httpClient.close();
112
-				} catch (IOException e) {
113
-					e.printStackTrace();
114
-				}
115
-			}
116
-		}
117
-		
118
-		return callback;
119
-	}
120
-	
121
-	/**
122
-	 * parse address ip:port to url http://.../ 
123
-	 * @param address
124
-	 * @return
125
-	 */
126
-	public static String addressToUrl(String address){
127
-		return "http://" + address + "/";
128
-	}
129
-	
130
-}

+ 141 - 0
xxl-job-core/src/main/java/com/xxl/job/core/util/XxlJobNetCommUtil.java Visa fil

@@ -0,0 +1,141 @@
1
+package com.xxl.job.core.util;
2
+
3
+import com.xxl.job.core.router.model.RequestModel;
4
+import com.xxl.job.core.router.model.ResponseModel;
5
+import org.apache.http.HttpEntity;
6
+import org.apache.http.HttpResponse;
7
+import org.apache.http.NameValuePair;
8
+import org.apache.http.client.config.RequestConfig;
9
+import org.apache.http.client.entity.UrlEncodedFormEntity;
10
+import org.apache.http.client.methods.HttpPost;
11
+import org.apache.http.impl.client.CloseableHttpClient;
12
+import org.apache.http.impl.client.HttpClients;
13
+import org.apache.http.message.BasicNameValuePair;
14
+import org.apache.http.util.EntityUtils;
15
+import org.slf4j.Logger;
16
+import org.slf4j.LoggerFactory;
17
+
18
+import java.io.IOException;
19
+import java.util.ArrayList;
20
+import java.util.List;
21
+
22
+/**
23
+ * http util to send data
24
+ * @author xuxueli
25
+ * @version  2015-11-28 15:30:59
26
+ */
27
+public class XxlJobNetCommUtil {
28
+	private static Logger logger = LoggerFactory.getLogger(XxlJobNetCommUtil.class);
29
+
30
+    // hex param key
31
+    public static final String HEX = "hex";
32
+
33
+    /**
34
+     * format object to hex-json
35
+     * @param obj
36
+     * @return
37
+     */
38
+    public static String formatObj2HexJson(Object obj){
39
+        String json = JacksonUtil.writeValueAsString(obj);
40
+        String hex = ByteHexConverter.byte2hex(json.getBytes());
41
+        return hex;
42
+    }
43
+
44
+    /**
45
+     * parse hex-json to object
46
+     * @param hex
47
+     * @param clazz
48
+     * @return
49
+     */
50
+    public static <T> T parseHexJson2Obj(String hex, Class<T> clazz){
51
+        String json = new String(ByteHexConverter.hex2Byte(hex));
52
+        T obj = JacksonUtil.readValue(json, clazz);
53
+        return obj;
54
+    }
55
+
56
+    public static void main(String[] args) {
57
+        System.out.println(parseHexJson2Obj("7B22737461747573223A2253554343455353222C226D7367223A2254696D657374616D702054696D656F75742E227D", ResponseModel.class));
58
+    }
59
+
60
+	/**
61
+	 * http post request
62
+	 * @param reqURL
63
+	 */
64
+	public static ResponseModel postHex(String reqURL, RequestModel requestModel){
65
+
66
+		// parse RequestModel to hex-json
67
+		String requestHex = XxlJobNetCommUtil.formatObj2HexJson(requestModel);
68
+
69
+        // msg
70
+		String failMsg = null;
71
+		
72
+		// do post
73
+		HttpPost httpPost = null;
74
+		CloseableHttpClient httpClient = null;
75
+		try{
76
+			httpPost = new HttpPost(reqURL);
77
+			List<NameValuePair> formParams = new ArrayList<NameValuePair>();
78
+			formParams.add(new BasicNameValuePair(XxlJobNetCommUtil.HEX, requestHex));
79
+			httpPost.setEntity(new UrlEncodedFormEntity(formParams, "UTF-8"));
80
+
81
+
82
+			RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(5000).setConnectTimeout(5000).build();
83
+			httpPost.setConfig(requestConfig);
84
+			
85
+			//httpClient = HttpClients.createDefault();	// default retry 3 times
86
+			httpClient = HttpClients.custom().disableAutomaticRetries().build();
87
+
88
+			HttpResponse response = httpClient.execute(httpPost);
89
+			HttpEntity entity = response.getEntity();
90
+			if (response.getStatusLine().getStatusCode() == 200 && null != entity) {
91
+                String responseHex = EntityUtils.toString(entity, "UTF-8");
92
+                EntityUtils.consume(entity);
93
+
94
+                // i do not know why
95
+                responseHex = responseHex.replace("\n", "");
96
+
97
+                // parse hex-json to ResponseModel
98
+                ResponseModel responseModel = XxlJobNetCommUtil.parseHexJson2Obj(responseHex, ResponseModel.class);
99
+
100
+                if (responseModel!=null) {
101
+                    return responseModel;
102
+                }
103
+			} else {
104
+				failMsg = "http statusCode error, statusCode:" + response.getStatusLine().getStatusCode();
105
+			}
106
+		} catch (Exception e) {
107
+            logger.info("", e);
108
+			/*StringWriter out = new StringWriter();
109
+			e.printStackTrace(new PrintWriter(out));
110
+			callback.setMsg(out.toString());*/
111
+			failMsg = e.getMessage();
112
+		} finally{
113
+			if (httpPost!=null) {
114
+				httpPost.releaseConnection();
115
+			}
116
+			if (httpClient!=null) {
117
+				try {
118
+					httpClient.close();
119
+				} catch (IOException e) {
120
+                    logger.info("", e);
121
+				}
122
+			}
123
+		}
124
+
125
+		// other, default fail
126
+		ResponseModel callback = new ResponseModel();
127
+		callback.setStatus(ResponseModel.FAIL);
128
+		callback.setMsg(failMsg);
129
+		return callback;
130
+	}
131
+	
132
+	/**
133
+	 * parse address ip:port to url http://.../ 
134
+	 * @param address
135
+	 * @return
136
+	 */
137
+	public static String addressToUrl(String address){
138
+		return "http://" + address + "/";
139
+	}
140
+	
141
+}