This commit is contained in:
xueli.xue 2016-07-21 22:27:49 +08:00
parent 9591be6b13
commit 1e0ba18606
12 changed files with 215 additions and 184 deletions

View File

@ -156,6 +156,7 @@ CREATE TABLE `XXL_JOB_QRTZ_TRIGGER_INFO` (
`author` varchar(64) DEFAULT NULL COMMENT '作者', `author` varchar(64) DEFAULT NULL COMMENT '作者',
`alarm_email` varchar(255) DEFAULT NULL COMMENT '报警邮件', `alarm_email` varchar(255) DEFAULT NULL COMMENT '报警邮件',
`executor_address` varchar(255) DEFAULT NULL COMMENT '执行器地址,有多个则逗号分隔', `executor_address` varchar(255) DEFAULT NULL COMMENT '执行器地址,有多个则逗号分隔',
`executor_handler` varchar(255) DEFAULT NULL COMMENT '执行器任务handler',
`executor_param` varchar(255) DEFAULT NULL COMMENT '执行器任务参数', `executor_param` varchar(255) DEFAULT NULL COMMENT '执行器任务参数',
`glue_switch` int(11) DEFAULT '0' COMMENT 'GLUE模式开关0-否1-是', `glue_switch` int(11) DEFAULT '0' COMMENT 'GLUE模式开关0-否1-是',
`glue_source` text COMMENT 'GLUE源代码', `glue_source` text COMMENT 'GLUE源代码',
@ -169,6 +170,7 @@ CREATE TABLE `XXL_JOB_QRTZ_TRIGGER_LOG` (
`job_group` varchar(255) NOT NULL COMMENT '任务组', `job_group` varchar(255) NOT NULL COMMENT '任务组',
`job_name` varchar(255) NOT NULL COMMENT '任务名', `job_name` varchar(255) NOT NULL COMMENT '任务名',
`executor_address` varchar(255) DEFAULT NULL COMMENT '执行器地址,本次执行的地址', `executor_address` varchar(255) DEFAULT NULL COMMENT '执行器地址,本次执行的地址',
`executor_handler` varchar(255) DEFAULT NULL COMMENT '执行器任务handler',
`executor_param` varchar(255) DEFAULT NULL COMMENT 'executor_param', `executor_param` varchar(255) DEFAULT NULL COMMENT 'executor_param',
`trigger_time` datetime DEFAULT NULL COMMENT '调度-时间', `trigger_time` datetime DEFAULT NULL COMMENT '调度-时间',
`trigger_status` varchar(255) DEFAULT NULL COMMENT '调度-结果', `trigger_status` varchar(255) DEFAULT NULL COMMENT '调度-结果',

View File

@ -33,27 +33,27 @@ public class JobInfoController {
@ResponseBody @ResponseBody
public Map<String, Object> pageList(@RequestParam(required = false, defaultValue = "0") int start, public Map<String, Object> pageList(@RequestParam(required = false, defaultValue = "0") int start,
@RequestParam(required = false, defaultValue = "10") int length, @RequestParam(required = false, defaultValue = "10") int length,
String jobGroup, String jobDesc, String filterTime) { String jobGroup, String executorHandler, String filterTime) {
return xxlJobService.pageList(start, length, jobGroup, jobDesc, filterTime); return xxlJobService.pageList(start, length, jobGroup, executorHandler, filterTime);
} }
@RequestMapping("/add") @RequestMapping("/add")
@ResponseBody @ResponseBody
public ReturnT<String> add(String jobGroup, String jobCron, String jobDesc, public ReturnT<String> add(String jobGroup, String jobCron, String jobDesc, String author, String alarmEmail,
String executorAddress, String executorParam, String author, String alarmEmail, String executorAddress, String executorHandler, String executorParam, int glueSwitch, String glueSource, String glueRemark) {
int glueSwitch, String glueSource, String glueRemark) {
return xxlJobService.add(jobGroup, jobCron, jobDesc, executorAddress, executorParam, return xxlJobService.add(jobGroup, jobCron, jobDesc, author, alarmEmail,
author, alarmEmail, glueSwitch, glueSource, glueRemark); executorAddress, executorHandler, executorParam, glueSwitch, glueSource, glueRemark);
} }
@RequestMapping("/reschedule") @RequestMapping("/reschedule")
@ResponseBody @ResponseBody
public ReturnT<String> reschedule(String jobGroup, String jobName, String jobCron, String jobDesc, public ReturnT<String> reschedule(String jobGroup, String jobName, String jobCron, String jobDesc, String author, String alarmEmail,
String executorAddress, String executorParam, String author, String alarmEmail) { String executorAddress, String executorHandler, String executorParam, int glueSwitch) {
return xxlJobService.reschedule(jobGroup, jobName, jobCron, jobDesc, executorAddress, executorParam, author, alarmEmail); return xxlJobService.reschedule(jobGroup, jobName, jobCron, jobDesc, author, alarmEmail,
executorAddress, executorHandler, executorParam, glueSwitch);
} }
@RequestMapping("/remove") @RequestMapping("/remove")

View File

@ -22,6 +22,7 @@ public class XxlJobInfo {
private String alarmEmail; // 报警邮件 private String alarmEmail; // 报警邮件
private String executorAddress; // 执行器地址有多个则逗号分隔 private String executorAddress; // 执行器地址有多个则逗号分隔
private String executorHandler; // 执行器任务Handler名称
private String executorParam; // 执行器任务参数 private String executorParam; // 执行器任务参数
private int glueSwitch; // GLUE模式开关0-1- private int glueSwitch; // GLUE模式开关0-1-
@ -31,9 +32,6 @@ public class XxlJobInfo {
// copy from quartz // copy from quartz
private String jobStatus; // 任务状态 base on quartz private String jobStatus; // 任务状态 base on quartz
// generate job key
private String jobKey;
public int getId() { public int getId() {
return id; return id;
} }
@ -114,6 +112,14 @@ public class XxlJobInfo {
this.executorAddress = executorAddress; this.executorAddress = executorAddress;
} }
public String getExecutorHandler() {
return executorHandler;
}
public void setExecutorHandler(String executorHandler) {
this.executorHandler = executorHandler;
}
public String getExecutorParam() { public String getExecutorParam() {
return executorParam; return executorParam;
} }
@ -154,12 +160,4 @@ public class XxlJobInfo {
this.jobStatus = jobStatus; this.jobStatus = jobStatus;
} }
public String getJobKey() {
return jobGroup.concat("_").concat(jobName);
}
public void setJobKey(String jobKey) {
this.jobKey = jobKey;
}
} }

View File

@ -30,36 +30,35 @@ public class JobMonitorHelper {
@Override @Override
public void run() { public void run() {
while (true) { while (true) {
logger.info(">>>>>>>>>>> job monitor run ... "); try {
Integer jobLogId = JobMonitorHelper.helper.queue.poll(); logger.info(">>>>>>>>>>> job monitor beat ... ");
if (jobLogId != null && jobLogId > 0) { Integer jobLogId = JobMonitorHelper.helper.queue.take();
XxlJobLog log = DynamicSchedulerUtil.xxlJobLogDao.load(jobLogId); if (jobLogId != null && jobLogId > 0) {
if (log!=null) { logger.info(">>>>>>>>>>> job monitor heat success, JobLogId:{}", jobLogId);
if (RemoteCallBack.SUCCESS.equals(log.getTriggerStatus()) && StringUtils.isBlank(log.getHandleStatus())) { XxlJobLog log = DynamicSchedulerUtil.xxlJobLogDao.load(jobLogId);
try { if (log!=null) {
TimeUnit.SECONDS.sleep(10); if (RemoteCallBack.SUCCESS.equals(log.getTriggerStatus()) && StringUtils.isBlank(log.getHandleStatus())) {
} catch (InterruptedException e) { try {
e.printStackTrace(); TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
JobMonitorHelper.monitor(jobLogId);
} }
JobMonitorHelper.monitor(jobLogId); if (RemoteCallBack.SUCCESS.equals(log.getTriggerStatus()) && RemoteCallBack.SUCCESS.equals(log.getHandleStatus())) {
} // pass
if (RemoteCallBack.SUCCESS.equals(log.getTriggerStatus()) && RemoteCallBack.SUCCESS.equals(log.getHandleStatus())) { }
// pass if (RemoteCallBack.FAIL.equals(log.getTriggerStatus()) || RemoteCallBack.FAIL.equals(log.getHandleStatus())) {
} XxlJobInfo info = DynamicSchedulerUtil.xxlJobInfoDao.load(log.getJobGroup(), log.getJobName());
if (RemoteCallBack.FAIL.equals(log.getTriggerStatus()) || RemoteCallBack.FAIL.equals(log.getHandleStatus())) { if (info!=null && info.getAlarmEmail()!=null && info.getAlarmEmail().trim().length()>0) {
XxlJobInfo info = DynamicSchedulerUtil.xxlJobInfoDao.load(log.getJobGroup(), log.getJobName()); MailUtil.sendMail(info.getAlarmEmail(), "《调度监控报警-调度平台平台XXL-JOB》",
if (info!=null && info.getAlarmEmail()!=null && info.getAlarmEmail().trim().length()>0) { MessageFormat.format("任务调度失败, 任务组:{0}, 任务描述:{1}.", info.getJobGroup(), info.getJobDesc()), false, null);
MailUtil.sendMail(info.getAlarmEmail(), "《调度监控报警-调度平台平台XXL-JOB》", }
MessageFormat.format("任务调度失败, JobKey={0}, 任务描述:{1}.", info.getJobKey(), info.getJobDesc()), false, null);
} }
} }
} }
} else { } catch (Exception e) {
try { logger.error("job monitor error:{}", e);
TimeUnit.SECONDS.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
} }
} }
} }

View File

@ -12,8 +12,8 @@ import com.xxl.job.admin.core.model.XxlJobLog;
*/ */
public interface IXxlJobInfoDao { public interface IXxlJobInfoDao {
public List<XxlJobInfo> pageList(int offset, int pagesize, String jobGroup, String jobDesc); public List<XxlJobInfo> pageList(int offset, int pagesize, String jobGroup, String executorHandler);
public int pageListCount(int offset, int pagesize, String jobGroup, String jobDesc); public int pageListCount(int offset, int pagesize, String jobGroup, String executorHandler);
public int save(XxlJobInfo info); public int save(XxlJobInfo info);

View File

@ -23,23 +23,23 @@ public class XxlJobInfoDaoImpl implements IXxlJobInfoDao {
public SqlSessionTemplate sqlSessionTemplate; public SqlSessionTemplate sqlSessionTemplate;
@Override @Override
public List<XxlJobInfo> pageList(int offset, int pagesize, String jobGroup, String jobDesc) { public List<XxlJobInfo> pageList(int offset, int pagesize, String jobGroup, String executorHandler) {
HashMap<String, Object> params = new HashMap<String, Object>(); HashMap<String, Object> params = new HashMap<String, Object>();
params.put("offset", offset); params.put("offset", offset);
params.put("pagesize", pagesize); params.put("pagesize", pagesize);
params.put("jobGroup", jobGroup); params.put("jobGroup", jobGroup);
params.put("jobDesc", jobDesc); params.put("executorHandler", executorHandler);
return sqlSessionTemplate.selectList("XxlJobInfoMapper.pageList", params); return sqlSessionTemplate.selectList("XxlJobInfoMapper.pageList", params);
} }
@Override @Override
public int pageListCount(int offset, int pagesize, String jobGroup, String jobDesc) { public int pageListCount(int offset, int pagesize, String jobGroup, String executorHandler) {
HashMap<String, Object> params = new HashMap<String, Object>(); HashMap<String, Object> params = new HashMap<String, Object>();
params.put("offset", offset); params.put("offset", offset);
params.put("pagesize", pagesize); params.put("pagesize", pagesize);
params.put("jobGroup", jobGroup); params.put("jobGroup", jobGroup);
params.put("jobDesc", jobDesc); params.put("executorHandler", executorHandler);
return sqlSessionTemplate.selectOne("XxlJobInfoMapper.pageListCount", params); return sqlSessionTemplate.selectOne("XxlJobInfoMapper.pageListCount", params);
} }

View File

@ -11,14 +11,13 @@ import com.xxl.job.admin.core.model.ReturnT;
*/ */
public interface IXxlJobService { public interface IXxlJobService {
public Map<String, Object> pageList(int start, int length, String jobGroup, String jobDesc, String filterTime); public Map<String, Object> pageList(int start, int length, String jobGroup, String executorHandler, String filterTime);
public ReturnT<String> add(String jobGroup, String jobCron, String jobDesc, public ReturnT<String> add(String jobGroup, String jobCron, String jobDesc,String author, String alarmEmail,
String executorAddress, String executorParam, String author, String alarmEmail, String executorAddress, String executorHandler, String executorParam, int glueSwitch, String glueSource, String glueRemark);
int glueSwitch, String glueSource, String glueRemark);
public ReturnT<String> reschedule(String jobGroup, String jobName, String jobCron, String jobDesc, public ReturnT<String> reschedule(String jobGroup, String jobName, String jobCron, String jobDesc, String author, String alarmEmail,
String handler_address, String handler_params, String author, String alarmEmail); String executorAddress, String executorHandler, String executorParam, int glueSwitch);
public ReturnT<String> remove(String jobGroup, String jobName); public ReturnT<String> remove(String jobGroup, String jobName);

View File

@ -1,18 +1,6 @@
package com.xxl.job.admin.service.impl; package com.xxl.job.admin.service.impl;
import java.util.*;
import javax.annotation.Resource;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang.time.FastDateFormat;
import org.quartz.CronExpression;
import org.quartz.SchedulerException;
import org.springframework.stereotype.Service;
import com.xxl.job.admin.core.constant.Constants.JobGroupEnum; import com.xxl.job.admin.core.constant.Constants.JobGroupEnum;
import com.xxl.job.admin.core.jobbean.RemoteHttpJobBean;
import com.xxl.job.admin.core.model.ReturnT; import com.xxl.job.admin.core.model.ReturnT;
import com.xxl.job.admin.core.model.XxlJobInfo; import com.xxl.job.admin.core.model.XxlJobInfo;
import com.xxl.job.admin.core.util.DynamicSchedulerUtil; import com.xxl.job.admin.core.util.DynamicSchedulerUtil;
@ -20,6 +8,19 @@ import com.xxl.job.admin.dao.IXxlJobInfoDao;
import com.xxl.job.admin.dao.IXxlJobLogDao; import com.xxl.job.admin.dao.IXxlJobLogDao;
import com.xxl.job.admin.dao.IXxlJobLogGlueDao; import com.xxl.job.admin.dao.IXxlJobLogGlueDao;
import com.xxl.job.admin.service.IXxlJobService; import com.xxl.job.admin.service.IXxlJobService;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.FastDateFormat;
import org.quartz.CronExpression;
import org.quartz.SchedulerException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** /**
* core job service for xxl-job * core job service for xxl-job
@ -27,6 +28,7 @@ import com.xxl.job.admin.service.IXxlJobService;
*/ */
@Service @Service
public class XxlJobServiceImpl implements IXxlJobService { public class XxlJobServiceImpl implements IXxlJobService {
private static Logger logger = LoggerFactory.getLogger(XxlJobServiceImpl.class);
@Resource @Resource
private IXxlJobInfoDao xxlJobInfoDao; private IXxlJobInfoDao xxlJobInfoDao;
@ -36,11 +38,11 @@ public class XxlJobServiceImpl implements IXxlJobService {
private IXxlJobLogGlueDao xxlJobLogGlueDao; private IXxlJobLogGlueDao xxlJobLogGlueDao;
@Override @Override
public Map<String, Object> pageList(int start, int length, String jobGroup, String jobDesc, String filterTime) { public Map<String, Object> pageList(int start, int length, String jobGroup, String executorHandler, String filterTime) {
// page list // page list
List<XxlJobInfo> list = xxlJobInfoDao.pageList(start, length, jobGroup, jobDesc); List<XxlJobInfo> list = xxlJobInfoDao.pageList(start, length, jobGroup, executorHandler);
int list_count = xxlJobInfoDao.pageListCount(start, length, jobGroup, jobDesc); int list_count = xxlJobInfoDao.pageListCount(start, length, jobGroup, executorHandler);
// fill job info // fill job info
if (list!=null && list.size()>0) { if (list!=null && list.size()>0) {
@ -58,9 +60,8 @@ public class XxlJobServiceImpl implements IXxlJobService {
} }
@Override @Override
public ReturnT<String> add(String jobGroup, String jobCron, String jobDesc, public ReturnT<String> add(String jobGroup, String jobCron, String jobDesc, String author, String alarmEmail,
String executorAddress, String executorParam, String author, String alarmEmail, String executorAddress, String executorHandler, String executorParam, int glueSwitch, String glueSource, String glueRemark) {
int glueSwitch, String glueSource, String glueRemark) {
// valid // valid
if (JobGroupEnum.match(jobGroup) == null) { if (JobGroupEnum.match(jobGroup) == null) {
return new ReturnT<String>(500, "请选择“任务组”"); return new ReturnT<String>(500, "请选择“任务组”");
@ -71,15 +72,18 @@ public class XxlJobServiceImpl implements IXxlJobService {
if (StringUtils.isBlank(jobDesc)) { if (StringUtils.isBlank(jobDesc)) {
return new ReturnT<String>(500, "请输入“任务描述”"); return new ReturnT<String>(500, "请输入“任务描述”");
} }
if (StringUtils.isBlank(executorAddress)) {
return new ReturnT<String>(500, "请输入“执行器地址”");
}
if (StringUtils.isBlank(author)) { if (StringUtils.isBlank(author)) {
return new ReturnT<String>(500, "请输入“负责人”"); return new ReturnT<String>(500, "请输入“负责人”");
} }
if (StringUtils.isBlank(alarmEmail)) { if (StringUtils.isBlank(alarmEmail)) {
return new ReturnT<String>(500, "请输入“报警邮件”"); return new ReturnT<String>(500, "请输入“报警邮件”");
} }
if (StringUtils.isBlank(executorAddress)) {
return new ReturnT<String>(500, "请输入“执行器地址”");
}
if (glueSwitch==0 && StringUtils.isBlank(executorHandler)) {
return new ReturnT<String>(500, "请输入“JobHandler”");
}
// generate jobName // generate jobName
String jobName = FastDateFormat.getInstance("yyyyMMddHHmmssSSSS").format(new Date()); String jobName = FastDateFormat.getInstance("yyyyMMddHHmmssSSSS").format(new Date());
@ -100,33 +104,32 @@ public class XxlJobServiceImpl implements IXxlJobService {
jobInfo.setJobDesc(jobDesc); jobInfo.setJobDesc(jobDesc);
jobInfo.setAuthor(author); jobInfo.setAuthor(author);
jobInfo.setAlarmEmail(alarmEmail); jobInfo.setAlarmEmail(alarmEmail);
jobInfo.setExecutorAddress(executorAddress);
jobInfo.setExecutorHandler(executorHandler);
jobInfo.setExecutorParam(executorParam);
jobInfo.setGlueSwitch(glueSwitch); jobInfo.setGlueSwitch(glueSwitch);
jobInfo.setGlueSource(glueSource); jobInfo.setGlueSource(glueSource);
jobInfo.setGlueRemark(glueRemark); jobInfo.setGlueRemark(glueRemark);
jobInfo.setExecutorAddress(executorAddress);
jobInfo.setExecutorParam(executorParam);
xxlJobInfoDao.save(jobInfo);
try { try {
// add job 2 quartz // add job 2 quartz
boolean result = DynamicSchedulerUtil.addJob(jobInfo); boolean result = DynamicSchedulerUtil.addJob(jobInfo);
if (result) { if (result) {
xxlJobInfoDao.save(jobInfo);
return ReturnT.SUCCESS; return ReturnT.SUCCESS;
} else { } else {
xxlJobInfoDao.delete(jobGroup, jobName);
return new ReturnT<String>(500, "新增任务失败"); return new ReturnT<String>(500, "新增任务失败");
} }
} catch (SchedulerException e) { } catch (SchedulerException e) {
e.printStackTrace(); logger.error("", e);
} }
return ReturnT.FAIL; return ReturnT.FAIL;
} }
@Override @Override
public ReturnT<String> reschedule(String jobGroup, String jobName, String jobCron, String jobDesc, public ReturnT<String> reschedule(String jobGroup, String jobName, String jobCron, String jobDesc, String author, String alarmEmail,
String executorAddress, String executorParam, String executorAddress, String executorHandler, String executorParam, int glueSwitch) {
String author, String alarmEmail) {
// valid // valid
if (JobGroupEnum.match(jobGroup) == null) { if (JobGroupEnum.match(jobGroup) == null) {
return new ReturnT<String>(500, "请选择“任务组”"); return new ReturnT<String>(500, "请选择“任务组”");
@ -140,33 +143,41 @@ public class XxlJobServiceImpl implements IXxlJobService {
if (StringUtils.isBlank(jobDesc)) { if (StringUtils.isBlank(jobDesc)) {
return new ReturnT<String>(500, "请输入“任务描述”"); return new ReturnT<String>(500, "请输入“任务描述”");
} }
if (StringUtils.isBlank(executorAddress)) {
return new ReturnT<String>(500, "请输入“执行器地址”");
}
if (StringUtils.isBlank(author)) { if (StringUtils.isBlank(author)) {
return new ReturnT<String>(500, "请输入“负责人”"); return new ReturnT<String>(500, "请输入“负责人”");
} }
if (StringUtils.isBlank(alarmEmail)) { if (StringUtils.isBlank(alarmEmail)) {
return new ReturnT<String>(500, "请输入“报警邮件”"); return new ReturnT<String>(500, "请输入“报警邮件”");
} }
if (StringUtils.isBlank(executorAddress)) {
return new ReturnT<String>(500, "请输入“执行器地址”");
}
if (glueSwitch==0 && StringUtils.isBlank(executorHandler)) {
return new ReturnT<String>(500, "请输入“JobHandler”");
}
// stage job info
XxlJobInfo jobInfo = xxlJobInfoDao.load(jobGroup, jobName); XxlJobInfo jobInfo = xxlJobInfoDao.load(jobGroup, jobName);
jobInfo.setJobDesc(jobDesc);
jobInfo.setJobCron(jobCron); jobInfo.setJobCron(jobCron);
jobInfo.setJobDesc(jobDesc);
jobInfo.setAuthor(author); jobInfo.setAuthor(author);
jobInfo.setAlarmEmail(alarmEmail); jobInfo.setAlarmEmail(alarmEmail);
jobInfo.setExecutorAddress(executorAddress); jobInfo.setExecutorAddress(executorAddress);
jobInfo.setExecutorHandler(executorHandler);
jobInfo.setExecutorParam(executorParam); jobInfo.setExecutorParam(executorParam);
jobInfo.setGlueSwitch(glueSwitch);
try { try {
// fresh quartz // fresh quartz
DynamicSchedulerUtil.rescheduleJob(jobInfo); boolean ret = DynamicSchedulerUtil.rescheduleJob(jobInfo);
if (ret) {
// fresh db xxlJobInfoDao.update(jobInfo);
xxlJobInfoDao.update(jobInfo); return ReturnT.SUCCESS;
return ReturnT.SUCCESS; } else {
return new ReturnT<String>(500, "更新任务失败");
}
} catch (SchedulerException e) { } catch (SchedulerException e) {
e.printStackTrace(); logger.error("", e);
} }
return ReturnT.FAIL; return ReturnT.FAIL;
} }

View File

@ -18,6 +18,7 @@
<result column="alarm_email" property="alarmEmail" /> <result column="alarm_email" property="alarmEmail" />
<result column="executor_address" property="executorAddress" /> <result column="executor_address" property="executorAddress" />
<result column="executor_handler" property="executorHandler" />
<result column="executor_param" property="executorParam" /> <result column="executor_param" property="executorParam" />
<result column="glue_switch" property="glueSwitch" /> <result column="glue_switch" property="glueSwitch" />
@ -36,6 +37,7 @@
t.author, t.author,
t.alarm_email, t.alarm_email,
t.executor_address, t.executor_address,
t.executor_handler,
t.executor_param, t.executor_param,
t.glue_switch, t.glue_switch,
t.glue_source, t.glue_source,
@ -49,8 +51,8 @@
<if test="jobGroup != null and jobGroup != ''"> <if test="jobGroup != null and jobGroup != ''">
AND t.job_group = #{jobGroup} AND t.job_group = #{jobGroup}
</if> </if>
<if test="jobDesc != null and jobDesc != ''"> <if test="executorHandler != null and executorHandler != ''">
AND t.job_desc like CONCAT(CONCAT('%', #{jobDesc}), '%') AND t.executor_handler like CONCAT(CONCAT('%', #{executorHandler}), '%')
</if> </if>
</trim> </trim>
ORDER BY id DESC ORDER BY id DESC
@ -64,8 +66,8 @@
<if test="jobGroup != null and jobGroup != ''"> <if test="jobGroup != null and jobGroup != ''">
AND t.job_group = #{jobGroup} AND t.job_group = #{jobGroup}
</if> </if>
<if test="jobDesc != null and jobDesc != ''"> <if test="executorHandler != null and executorHandler != ''">
AND t.job_desc like CONCAT(CONCAT('%', #{jobDesc}), '%') AND t.executor_handler like CONCAT(CONCAT('%', #{executorHandler}), '%')
</if> </if>
</trim> </trim>
</select> </select>
@ -81,6 +83,7 @@
author, author,
alarm_email, alarm_email,
executor_address, executor_address,
executor_handler,
executor_param, executor_param,
glue_switch, glue_switch,
glue_source, glue_source,
@ -95,6 +98,7 @@
#{author}, #{author},
#{alarmEmail}, #{alarmEmail},
#{executorAddress}, #{executorAddress},
#{executorHandler},
#{executorParam}, #{executorParam},
#{glueSwitch}, #{glueSwitch},
#{glueSource}, #{glueSource},
@ -121,6 +125,7 @@
author = #{author}, author = #{author},
alarm_email = #{alarmEmail}, alarm_email = #{alarmEmail},
executor_address = #{executorAddress}, executor_address = #{executorAddress},
executor_handler = #{executorHandler},
executor_param = #{executorParam}, executor_param = #{executorParam},
glue_switch = #{glueSwitch}, glue_switch = #{glueSwitch},
glue_source = #{glueSource}, glue_source = #{glueSource},

View File

@ -38,7 +38,7 @@
<section class="content"> <section class="content">
<div class="row"> <div class="row">
<div class="col-xs-2"> <div class="col-xs-4">
<div class="input-group"> <div class="input-group">
<span class="input-group-addon">分组</span> <span class="input-group-addon">分组</span>
<select class="form-control" id="jobGroup" > <select class="form-control" id="jobGroup" >
@ -48,18 +48,12 @@
</select> </select>
</div> </div>
</div> </div>
<div class="col-xs-3"> <div class="col-xs-4">
<div class="input-group"> <div class="input-group">
<span class="input-group-addon">JobKey</span> <span class="input-group-addon">JobHandler</span>
<input type="text" class="form-control" id="JobKey" value="${jobName}" autocomplete="on" > <input type="text" class="form-control" id="executorHandler" value="${jobName}" autocomplete="on" >
</div> </div>
</div> </div>
<div class="col-xs-3">
<div class="input-group">
<span class="input-group-addon">描述</span>
<input type="text" class="form-control" id="jobDesc" value="${jobName}" autocomplete="on" >
</div>
</div>
<div class="col-xs-2"> <div class="col-xs-2">
<button class="btn btn-block btn-info" id="searchBtn">搜索</button> <button class="btn btn-block btn-info" id="searchBtn">搜索</button>
</div> </div>
@ -81,10 +75,10 @@
<th name="id" >id</th> <th name="id" >id</th>
<th name="jobGroup" >jobGroup</th> <th name="jobGroup" >jobGroup</th>
<th name="jobName" >jobName</th> <th name="jobName" >jobName</th>
<th name="JobKey" >JobKey</th>
<th name="jobDesc" >描述</th> <th name="jobDesc" >描述</th>
<th name="jobCron" >Cron</th> <th name="jobCron" >Cron</th>
<th name="executorAddress" >执行器地址</th> <th name="executorAddress" >执行器地址</th>
<th name="executorHandler" >JobJandler</th>
<th name="executorParam" >任务参数</th> <th name="executorParam" >任务参数</th>
<th name="addTime" >新增时间</th> <th name="addTime" >新增时间</th>
<th name="updateTime" >更新时间</th> <th name="updateTime" >更新时间</th>
@ -137,15 +131,16 @@
<div class="col-sm-4"><input type="text" class="form-control" name="jobCron" placeholder="请输入“Cron”" maxlength="20" ></div> <div class="col-sm-4"><input type="text" class="form-control" name="jobCron" placeholder="请输入“Cron”" maxlength="20" ></div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="firstname" class="col-sm-2 control-label">执行参数<font color="black">*</font></label> <label for="firstname" class="col-sm-2 control-label">JobHandler<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="executorParam" placeholder="请输入“执行参数”" maxlength="100" ></div>
<label for="firstname" class="col-sm-2 control-label">任务模式<font color="red">*</font></label>
<div class="col-sm-4"> <div class="col-sm-4">
<select class="form-control" name="glueSwitch" > <div class="input-group">
<option value="0" >BEAN模式</option> <input type="text" class="form-control" name="executorHandler" placeholder="请输入“JobHandler”" maxlength="100" >
<option value="1" >GLUE模式</option> <span class="input-group-addon"><b>GLUE</b>&nbsp;<input type="checkbox" class="ifGLUE" ></span>
</select> <input type="hidden" name="glueSwitch" value="0" >
</div> </div>
</div>
<label for="firstname" class="col-sm-2 control-label">执行参数<font color="black">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="executorParam" placeholder="请输入“执行参数”" maxlength="100" ></div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="lastname" class="col-sm-2 control-label">报警邮件<font color="red">*</font></label> <label for="lastname" class="col-sm-2 control-label">报警邮件<font color="red">*</font></label>
@ -212,15 +207,19 @@ public class DemoJobHandler extends IJobHandler {
<label for="lastname" class="col-sm-2 control-label">Cron<font color="red">*</font></label> <label for="lastname" class="col-sm-2 control-label">Cron<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="jobCron" placeholder="请输入“Cron”" maxlength="20" ></div> <div class="col-sm-4"><input type="text" class="form-control" name="jobCron" placeholder="请输入“Cron”" maxlength="20" ></div>
</div> </div>
<div class="form-group">
<div class="form-group"> <label for="firstname" class="col-sm-2 control-label">JobHandler<font color="red">*</font></label>
<div class="col-sm-4">
<div class="input-group">
<input type="text" class="form-control" name="executorHandler" placeholder="请输入“JobHandler”" maxlength="100" >
<span class="input-group-addon"><b>GLUE</b>&nbsp;<input type="checkbox" class="ifGLUE" ></span>
<input type="hidden" name="glueSwitch" value="0" >
</div>
</div>
<label for="firstname" class="col-sm-2 control-label">执行参数<font color="black">*</font></label> <label for="firstname" class="col-sm-2 control-label">执行参数<font color="black">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="executorParam" placeholder="请输入“执行参数”" maxlength="100" ></div> <div class="col-sm-4"><input type="text" class="form-control" name="executorParam" placeholder="请输入“执行参数”" maxlength="100" ></div>
<label for="firstname" class="col-sm-2 control-label">任务模式<font color="red">*</font></label> </div>
<div class="col-sm-4">
<input type="text" class="form-control glueSwitchTitle" readonly >
</div>
</div>
<div class="form-group"> <div class="form-group">
<label for="lastname" class="col-sm-2 control-label">报警邮件<font color="red">*</font></label> <label for="lastname" class="col-sm-2 control-label">报警邮件<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="alarmEmail" placeholder="请输入“报警邮件”,多个邮件地址逗号分隔" maxlength="100" ></div> <div class="col-sm-4"><input type="text" class="form-control" name="alarmEmail" placeholder="请输入“报警邮件”,多个邮件地址逗号分隔" maxlength="100" ></div>
@ -229,16 +228,12 @@ public class DemoJobHandler extends IJobHandler {
</div> </div>
<hr> <hr>
<div class="form-group"> <div class="form-group">
<div class="col-sm-offset-3 col-sm-3"> <div class="col-sm-offset-3 col-sm-6">
<button type="submit" class="btn btn-primary" >保存</button> <button type="submit" class="btn btn-primary" >保存</button>
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button> <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
<input type="hidden" name="jobGroup" > <input type="hidden" name="jobGroup" >
<input type="hidden" name="jobName" > <input type="hidden" name="jobName" >
</div> </div>
<label for="firstname" class="col-sm-2 control-label">JobKey</label>
<div class="col-sm-4">
<input type="text" class="form-control jobKey" readonly >
</div>
</div> </div>
</form> </form>
</div> </div>

View File

@ -10,7 +10,7 @@ $(function() {
data : function ( d ) { data : function ( d ) {
var obj = {}; var obj = {};
obj.jobGroup = $('#jobGroup').val(); obj.jobGroup = $('#jobGroup').val();
obj.jobDesc = $('#jobDesc').val(); obj.executorHandler = $('#executorHandler').val();
obj.start = d.start; obj.start = d.start;
obj.length = d.length; obj.length = d.length;
return obj; return obj;
@ -35,10 +35,10 @@ $(function() {
} }
}, },
{ "data": 'jobName', "visible" : false}, { "data": 'jobName', "visible" : false},
{ "data": 'jobKey', "visible" : true},
{ "data": 'jobDesc', "visible" : true}, { "data": 'jobDesc', "visible" : true},
{ "data": 'jobCron', "visible" : true}, { "data": 'jobCron', "visible" : true},
{ "data": 'executorAddress', "visible" : false}, { "data": 'executorAddress', "visible" : false},
{ "data": 'executorHandler', "visible" : false},
{ "data": 'executorParam', "visible" : false}, { "data": 'executorParam', "visible" : false},
{ {
"data": 'addTime', "data": 'addTime',
@ -87,33 +87,33 @@ $(function() {
// log url // log url
var codeBtn = ""; var codeBtn = "";
if(row.glueSwitch > 0){ if(row.glueSwitch > 0){
var codeUrl = base_url +'/jobcode?jobGroup='+ row.jobGroup +'&jobName='+ row.jobName; var codeUrl = base_url +'/jobcode?jobGroup='+ row.jobGroup +'&jobName='+ row.jobName;
codeBtn = '<button class="btn btn-warning btn-xs" type="button" onclick="javascript:window.open(\'' + codeUrl + '\')" >GLUE</button> ' codeBtn = '<button class="btn btn-warning btn-xs" type="button" onclick="javascript:window.open(\'' + codeUrl + '\')" >GLUE</button> '
} }
var html = '<p id="'+ row.id +'" '+ // html
' jobGroup="'+ row.jobGroup +'" '+ var html = '<p id="'+ row.id +'" '+
' jobName="'+ row.jobName +'" '+ ' jobGroup="'+ row.jobGroup +'" '+
' jobKey="'+ row.jobKey +'" '+ ' jobName="'+ row.jobName +'" '+
' jobCron="'+ row.jobCron +'" '+ ' jobCron="'+ row.jobCron +'" '+
' jobDesc="'+ row.jobDesc +'" '+ ' jobDesc="'+ row.jobDesc +'" '+
' executorAddress="'+row.executorAddress +'" '+ ' author="'+ row.author +'" '+
' executorParam="'+ row.executorParam +'" '+ ' alarmEmail="'+ row.alarmEmail +'" '+
' author="'+ row.author +'" '+ ' executorAddress="'+row.executorAddress +'" '+
' alarmEmail="'+ row.alarmEmail +'" '+ ' executorHandler="'+row.executorHandler +'" '+
' glueSwitch="'+ row.glueSwitch +'" '+ ' executorParam="'+ row.executorParam +'" '+
'>'+ ' glueSwitch="'+ row.glueSwitch +'" '+
'<button class="btn btn-primary btn-xs job_operate" type="job_trigger" type="button">执行</button> '+ '>'+
pause_resume + '<button class="btn btn-primary btn-xs job_operate" type="job_trigger" type="button">执行</button> '+
'<button class="btn btn-primary btn-xs" type="job_del" type="button" onclick="javascript:window.open(\'' + logUrl + '\')" >日志</button><br> '+ pause_resume +
'<button class="btn btn-warning btn-xs update" type="button">编辑</button> '+ '<button class="btn btn-primary btn-xs" type="job_del" type="button" onclick="javascript:window.open(\'' + logUrl + '\')" >日志</button><br> '+
codeBtn + '<button class="btn btn-warning btn-xs update" type="button">编辑</button> '+
'<button class="btn btn-danger btn-xs job_operate" type="job_del" type="button">删除</button> '+ codeBtn +
'<button class="btn btn-danger btn-xs job_operate" type="job_del" type="button">删除</button> '+
'</p>'; '</p>';
return html; return html;
}; };
} }
} }
], ],
@ -221,6 +221,9 @@ $(function() {
executorAddress : { executorAddress : {
required : true required : true
}, },
executorHandler : {
required : false
},
alarmEmail : { alarmEmail : {
required : true required : true
}, },
@ -238,6 +241,9 @@ $(function() {
executorAddress : { executorAddress : {
required :"请输入“执行器地址”." required :"请输入“执行器地址”."
}, },
executorHandler : {
required : "请输入“jobHandler”."
},
alarmEmail : { alarmEmail : {
required : "请输入“报警邮件”." required : "请输入“报警邮件”."
}, },
@ -277,6 +283,21 @@ $(function() {
$("#addModal .form .form-group").removeClass("has-error"); $("#addModal .form .form-group").removeClass("has-error");
$(".remote_panel").show(); // remote $(".remote_panel").show(); // remote
}); });
// GLUE模式开启
$(".ifGLUE").click(function(){
var ifGLUE = $(this).is(':checked');
var $executorHandler = $(this).parents("form").find("input[name='executorHandler']");
var $glueSwitch = $(this).parents("form").find("input[name='glueSwitch']");
if (ifGLUE) {
$executorHandler.val("");
$executorHandler.attr("readonly","readonly");
$glueSwitch.val(1);
} else {
$executorHandler.removeAttr("readonly");
$glueSwitch.val(0);
}
});
// 更新 // 更新
$("#job_list").on('click', '.update',function() { $("#job_list").on('click', '.update',function() {
@ -284,20 +305,31 @@ $(function() {
// base data // base data
$("#updateModal .form input[name='jobGroup']").val($(this).parent('p').attr("jobGroup")); $("#updateModal .form input[name='jobGroup']").val($(this).parent('p').attr("jobGroup"));
$("#updateModal .form input[name='jobName']").val($(this).parent('p').attr("jobName")); $("#updateModal .form input[name='jobName']").val($(this).parent('p').attr("jobName"));
$("#updateModal .form .jobKey").val( $(this).parent('p').attr("jobKey") );
$("#updateModal .form input[name='jobDesc']").val($(this).parent('p').attr("jobDesc")); $("#updateModal .form input[name='jobDesc']").val($(this).parent('p').attr("jobDesc"));
$("#updateModal .form input[name='jobCron']").val($(this).parent('p').attr("jobCron")); $("#updateModal .form input[name='jobCron']").val($(this).parent('p').attr("jobCron"));
$("#updateModal .form input[name='executorAddress']").val($(this).parent('p').attr("executorAddress"));
$("#updateModal .form input[name='executorParam']").val($(this).parent('p').attr("executorParam"));
$("#updateModal .form input[name='author']").val($(this).parent('p').attr("author")); $("#updateModal .form input[name='author']").val($(this).parent('p').attr("author"));
$("#updateModal .form input[name='alarmEmail']").val($(this).parent('p').attr("alarmEmail")); $("#updateModal .form input[name='alarmEmail']").val($(this).parent('p').attr("alarmEmail"));
$("#updateModal .form input[name='executorAddress']").val($(this).parent('p').attr("executorAddress"));
$("#updateModal .form input[name='executorHandler']").val($(this).parent('p').attr("executorHandler"));
$("#updateModal .form input[name='executorParam']").val($(this).parent('p').attr("executorParam"));
// jobGroupTitle // jobGroupTitle
var jobGroupTitle = $("#addModal .form select[name='jobGroup']").find("option[value='" + $(this).parent('p').attr("jobGroup") + "']").text(); var jobGroupTitle = $("#addModal .form select[name='jobGroup']").find("option[value='" + $(this).parent('p').attr("jobGroup") + "']").text();
$("#updateModal .form .jobGroupTitle").val(jobGroupTitle); $("#updateModal .form .jobGroupTitle").val(jobGroupTitle);
// glueSwitchTitle // glueSwitch
$("#updateModal .form .glueSwitchTitle").val( ($(this).parent('p').attr("glueSwitch") == 0)?"BEAN模式":"GLUE模式" ); var glueSwitch = $(this).parent('p').attr("glueSwitch");
$("#updateModal .form input[name='glueSwitch']").val(glueSwitch);
var $ifGLUE = $("#updateModal .form .ifGLUE");
var $executorHandler = $("#updateModal .form input[name='executorHandler']");
if (glueSwitch == 1) {
$ifGLUE.attr("checked", true);
$executorHandler.val("");
$executorHandler.attr("readonly","readonly");
} else {
$ifGLUE.attr("checked", false);
$executorHandler.removeAttr("readonly");
}
// show // show
$('#updateModal').modal({backdrop: false, keyboard: false}).modal('show'); $('#updateModal').modal({backdrop: false, keyboard: false}).modal('show');
@ -318,6 +350,9 @@ $(function() {
executorAddress : { executorAddress : {
required : true required : true
}, },
executorHandler : {
required : false
},
alarmEmail : { alarmEmail : {
required : true required : true
}, },
@ -335,6 +370,9 @@ $(function() {
executorAddress : { executorAddress : {
required :"请输入“执行器地址”." required :"请输入“执行器地址”."
}, },
executorHandler : {
required : "请输入“jobHandler”."
},
alarmEmail : { alarmEmail : {
required : "请输入“报警邮件”." required : "请输入“报警邮件”."
}, },
@ -353,7 +391,6 @@ $(function() {
element.parent('div').append(error); element.parent('div').append(error);
}, },
submitHandler : function(form) { submitHandler : function(form) {
// post // post
$.post(base_url + "/jobinfo/reschedule", $("#updateModal .form").serialize(), function(data, status) { $.post(base_url + "/jobinfo/reschedule", $("#updateModal .form").serialize(), function(data, status) {
if (data.code == "200") { if (data.code == "200") {
@ -374,22 +411,6 @@ $(function() {
$("#updateModal .form")[0].reset() $("#updateModal .form")[0].reset()
}); });
// GLUE模式开启
/*
$("#addModal .form .ifGLUE").click(function(){
var ifGLUE = $(this).is(':checked');
var $executorHandler = $("#addModal .form input[name='executorHandler']");
var $glueSwitch = $("#addModal .form input[name='glueSwitch']");
if (ifGLUE) {
$executorHandler.val("");
$executorHandler.attr("readonly","readonly");
$glueSwitch.val(1);
} else {
$executorHandler.removeAttr("readonly");
$glueSwitch.val(0);
}
});
*/
/* /*
// 新增-添加参数 // 新增-添加参数

View File

@ -56,6 +56,7 @@ public class HandlerThread extends Thread{
public void run() { public void run() {
while(!toStop){ while(!toStop){
try { try {
// to check toStop signal, we need cycle, so wo cannot use queue.take(), instand of poll(timeout)
Map<String, String> handlerData = handlerDataQueue.poll(3L, TimeUnit.SECONDS); Map<String, String> handlerData = handlerDataQueue.poll(3L, TimeUnit.SECONDS);
if (handlerData!=null) { if (handlerData!=null) {
i= 0; i= 0;