Annotate actuator internal infrastructure with @Reflective

This commit simplifies the registration of hints for the infrastructure
of the Actuator that is invoked via reflection.
This commit is contained in:
Stephane Nicoll 2022-08-17 17:25:06 +02:00
parent 6d6270edaf
commit 24a52aa66d
6 changed files with 38 additions and 40 deletions

View File

@ -16,7 +16,6 @@
package org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
@ -28,6 +27,8 @@ import reactor.core.publisher.Mono;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.aot.hint.annotation.Reflective;
import org.springframework.aot.hint.annotation.ReflectiveRuntimeHintsRegistrar;
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.AccessLevel;
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.SecurityResponse;
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive.CloudFoundryWebFluxEndpointHandlerMapping.CloudFoundryWebFluxEndpointHandlerMappingRuntimeHints;
@ -44,8 +45,6 @@ import org.springframework.context.aot.BindingReflectionHintsRegistrar;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.reactive.result.method.RequestMappingInfoHandlerMapping;
import org.springframework.web.server.ServerWebExchange;
@ -88,6 +87,7 @@ class CloudFoundryWebFluxEndpointHandlerMapping extends AbstractWebFluxEndpointH
class CloudFoundryLinksHandler implements LinksHandler {
@Override
@Reflective
public Publisher<ResponseEntity<Object>> links(ServerWebExchange exchange) {
ServerHttpRequest request = exchange.getRequest();
return CloudFoundryWebFluxEndpointHandlerMapping.this.securityInterceptor.preHandle(exchange, "")
@ -156,14 +156,13 @@ class CloudFoundryWebFluxEndpointHandlerMapping extends AbstractWebFluxEndpointH
static class CloudFoundryWebFluxEndpointHandlerMappingRuntimeHints implements RuntimeHintsRegistrar {
private final ReflectiveRuntimeHintsRegistrar reflectiveRegistrar = new ReflectiveRuntimeHintsRegistrar();
private final BindingReflectionHintsRegistrar bindingRegistrar = new BindingReflectionHintsRegistrar();
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
Method linksMethod = ReflectionUtils.findMethod(CloudFoundryLinksHandler.class, "links",
ServerWebExchange.class);
Assert.state(linksMethod != null, "Unable to find 'links' method");
hints.reflection().registerMethod(linksMethod);
this.reflectiveRegistrar.registerRuntimeHints(hints, CloudFoundryLinksHandler.class);
this.bindingRegistrar.registerReflectionHints(hints.reflection(), Link.class);
}

View File

@ -16,7 +16,6 @@
package org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
@ -30,6 +29,8 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.aot.hint.annotation.Reflective;
import org.springframework.aot.hint.annotation.ReflectiveRuntimeHintsRegistrar;
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.AccessLevel;
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.SecurityResponse;
import org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet.CloudFoundryWebEndpointServletHandlerMapping.CloudFoundryWebEndpointServletHandlerMappingRuntimeHints;
@ -45,8 +46,6 @@ import org.springframework.context.annotation.ImportRuntimeHints;
import org.springframework.context.aot.BindingReflectionHintsRegistrar;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;
@ -92,6 +91,7 @@ class CloudFoundryWebEndpointServletHandlerMapping extends AbstractWebMvcEndpoin
@Override
@ResponseBody
@Reflective
public Map<String, Map<String, Link>> links(HttpServletRequest request, HttpServletResponse response) {
SecurityResponse securityResponse = CloudFoundryWebEndpointServletHandlerMapping.this.securityInterceptor
.preHandle(request, null);
@ -158,14 +158,13 @@ class CloudFoundryWebEndpointServletHandlerMapping extends AbstractWebMvcEndpoin
static class CloudFoundryWebEndpointServletHandlerMappingRuntimeHints implements RuntimeHintsRegistrar {
private final ReflectiveRuntimeHintsRegistrar reflectiveRegistrar = new ReflectiveRuntimeHintsRegistrar();
private final BindingReflectionHintsRegistrar bindingRegistrar = new BindingReflectionHintsRegistrar();
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
Method linksMethod = ReflectionUtils.findMethod(CloudFoundryLinksHandler.class, "links",
HttpServletRequest.class, HttpServletResponse.class);
Assert.state(linksMethod != null, "Unable to find 'links' method");
hints.reflection().registerMethod(linksMethod);
this.reflectiveRegistrar.registerRuntimeHints(hints, CloudFoundryLinksHandler.class);
this.bindingRegistrar.registerReflectionHints(hints.reflection(), Link.class);
}

View File

@ -32,6 +32,8 @@ import reactor.core.scheduler.Schedulers;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.aot.hint.annotation.Reflective;
import org.springframework.aot.hint.annotation.ReflectiveRuntimeHintsRegistrar;
import org.springframework.boot.actuate.endpoint.InvalidEndpointRequestException;
import org.springframework.boot.actuate.endpoint.InvocationContext;
import org.springframework.boot.actuate.endpoint.OperationArgumentResolver;
@ -59,7 +61,6 @@ import org.springframework.security.access.vote.RoleVoter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
@ -410,6 +411,7 @@ public abstract class AbstractWebFluxEndpointHandlerMapping extends RequestMappi
}
@ResponseBody
@Reflective
Publisher<ResponseEntity<Object>> handle(ServerWebExchange exchange,
@RequestBody(required = false) Map<String, String> body) {
return this.operation.handle(exchange, body);
@ -434,6 +436,7 @@ public abstract class AbstractWebFluxEndpointHandlerMapping extends RequestMappi
}
@ResponseBody
@Reflective
Publisher<ResponseEntity<Object>> handle(ServerWebExchange exchange) {
return this.operation.handle(exchange, null);
}
@ -492,15 +495,12 @@ public abstract class AbstractWebFluxEndpointHandlerMapping extends RequestMappi
static class AbstractWebFluxEndpointHandlerMappingRuntimeHints implements RuntimeHintsRegistrar {
private final ReflectiveRuntimeHintsRegistrar reflectiveRegistrar = new ReflectiveRuntimeHintsRegistrar();
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
Method writeOperationHandleMethod = ReflectionUtils.findMethod(WriteOperationHandler.class, "handle",
ServerWebExchange.class, Map.class);
Assert.state(writeOperationHandleMethod != null, () -> "Unable to find write operation 'handle' method");
Method readOperationHandleMethod = ReflectionUtils.findMethod(ReadOperationHandler.class, "handle",
ServerWebExchange.class);
Assert.state(readOperationHandleMethod != null, () -> "Unable to find read operation 'handle' method");
hints.reflection().registerMethod(writeOperationHandleMethod).registerMethod(readOperationHandleMethod);
this.reflectiveRegistrar.registerRuntimeHints(hints, WriteOperationHandler.class,
ReadOperationHandler.class);
}
}

View File

@ -16,13 +16,14 @@
package org.springframework.boot.actuate.endpoint.web.reactive;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.aot.hint.annotation.Reflective;
import org.springframework.aot.hint.annotation.ReflectiveRuntimeHintsRegistrar;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver;
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
@ -32,8 +33,6 @@ import org.springframework.boot.actuate.endpoint.web.Link;
import org.springframework.boot.actuate.endpoint.web.reactive.WebFluxEndpointHandlerMapping.WebFluxEndpointHandlerMappingRuntimeHints;
import org.springframework.context.annotation.ImportRuntimeHints;
import org.springframework.context.aot.BindingReflectionHintsRegistrar;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.reactive.HandlerMapping;
@ -84,6 +83,7 @@ public class WebFluxEndpointHandlerMapping extends AbstractWebFluxEndpointHandle
@Override
@ResponseBody
@Reflective
public Map<String, Map<String, Link>> links(ServerWebExchange exchange) {
String requestUri = UriComponentsBuilder.fromUri(exchange.getRequest().getURI()).replaceQuery(null)
.toUriString();
@ -100,14 +100,13 @@ public class WebFluxEndpointHandlerMapping extends AbstractWebFluxEndpointHandle
static class WebFluxEndpointHandlerMappingRuntimeHints implements RuntimeHintsRegistrar {
private final ReflectiveRuntimeHintsRegistrar reflectiveRegistrar = new ReflectiveRuntimeHintsRegistrar();
private final BindingReflectionHintsRegistrar bindingRegistrar = new BindingReflectionHintsRegistrar();
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
Method linksMethod = ReflectionUtils.findMethod(WebFluxLinksHandler.class, "links",
ServerWebExchange.class);
Assert.state(linksMethod != null, "Unable to find 'links' method");
hints.reflection().registerMethod(linksMethod);
this.reflectiveRegistrar.registerRuntimeHints(hints, WebFluxLinksHandler.class);
this.bindingRegistrar.registerReflectionHints(hints.reflection(), Link.class);
}

View File

@ -34,6 +34,8 @@ import reactor.core.publisher.Flux;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.aot.hint.annotation.Reflective;
import org.springframework.aot.hint.annotation.ReflectiveRuntimeHintsRegistrar;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.actuate.endpoint.InvalidEndpointRequestException;
import org.springframework.boot.actuate.endpoint.InvocationContext;
@ -417,6 +419,7 @@ public abstract class AbstractWebMvcEndpointHandlerMapping extends RequestMappin
}
@ResponseBody
@Reflective
Object handle(HttpServletRequest request, @RequestBody(required = false) Map<String, String> body) {
return this.operation.handle(request, body);
}
@ -483,12 +486,11 @@ public abstract class AbstractWebMvcEndpointHandlerMapping extends RequestMappin
static class AbstractWebMvcEndpointHandlerMappingRuntimeHints implements RuntimeHintsRegistrar {
private final ReflectiveRuntimeHintsRegistrar reflectiveRegistrar = new ReflectiveRuntimeHintsRegistrar();
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
Method handlerMethod = ReflectionUtils.findMethod(OperationHandler.class, "handle",
HttpServletRequest.class, Map.class);
Assert.state(handlerMethod != null, "Unable to find 'handler' method");
hints.reflection().registerMethod(handlerMethod);
this.reflectiveRegistrar.registerRuntimeHints(hints, OperationHandler.class);
}
}

View File

@ -16,7 +16,6 @@
package org.springframework.boot.actuate.endpoint.web.servlet;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
@ -26,6 +25,8 @@ import jakarta.servlet.http.HttpServletResponse;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.aot.hint.annotation.Reflective;
import org.springframework.aot.hint.annotation.ReflectiveRuntimeHintsRegistrar;
import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver;
import org.springframework.boot.actuate.endpoint.web.EndpointMapping;
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
@ -34,8 +35,6 @@ import org.springframework.boot.actuate.endpoint.web.Link;
import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping.WebMvcEndpointHandlerMappingRuntimeHints;
import org.springframework.context.annotation.ImportRuntimeHints;
import org.springframework.context.aot.BindingReflectionHintsRegistrar;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.servlet.HandlerMapping;
@ -83,6 +82,7 @@ public class WebMvcEndpointHandlerMapping extends AbstractWebMvcEndpointHandlerM
@Override
@ResponseBody
@Reflective
public Map<String, Map<String, Link>> links(HttpServletRequest request, HttpServletResponse response) {
return Collections.singletonMap("_links",
WebMvcEndpointHandlerMapping.this.linksResolver.resolveLinks(request.getRequestURL().toString()));
@ -97,14 +97,13 @@ public class WebMvcEndpointHandlerMapping extends AbstractWebMvcEndpointHandlerM
static class WebMvcEndpointHandlerMappingRuntimeHints implements RuntimeHintsRegistrar {
private final ReflectiveRuntimeHintsRegistrar reflectiveRegistrar = new ReflectiveRuntimeHintsRegistrar();
private final BindingReflectionHintsRegistrar bindingRegistrar = new BindingReflectionHintsRegistrar();
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
Method linksMethod = ReflectionUtils.findMethod(WebMvcLinksHandler.class, "links", HttpServletRequest.class,
HttpServletResponse.class);
Assert.state(linksMethod != null, "Unable to find 'links' method");
hints.reflection().registerMethod(linksMethod);
this.reflectiveRegistrar.registerRuntimeHints(hints, WebMvcLinksHandler.class);
this.bindingRegistrar.registerReflectionHints(hints.reflection(), Link.class);
}