关于 ARAN Agent SDK 模块化重构的设计思考与实践

1. 前言

ARAN Agent SDK 的核心目标,是为业务系统提供一套稳定的小区问题推送、问题反馈、决策方案反馈调用能力。若 SDK 直接把接口文档模型、Spring Boot 自动配置、内部参数查询、小区属性补全、MyBatis Mapper、HTTP 重试等能力全部揉在一起,短期看使用方便,长期则容易形成依赖污染和职责混杂。

本项目的重构思路比较明确:将 SDK 拆分为 coreadapter 两层。

  • mtex-aran-agent-core:只表达 ARAN Agent 接口文档契约,提供原生同步客户端、请求/响应模型、最小校验和 JDK HTTP 默认实现。

  • mtex-aran-agent-adapter:面向内部业务系统,基于 core 封装 Spring Boot 自动配置、业务模型转换、小区参数补全、邻区数量统计、RestTemplate 执行器和重试策略。

fig1-pre-refactor-coupling.png

图1 重构前的耦合状态

2. 问题与目标

这次拆分本质上解决的是“协议能力”和“业务适配能力”的边界问题。

协议能力应当稳定、轻量、可脱离框架运行;业务适配能力则天然依赖内部环境,例如配置中心、公共参数服务、MyBatis、Spring Bean 生命周期等。若二者放在同一模块内,非 Spring 场景会被迫感知无关依赖,内部业务系统也难以清晰判断哪些模型是外部接口契约,哪些模型只是本地适配。

因此项目目标可以概括为三点:

1. core 保持纯粹:只对齐接口文档,承担序列化、反序列化、HTTP POST 和必填校验。

2. adapter 承担增强:对内部业务模型进行转换,并在必要时补齐小区属性、参数、邻区数量等上下文。

3. 依赖边界显式化:Spring、MyBatis、公共参数服务放在 adapter,并以 provided 或 optional 方式引入。

图2 core / adapter 分层结构

3. 设计及实现

核心层的入口是 AranAgentCoreClient,它暴露三个方法:`pushCellIssue`、`feedbackCellIssue`、`feedbackCellIssuePlan`。调用前先执行请求模型的 validate(),再由 JsonHttpExecutor 发送 JSON 请求,并将响应反序列化为 ApiResponse

这里的设计取舍比较克制:HTTP 执行能力被抽象为 JsonHttpExecutor,默认实现是 JDK8 HttpURLConnection。这使 core 模块既能开箱即用,也允许 adapter 或业务方替换为 RestTemplate、OkHttp 等实现。

adapter 层的关键入口是 AranAgentAdapterService,它围绕 ARAN Agent 的三个业务动作提供适配能力:

1. 小区问题推送:`pushCellIssue`

2. 小区问题反馈:`feedbackCellIssue`

3. 小区问题决策方案反馈:`feedbackCellIssuePlan`

图3.1 三个业务动作与推送双入口

其中,小区问题推送是最复杂的场景,因此 adapter 在该动作下提供了两类输入方式。

第一类是完整上下文推送请求,即 EnrichedIssuePushRequest。调用方已经显式提供 ARAN Agent 接口所需的小区属性、厂家、频段、带宽、发射功率、邻区数量等字段,adapter 只负责将内部业务模型转换为 core 层的 CellIssuePushApiRequest,然后调用 AranAgentCoreClient

第二类是基础问题推送请求,即 IssuePushRequest。调用方只提供 orderId、`cgi`、`issueId`、`issueType`、`time`、`scene`、`ind`、`cogMethods` 等问题基础信息,adapter 会根据 CGI 查询 LTE/NR 小区属性,再通过公共参数服务查询小区参数,并统计邻区数量,最终组装为 EnrichedIssuePushRequest 后复用第一类推送流程。

图3.2 基础问题推送的补全流程

问题反馈和决策方案反馈相对简单,主要职责是完成内部模型到 core 文档模型的转换。例如 feedbackCellIssueIssueFeedbackRequest 转换为 CellIssueFeedbackApiRequest,`feedbackCellIssuePlan` 将 PlanFeedbackRequest 转换为 PlanFeedbackApiRequest,再统一交由 AranAgentCoreClient 执行 HTTP 调用。

参数查询部分采用了 provider 路由机制。`DefaultAranAgentParamQueryManager` 内部维护一条 Predicate<ParamQueryRouterKey> -> AranAgentParamQueryProvider 的路由链,根据网络制式、厂家、频段、是否 3D MIMO 等信息选择不同 Provider,例如华为 LTE、中兴 FDD、中兴 TDD、NR 等场景。这种设计与简单的 if-else 分派相比,更适合后续扩展新的厂家或网络类型。

Spring Boot 自动配置集中在 AranAgentAdapterAutoConfiguration:当配置了 aran-agent.cell-issue-push-url、`cell-issue-feedback-url`、`cell-issue-scheme-feedback-url` 后,自动注册 RestTemplate、`JsonHttpExecutor`、`AranAgentCoreClient` 和 AranAgentAdapterService。若运行环境存在公共参数服务相关 Bean,则额外注册默认参数查询管理器。

HTTP 重试没有放在 core,而是落在 adapter 的 RestTemplateJsonHttpExecutor 中。它对连接异常、超时、未知主机等可重试异常执行退避重试,同时复用 core 的 JsonHttpExecutor 抽象。这一点比较符合职责划分:重试策略是内部运行环境的可靠性增强,而不是 ARAN Agent 协议本身的一部分。

4. 小结

本项目的核心价值不在于“多封装了一层客户端”,而在于把 SDK 中不同稳定性的能力拆开了。

core 解决协议对接问题,稳定、轻量、低依赖;`adapter` 解决内部业务落地问题,负责 Spring 集成、模型转换、参数补全和重试。这样的结构符合 KISS 和 SRP:协议层不感知业务上下文,业务层也不直接散落接口文档字段拼装逻辑。

对外看,SDK 提供小区问题推送、问题反馈、决策方案反馈三个业务动作;对内看,推送动作由于上下文装配复杂,又进一步区分为完整上下文推送请求和基础问题推送请求两种输入方式。这个层次划分能够同时兼顾简单接入和内部业务增强。

Comment