12 KiB
API 文档:003-03 部署操作
元数据
- 需求编号: 003-03
- 需求名称: 部署操作
- 创建时间: 2026-02-06
- 创建人: AI Assistant
- 版本号: v1.0.0
- 状态: 已完成
API 概述
部署操作 API 提供通用的 ZIP 部署服务,支持字节数组格式的 ZIP 文件部署、同步轮询、状态查询和取消部署功能。该服务与 003-02 的元数据类型定义功能完全解耦,通过通用字节流接口接收 ZIP 数据。
核心功能
- 部署 ZIP 包: 接收 ZIP 文件进行元数据部署
- 同步轮询: 后端轮询直到部署完成(成功或失败)
- 状态查询: 通过 deployId 查询部署状态
- 取消部署: 取消正在进行的部署操作
技术特点
- 通用字节流接口: 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 |
成功示例
{
"code": 200,
"msg": "操作成功",
"data": {
"deployId": "0Afxx0000004M5sCAE"
}
}
失败示例
{
"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 字段说明
| 字段名 | 类型 | 说明 |
|---|---|---|
| changed | boolean | 是否已更改 |
| columnNumber | int | 列号 |
| componentType | String | 组件类型 |
| fileName | String | 文件名 |
| fullName | String | 完整名称 |
| lineNumber | int | 行号 |
| problem | String | 问题描述 |
| success | boolean | 是否成功 |
成功示例
{
"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
}
]
}
}
失败示例
{
"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 字段。
成功示例
{
"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": []
}
}
失败示例
{
"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 | 是否成功取消 |
成功示例
{
"code": 200,
"msg": "操作成功",
"data": {
"success": true
}
}
失败示例
{
"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 包并轮询结果
// 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:查询部署状态
// 查询部署状态
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:取消部署
// 取消部署
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("取消部署失败!");
}
注意事项
-
文件大小限制: ZIP 文件大小不能超过 50MB,否则会导致内存溢出。
-
同步轮询超时: 同步轮询最多持续 5 分钟(60 次,每 5 秒一次),超时后会抛出异常。
-
部署状态: 部署状态包括 Queued、InProgress、Succeeded、Failed、Canceled,只有 Succeeded、Failed、Canceled 是终态。
-
权限控制: 所有接口都需要相应的权限,确保用户具有足够的权限才能调用。
-
异步日志: 部署操作会异步记录到
datai_metadata_deploy_log表,可以通过该表查询部署历史。 -
错误处理: 所有错误都会转换为
SalesforceOperationException,包含详细的错误码和错误信息。
相关文档
版本历史
| 版本号 | 日期 | 变更内容 | 作者 |
|---|---|---|---|
| v1.0.0 | 2026-02-06 | 初始版本,实现部署 ZIP 包、同步轮询、状态查询、取消部署功能 | AI Assistant |