From 18c4d3c0d7253e40140262996af9558da1233f53 Mon Sep 17 00:00:00 2001 From: lixiaolong <702156524@qq.com> Date: Tue, 11 Aug 2026 17:32:10 +0800 Subject: [PATCH] =?UTF-8?q?fix(flow):=20=E4=BF=AE=E5=A4=8D=E8=BE=B9?= =?UTF-8?q?=E7=BC=98=E8=8A=82=E7=82=B9=E6=89=A7=E8=A1=8C=E7=9B=AE=E6=A0=87?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E9=AA=8C=E8=AF=81=E5=92=8C=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 EdgeCameraOperateService 中启用视频录制功能并移除硬编码路径 - 为 FlowRuntimeAssignmentResolver 添加节点类型检查避免非边缘节点处理 - 当执行目标为空且运行时分配存在时抛出异常提供明确错误信息 - 在 FlowRuntimeDefinitionValidator 中增强节点验证逻辑确保边缘节点配置完整性 - 添加单元测试验证遗留机器人配置和非机器人节点处理场景 - 修复测试用例中的节点类型配置确保测试准确性 --- .../engine/FlowRuntimeAssignmentResolver.java | 11 +++++-- .../FlowRuntimeDefinitionValidator.java | 10 ++++-- .../edge/EdgeCameraOperateService.java | 4 +-- .../FlowRuntimeAssignmentResolverTest.java | 32 +++++++++++++++++++ 4 files changed, 51 insertions(+), 6 deletions(-) diff --git a/cmvr-iot-test/src/main/java/com/cmvr/test/flow/runtime/engine/FlowRuntimeAssignmentResolver.java b/cmvr-iot-test/src/main/java/com/cmvr/test/flow/runtime/engine/FlowRuntimeAssignmentResolver.java index 72dcfe4..c68105d 100644 --- a/cmvr-iot-test/src/main/java/com/cmvr/test/flow/runtime/engine/FlowRuntimeAssignmentResolver.java +++ b/cmvr-iot-test/src/main/java/com/cmvr/test/flow/runtime/engine/FlowRuntimeAssignmentResolver.java @@ -17,10 +17,17 @@ import java.util.List; public class FlowRuntimeAssignmentResolver { public void resolveNode(FlowNodeWrapper node, TaskNodeExecuteMessage message) { - JSONObject executionTarget = node.getRawProperties().getJSONObject("executionTarget"); - if (executionTarget == null) { + JSONObject properties = node.getRawProperties(); + if (properties == null || !"EDGE".equalsIgnoreCase(properties.getString("nodeType"))) { return; } + JSONObject executionTarget = properties.getJSONObject("executionTarget"); + if (executionTarget == null) { + if (message.getRuntimeAssignments() == null || message.getRuntimeAssignments().isEmpty()) { + return; + } + throw new GlobalException("节点[" + node.getNodeName() + "]未配置机器人角色"); + } String roleKey = executionTarget.getString("roleKey"); if (StrUtil.isBlank(roleKey)) { diff --git a/cmvr-iot-test/src/main/java/com/cmvr/test/flow/runtime/engine/FlowRuntimeDefinitionValidator.java b/cmvr-iot-test/src/main/java/com/cmvr/test/flow/runtime/engine/FlowRuntimeDefinitionValidator.java index 150ddd8..9b49ca1 100644 --- a/cmvr-iot-test/src/main/java/com/cmvr/test/flow/runtime/engine/FlowRuntimeDefinitionValidator.java +++ b/cmvr-iot-test/src/main/java/com/cmvr/test/flow/runtime/engine/FlowRuntimeDefinitionValidator.java @@ -87,11 +87,17 @@ public class FlowRuntimeDefinitionValidator { for (int i = 0; i < nodes.size(); i++) { JSONObject node = nodes.getJSONObject(i); JSONObject properties = node.getJSONObject("properties"); - JSONObject target = properties == null ? null : properties.getJSONObject("executionTarget"); - if (target == null) { + if (properties == null || !"EDGE".equalsIgnoreCase(properties.getString("nodeType"))) { continue; } + JSONObject target = properties.getJSONObject("executionTarget"); + if (target == null) { + throw new GlobalException("节点[" + properties.getString("name") + "]未配置机器人角色"); + } String roleKey = target.getString("roleKey"); + if (StrUtil.isBlank(roleKey)) { + throw new GlobalException("节点[" + properties.getString("name") + "]未配置机器人角色"); + } Set slotKeys = slotKeysByRole.get(roleKey); if (slotKeys == null) { throw new GlobalException("节点[" + properties.getString("name") + "]引用了不存在的机器人角色"); diff --git a/cmvr-iot-test/src/main/java/com/cmvr/test/flow/runtime/operator/edge/EdgeCameraOperateService.java b/cmvr-iot-test/src/main/java/com/cmvr/test/flow/runtime/operator/edge/EdgeCameraOperateService.java index 48bc841..6b5227b 100644 --- a/cmvr-iot-test/src/main/java/com/cmvr/test/flow/runtime/operator/edge/EdgeCameraOperateService.java +++ b/cmvr-iot-test/src/main/java/com/cmvr/test/flow/runtime/operator/edge/EdgeCameraOperateService.java @@ -106,9 +106,9 @@ public class EdgeCameraOperateService implements EdgeOperateService { case CAMERA_RECORDING_START: { // 生成视频路径 -// String videoUrl = edgeCameraService.startRecording(edgeCommonVO); + String videoUrl = edgeCameraService.startRecording(edgeCommonVO); // String videoUrl = StrUtil.format("{}/{}_{}.mp4", "/home/share/assets/video", deviceId, System.currentTimeMillis()); - String videoUrl = "/home/xtkuang/Projects/models/assets/video/IMG_0524_silent.mp4"; +// String videoUrl = "/home/xtkuang/Projects/models/assets/video/IMG_0524_silent.mp4"; // 创建一个新的 JSONObject 来保存视频路径和其他信息 JSONObject videoInfo = new JSONObject(); videoInfo.put("videoUrl", videoUrl); diff --git a/cmvr-iot-test/src/test/java/com/cmvr/test/flow/runtime/engine/FlowRuntimeAssignmentResolverTest.java b/cmvr-iot-test/src/test/java/com/cmvr/test/flow/runtime/engine/FlowRuntimeAssignmentResolverTest.java index dd980ea..904a598 100644 --- a/cmvr-iot-test/src/test/java/com/cmvr/test/flow/runtime/engine/FlowRuntimeAssignmentResolverTest.java +++ b/cmvr-iot-test/src/test/java/com/cmvr/test/flow/runtime/engine/FlowRuntimeAssignmentResolverTest.java @@ -12,6 +12,7 @@ import java.util.List; import java.util.Map; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; public class FlowRuntimeAssignmentResolverTest { @@ -23,6 +24,7 @@ public class FlowRuntimeAssignmentResolverTest { node.setNodeName("拍摄"); node.setRawProperties(JSON.parseObject(""" { + "nodeType": "EDGE", "executionTarget": { "roleKey": "inspection", "deviceSlotKey": "front_camera" @@ -55,6 +57,7 @@ public class FlowRuntimeAssignmentResolverTest { FlowNodeWrapper node = new FlowNodeWrapper(); node.setNodeName("旧节点"); node.setRawProperties(new JSONObject(Map.of( + "nodeType", "EDGE", "executionTarget", new JSONObject(Map.of("roleKey", "default_executor")) ))); TaskNodeExecuteMessage message = new TaskNodeExecuteMessage(); @@ -65,4 +68,33 @@ public class FlowRuntimeAssignmentResolverTest { assertEquals("default_executor", message.getRoleKey()); assertEquals("legacy-robot", message.getRobotId()); } + + @Test + public void keepsLegacyRobotWhenExecutionTargetIsAbsent() { + FlowNodeWrapper node = new FlowNodeWrapper(); + node.setNodeName("旧机器人节点"); + node.setRawProperties(new JSONObject(Map.of("nodeType", "EDGE"))); + TaskNodeExecuteMessage message = new TaskNodeExecuteMessage(); + message.setRobotId("legacy-robot"); + + resolver.resolveNode(node, message); + + assertEquals("legacy-robot", message.getRobotId()); + assertNull(message.getRoleKey()); + } + + @Test + public void ignoresStaleExecutionTargetOnNonRobotNode() { + FlowNodeWrapper node = new FlowNodeWrapper(); + node.setNodeName("睡眠"); + node.setRawProperties(new JSONObject(Map.of( + "executionTarget", new JSONObject() + ))); + TaskNodeExecuteMessage message = new TaskNodeExecuteMessage(); + + resolver.resolveNode(node, message); + + assertNull(message.getRoleKey()); + assertNull(message.getResolvedDeviceBindings()); + } }