refactor(task): 移除任务模块相关常量、控制器和核心实现类
This commit is contained in:
@@ -118,4 +118,3 @@
|
|||||||
|
|
||||||
- cutejava-framework:系统基础框架。提供核心功能,如:权限、数据权限、异常处理、缓存、工具类、接口限流、接口防重、接口幂等。
|
- cutejava-framework:系统基础框架。提供核心功能,如:权限、数据权限、异常处理、缓存、工具类、接口限流、接口防重、接口幂等。
|
||||||
- cutejava-module-system:系统功能模块。提供用户、角色、菜单、部门、岗位、字典、定时任务、邮件、Minio存储、服务监控等功能
|
- cutejava-module-system:系统功能模块。提供用户、角色、菜单、部门、岗位、字典、定时任务、邮件、Minio存储、服务监控等功能
|
||||||
- cutejava-module-task:串行任务模块,已实现流水线功能。参考阿里云云效,提供流水线功能,可配置流水线任务,并支持任务依赖、任务参数、任务参数校验、任务参数回填。
|
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<parent>
|
|
||||||
<artifactId>cutejava</artifactId>
|
|
||||||
<groupId>cn.odboy</groupId>
|
|
||||||
<version>1.5.2</version>
|
|
||||||
</parent>
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<artifactId>cutejava-module-task-v1</artifactId>
|
|
||||||
<name>任务模块V1:强制停止任务线程</name>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>cn.odboy</groupId>
|
|
||||||
<artifactId>cutejava-module-system</artifactId>
|
|
||||||
<version>1.5.2</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</project>
|
|
||||||
-40
@@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.constant;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 任务变更类型(固定值)
|
|
||||||
*
|
|
||||||
* @author odboy
|
|
||||||
* @date 2025-09-26
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@AllArgsConstructor
|
|
||||||
public enum TaskChangeTypeEnum {
|
|
||||||
AppApply("AppApply", "申请应用"), AppContainerRestart("AppContainerRestart", "容器应用重启"),
|
|
||||||
AppContainerDeploy("AppContainerDeploy", "容器应用部署"), AppOffline("AppOffline", "应用下线"),
|
|
||||||
AppChangeReplicas("AppChangeReplicas", "应用扩缩容"), AppUpgrade("AppUpgrade", "应用升配"),
|
|
||||||
AppDowngrade("AppDowngrade", "应用降配"), AppHostRestart("AppHostRestart", "主机应用重启"),
|
|
||||||
AppHostDeploy("AppHostDeploy", "主机应用部署"), AppContainerRollback("AppContainerRollback", "容器应用回滚"),
|
|
||||||
AppHostRollback("AppHostRollback", "主机应用回滚"), ResourceApply("ResourceApply", "申请资源"),
|
|
||||||
ResourceOffline("ResourceOffline", "资源下线"), DataChange("DataChange", "数据变更"),
|
|
||||||
HostnameApply("HostnameApply", "申请域名"), HostnameChange("HostnameChange", "域名变更");
|
|
||||||
private final String code;
|
|
||||||
private final String name;
|
|
||||||
}
|
|
||||||
-17
@@ -1,17 +0,0 @@
|
|||||||
package cn.odboy.task.constant;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 任务共用Keys
|
|
||||||
*
|
|
||||||
* @author odboy
|
|
||||||
* @date 2025-10-25
|
|
||||||
*/
|
|
||||||
public interface TaskJobKeys {
|
|
||||||
|
|
||||||
String ID = "id";
|
|
||||||
String CONTEXT_NAME = "contextName";
|
|
||||||
String LANGUAGE = "language";
|
|
||||||
String ENV_ALIAS = "envAlias";
|
|
||||||
String CHANGE_TYPE = "changeType";
|
|
||||||
String RETRY_NODE_CODE = "retryNodeCode";
|
|
||||||
}
|
|
||||||
-43
@@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.constant;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 任务状态(固定值)
|
|
||||||
*
|
|
||||||
* @author odboy
|
|
||||||
* @date 2025-09-26
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@AllArgsConstructor
|
|
||||||
public enum TaskStatusEnum {
|
|
||||||
Pending("pending", "未开始"), Running("running", "运行中"), Success("success", "执行成功"),
|
|
||||||
Fail("fail", "执行失败");
|
|
||||||
private final String code;
|
|
||||||
private final String name;
|
|
||||||
|
|
||||||
public static String getDesc(String code) {
|
|
||||||
for (TaskStatusEnum taskStatusEnum : TaskStatusEnum.values()) {
|
|
||||||
if (taskStatusEnum.code.equals(code)) {
|
|
||||||
return taskStatusEnum.getName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-83
@@ -1,83 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.controller;
|
|
||||||
|
|
||||||
import cn.hutool.core.thread.ThreadUtil;
|
|
||||||
import cn.odboy.annotation.AnonymousAccess;
|
|
||||||
import cn.odboy.task.constant.TaskChangeTypeEnum;
|
|
||||||
import cn.odboy.task.core.TaskManage;
|
|
||||||
import cn.odboy.task.dal.dataobject.TaskInstanceInfoTb;
|
|
||||||
import cn.odboy.task.dal.model.TaskInstanceInfoVo;
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.http.ResponseEntity;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/task")
|
|
||||||
public class TaskTestsController {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private TaskManage taskManage;
|
|
||||||
|
|
||||||
@AnonymousAccess
|
|
||||||
@GetMapping(value = "/testCreate")
|
|
||||||
public ResponseEntity<?> testCreate() {
|
|
||||||
TaskInstanceInfoTb instanceInfo =
|
|
||||||
taskManage.createJob("cutejava", TaskChangeTypeEnum.AppContainerDeploy, "java", "daily", "cutejava",
|
|
||||||
"功能测试", null);
|
|
||||||
log.info("任务创建成功,实例为:{}", JSON.toJSONString(instanceInfo));
|
|
||||||
return ResponseEntity.ok(instanceInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
@AnonymousAccess
|
|
||||||
@GetMapping(value = "/testCreateAfterStop")
|
|
||||||
public ResponseEntity<?> testCreateAfterStop() {
|
|
||||||
TaskInstanceInfoTb instanceInfo =
|
|
||||||
taskManage.createJob("cutejava", TaskChangeTypeEnum.AppContainerDeploy, "java", "daily", "cutejava",
|
|
||||||
"功能测试", null);
|
|
||||||
log.info("任务创建成功,实例为:{}", JSON.toJSONString(instanceInfo));
|
|
||||||
ThreadUtil.execAsync(() -> {
|
|
||||||
ThreadUtil.safeSleep(5000);
|
|
||||||
taskManage.stopJob(instanceInfo.getId());
|
|
||||||
});
|
|
||||||
return ResponseEntity.ok(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@AnonymousAccess
|
|
||||||
@GetMapping(value = "/testRetry")
|
|
||||||
public ResponseEntity<?> testRetry(@RequestParam Long instanceId, @RequestParam String retryNodeCode) {
|
|
||||||
TaskInstanceInfoTb instanceInfo = taskManage.retryJob(instanceId, retryNodeCode);
|
|
||||||
log.info("任务重试成功,实例为:{}", JSON.toJSONString(instanceInfo));
|
|
||||||
return ResponseEntity.ok(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@AnonymousAccess
|
|
||||||
@GetMapping(value = "/last")
|
|
||||||
public ResponseEntity<?> testLast() {
|
|
||||||
String contextName = "cutejava";
|
|
||||||
String language = "java";
|
|
||||||
String changeType = TaskChangeTypeEnum.AppContainerDeploy.getCode();
|
|
||||||
String envAlias = "daily";
|
|
||||||
TaskInstanceInfoVo instanceInfo = taskManage.getLastInfo(contextName, language, envAlias, changeType);
|
|
||||||
return ResponseEntity.ok(instanceInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,215 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.core;
|
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import cn.odboy.framework.context.KitSpringBeanHolder;
|
|
||||||
import cn.odboy.framework.exception.BadRequestException;
|
|
||||||
import cn.odboy.framework.exception.ServerException;
|
|
||||||
import cn.odboy.task.constant.TaskJobKeys;
|
|
||||||
import cn.odboy.task.constant.TaskStatusEnum;
|
|
||||||
import cn.odboy.task.dal.dataobject.TaskInstanceDetailTb;
|
|
||||||
import cn.odboy.task.dal.dataobject.TaskInstanceInfoTb;
|
|
||||||
import cn.odboy.task.dal.model.TaskTemplateNodeVo;
|
|
||||||
import cn.odboy.task.service.TaskInstanceDetailService;
|
|
||||||
import cn.odboy.task.service.TaskInstanceInfoService;
|
|
||||||
import cn.odboy.task.service.TaskInstanceStepDetailService;
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.quartz.InterruptableJob;
|
|
||||||
import org.quartz.JobDataMap;
|
|
||||||
import org.quartz.JobExecutionContext;
|
|
||||||
import org.springframework.scheduling.quartz.QuartzJobBean;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class TaskJobBean extends QuartzJobBean implements InterruptableJob {
|
|
||||||
|
|
||||||
private Thread workThread = null;
|
|
||||||
|
|
||||||
private String getBeanAlias(String code) {
|
|
||||||
if (StrUtil.isBlank(code)) {
|
|
||||||
throw new ServerException("参数code必填");
|
|
||||||
}
|
|
||||||
// node_init
|
|
||||||
String[] s = code.split("_");
|
|
||||||
return Arrays.stream(s).map(StrUtil::upperFirst).collect(Collectors.joining());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void executeInternal(JobExecutionContext context) {
|
|
||||||
this.workThread = Thread.currentThread();
|
|
||||||
// ========================== 获取代理类 ==========================
|
|
||||||
TaskInstanceInfoService taskInstanceInfoService = KitSpringBeanHolder.getBean(TaskInstanceInfoService.class);
|
|
||||||
TaskInstanceDetailService taskInstanceDetailService =
|
|
||||||
KitSpringBeanHolder.getBean(TaskInstanceDetailService.class);
|
|
||||||
// ========================== 获取参数 ==========================
|
|
||||||
JobDataMap dataMap = context.getMergedJobDataMap();
|
|
||||||
long id = dataMap.getLong(TaskJobKeys.ID);
|
|
||||||
// ========================== 获取任务编排模板 ==========================
|
|
||||||
TaskInstanceInfoTb taskInstanceInfoVo = taskInstanceInfoService.getById(id);
|
|
||||||
String templateInfo = taskInstanceInfoVo.getTemplate();
|
|
||||||
List<TaskTemplateNodeVo> taskTemplateNodeVos = JSON.parseArray(templateInfo, TaskTemplateNodeVo.class);
|
|
||||||
// ========================== 判断是否重试任务 ==========================
|
|
||||||
String retryNodeCode = dataMap.getString(TaskJobKeys.RETRY_NODE_CODE);
|
|
||||||
if (StrUtil.isBlank(retryNodeCode)) {
|
|
||||||
executeNormalTask(taskInstanceInfoService, taskInstanceDetailService, id, dataMap, taskTemplateNodeVos);
|
|
||||||
} else {
|
|
||||||
executeRetryTask(taskInstanceInfoService, taskInstanceDetailService, id, dataMap, taskTemplateNodeVos,
|
|
||||||
retryNodeCode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行普通任务(非重试任务)
|
|
||||||
*
|
|
||||||
* @param taskInstanceInfoService 任务实例信息服务
|
|
||||||
* @param taskInstanceDetailService 任务实例明细服务
|
|
||||||
* @param id 任务实例ID
|
|
||||||
* @param dataMap 数据映射
|
|
||||||
* @param taskTemplateNodeVos 模板节点列表
|
|
||||||
*/
|
|
||||||
private void executeNormalTask(TaskInstanceInfoService taskInstanceInfoService,
|
|
||||||
TaskInstanceDetailService taskInstanceDetailService, long id, JobDataMap dataMap,
|
|
||||||
List<TaskTemplateNodeVo> taskTemplateNodeVos) {
|
|
||||||
// ========================== 初始化执行明细 ==========================
|
|
||||||
List<TaskInstanceDetailTb> taskInstanceDetails =
|
|
||||||
taskTemplateNodeVos.stream().map(taskTemplateNodeVo -> buildTaskInstanceDetail(id, taskTemplateNodeVo))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
taskInstanceDetailService.saveBatch(taskInstanceDetails);
|
|
||||||
Map<String, Long> codeIdMap = taskInstanceDetails.stream()
|
|
||||||
.collect(Collectors.toMap(TaskInstanceDetailTb::getBizCode, TaskInstanceDetailTb::getId));
|
|
||||||
// ========================== 顺序执行 ==========================
|
|
||||||
executeTaskSteps(taskInstanceInfoService, taskInstanceDetailService, id, dataMap, taskTemplateNodeVos,
|
|
||||||
codeIdMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行重试任务
|
|
||||||
*
|
|
||||||
* @param taskInstanceInfoService 任务实例信息服务
|
|
||||||
* @param taskInstanceDetailService 任务实例明细服务
|
|
||||||
* @param id 任务实例ID
|
|
||||||
* @param dataMap 数据映射
|
|
||||||
* @param taskTemplateNodeVos 模板节点列表
|
|
||||||
* @param retryNodeCode 重试节点编码
|
|
||||||
*/
|
|
||||||
private void executeRetryTask(TaskInstanceInfoService taskInstanceInfoService,
|
|
||||||
TaskInstanceDetailService taskInstanceDetailService, long id, JobDataMap dataMap,
|
|
||||||
List<TaskTemplateNodeVo> taskTemplateNodeVos, String retryNodeCode) {
|
|
||||||
boolean isFound = false;
|
|
||||||
// ========================== 初始化执行明细 ==========================
|
|
||||||
List<TaskInstanceDetailTb> taskInstanceDetails = new ArrayList<>();
|
|
||||||
List<TaskTemplateNodeVo> taskTemplateNodeRetryList = new ArrayList<>();
|
|
||||||
for (TaskTemplateNodeVo taskTemplateNodeVo : taskTemplateNodeVos) {
|
|
||||||
if (isFound) {
|
|
||||||
taskInstanceDetails.add(buildTaskInstanceDetail(id, taskTemplateNodeVo));
|
|
||||||
taskTemplateNodeRetryList.add(taskTemplateNodeVo);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (taskTemplateNodeVo.getCode().equals(retryNodeCode)) {
|
|
||||||
if (!taskTemplateNodeVo.getRetry()) {
|
|
||||||
throw new BadRequestException("节点 '" + taskTemplateNodeVo.getName() + "' 不支持重试");
|
|
||||||
}
|
|
||||||
taskInstanceDetails.add(buildTaskInstanceDetail(id, taskTemplateNodeVo));
|
|
||||||
taskTemplateNodeRetryList.add(taskTemplateNodeVo);
|
|
||||||
isFound = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TaskInstanceStepDetailService taskInstanceStepDetailService =
|
|
||||||
KitSpringBeanHolder.getBean(TaskInstanceStepDetailService.class);
|
|
||||||
List<String> bizCodeList =
|
|
||||||
taskInstanceDetails.stream().map(TaskInstanceDetailTb::getBizCode).distinct().collect(Collectors.toList());
|
|
||||||
List<TaskInstanceDetailTb> taskInstanceDetailTbs =
|
|
||||||
taskInstanceDetailService.queryByInstanceIdAndBizCodeList(id, bizCodeList);
|
|
||||||
List<Long> taskInstanceDetailIds =
|
|
||||||
taskInstanceDetailTbs.stream().map(TaskInstanceDetailTb::getId).collect(Collectors.toList());
|
|
||||||
// 根据ID删除明细
|
|
||||||
taskInstanceDetailService.removeByIds(taskInstanceDetailIds);
|
|
||||||
// 根据明细删除步骤
|
|
||||||
taskInstanceStepDetailService.removeByInstanceDetailIds(taskInstanceDetailIds);
|
|
||||||
taskInstanceDetailService.saveBatch(taskInstanceDetails);
|
|
||||||
Map<String, Long> codeIdMap = taskInstanceDetails.stream()
|
|
||||||
.collect(Collectors.toMap(TaskInstanceDetailTb::getBizCode, TaskInstanceDetailTb::getId));
|
|
||||||
// ========================== 顺序执行 ==========================
|
|
||||||
executeTaskSteps(taskInstanceInfoService, taskInstanceDetailService, id, dataMap, taskTemplateNodeRetryList,
|
|
||||||
codeIdMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构建任务实例明细对象
|
|
||||||
*
|
|
||||||
* @param id 实例ID
|
|
||||||
* @param taskTemplateNodeVo 模板节点
|
|
||||||
* @return 任务实例明细对象
|
|
||||||
*/
|
|
||||||
private TaskInstanceDetailTb buildTaskInstanceDetail(long id, TaskTemplateNodeVo taskTemplateNodeVo) {
|
|
||||||
TaskInstanceDetailTb taskInstanceDetail = new TaskInstanceDetailTb();
|
|
||||||
taskInstanceDetail.setInstanceId(id);
|
|
||||||
taskInstanceDetail.setFinishTime(null);
|
|
||||||
taskInstanceDetail.setBizCode(taskTemplateNodeVo.getCode());
|
|
||||||
taskInstanceDetail.setBizName(taskTemplateNodeVo.getName());
|
|
||||||
taskInstanceDetail.setExecuteInfo(TaskStatusEnum.Pending.getName());
|
|
||||||
taskInstanceDetail.setExecuteStatus(TaskStatusEnum.Pending.getCode());
|
|
||||||
return taskInstanceDetail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行任务步骤
|
|
||||||
*
|
|
||||||
* @param taskInstanceInfoService 任务实例信息服务
|
|
||||||
* @param taskInstanceDetailService 任务实例明细服务
|
|
||||||
* @param id 实例ID
|
|
||||||
* @param dataMap 数据映射
|
|
||||||
* @param taskTemplateNodes 需要执行的任务节点列表
|
|
||||||
* @param codeIdMap 节点编码与明细ID映射
|
|
||||||
*/
|
|
||||||
private void executeTaskSteps(TaskInstanceInfoService taskInstanceInfoService,
|
|
||||||
TaskInstanceDetailService taskInstanceDetailService, Long id, JobDataMap dataMap,
|
|
||||||
List<TaskTemplateNodeVo> taskTemplateNodes, Map<String, Long> codeIdMap) {
|
|
||||||
try {
|
|
||||||
for (TaskTemplateNodeVo taskTemplateNodeVo : taskTemplateNodes) {
|
|
||||||
String code = taskTemplateNodeVo.getCode();
|
|
||||||
try {
|
|
||||||
TaskStepExecutor executor = KitSpringBeanHolder.getBean("taskStep" + getBeanAlias(code));
|
|
||||||
taskInstanceDetailService.fastStart(id, code, dataMap);
|
|
||||||
executor.execute(codeIdMap.getOrDefault(code, null), dataMap, taskTemplateNodeVo);
|
|
||||||
taskInstanceDetailService.fastSuccessWithInfo(id, code, null);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("任务节点执行失败", e);
|
|
||||||
taskInstanceDetailService.fastFailWithInfo(id, code, e.getMessage());
|
|
||||||
throw new ServerException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
taskInstanceInfoService.fastSuccessWithData(id, dataMap);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("任务执行失败", e);
|
|
||||||
taskInstanceInfoService.fastFailWithMessageData(id, e.getMessage(), dataMap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void interrupt() {
|
|
||||||
if (workThread != null) {
|
|
||||||
// TODO 非正常手段
|
|
||||||
workThread.stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,265 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.core;
|
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import cn.odboy.framework.context.KitSpringBeanHolder;
|
|
||||||
import cn.odboy.framework.exception.BadRequestException;
|
|
||||||
import cn.odboy.task.constant.TaskChangeTypeEnum;
|
|
||||||
import cn.odboy.task.constant.TaskJobKeys;
|
|
||||||
import cn.odboy.task.constant.TaskStatusEnum;
|
|
||||||
import cn.odboy.task.dal.dataobject.TaskInstanceDetailTb;
|
|
||||||
import cn.odboy.task.dal.dataobject.TaskInstanceInfoTb;
|
|
||||||
import cn.odboy.task.dal.model.TaskInstanceInfoVo;
|
|
||||||
import cn.odboy.task.dal.model.TaskInstanceNodeVo;
|
|
||||||
import cn.odboy.task.dal.model.TaskTemplateInfoVo;
|
|
||||||
import cn.odboy.task.dal.model.TaskTemplateNodeVo;
|
|
||||||
import cn.odboy.task.service.TaskInstanceDetailService;
|
|
||||||
import cn.odboy.task.service.TaskInstanceInfoService;
|
|
||||||
import cn.odboy.task.service.TaskTemplateInfoService;
|
|
||||||
import cn.odboy.util.KitBeanUtil;
|
|
||||||
import cn.odboy.util.KitDateUtil;
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.quartz.JobBuilder;
|
|
||||||
import org.quartz.JobDataMap;
|
|
||||||
import org.quartz.JobDetail;
|
|
||||||
import org.quartz.JobKey;
|
|
||||||
import org.quartz.ObjectAlreadyExistsException;
|
|
||||||
import org.quartz.Scheduler;
|
|
||||||
import org.quartz.SchedulerException;
|
|
||||||
import org.quartz.Trigger;
|
|
||||||
import org.quartz.TriggerBuilder;
|
|
||||||
import org.quartz.TriggerKey;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@Component
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class TaskManage {
|
|
||||||
|
|
||||||
private final Scheduler scheduler;
|
|
||||||
private final TaskTemplateInfoService taskTemplateInfoService;
|
|
||||||
private final TaskInstanceInfoService taskInstanceInfoService;
|
|
||||||
private final TaskInstanceDetailService taskInstanceDetailService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建任务单(注:同一应用同一变更类型无法并发多实例)
|
|
||||||
*
|
|
||||||
* @param contextName 上下文名称,这里特指应用名
|
|
||||||
* @param changeTypeEnum 变更类型
|
|
||||||
* @param language 开发语言、资源版本
|
|
||||||
* @param envAlias 环境别名
|
|
||||||
* @param source 来源
|
|
||||||
* @param reason 变更原因
|
|
||||||
* @param dataMap 任务参数
|
|
||||||
*/
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public TaskInstanceInfoTb createJob(String contextName, TaskChangeTypeEnum changeTypeEnum, String language,
|
|
||||||
String envAlias, String source, String reason, JobDataMap dataMap) {
|
|
||||||
if (StrUtil.isBlank(contextName)) {
|
|
||||||
throw new BadRequestException("参数contextName必填");
|
|
||||||
}
|
|
||||||
if (changeTypeEnum == null) {
|
|
||||||
throw new BadRequestException("参数changeTypeEnum必填");
|
|
||||||
}
|
|
||||||
if (StrUtil.isBlank(language)) {
|
|
||||||
throw new BadRequestException("参数language必填");
|
|
||||||
}
|
|
||||||
if (StrUtil.isBlank(envAlias)) {
|
|
||||||
throw new BadRequestException("参数envAlias必填");
|
|
||||||
}
|
|
||||||
if (StrUtil.isBlank(source)) {
|
|
||||||
throw new BadRequestException("参数source必填");
|
|
||||||
}
|
|
||||||
if (dataMap == null) {
|
|
||||||
dataMap = new JobDataMap();
|
|
||||||
}
|
|
||||||
// ========================== 获取任务编排模板 ==========================
|
|
||||||
TaskTemplateInfoVo taskInstanceInfoVo =
|
|
||||||
taskTemplateInfoService.getTemplateInfoByECL(envAlias, contextName, language, changeTypeEnum.getCode());
|
|
||||||
if (taskInstanceInfoVo == null) {
|
|
||||||
throw new BadRequestException("没有查询到任务编排模板");
|
|
||||||
}
|
|
||||||
String templateInfo = taskInstanceInfoVo.getTemplateInfo();
|
|
||||||
List<TaskTemplateNodeVo> taskTemplateNodeVos;
|
|
||||||
try {
|
|
||||||
taskTemplateNodeVos = JSON.parseArray(templateInfo, TaskTemplateNodeVo.class);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("任务编排模板解析失败", e);
|
|
||||||
throw new BadRequestException("任务编排模板解析失败");
|
|
||||||
}
|
|
||||||
if (taskTemplateNodeVos == null || taskTemplateNodeVos.isEmpty()) {
|
|
||||||
throw new BadRequestException("没有查询到任务编排明细");
|
|
||||||
}
|
|
||||||
// ========================== 创建任务 ==========================
|
|
||||||
TaskManage taskManage = KitSpringBeanHolder.getBean(TaskManage.class);
|
|
||||||
TaskInstanceInfoTb newInstance =
|
|
||||||
taskManage.saveTaskInstanceInfoTb(contextName, changeTypeEnum, language, envAlias, source, reason, dataMap,
|
|
||||||
templateInfo);
|
|
||||||
dataMap.put(TaskJobKeys.ID, newInstance.getId());
|
|
||||||
// 应用名、资源类型
|
|
||||||
dataMap.put(TaskJobKeys.CONTEXT_NAME, contextName);
|
|
||||||
// 开发语言、资源版本
|
|
||||||
dataMap.put(TaskJobKeys.LANGUAGE, language);
|
|
||||||
dataMap.put(TaskJobKeys.ENV_ALIAS, envAlias);
|
|
||||||
// 变更类型
|
|
||||||
dataMap.put(TaskJobKeys.CHANGE_TYPE, changeTypeEnum.getCode());
|
|
||||||
buildAndSchedule(changeTypeEnum.getCode(), contextName, dataMap);
|
|
||||||
return newInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public TaskInstanceInfoTb saveTaskInstanceInfoTb(String contextName, TaskChangeTypeEnum changeTypeEnum,
|
|
||||||
String language, String envAlias, String source, String reason, JobDataMap dataMap, String templateInfo) {
|
|
||||||
TaskInstanceInfoTb newInstance = new TaskInstanceInfoTb();
|
|
||||||
newInstance.setContextName(contextName);
|
|
||||||
newInstance.setLanguage(language);
|
|
||||||
newInstance.setChangeType(changeTypeEnum.getCode());
|
|
||||||
newInstance.setEnvAlias(envAlias);
|
|
||||||
newInstance.setStatus(TaskStatusEnum.Running.getCode());
|
|
||||||
newInstance.setFinishTime(null);
|
|
||||||
newInstance.setSource(source);
|
|
||||||
newInstance.setReason(reason);
|
|
||||||
newInstance.setTemplate(templateInfo);
|
|
||||||
newInstance.setJobData(JSON.toJSONString(dataMap));
|
|
||||||
taskInstanceInfoService.save(newInstance);
|
|
||||||
return newInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void buildAndSchedule(String changeTypeEnum, String contextName, JobDataMap dataMap) {
|
|
||||||
// ========================== 执行任务 ==========================
|
|
||||||
JobKey jobKey = JobKey.jobKey(changeTypeEnum, contextName);
|
|
||||||
TriggerKey triggerKey = TriggerKey.triggerKey(changeTypeEnum, contextName);
|
|
||||||
JobDetail jobDetail = JobBuilder.newJob(TaskJobBean.class).withIdentity(jobKey).usingJobData(dataMap).build();
|
|
||||||
Trigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).startNow().build();
|
|
||||||
try {
|
|
||||||
scheduler.scheduleJob(jobDetail, trigger);
|
|
||||||
} catch (ObjectAlreadyExistsException e) {
|
|
||||||
log.error("任务jobKey={},triggerKey={}任务已存在,跳过加载", jobKey.getName(), triggerKey.getName(), e);
|
|
||||||
throw new BadRequestException("任务已存在,跳过加载");
|
|
||||||
} catch (SchedulerException e) {
|
|
||||||
log.error("任务jobKey={},triggerKey={}执行失败", jobKey.getName(), triggerKey.getName(), e);
|
|
||||||
throw new BadRequestException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public void stopJob(Long instanceId) {
|
|
||||||
TaskInstanceInfoTb taskInstanceInfoTb = taskInstanceInfoService.getRunningById(instanceId);
|
|
||||||
String changeType = taskInstanceInfoTb.getChangeType();
|
|
||||||
String contextName = taskInstanceInfoTb.getContextName();
|
|
||||||
taskInstanceInfoTb.setStatus(TaskStatusEnum.Fail.getCode());
|
|
||||||
taskInstanceInfoTb.setErrorMessage("任务被中断");
|
|
||||||
taskInstanceInfoTb.setFinishTime(new Date());
|
|
||||||
taskInstanceInfoService.updateById(taskInstanceInfoTb);
|
|
||||||
try {
|
|
||||||
JobKey jobKey = JobKey.jobKey(changeType, contextName);
|
|
||||||
TriggerKey triggerKey = TriggerKey.triggerKey(changeType, contextName);
|
|
||||||
// 停止触发器
|
|
||||||
scheduler.pauseTrigger(triggerKey);
|
|
||||||
// 移除触发器
|
|
||||||
scheduler.unscheduleJob(triggerKey);
|
|
||||||
// 删除并中断任务
|
|
||||||
scheduler.deleteJob(jobKey);
|
|
||||||
scheduler.interrupt(jobKey);
|
|
||||||
} catch (SchedulerException e) {
|
|
||||||
log.error("任务停止失败", e);
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public TaskInstanceInfoTb retryJob(Long id, String retryNodeCode) {
|
|
||||||
// ========================== 查询任务 ==========================
|
|
||||||
TaskInstanceInfoTb taskInstanceInfoTb = taskInstanceInfoService.getById(id);
|
|
||||||
if (taskInstanceInfoTb == null) {
|
|
||||||
throw new BadRequestException("任务不存在");
|
|
||||||
}
|
|
||||||
// ========================== 失败的任务才能重试 ==========================
|
|
||||||
if (TaskStatusEnum.Success.getCode().equals(taskInstanceInfoTb.getStatus())) {
|
|
||||||
throw new BadRequestException("任务已执行完毕,无法重试");
|
|
||||||
}
|
|
||||||
// 参数重放
|
|
||||||
JobDataMap dataMap = JSON.parseObject(taskInstanceInfoTb.getJobData(), JobDataMap.class);
|
|
||||||
if (dataMap == null) {
|
|
||||||
dataMap = new JobDataMap();
|
|
||||||
}
|
|
||||||
taskInstanceInfoTb.setStatus(TaskStatusEnum.Running.getCode());
|
|
||||||
taskInstanceInfoTb.setFinishTime(null);
|
|
||||||
taskInstanceInfoService.updateById(taskInstanceInfoTb);
|
|
||||||
// ========================== 执行任务 ==========================
|
|
||||||
dataMap.put(TaskJobKeys.RETRY_NODE_CODE, retryNodeCode);
|
|
||||||
String changeType = taskInstanceInfoTb.getChangeType();
|
|
||||||
String contextName = taskInstanceInfoTb.getContextName();
|
|
||||||
buildAndSchedule(changeType, contextName, dataMap);
|
|
||||||
return taskInstanceInfoTb;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskInstanceInfoVo getLastInfo(String contextName, String language, String envAlias, String changeType) {
|
|
||||||
TaskInstanceInfoVo record = new TaskInstanceInfoVo();
|
|
||||||
TaskInstanceInfoTb historyInstance =
|
|
||||||
taskInstanceInfoService.getLastHistoryInstance(contextName, language, envAlias, changeType);
|
|
||||||
if (historyInstance == null) {
|
|
||||||
// 仅返回模板
|
|
||||||
TaskTemplateInfoVo templateInfo =
|
|
||||||
taskTemplateInfoService.getTemplateInfoByECL(envAlias, contextName, language, changeType);
|
|
||||||
if (templateInfo == null) {
|
|
||||||
throw new BadRequestException("没有查询到任务编排模板");
|
|
||||||
}
|
|
||||||
record.setTemplate(templateInfo.getTemplateInfo());
|
|
||||||
return record;
|
|
||||||
}
|
|
||||||
record = KitBeanUtil.copyToClass(historyInstance, TaskInstanceInfoVo.class);
|
|
||||||
record.setHistory(buildNodeList(record));
|
|
||||||
TaskInstanceInfoTb runningInstance = taskInstanceInfoService.getLastRunningInstance(contextName, language, envAlias, changeType);
|
|
||||||
if (runningInstance != null) {
|
|
||||||
TaskInstanceInfoVo taskInstanceInfoVo = KitBeanUtil.copyToClass(runningInstance, TaskInstanceInfoVo.class);
|
|
||||||
record.setCurrent(buildNodeList(taskInstanceInfoVo));
|
|
||||||
}
|
|
||||||
return record;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<TaskInstanceNodeVo> buildNodeList(TaskInstanceInfoVo record) {
|
|
||||||
List<TaskInstanceNodeVo> records = new ArrayList<>();
|
|
||||||
// 节点明细
|
|
||||||
List<TaskInstanceDetailTb> taskInstanceDetails = taskInstanceDetailService.queryByInstanceId(record.getId());
|
|
||||||
for (TaskInstanceDetailTb taskInstanceDetail : taskInstanceDetails) {
|
|
||||||
TaskInstanceNodeVo instanceNodeVo = new TaskInstanceNodeVo();
|
|
||||||
instanceNodeVo.setCode(taskInstanceDetail.getBizCode());
|
|
||||||
instanceNodeVo.setName(taskInstanceDetail.getBizName());
|
|
||||||
instanceNodeVo.setStartTime(taskInstanceDetail.getStartTime());
|
|
||||||
instanceNodeVo.setFinishTime(taskInstanceDetail.getFinishTime());
|
|
||||||
if (taskInstanceDetail.getFinishTime() == null) {
|
|
||||||
instanceNodeVo.setDurationDesc(
|
|
||||||
KitDateUtil.formatSecondsDuration(taskInstanceDetail.getStartTime(), new Date()));
|
|
||||||
} else {
|
|
||||||
instanceNodeVo.setDurationDesc(KitDateUtil.formatSecondsDuration(taskInstanceDetail.getStartTime(),
|
|
||||||
taskInstanceDetail.getFinishTime()));
|
|
||||||
}
|
|
||||||
instanceNodeVo.setRunningDesc(taskInstanceDetail.getExecuteInfo());
|
|
||||||
instanceNodeVo.setStatus(taskInstanceDetail.getExecuteStatus());
|
|
||||||
instanceNodeVo.setStatusDesc(TaskStatusEnum.getDesc(taskInstanceDetail.getExecuteStatus()));
|
|
||||||
records.add(instanceNodeVo);
|
|
||||||
}
|
|
||||||
return records;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-31
@@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.core;
|
|
||||||
|
|
||||||
import cn.odboy.framework.exception.BadRequestException;
|
|
||||||
import cn.odboy.task.dal.model.TaskTemplateNodeVo;
|
|
||||||
import org.quartz.JobDataMap;
|
|
||||||
|
|
||||||
public interface TaskStepExecutor {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param instanceDetailId 任务实例明细id
|
|
||||||
* @param jobDataMap 执行参数
|
|
||||||
* @param taskTemplateNode 任务节点信息
|
|
||||||
*/
|
|
||||||
void execute(Long instanceDetailId, JobDataMap jobDataMap, TaskTemplateNodeVo taskTemplateNode)
|
|
||||||
throws BadRequestException;
|
|
||||||
}
|
|
||||||
-35
@@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.core.impl;
|
|
||||||
|
|
||||||
import cn.hutool.core.thread.ThreadUtil;
|
|
||||||
import cn.odboy.framework.exception.BadRequestException;
|
|
||||||
import cn.odboy.task.core.TaskStepExecutor;
|
|
||||||
import cn.odboy.task.dal.model.TaskTemplateNodeVo;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.quartz.JobDataMap;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@Component
|
|
||||||
public class TaskStepNodeBuildJava implements TaskStepExecutor {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(Long instanceDetailId, JobDataMap jobDataMap, TaskTemplateNodeVo taskTemplateNode)
|
|
||||||
throws BadRequestException {
|
|
||||||
ThreadUtil.sleep(2000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-35
@@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.core.impl;
|
|
||||||
|
|
||||||
import cn.hutool.core.thread.ThreadUtil;
|
|
||||||
import cn.odboy.framework.exception.BadRequestException;
|
|
||||||
import cn.odboy.task.core.TaskStepExecutor;
|
|
||||||
import cn.odboy.task.dal.model.TaskTemplateNodeVo;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.quartz.JobDataMap;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@Component
|
|
||||||
public class TaskStepNodeDeployJava implements TaskStepExecutor {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(Long instanceDetailId, JobDataMap jobDataMap, TaskTemplateNodeVo taskTemplateNode)
|
|
||||||
throws BadRequestException {
|
|
||||||
ThreadUtil.sleep(5000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-41
@@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.core.impl;
|
|
||||||
|
|
||||||
import cn.odboy.framework.exception.BadRequestException;
|
|
||||||
import cn.odboy.task.core.TaskStepExecutor;
|
|
||||||
import cn.odboy.task.dal.model.TaskTemplateNodeVo;
|
|
||||||
import cn.odboy.task.service.TaskInstanceStepDetailService;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.quartz.JobDataMap;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@Component
|
|
||||||
public class TaskStepNodeInit implements TaskStepExecutor {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private TaskInstanceStepDetailService stepDetailService;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(Long instanceDetailId, JobDataMap jobDataMap, TaskTemplateNodeVo taskTemplateNode)
|
|
||||||
throws BadRequestException {
|
|
||||||
stepDetailService.success(instanceDetailId, "开始初始化");
|
|
||||||
stepDetailService.success(instanceDetailId, "初始化完毕后,放入了一些参数");
|
|
||||||
jobDataMap.put("ExcuseMe", "Hello World!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-42
@@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.core.impl;
|
|
||||||
|
|
||||||
import cn.hutool.core.thread.ThreadUtil;
|
|
||||||
import cn.odboy.framework.exception.BadRequestException;
|
|
||||||
import cn.odboy.task.core.TaskStepExecutor;
|
|
||||||
import cn.odboy.task.dal.model.TaskTemplateNodeVo;
|
|
||||||
import cn.odboy.task.service.TaskInstanceStepDetailService;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.quartz.JobDataMap;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@Component
|
|
||||||
public class TaskStepNodeMergeBranch implements TaskStepExecutor {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private TaskInstanceStepDetailService stepDetailService;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(Long instanceDetailId, JobDataMap jobDataMap, TaskTemplateNodeVo taskTemplateNode)
|
|
||||||
throws BadRequestException {
|
|
||||||
ThreadUtil.sleep(3000);
|
|
||||||
stepDetailService.fail(instanceDetailId, "执行失败测试");
|
|
||||||
// stepDetailService.success(instanceDetailId, "执行成功");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-109
@@ -1,109 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.dal.dataobject;
|
|
||||||
|
|
||||||
import cn.odboy.base.KitObject;
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
|
||||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
|
||||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import java.util.Date;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import lombok.ToString;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 任务实例明细
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author codegen
|
|
||||||
* @since 2025-09-26
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@ToString
|
|
||||||
@TableName("task_instance_detail")
|
|
||||||
@ApiModel(value = "TaskInstanceDetailTb对象", description = "任务实例明细")
|
|
||||||
public class TaskInstanceDetailTb extends KitObject {
|
|
||||||
|
|
||||||
@TableField(fill = FieldFill.INSERT)
|
|
||||||
@ApiModelProperty(value = "创建时间: yyyy-MM-dd HH:mm:ss", hidden = true)
|
|
||||||
private Date createTime;
|
|
||||||
/**
|
|
||||||
* id
|
|
||||||
*/
|
|
||||||
@ApiModelProperty("id")
|
|
||||||
@TableId(value = "id", type = IdType.ASSIGN_ID)
|
|
||||||
@JsonSerialize(using = ToStringSerializer.class)
|
|
||||||
@JSONField(format = "string")
|
|
||||||
private Long id;
|
|
||||||
/**
|
|
||||||
* 任务实例id
|
|
||||||
*/
|
|
||||||
@TableField("instance_id")
|
|
||||||
@ApiModelProperty("任务实例id")
|
|
||||||
private Long instanceId;
|
|
||||||
/**
|
|
||||||
* 开始时间
|
|
||||||
*/
|
|
||||||
@ApiModelProperty("开始时间")
|
|
||||||
@TableField("start_time")
|
|
||||||
private Date startTime;
|
|
||||||
/**
|
|
||||||
* 结束时间
|
|
||||||
*/
|
|
||||||
@ApiModelProperty("结束时间")
|
|
||||||
@TableField("finish_time")
|
|
||||||
private Date finishTime;
|
|
||||||
/**
|
|
||||||
* 业务编码
|
|
||||||
*/
|
|
||||||
@TableField("biz_code")
|
|
||||||
@ApiModelProperty("业务编码")
|
|
||||||
private String bizCode;
|
|
||||||
/**
|
|
||||||
* 业务名称(步骤)
|
|
||||||
*/
|
|
||||||
@TableField("biz_name")
|
|
||||||
@ApiModelProperty("业务名称(步骤)")
|
|
||||||
private String bizName;
|
|
||||||
/**
|
|
||||||
* 执行参数
|
|
||||||
*/
|
|
||||||
@ApiModelProperty("执行参数")
|
|
||||||
@TableField("execute_params")
|
|
||||||
private String executeParams;
|
|
||||||
/**
|
|
||||||
* 执行信息
|
|
||||||
*/
|
|
||||||
@ApiModelProperty("执行信息")
|
|
||||||
@TableField("execute_info")
|
|
||||||
private String executeInfo;
|
|
||||||
/**
|
|
||||||
* 执行状态(running进行中 success成功 fail失败)
|
|
||||||
*/
|
|
||||||
@TableField("execute_status")
|
|
||||||
@ApiModelProperty("执行状态(running进行中 success成功 fail失败)")
|
|
||||||
private String
|
|
||||||
executeStatus;
|
|
||||||
}
|
|
||||||
-135
@@ -1,135 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.dal.dataobject;
|
|
||||||
|
|
||||||
import cn.odboy.base.KitObject;
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
|
||||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
|
||||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import java.util.Date;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import lombok.ToString;
|
|
||||||
import org.springframework.data.annotation.CreatedBy;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 任务实例
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author codegen
|
|
||||||
* @since 2025-09-26
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@ToString
|
|
||||||
@TableName("task_instance_info")
|
|
||||||
@ApiModel(value = "TaskInstanceInfoTb对象", description = "任务实例")
|
|
||||||
public class TaskInstanceInfoTb extends KitObject {
|
|
||||||
|
|
||||||
@CreatedBy
|
|
||||||
@TableField(fill = FieldFill.INSERT)
|
|
||||||
@ApiModelProperty(value = "创建人", hidden = true)
|
|
||||||
private String
|
|
||||||
createBy;
|
|
||||||
@TableField(fill = FieldFill.INSERT)
|
|
||||||
@ApiModelProperty(value = "创建时间: yyyy-MM-dd HH:mm:ss", hidden = true)
|
|
||||||
private Date createTime;
|
|
||||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
|
||||||
@ApiModelProperty(value = "更新时间: yyyy-MM-dd HH:mm:ss", hidden = true)
|
|
||||||
private Date updateTime;
|
|
||||||
/**
|
|
||||||
* id, @JsonSerialize和@JSONField,用于处理大数精度丢失问题
|
|
||||||
*/
|
|
||||||
@ApiModelProperty("id")
|
|
||||||
@TableId(value = "id", type = IdType.ASSIGN_ID)
|
|
||||||
@JsonSerialize(using = ToStringSerializer.class)
|
|
||||||
@JSONField(format = "string")
|
|
||||||
private Long id;
|
|
||||||
/**
|
|
||||||
* 名称
|
|
||||||
*/
|
|
||||||
@ApiModelProperty("名称")
|
|
||||||
@TableField("context_name")
|
|
||||||
private String contextName;
|
|
||||||
/**
|
|
||||||
* 语言
|
|
||||||
*/
|
|
||||||
@ApiModelProperty("语言")
|
|
||||||
@TableField("`language`")
|
|
||||||
private String language;
|
|
||||||
/**
|
|
||||||
* 变更类型
|
|
||||||
*/
|
|
||||||
@ApiModelProperty("变更类型")
|
|
||||||
@TableField("change_type")
|
|
||||||
private String changeType;
|
|
||||||
/**
|
|
||||||
* 环境别名
|
|
||||||
*/
|
|
||||||
@TableField("env_alias")
|
|
||||||
@ApiModelProperty("环境别名")
|
|
||||||
private String envAlias;
|
|
||||||
/**
|
|
||||||
* 状态(running进行中 success成功 fail失败)
|
|
||||||
*/
|
|
||||||
@TableField("`status`")
|
|
||||||
@ApiModelProperty("状态(running进行中 success成功 fail失败)")
|
|
||||||
private String status;
|
|
||||||
/**
|
|
||||||
* 完成时间
|
|
||||||
*/
|
|
||||||
@ApiModelProperty("完成时间")
|
|
||||||
@TableField("finish_time")
|
|
||||||
private Date finishTime;
|
|
||||||
/**
|
|
||||||
* 来源
|
|
||||||
*/
|
|
||||||
@ApiModelProperty("来源")
|
|
||||||
@TableField("`source`")
|
|
||||||
private String source;
|
|
||||||
/**
|
|
||||||
* 变更原因
|
|
||||||
*/
|
|
||||||
@TableField("reason")
|
|
||||||
@ApiModelProperty("变更原因")
|
|
||||||
private String reason;
|
|
||||||
/**
|
|
||||||
* 任务模板
|
|
||||||
*/
|
|
||||||
@TableField("template")
|
|
||||||
@ApiModelProperty("template")
|
|
||||||
private String template;
|
|
||||||
/**
|
|
||||||
* QuartzJob参数
|
|
||||||
*/
|
|
||||||
@TableField("job_data")
|
|
||||||
@ApiModelProperty("QuartzJob参数")
|
|
||||||
private String jobData;
|
|
||||||
/**
|
|
||||||
* 异常信息
|
|
||||||
*/
|
|
||||||
@TableField("error_message")
|
|
||||||
@ApiModelProperty("异常信息")
|
|
||||||
private String errorMessage;
|
|
||||||
}
|
|
||||||
-78
@@ -1,78 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.dal.dataobject;
|
|
||||||
|
|
||||||
import cn.odboy.base.KitObject;
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
|
||||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
|
||||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import java.util.Date;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import lombok.ToString;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 任务实例步骤明细
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author codegen
|
|
||||||
* @since 2025-09-28
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@ToString
|
|
||||||
@TableName("task_instance_step_detail")
|
|
||||||
@ApiModel(value = "TaskInstanceStepDetailTb对象", description = "")
|
|
||||||
public class TaskInstanceStepDetailTb extends KitObject {
|
|
||||||
|
|
||||||
@TableField(fill = FieldFill.INSERT)
|
|
||||||
@ApiModelProperty(value = "创建时间: yyyy-MM-dd HH:mm:ss", hidden = true)
|
|
||||||
private Date createTime;
|
|
||||||
/**
|
|
||||||
* id
|
|
||||||
*/
|
|
||||||
@ApiModelProperty("id")
|
|
||||||
@TableId(value = "id", type = IdType.ASSIGN_ID)
|
|
||||||
@JsonSerialize(using = ToStringSerializer.class)
|
|
||||||
@JSONField(format = "string")
|
|
||||||
private Long id;
|
|
||||||
/**
|
|
||||||
* task_instance_detail表id
|
|
||||||
*/
|
|
||||||
@TableField("instance_detail_id")
|
|
||||||
@ApiModelProperty("task_instance_detail表id")
|
|
||||||
private Long instanceDetailId;
|
|
||||||
/**
|
|
||||||
* 步骤描述
|
|
||||||
*/
|
|
||||||
@TableField("step_desc")
|
|
||||||
@ApiModelProperty("步骤描述")
|
|
||||||
private String stepDesc;
|
|
||||||
/**
|
|
||||||
* 状态(success成功 fail失败)
|
|
||||||
*/
|
|
||||||
@TableField("step_status")
|
|
||||||
@ApiModelProperty("状态(success成功 fail失败)")
|
|
||||||
private String stepStatus;
|
|
||||||
}
|
|
||||||
-92
@@ -1,92 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.dal.dataobject;
|
|
||||||
|
|
||||||
import cn.odboy.base.KitBaseUserTimeTb;
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import lombok.ToString;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 任务模板
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author codegen
|
|
||||||
* @since 2025-09-28
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@ToString
|
|
||||||
@TableName("task_template_info")
|
|
||||||
@ApiModel(value = "TaskTemplateInfoTb对象", description = "任务模板")
|
|
||||||
public class TaskTemplateInfoTb extends KitBaseUserTimeTb {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* id
|
|
||||||
*/
|
|
||||||
@ApiModelProperty("id")
|
|
||||||
@TableId(value = "id", type = IdType.AUTO)
|
|
||||||
private Long id;
|
|
||||||
/**
|
|
||||||
* 数据有效性
|
|
||||||
*/
|
|
||||||
@TableField("available")
|
|
||||||
@ApiModelProperty("数据有效性")
|
|
||||||
private Boolean available;
|
|
||||||
/**
|
|
||||||
* 变更类型
|
|
||||||
*/
|
|
||||||
@ApiModelProperty("变更类型")
|
|
||||||
@TableField("change_type")
|
|
||||||
private String changeType;
|
|
||||||
/**
|
|
||||||
* 流水线名称
|
|
||||||
*/
|
|
||||||
@TableField("`name`")
|
|
||||||
@ApiModelProperty("流水线名称")
|
|
||||||
private String name;
|
|
||||||
/**
|
|
||||||
* 流水线描述
|
|
||||||
*/
|
|
||||||
@ApiModelProperty("流水线描述")
|
|
||||||
@TableField("`description`")
|
|
||||||
private String description;
|
|
||||||
/**
|
|
||||||
* 流水线模板内容
|
|
||||||
*/
|
|
||||||
@TableField("template")
|
|
||||||
@ApiModelProperty("流水线模板内容")
|
|
||||||
private String template;
|
|
||||||
/**
|
|
||||||
* 环境别名
|
|
||||||
*/
|
|
||||||
@TableField("env_alias")
|
|
||||||
@ApiModelProperty("环境别名")
|
|
||||||
private String envAlias;
|
|
||||||
/**
|
|
||||||
* 应用为语言,资源为类型
|
|
||||||
*/
|
|
||||||
@TableField("`language`")
|
|
||||||
@ApiModelProperty("应用为语言,资源为类型")
|
|
||||||
private String language;
|
|
||||||
}
|
|
||||||
-26
@@ -1,26 +0,0 @@
|
|||||||
package cn.odboy.task.dal.model;
|
|
||||||
|
|
||||||
import cn.odboy.task.dal.dataobject.TaskInstanceInfoTb;
|
|
||||||
import java.util.List;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 任务实例数据
|
|
||||||
*
|
|
||||||
* @author odboy
|
|
||||||
* @date 2025-10-01
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
public class TaskInstanceInfoVo extends TaskInstanceInfoTb {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 进行中
|
|
||||||
*/
|
|
||||||
private List<TaskInstanceNodeVo> current;
|
|
||||||
/**
|
|
||||||
* 历史已完成或异常
|
|
||||||
*/
|
|
||||||
private List<TaskInstanceNodeVo> history;
|
|
||||||
}
|
|
||||||
-64
@@ -1,64 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.dal.model;
|
|
||||||
|
|
||||||
import cn.odboy.base.KitObject;
|
|
||||||
import java.util.Date;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 任务节点数据
|
|
||||||
*
|
|
||||||
* @author odboy
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
public class TaskInstanceNodeVo extends KitObject {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 业务编码
|
|
||||||
*/
|
|
||||||
protected String code;
|
|
||||||
/**
|
|
||||||
* 业务名称
|
|
||||||
*/
|
|
||||||
protected String name;
|
|
||||||
/**
|
|
||||||
* 开始时间
|
|
||||||
*/
|
|
||||||
protected Date startTime;
|
|
||||||
/**
|
|
||||||
* 完成时间
|
|
||||||
*/
|
|
||||||
protected Date finishTime;
|
|
||||||
/**
|
|
||||||
* 耗时多久
|
|
||||||
*/
|
|
||||||
protected String durationDesc;
|
|
||||||
/**
|
|
||||||
* 进行中描述
|
|
||||||
*/
|
|
||||||
protected String runningDesc;
|
|
||||||
/**
|
|
||||||
* 节点状态编码
|
|
||||||
*/
|
|
||||||
protected String status;
|
|
||||||
/**
|
|
||||||
* 节点状态描述
|
|
||||||
*/
|
|
||||||
protected String statusDesc;
|
|
||||||
}
|
|
||||||
-33
@@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.dal.model;
|
|
||||||
|
|
||||||
import cn.odboy.base.KitObject;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
public class TaskTemplateInfoVo extends KitObject {
|
|
||||||
|
|
||||||
private String changeType;
|
|
||||||
private String name;
|
|
||||||
private String description;
|
|
||||||
private String envAlias;
|
|
||||||
private String language;
|
|
||||||
private String contextName;
|
|
||||||
private String templateInfo;
|
|
||||||
}
|
|
||||||
-49
@@ -1,49 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.dal.model;
|
|
||||||
|
|
||||||
import cn.odboy.base.KitObject;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 流水线节点控制按钮
|
|
||||||
*
|
|
||||||
* @author odboy
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
public class TaskTemplateNodeOperateButtonVo extends KitObject {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按钮类型(service:调用某个服务并传递参数 link:带参跳转)
|
|
||||||
*/
|
|
||||||
private String type;
|
|
||||||
/**
|
|
||||||
* 按钮标题
|
|
||||||
*/
|
|
||||||
private String title;
|
|
||||||
/**
|
|
||||||
* 按钮传递的参数
|
|
||||||
*/
|
|
||||||
private String code;
|
|
||||||
/**
|
|
||||||
* 默认附加参数
|
|
||||||
*/
|
|
||||||
private Map<String, String> parameters = new HashMap<>();
|
|
||||||
}
|
|
||||||
-67
@@ -1,67 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.dal.model;
|
|
||||||
|
|
||||||
import cn.odboy.base.KitObject;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 任务节点模板
|
|
||||||
*
|
|
||||||
* @author odboy
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
public class TaskTemplateNodeVo extends KitObject {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 业务编码
|
|
||||||
*/
|
|
||||||
protected String code;
|
|
||||||
/**
|
|
||||||
* 业务类型(service:系统内置服务 rpc:远程调用)
|
|
||||||
*/
|
|
||||||
protected String type;
|
|
||||||
/**
|
|
||||||
* 业务名称
|
|
||||||
*/
|
|
||||||
protected String name;
|
|
||||||
/**
|
|
||||||
* 是否可点击
|
|
||||||
*/
|
|
||||||
protected Boolean click = false;
|
|
||||||
/**
|
|
||||||
* 是否可重试
|
|
||||||
*/
|
|
||||||
protected Boolean retry = false;
|
|
||||||
/**
|
|
||||||
* 是否可点击:点击展示详情,详情内容类型
|
|
||||||
*/
|
|
||||||
protected String detailType = "";
|
|
||||||
/**
|
|
||||||
* 默认参数<br/> execute: 执行调用 describe: 明细调用
|
|
||||||
*/
|
|
||||||
protected Map<String, String> parameters = new HashMap<>();
|
|
||||||
/**
|
|
||||||
* 流水线节点控制按钮
|
|
||||||
*/
|
|
||||||
protected List<TaskTemplateNodeOperateButtonVo> buttons = new ArrayList<>();
|
|
||||||
}
|
|
||||||
-33
@@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.dal.mysql;
|
|
||||||
|
|
||||||
import cn.odboy.task.dal.dataobject.TaskInstanceDetailTb;
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 任务实例明细 Mapper 接口
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author codegen
|
|
||||||
* @since 2025-09-26
|
|
||||||
*/
|
|
||||||
@Mapper
|
|
||||||
public interface TaskInstanceDetailMapper extends BaseMapper<TaskInstanceDetailTb> {
|
|
||||||
|
|
||||||
}
|
|
||||||
-33
@@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.dal.mysql;
|
|
||||||
|
|
||||||
import cn.odboy.task.dal.dataobject.TaskInstanceInfoTb;
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 任务实例 Mapper 接口
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author codegen
|
|
||||||
* @since 2025-09-26
|
|
||||||
*/
|
|
||||||
@Mapper
|
|
||||||
public interface TaskInstanceInfoMapper extends BaseMapper<TaskInstanceInfoTb> {
|
|
||||||
|
|
||||||
}
|
|
||||||
-33
@@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.dal.mysql;
|
|
||||||
|
|
||||||
import cn.odboy.task.dal.dataobject.TaskInstanceStepDetailTb;
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 任务实例步骤明细 Mapper 接口
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author codegen
|
|
||||||
* @since 2025-09-28
|
|
||||||
*/
|
|
||||||
@Mapper
|
|
||||||
public interface TaskInstanceStepDetailMapper extends BaseMapper<TaskInstanceStepDetailTb> {
|
|
||||||
|
|
||||||
}
|
|
||||||
-45
@@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.dal.mysql;
|
|
||||||
|
|
||||||
import cn.odboy.task.dal.dataobject.TaskTemplateInfoTb;
|
|
||||||
import cn.odboy.task.dal.model.TaskTemplateInfoVo;
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
|
||||||
import org.apache.ibatis.annotations.Param;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 任务模板 Mapper 接口
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author codegen
|
|
||||||
* @since 2025-09-28
|
|
||||||
*/
|
|
||||||
@Mapper
|
|
||||||
public interface TaskTemplateInfoMapper extends BaseMapper<TaskTemplateInfoTb> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param envAlias 环境别称
|
|
||||||
* @param contextName 应用名称、资源类型
|
|
||||||
* @param language 语言、版本
|
|
||||||
* @param changeType 变更类型
|
|
||||||
* @return /
|
|
||||||
*/
|
|
||||||
TaskTemplateInfoVo selectTemplateInfoByECL(@Param("envAlias") String envAlias,
|
|
||||||
@Param("contextName") String contextName, @Param("language") String language,
|
|
||||||
@Param("changeType") String changeType);
|
|
||||||
}
|
|
||||||
-111
@@ -1,111 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.service;
|
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
|
||||||
import cn.odboy.task.constant.TaskStatusEnum;
|
|
||||||
import cn.odboy.task.dal.dataobject.TaskInstanceDetailTb;
|
|
||||||
import cn.odboy.task.dal.mysql.TaskInstanceDetailMapper;
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
import org.quartz.JobDataMap;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 任务实例明细
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author codegen
|
|
||||||
* @since 2025-09-28
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
public class TaskInstanceDetailService {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private TaskInstanceDetailMapper taskInstanceDetailMapper;
|
|
||||||
|
|
||||||
public void fastFailWithInfo(Long instanceId, String code, String executeInfo) {
|
|
||||||
LambdaUpdateWrapper<TaskInstanceDetailTb> wrapper = new LambdaUpdateWrapper<>();
|
|
||||||
wrapper.eq(TaskInstanceDetailTb::getInstanceId, instanceId);
|
|
||||||
wrapper.eq(TaskInstanceDetailTb::getBizCode, code);
|
|
||||||
wrapper.set(TaskInstanceDetailTb::getFinishTime, new Date());
|
|
||||||
wrapper.set(TaskInstanceDetailTb::getExecuteInfo, executeInfo);
|
|
||||||
wrapper.set(TaskInstanceDetailTb::getExecuteStatus, TaskStatusEnum.Fail.getCode());
|
|
||||||
taskInstanceDetailMapper.update(null, wrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fastSuccess(Long instanceId, String code) {
|
|
||||||
LambdaUpdateWrapper<TaskInstanceDetailTb> wrapper = new LambdaUpdateWrapper<>();
|
|
||||||
wrapper.eq(TaskInstanceDetailTb::getInstanceId, instanceId);
|
|
||||||
wrapper.eq(TaskInstanceDetailTb::getBizCode, code);
|
|
||||||
wrapper.set(TaskInstanceDetailTb::getFinishTime, new Date());
|
|
||||||
wrapper.set(TaskInstanceDetailTb::getExecuteInfo, TaskStatusEnum.Success.getName());
|
|
||||||
wrapper.set(TaskInstanceDetailTb::getExecuteStatus, TaskStatusEnum.Success.getCode());
|
|
||||||
taskInstanceDetailMapper.update(null, wrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fastSuccessWithInfo(Long instanceId, String code, String executeInfo) {
|
|
||||||
LambdaUpdateWrapper<TaskInstanceDetailTb> wrapper = new LambdaUpdateWrapper<>();
|
|
||||||
wrapper.eq(TaskInstanceDetailTb::getInstanceId, instanceId);
|
|
||||||
wrapper.eq(TaskInstanceDetailTb::getBizCode, code);
|
|
||||||
wrapper.set(TaskInstanceDetailTb::getFinishTime, new Date());
|
|
||||||
wrapper.set(TaskInstanceDetailTb::getExecuteInfo,
|
|
||||||
executeInfo == null ? TaskStatusEnum.Success.getName() : executeInfo);
|
|
||||||
wrapper.set(TaskInstanceDetailTb::getExecuteStatus, TaskStatusEnum.Success.getCode());
|
|
||||||
taskInstanceDetailMapper.update(null, wrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fastStart(Long instanceId, String code, JobDataMap dataMap) {
|
|
||||||
LambdaUpdateWrapper<TaskInstanceDetailTb> wrapper = new LambdaUpdateWrapper<>();
|
|
||||||
wrapper.eq(TaskInstanceDetailTb::getInstanceId, instanceId);
|
|
||||||
wrapper.eq(TaskInstanceDetailTb::getBizCode, code);
|
|
||||||
wrapper.set(TaskInstanceDetailTb::getStartTime, new Date());
|
|
||||||
wrapper.set(TaskInstanceDetailTb::getExecuteInfo, TaskStatusEnum.Running.getName());
|
|
||||||
wrapper.set(TaskInstanceDetailTb::getExecuteParams, JSON.toJSONString(dataMap));
|
|
||||||
wrapper.set(TaskInstanceDetailTb::getExecuteStatus, TaskStatusEnum.Running.getCode());
|
|
||||||
taskInstanceDetailMapper.update(null, wrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<TaskInstanceDetailTb> queryByInstanceIdAndBizCodeList(Long instanceId, List<String> bizCodeList) {
|
|
||||||
if (CollUtil.isEmpty(bizCodeList)) {
|
|
||||||
return CollUtil.newArrayList();
|
|
||||||
}
|
|
||||||
LambdaQueryWrapper<TaskInstanceDetailTb> wrapper = new LambdaQueryWrapper<>();
|
|
||||||
wrapper.eq(TaskInstanceDetailTb::getInstanceId, instanceId);
|
|
||||||
wrapper.in(TaskInstanceDetailTb::getBizCode, bizCodeList);
|
|
||||||
return taskInstanceDetailMapper.selectList(wrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<TaskInstanceDetailTb> queryByInstanceId(Long instanceId) {
|
|
||||||
LambdaUpdateWrapper<TaskInstanceDetailTb> wrapper = new LambdaUpdateWrapper<>();
|
|
||||||
wrapper.eq(TaskInstanceDetailTb::getInstanceId, instanceId);
|
|
||||||
wrapper.orderByAsc(TaskInstanceDetailTb::getId);
|
|
||||||
return taskInstanceDetailMapper.selectList(wrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void saveBatch(List<TaskInstanceDetailTb> taskInstanceDetails) {
|
|
||||||
taskInstanceDetailMapper.insert(taskInstanceDetails);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeByIds(List<Long> taskInstanceDetailIds) {
|
|
||||||
taskInstanceDetailMapper.deleteByIds(taskInstanceDetailIds);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-117
@@ -1,117 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.service;
|
|
||||||
|
|
||||||
import cn.odboy.task.constant.TaskStatusEnum;
|
|
||||||
import cn.odboy.task.dal.dataobject.TaskInstanceInfoTb;
|
|
||||||
import cn.odboy.task.dal.mysql.TaskInstanceInfoMapper;
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
||||||
import java.util.Date;
|
|
||||||
import org.quartz.JobDataMap;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 任务实例 服务实现类
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author codegen
|
|
||||||
* @since 2025-09-26
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
public class TaskInstanceInfoService {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private TaskInstanceInfoMapper taskInstanceInfoMapper;
|
|
||||||
|
|
||||||
public TaskInstanceInfoTb getRunningById(Long id) {
|
|
||||||
LambdaUpdateWrapper<TaskInstanceInfoTb> wrapper = new LambdaUpdateWrapper<>();
|
|
||||||
wrapper.eq(TaskInstanceInfoTb::getId, id);
|
|
||||||
wrapper.eq(TaskInstanceInfoTb::getStatus, TaskStatusEnum.Running.getCode());
|
|
||||||
wrapper.orderByDesc(TaskInstanceInfoTb::getId);
|
|
||||||
return taskInstanceInfoMapper.selectOne(wrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public void fastFailWithMessage(Long id, String errorMessage) {
|
|
||||||
TaskInstanceInfoTb updRecord = new TaskInstanceInfoTb();
|
|
||||||
updRecord.setId(id);
|
|
||||||
updRecord.setFinishTime(new Date());
|
|
||||||
updRecord.setStatus(TaskStatusEnum.Fail.getCode());
|
|
||||||
updRecord.setErrorMessage(errorMessage);
|
|
||||||
taskInstanceInfoMapper.updateById(updRecord);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public void fastFailWithMessageData(Long id, String errorMessage, JobDataMap dataMap) {
|
|
||||||
TaskInstanceInfoTb updRecord = new TaskInstanceInfoTb();
|
|
||||||
updRecord.setId(id);
|
|
||||||
updRecord.setFinishTime(new Date());
|
|
||||||
updRecord.setStatus(TaskStatusEnum.Fail.getCode());
|
|
||||||
updRecord.setErrorMessage(errorMessage);
|
|
||||||
updRecord.setJobData(JSON.toJSONString(dataMap));
|
|
||||||
taskInstanceInfoMapper.updateById(updRecord);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public void fastSuccessWithData(Long id, JobDataMap dataMap) {
|
|
||||||
TaskInstanceInfoTb updRecord = new TaskInstanceInfoTb();
|
|
||||||
updRecord.setId(id);
|
|
||||||
updRecord.setFinishTime(new Date());
|
|
||||||
updRecord.setStatus(TaskStatusEnum.Success.getCode());
|
|
||||||
updRecord.setJobData(JSON.toJSONString(dataMap));
|
|
||||||
taskInstanceInfoMapper.updateById(updRecord);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskInstanceInfoTb getLastRunningInstance(String contextName, String language, String envAlias,
|
|
||||||
String changeType) {
|
|
||||||
LambdaUpdateWrapper<TaskInstanceInfoTb> wrapper = new LambdaUpdateWrapper<>();
|
|
||||||
wrapper.eq(TaskInstanceInfoTb::getContextName, contextName);
|
|
||||||
wrapper.eq(TaskInstanceInfoTb::getLanguage, language);
|
|
||||||
wrapper.eq(TaskInstanceInfoTb::getEnvAlias, envAlias);
|
|
||||||
wrapper.eq(TaskInstanceInfoTb::getChangeType, changeType);
|
|
||||||
wrapper.eq(TaskInstanceInfoTb::getStatus, TaskStatusEnum.Running.getCode());
|
|
||||||
wrapper.orderByDesc(TaskInstanceInfoTb::getId);
|
|
||||||
return taskInstanceInfoMapper.selectOne(wrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskInstanceInfoTb getLastHistoryInstance(String contextName, String language, String envAlias,
|
|
||||||
String changeType) {
|
|
||||||
LambdaUpdateWrapper<TaskInstanceInfoTb> wrapper = new LambdaUpdateWrapper<>();
|
|
||||||
wrapper.eq(TaskInstanceInfoTb::getContextName, contextName);
|
|
||||||
wrapper.eq(TaskInstanceInfoTb::getLanguage, language);
|
|
||||||
wrapper.eq(TaskInstanceInfoTb::getEnvAlias, envAlias);
|
|
||||||
wrapper.eq(TaskInstanceInfoTb::getChangeType, changeType);
|
|
||||||
wrapper.orderByDesc(TaskInstanceInfoTb::getId);
|
|
||||||
wrapper.last("LIMIT 1");
|
|
||||||
return taskInstanceInfoMapper.selectOne(wrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void save(TaskInstanceInfoTb newInstance) {
|
|
||||||
taskInstanceInfoMapper.insert(newInstance);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskInstanceInfoTb getById(Long id) {
|
|
||||||
return taskInstanceInfoMapper.selectById(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateById(TaskInstanceInfoTb taskInstanceInfoTb) {
|
|
||||||
taskInstanceInfoMapper.updateById(taskInstanceInfoTb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-84
@@ -1,84 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.service;
|
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
|
||||||
import cn.odboy.framework.exception.BadRequestException;
|
|
||||||
import cn.odboy.task.constant.TaskStatusEnum;
|
|
||||||
import cn.odboy.task.dal.dataobject.TaskInstanceStepDetailTb;
|
|
||||||
import cn.odboy.task.dal.mysql.TaskInstanceStepDetailMapper;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
||||||
import java.util.List;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 任务实例步骤明细 服务实现类
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author codegen
|
|
||||||
* @since 2025-09-28
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
public class TaskInstanceStepDetailService {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private TaskInstanceStepDetailMapper taskInstanceStepDetailMapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 步骤执行成功
|
|
||||||
*
|
|
||||||
* @param instanceDetailId 任务实例明细id
|
|
||||||
* @param stepDesc 步骤描述
|
|
||||||
*/
|
|
||||||
public void success(Long instanceDetailId, String stepDesc) {
|
|
||||||
TaskInstanceStepDetailTb stepDetail = new TaskInstanceStepDetailTb();
|
|
||||||
stepDetail.setInstanceDetailId(instanceDetailId);
|
|
||||||
stepDetail.setStepDesc(stepDesc);
|
|
||||||
stepDetail.setStepStatus(TaskStatusEnum.Success.getCode());
|
|
||||||
taskInstanceStepDetailMapper.insert(stepDetail);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 步骤执行失败
|
|
||||||
*
|
|
||||||
* @param instanceDetailId 任务实例明细id
|
|
||||||
* @param stepDesc 步骤描述
|
|
||||||
*/
|
|
||||||
public void fail(Long instanceDetailId, String stepDesc) {
|
|
||||||
TaskInstanceStepDetailTb stepDetail = new TaskInstanceStepDetailTb();
|
|
||||||
stepDetail.setInstanceDetailId(instanceDetailId);
|
|
||||||
stepDetail.setStepDesc(stepDesc);
|
|
||||||
stepDetail.setStepStatus(TaskStatusEnum.Fail.getCode());
|
|
||||||
taskInstanceStepDetailMapper.insert(stepDetail);
|
|
||||||
throw new BadRequestException(stepDesc);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据明细ID删除步骤明细
|
|
||||||
*
|
|
||||||
* @param instanceDetailIds 任务实例明细id集合
|
|
||||||
*/
|
|
||||||
public void removeByInstanceDetailIds(List<Long> instanceDetailIds) {
|
|
||||||
if (CollUtil.isNotEmpty(instanceDetailIds)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
LambdaQueryWrapper<TaskInstanceStepDetailTb> wrapper = new LambdaQueryWrapper<>();
|
|
||||||
wrapper.in(TaskInstanceStepDetailTb::getInstanceDetailId, instanceDetailIds);
|
|
||||||
taskInstanceStepDetailMapper.delete(wrapper);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-41
@@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.service;
|
|
||||||
|
|
||||||
import cn.odboy.task.dal.model.TaskTemplateInfoVo;
|
|
||||||
import cn.odboy.task.dal.mysql.TaskTemplateInfoMapper;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 任务模板
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author codegen
|
|
||||||
* @since 2025-09-28
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
public class TaskTemplateInfoService {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private TaskTemplateInfoMapper taskTemplateInfoMapper;
|
|
||||||
|
|
||||||
public TaskTemplateInfoVo getTemplateInfoByECL(String envAlias, String contextName, String language,
|
|
||||||
String changeType) {
|
|
||||||
return taskTemplateInfoMapper.selectTemplateInfoByECL(envAlias, contextName, language, changeType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-4
@@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
|
||||||
<mapper namespace="cn.odboy.task.dal.mysql.TaskInstanceDetailMapper">
|
|
||||||
</mapper>
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
|
||||||
<mapper namespace="cn.odboy.task.dal.mysql.TaskInstanceInfoMapper">
|
|
||||||
</mapper>
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
|
||||||
<mapper namespace="cn.odboy.task.dal.mysql.TaskTemplateInfoMapper">
|
|
||||||
<select id="selectTemplateInfoByECL" resultType="cn.odboy.task.dal.model.TaskTemplateInfoVo">
|
|
||||||
SELECT t2.change_type,
|
|
||||||
t2.`name`,
|
|
||||||
t2.description,
|
|
||||||
t2.env_alias,
|
|
||||||
t2.`language`,
|
|
||||||
t1.context_name,
|
|
||||||
t1.template_info
|
|
||||||
FROM task_pipeline_config t1
|
|
||||||
LEFT JOIN task_template_info t2 ON t1.template_info_id = t2.id
|
|
||||||
WHERE t1.context_name = #{contextName}
|
|
||||||
AND t2.env_alias = #{envAlias}
|
|
||||||
AND t2.`language` = #{language}
|
|
||||||
AND t2.`change_type` = #{changeType}
|
|
||||||
</select>
|
|
||||||
</mapper>
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<parent>
|
|
||||||
<artifactId>cutejava</artifactId>
|
|
||||||
<groupId>cn.odboy</groupId>
|
|
||||||
<version>1.5.2</version>
|
|
||||||
</parent>
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<artifactId>cutejava-module-task-v2</artifactId>
|
|
||||||
<name>任务模块V2:根据任务标记停止轮询检查</name>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>cn.odboy</groupId>
|
|
||||||
<artifactId>cutejava-module-system</artifactId>
|
|
||||||
<version>1.5.2</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</project>
|
|
||||||
-40
@@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.constant;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 任务变更类型(固定值)
|
|
||||||
*
|
|
||||||
* @author odboy
|
|
||||||
* @date 2025-09-26
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@AllArgsConstructor
|
|
||||||
public enum TaskChangeTypeEnum {
|
|
||||||
AppApply("AppApply", "申请应用"), AppContainerRestart("AppContainerRestart", "容器应用重启"),
|
|
||||||
AppContainerDeploy("AppContainerDeploy", "容器应用部署"), AppOffline("AppOffline", "应用下线"),
|
|
||||||
AppChangeReplicas("AppChangeReplicas", "应用扩缩容"), AppUpgrade("AppUpgrade", "应用升配"),
|
|
||||||
AppDowngrade("AppDowngrade", "应用降配"), AppHostRestart("AppHostRestart", "主机应用重启"),
|
|
||||||
AppHostDeploy("AppHostDeploy", "主机应用部署"), AppContainerRollback("AppContainerRollback", "容器应用回滚"),
|
|
||||||
AppHostRollback("AppHostRollback", "主机应用回滚"), ResourceApply("ResourceApply", "申请资源"),
|
|
||||||
ResourceOffline("ResourceOffline", "资源下线"), DataChange("DataChange", "数据变更"),
|
|
||||||
HostnameApply("HostnameApply", "申请域名"), HostnameChange("HostnameChange", "域名变更");
|
|
||||||
private final String code;
|
|
||||||
private final String name;
|
|
||||||
}
|
|
||||||
-17
@@ -1,17 +0,0 @@
|
|||||||
package cn.odboy.task.constant;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 任务共用Keys
|
|
||||||
*
|
|
||||||
* @author odboy
|
|
||||||
* @date 2025-10-25
|
|
||||||
*/
|
|
||||||
public interface TaskJobKeys {
|
|
||||||
|
|
||||||
String ID = "id";
|
|
||||||
String CONTEXT_NAME = "contextName";
|
|
||||||
String LANGUAGE = "language";
|
|
||||||
String ENV_ALIAS = "envAlias";
|
|
||||||
String CHANGE_TYPE = "changeType";
|
|
||||||
String RETRY_NODE_CODE = "retryNodeCode";
|
|
||||||
}
|
|
||||||
-43
@@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.constant;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 任务状态(固定值)
|
|
||||||
*
|
|
||||||
* @author odboy
|
|
||||||
* @date 2025-09-26
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@AllArgsConstructor
|
|
||||||
public enum TaskStatusEnum {
|
|
||||||
Pending("pending", "未开始"), Running("running", "运行中"), Success("success", "执行成功"),
|
|
||||||
Fail("fail", "执行失败");
|
|
||||||
private final String code;
|
|
||||||
private final String name;
|
|
||||||
|
|
||||||
public static String getDesc(String code) {
|
|
||||||
for (TaskStatusEnum taskStatusEnum : TaskStatusEnum.values()) {
|
|
||||||
if (taskStatusEnum.code.equals(code)) {
|
|
||||||
return taskStatusEnum.getName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-83
@@ -1,83 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.controller;
|
|
||||||
|
|
||||||
import cn.hutool.core.thread.ThreadUtil;
|
|
||||||
import cn.odboy.annotation.AnonymousAccess;
|
|
||||||
import cn.odboy.task.constant.TaskChangeTypeEnum;
|
|
||||||
import cn.odboy.task.core.TaskManage;
|
|
||||||
import cn.odboy.task.dal.dataobject.TaskInstanceInfoTb;
|
|
||||||
import cn.odboy.task.dal.model.TaskInstanceInfoVo;
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.http.ResponseEntity;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/api/task")
|
|
||||||
public class TaskTestsController {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private TaskManage taskManage;
|
|
||||||
|
|
||||||
@AnonymousAccess
|
|
||||||
@GetMapping(value = "/testCreate")
|
|
||||||
public ResponseEntity<?> testCreate() {
|
|
||||||
TaskInstanceInfoTb instanceInfo =
|
|
||||||
taskManage.createJob("cutejava", TaskChangeTypeEnum.AppContainerDeploy, "java", "daily", "cutejava",
|
|
||||||
"功能测试", null);
|
|
||||||
log.info("任务创建成功,实例为:{}", JSON.toJSONString(instanceInfo));
|
|
||||||
return ResponseEntity.ok(instanceInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
@AnonymousAccess
|
|
||||||
@GetMapping(value = "/testCreateAfterStop")
|
|
||||||
public ResponseEntity<?> testCreateAfterStop() {
|
|
||||||
TaskInstanceInfoTb instanceInfo =
|
|
||||||
taskManage.createJob("cutejava", TaskChangeTypeEnum.AppContainerDeploy, "java", "daily", "cutejava",
|
|
||||||
"功能测试", null);
|
|
||||||
log.info("任务创建成功,实例为:{}", JSON.toJSONString(instanceInfo));
|
|
||||||
ThreadUtil.execAsync(() -> {
|
|
||||||
ThreadUtil.safeSleep(5000);
|
|
||||||
taskManage.stopJob(instanceInfo.getId());
|
|
||||||
});
|
|
||||||
return ResponseEntity.ok(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@AnonymousAccess
|
|
||||||
@GetMapping(value = "/testRetry")
|
|
||||||
public ResponseEntity<?> testRetry(@RequestParam Long instanceId, @RequestParam String retryNodeCode) {
|
|
||||||
TaskInstanceInfoTb instanceInfo = taskManage.retryJob(instanceId, retryNodeCode);
|
|
||||||
log.info("任务重试成功,实例为:{}", JSON.toJSONString(instanceInfo));
|
|
||||||
return ResponseEntity.ok(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@AnonymousAccess
|
|
||||||
@GetMapping(value = "/last")
|
|
||||||
public ResponseEntity<?> testLast() {
|
|
||||||
String contextName = "cutejava";
|
|
||||||
String language = "java";
|
|
||||||
String changeType = TaskChangeTypeEnum.AppContainerDeploy.getCode();
|
|
||||||
String envAlias = "daily";
|
|
||||||
TaskInstanceInfoVo instanceInfo = taskManage.getLastInfo(contextName, language, envAlias, changeType);
|
|
||||||
return ResponseEntity.ok(instanceInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,225 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.core;
|
|
||||||
|
|
||||||
import cn.hutool.core.thread.ThreadUtil;
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import cn.odboy.framework.context.KitSpringBeanHolder;
|
|
||||||
import cn.odboy.framework.exception.BadRequestException;
|
|
||||||
import cn.odboy.framework.exception.ServerException;
|
|
||||||
import cn.odboy.task.constant.TaskJobKeys;
|
|
||||||
import cn.odboy.task.constant.TaskStatusEnum;
|
|
||||||
import cn.odboy.task.dal.dataobject.TaskInstanceDetailTb;
|
|
||||||
import cn.odboy.task.dal.dataobject.TaskInstanceInfoTb;
|
|
||||||
import cn.odboy.task.dal.model.TaskTemplateNodeVo;
|
|
||||||
import cn.odboy.task.service.TaskInstanceDetailService;
|
|
||||||
import cn.odboy.task.service.TaskInstanceInfoService;
|
|
||||||
import cn.odboy.task.service.TaskInstanceStepDetailService;
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.quartz.JobDataMap;
|
|
||||||
import org.quartz.JobExecutionContext;
|
|
||||||
import org.springframework.scheduling.quartz.QuartzJobBean;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class TaskJobBean extends QuartzJobBean {
|
|
||||||
|
|
||||||
private String getBeanAlias(String code) {
|
|
||||||
if (StrUtil.isBlank(code)) {
|
|
||||||
throw new ServerException("参数code必填");
|
|
||||||
}
|
|
||||||
// node_init
|
|
||||||
String[] s = code.split("_");
|
|
||||||
return Arrays.stream(s).map(StrUtil::upperFirst).collect(Collectors.joining());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void executeInternal(JobExecutionContext context) {
|
|
||||||
// ========================== 获取代理类 ==========================
|
|
||||||
TaskInstanceInfoService taskInstanceInfoService = KitSpringBeanHolder.getBean(TaskInstanceInfoService.class);
|
|
||||||
TaskInstanceDetailService taskInstanceDetailService = KitSpringBeanHolder.getBean(TaskInstanceDetailService.class);
|
|
||||||
// ========================== 获取参数 ==========================
|
|
||||||
JobDataMap dataMap = context.getMergedJobDataMap();
|
|
||||||
long id = dataMap.getLong(TaskJobKeys.ID);
|
|
||||||
// ========================== 获取任务编排模板 ==========================
|
|
||||||
TaskInstanceInfoTb taskInstanceInfoVo = taskInstanceInfoService.getRunningById(id);
|
|
||||||
String templateInfo = taskInstanceInfoVo.getTemplate();
|
|
||||||
List<TaskTemplateNodeVo> taskTemplateNodeVos = JSON.parseArray(templateInfo, TaskTemplateNodeVo.class);
|
|
||||||
// ========================== 判断是否重试任务 ==========================
|
|
||||||
String retryNodeCode = dataMap.getString(TaskJobKeys.RETRY_NODE_CODE);
|
|
||||||
if (StrUtil.isBlank(retryNodeCode)) {
|
|
||||||
executeNormalTask(taskInstanceInfoService, taskInstanceDetailService, id, dataMap, taskTemplateNodeVos);
|
|
||||||
} else {
|
|
||||||
executeRetryTask(taskInstanceInfoService, taskInstanceDetailService, id, dataMap, taskTemplateNodeVos, retryNodeCode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行普通任务(非重试任务)
|
|
||||||
*
|
|
||||||
* @param taskInstanceInfoService 任务实例信息服务
|
|
||||||
* @param taskInstanceDetailService 任务实例明细服务
|
|
||||||
* @param id 任务实例ID
|
|
||||||
* @param dataMap 数据映射
|
|
||||||
* @param taskTemplateNodeVos 模板节点列表
|
|
||||||
*/
|
|
||||||
private void executeNormalTask(TaskInstanceInfoService taskInstanceInfoService, TaskInstanceDetailService taskInstanceDetailService, long id, JobDataMap dataMap, List<TaskTemplateNodeVo> taskTemplateNodeVos) {
|
|
||||||
// ========================== 初始化执行明细 ==========================
|
|
||||||
List<TaskInstanceDetailTb> taskInstanceDetails = taskTemplateNodeVos.stream().map(taskTemplateNodeVo -> buildTaskInstanceDetail(id, taskTemplateNodeVo))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
taskInstanceDetailService.saveBatch(taskInstanceDetails);
|
|
||||||
Map<String, Long> codeIdMap = taskInstanceDetails.stream().collect(Collectors.toMap(TaskInstanceDetailTb::getBizCode, TaskInstanceDetailTb::getId));
|
|
||||||
// ========================== 顺序执行 ==========================
|
|
||||||
executeTaskSteps(taskInstanceInfoService, taskInstanceDetailService, id, dataMap, taskTemplateNodeVos, codeIdMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行重试任务
|
|
||||||
*
|
|
||||||
* @param taskInstanceInfoService 任务实例信息服务
|
|
||||||
* @param taskInstanceDetailService 任务实例明细服务
|
|
||||||
* @param id 任务实例ID
|
|
||||||
* @param dataMap 数据映射
|
|
||||||
* @param taskTemplateNodeVos 模板节点列表
|
|
||||||
* @param retryNodeCode 重试节点编码
|
|
||||||
*/
|
|
||||||
private void executeRetryTask(TaskInstanceInfoService taskInstanceInfoService,
|
|
||||||
TaskInstanceDetailService taskInstanceDetailService, long id, JobDataMap dataMap,
|
|
||||||
List<TaskTemplateNodeVo> taskTemplateNodeVos, String retryNodeCode) {
|
|
||||||
boolean isFound = false;
|
|
||||||
// ========================== 初始化执行明细 ==========================
|
|
||||||
List<TaskInstanceDetailTb> taskInstanceDetails = new ArrayList<>();
|
|
||||||
List<TaskTemplateNodeVo> taskTemplateNodeRetryList = new ArrayList<>();
|
|
||||||
for (TaskTemplateNodeVo taskTemplateNodeVo : taskTemplateNodeVos) {
|
|
||||||
if (isFound) {
|
|
||||||
taskInstanceDetails.add(buildTaskInstanceDetail(id, taskTemplateNodeVo));
|
|
||||||
taskTemplateNodeRetryList.add(taskTemplateNodeVo);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (taskTemplateNodeVo.getCode().equals(retryNodeCode)) {
|
|
||||||
if (!taskTemplateNodeVo.getRetry()) {
|
|
||||||
throw new BadRequestException("节点 '" + taskTemplateNodeVo.getName() + "' 不支持重试");
|
|
||||||
}
|
|
||||||
taskInstanceDetails.add(buildTaskInstanceDetail(id, taskTemplateNodeVo));
|
|
||||||
taskTemplateNodeRetryList.add(taskTemplateNodeVo);
|
|
||||||
isFound = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TaskInstanceStepDetailService taskInstanceStepDetailService =
|
|
||||||
KitSpringBeanHolder.getBean(TaskInstanceStepDetailService.class);
|
|
||||||
List<String> bizCodeList =
|
|
||||||
taskInstanceDetails.stream().map(TaskInstanceDetailTb::getBizCode).distinct().collect(Collectors.toList());
|
|
||||||
List<TaskInstanceDetailTb> taskInstanceDetailTbs =
|
|
||||||
taskInstanceDetailService.queryByInstanceIdAndBizCodeList(id, bizCodeList);
|
|
||||||
List<Long> taskInstanceDetailIds =
|
|
||||||
taskInstanceDetailTbs.stream().map(TaskInstanceDetailTb::getId).collect(Collectors.toList());
|
|
||||||
// 根据ID删除明细
|
|
||||||
taskInstanceDetailService.removeByIds(taskInstanceDetailIds);
|
|
||||||
// 根据明细删除步骤
|
|
||||||
taskInstanceStepDetailService.removeByInstanceDetailIds(taskInstanceDetailIds);
|
|
||||||
taskInstanceDetailService.saveBatch(taskInstanceDetails);
|
|
||||||
Map<String, Long> codeIdMap = taskInstanceDetails.stream()
|
|
||||||
.collect(Collectors.toMap(TaskInstanceDetailTb::getBizCode, TaskInstanceDetailTb::getId));
|
|
||||||
// ========================== 顺序执行 ==========================
|
|
||||||
executeTaskSteps(taskInstanceInfoService, taskInstanceDetailService, id, dataMap, taskTemplateNodeRetryList,
|
|
||||||
codeIdMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构建任务实例明细对象
|
|
||||||
*
|
|
||||||
* @param id 实例ID
|
|
||||||
* @param taskTemplateNodeVo 模板节点
|
|
||||||
* @return 任务实例明细对象
|
|
||||||
*/
|
|
||||||
private TaskInstanceDetailTb buildTaskInstanceDetail(long id, TaskTemplateNodeVo taskTemplateNodeVo) {
|
|
||||||
TaskInstanceDetailTb taskInstanceDetail = new TaskInstanceDetailTb();
|
|
||||||
taskInstanceDetail.setInstanceId(id);
|
|
||||||
taskInstanceDetail.setFinishTime(null);
|
|
||||||
taskInstanceDetail.setBizCode(taskTemplateNodeVo.getCode());
|
|
||||||
taskInstanceDetail.setBizName(taskTemplateNodeVo.getName());
|
|
||||||
taskInstanceDetail.setExecuteInfo(TaskStatusEnum.Pending.getName());
|
|
||||||
taskInstanceDetail.setExecuteStatus(TaskStatusEnum.Pending.getCode());
|
|
||||||
return taskInstanceDetail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行任务步骤
|
|
||||||
*
|
|
||||||
* @param taskInstanceInfoService 任务实例信息服务
|
|
||||||
* @param taskInstanceDetailService 任务实例明细服务
|
|
||||||
* @param id 实例ID
|
|
||||||
* @param dataMap 数据映射
|
|
||||||
* @param taskTemplateNodes 需要执行的任务节点列表
|
|
||||||
* @param codeIdMap 节点编码与明细ID映射
|
|
||||||
*/
|
|
||||||
private void executeTaskSteps(TaskInstanceInfoService taskInstanceInfoService, TaskInstanceDetailService taskInstanceDetailService, Long id, JobDataMap dataMap, List<TaskTemplateNodeVo> taskTemplateNodes, Map<String, Long> codeIdMap) {
|
|
||||||
try {
|
|
||||||
boolean isTerminate = false;
|
|
||||||
for (TaskTemplateNodeVo taskTemplateNodeVo : taskTemplateNodes) {
|
|
||||||
String code = taskTemplateNodeVo.getCode();
|
|
||||||
while (true) {
|
|
||||||
ThreadUtil.safeSleep(5000);
|
|
||||||
TaskInstanceDetailTb currentTaskInstanceNode = taskInstanceDetailService.getOneByInstanceIdAndCode(id, code);
|
|
||||||
if (TaskStatusEnum.Fail.getCode().equals(currentTaskInstanceNode.getExecuteStatus())) {
|
|
||||||
log.info("任务节点执行失败, instanceId={}, bizCode={}", id, code);
|
|
||||||
isTerminate = true;
|
|
||||||
break;
|
|
||||||
} else if (TaskStatusEnum.Success.getCode().equals(currentTaskInstanceNode.getExecuteStatus())) {
|
|
||||||
log.info("任务节点执行成功, instanceId={}, bizCode={}", id, code);
|
|
||||||
break;
|
|
||||||
} else if (TaskStatusEnum.Pending.getCode().equals(currentTaskInstanceNode.getExecuteStatus())) {
|
|
||||||
log.info("任务节点由待执行变更为执行中, instanceId={}, bizCode={}", id, code);
|
|
||||||
ThreadUtil.execAsync(() -> {
|
|
||||||
try {
|
|
||||||
TaskStepExecutor executor = KitSpringBeanHolder.getBean("taskStep" + getBeanAlias(code));
|
|
||||||
taskInstanceDetailService.fastStart(id, code, dataMap);
|
|
||||||
executor.execute(codeIdMap.getOrDefault(code, null), dataMap, taskTemplateNodeVo);
|
|
||||||
taskInstanceDetailService.fastSuccessWithInfo(id, code, null);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("任务节点执行失败", e);
|
|
||||||
taskInstanceDetailService.fastFailWithInfo(id, code, e.getMessage());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if (TaskStatusEnum.Running.getCode().equals(currentTaskInstanceNode.getExecuteStatus())) {
|
|
||||||
log.info("任务节点执行中, instanceId={}, bizCode={}", id, code);
|
|
||||||
} else {
|
|
||||||
// 处理未知状态
|
|
||||||
log.warn("任务节点处于未知状态, instanceId={}, bizCode={}, status={}", id, code, currentTaskInstanceNode.getExecuteStatus());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (isTerminate) {
|
|
||||||
// 跳出任务线
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 主动终止 或者 被动退出的
|
|
||||||
if (isTerminate) {
|
|
||||||
taskInstanceInfoService.fastFailWithMessageData(id, "任务执行失败", dataMap);
|
|
||||||
} else {
|
|
||||||
taskInstanceInfoService.fastSuccessWithData(id, dataMap);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("任务执行失败", e);
|
|
||||||
taskInstanceInfoService.fastFailWithMessageData(id, e.getMessage(), dataMap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,265 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.core;
|
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import cn.odboy.framework.context.KitSpringBeanHolder;
|
|
||||||
import cn.odboy.framework.exception.BadRequestException;
|
|
||||||
import cn.odboy.task.constant.TaskChangeTypeEnum;
|
|
||||||
import cn.odboy.task.constant.TaskJobKeys;
|
|
||||||
import cn.odboy.task.constant.TaskStatusEnum;
|
|
||||||
import cn.odboy.task.dal.dataobject.TaskInstanceDetailTb;
|
|
||||||
import cn.odboy.task.dal.dataobject.TaskInstanceInfoTb;
|
|
||||||
import cn.odboy.task.dal.model.TaskInstanceInfoVo;
|
|
||||||
import cn.odboy.task.dal.model.TaskInstanceNodeVo;
|
|
||||||
import cn.odboy.task.dal.model.TaskTemplateInfoVo;
|
|
||||||
import cn.odboy.task.dal.model.TaskTemplateNodeVo;
|
|
||||||
import cn.odboy.task.service.TaskInstanceDetailService;
|
|
||||||
import cn.odboy.task.service.TaskInstanceInfoService;
|
|
||||||
import cn.odboy.task.service.TaskTemplateInfoService;
|
|
||||||
import cn.odboy.util.KitBeanUtil;
|
|
||||||
import cn.odboy.util.KitDateUtil;
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.quartz.JobBuilder;
|
|
||||||
import org.quartz.JobDataMap;
|
|
||||||
import org.quartz.JobDetail;
|
|
||||||
import org.quartz.JobKey;
|
|
||||||
import org.quartz.ObjectAlreadyExistsException;
|
|
||||||
import org.quartz.Scheduler;
|
|
||||||
import org.quartz.SchedulerException;
|
|
||||||
import org.quartz.Trigger;
|
|
||||||
import org.quartz.TriggerBuilder;
|
|
||||||
import org.quartz.TriggerKey;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@Component
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class TaskManage {
|
|
||||||
|
|
||||||
private final Scheduler scheduler;
|
|
||||||
private final TaskTemplateInfoService taskTemplateInfoService;
|
|
||||||
private final TaskInstanceInfoService taskInstanceInfoService;
|
|
||||||
private final TaskInstanceDetailService taskInstanceDetailService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建任务单(注:同一应用同一变更类型无法并发多实例)
|
|
||||||
*
|
|
||||||
* @param contextName 上下文名称,这里特指应用名
|
|
||||||
* @param changeTypeEnum 变更类型
|
|
||||||
* @param language 开发语言、资源版本
|
|
||||||
* @param envAlias 环境别名
|
|
||||||
* @param source 来源
|
|
||||||
* @param reason 变更原因
|
|
||||||
* @param dataMap 任务参数
|
|
||||||
*/
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public TaskInstanceInfoTb createJob(String contextName, TaskChangeTypeEnum changeTypeEnum, String language,
|
|
||||||
String envAlias, String source, String reason, JobDataMap dataMap) {
|
|
||||||
if (StrUtil.isBlank(contextName)) {
|
|
||||||
throw new BadRequestException("参数contextName必填");
|
|
||||||
}
|
|
||||||
if (changeTypeEnum == null) {
|
|
||||||
throw new BadRequestException("参数changeTypeEnum必填");
|
|
||||||
}
|
|
||||||
if (StrUtil.isBlank(language)) {
|
|
||||||
throw new BadRequestException("参数language必填");
|
|
||||||
}
|
|
||||||
if (StrUtil.isBlank(envAlias)) {
|
|
||||||
throw new BadRequestException("参数envAlias必填");
|
|
||||||
}
|
|
||||||
if (StrUtil.isBlank(source)) {
|
|
||||||
throw new BadRequestException("参数source必填");
|
|
||||||
}
|
|
||||||
if (dataMap == null) {
|
|
||||||
dataMap = new JobDataMap();
|
|
||||||
}
|
|
||||||
// ========================== 获取任务编排模板 ==========================
|
|
||||||
TaskTemplateInfoVo taskInstanceInfoVo =
|
|
||||||
taskTemplateInfoService.getTemplateInfoByECL(envAlias, contextName, language, changeTypeEnum.getCode());
|
|
||||||
if (taskInstanceInfoVo == null) {
|
|
||||||
throw new BadRequestException("没有查询到任务编排模板");
|
|
||||||
}
|
|
||||||
String templateInfo = taskInstanceInfoVo.getTemplateInfo();
|
|
||||||
List<TaskTemplateNodeVo> taskTemplateNodeVos;
|
|
||||||
try {
|
|
||||||
taskTemplateNodeVos = JSON.parseArray(templateInfo, TaskTemplateNodeVo.class);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("任务编排模板解析失败", e);
|
|
||||||
throw new BadRequestException("任务编排模板解析失败");
|
|
||||||
}
|
|
||||||
if (taskTemplateNodeVos == null || taskTemplateNodeVos.isEmpty()) {
|
|
||||||
throw new BadRequestException("没有查询到任务编排明细");
|
|
||||||
}
|
|
||||||
// ========================== 创建任务 ==========================
|
|
||||||
TaskManage taskManage = KitSpringBeanHolder.getBean(TaskManage.class);
|
|
||||||
TaskInstanceInfoTb newInstance =
|
|
||||||
taskManage.saveTaskInstanceInfoTb(contextName, changeTypeEnum, language, envAlias, source, reason, dataMap,
|
|
||||||
templateInfo);
|
|
||||||
dataMap.put(TaskJobKeys.ID, newInstance.getId());
|
|
||||||
// 应用名、资源类型
|
|
||||||
dataMap.put(TaskJobKeys.CONTEXT_NAME, contextName);
|
|
||||||
// 开发语言、资源版本
|
|
||||||
dataMap.put(TaskJobKeys.LANGUAGE, language);
|
|
||||||
dataMap.put(TaskJobKeys.ENV_ALIAS, envAlias);
|
|
||||||
// 变更类型
|
|
||||||
dataMap.put(TaskJobKeys.CHANGE_TYPE, changeTypeEnum.getCode());
|
|
||||||
buildAndSchedule(changeTypeEnum.getCode(), contextName, dataMap);
|
|
||||||
return newInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public TaskInstanceInfoTb saveTaskInstanceInfoTb(String contextName, TaskChangeTypeEnum changeTypeEnum,
|
|
||||||
String language, String envAlias, String source, String reason, JobDataMap dataMap, String templateInfo) {
|
|
||||||
TaskInstanceInfoTb newInstance = new TaskInstanceInfoTb();
|
|
||||||
newInstance.setContextName(contextName);
|
|
||||||
newInstance.setLanguage(language);
|
|
||||||
newInstance.setChangeType(changeTypeEnum.getCode());
|
|
||||||
newInstance.setEnvAlias(envAlias);
|
|
||||||
newInstance.setStatus(TaskStatusEnum.Running.getCode());
|
|
||||||
newInstance.setFinishTime(null);
|
|
||||||
newInstance.setSource(source);
|
|
||||||
newInstance.setReason(reason);
|
|
||||||
newInstance.setTemplate(templateInfo);
|
|
||||||
newInstance.setJobData(JSON.toJSONString(dataMap));
|
|
||||||
taskInstanceInfoService.save(newInstance);
|
|
||||||
return newInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void buildAndSchedule(String changeTypeEnum, String contextName, JobDataMap dataMap) {
|
|
||||||
// ========================== 执行任务 ==========================
|
|
||||||
JobKey jobKey = JobKey.jobKey(changeTypeEnum, contextName);
|
|
||||||
TriggerKey triggerKey = TriggerKey.triggerKey(changeTypeEnum, contextName);
|
|
||||||
JobDetail jobDetail = JobBuilder.newJob(TaskJobBean.class).withIdentity(jobKey).usingJobData(dataMap).build();
|
|
||||||
Trigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).startNow().build();
|
|
||||||
try {
|
|
||||||
scheduler.scheduleJob(jobDetail, trigger);
|
|
||||||
} catch (ObjectAlreadyExistsException e) {
|
|
||||||
log.error("任务jobKey={},triggerKey={}任务已存在,跳过加载", jobKey.getName(), triggerKey.getName(), e);
|
|
||||||
throw new BadRequestException("任务已存在,跳过加载");
|
|
||||||
} catch (SchedulerException e) {
|
|
||||||
log.error("任务jobKey={},triggerKey={}执行失败", jobKey.getName(), triggerKey.getName(), e);
|
|
||||||
throw new BadRequestException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public void stopJob(Long instanceId) {
|
|
||||||
TaskInstanceInfoTb taskInstanceInfoTb = taskInstanceInfoService.getRunningById(instanceId);
|
|
||||||
String changeType = taskInstanceInfoTb.getChangeType();
|
|
||||||
String contextName = taskInstanceInfoTb.getContextName();
|
|
||||||
taskInstanceInfoTb.setStatus(TaskStatusEnum.Fail.getCode());
|
|
||||||
taskInstanceInfoTb.setErrorMessage("任务被中断");
|
|
||||||
taskInstanceInfoTb.setFinishTime(new Date());
|
|
||||||
taskInstanceInfoService.updateById(taskInstanceInfoTb);
|
|
||||||
try {
|
|
||||||
JobKey jobKey = JobKey.jobKey(changeType, contextName);
|
|
||||||
TriggerKey triggerKey = TriggerKey.triggerKey(changeType, contextName);
|
|
||||||
// 停止触发器
|
|
||||||
scheduler.pauseTrigger(triggerKey);
|
|
||||||
// 移除触发器
|
|
||||||
scheduler.unscheduleJob(triggerKey);
|
|
||||||
// 删除任务
|
|
||||||
scheduler.deleteJob(jobKey);
|
|
||||||
// scheduler.interrupt(jobKey);
|
|
||||||
} catch (SchedulerException e) {
|
|
||||||
log.error("任务停止失败", e);
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public TaskInstanceInfoTb retryJob(Long id, String retryNodeCode) {
|
|
||||||
// ========================== 查询任务 ==========================
|
|
||||||
TaskInstanceInfoTb taskInstanceInfoTb = taskInstanceInfoService.getById(id);
|
|
||||||
if (taskInstanceInfoTb == null) {
|
|
||||||
throw new BadRequestException("任务不存在");
|
|
||||||
}
|
|
||||||
// ========================== 失败的任务才能重试 ==========================
|
|
||||||
if (TaskStatusEnum.Success.getCode().equals(taskInstanceInfoTb.getStatus())) {
|
|
||||||
throw new BadRequestException("任务已执行完毕,无法重试");
|
|
||||||
}
|
|
||||||
// 参数重放
|
|
||||||
JobDataMap dataMap = JSON.parseObject(taskInstanceInfoTb.getJobData(), JobDataMap.class);
|
|
||||||
if (dataMap == null) {
|
|
||||||
dataMap = new JobDataMap();
|
|
||||||
}
|
|
||||||
taskInstanceInfoTb.setStatus(TaskStatusEnum.Pending.getCode());
|
|
||||||
taskInstanceInfoTb.setFinishTime(null);
|
|
||||||
taskInstanceInfoService.updateById(taskInstanceInfoTb);
|
|
||||||
// ========================== 执行任务 ==========================
|
|
||||||
dataMap.put(TaskJobKeys.RETRY_NODE_CODE, retryNodeCode);
|
|
||||||
String changeType = taskInstanceInfoTb.getChangeType();
|
|
||||||
String contextName = taskInstanceInfoTb.getContextName();
|
|
||||||
buildAndSchedule(changeType, contextName, dataMap);
|
|
||||||
return taskInstanceInfoTb;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskInstanceInfoVo getLastInfo(String contextName, String language, String envAlias, String changeType) {
|
|
||||||
TaskInstanceInfoVo record = new TaskInstanceInfoVo();
|
|
||||||
TaskInstanceInfoTb historyInstance =
|
|
||||||
taskInstanceInfoService.getLastHistoryInstance(contextName, language, envAlias, changeType);
|
|
||||||
if (historyInstance == null) {
|
|
||||||
// 仅返回模板
|
|
||||||
TaskTemplateInfoVo templateInfo =
|
|
||||||
taskTemplateInfoService.getTemplateInfoByECL(envAlias, contextName, language, changeType);
|
|
||||||
if (templateInfo == null) {
|
|
||||||
throw new BadRequestException("没有查询到任务编排模板");
|
|
||||||
}
|
|
||||||
record.setTemplate(templateInfo.getTemplateInfo());
|
|
||||||
return record;
|
|
||||||
}
|
|
||||||
record = KitBeanUtil.copyToClass(historyInstance, TaskInstanceInfoVo.class);
|
|
||||||
record.setHistory(buildNodeList(record));
|
|
||||||
TaskInstanceInfoTb runningInstance = taskInstanceInfoService.getLastRunningInstance(contextName, language, envAlias, changeType);
|
|
||||||
if (runningInstance != null) {
|
|
||||||
TaskInstanceInfoVo taskInstanceInfoVo = KitBeanUtil.copyToClass(runningInstance, TaskInstanceInfoVo.class);
|
|
||||||
record.setCurrent(buildNodeList(taskInstanceInfoVo));
|
|
||||||
}
|
|
||||||
return record;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<TaskInstanceNodeVo> buildNodeList(TaskInstanceInfoVo record) {
|
|
||||||
List<TaskInstanceNodeVo> records = new ArrayList<>();
|
|
||||||
// 节点明细
|
|
||||||
List<TaskInstanceDetailTb> taskInstanceDetails = taskInstanceDetailService.queryByInstanceId(record.getId());
|
|
||||||
for (TaskInstanceDetailTb taskInstanceDetail : taskInstanceDetails) {
|
|
||||||
TaskInstanceNodeVo instanceNodeVo = new TaskInstanceNodeVo();
|
|
||||||
instanceNodeVo.setCode(taskInstanceDetail.getBizCode());
|
|
||||||
instanceNodeVo.setName(taskInstanceDetail.getBizName());
|
|
||||||
instanceNodeVo.setStartTime(taskInstanceDetail.getStartTime());
|
|
||||||
instanceNodeVo.setFinishTime(taskInstanceDetail.getFinishTime());
|
|
||||||
if (taskInstanceDetail.getFinishTime() == null) {
|
|
||||||
instanceNodeVo.setDurationDesc(
|
|
||||||
KitDateUtil.formatSecondsDuration(taskInstanceDetail.getStartTime(), new Date()));
|
|
||||||
} else {
|
|
||||||
instanceNodeVo.setDurationDesc(KitDateUtil.formatSecondsDuration(taskInstanceDetail.getStartTime(),
|
|
||||||
taskInstanceDetail.getFinishTime()));
|
|
||||||
}
|
|
||||||
instanceNodeVo.setRunningDesc(taskInstanceDetail.getExecuteInfo());
|
|
||||||
instanceNodeVo.setStatus(taskInstanceDetail.getExecuteStatus());
|
|
||||||
instanceNodeVo.setStatusDesc(TaskStatusEnum.getDesc(taskInstanceDetail.getExecuteStatus()));
|
|
||||||
records.add(instanceNodeVo);
|
|
||||||
}
|
|
||||||
return records;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-30
@@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.core;
|
|
||||||
|
|
||||||
import cn.odboy.framework.exception.BadRequestException;
|
|
||||||
import cn.odboy.task.dal.model.TaskTemplateNodeVo;
|
|
||||||
import org.quartz.JobDataMap;
|
|
||||||
|
|
||||||
public interface TaskStepExecutor {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param instanceDetailId 任务实例明细id
|
|
||||||
* @param jobDataMap 执行参数
|
|
||||||
* @param taskTemplateNode 任务节点信息
|
|
||||||
*/
|
|
||||||
void execute(Long instanceDetailId, JobDataMap jobDataMap, TaskTemplateNodeVo taskTemplateNode) throws BadRequestException;
|
|
||||||
}
|
|
||||||
-35
@@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.core.impl;
|
|
||||||
|
|
||||||
import cn.hutool.core.thread.ThreadUtil;
|
|
||||||
import cn.odboy.framework.exception.BadRequestException;
|
|
||||||
import cn.odboy.task.core.TaskStepExecutor;
|
|
||||||
import cn.odboy.task.dal.model.TaskTemplateNodeVo;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.quartz.JobDataMap;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@Component
|
|
||||||
public class TaskStepNodeBuildJava implements TaskStepExecutor {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(Long instanceDetailId, JobDataMap jobDataMap, TaskTemplateNodeVo taskTemplateNode)
|
|
||||||
throws BadRequestException {
|
|
||||||
ThreadUtil.sleep(2000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-35
@@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.core.impl;
|
|
||||||
|
|
||||||
import cn.hutool.core.thread.ThreadUtil;
|
|
||||||
import cn.odboy.framework.exception.BadRequestException;
|
|
||||||
import cn.odboy.task.core.TaskStepExecutor;
|
|
||||||
import cn.odboy.task.dal.model.TaskTemplateNodeVo;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.quartz.JobDataMap;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@Component
|
|
||||||
public class TaskStepNodeDeployJava implements TaskStepExecutor {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(Long instanceDetailId, JobDataMap jobDataMap, TaskTemplateNodeVo taskTemplateNode)
|
|
||||||
throws BadRequestException {
|
|
||||||
ThreadUtil.sleep(5000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-41
@@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.core.impl;
|
|
||||||
|
|
||||||
import cn.odboy.framework.exception.BadRequestException;
|
|
||||||
import cn.odboy.task.core.TaskStepExecutor;
|
|
||||||
import cn.odboy.task.dal.model.TaskTemplateNodeVo;
|
|
||||||
import cn.odboy.task.service.TaskInstanceStepDetailService;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.quartz.JobDataMap;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@Component
|
|
||||||
public class TaskStepNodeInit implements TaskStepExecutor {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private TaskInstanceStepDetailService stepDetailService;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(Long instanceDetailId, JobDataMap jobDataMap, TaskTemplateNodeVo taskTemplateNode)
|
|
||||||
throws BadRequestException {
|
|
||||||
stepDetailService.success(instanceDetailId, "开始初始化");
|
|
||||||
stepDetailService.success(instanceDetailId, "初始化完毕后,放入了一些参数");
|
|
||||||
jobDataMap.put("ExcuseMe", "Hello World!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-42
@@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.core.impl;
|
|
||||||
|
|
||||||
import cn.hutool.core.thread.ThreadUtil;
|
|
||||||
import cn.odboy.framework.exception.BadRequestException;
|
|
||||||
import cn.odboy.task.core.TaskStepExecutor;
|
|
||||||
import cn.odboy.task.dal.model.TaskTemplateNodeVo;
|
|
||||||
import cn.odboy.task.service.TaskInstanceStepDetailService;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.quartz.JobDataMap;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@Component
|
|
||||||
public class TaskStepNodeMergeBranch implements TaskStepExecutor {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private TaskInstanceStepDetailService stepDetailService;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(Long instanceDetailId, JobDataMap jobDataMap, TaskTemplateNodeVo taskTemplateNode)
|
|
||||||
throws BadRequestException {
|
|
||||||
ThreadUtil.sleep(3000);
|
|
||||||
stepDetailService.fail(instanceDetailId, "执行失败测试");
|
|
||||||
// stepDetailService.success(instanceDetailId, "执行成功");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-109
@@ -1,109 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.dal.dataobject;
|
|
||||||
|
|
||||||
import cn.odboy.base.KitObject;
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
|
||||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
|
||||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import java.util.Date;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import lombok.ToString;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 任务实例明细
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author codegen
|
|
||||||
* @since 2025-09-26
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@ToString
|
|
||||||
@TableName("task_instance_detail")
|
|
||||||
@ApiModel(value = "TaskInstanceDetailTb对象", description = "任务实例明细")
|
|
||||||
public class TaskInstanceDetailTb extends KitObject {
|
|
||||||
|
|
||||||
@TableField(fill = FieldFill.INSERT)
|
|
||||||
@ApiModelProperty(value = "创建时间: yyyy-MM-dd HH:mm:ss", hidden = true)
|
|
||||||
private Date createTime;
|
|
||||||
/**
|
|
||||||
* id
|
|
||||||
*/
|
|
||||||
@ApiModelProperty("id")
|
|
||||||
@TableId(value = "id", type = IdType.ASSIGN_ID)
|
|
||||||
@JsonSerialize(using = ToStringSerializer.class)
|
|
||||||
@JSONField(format = "string")
|
|
||||||
private Long id;
|
|
||||||
/**
|
|
||||||
* 任务实例id
|
|
||||||
*/
|
|
||||||
@TableField("instance_id")
|
|
||||||
@ApiModelProperty("任务实例id")
|
|
||||||
private Long instanceId;
|
|
||||||
/**
|
|
||||||
* 开始时间
|
|
||||||
*/
|
|
||||||
@ApiModelProperty("开始时间")
|
|
||||||
@TableField("start_time")
|
|
||||||
private Date startTime;
|
|
||||||
/**
|
|
||||||
* 结束时间
|
|
||||||
*/
|
|
||||||
@ApiModelProperty("结束时间")
|
|
||||||
@TableField("finish_time")
|
|
||||||
private Date finishTime;
|
|
||||||
/**
|
|
||||||
* 业务编码
|
|
||||||
*/
|
|
||||||
@TableField("biz_code")
|
|
||||||
@ApiModelProperty("业务编码")
|
|
||||||
private String bizCode;
|
|
||||||
/**
|
|
||||||
* 业务名称(步骤)
|
|
||||||
*/
|
|
||||||
@TableField("biz_name")
|
|
||||||
@ApiModelProperty("业务名称(步骤)")
|
|
||||||
private String bizName;
|
|
||||||
/**
|
|
||||||
* 执行参数
|
|
||||||
*/
|
|
||||||
@ApiModelProperty("执行参数")
|
|
||||||
@TableField("execute_params")
|
|
||||||
private String executeParams;
|
|
||||||
/**
|
|
||||||
* 执行信息
|
|
||||||
*/
|
|
||||||
@ApiModelProperty("执行信息")
|
|
||||||
@TableField("execute_info")
|
|
||||||
private String executeInfo;
|
|
||||||
/**
|
|
||||||
* 执行状态(running进行中 success成功 fail失败)
|
|
||||||
*/
|
|
||||||
@TableField("execute_status")
|
|
||||||
@ApiModelProperty("执行状态(running进行中 success成功 fail失败)")
|
|
||||||
private String
|
|
||||||
executeStatus;
|
|
||||||
}
|
|
||||||
-135
@@ -1,135 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.dal.dataobject;
|
|
||||||
|
|
||||||
import cn.odboy.base.KitObject;
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
|
||||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
|
||||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import java.util.Date;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import lombok.ToString;
|
|
||||||
import org.springframework.data.annotation.CreatedBy;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 任务实例
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author codegen
|
|
||||||
* @since 2025-09-26
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@ToString
|
|
||||||
@TableName("task_instance_info")
|
|
||||||
@ApiModel(value = "TaskInstanceInfoTb对象", description = "任务实例")
|
|
||||||
public class TaskInstanceInfoTb extends KitObject {
|
|
||||||
|
|
||||||
@CreatedBy
|
|
||||||
@TableField(fill = FieldFill.INSERT)
|
|
||||||
@ApiModelProperty(value = "创建人", hidden = true)
|
|
||||||
private String
|
|
||||||
createBy;
|
|
||||||
@TableField(fill = FieldFill.INSERT)
|
|
||||||
@ApiModelProperty(value = "创建时间: yyyy-MM-dd HH:mm:ss", hidden = true)
|
|
||||||
private Date createTime;
|
|
||||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
|
||||||
@ApiModelProperty(value = "更新时间: yyyy-MM-dd HH:mm:ss", hidden = true)
|
|
||||||
private Date updateTime;
|
|
||||||
/**
|
|
||||||
* id, @JsonSerialize和@JSONField,用于处理大数精度丢失问题
|
|
||||||
*/
|
|
||||||
@ApiModelProperty("id")
|
|
||||||
@TableId(value = "id", type = IdType.ASSIGN_ID)
|
|
||||||
@JsonSerialize(using = ToStringSerializer.class)
|
|
||||||
@JSONField(format = "string")
|
|
||||||
private Long id;
|
|
||||||
/**
|
|
||||||
* 名称
|
|
||||||
*/
|
|
||||||
@ApiModelProperty("名称")
|
|
||||||
@TableField("context_name")
|
|
||||||
private String contextName;
|
|
||||||
/**
|
|
||||||
* 语言
|
|
||||||
*/
|
|
||||||
@ApiModelProperty("语言")
|
|
||||||
@TableField("`language`")
|
|
||||||
private String language;
|
|
||||||
/**
|
|
||||||
* 变更类型
|
|
||||||
*/
|
|
||||||
@ApiModelProperty("变更类型")
|
|
||||||
@TableField("change_type")
|
|
||||||
private String changeType;
|
|
||||||
/**
|
|
||||||
* 环境别名
|
|
||||||
*/
|
|
||||||
@TableField("env_alias")
|
|
||||||
@ApiModelProperty("环境别名")
|
|
||||||
private String envAlias;
|
|
||||||
/**
|
|
||||||
* 状态(running进行中 success成功 fail失败)
|
|
||||||
*/
|
|
||||||
@TableField("`status`")
|
|
||||||
@ApiModelProperty("状态(running进行中 success成功 fail失败)")
|
|
||||||
private String status;
|
|
||||||
/**
|
|
||||||
* 完成时间
|
|
||||||
*/
|
|
||||||
@ApiModelProperty("完成时间")
|
|
||||||
@TableField("finish_time")
|
|
||||||
private Date finishTime;
|
|
||||||
/**
|
|
||||||
* 来源
|
|
||||||
*/
|
|
||||||
@ApiModelProperty("来源")
|
|
||||||
@TableField("`source`")
|
|
||||||
private String source;
|
|
||||||
/**
|
|
||||||
* 变更原因
|
|
||||||
*/
|
|
||||||
@TableField("reason")
|
|
||||||
@ApiModelProperty("变更原因")
|
|
||||||
private String reason;
|
|
||||||
/**
|
|
||||||
* 任务模板
|
|
||||||
*/
|
|
||||||
@TableField("template")
|
|
||||||
@ApiModelProperty("template")
|
|
||||||
private String template;
|
|
||||||
/**
|
|
||||||
* QuartzJob参数
|
|
||||||
*/
|
|
||||||
@TableField("job_data")
|
|
||||||
@ApiModelProperty("QuartzJob参数")
|
|
||||||
private String jobData;
|
|
||||||
/**
|
|
||||||
* 异常信息
|
|
||||||
*/
|
|
||||||
@TableField("error_message")
|
|
||||||
@ApiModelProperty("异常信息")
|
|
||||||
private String errorMessage;
|
|
||||||
}
|
|
||||||
-78
@@ -1,78 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.dal.dataobject;
|
|
||||||
|
|
||||||
import cn.odboy.base.KitObject;
|
|
||||||
import com.alibaba.fastjson2.annotation.JSONField;
|
|
||||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
|
||||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import java.util.Date;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import lombok.ToString;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 任务实例步骤明细
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author codegen
|
|
||||||
* @since 2025-09-28
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@ToString
|
|
||||||
@TableName("task_instance_step_detail")
|
|
||||||
@ApiModel(value = "TaskInstanceStepDetailTb对象", description = "")
|
|
||||||
public class TaskInstanceStepDetailTb extends KitObject {
|
|
||||||
|
|
||||||
@TableField(fill = FieldFill.INSERT)
|
|
||||||
@ApiModelProperty(value = "创建时间: yyyy-MM-dd HH:mm:ss", hidden = true)
|
|
||||||
private Date createTime;
|
|
||||||
/**
|
|
||||||
* id
|
|
||||||
*/
|
|
||||||
@ApiModelProperty("id")
|
|
||||||
@TableId(value = "id", type = IdType.ASSIGN_ID)
|
|
||||||
@JsonSerialize(using = ToStringSerializer.class)
|
|
||||||
@JSONField(format = "string")
|
|
||||||
private Long id;
|
|
||||||
/**
|
|
||||||
* task_instance_detail表id
|
|
||||||
*/
|
|
||||||
@TableField("instance_detail_id")
|
|
||||||
@ApiModelProperty("task_instance_detail表id")
|
|
||||||
private Long instanceDetailId;
|
|
||||||
/**
|
|
||||||
* 步骤描述
|
|
||||||
*/
|
|
||||||
@TableField("step_desc")
|
|
||||||
@ApiModelProperty("步骤描述")
|
|
||||||
private String stepDesc;
|
|
||||||
/**
|
|
||||||
* 状态(success成功 fail失败)
|
|
||||||
*/
|
|
||||||
@TableField("step_status")
|
|
||||||
@ApiModelProperty("状态(success成功 fail失败)")
|
|
||||||
private String stepStatus;
|
|
||||||
}
|
|
||||||
-92
@@ -1,92 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.dal.dataobject;
|
|
||||||
|
|
||||||
import cn.odboy.base.KitBaseUserTimeTb;
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
|
||||||
import io.swagger.annotations.ApiModel;
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import lombok.ToString;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 任务模板
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author codegen
|
|
||||||
* @since 2025-09-28
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@ToString
|
|
||||||
@TableName("task_template_info")
|
|
||||||
@ApiModel(value = "TaskTemplateInfoTb对象", description = "任务模板")
|
|
||||||
public class TaskTemplateInfoTb extends KitBaseUserTimeTb {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* id
|
|
||||||
*/
|
|
||||||
@ApiModelProperty("id")
|
|
||||||
@TableId(value = "id", type = IdType.AUTO)
|
|
||||||
private Long id;
|
|
||||||
/**
|
|
||||||
* 数据有效性
|
|
||||||
*/
|
|
||||||
@TableField("available")
|
|
||||||
@ApiModelProperty("数据有效性")
|
|
||||||
private Boolean available;
|
|
||||||
/**
|
|
||||||
* 变更类型
|
|
||||||
*/
|
|
||||||
@ApiModelProperty("变更类型")
|
|
||||||
@TableField("change_type")
|
|
||||||
private String changeType;
|
|
||||||
/**
|
|
||||||
* 流水线名称
|
|
||||||
*/
|
|
||||||
@TableField("`name`")
|
|
||||||
@ApiModelProperty("流水线名称")
|
|
||||||
private String name;
|
|
||||||
/**
|
|
||||||
* 流水线描述
|
|
||||||
*/
|
|
||||||
@ApiModelProperty("流水线描述")
|
|
||||||
@TableField("`description`")
|
|
||||||
private String description;
|
|
||||||
/**
|
|
||||||
* 流水线模板内容
|
|
||||||
*/
|
|
||||||
@TableField("template")
|
|
||||||
@ApiModelProperty("流水线模板内容")
|
|
||||||
private String template;
|
|
||||||
/**
|
|
||||||
* 环境别名
|
|
||||||
*/
|
|
||||||
@TableField("env_alias")
|
|
||||||
@ApiModelProperty("环境别名")
|
|
||||||
private String envAlias;
|
|
||||||
/**
|
|
||||||
* 应用为语言,资源为类型
|
|
||||||
*/
|
|
||||||
@TableField("`language`")
|
|
||||||
@ApiModelProperty("应用为语言,资源为类型")
|
|
||||||
private String language;
|
|
||||||
}
|
|
||||||
-26
@@ -1,26 +0,0 @@
|
|||||||
package cn.odboy.task.dal.model;
|
|
||||||
|
|
||||||
import cn.odboy.task.dal.dataobject.TaskInstanceInfoTb;
|
|
||||||
import java.util.List;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 任务实例数据
|
|
||||||
*
|
|
||||||
* @author odboy
|
|
||||||
* @date 2025-10-01
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
public class TaskInstanceInfoVo extends TaskInstanceInfoTb {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 进行中
|
|
||||||
*/
|
|
||||||
private List<TaskInstanceNodeVo> current;
|
|
||||||
/**
|
|
||||||
* 历史已完成或异常
|
|
||||||
*/
|
|
||||||
private List<TaskInstanceNodeVo> history;
|
|
||||||
}
|
|
||||||
-64
@@ -1,64 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.dal.model;
|
|
||||||
|
|
||||||
import cn.odboy.base.KitObject;
|
|
||||||
import java.util.Date;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 任务节点数据
|
|
||||||
*
|
|
||||||
* @author odboy
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
public class TaskInstanceNodeVo extends KitObject {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 业务编码
|
|
||||||
*/
|
|
||||||
protected String code;
|
|
||||||
/**
|
|
||||||
* 业务名称
|
|
||||||
*/
|
|
||||||
protected String name;
|
|
||||||
/**
|
|
||||||
* 开始时间
|
|
||||||
*/
|
|
||||||
protected Date startTime;
|
|
||||||
/**
|
|
||||||
* 完成时间
|
|
||||||
*/
|
|
||||||
protected Date finishTime;
|
|
||||||
/**
|
|
||||||
* 耗时多久
|
|
||||||
*/
|
|
||||||
protected String durationDesc;
|
|
||||||
/**
|
|
||||||
* 进行中描述
|
|
||||||
*/
|
|
||||||
protected String runningDesc;
|
|
||||||
/**
|
|
||||||
* 节点状态编码
|
|
||||||
*/
|
|
||||||
protected String status;
|
|
||||||
/**
|
|
||||||
* 节点状态描述
|
|
||||||
*/
|
|
||||||
protected String statusDesc;
|
|
||||||
}
|
|
||||||
-49
@@ -1,49 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.dal.model;
|
|
||||||
|
|
||||||
import cn.odboy.base.KitObject;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 流水线节点控制按钮
|
|
||||||
*
|
|
||||||
* @author odboy
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
public class TaskTemplateNodeOperateButtonVo extends KitObject {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 按钮类型(service:调用某个服务并传递参数 link:带参跳转)
|
|
||||||
*/
|
|
||||||
private String type;
|
|
||||||
/**
|
|
||||||
* 按钮标题
|
|
||||||
*/
|
|
||||||
private String title;
|
|
||||||
/**
|
|
||||||
* 按钮传递的参数
|
|
||||||
*/
|
|
||||||
private String code;
|
|
||||||
/**
|
|
||||||
* 默认附加参数
|
|
||||||
*/
|
|
||||||
private Map<String, String> parameters = new HashMap<>();
|
|
||||||
}
|
|
||||||
-67
@@ -1,67 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.dal.model;
|
|
||||||
|
|
||||||
import cn.odboy.base.KitObject;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 任务节点模板
|
|
||||||
*
|
|
||||||
* @author odboy
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
public class TaskTemplateNodeVo extends KitObject {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 业务编码
|
|
||||||
*/
|
|
||||||
protected String code;
|
|
||||||
/**
|
|
||||||
* 业务类型(service:系统内置服务 rpc:远程调用)
|
|
||||||
*/
|
|
||||||
protected String type;
|
|
||||||
/**
|
|
||||||
* 业务名称
|
|
||||||
*/
|
|
||||||
protected String name;
|
|
||||||
/**
|
|
||||||
* 是否可点击
|
|
||||||
*/
|
|
||||||
protected Boolean click = false;
|
|
||||||
/**
|
|
||||||
* 是否可重试
|
|
||||||
*/
|
|
||||||
protected Boolean retry = false;
|
|
||||||
/**
|
|
||||||
* 是否可点击:点击展示详情,详情内容类型
|
|
||||||
*/
|
|
||||||
protected String detailType = "";
|
|
||||||
/**
|
|
||||||
* 默认参数<br/> execute: 执行调用 describe: 明细调用
|
|
||||||
*/
|
|
||||||
protected Map<String, String> parameters = new HashMap<>();
|
|
||||||
/**
|
|
||||||
* 流水线节点控制按钮
|
|
||||||
*/
|
|
||||||
protected List<TaskTemplateNodeOperateButtonVo> buttons = new ArrayList<>();
|
|
||||||
}
|
|
||||||
-33
@@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.dal.mysql;
|
|
||||||
|
|
||||||
import cn.odboy.task.dal.dataobject.TaskInstanceDetailTb;
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 任务实例明细 Mapper 接口
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author codegen
|
|
||||||
* @since 2025-09-26
|
|
||||||
*/
|
|
||||||
@Mapper
|
|
||||||
public interface TaskInstanceDetailMapper extends BaseMapper<TaskInstanceDetailTb> {
|
|
||||||
|
|
||||||
}
|
|
||||||
-33
@@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.dal.mysql;
|
|
||||||
|
|
||||||
import cn.odboy.task.dal.dataobject.TaskInstanceInfoTb;
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 任务实例 Mapper 接口
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author codegen
|
|
||||||
* @since 2025-09-26
|
|
||||||
*/
|
|
||||||
@Mapper
|
|
||||||
public interface TaskInstanceInfoMapper extends BaseMapper<TaskInstanceInfoTb> {
|
|
||||||
|
|
||||||
}
|
|
||||||
-33
@@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.dal.mysql;
|
|
||||||
|
|
||||||
import cn.odboy.task.dal.dataobject.TaskInstanceStepDetailTb;
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 任务实例步骤明细 Mapper 接口
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author codegen
|
|
||||||
* @since 2025-09-28
|
|
||||||
*/
|
|
||||||
@Mapper
|
|
||||||
public interface TaskInstanceStepDetailMapper extends BaseMapper<TaskInstanceStepDetailTb> {
|
|
||||||
|
|
||||||
}
|
|
||||||
-45
@@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.dal.mysql;
|
|
||||||
|
|
||||||
import cn.odboy.task.dal.dataobject.TaskTemplateInfoTb;
|
|
||||||
import cn.odboy.task.dal.model.TaskTemplateInfoVo;
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
|
||||||
import org.apache.ibatis.annotations.Param;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 任务模板 Mapper 接口
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author codegen
|
|
||||||
* @since 2025-09-28
|
|
||||||
*/
|
|
||||||
@Mapper
|
|
||||||
public interface TaskTemplateInfoMapper extends BaseMapper<TaskTemplateInfoTb> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param envAlias 环境别称
|
|
||||||
* @param contextName 应用名称、资源类型
|
|
||||||
* @param language 语言、版本
|
|
||||||
* @param changeType 变更类型
|
|
||||||
* @return /
|
|
||||||
*/
|
|
||||||
TaskTemplateInfoVo selectTemplateInfoByECL(@Param("envAlias") String envAlias,
|
|
||||||
@Param("contextName") String contextName, @Param("language") String language,
|
|
||||||
@Param("changeType") String changeType);
|
|
||||||
}
|
|
||||||
-118
@@ -1,118 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.service;
|
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
|
||||||
import cn.odboy.task.constant.TaskStatusEnum;
|
|
||||||
import cn.odboy.task.dal.dataobject.TaskInstanceDetailTb;
|
|
||||||
import cn.odboy.task.dal.mysql.TaskInstanceDetailMapper;
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
import org.quartz.JobDataMap;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 任务实例明细
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author codegen
|
|
||||||
* @since 2025-09-26
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
public class TaskInstanceDetailService {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private TaskInstanceDetailMapper taskInstanceDetailMapper;
|
|
||||||
|
|
||||||
public TaskInstanceDetailTb getOneByInstanceIdAndCode(Long id, String code) {
|
|
||||||
LambdaQueryWrapper<TaskInstanceDetailTb> wrapper = new LambdaQueryWrapper<>();
|
|
||||||
wrapper.eq(TaskInstanceDetailTb::getInstanceId, id);
|
|
||||||
wrapper.eq(TaskInstanceDetailTb::getBizCode, code);
|
|
||||||
return taskInstanceDetailMapper.selectOne(wrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fastFailWithInfo(Long instanceId, String code, String executeInfo) {
|
|
||||||
LambdaUpdateWrapper<TaskInstanceDetailTb> wrapper = new LambdaUpdateWrapper<>();
|
|
||||||
wrapper.eq(TaskInstanceDetailTb::getInstanceId, instanceId);
|
|
||||||
wrapper.eq(TaskInstanceDetailTb::getBizCode, code);
|
|
||||||
wrapper.set(TaskInstanceDetailTb::getFinishTime, new Date());
|
|
||||||
wrapper.set(TaskInstanceDetailTb::getExecuteInfo, executeInfo);
|
|
||||||
wrapper.set(TaskInstanceDetailTb::getExecuteStatus, TaskStatusEnum.Fail.getCode());
|
|
||||||
taskInstanceDetailMapper.update(null, wrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fastSuccess(Long instanceId, String code) {
|
|
||||||
LambdaUpdateWrapper<TaskInstanceDetailTb> wrapper = new LambdaUpdateWrapper<>();
|
|
||||||
wrapper.eq(TaskInstanceDetailTb::getInstanceId, instanceId);
|
|
||||||
wrapper.eq(TaskInstanceDetailTb::getBizCode, code);
|
|
||||||
wrapper.set(TaskInstanceDetailTb::getFinishTime, new Date());
|
|
||||||
wrapper.set(TaskInstanceDetailTb::getExecuteInfo, TaskStatusEnum.Success.getName());
|
|
||||||
wrapper.set(TaskInstanceDetailTb::getExecuteStatus, TaskStatusEnum.Success.getCode());
|
|
||||||
taskInstanceDetailMapper.update(null, wrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fastSuccessWithInfo(Long instanceId, String code, String executeInfo) {
|
|
||||||
LambdaUpdateWrapper<TaskInstanceDetailTb> wrapper = new LambdaUpdateWrapper<>();
|
|
||||||
wrapper.eq(TaskInstanceDetailTb::getInstanceId, instanceId);
|
|
||||||
wrapper.eq(TaskInstanceDetailTb::getBizCode, code);
|
|
||||||
wrapper.set(TaskInstanceDetailTb::getFinishTime, new Date());
|
|
||||||
wrapper.set(TaskInstanceDetailTb::getExecuteInfo,
|
|
||||||
executeInfo == null ? TaskStatusEnum.Success.getName() : executeInfo);
|
|
||||||
wrapper.set(TaskInstanceDetailTb::getExecuteStatus, TaskStatusEnum.Success.getCode());
|
|
||||||
taskInstanceDetailMapper.update(null, wrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fastStart(Long instanceId, String code, JobDataMap dataMap) {
|
|
||||||
LambdaUpdateWrapper<TaskInstanceDetailTb> wrapper = new LambdaUpdateWrapper<>();
|
|
||||||
wrapper.eq(TaskInstanceDetailTb::getInstanceId, instanceId);
|
|
||||||
wrapper.eq(TaskInstanceDetailTb::getBizCode, code);
|
|
||||||
wrapper.set(TaskInstanceDetailTb::getFinishTime, new Date());
|
|
||||||
wrapper.set(TaskInstanceDetailTb::getExecuteInfo, TaskStatusEnum.Running.getName());
|
|
||||||
wrapper.set(TaskInstanceDetailTb::getExecuteParams, JSON.toJSONString(dataMap));
|
|
||||||
wrapper.set(TaskInstanceDetailTb::getExecuteStatus, TaskStatusEnum.Running.getCode());
|
|
||||||
taskInstanceDetailMapper.update(null, wrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<TaskInstanceDetailTb> queryByInstanceIdAndBizCodeList(Long instanceId, List<String> bizCodeList) {
|
|
||||||
if (CollUtil.isEmpty(bizCodeList)) {
|
|
||||||
return CollUtil.newArrayList();
|
|
||||||
}
|
|
||||||
LambdaQueryWrapper<TaskInstanceDetailTb> wrapper = new LambdaQueryWrapper<>();
|
|
||||||
wrapper.eq(TaskInstanceDetailTb::getInstanceId, instanceId);
|
|
||||||
wrapper.in(TaskInstanceDetailTb::getBizCode, bizCodeList);
|
|
||||||
return taskInstanceDetailMapper.selectList(wrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<TaskInstanceDetailTb> queryByInstanceId(Long instanceId) {
|
|
||||||
LambdaQueryWrapper<TaskInstanceDetailTb> wrapper = new LambdaQueryWrapper<>();
|
|
||||||
wrapper.eq(TaskInstanceDetailTb::getInstanceId, instanceId);
|
|
||||||
wrapper.orderByAsc(TaskInstanceDetailTb::getId);
|
|
||||||
return taskInstanceDetailMapper.selectList(wrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void saveBatch(List<TaskInstanceDetailTb> taskInstanceDetails) {
|
|
||||||
taskInstanceDetailMapper.insert(taskInstanceDetails);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeByIds(List<Long> taskInstanceDetailIds) {
|
|
||||||
taskInstanceDetailMapper.deleteByIds(taskInstanceDetailIds);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-116
@@ -1,116 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.service;
|
|
||||||
|
|
||||||
import cn.odboy.task.constant.TaskStatusEnum;
|
|
||||||
import cn.odboy.task.dal.dataobject.TaskInstanceInfoTb;
|
|
||||||
import cn.odboy.task.dal.mysql.TaskInstanceInfoMapper;
|
|
||||||
import com.alibaba.fastjson2.JSON;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
||||||
import java.util.Date;
|
|
||||||
import org.quartz.JobDataMap;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 任务实例
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author codegen
|
|
||||||
* @since 2025-09-26
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
public class TaskInstanceInfoService {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private TaskInstanceInfoMapper taskInstanceInfoMapper;
|
|
||||||
|
|
||||||
public TaskInstanceInfoTb getRunningById(Long id) {
|
|
||||||
LambdaQueryWrapper<TaskInstanceInfoTb> wrapper = new LambdaQueryWrapper<>();
|
|
||||||
wrapper.eq(TaskInstanceInfoTb::getStatus, TaskStatusEnum.Running.getCode());
|
|
||||||
wrapper.orderByDesc(TaskInstanceInfoTb::getId);
|
|
||||||
return taskInstanceInfoMapper.selectOne(wrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public void fastFailWithMessage(Long id, String errorMessage) {
|
|
||||||
TaskInstanceInfoTb updRecord = new TaskInstanceInfoTb();
|
|
||||||
updRecord.setId(id);
|
|
||||||
updRecord.setFinishTime(new Date());
|
|
||||||
updRecord.setStatus(TaskStatusEnum.Fail.getCode());
|
|
||||||
updRecord.setErrorMessage(errorMessage);
|
|
||||||
taskInstanceInfoMapper.updateById(updRecord);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public void fastFailWithMessageData(Long id, String errorMessage, JobDataMap dataMap) {
|
|
||||||
TaskInstanceInfoTb updRecord = new TaskInstanceInfoTb();
|
|
||||||
updRecord.setId(id);
|
|
||||||
updRecord.setFinishTime(new Date());
|
|
||||||
updRecord.setStatus(TaskStatusEnum.Fail.getCode());
|
|
||||||
updRecord.setErrorMessage(errorMessage);
|
|
||||||
updRecord.setJobData(JSON.toJSONString(dataMap));
|
|
||||||
taskInstanceInfoMapper.updateById(updRecord);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public void fastSuccessWithData(Long id, JobDataMap dataMap) {
|
|
||||||
TaskInstanceInfoTb updRecord = new TaskInstanceInfoTb();
|
|
||||||
updRecord.setId(id);
|
|
||||||
updRecord.setFinishTime(new Date());
|
|
||||||
updRecord.setStatus(TaskStatusEnum.Success.getCode());
|
|
||||||
updRecord.setJobData(JSON.toJSONString(dataMap));
|
|
||||||
taskInstanceInfoMapper.updateById(updRecord);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskInstanceInfoTb getLastRunningInstance(String contextName, String language, String envAlias,
|
|
||||||
String changeType) {
|
|
||||||
LambdaQueryWrapper<TaskInstanceInfoTb> wrapper = new LambdaQueryWrapper<>();
|
|
||||||
wrapper.eq(TaskInstanceInfoTb::getContextName, contextName);
|
|
||||||
wrapper.eq(TaskInstanceInfoTb::getLanguage, language);
|
|
||||||
wrapper.eq(TaskInstanceInfoTb::getEnvAlias, envAlias);
|
|
||||||
wrapper.eq(TaskInstanceInfoTb::getChangeType, changeType);
|
|
||||||
wrapper.eq(TaskInstanceInfoTb::getStatus, TaskStatusEnum.Running.getCode());
|
|
||||||
wrapper.orderByDesc(TaskInstanceInfoTb::getId);
|
|
||||||
return taskInstanceInfoMapper.selectOne(wrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskInstanceInfoTb getLastHistoryInstance(String contextName, String language, String envAlias,
|
|
||||||
String changeType) {
|
|
||||||
LambdaQueryWrapper<TaskInstanceInfoTb> wrapper = new LambdaQueryWrapper<>();
|
|
||||||
wrapper.eq(TaskInstanceInfoTb::getContextName, contextName);
|
|
||||||
wrapper.eq(TaskInstanceInfoTb::getLanguage, language);
|
|
||||||
wrapper.eq(TaskInstanceInfoTb::getEnvAlias, envAlias);
|
|
||||||
wrapper.eq(TaskInstanceInfoTb::getChangeType, changeType);
|
|
||||||
wrapper.orderByDesc(TaskInstanceInfoTb::getId);
|
|
||||||
wrapper.last("LIMIT 1");
|
|
||||||
return taskInstanceInfoMapper.selectOne(wrapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void save(TaskInstanceInfoTb newInstance) {
|
|
||||||
taskInstanceInfoMapper.insert(newInstance);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateById(TaskInstanceInfoTb taskInstanceInfoTb) {
|
|
||||||
taskInstanceInfoMapper.updateById(taskInstanceInfoTb);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskInstanceInfoTb getById(Long id) {
|
|
||||||
return taskInstanceInfoMapper.selectById(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-84
@@ -1,84 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.service;
|
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
|
||||||
import cn.odboy.framework.exception.BadRequestException;
|
|
||||||
import cn.odboy.task.constant.TaskStatusEnum;
|
|
||||||
import cn.odboy.task.dal.dataobject.TaskInstanceStepDetailTb;
|
|
||||||
import cn.odboy.task.dal.mysql.TaskInstanceStepDetailMapper;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
||||||
import java.util.List;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 任务实例步骤明细
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author codegen
|
|
||||||
* @since 2025-09-28
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
public class TaskInstanceStepDetailService {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private TaskInstanceStepDetailMapper taskInstanceStepDetailMapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 步骤执行成功
|
|
||||||
*
|
|
||||||
* @param instanceDetailId 任务实例明细id
|
|
||||||
* @param stepDesc 步骤描述
|
|
||||||
*/
|
|
||||||
public void success(Long instanceDetailId, String stepDesc) {
|
|
||||||
TaskInstanceStepDetailTb stepDetail = new TaskInstanceStepDetailTb();
|
|
||||||
stepDetail.setInstanceDetailId(instanceDetailId);
|
|
||||||
stepDetail.setStepDesc(stepDesc);
|
|
||||||
stepDetail.setStepStatus(TaskStatusEnum.Success.getCode());
|
|
||||||
taskInstanceStepDetailMapper.insert(stepDetail);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 步骤执行失败
|
|
||||||
*
|
|
||||||
* @param instanceDetailId 任务实例明细id
|
|
||||||
* @param stepDesc 步骤描述
|
|
||||||
*/
|
|
||||||
public void fail(Long instanceDetailId, String stepDesc) {
|
|
||||||
TaskInstanceStepDetailTb stepDetail = new TaskInstanceStepDetailTb();
|
|
||||||
stepDetail.setInstanceDetailId(instanceDetailId);
|
|
||||||
stepDetail.setStepDesc(stepDesc);
|
|
||||||
stepDetail.setStepStatus(TaskStatusEnum.Fail.getCode());
|
|
||||||
taskInstanceStepDetailMapper.insert(stepDetail);
|
|
||||||
throw new BadRequestException(stepDesc);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据明细ID删除步骤明细
|
|
||||||
*
|
|
||||||
* @param instanceDetailIds 任务实例明细id集合
|
|
||||||
*/
|
|
||||||
public void removeByInstanceDetailIds(List<Long> instanceDetailIds) {
|
|
||||||
if (CollUtil.isEmpty(instanceDetailIds)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
LambdaQueryWrapper<TaskInstanceStepDetailTb> wrapper = new LambdaQueryWrapper<>();
|
|
||||||
wrapper.in(TaskInstanceStepDetailTb::getInstanceDetailId, instanceDetailIds);
|
|
||||||
taskInstanceStepDetailMapper.delete(wrapper);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-41
@@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2021-2026 Odboy
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package cn.odboy.task.service;
|
|
||||||
|
|
||||||
import cn.odboy.task.dal.model.TaskTemplateInfoVo;
|
|
||||||
import cn.odboy.task.dal.mysql.TaskTemplateInfoMapper;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 任务模板
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author codegen
|
|
||||||
* @since 2025-09-28
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
public class TaskTemplateInfoService {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private TaskTemplateInfoMapper taskTemplateInfoMapper;
|
|
||||||
|
|
||||||
public TaskTemplateInfoVo getTemplateInfoByECL(String envAlias, String contextName, String language,
|
|
||||||
String changeType) {
|
|
||||||
return taskTemplateInfoMapper.selectTemplateInfoByECL(envAlias, contextName, language, changeType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-4
@@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
|
||||||
<mapper namespace="cn.odboy.task.dal.mysql.TaskInstanceDetailMapper">
|
|
||||||
</mapper>
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
|
||||||
<mapper namespace="cn.odboy.task.dal.mysql.TaskInstanceInfoMapper">
|
|
||||||
</mapper>
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
|
||||||
<mapper namespace="cn.odboy.task.dal.mysql.TaskTemplateInfoMapper">
|
|
||||||
<select id="selectTemplateInfoByECL" resultType="cn.odboy.task.dal.model.TaskTemplateInfoVo">
|
|
||||||
SELECT t2.change_type,
|
|
||||||
t2.`name`,
|
|
||||||
t2.description,
|
|
||||||
t2.env_alias,
|
|
||||||
t2.`language`,
|
|
||||||
t1.context_name,
|
|
||||||
t1.template_info
|
|
||||||
FROM task_pipeline_config t1
|
|
||||||
LEFT JOIN task_template_info t2 ON t1.template_info_id = t2.id
|
|
||||||
WHERE t1.context_name = #{contextName}
|
|
||||||
AND t2.env_alias = #{envAlias}
|
|
||||||
AND t2.`language` = #{language}
|
|
||||||
AND t2.`change_type` = #{changeType}
|
|
||||||
</select>
|
|
||||||
</mapper>
|
|
||||||
@@ -8,11 +8,8 @@
|
|||||||
<version>1.5.2</version>
|
<version>1.5.2</version>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
<!-- 基础设施 -->
|
|
||||||
<module>cutejava-framework</module>
|
<module>cutejava-framework</module>
|
||||||
<module>cutejava-module-system</module>
|
<module>cutejava-module-system</module>
|
||||||
<module>cutejava-module-task-v1</module>
|
|
||||||
<module>cutejava-module-task-v2</module>
|
|
||||||
<module>cutejava-starter</module>
|
<module>cutejava-starter</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user