记录调度日志
This commit is contained in:
parent
abf21f1828
commit
87ce15368e
|
@ -27,3 +27,6 @@ git.osc地址:http://git.oschina.net/xuxueli0323/xxl-job
|
|||
|
||||
Tips:如果您追求一个简单调度服务,这里也提供了一个简洁分支[xxl-job-simple],它针对旧版调度框架做了细微完善;
|
||||
|
||||
# 其他说明
|
||||
清楚僵尸任务:qrtz_cron_triggers、qrtz_triggers、qrtz_job_details顺序删除
|
||||
|
|
@ -1 +1,2 @@
|
|||
/target/
|
||||
/.settings/
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
eclipse.preferences.version=1
|
||||
encoding//src/main/java=UTF8
|
||||
encoding//src/test/java=UTF8
|
||||
|
|
|
@ -1,27 +1,13 @@
|
|||
package com.xxl.job.controller;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.quartz.CronExpression;
|
||||
import org.quartz.Job;
|
||||
import org.quartz.SchedulerException;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import com.xxl.job.client.handler.HandlerRepository;
|
||||
import com.xxl.job.core.model.ReturnT;
|
||||
import com.xxl.job.core.util.DynamicSchedulerUtil;
|
||||
import com.xxl.job.service.job.HttpJobBean;
|
||||
|
||||
/**
|
||||
* index controller
|
||||
|
@ -30,7 +16,6 @@ import com.xxl.job.service.job.HttpJobBean;
|
|||
@Controller
|
||||
public class IndexController {
|
||||
|
||||
|
||||
@RequestMapping("")
|
||||
public String index(Model model) {
|
||||
List<Map<String, Object>> jobList = DynamicSchedulerUtil.getJobList();
|
||||
|
@ -43,138 +28,4 @@ public class IndexController {
|
|||
return "job/help";
|
||||
}
|
||||
|
||||
@RequestMapping("/job/add")
|
||||
@ResponseBody
|
||||
public ReturnT<String> add(HttpServletRequest request) {
|
||||
String triggerKeyName = null;
|
||||
String cronExpression = null;
|
||||
Map<String, Object> jobData = new HashMap<String, Object>();
|
||||
|
||||
try {
|
||||
request.setCharacterEncoding("utf-8");
|
||||
} catch (UnsupportedEncodingException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
Set<Map.Entry<String, String[]>> paramSet = request.getParameterMap().entrySet();
|
||||
for (Entry<String, String[]> param : paramSet) {
|
||||
if (param.getKey().equals("triggerKeyName")) {
|
||||
triggerKeyName = param.getValue()[0];
|
||||
} else if (param.getKey().equals("cronExpression")) {
|
||||
cronExpression = param.getValue()[0];
|
||||
} else {
|
||||
jobData.put(param.getKey(), param.getValue().length>0?param.getValue()[0]:param.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
// triggerKeyName
|
||||
if (StringUtils.isBlank(triggerKeyName)) {
|
||||
return new ReturnT<String>(500, "请输入“任务key”");
|
||||
}
|
||||
|
||||
// cronExpression
|
||||
if (StringUtils.isBlank(cronExpression)) {
|
||||
return new ReturnT<String>(500, "请输入“任务corn”");
|
||||
}
|
||||
if (!CronExpression.isValidExpression(cronExpression)) {
|
||||
return new ReturnT<String>(500, "“任务corn”不合法");
|
||||
}
|
||||
|
||||
// jobData
|
||||
if (jobData.get(DynamicSchedulerUtil.job_desc)==null || jobData.get(DynamicSchedulerUtil.job_desc).toString().trim().length()==0) {
|
||||
return new ReturnT<String>(500, "请输入“任务描述”");
|
||||
}
|
||||
if (jobData.get(DynamicSchedulerUtil.job_url)==null || jobData.get(DynamicSchedulerUtil.job_url).toString().trim().length()==0) {
|
||||
return new ReturnT<String>(500, "请输入“任务URL”");
|
||||
}
|
||||
if (jobData.get(HandlerRepository.handleName)==null || jobData.get(HandlerRepository.handleName).toString().trim().length()==0) {
|
||||
return new ReturnT<String>(500, "请输入“任务handler”");
|
||||
}
|
||||
|
||||
// jobClass
|
||||
Class<? extends Job> jobClass = HttpJobBean.class;
|
||||
|
||||
try {
|
||||
boolean result = DynamicSchedulerUtil.addJob(triggerKeyName, cronExpression, jobClass, jobData);
|
||||
if (!result) {
|
||||
return new ReturnT<String>(500, "任务ID重复,请更换确认");
|
||||
}
|
||||
return ReturnT.SUCCESS;
|
||||
} catch (SchedulerException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return ReturnT.FAIL;
|
||||
}
|
||||
|
||||
@RequestMapping("/job/reschedule")
|
||||
@ResponseBody
|
||||
public ReturnT<String> reschedule(String triggerKeyName, String cronExpression) {
|
||||
// triggerKeyName
|
||||
if (StringUtils.isBlank(triggerKeyName)) {
|
||||
return new ReturnT<String>(500, "请输入“任务key”");
|
||||
}
|
||||
// cronExpression
|
||||
if (StringUtils.isBlank(cronExpression)) {
|
||||
return new ReturnT<String>(500, "请输入“任务corn”");
|
||||
}
|
||||
if (!CronExpression.isValidExpression(cronExpression)) {
|
||||
return new ReturnT<String>(500, "“任务corn”不合法");
|
||||
}
|
||||
try {
|
||||
DynamicSchedulerUtil.rescheduleJob(triggerKeyName, cronExpression);
|
||||
return ReturnT.SUCCESS;
|
||||
} catch (SchedulerException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return ReturnT.FAIL;
|
||||
}
|
||||
|
||||
@RequestMapping("/job/remove")
|
||||
@ResponseBody
|
||||
public ReturnT<String> remove(String triggerKeyName) {
|
||||
try {
|
||||
DynamicSchedulerUtil.removeJob(triggerKeyName);
|
||||
return ReturnT.SUCCESS;
|
||||
} catch (SchedulerException e) {
|
||||
e.printStackTrace();
|
||||
return ReturnT.FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping("/job/pause")
|
||||
@ResponseBody
|
||||
public ReturnT<String> pause(String triggerKeyName) {
|
||||
try {
|
||||
DynamicSchedulerUtil.pauseJob(triggerKeyName);
|
||||
return ReturnT.SUCCESS;
|
||||
} catch (SchedulerException e) {
|
||||
e.printStackTrace();
|
||||
return ReturnT.FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping("/job/resume")
|
||||
@ResponseBody
|
||||
public ReturnT<String> resume(String triggerKeyName) {
|
||||
try {
|
||||
DynamicSchedulerUtil.resumeJob(triggerKeyName);
|
||||
return ReturnT.SUCCESS;
|
||||
} catch (SchedulerException e) {
|
||||
e.printStackTrace();
|
||||
return ReturnT.FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping("/job/trigger")
|
||||
@ResponseBody
|
||||
public ReturnT<String> triggerJob(String triggerKeyName) {
|
||||
try {
|
||||
DynamicSchedulerUtil.triggerJob(triggerKeyName);
|
||||
return ReturnT.SUCCESS;
|
||||
} catch (SchedulerException e) {
|
||||
e.printStackTrace();
|
||||
return ReturnT.FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,166 @@
|
|||
package com.xxl.job.controller;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.quartz.CronExpression;
|
||||
import org.quartz.Job;
|
||||
import org.quartz.SchedulerException;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import com.xxl.job.client.handler.HandlerRepository;
|
||||
import com.xxl.job.core.model.ReturnT;
|
||||
import com.xxl.job.core.util.DynamicSchedulerUtil;
|
||||
import com.xxl.job.service.job.HttpJobBean;
|
||||
|
||||
/**
|
||||
* index controller
|
||||
* @author xuxueli 2015-12-19 16:13:16
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/job")
|
||||
public class JobController {
|
||||
|
||||
@RequestMapping("/add")
|
||||
@ResponseBody
|
||||
public ReturnT<String> add(HttpServletRequest request) {
|
||||
String triggerKeyName = null;
|
||||
String cronExpression = null;
|
||||
Map<String, Object> jobData = new HashMap<String, Object>();
|
||||
|
||||
try {
|
||||
request.setCharacterEncoding("utf-8");
|
||||
} catch (UnsupportedEncodingException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
Set<Map.Entry<String, String[]>> paramSet = request.getParameterMap().entrySet();
|
||||
for (Entry<String, String[]> param : paramSet) {
|
||||
if (param.getKey().equals("triggerKeyName")) {
|
||||
triggerKeyName = param.getValue()[0];
|
||||
} else if (param.getKey().equals("cronExpression")) {
|
||||
cronExpression = param.getValue()[0];
|
||||
} else {
|
||||
jobData.put(param.getKey(), param.getValue().length>0?param.getValue()[0]:param.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
// triggerKeyName
|
||||
if (StringUtils.isBlank(triggerKeyName)) {
|
||||
return new ReturnT<String>(500, "请输入“任务key”");
|
||||
}
|
||||
|
||||
// cronExpression
|
||||
if (StringUtils.isBlank(cronExpression)) {
|
||||
return new ReturnT<String>(500, "请输入“任务corn”");
|
||||
}
|
||||
if (!CronExpression.isValidExpression(cronExpression)) {
|
||||
return new ReturnT<String>(500, "“任务corn”不合法");
|
||||
}
|
||||
|
||||
// jobData
|
||||
if (jobData.get(HandlerRepository.job_desc)==null || jobData.get(HandlerRepository.job_desc).toString().trim().length()==0) {
|
||||
return new ReturnT<String>(500, "请输入“任务描述”");
|
||||
}
|
||||
if (jobData.get(HandlerRepository.job_url)==null || jobData.get(HandlerRepository.job_url).toString().trim().length()==0) {
|
||||
return new ReturnT<String>(500, "请输入“任务URL”");
|
||||
}
|
||||
if (jobData.get(HandlerRepository.handleName)==null || jobData.get(HandlerRepository.handleName).toString().trim().length()==0) {
|
||||
return new ReturnT<String>(500, "请输入“任务handler”");
|
||||
}
|
||||
|
||||
// jobClass
|
||||
Class<? extends Job> jobClass = HttpJobBean.class;
|
||||
|
||||
try {
|
||||
boolean result = DynamicSchedulerUtil.addJob(triggerKeyName, cronExpression, jobClass, jobData);
|
||||
if (!result) {
|
||||
return new ReturnT<String>(500, "任务ID重复,请更换确认");
|
||||
}
|
||||
return ReturnT.SUCCESS;
|
||||
} catch (SchedulerException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return ReturnT.FAIL;
|
||||
}
|
||||
|
||||
@RequestMapping("/reschedule")
|
||||
@ResponseBody
|
||||
public ReturnT<String> reschedule(String triggerKeyName, String cronExpression) {
|
||||
// triggerKeyName
|
||||
if (StringUtils.isBlank(triggerKeyName)) {
|
||||
return new ReturnT<String>(500, "请输入“任务key”");
|
||||
}
|
||||
// cronExpression
|
||||
if (StringUtils.isBlank(cronExpression)) {
|
||||
return new ReturnT<String>(500, "请输入“任务corn”");
|
||||
}
|
||||
if (!CronExpression.isValidExpression(cronExpression)) {
|
||||
return new ReturnT<String>(500, "“任务corn”不合法");
|
||||
}
|
||||
try {
|
||||
DynamicSchedulerUtil.rescheduleJob(triggerKeyName, cronExpression);
|
||||
return ReturnT.SUCCESS;
|
||||
} catch (SchedulerException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return ReturnT.FAIL;
|
||||
}
|
||||
|
||||
@RequestMapping("/remove")
|
||||
@ResponseBody
|
||||
public ReturnT<String> remove(String triggerKeyName) {
|
||||
try {
|
||||
DynamicSchedulerUtil.removeJob(triggerKeyName);
|
||||
return ReturnT.SUCCESS;
|
||||
} catch (SchedulerException e) {
|
||||
e.printStackTrace();
|
||||
return ReturnT.FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping("/pause")
|
||||
@ResponseBody
|
||||
public ReturnT<String> pause(String triggerKeyName) {
|
||||
try {
|
||||
DynamicSchedulerUtil.pauseJob(triggerKeyName);
|
||||
return ReturnT.SUCCESS;
|
||||
} catch (SchedulerException e) {
|
||||
e.printStackTrace();
|
||||
return ReturnT.FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping("/resume")
|
||||
@ResponseBody
|
||||
public ReturnT<String> resume(String triggerKeyName) {
|
||||
try {
|
||||
DynamicSchedulerUtil.resumeJob(triggerKeyName);
|
||||
return ReturnT.SUCCESS;
|
||||
} catch (SchedulerException e) {
|
||||
e.printStackTrace();
|
||||
return ReturnT.FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping("/trigger")
|
||||
@ResponseBody
|
||||
public ReturnT<String> triggerJob(String triggerKeyName) {
|
||||
try {
|
||||
DynamicSchedulerUtil.triggerJob(triggerKeyName);
|
||||
return ReturnT.SUCCESS;
|
||||
} catch (SchedulerException e) {
|
||||
e.printStackTrace();
|
||||
return ReturnT.FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package com.xxl.job.controller;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import com.xxl.job.core.model.ReturnT;
|
||||
import com.xxl.job.core.model.XxlJobLog;
|
||||
import com.xxl.job.dao.IXxlJobLogDao;
|
||||
|
||||
/**
|
||||
* index controller
|
||||
* @author xuxueli 2015-12-19 16:13:16
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/joblog")
|
||||
public class JobLogController {
|
||||
|
||||
@Resource
|
||||
public IXxlJobLogDao xxlJobLogDao;
|
||||
|
||||
@RequestMapping("/save")
|
||||
@ResponseBody
|
||||
public ReturnT<String> triggerLog(int triggerLogId, String status, String msg) {
|
||||
XxlJobLog log = xxlJobLogDao.load(triggerLogId);
|
||||
if (log!=null) {
|
||||
log.setHandleTime(new Date());
|
||||
log.setHandleStatus(status);
|
||||
log.setHandleMsg(msg);
|
||||
xxlJobLogDao.updateHandleInfo(log);
|
||||
return ReturnT.SUCCESS;
|
||||
}
|
||||
return ReturnT.FAIL;
|
||||
}
|
||||
|
||||
}
|
|
@ -8,28 +8,52 @@ import java.util.Date;
|
|||
*/
|
||||
public class XxlJobLog {
|
||||
|
||||
private String jobTriggerUuid;
|
||||
private String jobHandleName;
|
||||
private int id;
|
||||
// job info
|
||||
private String jobName;
|
||||
private String jobCron;
|
||||
private String jobClass;
|
||||
private String jobData;
|
||||
|
||||
// trigger info
|
||||
private Date triggerTime;
|
||||
private String triggerStatus;
|
||||
private String triggerDetailLog;
|
||||
private String triggerMsg;
|
||||
|
||||
// handle info
|
||||
private Date handleTime;
|
||||
private String handleStatus;
|
||||
private String handleDetailLog;
|
||||
private String handleMsg;
|
||||
|
||||
public String getJobTriggerUuid() {
|
||||
return jobTriggerUuid;
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
public void setJobTriggerUuid(String jobTriggerUuid) {
|
||||
this.jobTriggerUuid = jobTriggerUuid;
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
public String getJobHandleName() {
|
||||
return jobHandleName;
|
||||
public String getJobName() {
|
||||
return jobName;
|
||||
}
|
||||
public void setJobHandleName(String jobHandleName) {
|
||||
this.jobHandleName = jobHandleName;
|
||||
public void setJobName(String jobName) {
|
||||
this.jobName = jobName;
|
||||
}
|
||||
public String getJobCron() {
|
||||
return jobCron;
|
||||
}
|
||||
public void setJobCron(String jobCron) {
|
||||
this.jobCron = jobCron;
|
||||
}
|
||||
public String getJobClass() {
|
||||
return jobClass;
|
||||
}
|
||||
public void setJobClass(String jobClass) {
|
||||
this.jobClass = jobClass;
|
||||
}
|
||||
public String getJobData() {
|
||||
return jobData;
|
||||
}
|
||||
public void setJobData(String jobData) {
|
||||
this.jobData = jobData;
|
||||
}
|
||||
public Date getTriggerTime() {
|
||||
return triggerTime;
|
||||
|
@ -43,11 +67,11 @@ public class XxlJobLog {
|
|||
public void setTriggerStatus(String triggerStatus) {
|
||||
this.triggerStatus = triggerStatus;
|
||||
}
|
||||
public String getTriggerDetailLog() {
|
||||
return triggerDetailLog;
|
||||
public String getTriggerMsg() {
|
||||
return triggerMsg;
|
||||
}
|
||||
public void setTriggerDetailLog(String triggerDetailLog) {
|
||||
this.triggerDetailLog = triggerDetailLog;
|
||||
public void setTriggerMsg(String triggerMsg) {
|
||||
this.triggerMsg = triggerMsg;
|
||||
}
|
||||
public Date getHandleTime() {
|
||||
return handleTime;
|
||||
|
@ -61,19 +85,19 @@ public class XxlJobLog {
|
|||
public void setHandleStatus(String handleStatus) {
|
||||
this.handleStatus = handleStatus;
|
||||
}
|
||||
public String getHandleDetailLog() {
|
||||
return handleDetailLog;
|
||||
public String getHandleMsg() {
|
||||
return handleMsg;
|
||||
}
|
||||
public void setHandleDetailLog(String handleDetailLog) {
|
||||
this.handleDetailLog = handleDetailLog;
|
||||
public void setHandleMsg(String handleMsg) {
|
||||
this.handleMsg = handleMsg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "XxlJobLog [jobTriggerUuid=" + jobTriggerUuid + ", jobHandleName=" + jobHandleName
|
||||
+ ", triggerTime=" + triggerTime + ", triggerStatus=" + triggerStatus + ", triggerDetailLog="
|
||||
+ triggerDetailLog + ", handleTime=" + handleTime + ", handleStatus=" + handleStatus
|
||||
+ ", handleDetailLog=" + handleDetailLog + "]";
|
||||
return "XxlJobLog [id=" + id + ", jobName=" + jobName + ", jobCron=" + jobCron + ", jobClass=" + jobClass
|
||||
+ ", jobData=" + jobData + ", triggerTime=" + triggerTime + ", triggerStatus=" + triggerStatus
|
||||
+ ", triggerMsg=" + triggerMsg + ", handleTime=" + handleTime + ", handleStatus=" + handleStatus
|
||||
+ ", handleMsg=" + handleMsg + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="XxlJobLogMapper">
|
||||
|
||||
<resultMap id="XxlJobLog" type="com.xxl.job.core.model.XxlJobLog" >
|
||||
<result column="id" property="id" />
|
||||
|
||||
<result column="job_name" property="jobName" />
|
||||
<result column="job_cron" property="jobCron" />
|
||||
<result column="job_class" property="jobClass" />
|
||||
<result column="job_data" property="jobData" />
|
||||
|
||||
<result column="trigger_time" property="triggerTime" />
|
||||
<result column="trigger_status" property="triggerStatus" />
|
||||
<result column="trigger_msg" property="triggerMsg" />
|
||||
|
||||
<result column="handle_time" property="handleTime" />
|
||||
<result column="handle_status" property="handleStatus" />
|
||||
<result column="handle_msg" property="handleMsg" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
t.id,
|
||||
t.job_name,
|
||||
t.job_cron,
|
||||
t.job_class,
|
||||
t.job_data,
|
||||
t.trigger_time,
|
||||
t.trigger_status,
|
||||
t.trigger_msg,
|
||||
t.handle_time,
|
||||
t.handle_status,
|
||||
t.handle_msg
|
||||
</sql>
|
||||
|
||||
<insert id="save" parameterType="com.xxl.job.core.model.XxlJobLog" useGeneratedKeys="true" keyProperty="id" >
|
||||
INSERT INTO `qrtz_trigger_log` (
|
||||
`job_name`,
|
||||
`job_cron`,
|
||||
`job_class`,
|
||||
`job_data`
|
||||
) VALUES (
|
||||
#{jobName},
|
||||
#{jobCron},
|
||||
#{jobClass},
|
||||
#{jobData}
|
||||
);
|
||||
<selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id">
|
||||
SELECT LAST_INSERT_ID()
|
||||
</selectKey>
|
||||
</insert>
|
||||
|
||||
<select id="load" parameterType="java.lang.Integer" resultMap="XxlJobLog">
|
||||
SELECT <include refid="Base_Column_List" />
|
||||
FROM qrtz_trigger_log AS t
|
||||
WHERE t.id = #{id}
|
||||
</select>
|
||||
|
||||
<update id="updateTriggerInfo">
|
||||
UPDATE `qrtz_trigger_log`
|
||||
SET
|
||||
`trigger_time`= #{triggerTime},
|
||||
`trigger_status`= #{triggerStatus},
|
||||
`trigger_msg`= #{triggerMsg}
|
||||
WHERE `id`= #{id}
|
||||
</update>
|
||||
|
||||
<update id="updateHandleInfo">
|
||||
UPDATE `qrtz_trigger_log`
|
||||
SET
|
||||
`handle_time`= #{handleTime},
|
||||
`handle_status`= #{handleStatus},
|
||||
`handle_msg`= #{handleMsg}
|
||||
WHERE `id`= #{id}
|
||||
</update>
|
||||
|
||||
<select id="pageList" parameterType="java.util.HashMap" resultMap="XxlJobLog">
|
||||
SELECT <include refid="Base_Column_List" />
|
||||
FROM qrtz_trigger_log AS t
|
||||
<if test="jobName != null and jobName!=''">
|
||||
WHERE t.job_name = #{jobName}
|
||||
</if>
|
||||
LIMIT #{offset}, #{pagesize}
|
||||
</select>
|
||||
|
||||
<select id="pageListCount" parameterType="java.util.HashMap" resultType="int">
|
||||
SELECT count(1)
|
||||
FROM qrtz_trigger_log AS t
|
||||
<if test="jobName != null and jobName!=''">
|
||||
WHERE t.job_name = #{jobName}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
</mapper>
|
|
@ -7,6 +7,8 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.quartz.CronScheduleBuilder;
|
||||
import org.quartz.CronTrigger;
|
||||
import org.quartz.Job;
|
||||
|
@ -26,6 +28,8 @@ import org.slf4j.LoggerFactory;
|
|||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.xxl.job.dao.IXxlJobLogDao;
|
||||
|
||||
/**
|
||||
* base quartz scheduler util
|
||||
* @author xuxueli 2015-12-19 16:13:53
|
||||
|
@ -33,6 +37,16 @@ import org.springframework.util.Assert;
|
|||
public final class DynamicSchedulerUtil implements InitializingBean {
|
||||
private static final Logger logger = LoggerFactory.getLogger(DynamicSchedulerUtil.class);
|
||||
|
||||
// xxlJobLogDao
|
||||
public static IXxlJobLogDao xxlJobLogDao;
|
||||
@Resource
|
||||
public void setXxlJobLogDao(IXxlJobLogDao xxlJobLogDao) {
|
||||
DynamicSchedulerUtil.xxlJobLogDao = xxlJobLogDao;
|
||||
}
|
||||
public static IXxlJobLogDao getXxlJobLogDao() {
|
||||
return xxlJobLogDao;
|
||||
}
|
||||
|
||||
// Scheduler
|
||||
private static Scheduler scheduler;
|
||||
public static void setScheduler(Scheduler scheduler) {
|
||||
|
@ -77,8 +91,6 @@ public final class DynamicSchedulerUtil implements InitializingBean {
|
|||
return jobList;
|
||||
}
|
||||
|
||||
public static final String job_desc = "job_desc";
|
||||
public static final String job_url = "job_url";
|
||||
// addJob 新增
|
||||
public static boolean addJob(String triggerKeyName, String cronExpression, Class<? extends Job> jobClass, Map<String, Object> jobData) throws SchedulerException {
|
||||
// TriggerKey : name + group
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
package com.xxl.job.core.util;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* properties util
|
||||
* @author xuxueli 2015-8-28 10:35:53
|
||||
*/
|
||||
public class PropertiesUtil {
|
||||
private static Logger logger = LoggerFactory.getLogger(PropertiesUtil.class);
|
||||
private static final String file_name = "config.properties";
|
||||
|
||||
/**
|
||||
* load properties
|
||||
* @param propertyFileName
|
||||
* @param ifClassPath
|
||||
* @return
|
||||
*/
|
||||
public static Properties loadProperties(String propertyFileName) {
|
||||
Properties prop = new Properties();
|
||||
InputStreamReader in = null;
|
||||
try {
|
||||
URL url = null;
|
||||
ClassLoader loder = Thread.currentThread().getContextClassLoader();
|
||||
url = loder.getResource(propertyFileName);
|
||||
in = new InputStreamReader(new FileInputStream(url.getPath()), "UTF-8");
|
||||
prop.load(in);
|
||||
} catch (IOException e) {
|
||||
logger.error("load {} error!", propertyFileName);
|
||||
} finally {
|
||||
if (in != null) {
|
||||
try {
|
||||
in.close();
|
||||
} catch (IOException e) {
|
||||
logger.error("close {} error!", propertyFileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
return prop;
|
||||
}
|
||||
|
||||
public static String getString(String key) {
|
||||
Properties prop = loadProperties(file_name);
|
||||
if (prop!=null) {
|
||||
return prop.getProperty(key);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(getString("triggerLogUrl"));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.xxl.job.dao;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.xxl.job.core.model.XxlJobLog;
|
||||
|
||||
public interface IXxlJobLogDao {
|
||||
|
||||
public int save(XxlJobLog xxlJobLog);
|
||||
|
||||
public XxlJobLog load(int id);
|
||||
|
||||
public int updateTriggerInfo(XxlJobLog xxlJobLog);
|
||||
|
||||
public int updateHandleInfo(XxlJobLog xxlJobLog);
|
||||
|
||||
public List<XxlJobLog> pageList(int offset, int pagesize,String jobName);
|
||||
|
||||
public int pageListCount(int offset, int pagesize,String jobName);
|
||||
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
package com.xxl.job.dao.impl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.mybatis.spring.SqlSessionTemplate;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import com.xxl.job.core.model.XxlJobLog;
|
||||
import com.xxl.job.dao.IXxlJobLogDao;
|
||||
|
||||
@Repository
|
||||
public class XxlJobLogDaoImpl implements IXxlJobLogDao {
|
||||
|
||||
@Resource
|
||||
public SqlSessionTemplate sqlSessionTemplate;
|
||||
|
||||
@Override
|
||||
public int save(XxlJobLog xxlJobLog) {
|
||||
return sqlSessionTemplate.insert("XxlJobLogMapper.save", xxlJobLog);
|
||||
}
|
||||
|
||||
@Override
|
||||
public XxlJobLog load(int id) {
|
||||
return sqlSessionTemplate.selectOne("XxlJobLogMapper.load", id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateTriggerInfo(XxlJobLog xxlJobLog) {
|
||||
return sqlSessionTemplate.update("XxlJobLogMapper.updateTriggerInfo", xxlJobLog);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateHandleInfo(XxlJobLog xxlJobLog) {
|
||||
return sqlSessionTemplate.update("XxlJobLogMapper.updateHandleInfo", xxlJobLog);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<XxlJobLog> pageList(int offset, int pagesize, String jobName) {
|
||||
HashMap<String, Object> params = new HashMap<String, Object>();
|
||||
params.put("offset", offset);
|
||||
params.put("pagesize", pagesize);
|
||||
params.put("jobName", jobName);
|
||||
return sqlSessionTemplate.selectList("XxlJobLogMapper.pageList", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int pageListCount(int offset, int pagesize, String jobName) {
|
||||
HashMap<String, Object> params = new HashMap<String, Object>();
|
||||
params.put("offset", offset);
|
||||
params.put("pagesize", pagesize);
|
||||
params.put("jobName", jobName);
|
||||
return sqlSessionTemplate.selectOne("XxlJobLogMapper.pageListCount", params);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
package com.xxl.job.service;
|
||||
|
||||
/**
|
||||
* local trigger, only exists in local jvm
|
||||
* @author xuxueli 2015-12-17 17:29:23
|
||||
*/
|
||||
public interface ITriggerService {
|
||||
|
||||
public void beat();
|
||||
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
package com.xxl.job.service.impl;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.xxl.job.service.ITriggerService;
|
||||
|
||||
/**
|
||||
* local trigger, only exists in local jvm
|
||||
* @author xuxueli 2015-12-17 17:31:24
|
||||
*/
|
||||
@Service("triggerService")
|
||||
public class TriggerServiceImpl implements ITriggerService {
|
||||
private static transient Logger logger = LoggerFactory.getLogger(TriggerServiceImpl.class);
|
||||
|
||||
public void beat() {
|
||||
logger.info(">>>>>>>>>>> xxl-job beat success.");
|
||||
}
|
||||
|
||||
}
|
|
@ -1,26 +1,11 @@
|
|||
package com.xxl.job.service.job;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.JobExecutionException;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -28,9 +13,11 @@ import org.slf4j.LoggerFactory;
|
|||
import org.springframework.scheduling.quartz.QuartzJobBean;
|
||||
|
||||
import com.xxl.job.client.handler.HandlerRepository;
|
||||
import com.xxl.job.client.handler.IJobHandler.JobTriggerStatus;
|
||||
import com.xxl.job.client.util.HttpUtil;
|
||||
import com.xxl.job.client.util.JacksonUtil;
|
||||
import com.xxl.job.core.model.XxlJobLog;
|
||||
import com.xxl.job.core.util.DynamicSchedulerUtil;
|
||||
import com.xxl.job.core.util.PropertiesUtil;
|
||||
|
||||
/**
|
||||
* http job bean
|
||||
|
@ -43,11 +30,9 @@ public class HttpJobBean extends QuartzJobBean {
|
|||
protected void executeInternal(JobExecutionContext context)
|
||||
throws JobExecutionException {
|
||||
|
||||
String triggerKey = context.getTrigger().getKey().getName();
|
||||
String triggerGroup = context.getTrigger().getKey().getGroup();
|
||||
Map<String, Object> jobDataMap = context.getMergedJobDataMap().getWrappedMap();
|
||||
|
||||
String triggerKey = context.getTrigger().getJobKey().getName();
|
||||
// jobDataMap 2 params
|
||||
Map<String, Object> jobDataMap = context.getMergedJobDataMap().getWrappedMap();
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
if (jobDataMap!=null && jobDataMap.size()>0) {
|
||||
for (Entry<String, Object> item : jobDataMap.entrySet()) {
|
||||
|
@ -55,83 +40,41 @@ public class HttpJobBean extends QuartzJobBean {
|
|||
}
|
||||
}
|
||||
|
||||
String job_url = params.get(DynamicSchedulerUtil.job_url);
|
||||
triggerPost(job_url, params);
|
||||
|
||||
logger.info(">>>>>>>>>>> xxl-job run :jobId:{}, group:{}, jobDataMap:{}",
|
||||
new Object[]{triggerKey, triggerGroup, jobDataMap});
|
||||
}
|
||||
|
||||
public static void triggerPost(String reqURL, Map<String, String> params){
|
||||
// save log
|
||||
XxlJobLog jobLog = new XxlJobLog();
|
||||
jobLog.setJobTriggerUuid(UUID.randomUUID().toString());
|
||||
jobLog.setJobHandleName(params.get(HandlerRepository.handleName));
|
||||
jobLog.setJobName(triggerKey);
|
||||
jobLog.setJobCron(null);
|
||||
jobLog.setJobClass(HttpJobBean.class.getName());
|
||||
jobLog.setJobData(JacksonUtil.writeValueAsString(params));
|
||||
DynamicSchedulerUtil.xxlJobLogDao.save(jobLog);
|
||||
logger.info(">>>>>>>>>>> xxl-job trigger start, jobLog:{}", jobLog);
|
||||
|
||||
// trigger request
|
||||
params.put(HandlerRepository.triggerLogId, String.valueOf(jobLog.getId()));
|
||||
params.put(HandlerRepository.triggerLogUrl, PropertiesUtil.getString(HandlerRepository.triggerLogUrl));
|
||||
String[] postResp = HttpUtil.post(params.get(HandlerRepository.job_url), params);
|
||||
logger.info(">>>>>>>>>>> xxl-job trigger http response, jobLog.id:{}, jobLog:{}", jobLog.getId(), jobLog);
|
||||
|
||||
// parse trigger response
|
||||
String responseMsg = postResp[0];
|
||||
String exceptionMsg = postResp[1];
|
||||
|
||||
jobLog.setTriggerTime(new Date());
|
||||
logger.info(">>>>>>>>>>> xxl-job trigger start :jobLog:{}", jobLog);
|
||||
|
||||
// post
|
||||
String responseContent = null;
|
||||
HttpPost httpPost = new HttpPost(reqURL);
|
||||
CloseableHttpClient httpClient = HttpClients.createDefault();
|
||||
try{
|
||||
if (params != null && !params.isEmpty()) {
|
||||
List<NameValuePair> formParams = new ArrayList<NameValuePair>();
|
||||
for(Map.Entry<String,String> entry : params.entrySet()){
|
||||
formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
|
||||
}
|
||||
httpPost.setEntity(new UrlEncodedFormEntity(formParams, "UTF-8"));
|
||||
jobLog.setTriggerStatus(HttpUtil.FAIL);
|
||||
jobLog.setTriggerMsg(exceptionMsg);
|
||||
if (StringUtils.isNotBlank(responseMsg)) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, String> responseMap = JacksonUtil.readValue(responseMsg, Map.class);
|
||||
if (responseMap!=null && StringUtils.isNotBlank(responseMap.get(HttpUtil.status))) {
|
||||
jobLog.setTriggerStatus(responseMap.get(HttpUtil.status));
|
||||
jobLog.setTriggerMsg(responseMap.get(HttpUtil.msg));
|
||||
}
|
||||
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(5000).setConnectTimeout(5000).build();
|
||||
httpPost.setConfig(requestConfig);
|
||||
|
||||
HttpResponse response = httpClient.execute(httpPost);
|
||||
HttpEntity entity = response.getEntity();
|
||||
if (null != entity) {
|
||||
responseContent = EntityUtils.toString(entity, "UTF-8");
|
||||
EntityUtils.consume(entity);
|
||||
}
|
||||
logger.info(">>>>>>>>>>> xxl-job trigger ing :jobLog:{}, response:{}, responseContent:{}", jobLog, response, responseContent);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
||||
StringWriter out = new StringWriter();
|
||||
e.printStackTrace(new PrintWriter(out));
|
||||
responseContent = out.toString();
|
||||
} finally{
|
||||
httpPost.releaseConnection();
|
||||
try {
|
||||
httpClient.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// update trigger status
|
||||
if (responseContent!=null && responseContent.equals(JobTriggerStatus.SUCCESS.name())) {
|
||||
jobLog.setTriggerStatus(JobTriggerStatus.SUCCESS.name());
|
||||
} else {
|
||||
jobLog.setTriggerStatus(JobTriggerStatus.FAIL.name());
|
||||
}
|
||||
jobLog.setTriggerDetailLog(responseContent);
|
||||
if (jobLog.getTriggerDetailLog()!=null && jobLog.getTriggerDetailLog().length()>1000) {
|
||||
jobLog.setTriggerDetailLog(jobLog.getTriggerDetailLog().substring(0, 1000));
|
||||
}
|
||||
|
||||
logger.info(">>>>>>>>>>> xxl-job trigger end :jobLog:{}", jobLog);
|
||||
}
|
||||
|
||||
}
|
||||
// update trigger info
|
||||
DynamicSchedulerUtil.xxlJobLogDao.updateTriggerInfo(jobLog);
|
||||
logger.info(">>>>>>>>>>> xxl-job trigger end, jobLog.id:{}, jobLog:{}", jobLog.getId(), jobLog);
|
||||
|
||||
public static void main(String[] args) {
|
||||
String url = "http://localhost:8080/xxl-job-client-demo/xxlJobServlet";
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put(HandlerRepository.handleName, "com.xxl.job.service.handler.DemoJobHandler");
|
||||
params.put(HandlerRepository.triggerUuid, i+"");
|
||||
params.put("key", i+"");
|
||||
|
||||
triggerPost(url, params);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,7 +10,7 @@
|
|||
http://www.springframework.org/schema/util/spring-util.xsd">
|
||||
|
||||
<context:annotation-config />
|
||||
<context:component-scan base-package="com.xxl.job.service" />
|
||||
<context:component-scan base-package="com.xxl.job.service, com.xxl.job.dao" />
|
||||
|
||||
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
|
||||
<property name="templateLoaderPath" value="/WEB-INF/template/" />
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
|
||||
<property name="dataSource" ref="dataSource" />
|
||||
<property name="mapperLocations" value="classpath*:com/xxl/core/model/mapper/*.xml"/>
|
||||
<property name="mapperLocations" value="classpath*:com/xxl/job/core/model/mapper/*.xml"/>
|
||||
</bean>
|
||||
|
||||
<!-- scope must be "prototype" when junit -->
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://www.springframework.org/schema/context
|
||||
http://www.springframework.org/schema/context/spring-context-3.0.xsd
|
||||
http://www.springframework.org/schema/util
|
||||
http://www.springframework.org/schema/util/spring-util.xsd">
|
||||
|
||||
<bean id="beatJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
|
||||
<property name="targetObject" ref="triggerService" />
|
||||
<property name="targetMethod" value="beat" />
|
||||
<property name="concurrent" value="false" />
|
||||
</bean>
|
||||
|
||||
<bean id="beatTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
|
||||
<property name="jobDetail" ref="beatJobDetail" />
|
||||
<property name="cronExpression" value="0/10 * * * * ? *" />
|
||||
</bean>
|
||||
|
||||
<!-- 进程-调度器 -->
|
||||
<bean name="jvmQuertz" lazy-init="false" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
|
||||
<property name="triggers">
|
||||
<list>
|
||||
<!-- <ref bean="beatTrigger" /> -->
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
</beans>
|
|
@ -0,0 +1 @@
|
|||
triggerLogUrl=http://localhost:8080/xxl-job-admin/joblog/save
|
|
@ -0,0 +1,67 @@
|
|||
package com.xxl.job.dao.impl;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.xxl.job.client.handler.IJobHandler;
|
||||
import com.xxl.job.client.util.HttpUtil;
|
||||
import com.xxl.job.core.model.XxlJobLog;
|
||||
import com.xxl.job.dao.IXxlJobLogDao;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations = "classpath*:applicationcontext-*.xml")
|
||||
public class XxlJobLogTest {
|
||||
|
||||
@Resource
|
||||
private IXxlJobLogDao xxlJobLogDao;
|
||||
|
||||
@Test
|
||||
public void save_load(){
|
||||
XxlJobLog xxlJobLog = new XxlJobLog();
|
||||
xxlJobLog.setJobName("job_name");
|
||||
xxlJobLog.setJobCron("jobCron");
|
||||
xxlJobLog.setJobClass("jobClass");
|
||||
xxlJobLog.setJobData("jobData");
|
||||
int count = xxlJobLogDao.save(xxlJobLog);
|
||||
System.out.println(count);
|
||||
System.out.println(xxlJobLog.getId());
|
||||
|
||||
XxlJobLog item = xxlJobLogDao.load(xxlJobLog.getId());
|
||||
System.out.println(item);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateTriggerInfo(){
|
||||
XxlJobLog xxlJobLog = xxlJobLogDao.load(29);
|
||||
xxlJobLog.setTriggerTime(new Date());
|
||||
xxlJobLog.setTriggerStatus(HttpUtil.SUCCESS);
|
||||
xxlJobLog.setTriggerMsg("trigger msg");
|
||||
xxlJobLogDao.updateTriggerInfo(xxlJobLog);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateHandleInfo(){
|
||||
XxlJobLog xxlJobLog = xxlJobLogDao.load(29);
|
||||
xxlJobLog.setHandleTime(new Date());
|
||||
xxlJobLog.setHandleStatus(IJobHandler.JobHandleStatus.SUCCESS.name());
|
||||
xxlJobLog.setHandleMsg("handle msg");
|
||||
xxlJobLogDao.updateHandleInfo(xxlJobLog);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pageList(){
|
||||
List<XxlJobLog> list = xxlJobLogDao.pageList(0, 20, null);
|
||||
int list_count = xxlJobLogDao.pageListCount(0, 20, null);
|
||||
|
||||
System.out.println(list);
|
||||
System.out.println(list_count);
|
||||
}
|
||||
|
||||
}
|
|
@ -2,6 +2,7 @@ package com.xxl.job.client.handler;
|
|||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
@ -11,7 +12,8 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.xxl.job.client.handler.IJobHandler.JobHandleStatus;
|
||||
import com.xxl.job.client.handler.IJobHandler.JobTriggerStatus;
|
||||
import com.xxl.job.client.util.HttpUtil;
|
||||
import com.xxl.job.client.util.JacksonUtil;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -21,8 +23,11 @@ import com.xxl.job.client.handler.IJobHandler.JobTriggerStatus;
|
|||
public class HandlerRepository {
|
||||
private static Logger logger = LoggerFactory.getLogger(HandlerRepository.class);
|
||||
|
||||
public static final String triggerUuid = "triggerUuid";
|
||||
public static final String job_desc = "job_desc";
|
||||
public static final String job_url = "job_url";
|
||||
public static final String handleName = "handleName";
|
||||
public static final String triggerLogId = "triggerLogId";
|
||||
public static final String triggerLogUrl = "triggerLogUrl";
|
||||
|
||||
// handler class map
|
||||
private static ConcurrentHashMap<String, IJobHandler> handlerClassMap = new ConcurrentHashMap<String, IJobHandler>();
|
||||
|
@ -57,23 +62,36 @@ public class HandlerRepository {
|
|||
public void run() {
|
||||
while (isValid) {
|
||||
LinkedBlockingQueue<Map<String, String>> handlerDateQueue = handlerDataQueueMap.get(_handleName);
|
||||
Map<String, String> handlerDate = handlerDateQueue.poll();
|
||||
if (handlerDate!=null) {
|
||||
JobHandleStatus jobHandleStatus = null;
|
||||
String jobHandleDetail = null;
|
||||
Map<String, String> handlerData = handlerDateQueue.poll();
|
||||
if (handlerData!=null) {
|
||||
// handle job
|
||||
JobHandleStatus _status = JobHandleStatus.FAIL;
|
||||
String _msg = null;
|
||||
try {
|
||||
IJobHandler handler = handlerClassMap.get(_handleName);
|
||||
jobHandleStatus = handler.handle(handlerDate);
|
||||
_status = handler.handle(handlerData);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
jobHandleStatus = JobHandleStatus.FAIL;
|
||||
_status = JobHandleStatus.FAIL;
|
||||
StringWriter out = new StringWriter();
|
||||
e.printStackTrace(new PrintWriter(out));
|
||||
jobHandleDetail = out.toString();
|
||||
_msg = out.toString();
|
||||
}
|
||||
String _triggerUuid = handlerDate.get(triggerUuid);
|
||||
logger.info("<<<<<<<<<<< xxl-job thread handle, _triggerUuid:{}, _handleName:{}, jobHandleStatus:{}, jobHandleDetail:{}, thread:{}",
|
||||
new Object[]{_triggerUuid, _handleName, jobHandleStatus, jobHandleDetail, this});
|
||||
|
||||
// callback handler info
|
||||
String callback_response[] = null;
|
||||
try {
|
||||
String _triggerLogUrl = handlerData.get(HandlerRepository.triggerLogUrl);
|
||||
HashMap<String, String> params = new HashMap<String, String>();
|
||||
params.put(HandlerRepository.triggerLogId, handlerData.get(HandlerRepository.triggerLogId));
|
||||
params.put(HttpUtil.status, _status.name());
|
||||
params.put(HttpUtil.msg, _msg);
|
||||
callback_response = HttpUtil.post(_triggerLogUrl, params);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
logger.info("<<<<<<<<<<< xxl-job thread handle, handlerData:{}, callback_status:{}, callback_msg:{}, callback_response:{}, thread:{}",
|
||||
new Object[]{handlerData, _status, _msg, callback_response, this});
|
||||
} else {
|
||||
try {
|
||||
TimeUnit.SECONDS.sleep(3);
|
||||
|
@ -86,51 +104,56 @@ public class HandlerRepository {
|
|||
}
|
||||
|
||||
// handler push to queue
|
||||
public static String pushHandleQueue(String triggerUuid, String handleName, Map<String, String> _param) {
|
||||
JobTriggerStatus _triggerStatus = JobTriggerStatus.FAIL;
|
||||
String _triggerDetailLog = null;
|
||||
public static String pushHandleQueue(Map<String, String> _param) {
|
||||
|
||||
// resuolt
|
||||
String _status = HttpUtil.FAIL;
|
||||
String _msg = "";
|
||||
// push data to queue
|
||||
String _handleName = _param.get(HandlerRepository.handleName);
|
||||
int _triggerLogId = Integer.valueOf(_param.get(HandlerRepository.triggerLogId));
|
||||
try {
|
||||
if (handleName!=null && handleName.trim().length()>0) {
|
||||
IJobHandler handler = handlerClassMap.get(handleName);
|
||||
if (_handleName!=null && _handleName.trim().length()>0) {
|
||||
IJobHandler handler = handlerClassMap.get(_handleName);
|
||||
if (handler != null) {
|
||||
// push data to handler queue
|
||||
LinkedBlockingQueue<Map<String, String>> handlerDateQueue = handlerDataQueueMap.get(handleName);
|
||||
LinkedBlockingQueue<Map<String, String>> handlerDateQueue = handlerDataQueueMap.get(_handleName);
|
||||
if (handlerDateQueue == null) {
|
||||
handlerDateQueue = new LinkedBlockingQueue<Map<String, String>>();
|
||||
handlerDataQueueMap.put(handleName, handlerDateQueue);
|
||||
logger.info(">>>>>>>>>>> xxl-job handler lazy fresh handlerDateQueue, handleName:{}, handler:{}, handlerDateQueue:{}",
|
||||
new Object[]{handleName, handler, handlerDateQueue});
|
||||
handlerDataQueueMap.put(_handleName, handlerDateQueue);
|
||||
logger.info(">>>>>>>>>>> xxl-job handler lazy fresh handlerDateQueue, _handleName:{}, handler:{}, handlerDateQueue:{}",
|
||||
new Object[]{_handleName, handler, handlerDateQueue});
|
||||
}
|
||||
handlerDateQueue.offer(_param);
|
||||
// check handler thread
|
||||
HandlerThread handlerThreadOld = handlerTreadMap.get(handleName);
|
||||
HandlerThread handlerThreadOld = handlerTreadMap.get(_handleName);
|
||||
if (!handlerThreadOld.isAlive()) {
|
||||
handlerThreadOld.stopThread();
|
||||
HandlerThread handlerThread = new HandlerThread(handleName);
|
||||
HandlerThread handlerThread = new HandlerThread(_handleName);
|
||||
handlerThread.start();
|
||||
handlerTreadMap.put(handleName, handlerThread);
|
||||
logger.info(">>>>>>>>>>> xxl-job handler lazy fresh thread, handleName:{}, handler:{}, handlerThread:{}",
|
||||
new Object[]{handleName, handler, handlerThread});
|
||||
handlerTreadMap.put(_handleName, handlerThread);
|
||||
logger.info(">>>>>>>>>>> xxl-job handler lazy fresh thread, _handleName:{}, handler:{}, handlerThread:{}",
|
||||
new Object[]{_handleName, handler, handlerThread});
|
||||
}
|
||||
_triggerStatus = JobTriggerStatus.SUCCESS;
|
||||
// push to queue
|
||||
handlerDateQueue.offer(_param);
|
||||
_status = HttpUtil.SUCCESS;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
_triggerStatus = JobTriggerStatus.FAIL;
|
||||
StringWriter out = new StringWriter();
|
||||
e.printStackTrace(new PrintWriter(out));
|
||||
_triggerDetailLog = out.toString();
|
||||
_status = HttpUtil.FAIL;
|
||||
_msg = out.toString();
|
||||
}
|
||||
logger.info(">>>>>>>>>>> xxl-job pushHandleQueue, triggerUuid:{}, handleName, _triggerStatus:{}, _triggerDetailLog",
|
||||
new Object[]{triggerUuid, handleName, _triggerStatus, _triggerDetailLog});
|
||||
logger.info(">>>>>>>>>>> xxl-job pushHandleQueue, _handleName:{}, _triggerLogId:{}, _param:{}, _status:{}, _msg:{}",
|
||||
new Object[]{_handleName, _triggerLogId, _param, _status, _msg});
|
||||
|
||||
HashMap<String, String> triggerData = new HashMap<String, String>();
|
||||
triggerData.put(HttpUtil.status, _status);
|
||||
triggerData.put(HttpUtil.msg, _msg);
|
||||
return JacksonUtil.writeValueAsString(triggerData);
|
||||
|
||||
String responseBody = _triggerStatus.name();
|
||||
if (JobTriggerStatus.SUCCESS != _triggerStatus) {
|
||||
responseBody += "#" + _triggerDetailLog;
|
||||
}
|
||||
return responseBody;
|
||||
/**
|
||||
* trigger-log :
|
||||
* trigger side : store trigger-info >> trigger request >> update trigger-response-status
|
||||
|
|
|
@ -32,15 +32,4 @@ public abstract class IJobHandler extends HandlerRepository{
|
|||
NOT_FOUND;
|
||||
}
|
||||
|
||||
public enum JobTriggerStatus{
|
||||
/**
|
||||
* trigger success
|
||||
*/
|
||||
SUCCESS,
|
||||
/**
|
||||
* trigger fail
|
||||
*/
|
||||
FAIL;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -43,10 +43,8 @@ public class XxlJobServlet extends HttpServlet {
|
|||
}
|
||||
}
|
||||
}
|
||||
String _triggerUuid = _param.get(HandlerRepository.triggerUuid);
|
||||
String _handleName = _param.get(HandlerRepository.handleName);
|
||||
|
||||
String resp = HandlerRepository.pushHandleQueue(_triggerUuid, _handleName, _param);
|
||||
String resp = HandlerRepository.pushHandleQueue(_param);
|
||||
response.getWriter().append(resp);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,59 +1,84 @@
|
|||
package com.xxl.job.client.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.NameValuePair;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.message.BasicNameValuePair;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
|
||||
/**
|
||||
* http util to send hex data
|
||||
* http util to send data
|
||||
* @author xuxueli
|
||||
* @version 2015-11-28 15:30:59
|
||||
*/
|
||||
public class HttpUtil {
|
||||
|
||||
public static String sendHex(String reqURL, String queryString) {
|
||||
// response param
|
||||
public static final String status = "status";
|
||||
public static final String msg = "msg";
|
||||
// response status enum
|
||||
public static final String SUCCESS = "SUCCESS";
|
||||
public static final String FAIL = "FAIL";
|
||||
|
||||
String responseContent = null;
|
||||
if (queryString != null && !queryString.equals("")) {
|
||||
reqURL = reqURL + "?data=" + queryString;
|
||||
}
|
||||
/**
|
||||
* http post request
|
||||
* @param reqURL
|
||||
* @param params
|
||||
* @return [0]=responseMsg, [1]=exceptionMsg
|
||||
*/
|
||||
public static String[] post(String reqURL, Map<String, String> params){
|
||||
String responseMsg = null;
|
||||
String exceptionMsg = null;
|
||||
|
||||
HttpGet httpGet = new HttpGet(reqURL);
|
||||
// do post
|
||||
HttpPost httpPost = new HttpPost(reqURL);
|
||||
CloseableHttpClient httpClient = HttpClients.createDefault();
|
||||
try {
|
||||
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(3000).setConnectTimeout(3000).build();
|
||||
httpGet.setConfig(requestConfig);
|
||||
|
||||
HttpResponse response = httpClient.execute(httpGet);
|
||||
try{
|
||||
if (params != null && !params.isEmpty()) {
|
||||
List<NameValuePair> formParams = new ArrayList<NameValuePair>();
|
||||
for(Map.Entry<String,String> entry : params.entrySet()){
|
||||
formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
|
||||
}
|
||||
httpPost.setEntity(new UrlEncodedFormEntity(formParams, "UTF-8"));
|
||||
}
|
||||
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(5000).setConnectTimeout(5000).build();
|
||||
httpPost.setConfig(requestConfig);
|
||||
|
||||
HttpResponse response = httpClient.execute(httpPost);
|
||||
HttpEntity entity = response.getEntity();
|
||||
if (null != entity) {
|
||||
responseContent = EntityUtils.toString(entity, "UTF-8");
|
||||
responseMsg = EntityUtils.toString(entity, "UTF-8");
|
||||
EntityUtils.consume(entity);
|
||||
if (responseContent!=null) {
|
||||
responseContent = responseContent.trim();
|
||||
}
|
||||
}
|
||||
} catch (ClientProtocolException e) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
httpGet.releaseConnection();
|
||||
StringWriter out = new StringWriter();
|
||||
e.printStackTrace(new PrintWriter(out));
|
||||
exceptionMsg = out.toString();
|
||||
} finally{
|
||||
httpPost.releaseConnection();
|
||||
try {
|
||||
httpClient.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return responseContent;
|
||||
}
|
||||
|
||||
String[] result = new String[2];
|
||||
result[0] = responseMsg;
|
||||
result[1] = exceptionMsg;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
package com.xxl.job.client.util;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.codehaus.jackson.JsonGenerationException;
|
||||
import org.codehaus.jackson.JsonParseException;
|
||||
import org.codehaus.jackson.map.JsonMappingException;
|
||||
import org.codehaus.jackson.map.ObjectMapper;
|
||||
import org.codehaus.jackson.type.TypeReference;
|
||||
|
||||
/**
|
||||
* Jackson util
|
||||
*
|
||||
* 1、obj need private and set/get;
|
||||
* 2、do not support inner class;
|
||||
*
|
||||
* @author xuxueli 2015-9-25 18:02:56
|
||||
*/
|
||||
public class JacksonUtil {
|
||||
private final static ObjectMapper objectMapper = new ObjectMapper();
|
||||
public static ObjectMapper getInstance() {
|
||||
return objectMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* bean、array、List、Map --> json
|
||||
*
|
||||
* @param obj
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String writeValueAsString(Object obj) {
|
||||
try {
|
||||
return getInstance().writeValueAsString(obj);
|
||||
} catch (JsonGenerationException e) {
|
||||
e.printStackTrace();
|
||||
} catch (JsonMappingException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* string --> bean、Map、List(array)
|
||||
*
|
||||
* @param jsonStr
|
||||
* @param clazz
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static <T> T readValue(String jsonStr, Class<T> clazz) {
|
||||
try {
|
||||
return getInstance().readValue(jsonStr, clazz);
|
||||
} catch (JsonParseException e) {
|
||||
e.printStackTrace();
|
||||
} catch (JsonMappingException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public static <T> T readValueRefer(String jsonStr, Class<T> clazz) {
|
||||
try {
|
||||
return getInstance().readValue(jsonStr, new TypeReference<T>() { });
|
||||
} catch (JsonParseException e) {
|
||||
e.printStackTrace();
|
||||
} catch (JsonMappingException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
map.put("aaa", "111");
|
||||
map.put("bbb", "222");
|
||||
String json = writeValueAsString(map);
|
||||
System.out.println(json);
|
||||
System.out.println(readValue(json, Map.class));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue