diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/actuate/AbstractGatewayControllerEndpoint.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/actuate/AbstractGatewayControllerEndpoint.java index ab521961..f946b16d 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/actuate/AbstractGatewayControllerEndpoint.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/actuate/AbstractGatewayControllerEndpoint.java @@ -32,6 +32,7 @@ import org.apache.commons.logging.LogFactory; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; import org.springframework.cloud.gateway.event.RefreshRoutesEvent; import org.springframework.cloud.gateway.filter.FilterDefinition; import org.springframework.cloud.gateway.filter.GlobalFilter; @@ -71,8 +72,6 @@ public class AbstractGatewayControllerEndpoint implements ApplicationEventPublis private static final Log log = LogFactory.getLog(GatewayControllerEndpoint.class); - private static final String ENDPOINT_PREFIX = "/actuator/gateway"; - protected RouteDefinitionLocator routeDefinitionLocator; protected List globalFilters; @@ -88,25 +87,55 @@ public class AbstractGatewayControllerEndpoint implements ApplicationEventPublis protected ApplicationEventPublisher publisher; + protected WebEndpointProperties webEndpointProperties; + + private final SimpleMetadataReaderFactory simpleMetadataReaderFactory = new SimpleMetadataReaderFactory(); + public AbstractGatewayControllerEndpoint(RouteDefinitionLocator routeDefinitionLocator, List globalFilters, List gatewayFilters, List routePredicates, RouteDefinitionWriter routeDefinitionWriter, - RouteLocator routeLocator) { + RouteLocator routeLocator, WebEndpointProperties webEndpointProperties) { this.routeDefinitionLocator = routeDefinitionLocator; this.globalFilters = globalFilters; this.GatewayFilters = gatewayFilters; this.routePredicates = routePredicates; this.routeDefinitionWriter = routeDefinitionWriter; this.routeLocator = routeLocator; + this.webEndpointProperties = webEndpointProperties; + } + + @GetMapping("/") + Mono> getEndpoints() { + List endpoints = mergeEndpoints( + getAvailableEndpointsForClass(AbstractGatewayControllerEndpoint.class.getName()), + getAvailableEndpointsForClass(GatewayControllerEndpoint.class.getName())); + + return Flux.fromIterable(endpoints).map(p -> p) + .flatMap(path -> this.routeLocator.getRoutes().map(r -> generateHref(r, path)).distinct().collectList() + .flatMapMany(Flux::fromIterable)) + .distinct() // Ensure overall uniqueness + .collectList(); + } + + private List mergeEndpoints(List listA, + List listB) { + Map> mergedMap = new HashMap<>(); + + Stream.concat(listA.stream(), listB.stream()).forEach(e -> mergedMap + .computeIfAbsent(e.getHref(), k -> new ArrayList<>()).addAll(Arrays.asList(e.getMethods()))); + + return mergedMap.entrySet().stream().map(entry -> new GatewayEndpointInfo(entry.getKey(), entry.getValue())) + .collect(Collectors.toList()); } private List getAvailableEndpointsForClass(String className) { try { - MetadataReader metadataReader = new SimpleMetadataReaderFactory().getMetadataReader(className); + MetadataReader metadataReader = simpleMetadataReaderFactory.getMetadataReader(className); Set annotatedMethods = metadataReader.getAnnotationMetadata() .getAnnotatedMethods(RequestMapping.class.getName()); - return annotatedMethods.stream().map(method -> new GatewayEndpointInfo(ENDPOINT_PREFIX + String gatewayActuatorPath = webEndpointProperties.getBasePath() + "/gateway"; + return annotatedMethods.stream().map(method -> new GatewayEndpointInfo(gatewayActuatorPath + ((String[]) method.getAnnotationAttributes(RequestMapping.class.getName()).get("path"))[0], ((RequestMethod[]) method.getAnnotationAttributes(RequestMapping.class.getName()).get("method"))[0] .name())) @@ -118,35 +147,10 @@ public class AbstractGatewayControllerEndpoint implements ApplicationEventPublis } } - public static List mergeEndpoints(List listA, - List listB) { - Map> mergedMap = new HashMap<>(); - - Stream.concat(listA.stream(), listB.stream()).forEach(e -> mergedMap - .computeIfAbsent(e.getHref(), k -> new ArrayList<>()).addAll(Arrays.asList(e.getMethods()))); - - return mergedMap.entrySet().stream().map(entry -> new GatewayEndpointInfo(entry.getKey(), entry.getValue())) - .collect(Collectors.toList()); - } - - GatewayEndpointInfo generateHref(Route r, GatewayEndpointInfo path) { + private GatewayEndpointInfo generateHref(Route r, GatewayEndpointInfo path) { return new GatewayEndpointInfo(path.getHref().replace("{id}", r.getId()), Arrays.asList(path.getMethods())); } - @GetMapping("/") - public Mono> getEndpoints() { - List endpoints = mergeEndpoints( - getAvailableEndpointsForClass(AbstractGatewayControllerEndpoint.class.getName()), - getAvailableEndpointsForClass(GatewayControllerEndpoint.class.getName())); - - return Flux.fromIterable(endpoints).map(p -> p) - .flatMap(path -> this.routeLocator.getRoutes().map(r -> generateHref(r, path)).distinct().collectList() - .flatMapMany(Flux::fromIterable)) - .distinct() // Ensure overall uniqueness - .collectList(); - - } - @Override public void setApplicationEventPublisher(ApplicationEventPublisher publisher) { this.publisher = publisher; diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/actuate/GatewayControllerEndpoint.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/actuate/GatewayControllerEndpoint.java index 109f2888..34553f86 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/actuate/GatewayControllerEndpoint.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/actuate/GatewayControllerEndpoint.java @@ -24,6 +24,7 @@ import java.util.Map; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; import org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint; import org.springframework.cloud.gateway.filter.GatewayFilter; import org.springframework.cloud.gateway.filter.GlobalFilter; @@ -47,9 +48,10 @@ public class GatewayControllerEndpoint extends AbstractGatewayControllerEndpoint public GatewayControllerEndpoint(List globalFilters, List gatewayFilters, List routePredicates, RouteDefinitionWriter routeDefinitionWriter, - RouteLocator routeLocator, RouteDefinitionLocator routeDefinitionLocator) { - super(routeDefinitionLocator, globalFilters, gatewayFilters, routePredicates, routeDefinitionWriter, - routeLocator); + RouteLocator routeLocator, RouteDefinitionLocator routeDefinitionLocator, + WebEndpointProperties webEndpointProperties) { + super(routeDefinitionLocator, globalFilters, gatewayFilters, routePredicates, + routeDefinitionWriter, routeLocator, webEndpointProperties); } @GetMapping("/routedefinitions") diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/actuate/GatewayLegacyControllerEndpoint.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/actuate/GatewayLegacyControllerEndpoint.java index 5e2064cb..32f9b184 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/actuate/GatewayLegacyControllerEndpoint.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/actuate/GatewayLegacyControllerEndpoint.java @@ -23,6 +23,7 @@ import java.util.Map; import reactor.core.publisher.Mono; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; import org.springframework.boot.actuate.endpoint.web.annotation.RestControllerEndpoint; import org.springframework.cloud.gateway.filter.GatewayFilter; import org.springframework.cloud.gateway.filter.GlobalFilter; @@ -47,9 +48,9 @@ public class GatewayLegacyControllerEndpoint extends AbstractGatewayControllerEn public GatewayLegacyControllerEndpoint(RouteDefinitionLocator routeDefinitionLocator, List globalFilters, List gatewayFilterFactories, List routePredicates, RouteDefinitionWriter routeDefinitionWriter, - RouteLocator routeLocator) { + RouteLocator routeLocator, WebEndpointProperties webEndpointProperties) { super(routeDefinitionLocator, globalFilters, gatewayFilterFactories, routePredicates, routeDefinitionWriter, - routeLocator); + routeLocator, webEndpointProperties); } @GetMapping("/routes") diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java index 534277df..2da24fe6 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java @@ -40,6 +40,7 @@ import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; import org.springframework.boot.actuate.health.Health; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureBefore; @@ -817,9 +818,9 @@ public class GatewayAutoConfiguration { public GatewayControllerEndpoint gatewayControllerEndpoint(List globalFilters, List gatewayFilters, List routePredicates, RouteDefinitionWriter routeDefinitionWriter, RouteLocator routeLocator, - RouteDefinitionLocator routeDefinitionLocator) { + RouteDefinitionLocator routeDefinitionLocator, WebEndpointProperties webEndpointProperties) { return new GatewayControllerEndpoint(globalFilters, gatewayFilters, routePredicates, routeDefinitionWriter, - routeLocator, routeDefinitionLocator); + routeLocator, routeDefinitionLocator, webEndpointProperties); } @Bean @@ -828,9 +829,10 @@ public class GatewayAutoConfiguration { public GatewayLegacyControllerEndpoint gatewayLegacyControllerEndpoint( RouteDefinitionLocator routeDefinitionLocator, List globalFilters, List gatewayFilters, List routePredicates, - RouteDefinitionWriter routeDefinitionWriter, RouteLocator routeLocator) { + RouteDefinitionWriter routeDefinitionWriter, RouteLocator routeLocator, + WebEndpointProperties webEndpointProperties) { return new GatewayLegacyControllerEndpoint(routeDefinitionLocator, globalFilters, gatewayFilters, - routePredicates, routeDefinitionWriter, routeLocator); + routePredicates, routeDefinitionWriter, routeLocator, webEndpointProperties); } }