mirror of
https://github.com/hpd840321/starRiverProperty.git
synced 2026-06-10 00:40:30 +08:00
7b2bd307f1
- backend/: 13 Maven modules (cw-elevator-application, cloudwalk-cloud, intelligent-cwoscomponent, ninca-crk, etc.) - frontend/: 4 Vue projects (elevator-front, cwos-portal, alarm-front, front_acs) + decompiled + scripts - scripts/: build, test-env, tools (Docker Compose, service templates, API parity) - docs/: AGENTS.md, superpowers specs, architecture docs - .gitignore: standard Java/Maven exclusions Moved from legacy maven-*/ root layout to backend/ organized structure.
4.6 KiB
4.6 KiB
电梯 HTTP 接口:清单核对、调用一致性、不一致根因
本文把三件事拆开说明,避免与「对拍脚本 bug」混淆。
一、接口清单核对(「有哪些接口」)
| 来源 | 产物 / 命令 | 核对内容 |
|---|---|---|
| 自动化清单 | api_catalog.json |
43 条:对拍/冒烟用的 id、method、path、fixture/body。 |
| 代码事实 | python3 report/build_backend_api_inventory.py --out report/BACKEND-API-INVENTORY.md |
扫描 cw-elevator-application-web/**Controller.java,与 catalog 对照。 |
| 结论 | 当前仓库生成结果 | catalog 与 Controller 声明路径 一致;额外仅有 POST /file/imgupload(multipart,未进 JSON catalog)。 |
清单层面:V1 与 V2 共用同一套 Controller 源码与同一 catalog,不存在「V2 少注册了一批路径」这类清单差异。
二、接口调用是否一致(「测试怎么打」)
对拍/冒烟使用 同一份 Python 逻辑(parity/client.py):
- 方法:catalog 中的
method(均为POST)。 - 路径:同一
path分别拼在--base-old与--base-new后。 - 请求体:同一
fixture或内联body。 - 请求头:
default_headers()(Content-Type: application/json+ 环境变量ELEVATOR_HEADER_*可选)。
因此:从测试工具角度,对 V1、V2 的 HTTP 调用是同一套;若一端返回 Cloudwalk JSON、另一端返回 Spring Boot 500 错误 JSON,属于 服务端行为差异,不是「调用了不同接口」。
三、不一致的表现与根因(「为什么 V2 全是 new=None / 500」)
3.1 现象(如何读冒烟 JSON)
- V1:
http_status多为 200,response_head形如{"code":"...", "success":..., ...}→ 能解析顶层code(业务码)。 - V2(修复前):
http_status500,response_head形如
{"timestamp":...,"status":500,"error":"Internal Server Error","exception":"java.lang.NullPointerException",...}
→ 没有顶层code,对拍里显示为new=None。
3.2 根因(代码链)
AbstractCloudwalkController.getCloudwalkContext()调用
CloudwalkCallContextBuilder.buildContext(cloudwalkSessionContextHolder)。CloudwalkCallContextBuilder第一行:
CloudwalkSessionObject session = sessionContextHolder.getSession();
接着session.getUser()等;若session == null→ NPE。CloudwalkSessionContextHolder使用 ThreadLocal;会话对象由CloudwalkContextParameterFilter(包cn.cloudwalk.web.filter)在doFilterInternal里putSession(sessionObject)写入。- Maven V2 启动类原先 未扫描
cn.cloudwalk.web.filter,过滤器 未注册 → 请求线程从未putSession→getSession()恒为 null → 所有依赖getCloudwalkContext()的接口统一 NPE。
这与「接口清单不一致」无关,是 运行时上下文未初始化。
3.3 修复(应用侧)
在 ElevatorApplication 的 scanBasePackages 中增加 cn.cloudwalk.web.filter,使 CloudwalkContextParameterFilter 成为 Spring Bean 并参与 Filter 链。
注意:不要整包扫描 cn.cloudwalk.web(会带入 LocaleConfiguration 再声明一个 CloudwalkSessionContextHolder Bean,与 CloudwalkSessionHolderConfiguration 冲突);只扫描 cn.cloudwalk.web.filter 即可。
修复后应重新构建 V2 JAR,再跑:
./scripts/run_full_elevator_api_suite.sh
预期:V2 的 http_status 回到与 V1 同类的业务响应(多为 200 + Cloudwalk code),对拍 new=None 应消失或仅剩真实业务差异。
四、核对清单速查表
| 步骤 | 做什么 |
|---|---|
| 0 | V1/V2 电梯业务源码比对(仅白名单文件、忽略空白):docs/architecture/V1-V2-电梯API源码比对白名单.md;依赖比对(lib/cw_lib vs 反应堆):docs/architecture/V1-V2-电梯依赖比对.md。 |
| 1 | 跑 build_backend_api_inventory.py,打开 BACKEND-API-INVENTORY.md,确认 §3 无遗漏 path。 |
| 2 | 跑全量冒烟,打开 smoke-v1_*.json / smoke-v2_*.json,逐条对比 http_status + response_head 前缀(是否均为 {"code":)。 |
| 3 | 若 V2 仍为 500,在 V2 日志中搜 NullPointerException 与具体 path,确认是否还有 其它 未注册的 Filter/Interceptor。 |
文档与 ElevatorApplication 扫描修复同步维护。