增加工作流代码可正常启动
This commit is contained in:
parent
45e05fd935
commit
48524b9eb1
102
backend/docs/workflow-data-format.md
Normal file
102
backend/docs/workflow-data-format.md
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
# 工作流数据格式说明
|
||||||
|
|
||||||
|
## 1. 节点类型数据示例
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": 2003,
|
||||||
|
"createTime": "2024-12-05 12:40:03",
|
||||||
|
"createBy": "system",
|
||||||
|
"updateTime": "2024-12-05 12:40:03",
|
||||||
|
"updateBy": "system",
|
||||||
|
"version": 1,
|
||||||
|
"deleted": false,
|
||||||
|
"extraData": null,
|
||||||
|
"code": "SHELL",
|
||||||
|
"name": "Shell脚本节点",
|
||||||
|
"description": "执行Shell脚本的任务节点",
|
||||||
|
"category": "TASK",
|
||||||
|
"icon": "code",
|
||||||
|
"color": "#1890ff",
|
||||||
|
"executors": [
|
||||||
|
{
|
||||||
|
"code": "SHELL",
|
||||||
|
"name": "Shell脚本执行器",
|
||||||
|
"description": "执行Shell脚本,支持配置超时时间和工作目录",
|
||||||
|
"configSchema": "{\"type\":\"object\",\"required\":[\"script\"],\"properties\":{\"script\":{\"type\":\"string\",\"title\":\"脚本内容\",\"format\":\"shell\",\"description\":\"需要执行的Shell脚本内容\"},\"timeout\":{\"type\":\"number\",\"title\":\"超时时间\",\"description\":\"脚本执行的最大时间(秒)\",\"minimum\":1,\"maximum\":3600,\"default\":300},\"workingDir\":{\"type\":\"string\",\"title\":\"工作目录\",\"description\":\"脚本执行的工作目录\",\"default\":\"/tmp\"}}}",
|
||||||
|
"defaultConfig": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"configSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"string\",\n \"title\": \"节点名称\",\n \"minLength\": 1,\n \"maxLength\": 50\n },\n \"description\": {\n \"type\": \"string\",\n \"title\": \"节点描述\",\n \"maxLength\": 200\n },\n \"executor\": {\n \"type\": \"string\",\n \"title\": \"执行器\",\n \"enum\": [\"SHELL\"],\n \"enumNames\": [\"Shell脚本执行器\"]\n },\n \"retryTimes\": {\n \"type\": \"number\",\n \"title\": \"重试次数\",\n \"minimum\": 0,\n \"maximum\": 3,\n \"default\": 0\n },\n \"retryInterval\": {\n \"type\": \"number\",\n \"title\": \"重试间隔(秒)\",\n \"minimum\": 1,\n \"maximum\": 300,\n \"default\": 60\n }\n },\n \"required\": [\"name\", \"executor\"]\n}",
|
||||||
|
"defaultConfig": "{\"name\": \"Shell脚本\", \"executor\": \"SHELL\", \"retryTimes\": 0, \"retryInterval\": 60}",
|
||||||
|
"enabled": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. 流程设计数据示例
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"id": "node_1",
|
||||||
|
"type": "START",
|
||||||
|
"position": { "x": 100, "y": 100 },
|
||||||
|
"data": {
|
||||||
|
"name": "开始",
|
||||||
|
"description": "流程开始节点",
|
||||||
|
"config": {
|
||||||
|
"name": "开始",
|
||||||
|
"description": "这是一个开始节点"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"edges": [
|
||||||
|
{
|
||||||
|
"id": "edge_1",
|
||||||
|
"source": "node_1",
|
||||||
|
"target": "node_2",
|
||||||
|
"type": "default",
|
||||||
|
"data": {
|
||||||
|
"condition": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3. 关键字段说明
|
||||||
|
|
||||||
|
### configSchema(节点配置模式)
|
||||||
|
**用途**:
|
||||||
|
1. 前端动态生成配置表单
|
||||||
|
2. 后端验证配置数据的合法性
|
||||||
|
3. 提供配置项的约束和验证规则
|
||||||
|
|
||||||
|
### defaultConfig(默认配置)
|
||||||
|
**用途**:
|
||||||
|
1. 新建节点时的默认值
|
||||||
|
2. 重置配置时的参考值
|
||||||
|
3. 必须符合configSchema定义的格式
|
||||||
|
|
||||||
|
### executors(执行器定义)
|
||||||
|
**用途**:
|
||||||
|
1. 定义节点支持的执行器类型
|
||||||
|
2. 每个执行器的配置要求
|
||||||
|
3. 用于任务节点的具体执行逻辑
|
||||||
|
|
||||||
|
## 4. 字段关系说明
|
||||||
|
|
||||||
|
1. configSchema定义节点的整体配置结构
|
||||||
|
2. defaultConfig提供符合configSchema的默认值
|
||||||
|
3. executors中的configSchema定义具体执行器的配置结构
|
||||||
|
4. 实际节点配置时,executorConfig需要符合选定执行器的configSchema
|
||||||
|
|
||||||
|
## 5. 设计优点
|
||||||
|
|
||||||
|
1. 配置灵活可扩展
|
||||||
|
2. 前端可以动态生成表单
|
||||||
|
3. 后端可以严格验证配置
|
||||||
|
4. 支持不同类型节点的差异化配置
|
||||||
|
5. 便于新增节点类型和执行器
|
||||||
@ -26,7 +26,7 @@ import java.util.List;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
@Tag(name = "节点类型管理", description = "节点类型相关接口")
|
@Tag(name = "节点类型管理", description = "节点类型相关接口")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/v1/node-type")
|
@RequestMapping("/api/v1/node-types")
|
||||||
public class NodeTypeApiController extends BaseController<NodeType, NodeTypeDTO, Long, NodeTypeQuery> {
|
public class NodeTypeApiController extends BaseController<NodeType, NodeTypeDTO, Long, NodeTypeQuery> {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
package com.qqchen.deploy.backend.workflow.converter.impl;
|
package com.qqchen.deploy.backend.workflow.converter.impl;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
|
import com.qqchen.deploy.backend.framework.enums.ResponseCode;
|
||||||
import com.qqchen.deploy.backend.framework.exception.SystemException;
|
import com.qqchen.deploy.backend.framework.exception.SystemException;
|
||||||
import com.qqchen.deploy.backend.workflow.converter.JsonConverter;
|
import com.qqchen.deploy.backend.workflow.converter.JsonConverter;
|
||||||
import com.qqchen.deploy.backend.workflow.engine.definition.TaskExecutorDefinition;
|
import com.qqchen.deploy.backend.workflow.engine.definition.TaskExecutorDefinition;
|
||||||
@ -30,9 +32,24 @@ public class DefaultJsonConverter implements JsonConverter {
|
|||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return objectMapper.readValue(json, new TypeReference<List<TaskExecutorDefinition>>() {});
|
// 先将JSON解析为JsonNode,以便我们可以手动处理configSchema字段
|
||||||
|
JsonNode rootNode = objectMapper.readTree(json);
|
||||||
|
if (!rootNode.isArray()) {
|
||||||
|
throw new SystemException(ResponseCode.WORKFLOW_CONFIG_INVALID, new Object[]{"Executors JSON must be an array"}, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<TaskExecutorDefinition> result = new ArrayList<>();
|
||||||
|
for (JsonNode node : rootNode) {
|
||||||
|
// 将configSchema转换为字符串
|
||||||
|
if (node.has("configSchema")) {
|
||||||
|
((ObjectNode) node).put("configSchema", node.get("configSchema").toString());
|
||||||
|
}
|
||||||
|
// 将处理后的节点转换为TaskExecutorDefinition对象
|
||||||
|
result.add(objectMapper.treeToValue(node, TaskExecutorDefinition.class));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
} catch (JsonProcessingException e) {
|
} catch (JsonProcessingException e) {
|
||||||
throw new SystemException("Failed to parse executors JSON: " + e.getMessage(), e);
|
throw new SystemException(ResponseCode.WORKFLOW_CONFIG_INVALID, new Object[]{"Failed to parse executors JSON: " + e.getMessage()}, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,9 +2,9 @@ server:
|
|||||||
port: 8080
|
port: 8080
|
||||||
spring:
|
spring:
|
||||||
datasource:
|
datasource:
|
||||||
url: jdbc:mysql://127.0.0.1:3306/deploy-ease-platform?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
|
url: jdbc:mysql://localhost:3306/deploy-ease-platform?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
|
||||||
username: root
|
username: root
|
||||||
password: root
|
password: ServBay.dev
|
||||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
jpa:
|
jpa:
|
||||||
hibernate:
|
hibernate:
|
||||||
|
|||||||
@ -247,4 +247,179 @@ INSERT INTO wf_workflow_variable (
|
|||||||
(2, 'admin', NOW(), 0, 'admin', NOW(), 0,
|
(2, 'admin', NOW(), 0, 'admin', NOW(), 0,
|
||||||
1, 'branch', 'master', 'STRING'),
|
1, 'branch', 'master', 'STRING'),
|
||||||
(3, 'admin', NOW(), 0, 'admin', NOW(), 0,
|
(3, 'admin', NOW(), 0, 'admin', NOW(), 0,
|
||||||
1, 'buildNumber', '123', 'STRING');
|
1, 'buildNumber', '123', 'STRING');
|
||||||
|
|
||||||
|
-- 节点类型初始化数据
|
||||||
|
INSERT INTO wf_node_type (id, code, name, description, category, icon, color, executors, config_schema, default_config, enabled, create_time, create_by, update_time, update_by, version, deleted)
|
||||||
|
VALUES
|
||||||
|
-- 基础节点类型
|
||||||
|
(2001, 'START', '开始节点', '工作流的开始节点', 'BASIC', 'play-circle', '#52c41a', '[]',
|
||||||
|
'{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "节点名称",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 50
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "节点描述",
|
||||||
|
"maxLength": 200
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["name"]
|
||||||
|
}',
|
||||||
|
'{"name": "开始", "description": ""}',
|
||||||
|
true, NOW(), 'system', NOW(), 'system', 1, false),
|
||||||
|
|
||||||
|
(2002, 'END', '结束节点', '工作流的结束节点', 'BASIC', 'stop', '#ff4d4f', '[]',
|
||||||
|
'{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "节点名称",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 50
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "节点描述",
|
||||||
|
"maxLength": 200
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["name"]
|
||||||
|
}',
|
||||||
|
'{"name": "结束", "description": ""}',
|
||||||
|
true, NOW(), 'system', NOW(), 'system', 1, false),
|
||||||
|
|
||||||
|
-- 任务节点类型
|
||||||
|
(2003, 'SHELL', 'Shell脚本节点', '执行Shell脚本的任务节点', 'TASK', 'code', '#1890ff',
|
||||||
|
'[{
|
||||||
|
"code": "SHELL",
|
||||||
|
"name": "Shell脚本执行器",
|
||||||
|
"description": "执行Shell脚本,支持配置超时时间和工作目录",
|
||||||
|
"configSchema": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["script"],
|
||||||
|
"properties": {
|
||||||
|
"script": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "脚本内容",
|
||||||
|
"format": "shell",
|
||||||
|
"description": "需要执行的Shell脚本内容"
|
||||||
|
},
|
||||||
|
"timeout": {
|
||||||
|
"type": "number",
|
||||||
|
"title": "超时时间",
|
||||||
|
"description": "脚本执行的最大时间(秒)",
|
||||||
|
"minimum": 1,
|
||||||
|
"maximum": 3600,
|
||||||
|
"default": 300
|
||||||
|
},
|
||||||
|
"workingDir": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "工作目录",
|
||||||
|
"description": "脚本执行的工作目录",
|
||||||
|
"default": "/tmp"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}]',
|
||||||
|
'{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "节点名称",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 50
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "节点描述",
|
||||||
|
"maxLength": 200
|
||||||
|
},
|
||||||
|
"executor": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "执行器",
|
||||||
|
"enum": ["SHELL"],
|
||||||
|
"enumNames": ["Shell脚本执行器"]
|
||||||
|
},
|
||||||
|
"retryTimes": {
|
||||||
|
"type": "number",
|
||||||
|
"title": "重试次数",
|
||||||
|
"minimum": 0,
|
||||||
|
"maximum": 3,
|
||||||
|
"default": 0
|
||||||
|
},
|
||||||
|
"retryInterval": {
|
||||||
|
"type": "number",
|
||||||
|
"title": "重试间隔(秒)",
|
||||||
|
"minimum": 1,
|
||||||
|
"maximum": 300,
|
||||||
|
"default": 60
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["name", "executor"]
|
||||||
|
}',
|
||||||
|
'{"name": "Shell脚本", "executor": "SHELL", "retryTimes": 0, "retryInterval": 60}',
|
||||||
|
true, NOW(), 'system', NOW(), 'system', 1, false),
|
||||||
|
|
||||||
|
-- 网关节点类型
|
||||||
|
(2004, 'GATEWAY', '网关节点', '控制流程流转的网关节点', 'GATEWAY', 'fork', '#faad14', '[]',
|
||||||
|
'{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "节点名称",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 50
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "节点描述",
|
||||||
|
"maxLength": 200
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "网关类型",
|
||||||
|
"enum": ["PARALLEL", "EXCLUSIVE", "INCLUSIVE"],
|
||||||
|
"enumNames": ["并行网关", "排他网关", "包容网关"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["name", "type"]
|
||||||
|
}',
|
||||||
|
'{"name": "网关", "type": "EXCLUSIVE"}',
|
||||||
|
true, NOW(), 'system', NOW(), 'system', 1, false),
|
||||||
|
|
||||||
|
-- 事件节点类型
|
||||||
|
(2005, 'TIMER', '定时器节点', '定时触发的事件节点', 'EVENT', 'clock-circle', '#722ed1', '[]',
|
||||||
|
'{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "节点名称",
|
||||||
|
"minLength": 1,
|
||||||
|
"maxLength": 50
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "节点描述",
|
||||||
|
"maxLength": 200
|
||||||
|
},
|
||||||
|
"cron": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "CRON表达式",
|
||||||
|
"pattern": "^(\\d+|\\*|\\*/\\d+|\\d+\\-\\d+|\\d+(,\\d+)*) (\\d+|\\*|\\*/\\d+|\\d+\\-\\d+|\\d+(,\\d+)*) (\\d+|\\*|\\*/\\d+|\\d+\\-\\d+|\\d+(,\\d+)*) (\\d+|\\*|\\*/\\d+|\\d+\\-\\d+|\\d+(,\\d+)*) (\\d+|\\*|\\*/\\d+|\\d+\\-\\d+|\\d+(,\\d+)*) (\\d+|\\*|\\*/\\d+|\\d+\\-\\d+|\\d+(,\\d+)*)$",
|
||||||
|
"description": "定时触发的CRON表达式"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["name", "cron"]
|
||||||
|
}',
|
||||||
|
'{"name": "定时器", "cron": "0 0 * * * ?"}',
|
||||||
|
true, NOW(), 'system', NOW(), 'system', 1, false);
|
||||||
Loading…
Reference in New Issue
Block a user