🔨 集成定时执行.
This commit is contained in:
@@ -13,6 +13,8 @@ public interface ErrorMessage {
|
||||
|
||||
String PARAM_MISSING = "参数不能为空";
|
||||
|
||||
String PARAM_ERROR = "参数错误";
|
||||
|
||||
String ID_MISSING = "id 不能为空";
|
||||
|
||||
String INVALID_PARAM = "参数验证失败";
|
||||
@@ -91,4 +93,6 @@ public interface ErrorMessage {
|
||||
|
||||
String FILE_READ_ERROR = "文件读取失败";
|
||||
|
||||
String PLEASE_CHECK_HOST_SSH = "请检查主机 {} 是否存在/权限/SSH配置";
|
||||
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package com.orion.ops.framework.job.core.utils;
|
||||
|
||||
import com.orion.lang.utils.Exceptions;
|
||||
import com.orion.lang.utils.Objects1;
|
||||
import com.orion.lang.utils.collect.Maps;
|
||||
import com.orion.ops.framework.common.constant.FieldConst;
|
||||
import org.quartz.*;
|
||||
import org.quartz.spi.MutableTrigger;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@@ -16,6 +17,10 @@ import java.util.Map;
|
||||
*/
|
||||
public class QuartzUtils {
|
||||
|
||||
private static final String JOB_PREFIX = "Job_";
|
||||
|
||||
private static final String TRIGGER_PREFIX = "Trigger_";
|
||||
|
||||
private static Scheduler scheduler;
|
||||
|
||||
private QuartzUtils() {
|
||||
@@ -24,39 +29,48 @@ public class QuartzUtils {
|
||||
/**
|
||||
* 添加任务
|
||||
*
|
||||
* @param name name
|
||||
* @param group group
|
||||
* @param type type
|
||||
* @param key key
|
||||
* @param cron cron
|
||||
* @param desc desc
|
||||
* @param jobClass jobClass
|
||||
*/
|
||||
public static void addJob(String name, String group,
|
||||
String cron, Class<? extends Job> jobClass) {
|
||||
QuartzUtils.addJob(name, group,
|
||||
cron, jobClass,
|
||||
Maps.empty());
|
||||
public static void addJob(String type, Object key,
|
||||
String cron, String desc,
|
||||
Class<? extends Job> jobClass) {
|
||||
QuartzUtils.addJob(type, key,
|
||||
cron, desc,
|
||||
jobClass, Maps.newMap());
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加任务
|
||||
*
|
||||
* @param name name
|
||||
* @param group group
|
||||
* @param type type
|
||||
* @param key key
|
||||
* @param cron cron
|
||||
* @param desc desc
|
||||
* @param jobClass jobClass
|
||||
* @param params params
|
||||
*/
|
||||
public static void addJob(String name, String group,
|
||||
String cron, Class<? extends Job> jobClass,
|
||||
Map<Object, Object> params) {
|
||||
public static void addJob(String type, Object key,
|
||||
String cron, String desc,
|
||||
Class<? extends Job> jobClass,
|
||||
Map<String, Object> params) {
|
||||
params.put(FieldConst.KEY, key);
|
||||
// 生成 job
|
||||
JobDetail jobDetail = JobBuilder.newJob(jobClass)
|
||||
.withIdentity(name, group)
|
||||
.withDescription(desc)
|
||||
.withIdentity(getJobKey(type, key))
|
||||
.usingJobData(new JobDataMap(params))
|
||||
.storeDurably()
|
||||
.build();
|
||||
// 生成触发器
|
||||
MutableTrigger trigger = CronScheduleBuilder.cronSchedule(cron)
|
||||
.withMisfireHandlingInstructionDoNothing()
|
||||
Trigger trigger = TriggerBuilder.newTrigger()
|
||||
.withIdentity(getTriggerKey(type, key))
|
||||
.withSchedule(CronScheduleBuilder
|
||||
.cronSchedule(cron)
|
||||
.withMisfireHandlingInstructionIgnoreMisfires())
|
||||
.build();
|
||||
QuartzUtils.addJob(jobDetail, trigger);
|
||||
}
|
||||
@@ -71,66 +85,100 @@ public class QuartzUtils {
|
||||
try {
|
||||
scheduler.scheduleJob(jobDetail, trigger);
|
||||
} catch (Exception e) {
|
||||
throw Exceptions.task();
|
||||
throw Exceptions.task(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除任务
|
||||
*
|
||||
* @param name name
|
||||
* @param group group
|
||||
* @param type type
|
||||
* @param key key
|
||||
*/
|
||||
public static void deleteJob(String name, String group) {
|
||||
public static void deleteJob(String type, Object key) {
|
||||
try {
|
||||
scheduler.deleteJob(new JobKey(name, group));
|
||||
scheduler.deleteJob(getJobKey(type, key));
|
||||
} catch (Exception e) {
|
||||
throw Exceptions.task();
|
||||
throw Exceptions.task(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 暂停任务
|
||||
*
|
||||
* @param name name
|
||||
* @param group group
|
||||
* @param type type
|
||||
* @param key key
|
||||
*/
|
||||
public static void pauseJob(String name, String group) {
|
||||
public static void pauseJob(String type, Object key) {
|
||||
try {
|
||||
scheduler.pauseJob(new JobKey(name, group));
|
||||
scheduler.pauseJob(getJobKey(type, key));
|
||||
} catch (Exception e) {
|
||||
throw Exceptions.task();
|
||||
throw Exceptions.task(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复任务
|
||||
*
|
||||
* @param name name
|
||||
* @param group group
|
||||
* @param type type
|
||||
* @param key key
|
||||
*/
|
||||
public static void resumeJob(String name, String group) {
|
||||
public static void resumeJob(String type, Object key) {
|
||||
try {
|
||||
scheduler.resumeJob(new JobKey(name, group));
|
||||
scheduler.resumeJob(getJobKey(type, key));
|
||||
} catch (Exception e) {
|
||||
throw Exceptions.task();
|
||||
throw Exceptions.task(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 立即执行任务
|
||||
*
|
||||
* @param name name
|
||||
* @param group group
|
||||
* @param type type
|
||||
* @param key key
|
||||
*/
|
||||
public static void triggerJob(String name, String group) {
|
||||
public static void triggerJob(String type, Object key) {
|
||||
triggerJob(type, key, Maps.newMap());
|
||||
}
|
||||
|
||||
/**
|
||||
* 立即执行任务
|
||||
*
|
||||
* @param type type
|
||||
* @param key key
|
||||
* @param params params
|
||||
*/
|
||||
public static void triggerJob(String type, Object key, Map<String, Object> params) {
|
||||
try {
|
||||
scheduler.triggerJob(new JobKey(name, group));
|
||||
params.put(FieldConst.KEY, key);
|
||||
scheduler.triggerJob(getJobKey(type, key), new JobDataMap(params));
|
||||
} catch (Exception e) {
|
||||
throw Exceptions.task();
|
||||
throw Exceptions.task(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 jobKey
|
||||
*
|
||||
* @param type type
|
||||
* @param key key
|
||||
* @return jobKey
|
||||
*/
|
||||
private static JobKey getJobKey(String type, Object key) {
|
||||
return new JobKey(JOB_PREFIX + type + "_" + Objects1.toString(key), JOB_PREFIX + type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 triggerKey
|
||||
*
|
||||
* @param type type
|
||||
* @param key key
|
||||
* @return triggerKey
|
||||
*/
|
||||
private static TriggerKey getTriggerKey(String type, Object key) {
|
||||
return new TriggerKey(TRIGGER_PREFIX + type + "_" + Objects1.toString(key), TRIGGER_PREFIX + type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置调度器
|
||||
*
|
||||
|
||||
@@ -68,7 +68,7 @@ spring:
|
||||
job-store-type: JDBC
|
||||
overwrite-existing-jobs: false
|
||||
jdbc:
|
||||
initialize-schema: ALWAYS
|
||||
initialize-schema: NEVER
|
||||
properties:
|
||||
org:
|
||||
quartz:
|
||||
|
||||
@@ -4,13 +4,12 @@ Content-Type: application/json
|
||||
Authorization: {{token}}
|
||||
|
||||
{
|
||||
"name": "",
|
||||
"expression": "",
|
||||
"timeout": "",
|
||||
"command": "",
|
||||
"parameterSchema": "",
|
||||
"status": "",
|
||||
"recentLogId": ""
|
||||
"name": "测试 1",
|
||||
"expression": "0 */3 * * * ?",
|
||||
"timeout": "0",
|
||||
"command": "echo 123",
|
||||
"parameterSchema": "[]",
|
||||
"hostIdList": [1]
|
||||
}
|
||||
|
||||
|
||||
@@ -19,15 +18,27 @@ PUT {{baseUrl}}/asset/exec-job/update
|
||||
Content-Type: application/json
|
||||
Authorization: {{token}}
|
||||
|
||||
{
|
||||
"id": 5,
|
||||
"name": "测试 1",
|
||||
"expression": "0 */1 * * * ?",
|
||||
"timeout": "0",
|
||||
"command": "echo 123",
|
||||
"parameterSchema": "[]",
|
||||
"hostIdList": [
|
||||
1
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
### 更新计划执行任务状态
|
||||
PUT {{baseUrl}}/asset/exec-job/update-status
|
||||
Content-Type: application/json
|
||||
Authorization: {{token}}
|
||||
|
||||
{
|
||||
"id": "",
|
||||
"name": "",
|
||||
"expression": "",
|
||||
"timeout": "",
|
||||
"command": "",
|
||||
"parameterSchema": "",
|
||||
"status": "",
|
||||
"recentLogId": ""
|
||||
"status": ""
|
||||
}
|
||||
|
||||
|
||||
@@ -36,28 +47,6 @@ GET {{baseUrl}}/asset/exec-job/get?id=1
|
||||
Authorization: {{token}}
|
||||
|
||||
|
||||
### 批量查询计划执行任务
|
||||
GET {{baseUrl}}/asset/exec-job/batch-get?idList=1,2,3
|
||||
Authorization: {{token}}
|
||||
|
||||
|
||||
### 查询全部计划执行任务
|
||||
POST {{baseUrl}}/asset/exec-job/list
|
||||
Content-Type: application/json
|
||||
Authorization: {{token}}
|
||||
|
||||
{
|
||||
"id": "",
|
||||
"name": "",
|
||||
"expression": "",
|
||||
"timeout": "",
|
||||
"command": "",
|
||||
"parameterSchema": "",
|
||||
"status": "",
|
||||
"recentLogId": ""
|
||||
}
|
||||
|
||||
|
||||
### 分页查询计划执行任务
|
||||
POST {{baseUrl}}/asset/exec-job/query
|
||||
Content-Type: application/json
|
||||
@@ -68,12 +57,8 @@ Authorization: {{token}}
|
||||
"limit": 10,
|
||||
"id": "",
|
||||
"name": "",
|
||||
"expression": "",
|
||||
"timeout": "",
|
||||
"command": "",
|
||||
"parameterSchema": "",
|
||||
"status": "",
|
||||
"recentLogId": ""
|
||||
"status": ""
|
||||
}
|
||||
|
||||
|
||||
@@ -82,8 +67,4 @@ DELETE {{baseUrl}}/asset/exec-job/delete?id=1
|
||||
Authorization: {{token}}
|
||||
|
||||
|
||||
### 批量删除计划执行任务
|
||||
DELETE {{baseUrl}}/asset/exec-job/batch-delete?idList=1,2,3
|
||||
Authorization: {{token}}
|
||||
|
||||
###
|
||||
|
||||
@@ -39,13 +39,6 @@ import javax.annotation.Resource;
|
||||
@SuppressWarnings({"ELValidationInJSP", "SpringElInspection"})
|
||||
public class ExecJobController {
|
||||
|
||||
|
||||
// TODO EXEC_seq
|
||||
// todo 测试一下添加失败 操作日志是怎么
|
||||
// TODO 操作日志 菜单
|
||||
// TODO 手动执行
|
||||
// TODO NEXT time
|
||||
|
||||
@Resource
|
||||
private ExecJobService execJobService;
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.orion.ops.module.asset.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.orion.ops.framework.mybatis.core.mapper.IMapper;
|
||||
import com.orion.ops.module.asset.entity.domain.ExecJobDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* 计划执行任务 Mapper 接口
|
||||
@@ -16,21 +16,10 @@ import org.apache.ibatis.annotations.Mapper;
|
||||
public interface ExecJobDAO extends IMapper<ExecJobDO> {
|
||||
|
||||
/**
|
||||
* 获取查询条件
|
||||
* 自增 exec_seq
|
||||
*
|
||||
* @param entity entity
|
||||
* @return 查询条件
|
||||
* @param id id
|
||||
*/
|
||||
default LambdaQueryWrapper<ExecJobDO> queryCondition(ExecJobDO entity) {
|
||||
return this.wrapper()
|
||||
.eq(ExecJobDO::getId, entity.getId())
|
||||
.eq(ExecJobDO::getName, entity.getName())
|
||||
.eq(ExecJobDO::getExpression, entity.getExpression())
|
||||
.eq(ExecJobDO::getTimeout, entity.getTimeout())
|
||||
.eq(ExecJobDO::getCommand, entity.getCommand())
|
||||
.eq(ExecJobDO::getParameterSchema, entity.getParameterSchema())
|
||||
.eq(ExecJobDO::getStatus, entity.getStatus())
|
||||
.eq(ExecJobDO::getRecentLogId, entity.getRecentLogId());
|
||||
}
|
||||
void incrExecSeq(@Param("id") Long id);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.orion.ops.module.asset.define.operator;
|
||||
package com.orion.ops.module.asset.define.operator;
|
||||
|
||||
import com.orion.ops.framework.biz.operator.log.core.annotation.Module;
|
||||
import com.orion.ops.framework.biz.operator.log.core.factory.InitializingOperatorTypes;
|
||||
@@ -30,9 +30,9 @@ public class ExecJobOperatorType extends InitializingOperatorTypes {
|
||||
public OperatorType[] types() {
|
||||
return new OperatorType[]{
|
||||
new OperatorType(L, CREATE, "创建计划任务 <sb>${name}</sb>"),
|
||||
new OperatorType(M, UPDATE, "更新计划任务 <sb>${before}</sb>"),
|
||||
new OperatorType(M, UPDATE_STATUS, "<sb>${statusName}</sb>计划任务 <sb>${name}</sb>"),
|
||||
new OperatorType(M, EXEC, "手动执行计划任务 <sb>${name}</sb>"),
|
||||
new OperatorType(M, UPDATE, "更新计划任务 <sb>${name}</sb>"),
|
||||
new OperatorType(M, UPDATE_STATUS, "更新计划任务状态 <sb>${name}</sb> <sb>${statusName}</sb>"),
|
||||
new OperatorType(H, DELETE, "删除计划任务 <sb>${name}</sb>"),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -34,4 +34,7 @@ public class ExecJobQueryRequest extends PageRequest {
|
||||
@Schema(description = "启用状态 0禁用 1启用")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "是否查询最近执行任务")
|
||||
private Boolean queryRecentLog;
|
||||
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 计划执行任务 视图响应对象
|
||||
@@ -31,9 +32,6 @@ public class ExecJobVO implements Serializable {
|
||||
@Schema(description = "任务名称")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "执行序列")
|
||||
private Integer execSeq;
|
||||
|
||||
@Schema(description = "cron 表达式")
|
||||
private String expression;
|
||||
|
||||
@@ -52,16 +50,19 @@ public class ExecJobVO implements Serializable {
|
||||
@Schema(description = "最近执行id")
|
||||
private Long recentLogId;
|
||||
|
||||
@Schema(description = "最近执行状态")
|
||||
private String recentExecStatus;
|
||||
|
||||
@Schema(description = "最近执行时间")
|
||||
private Date recentExecTime;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
private Date createTime;
|
||||
|
||||
@Schema(description = "修改时间")
|
||||
private Date updateTime;
|
||||
|
||||
@Schema(description = "创建人")
|
||||
private String creator;
|
||||
|
||||
@Schema(description = "修改人")
|
||||
private String updater;
|
||||
@Schema(description = "执行主机")
|
||||
private List<Long> hostIdList;
|
||||
|
||||
}
|
||||
|
||||
@@ -17,17 +17,19 @@ public enum ExecJobStatusEnum {
|
||||
/**
|
||||
* 停用
|
||||
*/
|
||||
DISABLED(0),
|
||||
DISABLED(0, "停用"),
|
||||
|
||||
/**
|
||||
* 启用
|
||||
*/
|
||||
ENABLED(1),
|
||||
ENABLED(1, "启用"),
|
||||
|
||||
;
|
||||
|
||||
private final Integer status;
|
||||
|
||||
private final String statusName;
|
||||
|
||||
public static ExecJobStatusEnum of(Integer status) {
|
||||
if (status == null) {
|
||||
return null;
|
||||
|
||||
@@ -56,6 +56,14 @@ public interface ExecJobService {
|
||||
*/
|
||||
DataGrid<ExecJobVO> getExecJobPage(ExecJobQueryRequest request);
|
||||
|
||||
/**
|
||||
* 获取下一个执行序列
|
||||
*
|
||||
* @param id id
|
||||
* @return seq
|
||||
*/
|
||||
Integer getNextExecSeq(Long id);
|
||||
|
||||
/**
|
||||
* 删除计划执行任务
|
||||
*
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.orion.ops.module.asset.service.impl;
|
||||
|
||||
import com.orion.lang.utils.collect.Lists;
|
||||
import com.orion.ops.module.asset.dao.ExecJobHostDAO;
|
||||
import com.orion.ops.module.asset.entity.domain.ExecJobHostDO;
|
||||
import com.orion.ops.module.asset.service.ExecJobHostService;
|
||||
@@ -30,16 +29,14 @@ public class ExecJobHostServiceImpl implements ExecJobHostService {
|
||||
log.info("ExecJobHostService.setHostIdByJobId jobId: {}, hostIdList: {}", jobId, hostIdList);
|
||||
// 删除
|
||||
execJobHostDAO.deleteByJobId(jobId);
|
||||
// 如果不为空则重新插入
|
||||
if (!Lists.isEmpty(hostIdList)) {
|
||||
List<ExecJobHostDO> rows = hostIdList.stream()
|
||||
.map(s -> ExecJobHostDO.builder()
|
||||
.hostId(s)
|
||||
.jobId(jobId)
|
||||
.build())
|
||||
.collect(Collectors.toList());
|
||||
execJobHostDAO.insertBatch(rows);
|
||||
}
|
||||
// 重新插入
|
||||
List<ExecJobHostDO> rows = hostIdList.stream()
|
||||
.map(s -> ExecJobHostDO.builder()
|
||||
.hostId(s)
|
||||
.jobId(jobId)
|
||||
.build())
|
||||
.collect(Collectors.toList());
|
||||
execJobHostDAO.insertBatch(rows);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -3,21 +3,43 @@ package com.orion.ops.module.asset.service.impl;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.orion.lang.define.wrapper.DataGrid;
|
||||
import com.orion.lang.utils.Booleans;
|
||||
import com.orion.lang.utils.Strings;
|
||||
import com.orion.lang.utils.time.Dates;
|
||||
import com.orion.lang.utils.time.cron.Cron;
|
||||
import com.orion.ops.framework.biz.operator.log.core.utils.OperatorLogs;
|
||||
import com.orion.ops.framework.common.constant.ErrorMessage;
|
||||
import com.orion.ops.framework.common.constant.FieldConst;
|
||||
import com.orion.ops.framework.common.utils.Valid;
|
||||
import com.orion.ops.framework.job.core.utils.QuartzUtils;
|
||||
import com.orion.ops.framework.security.core.utils.SecurityUtils;
|
||||
import com.orion.ops.module.asset.convert.ExecJobConvert;
|
||||
import com.orion.ops.module.asset.dao.ExecJobDAO;
|
||||
import com.orion.ops.module.asset.dao.ExecLogDAO;
|
||||
import com.orion.ops.module.asset.entity.domain.ExecJobDO;
|
||||
import com.orion.ops.module.asset.entity.domain.ExecLogDO;
|
||||
import com.orion.ops.module.asset.entity.request.exec.ExecJobCreateRequest;
|
||||
import com.orion.ops.module.asset.entity.request.exec.ExecJobQueryRequest;
|
||||
import com.orion.ops.module.asset.entity.request.exec.ExecJobUpdateRequest;
|
||||
import com.orion.ops.module.asset.entity.request.exec.ExecJobUpdateStatusRequest;
|
||||
import com.orion.ops.module.asset.entity.vo.ExecJobVO;
|
||||
import com.orion.ops.module.asset.enums.ExecJobStatusEnum;
|
||||
import com.orion.ops.module.asset.enums.HostConfigTypeEnum;
|
||||
import com.orion.ops.module.asset.service.AssetAuthorizedDataService;
|
||||
import com.orion.ops.module.asset.service.ExecJobHostService;
|
||||
import com.orion.ops.module.asset.service.ExecJobService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 计划执行任务 服务实现类
|
||||
@@ -30,30 +52,57 @@ import javax.annotation.Resource;
|
||||
@Service
|
||||
public class ExecJobServiceImpl implements ExecJobService {
|
||||
|
||||
// TODO 测试 SSH 禁用后是什么样子的
|
||||
// TODO 操作日志 菜单
|
||||
// TODO 执行日志抽象
|
||||
// TODO 任务分组
|
||||
// TODO 手动执行 测试 quartz
|
||||
|
||||
private static final String QUARTZ_TYPE = "Exec";
|
||||
|
||||
@Resource
|
||||
private ExecJobDAO execJobDAO;
|
||||
|
||||
@Resource
|
||||
private ExecJobHostService execJobHostService;
|
||||
|
||||
@Resource
|
||||
private ExecLogDAO execLogDAO;
|
||||
|
||||
@Resource
|
||||
private AssetAuthorizedDataService assetAuthorizedDataService;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long createExecJob(ExecJobCreateRequest request) {
|
||||
log.info("ExecJobService-createExecJob request: {}", JSON.toJSONString(request));
|
||||
// 验证表达式是否正确
|
||||
Cron.of(request.getExpression());
|
||||
// 转换
|
||||
ExecJobDO record = ExecJobConvert.MAPPER.to(request);
|
||||
// 查询数据是否冲突
|
||||
this.checkExecJobPresent(record);
|
||||
// TODO 查询主机是否存在
|
||||
// 查询是否有主机权限
|
||||
// 插入
|
||||
// 查询主机是否有权限
|
||||
this.checkHostPermission(request.getHostIdList());
|
||||
// 插入任务
|
||||
record.setStatus(ExecJobStatusEnum.ENABLED.getStatus());
|
||||
int effect = execJobDAO.insert(record);
|
||||
Long id = record.getId();
|
||||
// TODO 插入主机
|
||||
// 设置任务主机
|
||||
execJobHostService.setHostIdByJobId(id, request.getHostIdList());
|
||||
// 设置 quartz 状态
|
||||
this.setQuartzJobStatus(record, false, true);
|
||||
log.info("ExecJobService-createExecJob id: {}, effect: {}", id, effect);
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Integer updateExecJobById(ExecJobUpdateRequest request) {
|
||||
Long id = Valid.notNull(request.getId(), ErrorMessage.ID_MISSING);
|
||||
log.info("ExecJobService-updateExecJobById id: {}, request: {}", id, JSON.toJSONString(request));
|
||||
// 验证表达式是否正确
|
||||
Cron.of(request.getExpression());
|
||||
// 查询
|
||||
ExecJobDO record = execJobDAO.selectById(id);
|
||||
Valid.notNull(record, ErrorMessage.DATA_ABSENT);
|
||||
@@ -61,44 +110,120 @@ public class ExecJobServiceImpl implements ExecJobService {
|
||||
ExecJobDO updateRecord = ExecJobConvert.MAPPER.to(request);
|
||||
// 查询数据是否冲突
|
||||
this.checkExecJobPresent(updateRecord);
|
||||
// 更新
|
||||
// 查询主机是否有权限
|
||||
this.checkHostPermission(request.getHostIdList());
|
||||
// 更新任务
|
||||
int effect = execJobDAO.updateById(updateRecord);
|
||||
// 设置任务主机
|
||||
execJobHostService.setHostIdByJobId(id, request.getHostIdList());
|
||||
// 设置日志参数
|
||||
OperatorLogs.add(OperatorLogs.BEFORE, record.getName());
|
||||
// 设置 quartz 状态
|
||||
this.setQuartzJobStatus(updateRecord, true, ExecJobStatusEnum.ENABLED.getStatus().equals(record.getStatus()));
|
||||
log.info("ExecJobService-updateExecJobById effect: {}", effect);
|
||||
return effect;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Integer updateExecJobStatus(ExecJobUpdateStatusRequest request) {
|
||||
return null;
|
||||
Long id = request.getId();
|
||||
ExecJobStatusEnum status = ExecJobStatusEnum.of(request.getStatus());
|
||||
Valid.notNull(status, ErrorMessage.PARAM_ERROR);
|
||||
log.info("ExecJobService-updateExecJobStatus id: {}, status: {}", id, status);
|
||||
// 查询任务
|
||||
ExecJobDO record = execJobDAO.selectById(id);
|
||||
Valid.notNull(record, ErrorMessage.DATA_ABSENT);
|
||||
// 更新状态
|
||||
ExecJobDO update = new ExecJobDO();
|
||||
update.setId(id);
|
||||
update.setStatus(status.getStatus());
|
||||
int effect = execJobDAO.updateById(update);
|
||||
// 设置日志参数
|
||||
OperatorLogs.add(OperatorLogs.NAME, record.getName());
|
||||
OperatorLogs.add(OperatorLogs.STATUS_NAME, status.getStatusName());
|
||||
// 设置 quartz 状态
|
||||
this.setQuartzJobStatus(record, true, ExecJobStatusEnum.ENABLED.equals(status));
|
||||
return effect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecJobVO getExecJobById(Long id) {
|
||||
// 查询
|
||||
// 查询任务
|
||||
ExecJobDO record = execJobDAO.selectById(id);
|
||||
Valid.notNull(record, ErrorMessage.DATA_ABSENT);
|
||||
// 转换
|
||||
return ExecJobConvert.MAPPER.to(record);
|
||||
ExecJobVO vo = ExecJobConvert.MAPPER.to(record);
|
||||
// 查询任务主机
|
||||
List<Long> hostIdList = execJobHostService.getHostIdByJobId(id);
|
||||
vo.setHostIdList(hostIdList);
|
||||
return vo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataGrid<ExecJobVO> getExecJobPage(ExecJobQueryRequest request) {
|
||||
// 条件
|
||||
LambdaQueryWrapper<ExecJobDO> wrapper = this.buildQueryWrapper(request);
|
||||
// 查询
|
||||
return execJobDAO.of(wrapper)
|
||||
// 查询任务
|
||||
DataGrid<ExecJobVO> dataGrid = execJobDAO.of(wrapper)
|
||||
.page(request)
|
||||
.dataGrid(ExecJobConvert.MAPPER::to);
|
||||
if (!Booleans.isTrue(request.getQueryRecentLog())) {
|
||||
return dataGrid;
|
||||
}
|
||||
// 查询最近执行任务
|
||||
List<Long> logIdList = dataGrid.stream()
|
||||
.map(ExecJobVO::getRecentLogId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
if (!logIdList.isEmpty()) {
|
||||
List<ExecLogDO> logList = execLogDAO.selectBatchIds(logIdList);
|
||||
Map<Long, ExecLogDO> logMap = logList.stream()
|
||||
.collect(Collectors.toMap(ExecLogDO::getId, Function.identity()));
|
||||
dataGrid.forEach(s -> {
|
||||
Long logId = s.getRecentLogId();
|
||||
if (logId == null) {
|
||||
return;
|
||||
}
|
||||
ExecLogDO execLog = logMap.get(logId);
|
||||
if (execLog == null) {
|
||||
return;
|
||||
}
|
||||
s.setRecentExecTime(execLog.getStartTime());
|
||||
s.setRecentExecStatus(execLog.getStatus());
|
||||
});
|
||||
}
|
||||
return dataGrid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getNextExecSeq(Long id) {
|
||||
// 自增
|
||||
execJobDAO.incrExecSeq(id);
|
||||
// 获取
|
||||
return execJobDAO.of()
|
||||
.createWrapper()
|
||||
.select(ExecJobDO::getExecSeq)
|
||||
.eq(ExecJobDO::getId, id)
|
||||
.then()
|
||||
.getOne(ExecJobDO::getExecSeq);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Integer deleteExecJobById(Long id) {
|
||||
log.info("ExecJobService-deleteExecJobById id: {}", id);
|
||||
// 检查数据是否存在
|
||||
ExecJobDO record = execJobDAO.selectById(id);
|
||||
Valid.notNull(record, ErrorMessage.DATA_ABSENT);
|
||||
// 删除
|
||||
// 删除任务
|
||||
int effect = execJobDAO.deleteById(id);
|
||||
// 删除任务主机
|
||||
effect += execJobHostService.deleteByJobId(id);
|
||||
// 设置日志参数
|
||||
OperatorLogs.add(OperatorLogs.NAME, record.getName());
|
||||
// 设置 quartz 状态
|
||||
this.setQuartzJobStatus(record, true, false);
|
||||
log.info("ExecJobService-deleteExecJobById id: {}, effect: {}", id, effect);
|
||||
return effect;
|
||||
}
|
||||
@@ -135,4 +260,48 @@ public class ExecJobServiceImpl implements ExecJobService {
|
||||
.orderByDesc(ExecJobDO::getId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 quartz 任务状态
|
||||
*
|
||||
* @param record record
|
||||
* @param delete 是否删除
|
||||
* @param add 是否新增
|
||||
*/
|
||||
private void setQuartzJobStatus(ExecJobDO record, boolean delete, boolean add) {
|
||||
Long id = record.getId();
|
||||
// 删除 quartz job
|
||||
if (delete) {
|
||||
QuartzUtils.deleteJob(QUARTZ_TYPE, id);
|
||||
}
|
||||
// FIXME
|
||||
// 启动 quartz job
|
||||
if (add) {
|
||||
QuartzUtils.addJob(QUARTZ_TYPE, id, record.getExpression(), record.getName(), TestJob.class);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查主机权限
|
||||
*
|
||||
* @param hostIdList hostIdList
|
||||
*/
|
||||
private void checkHostPermission(List<Long> hostIdList) {
|
||||
// 查询有权限的主机
|
||||
List<Long> authorizedHostIdList = assetAuthorizedDataService.getUserAuthorizedHostId(SecurityUtils.getLoginUserId(), HostConfigTypeEnum.SSH);
|
||||
for (Long hostId : hostIdList) {
|
||||
Valid.isTrue(authorizedHostIdList.contains(hostId), Strings.format(ErrorMessage.PLEASE_CHECK_HOST_SSH, hostId));
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME
|
||||
static class TestJob implements Job {
|
||||
|
||||
@Override
|
||||
public void execute(JobExecutionContext context) {
|
||||
System.out.println("----------------------");
|
||||
System.out.println(Dates.current());
|
||||
System.out.println(context.getMergedJobDataMap().getLong(FieldConst.KEY));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.orion.ops.module.asset.entity.request.host.HostCreateRequest;
|
||||
import com.orion.ops.module.asset.entity.request.host.HostQueryRequest;
|
||||
import com.orion.ops.module.asset.entity.request.host.HostUpdateRequest;
|
||||
import com.orion.ops.module.asset.entity.vo.HostVO;
|
||||
import com.orion.ops.module.asset.service.ExecJobHostService;
|
||||
import com.orion.ops.module.asset.service.HostConfigService;
|
||||
import com.orion.ops.module.asset.service.HostService;
|
||||
import com.orion.ops.module.infra.api.DataExtraApi;
|
||||
@@ -66,6 +67,9 @@ public class HostServiceImpl implements HostService {
|
||||
@Resource
|
||||
private HostConfigService hostConfigService;
|
||||
|
||||
@Resource
|
||||
private ExecJobHostService execJobHostService;
|
||||
|
||||
@Resource
|
||||
private TagRelApi tagRelApi;
|
||||
|
||||
@@ -210,8 +214,11 @@ public class HostServiceImpl implements HostService {
|
||||
@Override
|
||||
@Async("asyncExecutor")
|
||||
public void deleteHostRelByIdAsync(Long id) {
|
||||
// 删除配置
|
||||
log.info("HostService-deleteHostRelByIdAsync id: {}", id);
|
||||
// 删除主机配置
|
||||
hostConfigDAO.deleteByHostId(id);
|
||||
// 删除计划执行任务主机
|
||||
execJobHostService.deleteByHostId(id);
|
||||
// 删除分组
|
||||
dataGroupRelApi.deleteByRelId(DataGroupTypeEnum.HOST, id);
|
||||
// 删除 tag 引用
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<resultMap id="BaseResultMap" type="com.orion.ops.module.asset.entity.domain.ExecJobDO">
|
||||
<id column="id" property="id"/>
|
||||
<result column="name" property="name"/>
|
||||
<result column="exec_seq" property="execSeq"/>
|
||||
<result column="expression" property="expression"/>
|
||||
<result column="timeout" property="timeout"/>
|
||||
<result column="command" property="command"/>
|
||||
@@ -21,7 +22,13 @@
|
||||
|
||||
<!-- 通用查询结果列 -->
|
||||
<sql id="Base_Column_List">
|
||||
id, name, expression, timeout, command, parameter_schema, status, recent_log_id, create_time, update_time, creator, updater, deleted
|
||||
id, name, exec_seq, expression, timeout, command, parameter_schema, status, recent_log_id, create_time, update_time, creator, updater, deleted
|
||||
</sql>
|
||||
|
||||
<update id="incrExecSeq">
|
||||
UPDATE exec_job
|
||||
SET exec_seq = exec_seq + 1
|
||||
WHERE id = #{id}
|
||||
</update>
|
||||
|
||||
</mapper>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
<result column="source" property="source"/>
|
||||
<result column="source_id" property="sourceId"/>
|
||||
<result column="description" property="description"/>
|
||||
<result column="exec_seq" property="exec_seq"/>
|
||||
<result column="command" property="command"/>
|
||||
<result column="parameter_schema" property="parameterSchema"/>
|
||||
<result column="timeout" property="timeout"/>
|
||||
@@ -25,7 +26,7 @@
|
||||
|
||||
<!-- 通用查询结果列 -->
|
||||
<sql id="Base_Column_List">
|
||||
id, user_id, username, source, source_id, description, command, parameter_schema, timeout, status, start_time, finish_time, create_time, update_time, creator, updater, deleted
|
||||
id, user_id, username, source, source_id, description, exec_seq, command, parameter_schema, timeout, status, start_time, finish_time, create_time, update_time, creator, updater, deleted
|
||||
</sql>
|
||||
|
||||
<select id="getExecHistory" resultMap="BaseResultMap">
|
||||
|
||||
Reference in New Issue
Block a user