datai/datai-scenes/datai-scene-salesforce/docs/decisions/2026-02-03-004-06-ADR-访问和安全功能技术选型.md

6.8 KiB
Raw Permalink Blame History

ADR-004-06: Tooling API 访问和安全功能技术选型

状态

已接受

日期

2026-02-03

背景

Tooling API 访问和安全功能是 Salesforce Tooling API 集成的重要组成部分,需要设计一个可靠、高效的访问和安全方案。该功能需要满足以下要求:

  1. 访问控制查询支持查询访问方法AccessMethod、访问资源类型AccessResourceType、API 访问级别APIAccessLevel、API 类型APIType
  2. 连接器查询支持查询激活平台连接器类型ActivationPlatformConnectorType、激活平台创建类型ActivationPlatformCreationType
  3. 连接管理:复用子需求 004-01 实现的 ToolingConnectionFactory通过工厂模式获取 ToolingConnection
  4. 数据库日志记录:所有访问和安全操作都记录到数据库,支持操作审计和故障排查
  5. 异步日志记录:使用异步方式记录日志,避免影响主操作性能
  6. 异常处理机制:将 Salesforce 异常转换为自定义异常,提供友好的错误信息
  7. SOQL 查询构建:使用 SoqlBuilder 构建 SOQL 查询,提高代码可读性和可维护性
  8. RESTful API 设计:提供标准的 REST API 接口
  9. 错误码枚举:使用 ToolingAccessSecurityErrorCode 枚举定义错误码

决策

选择方案 1Service + ToolingConnectionFactory + 异步日志记录 + 自定义异常 + SoqlBuilder + RESTful API理由如下

  1. 复用子需求 004-01 的连接管理功能ToolingConnectionFactory 已经实现了连接缓存、自动 Session 有效性检查、线程安全等功能,可以直接复用,减少重复代码
  2. 异步记录操作日志:使用 CompletableFuture 异步记录日志,不影响主操作性能,日志记录失败不影响主操作
  3. 统一的异常处理:将 Salesforce 异常转换为自定义异常SalesforceAuthException使用 ToolingAccessSecurityErrorCode 枚举定义错误码,提供友好的错误信息
  4. 使用 SoqlBuilder 构建 SOQL 查询:提高代码可读性和可维护性,支持动态添加查询条件,优化查询性能
  5. 遵循 RESTful API 设计规范:使用 HTTP 方法表示操作类型GET 用于查询),使用资源路径表示操作对象,统一的响应格式,支持分页查询
  6. 完整的操作审计:所有操作记录到 datai_tooling_access_security_log 表,支持按操作类型、元数据类型、时间范围等条件查询
  7. 与项目现有架构保持一致:与子需求 004-01、004-02、004-03、004-04、004-05 的实现方式一致,使用相同的技术栈和设计模式

后果

正面影响

  1. 开发效率高:复用子需求 004-01 的连接管理功能避免重复实现连接缓存、Session 有效性检查、线程安全等功能
  2. 代码复用率高:与子需求 004-01、004-02、004-03、004-04、004-05 共享相同的连接管理、日志记录、异常处理等基础功能
  3. 维护成本低:使用与子需求 004-01、004-02、004-03、004-04、004-05 相同的技术栈和设计模式,便于统一维护
  4. 性能优秀:异步日志记录不影响主操作性能,连接缓存机制避免重复创建连接
  5. 代码可读性高:使用 SoqlBuilder 构建 SOQL 查询,代码清晰易懂
  6. 易于维护:统一的异常处理、错误码定义、日志记录机制,便于问题定位和故障排查
  7. 接口清晰:遵循 RESTful API 设计规范,接口清晰易懂,易于集成
  8. 完整的操作审计:所有操作记录到数据库,支持操作审计和故障排查

负面影响

  1. 依赖关系:需要依赖子需求 004-01 的 ToolingConnectionFactory增加了模块间的耦合度
  2. 异步日志延迟:异步日志记录可能有延迟,不适用于对实时性要求极高的场景
  3. 线程池管理:需要管理异步日志记录的线程池,增加了系统复杂度
  4. 数据库写入压力:所有操作都记录到数据库,可能增加数据库写入压力

替代方案

连接管理方案

方案 2每次调用创建新连接

  • 优点:实现简单,无需管理连接缓存
  • 缺点性能较差每次都要建立新连接重复代码多Session 过期处理复杂
  • 适用场景:调用频率低的场景

方案 3自定义工厂模式

  • 优点:灵活性高,完全定制化
  • 缺点:开发成本高,维护成本高,与项目现有架构不一致
  • 适用场景:对连接管理有特殊要求的场景

数据库日志记录方案

方案 2同步日志记录

  • 优点:实现简单,日志记录实时性强
  • 缺点:影响主操作性能,日志记录失败可能影响主操作
  • 适用场景:对实时性要求高的场景

方案 3仅记录失败日志

  • 优点:减少数据库写入,性能较好
  • 缺点:无法完整审计,无法追踪成功操作
  • 适用场景:对审计要求不高的场景

方案 4使用消息队列

  • 优点:可靠性高,支持异步处理,可扩展性强
  • 缺点:增加系统复杂度,需要额外的消息队列服务
  • 适用场景:大规模分布式系统

方案 5文件日志记录

  • 优点:写入性能高,实现简单
  • 缺点:不便于查询,不支持统计分析
  • 适用场景:对查询要求不高的场景

异常处理方案

方案 2直接抛出 Salesforce 异常

  • 优点:实现简单,保留原始异常信息
  • 缺点:错误信息不友好,暴露内部实现细节
  • 适用场景:内部系统或调试环境

方案 3使用通用异常处理

  • 优点:实现简单,统一处理
  • 缺点:错误信息不够具体,难以定位问题
  • 适用场景:简单的应用场景

SOQL 查询构建方案

方案 2直接拼接 SQL 字符串

  • 优点:实现简单,灵活性高
  • 缺点代码可读性差易于出错SQL 注入风险
  • 适用场景:简单查询场景

方案 3使用 JPA/Hibernate

  • 优点:对象关系映射,自动生成 SQL
  • 缺点:不适用于 Salesforce Tooling API学习成本高
  • 适用场景:传统数据库应用

RESTful API 设计方案

方案 2GraphQL API

  • 优点:灵活的查询,减少网络请求,类型安全
  • 缺点:学习成本高,不符合项目现有架构
  • 适用场景:复杂查询场景

方案 3RPC API

  • 优点:调用简单,性能较好
  • 缺点:不符合现代 API 设计,难以集成
  • 适用场景:内部系统调用

相关文档