# 生产端配置同步接口文档 V1 ## 1. 文档目的 本文档基于 `testapi.txt` 的正式协议,说明 Git 直连同步工具如何对接生产侧接口。 当前文档同时覆盖两层内容: 1. 接口协议本身 2. 当前代码如何把 Git 仓库结构映射成接口参数 ## 2. 当前 Git 仓库约定 ### 2.1 Git -> PROD 输入约定 当前实现约定: - `git.repo.scan-branch` 指向当前待同步的版本分支 - **分支名本身就是 `configVersion`** - 分支内目录结构必须为: ```text //<模块内文件相对路径> ``` 示例: ```text R_XXX_V3.0.3_XXX ├─ PEK │ └─ monitor │ ├─ application.yml │ └─ jobs/sync-job.json └─ SHA └─ gate └─ gate-rule.json ``` 映射规则: - `airportId` = 路径第 1 段 - `appName` = 路径第 2 段 - `fileName` = 从第 3 段开始的模块内相对路径 - `configVersion` = 当前 Git 分支名 例如文件: ```text PEK/monitor/jobs/sync-job.json ``` 会被映射为: ```json { "airportId": "PEK", "appName": "monitor", "configVersion": "R_XXX_V3.0.3_XXX", "fileName": "jobs/sync-job.json" } ``` ### 2.2 PROD -> Git 输出约定 当前实现会把 `pullConfig` 返回项按版本分组后落到本地 staging 目录,目录结构同样为: ```text // ``` 之后按动态分支提交到 `git.repo.snapshot-branch/`。 ## 3. 统一接口约定 ### 3.1 编码与格式 - 编码:`UTF-8` - 返回格式:`JSON` - 鉴权:请求头中携带 `token` ### 3.2 成功判定 接口成功时返回: - `code = "0"` - `msg = "ok"` ### 3.3 失败响应格式 ```json { "code": "XXX-00-00-XXX", "data": null, "msg": "errmsg!", "timestamp": "1776735560594" } ``` ## 4. 接口一:推送 Git 配置到生产 ### 4.1 基本信息 - 地址:`http://ip:port/pic_bus_manage_monitor/configSync/pushConfig` - 方法:`POST` - 内容格式:`JSON` - 鉴权:Header 中携带 `token` ### 4.2 请求参数 无 URL 参数。 ### 4.3 请求体 请求体为 JSON 数组,每个数组元素代表一个配置文件: ```json [ { "airportId": "PEK", "appName": "monitor", "configVersion": "R_XXX_V3.0.3_XXX", "configContent": "配置内容", "fileName": "jobs/sync-job.json" } ] ``` 字段说明: | 字段 | 必填 | 说明 | | --- | --- | --- | | `airportId` | 是 | 机场编码,来自 Git 路径第 1 段 | | `appName` | 是 | 模块名,来自 Git 路径第 2 段 | | `configVersion` | 是 | 配置版本号,当前实现取 Git 分支名 | | `configContent` | 是 | 文件内容,当前实现按 UTF-8 文本直接读取 | | `fileName` | 是 | 模块内文件相对路径,不包含 `airportId/appName` 前缀 | ### 4.4 响应体 ```json { "code": "0", "data": { "ackFail": [ { "airportId": "PEK", "appName": "monitor", "configVersion": "R_XXX_V3.0.3_XXX", "fileName": "jobs/sync-job.json" } ] }, "msg": "ok" } ``` 字段说明: - `ackFail`:本次推送失败的配置项列表 - 如果 `ackFail` 为空或不存在,可视为本次推送成功 - 如果 `ackFail` 非空,当前代码直接抛错,视为本次同步失败 ### 4.5 当前实现说明 - 第一次推送走全量 - 后续优先走最小增量 - 如果检测到文件删除,会自动回退到全量推送 - 基线目录按版本分支隔离保存 - `configContent` 当前已统一经过 `ConfigCryptoService` - 默认实现仍为透传,正式加密算法待补 ## 5. 接口二:从生产拉取配置到 Git ### 5.1 基本信息 - 地址:`http://ip:port/pic_bus_manage_monitor/configSync/pullConfig` - 方法:`GET` - 内容格式:`JSON` - 鉴权:Header 中携带 `token` ### 5.2 请求参数 接口协议中的字段如下: ```json { "airportId": "PEK", "appName": "monitor", "configVersion": "R_XXX_V3.0.3_XXX", "fileName": "jobs/sync-job.json", "ackSuc": "1,2", "ackFail": "9" } ``` 说明: - 由于接口是 `GET`,当前实现按 query string 传参 - 当前实现已经支持: - `airportId` 可选过滤 - `appName` 可选过滤 - `ackSuc` 自动回传 - `ackFail` 自动回传 - 当前已经支持: - `configVersion` 可选过滤 - `fileName` 可选过滤 ### 5.3 当前请求行为 当前代码只有在配置了过滤条件时才会发送: - `prod.api.airport-id` - `prod.api.app-name` - `prod.api.pull-config-version` - `prod.api.pull-file-name` 如果这两个配置为空,则不会在请求中携带它们,此时依赖生产端返回所有已审核且未同步的配置。 ### 5.4 响应体 ```json { "code": "0", "data": [ { "id": "1", "airportId": "PEK", "appName": "monitor", "configVersion": "R_XXX_V3.0.3_XXX", "configContent": "配置内容(加密)", "fileName": "jobs/sync-job.json" } ], "msg": "ok" } ``` 字段说明: | 字段 | 说明 | | --- | --- | | `id` | 配置记录标识 | | `airportId` | 机场编码 | | `appName` | 模块名 | | `configVersion` | 配置版本号 | | `configContent` | 配置内容 | | `fileName` | 模块内文件相对路径 | ### 5.5 当前实现说明 - `pullConfig` 返回项会先按 `configVersion` 分组,再分别落盘为 `airportId/appName/fileName` - 如果某组内所有项的 `configVersion` 相同,则该值作为该组的 `sourceVersion` - 如果某组缺少统一版本号,则该组退回为内容哈希作为 `sourceVersion` - `configContent` 当前已统一经过 `ConfigCryptoService`,默认实现仍为透传 - 当本地处理失败时,会把失败项写入 ACK 重试表,并在下次按 `airportId/appName/configVersion/fileName` 定向重拉 ## 6. 接口三:获取 token ### 6.1 基本信息 - 地址:`http://ip:port/pic_bus_manage_monitor/pam-monitor/login` - 方法:`POST` - 内容格式:`JSON` ### 6.2 请求体 ```json { "name": "XXXxx", "password": "" } ``` ### 6.3 响应体 ```json { "code": "0", "data": { "token": "tetttwe", "expireTime": "2026-07-11 11:11:11" }, "msg": "ok" } ``` ### 6.4 当前实现说明 - 如果 `prod.api.token` 已显式配置,则优先使用静态 token - 如果未配置静态 token,则调用 `login` 接口获取 token - token 会按 `expireTime` 做本地缓存 ## 7. 当前代码实现对齐情况 当前接口适配实现: - [ProdConfigApiService.java](e:/AIcoding/FtpTool/src/main/java/com/ftptool/sync/service/ProdConfigApiService.java) 当前已经对齐到以下协议: - `pushConfig` 使用 `POST + JSON 数组` - `pullConfig` 使用 `GET + JSON 响应` - `login` 使用 `POST + JSON` - `ackSuc/ackFail` 已接入请求回传和本地状态更新 - `pushConfig` 参数已按 `airportId/appName/fileName` 目录结构解析 - `pullConfig` 响应已按 `airportId/appName/fileName` 结构恢复到本地目录 当前仍保留的 `TODO`: - 将 `ConfigCryptoService` 的透传实现替换为正式加解密算法 ## 8. 当前配置项说明 建议配置: ```properties prod.api.base-url=https://prod.example.com prod.api.push-path=/pic_bus_manage_monitor/configSync/pushConfig prod.api.pull-path=/pic_bus_manage_monitor/configSync/pullConfig prod.api.login-path=/pic_bus_manage_monitor/pam-monitor/login prod.api.token=replace-me prod.api.token-header-name=token prod.api.airport-id= prod.api.app-name= prod.api.pull-config-version= prod.api.pull-file-name= prod.api.login-name= prod.api.login-password= ``` 说明: - `prod.api.airport-id`、`prod.api.app-name` **不再用于 pushConfig 参数组装** - 它们当前只作为 `pullConfig` 的可选过滤条件 - `prod.api.pull-config-version`、`prod.api.pull-file-name` 可用于精细过滤拉取范围 - 如果希望拉全量已审核数据,建议留空 ## 9. 联调建议 联调时建议优先确认: 1. `token` 请求头名称是否就是 `token` 2. `pullConfig` 的 GET 参数是否按 query string 传递 3. `configVersion/fileName` 过滤规则是否需要尽快接入 4. `configContent` 加密/解密算法何时补齐 5. `fileName` 是否始终是模块内相对路径,而不是包含 `airportId/appName`