增加工作流代码可正常启动

This commit is contained in:
戚辰先生 2024-12-05 13:24:05 +08:00
parent 45e05fd935
commit 48524b9eb1
5 changed files with 301 additions and 7 deletions

View 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. 便于新增节点类型和执行器

View File

@ -26,7 +26,7 @@ import java.util.List;
@Slf4j
@Tag(name = "节点类型管理", description = "节点类型相关接口")
@RestController
@RequestMapping("/api/v1/node-type")
@RequestMapping("/api/v1/node-types")
public class NodeTypeApiController extends BaseController<NodeType, NodeTypeDTO, Long, NodeTypeQuery> {
@Resource

View File

@ -1,8 +1,10 @@
package com.qqchen.deploy.backend.workflow.converter.impl;
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.node.ObjectNode;
import com.qqchen.deploy.backend.framework.enums.ResponseCode;
import com.qqchen.deploy.backend.framework.exception.SystemException;
import com.qqchen.deploy.backend.workflow.converter.JsonConverter;
import com.qqchen.deploy.backend.workflow.engine.definition.TaskExecutorDefinition;
@ -30,9 +32,24 @@ public class DefaultJsonConverter implements JsonConverter {
return new ArrayList<>();
}
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) {
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);
}
}

View File

@ -2,9 +2,9 @@ server:
port: 8080
spring:
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
password: root
password: ServBay.dev
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:

View File

@ -247,4 +247,179 @@ INSERT INTO wf_workflow_variable (
(2, 'admin', NOW(), 0, 'admin', NOW(), 0,
1, 'branch', 'master', 'STRING'),
(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);