datai/datai-scenes/datai-scene-salesforce/docs/decisions/adr/0014-metadata-api-client.md

418 lines
14 KiB
Markdown
Raw Normal View History

# 架构决策记录 - Metadata API客户端封装
## 背景
REQ-010-5 需要封装 Salesforce Metadata API 客户端,提供 retrieve() 和 deploy() 方法的调用接口支持异步执行、状态轮询、Job ID 获取、Zip 文件下载、部署结果解析、错误处理机制等。
当前项目已经完成了数据库表结构设计、基础实体类和 Mapper 创建、Salesforce 组织配置管理、元数据任务定义管理等功能,现在需要实现 Metadata API 客户端封装,为后续的元数据拉取和部署功能提供基础。
## 决策
### 1. MetadataApiClient 客户端类创建方案
**决策**: 使用 Salesforce WSC (Web Service Connector) 库创建 MetadataApiClient 客户端类,封装 Salesforce Metadata API 调用。
**理由**:
- Salesforce WSC 库是官方推荐的 Java 客户端库,提供了完整的 Metadata API 支持
- WSC 库已经处理了 SOAP 协议的复杂性,简化了 API 调用
- WSC 库支持异步调用和状态轮询,满足业务需求
- WSC 库支持 OAuth 认证,与 SessionManager 集成方便
**实现方案**:
- 使用 Salesforce WSC 库创建 MetadataApiClient 客户端类
- 使用 SessionManager 进行会话管理和自动重新登录
- 使用 WSC 库的 MetadataConnection 类创建连接
- 使用 WSC 库的 RetrieveRequest 和 DeployRequest 类创建请求
- 使用 WSC 库的 AsyncResult 类处理异步结果
### 2. retrieve() 方法实现方案
**决策**: 使用异步线程池执行 retrieve() 方法,使用轮询机制检查任务状态,使用 ZipInputStream 处理 Zip 文件。
**理由**:
- 异步线程池可以避免阻塞主线程,提高系统响应速度
- 轮询机制可以及时获取任务状态,支持超时处理
- ZipInputStream 可以流式处理 Zip 文件,避免内存溢出
- 支持大文件处理,满足业务需求
**实现方案**:
- 使用 Spring 的 @Async 注解实现异步执行
- 使用 ThreadPoolTaskExecutor 配置线程池
- 使用 WSC 库的 checkStatus() 方法检查任务状态
- 使用 ScheduledExecutorService 实现轮询机制
- 使用 ZipInputStream 处理 Zip 文件,使用流式处理避免内存溢出
### 3. deploy() 方法实现方案
**决策**: 使用异步线程池执行 deploy() 方法,使用轮询机制检查任务状态,使用 JSON 解析库处理 API 响应。
**理由**:
- 异步线程池可以避免阻塞主线程,提高系统响应速度
- 轮询机制可以及时获取任务状态,支持超时处理
- JSON 解析库可以灵活处理 API 响应,提取错误信息和代码覆盖率
- 支持多种部署状态,满足业务需求
**实现方案**:
- 使用 Spring 的 @Async 注解实现异步执行
- 使用 ThreadPoolTaskExecutor 配置线程池
- 使用 WSC 库的 checkStatus() 方法检查任务状态
- 使用 ScheduledExecutorService 实现轮询机制
- 使用 Jackson 库处理 API 响应,使用正则表达式提取错误信息
### 4. 状态轮询机制方案
**决策**: 使用定时任务实现轮询机制,使用超时机制防止无限轮询,使用取消机制支持取消轮询。
**理由**:
- 定时任务可以定期检查任务状态,及时获取任务进度
- 超时机制可以防止无限轮询,避免资源浪费
- 取消机制可以支持用户取消任务,提高用户体验
- 轮询频率合理,避免 API 限流
**实现方案**:
- 使用 ScheduledExecutorService 实现定时任务
- 使用 Future 接口支持取消操作
- 使用 TimeoutException 处理超时情况
- 使用指数退避算法调整轮询频率,避免 API 限流
### 5. Zip 文件处理方案
**决策**: 使用 ZipInputStream 处理 Zip 文件,使用流式处理避免内存溢出,支持大文件处理。
**理由**:
- ZipInputStream 是 Java 标准库的一部分,无需引入额外依赖
- ZipInputStream 支持流式处理,可以逐个文件处理,避免内存溢出
- 支持大文件处理,满足业务需求
- 内存使用合理,不会因为文件过大导致内存溢出
**实现方案**:
- 使用 ZipInputStream 处理 Zip 文件
- 使用 BufferedInputStream 提高读取性能
- 使用 ByteArrayOutputStream 临时存储文件内容
- 使用 FileOutputStream 保存文件到磁盘
### 6. 部署结果解析方案
**决策**: 使用 Jackson 库处理 API 响应,使用正则表达式提取错误信息和代码覆盖率。
**理由**:
- Jackson 库是 Java 标准的 JSON 解析库,性能高,功能强大
- 正则表达式可以灵活提取错误信息和代码覆盖率
- 支持多种部署状态,满足业务需求
- 错误信息详细,方便用户排查问题
**实现方案**:
- 使用 Jackson 库的 ObjectMapper 类处理 API 响应
- 使用 JsonNode 类遍历 JSON 数据
- 使用 Pattern 和 Matcher 类提取错误信息和代码覆盖率
- 使用自定义异常类处理部署错误
### 7. 错误处理机制方案
**决策**: 使用统一的异常处理机制,使用重试机制处理网络异常,使用日志记录机制记录错误信息。
**理由**:
- 统一的异常处理机制可以简化代码,提高代码质量
- 重试机制可以处理网络异常,提高系统稳定性
- 日志记录机制可以记录错误信息,方便排查问题
- 支持多种异常类型,满足业务需求
**实现方案**:
- 使用自定义异常类封装 API 调用异常
- 使用 @Retryable 注解实现重试机制
- 使用 Slf4j 记录错误信息
- 使用 GlobalExceptionHandler 统一处理异常
## 备选方案
### 1. MetadataApiClient 客户端类创建备选方案
**备选方案 1**: 使用 Salesforce REST API 创建 MetadataApiClient 客户端类
**优点**:
- REST API 是轻量级的,易于使用
- 不需要引入额外的依赖
**缺点**:
- REST API 功能有限,不支持所有 Metadata API 功能
- 需要手动处理 SOAP 协议,开发成本高
- 不支持异步调用和状态轮询
**备选方案 2**: 使用第三方库创建 MetadataApiClient 客户端类
**优点**:
- 第三方库可能提供更友好的 API
- 可能提供额外的功能
**缺点**:
- 第三方库可能不稳定,维护成本高
- 第三方库可能不支持所有 Metadata API 功能
- 第三方库可能不兼容 WSC 库
### 2. retrieve() 方法实现备选方案
**备选方案 1**: 使用同步方式实现 retrieve() 方法
**优点**:
- 实现简单,不需要处理异步逻辑
- 代码易于理解和维护
**缺点**:
- 同步方式会阻塞主线程,影响系统响应速度
- 不支持超时处理和取消操作
**备选方案 2**: 使用消息队列实现 retrieve() 方法
**优点**:
- 消息队列可以解耦任务提交和任务执行
- 支持任务持久化和重试
**缺点**:
- 消息队列增加了系统复杂度
- 需要引入额外的依赖
### 3. deploy() 方法实现备选方案
**备选方案 1**: 使用同步方式实现 deploy() 方法
**优点**:
- 实现简单,不需要处理异步逻辑
- 代码易于理解和维护
**缺点**:
- 同步方式会阻塞主线程,影响系统响应速度
- 不支持超时处理和取消操作
**备选方案 2**: 使用消息队列实现 deploy() 方法
**优点**:
- 消息队列可以解耦任务提交和任务执行
- 支持任务持久化和重试
**缺点**:
- 消息队列增加了系统复杂度
- 需要引入额外的依赖
### 4. 状态轮询机制备选方案
**备选方案 1**: 使用回调机制实现状态轮询
**优点**:
- 回调机制可以及时获取任务状态
- 不需要定时任务,实现简单
**缺点**:
- Salesforce Metadata API 不支持回调机制
- 需要使用 Webhook增加系统复杂度
**备选方案 2**: 使用 WebSocket 实现状态轮询
**优点**:
- WebSocket 可以实时推送任务状态
- 用户体验好
**缺点**:
- WebSocket 增加了系统复杂度
- 需要引入额外的依赖
### 5. Zip 文件处理备选方案
**备选方案 1**: 使用 ZipFile 类处理 Zip 文件
**优点**:
- ZipFile 类提供了随机访问功能
- 可以直接读取 Zip 文件中的文件
**缺点**:
- ZipFile 类需要将整个 Zip 文件加载到内存,可能导致内存溢出
- 不支持大文件处理
**备选方案 2**: 使用第三方库处理 Zip 文件
**优点**:
- 第三方库可能提供更好的性能
- 可能提供额外的功能
**缺点**:
- 第三方库增加了依赖
- 可能不稳定
### 6. 部署结果解析备选方案
**备选方案 1**: 使用 XML 解析库处理 API 响应
**优点**:
- XML 解析库可以处理 XML 格式的 API 响应
**缺点**:
- XML 解析库增加了依赖
- XML 解析比 JSON 解析慢
**备选方案 2**: 使用字符串处理提取错误信息和代码覆盖率
**优点**:
- 字符串处理不需要引入额外的依赖
- 实现简单
**缺点**:
- 字符串处理容易出错,维护成本高
- 不支持复杂的提取逻辑
### 7. 错误处理机制备选方案
**备选方案 1**: 使用 try-catch 处理异常
**优点**:
- try-catch 是 Java 标准的异常处理机制
- 实现简单
**缺点**:
- try-catch 需要在每个方法中重复编写,代码冗余
- 不支持重试机制
**备选方案 2**: 使用 AOP 实现异常处理
**优点**:
- AOP 可以统一处理异常,减少代码冗余
- 支持切面编程,灵活度高
**缺点**:
- AOP 增加了系统复杂度
- 需要引入额外的依赖
## 影响
### 系统架构影响
- 新增 MetadataApiClient 客户端类,封装 Salesforce Metadata API 调用
- 新增异步线程池,支持异步执行
- 新增状态轮询机制,支持任务状态查询
- 新增 Zip 文件处理功能,支持大文件处理
- 新增部署结果解析功能,支持错误信息和代码覆盖率提取
- 新增错误处理机制,支持异常处理和重试
### 开发流程影响
- 需要引入 Salesforce WSC 库依赖
- 需要配置异步线程池
- 需要编写单元测试和集成测试
- 需要编写使用文档
### 运维管理影响
- 需要监控异步线程池的使用情况
- 需要监控状态轮询的频率
- 需要监控 Zip 文件处理的性能
- 需要监控 API 调用的成功率
## 风险
### 技术风险
- **WSC 库版本兼容性风险**: WSC 库版本可能与项目其他依赖不兼容
- **异步执行风险**: 异步执行机制复杂可能导致状态管理困难
- **状态轮询风险**: 状态轮询频率不当可能导致 API 限流
- **Zip 文件处理风险**: Zip 文件处理不当可能导致内存溢出
- **错误处理风险**: 错误处理不完善可能导致任务失败无法恢复
### 业务风险
- **API 调用失败风险**: API 调用失败可能导致元数据拉取和部署失败
- **任务状态不一致风险**: 任务状态不一致可能导致用户困惑
- **数据丢失风险**: Zip 文件处理失败可能导致数据丢失
- **部署失败风险**: 部署失败可能导致系统不可用
### 实施风险
- **开发时间风险**: 开发时间可能超出预期
- **测试时间风险**: 测试时间可能超出预期
- **上线时间风险**: 上线时间可能超出预期
## 回滚策略
如果决策实施后出现问题,可以采取以下回滚策略:
1. **回滚 WSC 库版本**: 如果 WSC 库版本兼容性问题,可以回滚到之前的版本
2. **禁用异步执行**: 如果异步执行机制有问题,可以禁用异步执行,使用同步方式
3. **调整轮询频率**: 如果状态轮询频率有问题,可以调整轮询频率
4. **禁用 Zip 文件处理**: 如果 Zip 文件处理有问题,可以禁用 Zip 文件处理,使用其他方式
5. **简化错误处理**: 如果错误处理机制有问题,可以简化错误处理,使用 try-catch
## 验收标准
定义验证该决策有效性的具体标准和测试方法:
1. **MetadataApiClient 客户端类创建验收标准**:
- MetadataApiClient 创建成功
- 使用 Salesforce WSC 库成功
- 与 SessionManager 集成成功
- 代码符合项目编码规范
2. **retrieve() 方法实现验收标准**:
- retrieve() 方法调用成功
- 支持异步执行
- 支持 Job ID 获取
- 支持状态轮询
- 支持 Zip 文件下载
- 错误处理机制正常工作
3. **deploy() 方法实现验收标准**:
- deploy() 方法调用成功
- 支持异步执行
- 支持 Job ID 获取
- 支持状态轮询
- 支持部署结果解析
- 错误处理机制正常工作
4. **状态轮询机制验收标准**:
- 状态轮询机制正常工作
- 轮询频率合理
- 支持超时处理
- 支持取消轮询
5. **Zip 文件处理验收标准**:
- Zip 文件下载成功
- Zip 文件解压成功
- 支持大文件处理
- 内存使用合理
6. **部署结果解析验收标准**:
- 部署结果解析成功
- 错误信息提取正确
- 代码覆盖率提取正确
- 支持多种部署状态
7. **错误处理机制验收标准**:
- 错误处理机制正常工作
- 支持多种异常类型
- 错误信息详细
- 支持错误重试
## 视觉锚点
### Visual Reference
引用 Canvas 的具体节点或快照:
- [Authentication.canvas](../../Authentication.canvas) - 项目架构视觉化展示
- **相关节点**: [集成核心](node_integration_core) - 提供与Salesforce的各种连接方式
- **相关节点**: [SessionManager](node_session_manager_detail) - 会话管理,提供登录服务
### Status
- [x] Draft
- [ ] Accepted
- [ ] Superceded
## 参考资料
列出与该决策相关的参考资料,包括文档、文章或其他资源:
- [REQ-010-5.md](../requirements/REQ-010-5.md) - Metadata API客户端封装需求文档
- [REQ-010-1.md](../requirements/REQ-010-1.md) - 数据库表结构设计和创建
- [REQ-010-2.md](../requirements/REQ-010-2.md) - 基础实体类和Mapper创建
- [REQ-010-3.md](../requirements/REQ-010-3.md) - Salesforce组织配置管理
- [REQ-010-4.md](../requirements/REQ-010-4.md) - 元数据任务定义管理
- [Salesforce Metadata API Developer Guide](https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/) - Salesforce Metadata API 官方文档
- [Salesforce WSC (Web Service Connector)](https://github.com/forcedotcom/wsc) - Salesforce WSC 库 GitHub 仓库
- [Spring Async Documentation](https://docs.spring.io/spring-framework/docs/current/reference/html/integration.html#scheduling-annotation-support-async) - Spring 异步支持文档