diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobInfoController.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobInfoController.java index fefb5ab2..3a889fa8 100644 --- a/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobInfoController.java +++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobInfoController.java @@ -1,95 +1,95 @@ -package com.xxl.job.admin.controller; - -import com.xxl.job.admin.core.model.XxlJobGroup; -import com.xxl.job.admin.core.model.XxlJobInfo; -import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum; -import com.xxl.job.admin.dao.XxlJobGroupDao; -import com.xxl.job.admin.service.XxlJobService; -import com.xxl.job.core.biz.model.ReturnT; -import com.xxl.job.core.enums.ExecutorBlockStrategyEnum; -import com.xxl.job.core.glue.GlueTypeEnum; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseBody; - -import javax.annotation.Resource; -import java.util.List; -import java.util.Map; - -/** - * index controller - * @author xuxueli 2015-12-19 16:13:16 - */ -@Controller -@RequestMapping("/jobinfo") -public class JobInfoController { - - @Resource - private XxlJobGroupDao xxlJobGroupDao; - @Resource - private XxlJobService xxlJobService; - - @RequestMapping - public String index(Model model, @RequestParam(required = false, defaultValue = "-1") int jobGroup) { - - // 枚举-字典 - model.addAttribute("ExecutorRouteStrategyEnum", ExecutorRouteStrategyEnum.values()); // 路由策略-列表 - model.addAttribute("GlueTypeEnum", GlueTypeEnum.values()); // Glue类型-字典 - model.addAttribute("ExecutorBlockStrategyEnum", ExecutorBlockStrategyEnum.values()); // 阻塞处理策略-字典 - - // 任务组 - List jobGroupList = xxlJobGroupDao.findAll(); - model.addAttribute("JobGroupList", jobGroupList); - model.addAttribute("jobGroup", jobGroup); - - return "jobinfo/jobinfo.index"; - } - - @RequestMapping("/pageList") - @ResponseBody - public Map pageList(@RequestParam(required = false, defaultValue = "0") int start, - @RequestParam(required = false, defaultValue = "10") int length, - int jobGroup, String jobDesc, String executorHandler, String filterTime) { - - return xxlJobService.pageList(start, length, jobGroup, jobDesc, executorHandler, filterTime); - } - - @RequestMapping("/add") - @ResponseBody - public ReturnT add(XxlJobInfo jobInfo) { - return xxlJobService.add(jobInfo); - } - - @RequestMapping("/update") - @ResponseBody - public ReturnT update(XxlJobInfo jobInfo) { - return xxlJobService.update(jobInfo); - } - - @RequestMapping("/remove") - @ResponseBody - public ReturnT remove(int id) { - return xxlJobService.remove(id); - } - - @RequestMapping("/pause") - @ResponseBody - public ReturnT pause(int id) { - return xxlJobService.pause(id); - } - - @RequestMapping("/resume") - @ResponseBody - public ReturnT resume(int id) { - return xxlJobService.resume(id); - } - - @RequestMapping("/trigger") - @ResponseBody - public ReturnT triggerJob(int id) { - return xxlJobService.triggerJob(id); - } - -} +package com.xxl.job.admin.controller; + +import com.xxl.job.admin.core.model.XxlJobGroup; +import com.xxl.job.admin.core.model.XxlJobInfo; +import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum; +import com.xxl.job.admin.dao.XxlJobGroupDao; +import com.xxl.job.admin.service.XxlJobService; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.enums.ExecutorBlockStrategyEnum; +import com.xxl.job.core.glue.GlueTypeEnum; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Map; + +/** + * index controller + * @author xuxueli 2015-12-19 16:13:16 + */ +@Controller +@RequestMapping("/jobinfo") +public class JobInfoController { + + @Resource + private XxlJobGroupDao xxlJobGroupDao; + @Resource + private XxlJobService xxlJobService; + + @RequestMapping + public String index(Model model, @RequestParam(required = false, defaultValue = "-1") int jobGroup) { + + // 枚举-字典 + model.addAttribute("ExecutorRouteStrategyEnum", ExecutorRouteStrategyEnum.values()); // 路由策略-列表 + model.addAttribute("GlueTypeEnum", GlueTypeEnum.values()); // Glue类型-字典 + model.addAttribute("ExecutorBlockStrategyEnum", ExecutorBlockStrategyEnum.values()); // 阻塞处理策略-字典 + + // 任务组 + List jobGroupList = xxlJobGroupDao.findAll(); + model.addAttribute("JobGroupList", jobGroupList); + model.addAttribute("jobGroup", jobGroup); + + return "jobinfo/jobinfo.index"; + } + + @RequestMapping("/pageList") + @ResponseBody + public Map pageList(@RequestParam(required = false, defaultValue = "0") int start, + @RequestParam(required = false, defaultValue = "10") int length, + int jobGroup, String jobDesc, String executorHandler, String filterTime) { + + return xxlJobService.pageList(start, length, jobGroup, jobDesc, executorHandler, filterTime); + } + + @RequestMapping("/add") + @ResponseBody + public ReturnT add(XxlJobInfo jobInfo) { + return xxlJobService.add(jobInfo); + } + + @RequestMapping("/update") + @ResponseBody + public ReturnT update(XxlJobInfo jobInfo) { + return xxlJobService.update(jobInfo); + } + + @RequestMapping("/remove") + @ResponseBody + public ReturnT remove(int id) { + return xxlJobService.remove(id); + } + + @RequestMapping("/pause") + @ResponseBody + public ReturnT pause(int id) { + return xxlJobService.pause(id); + } + + @RequestMapping("/resume") + @ResponseBody + public ReturnT resume(int id) { + return xxlJobService.resume(id); + } + + @RequestMapping("/trigger") + @ResponseBody + public ReturnT triggerJob(int id) { + return xxlJobService.triggerJob(id); + } + +} diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobInfo.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobInfo.java index 67a9c1fc..2a0ce1c1 100644 --- a/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobInfo.java +++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobInfo.java @@ -1,211 +1,211 @@ -package com.xxl.job.admin.core.model; - -import java.util.Date; - -/** - * xxl-job info - * - * @author xuxueli 2016-1-12 18:25:49 - */ -public class XxlJobInfo { - - private int id; // 主键ID (JobKey.name) - - private int jobGroup; // 执行器主键ID (JobKey.group) - private String jobCron; // 任务执行CRON表达式 【base on quartz】 - private String jobDesc; - - private Date addTime; - private Date updateTime; - - private String author; // 负责人 - private String alarmEmail; // 报警邮件 - - private String executorRouteStrategy; // 执行器路由策略 - private String executorHandler; // 执行器,任务Handler名称 - private String executorParam; // 执行器,任务参数 - private String executorBlockStrategy; // 阻塞处理策略 - private String executorFailStrategy; // 失败处理策略 - private int executorTimeout; // 任务执行超时时间,单位秒 - private int executorFailRetryCount; // 失败重试次数 - - private String glueType; // GLUE类型 #com.xxl.job.core.glue.GlueTypeEnum - private String glueSource; // GLUE源代码 - private String glueRemark; // GLUE备注 - private Date glueUpdatetime; // GLUE更新时间 - - private String childJobId; // 子任务ID,多个逗号分隔 - - // copy from quartz - private String jobStatus; // 任务状态 【base on quartz】 - - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public int getJobGroup() { - return jobGroup; - } - - public void setJobGroup(int jobGroup) { - this.jobGroup = jobGroup; - } - - 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 Date getAddTime() { - return addTime; - } - - public void setAddTime(Date addTime) { - this.addTime = addTime; - } - - public Date getUpdateTime() { - return updateTime; - } - - public void setUpdateTime(Date updateTime) { - this.updateTime = updateTime; - } - - public String getAuthor() { - return author; - } - - public void setAuthor(String author) { - this.author = author; - } - - public String getAlarmEmail() { - return alarmEmail; - } - - public void setAlarmEmail(String alarmEmail) { - this.alarmEmail = alarmEmail; - } - - public String getExecutorRouteStrategy() { - return executorRouteStrategy; - } - - public void setExecutorRouteStrategy(String executorRouteStrategy) { - this.executorRouteStrategy = executorRouteStrategy; - } - - public String getExecutorHandler() { - return executorHandler; - } - - public void setExecutorHandler(String executorHandler) { - this.executorHandler = executorHandler; - } - - public String getExecutorParam() { - return executorParam; - } - - public void setExecutorParam(String executorParam) { - this.executorParam = executorParam; - } - - public String getExecutorBlockStrategy() { - return executorBlockStrategy; - } - - public void setExecutorBlockStrategy(String executorBlockStrategy) { - this.executorBlockStrategy = executorBlockStrategy; - } - - public String getExecutorFailStrategy() { - return executorFailStrategy; - } - - public void setExecutorFailStrategy(String executorFailStrategy) { - this.executorFailStrategy = executorFailStrategy; - } - - public int getExecutorTimeout() { - return executorTimeout; - } - - public void setExecutorTimeout(int executorTimeout) { - this.executorTimeout = executorTimeout; - } - - public int getExecutorFailRetryCount() { - return executorFailRetryCount; - } - - public void setExecutorFailRetryCount(int executorFailRetryCount) { - this.executorFailRetryCount = executorFailRetryCount; - } - - public String getGlueType() { - return glueType; - } - - public void setGlueType(String glueType) { - this.glueType = glueType; - } - - public String getGlueSource() { - return glueSource; - } - - public void setGlueSource(String glueSource) { - this.glueSource = glueSource; - } - - public String getGlueRemark() { - return glueRemark; - } - - public void setGlueRemark(String glueRemark) { - this.glueRemark = glueRemark; - } - - public Date getGlueUpdatetime() { - return glueUpdatetime; - } - - public void setGlueUpdatetime(Date glueUpdatetime) { - this.glueUpdatetime = glueUpdatetime; - } - - public String getChildJobId() { - return childJobId; - } - - public void setChildJobId(String childJobId) { - this.childJobId = childJobId; - } - - public String getJobStatus() { - return jobStatus; - } - - public void setJobStatus(String jobStatus) { - this.jobStatus = jobStatus; - } - -} +package com.xxl.job.admin.core.model; + +import java.util.Date; + +/** + * xxl-job info + * + * @author xuxueli 2016-1-12 18:25:49 + */ +public class XxlJobInfo { + + private int id; // 主键ID (JobKey.name) + + private int jobGroup; // 执行器主键ID (JobKey.group) + private String jobCron; // 任务执行CRON表达式 【base on quartz】 + private String jobDesc; + + private Date addTime; + private Date updateTime; + + private String author; // 负责人 + private String alarmEmail; // 报警邮件 + + private String executorRouteStrategy; // 执行器路由策略 + private String executorHandler; // 执行器,任务Handler名称 + private String executorParam; // 执行器,任务参数 + private String executorBlockStrategy; // 阻塞处理策略 + private String executorFailStrategy; // 失败处理策略 + private int executorTimeout; // 任务执行超时时间,单位秒 + private int executorFailRetryCount; // 失败重试次数 + + private String glueType; // GLUE类型 #com.xxl.job.core.glue.GlueTypeEnum + private String glueSource; // GLUE源代码 + private String glueRemark; // GLUE备注 + private Date glueUpdatetime; // GLUE更新时间 + + private String childJobId; // 子任务ID,多个逗号分隔 + + // copy from quartz + private String jobStatus; // 任务状态 【base on quartz】 + + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getJobGroup() { + return jobGroup; + } + + public void setJobGroup(int jobGroup) { + this.jobGroup = jobGroup; + } + + 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 Date getAddTime() { + return addTime; + } + + public void setAddTime(Date addTime) { + this.addTime = addTime; + } + + public Date getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(Date updateTime) { + this.updateTime = updateTime; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getAlarmEmail() { + return alarmEmail; + } + + public void setAlarmEmail(String alarmEmail) { + this.alarmEmail = alarmEmail; + } + + public String getExecutorRouteStrategy() { + return executorRouteStrategy; + } + + public void setExecutorRouteStrategy(String executorRouteStrategy) { + this.executorRouteStrategy = executorRouteStrategy; + } + + public String getExecutorHandler() { + return executorHandler; + } + + public void setExecutorHandler(String executorHandler) { + this.executorHandler = executorHandler; + } + + public String getExecutorParam() { + return executorParam; + } + + public void setExecutorParam(String executorParam) { + this.executorParam = executorParam; + } + + public String getExecutorBlockStrategy() { + return executorBlockStrategy; + } + + public void setExecutorBlockStrategy(String executorBlockStrategy) { + this.executorBlockStrategy = executorBlockStrategy; + } + + public String getExecutorFailStrategy() { + return executorFailStrategy; + } + + public void setExecutorFailStrategy(String executorFailStrategy) { + this.executorFailStrategy = executorFailStrategy; + } + + public int getExecutorTimeout() { + return executorTimeout; + } + + public void setExecutorTimeout(int executorTimeout) { + this.executorTimeout = executorTimeout; + } + + public int getExecutorFailRetryCount() { + return executorFailRetryCount; + } + + public void setExecutorFailRetryCount(int executorFailRetryCount) { + this.executorFailRetryCount = executorFailRetryCount; + } + + public String getGlueType() { + return glueType; + } + + public void setGlueType(String glueType) { + this.glueType = glueType; + } + + public String getGlueSource() { + return glueSource; + } + + public void setGlueSource(String glueSource) { + this.glueSource = glueSource; + } + + public String getGlueRemark() { + return glueRemark; + } + + public void setGlueRemark(String glueRemark) { + this.glueRemark = glueRemark; + } + + public Date getGlueUpdatetime() { + return glueUpdatetime; + } + + public void setGlueUpdatetime(Date glueUpdatetime) { + this.glueUpdatetime = glueUpdatetime; + } + + public String getChildJobId() { + return childJobId; + } + + public void setChildJobId(String childJobId) { + this.childJobId = childJobId; + } + + public String getJobStatus() { + return jobStatus; + } + + public void setJobStatus(String jobStatus) { + this.jobStatus = jobStatus; + } + +} diff --git a/xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java b/xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java index 56b53c6f..2f597794 100644 --- a/xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java +++ b/xxl-job-admin/src/main/java/com/xxl/job/admin/service/impl/XxlJobServiceImpl.java @@ -1,385 +1,385 @@ -package com.xxl.job.admin.service.impl; - -import com.xxl.job.admin.core.model.XxlJobGroup; -import com.xxl.job.admin.core.model.XxlJobInfo; -import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum; -import com.xxl.job.admin.core.schedule.XxlJobDynamicScheduler; -import com.xxl.job.admin.core.thread.JobTriggerPoolHelper; -import com.xxl.job.admin.core.util.I18nUtil; -import com.xxl.job.admin.dao.XxlJobGroupDao; -import com.xxl.job.admin.dao.XxlJobInfoDao; -import com.xxl.job.admin.dao.XxlJobLogDao; -import com.xxl.job.admin.dao.XxlJobLogGlueDao; -import com.xxl.job.admin.service.XxlJobService; -import com.xxl.job.core.biz.model.ReturnT; -import com.xxl.job.core.enums.ExecutorBlockStrategyEnum; -import com.xxl.job.core.glue.GlueTypeEnum; -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.time.DateUtils; -import org.apache.commons.lang3.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.text.MessageFormat; -import java.util.*; - -/** - * core job action for xxl-job - * @author xuxueli 2016-5-28 15:30:33 - */ -@Service -public class XxlJobServiceImpl implements XxlJobService { - private static Logger logger = LoggerFactory.getLogger(XxlJobServiceImpl.class); - - @Resource - private XxlJobGroupDao xxlJobGroupDao; - @Resource - private XxlJobInfoDao xxlJobInfoDao; - @Resource - public XxlJobLogDao xxlJobLogDao; - @Resource - private XxlJobLogGlueDao xxlJobLogGlueDao; - - @Override - public Map pageList(int start, int length, int jobGroup, String jobDesc, String executorHandler, String filterTime) { - - // page list - List list = xxlJobInfoDao.pageList(start, length, jobGroup, jobDesc, executorHandler); - int list_count = xxlJobInfoDao.pageListCount(start, length, jobGroup, jobDesc, executorHandler); - - // fill job info - if (list!=null && list.size()>0) { - for (XxlJobInfo jobInfo : list) { - XxlJobDynamicScheduler.fillJobInfo(jobInfo); - } - } - - // package result - Map maps = new HashMap(); - maps.put("recordsTotal", list_count); // 总记录数 - maps.put("recordsFiltered", list_count); // 过滤后的总记录数 - maps.put("data", list); // 分页列表 - return maps; - } - - @Override - public ReturnT add(XxlJobInfo jobInfo) { - // valid - XxlJobGroup group = xxlJobGroupDao.load(jobInfo.getJobGroup()); - if (group == null) { - return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_choose")+I18nUtil.getString("jobinfo_field_jobgroup")) ); - } - if (!CronExpression.isValidExpression(jobInfo.getJobCron())) { - return new ReturnT(ReturnT.FAIL_CODE, I18nUtil.getString("jobinfo_field_cron_unvalid") ); - } - if (StringUtils.isBlank(jobInfo.getJobDesc())) { - return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input")+I18nUtil.getString("jobinfo_field_jobdesc")) ); - } - if (StringUtils.isBlank(jobInfo.getAuthor())) { - return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input")+I18nUtil.getString("jobinfo_field_author")) ); - } - if (ExecutorRouteStrategyEnum.match(jobInfo.getExecutorRouteStrategy(), null) == null) { - return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorRouteStrategy")+I18nUtil.getString("system_unvalid")) ); - } - if (ExecutorBlockStrategyEnum.match(jobInfo.getExecutorBlockStrategy(), null) == null) { - return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorBlockStrategy")+I18nUtil.getString("system_unvalid")) ); - } - if (GlueTypeEnum.match(jobInfo.getGlueType()) == null) { - return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_gluetype")+I18nUtil.getString("system_unvalid")) ); - } - if (GlueTypeEnum.BEAN==GlueTypeEnum.match(jobInfo.getGlueType()) && StringUtils.isBlank(jobInfo.getExecutorHandler())) { - return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input")+"JobHandler") ); - } - - // fix "\r" in shell - if (GlueTypeEnum.GLUE_SHELL==GlueTypeEnum.match(jobInfo.getGlueType()) && jobInfo.getGlueSource()!=null) { - jobInfo.setGlueSource(jobInfo.getGlueSource().replaceAll("\r", "")); - } - - // ChildJobId valid - if (StringUtils.isNotBlank(jobInfo.getChildJobId())) { - String[] childJobIds = StringUtils.split(jobInfo.getChildJobId(), ","); - for (String childJobIdItem: childJobIds) { - if (StringUtils.isNotBlank(childJobIdItem) && StringUtils.isNumeric(childJobIdItem)) { - XxlJobInfo childJobInfo = xxlJobInfoDao.loadById(Integer.valueOf(childJobIdItem)); - if (childJobInfo==null) { - return new ReturnT(ReturnT.FAIL_CODE, - MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId")+"({0})"+I18nUtil.getString("system_not_found")), childJobIdItem)); - } - } else { - return new ReturnT(ReturnT.FAIL_CODE, - MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId")+"({0})"+I18nUtil.getString("system_unvalid")), childJobIdItem)); - } - } - jobInfo.setChildJobId(StringUtils.join(childJobIds, ",")); - } - - // add in db - xxlJobInfoDao.save(jobInfo); - if (jobInfo.getId() < 1) { - return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_add")+I18nUtil.getString("system_fail")) ); - } - - // add in quartz - String qz_group = String.valueOf(jobInfo.getJobGroup()); - String qz_name = String.valueOf(jobInfo.getId()); - try { - XxlJobDynamicScheduler.addJob(qz_name, qz_group, jobInfo.getJobCron()); - //XxlJobDynamicScheduler.pauseJob(qz_name, qz_group); - return ReturnT.SUCCESS; - } catch (SchedulerException e) { - logger.error(e.getMessage(), e); - try { - xxlJobInfoDao.delete(jobInfo.getId()); - XxlJobDynamicScheduler.removeJob(qz_name, qz_group); - } catch (SchedulerException e1) { - logger.error(e.getMessage(), e1); - } - return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_add")+I18nUtil.getString("system_fail"))+":" + e.getMessage()); - } - } - - @Override - public ReturnT update(XxlJobInfo jobInfo) { - - // valid - if (!CronExpression.isValidExpression(jobInfo.getJobCron())) { - return new ReturnT(ReturnT.FAIL_CODE, I18nUtil.getString("jobinfo_field_cron_unvalid") ); - } - if (StringUtils.isBlank(jobInfo.getJobDesc())) { - return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input")+I18nUtil.getString("jobinfo_field_jobdesc")) ); - } - if (StringUtils.isBlank(jobInfo.getAuthor())) { - return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input")+I18nUtil.getString("jobinfo_field_author")) ); - } - if (ExecutorRouteStrategyEnum.match(jobInfo.getExecutorRouteStrategy(), null) == null) { - return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorRouteStrategy")+I18nUtil.getString("system_unvalid")) ); - } - if (ExecutorBlockStrategyEnum.match(jobInfo.getExecutorBlockStrategy(), null) == null) { - return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorBlockStrategy")+I18nUtil.getString("system_unvalid")) ); - } - - // ChildJobId valid - if (StringUtils.isNotBlank(jobInfo.getChildJobId())) { - String[] childJobIds = StringUtils.split(jobInfo.getChildJobId(), ","); - for (String childJobIdItem: childJobIds) { - if (StringUtils.isNotBlank(childJobIdItem) && StringUtils.isNumeric(childJobIdItem)) { - XxlJobInfo childJobInfo = xxlJobInfoDao.loadById(Integer.valueOf(childJobIdItem)); - if (childJobInfo==null) { - return new ReturnT(ReturnT.FAIL_CODE, - MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId")+"({0})"+I18nUtil.getString("system_not_found")), childJobIdItem)); - } - // avoid cycle relate - if (childJobInfo.getId() == jobInfo.getId()) { - return new ReturnT(ReturnT.FAIL_CODE, MessageFormat.format(I18nUtil.getString("jobinfo_field_childJobId_limit"), childJobIdItem)); - } - } else { - return new ReturnT(ReturnT.FAIL_CODE, - MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId")+"({0})"+I18nUtil.getString("system_unvalid")), childJobIdItem)); - } - } - jobInfo.setChildJobId(StringUtils.join(childJobIds, ",")); - } - - // stage job info - XxlJobInfo exists_jobInfo = xxlJobInfoDao.loadById(jobInfo.getId()); - if (exists_jobInfo == null) { - return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_id")+I18nUtil.getString("system_not_found")) ); - } - //String old_cron = exists_jobInfo.getJobCron(); - - exists_jobInfo.setJobCron(jobInfo.getJobCron()); - exists_jobInfo.setJobDesc(jobInfo.getJobDesc()); - exists_jobInfo.setAuthor(jobInfo.getAuthor()); - exists_jobInfo.setAlarmEmail(jobInfo.getAlarmEmail()); - exists_jobInfo.setExecutorRouteStrategy(jobInfo.getExecutorRouteStrategy()); - exists_jobInfo.setExecutorHandler(jobInfo.getExecutorHandler()); - exists_jobInfo.setExecutorParam(jobInfo.getExecutorParam()); - exists_jobInfo.setExecutorBlockStrategy(jobInfo.getExecutorBlockStrategy()); - exists_jobInfo.setExecutorFailStrategy(jobInfo.getExecutorFailStrategy()); - exists_jobInfo.setExecutorTimeout(jobInfo.getExecutorTimeout()); - exists_jobInfo.setExecutorFailRetryCount(jobInfo.getExecutorFailRetryCount()); - exists_jobInfo.setChildJobId(jobInfo.getChildJobId()); - xxlJobInfoDao.update(exists_jobInfo); - - // fresh quartz - String qz_group = String.valueOf(exists_jobInfo.getJobGroup()); - String qz_name = String.valueOf(exists_jobInfo.getId()); - try { - boolean ret = XxlJobDynamicScheduler.rescheduleJob(qz_group, qz_name, exists_jobInfo.getJobCron()); - return ret?ReturnT.SUCCESS:ReturnT.FAIL; - } catch (SchedulerException e) { - logger.error(e.getMessage(), e); - } - - return ReturnT.FAIL; - } - - @Override - public ReturnT remove(int id) { - XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id); - String group = String.valueOf(xxlJobInfo.getJobGroup()); - String name = String.valueOf(xxlJobInfo.getId()); - - try { - XxlJobDynamicScheduler.removeJob(name, group); - xxlJobInfoDao.delete(id); - xxlJobLogDao.delete(id); - xxlJobLogGlueDao.deleteByJobId(id); - return ReturnT.SUCCESS; - } catch (SchedulerException e) { - logger.error(e.getMessage(), e); - } - return ReturnT.FAIL; - } - - @Override - public ReturnT pause(int id) { - XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id); - String group = String.valueOf(xxlJobInfo.getJobGroup()); - String name = String.valueOf(xxlJobInfo.getId()); - - try { - boolean ret = XxlJobDynamicScheduler.pauseJob(name, group); // jobStatus do not store - return ret?ReturnT.SUCCESS:ReturnT.FAIL; - } catch (SchedulerException e) { - logger.error(e.getMessage(), e); - return ReturnT.FAIL; - } - } - - @Override - public ReturnT resume(int id) { - XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id); - String group = String.valueOf(xxlJobInfo.getJobGroup()); - String name = String.valueOf(xxlJobInfo.getId()); - - try { - boolean ret = XxlJobDynamicScheduler.resumeJob(name, group); - return ret?ReturnT.SUCCESS:ReturnT.FAIL; - } catch (SchedulerException e) { - logger.error(e.getMessage(), e); - return ReturnT.FAIL; - } - } - - @Override - public ReturnT triggerJob(int id) { - - JobTriggerPoolHelper.trigger(id); - return ReturnT.SUCCESS; - - /*XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id); - if (xxlJobInfo == null) { - return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_id")+I18nUtil.getString("system_unvalid")) ); - } - - String group = String.valueOf(xxlJobInfo.getJobGroup()); - String name = String.valueOf(xxlJobInfo.getId()); - - try { - XxlJobDynamicScheduler.triggerJob(name, group); - return ReturnT.SUCCESS; - } catch (SchedulerException e) { - logger.error(e.getMessage(), e); - return new ReturnT(ReturnT.FAIL_CODE, e.getMessage()); - }*/ - - } - - @Override - public Map dashboardInfo() { - - int jobInfoCount = xxlJobInfoDao.findAllCount(); - int jobLogCount = xxlJobLogDao.triggerCountByHandleCode(-1); - int jobLogSuccessCount = xxlJobLogDao.triggerCountByHandleCode(ReturnT.SUCCESS_CODE); - - // executor count - Set executerAddressSet = new HashSet(); - List groupList = xxlJobGroupDao.findAll(); - - if (CollectionUtils.isNotEmpty(groupList)) { - for (XxlJobGroup group: groupList) { - if (CollectionUtils.isNotEmpty(group.getRegistryList())) { - executerAddressSet.addAll(group.getRegistryList()); - } - } - } - - int executorCount = executerAddressSet.size(); - - Map dashboardMap = new HashMap(); - dashboardMap.put("jobInfoCount", jobInfoCount); - dashboardMap.put("jobLogCount", jobLogCount); - dashboardMap.put("jobLogSuccessCount", jobLogSuccessCount); - dashboardMap.put("executorCount", executorCount); - return dashboardMap; - } - - private static final String TRIGGER_CHART_DATA_CACHE = "trigger_chart_data_cache"; - @Override - public ReturnT> chartInfo(Date startDate, Date endDate) { - /*// get cache - String cacheKey = TRIGGER_CHART_DATA_CACHE + "_" + startDate.getTime() + "_" + endDate.getTime(); - Map chartInfo = (Map) LocalCacheUtil.get(cacheKey); - if (chartInfo != null) { - return new ReturnT>(chartInfo); - }*/ - - // process - List triggerDayList = new ArrayList(); - List triggerDayCountRunningList = new ArrayList(); - List triggerDayCountSucList = new ArrayList(); - List triggerDayCountFailList = new ArrayList(); - int triggerCountRunningTotal = 0; - int triggerCountSucTotal = 0; - int triggerCountFailTotal = 0; - - List> triggerCountMapAll = xxlJobLogDao.triggerCountByDay(startDate, endDate); - if (CollectionUtils.isNotEmpty(triggerCountMapAll)) { - for (Map item: triggerCountMapAll) { - String day = String.valueOf(item.get("triggerDay")); - int triggerDayCount = Integer.valueOf(String.valueOf(item.get("triggerDayCount"))); - int triggerDayCountRunning = Integer.valueOf(String.valueOf(item.get("triggerDayCountRunning"))); - int triggerDayCountSuc = Integer.valueOf(String.valueOf(item.get("triggerDayCountSuc"))); - int triggerDayCountFail = triggerDayCount - triggerDayCountRunning - triggerDayCountSuc; - - triggerDayList.add(day); - triggerDayCountRunningList.add(triggerDayCountRunning); - triggerDayCountSucList.add(triggerDayCountSuc); - triggerDayCountFailList.add(triggerDayCountFail); - - triggerCountRunningTotal += triggerDayCountRunning; - triggerCountSucTotal += triggerDayCountSuc; - triggerCountFailTotal += triggerDayCountFail; - } - } else { - for (int i = 4; i > -1; i--) { - triggerDayList.add(FastDateFormat.getInstance("yyyy-MM-dd").format(DateUtils.addDays(new Date(), -i))); - triggerDayCountSucList.add(0); - triggerDayCountFailList.add(0); - } - } - - Map result = new HashMap(); - result.put("triggerDayList", triggerDayList); - result.put("triggerDayCountRunningList", triggerDayCountRunningList); - result.put("triggerDayCountSucList", triggerDayCountSucList); - result.put("triggerDayCountFailList", triggerDayCountFailList); - - result.put("triggerCountRunningTotal", triggerCountRunningTotal); - result.put("triggerCountSucTotal", triggerCountSucTotal); - result.put("triggerCountFailTotal", triggerCountFailTotal); - - /*// set cache - LocalCacheUtil.set(cacheKey, result, 60*1000); // cache 60s*/ - - return new ReturnT>(result); - } - -} +package com.xxl.job.admin.service.impl; + +import com.xxl.job.admin.core.model.XxlJobGroup; +import com.xxl.job.admin.core.model.XxlJobInfo; +import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum; +import com.xxl.job.admin.core.schedule.XxlJobDynamicScheduler; +import com.xxl.job.admin.core.thread.JobTriggerPoolHelper; +import com.xxl.job.admin.core.util.I18nUtil; +import com.xxl.job.admin.dao.XxlJobGroupDao; +import com.xxl.job.admin.dao.XxlJobInfoDao; +import com.xxl.job.admin.dao.XxlJobLogDao; +import com.xxl.job.admin.dao.XxlJobLogGlueDao; +import com.xxl.job.admin.service.XxlJobService; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.enums.ExecutorBlockStrategyEnum; +import com.xxl.job.core.glue.GlueTypeEnum; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.DateUtils; +import org.apache.commons.lang3.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.text.MessageFormat; +import java.util.*; + +/** + * core job action for xxl-job + * @author xuxueli 2016-5-28 15:30:33 + */ +@Service +public class XxlJobServiceImpl implements XxlJobService { + private static Logger logger = LoggerFactory.getLogger(XxlJobServiceImpl.class); + + @Resource + private XxlJobGroupDao xxlJobGroupDao; + @Resource + private XxlJobInfoDao xxlJobInfoDao; + @Resource + public XxlJobLogDao xxlJobLogDao; + @Resource + private XxlJobLogGlueDao xxlJobLogGlueDao; + + @Override + public Map pageList(int start, int length, int jobGroup, String jobDesc, String executorHandler, String filterTime) { + + // page list + List list = xxlJobInfoDao.pageList(start, length, jobGroup, jobDesc, executorHandler); + int list_count = xxlJobInfoDao.pageListCount(start, length, jobGroup, jobDesc, executorHandler); + + // fill job info + if (list!=null && list.size()>0) { + for (XxlJobInfo jobInfo : list) { + XxlJobDynamicScheduler.fillJobInfo(jobInfo); + } + } + + // package result + Map maps = new HashMap(); + maps.put("recordsTotal", list_count); // 总记录数 + maps.put("recordsFiltered", list_count); // 过滤后的总记录数 + maps.put("data", list); // 分页列表 + return maps; + } + + @Override + public ReturnT add(XxlJobInfo jobInfo) { + // valid + XxlJobGroup group = xxlJobGroupDao.load(jobInfo.getJobGroup()); + if (group == null) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_choose")+I18nUtil.getString("jobinfo_field_jobgroup")) ); + } + if (!CronExpression.isValidExpression(jobInfo.getJobCron())) { + return new ReturnT(ReturnT.FAIL_CODE, I18nUtil.getString("jobinfo_field_cron_unvalid") ); + } + if (StringUtils.isBlank(jobInfo.getJobDesc())) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input")+I18nUtil.getString("jobinfo_field_jobdesc")) ); + } + if (StringUtils.isBlank(jobInfo.getAuthor())) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input")+I18nUtil.getString("jobinfo_field_author")) ); + } + if (ExecutorRouteStrategyEnum.match(jobInfo.getExecutorRouteStrategy(), null) == null) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorRouteStrategy")+I18nUtil.getString("system_unvalid")) ); + } + if (ExecutorBlockStrategyEnum.match(jobInfo.getExecutorBlockStrategy(), null) == null) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorBlockStrategy")+I18nUtil.getString("system_unvalid")) ); + } + if (GlueTypeEnum.match(jobInfo.getGlueType()) == null) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_gluetype")+I18nUtil.getString("system_unvalid")) ); + } + if (GlueTypeEnum.BEAN==GlueTypeEnum.match(jobInfo.getGlueType()) && StringUtils.isBlank(jobInfo.getExecutorHandler())) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input")+"JobHandler") ); + } + + // fix "\r" in shell + if (GlueTypeEnum.GLUE_SHELL==GlueTypeEnum.match(jobInfo.getGlueType()) && jobInfo.getGlueSource()!=null) { + jobInfo.setGlueSource(jobInfo.getGlueSource().replaceAll("\r", "")); + } + + // ChildJobId valid + if (StringUtils.isNotBlank(jobInfo.getChildJobId())) { + String[] childJobIds = StringUtils.split(jobInfo.getChildJobId(), ","); + for (String childJobIdItem: childJobIds) { + if (StringUtils.isNotBlank(childJobIdItem) && StringUtils.isNumeric(childJobIdItem)) { + XxlJobInfo childJobInfo = xxlJobInfoDao.loadById(Integer.valueOf(childJobIdItem)); + if (childJobInfo==null) { + return new ReturnT(ReturnT.FAIL_CODE, + MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId")+"({0})"+I18nUtil.getString("system_not_found")), childJobIdItem)); + } + } else { + return new ReturnT(ReturnT.FAIL_CODE, + MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId")+"({0})"+I18nUtil.getString("system_unvalid")), childJobIdItem)); + } + } + jobInfo.setChildJobId(StringUtils.join(childJobIds, ",")); + } + + // add in db + xxlJobInfoDao.save(jobInfo); + if (jobInfo.getId() < 1) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_add")+I18nUtil.getString("system_fail")) ); + } + + // add in quartz + String qz_group = String.valueOf(jobInfo.getJobGroup()); + String qz_name = String.valueOf(jobInfo.getId()); + try { + XxlJobDynamicScheduler.addJob(qz_name, qz_group, jobInfo.getJobCron()); + //XxlJobDynamicScheduler.pauseJob(qz_name, qz_group); + return ReturnT.SUCCESS; + } catch (SchedulerException e) { + logger.error(e.getMessage(), e); + try { + xxlJobInfoDao.delete(jobInfo.getId()); + XxlJobDynamicScheduler.removeJob(qz_name, qz_group); + } catch (SchedulerException e1) { + logger.error(e.getMessage(), e1); + } + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_add")+I18nUtil.getString("system_fail"))+":" + e.getMessage()); + } + } + + @Override + public ReturnT update(XxlJobInfo jobInfo) { + + // valid + if (!CronExpression.isValidExpression(jobInfo.getJobCron())) { + return new ReturnT(ReturnT.FAIL_CODE, I18nUtil.getString("jobinfo_field_cron_unvalid") ); + } + if (StringUtils.isBlank(jobInfo.getJobDesc())) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input")+I18nUtil.getString("jobinfo_field_jobdesc")) ); + } + if (StringUtils.isBlank(jobInfo.getAuthor())) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("system_please_input")+I18nUtil.getString("jobinfo_field_author")) ); + } + if (ExecutorRouteStrategyEnum.match(jobInfo.getExecutorRouteStrategy(), null) == null) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorRouteStrategy")+I18nUtil.getString("system_unvalid")) ); + } + if (ExecutorBlockStrategyEnum.match(jobInfo.getExecutorBlockStrategy(), null) == null) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_executorBlockStrategy")+I18nUtil.getString("system_unvalid")) ); + } + + // ChildJobId valid + if (StringUtils.isNotBlank(jobInfo.getChildJobId())) { + String[] childJobIds = StringUtils.split(jobInfo.getChildJobId(), ","); + for (String childJobIdItem: childJobIds) { + if (StringUtils.isNotBlank(childJobIdItem) && StringUtils.isNumeric(childJobIdItem)) { + XxlJobInfo childJobInfo = xxlJobInfoDao.loadById(Integer.valueOf(childJobIdItem)); + if (childJobInfo==null) { + return new ReturnT(ReturnT.FAIL_CODE, + MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId")+"({0})"+I18nUtil.getString("system_not_found")), childJobIdItem)); + } + // avoid cycle relate + if (childJobInfo.getId() == jobInfo.getId()) { + return new ReturnT(ReturnT.FAIL_CODE, MessageFormat.format(I18nUtil.getString("jobinfo_field_childJobId_limit"), childJobIdItem)); + } + } else { + return new ReturnT(ReturnT.FAIL_CODE, + MessageFormat.format((I18nUtil.getString("jobinfo_field_childJobId")+"({0})"+I18nUtil.getString("system_unvalid")), childJobIdItem)); + } + } + jobInfo.setChildJobId(StringUtils.join(childJobIds, ",")); + } + + // stage job info + XxlJobInfo exists_jobInfo = xxlJobInfoDao.loadById(jobInfo.getId()); + if (exists_jobInfo == null) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_id")+I18nUtil.getString("system_not_found")) ); + } + //String old_cron = exists_jobInfo.getJobCron(); + + exists_jobInfo.setJobCron(jobInfo.getJobCron()); + exists_jobInfo.setJobDesc(jobInfo.getJobDesc()); + exists_jobInfo.setAuthor(jobInfo.getAuthor()); + exists_jobInfo.setAlarmEmail(jobInfo.getAlarmEmail()); + exists_jobInfo.setExecutorRouteStrategy(jobInfo.getExecutorRouteStrategy()); + exists_jobInfo.setExecutorHandler(jobInfo.getExecutorHandler()); + exists_jobInfo.setExecutorParam(jobInfo.getExecutorParam()); + exists_jobInfo.setExecutorBlockStrategy(jobInfo.getExecutorBlockStrategy()); + exists_jobInfo.setExecutorFailStrategy(jobInfo.getExecutorFailStrategy()); + exists_jobInfo.setExecutorTimeout(jobInfo.getExecutorTimeout()); + exists_jobInfo.setExecutorFailRetryCount(jobInfo.getExecutorFailRetryCount()); + exists_jobInfo.setChildJobId(jobInfo.getChildJobId()); + xxlJobInfoDao.update(exists_jobInfo); + + // fresh quartz + String qz_group = String.valueOf(exists_jobInfo.getJobGroup()); + String qz_name = String.valueOf(exists_jobInfo.getId()); + try { + boolean ret = XxlJobDynamicScheduler.rescheduleJob(qz_group, qz_name, exists_jobInfo.getJobCron()); + return ret?ReturnT.SUCCESS:ReturnT.FAIL; + } catch (SchedulerException e) { + logger.error(e.getMessage(), e); + } + + return ReturnT.FAIL; + } + + @Override + public ReturnT remove(int id) { + XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id); + String group = String.valueOf(xxlJobInfo.getJobGroup()); + String name = String.valueOf(xxlJobInfo.getId()); + + try { + XxlJobDynamicScheduler.removeJob(name, group); + xxlJobInfoDao.delete(id); + xxlJobLogDao.delete(id); + xxlJobLogGlueDao.deleteByJobId(id); + return ReturnT.SUCCESS; + } catch (SchedulerException e) { + logger.error(e.getMessage(), e); + } + return ReturnT.FAIL; + } + + @Override + public ReturnT pause(int id) { + XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id); + String group = String.valueOf(xxlJobInfo.getJobGroup()); + String name = String.valueOf(xxlJobInfo.getId()); + + try { + boolean ret = XxlJobDynamicScheduler.pauseJob(name, group); // jobStatus do not store + return ret?ReturnT.SUCCESS:ReturnT.FAIL; + } catch (SchedulerException e) { + logger.error(e.getMessage(), e); + return ReturnT.FAIL; + } + } + + @Override + public ReturnT resume(int id) { + XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id); + String group = String.valueOf(xxlJobInfo.getJobGroup()); + String name = String.valueOf(xxlJobInfo.getId()); + + try { + boolean ret = XxlJobDynamicScheduler.resumeJob(name, group); + return ret?ReturnT.SUCCESS:ReturnT.FAIL; + } catch (SchedulerException e) { + logger.error(e.getMessage(), e); + return ReturnT.FAIL; + } + } + + @Override + public ReturnT triggerJob(int id) { + + JobTriggerPoolHelper.trigger(id); + return ReturnT.SUCCESS; + + /*XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(id); + if (xxlJobInfo == null) { + return new ReturnT(ReturnT.FAIL_CODE, (I18nUtil.getString("jobinfo_field_id")+I18nUtil.getString("system_unvalid")) ); + } + + String group = String.valueOf(xxlJobInfo.getJobGroup()); + String name = String.valueOf(xxlJobInfo.getId()); + + try { + XxlJobDynamicScheduler.triggerJob(name, group); + return ReturnT.SUCCESS; + } catch (SchedulerException e) { + logger.error(e.getMessage(), e); + return new ReturnT(ReturnT.FAIL_CODE, e.getMessage()); + }*/ + + } + + @Override + public Map dashboardInfo() { + + int jobInfoCount = xxlJobInfoDao.findAllCount(); + int jobLogCount = xxlJobLogDao.triggerCountByHandleCode(-1); + int jobLogSuccessCount = xxlJobLogDao.triggerCountByHandleCode(ReturnT.SUCCESS_CODE); + + // executor count + Set executerAddressSet = new HashSet(); + List groupList = xxlJobGroupDao.findAll(); + + if (CollectionUtils.isNotEmpty(groupList)) { + for (XxlJobGroup group: groupList) { + if (CollectionUtils.isNotEmpty(group.getRegistryList())) { + executerAddressSet.addAll(group.getRegistryList()); + } + } + } + + int executorCount = executerAddressSet.size(); + + Map dashboardMap = new HashMap(); + dashboardMap.put("jobInfoCount", jobInfoCount); + dashboardMap.put("jobLogCount", jobLogCount); + dashboardMap.put("jobLogSuccessCount", jobLogSuccessCount); + dashboardMap.put("executorCount", executorCount); + return dashboardMap; + } + + private static final String TRIGGER_CHART_DATA_CACHE = "trigger_chart_data_cache"; + @Override + public ReturnT> chartInfo(Date startDate, Date endDate) { + /*// get cache + String cacheKey = TRIGGER_CHART_DATA_CACHE + "_" + startDate.getTime() + "_" + endDate.getTime(); + Map chartInfo = (Map) LocalCacheUtil.get(cacheKey); + if (chartInfo != null) { + return new ReturnT>(chartInfo); + }*/ + + // process + List triggerDayList = new ArrayList(); + List triggerDayCountRunningList = new ArrayList(); + List triggerDayCountSucList = new ArrayList(); + List triggerDayCountFailList = new ArrayList(); + int triggerCountRunningTotal = 0; + int triggerCountSucTotal = 0; + int triggerCountFailTotal = 0; + + List> triggerCountMapAll = xxlJobLogDao.triggerCountByDay(startDate, endDate); + if (CollectionUtils.isNotEmpty(triggerCountMapAll)) { + for (Map item: triggerCountMapAll) { + String day = String.valueOf(item.get("triggerDay")); + int triggerDayCount = Integer.valueOf(String.valueOf(item.get("triggerDayCount"))); + int triggerDayCountRunning = Integer.valueOf(String.valueOf(item.get("triggerDayCountRunning"))); + int triggerDayCountSuc = Integer.valueOf(String.valueOf(item.get("triggerDayCountSuc"))); + int triggerDayCountFail = triggerDayCount - triggerDayCountRunning - triggerDayCountSuc; + + triggerDayList.add(day); + triggerDayCountRunningList.add(triggerDayCountRunning); + triggerDayCountSucList.add(triggerDayCountSuc); + triggerDayCountFailList.add(triggerDayCountFail); + + triggerCountRunningTotal += triggerDayCountRunning; + triggerCountSucTotal += triggerDayCountSuc; + triggerCountFailTotal += triggerDayCountFail; + } + } else { + for (int i = 4; i > -1; i--) { + triggerDayList.add(FastDateFormat.getInstance("yyyy-MM-dd").format(DateUtils.addDays(new Date(), -i))); + triggerDayCountSucList.add(0); + triggerDayCountFailList.add(0); + } + } + + Map result = new HashMap(); + result.put("triggerDayList", triggerDayList); + result.put("triggerDayCountRunningList", triggerDayCountRunningList); + result.put("triggerDayCountSucList", triggerDayCountSucList); + result.put("triggerDayCountFailList", triggerDayCountFailList); + + result.put("triggerCountRunningTotal", triggerCountRunningTotal); + result.put("triggerCountSucTotal", triggerCountSucTotal); + result.put("triggerCountFailTotal", triggerCountFailTotal); + + /*// set cache + LocalCacheUtil.set(cacheKey, result, 60*1000); // cache 60s*/ + + return new ReturnT>(result); + } + +} diff --git a/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml b/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml index 336394ad..59d24452 100644 --- a/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml +++ b/xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobInfoMapper.xml @@ -1,186 +1,186 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - t.id, - t.job_group, - t.job_cron, - t.job_desc, - t.add_time, - t.update_time, - t.author, - t.alarm_email, - t.executor_route_strategy, - t.executor_handler, - t.executor_param, - t.executor_block_strategy, - t.executor_fail_strategy, - t.executor_timeout, - t.executor_fail_retry_count, - t.glue_type, - t.glue_source, - t.glue_remark, - t.glue_updatetime, - t.child_jobid - - - - - - - - INSERT INTO XXL_JOB_QRTZ_TRIGGER_INFO ( - job_group, - job_cron, - job_desc, - add_time, - update_time, - author, - alarm_email, - executor_route_strategy, - executor_handler, - executor_param, - executor_block_strategy, - executor_fail_strategy, - executor_timeout, - executor_fail_retry_count, - glue_type, - glue_source, - glue_remark, - glue_updatetime, - child_jobid - ) VALUES ( - #{jobGroup}, - #{jobCron}, - #{jobDesc}, - NOW(), - NOW(), - #{author}, - #{alarmEmail}, - #{executorRouteStrategy}, - #{executorHandler}, - #{executorParam}, - #{executorBlockStrategy}, - #{executorFailStrategy}, - #{executorTimeout}, - #{executorFailRetryCount}, - #{glueType}, - #{glueSource}, - #{glueRemark}, - NOW(), - #{childJobId} - ); - - - - - - - UPDATE XXL_JOB_QRTZ_TRIGGER_INFO - SET - job_cron = #{jobCron}, - job_desc = #{jobDesc}, - update_time = NOW(), - author = #{author}, - alarm_email = #{alarmEmail}, - executor_route_strategy = #{executorRouteStrategy}, - executor_handler = #{executorHandler}, - executor_param = #{executorParam}, - executor_block_strategy = #{executorBlockStrategy}, - executor_fail_strategy = #{executorFailStrategy}, - executor_timeout = ${executorTimeout}, - executor_fail_retry_count = ${executorFailRetryCount}, - glue_type = #{glueType}, - glue_source = #{glueSource}, - glue_remark = #{glueRemark}, - glue_updatetime = #{glueUpdatetime}, - child_jobid = #{childJobId} - WHERE id = #{id} - - - - DELETE - FROM XXL_JOB_QRTZ_TRIGGER_INFO - WHERE id = #{id} - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + t.id, + t.job_group, + t.job_cron, + t.job_desc, + t.add_time, + t.update_time, + t.author, + t.alarm_email, + t.executor_route_strategy, + t.executor_handler, + t.executor_param, + t.executor_block_strategy, + t.executor_fail_strategy, + t.executor_timeout, + t.executor_fail_retry_count, + t.glue_type, + t.glue_source, + t.glue_remark, + t.glue_updatetime, + t.child_jobid + + + + + + + + INSERT INTO XXL_JOB_QRTZ_TRIGGER_INFO ( + job_group, + job_cron, + job_desc, + add_time, + update_time, + author, + alarm_email, + executor_route_strategy, + executor_handler, + executor_param, + executor_block_strategy, + executor_fail_strategy, + executor_timeout, + executor_fail_retry_count, + glue_type, + glue_source, + glue_remark, + glue_updatetime, + child_jobid + ) VALUES ( + #{jobGroup}, + #{jobCron}, + #{jobDesc}, + NOW(), + NOW(), + #{author}, + #{alarmEmail}, + #{executorRouteStrategy}, + #{executorHandler}, + #{executorParam}, + #{executorBlockStrategy}, + #{executorFailStrategy}, + #{executorTimeout}, + #{executorFailRetryCount}, + #{glueType}, + #{glueSource}, + #{glueRemark}, + NOW(), + #{childJobId} + ); + + + + + + + UPDATE XXL_JOB_QRTZ_TRIGGER_INFO + SET + job_cron = #{jobCron}, + job_desc = #{jobDesc}, + update_time = NOW(), + author = #{author}, + alarm_email = #{alarmEmail}, + executor_route_strategy = #{executorRouteStrategy}, + executor_handler = #{executorHandler}, + executor_param = #{executorParam}, + executor_block_strategy = #{executorBlockStrategy}, + executor_fail_strategy = #{executorFailStrategy}, + executor_timeout = ${executorTimeout}, + executor_fail_retry_count = ${executorFailRetryCount}, + glue_type = #{glueType}, + glue_source = #{glueSource}, + glue_remark = #{glueRemark}, + glue_updatetime = #{glueUpdatetime}, + child_jobid = #{childJobId} + WHERE id = #{id} + + + + DELETE + FROM XXL_JOB_QRTZ_TRIGGER_INFO + WHERE id = #{id} + + + + + + \ No newline at end of file diff --git a/xxl-job-admin/src/main/webapp/WEB-INF/template/jobinfo/jobinfo.index.ftl b/xxl-job-admin/src/main/webapp/WEB-INF/template/jobinfo/jobinfo.index.ftl index 6c766544..d709c93a 100644 --- a/xxl-job-admin/src/main/webapp/WEB-INF/template/jobinfo/jobinfo.index.ftl +++ b/xxl-job-admin/src/main/webapp/WEB-INF/template/jobinfo/jobinfo.index.ftl @@ -1,377 +1,377 @@ - - - - <#import "/common/common.macro.ftl" as netCommon> - <@netCommon.commonStyle /> - - - ${I18n.admin_name} - -sidebar-collapse"> -
- - <@netCommon.commonHeader /> - - <@netCommon.commonLeft "jobinfo" /> - - -
- -
-

${I18n.jobinfo_name}

-
- - -
- -
-
-
- ${I18n.jobinfo_field_jobgroup} - -
-
-
-
- ${I18n.jobinfo_field_jobdesc} - -
-
-
-
- JobHandler - -
-
-
- -
-
- -
-
- -
-
-
- <#--
-

调度列表

-
--> -
- - - - - - - - - - - - - - - - - - - -
${I18n.jobinfo_field_id}${I18n.jobinfo_field_jobgroup}${I18n.jobinfo_field_jobdesc}${I18n.jobinfo_field_gluetype}${I18n.jobinfo_field_executorparam}CronaddTimeupdateTime${I18n.jobinfo_field_author}${I18n.jobinfo_field_alarmemail}${I18n.system_status}${I18n.system_opt}
-
-
-
-
-
-
- - - <@netCommon.commonFooter /> -
- - - - - - - -<@netCommon.commonScript /> - - - - - - - - - + + + + <#import "/common/common.macro.ftl" as netCommon> + <@netCommon.commonStyle /> + + + ${I18n.admin_name} + +sidebar-collapse"> +
+ + <@netCommon.commonHeader /> + + <@netCommon.commonLeft "jobinfo" /> + + +
+ +
+

${I18n.jobinfo_name}

+
+ + +
+ +
+
+
+ ${I18n.jobinfo_field_jobgroup} + +
+
+
+
+ ${I18n.jobinfo_field_jobdesc} + +
+
+
+
+ JobHandler + +
+
+
+ +
+
+ +
+
+ +
+
+
+ <#--
+

调度列表

+
--> +
+ + + + + + + + + + + + + + + + + + + +
${I18n.jobinfo_field_id}${I18n.jobinfo_field_jobgroup}${I18n.jobinfo_field_jobdesc}${I18n.jobinfo_field_gluetype}${I18n.jobinfo_field_executorparam}CronaddTimeupdateTime${I18n.jobinfo_field_author}${I18n.jobinfo_field_alarmemail}${I18n.system_status}${I18n.system_opt}
+
+
+
+
+
+
+ + + <@netCommon.commonFooter /> +
+ + + + + + + +<@netCommon.commonScript /> + + + + + + + + + diff --git a/xxl-job-admin/src/main/webapp/static/js/jobinfo.index.1.js b/xxl-job-admin/src/main/webapp/static/js/jobinfo.index.1.js index e02f7ef3..ef1bc6c3 100644 --- a/xxl-job-admin/src/main/webapp/static/js/jobinfo.index.1.js +++ b/xxl-job-admin/src/main/webapp/static/js/jobinfo.index.1.js @@ -1,505 +1,505 @@ -$(function() { - - // init date tables - var jobTable = $("#job_list").dataTable({ - "deferRender": true, - "processing" : true, - "serverSide": true, - "ajax": { - url: base_url + "/jobinfo/pageList", - type:"post", - data : function ( d ) { - var obj = {}; - obj.jobGroup = $('#jobGroup').val(); - obj.jobDesc = $('#jobDesc').val(); - obj.executorHandler = $('#executorHandler').val(); - obj.start = d.start; - obj.length = d.length; - return obj; - } - }, - "searching": false, - "ordering": false, - //"scrollX": true, // scroll x,close self-adaption - "columns": [ - { - "data": 'id', - "bSortable": false, - "visible" : true, - "width":'10%' - }, - { - "data": 'jobGroup', - "visible" : false, - "width":'20%', - "render": function ( data, type, row ) { - var groupMenu = $("#jobGroup").find("option"); - for ( var index in $("#jobGroup").find("option")) { - if ($(groupMenu[index]).attr('value') == data) { - return $(groupMenu[index]).html(); - } - } - return data; - } - }, - { - "data": 'jobDesc', - "visible" : true, - "width":'20%' - }, - { - "data": 'glueType', - "width":'20%', - "visible" : true, - "render": function ( data, type, row ) { - var glueTypeTitle = findGlueTypeTitle(row.glueType); - if (row.executorHandler) { - return glueTypeTitle +":" + row.executorHandler; - } else { - return glueTypeTitle; - } - } - }, - { "data": 'executorParam', "visible" : false}, - { - "data": 'jobCron', - "visible" : true, - "width":'10%' - }, - { - "data": 'addTime', - "visible" : false, - "render": function ( data, type, row ) { - return data?moment(new Date(data)).format("YYYY-MM-DD HH:mm:ss"):""; - } - }, - { - "data": 'updateTime', - "visible" : false, - "render": function ( data, type, row ) { - return data?moment(new Date(data)).format("YYYY-MM-DD HH:mm:ss"):""; - } - }, - { "data": 'author', "visible" : true, "width":'10%'}, - { "data": 'alarmEmail', "visible" : false}, - { - "data": 'jobStatus', - "width":'10%', - "visible" : true, - "render": function ( data, type, row ) { - if ('NORMAL' == data) { - return ''+ data +''; - } else if ('PAUSED' == data){ - return ''+ data +''; - } else if ('BLOCKED' == data){ - return ''+ data +''; - } - return data; - } - }, - { - "data": I18n.system_opt , - "width":'15%', - "render": function ( data, type, row ) { - return function(){ - // status - var pause_resume = ""; - if ('NORMAL' == row.jobStatus) { - pause_resume = ' '; - } else if ('PAUSED' == row.jobStatus){ - pause_resume = ' '; - } - // log url - var logUrl = base_url +'/joblog?jobId='+ row.id; - - // log url - var codeBtn = ""; - if ('BEAN' != row.glueType) { - var codeUrl = base_url +'/jobcode?jobId='+ row.id; - codeBtn = ' ' - } - - // html - tableData['key'+row.id] = row; - var html = '

'+ - ' '+ - pause_resume + - '
'+ - ' '+ - codeBtn + - ' '+ - '

'; - - return html; - }; - } - } - ], - "language" : { - "sProcessing" : I18n.dataTable_sProcessing , - "sLengthMenu" : I18n.dataTable_sLengthMenu , - "sZeroRecords" : I18n.dataTable_sZeroRecords , - "sInfo" : I18n.dataTable_sInfo , - "sInfoEmpty" : I18n.dataTable_sInfoEmpty , - "sInfoFiltered" : I18n.dataTable_sInfoFiltered , - "sInfoPostFix" : "", - "sSearch" : I18n.dataTable_sSearch , - "sUrl" : "", - "sEmptyTable" : I18n.dataTable_sEmptyTable , - "sLoadingRecords" : I18n.dataTable_sLoadingRecords , - "sInfoThousands" : ",", - "oPaginate" : { - "sFirst" : I18n.dataTable_sFirst , - "sPrevious" : I18n.dataTable_sPrevious , - "sNext" : I18n.dataTable_sNext , - "sLast" : I18n.dataTable_sLast - }, - "oAria" : { - "sSortAscending" : I18n.dataTable_sSortAscending , - "sSortDescending" : I18n.dataTable_sSortDescending - } - } - }); - - // table data - var tableData = {}; - - // search btn - $('#searchBtn').on('click', function(){ - jobTable.fnDraw(); - }); - - // jobGroup change - $('#jobGroup').on('change', function(){ - //reload - var jobGroup = $('#jobGroup').val(); - window.location.href = base_url + "/jobinfo?jobGroup=" + jobGroup; - }); - - // job operate - $("#job_list").on('click', '.job_operate',function() { - var typeName; - var url; - var needFresh = false; - - var type = $(this).attr("_type"); - if ("job_pause" == type) { - typeName = I18n.jobinfo_opt_pause ; - url = base_url + "/jobinfo/pause"; - needFresh = true; - } else if ("job_resume" == type) { - typeName = I18n.jobinfo_opt_resume ; - url = base_url + "/jobinfo/resume"; - needFresh = true; - } else if ("job_del" == type) { - typeName = I18n.system_opt_del ; - url = base_url + "/jobinfo/remove"; - needFresh = true; - } else if ("job_trigger" == type) { - typeName = I18n.jobinfo_opt_run ; - url = base_url + "/jobinfo/trigger"; - } else { - return; - } - - var id = $(this).parent('p').attr("id"); - - layer.confirm( I18n.system_ok + typeName + '?', { - icon: 3, - title: I18n.system_tips , - btn: [ I18n.system_ok, I18n.system_cancel ] - }, function(index){ - layer.close(index); - - $.ajax({ - type : 'POST', - url : url, - data : { - "id" : id - }, - dataType : "json", - success : function(data){ - if (data.code == 200) { - - layer.open({ - title: I18n.system_tips, - btn: [ I18n.system_ok ], - content: typeName + I18n.system_success , - icon: '1', - end: function(layero, index){ - if (needFresh) { - //window.location.reload(); - jobTable.fnDraw(false); - } - } - }); - } else { - layer.open({ - title: I18n.system_tips, - btn: [ I18n.system_ok ], - content: (data.msg || typeName + I18n.system_fail ), - icon: '2' - }); - } - }, - }); - }); - }); - - // add - $(".add").click(function(){ - $('#addModal').modal({backdrop: false, keyboard: false}).modal('show'); - }); - var addModalValidate = $("#addModal .form").validate({ - errorElement : 'span', - errorClass : 'help-block', - focusInvalid : true, - rules : { - jobDesc : { - required : true, - maxlength: 50 - }, - jobCron : { - required : true - }, - author : { - required : true - }, - executorTimeout : { - digits:true - }, - executorFailRetryCount : { - digits:true - } - }, - messages : { - jobDesc : { - required : I18n.system_please_input + I18n.jobinfo_field_jobdesc - }, - jobCron : { - required : I18n.system_please_input + "Cron" - }, - author : { - required : I18n.system_please_input + I18n.jobinfo_field_author - }, - executorTimeout : { - digits: I18n.system_please_input + I18n.system_digits - }, - executorFailRetryCount : { - digits: I18n.system_please_input + I18n.system_digits - } - }, - highlight : function(element) { - $(element).closest('.form-group').addClass('has-error'); - }, - success : function(label) { - label.closest('.form-group').removeClass('has-error'); - label.remove(); - }, - errorPlacement : function(error, element) { - element.parent('div').append(error); - }, - submitHandler : function(form) { - - // process - var executorTimeout = $("#addModal .form input[name='executorTimeout']").val(); - if(!/^\d+$/.test(executorTimeout)) { - executorTimeout = 0; - } - $("#addModal .form input[name='executorTimeout']").val(executorTimeout); - - $.post(base_url + "/jobinfo/add", $("#addModal .form").serialize(), function(data, status) { - if (data.code == "200") { - $('#addModal').modal('hide'); - layer.open({ - title: I18n.system_tips , - btn: [ I18n.system_ok ], - content: I18n.system_add_suc , - icon: '1', - end: function(layero, index){ - jobTable.fnDraw(); - //window.location.reload(); - } - }); - } else { - layer.open({ - title: I18n.system_tips , - btn: [ I18n.system_ok ], - content: (data.msg || I18n.system_add_fail), - icon: '2' - }); - } - }); - } - }); - $("#addModal").on('hide.bs.modal', function () { - $("#addModal .form")[0].reset(); - addModalValidate.resetForm(); - $("#addModal .form .form-group").removeClass("has-error"); - $(".remote_panel").show(); // remote - - $("#addModal .form input[name='executorHandler']").removeAttr("readonly"); - }); - - - // glueType change - $(".glueType").change(function(){ - // executorHandler - var $executorHandler = $(this).parents("form").find("input[name='executorHandler']"); - var glueType = $(this).val(); - if ('BEAN' != glueType) { - $executorHandler.val(""); - $executorHandler.attr("readonly","readonly"); - } else { - $executorHandler.removeAttr("readonly"); - } - }); - - $("#addModal .glueType").change(function(){ - // glueSource - var glueType = $(this).val(); - if ('GLUE_GROOVY'==glueType){ - $("#addModal .form textarea[name='glueSource']").val( $("#addModal .form .glueSource_java").val() ); - } else if ('GLUE_SHELL'==glueType){ - $("#addModal .form textarea[name='glueSource']").val( $("#addModal .form .glueSource_shell").val() ); - } else if ('GLUE_PYTHON'==glueType){ - $("#addModal .form textarea[name='glueSource']").val( $("#addModal .form .glueSource_python").val() ); - } else if ('GLUE_PHP'==glueType){ - $("#addModal .form textarea[name='glueSource']").val( $("#addModal .form .glueSource_php").val() ); - } else if ('GLUE_NODEJS'==glueType){ - $("#addModal .form textarea[name='glueSource']").val( $("#addModal .form .glueSource_nodejs").val() ); - } - }); - - // update - $("#job_list").on('click', '.update',function() { - - var id = $(this).parent('p').attr("id"); - var row = tableData['key'+id]; - - // base data - $("#updateModal .form input[name='id']").val( row.id ); - $('#updateModal .form select[name=jobGroup] option[value='+ row.jobGroup +']').prop('selected', true); - $("#updateModal .form input[name='jobDesc']").val( row.jobDesc ); - $("#updateModal .form input[name='jobCron']").val( row.jobCron ); - $("#updateModal .form input[name='author']").val( row.author ); - $("#updateModal .form input[name='alarmEmail']").val( row.alarmEmail ); - $("#updateModal .form input[name='executorTimeout']").val( row.executorTimeout ); - $("#updateModal .form input[name='executorFailRetryCount']").val( row.executorFailRetryCount ); - $('#updateModal .form select[name=executorRouteStrategy] option[value='+ row.executorRouteStrategy +']').prop('selected', true); - $("#updateModal .form input[name='executorHandler']").val( row.executorHandler ); - $("#updateModal .form input[name='executorParam']").val( row.executorParam ); - $("#updateModal .form input[name='childJobId']").val( row.childJobId ); - $('#updateModal .form select[name=executorBlockStrategy] option[value='+ row.executorBlockStrategy +']').prop('selected', true); - $('#updateModal .form select[name=glueType] option[value='+ row.glueType +']').prop('selected', true); - - $("#updateModal .form select[name=glueType]").change(); - - // show - $('#updateModal').modal({backdrop: false, keyboard: false}).modal('show'); - }); - var updateModalValidate = $("#updateModal .form").validate({ - errorElement : 'span', - errorClass : 'help-block', - focusInvalid : true, - - rules : { - jobDesc : { - required : true, - maxlength: 50 - }, - jobCron : { - required : true - }, - author : { - required : true - }, - executorTimeout : { - digits:true - }, - executorFailRetryCount : { - digits:true - } - }, - messages : { - jobDesc : { - required : I18n.system_please_input + I18n.jobinfo_field_jobdesc - }, - jobCron : { - required : I18n.system_please_input + "Cron" - }, - author : { - required : I18n.system_please_input + I18n.jobinfo_field_author - }, - executorTimeout : { - digits: I18n.system_please_input + I18n.system_digits - }, - executorFailRetryCount : { - digits: I18n.system_please_input + I18n.system_digits - } - }, - highlight : function(element) { - $(element).closest('.form-group').addClass('has-error'); - }, - success : function(label) { - label.closest('.form-group').removeClass('has-error'); - label.remove(); - }, - errorPlacement : function(error, element) { - element.parent('div').append(error); - }, - submitHandler : function(form) { - - // process - var executorTimeout = $("#updateModal .form input[name='executorTimeout']").val(); - if(!/^\d+$/.test(executorTimeout)) { - executorTimeout = 0; - } - $("#updateModal .form input[name='executorTimeout']").val(executorTimeout); - - // post - $.post(base_url + "/jobinfo/update", $("#updateModal .form").serialize(), function(data, status) { - if (data.code == "200") { - $('#updateModal').modal('hide'); - layer.open({ - title: I18n.system_tips , - btn: [ I18n.system_ok ], - content: I18n.system_update_suc , - icon: '1', - end: function(layero, index){ - //window.location.reload(); - jobTable.fnDraw(); - } - }); - } else { - layer.open({ - title: I18n.system_tips , - btn: [ I18n.system_ok ], - content: (data.msg || I18n.system_update_fail ), - icon: '2' - }); - } - }); - } - }); - $("#updateModal").on('hide.bs.modal', function () { - $("#updateModal .form")[0].reset() - }); - - /** - * find title by name, GlueType - */ - function findGlueTypeTitle(glueType) { - var glueTypeTitle; - $("#addModal .form select[name=glueType] option").each(function () { - var name = $(this).val(); - var title = $(this).text(); - if (glueType == name) { - glueTypeTitle = title; - return false - } - }); - return glueTypeTitle; - } - -}); +$(function() { + + // init date tables + var jobTable = $("#job_list").dataTable({ + "deferRender": true, + "processing" : true, + "serverSide": true, + "ajax": { + url: base_url + "/jobinfo/pageList", + type:"post", + data : function ( d ) { + var obj = {}; + obj.jobGroup = $('#jobGroup').val(); + obj.jobDesc = $('#jobDesc').val(); + obj.executorHandler = $('#executorHandler').val(); + obj.start = d.start; + obj.length = d.length; + return obj; + } + }, + "searching": false, + "ordering": false, + //"scrollX": true, // scroll x,close self-adaption + "columns": [ + { + "data": 'id', + "bSortable": false, + "visible" : true, + "width":'10%' + }, + { + "data": 'jobGroup', + "visible" : false, + "width":'20%', + "render": function ( data, type, row ) { + var groupMenu = $("#jobGroup").find("option"); + for ( var index in $("#jobGroup").find("option")) { + if ($(groupMenu[index]).attr('value') == data) { + return $(groupMenu[index]).html(); + } + } + return data; + } + }, + { + "data": 'jobDesc', + "visible" : true, + "width":'20%' + }, + { + "data": 'glueType', + "width":'20%', + "visible" : true, + "render": function ( data, type, row ) { + var glueTypeTitle = findGlueTypeTitle(row.glueType); + if (row.executorHandler) { + return glueTypeTitle +":" + row.executorHandler; + } else { + return glueTypeTitle; + } + } + }, + { "data": 'executorParam', "visible" : false}, + { + "data": 'jobCron', + "visible" : true, + "width":'10%' + }, + { + "data": 'addTime', + "visible" : false, + "render": function ( data, type, row ) { + return data?moment(new Date(data)).format("YYYY-MM-DD HH:mm:ss"):""; + } + }, + { + "data": 'updateTime', + "visible" : false, + "render": function ( data, type, row ) { + return data?moment(new Date(data)).format("YYYY-MM-DD HH:mm:ss"):""; + } + }, + { "data": 'author', "visible" : true, "width":'10%'}, + { "data": 'alarmEmail', "visible" : false}, + { + "data": 'jobStatus', + "width":'10%', + "visible" : true, + "render": function ( data, type, row ) { + if ('NORMAL' == data) { + return ''+ data +''; + } else if ('PAUSED' == data){ + return ''+ data +''; + } else if ('BLOCKED' == data){ + return ''+ data +''; + } + return data; + } + }, + { + "data": I18n.system_opt , + "width":'15%', + "render": function ( data, type, row ) { + return function(){ + // status + var pause_resume = ""; + if ('NORMAL' == row.jobStatus) { + pause_resume = ' '; + } else if ('PAUSED' == row.jobStatus){ + pause_resume = ' '; + } + // log url + var logUrl = base_url +'/joblog?jobId='+ row.id; + + // log url + var codeBtn = ""; + if ('BEAN' != row.glueType) { + var codeUrl = base_url +'/jobcode?jobId='+ row.id; + codeBtn = ' ' + } + + // html + tableData['key'+row.id] = row; + var html = '

'+ + ' '+ + pause_resume + + '
'+ + ' '+ + codeBtn + + ' '+ + '

'; + + return html; + }; + } + } + ], + "language" : { + "sProcessing" : I18n.dataTable_sProcessing , + "sLengthMenu" : I18n.dataTable_sLengthMenu , + "sZeroRecords" : I18n.dataTable_sZeroRecords , + "sInfo" : I18n.dataTable_sInfo , + "sInfoEmpty" : I18n.dataTable_sInfoEmpty , + "sInfoFiltered" : I18n.dataTable_sInfoFiltered , + "sInfoPostFix" : "", + "sSearch" : I18n.dataTable_sSearch , + "sUrl" : "", + "sEmptyTable" : I18n.dataTable_sEmptyTable , + "sLoadingRecords" : I18n.dataTable_sLoadingRecords , + "sInfoThousands" : ",", + "oPaginate" : { + "sFirst" : I18n.dataTable_sFirst , + "sPrevious" : I18n.dataTable_sPrevious , + "sNext" : I18n.dataTable_sNext , + "sLast" : I18n.dataTable_sLast + }, + "oAria" : { + "sSortAscending" : I18n.dataTable_sSortAscending , + "sSortDescending" : I18n.dataTable_sSortDescending + } + } + }); + + // table data + var tableData = {}; + + // search btn + $('#searchBtn').on('click', function(){ + jobTable.fnDraw(); + }); + + // jobGroup change + $('#jobGroup').on('change', function(){ + //reload + var jobGroup = $('#jobGroup').val(); + window.location.href = base_url + "/jobinfo?jobGroup=" + jobGroup; + }); + + // job operate + $("#job_list").on('click', '.job_operate',function() { + var typeName; + var url; + var needFresh = false; + + var type = $(this).attr("_type"); + if ("job_pause" == type) { + typeName = I18n.jobinfo_opt_pause ; + url = base_url + "/jobinfo/pause"; + needFresh = true; + } else if ("job_resume" == type) { + typeName = I18n.jobinfo_opt_resume ; + url = base_url + "/jobinfo/resume"; + needFresh = true; + } else if ("job_del" == type) { + typeName = I18n.system_opt_del ; + url = base_url + "/jobinfo/remove"; + needFresh = true; + } else if ("job_trigger" == type) { + typeName = I18n.jobinfo_opt_run ; + url = base_url + "/jobinfo/trigger"; + } else { + return; + } + + var id = $(this).parent('p').attr("id"); + + layer.confirm( I18n.system_ok + typeName + '?', { + icon: 3, + title: I18n.system_tips , + btn: [ I18n.system_ok, I18n.system_cancel ] + }, function(index){ + layer.close(index); + + $.ajax({ + type : 'POST', + url : url, + data : { + "id" : id + }, + dataType : "json", + success : function(data){ + if (data.code == 200) { + + layer.open({ + title: I18n.system_tips, + btn: [ I18n.system_ok ], + content: typeName + I18n.system_success , + icon: '1', + end: function(layero, index){ + if (needFresh) { + //window.location.reload(); + jobTable.fnDraw(false); + } + } + }); + } else { + layer.open({ + title: I18n.system_tips, + btn: [ I18n.system_ok ], + content: (data.msg || typeName + I18n.system_fail ), + icon: '2' + }); + } + }, + }); + }); + }); + + // add + $(".add").click(function(){ + $('#addModal').modal({backdrop: false, keyboard: false}).modal('show'); + }); + var addModalValidate = $("#addModal .form").validate({ + errorElement : 'span', + errorClass : 'help-block', + focusInvalid : true, + rules : { + jobDesc : { + required : true, + maxlength: 50 + }, + jobCron : { + required : true + }, + author : { + required : true + }, + executorTimeout : { + digits:true + }, + executorFailRetryCount : { + digits:true + } + }, + messages : { + jobDesc : { + required : I18n.system_please_input + I18n.jobinfo_field_jobdesc + }, + jobCron : { + required : I18n.system_please_input + "Cron" + }, + author : { + required : I18n.system_please_input + I18n.jobinfo_field_author + }, + executorTimeout : { + digits: I18n.system_please_input + I18n.system_digits + }, + executorFailRetryCount : { + digits: I18n.system_please_input + I18n.system_digits + } + }, + highlight : function(element) { + $(element).closest('.form-group').addClass('has-error'); + }, + success : function(label) { + label.closest('.form-group').removeClass('has-error'); + label.remove(); + }, + errorPlacement : function(error, element) { + element.parent('div').append(error); + }, + submitHandler : function(form) { + + // process + var executorTimeout = $("#addModal .form input[name='executorTimeout']").val(); + if(!/^\d+$/.test(executorTimeout)) { + executorTimeout = 0; + } + $("#addModal .form input[name='executorTimeout']").val(executorTimeout); + + $.post(base_url + "/jobinfo/add", $("#addModal .form").serialize(), function(data, status) { + if (data.code == "200") { + $('#addModal').modal('hide'); + layer.open({ + title: I18n.system_tips , + btn: [ I18n.system_ok ], + content: I18n.system_add_suc , + icon: '1', + end: function(layero, index){ + jobTable.fnDraw(); + //window.location.reload(); + } + }); + } else { + layer.open({ + title: I18n.system_tips , + btn: [ I18n.system_ok ], + content: (data.msg || I18n.system_add_fail), + icon: '2' + }); + } + }); + } + }); + $("#addModal").on('hide.bs.modal', function () { + $("#addModal .form")[0].reset(); + addModalValidate.resetForm(); + $("#addModal .form .form-group").removeClass("has-error"); + $(".remote_panel").show(); // remote + + $("#addModal .form input[name='executorHandler']").removeAttr("readonly"); + }); + + + // glueType change + $(".glueType").change(function(){ + // executorHandler + var $executorHandler = $(this).parents("form").find("input[name='executorHandler']"); + var glueType = $(this).val(); + if ('BEAN' != glueType) { + $executorHandler.val(""); + $executorHandler.attr("readonly","readonly"); + } else { + $executorHandler.removeAttr("readonly"); + } + }); + + $("#addModal .glueType").change(function(){ + // glueSource + var glueType = $(this).val(); + if ('GLUE_GROOVY'==glueType){ + $("#addModal .form textarea[name='glueSource']").val( $("#addModal .form .glueSource_java").val() ); + } else if ('GLUE_SHELL'==glueType){ + $("#addModal .form textarea[name='glueSource']").val( $("#addModal .form .glueSource_shell").val() ); + } else if ('GLUE_PYTHON'==glueType){ + $("#addModal .form textarea[name='glueSource']").val( $("#addModal .form .glueSource_python").val() ); + } else if ('GLUE_PHP'==glueType){ + $("#addModal .form textarea[name='glueSource']").val( $("#addModal .form .glueSource_php").val() ); + } else if ('GLUE_NODEJS'==glueType){ + $("#addModal .form textarea[name='glueSource']").val( $("#addModal .form .glueSource_nodejs").val() ); + } + }); + + // update + $("#job_list").on('click', '.update',function() { + + var id = $(this).parent('p').attr("id"); + var row = tableData['key'+id]; + + // base data + $("#updateModal .form input[name='id']").val( row.id ); + $('#updateModal .form select[name=jobGroup] option[value='+ row.jobGroup +']').prop('selected', true); + $("#updateModal .form input[name='jobDesc']").val( row.jobDesc ); + $("#updateModal .form input[name='jobCron']").val( row.jobCron ); + $("#updateModal .form input[name='author']").val( row.author ); + $("#updateModal .form input[name='alarmEmail']").val( row.alarmEmail ); + $("#updateModal .form input[name='executorTimeout']").val( row.executorTimeout ); + $("#updateModal .form input[name='executorFailRetryCount']").val( row.executorFailRetryCount ); + $('#updateModal .form select[name=executorRouteStrategy] option[value='+ row.executorRouteStrategy +']').prop('selected', true); + $("#updateModal .form input[name='executorHandler']").val( row.executorHandler ); + $("#updateModal .form input[name='executorParam']").val( row.executorParam ); + $("#updateModal .form input[name='childJobId']").val( row.childJobId ); + $('#updateModal .form select[name=executorBlockStrategy] option[value='+ row.executorBlockStrategy +']').prop('selected', true); + $('#updateModal .form select[name=glueType] option[value='+ row.glueType +']').prop('selected', true); + + $("#updateModal .form select[name=glueType]").change(); + + // show + $('#updateModal').modal({backdrop: false, keyboard: false}).modal('show'); + }); + var updateModalValidate = $("#updateModal .form").validate({ + errorElement : 'span', + errorClass : 'help-block', + focusInvalid : true, + + rules : { + jobDesc : { + required : true, + maxlength: 50 + }, + jobCron : { + required : true + }, + author : { + required : true + }, + executorTimeout : { + digits:true + }, + executorFailRetryCount : { + digits:true + } + }, + messages : { + jobDesc : { + required : I18n.system_please_input + I18n.jobinfo_field_jobdesc + }, + jobCron : { + required : I18n.system_please_input + "Cron" + }, + author : { + required : I18n.system_please_input + I18n.jobinfo_field_author + }, + executorTimeout : { + digits: I18n.system_please_input + I18n.system_digits + }, + executorFailRetryCount : { + digits: I18n.system_please_input + I18n.system_digits + } + }, + highlight : function(element) { + $(element).closest('.form-group').addClass('has-error'); + }, + success : function(label) { + label.closest('.form-group').removeClass('has-error'); + label.remove(); + }, + errorPlacement : function(error, element) { + element.parent('div').append(error); + }, + submitHandler : function(form) { + + // process + var executorTimeout = $("#updateModal .form input[name='executorTimeout']").val(); + if(!/^\d+$/.test(executorTimeout)) { + executorTimeout = 0; + } + $("#updateModal .form input[name='executorTimeout']").val(executorTimeout); + + // post + $.post(base_url + "/jobinfo/update", $("#updateModal .form").serialize(), function(data, status) { + if (data.code == "200") { + $('#updateModal').modal('hide'); + layer.open({ + title: I18n.system_tips , + btn: [ I18n.system_ok ], + content: I18n.system_update_suc , + icon: '1', + end: function(layero, index){ + //window.location.reload(); + jobTable.fnDraw(); + } + }); + } else { + layer.open({ + title: I18n.system_tips , + btn: [ I18n.system_ok ], + content: (data.msg || I18n.system_update_fail ), + icon: '2' + }); + } + }); + } + }); + $("#updateModal").on('hide.bs.modal', function () { + $("#updateModal .form")[0].reset() + }); + + /** + * find title by name, GlueType + */ + function findGlueTypeTitle(glueType) { + var glueTypeTitle; + $("#addModal .form select[name=glueType] option").each(function () { + var name = $(this).val(); + var title = $(this).text(); + if (glueType == name) { + glueTypeTitle = title; + return false + } + }); + return glueTypeTitle; + } + +});