diff --git a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/actuate/GatewayControllerEndpoint.java b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/actuate/GatewayControllerEndpoint.java index a148f35c..52421b1f 100644 --- a/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/actuate/GatewayControllerEndpoint.java +++ b/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/actuate/GatewayControllerEndpoint.java @@ -18,6 +18,7 @@ package org.springframework.cloud.gateway.actuate; import java.net.URI; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -25,6 +26,7 @@ import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint; +import org.springframework.cloud.gateway.filter.GatewayFilter; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.cloud.gateway.filter.factory.GatewayFilterFactory; import org.springframework.cloud.gateway.event.RefreshRoutesEvent; @@ -109,15 +111,45 @@ public class GatewayControllerEndpoint implements ApplicationEventPublisherAware return map; } - // TODO: Add support for RouteLocator + // TODO: Flush out routes without a definition @GetMapping("/routes") - public Mono> routes() { - Mono> routeDefs = this.routeDefinitionLocator.getRouteDefinitions().collectList(); + public Mono>> routes() { + Mono> routeDefs = this.routeDefinitionLocator.getRouteDefinitions() + .collectMap(RouteDefinition::getId); Mono> routes = this.routeLocator.getRoutes().collectList(); return Mono.zip(routeDefs, routes).map(tuple -> { - Map allRoutes = new HashMap<>(); - allRoutes.put("routeDefinitions", tuple.getT1()); - // allRoutes.put("routes", tuple.getT2()); + Map defs = tuple.getT1(); + List routeList = tuple.getT2(); + List> allRoutes = new ArrayList<>(); + + routeList.forEach(route -> { + HashMap r = new HashMap<>(); + r.put("route_id", route.getId()); + r.put("order", route.getOrder()); + + if (defs.containsKey(route.getId())) { + r.put("route_definition", defs.get(route.getId())); + } else { + HashMap obj = new HashMap<>(); + + obj.put("predicate", route.getPredicate().toString()); + + if (!route.getFilters().isEmpty()) { + ArrayList filters = new ArrayList<>(); + for (GatewayFilter filter : route.getFilters()) { + filters.add(filter.toString()); + } + + obj.put("filters", filters); + } + + if (!obj.isEmpty()) { + r.put("route_object", obj); + } + } + allRoutes.add(r); + }); + return allRoutes; }); } diff --git a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/actuate/GatewayControllerEndpointTests.java b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/actuate/GatewayControllerEndpointTests.java index 4e411752..b12276b8 100644 --- a/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/actuate/GatewayControllerEndpointTests.java +++ b/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/actuate/GatewayControllerEndpointTests.java @@ -17,6 +17,9 @@ package org.springframework.cloud.gateway.actuate; +import java.util.List; +import java.util.Map; + import org.junit.Test; import org.junit.runner.RunWith; @@ -30,6 +33,7 @@ import org.springframework.context.annotation.Import; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.reactive.server.WebTestClient; +import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; @RunWith(SpringRunner.class) @@ -50,6 +54,19 @@ public class GatewayControllerEndpointTests { .expectStatus().isOk(); } + @Test + public void testRoutes() { + testClient.get() + .uri("http://localhost:"+port+"/actuator/gateway/routes") + .exchange() + .expectStatus().isOk() + .expectBodyList(Map.class) + .consumeWith(result -> { + List responseBody = result.getResponseBody(); + assertThat(responseBody).isNotEmpty(); + }); + } + @SpringBootConfiguration @EnableAutoConfiguration @Import(PermitAllSecurityConfiguration.class)