- 正常 pullConfig 请求不再夹带 ackSuc/ackFail,只保留业务过滤参数 - 在本轮生产数据处理完成后,新增一次 ACK-only 的 pullConfig 确认调用 - ACK 确认请求仅回传 ackSuc/ackFail,不再携带 airportId/appName/configVersion/fileName - 保持本地 ackFail 落库与定向重拉机制不变,确认成功后再标记 reported - 更新相关 HTTP/集成测试,并同步 current.md 与 prod-api-v1.md 文档
360 lines
8.5 KiB
Markdown
360 lines
8.5 KiB
Markdown
# 生产端配置同步接口文档 V1
|
||
|
||
## 1. 文档目的
|
||
|
||
本文档基于 `testapi.txt` 的正式协议,说明 Git 直连同步工具如何对接生产侧接口。
|
||
|
||
当前文档同时覆盖两层内容:
|
||
|
||
1. 接口协议本身
|
||
2. 当前代码如何把 Git 仓库结构映射成接口参数
|
||
|
||
## 2. 当前 Git 仓库约定
|
||
|
||
### 2.1 Git -> PROD 输入约定
|
||
|
||
当前实现约定:
|
||
|
||
- 优先使用 `git.repo.scan-branch-pattern` 批量匹配版本分支
|
||
- 如需定向同步单个版本,也可以显式配置 `git.repo.scan-branch`
|
||
- **分支名本身就是 `configVersion`**
|
||
- 分支内目录结构必须为:
|
||
|
||
```text
|
||
<airportId>/<appName>/<模块内文件相对路径>
|
||
```
|
||
|
||
示例:
|
||
|
||
```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
|
||
<airportId>/<appName>/<fileName>
|
||
```
|
||
|
||
之后按动态分支提交到 `git.repo.snapshot-branch/<configVersion>`。
|
||
|
||
## 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` 可选过滤
|
||
- `configVersion` 可选过滤
|
||
- `fileName` 可选过滤
|
||
- ACK 确认请求当前已经支持:
|
||
- `ackSuc` 自动回传
|
||
- `ackFail` 自动回传
|
||
|
||
### 5.3 当前请求行为
|
||
|
||
当前代码发起两类 `pullConfig` 请求:
|
||
|
||
1. 正常拉取请求:
|
||
|
||
- 只有在配置了过滤条件时才会发送:
|
||
- `prod.api.airport-id`
|
||
- `prod.api.app-name`
|
||
- `prod.api.pull-config-version`
|
||
- `prod.api.pull-file-name`
|
||
|
||
如果这些配置为空,则不会在请求中携带它们,此时依赖生产端返回所有已审核且未同步的配置。
|
||
|
||
2. ACK 确认请求:
|
||
|
||
- 在本轮 pull 数据处理完成后额外发起一次
|
||
- 请求只传:
|
||
- `ackSuc`
|
||
- `ackFail`
|
||
- 不再夹带 `airportId/appName/configVersion/fileName` 过滤参数
|
||
|
||
### 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`,默认实现仍为透传
|
||
- pull 结果本地处理完成后,会再补发一次 ACK-only `pullConfig` 请求,只带 `ackSuc/ackFail`
|
||
- 当本地处理失败时,会把失败项写入 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` 已接入 ACK-only 二次确认请求和本地状态更新
|
||
- `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`
|