OpenMetadata 测试通过自动关闭事故(Incident Auto-Close)设计方案全解析
2026/9/15 23:07:43 网站建设 项目流程

OpenMetadata 测试通过自动关闭事故(Incident Auto-Close)设计方案全解析

【免费下载链接】OpenMetadataThe Open Context Layer for Data and AI , OpenMetadata is the open platform for building trusted data context and business semantics for humans, AI assistants, and agents.项目地址: https://gitcode.com/GitHub_Trending/op/OpenMetadata

本方案是 OpenMetadata「Incident Manager → Governance Workflows 迁移」三阶段中的第二片(Slice 2),核心目标只有一个:当曾经失败的测试用例恢复通过时,系统自动把对应的事故(Incident)标记为已解决(reason:AutoResolved),并关闭其关联任务(Task),全程无需人工介入。读完本文,你将掌握该特性的触发链路、ResolveIncidentTask自动化节点设计、Schema 变更清单、默认工作流定义,以及它与生命周期工作流(Slice 1)之间的依赖关系,并结合当前仓库源码看清落地现状。

一、为什么需要自动关闭:Incident Manager 的 #1 缺口

OpenMetadata 的数据质量事故生命周期目前由 Incident Manager 管理:测试用例失败时创建事故,事故在New → Ack → Assigned → Resolved状态间流转,由人工分诊处理。

问题出在「测试恢复通过」这条路径上。当前仓库源码 TestCaseResultRepository.java 中的setTestCaseResultIncidentId()清楚地展示了这个缺口:

private void setTestCaseResultIncidentId( TestCaseResult testCaseResult, TestCase testCase, String updatedBy) { if (TestCaseStatus.Failed.equals(testCaseResult.getTestCaseStatus())) { UUID incidentStateId = TestCaseResolutionStatusRepository.getOrCreateIncident( testCase, updatedBy, testCaseResult.getResult()); testCaseResult.setIncidentId(incidentStateId); } else { testCaseResult.setIncidentId(null); // 只清空 incidentId,不 resolve 事故! } }

当测试结果不是Failed(即成功)时,该方法仅仅把TestCaseResult.incidentId置为null既不创建 Resolved 记录,也不关闭关联的 Task。后果是:底层问题已经修复、测试重新通过,事故却依然保持打开状态,长期悬挂在事故列表中与任务 Feed 里,直到有人手动处理。这正是本提案要修复的#1 缺口

二、What Ships:交付的用户可见行为

方案落地的用户可见变化有三点:

  • 测试通过 → 打开的事故自动解决 → 任务从 Feed 消失。用户不再需要手动关闭已被测试结果证明已修复的事故;
  • 解决原因为AutoResolved,与人工解决(手动输入原因)在数据上严格区分,便于审计与统计;
  • 完全可配置:用户可以通过治理工作流 UI(Governance Workflow)为自动关闭追加条件、副作用,或直接禁用该行为。

它解决的是一个高频场景:质量事故数据量庞大(ADR 中给出的企业规模估算为 5M 资产、50 万~150 万个带质量测试的用例、典型并发打开事故 1 万~7.5 万个),任何需要人工逐个关闭的事故都是一笔可观的运维成本。

三、核心构件:ResolveIncidentTask 自动化节点

方案引入一个新的自动化任务节点:

nodeType: automatedTask nodeSubType: resolveIncidentTask

该节点专门负责「为给定测试用例解决其打开的事故」。其核心实现ResolveIncidentImpl分五步执行:

  1. 取测试用例 FQN:从工作流变量relatedEntity中读取被测实体(TestCase)的全限定名;
  2. 查询最新事故状态:查询该测试用例当前打开的事故记录;
  3. 未解决则创建 Resolved 记录:事故仍处于未解决状态时,创建 Resolved 状态记录,reason固定为AutoResolved
  4. 关闭关联的 Thread 任务:通过 Repository 关闭与该事故关联的 Task;
  5. 终结生命周期进程:Repository 的 fire-and-forget 机制终止生命周期工作流进程(该能力由 Slice 1 接入)。

用户侧配置示例

{ "type": "automatedTask", "subType": "resolveIncidentTask", "config": { "reason": "AutoResolved" } }

节点类型为automatedTask,子类型为resolveIncidentTask,配置项当前只暴露reason(解决原因,默认AutoResolved)。这意味着工作流使用者不需要理解任何 Flowable/BPMN 细节,只需像拼积木一样声明节点即可。

四、Schema 变更清单

方案涉及三处 JSON Schema 变更,全部位于 openmetadata-spec:

  1. resolved.json:向TestCaseFailureReasonType枚举新增AutoResolved当前 resolved.json 中的testCaseFailureReasonType枚举仅有FalsePositive / MissingData / Duplicates / OutOfBounds / Other,尚无AutoResolved,因此本变更正是给「系统自动解决」一个合法的枚举身份;

  2. nodeSubType.json:新增resolveIncidentTask当前 nodeSubType.json 的枚举已包含userApprovalTaskcheckEntityAttributesTasksinkTaskendEventstartEvent等子类型,需要把resolveIncidentTask加入该枚举,节点才能通过 Schema 校验并被NodeFactory注册识别;

  3. 新增resolveIncidentTask.json节点定义automatedTask家族新增该子类型的专属节点 Schema(描述其config结构,如reason字段),作为节点配置的强类型约束。

从当前仓库源码看,第 1、2 项的枚举值尚未出现(AutoResolvedresolveIncidentTask均不在现有枚举中),说明这些 Schema 变更属于本提案待落地部分。

五、默认工作流:auto-close-incident-on-test-pass

方案随版本内置一个默认开启的工作流定义,命名为auto-close-incident-on-test-pass

Trigger: TestCase ENTITY_UPDATED, filter: testCaseStatus == Success Flow: [Start] → [ResolveIncidentTask] → [End] Config: reason: "AutoResolved"

三个关键设计点:

  • 触发器:监听TestCase实体的ENTITY_UPDATED事件,并通过过滤器(filter)只放行testCaseStatus == Success的更新,即「测试通过」这一精确事件;
  • 流程极短Start → ResolveIncidentTask → End,没有分支、没有等待、没有定时器;
  • 短生命周期、fire-and-forget:这是与生命周期工作流(Slice 1,长驻进程)最本质的区别——自动关闭流程是即用即焚的,处理完立即结束,不保留长期状态

正因如此,该工作流对系统资源占用极小,可以随测试结果高频触发,而不会积累运行中进程。

六、Out of Scope:明确不做的事

方案明确划定了本次(Slice 2)的范围边界,把相关但不属于本片的功能延后:

功能延后到原因
TTL / 陈旧事故过期Slice 3属于不同机制(边界定时器 boundary timer)
条件式自动关闭规则Future用户可自行添加checkEntityAttributesTask实现
关闭后的通知Future用户可自行在工作流末尾追加sinkTask

这一设计体现了治理工作流的核心理念:平台只提供最小、通用的自动化原语,复杂行为由用户通过编排工作流节点自由组合——想要条件判断就加checkEntityAttributesTask,想要通知就追加sinkTask,无需为每个需求改后端代码。

七、为什么必须依赖 Slice 1(生命周期工作流)

本提案标注为Slice 2 of 3,依赖 incident-lifecycle-workflow(Slice 1),依赖关系在根目录 ADR adr-incident-manager-governance-workflows.md 中有完整论述。

依赖的本质在于调用链:ResolveIncidentImpl通过 Repository 解决事故 → Repository 的 fire-and-forget 机制终止生命周期进程。如果没有 Slice 1 引入的生命周期进程(taskLifecycleNode),就没有进程可供终止——虽然 Repository 本身的解决逻辑不变、单独跑也能工作,但架构上不够干净。有了生命周期进程后,自动关闭天然成为该进程的自然终结者:事故解决即进程结束,两边语义完全对齐。

此外,Slice 1 建立的基础设施(以 OpenMetadata Task 为事实来源、通过IntermediateCatchEvent订阅消息、EventSubscriptionQuery.eventName(taskId)索引查找、WorkflowEventConsumer跳过governance-bot自身事件防止循环触发)都是本提案自动关闭工作流得以落地的前提。

八、当前仓库的落地情况与源码佐证

值得注意的是,当前仓库代码中已经出现了一个与提案同向的雏形实现。在 TestCaseResultRepository.java 中,addTestCaseResult()在写入成功结果时会调用autoResolveIncidentOnSuccess()

if (testCaseResult.getTestCaseStatus() == TestCaseStatus.Success) { testCaseRepository.deleteTestCaseFailedRowsSample(testCase.getId()); autoResolveIncidentOnSuccess(testCase); }

该方法的逻辑与提案高度吻合:

  • 通过isAutoCloseIncidentEnabled()检查测试用例的autoCloseIncident布尔标志(默认关闭);
  • 通过taskRepository.findTaskByEntityTypeAndStatuses()按 FQN 查找打开的TestCaseResolution类型任务;
  • 将任务 rehydrate 后,调用TaskWorkflowHandler.getInstance().resolveTask(..., "AutoResolved", WorkflowEventConsumer.GOVERNANCE_BOT)完成解决,原因正是提案中的AutoResolved,且以governance-bot身份执行以避免触发工作流循环。

从源码结构可以推断:AutoResolved这一语义在 Repository 层已被实际使用,而提案所规划的工作流化(resolveIncidentTask节点 +auto-close-incident-on-test-pass默认工作流)则是将这一能力从硬编码路径升级为可配置、可扩展的治理工作流原语——这也正是 ADR 中「扩展点缺失」问题的解决方向:把「测试通过即关闭事故」从写死在 Repository 里的行为,变成用户可以在 UI 中看到、配置、禁用和追加副作用的一等公民。

九、总结

incident-auto-close提案(proposal.md)用一个极轻量的自动化节点解决了事故管理中最痛的高频运维问题:测试通过后事故自动收敛。它继承了 Slice 1 的生命周期进程基建,把「自动关闭」做成可配置的默认工作流;同时通过 Out of Scope 划界,把 TTL(Slice 3)、条件规则、通知全部留给用户通过工作流节点自行组合。结合当前仓库源码可以看到,AutoResolved语义与自动解决逻辑已在实际代码路径中运转,本提案的落地将把这条硬编码路径完整迁移进治理工作流框架,为事故生命周期提供统一的扩展点。

【免费下载链接】OpenMetadataThe Open Context Layer for Data and AI , OpenMetadata is the open platform for building trusted data context and business semantics for humans, AI assistants, and agents.项目地址: https://gitcode.com/GitHub_Trending/op/OpenMetadata

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询