datai/docs/archive/REQ-014-4.md

92 lines
5.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 元数据容器与原子性部署需求
## 元数据
- 需求编号014-4
- 创建时间2026-01-26
- 创建人SSOT 架构师
- 状态:已完成
- 优先级:高
- 父需求:[REQ-014](../REQ-014.md)
- 关联代码:`com.sforce.soap.tooling.MetadataContainer`, `com.sforce.soap.tooling.ContainerAsyncRequest`, `com.sforce.soap.tooling.DeployDetails`
## 需求概述
实现基于 Tooling API 的“事务原子性”代码部署模块。通过 `MetadataContainer` 机制,支持将多个 Apex 类、触发器、Visualforce 页面等成员的修改打包,一次性原子部署。此机制是 Salesforce IDE 开发的核心,确保代码依赖的一致性。
## 目标
1. **原子性保证**:多文件修改(如 Class A 引用 Class B必须作为一个事务提交要么全成功要么全失败。
2. **编译与测试**:在部署过程中自动触发编译检查,并可选执行测试用例。
3. **状态反馈**:提供详细的部署结果,包括每一行的编译错误或测试失败信息。
## 功能需求
### 1. 容器生命周期管理 (Container Lifecycle)
必须处理容器名称冲突问题MetadataContainer Name 必须唯一)。
- `createContainer(String name)`: 创建新容器。如果同名容器已存在,应先尝试删除或使用唯一后缀生成新名称。
- `deleteContainer(String id)`: 部署完成后或发生异常时,清理容器以释放资源。
### 2. 成员管理 (Member Management)
支持添加多种类型的元数据成员到容器中。
- `addMember(String containerId, String metadataType, String contentEntityId, String body)`
- **metadataType**: 支持 `ApexClassMember`, `ApexTriggerMember`, `ApexComponentMember`, `ApexPageMember`
- **contentEntityId**: 对应 `ApexClass``ApexTrigger` 的 ID。如果是新建文件此字段可能为空取决于 API 版本行为,通常 Tooling API 更新需 ID
- **body**: 新的代码内容。
### 3. 异步部署请求 (Async Deployment)
创建 `ContainerAsyncRequest` 对象触发编译和部署。
- `deployContainer(String containerId, boolean isCheckOnly, boolean isRunTests)`
- **IsCheckOnly**: `true` 仅编译验证(不保存);`false` 实际保存代码。
- **IsRunTests**: 是否在部署后运行测试(通常用于生产环境部署或验证)。
- 返回 `requestId` (ContainerAsyncRequest ID)。
### 4. 状态轮询与结果解析 (Status Polling & Result Parsing)
由于部署是异步的,需要轮询状态并解析结果。
- `checkStatus(String requestId)`
- 轮询 `ContainerAsyncRequest` 对象的 `State` 字段。
- **状态流转**: `Queued` -> `Processing` -> `Completed` / `Failed` / `Error` / `Invalidated` / `Aborted`
- `getDeployDetails(String requestId)`
- 当状态为 `Completed``Failed` 时,读取 `DeployDetails` 字段。
- **解析编译错误**: 遍历 `DeployDetails.getComponentFailures()` (对应 `DeployMessage` 数组),提取 `fileName`, `lineNumber`, `problem` 等信息。
- **解析测试结果**: 如果运行了测试,解析 `DeployDetails.getRunTestResult()`
## 数据结构与接口定义
### 部署结果对象 (DeploymentResult)
```java
public class DeploymentResult {
private boolean success;
private String status; // Completed, Failed, etc.
private String errorMsg; // 系统级错误
private List<CompilationError> compilationErrors; // 代码编译错误
}
public class CompilationError {
private String fileName;
private int line;
private int column;
private String message;
}
```
## 异常处理
1. **容器名称冲突**: 捕获 `DUPLICATE_VALUE` 异常,自动重试或清理旧容器。
2. **成员添加失败**: 如 `contentEntityId` 无效或 `body` 为空,应在添加阶段报错。
3. **并发部署限制**: Salesforce 允许的并发 `ContainerAsyncRequest` 有限,需处理排队超时情况。
## 技术约束
- **DeployDetails 引用**: 必须使用 `com.sforce.soap.tooling.DeployDetails` 类进行反序列化。
- **API 版本**: 确保使用的 Tooling API 版本支持当前的元数据类型。
- **CheckOnly 限制**: `CheckOnly=true` 不会修改服务器代码,但会生成编译结果,适用于“保存前语法检查”。
## 成功标准
1. **原子性验证**: 创建一个依赖链Class A 依赖修改后的 Class B在同一个容器中部署成功。
2. **错误捕获**: 故意引入语法错误,部署状态应为 `Failed`,并能准确返回错误行号和错误信息。
3. **CheckOnly 模式**: 使用 `IsCheckOnly=true` 部署成功后,查询 `ApexClass` 内容确认未被修改。
## 相关文档
- [设计文档](../design/2026-01-27-014-4-元数据容器与原子性部署-设计.md)
- [决策记录](../decisions/adr/2026-01-27-014-4-ADR-元数据容器与原子性部署技术选型.md)
- [提示词文档](../prompts/2026-01-27-014-4-prompt-元数据容器与原子性部署.md)
- [变更日志](../changelog/2026-01-27-014-4-changelog.md)
- [复盘文档](../retros/2026-01-27-014-4-retro.md)
- [API 文档](../api-docs/2026-01-27-014-4-api.md)