datai/docs/archive/decisions/adr/0029-contentdocument-upload-download.md

231 lines
8.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 架构决策记录 - ContentDocument/ContentVersion 文件上传下载功能
## 背景
REQ-011-3 需求要求实现 Salesforce ContentDocument/ContentVersion 对象的文件上传下载功能。ContentDocument/ContentVersion 是 Salesforce 的现代文件对象(推荐使用),需要使用 REST API + Multipart/form-data 方式进行文件上传下载,最大支持 2GB 文件,使用流式处理避免内存溢出。
与 Attachment 对象相比ContentDocument/ContentVersion 具有以下优势:
- 支持更大的文件(最大 2GB vs 50MB
- 支持版本控制
- 支持多记录关联(通过 ContentDocumentLink
- 使用 Multipart/form-data 方式,不需要 Base64 编码,减少内存开销
## 决策
### 1. 上传方式决策
**决策**: 使用 REST API + Multipart/form-data 方式进行文件上传
**理由**:
- Multipart/form-data 方式不需要 Base64 编码,减少内存开销
- 支持流式处理,避免大文件导致内存溢出
- Salesforce 官方推荐使用 Multipart/form-data 方式上传大文件
- 与 Attachment 的 Base64 编码方式相比,性能更好
**实现方案**:
- 使用 Apache HttpClient 发送 Multipart/form-data 请求
- 使用 InputStream 流式读取文件内容
- 使用 MultipartEntityBuilder 构建 Multipart/form-data 请求
- 设置 Content-Type 为 multipart/form-data
### 2. HTTP 客户端决策
**决策**: 使用 Apache HttpClient 进行 HTTP 调用
**理由**:
- Apache HttpClient 提供完善的 Multipart/form-data 支持
- Apache HttpClient 提供流式处理支持
- Apache HttpClient 是成熟的 HTTP 客户端库,稳定性高
- Apache HttpClient 与 Spring Boot 3 兼容性好
**实现方案**:
- 引入 Apache HttpClient 依赖httpclient 4.5.13、httpmime 4.5.13
- 使用 HttpClient 发送 HTTP 请求
- 使用 MultipartEntityBuilder 构建 Multipart/form-data 请求
- 使用 InputStream 流式处理文件内容
### 3. 流式处理决策
**决策**: 使用流式处理避免内存溢出
**理由**:
- ContentDocument/ContentVersion 支持最大 2GB 文件,不能一次性加载到内存
- 流式处理可以有效控制内存使用
- 流式处理可以提高大文件上传下载的性能
**实现方案**:
- 上传时使用 FileInputStream 读取文件内容
- 下载时使用 InputStream 读取响应内容
- 使用 BufferedInputStream 和 BufferedOutputStream 提高性能
- 使用固定大小的缓冲区(如 8KB
### 4. 架构设计决策
**决策**: 使用策略模式封装上传下载逻辑
**理由**:
- 策略模式可以很好地支持多种文件对象类型的上传下载功能
- 符合开闭原则,易于扩展新的文件对象类型
- 代码结构清晰,易于维护
- 符合单一职责原则
**实现方案**:
- 复用 FileUploadStrategy 接口,定义 upload() 方法
- 复用 FileDownloadStrategy 接口,定义 download() 方法
- 实现 ContentVersionUploadStrategy 类,实现 FileUploadStrategy 接口
- 实现 ContentVersionDownloadStrategy 类,实现 FileDownloadStrategy 接口
- 定义 ContentVersionFileService 接口,封装上传下载逻辑
- 定义 ContentVersionFileServiceImpl 实现类,使用策略模式调用上传下载逻辑
## 备选方案
### 方案 1使用 REST API + Multipart/form-data + Apache HttpClient推荐
**优点**:
- 不需要 Base64 编码,减少内存开销
- 支持流式处理,避免大文件导致内存溢出
- Salesforce 官方推荐使用 Multipart/form-data 方式上传大文件
- Apache HttpClient 提供完善的 Multipart/form-data 支持
**缺点**:
- 需要引入 Apache HttpClient 依赖
- 实现复杂度较高
**评估**: 推荐使用
### 方案 2使用 REST API + Base64 编码
**优点**:
- 实现简单,不需要额外的依赖
- 与 Attachment 的实现方式一致
**缺点**:
- Base64 编码会导致文件大小增加约 33%
- 2GB 的文件在编码后约 2.66GB,可能超过 Salesforce 的限制
- 不支持流式处理,大文件可能导致内存溢出
**评估**: 不推荐使用
### 方案 3使用 Partner API (SOAP)
**优点**:
- Salesforce 官方支持
- 提供完善的 API 文档
**缺点**:
- SOAP 协议复杂,实现难度高
- 不支持流式处理
- 性能不如 REST API
**评估**: 不推荐使用
## 影响
### 对系统架构的影响
- **新增依赖**: 需要在 datai-salesforce-integration 模块引入 Apache HttpClient 依赖
- **新增类**: 需要新增 ContentVersionUploadStrategy、ContentVersionDownloadStrategy、ContentVersionFileService、ContentVersionFileServiceImpl 类
- **复用接口**: 复用 FileUploadStrategy 和 FileDownloadStrategy 接口
### 对开发流程的影响
- **开发复杂度**: 需要实现流式处理逻辑,开发复杂度较高
- **测试复杂度**: 需要测试大文件上传下载功能,测试复杂度较高
### 对运维管理的影响
- **依赖管理**: 需要管理 Apache HttpClient 依赖的版本
- **性能监控**: 需要监控大文件上传下载的性能
## 风险
### 技术风险
- **依赖冲突风险**: Apache HttpClient 依赖可能与其他依赖冲突
- **流式处理风险**: 流式处理实现不当可能导致内存泄漏
- **大文件处理风险**: 2GB 文件上传下载可能导致内存溢出或性能问题
### 业务风险
- **API 限流风险**: 频繁的 API 调用可能导致 Salesforce API 限流
- **认证失效风险**: Access Token 失效可能导致文件上传下载失败
- **网络异常风险**: 网络异常可能导致文件上传下载失败
### 实施风险
- **开发周期风险**: 流式处理实现复杂,可能延长开发周期
- **测试周期风险**: 大文件上传下载测试耗时较长,可能延长测试周期
## 回滚策略
如果决策实施后出现问题,可以采取以下回滚策略:
1. **依赖冲突**: 如果 Apache HttpClient 依赖与其他依赖冲突,可以:
- 调整 Apache HttpClient 的版本
- 使用其他 HTTP 客户端库(如 OkHttp
- 使用 Spring 的 RestTemplate但 RestTemplate 对 Multipart/form-data 支持有限)
2. **流式处理问题**: 如果流式处理实现不当导致内存泄漏,可以:
- 优化流式处理逻辑
- 使用更成熟的流式处理库
- 限制文件大小,避免处理超大文件
3. **性能问题**: 如果大文件上传下载性能不佳,可以:
- 优化缓冲区大小
- 使用多线程上传下载
- 使用断点续传功能
## 验收标准
定义验证该决策有效性的具体标准和测试方法:
1. **功能验收标准**:
- 能够成功上传本地文件到 Salesforce ContentVersion 对象
- 能够成功从 Salesforce ContentVersion 对象下载文件到本地
- 支持指定组织配置 ID
- 支持指定 FirstPublishLocationId可选
- 支持指定文件名Title 和 PathOnClient
- 上传成功返回 ContentVersion ID
- 下载成功返回文件信息
2. **性能验收标准**:
- 大文件上传下载不影响系统响应
- 流式处理有效避免内存溢出
- 2GB 文件上传下载性能良好
3. **代码质量验收标准**:
- 代码符合项目编码规范
- 使用策略模式封装上传下载逻辑
- 遵循单一职责原则和开闭原则
- 通过 SonarQube、Checkstyle、SpotBugs 检查
4. **测试验收标准**:
- 单元测试覆盖率 ≥ 90%
- 集成测试覆盖所有场景
- 性能测试验证大文件上传下载性能
## 视觉锚点
### Visual Reference
引用 Canvas 的具体节点或快照:
- [Authentication.canvas](../../Authentication.canvas) - 相关架构图
- **具体节点**: [集成核心](node_integration_core) - 提供与Salesforce的各种连接方式
- **具体节点**: [SessionManager](node_session_manager_detail) - 会话管理,提供登录服务
### Status
- [x] Draft
- [ ] Accepted
- [ ] Superceded
## 参考资料
列出与该决策相关的参考资料,包括文档、文章或其他资源:
- [REQ-011.md](../requirements/REQ-011.md) - Salesforce文件上传下载功能
- [REQ-011-3.md](../requirements/REQ-011-3.md) - ContentDocument/ContentVersion 文件上传下载功能
- [ContentVersion上传下载.md](../reference-code/data-dump/ContentVersion上传下载.md) - Salesforce ContentVersion 上传实现逻辑
- [大文件上传下载.md](../reference-code/data-dump/大文件上传下载.md) - 大文件上传下载实现逻辑Multipart/form-data
- [0028-attachment-upload-download.md](./0028-attachment-upload-download.md) - Attachment 文件上传下载架构决策