Files
starRiverProperty/maven-cw-elevator-application/tools/elevator_api_parity/API-RECONCILIATION.md
T
反编译工作区 e8672a3c7b fix: relocate cwos-portal decompiled output to correct path; remove nested directory
Former-commit-id: dc30d42a8c55ed8b2382a41dc2434233fbed9930
2026-04-29 12:09:48 +08:00

4.6 KiB
Raw Blame History

电梯 HTTP 接口:清单核对、调用一致性、不一致根因

本文把三件事拆开说明,避免与「对拍脚本 bug」混淆。


一、接口清单核对(「有哪些接口」)

来源 产物 / 命令 核对内容
自动化清单 api_catalog.json 43 条:对拍/冒烟用的 idmethodpathfixture/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/imguploadmultipart,未进 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

  • V1http_status 多为 200response_head 形如 {"code":"...", "success":..., ...} → 能解析顶层 code(业务码)。
  • V2(修复前)http_status 500response_head 形如
    {"timestamp":...,"status":500,"error":"Internal Server Error","exception":"java.lang.NullPointerException",...}
    没有顶层 code,对拍里显示为 new=None

3.2 根因(代码链)

  1. AbstractCloudwalkController.getCloudwalkContext() 调用
    CloudwalkCallContextBuilder.buildContext(cloudwalkSessionContextHolder)
  2. CloudwalkCallContextBuilder 第一行:
    CloudwalkSessionObject session = sessionContextHolder.getSession();
    接着 session.getUser() 等;若 session == null → NPE
  3. CloudwalkSessionContextHolder 使用 ThreadLocal;会话对象由 CloudwalkContextParameterFilter(包 cn.cloudwalk.web.filter)在 doFilterInternalputSession(sessionObject) 写入。
  4. Maven V2 启动类原先 未扫描 cn.cloudwalk.web.filter,过滤器 未注册 → 请求线程从未 putSessiongetSession() 恒为 null所有依赖 getCloudwalkContext() 的接口统一 NPE

这与「接口清单不一致」无关,是 运行时上下文未初始化

3.3 修复(应用侧)

ElevatorApplicationscanBasePackages 中增加 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 扫描修复同步维护。