# 架构决策记录 - 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 异步支持文档