重要重构;

1、优化调度Info表字段;
2、优化调度Log表字段;
3、优化"新增/更新任务"界面交互体验;
This commit is contained in:
xueli.xue 2016-07-20 23:24:21 +08:00
parent d4b3045fef
commit 9591be6b13
19 changed files with 85 additions and 243 deletions

View File

@ -145,20 +145,17 @@ CREATE TABLE XXL_JOB_QRTZ_LOCKS
CREATE TABLE XXL_JOB_QRTZ_TRIGGER_INFO ( CREATE TABLE `XXL_JOB_QRTZ_TRIGGER_INFO` (
`id` int(11) NOT NULL AUTO_INCREMENT, `id` int(11) NOT NULL AUTO_INCREMENT,
`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 '任务名',
`job_cron` varchar(128) NOT NULL COMMENT '任务执行CRON', `job_cron` varchar(128) NOT NULL COMMENT '任务执行CRON',
`job_desc` varchar(255) NOT NULL, `job_desc` varchar(255) NOT NULL,
`job_class` varchar(255) NOT NULL COMMENT '任务执行JobBean',
`add_time` datetime DEFAULT NULL, `add_time` datetime DEFAULT NULL,
`update_time` datetime DEFAULT NULL, `update_time` datetime DEFAULT NULL,
`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 '报警邮件',
`alarm_threshold` int(11) 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源代码',
@ -166,15 +163,12 @@ CREATE TABLE XXL_JOB_QRTZ_TRIGGER_INFO (
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8; ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE XXL_JOB_QRTZ_TRIGGER_LOG (
CREATE TABLE `XXL_JOB_QRTZ_TRIGGER_LOG` (
`id` int(11) NOT NULL AUTO_INCREMENT, `id` int(11) NOT NULL AUTO_INCREMENT,
`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 '任务名',
`job_cron` varchar(128) NOT NULL COMMENT '任务执行CRON表达式',
`job_desc` varchar(255) NOT NULL,
`job_class` varchar(255) NOT NULL COMMENT '任务执行JobBean',
`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

@ -40,23 +40,20 @@ public class JobInfoController {
@RequestMapping("/add") @RequestMapping("/add")
@ResponseBody @ResponseBody
public ReturnT<String> add(String jobGroup, String jobName, String jobCron, String jobDesc, public ReturnT<String> add(String jobGroup, String jobCron, String jobDesc,
String executorAddress, String executorParam, String executorAddress, String executorParam, String author, String alarmEmail,
String author, String alarmEmail, int alarmThreshold,
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, executorAddress, executorParam,
author, alarmEmail, alarmThreshold, glueSwitch, glueSource, glueRemark); author, alarmEmail, 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 executorAddress, String executorParam, String executorAddress, String executorParam, String author, String alarmEmail) {
String author, String alarmEmail, int alarmThreshold) {
return xxlJobService.reschedule(jobGroup, jobName, jobCron, jobDesc, executorAddress, executorParam, author, return xxlJobService.reschedule(jobGroup, jobName, jobCron, jobDesc, executorAddress, executorParam, author, alarmEmail);
alarmEmail, alarmThreshold);
} }
@RequestMapping("/remove") @RequestMapping("/remove")

View File

@ -1,20 +1,5 @@
package com.xxl.job.admin.core.jobbean; package com.xxl.job.admin.core.jobbean;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.quartz.QuartzJobBean;
import com.xxl.job.admin.core.callback.XxlJobLogCallbackServer; import com.xxl.job.admin.core.callback.XxlJobLogCallbackServer;
import com.xxl.job.admin.core.model.XxlJobInfo; import com.xxl.job.admin.core.model.XxlJobInfo;
import com.xxl.job.admin.core.model.XxlJobLog; import com.xxl.job.admin.core.model.XxlJobLog;
@ -24,6 +9,16 @@ import com.xxl.job.core.handler.HandlerRepository.ActionEnum;
import com.xxl.job.core.handler.HandlerRepository.HandlerParamEnum; import com.xxl.job.core.handler.HandlerRepository.HandlerParamEnum;
import com.xxl.job.core.util.HttpUtil; import com.xxl.job.core.util.HttpUtil;
import com.xxl.job.core.util.HttpUtil.RemoteCallBack; import com.xxl.job.core.util.HttpUtil.RemoteCallBack;
import org.apache.commons.lang.StringUtils;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.quartz.QuartzJobBean;
import java.text.MessageFormat;
import java.util.*;
/** /**
* http job bean * http job bean
@ -44,9 +39,6 @@ public class RemoteHttpJobBean extends QuartzJobBean {
XxlJobLog jobLog = new XxlJobLog(); XxlJobLog jobLog = new XxlJobLog();
jobLog.setJobGroup(jobInfo.getJobGroup()); jobLog.setJobGroup(jobInfo.getJobGroup());
jobLog.setJobName(jobInfo.getJobName()); jobLog.setJobName(jobInfo.getJobName());
jobLog.setJobCron(jobInfo.getJobCron());
jobLog.setJobDesc(jobInfo.getJobDesc());
jobLog.setJobClass(jobInfo.getJobClass());
DynamicSchedulerUtil.xxlJobLogDao.save(jobLog); DynamicSchedulerUtil.xxlJobLogDao.save(jobLog);
logger.info(">>>>>>>>>>> xxl-job trigger start, jobId:{}", jobLog.getId()); logger.info(">>>>>>>>>>> xxl-job trigger start, jobId:{}", jobLog.getId());
@ -66,7 +58,6 @@ public class RemoteHttpJobBean extends QuartzJobBean {
// failover trigger // failover trigger
RemoteCallBack callback = failoverTrigger(jobInfo.getExecutorAddress(), params, jobLog); RemoteCallBack callback = failoverTrigger(jobInfo.getExecutorAddress(), params, jobLog);
jobLog.setExecutorHandler(jobInfo.getGlueSwitch()==0?jobInfo.getExecutorHandler():"GLUE任务");
jobLog.setExecutorParam(jobInfo.getExecutorParam()); jobLog.setExecutorParam(jobInfo.getExecutorParam());
logger.info(">>>>>>>>>>> xxl-job failoverTrigger response, jobId:{}, callback:{}", jobLog.getId(), callback); logger.info(">>>>>>>>>>> xxl-job failoverTrigger response, jobId:{}, callback:{}", jobLog.getId(), callback);

View File

@ -14,18 +14,14 @@ public class XxlJobInfo {
private String jobName; // 任务名 private String jobName; // 任务名
private String jobCron; // 任务执行CRON表达式 base on quartz private String jobCron; // 任务执行CRON表达式 base on quartz
private String jobDesc; private String jobDesc;
private String jobClass; // 任务执行JobBean base on quartz
//private String jobData; // 任务执行数据 Map-JSON-String
private Date addTime; private Date addTime;
private Date updateTime; private Date updateTime;
private String author; // 负责人 private String author; // 负责人
private String alarmEmail; // 报警邮件 private String alarmEmail; // 报警邮件
private int alarmThreshold; // 报警阀值
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-
@ -35,6 +31,9 @@ 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;
} }
@ -75,14 +74,6 @@ public class XxlJobInfo {
this.jobDesc = jobDesc; this.jobDesc = jobDesc;
} }
public String getJobClass() {
return jobClass;
}
public void setJobClass(String jobClass) {
this.jobClass = jobClass;
}
public Date getAddTime() { public Date getAddTime() {
return addTime; return addTime;
} }
@ -115,14 +106,6 @@ public class XxlJobInfo {
this.alarmEmail = alarmEmail; this.alarmEmail = alarmEmail;
} }
public int getAlarmThreshold() {
return alarmThreshold;
}
public void setAlarmThreshold(int alarmThreshold) {
this.alarmThreshold = alarmThreshold;
}
public String getExecutorAddress() { public String getExecutorAddress() {
return executorAddress; return executorAddress;
} }
@ -131,14 +114,6 @@ 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;
} }
@ -179,4 +154,12 @@ 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

@ -13,12 +13,8 @@ public class XxlJobLog {
// job info // job info
private String jobGroup; private String jobGroup;
private String jobName; private String jobName;
private String jobCron;
private String jobDesc;
private String jobClass;
private String executorAddress; // 执行器地址有多个则逗号分隔 private String executorAddress; // 执行器地址有多个则逗号分隔
private String executorHandler; // 执行器任务Handler名称
private String executorParam; // 执行器任务参数 private String executorParam; // 执行器任务参数
// trigger info // trigger info
@ -49,36 +45,12 @@ public class XxlJobLog {
public void setJobName(String jobName) { public void setJobName(String jobName) {
this.jobName = jobName; this.jobName = jobName;
} }
public String getJobCron() {
return jobCron;
}
public void setJobCron(String jobCron) {
this.jobCron = jobCron;
}
public String getJobDesc() {
return jobDesc;
}
public void setJobDesc(String jobDesc) {
this.jobDesc = jobDesc;
}
public String getJobClass() {
return jobClass;
}
public void setJobClass(String jobClass) {
this.jobClass = jobClass;
}
public String getExecutorAddress() { public String getExecutorAddress() {
return executorAddress; return executorAddress;
} }
public void setExecutorAddress(String executorAddress) { public void setExecutorAddress(String executorAddress) {
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;
} }

View File

@ -1,21 +1,16 @@
package com.xxl.job.admin.core.thread; package com.xxl.job.admin.core.thread;
import java.text.MessageFormat;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.xxl.job.admin.core.model.XxlJobInfo; import com.xxl.job.admin.core.model.XxlJobInfo;
import com.xxl.job.admin.core.model.XxlJobLog; import com.xxl.job.admin.core.model.XxlJobLog;
import com.xxl.job.admin.core.util.DynamicSchedulerUtil; import com.xxl.job.admin.core.util.DynamicSchedulerUtil;
import com.xxl.job.admin.core.util.MailUtil; import com.xxl.job.admin.core.util.MailUtil;
import com.xxl.job.core.util.HttpUtil.RemoteCallBack; import com.xxl.job.core.util.HttpUtil.RemoteCallBack;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.MessageFormat;
import java.util.concurrent.*;
/** /**
* job monitor helper * job monitor helper
@ -52,18 +47,10 @@ public class JobMonitorHelper {
// pass // pass
} }
if (RemoteCallBack.FAIL.equals(log.getTriggerStatus()) || RemoteCallBack.FAIL.equals(log.getHandleStatus())) { if (RemoteCallBack.FAIL.equals(log.getTriggerStatus()) || RemoteCallBack.FAIL.equals(log.getHandleStatus())) {
String monotorKey = log.getJobGroup().concat("_").concat(log.getJobName());
Integer count = countMap.get(monotorKey);
if (count == null) {
count = new Integer(0);
}
count += 1;
countMap.put(monotorKey, count);
XxlJobInfo info = DynamicSchedulerUtil.xxlJobInfoDao.load(log.getJobGroup(), log.getJobName()); XxlJobInfo info = DynamicSchedulerUtil.xxlJobInfoDao.load(log.getJobGroup(), log.getJobName());
if (count >= info.getAlarmThreshold()) { if (info!=null && info.getAlarmEmail()!=null && info.getAlarmEmail().trim().length()>0) {
MailUtil.sendMail(info.getAlarmEmail(), "《调度平台中心-监控报警》", MailUtil.sendMail(info.getAlarmEmail(), "《调度监控报警-调度平台平台XXL-JOB》",
MessageFormat.format("调度任务[{0}]失败报警,连续失败次数:{1}", monotorKey, count), false, null); MessageFormat.format("任务调度失败, JobKey={0}, 任务描述:{1}.", info.getJobKey(), info.getJobDesc()), false, null);
countMap.remove(monotorKey);
} }
} }
} }

View File

@ -8,6 +8,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import com.xxl.job.admin.core.jobbean.RemoteHttpJobBean;
import org.quartz.CronScheduleBuilder; import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger; import org.quartz.CronTrigger;
import org.quartz.Job; import org.quartz.Job;
@ -130,7 +131,7 @@ public final class DynamicSchedulerUtil implements ApplicationContextAware, Init
JobKey jobKey = new JobKey(jobInfo.getJobName(), jobInfo.getJobGroup()); JobKey jobKey = new JobKey(jobInfo.getJobName(), jobInfo.getJobGroup());
try { try {
Trigger trigger = scheduler.getTrigger(triggerKey); Trigger trigger = scheduler.getTrigger(triggerKey);
JobDetail jobDetail = scheduler.getJobDetail(jobKey);
TriggerState triggerState = scheduler.getTriggerState(triggerKey); TriggerState triggerState = scheduler.getTriggerState(triggerKey);
// parse params // parse params
@ -138,10 +139,10 @@ public final class DynamicSchedulerUtil implements ApplicationContextAware, Init
String cronExpression = ((CronTriggerImpl) trigger).getCronExpression(); String cronExpression = ((CronTriggerImpl) trigger).getCronExpression();
jobInfo.setJobCron(cronExpression); jobInfo.setJobCron(cronExpression);
} }
if (jobDetail!=null) {
String jobClass = jobDetail.getJobClass().getName(); //JobDetail jobDetail = scheduler.getJobDetail(jobKey);
jobInfo.setJobClass(jobClass); //String jobClass = jobDetail.getJobClass().getName();
}
if (triggerState!=null) { if (triggerState!=null) {
jobInfo.setJobStatus(triggerState.name()); jobInfo.setJobStatus(triggerState.name());
} }
@ -175,12 +176,7 @@ public final class DynamicSchedulerUtil implements ApplicationContextAware, Init
CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build(); CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build();
// JobDetail : jobClass // JobDetail : jobClass
Class<? extends Job> jobClass_ = null; Class<? extends Job> jobClass_ = RemoteHttpJobBean.class; // Class.forName(jobInfo.getJobClass());
try {
jobClass_ = (Class<? extends Job>)Class.forName(jobInfo.getJobClass());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
JobDetail jobDetail = JobBuilder.newJob(jobClass_).withIdentity(jobKey).build(); JobDetail jobDetail = JobBuilder.newJob(jobClass_).withIdentity(jobKey).build();
/*if (jobInfo.getJobData()!=null) { /*if (jobInfo.getJobData()!=null) {

View File

@ -14,13 +14,11 @@ 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 jobDesc, String filterTime);
public ReturnT<String> add(String jobGroup, String jobCron, String jobDesc, public ReturnT<String> add(String jobGroup, String jobCron, String jobDesc,
String executorAddress, String executorParam, String executorAddress, String executorParam, String author, String alarmEmail,
String author, String alarmEmail, int alarmThreshold,
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 handler_address, String handler_params, String handler_address, String handler_params, String author, String alarmEmail);
String author, String alarmEmail, int alarmThreshold);
public ReturnT<String> remove(String jobGroup, String jobName); public ReturnT<String> remove(String jobGroup, String jobName);

View File

@ -59,8 +59,7 @@ 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 executorAddress, String executorParam, String executorAddress, String executorParam, String author, String alarmEmail,
String author, String alarmEmail, int alarmThreshold,
int glueSwitch, String glueSource, String glueRemark) { int glueSwitch, String glueSource, String glueRemark) {
// valid // valid
if (JobGroupEnum.match(jobGroup) == null) { if (JobGroupEnum.match(jobGroup) == null) {
@ -81,9 +80,6 @@ public class XxlJobServiceImpl implements IXxlJobService {
if (StringUtils.isBlank(alarmEmail)) { if (StringUtils.isBlank(alarmEmail)) {
return new ReturnT<String>(500, "请输入“报警邮件”"); return new ReturnT<String>(500, "请输入“报警邮件”");
} }
if (alarmThreshold < 0) {
alarmThreshold = 0;
}
// generate jobName // generate jobName
String jobName = FastDateFormat.getInstance("yyyyMMddHHmmssSSSS").format(new Date()); String jobName = FastDateFormat.getInstance("yyyyMMddHHmmssSSSS").format(new Date());
@ -102,10 +98,8 @@ public class XxlJobServiceImpl implements IXxlJobService {
jobInfo.setJobName(jobName); jobInfo.setJobName(jobName);
jobInfo.setJobCron(jobCron); jobInfo.setJobCron(jobCron);
jobInfo.setJobDesc(jobDesc); jobInfo.setJobDesc(jobDesc);
jobInfo.setJobClass(RemoteHttpJobBean.class.getName());
jobInfo.setAuthor(author); jobInfo.setAuthor(author);
jobInfo.setAlarmEmail(alarmEmail); jobInfo.setAlarmEmail(alarmEmail);
jobInfo.setAlarmThreshold(alarmThreshold);
jobInfo.setGlueSwitch(glueSwitch); jobInfo.setGlueSwitch(glueSwitch);
jobInfo.setGlueSource(glueSource); jobInfo.setGlueSource(glueSource);
jobInfo.setGlueRemark(glueRemark); jobInfo.setGlueRemark(glueRemark);
@ -131,7 +125,7 @@ public class XxlJobServiceImpl implements IXxlJobService {
@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 executorAddress, String executorParam, String executorAddress, String executorParam,
String author, String alarmEmail, int alarmThreshold) { String author, String alarmEmail) {
// valid // valid
if (JobGroupEnum.match(jobGroup) == null) { if (JobGroupEnum.match(jobGroup) == null) {
@ -161,7 +155,6 @@ public class XxlJobServiceImpl implements IXxlJobService {
jobInfo.setJobCron(jobCron); jobInfo.setJobCron(jobCron);
jobInfo.setAuthor(author); jobInfo.setAuthor(author);
jobInfo.setAlarmEmail(alarmEmail); jobInfo.setAlarmEmail(alarmEmail);
jobInfo.setAlarmThreshold(alarmThreshold);
jobInfo.setExecutorAddress(executorAddress); jobInfo.setExecutorAddress(executorAddress);
jobInfo.setExecutorParam(executorParam); jobInfo.setExecutorParam(executorParam);

View File

@ -4,7 +4,7 @@ mail.port=25
mail.username=ovono802302@163.com mail.username=ovono802302@163.com
mail.password=asdfzxcv mail.password=asdfzxcv
mail.sendFrom=ovono802302@163.com mail.sendFrom=ovono802302@163.com
mail.sendNick=任务调度中心xxl-job mail.sendNick=调度平台平台XXL-JOB
# for login # for login
login.username=admin login.username=admin

View File

@ -10,17 +10,14 @@
<result column="job_name" property="jobName" /> <result column="job_name" property="jobName" />
<result column="job_cron" property="jobCron" /> <result column="job_cron" property="jobCron" />
<result column="job_desc" property="jobDesc" /> <result column="job_desc" property="jobDesc" />
<result column="job_class" property="jobClass" />
<result column="add_time" property="addTime" /> <result column="add_time" property="addTime" />
<result column="update_time" property="updateTime" /> <result column="update_time" property="updateTime" />
<result column="author" property="author" /> <result column="author" property="author" />
<result column="alarm_email" property="alarmEmail" /> <result column="alarm_email" property="alarmEmail" />
<result column="alarm_threshold" property="alarmThreshold" />
<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" />
@ -34,14 +31,11 @@
t.job_name, t.job_name,
t.job_cron, t.job_cron,
t.job_desc, t.job_desc,
t.job_class,
t.add_time, t.add_time,
t.update_time, t.update_time,
t.author, t.author,
t.alarm_email, t.alarm_email,
t.alarm_threshold,
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,
@ -82,14 +76,11 @@
job_name, job_name,
job_cron, job_cron,
job_desc, job_desc,
job_class,
add_time, add_time,
update_time, update_time,
author, author,
alarm_email, alarm_email,
alarm_threshold,
executor_address, executor_address,
executor_handler,
executor_param, executor_param,
glue_switch, glue_switch,
glue_source, glue_source,
@ -99,14 +90,11 @@
#{jobName}, #{jobName},
#{jobCron}, #{jobCron},
#{jobDesc}, #{jobDesc},
#{jobClass},
NOW(), NOW(),
NOW(), NOW(),
#{author}, #{author},
#{alarmEmail}, #{alarmEmail},
#{alarmThreshold},
#{executorAddress}, #{executorAddress},
#{executorHandler},
#{executorParam}, #{executorParam},
#{glueSwitch}, #{glueSwitch},
#{glueSource}, #{glueSource},
@ -132,9 +120,7 @@
update_time = NOW(), update_time = NOW(),
author = #{author}, author = #{author},
alarm_email = #{alarmEmail}, alarm_email = #{alarmEmail},
alarm_threshold = #{alarmThreshold},
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

@ -8,12 +8,8 @@
<result column="job_group" property="jobGroup" /> <result column="job_group" property="jobGroup" />
<result column="job_name" property="jobName" /> <result column="job_name" property="jobName" />
<result column="job_cron" property="jobCron" />
<result column="job_desc" property="jobDesc" />
<result column="job_class" property="jobClass" />
<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="trigger_time" property="triggerTime" /> <result column="trigger_time" property="triggerTime" />
@ -30,11 +26,7 @@
t.id, t.id,
t.job_group, t.job_group,
t.job_name, t.job_name,
t.job_cron,
t.job_desc,
t.job_class,
t.executor_address, t.executor_address,
t.executor_handler,
t.executor_param, t.executor_param,
t.trigger_time, t.trigger_time,
t.trigger_status, t.trigger_status,
@ -101,20 +93,12 @@
INSERT INTO XXL_JOB_QRTZ_TRIGGER_LOG ( INSERT INTO XXL_JOB_QRTZ_TRIGGER_LOG (
`job_group`, `job_group`,
`job_name`, `job_name`,
`job_cron`,
`job_desc`,
`job_class`,
`executor_address`, `executor_address`,
`executor_handler`,
`executor_param` `executor_param`
) VALUES ( ) VALUES (
#{jobGroup}, #{jobGroup},
#{jobName}, #{jobName},
#{jobCron},
#{jobDesc},
#{jobClass},
#{executorAddress}, #{executorAddress},
#{executorHandler},
#{executorParam} #{executorParam}
); );
<selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id"> <selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id">
@ -129,7 +113,6 @@
`trigger_status`= #{triggerStatus}, `trigger_status`= #{triggerStatus},
`trigger_msg`= #{triggerMsg}, `trigger_msg`= #{triggerMsg},
`executor_address`= #{executorAddress}, `executor_address`= #{executorAddress},
`executor_handler`= #{executorHandler},
`executor_param`= #{executorParam} `executor_param`= #{executorParam}
WHERE `id`= #{id} WHERE `id`= #{id}
</update> </update>

View File

@ -38,7 +38,7 @@
<section class="content"> <section class="content">
<div class="row"> <div class="row">
<div class="col-xs-4"> <div class="col-xs-2">
<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,9 +48,15 @@
</select> </select>
</div> </div>
</div> </div>
<div class="col-xs-4"> <div class="col-xs-3">
<div class="input-group">
<span class="input-group-addon">JobKey</span>
<input type="text" class="form-control" id="JobKey" value="${jobName}" autocomplete="on" >
</div>
</div>
<div class="col-xs-3">
<div class="input-group"> <div class="input-group">
<span class="input-group-addon">名称</span> <span class="input-group-addon">描述</span>
<input type="text" class="form-control" id="jobDesc" value="${jobName}" autocomplete="on" > <input type="text" class="form-control" id="jobDesc" value="${jobName}" autocomplete="on" >
</div> </div>
</div> </div>
@ -75,16 +81,15 @@
<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="jobDesc" >名称</th> <th name="JobKey" >JobKey</th>
<th name="jobDesc" >描述</th>
<th name="jobCron" >Cron</th> <th name="jobCron" >Cron</th>
<th name="jobClass" >JobBean</th>
<th name="executorAddress" >执行器地址</th> <th name="executorAddress" >执行器地址</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>
<th name="author" >负责人</th> <th name="author" >负责人</th>
<th name="alarmEmail" >报警邮件</th> <th name="alarmEmail" >报警邮件</th>
<th name="alarmThreshold" >报警阀值</th>
<th name="glueSwitch" >GLUE模式</th> <th name="glueSwitch" >GLUE模式</th>
<th name="jobStatus" >状态</th> <th name="jobStatus" >状态</th>
<th>操作</th> <th>操作</th>
@ -122,7 +127,7 @@
</#list> </#list>
</select> </select>
</div> </div>
<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="jobDesc" placeholder="请输入“描述”" maxlength="50" ></div> <div class="col-sm-4"><input type="text" class="form-control" name="jobDesc" placeholder="请输入“描述”" maxlength="50" ></div>
</div> </div>
<div class="form-group"> <div class="form-group">
@ -134,16 +139,6 @@
<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">执行参数<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="lastname" class="col-sm-2 control-label">负责人<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="author" placeholder="请输入“负责人”" maxlength="50" ></div>
</div>
<div class="form-group">
<label for="lastname" class="col-sm-2 control-label">报警邮件<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="alarmEmail" placeholder="请输入“报警邮件”,多个邮件地址逗号分隔" maxlength="100" ></div>
<label for="lastname" class="col-sm-2 control-label">报警阈值<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="alarmThreshold" placeholder="请输入“报警阈值”" maxlength="5" ></div>
</div>
<div class="form-group">
<label for="firstname" class="col-sm-2 control-label">任务模式<font color="red">*</font></label> <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" > <select class="form-control" name="glueSwitch" >
@ -151,7 +146,13 @@
<option value="1" >GLUE模式</option> <option value="1" >GLUE模式</option>
</select> </select>
</div> </div>
</div> </div>
<div class="form-group">
<label for="lastname" class="col-sm-2 control-label">报警邮件<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="alarmEmail" placeholder="请输入“报警邮件”,多个邮件地址逗号分隔" maxlength="100" ></div>
<label for="lastname" class="col-sm-2 control-label">负责人<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="author" placeholder="请输入“负责人”" maxlength="50" ></div>
</div>
<hr> <hr>
<div class="form-group"> <div class="form-group">
<div class="col-sm-offset-3 col-sm-6"> <div class="col-sm-offset-3 col-sm-6">
@ -202,7 +203,7 @@ public class DemoJobHandler extends IJobHandler {
<div class="col-sm-4"> <div class="col-sm-4">
<input type="text" class="form-control jobGroupTitle" maxlength="50" readonly > <input type="text" class="form-control jobGroupTitle" maxlength="50" readonly >
</div> </div>
<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="jobDesc" placeholder="请输入“描述”" maxlength="50" ></div> <div class="col-sm-4"><input type="text" class="form-control" name="jobDesc" placeholder="请输入“描述”" maxlength="50" ></div>
</div> </div>
<div class="form-group"> <div class="form-group">
@ -215,21 +216,17 @@ public class DemoJobHandler extends IJobHandler {
<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">执行参数<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="lastname" class="col-sm-2 control-label">负责人<font color="red">*</font></label> <label for="firstname" class="col-sm-2 control-label">任务模式<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="author" placeholder="请输入“负责人”" maxlength="50" ></div> <div class="col-sm-4">
<input type="text" class="form-control glueSwitchTitle" readonly >
</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>
<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>
<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="alarmThreshold" placeholder="请输入“报警阈值”" maxlength="5" ></div> <div class="col-sm-4"><input type="text" class="form-control" name="author" placeholder="请输入“负责人”" maxlength="50" ></div>
</div> </div>
<div class="form-group">
<label for="firstname" class="col-sm-2 control-label">任务模式<font color="red">*</font></label>
<div class="col-sm-4">
<input type="text" class="form-control glueSwitchTitle" readonly >
</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-3">

View File

@ -78,11 +78,7 @@
<th name="id" >id</th> <th name="id" >id</th>
<th name="jobGroup" >任务组</th> <th name="jobGroup" >任务组</th>
<th name="jobName" >任务名</th> <th name="jobName" >任务名</th>
<th name="jobCron" >Cron</th>
<th name="jobDesc" >描述</th>
<th name="jobClass" >JobBean</th>
<th name="executorAddress" >执行器地址</th> <th name="executorAddress" >执行器地址</th>
<th name="executorHandler" >JobHandler</th>
<th name="executorParam" >任务参数</th> <th name="executorParam" >任务参数</th>
<th name="triggerTime" >调度时间</th> <th name="triggerTime" >调度时间</th>
<th name="triggerStatus" >调度结果</th> <th name="triggerStatus" >调度结果</th>

View File

@ -34,10 +34,10 @@ $(function() {
return data; return data;
} }
}, },
{ "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": 'jobClass', "visible" : false},
{ "data": 'executorAddress', "visible" : false}, { "data": 'executorAddress', "visible" : false},
{ "data": 'executorParam', "visible" : false}, { "data": 'executorParam', "visible" : false},
{ {
@ -56,7 +56,6 @@ $(function() {
}, },
{ "data": 'author', "visible" : true}, { "data": 'author', "visible" : true},
{ "data": 'alarmEmail', "visible" : false}, { "data": 'alarmEmail', "visible" : false},
{ "data": 'alarmThreshold', "visible" : false},
{ "data": 'glueSwitch', "visible" : false}, { "data": 'glueSwitch', "visible" : false},
{ {
"data": 'jobStatus', "data": 'jobStatus',
@ -95,14 +94,13 @@ $(function() {
var html = '<p id="'+ row.id +'" '+ var html = '<p id="'+ row.id +'" '+
' jobGroup="'+ row.jobGroup +'" '+ ' jobGroup="'+ row.jobGroup +'" '+
' jobName="'+ row.jobName +'" '+ ' jobName="'+ row.jobName +'" '+
' jobKey="'+ row.jobKey +'" '+
' jobCron="'+ row.jobCron +'" '+ ' jobCron="'+ row.jobCron +'" '+
' jobDesc="'+ row.jobDesc +'" '+ ' jobDesc="'+ row.jobDesc +'" '+
' jobClass="'+ row.jobClass +'" '+
' executorAddress="'+row.executorAddress +'" '+ ' executorAddress="'+row.executorAddress +'" '+
' executorParam="'+ row.executorParam +'" '+ ' executorParam="'+ row.executorParam +'" '+
' author="'+ row.author +'" '+ ' author="'+ row.author +'" '+
' alarmEmail="'+ row.alarmEmail +'" '+ ' alarmEmail="'+ row.alarmEmail +'" '+
' alarmThreshold="'+ row.alarmThreshold +'" '+
' glueSwitch="'+ row.glueSwitch +'" '+ ' glueSwitch="'+ row.glueSwitch +'" '+
'>'+ '>'+
'<button class="btn btn-primary btn-xs job_operate" type="job_trigger" type="button">执行</button> '+ '<button class="btn btn-primary btn-xs job_operate" type="job_trigger" type="button">执行</button> '+
@ -225,10 +223,6 @@ $(function() {
}, },
alarmEmail : { alarmEmail : {
required : true required : true
},
alarmThreshold : {
required : true ,
digits:true
}, },
author : { author : {
required : true required : true
@ -236,7 +230,7 @@ $(function() {
}, },
messages : { messages : {
jobDesc : { jobDesc : {
required :"请输入“名称”." required :"请输入“描述”."
}, },
jobCron : { jobCron : {
required :"请输入“Cron”." required :"请输入“Cron”."
@ -247,10 +241,6 @@ $(function() {
alarmEmail : { alarmEmail : {
required : "请输入“报警邮件”." required : "请输入“报警邮件”."
}, },
alarmThreshold : {
required : "请输入“报警阈值”." ,
digits:"阀值应该为整数."
},
author : { author : {
required : "请输入“负责人”." required : "请输入“负责人”."
} }
@ -294,26 +284,21 @@ $(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='executorAddress']").val($(this).parent('p').attr("executorAddress"));
$("#updateModal .form input[name='executorParam']").val($(this).parent('p').attr("executorParam")); $("#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='alarmThreshold']").val($(this).parent('p').attr("alarmThreshold"));
// 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);
// jobKey
var jobKey = $(this).parent('p').attr("jobGroup") + "_" + $(this).parent('p').attr("jobName");
$("#updateModal .form .jobKey").val(jobKey);
// glueSwitchTitle // glueSwitchTitle
$("#updateModal .form .glueSwitchTitle").val( ($(this).parent('p').attr("glueSwitch") == 0)?"BEAN模式":"GLUE模式" ); $("#updateModal .form .glueSwitchTitle").val( ($(this).parent('p').attr("glueSwitch") == 0)?"BEAN模式":"GLUE模式" );
// show // show
$('#updateModal').modal({backdrop: false, keyboard: false}).modal('show'); $('#updateModal').modal({backdrop: false, keyboard: false}).modal('show');
}); });
@ -336,17 +321,13 @@ $(function() {
alarmEmail : { alarmEmail : {
required : true required : true
}, },
alarmThreshold : {
required : true ,
digits:true
},
author : { author : {
required : true required : true
} }
}, },
messages : { messages : {
jobDesc : { jobDesc : {
required :"请输入“名称”." required :"请输入“描述”."
}, },
jobCron : { jobCron : {
required :"请输入“Cron”." required :"请输入“Cron”."
@ -357,10 +338,6 @@ $(function() {
alarmEmail : { alarmEmail : {
required : "请输入“报警邮件”." required : "请输入“报警邮件”."
}, },
alarmThreshold : {
required : "请输入“报警阈值”." ,
digits:"阀值应该为整数."
},
author : { author : {
required : "请输入“负责人”." required : "请输入“负责人”."
} }

View File

@ -96,12 +96,7 @@ $(function() {
} }
}, },
{ "data": 'jobName', "visible" : false}, { "data": 'jobName', "visible" : false},
{ "data": 'jobCron', "visible" : false},
{ "data": 'jobDesc', "visible" : false},
{ "data": 'jobClass', "visible" : false},
{ "data": 'executorAddress', "visible" : true}, { "data": 'executorAddress', "visible" : true},
{ "data": 'executorHandler', "visible" : true},
{ "data": 'executorParam', "visible" : true}, { "data": 'executorParam', "visible" : true},
{ {
"data": 'triggerTime', "data": 'triggerTime',

View File

@ -33,7 +33,6 @@ public class XxlJobInfoTest {
XxlJobInfo info = new XxlJobInfo(); XxlJobInfo info = new XxlJobInfo();
info.setJobName("job_name"); info.setJobName("job_name");
info.setJobCron("jobCron"); info.setJobCron("jobCron");
info.setJobClass("jobClass");
int count = xxlJobInfoDao.save(info); int count = xxlJobInfoDao.save(info);
System.out.println(count); System.out.println(count);
System.out.println(info.getId()); System.out.println(info.getId());

View File

@ -26,8 +26,6 @@ public class XxlJobLogTest {
public void save_load(){ public void save_load(){
XxlJobLog xxlJobLog = new XxlJobLog(); XxlJobLog xxlJobLog = new XxlJobLog();
xxlJobLog.setJobName("job_name"); xxlJobLog.setJobName("job_name");
xxlJobLog.setJobCron("jobCron");
xxlJobLog.setJobClass("jobClass");
int count = xxlJobLogDao.save(xxlJobLog); int count = xxlJobLogDao.save(xxlJobLog);
System.out.println(count); System.out.println(count);
System.out.println(xxlJobLog.getId()); System.out.println(xxlJobLog.getId());

View File

@ -20,7 +20,7 @@ import com.xxl.job.core.handler.annotation.JobHander;
* *
* @author xuxueli 2015-12-19 19:43:36 * @author xuxueli 2015-12-19 19:43:36
*/ */
@JobHander(value="defaults_201607192256270689,defaults_201607192256270689") @JobHander(value="waimai_201607202316260736,waimai_201607202316260736")
@Service @Service
public class DemoJobHandler extends IJobHandler { public class DemoJobHandler extends IJobHandler {
private static transient Logger logger = LoggerFactory.getLogger(DemoJobHandler.class); private static transient Logger logger = LoggerFactory.getLogger(DemoJobHandler.class);