target base-url 由 open_api_target 快照优先解析,无行/禁用行/空白地址行回落 yml yh.gateway.routes;/api/internal/routes/refresh 同时重载两表。
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
package com.yunhai.platform.gateway.route;
|
||||
|
||||
import com.yunhai.platform.gateway.entity.OpenApiRoute;
|
||||
import com.yunhai.platform.gateway.entity.OpenApiTarget;
|
||||
import com.yunhai.platform.gateway.repository.OpenApiRouteRepository;
|
||||
import com.yunhai.platform.gateway.repository.OpenApiTargetRepository;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
@@ -109,4 +111,27 @@ class RouteRegistryTest {
|
||||
assertThat(spec.authMode).as("refresh 后新增条目生效").isEqualTo("ANON");
|
||||
assertThat(spec.cacheTtlSeconds).isEqualTo(120);
|
||||
}
|
||||
|
||||
@Test
|
||||
void reloadTargets_装载数只计有效行_空白地址不入快照() {
|
||||
// E11:target 地址快照与路由条目同库不同表,装载口径一致(enabled 行 + 非空地址)
|
||||
OpenApiTargetRepository targetRepo = Mockito.mock(OpenApiTargetRepository.class);
|
||||
when(targetRepo.findByEnabledTrue()).thenReturn(Arrays.asList(
|
||||
targetRow("userbase", "http://userbase-service:8080"),
|
||||
targetRow("notice", " ")));
|
||||
RouteRegistry reg = new RouteRegistry();
|
||||
ReflectionTestUtils.setField(reg, "targetRepo", targetRepo);
|
||||
assertThat(reg.reloadTargets()).as("空白地址行不装载").isEqualTo(1);
|
||||
assertThat(reg.targetBaseUrl("userbase")).isEqualTo("http://userbase-service:8080");
|
||||
assertThat(reg.targetBaseUrl("notice")).as("空白地址 = 无 DB 行语义,由 TargetRouter 回落 yml").isNull();
|
||||
assertThat(reg.targetBaseUrl("nobody")).as("DB 无此 target").isNull();
|
||||
}
|
||||
|
||||
private static OpenApiTarget targetRow(String code, String baseUrl) {
|
||||
OpenApiTarget t = new OpenApiTarget();
|
||||
t.setTargetCode(code);
|
||||
t.setBaseUrl(baseUrl);
|
||||
t.setEnabled(true);
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,33 @@
|
||||
package com.yunhai.platform.gateway.route;
|
||||
|
||||
import com.yunhai.platform.gateway.entity.OpenApiTarget;
|
||||
import com.yunhai.platform.gateway.repository.OpenApiTargetRepository;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* TargetRouter 用例(T0.12 TDD):已知 target forwardUrl 逐字符断言(换主机不换路径)、
|
||||
* 未知 target / 单段 / 非 oapi 第二段一律裸 404(null)、base-url 尾斜杠归一化。
|
||||
* <p>
|
||||
* E11 追加 DB>yml 四例:DB 有行覆盖 yml、DB 无行回落 yml、enabled=0 回落 yml、
|
||||
* refresh 后新增行生效。target 快照经真实 {@link RouteRegistry}(mock repository)走,
|
||||
* 不 stub 解析逻辑本身。
|
||||
*/
|
||||
class TargetRouterTest {
|
||||
|
||||
private TargetRouter router;
|
||||
private RouteRegistry registry;
|
||||
private List<OpenApiTarget> targetRows;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
@@ -25,6 +38,26 @@ class TargetRouterTest {
|
||||
routes.put("notice", "http://notice-service:8080/");
|
||||
props.setRoutes(routes);
|
||||
router.setProperties(props);
|
||||
|
||||
targetRows = new ArrayList<>();
|
||||
OpenApiTargetRepository targetRepo = Mockito.mock(OpenApiTargetRepository.class);
|
||||
when(targetRepo.findByEnabledTrue()).thenReturn(targetRows);
|
||||
registry = new RouteRegistry();
|
||||
ReflectionTestUtils.setField(registry, "targetRepo", targetRepo);
|
||||
router.setRouteRegistry(registry);
|
||||
}
|
||||
|
||||
private static OpenApiTarget target(String code, String baseUrl, boolean enabled) {
|
||||
OpenApiTarget t = new OpenApiTarget();
|
||||
t.setTargetCode(code);
|
||||
t.setBaseUrl(baseUrl);
|
||||
t.setEnabled(enabled);
|
||||
return t;
|
||||
}
|
||||
|
||||
/** 模拟 refresh 端点:重载 target 表快照 */
|
||||
private void refreshTargets() {
|
||||
registry.reloadTargets();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -76,4 +109,41 @@ class TargetRouterTest {
|
||||
assertThat(r.forwardUrl).isEqualTo("http://userbase-service:8080/userbase/oapi");
|
||||
assertThat(r.pathAfterStrip).isEqualTo("/oapi");
|
||||
}
|
||||
|
||||
@Test
|
||||
void DB有行_用DB地址覆盖yml() {
|
||||
targetRows.add(target("userbase", "http://10.0.0.9:9999", true));
|
||||
refreshTargets();
|
||||
TargetRouter.Routing r = router.route("/userbase/oapi/x", "a=1");
|
||||
assertThat(r.forwardUrl).as("DB 行优先于 yml 同名 target")
|
||||
.isEqualTo("http://10.0.0.9:9999/userbase/oapi/x?a=1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void DB无行_回落yml() {
|
||||
refreshTargets();
|
||||
TargetRouter.Routing r = router.route("/userbase/oapi/x", null);
|
||||
assertThat(r.forwardUrl).isEqualTo("http://userbase-service:8080/userbase/oapi/x");
|
||||
}
|
||||
|
||||
@Test
|
||||
void DB禁用行_回落yml() {
|
||||
// repo 契约按 enabled=true 过滤;注册表再滤一层(与 RouteRegistry 同口径双保险)
|
||||
targetRows.add(target("userbase", "http://10.0.0.9:9999", false));
|
||||
refreshTargets();
|
||||
TargetRouter.Routing r = router.route("/userbase/oapi/x", null);
|
||||
assertThat(r.forwardUrl).as("enabled=0 行不参与解析").isEqualTo("http://userbase-service:8080/userbase/oapi/x");
|
||||
}
|
||||
|
||||
@Test
|
||||
void DB行只在解析后新增时可见_未refresh不生效() {
|
||||
refreshTargets();
|
||||
targetRows.add(target("flowcenter", "http://flow-center-service:8080", true));
|
||||
assertThat(router.route("/flowcenter/oapi/x", null))
|
||||
.as("快照未 refresh 前 DB 新行不生效").isNull();
|
||||
refreshTargets();
|
||||
TargetRouter.Routing r = router.route("/flowcenter/oapi/x", null);
|
||||
assertThat(r).as("refresh 后 DB 新增 target 生效(yml 无此 target)").isNotNull();
|
||||
assertThat(r.forwardUrl).isEqualTo("http://flow-center-service:8080/flowcenter/oapi/x");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,11 @@ spring:
|
||||
password:
|
||||
sql:
|
||||
init:
|
||||
# 直接跑交付 DDL(docs/sql/01_schema.sql)——round-trip 钉死「DDL ↔ 实体」一致
|
||||
# 直接跑交付 DDL(docs/sql/01_schema.sql + 03_target.sql)——round-trip 钉死「DDL ↔ 实体」一致
|
||||
mode: always
|
||||
schema-locations: file:docs/sql/01_schema.sql
|
||||
schema-locations:
|
||||
- file:docs/sql/01_schema.sql
|
||||
- file:docs/sql/03_target.sql
|
||||
jpa:
|
||||
hibernate:
|
||||
ddl-auto: none
|
||||
|
||||
Reference in New Issue
Block a user