datai/datai-scenes/datai-scene-salesforce/docs/decisions/adr/0030-document-upload-download.md

11 KiB
Raw Blame History

架构决策记录 - Document 文件上传下载功能

背景

REQ-011-4 需求要求实现 Salesforce Document 对象的文件上传下载功能。Document 是 Salesforce 的传统文档对象(用于存储 Email 模板 Logo、Classic 模式附件等),使用 Partner API (SOAP) 方式进行文件上传下载,最大支持 20-30MB 文件。

与 Attachment 和 ContentDocument/ContentVersion 相比Document 对象具有以下特点:

  • 仅适用于特定遗留功能Email 模板 Logo、Classic 附件)
  • 不支持版本管理(只能覆盖)
  • 存储在 DocumentFolder 中
  • 必填字段FolderId, Name, Body
  • 使用 Partner API (SOAP) 进行操作

面临的问题

  1. API 方式选择: 需要选择合适的 API 方式,考虑 Document 对象的特殊性和官方推荐
  2. 文件编码方式选择: 需要选择合适的文件编码方式,考虑文件大小限制和性能
  3. 架构设计: 需要设计合理的架构,支持多种文件对象类型的上传下载功能
  4. 依赖管理: 需要合理管理依赖关系,确保与现有系统的兼容性

约束条件

  1. 技术栈限制: 必须基于现有的 Spring Boot 3 技术栈
  2. 架构约束: 必须遵循 Authentication.canvas 中定义的架构和调用关系
  3. 模块约束: 必须在 datai-salesforce-integration 模块下实现
  4. 认证约束: 必须使用 SessionManager 进行会话管理和自动重新登录
  5. API约束: 必须使用 Salesforce Partner API (SOAP)
  6. 文件大小约束: 单个文件大小建议不超过 20-30MB
  7. 内存约束: 必须使用流式处理避免内存溢出
  8. 设计模式约束: 必须使用策略模式封装上传下载逻辑

决策

1. API 方式选择

决策: 使用 Partner API (SOAP) 进行文件上传下载

理由:

  • Document 对象的官方推荐 API 方式是 Partner API (SOAP)
  • Document 对象是传统对象,主要使用 SOAP API 进行操作
  • Partner API (SOAP) 提供完整的 CRUD 操作
  • REST API 对 Document 对象的支持有限

实现方案:

  • 使用 PartnerV1Connection 进行 SOAP API 调用
  • 使用 SessionManager 获取 Session ID
  • 使用 Partner API 的 create() 方法创建 Document 对象
  • 使用 Partner API 的 query() 方法查询 Document 对象

2. 文件编码方式选择

决策: 使用 Base64 编码进行文件上传下载

理由:

  • Document 对象的 Body 字段使用 Base64 编码
  • Base64 编码方式简单易实现,兼容性好
  • 20-30MB 文件大小限制适合 Base64 编码方式
  • 与 SOAP API 的实现方式一致

实现方案:

  • 上传时使用 Base64 编码文件内容
  • 下载时使用 Base64 解码文件内容
  • 使用 Java 的 Base64 工具类进行编码解码
  • 使用流式处理避免内存溢出

3. 流式处理决策

决策: 使用流式处理避免内存溢出

理由:

  • Document 对象支持最大 20-30MB 文件,建议使用流式处理
  • 流式处理可以有效控制内存使用
  • 流式处理可以提高大文件上传下载的性能

实现方案:

  • 上传时使用 FileInputStream 读取文件内容
  • 使用 BufferedInputStream 提高性能
  • 使用固定大小的缓冲区(如 8KB
  • 下载时使用 InputStream 读取 Body 字段内容
  • 使用 FileOutputStream 保存文件到本地

4. 架构设计决策

决策: 使用策略模式封装上传下载逻辑

理由:

  • 策略模式可以很好地支持多种文件对象类型的上传下载功能
  • 符合开闭原则,易于扩展新的文件对象类型
  • 代码结构清晰,易于维护
  • 符合单一职责原则

实现方案:

  • 复用 FileUploadStrategy 接口,定义 upload() 方法
  • 复用 FileDownloadStrategy 接口,定义 download() 方法
  • 实现 DocumentUploadStrategy 类,实现 FileUploadStrategy 接口
  • 实现 DocumentDownloadStrategy 类,实现 FileDownloadStrategy 接口
  • 定义 DocumentFileService 接口,封装上传下载逻辑
  • 定义 DocumentFileServiceImpl 实现类,使用策略模式调用上传下载逻辑

5. 依赖管理决策

决策: 依赖 REQ-011-1 的基础设施和 datai-salesforce-integration 模块的 SessionManager、PartnerV1Connection

理由:

  • REQ-011-1 提供了完整的基础设施,包括枚举、异常、参数、验证等
  • SessionManager 提供了会话管理和自动重新登录功能
  • PartnerV1Connection 提供了 SOAP API 调用功能
  • 避免重复造轮子,提高代码复用性

实现方案:

  • 使用 @Autowired 注入 SessionManager
  • 使用 @Autowired 注入 PartnerV1Connection
  • 使用 REQ-011-1 提供的 FileObjectType、FileErrorCode、FileUploadRequest、FileDownloadRequest、FileUploadResponse、FileDownloadResponse、FileValidationUtils

备选方案

方案 1使用 Partner API (SOAP) + Base64 编码(推荐)

优点:

  • Document 对象的官方推荐 API 方式
  • Base64 编码方式简单易实现,兼容性好
  • 20-30MB 文件大小限制适合 Base64 编码方式
  • 与 SOAP API 的实现方式一致

缺点:

  • SOAP 协议复杂,实现难度高
  • Base64 编码会导致文件大小增加约 33%
  • 不支持流式处理,大文件可能导致内存溢出

评估: 推荐使用

方案 2使用 REST API + Base64 编码

优点:

  • REST API 简单易用
  • 实现复杂度低

缺点:

  • REST API 对 Document 对象的支持有限
  • 不符合 Document 对象的官方推荐方式
  • 可能存在功能限制

评估: 不推荐使用

方案 3使用 REST API + Multipart/form-data

优点:

  • Multipart/form-data 方式不需要 Base64 编码,减少内存开销
  • 支持流式处理,避免大文件导致内存溢出

缺点:

  • REST API 对 Document 对象的支持有限
  • 不符合 Document 对象的官方推荐方式
  • 可能存在功能限制

评估: 不推荐使用

影响

对系统架构的影响

  • 新增类: 需要新增 DocumentUploadStrategy、DocumentDownloadStrategy、DocumentFileService、DocumentFileServiceImpl 类
  • 复用接口: 复用 FileUploadStrategy 和 FileDownloadStrategy 接口
  • 复用依赖: 复用 SessionManager 和 PartnerV1Connection

对开发流程的影响

  • 开发复杂度: 需要实现 SOAP API 调用逻辑,开发复杂度较高
  • 测试复杂度: 需要测试大文件上传下载功能,测试复杂度较高

对运维管理的影响

  • 性能监控: 需要监控大文件上传下载的性能
  • 日志要求: 需要记录详细的日志,便于问题排查

风险

技术风险

  1. SOAP API 复杂度风险: SOAP API 复杂度高,实现难度大
    • 缓解措施: 参考官方文档和示例代码,使用成熟的 SOAP 客户端库
  2. 文件大小风险: 大文件上传下载可能导致内存溢出
    • 缓解措施: 使用流式处理,限制文件大小
  3. Base64 编码风险: Base64 编码会导致文件大小增加约 33%
    • 缓解措施: 限制文件大小,建议不超过 20-30MB
  4. API 限流风险: 频繁的 API 调用可能导致 Salesforce API 限流
    • 缓解措施: 实现重试机制,监控 API 调用频率

业务风险

  1. 功能受限风险: Document 功能受限,仅适用于特定场景
    • 缓解措施: 提供迁移方案,建议用户使用 ContentDocument
  2. 兼容性风险: 旧系统可能依赖 Document 对象
    • 缓解措施: 保持 Document 对象的兼容性,提供迁移指南
  3. 弃用风险: Document 可能被 Salesforce 弃用
    • 缓解措施: 提供迁移方案,建议用户使用 ContentDocument

实施风险

  1. 开发风险: 开发过程中可能遇到技术难题
    • 缓解措施: 提前进行技术调研,参考官方文档和示例代码
  2. 测试风险: 测试过程中可能发现性能问题
    • 缓解措施: 提前进行性能测试,优化代码性能

回滚策略

如果决策实施后出现问题,可以采取以下回滚策略:

  1. SOAP API 问题: 如果 SOAP API 调用出现问题,可以:

    • 检查 PartnerV1Connection 的配置和实现
    • 检查 Session ID 的获取和有效性
    • 检查 SOAP 请求的格式和参数
  2. Base64 编码问题: 如果 Base64 编码出现问题,可以:

    • 检查 Base64 编码和解码的实现
    • 检查文件内容的完整性
    • 使用更成熟的 Base64 编码库
  3. 性能问题: 如果大文件上传下载性能不佳,可以:

    • 优化缓冲区大小
    • 使用更高效的流式处理方式
    • 限制文件大小,避免处理超大文件
  4. 功能不满足需求: 如果实现的功能不满足需求,可以:

    • 检查需求文档和实现的一致性
    • 调整实现方案,满足需求
    • 与用户沟通,确认需求的合理性

验收标准

定义验证该决策有效性的具体标准和测试方法:

  1. 功能验收标准:

    • 能够成功上传本地文件到 Salesforce Document 对象
    • 能够成功从 Salesforce Document 对象下载文件到本地
    • 支持指定组织配置 ID
    • 支持指定 FolderId必填
    • 支持指定文件名和 DeveloperName
    • 上传成功返回 Document ID
    • 下载成功返回文件信息
  2. 性能验收标准:

    • 大文件上传下载不影响系统响应
    • 流式处理有效避免内存溢出
    • 20-30MB 文件上传下载性能良好
  3. 代码质量验收标准:

    • 代码符合项目编码规范
    • 使用策略模式封装上传下载逻辑
    • 遵循单一职责原则和开闭原则
    • 通过 IDE 诊断检查,无编译错误或警告
  4. 测试验收标准:

    • 单元测试覆盖率 ≥ 90%
    • 集成测试覆盖所有场景
    • 性能测试验证大文件上传下载性能

视觉锚点

Visual Reference

引用 Canvas 的具体节点或快照:

Status

  • Draft
  • Accepted
  • Superceded

参考资料

列出与该决策相关的参考资料,包括文档、文章或其他资源: