457 lines
12 KiB
Markdown
457 lines
12 KiB
Markdown
# API 文档:003-03 部署操作
|
||
|
||
## 元数据
|
||
|
||
- **需求编号**: 003-03
|
||
- **需求名称**: 部署操作
|
||
- **创建时间**: 2026-02-06
|
||
- **创建人**: AI Assistant
|
||
- **版本号**: v1.0.0
|
||
- **状态**: 已完成
|
||
|
||
---
|
||
|
||
## API 概述
|
||
|
||
部署操作 API 提供通用的 ZIP 部署服务,支持字节数组格式的 ZIP 文件部署、同步轮询、状态查询和取消部署功能。该服务与 003-02 的元数据类型定义功能完全解耦,通过通用字节流接口接收 ZIP 数据。
|
||
|
||
### 核心功能
|
||
1. **部署 ZIP 包**: 接收 ZIP 文件进行元数据部署
|
||
2. **同步轮询**: 后端轮询直到部署完成(成功或失败)
|
||
3. **状态查询**: 通过 deployId 查询部署状态
|
||
4. **取消部署**: 取消正在进行的部署操作
|
||
|
||
### 技术特点
|
||
- **通用字节流接口**: Service 层接收 `byte[]` 格式的 ZIP 数据
|
||
- **文件上传支持**: 支持最大 50MB 的 ZIP 文件上传
|
||
- **同步轮询机制**: 最多轮询 60 次,每 5 秒检查一次状态
|
||
- **异步日志记录**: 使用 Spring @Async 异步记录部署历史
|
||
- **完整错误码体系**: 定义 6 个标准错误码
|
||
|
||
---
|
||
|
||
## 接口列表
|
||
|
||
### 1. 部署 ZIP 包
|
||
|
||
**功能描述**: 接收 ZIP 文件进行元数据部署,返回部署 ID。
|
||
|
||
**请求方式**: POST
|
||
|
||
**请求路径**: `/salesforce/metadata/deploy`
|
||
|
||
**权限要求**: `salesforce:metadata:deploy`
|
||
|
||
#### 请求参数
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| file | MultipartFile | 是 | ZIP 文件,最大 50MB |
|
||
| deployOptionsJson | String | 否 | 部署选项 JSON 字符串 |
|
||
|
||
#### DeployOptions 字段说明
|
||
|
||
| 字段名 | 类型 | 默认值 | 说明 |
|
||
|--------|------|--------|------|
|
||
| allowMissingFiles | boolean | false | 是否允许缺少文件 |
|
||
| autoUpdatePackage | boolean | false | 是否自动更新包 |
|
||
| checkOnly | boolean | false | 是否只检查不部署 |
|
||
| ignoreWarnings | boolean | false | 是否忽略警告 |
|
||
| performRetrieve | boolean | false | 是否执行检索 |
|
||
| purgeOnDelete | boolean | false | 删除时是否清除 |
|
||
| rollbackOnError | boolean | true | 出错时是否回滚 |
|
||
| testLevel | String | null | 测试级别(NoTestRun, RunSpecifiedTests, RunLocalTests, RunAllTestsInOrg) |
|
||
| runTests | String[] | null | 指定要运行的测试类 |
|
||
| singlePackage | boolean | true | 是否为单个包 |
|
||
| validateOnly | boolean | false | 是否仅验证 |
|
||
|
||
#### 响应参数
|
||
|
||
| 参数名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| code | int | 状态码(200 成功,其他失败) |
|
||
| msg | String | 提示信息 |
|
||
| data | Object | 部署结果 |
|
||
|
||
#### data 字段说明
|
||
|
||
| 字段名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| deployId | String | 部署 ID |
|
||
|
||
#### 成功示例
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "操作成功",
|
||
"data": {
|
||
"deployId": "0Afxx0000004M5sCAE"
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 失败示例
|
||
|
||
```json
|
||
{
|
||
"code": 500,
|
||
"msg": "部署失败: 文件格式错误,请上传 ZIP 文件"
|
||
}
|
||
```
|
||
|
||
#### 错误码
|
||
|
||
- 500: 部署失败
|
||
- 500: 文件格式错误(非 ZIP 文件)
|
||
- 500: 文件大小超过 50MB 限制
|
||
|
||
---
|
||
|
||
### 2. 检查部署状态
|
||
|
||
**功能描述**: 通过 deployId 查询当前部署状态。
|
||
|
||
**请求方式**: GET
|
||
|
||
**请求路径**: `/salesforce/metadata/deploy/status/{deployId}`
|
||
|
||
**权限要求**: `salesforce:metadata:deploy:query`
|
||
|
||
#### 请求参数
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| deployId | String | 是 | 部署 ID(路径参数) |
|
||
|
||
#### 响应参数
|
||
|
||
| 参数名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| code | int | 状态码(200 成功,其他失败) |
|
||
| msg | String | 提示信息 |
|
||
| data | Object | 部署状态结果 |
|
||
|
||
#### data 字段说明(DeployResultVo)
|
||
|
||
| 字段名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| success | boolean | 是否成功 |
|
||
| id | String | 部署 ID |
|
||
| status | String | 部署状态(Queued, InProgress, Succeeded, Failed, Canceled) |
|
||
| numberComponentErrors | int | 组件错误数 |
|
||
| numberComponentsDeployed | int | 已部署组件数 |
|
||
| numberComponentsTotal | int | 总组件数 |
|
||
| numberTestErrors | int | 测试错误数 |
|
||
| numberTestsCompleted | int | 已完成测试数 |
|
||
| numberTestsTotal | int | 总测试数 |
|
||
| errorMessage | String | 错误消息 |
|
||
| messages | List<DeployMessageVo> | 部署消息列表 |
|
||
|
||
#### DeployMessageVo 字段说明
|
||
|
||
| 字段名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| changed | boolean | 是否已更改 |
|
||
| columnNumber | int | 列号 |
|
||
| componentType | String | 组件类型 |
|
||
| fileName | String | 文件名 |
|
||
| fullName | String | 完整名称 |
|
||
| lineNumber | int | 行号 |
|
||
| problem | String | 问题描述 |
|
||
| success | boolean | 是否成功 |
|
||
|
||
#### 成功示例
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "操作成功",
|
||
"data": {
|
||
"success": true,
|
||
"id": "0Afxx0000004M5sCAE",
|
||
"status": "Succeeded",
|
||
"numberComponentErrors": 0,
|
||
"numberComponentsDeployed": 5,
|
||
"numberComponentsTotal": 5,
|
||
"numberTestErrors": 0,
|
||
"numberTestsCompleted": 10,
|
||
"numberTestsTotal": 10,
|
||
"errorMessage": null,
|
||
"messages": [
|
||
{
|
||
"changed": true,
|
||
"columnNumber": 0,
|
||
"componentType": "CustomObject",
|
||
"fileName": "objects/Account.object",
|
||
"fullName": "Account",
|
||
"lineNumber": 0,
|
||
"problem": null,
|
||
"success": true
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 失败示例
|
||
|
||
```json
|
||
{
|
||
"code": 500,
|
||
"msg": "状态查询失败: 部署 ID 不存在"
|
||
}
|
||
```
|
||
|
||
#### 错误码
|
||
|
||
- 500: 状态查询失败
|
||
|
||
---
|
||
|
||
### 3. 同步轮询部署状态
|
||
|
||
**功能描述**: 后端轮询直到部署完成(成功或失败),最多轮询 60 次,每 5 秒一次,5 分钟超时。
|
||
|
||
**请求方式**: GET
|
||
|
||
**请求路径**: `/salesforce/metadata/deploy/poll/{deployId}`
|
||
|
||
**权限要求**: `salesforce:metadata:deploy:query`
|
||
|
||
#### 请求参数
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| deployId | String | 是 | 部署 ID(路径参数) |
|
||
|
||
#### 响应参数
|
||
|
||
| 参数名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| code | int | 状态码(200 成功,其他失败) |
|
||
| msg | String | 提示信息 |
|
||
| data | Object | 部署结果(DeployResultVo) |
|
||
|
||
#### data 字段说明
|
||
|
||
同"检查部署状态"接口的 data 字段。
|
||
|
||
#### 成功示例
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "操作成功",
|
||
"data": {
|
||
"success": true,
|
||
"id": "0Afxx0000004M5sCAE",
|
||
"status": "Succeeded",
|
||
"numberComponentErrors": 0,
|
||
"numberComponentsDeployed": 5,
|
||
"numberComponentsTotal": 5,
|
||
"numberTestErrors": 0,
|
||
"numberTestsCompleted": 10,
|
||
"numberTestsTotal": 10,
|
||
"errorMessage": null,
|
||
"messages": []
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 失败示例
|
||
|
||
```json
|
||
{
|
||
"code": 500,
|
||
"msg": "部署超时(超过5分钟)"
|
||
}
|
||
```
|
||
|
||
#### 错误码
|
||
|
||
- 500: 轮询被中断
|
||
- 500: 部署超时(超过5分钟)
|
||
|
||
---
|
||
|
||
### 4. 取消部署
|
||
|
||
**功能描述**: 取消正在进行的部署操作。
|
||
|
||
**请求方式**: POST
|
||
|
||
**请求路径**: `/salesforce/metadata/deploy/cancel/{deployId}`
|
||
|
||
**权限要求**: `salesforce:metadata:deploy:cancel`
|
||
|
||
#### 请求参数
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| deployId | String | 是 | 部署 ID(路径参数) |
|
||
|
||
#### 响应参数
|
||
|
||
| 参数名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| code | int | 状态码(200 成功,其他失败) |
|
||
| msg | String | 提示信息 |
|
||
| data | Object | 取消结果 |
|
||
|
||
#### data 字段说明
|
||
|
||
| 字段名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| success | boolean | 是否成功取消 |
|
||
|
||
#### 成功示例
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "操作成功",
|
||
"data": {
|
||
"success": true
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 失败示例
|
||
|
||
```json
|
||
{
|
||
"code": 500,
|
||
"msg": "取消部署失败: 部署已完成或已取消"
|
||
}
|
||
```
|
||
|
||
#### 错误码
|
||
|
||
- 500: 取消部署失败
|
||
|
||
---
|
||
|
||
## 错误码
|
||
|
||
### 业务错误码
|
||
|
||
| 错误码 | 错误信息 | 说明 | 处理建议 |
|
||
|--------|----------|------|----------|
|
||
| METADATA_DEPLOY_001 | 部署失败 | 部署过程中发生错误 | 检查 ZIP 文件内容和部署选项 |
|
||
| METADATA_DEPLOY_002 | 状态查询失败 | 查询部署状态时发生错误 | 检查 deployId 是否正确 |
|
||
| METADATA_DEPLOY_003 | 轮询被中断 | 同步轮询过程中被中断 | 检查线程状态,重新发起轮询 |
|
||
| METADATA_DEPLOY_004 | 取消部署失败 | 取消部署时发生错误 | 检查部署状态是否可取消 |
|
||
| METADATA_DEPLOY_005 | 部署超时(超过5分钟) | 同步轮询超过 5 分钟 | 检查 Salesforce 服务状态,稍后重试 |
|
||
| METADATA_DEPLOY_006 | 文件格式错误(非ZIP文件) | 上传的文件不是 ZIP 格式 | 请上传 ZIP 格式的文件 |
|
||
|
||
### HTTP 状态码
|
||
|
||
| 状态码 | 说明 | 处理建议 |
|
||
|--------|------|----------|
|
||
| 200 | 请求成功 | - |
|
||
| 401 | 未授权 | 检查用户权限 |
|
||
| 403 | 禁止访问 | 检查用户角色权限 |
|
||
| 404 | 资源不存在 | 检查请求路径和参数 |
|
||
| 500 | 服务器内部错误 | 查看错误日志,联系管理员 |
|
||
|
||
---
|
||
|
||
## 部署状态说明
|
||
|
||
| 状态 | 说明 | 是否终态 |
|
||
|------|------|----------|
|
||
| Queued | 已排队,等待执行 | 否 |
|
||
| InProgress | 正在进行中 | 否 |
|
||
| Succeeded | 部署成功 | 是 |
|
||
| Failed | 部署失败 | 是 |
|
||
| Canceled | 已取消 | 是 |
|
||
|
||
---
|
||
|
||
## 使用示例
|
||
|
||
### 场景 1:部署 ZIP 包并轮询结果
|
||
|
||
```java
|
||
// 1. 部署 ZIP 包
|
||
MultipartFile zipFile = ...; // 获取 ZIP 文件
|
||
String deployOptionsJson = "{\"rollbackOnError\":true,\"testLevel\":\"RunLocalTests\"}";
|
||
AjaxResult result = deployController.deploy(zipFile, deployOptionsJson);
|
||
String deployId = (String) ((Map) result.get("data")).get("deployId");
|
||
|
||
// 2. 同步轮询直到部署完成
|
||
AjaxResult pollResult = deployController.pollStatus(deployId);
|
||
DeployResultVo deployResult = (DeployResultVo) pollResult.get("data");
|
||
|
||
// 3. 处理结果
|
||
if (deployResult.isSuccess()) {
|
||
System.out.println("部署成功!");
|
||
} else {
|
||
System.out.println("部署失败:" + deployResult.getErrorMessage());
|
||
}
|
||
```
|
||
|
||
### 场景 2:查询部署状态
|
||
|
||
```java
|
||
// 查询部署状态
|
||
String deployId = "0Afxx0000004M5sCAE";
|
||
AjaxResult result = deployController.checkStatus(deployId);
|
||
DeployResultVo deployResult = (DeployResultVo) result.get("data");
|
||
|
||
System.out.println("部署状态:" + deployResult.getStatus());
|
||
System.out.println("已部署组件数:" + deployResult.getNumberComponentsDeployed());
|
||
System.out.println("总组件数:" + deployResult.getNumberComponentsTotal());
|
||
```
|
||
|
||
### 场景 3:取消部署
|
||
|
||
```java
|
||
// 取消部署
|
||
String deployId = "0Afxx0000004M5sCAE";
|
||
AjaxResult result = deployController.cancelDeploy(deployId);
|
||
boolean success = (Boolean) ((Map) result.get("data")).get("success");
|
||
|
||
if (success) {
|
||
System.out.println("取消部署成功!");
|
||
} else {
|
||
System.out.println("取消部署失败!");
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 注意事项
|
||
|
||
1. **文件大小限制**: ZIP 文件大小不能超过 50MB,否则会导致内存溢出。
|
||
|
||
2. **同步轮询超时**: 同步轮询最多持续 5 分钟(60 次,每 5 秒一次),超时后会抛出异常。
|
||
|
||
3. **部署状态**: 部署状态包括 Queued、InProgress、Succeeded、Failed、Canceled,只有 Succeeded、Failed、Canceled 是终态。
|
||
|
||
4. **权限控制**: 所有接口都需要相应的权限,确保用户具有足够的权限才能调用。
|
||
|
||
5. **异步日志**: 部署操作会异步记录到 `datai_metadata_deploy_log` 表,可以通过该表查询部署历史。
|
||
|
||
6. **错误处理**: 所有错误都会转换为 `SalesforceOperationException`,包含详细的错误码和错误信息。
|
||
|
||
---
|
||
|
||
## 相关文档
|
||
|
||
- [需求文档](../requirements/sub/2026-01-28-003-03-部署操作.md)
|
||
- [设计文档](../design/2026-02-03-003-03-部署操作-设计.md)
|
||
- [决策记录](../decisions/2026-02-03-003-03-ADR-通用部署接口设计.md)
|
||
- [变更日志](../changelog/2026-02-06-003-03-changelog.md)
|
||
- [会话记录](../sessions/2026-02-03-003-03-session.md)
|
||
- [复盘文档](../retros/2026-02-06-003-03-retro.md)
|
||
|
||
---
|
||
|
||
## 版本历史
|
||
|
||
| 版本号 | 日期 | 变更内容 | 作者 |
|
||
|--------|------|----------|------|
|
||
| v1.0.0 | 2026-02-06 | 初始版本,实现部署 ZIP 包、同步轮询、状态查询、取消部署功能 | AI Assistant |
|