소스 검색

兼容旧接口

zhangqiankun 3 년 전
부모
커밋
f2ca267cba

doc/XXL-JOB-English-Documentation.md → doc/design/XXL-JOB-English-Documentation.md


doc/XXL-JOB官方文档.md → doc/design/XXL-JOB官方文档.md


doc/XXL-JOB架构图.pptx → doc/design/XXL-JOB架构图.pptx


+ 279 - 0
doc/interface/xxl-job.md

@@ -0,0 +1,279 @@
+# XXL-JOB接口文档
+
+# 执行器管理
+
+## 添加执行器
+
+```
+URL:http://develop.persagy.com/job-admin/customGroup/save
+Method:POST
+Header:Content-Type=application/json
+```
+
+请求:
+
+```
+{
+	"id":1,		// ID,
+    "appname":"",	// 名称,必填
+    "title": "测试",	// 标题,必填
+    "addressType":0,		// 执行器地址类型:0=自动注册、1=手动录入
+    "addressList":"DO_NOTHING"		//执行器地址列表
+}
+```
+
+返回:
+
+```
+{
+	"code":200,			// 成功
+	"content":"1"		// 执行器ID
+}
+```
+
+# 任务管理
+
+## 创建或更新并启动任务
+
+```
+URL:http://develop.persagy.com/job-admin/customInfo/addOrUpdate2Start
+Method:POST
+Header:Content-Type=application/json
+```
+
+请求:
+
+```
+
+{
+	"id":1,		// 任务ID,存在更新,不存在新增
+    "jobGroup": 1,   // 执行器主键ID,必填
+    "childJobId":"",	// 子级任务ID,选填
+    "jobDesc": "测试",	// 任务描述,必填
+    "scheduleConf":"0/20 * * * * ?", 	//cron表达式,或者时间间隔单位:S,根据 scheduleType 来,必填
+    "scheduleType": "CRON",	//调度类型,根据字典值来,必填
+    "author":"测试人员", 	// 负责人,必填
+    "executorParam":{     // 任务参数,必填
+        "test":"123",
+        "callBackUrl":"http://www.baidu.com"	// 回调地址,必填
+    },
+    "executorRouteStrategy":"ROUND",    //路由策略,来源于字典值,必填
+    "executorBlockStrategy":"SERIAL_EXECUTION",    //阻塞处理策略,来源于字典值,必填
+    "executorFailRetryCount":0, 		// 失败重试次数,大于0时生效,选填
+    "executorHandler":"commonTimeRuleJob",	// 执行处理器,选填,不填,BEAN类型下,默认为 commonTimeRuleJob
+    "executorTimeout":0,		// 执行超时时间,大于0时生效
+    "misfireStrategy":"DO_NOTHING",		//调度过期策略,来源于字典值
+    "alarmEmail": "",		// 报警邮箱,多个用英文,隔开,选填
+    "glueType":"BEAN",		// BEAN 类型,目前写死即可,不填,默认即为BEAN
+    "glueRemark":"备注" 		// 备注
+}
+```
+
+返回:
+
+```
+{
+	"code":200,			// 成功
+	"content":"1"		// 任务ID
+}
+```
+
+## 创建任务(不会启动)
+
+	URL:http://develop.persagy.com/job-admin/customInfo/add
+	Method:POST
+	Header:Content-Type=application/json
+
+请求:
+
+	{
+	    "jobGroup": 1,   // 执行器主键ID,必填
+	    "childJobId":"",	// 子级任务ID,选填
+	    "jobDesc": "测试",	// 任务描述,必填
+	    "scheduleConf":"0/20 * * * * ?", 	//cron表达式,或者时间间隔单位:S,根据 scheduleType 来,必填
+	    "scheduleType": "CRON",	//调度类型,根据字典值来,必填
+	    "author":"测试人员", 	// 负责人,必填
+	    "executorParam":{     // 任务参数,必填
+	        "test":"123",
+	        "callBackUrl":"http://www.baidu.com"	// 回调地址,必填
+	    },
+	    "executorRouteStrategy":"ROUND",    //路由策略,来源于字典值,必填
+	    "executorBlockStrategy":"SERIAL_EXECUTION",    //阻塞处理策略,来源于字典值,必填
+	    "executorFailRetryCount":0, 		// 失败重试次数,大于0时生效,选填
+	    "executorHandler":"commonTimeRuleJob",	// 执行处理器,选填,不填,BEAN类型下,默认为 commonTimeRuleJob
+	    "executorTimeout":0,		// 执行超时时间,大于0时生效
+	    "misfireStrategy":"DO_NOTHING",		//调度过期策略,来源于字典值
+	    "alarmEmail": "",		// 报警邮箱,多个用英文,隔开,选填
+	    "glueType":"BEAN",		// BEAN 类型,目前写死即可,不填,默认即为BEAN
+	    "glueRemark":"备注" 		// 备注
+	}
+
+返回:
+
+	{
+		"code":200,			// 成功
+		"content":"2"		// 任务ID
+	}
+
+## 更新任务
+
+	URL:http://develop.persagy.com/job-admin/customInfo/update
+	Method:POST
+	Header:Content-Type=application/json
+
+请求:
+
+
+	{
+	    "jobGroup": 1,   // 执行器主键ID,必填
+	    "childJobId":"",	// 子级任务ID,选填
+	    "jobDesc": "测试",	// 任务描述,必填
+	    "scheduleConf":"0/20 * * * * ?", 	//cron表达式,或者时间间隔单位:S,根据 scheduleType 来,必填
+	    "scheduleType": "CRON",	//调度类型,根据字典值来,必填
+	    "author":"测试人员", 	// 负责人,必填
+	    "executorParam":{     // 任务参数,必填
+	        "test":"123",
+	        "callBackUrl":"http://www.baidu.com"	// 回调地址,必填
+	    },
+	    "executorRouteStrategy":"ROUND",    //路由策略,来源于字典值,必填
+	    "executorBlockStrategy":"SERIAL_EXECUTION",    //阻塞处理策略,来源于字典值,必填
+	    "executorFailRetryCount":0, 		// 失败重试次数,大于0时生效,选填
+	    "executorHandler":"commonTimeRuleJob",	// 执行处理器,选填,不填,BEAN类型下,默认为 commonTimeRuleJob
+	    "executorTimeout":0,		// 执行超时时间,大于0时生效
+	    "misfireStrategy":"DO_NOTHING",		//调度过期策略,来源于字典值
+	    "alarmEmail": "",		// 报警邮箱,多个用英文,隔开,选填
+	    "glueType":"BEAN",		// BEAN 类型,目前写死即可,不填,默认即为BEAN
+	    "glueRemark":"备注" 		// 备注
+	}
+
+返回:
+
+	{
+		"code":200
+	}
+
+## 启动任务
+
+	URL:http://develop.persagy.com/job-admin/customInfo/start
+	Method:POST
+	Header:Content-Type=application/json
+
+请求:
+
+
+	{
+	     "id":1	// 任务ID
+	}	
+
+返回:
+
+	{
+		"code":200
+	}
+
+## 停止任务
+
+	URL:http://develop.persagy.com/job-admin/customInfo/stop
+	Method:POST
+	Header:Content-Type=application/json
+
+请求:
+
+
+	{
+	     "id":1	// 任务ID
+	}	
+
+返回:
+
+	{
+		"code":200
+	}
+
+## 删除任务
+
+	URL:http://develop.persagy.com/job-admin/customInfo/remove
+	Method:POST
+	Header:Content-Type=application/json
+
+请求:
+
+
+	{
+	     "id":1	// 任务ID
+	}	
+
+返回:
+
+	{
+		"code":200		//成功
+	}
+
+
+
+# 字典值管理
+
+## 字典值查询
+
+	URL:http://develop.persagy.com/job-admin/dict/dictQuery
+	Method:POST
+	Header:Content-Type=application/json
+
+请求:
+
+	{
+	    "queryType":"executorRouteStrategy"		// 字段取值参考下面说明
+	}
+
+返回:
+
+	// 根据queryType的不同,返回值如下
+	// 路由策略 queryType: executorRouteStrategy
+	{
+	    "code": 200,
+	    "content": {
+	        "BUSYOVER": "忙碌转移",
+	        "CONSISTENT_HASH": "一致性HASH",
+	        "LAST": "最后一个",
+	        "SHARDING_BROADCAST": "分片广播",
+	        "ROUND": "轮询",
+	        "RANDOM": "随机",
+	        "LEAST_RECENTLY_USED": "最近最久未使用",
+	        "FIRST": "第一个",
+	        "LEAST_FREQUENTLY_USED": "最不经常使用",
+	        "FAILOVER": "故障转移"
+	    }
+	}
+	
+	// 阻塞策略 queryType: executorBlockStrategy
+	{
+	    "code": 200,
+	    "content": {
+	        "COVER_EARLY": "覆盖之前调度",
+	        "SERIAL_EXECUTION": "单机串行",
+	        "DISCARD_LATER": "丢弃后续调度"
+	    }
+	}
+	
+	// 调度过期策略 queryType: misfireStrategy
+	{
+	    "code": 200,
+	    "content": {
+	        "DO_NOTHING": "忽略",
+	        "FIRE_ONCE_NOW": "立即执行一次"
+	    }
+	}
+	
+	// 调度类型 queryType: scheduleType
+	{
+	    "code": 200,
+	    "content": {
+	        "CRON": "CRON",
+	        "NONE": "无",			// 暂
+	        "FIX_RATE": "固定速度"
+	    }
+	}
+
+
+
+

+ 20 - 2
job-admin/src/main/java/com/xxl/job/admin/controller/custom/CustomInfoController.java

@@ -67,10 +67,17 @@ public class CustomInfoController {
 		return customInfoHandler.transfer();
 	}
 	
-	@RequestMapping(value = "/addOrUpdateAndStart")
+	@RequestMapping(value = "/addOrUpdate2Start")
 	public ReturnT<String> addOrUpdateAndStart(@RequestBody @Validated XxlJobInfoValid valid) {
 		XxlJobInfo jobInfo = new XxlJobInfo();
 		BeanUtils.copyProperties(valid, jobInfo);
+
+		if (StringUtil.isNotBlank(valid.getCallBackUrl())) {
+			valid.getExecutorParam().put("callBackUrl", valid.getCallBackUrl());
+		}
+		if (StringUtil.isNotBlank(valid.getJobCron())) {
+			jobInfo.setScheduleConf(valid.getJobCron());
+		}
 		jobInfo.setExecutorParam(valid.getExecutorParam().toJSONString());
 		
 		if (valid.getId() == null) {
@@ -86,6 +93,12 @@ public class CustomInfoController {
 	public ReturnT<String> add(@RequestBody @Validated XxlJobInfoValid valid) {
 		XxlJobInfo jobInfo = new XxlJobInfo();
 		BeanUtils.copyProperties(valid, jobInfo);
+		if (StringUtil.isNotBlank(valid.getCallBackUrl())) {
+			valid.getExecutorParam().put("callBackUrl", valid.getCallBackUrl());
+		}
+		if (StringUtil.isNotBlank(valid.getJobCron())) {
+			jobInfo.setScheduleConf(valid.getJobCron());
+		}
 		jobInfo.setExecutorParam(valid.getExecutorParam().toJSONString());
 		return xxlJobService.add(jobInfo);
 	}
@@ -94,7 +107,12 @@ public class CustomInfoController {
 	public ReturnT<String> update(@RequestBody @Validated XxlJobInfoValid valid) {
 		XxlJobInfo jobInfo = new XxlJobInfo();
 		BeanUtils.copyProperties(valid, jobInfo);
-		
+		if (StringUtil.isNotBlank(valid.getCallBackUrl())) {
+			valid.getExecutorParam().put("callBackUrl", valid.getCallBackUrl());
+		}
+		if (StringUtil.isNotBlank(valid.getJobCron())) {
+			jobInfo.setScheduleConf(valid.getJobCron());
+		}
 		jobInfo.setExecutorParam(valid.getExecutorParam().toJSONString());
 		return xxlJobService.update(jobInfo);
 	}

+ 167 - 0
job-admin/src/main/java/com/xxl/job/admin/controller/custom/OldCustomInfoController.java

@@ -0,0 +1,167 @@
+package com.xxl.job.admin.controller.custom;
+
+import javax.annotation.Resource;
+
+import org.springframework.beans.BeanUtils;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.persagy.common.utils.StringUtil;
+import com.xxl.job.admin.core.model.DictQuery;
+import com.xxl.job.admin.core.model.XxlJobGroup;
+import com.xxl.job.admin.core.model.XxlJobInfo;
+import com.xxl.job.admin.core.model.XxlJobInfoIdValid;
+import com.xxl.job.admin.core.model.XxlJobInfoValid;
+import com.xxl.job.admin.core.route.ExecutorRouteStrategyEnum;
+import com.xxl.job.admin.core.scheduler.MisfireStrategyEnum;
+import com.xxl.job.admin.core.scheduler.ScheduleTypeEnum;
+import com.xxl.job.admin.core.thread.JobTriggerPoolHelper;
+import com.xxl.job.admin.core.trigger.TriggerTypeEnum;
+import com.xxl.job.admin.dao.XxlJobGroupDao;
+import com.xxl.job.admin.dao.XxlJobInfoDao;
+import com.xxl.job.admin.service.XxlJobService;
+import com.xxl.job.core.biz.model.ReturnT;
+import com.xxl.job.core.constant.CommonConstant;
+import com.xxl.job.core.enums.ExecutorBlockStrategyEnum;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+
+/**
+ * 暴露接口
+ * @version 1.0.0
+ * @company persagy 
+ * @author zhangqiankun
+ * @date 2021年9月24日 下午2:37:55
+ */
+@RestController
+@Api(tags = "任务触发点设置")
+@RequestMapping(value = "/admin/customJobInfo", method = {RequestMethod.POST})
+public class OldCustomInfoController {
+
+	@Resource
+	private XxlJobService xxlJobService;
+	
+	@Resource
+	private XxlJobInfoDao xxlJobInfoDao;
+	
+	@Resource
+	private XxlJobGroupDao xxlJobGroupDao;
+	
+	@RequestMapping(value = "/addOrUpdateAndStart")
+	public ReturnT<String> addOrUpdateAndStart(@RequestBody @Validated XxlJobInfoValid valid) {
+		XxlJobInfo jobInfo = new XxlJobInfo();
+		BeanUtils.copyProperties(valid, jobInfo);
+
+		if (StringUtil.isNotBlank(valid.getCallBackUrl())) {
+			valid.getExecutorParam().put("callBackUrl", valid.getCallBackUrl());
+		}
+		if (StringUtil.isNotBlank(valid.getJobCron())) {
+			jobInfo.setScheduleConf(valid.getJobCron());
+		}
+		jobInfo.setExecutorParam(valid.getExecutorParam().toJSONString());
+		
+		if (valid.getId() == null) {
+			xxlJobService.add(jobInfo);
+		} else {
+			xxlJobService.update(jobInfo);
+		}
+		// 启动任务
+		return xxlJobService.start(jobInfo.getId());
+	}
+	
+	@RequestMapping(value = "/add")
+	public ReturnT<String> add(@RequestBody @Validated XxlJobInfoValid valid) {
+		XxlJobInfo jobInfo = new XxlJobInfo();
+		BeanUtils.copyProperties(valid, jobInfo);
+		if (StringUtil.isNotBlank(valid.getCallBackUrl())) {
+			valid.getExecutorParam().put("callBackUrl", valid.getCallBackUrl());
+		}
+		if (StringUtil.isNotBlank(valid.getJobCron())) {
+			jobInfo.setScheduleConf(valid.getJobCron());
+		}
+		jobInfo.setExecutorParam(valid.getExecutorParam().toJSONString());
+		return xxlJobService.add(jobInfo);
+	}
+	
+	@RequestMapping(value = "/update")
+	public ReturnT<String> update(@RequestBody @Validated XxlJobInfoValid valid) {
+		XxlJobInfo jobInfo = new XxlJobInfo();
+		BeanUtils.copyProperties(valid, jobInfo);
+		if (StringUtil.isNotBlank(valid.getCallBackUrl())) {
+			valid.getExecutorParam().put("callBackUrl", valid.getCallBackUrl());
+		}
+		if (StringUtil.isNotBlank(valid.getJobCron())) {
+			jobInfo.setScheduleConf(valid.getJobCron());
+		}
+		jobInfo.setExecutorParam(valid.getExecutorParam().toJSONString());
+		return xxlJobService.update(jobInfo);
+	}
+	
+	@RequestMapping(value = "/remove")
+	public ReturnT<String> remove(@RequestBody @Validated XxlJobInfoIdValid valid) {
+		return xxlJobService.remove(valid.getId());
+	}
+	
+	@RequestMapping(value = "/stop")
+	public ReturnT<String> pause(@RequestBody @Validated XxlJobInfoIdValid valid) {
+		return xxlJobService.stop(valid.getId());
+	}
+	
+	@RequestMapping(value = "/start")
+	public ReturnT<String> start(@RequestBody @Validated XxlJobInfoIdValid valid) {
+		return xxlJobService.start(valid.getId());
+	}
+	
+	@RequestMapping(value = "/trigger")
+	public ReturnT<String> triggerJob(@RequestBody @Validated XxlJobInfoIdValid valid) {
+		XxlJobInfo xxlJobInfo = xxlJobInfoDao.loadById(valid.getId());
+		if (xxlJobInfo == null || StringUtil.isBlank(xxlJobInfo.getExecutorParam())) {
+			throw new IllegalArgumentException("非法请求,任务参数不存在");
+		}
+		
+		XxlJobGroup xxlJobGroup = xxlJobGroupDao.load(xxlJobInfo.getJobGroup());
+		if (xxlJobGroup == null) {
+			throw new IllegalArgumentException("非法请求,执行器不存在");
+		}
+		
+		JobTriggerPoolHelper.trigger(xxlJobInfo.getId(), TriggerTypeEnum.MANUAL, -1, null, xxlJobInfo.getExecutorParam(), xxlJobGroup.getAddressList());
+		return ReturnT.SUCCESS;
+	}
+	
+	
+	/************************************************ 字典值查询  *********************************************/
+	
+	@RequestMapping("/dictQuery")
+	@ApiOperation(value = "字典值查询")
+	public String remove(@RequestBody @Validated DictQuery query) {
+		JSONObject content = new JSONObject();
+		if (CommonConstant.EXECUTOR_ROUTE_STRATEGY.equals(query.getQueryType())) {
+			for (ExecutorRouteStrategyEnum item : ExecutorRouteStrategyEnum.values()) {
+				content.put(item.name(), item.getTitle());
+	        }
+		} else if (CommonConstant.EXECUTOR_BLOCK_STRATEGY.equals(query.getQueryType())) {
+			for (ExecutorBlockStrategyEnum item : ExecutorBlockStrategyEnum.values()) {
+				content.put(item.name(), item.getTitle());
+            }
+		} else if (CommonConstant.MISFIRE_STRATEGY.equals(query.getQueryType())) {
+			for (MisfireStrategyEnum item : MisfireStrategyEnum.values()) {
+				content.put(item.name(), item.getTitle());
+            }
+		} else if (CommonConstant.SCHEDULE_TYPE.equals(query.getQueryType())) {
+			for (ScheduleTypeEnum item : ScheduleTypeEnum.values()) {
+				content.put(item.name(), item.getTitle());
+            }
+		} else {
+			content = null;
+		}
+		ReturnT<JSONObject> returnT = new ReturnT<JSONObject>(content);
+		return JSON.toJSONString(returnT);
+	}
+	
+}

+ 1 - 0
job-admin/src/main/java/com/xxl/job/admin/controller/interceptor/WebMvcConfig.java

@@ -27,6 +27,7 @@ public class WebMvcConfig implements WebMvcConfigurer {
     public static final List<String> excludePaths = new ArrayList<String>();
     
     static {
+    	excludePaths.add("/admin/customJobInfo/**");
     	excludePaths.add("/customInfo/**");
     	excludePaths.add("/customGroup/**");
     	excludePaths.add("/v2/api-docs");

+ 5 - 0
job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobInfoValid.java

@@ -70,5 +70,10 @@ public class XxlJobInfoValid {
 	private String childJobId;		// 子任务ID,多个逗号分隔
 
 	private String addressList;		//执行器地址
+	
+	/** 旧接口兼容字段 */
+	private String jobCron;
+	
+	private String callBackUrl;
 
 }