|
@@ -0,0 +1,63 @@
|
|
|
|
|
+package com.guanlan.gateway.web;
|
|
|
|
|
+
|
|
|
|
|
+import org.springframework.http.MediaType;
|
|
|
|
|
+import org.springframework.http.ResponseEntity;
|
|
|
|
|
+import org.springframework.web.bind.annotation.GetMapping;
|
|
|
|
|
+import org.springframework.web.bind.annotation.RestController;
|
|
|
|
|
+import org.springframework.web.reactive.function.client.WebClient;
|
|
|
|
|
+import reactor.core.publisher.Mono;
|
|
|
|
|
+
|
|
|
|
|
+import java.time.Duration;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 精确路径别名(P13):路由表谓词在本版本对**精确路径**不生效(实逮:`Path=/algorithm` 与 `Path=/sim/sys` 均匹配不上,
|
|
|
|
|
+ * 而同一份配置里带通配的 `/algorithm/**`、`/ops/**` 正常;`Path=/` 也匹配不上根路径 —— 当时就是改用控制器解决的),
|
|
|
|
|
+ * 故这里沿用**已验证可行**的办法:用控制器兜住这两条精确路径,并加响应头标明别名来源(便于随时核验)。
|
|
|
|
|
+ *
|
|
|
|
|
+ * <p>· `/algorithm` → 算法服务 `/healthz`(契约要 JSON ≥104 B)
|
|
|
|
|
+ * <p>· `/sim/sys` 与 `/sim/sys/**` → 四系统联调台 18792(裸路径给它的根页面)
|
|
|
|
|
+ *
|
|
|
|
|
+ * <p>上游地址可用环境变量覆盖:GUANLAN_ALGORITHM_UP / GUANLAN_SIM_SYS_UP。
|
|
|
|
|
+ */
|
|
|
|
|
+@RestController
|
|
|
|
|
+public class AliasController {
|
|
|
|
|
+
|
|
|
|
|
+ private final WebClient algorithm;
|
|
|
|
|
+ private final WebClient simSys;
|
|
|
|
|
+
|
|
|
|
|
+ public AliasController() {
|
|
|
|
|
+ String algo = env("GUANLAN_ALGORITHM_UP", "http://127.0.0.1:18050");
|
|
|
|
|
+ String sim = env("GUANLAN_SIM_SYS_UP", "http://127.0.0.1:18792");
|
|
|
|
|
+ this.algorithm = WebClient.builder().baseUrl(algo)
|
|
|
|
|
+ .codecs(c -> c.defaultCodecs().maxInMemorySize(-1)).build();
|
|
|
|
|
+ this.simSys = WebClient.builder().baseUrl(sim)
|
|
|
|
|
+ .codecs(c -> c.defaultCodecs().maxInMemorySize(-1)).build();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private static String env(String key, String dflt) {
|
|
|
|
|
+ String v = System.getenv(key);
|
|
|
|
|
+ return (v == null || v.isEmpty()) ? dflt : v;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @GetMapping(value = "/algorithm", produces = "application/json; charset=utf-8")
|
|
|
|
|
+ public Mono<ResponseEntity<String>> algorithmRoot() {
|
|
|
|
|
+ return algorithm.get().uri("/healthz").retrieve().bodyToMono(String.class)
|
|
|
|
|
+ .timeout(Duration.ofSeconds(60))
|
|
|
|
|
+ .map(b -> ResponseEntity.ok().header("X-Alias-Source", "algorithm-healthz")
|
|
|
|
|
+ .contentType(MediaType.valueOf("application/json; charset=utf-8")).body(b))
|
|
|
|
|
+ .onErrorResume(e -> Mono.just(ResponseEntity.status(503)
|
|
|
|
|
+ .contentType(MediaType.valueOf("application/json; charset=utf-8"))
|
|
|
|
|
+ .body("{\"err\":\"算法服务不可达: " + e.getClass().getSimpleName() + "\"}")));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @GetMapping(value = {"/sim/sys", "/sim/sys/**"}, produces = "text/html; charset=utf-8")
|
|
|
|
|
+ public Mono<ResponseEntity<String>> simSysRoot() {
|
|
|
|
|
+ return simSys.get().uri("/").retrieve().bodyToMono(String.class)
|
|
|
|
|
+ .timeout(Duration.ofSeconds(60))
|
|
|
|
|
+ .map(b -> ResponseEntity.ok().header("X-Alias-Source", "sim-sys-root")
|
|
|
|
|
+ .contentType(MediaType.valueOf("text/html; charset=utf-8")).body(b))
|
|
|
|
|
+ .onErrorResume(e -> Mono.just(ResponseEntity.status(503)
|
|
|
|
|
+ .contentType(MediaType.valueOf("text/html; charset=utf-8"))
|
|
|
|
|
+ .body("<h1>四系统联调台不可达</h1><p>" + e.getClass().getSimpleName() + "</p>")));
|
|
|
|
|
+ }
|
|
|
|
|
+}
|