10 KiB
10 KiB
提示词:Apex 连接管理
引用真源
需求描述
根据需求文档,实现 Salesforce Apex API 连接管理功能,包括:
- 连接工厂:创建和管理 SoapConnection 实例
- 会话头管理:设置和更新 SessionHeader
- 调用选项:配置 CallOptions 头部
- 调试头部:配置 DebuggingHeader 用于调试
- 字段截断头:配置 AllowFieldTruncationHeader
- 包版本头:配置 PackageVersionHeader
- 连接缓存:使用 AbstractConnectionFactory 提供的缓存机制
核心要求:
- 固定使用 source org 类型
- 继承 AbstractConnectionFactory
- 集成 SessionManager 获取会话信息
- 提供 RESTful API 接口
设计方案
根据设计文档,采用以下技术方案:
- 模块:
datai-salesforce-apex - 连接工厂:
ApexConnectionFactory继承AbstractConnectionFactory<SoapConnection> - 服务层:
IApexConnectionService接口 +ApexConnectionServiceImpl实现 - 控制器:
ApexConnectionController提供 REST API - 数据模型:DTO 和 VO 类用于请求参数和响应数据
- 异常处理:使用
SalesforceAuthException和SalesforceOperationException - API 版本:Salesforce API 65.0
- 超时配置:连接超时 60 秒,读取超时 60 秒
包结构
com.datai.apex
├── controller
│ └── ApexConnectionController.java
├── service
│ ├── IApexConnectionService.java
│ └── impl
│ └── ApexConnectionServiceImpl.java
├── factory
│ └── ApexConnectionFactory.java
├── model
│ ├── dto
│ │ ├── SetSessionHeaderDto.java
│ │ ├── SetCallOptionsDto.java
│ │ ├── SetDebuggingHeaderDto.java
│ │ ├── SetFieldTruncationHeaderDto.java
│ │ └── SetPackageVersionHeaderDto.java
│ └── vo
│ └── ConnectionInfoVo.java
└── exception
└── ApexConnectionException.java
输出格式要求
必须包含的文件
-
连接工厂:
ApexConnectionFactory.java- 路径:
datai-salesforce-apex/src/main/java/com/datai/apex/factory/ApexConnectionFactory.java - 必须继承
AbstractConnectionFactory<SoapConnection> - 必须实现
createConnection()方法 - 必须实现
getConnectionType()方法,返回 "apex"
- 路径:
-
服务接口:
IApexConnectionService.java- 路径:
datai-salesforce-apex/src/main/java/com/datai/apex/service/IApexConnectionService.java - 定义所有连接管理方法
- 路径:
-
服务实现:
ApexConnectionServiceImpl.java- 路径:
datai-salesforce-apex/src/main/java/com/datai/apex/service/impl/ApexConnectionServiceImpl.java - 实现所有服务方法
- 固定使用 source org 类型
- 路径:
-
控制器:
ApexConnectionController.java- 路径:
datai-salesforce-apex/src/main/java/com/datai/apex/controller/ApexConnectionController.java - 提供 7 个 REST API 接口
- 使用
@Tag注解定义 Swagger 文档 - 使用
@PreAuthorize注解进行权限控制
- 路径:
-
DTO 类:
SetSessionHeaderDto.java- 设置会话头请求参数SetCallOptionsDto.java- 设置调用选项请求参数SetDebuggingHeaderDto.java- 设置调试头部请求参数SetFieldTruncationHeaderDto.java- 设置字段截断头请求参数SetPackageVersionHeaderDto.java- 设置包版本头请求参数- 路径:
datai-salesforce-apex/src/main/java/com/datai/apex/model/dto/ - 使用
@Schema注解定义 Swagger 文档 - 使用
@NotBlank等注解进行参数校验
-
VO 类:
ConnectionInfoVo.java- 连接信息响应- 路径:
datai-salesforce-apex/src/main/java/com/datai/apex/model/vo/ - 使用
@Schema注解定义 Swagger 文档
-
异常类(可选):
ApexConnectionException.java- 路径:
datai-salesforce-apex/src/main/java/com/datai/apex/exception/ApexConnectionException.java - 继承
SalesforceOperationException
- 路径:
REST API 接口列表
-
获取连接
- 方法:GET
- 路径:
/api/apex/connection - 权限:
apex:connection:get - 响应:
ConnectionInfoVo
-
设置会话头
- 方法:POST
- 路径:
/api/apex/connection/session-header - 权限:
apex:connection:session - 请求:
SetSessionHeaderDto
-
设置调用选项
- 方法:POST
- 路径:
/api/apex/connection/call-options - 权限:
apex:connection:call - 请求:
SetCallOptionsDto
-
设置调试头部
- 方法:POST
- 路径:
/api/apex/connection/debugging-header - 权限:
apex:connection:debug - 请求:
SetDebuggingHeaderDto
-
设置字段截断头
- 方法:POST
- 路径:
/api/apex/connection/field-truncation-header - 权限:
apex:connection:truncate - 请求:
SetFieldTruncationHeaderDto
-
设置包版本头
- 方法:POST
- 路径:
/api/apex/connection/package-version-header - 权限:
apex:connection:version - 请求:
SetPackageVersionHeaderDto
-
清除连接缓存
- 方法:DELETE
- 路径:
/api/apex/connection/cache - 权限:
apex:connection:clear
代码规范要求
- 类命名:首字母大写,驼峰命名,如
ApexConnectionController - 方法命名:首字母小写,驼峰命名,如
getConnection - 变量命名:首字母小写,驼峰命名,如
connectionFactory - 常量命名:全大写,下划线分隔,如
ORG_TYPE - 注释规范:
- 类注释:使用
/** */,包含类功能描述、作者、创建时间 - 方法注释:使用
/** */,包含方法功能、参数、返回值、异常描述 - 字段注释:使用
/** */,包含字段功能描述
- 类注释:使用
- 日志规范:使用 Lombok 的
@Slf4j注解,日志级别使用log.info()、log.error()、log.debug() - 异常处理:
- 捕获异常后记录日志
- 抛出
SalesforceAuthException或SalesforceOperationException - 在 Controller 层转换为
ServiceException或AjaxResult
- 代码格式:使用 4 个空格缩进,行宽不超过 120 字符
依赖要求
-
必须导入的类:
com.datai.common.exception.SalesforceAuthExceptioncom.datai.common.exception.SalesforceOperationExceptioncom.datai.common.exception.ServiceExceptioncom.datai.common.core.domain.AjaxResultcom.datai.auth.manager.SessionManagercom.datai.auth.factory.AbstractConnectionFactorycom.sforce.soap.apex.Connectorcom.sforce.soap.apex.SoapConnectioncom.sforce.soap.apex.SessionHeader_elementcom.sforce.soap.apex.CallOptions_elementcom.sforce.soap.apex.DebuggingHeader_elementcom.sforce.soap.apex.LogInfocom.sforce.soap.apex.LogTypecom.sforce.soap.apex.AllowFieldTruncationHeader_elementcom.sforce.soap.apex.PackageVersioncom.sforce.soap.apex.PackageVersionHeader_element
-
Spring 注解:
@RestController@RequestMapping@Autowired@Tag(Swagger)@Operation(Swagger)@PreAuthorize(Spring Security)@Valid@RequestBody@Schema(Swagger)@NotBlank(Validation)
-
Lombok 注解:
@Slf4j@Data@Builder(可选)
测试要求
- 单元测试覆盖率:不低于 80%
- 测试用例场景:
- 正常获取连接成功
- 会话过期时自动重新登录
- 设置会话头成功
- 设置调用选项成功
- 设置调试头部成功
- 清除连接缓存成功
- 连接失败异常处理
- 会话无效异常处理
- 测试框架:使用 JUnit 5 和 Mockito
- 测试用例命名规范:
test+方法名+场景,如testGetConnectionSuccess - 测试数据:使用 Mockito 模拟 SessionManager 和 Salesforce API
实现要点
1. ApexConnectionFactory 实现
@Component
public class ApexConnectionFactory extends AbstractConnectionFactory<SoapConnection> {
@Autowired
private SessionManager sessionManager;
@Override
protected SoapConnection createConnection() throws SalesforceAuthException {
try {
// 获取会话信息
SalesforceLoginResult loginResult = sessionManager.getCurrentLoginResult("source");
String sessionId = loginResult.getSessionId();
String instanceUrl = loginResult.getInstanceUrl();
// 创建连接
ConnectorConfig config = new ConnectorConfig();
config.setSessionId(sessionId);
config.setServiceEndpoint(instanceUrl + "/services/Soap/s/65.0");
config.setConnectionTimeout(60000);
config.setReadTimeout(60000);
return Connector.newConnection(config);
} catch (Exception e) {
throw new SalesforceAuthException("创建 Apex 连接失败: " + e.getMessage(), e);
}
}
@Override
public String getConnectionType() {
return "apex";
}
}
2. 会话有效性检查
private boolean isConnectionValid(SoapConnection connection) {
try {
connection.getUserInfo();
return true;
} catch (Exception e) {
return false;
}
}
3. 固定使用 source org
所有方法中固定使用 "source" 作为 org 类型:
private static final String ORG_TYPE = "source";
// 在方法中使用
SoapConnection connection = apexConnectionFactory.getConnection(ORG_TYPE);
注意事项
- 固定使用 source org:所有方法必须固定使用 source org 类型,不要支持动态 org 类型
- 异常处理:必须正确处理 Salesforce API 的空值情况
- 日志记录:关键操作必须记录日志,包括成功和失败场景
- 权限控制:所有接口必须使用
@PreAuthorize注解进行权限控制 - 参数校验:使用 Bean Validation 进行请求参数校验
- 敏感信息:不在日志中记录完整的 Session ID
- 连接缓存:复用 AbstractConnectionFactory 提供的缓存机制,不要自己实现缓存
- 线程安全:AbstractConnectionFactory 已经保证线程安全,无需额外处理