diff --git a/src/main/java/com/yunhai/notice/service/flow/NoticeFlowProperties.java b/src/main/java/com/yunhai/notice/service/flow/NoticeFlowProperties.java index 0e7d2d3..d8153f9 100644 --- a/src/main/java/com/yunhai/notice/service/flow/NoticeFlowProperties.java +++ b/src/main/java/com/yunhai/notice/service/flow/NoticeFlowProperties.java @@ -31,8 +31,10 @@ public class NoticeFlowProperties { /** * 回调路径:挂在开放接口域下,由平台应用验签(/oapi/* 强制)保护,不再有独立回调过滤器。 + * 取 starter 默认形态 /oapi/flow/callback——网关契约 /{target}/oapi/** 的首段已由 target + * 承担,端点内不再带应用名前缀(2026-09-24 由 /oapi/notice/flow/callback 收敛)。 */ - private String callbackPath = "/oapi/notice/flow/callback"; + private String callbackPath = "/oapi/flow/callback"; /** * 本服务部署 context-path(可选,无则空):注册时随 basePath 一并申报给 flow-center, diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index c61187b..bcc6fad 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -59,9 +59,10 @@ notice: # (构造期 fail-fast),不静默打 localhost。 # 本应用对外可达基址(flow-center 回调探活/事件推送打这里;本地=后端直连端口) callback-base: http://localhost:8101 - # 回调端点:必须与 OapiFlowCallbackController 映射一致(/callback/* 已随 X-Flw-* 过滤器下线, - # 旧值会让本地注册的回调地址 404)。不变式由 NoticeFlowCallbackConfigContractTest 冻结。 - callback-path: /oapi/notice/flow/callback + # 回调端点:网关契约 /{target}/oapi/** 的首段已由 target 承担,端点不再带应用名前缀(2026-09-24 + # 由 /oapi/notice/flow/callback 收敛为 starter 默认值);必须与 yh.flow-callback.path 一致, + # 否则 flow-center 探活/推送 404。不变式由 NoticeFlowCallbackConfigContractTest 冻结。 + callback-path: /oapi/flow/callback # Notice 前端基址(apply bizUrl 拼接,审批人点击跳回通知详情) front-base-url: http://localhost:8077 # 短信到点补发调度(§3.2 修 BP-R5-2):fixedDelay 5min,扫"已发布+要短信+未发过+已到点" @@ -105,10 +106,17 @@ yh: flow-callback: # 流程中心回调接收端 starter(2026-09-20 迁移):端点/幂等/乱序门由 starter 承担, # 业务映射见 NoticeFlowCallbackHandler;验签仍由上方 /oapi/* 平台强制验签负责(X-Flw 不启用) - path: /oapi/notice/flow/callback + # path 取 starter 默认值 /oapi/flow/callback(2026-09-24 由 /oapi/notice/flow/callback 收敛) + path: /oapi/flow/callback biz-types: [notice] - # 注册用回调地址=对外基址+端点路径(占位符组合,防两处配置漂移;base-path 本地无 context-path 不填) - callback-url: ${notice.flow.callback-base}${yh.flow-callback.path} + # 漂移自动核对(2026-09-24 开):端点路径/ctx/base-path 变更后,镜像行有效但登记 URL 与当前 + # 期望不一致时自动重新注册,替代"删镜像行→重新保存绑定"的手工恢复路径。注意重注册会轮换 secret。 + reconcile-on-register: true + # 注册地址不再显式配置(2026-09-24 摘除 callback-url):由 starter 推导 + # (open-host ?: yh.open.base-host) + /{target ?: base-path} + path + # ⇒ 生产 = http://open-gateway-service:10013 + /notice + /oapi/flow/callback + # base-path 本地无 context-path 不填(生产由 projman 注入 /notice)。改地址回滚:把全地址写回 + # callback-url 即可(回滚绳),无需回滚镜像。 open: # 四域服务目录零配置:userbase/userclass/usermsg/flowcenter 枚举兜底 = base-host + 默认 ctx base-host: http://base.yunhaixingtong.com diff --git a/src/test/java/com/yunhai/notice/flow/FlowCallbackTransientIT.java b/src/test/java/com/yunhai/notice/flow/FlowCallbackTransientIT.java index 6bedacf..59230bc 100644 --- a/src/test/java/com/yunhai/notice/flow/FlowCallbackTransientIT.java +++ b/src/test/java/com/yunhai/notice/flow/FlowCallbackTransientIT.java @@ -105,7 +105,7 @@ class FlowCallbackTransientIT { // 回调端点挂在 /oapi/* 下:以推送方 flow-center(100019)身份带应用签名投递 return new com.yunhai.notice.support.OapiSignedClient( "http://localhost:" + port, "100019", "flow-center-dev-secret-100019") - .post("/oapi/notice/flow/callback", body, String.class); + .post("/oapi/flow/callback", body, String.class); } private static String uuid() { diff --git a/src/test/java/com/yunhai/notice/flow/NoticeFlowApiIT.java b/src/test/java/com/yunhai/notice/flow/NoticeFlowApiIT.java index 68de39d..c97cc8e 100644 --- a/src/test/java/com/yunhai/notice/flow/NoticeFlowApiIT.java +++ b/src/test/java/com/yunhai/notice/flow/NoticeFlowApiIT.java @@ -25,7 +25,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; /** * Notice 流程接缝 IT(T2.1/T2.3/T2.5,RANDOM_PORT 真实过滤链 + bsch_notice_test): - * ① 回调端点 /oapi/notice/flow/callback 的应用验签(复用平台能力):以 flow-center 身份 + * ① 回调端点 /oapi/flow/callback 的应用验签(复用平台能力):以 flow-center 身份 * (appKey=100019,密钥取 trusted-apps)合法签名 200 推进状态 / 坏签名 401 / 匿名 401 / * 毒 body(缺字段)200 / ping 200 / 重复 eventId 幂等; * ② /oapi/notice/getDict 提供方三态(匿名 401 / 合法签名 200 / 错误密钥 401); @@ -42,7 +42,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; class NoticeFlowApiIT { /** 回调端点(开放接口域;验签由 yh.app-auth enforce-patterns=/oapi/* 强制) */ - private static final String CALLBACK_PATH = "/oapi/notice/flow/callback"; + private static final String CALLBACK_PATH = "/oapi/flow/callback"; /** 推送方身份:flow-center 的 appKey/secret(Notice trusted-apps 白名单) */ private static final String FLOW_APP_KEY = "100019"; private static final String FLOW_APP_SECRET = "flow-center-dev-secret-100019"; diff --git a/src/test/java/com/yunhai/notice/service/flow/FlowCenterClientTest.java b/src/test/java/com/yunhai/notice/service/flow/FlowCenterClientTest.java index d55d445..952270f 100644 --- a/src/test/java/com/yunhai/notice/service/flow/FlowCenterClientTest.java +++ b/src/test/java/com/yunhai/notice/service/flow/FlowCenterClientTest.java @@ -223,13 +223,13 @@ class FlowCenterClientTest { void registerCallback_contractFields() { FlowModels.CallbackRegBody body = new FlowModels.CallbackRegBody(); body.setFlowGuid("fg-1"); - body.setCallbackUrl("http://localhost:8101/oapi/notice/flow/callback"); + body.setCallbackUrl("http://localhost:8101/oapi/flow/callback"); FlowModels.CallbackRegResultVo result = newClient().registerCallback(1, body); assertEquals("reg-secret-0123456789abcdef", result.getSecret()); Captured c = captured.get(0); assertEquals("POST", c.method); assertEquals("/oapi/flow/callback/reg", c.path); - assertEquals("http://localhost:8101/oapi/notice/flow/callback", c.body.get("callbackUrl").asText()); + assertEquals("http://localhost:8101/oapi/flow/callback", c.body.get("callbackUrl").asText()); } @Test diff --git a/src/test/java/com/yunhai/notice/service/flow/NoticeFlowCallbackConfigContractTest.java b/src/test/java/com/yunhai/notice/service/flow/NoticeFlowCallbackConfigContractTest.java index 94dc534..789e364 100644 --- a/src/test/java/com/yunhai/notice/service/flow/NoticeFlowCallbackConfigContractTest.java +++ b/src/test/java/com/yunhai/notice/service/flow/NoticeFlowCallbackConfigContractTest.java @@ -14,15 +14,17 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; * 回调路径配置契约测试(防"过期值"回归;2026-09-20 迁 starter 后改版)。

* 不变式:{@code yh.flow-callback.path}(starter 接收端点的真实映射来源)必须与 * {@code notice.flow.callback-path}(回调地址尾段的历史真源)逐字一致且等于冻结字面量 - * {@code /oapi/notice/flow/callback}——不一致时 flow-center 探活/推送全部 404, + * {@code /oapi/flow/callback}——不一致时 flow-center 探活/推送全部 404, * 而本地单测因为走伪服务端不会发现。
+ * 2026-09-24:字面量由 {@code /oapi/notice/flow/callback} 收敛为 starter 默认值 + * (网关契约 {@code /{target}/oapi/**} 首段已由 target 承担,端点内不再带应用名前缀)。
* 迁移背景:端点由 yh-flow-callback-spring-boot-starter 的 FlowCallbackReceiverController * 提供(@RequestMapping("${yh.flow-callback.path:...}")),不再有本地控制器类可反射。 */ @DisplayName("Notice 回调路径配置 - 与 starter 端点映射咬合") class NoticeFlowCallbackConfigContractTest { - private static final String FROZEN_CALLBACK_PATH = "/oapi/notice/flow/callback"; + private static final String FROZEN_CALLBACK_PATH = "/oapi/flow/callback"; @SuppressWarnings("unchecked") private static Object yamlValue(String path) throws Exception {