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

92 lines
5.1 KiB
Markdown
Raw Normal View History

# 元数据容器与原子性部署需求
## 元数据
- 需求编号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)