调度信息迁移至DB中

v1.3
xueli.xue 9 years ago
parent 5afcf116fd
commit 2bc58f34ed

@ -7,6 +7,7 @@ import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
@ -16,11 +17,15 @@ import org.quartz.SchedulerException;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import com.xxl.job.client.handler.HandlerRepository; import com.xxl.job.client.handler.HandlerRepository;
import com.xxl.job.client.util.JacksonUtil;
import com.xxl.job.core.model.ReturnT; import com.xxl.job.core.model.ReturnT;
import com.xxl.job.core.model.XxlJobInfo;
import com.xxl.job.core.util.DynamicSchedulerUtil; import com.xxl.job.core.util.DynamicSchedulerUtil;
import com.xxl.job.dao.IXxlJobInfoDao;
import com.xxl.job.service.job.HttpJobBean; import com.xxl.job.service.job.HttpJobBean;
/** /**
@ -31,19 +36,47 @@ import com.xxl.job.service.job.HttpJobBean;
@RequestMapping("/job") @RequestMapping("/job")
public class JobController { public class JobController {
@Resource
private IXxlJobInfoDao xxlJobInfoDao;
@RequestMapping @RequestMapping
public String index(Model model) { public String index(Model model) {
List<Map<String, Object>> jobList = DynamicSchedulerUtil.getJobList(); //List<Map<String, Object>> jobList = DynamicSchedulerUtil.getJobList();
model.addAttribute("jobList", jobList); //model.addAttribute("jobList", jobList);
return "job/index"; return "job/index";
} }
@RequestMapping("/pageList")
@ResponseBody
public Map<String, Object> pageList(@RequestParam(required = false, defaultValue = "0") int start,
@RequestParam(required = false, defaultValue = "10") int length,
String jobName, String filterTime) {
// page list
List<XxlJobInfo> list = xxlJobInfoDao.pageList(start, length, jobName, null, null);
int list_count = xxlJobInfoDao.pageListCount(start, length, jobName, null, null);
// fill job info
if (list!=null && list.size()>0) {
for (XxlJobInfo jobInfo : list) {
DynamicSchedulerUtil.fillJobInfo(jobInfo);
}
}
// package result
Map<String, Object> maps = new HashMap<String, Object>();
maps.put("recordsTotal", list_count); // 总记录数
maps.put("recordsFiltered", list_count); // 过滤后的总记录数
maps.put("data", list); // 分页列表
return maps;
}
@RequestMapping("/add") @RequestMapping("/add")
@ResponseBody @ResponseBody
public ReturnT<String> add(HttpServletRequest request) { public ReturnT<String> add(HttpServletRequest request) {
String triggerKeyName = null; String triggerKeyName = null;
String cronExpression = null; String cronExpression = null;
Map<String, Object> jobData = new HashMap<String, Object>(); Map<String, String> jobData = new HashMap<String, String>();
try { try {
request.setCharacterEncoding("utf-8"); request.setCharacterEncoding("utf-8");
@ -58,7 +91,7 @@ public class JobController {
} else if (param.getKey().equals("cronExpression")) { } else if (param.getKey().equals("cronExpression")) {
cronExpression = param.getValue()[0]; cronExpression = param.getValue()[0];
} else { } else {
jobData.put(param.getKey(), param.getValue().length>0?param.getValue()[0]:param.getValue()); jobData.put(param.getKey(), (String) (param.getValue().length>0?param.getValue()[0]:param.getValue()));
} }
} }
@ -90,10 +123,19 @@ public class JobController {
Class<? extends Job> jobClass = HttpJobBean.class; Class<? extends Job> jobClass = HttpJobBean.class;
try { try {
boolean result = DynamicSchedulerUtil.addJob(triggerKeyName, cronExpression, jobClass, jobData); // add job 2 quartz
boolean result = DynamicSchedulerUtil.addJob(triggerKeyName, cronExpression, jobClass, null);
if (!result) { if (!result) {
return new ReturnT<String>(500, "任务ID重复请更换确认"); return new ReturnT<String>(500, "任务ID重复请更换确认");
} }
// Backup to the database
XxlJobInfo jobInfo = new XxlJobInfo();
jobInfo.setJobName(triggerKeyName);
jobInfo.setJobCron(cronExpression);
jobInfo.setJobClass(jobClass.getName());
jobInfo.setJobData(JacksonUtil.writeValueAsString(jobData));
xxlJobInfoDao.save(jobInfo);
return ReturnT.SUCCESS; return ReturnT.SUCCESS;
} catch (SchedulerException e) { } catch (SchedulerException e) {
e.printStackTrace(); e.printStackTrace();
@ -117,6 +159,13 @@ public class JobController {
} }
try { try {
DynamicSchedulerUtil.rescheduleJob(triggerKeyName, cronExpression); DynamicSchedulerUtil.rescheduleJob(triggerKeyName, cronExpression);
// update
XxlJobInfo jobInfo = xxlJobInfoDao.load(triggerKeyName);
if (jobInfo!=null) {
jobInfo.setJobCron(cronExpression);
xxlJobInfoDao.update(jobInfo);
}
return ReturnT.SUCCESS; return ReturnT.SUCCESS;
} catch (SchedulerException e) { } catch (SchedulerException e) {
e.printStackTrace(); e.printStackTrace();
@ -128,12 +177,15 @@ public class JobController {
@ResponseBody @ResponseBody
public ReturnT<String> remove(String triggerKeyName) { public ReturnT<String> remove(String triggerKeyName) {
try { try {
DynamicSchedulerUtil.removeJob(triggerKeyName); if (triggerKeyName!=null) {
return ReturnT.SUCCESS; DynamicSchedulerUtil.removeJob(triggerKeyName);
xxlJobInfoDao.delete(triggerKeyName);
return ReturnT.SUCCESS;
}
} catch (SchedulerException e) { } catch (SchedulerException e) {
e.printStackTrace(); e.printStackTrace();
return ReturnT.FAIL;
} }
return ReturnT.FAIL;
} }
@RequestMapping("/pause") @RequestMapping("/pause")
@ -141,6 +193,12 @@ public class JobController {
public ReturnT<String> pause(String triggerKeyName) { public ReturnT<String> pause(String triggerKeyName) {
try { try {
DynamicSchedulerUtil.pauseJob(triggerKeyName); DynamicSchedulerUtil.pauseJob(triggerKeyName);
// update
XxlJobInfo jobInfo = xxlJobInfoDao.load(triggerKeyName);
if (jobInfo!=null) {
jobInfo.setJobStatus("PAUSED");
xxlJobInfoDao.update(jobInfo);
}
return ReturnT.SUCCESS; return ReturnT.SUCCESS;
} catch (SchedulerException e) { } catch (SchedulerException e) {
e.printStackTrace(); e.printStackTrace();
@ -153,6 +211,12 @@ public class JobController {
public ReturnT<String> resume(String triggerKeyName) { public ReturnT<String> resume(String triggerKeyName) {
try { try {
DynamicSchedulerUtil.resumeJob(triggerKeyName); DynamicSchedulerUtil.resumeJob(triggerKeyName);
// update
XxlJobInfo jobInfo = xxlJobInfoDao.load(triggerKeyName);
if (jobInfo!=null) {
jobInfo.setJobStatus("NORMAL");
xxlJobInfoDao.update(jobInfo);
}
return ReturnT.SUCCESS; return ReturnT.SUCCESS;
} catch (SchedulerException e) { } catch (SchedulerException e) {
e.printStackTrace(); e.printStackTrace();

@ -23,11 +23,14 @@ import org.quartz.Trigger.TriggerState;
import org.quartz.TriggerBuilder; import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey; import org.quartz.TriggerKey;
import org.quartz.impl.matchers.GroupMatcher; import org.quartz.impl.matchers.GroupMatcher;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import com.xxl.job.core.model.XxlJobInfo;
import com.xxl.job.dao.IXxlJobInfoDao;
import com.xxl.job.dao.IXxlJobLogDao; import com.xxl.job.dao.IXxlJobLogDao;
/** /**
@ -43,8 +46,11 @@ public final class DynamicSchedulerUtil implements InitializingBean {
public void setXxlJobLogDao(IXxlJobLogDao xxlJobLogDao) { public void setXxlJobLogDao(IXxlJobLogDao xxlJobLogDao) {
DynamicSchedulerUtil.xxlJobLogDao = xxlJobLogDao; DynamicSchedulerUtil.xxlJobLogDao = xxlJobLogDao;
} }
public static IXxlJobLogDao getXxlJobLogDao() { // xxlJobInfoDao
return xxlJobLogDao; public static IXxlJobInfoDao xxlJobInfoDao;
@Resource
public void setXxlJobInfoDao(IXxlJobInfoDao xxlJobInfoDao) {
DynamicSchedulerUtil.xxlJobInfoDao = xxlJobInfoDao;
} }
// Scheduler // Scheduler
@ -90,6 +96,34 @@ public final class DynamicSchedulerUtil implements InitializingBean {
} }
return jobList; return jobList;
} }
// fill job info
public static void fillJobInfo(XxlJobInfo jobInfo) {
// TriggerKey : name + group
TriggerKey triggerKey = TriggerKey.triggerKey(jobInfo.getJobName(), Scheduler.DEFAULT_GROUP);
JobKey jobKey = new JobKey(jobInfo.getJobName(), Scheduler.DEFAULT_GROUP);
try {
Trigger trigger = scheduler.getTrigger(triggerKey);
JobDetail jobDetail = scheduler.getJobDetail(jobKey);
TriggerState triggerState = scheduler.getTriggerState(triggerKey);
// parse params
if (trigger!=null && trigger instanceof CronTriggerImpl) {
String cronExpression = ((CronTriggerImpl) trigger).getCronExpression();
jobInfo.setJobCron(cronExpression);
}
if (jobDetail!=null) {
String jobClass = jobDetail.getJobClass().getName();
jobInfo.setJobClass(jobClass);
}
if (triggerState!=null) {
jobInfo.setJobStatus(triggerState.name());
}
} catch (SchedulerException e) {
e.printStackTrace();
}
}
// addJob 新增 // addJob 新增
public static boolean addJob(String triggerKeyName, String cronExpression, Class<? extends Job> jobClass, Map<String, Object> jobData) throws SchedulerException { public static boolean addJob(String triggerKeyName, String cronExpression, Class<? extends Job> jobClass, Map<String, Object> jobData) throws SchedulerException {

@ -6,6 +6,10 @@ import java.util.List;
import com.xxl.job.core.model.XxlJobLog; import com.xxl.job.core.model.XxlJobLog;
/**
* job log
* @author xuxueli 2016-1-12 18:03:06
*/
public interface IXxlJobLogDao { public interface IXxlJobLogDao {
public int save(XxlJobLog xxlJobLog); public int save(XxlJobLog xxlJobLog);

@ -12,6 +12,10 @@ import org.springframework.stereotype.Repository;
import com.xxl.job.core.model.XxlJobLog; import com.xxl.job.core.model.XxlJobLog;
import com.xxl.job.dao.IXxlJobLogDao; import com.xxl.job.dao.IXxlJobLogDao;
/**
* job log
* @author xuxueli 2016-1-12 18:03:06
*/
@Repository @Repository
public class XxlJobLogDaoImpl implements IXxlJobLogDao { public class XxlJobLogDaoImpl implements IXxlJobLogDao {

@ -3,7 +3,6 @@ package com.xxl.job.service.job;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.quartz.JobExecutionContext; import org.quartz.JobExecutionContext;
@ -16,6 +15,7 @@ import org.springframework.scheduling.quartz.QuartzJobBean;
import com.xxl.job.client.handler.HandlerRepository; import com.xxl.job.client.handler.HandlerRepository;
import com.xxl.job.client.util.HttpUtil; import com.xxl.job.client.util.HttpUtil;
import com.xxl.job.client.util.JacksonUtil; import com.xxl.job.client.util.JacksonUtil;
import com.xxl.job.core.model.XxlJobInfo;
import com.xxl.job.core.model.XxlJobLog; import com.xxl.job.core.model.XxlJobLog;
import com.xxl.job.core.util.DynamicSchedulerUtil; import com.xxl.job.core.util.DynamicSchedulerUtil;
import com.xxl.job.core.util.PropertiesUtil; import com.xxl.job.core.util.PropertiesUtil;
@ -27,18 +27,17 @@ import com.xxl.job.core.util.PropertiesUtil;
public class HttpJobBean extends QuartzJobBean { public class HttpJobBean extends QuartzJobBean {
private static Logger logger = LoggerFactory.getLogger(HttpJobBean.class); private static Logger logger = LoggerFactory.getLogger(HttpJobBean.class);
@SuppressWarnings("unchecked")
@Override @Override
protected void executeInternal(JobExecutionContext context) protected void executeInternal(JobExecutionContext context)
throws JobExecutionException { throws JobExecutionException {
String triggerKey = context.getTrigger().getJobKey().getName(); String triggerKey = context.getTrigger().getJobKey().getName();
// jobDataMap 2 params // jobDataMap 2 params
Map<String, Object> jobDataMap = context.getMergedJobDataMap().getWrappedMap();
Map<String, String> params = new HashMap<String, String>(); Map<String, String> params = new HashMap<String, String>();
if (jobDataMap!=null && jobDataMap.size()>0) { XxlJobInfo jobInfo = DynamicSchedulerUtil.xxlJobInfoDao.load(triggerKey);
for (Entry<String, Object> item : jobDataMap.entrySet()) { if (jobInfo!=null && jobInfo.getJobData()!=null) {
params.put(item.getKey(), String.valueOf(item.getValue())); params = JacksonUtil.readValue(jobInfo.getJobData(), Map.class);
}
} }
// corn // corn
@ -53,7 +52,7 @@ public class HttpJobBean extends QuartzJobBean {
jobLog.setJobName(triggerKey); jobLog.setJobName(triggerKey);
jobLog.setJobCron(cornExp); jobLog.setJobCron(cornExp);
jobLog.setJobClass(HttpJobBean.class.getName()); jobLog.setJobClass(HttpJobBean.class.getName());
jobLog.setJobData(JacksonUtil.writeValueAsString(params)); jobLog.setJobData(jobInfo.getJobData());
DynamicSchedulerUtil.xxlJobLogDao.save(jobLog); DynamicSchedulerUtil.xxlJobLogDao.save(jobLog);
logger.info(">>>>>>>>>>> xxl-job trigger start, jobLog:{}", jobLog); logger.info(">>>>>>>>>>> xxl-job trigger start, jobLog:{}", jobLog);
@ -70,8 +69,7 @@ public class HttpJobBean extends QuartzJobBean {
jobLog.setTriggerTime(new Date()); jobLog.setTriggerTime(new Date());
jobLog.setTriggerStatus(HttpUtil.FAIL); jobLog.setTriggerStatus(HttpUtil.FAIL);
jobLog.setTriggerMsg("[responseMsg]:"+responseMsg+"<br>[exceptionMsg]:"+exceptionMsg); jobLog.setTriggerMsg("[responseMsg]:"+responseMsg+"<br>[exceptionMsg]:"+exceptionMsg);
if (StringUtils.isNotBlank(responseMsg)) { if (StringUtils.isNotBlank(responseMsg) && responseMsg.indexOf("{")>-1 ) {
@SuppressWarnings("unchecked")
Map<String, String> responseMap = JacksonUtil.readValue(responseMsg, Map.class); Map<String, String> responseMap = JacksonUtil.readValue(responseMsg, Map.class);
if (responseMap!=null && StringUtils.isNotBlank(responseMap.get(HttpUtil.status))) { if (responseMap!=null && StringUtils.isNotBlank(responseMap.get(HttpUtil.status))) {
jobLog.setTriggerStatus(responseMap.get(HttpUtil.status)); jobLog.setTriggerStatus(responseMap.get(HttpUtil.status));

@ -31,7 +31,7 @@
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" /> <property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath*:com/xxl/job/core/model/mapper/*.xml"/> <property name="mapperLocations" value="classpath*:mybatis-mapper/*.xml"/>
</bean> </bean>
<!-- scope must be "prototype" when junit --> <!-- scope must be "prototype" when junit -->

@ -68,8 +68,6 @@
<!-- footer --> <!-- footer -->
<@netCommon.commonFooter /> <@netCommon.commonFooter />
<!-- control -->
<@netCommon.commonControl />
</div> </div>
<@netCommon.commonScript /> <@netCommon.commonScript />
</body> </body>

@ -28,32 +28,53 @@
<!-- Main content --> <!-- Main content -->
<section class="content"> <section class="content">
<div class="row">
<div class="col-xs-4">
<div class="input-group">
<span class="input-group-addon">
jobName
</span>
<input type="text" class="form-control" id="jobName" value="${jobName}" autocomplete="on" >
</div>
</div>
<div class="col-xs-2">
<button class="btn btn-block btn-info" id="searchBtn">搜索</button>
</div>
<div class="col-xs-2">
<button class="btn btn-block btn-success add" type="button">+新增任务</button>
</div>
</div>
<div class="row"> <div class="row">
<div class="col-xs-12"> <div class="col-xs-12">
<div class="box"> <div class="box">
<div class="box-header"> <div class="box-header">
<h3 class="box-title">调度列表</h3> <h3 class="box-title">调度列表</h3>
<button class="btn btn-info btn-xs add" type="button">+新增任务</button>
</div> </div>
<div class="box-body"> <div class="box-body">
<table id="job_list" class="table table-bordered table-striped"> <table id="job_list" class="table table-bordered table-striped">
<thead> <thead>
<tr> <tr>
<th>调度key</th> <th>id</th>
<th>cron</th> <th>任务Key</th>
<!--<th>类路径</th>--> <th>任务Cron</th>
<th>任务Class</th>
<th>状态Status</th>
<th>参数</th> <th>参数</th>
<th>状态</th> <th>addTime</th>
<th>updateTime</th>
<th>操作</th> <th>操作</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<#--
<#if jobList?exists && jobList?size gt 0> <#if jobList?exists && jobList?size gt 0>
<#list jobList as item> <#list jobList as item>
<tr> <tr>
<td>${item['TriggerKey'].name}</td> <td>${item['TriggerKey'].name}</td>
<td>${item['Trigger'].cronExpression}</td> <td>${item['Trigger'].cronExpression}</td>
<!--<td>${item['JobDetail'].jobClass}</td>--> <td>${item['JobDetail'].jobClass}</td>
<td> <td>
<#assign jobDataMap = item['JobDetail'].jobDataMap /> <#assign jobDataMap = item['JobDetail'].jobDataMap />
<#if jobDataMap?exists && jobDataMap?keys?size gt 0> <#if jobDataMap?exists && jobDataMap?keys?size gt 0>
@ -89,17 +110,10 @@
</tr> </tr>
</#list> </#list>
</#if> </#if>
-->
</tbody> </tbody>
<tfoot> <tfoot></tfoot>
<tr>
<th>调度key</th>
<th>cron</th>
<!--<th>类路径</th>-->
<th>参数</th>
<th>状态</th>
<th>操作</th>
</tr>
</tfoot>
</table> </table>
</div> </div>
</div> </div>
@ -110,8 +124,6 @@
<!-- footer --> <!-- footer -->
<@netCommon.commonFooter /> <@netCommon.commonFooter />
<!-- control -->
<@netCommon.commonControl />
</div> </div>
<!-- job新增.模态框 --> <!-- job新增.模态框 -->
@ -129,19 +141,19 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="lastname" class="col-sm-3 control-label">任务Corn</label> <label for="lastname" class="col-sm-3 control-label">任务Corn</label>
<div class="col-sm-9"><input type="text" class="form-control" name="cronExpression" placeholder="请输入任务Corn[允许修改]" maxlength="100" ></div> <div class="col-sm-9"><input type="text" class="form-control" name="cronExpression" placeholder="请输入任务Corn" maxlength="100" ></div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="lastname" class="col-sm-3 control-label">任务描述</label> <label for="lastname" class="col-sm-3 control-label">任务描述</label>
<div class="col-sm-9"><input type="text" class="form-control" name="job_desc" placeholder="请输入任务描述[不支持修改]" maxlength="200" ></div> <div class="col-sm-9"><input type="text" class="form-control" name="job_desc" placeholder="请输入任务描述" maxlength="200" ></div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="lastname" class="col-sm-3 control-label">任务URL</label> <label for="lastname" class="col-sm-3 control-label">任务URL</label>
<div class="col-sm-9"><input type="text" class="form-control" name="job_url" placeholder="请输入任务URL[不支持修改]" maxlength="200" ></div> <div class="col-sm-9"><input type="text" class="form-control" name="job_url" placeholder="请输入任务URL" maxlength="200" ></div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="lastname" class="col-sm-3 control-label">任务handler</label> <label for="lastname" class="col-sm-3 control-label">任务handler</label>
<div class="col-sm-9"><input type="text" class="form-control" name="handleName" placeholder="请输入任务handler[不支持修改]" maxlength="200" ></div> <div class="col-sm-9"><input type="text" class="form-control" name="handleName" placeholder="请输入任务handler" maxlength="200" ></div>
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="col-sm-offset-3 col-sm-9"> <div class="col-sm-offset-3 col-sm-9">
@ -166,12 +178,24 @@
<div class="modal-body"> <div class="modal-body">
<form class="form-horizontal form" role="form" > <form class="form-horizontal form" role="form" >
<div class="form-group"> <div class="form-group">
<label for="firstname" class="col-sm-2 control-label">任务Key</label> <label for="firstname" class="col-sm-3 control-label">任务Key</label>
<div class="col-sm-10"><input type="text" class="form-control" name="triggerKeyName" placeholder="请输入任务Key" minlength="4" maxlength="100" readonly ></div> <div class="col-sm-9"><input type="text" class="form-control" name="triggerKeyName" placeholder="请输入任务Key" minlength="4" maxlength="100" readonly ></div>
</div>
<div class="form-group">
<label for="lastname" class="col-sm-3 control-label">任务Corn</label>
<div class="col-sm-9"><input type="text" class="form-control" name="cronExpression" placeholder="请输入任务Corn" maxlength="100" ></div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="lastname" class="col-sm-2 control-label">任务Corn</label> <label for="lastname" class="col-sm-3 control-label">任务描述</label>
<div class="col-sm-10"><input type="text" class="form-control" name="cronExpression" placeholder="请输入任务Corn" maxlength="100" ></div> <div class="col-sm-9"><input type="text" class="form-control" name="job_desc" placeholder="请输入任务描述" maxlength="200" ></div>
</div>
<div class="form-group">
<label for="lastname" class="col-sm-3 control-label">任务URL</label>
<div class="col-sm-9"><input type="text" class="form-control" name="job_url" placeholder="请输入任务URL" maxlength="200" ></div>
</div>
<div class="form-group">
<label for="lastname" class="col-sm-3 control-label">任务handler</label>
<div class="col-sm-9"><input type="text" class="form-control" name="handleName" placeholder="请输入任务handler" maxlength="200" ></div>
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="col-sm-offset-2 col-sm-10"> <div class="col-sm-offset-2 col-sm-10">
@ -191,6 +215,9 @@
<script src="${request.contextPath}/static/adminlte/plugins/datatables/jquery.dataTables.min.js"></script> <script src="${request.contextPath}/static/adminlte/plugins/datatables/jquery.dataTables.min.js"></script>
<script src="${request.contextPath}/static/adminlte/plugins/datatables/dataTables.bootstrap.min.js"></script> <script src="${request.contextPath}/static/adminlte/plugins/datatables/dataTables.bootstrap.min.js"></script>
<script src="${request.contextPath}/static/plugins/jquery/jquery.validate.min.js"></script> <script src="${request.contextPath}/static/plugins/jquery/jquery.validate.min.js"></script>
<!-- daterangepicker -->
<script src="${request.contextPath}/static/adminlte/plugins/daterangepicker/moment.min.js"></script>
<script src="${request.contextPath}/static/adminlte/plugins/daterangepicker/daterangepicker.js"></script>
<script>var base_url = '${request.contextPath}';</script> <script>var base_url = '${request.contextPath}';</script>
<script src="${request.contextPath}/static/js/job.index.1.js"></script> <script src="${request.contextPath}/static/js/job.index.1.js"></script>
</body> </body>

@ -84,8 +84,6 @@
<!-- footer --> <!-- footer -->
<@netCommon.commonFooter /> <@netCommon.commonFooter />
<!-- control -->
<@netCommon.commonControl />
</div> </div>
<@netCommon.commonScript /> <@netCommon.commonScript />

@ -1,6 +1,75 @@
$(function() { $(function() {
// init date tables // init date tables
$("#job_list").DataTable({ var jobTable = $("#job_list").dataTable({
"deferRender": true,
"processing" : true,
"serverSide": true,
"ajax": {
url: base_url + "/job/pageList",
data : function ( d ) {
d.jobName = $('#jobName').val()
}
},
//"scrollX": true, // X轴滚动条取消自适应
"columns": [
{ "data": 'id', "bSortable": false, "visible" : false},
{ "data": 'jobName', "bSortable": false},
{ "data": 'jobCron', "bSortable": false, "visible" : true},
{ "data": 'jobClass', "bSortable": false, "visible" : false},
{ "data": 'jobStatus', "bSortable": false, "visible" : true},
{ "data": 'jobData', "bSortable": false, "visible" : true},
{
"data": 'addTime',
"bSortable": false,
"render": function ( data, type, row ) {
return data?moment(new Date(data)).format("YYYY-MM-DD HH:mm:ss"):"";
}
},
{
"data": 'updateTime',
"bSortable": false,
"render": function ( data, type, row ) {
return data?moment(new Date(data)).format("YYYY-MM-DD HH:mm:ss"):"";
}
},
{ "data": '操作' , "bSortable": false,
"render": function ( data, type, row ) {
return function(){
// status
var pause_resume = "";
if ('NORMAL' == row.jobStatus) {
pause_resume = '<button class="btn btn-info btn-xs job_operate" type="job_pause" type="button">暂停</button> ';
} else if ('PAUSED' == row.jobStatus){
pause_resume = '<button class="btn btn-info btn-xs job_operate" type="job_resume" type="button">恢复</button> ';
}
// log url
var logUrl = base_url +'/joblog?jobName='+ row.jobName;
// job data
var jobDataMap = eval('(' + row.jobData + ')');
var html = '<p jobName="'+ row.jobName +'" '+
' cronExpression="'+ row.jobCron +'" '+
' job_desc="'+jobDataMap.job_desc +'" '+
' job_url="'+ jobDataMap.job_url +'" '+
' handleName="'+ jobDataMap.handleName +'" '+
'>'+
pause_resume +
'<button class="btn btn-info btn-xs job_operate" type="job_trigger" type="button">执行</button> '+
'<button class="btn btn-info btn-xs update" type="button">更新corn</button> '+
'<button class="btn btn-danger btn-xs job_operate" type="job_del" type="button">删除</button> '+
'<button class="btn btn-warning btn-xs" type="job_del" type="button" '+
'onclick="javascript:window.open(\'' + logUrl + '\')" >查看日志</button>'+
'</p>';
return html;
};
}
}
],
"searching": false,
"ordering": true,
"language" : { "language" : {
"sProcessing" : "处理中...", "sProcessing" : "处理中...",
"sLengthMenu" : "每页 _MENU_ 条记录", "sLengthMenu" : "每页 _MENU_ 条记录",
@ -27,8 +96,13 @@ $(function() {
} }
}); });
// 搜索按钮
$('#searchBtn').on('click', function(){
jobTable.fnDraw();
});
// job operate // job operate
$(".job_operate").click(function() { $("#job_list").on('click', '.job_operate',function() {
var typeName; var typeName;
var url; var url;
var type = $(this).attr("type"); var type = $(this).attr("type");
@ -48,22 +122,21 @@ $(function() {
return; return;
} }
var name = $(this).parent('p').attr("name"); var name = $(this).parent('p').attr("jobName");
var group = $(this).parent('p').attr("group");
ComConfirm.show("确认" + typeName + "?", function(){ ComConfirm.show("确认" + typeName + "?", function(){
$.ajax({ $.ajax({
type : 'POST', type : 'POST',
url : url, url : url,
data : { data : {
"triggerKeyName" : name, "triggerKeyName" : name
"group" : group
}, },
dataType : "json", dataType : "json",
success : function(data){ success : function(data){
if (data.code == 200) { if (data.code == 200) {
ComAlert.show(1, typeName + "成功", function(){ ComAlert.show(1, typeName + "成功", function(){
window.location.reload(); //window.location.reload();
jobTable.fnDraw();
}); });
} else { } else {
ComAlert.show(1, typeName + "失败"); ComAlert.show(1, typeName + "失败");
@ -215,9 +288,12 @@ $(function() {
}); });
// 更新 // 更新
$(".update").click(function(){ $("#job_list").on('click', '.update',function() {
$("#updateModal .form input[name='triggerKeyName']").val($(this).parent('p').attr("name")); $("#updateModal .form input[name='triggerKeyName']").val($(this).parent('p').attr("jobName"));
$("#updateModal .form input[name='cronExpression']").val($(this).parent('p').attr("cronExpression")); $("#updateModal .form input[name='cronExpression']").val($(this).parent('p').attr("cronExpression"));
$("#updateModal .form input[name='job_desc']").val($(this).parent('p').attr("job_desc"));
$("#updateModal .form input[name='job_url']").val($(this).parent('p').attr("job_url"));
$("#updateModal .form input[name='handleName']").val($(this).parent('p').attr("handleName"));
$('#updateModal').modal({backdrop: false, keyboard: false}).modal('show'); $('#updateModal').modal({backdrop: false, keyboard: false}).modal('show');
}); });
var updateModalValidate = $("#updateModal .form").validate({ var updateModalValidate = $("#updateModal .form").validate({
@ -233,6 +309,18 @@ $(function() {
cronExpression : { cronExpression : {
required : true , required : true ,
maxlength: 100 maxlength: 100
},
job_desc : {
required : true ,
maxlength: 200
},
job_url : {
required : true ,
maxlength: 200
},
handleName : {
required : true ,
maxlength: 200
} }
}, },
messages : { messages : {
@ -244,6 +332,18 @@ $(function() {
cronExpression : { cronExpression : {
required :"请输入“任务Corn”." , required :"请输入“任务Corn”." ,
maxlength:"“任务Corn”不应超过100位" maxlength:"“任务Corn”不应超过100位"
},
job_desc : {
required :"请输入“任务描述”." ,
maxlength:"“任务描述”长度不应超过200位"
},
job_url : {
required :"请输入“任务URL”." ,
maxlength:"“任务URL”长度不应超过200位"
},
handleName : {
required : "请输入“任务handler”." ,
maxlength: "“任务handler”长度不应超过200位"
} }
}, },
highlight : function(element) { highlight : function(element) {

@ -29,7 +29,7 @@ $(function() {
{ "data": 'triggerStatus', "bSortable": false}, { "data": 'triggerStatus', "bSortable": false},
{ "data": 'triggerMsg',"bSortable": false, { "data": 'triggerMsg',"bSortable": false,
"render": function ( data, type, row ) { "render": function ( data, type, row ) {
return data?'<a class="logTips" title="'+ data +'">调度日志</a>':"无"; return data?'<a class="logTips" href="javascript:;" >调度日志<span style="display:none;">'+ data +'</span></a>':"无";
} }
}, },
{ {
@ -42,7 +42,7 @@ $(function() {
{ "data": 'handleStatus',"bSortable": false}, { "data": 'handleStatus',"bSortable": false},
{ "data": 'handleMsg' , "bSortable": false, { "data": 'handleMsg' , "bSortable": false,
"render": function ( data, type, row ) { "render": function ( data, type, row ) {
return data?'<a class="logTips" title="'+ data +'">执行日志</a>':"无"; return data?'<a class="logTips" href="javascript:;" >执行日志<span style="display:none;">'+ data +'</span></a>':"无";
} }
} }
], ],
@ -76,8 +76,8 @@ $(function() {
// 日志弹框提示 // 日志弹框提示
$('#joblog_list').on('click', '.logTips', function(){ $('#joblog_list').on('click', '.logTips', function(){
var title = $(this).attr('title'); var msg = $(this).find('span').html();
ComAlertTec.show(title); ComAlertTec.show(msg);
}); });
// 过滤时间 // 过滤时间

@ -64,6 +64,9 @@ public class HttpUtil {
responseMsg = EntityUtils.toString(entity, "UTF-8"); responseMsg = EntityUtils.toString(entity, "UTF-8");
EntityUtils.consume(entity); EntityUtils.consume(entity);
} }
if (response.getStatusLine().getStatusCode() != 200) {
exceptionMsg = "response.getStatusLine().getStatusCode() = " + response.getStatusLine().getStatusCode();
}
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
StringWriter out = new StringWriter(); StringWriter out = new StringWriter();

Loading…
Cancel
Save