6.8 KiB
6.8 KiB
ADR-004-06: Tooling API 访问和安全功能技术选型
状态
已接受
日期
2026-02-03
背景
Tooling API 访问和安全功能是 Salesforce Tooling API 集成的重要组成部分,需要设计一个可靠、高效的访问和安全方案。该功能需要满足以下要求:
- 访问控制查询:支持查询访问方法(AccessMethod)、访问资源类型(AccessResourceType)、API 访问级别(APIAccessLevel)、API 类型(APIType)
- 连接器查询:支持查询激活平台连接器类型(ActivationPlatformConnectorType)、激活平台创建类型(ActivationPlatformCreationType)
- 连接管理:复用子需求 004-01 实现的 ToolingConnectionFactory,通过工厂模式获取 ToolingConnection
- 数据库日志记录:所有访问和安全操作都记录到数据库,支持操作审计和故障排查
- 异步日志记录:使用异步方式记录日志,避免影响主操作性能
- 异常处理机制:将 Salesforce 异常转换为自定义异常,提供友好的错误信息
- SOQL 查询构建:使用 SoqlBuilder 构建 SOQL 查询,提高代码可读性和可维护性
- RESTful API 设计:提供标准的 REST API 接口
- 错误码枚举:使用 ToolingAccessSecurityErrorCode 枚举定义错误码
决策
选择方案 1:Service + ToolingConnectionFactory + 异步日志记录 + 自定义异常 + SoqlBuilder + RESTful API,理由如下:
- 复用子需求 004-01 的连接管理功能:ToolingConnectionFactory 已经实现了连接缓存、自动 Session 有效性检查、线程安全等功能,可以直接复用,减少重复代码
- 异步记录操作日志:使用 CompletableFuture 异步记录日志,不影响主操作性能,日志记录失败不影响主操作
- 统一的异常处理:将 Salesforce 异常转换为自定义异常(SalesforceAuthException),使用 ToolingAccessSecurityErrorCode 枚举定义错误码,提供友好的错误信息
- 使用 SoqlBuilder 构建 SOQL 查询:提高代码可读性和可维护性,支持动态添加查询条件,优化查询性能
- 遵循 RESTful API 设计规范:使用 HTTP 方法表示操作类型(GET 用于查询),使用资源路径表示操作对象,统一的响应格式,支持分页查询
- 完整的操作审计:所有操作记录到 datai_tooling_access_security_log 表,支持按操作类型、元数据类型、时间范围等条件查询
- 与项目现有架构保持一致:与子需求 004-01、004-02、004-03、004-04、004-05 的实现方式一致,使用相同的技术栈和设计模式
后果
正面影响
- 开发效率高:复用子需求 004-01 的连接管理功能,避免重复实现连接缓存、Session 有效性检查、线程安全等功能
- 代码复用率高:与子需求 004-01、004-02、004-03、004-04、004-05 共享相同的连接管理、日志记录、异常处理等基础功能
- 维护成本低:使用与子需求 004-01、004-02、004-03、004-04、004-05 相同的技术栈和设计模式,便于统一维护
- 性能优秀:异步日志记录不影响主操作性能,连接缓存机制避免重复创建连接
- 代码可读性高:使用 SoqlBuilder 构建 SOQL 查询,代码清晰易懂
- 易于维护:统一的异常处理、错误码定义、日志记录机制,便于问题定位和故障排查
- 接口清晰:遵循 RESTful API 设计规范,接口清晰易懂,易于集成
- 完整的操作审计:所有操作记录到数据库,支持操作审计和故障排查
负面影响
- 依赖关系:需要依赖子需求 004-01 的 ToolingConnectionFactory,增加了模块间的耦合度
- 异步日志延迟:异步日志记录可能有延迟,不适用于对实时性要求极高的场景
- 线程池管理:需要管理异步日志记录的线程池,增加了系统复杂度
- 数据库写入压力:所有操作都记录到数据库,可能增加数据库写入压力
替代方案
连接管理方案
方案 2:每次调用创建新连接
- 优点:实现简单,无需管理连接缓存
- 缺点:性能较差,每次都要建立新连接,重复代码多,Session 过期处理复杂
- 适用场景:调用频率低的场景
方案 3:自定义工厂模式
- 优点:灵活性高,完全定制化
- 缺点:开发成本高,维护成本高,与项目现有架构不一致
- 适用场景:对连接管理有特殊要求的场景
数据库日志记录方案
方案 2:同步日志记录
- 优点:实现简单,日志记录实时性强
- 缺点:影响主操作性能,日志记录失败可能影响主操作
- 适用场景:对实时性要求高的场景
方案 3:仅记录失败日志
- 优点:减少数据库写入,性能较好
- 缺点:无法完整审计,无法追踪成功操作
- 适用场景:对审计要求不高的场景
方案 4:使用消息队列
- 优点:可靠性高,支持异步处理,可扩展性强
- 缺点:增加系统复杂度,需要额外的消息队列服务
- 适用场景:大规模分布式系统
方案 5:文件日志记录
- 优点:写入性能高,实现简单
- 缺点:不便于查询,不支持统计分析
- 适用场景:对查询要求不高的场景
异常处理方案
方案 2:直接抛出 Salesforce 异常
- 优点:实现简单,保留原始异常信息
- 缺点:错误信息不友好,暴露内部实现细节
- 适用场景:内部系统或调试环境
方案 3:使用通用异常处理
- 优点:实现简单,统一处理
- 缺点:错误信息不够具体,难以定位问题
- 适用场景:简单的应用场景
SOQL 查询构建方案
方案 2:直接拼接 SQL 字符串
- 优点:实现简单,灵活性高
- 缺点:代码可读性差,易于出错,SQL 注入风险
- 适用场景:简单查询场景
方案 3:使用 JPA/Hibernate
- 优点:对象关系映射,自动生成 SQL
- 缺点:不适用于 Salesforce Tooling API,学习成本高
- 适用场景:传统数据库应用
RESTful API 设计方案
方案 2:GraphQL API
- 优点:灵活的查询,减少网络请求,类型安全
- 缺点:学习成本高,不符合项目现有架构
- 适用场景:复杂查询场景
方案 3:RPC API
- 优点:调用简单,性能较好
- 缺点:不符合现代 API 设计,难以集成
- 适用场景:内部系统调用