From 584b7d134324fecb68d89b81306261e52ce5f108 Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Mon, 18 Jul 2022 15:45:07 +0200 Subject: [PATCH 1/2] Add AOT support for actuator Mainly adds reflection hints for the actuator infrastructure. Also adds the OperationReflectiveProcessor, which registers the @ReadMethod, @DeleteMethod and @WriteMethod annotated methods for reflection and adds reflection hints for method return types. See gh-31671 --- .../CloudFoundryWebEndpointDiscoverer.java | 18 ++- ...dFoundryWebFluxEndpointHandlerMapping.java | 26 +++- ...undryWebEndpointServletHandlerMapping.java | 25 ++++ .../endpoint/EndpointAutoConfiguration.java | 3 + .../ThreadDumpEndpointAutoConfiguration.java | 11 ++ ...ebEndpointDiscovererRuntimeHintsTests.java | 45 ++++++ ...dpointHandlerMappingRuntimeHintsTests.java | 46 ++++++ ...ervletHandlerMappingRuntimeHintsTests.java | 47 +++++++ ...eadDumpEndpointAutoConfigurationTests.java | 21 ++- ...uatorAnnotationsRuntimeHintsRegistrar.java | 49 +++++++ .../boot/actuate/aot/package-info.java | 20 +++ .../endpoint/annotation/DeleteOperation.java | 4 +- .../actuate/endpoint/annotation/Endpoint.java | 4 +- .../annotation/EndpointExtension.java | 4 +- .../OperationReflectiveProcessor.java | 74 ++++++++++ .../endpoint/annotation/ReadOperation.java | 4 +- .../endpoint/annotation/WriteOperation.java | 4 +- .../jmx/annotation/JmxEndpointDiscoverer.java | 18 ++- .../ControllerEndpointDiscoverer.java | 18 ++- .../annotation/ServletEndpointDiscoverer.java | 18 ++- .../web/annotation/WebEndpointDiscoverer.java | 18 ++- ...AbstractWebFluxEndpointHandlerMapping.java | 23 +++ .../WebFluxEndpointHandlerMapping.java | 26 +++- .../AbstractWebMvcEndpointHandlerMapping.java | 19 +++ .../servlet/WebMvcEndpointHandlerMapping.java | 27 +++- .../health/HealthEndpointWebExtension.java | 18 +++ .../actuate/info/BuildInfoContributor.java | 19 ++- .../boot/actuate/info/GitInfoContributor.java | 19 ++- .../actuate/info/JavaInfoContributor.java | 19 ++- .../boot/actuate/info/OsInfoContributor.java | 17 +++ .../integration/IntegrationGraphEndpoint.java | 40 +++++- .../management/ThreadDumpEndpoint.java | 39 +++++- .../ThreadDumpEndpointWebExtension.java | 60 ++++++++ .../HazelcastCacheMeterBinderProvider.java | 22 +++ .../quartz/QuartzEndpointWebExtension.java | 23 ++- .../scheduling/ScheduledTasksEndpoint.java | 18 +++ .../boot/actuate/startup/StartupEndpoint.java | 31 +++- ...herHandlersMappingDescriptionProvider.java | 20 ++- ...herServletsMappingDescriptionProvider.java | 18 +++ .../FiltersMappingDescriptionProvider.java | 18 +++ .../ServletsMappingDescriptionProvider.java | 18 +++ ...AnnotationsRuntimeHintsRegistrarTests.java | 73 ++++++++++ .../OperationReflectiveProcessorTests.java | 132 ++++++++++++++++++ ...mxEndpointDiscovererRuntimeHintsTests.java | 45 ++++++ ...erEndpointDiscovererRuntimeHintsTests.java | 46 ++++++ ...etEndpointDiscovererRuntimeHintsTests.java | 46 ++++++ ...ebEndpointDiscovererRuntimeHintsTests.java | 46 ++++++ ...dpointHandlerMappingRuntimeHintsTests.java | 49 +++++++ ...dpointHandlerMappingRuntimeHintsTests.java | 47 +++++++ ...dpointHandlerMappingRuntimeHintsTests.java | 46 ++++++ ...dpointHandlerMappingRuntimeHintsTests.java | 47 +++++++ ...EndpointWebExtensionRuntimeHintsTests.java | 51 +++++++ ...BuildInfoContributorRuntimeHintsTests.java | 47 +++++++ .../GitInfoContributorRuntimeHintsTests.java | 48 +++++++ .../JavaInfoContributorRuntimeHintsTests.java | 47 +++++++ .../OsInfoContributorRuntimeHintsTests.java | 48 +++++++ ...grationGraphEndpointRuntimeHintsTests.java | 72 ++++++++++ .../ThreadDumpEndpointWebExtensionTests.java | 63 +++++++++ ...eMeterBinderProviderRuntimeHintsTests.java | 47 +++++++ ...EndpointWebExtensionRuntimeHintsTests.java | 56 ++++++++ ...heduledTasksEndpointRuntimeHintsTests.java | 56 ++++++++ .../StartupEndpointRuntimeHintsTests.java | 53 +++++++ ...gDescriptionProviderRuntimeHintsTests.java | 47 +++++++ ...gDescriptionProviderRuntimeHintsTests.java | 46 ++++++ ...gDescriptionProviderRuntimeHintsTests.java | 47 +++++++ ...gDescriptionProviderRuntimeHintsTests.java | 46 ++++++ .../boot/info/BuildProperties.java | 17 ++- .../boot/info/GitProperties.java | 17 ++- .../BuildPropertiesRuntimeHintsTests.java | 44 ++++++ .../info/GitPropertiesRuntimeHintsTests.java | 43 ++++++ 70 files changed, 2413 insertions(+), 30 deletions(-) create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryWebEndpointDiscovererRuntimeHintsTests.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMappingRuntimeHintsTests.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMappingRuntimeHintsTests.java create mode 100644 spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/aot/ActuatorAnnotationsRuntimeHintsRegistrar.java create mode 100644 spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/aot/package-info.java create mode 100644 spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/OperationReflectiveProcessor.java create mode 100644 spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/management/ThreadDumpEndpointWebExtension.java create mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/aot/ActuatorAnnotationsRuntimeHintsRegistrarTests.java create mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/annotation/OperationReflectiveProcessorTests.java create mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/jmx/annotation/JmxEndpointDiscovererRuntimeHintsTests.java create mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/ControllerEndpointDiscovererRuntimeHintsTests.java create mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/ServletEndpointDiscovererRuntimeHintsTests.java create mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/WebEndpointDiscovererRuntimeHintsTests.java create mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMappingRuntimeHintsTests.java create mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointHandlerMappingRuntimeHintsTests.java create mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/AbstractWebMvcEndpointHandlerMappingRuntimeHintsTests.java create mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMappingRuntimeHintsTests.java create mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointWebExtensionRuntimeHintsTests.java create mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/BuildInfoContributorRuntimeHintsTests.java create mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/GitInfoContributorRuntimeHintsTests.java create mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/JavaInfoContributorRuntimeHintsTests.java create mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/OsInfoContributorRuntimeHintsTests.java create mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/integration/IntegrationGraphEndpointRuntimeHintsTests.java create mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/management/ThreadDumpEndpointWebExtensionTests.java create mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProviderRuntimeHintsTests.java create mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/quartz/QuartzEndpointWebExtensionRuntimeHintsTests.java create mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/scheduling/ScheduledTasksEndpointRuntimeHintsTests.java create mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/startup/StartupEndpointRuntimeHintsTests.java create mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/reactive/DispatcherHandlersMappingDescriptionProviderRuntimeHintsTests.java create mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/DispatcherServletsMappingDescriptionProviderRuntimeHintsTests.java create mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/FiltersMappingDescriptionProviderRuntimeHintsTests.java create mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/ServletsMappingDescriptionProviderRuntimeHintsTests.java create mode 100644 spring-boot-project/spring-boot/src/test/java/org/springframework/boot/info/BuildPropertiesRuntimeHintsTests.java create mode 100644 spring-boot-project/spring-boot/src/test/java/org/springframework/boot/info/GitPropertiesRuntimeHintsTests.java diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryWebEndpointDiscoverer.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryWebEndpointDiscoverer.java index a01fe72a92..ccce390624 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryWebEndpointDiscoverer.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryWebEndpointDiscoverer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,10 @@ package org.springframework.boot.actuate.autoconfigure.cloudfoundry; import java.util.Collection; import java.util.List; +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; +import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryWebEndpointDiscoverer.CloudFoundryWebEndpointDiscovererRuntimeHints; import org.springframework.boot.actuate.endpoint.EndpointFilter; import org.springframework.boot.actuate.endpoint.invoke.OperationInvokerAdvisor; import org.springframework.boot.actuate.endpoint.invoke.ParameterValueMapper; @@ -29,6 +33,7 @@ import org.springframework.boot.actuate.endpoint.web.annotation.EndpointWebExten import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointDiscoverer; import org.springframework.boot.actuate.health.HealthEndpoint; import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.ImportRuntimeHints; import org.springframework.core.annotation.MergedAnnotations; /** @@ -38,6 +43,7 @@ import org.springframework.core.annotation.MergedAnnotations; * @author Madhura Bhave * @since 2.0.0 */ +@ImportRuntimeHints(CloudFoundryWebEndpointDiscovererRuntimeHints.class) public class CloudFoundryWebEndpointDiscoverer extends WebEndpointDiscoverer { /** @@ -75,4 +81,14 @@ public class CloudFoundryWebEndpointDiscoverer extends WebEndpointDiscoverer { return MergedAnnotations.from(extensionBeanType).isPresent(EndpointCloudFoundryExtension.class); } + static class CloudFoundryWebEndpointDiscovererRuntimeHints implements RuntimeHintsRegistrar { + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + hints.reflection().registerType(CloudFoundryEndpointFilter.class, + (hint) -> hint.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)); + } + + } + } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMapping.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMapping.java index 0df6400d0a..dbca38daa4 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMapping.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMapping.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,14 +19,20 @@ package org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import java.util.stream.Collectors; import org.reactivestreams.Publisher; import reactor.core.publisher.Mono; +import org.springframework.aot.hint.ExecutableMode; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; +import org.springframework.aot.hint.TypeReference; 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; import org.springframework.boot.actuate.endpoint.EndpointId; import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver; import org.springframework.boot.actuate.endpoint.web.EndpointMapping; @@ -35,6 +41,8 @@ import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint; import org.springframework.boot.actuate.endpoint.web.Link; import org.springframework.boot.actuate.endpoint.web.WebOperation; import org.springframework.boot.actuate.endpoint.web.reactive.AbstractWebFluxEndpointHandlerMapping; +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.http.server.reactive.ServerHttpRequest; @@ -50,6 +58,7 @@ import org.springframework.web.server.ServerWebExchange; * @author Phillip Webb * @author Brian Clozel */ +@ImportRuntimeHints(CloudFoundryWebFluxEndpointHandlerMappingRuntimeHints.class) class CloudFoundryWebFluxEndpointHandlerMapping extends AbstractWebFluxEndpointHandlerMapping { private final CloudFoundrySecurityInterceptor securityInterceptor; @@ -145,4 +154,19 @@ class CloudFoundryWebFluxEndpointHandlerMapping extends AbstractWebFluxEndpointH } + static class CloudFoundryWebFluxEndpointHandlerMappingRuntimeHints implements RuntimeHintsRegistrar { + + private final BindingReflectionHintsRegistrar bindingRegistrar = new BindingReflectionHintsRegistrar(); + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + hints.reflection().registerType(CloudFoundryLinksHandler.class, + (hint) -> hint.onReachableType(TypeReference.of(CloudFoundryLinksHandler.class)).withMethod("links", + List.of(TypeReference.of(ServerWebExchange.class)), + (method) -> method.setModes(ExecutableMode.INVOKE))); + this.bindingRegistrar.registerReflectionHints(hints.reflection(), Link.class); + } + + } + } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMapping.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMapping.java index fd8fe0e74c..5ccac0b045 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMapping.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMapping.java @@ -19,6 +19,7 @@ package org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -27,8 +28,13 @@ import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.aot.hint.ExecutableMode; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; +import org.springframework.aot.hint.TypeReference; 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; import org.springframework.boot.actuate.endpoint.EndpointId; import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver; import org.springframework.boot.actuate.endpoint.web.EndpointMapping; @@ -37,6 +43,8 @@ import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint; import org.springframework.boot.actuate.endpoint.web.Link; import org.springframework.boot.actuate.endpoint.web.WebOperation; import org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping; +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.web.bind.annotation.ResponseBody; @@ -51,6 +59,7 @@ import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMappi * @author Phillip Webb * @author Brian Clozel */ +@ImportRuntimeHints(CloudFoundryWebEndpointServletHandlerMappingRuntimeHints.class) class CloudFoundryWebEndpointServletHandlerMapping extends AbstractWebMvcEndpointHandlerMapping { private static final Log logger = LogFactory.getLog(CloudFoundryWebEndpointServletHandlerMapping.class); @@ -147,4 +156,20 @@ class CloudFoundryWebEndpointServletHandlerMapping extends AbstractWebMvcEndpoin } + static class CloudFoundryWebEndpointServletHandlerMappingRuntimeHints implements RuntimeHintsRegistrar { + + private final BindingReflectionHintsRegistrar bindingRegistrar = new BindingReflectionHintsRegistrar(); + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + hints.reflection().registerType(CloudFoundryLinksHandler.class, + (hint) -> hint.onReachableType(TypeReference.of(CloudFoundryLinksHandler.class)).withMethod("links", + List.of(TypeReference.of(HttpServletRequest.class), + TypeReference.of(HttpServletResponse.class)), + (method) -> method.setModes(ExecutableMode.INVOKE))); + this.bindingRegistrar.registerReflectionHints(hints.reflection(), Link.class); + } + + } + } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/EndpointAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/EndpointAutoConfiguration.java index a7bcd2f262..01951ce41f 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/EndpointAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/EndpointAutoConfiguration.java @@ -20,6 +20,7 @@ import java.util.List; import java.util.stream.Collectors; import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.actuate.aot.ActuatorAnnotationsRuntimeHintsRegistrar; import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.actuate.endpoint.annotation.EndpointConverter; import org.springframework.boot.actuate.endpoint.invoke.ParameterValueMapper; @@ -30,6 +31,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.convert.ApplicationConversionService; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ImportRuntimeHints; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.GenericConverter; @@ -45,6 +47,7 @@ import org.springframework.core.env.Environment; * @since 2.0.0 */ @AutoConfiguration +@ImportRuntimeHints(ActuatorAnnotationsRuntimeHintsRegistrar.class) public class EndpointAutoConfiguration { @Bean diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/management/ThreadDumpEndpointAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/management/ThreadDumpEndpointAutoConfiguration.java index d5e00f03e5..939e74de19 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/management/ThreadDumpEndpointAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/management/ThreadDumpEndpointAutoConfiguration.java @@ -17,9 +17,12 @@ package org.springframework.boot.actuate.autoconfigure.management; import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; +import org.springframework.boot.actuate.autoconfigure.endpoint.expose.EndpointExposure; import org.springframework.boot.actuate.management.ThreadDumpEndpoint; +import org.springframework.boot.actuate.management.ThreadDumpEndpointWebExtension; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; @@ -39,4 +42,12 @@ public class ThreadDumpEndpointAutoConfiguration { return new ThreadDumpEndpoint(); } + @Bean + @ConditionalOnMissingBean + @ConditionalOnBean(ThreadDumpEndpoint.class) + @ConditionalOnAvailableEndpoint(exposure = { EndpointExposure.WEB, EndpointExposure.CLOUD_FOUNDRY }) + public ThreadDumpEndpointWebExtension threadDumpWebExtension(ThreadDumpEndpoint threadDumpEndpoint) { + return new ThreadDumpEndpointWebExtension(threadDumpEndpoint); + } + } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryWebEndpointDiscovererRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryWebEndpointDiscovererRuntimeHintsTests.java new file mode 100644 index 0000000000..7aea479685 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryWebEndpointDiscovererRuntimeHintsTests.java @@ -0,0 +1,45 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.autoconfigure.cloudfoundry; + +import org.junit.jupiter.api.Test; + +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryWebEndpointDiscoverer.CloudFoundryWebEndpointDiscovererRuntimeHints; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link CloudFoundryWebEndpointDiscovererRuntimeHints}. + * + * @author Moritz Halbritter + */ +class CloudFoundryWebEndpointDiscovererRuntimeHintsTests { + + private final CloudFoundryWebEndpointDiscovererRuntimeHints sut = new CloudFoundryWebEndpointDiscovererRuntimeHints(); + + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + assertThat(RuntimeHintsPredicates.reflection().onType(CloudFoundryEndpointFilter.class) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(runtimeHints); + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMappingRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMappingRuntimeHintsTests.java new file mode 100644 index 0000000000..f4043f317d --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMappingRuntimeHintsTests.java @@ -0,0 +1,46 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive.CloudFoundryWebFluxEndpointHandlerMapping.CloudFoundryLinksHandler; +import org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive.CloudFoundryWebFluxEndpointHandlerMapping.CloudFoundryWebFluxEndpointHandlerMappingRuntimeHints; +import org.springframework.boot.actuate.endpoint.web.Link; + +/** + * Tests for {@link CloudFoundryWebFluxEndpointHandlerMappingRuntimeHints}. + * + * @author Moritz Halbritter + */ +class CloudFoundryWebFluxEndpointHandlerMappingRuntimeHintsTests { + + private final CloudFoundryWebFluxEndpointHandlerMappingRuntimeHints sut = new CloudFoundryWebFluxEndpointHandlerMappingRuntimeHints(); + + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + Assertions.assertThat(RuntimeHintsPredicates.reflection().onMethod(CloudFoundryLinksHandler.class, "links")) + .accepts(runtimeHints); + Assertions.assertThat(RuntimeHintsPredicates.reflection().onType(Link.class)).accepts(runtimeHints); + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMappingRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMappingRuntimeHintsTests.java new file mode 100644 index 0000000000..03902421ee --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMappingRuntimeHintsTests.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet; + +import org.junit.jupiter.api.Test; + +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet.CloudFoundryWebEndpointServletHandlerMapping.CloudFoundryLinksHandler; +import org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet.CloudFoundryWebEndpointServletHandlerMapping.CloudFoundryWebEndpointServletHandlerMappingRuntimeHints; +import org.springframework.boot.actuate.endpoint.web.Link; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link CloudFoundryWebEndpointServletHandlerMappingRuntimeHints}. + * + * @author Moritz Halbritter + */ +class CloudFoundryWebEndpointServletHandlerMappingRuntimeHintsTests { + + private final CloudFoundryWebEndpointServletHandlerMappingRuntimeHints sut = new CloudFoundryWebEndpointServletHandlerMappingRuntimeHints(); + + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + assertThat(RuntimeHintsPredicates.reflection().onMethod(CloudFoundryLinksHandler.class, "links")) + .accepts(runtimeHints); + assertThat(RuntimeHintsPredicates.reflection().onType(Link.class)).accepts(runtimeHints); + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/management/ThreadDumpEndpointAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/management/ThreadDumpEndpointAutoConfigurationTests.java index ac7fb7be20..5d8d895a6b 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/management/ThreadDumpEndpointAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/management/ThreadDumpEndpointAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ package org.springframework.boot.actuate.autoconfigure.management; import org.junit.jupiter.api.Test; import org.springframework.boot.actuate.management.ThreadDumpEndpoint; +import org.springframework.boot.actuate.management.ThreadDumpEndpointWebExtension; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -28,6 +29,7 @@ import static org.assertj.core.api.Assertions.assertThat; * Tests for {@link ThreadDumpEndpointAutoConfiguration}. * * @author Phillip Webb + * @author Moritz Halbritter */ class ThreadDumpEndpointAutoConfigurationTests { @@ -36,20 +38,27 @@ class ThreadDumpEndpointAutoConfigurationTests { @Test void runShouldHaveEndpointBean() { - this.contextRunner.withPropertyValues("management.endpoints.web.exposure.include=threaddump") - .run((context) -> assertThat(context).hasSingleBean(ThreadDumpEndpoint.class)); + this.contextRunner.withPropertyValues("management.endpoints.web.exposure.include=threaddump").run((context) -> { + assertThat(context).hasSingleBean(ThreadDumpEndpoint.class); + assertThat(context).hasSingleBean(ThreadDumpEndpointWebExtension.class); + }); } @Test void runWhenNotExposedShouldNotHaveEndpointBean() { - this.contextRunner.run((context) -> assertThat(context).doesNotHaveBean(ThreadDumpEndpoint.class)); + this.contextRunner.run((context) -> { + assertThat(context).doesNotHaveBean(ThreadDumpEndpoint.class); + assertThat(context).doesNotHaveBean(ThreadDumpEndpointWebExtension.class); + }); } @Test void runWhenEnabledPropertyIsFalseShouldNotHaveEndpointBean() { this.contextRunner.withPropertyValues("management.endpoints.web.exposure.include=*") - .withPropertyValues("management.endpoint.threaddump.enabled:false") - .run((context) -> assertThat(context).doesNotHaveBean(ThreadDumpEndpoint.class)); + .withPropertyValues("management.endpoint.threaddump.enabled:false").run((context) -> { + assertThat(context).doesNotHaveBean(ThreadDumpEndpoint.class); + assertThat(context).doesNotHaveBean(ThreadDumpEndpointWebExtension.class); + }); } } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/aot/ActuatorAnnotationsRuntimeHintsRegistrar.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/aot/ActuatorAnnotationsRuntimeHintsRegistrar.java new file mode 100644 index 0000000000..87a6fc6eec --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/aot/ActuatorAnnotationsRuntimeHintsRegistrar.java @@ -0,0 +1,49 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.aot; + +import java.util.stream.Stream; + +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; +import org.springframework.aot.hint.support.RuntimeHintsUtils; +import org.springframework.boot.actuate.endpoint.annotation.DeleteOperation; +import org.springframework.boot.actuate.endpoint.annotation.Endpoint; +import org.springframework.boot.actuate.endpoint.annotation.EndpointExtension; +import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; +import org.springframework.boot.actuate.endpoint.annotation.WriteOperation; +import org.springframework.core.annotation.SynthesizedAnnotation; + +/** + * Registrar which registers the annotations needed for actuator support. + * + * @author Moritz Halbritter + * @since 3.0.0 + */ +public class ActuatorAnnotationsRuntimeHintsRegistrar implements RuntimeHintsRegistrar { + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + Stream.of(Endpoint.class, ReadOperation.class, WriteOperation.class, DeleteOperation.class, + EndpointExtension.class) + .forEach((annotationType) -> RuntimeHintsUtils.registerAnnotation(hints, annotationType)); + // TODO: See https://github.com/spring-projects/spring-framework/issues/28767 + Stream.of(Endpoint.class, EndpointExtension.class).forEach( + (annotationType) -> hints.proxies().registerJdkProxy(annotationType, SynthesizedAnnotation.class)); + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/aot/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/aot/package-info.java new file mode 100644 index 0000000000..15e4e2bd03 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/aot/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Support classes for actuator in AOT mode. + */ +package org.springframework.boot.actuate.aot; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/DeleteOperation.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/DeleteOperation.java index a052504589..3b9df3d745 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/DeleteOperation.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/DeleteOperation.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.springframework.aot.hint.annotation.Reflective; import org.springframework.boot.actuate.endpoint.Producible; /** @@ -34,6 +35,7 @@ import org.springframework.boot.actuate.endpoint.Producible; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented +@Reflective(OperationReflectiveProcessor.class) public @interface DeleteOperation { /** diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/Endpoint.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/Endpoint.java index de1848073e..8f8c793e42 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/Endpoint.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/Endpoint.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.springframework.aot.hint.annotation.Reflective; import org.springframework.boot.actuate.endpoint.EndpointId; /** @@ -51,6 +52,7 @@ import org.springframework.boot.actuate.endpoint.EndpointId; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented +@Reflective public @interface Endpoint { /** diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/EndpointExtension.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/EndpointExtension.java index 94fb64d3d7..84564372f3 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/EndpointExtension.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/EndpointExtension.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.springframework.aot.hint.annotation.Reflective; import org.springframework.boot.actuate.endpoint.EndpointFilter; import org.springframework.boot.actuate.endpoint.Operation; import org.springframework.core.annotation.AliasFor; @@ -51,6 +52,7 @@ import org.springframework.core.annotation.AliasFor; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented +@Reflective public @interface EndpointExtension { /** diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/OperationReflectiveProcessor.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/OperationReflectiveProcessor.java new file mode 100644 index 0000000000..55329c0748 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/OperationReflectiveProcessor.java @@ -0,0 +1,74 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.endpoint.annotation; + +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Method; +import java.lang.reflect.Type; + +import org.springframework.aot.hint.ExecutableMode; +import org.springframework.aot.hint.ReflectionHints; +import org.springframework.aot.hint.annotation.ReflectiveProcessor; +import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse; +import org.springframework.context.aot.BindingReflectionHintsRegistrar; +import org.springframework.core.ResolvableType; +import org.springframework.core.io.Resource; + +/** + * Processor which registers the annotated operation method and its return type for + * reflection. + * + * @author Moritz Halbritter + */ +class OperationReflectiveProcessor implements ReflectiveProcessor { + + private final BindingReflectionHintsRegistrar bindingRegistrar = new BindingReflectionHintsRegistrar(); + + @Override + public void registerReflectionHints(ReflectionHints hints, AnnotatedElement element) { + if (!(element instanceof Method method)) { + throw new IllegalArgumentException("This processor can only be invoked for annotated methods"); + } + hints.registerMethod(method, (hint) -> hint.setModes(ExecutableMode.INVOKE)); + registerReturnValueHints(hints, method); + } + + private void registerReturnValueHints(ReflectionHints hints, Method method) { + ResolvableType returnType = ResolvableType.forMethodReturnType(method); + if (WebEndpointResponse.class.isAssignableFrom(method.getReturnType())) { + registerWebEndpointResponse(hints, returnType); + } + else { + registerReflectionHints(hints, returnType.getType()); + } + } + + private void registerWebEndpointResponse(ReflectionHints hints, ResolvableType returnType) { + ResolvableType genericParameter = returnType.getGeneric(0); + if (genericParameter.getRawClass() != null) { + registerReflectionHints(hints, genericParameter.getType()); + } + } + + private void registerReflectionHints(ReflectionHints hints, Type type) { + if (type.equals(Resource.class)) { + return; + } + this.bindingRegistrar.registerReflectionHints(hints, type); + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/ReadOperation.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/ReadOperation.java index 1997393171..ead39bc309 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/ReadOperation.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/ReadOperation.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.springframework.aot.hint.annotation.Reflective; import org.springframework.boot.actuate.endpoint.Producible; /** @@ -33,6 +34,7 @@ import org.springframework.boot.actuate.endpoint.Producible; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented +@Reflective(OperationReflectiveProcessor.class) public @interface ReadOperation { /** diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/WriteOperation.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/WriteOperation.java index df39b75fec..b9a63c4f69 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/WriteOperation.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/WriteOperation.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.springframework.aot.hint.annotation.Reflective; import org.springframework.boot.actuate.endpoint.Producible; /** @@ -33,6 +34,7 @@ import org.springframework.boot.actuate.endpoint.Producible; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented +@Reflective(OperationReflectiveProcessor.class) public @interface WriteOperation { /** diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/jmx/annotation/JmxEndpointDiscoverer.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/jmx/annotation/JmxEndpointDiscoverer.java index f9106e3fe1..7dde444a5c 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/jmx/annotation/JmxEndpointDiscoverer.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/jmx/annotation/JmxEndpointDiscoverer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,9 @@ package org.springframework.boot.actuate.endpoint.jmx.annotation; import java.util.Collection; +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; import org.springframework.boot.actuate.endpoint.EndpointFilter; import org.springframework.boot.actuate.endpoint.EndpointId; import org.springframework.boot.actuate.endpoint.annotation.DiscoveredOperationMethod; @@ -28,7 +31,9 @@ import org.springframework.boot.actuate.endpoint.invoke.ParameterValueMapper; import org.springframework.boot.actuate.endpoint.jmx.ExposableJmxEndpoint; import org.springframework.boot.actuate.endpoint.jmx.JmxEndpointsSupplier; import org.springframework.boot.actuate.endpoint.jmx.JmxOperation; +import org.springframework.boot.actuate.endpoint.jmx.annotation.JmxEndpointDiscoverer.JmxEndpointDiscovererRuntimeHints; import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.ImportRuntimeHints; /** * {@link EndpointDiscoverer} for {@link ExposableJmxEndpoint JMX endpoints}. @@ -36,6 +41,7 @@ import org.springframework.context.ApplicationContext; * @author Phillip Webb * @since 2.0.0 */ +@ImportRuntimeHints(JmxEndpointDiscovererRuntimeHints.class) public class JmxEndpointDiscoverer extends EndpointDiscoverer implements JmxEndpointsSupplier { @@ -69,4 +75,14 @@ public class JmxEndpointDiscoverer extends EndpointDiscoverer "MBean call '" + operation.getName() + "'"); } + static class JmxEndpointDiscovererRuntimeHints implements RuntimeHintsRegistrar { + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + hints.reflection().registerType(JmxEndpointFilter.class, + (hint) -> hint.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)); + } + + } + } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/annotation/ControllerEndpointDiscoverer.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/annotation/ControllerEndpointDiscoverer.java index 1b991c71ff..43b6181207 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/annotation/ControllerEndpointDiscoverer.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/annotation/ControllerEndpointDiscoverer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,9 @@ import java.util.Collection; import java.util.Collections; import java.util.List; +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; import org.springframework.boot.actuate.endpoint.EndpointFilter; import org.springframework.boot.actuate.endpoint.EndpointId; import org.springframework.boot.actuate.endpoint.Operation; @@ -28,7 +31,9 @@ import org.springframework.boot.actuate.endpoint.annotation.EndpointDiscoverer; import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker; import org.springframework.boot.actuate.endpoint.invoke.ParameterValueMapper; import org.springframework.boot.actuate.endpoint.web.PathMapper; +import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointDiscoverer.ControllerEndpointDiscovererRuntimeHints; import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.ImportRuntimeHints; import org.springframework.core.annotation.MergedAnnotations; import org.springframework.core.annotation.MergedAnnotations.SearchStrategy; @@ -39,6 +44,7 @@ import org.springframework.core.annotation.MergedAnnotations.SearchStrategy; * @author Phillip Webb * @since 2.0.0 */ +@ImportRuntimeHints(ControllerEndpointDiscovererRuntimeHints.class) public class ControllerEndpointDiscoverer extends EndpointDiscoverer implements ControllerEndpointsSupplier { @@ -80,4 +86,14 @@ public class ControllerEndpointDiscoverer extends EndpointDiscoverer hint.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)); + } + + } + } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/annotation/ServletEndpointDiscoverer.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/annotation/ServletEndpointDiscoverer.java index 0349c4a3d1..366a55210a 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/annotation/ServletEndpointDiscoverer.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/annotation/ServletEndpointDiscoverer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,9 @@ import java.util.Collection; import java.util.Collections; import java.util.List; +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; import org.springframework.boot.actuate.endpoint.EndpointFilter; import org.springframework.boot.actuate.endpoint.EndpointId; import org.springframework.boot.actuate.endpoint.Operation; @@ -29,7 +32,9 @@ import org.springframework.boot.actuate.endpoint.invoke.OperationInvoker; import org.springframework.boot.actuate.endpoint.invoke.ParameterValueMapper; import org.springframework.boot.actuate.endpoint.web.ExposableServletEndpoint; import org.springframework.boot.actuate.endpoint.web.PathMapper; +import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointDiscoverer.ServletEndpointDiscovererRuntimeHints; import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.ImportRuntimeHints; import org.springframework.core.annotation.MergedAnnotations; import org.springframework.core.annotation.MergedAnnotations.SearchStrategy; @@ -39,6 +44,7 @@ import org.springframework.core.annotation.MergedAnnotations.SearchStrategy; * @author Phillip Webb * @since 2.0.0 */ +@ImportRuntimeHints(ServletEndpointDiscovererRuntimeHints.class) public class ServletEndpointDiscoverer extends EndpointDiscoverer implements ServletEndpointsSupplier { @@ -79,4 +85,14 @@ public class ServletEndpointDiscoverer extends EndpointDiscoverer hint.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)); + } + + } + } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/annotation/WebEndpointDiscoverer.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/annotation/WebEndpointDiscoverer.java index 42d4d631b4..3c3004e762 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/annotation/WebEndpointDiscoverer.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/annotation/WebEndpointDiscoverer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,9 @@ package org.springframework.boot.actuate.endpoint.web.annotation; import java.util.Collection; import java.util.List; +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; import org.springframework.boot.actuate.endpoint.EndpointFilter; import org.springframework.boot.actuate.endpoint.EndpointId; import org.springframework.boot.actuate.endpoint.annotation.DiscoveredOperationMethod; @@ -32,7 +35,9 @@ import org.springframework.boot.actuate.endpoint.web.PathMapper; import org.springframework.boot.actuate.endpoint.web.WebEndpointsSupplier; import org.springframework.boot.actuate.endpoint.web.WebOperation; import org.springframework.boot.actuate.endpoint.web.WebOperationRequestPredicate; +import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointDiscoverer.WebEndpointDiscovererRuntimeHints; import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.ImportRuntimeHints; /** * {@link EndpointDiscoverer} for {@link ExposableWebEndpoint web endpoints}. @@ -40,6 +45,7 @@ import org.springframework.context.ApplicationContext; * @author Phillip Webb * @since 2.0.0 */ +@ImportRuntimeHints(WebEndpointDiscovererRuntimeHints.class) public class WebEndpointDiscoverer extends EndpointDiscoverer implements WebEndpointsSupplier { @@ -87,4 +93,14 @@ public class WebEndpointDiscoverer extends EndpointDiscoverer "web request predicate " + operation.getRequestPredicate()); } + static class WebEndpointDiscovererRuntimeHints implements RuntimeHintsRegistrar { + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + hints.reflection().registerType(WebEndpointFilter.class, + (hint) -> hint.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)); + } + + } + } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMapping.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMapping.java index 1c0e1ab180..0c0e38ce9a 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMapping.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMapping.java @@ -22,6 +22,7 @@ import java.security.Principal; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import java.util.function.Supplier; @@ -30,6 +31,10 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.core.scheduler.Schedulers; +import org.springframework.aot.hint.ExecutableMode; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; +import org.springframework.aot.hint.TypeReference; import org.springframework.boot.actuate.endpoint.InvalidEndpointRequestException; import org.springframework.boot.actuate.endpoint.InvocationContext; import org.springframework.boot.actuate.endpoint.OperationArgumentResolver; @@ -44,7 +49,9 @@ import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse; import org.springframework.boot.actuate.endpoint.web.WebOperation; import org.springframework.boot.actuate.endpoint.web.WebOperationRequestPredicate; import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; +import org.springframework.boot.actuate.endpoint.web.reactive.AbstractWebFluxEndpointHandlerMapping.AbstractWebFluxEndpointHandlerMappingRuntimeHints; import org.springframework.boot.web.context.WebServerApplicationContext; +import org.springframework.context.annotation.ImportRuntimeHints; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -80,6 +87,7 @@ import org.springframework.web.util.pattern.PathPattern; * @author Brian Clozel * @since 2.0.0 */ +@ImportRuntimeHints(AbstractWebFluxEndpointHandlerMappingRuntimeHints.class) public abstract class AbstractWebFluxEndpointHandlerMapping extends RequestMappingInfoHandlerMapping { private final EndpointMapping endpointMapping; @@ -484,4 +492,19 @@ public abstract class AbstractWebFluxEndpointHandlerMapping extends RequestMappi } + static class AbstractWebFluxEndpointHandlerMappingRuntimeHints implements RuntimeHintsRegistrar { + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + hints.reflection().registerType(WriteOperationHandler.class, + (hint) -> hint.withMethod("handle", + List.of(TypeReference.of(ServerWebExchange.class), TypeReference.of(Map.class)), + (method) -> method.withMode(ExecutableMode.INVOKE))); + hints.reflection().registerType(ReadOperationHandler.class, + (hint) -> hint.withMethod("handle", List.of(TypeReference.of(ServerWebExchange.class)), + (method) -> method.withMode(ExecutableMode.INVOKE))); + } + + } + } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointHandlerMapping.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointHandlerMapping.java index 2b0a7ae83f..c18cc203d2 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointHandlerMapping.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointHandlerMapping.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,14 +18,22 @@ package org.springframework.boot.actuate.endpoint.web.reactive; import java.util.Collection; import java.util.Collections; +import java.util.List; import java.util.Map; +import org.springframework.aot.hint.ExecutableMode; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; +import org.springframework.aot.hint.TypeReference; import org.springframework.beans.factory.InitializingBean; import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver; import org.springframework.boot.actuate.endpoint.web.EndpointMapping; import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint; 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.web.bind.annotation.ResponseBody; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.reactive.HandlerMapping; @@ -41,6 +49,7 @@ import org.springframework.web.util.UriComponentsBuilder; * @author Brian Clozel * @since 2.0.0 */ +@ImportRuntimeHints(WebFluxEndpointHandlerMappingRuntimeHints.class) public class WebFluxEndpointHandlerMapping extends AbstractWebFluxEndpointHandlerMapping implements InitializingBean { private final EndpointLinksResolver linksResolver; @@ -89,4 +98,19 @@ public class WebFluxEndpointHandlerMapping extends AbstractWebFluxEndpointHandle } + static class WebFluxEndpointHandlerMappingRuntimeHints implements RuntimeHintsRegistrar { + + private final BindingReflectionHintsRegistrar bindingRegistrar = new BindingReflectionHintsRegistrar(); + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + hints.reflection().registerType(WebFluxLinksHandler.class, + (hint) -> hint.onReachableType(TypeReference.of(WebFluxLinksHandler.class)).withMethod("links", + List.of(TypeReference.of(ServerWebExchange.class)), + (method) -> method.setModes(ExecutableMode.INVOKE))); + this.bindingRegistrar.registerReflectionHints(hints.reflection(), Link.class); + } + + } + } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/AbstractWebMvcEndpointHandlerMapping.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/AbstractWebMvcEndpointHandlerMapping.java index 3bc469d87c..434ceca029 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/AbstractWebMvcEndpointHandlerMapping.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/AbstractWebMvcEndpointHandlerMapping.java @@ -32,6 +32,10 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import reactor.core.publisher.Flux; +import org.springframework.aot.hint.ExecutableMode; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; +import org.springframework.aot.hint.TypeReference; import org.springframework.beans.factory.InitializingBean; import org.springframework.boot.actuate.endpoint.InvalidEndpointRequestException; import org.springframework.boot.actuate.endpoint.InvocationContext; @@ -46,7 +50,9 @@ import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse; import org.springframework.boot.actuate.endpoint.web.WebOperation; import org.springframework.boot.actuate.endpoint.web.WebOperationRequestPredicate; import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; +import org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping.AbstractWebMvcEndpointHandlerMappingRuntimeHints; import org.springframework.boot.web.context.WebServerApplicationContext; +import org.springframework.context.annotation.ImportRuntimeHints; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; @@ -80,6 +86,7 @@ import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMappi * @author Brian Clozel * @since 2.0.0 */ +@ImportRuntimeHints(AbstractWebMvcEndpointHandlerMappingRuntimeHints.class) public abstract class AbstractWebMvcEndpointHandlerMapping extends RequestMappingInfoHandlerMapping implements InitializingBean { @@ -476,4 +483,16 @@ public abstract class AbstractWebMvcEndpointHandlerMapping extends RequestMappin } + static class AbstractWebMvcEndpointHandlerMappingRuntimeHints implements RuntimeHintsRegistrar { + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + hints.reflection().registerType(OperationHandler.class, + (hint) -> hint.withMethod("handle", + List.of(TypeReference.of(HttpServletRequest.class), TypeReference.of(Map.class)), + (method) -> method.withMode(ExecutableMode.INVOKE))); + } + + } + } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMapping.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMapping.java index a6f3cfb96d..3f85334151 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMapping.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMapping.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,16 +18,24 @@ package org.springframework.boot.actuate.endpoint.web.servlet; import java.util.Collection; import java.util.Collections; +import java.util.List; import java.util.Map; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import org.springframework.aot.hint.ExecutableMode; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; +import org.springframework.aot.hint.TypeReference; import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver; import org.springframework.boot.actuate.endpoint.web.EndpointMapping; import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; import org.springframework.boot.actuate.endpoint.web.ExposableWebEndpoint; 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.web.bind.annotation.ResponseBody; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.servlet.HandlerMapping; @@ -40,6 +48,7 @@ import org.springframework.web.servlet.HandlerMapping; * @author Phillip Webb * @since 2.0.0 */ +@ImportRuntimeHints(WebMvcEndpointHandlerMappingRuntimeHints.class) public class WebMvcEndpointHandlerMapping extends AbstractWebMvcEndpointHandlerMapping { private final EndpointLinksResolver linksResolver; @@ -86,4 +95,20 @@ public class WebMvcEndpointHandlerMapping extends AbstractWebMvcEndpointHandlerM } + static class WebMvcEndpointHandlerMappingRuntimeHints implements RuntimeHintsRegistrar { + + private final BindingReflectionHintsRegistrar bindingRegistrar = new BindingReflectionHintsRegistrar(); + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + hints.reflection().registerType(WebMvcLinksHandler.class, + (hint) -> hint.onReachableType(TypeReference.of(WebMvcLinksHandler.class)).withMethod("links", + List.of(TypeReference.of(HttpServletRequest.class), + TypeReference.of(HttpServletResponse.class)), + (method) -> method.setModes(ExecutableMode.INVOKE))); + this.bindingRegistrar.registerReflectionHints(hints.reflection(), Link.class); + } + + } + } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpointWebExtension.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpointWebExtension.java index e019e3e9bf..13f940a5e1 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpointWebExtension.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpointWebExtension.java @@ -21,6 +21,8 @@ import java.util.Arrays; import java.util.Map; import java.util.Set; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; import org.springframework.boot.actuate.endpoint.ApiVersion; import org.springframework.boot.actuate.endpoint.SecurityContext; import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; @@ -29,6 +31,9 @@ import org.springframework.boot.actuate.endpoint.annotation.Selector.Match; import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse; import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; import org.springframework.boot.actuate.endpoint.web.annotation.EndpointWebExtension; +import org.springframework.boot.actuate.health.HealthEndpointWebExtension.HealthEndpointWebExtensionRuntimeHints; +import org.springframework.context.annotation.ImportRuntimeHints; +import org.springframework.context.aot.BindingReflectionHintsRegistrar; /** * {@link EndpointWebExtension @EndpointWebExtension} for the {@link HealthEndpoint}. @@ -44,6 +49,7 @@ import org.springframework.boot.actuate.endpoint.web.annotation.EndpointWebExten * @since 2.0.0 */ @EndpointWebExtension(endpoint = HealthEndpoint.class) +@ImportRuntimeHints(HealthEndpointWebExtensionRuntimeHints.class) public class HealthEndpointWebExtension extends HealthEndpointSupport { private static final String[] NO_PATH = {}; @@ -110,4 +116,16 @@ public class HealthEndpointWebExtension extends HealthEndpointSupport { public BuildInfoContributor(BuildProperties properties) { @@ -56,4 +62,15 @@ public class BuildInfoContributor extends InfoPropertiesInfoContributor { public GitInfoContributor(GitProperties properties) { @@ -68,4 +74,15 @@ public class GitInfoContributor extends InfoPropertiesInfoContributor T getFormattedThreadDump(Function formatter) { - return formatter.apply(ManagementFactory.getThreadMXBean().dumpAllThreads(true, true)); + ThreadDumper threadDumper = createThreadDumper(); + return formatter.apply(threadDumper.dumpAllThreads()); + } + + private ThreadDumper createThreadDumper() { + if (NativeDetector.inNativeImage()) { + throw new ThreadDumperUnavailableException("Running in native image"); + } + return new ThreadMXBeanThreadDumper(); + } + + private interface ThreadDumper { + + ThreadInfo[] dumpAllThreads(); + + } + + private static class ThreadMXBeanThreadDumper implements ThreadDumper { + + @Override + public ThreadInfo[] dumpAllThreads() { + return ManagementFactory.getThreadMXBean().dumpAllThreads(true, true); + } + + } + + /** + * Exception to be thrown if the {@link ThreadDumper} cannot be created. + */ + static class ThreadDumperUnavailableException extends RuntimeException { + + ThreadDumperUnavailableException(String message) { + super(message); + } + } /** diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/management/ThreadDumpEndpointWebExtension.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/management/ThreadDumpEndpointWebExtension.java new file mode 100644 index 0000000000..76a1f38a30 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/management/ThreadDumpEndpointWebExtension.java @@ -0,0 +1,60 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.management; + +import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; +import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse; +import org.springframework.boot.actuate.endpoint.web.annotation.EndpointWebExtension; +import org.springframework.boot.actuate.management.ThreadDumpEndpoint.ThreadDumpDescriptor; +import org.springframework.boot.actuate.management.ThreadDumpEndpoint.ThreadDumperUnavailableException; + +/** + * {@link EndpointWebExtension @EndpointWebExtension} for the {@link ThreadDumpEndpoint}. + * + * @author Moritz Halbritter + * @since 3.0.0 + */ +@EndpointWebExtension(endpoint = ThreadDumpEndpoint.class) +public class ThreadDumpEndpointWebExtension { + + private final ThreadDumpEndpoint delegate; + + public ThreadDumpEndpointWebExtension(ThreadDumpEndpoint delegate) { + this.delegate = delegate; + } + + @ReadOperation + public WebEndpointResponse threadDump() { + try { + return new WebEndpointResponse<>(this.delegate.threadDump()); + } + catch (ThreadDumperUnavailableException ex) { + return new WebEndpointResponse<>(WebEndpointResponse.STATUS_SERVICE_UNAVAILABLE); + } + } + + @ReadOperation(produces = "text/plain;charset=UTF-8") + public WebEndpointResponse textThreadDump() { + try { + return new WebEndpointResponse<>(this.delegate.textThreadDump()); + } + catch (ThreadDumperUnavailableException ex) { + return new WebEndpointResponse<>(WebEndpointResponse.STATUS_SERVICE_UNAVAILABLE); + } + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProvider.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProvider.java index 92894ec0f4..a7f4f26de5 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProvider.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProvider.java @@ -17,12 +17,19 @@ package org.springframework.boot.actuate.metrics.cache; import java.lang.reflect.Method; +import java.util.List; import com.hazelcast.spring.cache.HazelcastCache; import io.micrometer.core.instrument.Tag; import io.micrometer.core.instrument.binder.MeterBinder; import io.micrometer.core.instrument.binder.cache.HazelcastCacheMetrics; +import org.springframework.aot.hint.ExecutableMode; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; +import org.springframework.aot.hint.TypeReference; +import org.springframework.boot.actuate.metrics.cache.HazelcastCacheMeterBinderProvider.HazelcastCacheMeterBinderProviderRuntimeHints; +import org.springframework.context.annotation.ImportRuntimeHints; import org.springframework.util.ReflectionUtils; /** @@ -31,6 +38,7 @@ import org.springframework.util.ReflectionUtils; * @author Stephane Nicoll * @since 2.0.0 */ +@ImportRuntimeHints(HazelcastCacheMeterBinderProviderRuntimeHints.class) public class HazelcastCacheMeterBinderProvider implements CacheMeterBinderProvider { @Override @@ -56,4 +64,18 @@ public class HazelcastCacheMeterBinderProvider implements CacheMeterBinderProvid } } + static class HazelcastCacheMeterBinderProviderRuntimeHints implements RuntimeHintsRegistrar { + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + hints.reflection().registerType(HazelcastCache.class, (hint) -> hint.withMethod("getNativeCache", List.of(), + (method) -> method.withMode(ExecutableMode.INVOKE))); + hints.reflection().registerType(HazelcastCacheMetrics.class, + (hint) -> hint.withConstructor( + List.of(TypeReference.of(Object.class), TypeReference.of(Iterable.class)), + (ctor) -> ctor.withMode(ExecutableMode.INVOKE))); + } + + } + } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/quartz/QuartzEndpointWebExtension.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/quartz/QuartzEndpointWebExtension.java index ab52b8707d..e3468512e2 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/quartz/QuartzEndpointWebExtension.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/quartz/QuartzEndpointWebExtension.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,11 +18,19 @@ package org.springframework.boot.actuate.quartz; import org.quartz.SchedulerException; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; import org.springframework.boot.actuate.endpoint.annotation.Selector; import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse; import org.springframework.boot.actuate.endpoint.web.annotation.EndpointWebExtension; import org.springframework.boot.actuate.quartz.QuartzEndpoint.QuartzGroups; +import org.springframework.boot.actuate.quartz.QuartzEndpoint.QuartzJobDetails; +import org.springframework.boot.actuate.quartz.QuartzEndpoint.QuartzJobGroupSummary; +import org.springframework.boot.actuate.quartz.QuartzEndpoint.QuartzTriggerGroupSummary; +import org.springframework.boot.actuate.quartz.QuartzEndpointWebExtension.QuartzEndpointWebExtensionRuntimeHints; +import org.springframework.context.annotation.ImportRuntimeHints; +import org.springframework.context.aot.BindingReflectionHintsRegistrar; /** * {@link EndpointWebExtension @EndpointWebExtension} for the {@link QuartzEndpoint}. @@ -31,6 +39,7 @@ import org.springframework.boot.actuate.quartz.QuartzEndpoint.QuartzGroups; * @since 2.5.0 */ @EndpointWebExtension(endpoint = QuartzEndpoint.class) +@ImportRuntimeHints(QuartzEndpointWebExtensionRuntimeHints.class) public class QuartzEndpointWebExtension { private final QuartzEndpoint delegate; @@ -84,4 +93,16 @@ public class QuartzEndpointWebExtension { } + static class QuartzEndpointWebExtensionRuntimeHints implements RuntimeHintsRegistrar { + + private final BindingReflectionHintsRegistrar bindingRegistrar = new BindingReflectionHintsRegistrar(); + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + this.bindingRegistrar.registerReflectionHints(hints.reflection(), QuartzGroups.class, + QuartzJobDetails.class, QuartzJobGroupSummary.class, QuartzTriggerGroupSummary.class); + } + + } + } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/scheduling/ScheduledTasksEndpoint.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/scheduling/ScheduledTasksEndpoint.java index 18e87b1684..00f79598a5 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/scheduling/ScheduledTasksEndpoint.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/scheduling/ScheduledTasksEndpoint.java @@ -26,8 +26,13 @@ import java.util.Objects; import java.util.function.Function; import java.util.stream.Collectors; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; +import org.springframework.boot.actuate.scheduling.ScheduledTasksEndpoint.ScheduledTasksEndpointRuntimeHints; +import org.springframework.context.annotation.ImportRuntimeHints; +import org.springframework.context.aot.BindingReflectionHintsRegistrar; import org.springframework.scheduling.Trigger; import org.springframework.scheduling.config.CronTask; import org.springframework.scheduling.config.FixedDelayTask; @@ -49,6 +54,7 @@ import org.springframework.scheduling.support.ScheduledMethodRunnable; * @since 2.0.0 */ @Endpoint(id = "scheduledtasks") +@ImportRuntimeHints(ScheduledTasksEndpointRuntimeHints.class) public class ScheduledTasksEndpoint { private final Collection scheduledTaskHolders; @@ -295,4 +301,16 @@ public class ScheduledTasksEndpoint { } + static class ScheduledTasksEndpointRuntimeHints implements RuntimeHintsRegistrar { + + private final BindingReflectionHintsRegistrar bindingRegistrar = new BindingReflectionHintsRegistrar(); + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + this.bindingRegistrar.registerReflectionHints(hints.reflection(), FixedRateTaskDescription.class, + FixedDelayTaskDescription.class, CronTaskDescription.class, CustomTriggerTaskDescription.class); + } + + } + } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/startup/StartupEndpoint.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/startup/StartupEndpoint.java index 51b0412a65..e0c03227aa 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/startup/StartupEndpoint.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/startup/StartupEndpoint.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,12 +16,18 @@ package org.springframework.boot.actuate.startup; +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; +import org.springframework.aot.hint.TypeReference; import org.springframework.boot.SpringBootVersion; import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; import org.springframework.boot.actuate.endpoint.annotation.WriteOperation; +import org.springframework.boot.actuate.startup.StartupEndpoint.StartupEndpointRuntimeHints; import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup; import org.springframework.boot.context.metrics.buffering.StartupTimeline; +import org.springframework.context.annotation.ImportRuntimeHints; /** * {@link Endpoint @Endpoint} to expose the timeline of the @@ -33,6 +39,7 @@ import org.springframework.boot.context.metrics.buffering.StartupTimeline; * @since 2.4.0 */ @Endpoint(id = "startup") +@ImportRuntimeHints(StartupEndpointRuntimeHints.class) public class StartupEndpoint { private final BufferingApplicationStartup applicationStartup; @@ -83,4 +90,26 @@ public class StartupEndpoint { } + static class StartupEndpointRuntimeHints implements RuntimeHintsRegistrar { + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + hints.reflection().registerType( + TypeReference + .of("org.springframework.boot.context.metrics.buffering.BufferedStartupStep$DefaultTag"), + (hint) -> hint + .onReachableType(TypeReference + .of("org.springframework.boot.context.metrics.buffering.BufferedStartupStep")) + .withMembers(MemberCategory.INVOKE_PUBLIC_METHODS)); + hints.reflection().registerType( + TypeReference + .of("org.springframework.core.metrics.jfr.FlightRecorderStartupStep$FlightRecorderTag"), + (hint) -> hint + .onReachableType( + TypeReference.of("org.springframework.core.metrics.jfr.FlightRecorderStartupStep")) + .withMembers(MemberCategory.INVOKE_PUBLIC_METHODS)); + } + + } + } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/reactive/DispatcherHandlersMappingDescriptionProvider.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/reactive/DispatcherHandlersMappingDescriptionProvider.java index 49ef361185..67d6ad941a 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/reactive/DispatcherHandlersMappingDescriptionProvider.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/reactive/DispatcherHandlersMappingDescriptionProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,9 +28,14 @@ import java.util.stream.Stream; import reactor.core.publisher.Mono; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; import org.springframework.boot.actuate.web.mappings.HandlerMethodDescription; import org.springframework.boot.actuate.web.mappings.MappingDescriptionProvider; +import org.springframework.boot.actuate.web.mappings.reactive.DispatcherHandlersMappingDescriptionProvider.DispatcherHandlersMappingDescriptionProviderRuntimeHints; import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.ImportRuntimeHints; +import org.springframework.context.aot.BindingReflectionHintsRegistrar; import org.springframework.core.io.Resource; import org.springframework.web.method.HandlerMethod; import org.springframework.web.reactive.DispatcherHandler; @@ -53,6 +58,7 @@ import org.springframework.web.util.pattern.PathPattern; * @author Andy Wilkinson * @since 2.0.0 */ +@ImportRuntimeHints(DispatcherHandlersMappingDescriptionProviderRuntimeHints.class) public class DispatcherHandlersMappingDescriptionProvider implements MappingDescriptionProvider { private static final List> descriptionProviders = Arrays @@ -194,4 +200,16 @@ public class DispatcherHandlersMappingDescriptionProvider implements MappingDesc } + static class DispatcherHandlersMappingDescriptionProviderRuntimeHints implements RuntimeHintsRegistrar { + + private final BindingReflectionHintsRegistrar bindingRegistrar = new BindingReflectionHintsRegistrar(); + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + this.bindingRegistrar.registerReflectionHints(hints.reflection(), + DispatcherHandlerMappingDescription.class); + } + + } + } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/DispatcherServletsMappingDescriptionProvider.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/DispatcherServletsMappingDescriptionProvider.java index 49b7e2ba3e..18592a7a9e 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/DispatcherServletsMappingDescriptionProvider.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/DispatcherServletsMappingDescriptionProvider.java @@ -28,10 +28,15 @@ import java.util.stream.Stream; import jakarta.servlet.Servlet; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; import org.springframework.boot.actuate.web.mappings.HandlerMethodDescription; import org.springframework.boot.actuate.web.mappings.MappingDescriptionProvider; +import org.springframework.boot.actuate.web.mappings.servlet.DispatcherServletsMappingDescriptionProvider.DispatcherServletsMappingDescriptionProviderRuntimeHints; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.ImportRuntimeHints; +import org.springframework.context.aot.BindingReflectionHintsRegistrar; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.DispatcherServlet; @@ -49,6 +54,7 @@ import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMappi * @author Stephane Nicoll * @since 2.0.0 */ +@ImportRuntimeHints(DispatcherServletsMappingDescriptionProviderRuntimeHints.class) public class DispatcherServletsMappingDescriptionProvider implements MappingDescriptionProvider { private static final List> descriptionProviders; @@ -195,4 +201,16 @@ public class DispatcherServletsMappingDescriptionProvider implements MappingDesc } + static class DispatcherServletsMappingDescriptionProviderRuntimeHints implements RuntimeHintsRegistrar { + + private final BindingReflectionHintsRegistrar bindingRegistrar = new BindingReflectionHintsRegistrar(); + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + this.bindingRegistrar.registerReflectionHints(hints.reflection(), + DispatcherServletMappingDescription.class); + } + + } + } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/FiltersMappingDescriptionProvider.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/FiltersMappingDescriptionProvider.java index c091d2dcfa..a03ad253c8 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/FiltersMappingDescriptionProvider.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/FiltersMappingDescriptionProvider.java @@ -23,8 +23,13 @@ import java.util.stream.Collectors; import jakarta.servlet.Filter; import jakarta.servlet.ServletContext; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; import org.springframework.boot.actuate.web.mappings.MappingDescriptionProvider; +import org.springframework.boot.actuate.web.mappings.servlet.FiltersMappingDescriptionProvider.FiltersMappingDescriptionProviderRuntimeHints; import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.ImportRuntimeHints; +import org.springframework.context.aot.BindingReflectionHintsRegistrar; import org.springframework.web.context.WebApplicationContext; /** @@ -34,6 +39,7 @@ import org.springframework.web.context.WebApplicationContext; * @author Andy Wilkinson * @since 2.0.0 */ +@ImportRuntimeHints(FiltersMappingDescriptionProviderRuntimeHints.class) public class FiltersMappingDescriptionProvider implements MappingDescriptionProvider { @Override @@ -50,4 +56,16 @@ public class FiltersMappingDescriptionProvider implements MappingDescriptionProv return "servletFilters"; } + static class FiltersMappingDescriptionProviderRuntimeHints implements RuntimeHintsRegistrar { + + private final BindingReflectionHintsRegistrar bindingRegistrar = new BindingReflectionHintsRegistrar(); + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + this.bindingRegistrar.registerReflectionHints(hints.reflection(), + FilterRegistrationMappingDescription.class); + } + + } + } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/ServletsMappingDescriptionProvider.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/ServletsMappingDescriptionProvider.java index 8c36e61811..d9fa2a7e42 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/ServletsMappingDescriptionProvider.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/web/mappings/servlet/ServletsMappingDescriptionProvider.java @@ -23,8 +23,13 @@ import java.util.stream.Collectors; import jakarta.servlet.Servlet; import jakarta.servlet.ServletContext; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; import org.springframework.boot.actuate.web.mappings.MappingDescriptionProvider; +import org.springframework.boot.actuate.web.mappings.servlet.ServletsMappingDescriptionProvider.ServletsMappingDescriptionProviderRuntimeHints; import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.ImportRuntimeHints; +import org.springframework.context.aot.BindingReflectionHintsRegistrar; import org.springframework.web.context.WebApplicationContext; /** @@ -34,6 +39,7 @@ import org.springframework.web.context.WebApplicationContext; * @author Andy Wilkinson * @since 2.0.0 */ +@ImportRuntimeHints(ServletsMappingDescriptionProviderRuntimeHints.class) public class ServletsMappingDescriptionProvider implements MappingDescriptionProvider { @Override @@ -50,4 +56,16 @@ public class ServletsMappingDescriptionProvider implements MappingDescriptionPro return "servlets"; } + static class ServletsMappingDescriptionProviderRuntimeHints implements RuntimeHintsRegistrar { + + private final BindingReflectionHintsRegistrar bindingRegistrar = new BindingReflectionHintsRegistrar(); + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + this.bindingRegistrar.registerReflectionHints(hints.reflection(), + ServletRegistrationMappingDescription.class); + } + + } + } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/aot/ActuatorAnnotationsRuntimeHintsRegistrarTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/aot/ActuatorAnnotationsRuntimeHintsRegistrarTests.java new file mode 100644 index 0000000000..9da4482ae0 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/aot/ActuatorAnnotationsRuntimeHintsRegistrarTests.java @@ -0,0 +1,73 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.aot; + +import java.util.Set; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.actuate.endpoint.annotation.DeleteOperation; +import org.springframework.boot.actuate.endpoint.annotation.Endpoint; +import org.springframework.boot.actuate.endpoint.annotation.EndpointExtension; +import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; +import org.springframework.boot.actuate.endpoint.annotation.WriteOperation; +import org.springframework.core.annotation.SynthesizedAnnotation; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link ActuatorAnnotationsRuntimeHintsRegistrar}. + * + * @author Moritz Halbritter + */ +class ActuatorAnnotationsRuntimeHintsRegistrarTests { + + private final ActuatorAnnotationsRuntimeHintsRegistrar sut = new ActuatorAnnotationsRuntimeHintsRegistrar(); + + private RuntimeHints runtimeHints; + + @BeforeEach + void setUp() { + this.runtimeHints = new RuntimeHints(); + this.sut.registerHints(this.runtimeHints, getClass().getClassLoader()); + } + + @Test + void shouldRegisterReflectionHints() { + Set> annotations = Set.of(Endpoint.class, ReadOperation.class, WriteOperation.class, + DeleteOperation.class, EndpointExtension.class); + for (Class annotation : annotations) { + assertThat(RuntimeHintsPredicates.reflection().onType(annotation) + .withAnyMemberCategory(MemberCategory.INVOKE_DECLARED_METHODS)).accepts(this.runtimeHints); + } + } + + @Test + void shouldRegisterProxyHints() { + Set> synthesizedAnnotations = Set.of(Endpoint.class, EndpointExtension.class); + for (Class synthesizedAnnotation : synthesizedAnnotations) { + assertThat( + RuntimeHintsPredicates.proxies().forInterfaces(synthesizedAnnotation, SynthesizedAnnotation.class)) + .accepts(this.runtimeHints); + } + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/annotation/OperationReflectiveProcessorTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/annotation/OperationReflectiveProcessorTests.java new file mode 100644 index 0000000000..dac08b3317 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/annotation/OperationReflectiveProcessorTests.java @@ -0,0 +1,132 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.endpoint.annotation; + +import java.lang.reflect.Method; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse; +import org.springframework.core.io.Resource; +import org.springframework.util.ReflectionUtils; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link OperationReflectiveProcessor}. + * + * @author Moritz Halbritter + */ +class OperationReflectiveProcessorTests { + + private final OperationReflectiveProcessor sut = new OperationReflectiveProcessor(); + + private RuntimeHints runtimeHints; + + @BeforeEach + void setUp() { + this.runtimeHints = new RuntimeHints(); + } + + @Test + void shouldRegisterMethodAsInvokable() { + Method method = ReflectionUtils.findMethod(Methods.class, "string"); + runProcessor(method); + assertThat(RuntimeHintsPredicates.reflection().onMethod(method)).accepts(this.runtimeHints); + } + + @Test + void shouldRegisterReturnType() { + Method method = ReflectionUtils.findMethod(Methods.class, "dto"); + runProcessor(method); + assertThat(RuntimeHintsPredicates.reflection().onType(Dto.class) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) + .accepts(this.runtimeHints); + assertThat(RuntimeHintsPredicates.reflection().onType(NestedDto.class) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) + .accepts(this.runtimeHints); + } + + @Test + void shouldRegisterWebEndpointResponseReturnType() { + Method method = ReflectionUtils.findMethod(Methods.class, "webEndpointResponse"); + runProcessor(method); + assertThat(RuntimeHintsPredicates.reflection().onType(Dto.class) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) + .accepts(this.runtimeHints); + assertThat(RuntimeHintsPredicates.reflection().onType(NestedDto.class) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) + .accepts(this.runtimeHints); + assertThat(RuntimeHintsPredicates.reflection().onType(WebEndpointResponse.class)).rejects(this.runtimeHints); + } + + @Test + void shouldNotRegisterResourceReturnType() { + Method method = ReflectionUtils.findMethod(Methods.class, "resource"); + runProcessor(method); + assertThat(RuntimeHintsPredicates.reflection().onType(Resource.class)).rejects(this.runtimeHints); + } + + private void runProcessor(Method method) { + this.sut.registerReflectionHints(this.runtimeHints.reflection(), method); + } + + private static class Methods { + + private String string() { + return null; + } + + private Dto dto() { + return null; + } + + private WebEndpointResponse webEndpointResponse() { + return null; + } + + private Resource resource() { + return null; + } + + } + + public static class Dto { + + private final NestedDto nestedDto = new NestedDto(); + + public NestedDto getNestedDto() { + return this.nestedDto; + } + + } + + public static class NestedDto { + + private final String string = "some-string"; + + public String getString() { + return this.string; + } + + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/jmx/annotation/JmxEndpointDiscovererRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/jmx/annotation/JmxEndpointDiscovererRuntimeHintsTests.java new file mode 100644 index 0000000000..5b039d186a --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/jmx/annotation/JmxEndpointDiscovererRuntimeHintsTests.java @@ -0,0 +1,45 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.endpoint.jmx.annotation; + +import org.junit.jupiter.api.Test; + +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.actuate.endpoint.jmx.annotation.JmxEndpointDiscoverer.JmxEndpointDiscovererRuntimeHints; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link JmxEndpointDiscovererRuntimeHints}. + * + * @author Moritz Halbritter + */ +class JmxEndpointDiscovererRuntimeHintsTests { + + private final JmxEndpointDiscovererRuntimeHints sut = new JmxEndpointDiscovererRuntimeHints(); + + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + assertThat(RuntimeHintsPredicates.reflection().onType(JmxEndpointFilter.class) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(runtimeHints); + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/ControllerEndpointDiscovererRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/ControllerEndpointDiscovererRuntimeHintsTests.java new file mode 100644 index 0000000000..dc7d674d4f --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/ControllerEndpointDiscovererRuntimeHintsTests.java @@ -0,0 +1,46 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.endpoint.web.annotation; + +import org.junit.jupiter.api.Test; + +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointDiscoverer.ControllerEndpointDiscovererRuntimeHints; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link ControllerEndpointDiscovererRuntimeHints}. + * + * @author Moritz Halbritter + */ +class ControllerEndpointDiscovererRuntimeHintsTests { + + private final ControllerEndpointDiscovererRuntimeHints sut = new ControllerEndpointDiscovererRuntimeHints(); + + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + assertThat(RuntimeHintsPredicates.reflection().onType(ControllerEndpointFilter.class) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(runtimeHints); + + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/ServletEndpointDiscovererRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/ServletEndpointDiscovererRuntimeHintsTests.java new file mode 100644 index 0000000000..43e2cb0506 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/ServletEndpointDiscovererRuntimeHintsTests.java @@ -0,0 +1,46 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.endpoint.web.annotation; + +import org.junit.jupiter.api.Test; + +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointDiscoverer.ServletEndpointDiscovererRuntimeHints; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link ServletEndpointDiscovererRuntimeHints}. + * + * @author Moritz Halbritter + */ +class ServletEndpointDiscovererRuntimeHintsTests { + + private final ServletEndpointDiscovererRuntimeHints sut = new ServletEndpointDiscovererRuntimeHints(); + + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + assertThat(RuntimeHintsPredicates.reflection().onType(ServletEndpointFilter.class) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(runtimeHints); + + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/WebEndpointDiscovererRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/WebEndpointDiscovererRuntimeHintsTests.java new file mode 100644 index 0000000000..255a0cff1f --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/WebEndpointDiscovererRuntimeHintsTests.java @@ -0,0 +1,46 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.endpoint.web.annotation; + +import org.junit.jupiter.api.Test; + +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointDiscoverer.WebEndpointDiscovererRuntimeHints; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link WebEndpointDiscovererRuntimeHints}. + * + * @author Moritz Halbritter + */ +class WebEndpointDiscovererRuntimeHintsTests { + + private final WebEndpointDiscovererRuntimeHints sut = new WebEndpointDiscovererRuntimeHints(); + + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + assertThat(RuntimeHintsPredicates.reflection().onType(WebEndpointFilter.class) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(runtimeHints); + + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMappingRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMappingRuntimeHintsTests.java new file mode 100644 index 0000000000..a33f8d0928 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMappingRuntimeHintsTests.java @@ -0,0 +1,49 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.endpoint.web.reactive; + +import org.junit.jupiter.api.Test; + +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.TypeReference; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.actuate.endpoint.web.reactive.AbstractWebFluxEndpointHandlerMapping.AbstractWebFluxEndpointHandlerMappingRuntimeHints; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link AbstractWebFluxEndpointHandlerMappingRuntimeHints}. + * + * @author Moritz Halbritter + */ +class AbstractWebFluxEndpointHandlerMappingRuntimeHintsTests { + + private final AbstractWebFluxEndpointHandlerMappingRuntimeHints sut = new AbstractWebFluxEndpointHandlerMappingRuntimeHints(); + + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + assertThat(RuntimeHintsPredicates.reflection().onType(TypeReference.of( + "org.springframework.boot.actuate.endpoint.web.reactive.AbstractWebFluxEndpointHandlerMapping.WriteOperationHandler"))) + .accepts(runtimeHints); + assertThat(RuntimeHintsPredicates.reflection().onType(TypeReference.of( + "org.springframework.boot.actuate.endpoint.web.reactive.AbstractWebFluxEndpointHandlerMapping.ReadOperationHandler"))) + .accepts(runtimeHints); + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointHandlerMappingRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointHandlerMappingRuntimeHintsTests.java new file mode 100644 index 0000000000..78077fc257 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointHandlerMappingRuntimeHintsTests.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.endpoint.web.reactive; + +import org.junit.jupiter.api.Test; + +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.actuate.endpoint.web.Link; +import org.springframework.boot.actuate.endpoint.web.reactive.WebFluxEndpointHandlerMapping.WebFluxEndpointHandlerMappingRuntimeHints; +import org.springframework.boot.actuate.endpoint.web.reactive.WebFluxEndpointHandlerMapping.WebFluxLinksHandler; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link WebFluxEndpointHandlerMappingRuntimeHints}. + * + * @author Moritz Halbritter + */ +class WebFluxEndpointHandlerMappingRuntimeHintsTests { + + private final WebFluxEndpointHandlerMappingRuntimeHints sut = new WebFluxEndpointHandlerMappingRuntimeHints(); + + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + assertThat(RuntimeHintsPredicates.reflection().onMethod(WebFluxLinksHandler.class, "links")) + .accepts(runtimeHints); + assertThat(RuntimeHintsPredicates.reflection().onType(Link.class)).accepts(runtimeHints); + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/AbstractWebMvcEndpointHandlerMappingRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/AbstractWebMvcEndpointHandlerMappingRuntimeHintsTests.java new file mode 100644 index 0000000000..f51743f6dc --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/AbstractWebMvcEndpointHandlerMappingRuntimeHintsTests.java @@ -0,0 +1,46 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.endpoint.web.servlet; + +import org.junit.jupiter.api.Test; + +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.TypeReference; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping.AbstractWebMvcEndpointHandlerMappingRuntimeHints; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link AbstractWebMvcEndpointHandlerMappingRuntimeHints}. + * + * @author Moritz Halbritter + */ +class AbstractWebMvcEndpointHandlerMappingRuntimeHintsTests { + + private final AbstractWebMvcEndpointHandlerMappingRuntimeHints sut = new AbstractWebMvcEndpointHandlerMappingRuntimeHints(); + + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + assertThat(RuntimeHintsPredicates.reflection().onType(TypeReference.of( + "org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping.OperationHandler"))) + .accepts(runtimeHints); + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMappingRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMappingRuntimeHintsTests.java new file mode 100644 index 0000000000..6351d89e46 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMappingRuntimeHintsTests.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.endpoint.web.servlet; + +import org.junit.jupiter.api.Test; + +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.actuate.endpoint.web.Link; +import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping.WebMvcEndpointHandlerMappingRuntimeHints; +import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping.WebMvcLinksHandler; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link WebMvcEndpointHandlerMappingRuntimeHints}. + * + * @author Moritz Halbritter + */ +class WebMvcEndpointHandlerMappingRuntimeHintsTests { + + private final WebMvcEndpointHandlerMappingRuntimeHints sut = new WebMvcEndpointHandlerMappingRuntimeHints(); + + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + assertThat(RuntimeHintsPredicates.reflection().onMethod(WebMvcLinksHandler.class, "links")) + .accepts(runtimeHints); + assertThat(RuntimeHintsPredicates.reflection().onType(Link.class)).accepts(runtimeHints); + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointWebExtensionRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointWebExtensionRuntimeHintsTests.java new file mode 100644 index 0000000000..89c4a260c1 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointWebExtensionRuntimeHintsTests.java @@ -0,0 +1,51 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.health; + +import java.util.Set; + +import org.junit.jupiter.api.Test; + +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.actuate.health.HealthEndpointWebExtension.HealthEndpointWebExtensionRuntimeHints; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link HealthEndpointWebExtensionRuntimeHints}. + * + * @author Moritz Halbritter + */ +class HealthEndpointWebExtensionRuntimeHintsTests { + + private final HealthEndpointWebExtensionRuntimeHints sut = new HealthEndpointWebExtensionRuntimeHints(); + + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + Set> bindingTypes = Set.of(Health.class, SystemHealth.class, CompositeHealth.class); + for (Class bindingType : bindingTypes) { + assertThat(RuntimeHintsPredicates.reflection().onType(bindingType) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) + .accepts(runtimeHints); + } + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/BuildInfoContributorRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/BuildInfoContributorRuntimeHintsTests.java new file mode 100644 index 0000000000..aa1af63019 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/BuildInfoContributorRuntimeHintsTests.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.info; + +import org.junit.jupiter.api.Test; + +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.actuate.info.BuildInfoContributor.BuildInfoContributorRuntimeHints; +import org.springframework.boot.info.BuildProperties; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link BuildInfoContributorRuntimeHints}. + * + * @author Moritz Halbritter + */ +class BuildInfoContributorRuntimeHintsTests { + + private final BuildInfoContributorRuntimeHints sut = new BuildInfoContributorRuntimeHints(); + + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + assertThat(RuntimeHintsPredicates.reflection().onType(BuildProperties.class) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) + .accepts(runtimeHints); + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/GitInfoContributorRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/GitInfoContributorRuntimeHintsTests.java new file mode 100644 index 0000000000..fd2e1f1c17 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/GitInfoContributorRuntimeHintsTests.java @@ -0,0 +1,48 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.info; + +import org.junit.jupiter.api.Test; + +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.actuate.info.GitInfoContributor.GitInfoContributorRuntimeHints; +import org.springframework.boot.info.GitProperties; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests forr {@link GitInfoContributorRuntimeHints}. + * + * @author Moritz Halbritter + */ +class GitInfoContributorRuntimeHintsTests { + + private final GitInfoContributorRuntimeHints sut = new GitInfoContributorRuntimeHints(); + + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + assertThat(RuntimeHintsPredicates.reflection().onType(GitProperties.class) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) + .accepts(runtimeHints); + + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/JavaInfoContributorRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/JavaInfoContributorRuntimeHintsTests.java new file mode 100644 index 0000000000..7490ac60a6 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/JavaInfoContributorRuntimeHintsTests.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.info; + +import org.junit.jupiter.api.Test; + +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.actuate.info.JavaInfoContributor.JavaInfoContributorRuntimeHints; +import org.springframework.boot.info.JavaInfo; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link JavaInfoContributorRuntimeHints}. + * + * @author Moritz Halbritter + */ +class JavaInfoContributorRuntimeHintsTests { + + private final JavaInfoContributorRuntimeHints sut = new JavaInfoContributorRuntimeHints(); + + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + assertThat(RuntimeHintsPredicates.reflection().onType(JavaInfo.class) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) + .accepts(runtimeHints); + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/OsInfoContributorRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/OsInfoContributorRuntimeHintsTests.java new file mode 100644 index 0000000000..893daa341e --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/OsInfoContributorRuntimeHintsTests.java @@ -0,0 +1,48 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.info; + +import org.junit.jupiter.api.Test; + +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.actuate.info.OsInfoContributor.OsInfoContributorRuntimeHints; +import org.springframework.boot.info.OsInfo; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link OsInfoContributorRuntimeHints}. + * + * @author Moritz Halbritter + */ +class OsInfoContributorRuntimeHintsTests { + + private final OsInfoContributorRuntimeHints sut = new OsInfoContributorRuntimeHints(); + + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + assertThat(RuntimeHintsPredicates.reflection().onType(OsInfo.class) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) + .accepts(runtimeHints); + + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/integration/IntegrationGraphEndpointRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/integration/IntegrationGraphEndpointRuntimeHintsTests.java new file mode 100644 index 0000000000..51d7e7c076 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/integration/IntegrationGraphEndpointRuntimeHintsTests.java @@ -0,0 +1,72 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.integration; + +import java.util.Set; + +import org.junit.jupiter.api.Test; + +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.actuate.integration.IntegrationGraphEndpoint.IntegrationGraphEndpointRuntimeHints; +import org.springframework.integration.graph.CompositeMessageHandlerNode; +import org.springframework.integration.graph.DiscardingMessageHandlerNode; +import org.springframework.integration.graph.EndpointNode; +import org.springframework.integration.graph.ErrorCapableCompositeMessageHandlerNode; +import org.springframework.integration.graph.ErrorCapableDiscardingMessageHandlerNode; +import org.springframework.integration.graph.ErrorCapableEndpointNode; +import org.springframework.integration.graph.ErrorCapableMessageHandlerNode; +import org.springframework.integration.graph.ErrorCapableRoutingNode; +import org.springframework.integration.graph.Graph; +import org.springframework.integration.graph.MessageChannelNode; +import org.springframework.integration.graph.MessageGatewayNode; +import org.springframework.integration.graph.MessageHandlerNode; +import org.springframework.integration.graph.MessageProducerNode; +import org.springframework.integration.graph.MessageSourceNode; +import org.springframework.integration.graph.PollableChannelNode; +import org.springframework.integration.graph.RoutingMessageHandlerNode; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link IntegrationGraphEndpointRuntimeHints}. + * + * @author Moritz Halbritter + */ +class IntegrationGraphEndpointRuntimeHintsTests { + + private final IntegrationGraphEndpointRuntimeHints sut = new IntegrationGraphEndpointRuntimeHints(); + + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + Set> bindingTypes = Set.of(Graph.class, EndpointNode.class, CompositeMessageHandlerNode.class, + DiscardingMessageHandlerNode.class, ErrorCapableCompositeMessageHandlerNode.class, + ErrorCapableDiscardingMessageHandlerNode.class, ErrorCapableEndpointNode.class, + ErrorCapableMessageHandlerNode.class, ErrorCapableRoutingNode.class, MessageGatewayNode.class, + MessageProducerNode.class, PollableChannelNode.class, MessageChannelNode.class, + MessageHandlerNode.class, MessageSourceNode.class, RoutingMessageHandlerNode.class); + for (Class bindingType : bindingTypes) { + assertThat(RuntimeHintsPredicates.reflection().onType(bindingType) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) + .accepts(runtimeHints); + } + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/management/ThreadDumpEndpointWebExtensionTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/management/ThreadDumpEndpointWebExtensionTests.java new file mode 100644 index 0000000000..c073558402 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/management/ThreadDumpEndpointWebExtensionTests.java @@ -0,0 +1,63 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.management; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse; +import org.springframework.boot.actuate.management.ThreadDumpEndpoint.ThreadDumpDescriptor; +import org.springframework.boot.actuate.management.ThreadDumpEndpoint.ThreadDumperUnavailableException; +import org.springframework.http.HttpStatus; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link ThreadDumpEndpointWebExtension}. + * + * @author Moritz Halbritter + */ +class ThreadDumpEndpointWebExtensionTests { + + private ThreadDumpEndpointWebExtension sut; + + private ThreadDumpEndpoint delegateMock; + + @BeforeEach + void setUp() { + this.delegateMock = Mockito.mock(ThreadDumpEndpoint.class); + this.sut = new ThreadDumpEndpointWebExtension(this.delegateMock); + } + + @Test + void shouldHandleThreadDumperUnavailable() { + Mockito.when(this.delegateMock.threadDump()) + .thenThrow(new ThreadDumperUnavailableException("No thread dumper available")); + WebEndpointResponse response = this.sut.threadDump(); + assertThat(response.getStatus()).isEqualTo(HttpStatus.SERVICE_UNAVAILABLE.value()); + } + + @Test + void shouldHandleThreadDumperUnavailableText() { + Mockito.when(this.delegateMock.textThreadDump()) + .thenThrow(new ThreadDumperUnavailableException("No thread dumper available")); + WebEndpointResponse response = this.sut.textThreadDump(); + assertThat(response.getStatus()).isEqualTo(HttpStatus.SERVICE_UNAVAILABLE.value()); + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProviderRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProviderRuntimeHintsTests.java new file mode 100644 index 0000000000..7101421547 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProviderRuntimeHintsTests.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.metrics.cache; + +import com.hazelcast.spring.cache.HazelcastCache; +import io.micrometer.core.instrument.binder.cache.HazelcastCacheMetrics; +import org.junit.jupiter.api.Test; + +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.actuate.metrics.cache.HazelcastCacheMeterBinderProvider.HazelcastCacheMeterBinderProviderRuntimeHints; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link HazelcastCacheMeterBinderProviderRuntimeHints}. + * + * @author Moritz Halbritter + */ +class HazelcastCacheMeterBinderProviderRuntimeHintsTests { + + private final HazelcastCacheMeterBinderProviderRuntimeHints sut = new HazelcastCacheMeterBinderProviderRuntimeHints(); + + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + assertThat(RuntimeHintsPredicates.reflection().onMethod(HazelcastCache.class, "getNativeCache")) + .accepts(runtimeHints); + assertThat(RuntimeHintsPredicates.reflection().onType(HazelcastCacheMetrics.class)).accepts(runtimeHints); + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/quartz/QuartzEndpointWebExtensionRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/quartz/QuartzEndpointWebExtensionRuntimeHintsTests.java new file mode 100644 index 0000000000..503424683a --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/quartz/QuartzEndpointWebExtensionRuntimeHintsTests.java @@ -0,0 +1,56 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.quartz; + +import java.util.Set; + +import org.junit.jupiter.api.Test; + +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.actuate.quartz.QuartzEndpoint.QuartzGroups; +import org.springframework.boot.actuate.quartz.QuartzEndpoint.QuartzJobDetails; +import org.springframework.boot.actuate.quartz.QuartzEndpoint.QuartzJobGroupSummary; +import org.springframework.boot.actuate.quartz.QuartzEndpoint.QuartzTriggerGroupSummary; +import org.springframework.boot.actuate.quartz.QuartzEndpointWebExtension.QuartzEndpointWebExtensionRuntimeHints; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link QuartzEndpointWebExtensionRuntimeHints}. + * + * @author Moritz Halbritter + */ +class QuartzEndpointWebExtensionRuntimeHintsTests { + + private final QuartzEndpointWebExtensionRuntimeHints sut = new QuartzEndpointWebExtensionRuntimeHints(); + + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + Set> bindingTypes = Set.of(QuartzGroups.class, QuartzJobDetails.class, QuartzJobGroupSummary.class, + QuartzTriggerGroupSummary.class); + for (Class bindingType : bindingTypes) { + assertThat(RuntimeHintsPredicates.reflection().onType(bindingType) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) + .accepts(runtimeHints); + } + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/scheduling/ScheduledTasksEndpointRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/scheduling/ScheduledTasksEndpointRuntimeHintsTests.java new file mode 100644 index 0000000000..d227347655 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/scheduling/ScheduledTasksEndpointRuntimeHintsTests.java @@ -0,0 +1,56 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.scheduling; + +import java.util.Set; + +import org.junit.jupiter.api.Test; + +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.actuate.scheduling.ScheduledTasksEndpoint.CronTaskDescription; +import org.springframework.boot.actuate.scheduling.ScheduledTasksEndpoint.CustomTriggerTaskDescription; +import org.springframework.boot.actuate.scheduling.ScheduledTasksEndpoint.FixedDelayTaskDescription; +import org.springframework.boot.actuate.scheduling.ScheduledTasksEndpoint.FixedRateTaskDescription; +import org.springframework.boot.actuate.scheduling.ScheduledTasksEndpoint.ScheduledTasksEndpointRuntimeHints; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link ScheduledTasksEndpointRuntimeHints}. + * + * @author Moritz Halbritter + */ +class ScheduledTasksEndpointRuntimeHintsTests { + + private final ScheduledTasksEndpointRuntimeHints sut = new ScheduledTasksEndpointRuntimeHints(); + + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + Set> bindingTypes = Set.of(FixedRateTaskDescription.class, FixedDelayTaskDescription.class, + CronTaskDescription.class, CustomTriggerTaskDescription.class); + for (Class bindingType : bindingTypes) { + assertThat(RuntimeHintsPredicates.reflection().onType(bindingType) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) + .accepts(runtimeHints); + } + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/startup/StartupEndpointRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/startup/StartupEndpointRuntimeHintsTests.java new file mode 100644 index 0000000000..bc65478ab7 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/startup/StartupEndpointRuntimeHintsTests.java @@ -0,0 +1,53 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.startup; + +import java.util.Set; + +import org.junit.jupiter.api.Test; + +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.TypeReference; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.actuate.startup.StartupEndpoint.StartupEndpointRuntimeHints; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link StartupEndpointRuntimeHints}. + * + * @author Moritz Halbritter + */ +class StartupEndpointRuntimeHintsTests { + + private final StartupEndpointRuntimeHints sut = new StartupEndpointRuntimeHints(); + + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + Set bindingTypes = Set.of( + TypeReference.of("org.springframework.boot.context.metrics.buffering.BufferedStartupStep$DefaultTag"), + TypeReference.of("org.springframework.core.metrics.jfr.FlightRecorderStartupStep$FlightRecorderTag")); + for (TypeReference bindingType : bindingTypes) { + assertThat(RuntimeHintsPredicates.reflection().onType(bindingType) + .withMemberCategories(MemberCategory.INVOKE_PUBLIC_METHODS)).accepts(runtimeHints); + } + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/reactive/DispatcherHandlersMappingDescriptionProviderRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/reactive/DispatcherHandlersMappingDescriptionProviderRuntimeHintsTests.java new file mode 100644 index 0000000000..990d9aa85b --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/reactive/DispatcherHandlersMappingDescriptionProviderRuntimeHintsTests.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.web.mappings.reactive; + +import org.junit.jupiter.api.Test; + +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.actuate.web.mappings.reactive.DispatcherHandlersMappingDescriptionProvider.DispatcherHandlersMappingDescriptionProviderRuntimeHints; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link DispatcherHandlersMappingDescriptionProviderRuntimeHints}. + * + * @author Moritz Halbritter + */ +class DispatcherHandlersMappingDescriptionProviderRuntimeHintsTests { + + private final DispatcherHandlersMappingDescriptionProviderRuntimeHints sut = new DispatcherHandlersMappingDescriptionProviderRuntimeHints(); + + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + assertThat(RuntimeHintsPredicates.reflection().onType(DispatcherHandlerMappingDescription.class) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) + .accepts(runtimeHints); + + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/DispatcherServletsMappingDescriptionProviderRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/DispatcherServletsMappingDescriptionProviderRuntimeHintsTests.java new file mode 100644 index 0000000000..b7b58cc135 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/DispatcherServletsMappingDescriptionProviderRuntimeHintsTests.java @@ -0,0 +1,46 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.web.mappings.servlet; + +import org.junit.jupiter.api.Test; + +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.actuate.web.mappings.servlet.DispatcherServletsMappingDescriptionProvider.DispatcherServletsMappingDescriptionProviderRuntimeHints; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link DispatcherServletsMappingDescriptionProviderRuntimeHints}. + * + * @author Moritz Halbritter + */ +class DispatcherServletsMappingDescriptionProviderRuntimeHintsTests { + + private final DispatcherServletsMappingDescriptionProviderRuntimeHints sut = new DispatcherServletsMappingDescriptionProviderRuntimeHints(); + + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + assertThat(RuntimeHintsPredicates.reflection().onType(DispatcherServletMappingDescription.class) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) + .accepts(runtimeHints); + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/FiltersMappingDescriptionProviderRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/FiltersMappingDescriptionProviderRuntimeHintsTests.java new file mode 100644 index 0000000000..81e6ae5f07 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/FiltersMappingDescriptionProviderRuntimeHintsTests.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.web.mappings.servlet; + +import org.junit.jupiter.api.Test; + +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.actuate.web.mappings.servlet.FiltersMappingDescriptionProvider.FiltersMappingDescriptionProviderRuntimeHints; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link FiltersMappingDescriptionProviderRuntimeHints}. + * + * @author Moritz Halbritter + */ +class FiltersMappingDescriptionProviderRuntimeHintsTests { + + private final FiltersMappingDescriptionProviderRuntimeHints sut = new FiltersMappingDescriptionProviderRuntimeHints(); + + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + assertThat(RuntimeHintsPredicates.reflection().onType(FilterRegistrationMappingDescription.class) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) + .accepts(runtimeHints); + + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/ServletsMappingDescriptionProviderRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/ServletsMappingDescriptionProviderRuntimeHintsTests.java new file mode 100644 index 0000000000..aa19dadc42 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/ServletsMappingDescriptionProviderRuntimeHintsTests.java @@ -0,0 +1,46 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.web.mappings.servlet; + +import org.junit.jupiter.api.Test; + +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.actuate.web.mappings.servlet.ServletsMappingDescriptionProvider.ServletsMappingDescriptionProviderRuntimeHints; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link ServletsMappingDescriptionProviderRuntimeHints}. + * + * @author Moritz Halbritter + */ +class ServletsMappingDescriptionProviderRuntimeHintsTests { + + private final ServletsMappingDescriptionProviderRuntimeHints sut = new ServletsMappingDescriptionProviderRuntimeHints(); + + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + assertThat(RuntimeHintsPredicates.reflection().onType(ServletRegistrationMappingDescription.class) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) + .accepts(runtimeHints); + } + +} diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/info/BuildProperties.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/info/BuildProperties.java index 76ec3485aa..efbc13065a 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/info/BuildProperties.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/info/BuildProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,12 +21,18 @@ import java.time.Instant; import java.time.format.DateTimeFormatter; import java.util.Properties; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; +import org.springframework.boot.info.BuildProperties.BuildPropertiesRuntimeHints; +import org.springframework.context.annotation.ImportRuntimeHints; + /** * Provide build-related information such as group and artifact. * * @author Stephane Nicoll * @since 1.4.0 */ +@ImportRuntimeHints(BuildPropertiesRuntimeHints.class) public class BuildProperties extends InfoProperties { /** @@ -100,4 +106,13 @@ public class BuildProperties extends InfoProperties { } } + static class BuildPropertiesRuntimeHints implements RuntimeHintsRegistrar { + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + hints.resources().registerPattern("META-INF/build-info.properties"); + } + + } + } diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/info/GitProperties.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/info/GitProperties.java index d07f6cf88d..ba5aff3c9c 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/info/GitProperties.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/info/GitProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,12 +21,18 @@ import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.util.Properties; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; +import org.springframework.boot.info.GitProperties.GitPropertiesRuntimeHints; +import org.springframework.context.annotation.ImportRuntimeHints; + /** * Provide git-related information such as commit id and time. * * @author Stephane Nicoll * @since 1.4.0 */ +@ImportRuntimeHints(GitPropertiesRuntimeHints.class) public class GitProperties extends InfoProperties { public GitProperties(Properties entries) { @@ -126,4 +132,13 @@ public class GitProperties extends InfoProperties { } } + static class GitPropertiesRuntimeHints implements RuntimeHintsRegistrar { + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + hints.resources().registerPattern("git.properties"); + } + + } + } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/info/BuildPropertiesRuntimeHintsTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/info/BuildPropertiesRuntimeHintsTests.java new file mode 100644 index 0000000000..e8be5ba690 --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/info/BuildPropertiesRuntimeHintsTests.java @@ -0,0 +1,44 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.info; + +import org.junit.jupiter.api.Test; + +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.info.BuildProperties.BuildPropertiesRuntimeHints; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link BuildPropertiesRuntimeHints}. + * + * @author Moritz Halbritter + */ +class BuildPropertiesRuntimeHintsTests { + + private final BuildPropertiesRuntimeHints sut = new BuildPropertiesRuntimeHints(); + + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + assertThat(RuntimeHintsPredicates.resource().forResource("META-INF/build-info.properties")) + .accepts(runtimeHints); + } + +} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/info/GitPropertiesRuntimeHintsTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/info/GitPropertiesRuntimeHintsTests.java new file mode 100644 index 0000000000..93de2c71a4 --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/info/GitPropertiesRuntimeHintsTests.java @@ -0,0 +1,43 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.info; + +import org.junit.jupiter.api.Test; + +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.info.GitProperties.GitPropertiesRuntimeHints; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link GitPropertiesRuntimeHints}. + * + * @author Moritz Halbritter + */ +class GitPropertiesRuntimeHintsTests { + + private final GitPropertiesRuntimeHints sut = new GitPropertiesRuntimeHints(); + + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + assertThat(RuntimeHintsPredicates.resource().forResource("git.properties")).accepts(runtimeHints); + } + +} From 51cba6ec727fc406d0dfc422eb95da504a5b0544 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Tue, 19 Jul 2022 11:52:39 +0200 Subject: [PATCH 2/2] Polish "Add AOT support for actuator" See gh-31671 --- ...dFoundryWebFluxEndpointHandlerMapping.java | 11 ++- ...undryWebEndpointServletHandlerMapping.java | 13 ++-- .../ActuatorAnnotationsRuntimeHints.java} | 7 +- .../endpoint/EndpointAutoConfiguration.java | 3 +- ...ebEndpointDiscovererRuntimeHintsTests.java | 45 ------------ ...loudFoundryWebEndpointDiscovererTests.java | 13 ++++ ...ryWebFluxEndpointHandlerMappingTests.java} | 9 ++- ...ebEndpointServletHandlerMappingTests.java} | 9 ++- ...ActuatorAnnotationsRuntimeHintsTests.java} | 10 +-- .../boot/actuate/aot/package-info.java | 20 ------ .../OperationReflectiveProcessor.java | 35 ++++----- ...AbstractWebFluxEndpointHandlerMapping.java | 16 ++--- .../WebFluxEndpointHandlerMapping.java | 11 ++- .../AbstractWebMvcEndpointHandlerMapping.java | 9 +-- .../servlet/WebMvcEndpointHandlerMapping.java | 13 ++-- .../HazelcastCacheMeterBinderProvider.java | 20 +++--- .../OperationReflectiveProcessorTests.java | 53 ++++++++------ ...mxEndpointDiscovererRuntimeHintsTests.java | 45 ------------ .../JmxEndpointDiscovererTests.java | 15 +++- ...erEndpointDiscovererRuntimeHintsTests.java | 46 ------------ .../ControllerEndpointDiscovererTests.java | 16 ++++- ...etEndpointDiscovererRuntimeHintsTests.java | 46 ------------ .../ServletEndpointDiscovererTests.java | 13 ++++ ...ebEndpointDiscovererRuntimeHintsTests.java | 46 ------------ .../WebEndpointDiscovererTests.java | 16 ++++- ...ctWebFluxEndpointHandlerMappingTests.java} | 9 ++- ...> WebFluxEndpointHandlerMappingTests.java} | 8 +-- ...actWebMvcEndpointHandlerMappingTests.java} | 8 +-- ...=> WebMvcEndpointHandlerMappingTests.java} | 8 +-- ...EndpointWebExtensionRuntimeHintsTests.java | 51 ------------- .../HealthEndpointWebExtensionTests.java | 18 +++++ ...ts.java => BuildInfoContributorTests.java} | 8 +-- .../GitInfoContributorRuntimeHintsTests.java | 48 ------------- .../actuate/info/GitInfoContributorTests.java | 17 ++++- .../JavaInfoContributorRuntimeHintsTests.java | 47 ------------ .../info/JavaInfoContributorTests.java | 16 ++++- .../OsInfoContributorRuntimeHintsTests.java | 48 ------------- .../actuate/info/OsInfoContributorTests.java | 14 ++++ ...grationGraphEndpointRuntimeHintsTests.java | 72 ------------------- .../IntegrationGraphEndpointTests.java | 39 ++++++++++ .../ThreadDumpEndpointWebExtensionTests.java | 8 +-- ...eMeterBinderProviderRuntimeHintsTests.java | 47 ------------ ...azelcastCacheMeterBinderProviderTests.java | 14 ++++ ...a => QuartzEndpointWebExtensionTests.java} | 8 +-- ...heduledTasksEndpointRuntimeHintsTests.java | 56 --------------- .../ScheduledTasksEndpointTests.java | 19 +++++ .../StartupEndpointRuntimeHintsTests.java | 53 -------------- .../actuate/startup/StartupEndpointTests.java | 22 +++++- ...dlersMappingDescriptionProviderTests.java} | 9 ++- ...vletsMappingDescriptionProviderTests.java} | 9 ++- ...ltersMappingDescriptionProviderTests.java} | 8 +-- ...vletsMappingDescriptionProviderTests.java} | 8 +-- .../BuildPropertiesRuntimeHintsTests.java | 44 ------------ .../boot/info/BuildPropertiesTests.java | 14 +++- .../info/GitPropertiesRuntimeHintsTests.java | 43 ----------- .../boot/info/GitPropertiesTests.java | 13 +++- 56 files changed, 387 insertions(+), 939 deletions(-) rename spring-boot-project/{spring-boot-actuator/src/main/java/org/springframework/boot/actuate/aot/ActuatorAnnotationsRuntimeHintsRegistrar.java => spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/ActuatorAnnotationsRuntimeHints.java} (89%) delete mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryWebEndpointDiscovererRuntimeHintsTests.java rename spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/{CloudFoundryWebFluxEndpointHandlerMappingRuntimeHintsTests.java => CloudFoundryWebFluxEndpointHandlerMappingTests.java} (82%) rename spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/{CloudFoundryWebEndpointServletHandlerMappingRuntimeHintsTests.java => CloudFoundryWebEndpointServletHandlerMappingTests.java} (85%) rename spring-boot-project/{spring-boot-actuator/src/test/java/org/springframework/boot/actuate/aot/ActuatorAnnotationsRuntimeHintsRegistrarTests.java => spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/ActuatorAnnotationsRuntimeHintsTests.java} (87%) delete mode 100644 spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/aot/package-info.java delete mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/jmx/annotation/JmxEndpointDiscovererRuntimeHintsTests.java delete mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/ControllerEndpointDiscovererRuntimeHintsTests.java delete mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/ServletEndpointDiscovererRuntimeHintsTests.java delete mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/WebEndpointDiscovererRuntimeHintsTests.java rename spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/{AbstractWebFluxEndpointHandlerMappingRuntimeHintsTests.java => AbstractWebFluxEndpointHandlerMappingTests.java} (83%) rename spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/{WebFluxEndpointHandlerMappingRuntimeHintsTests.java => WebFluxEndpointHandlerMappingTests.java} (83%) rename spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/{AbstractWebMvcEndpointHandlerMappingRuntimeHintsTests.java => AbstractWebMvcEndpointHandlerMappingTests.java} (81%) rename spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/{WebMvcEndpointHandlerMappingRuntimeHintsTests.java => WebMvcEndpointHandlerMappingTests.java} (83%) delete mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointWebExtensionRuntimeHintsTests.java rename spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/{BuildInfoContributorRuntimeHintsTests.java => BuildInfoContributorTests.java} (84%) delete mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/GitInfoContributorRuntimeHintsTests.java delete mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/JavaInfoContributorRuntimeHintsTests.java delete mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/OsInfoContributorRuntimeHintsTests.java delete mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/integration/IntegrationGraphEndpointRuntimeHintsTests.java delete mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProviderRuntimeHintsTests.java rename spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/quartz/{QuartzEndpointWebExtensionRuntimeHintsTests.java => QuartzEndpointWebExtensionTests.java} (87%) delete mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/scheduling/ScheduledTasksEndpointRuntimeHintsTests.java delete mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/startup/StartupEndpointRuntimeHintsTests.java rename spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/reactive/{DispatcherHandlersMappingDescriptionProviderRuntimeHintsTests.java => DispatcherHandlersMappingDescriptionProviderTests.java} (83%) rename spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/{DispatcherServletsMappingDescriptionProviderRuntimeHintsTests.java => DispatcherServletsMappingDescriptionProviderTests.java} (83%) rename spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/{FiltersMappingDescriptionProviderRuntimeHintsTests.java => FiltersMappingDescriptionProviderTests.java} (82%) rename spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/{ServletsMappingDescriptionProviderRuntimeHintsTests.java => ServletsMappingDescriptionProviderTests.java} (82%) delete mode 100644 spring-boot-project/spring-boot/src/test/java/org/springframework/boot/info/BuildPropertiesRuntimeHintsTests.java delete mode 100644 spring-boot-project/spring-boot/src/test/java/org/springframework/boot/info/GitPropertiesRuntimeHintsTests.java diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMapping.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMapping.java index dbca38daa4..303f31ab58 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMapping.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMapping.java @@ -19,17 +19,15 @@ package org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; -import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.stream.Collectors; import org.reactivestreams.Publisher; import reactor.core.publisher.Mono; -import org.springframework.aot.hint.ExecutableMode; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; -import org.springframework.aot.hint.TypeReference; 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; @@ -46,6 +44,7 @@ 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.ReflectionUtils; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.reactive.result.method.RequestMappingInfoHandlerMapping; import org.springframework.web.server.ServerWebExchange; @@ -160,10 +159,8 @@ class CloudFoundryWebFluxEndpointHandlerMapping extends AbstractWebFluxEndpointH @Override public void registerHints(RuntimeHints hints, ClassLoader classLoader) { - hints.reflection().registerType(CloudFoundryLinksHandler.class, - (hint) -> hint.onReachableType(TypeReference.of(CloudFoundryLinksHandler.class)).withMethod("links", - List.of(TypeReference.of(ServerWebExchange.class)), - (method) -> method.setModes(ExecutableMode.INVOKE))); + hints.reflection().registerMethod(Objects.requireNonNull( + ReflectionUtils.findMethod(CloudFoundryLinksHandler.class, "links", ServerWebExchange.class))); this.bindingRegistrar.registerReflectionHints(hints.reflection(), Link.class); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMapping.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMapping.java index 5ccac0b045..f3761e777b 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMapping.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMapping.java @@ -19,8 +19,8 @@ package org.springframework.boot.actuate.autoconfigure.cloudfoundry.servlet; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; -import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.stream.Collectors; import jakarta.servlet.http.HttpServletRequest; @@ -28,10 +28,8 @@ import jakarta.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.springframework.aot.hint.ExecutableMode; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; -import org.springframework.aot.hint.TypeReference; 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; @@ -47,6 +45,7 @@ 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.ReflectionUtils; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping; @@ -162,11 +161,9 @@ class CloudFoundryWebEndpointServletHandlerMapping extends AbstractWebMvcEndpoin @Override public void registerHints(RuntimeHints hints, ClassLoader classLoader) { - hints.reflection().registerType(CloudFoundryLinksHandler.class, - (hint) -> hint.onReachableType(TypeReference.of(CloudFoundryLinksHandler.class)).withMethod("links", - List.of(TypeReference.of(HttpServletRequest.class), - TypeReference.of(HttpServletResponse.class)), - (method) -> method.setModes(ExecutableMode.INVOKE))); + hints.reflection() + .registerMethod(Objects.requireNonNull(ReflectionUtils.findMethod(CloudFoundryLinksHandler.class, + "links", HttpServletRequest.class, HttpServletResponse.class))); this.bindingRegistrar.registerReflectionHints(hints.reflection(), Link.class); } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/aot/ActuatorAnnotationsRuntimeHintsRegistrar.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/ActuatorAnnotationsRuntimeHints.java similarity index 89% rename from spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/aot/ActuatorAnnotationsRuntimeHintsRegistrar.java rename to spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/ActuatorAnnotationsRuntimeHints.java index 87a6fc6eec..0249192934 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/aot/ActuatorAnnotationsRuntimeHintsRegistrar.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/ActuatorAnnotationsRuntimeHints.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.aot; +package org.springframework.boot.actuate.autoconfigure.endpoint; import java.util.stream.Stream; @@ -29,12 +29,11 @@ import org.springframework.boot.actuate.endpoint.annotation.WriteOperation; import org.springframework.core.annotation.SynthesizedAnnotation; /** - * Registrar which registers the annotations needed for actuator support. + * {@link RuntimeHintsRegistrar} for actuator support. * * @author Moritz Halbritter - * @since 3.0.0 */ -public class ActuatorAnnotationsRuntimeHintsRegistrar implements RuntimeHintsRegistrar { +class ActuatorAnnotationsRuntimeHints implements RuntimeHintsRegistrar { @Override public void registerHints(RuntimeHints hints, ClassLoader classLoader) { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/EndpointAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/EndpointAutoConfiguration.java index 01951ce41f..097db6229b 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/EndpointAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/EndpointAutoConfiguration.java @@ -20,7 +20,6 @@ import java.util.List; import java.util.stream.Collectors; import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.actuate.aot.ActuatorAnnotationsRuntimeHintsRegistrar; import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.actuate.endpoint.annotation.EndpointConverter; import org.springframework.boot.actuate.endpoint.invoke.ParameterValueMapper; @@ -47,7 +46,7 @@ import org.springframework.core.env.Environment; * @since 2.0.0 */ @AutoConfiguration -@ImportRuntimeHints(ActuatorAnnotationsRuntimeHintsRegistrar.class) +@ImportRuntimeHints(ActuatorAnnotationsRuntimeHints.class) public class EndpointAutoConfiguration { @Bean diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryWebEndpointDiscovererRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryWebEndpointDiscovererRuntimeHintsTests.java deleted file mode 100644 index 7aea479685..0000000000 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryWebEndpointDiscovererRuntimeHintsTests.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2012-2022 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.autoconfigure.cloudfoundry; - -import org.junit.jupiter.api.Test; - -import org.springframework.aot.hint.MemberCategory; -import org.springframework.aot.hint.RuntimeHints; -import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; -import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryWebEndpointDiscoverer.CloudFoundryWebEndpointDiscovererRuntimeHints; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link CloudFoundryWebEndpointDiscovererRuntimeHints}. - * - * @author Moritz Halbritter - */ -class CloudFoundryWebEndpointDiscovererRuntimeHintsTests { - - private final CloudFoundryWebEndpointDiscovererRuntimeHints sut = new CloudFoundryWebEndpointDiscovererRuntimeHints(); - - @Test - void shouldRegisterHints() { - RuntimeHints runtimeHints = new RuntimeHints(); - this.sut.registerHints(runtimeHints, getClass().getClassLoader()); - assertThat(RuntimeHintsPredicates.reflection().onType(CloudFoundryEndpointFilter.class) - .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(runtimeHints); - } - -} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryWebEndpointDiscovererTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryWebEndpointDiscovererTests.java index cf3a9494ce..9fe8956788 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryWebEndpointDiscovererTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryWebEndpointDiscovererTests.java @@ -23,6 +23,10 @@ import java.util.function.Function; import org.junit.jupiter.api.Test; +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryWebEndpointDiscoverer.CloudFoundryWebEndpointDiscovererRuntimeHints; import org.springframework.boot.actuate.endpoint.EndpointId; import org.springframework.boot.actuate.endpoint.InvocationContext; import org.springframework.boot.actuate.endpoint.SecurityContext; @@ -50,6 +54,7 @@ import static org.mockito.Mockito.mock; * Tests for {@link CloudFoundryWebEndpointDiscoverer}. * * @author Madhura Bhave + * @author Moritz Halbritter */ class CloudFoundryWebEndpointDiscovererTests { @@ -69,6 +74,14 @@ class CloudFoundryWebEndpointDiscovererTests { }); } + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + new CloudFoundryWebEndpointDiscovererRuntimeHints().registerHints(runtimeHints, getClass().getClassLoader()); + assertThat(RuntimeHintsPredicates.reflection().onType(CloudFoundryEndpointFilter.class) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(runtimeHints); + } + private WebOperation findMainReadOperation(ExposableWebEndpoint endpoint) { for (WebOperation operation : endpoint.getOperations()) { if (operation.getRequestPredicate().getPath().equals("health")) { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMappingRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMappingTests.java similarity index 82% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMappingRuntimeHintsTests.java rename to spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMappingTests.java index f4043f317d..ae612e9740 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMappingRuntimeHintsTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointHandlerMappingTests.java @@ -26,18 +26,17 @@ import org.springframework.boot.actuate.autoconfigure.cloudfoundry.reactive.Clou import org.springframework.boot.actuate.endpoint.web.Link; /** - * Tests for {@link CloudFoundryWebFluxEndpointHandlerMappingRuntimeHints}. + * Tests for {@link CloudFoundryWebFluxEndpointHandlerMapping}. * * @author Moritz Halbritter */ -class CloudFoundryWebFluxEndpointHandlerMappingRuntimeHintsTests { - - private final CloudFoundryWebFluxEndpointHandlerMappingRuntimeHints sut = new CloudFoundryWebFluxEndpointHandlerMappingRuntimeHints(); +class CloudFoundryWebFluxEndpointHandlerMappingTests { @Test void shouldRegisterHints() { RuntimeHints runtimeHints = new RuntimeHints(); - this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + new CloudFoundryWebFluxEndpointHandlerMappingRuntimeHints().registerHints(runtimeHints, + getClass().getClassLoader()); Assertions.assertThat(RuntimeHintsPredicates.reflection().onMethod(CloudFoundryLinksHandler.class, "links")) .accepts(runtimeHints); Assertions.assertThat(RuntimeHintsPredicates.reflection().onType(Link.class)).accepts(runtimeHints); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMappingRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMappingTests.java similarity index 85% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMappingRuntimeHintsTests.java rename to spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMappingTests.java index 03902421ee..100504cd45 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMappingRuntimeHintsTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryWebEndpointServletHandlerMappingTests.java @@ -27,18 +27,17 @@ import org.springframework.boot.actuate.endpoint.web.Link; import static org.assertj.core.api.Assertions.assertThat; /** - * Tests for {@link CloudFoundryWebEndpointServletHandlerMappingRuntimeHints}. + * Tests for {@link CloudFoundryWebEndpointServletHandlerMapping}. * * @author Moritz Halbritter */ -class CloudFoundryWebEndpointServletHandlerMappingRuntimeHintsTests { - - private final CloudFoundryWebEndpointServletHandlerMappingRuntimeHints sut = new CloudFoundryWebEndpointServletHandlerMappingRuntimeHints(); +class CloudFoundryWebEndpointServletHandlerMappingTests { @Test void shouldRegisterHints() { RuntimeHints runtimeHints = new RuntimeHints(); - this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + new CloudFoundryWebEndpointServletHandlerMappingRuntimeHints().registerHints(runtimeHints, + getClass().getClassLoader()); assertThat(RuntimeHintsPredicates.reflection().onMethod(CloudFoundryLinksHandler.class, "links")) .accepts(runtimeHints); assertThat(RuntimeHintsPredicates.reflection().onType(Link.class)).accepts(runtimeHints); diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/aot/ActuatorAnnotationsRuntimeHintsRegistrarTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/ActuatorAnnotationsRuntimeHintsTests.java similarity index 87% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/aot/ActuatorAnnotationsRuntimeHintsRegistrarTests.java rename to spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/ActuatorAnnotationsRuntimeHintsTests.java index 9da4482ae0..ec5377a617 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/aot/ActuatorAnnotationsRuntimeHintsRegistrarTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/ActuatorAnnotationsRuntimeHintsTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.actuate.aot; +package org.springframework.boot.actuate.autoconfigure.endpoint; import java.util.Set; @@ -34,20 +34,20 @@ import org.springframework.core.annotation.SynthesizedAnnotation; import static org.assertj.core.api.Assertions.assertThat; /** - * Tests for {@link ActuatorAnnotationsRuntimeHintsRegistrar}. + * Tests for {@link ActuatorAnnotationsRuntimeHints}. * * @author Moritz Halbritter */ -class ActuatorAnnotationsRuntimeHintsRegistrarTests { +class ActuatorAnnotationsRuntimeHintsTests { - private final ActuatorAnnotationsRuntimeHintsRegistrar sut = new ActuatorAnnotationsRuntimeHintsRegistrar(); + private final ActuatorAnnotationsRuntimeHints registrar = new ActuatorAnnotationsRuntimeHints(); private RuntimeHints runtimeHints; @BeforeEach void setUp() { this.runtimeHints = new RuntimeHints(); - this.sut.registerHints(this.runtimeHints, getClass().getClassLoader()); + this.registrar.registerHints(this.runtimeHints, getClass().getClassLoader()); } @Test diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/aot/package-info.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/aot/package-info.java deleted file mode 100644 index 15e4e2bd03..0000000000 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/aot/package-info.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2012-2022 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Support classes for actuator in AOT mode. - */ -package org.springframework.boot.actuate.aot; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/OperationReflectiveProcessor.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/OperationReflectiveProcessor.java index 55329c0748..2e934e40d1 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/OperationReflectiveProcessor.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/annotation/OperationReflectiveProcessor.java @@ -16,52 +16,43 @@ package org.springframework.boot.actuate.endpoint.annotation; -import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Method; import java.lang.reflect.Type; -import org.springframework.aot.hint.ExecutableMode; import org.springframework.aot.hint.ReflectionHints; import org.springframework.aot.hint.annotation.ReflectiveProcessor; +import org.springframework.aot.hint.annotation.SimpleReflectiveProcessor; import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse; import org.springframework.context.aot.BindingReflectionHintsRegistrar; import org.springframework.core.ResolvableType; import org.springframework.core.io.Resource; /** - * Processor which registers the annotated operation method and its return type for - * reflection. + * {@link ReflectiveProcessor} that registers the annotated operation method and its + * return type for reflection. * * @author Moritz Halbritter + * @author Stephane Nicoll */ -class OperationReflectiveProcessor implements ReflectiveProcessor { +class OperationReflectiveProcessor extends SimpleReflectiveProcessor { private final BindingReflectionHintsRegistrar bindingRegistrar = new BindingReflectionHintsRegistrar(); @Override - public void registerReflectionHints(ReflectionHints hints, AnnotatedElement element) { - if (!(element instanceof Method method)) { - throw new IllegalArgumentException("This processor can only be invoked for annotated methods"); + protected void registerMethodHint(ReflectionHints hints, Method method) { + super.registerMethodHint(hints, method); + Type returnType = extractReturnType(method); + if (returnType != null) { + registerReflectionHints(hints, returnType); } - hints.registerMethod(method, (hint) -> hint.setModes(ExecutableMode.INVOKE)); - registerReturnValueHints(hints, method); } - private void registerReturnValueHints(ReflectionHints hints, Method method) { + private Type extractReturnType(Method method) { ResolvableType returnType = ResolvableType.forMethodReturnType(method); if (WebEndpointResponse.class.isAssignableFrom(method.getReturnType())) { - registerWebEndpointResponse(hints, returnType); - } - else { - registerReflectionHints(hints, returnType.getType()); - } - } - - private void registerWebEndpointResponse(ReflectionHints hints, ResolvableType returnType) { - ResolvableType genericParameter = returnType.getGeneric(0); - if (genericParameter.getRawClass() != null) { - registerReflectionHints(hints, genericParameter.getType()); + return returnType.as(WebEndpointResponse.class).getGeneric(0).getType(); } + return returnType.getType(); } private void registerReflectionHints(ReflectionHints hints, Type type) { diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMapping.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMapping.java index 0c0e38ce9a..93c24f72d6 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMapping.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMapping.java @@ -22,8 +22,8 @@ import java.security.Principal; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; -import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.function.Supplier; import org.reactivestreams.Publisher; @@ -31,10 +31,8 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.core.scheduler.Schedulers; -import org.springframework.aot.hint.ExecutableMode; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; -import org.springframework.aot.hint.TypeReference; import org.springframework.boot.actuate.endpoint.InvalidEndpointRequestException; import org.springframework.boot.actuate.endpoint.InvocationContext; import org.springframework.boot.actuate.endpoint.OperationArgumentResolver; @@ -496,13 +494,11 @@ public abstract class AbstractWebFluxEndpointHandlerMapping extends RequestMappi @Override public void registerHints(RuntimeHints hints, ClassLoader classLoader) { - hints.reflection().registerType(WriteOperationHandler.class, - (hint) -> hint.withMethod("handle", - List.of(TypeReference.of(ServerWebExchange.class), TypeReference.of(Map.class)), - (method) -> method.withMode(ExecutableMode.INVOKE))); - hints.reflection().registerType(ReadOperationHandler.class, - (hint) -> hint.withMethod("handle", List.of(TypeReference.of(ServerWebExchange.class)), - (method) -> method.withMode(ExecutableMode.INVOKE))); + hints.reflection() + .registerMethod(Objects.requireNonNull(ReflectionUtils.findMethod(WriteOperationHandler.class, + "handle", ServerWebExchange.class, Map.class))) + .registerMethod(Objects.requireNonNull( + ReflectionUtils.findMethod(ReadOperationHandler.class, "handle", ServerWebExchange.class))); } } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointHandlerMapping.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointHandlerMapping.java index c18cc203d2..dff2b56b91 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointHandlerMapping.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointHandlerMapping.java @@ -18,13 +18,11 @@ package org.springframework.boot.actuate.endpoint.web.reactive; import java.util.Collection; import java.util.Collections; -import java.util.List; import java.util.Map; +import java.util.Objects; -import org.springframework.aot.hint.ExecutableMode; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; -import org.springframework.aot.hint.TypeReference; import org.springframework.beans.factory.InitializingBean; import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver; import org.springframework.boot.actuate.endpoint.web.EndpointMapping; @@ -34,6 +32,7 @@ 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.ReflectionUtils; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.reactive.HandlerMapping; @@ -104,10 +103,8 @@ public class WebFluxEndpointHandlerMapping extends AbstractWebFluxEndpointHandle @Override public void registerHints(RuntimeHints hints, ClassLoader classLoader) { - hints.reflection().registerType(WebFluxLinksHandler.class, - (hint) -> hint.onReachableType(TypeReference.of(WebFluxLinksHandler.class)).withMethod("links", - List.of(TypeReference.of(ServerWebExchange.class)), - (method) -> method.setModes(ExecutableMode.INVOKE))); + hints.reflection().registerMethod(Objects.requireNonNull( + ReflectionUtils.findMethod(WebFluxLinksHandler.class, "links", ServerWebExchange.class))); this.bindingRegistrar.registerReflectionHints(hints.reflection(), Link.class); } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/AbstractWebMvcEndpointHandlerMapping.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/AbstractWebMvcEndpointHandlerMapping.java index 434ceca029..bd90fa2377 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/AbstractWebMvcEndpointHandlerMapping.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/AbstractWebMvcEndpointHandlerMapping.java @@ -26,16 +26,15 @@ import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.function.Function; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import reactor.core.publisher.Flux; -import org.springframework.aot.hint.ExecutableMode; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; -import org.springframework.aot.hint.TypeReference; import org.springframework.beans.factory.InitializingBean; import org.springframework.boot.actuate.endpoint.InvalidEndpointRequestException; import org.springframework.boot.actuate.endpoint.InvocationContext; @@ -487,10 +486,8 @@ public abstract class AbstractWebMvcEndpointHandlerMapping extends RequestMappin @Override public void registerHints(RuntimeHints hints, ClassLoader classLoader) { - hints.reflection().registerType(OperationHandler.class, - (hint) -> hint.withMethod("handle", - List.of(TypeReference.of(HttpServletRequest.class), TypeReference.of(Map.class)), - (method) -> method.withMode(ExecutableMode.INVOKE))); + hints.reflection().registerMethod(Objects.requireNonNull( + ReflectionUtils.findMethod(OperationHandler.class, "handle", HttpServletRequest.class, Map.class))); } } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMapping.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMapping.java index 3f85334151..41b8cfae4e 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMapping.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMapping.java @@ -18,16 +18,14 @@ package org.springframework.boot.actuate.endpoint.web.servlet; import java.util.Collection; import java.util.Collections; -import java.util.List; import java.util.Map; +import java.util.Objects; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import org.springframework.aot.hint.ExecutableMode; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; -import org.springframework.aot.hint.TypeReference; import org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver; import org.springframework.boot.actuate.endpoint.web.EndpointMapping; import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes; @@ -36,6 +34,7 @@ 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.ReflectionUtils; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.servlet.HandlerMapping; @@ -101,11 +100,9 @@ public class WebMvcEndpointHandlerMapping extends AbstractWebMvcEndpointHandlerM @Override public void registerHints(RuntimeHints hints, ClassLoader classLoader) { - hints.reflection().registerType(WebMvcLinksHandler.class, - (hint) -> hint.onReachableType(TypeReference.of(WebMvcLinksHandler.class)).withMethod("links", - List.of(TypeReference.of(HttpServletRequest.class), - TypeReference.of(HttpServletResponse.class)), - (method) -> method.setModes(ExecutableMode.INVOKE))); + hints.reflection() + .registerMethod(Objects.requireNonNull(ReflectionUtils.findMethod(WebMvcLinksHandler.class, "links", + HttpServletRequest.class, HttpServletResponse.class))); this.bindingRegistrar.registerReflectionHints(hints.reflection(), Link.class); } diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProvider.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProvider.java index a7f4f26de5..7f38ad7fb0 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProvider.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProvider.java @@ -17,17 +17,15 @@ package org.springframework.boot.actuate.metrics.cache; import java.lang.reflect.Method; -import java.util.List; +import java.util.Objects; import com.hazelcast.spring.cache.HazelcastCache; import io.micrometer.core.instrument.Tag; import io.micrometer.core.instrument.binder.MeterBinder; import io.micrometer.core.instrument.binder.cache.HazelcastCacheMetrics; -import org.springframework.aot.hint.ExecutableMode; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.RuntimeHintsRegistrar; -import org.springframework.aot.hint.TypeReference; import org.springframework.boot.actuate.metrics.cache.HazelcastCacheMeterBinderProvider.HazelcastCacheMeterBinderProviderRuntimeHints; import org.springframework.context.annotation.ImportRuntimeHints; import org.springframework.util.ReflectionUtils; @@ -68,12 +66,16 @@ public class HazelcastCacheMeterBinderProvider implements CacheMeterBinderProvid @Override public void registerHints(RuntimeHints hints, ClassLoader classLoader) { - hints.reflection().registerType(HazelcastCache.class, (hint) -> hint.withMethod("getNativeCache", List.of(), - (method) -> method.withMode(ExecutableMode.INVOKE))); - hints.reflection().registerType(HazelcastCacheMetrics.class, - (hint) -> hint.withConstructor( - List.of(TypeReference.of(Object.class), TypeReference.of(Iterable.class)), - (ctor) -> ctor.withMode(ExecutableMode.INVOKE))); + try { + hints.reflection() + .registerMethod(Objects + .requireNonNull(ReflectionUtils.findMethod(HazelcastCache.class, "getNativeCache"))) + .registerConstructor(HazelcastCacheMetrics.class.getConstructor(Object.class, Iterable.class)); + } + catch (NoSuchMethodException ex) { + throw new IllegalStateException(ex); + } + } } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/annotation/OperationReflectiveProcessorTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/annotation/OperationReflectiveProcessorTests.java index dac08b3317..8d0618f30b 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/annotation/OperationReflectiveProcessorTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/annotation/OperationReflectiveProcessorTests.java @@ -17,8 +17,9 @@ package org.springframework.boot.actuate.endpoint.annotation; import java.lang.reflect.Method; +import java.util.List; +import java.util.Map; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.aot.hint.MemberCategory; @@ -34,17 +35,13 @@ import static org.assertj.core.api.Assertions.assertThat; * Tests for {@link OperationReflectiveProcessor}. * * @author Moritz Halbritter + * @author Stephane Nicoll */ class OperationReflectiveProcessorTests { - private final OperationReflectiveProcessor sut = new OperationReflectiveProcessor(); + private final OperationReflectiveProcessor processor = new OperationReflectiveProcessor(); - private RuntimeHints runtimeHints; - - @BeforeEach - void setUp() { - this.runtimeHints = new RuntimeHints(); - } + private final RuntimeHints runtimeHints = new RuntimeHints(); @Test void shouldRegisterMethodAsInvokable() { @@ -57,24 +54,21 @@ class OperationReflectiveProcessorTests { void shouldRegisterReturnType() { Method method = ReflectionUtils.findMethod(Methods.class, "dto"); runProcessor(method); - assertThat(RuntimeHintsPredicates.reflection().onType(Dto.class) - .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) - .accepts(this.runtimeHints); - assertThat(RuntimeHintsPredicates.reflection().onType(NestedDto.class) - .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) - .accepts(this.runtimeHints); + assertHintsForDto(); + } + + @Test + void shouldRegisterMapValueFromReturnType() { + Method method = ReflectionUtils.findMethod(Methods.class, "dtos"); + runProcessor(method); + assertHintsForDto(); } @Test void shouldRegisterWebEndpointResponseReturnType() { Method method = ReflectionUtils.findMethod(Methods.class, "webEndpointResponse"); runProcessor(method); - assertThat(RuntimeHintsPredicates.reflection().onType(Dto.class) - .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) - .accepts(this.runtimeHints); - assertThat(RuntimeHintsPredicates.reflection().onType(NestedDto.class) - .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) - .accepts(this.runtimeHints); + assertHintsForDto(); assertThat(RuntimeHintsPredicates.reflection().onType(WebEndpointResponse.class)).rejects(this.runtimeHints); } @@ -85,16 +79,30 @@ class OperationReflectiveProcessorTests { assertThat(RuntimeHintsPredicates.reflection().onType(Resource.class)).rejects(this.runtimeHints); } - private void runProcessor(Method method) { - this.sut.registerReflectionHints(this.runtimeHints.reflection(), method); + private void assertHintsForDto() { + assertThat(RuntimeHintsPredicates.reflection().onType(Dto.class) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) + .accepts(this.runtimeHints); + assertThat(RuntimeHintsPredicates.reflection().onType(NestedDto.class) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) + .accepts(this.runtimeHints); } + private void runProcessor(Method method) { + this.processor.registerReflectionHints(this.runtimeHints.reflection(), method); + } + + @SuppressWarnings("unused") private static class Methods { private String string() { return null; } + private Map> dtos() { + return null; + } + private Dto dto() { return null; } @@ -109,6 +117,7 @@ class OperationReflectiveProcessorTests { } + @SuppressWarnings("unused") public static class Dto { private final NestedDto nestedDto = new NestedDto(); diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/jmx/annotation/JmxEndpointDiscovererRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/jmx/annotation/JmxEndpointDiscovererRuntimeHintsTests.java deleted file mode 100644 index 5b039d186a..0000000000 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/jmx/annotation/JmxEndpointDiscovererRuntimeHintsTests.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2012-2022 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.endpoint.jmx.annotation; - -import org.junit.jupiter.api.Test; - -import org.springframework.aot.hint.MemberCategory; -import org.springframework.aot.hint.RuntimeHints; -import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; -import org.springframework.boot.actuate.endpoint.jmx.annotation.JmxEndpointDiscoverer.JmxEndpointDiscovererRuntimeHints; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link JmxEndpointDiscovererRuntimeHints}. - * - * @author Moritz Halbritter - */ -class JmxEndpointDiscovererRuntimeHintsTests { - - private final JmxEndpointDiscovererRuntimeHints sut = new JmxEndpointDiscovererRuntimeHints(); - - @Test - void shouldRegisterHints() { - RuntimeHints runtimeHints = new RuntimeHints(); - this.sut.registerHints(runtimeHints, getClass().getClassLoader()); - assertThat(RuntimeHintsPredicates.reflection().onType(JmxEndpointFilter.class) - .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(runtimeHints); - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/jmx/annotation/JmxEndpointDiscovererTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/jmx/annotation/JmxEndpointDiscovererTests.java index 3fc4eaa9a3..cc004288aa 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/jmx/annotation/JmxEndpointDiscovererTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/jmx/annotation/JmxEndpointDiscovererTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,9 @@ import java.util.function.Function; import org.junit.jupiter.api.Test; +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; import org.springframework.boot.actuate.endpoint.EndpointId; import org.springframework.boot.actuate.endpoint.annotation.DeleteOperation; import org.springframework.boot.actuate.endpoint.annotation.Endpoint; @@ -37,6 +40,7 @@ import org.springframework.boot.actuate.endpoint.invoker.cache.CachingOperationI import org.springframework.boot.actuate.endpoint.jmx.ExposableJmxEndpoint; import org.springframework.boot.actuate.endpoint.jmx.JmxOperation; import org.springframework.boot.actuate.endpoint.jmx.JmxOperationParameter; +import org.springframework.boot.actuate.endpoint.jmx.annotation.JmxEndpointDiscoverer.JmxEndpointDiscovererRuntimeHints; import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpoint; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; @@ -55,6 +59,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException; * * @author Stephane Nicoll * @author Phillip Webb + * @author Moritz Halbritter */ class JmxEndpointDiscovererTests { @@ -201,6 +206,14 @@ class JmxEndpointDiscovererTests { "Endpoint bean 'nonJmxEndpoint' cannot support the extension bean 'nonJmxJmxEndpointExtension'")); } + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + new JmxEndpointDiscovererRuntimeHints().registerHints(runtimeHints, getClass().getClassLoader()); + assertThat(RuntimeHintsPredicates.reflection().onType(JmxEndpointFilter.class) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(runtimeHints); + } + private Object getInvoker(JmxOperation operation) { return ReflectionTestUtils.getField(operation, "invoker"); } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/ControllerEndpointDiscovererRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/ControllerEndpointDiscovererRuntimeHintsTests.java deleted file mode 100644 index dc7d674d4f..0000000000 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/ControllerEndpointDiscovererRuntimeHintsTests.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2012-2022 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.endpoint.web.annotation; - -import org.junit.jupiter.api.Test; - -import org.springframework.aot.hint.MemberCategory; -import org.springframework.aot.hint.RuntimeHints; -import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; -import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointDiscoverer.ControllerEndpointDiscovererRuntimeHints; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link ControllerEndpointDiscovererRuntimeHints}. - * - * @author Moritz Halbritter - */ -class ControllerEndpointDiscovererRuntimeHintsTests { - - private final ControllerEndpointDiscovererRuntimeHints sut = new ControllerEndpointDiscovererRuntimeHints(); - - @Test - void shouldRegisterHints() { - RuntimeHints runtimeHints = new RuntimeHints(); - this.sut.registerHints(runtimeHints, getClass().getClassLoader()); - assertThat(RuntimeHintsPredicates.reflection().onType(ControllerEndpointFilter.class) - .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(runtimeHints); - - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/ControllerEndpointDiscovererTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/ControllerEndpointDiscovererTests.java index 94021c018c..4ca1a8eae8 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/ControllerEndpointDiscovererTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/ControllerEndpointDiscovererTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,10 +24,14 @@ import java.util.stream.Collectors; import org.junit.jupiter.api.Test; +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; import org.springframework.boot.actuate.endpoint.EndpointId; import org.springframework.boot.actuate.endpoint.annotation.DiscoveredEndpoint; import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; +import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointDiscoverer.ControllerEndpointDiscovererRuntimeHints; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; @@ -45,6 +49,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException; * * @author Phillip Webb * @author Stephane Nicoll + * @author Moritz Halbritter */ class ControllerEndpointDiscovererTests { @@ -126,6 +131,15 @@ class ControllerEndpointDiscovererTests { .withMessageContaining("ControllerEndpoints must not declare operations"))); } + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + new ControllerEndpointDiscovererRuntimeHints().registerHints(runtimeHints, getClass().getClassLoader()); + assertThat(RuntimeHintsPredicates.reflection().onType(ControllerEndpointFilter.class) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(runtimeHints); + + } + private ContextConsumer assertDiscoverer( Consumer consumer) { return (context) -> { diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/ServletEndpointDiscovererRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/ServletEndpointDiscovererRuntimeHintsTests.java deleted file mode 100644 index 43e2cb0506..0000000000 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/ServletEndpointDiscovererRuntimeHintsTests.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2012-2022 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.endpoint.web.annotation; - -import org.junit.jupiter.api.Test; - -import org.springframework.aot.hint.MemberCategory; -import org.springframework.aot.hint.RuntimeHints; -import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; -import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointDiscoverer.ServletEndpointDiscovererRuntimeHints; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link ServletEndpointDiscovererRuntimeHints}. - * - * @author Moritz Halbritter - */ -class ServletEndpointDiscovererRuntimeHintsTests { - - private final ServletEndpointDiscovererRuntimeHints sut = new ServletEndpointDiscovererRuntimeHints(); - - @Test - void shouldRegisterHints() { - RuntimeHints runtimeHints = new RuntimeHints(); - this.sut.registerHints(runtimeHints, getClass().getClassLoader()); - assertThat(RuntimeHintsPredicates.reflection().onType(ServletEndpointFilter.class) - .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(runtimeHints); - - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/ServletEndpointDiscovererTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/ServletEndpointDiscovererTests.java index cf8593b9a7..d5ca292891 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/ServletEndpointDiscovererTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/ServletEndpointDiscovererTests.java @@ -30,12 +30,16 @@ import jakarta.servlet.ServletRequest; import jakarta.servlet.ServletResponse; import org.junit.jupiter.api.Test; +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; import org.springframework.boot.actuate.endpoint.EndpointId; import org.springframework.boot.actuate.endpoint.annotation.DiscoveredEndpoint; import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; import org.springframework.boot.actuate.endpoint.web.EndpointServlet; import org.springframework.boot.actuate.endpoint.web.ExposableServletEndpoint; +import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointDiscoverer.ServletEndpointDiscovererRuntimeHints; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; @@ -53,6 +57,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException; * * @author Phillip Webb * @author Stephane Nicoll + * @author Moritz Halbritter */ class ServletEndpointDiscovererTests { @@ -129,6 +134,14 @@ class ServletEndpointDiscovererTests { .isThrownBy(discoverer::getEndpoints).withMessageContaining("must not supply null"))); } + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + new ServletEndpointDiscovererRuntimeHints().registerHints(runtimeHints, getClass().getClassLoader()); + assertThat(RuntimeHintsPredicates.reflection().onType(ServletEndpointFilter.class) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(runtimeHints); + } + private ContextConsumer assertDiscoverer( Consumer consumer) { return (context) -> { diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/WebEndpointDiscovererRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/WebEndpointDiscovererRuntimeHintsTests.java deleted file mode 100644 index 255a0cff1f..0000000000 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/WebEndpointDiscovererRuntimeHintsTests.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2012-2022 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.endpoint.web.annotation; - -import org.junit.jupiter.api.Test; - -import org.springframework.aot.hint.MemberCategory; -import org.springframework.aot.hint.RuntimeHints; -import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; -import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointDiscoverer.WebEndpointDiscovererRuntimeHints; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link WebEndpointDiscovererRuntimeHints}. - * - * @author Moritz Halbritter - */ -class WebEndpointDiscovererRuntimeHintsTests { - - private final WebEndpointDiscovererRuntimeHints sut = new WebEndpointDiscovererRuntimeHints(); - - @Test - void shouldRegisterHints() { - RuntimeHints runtimeHints = new RuntimeHints(); - this.sut.registerHints(runtimeHints, getClass().getClassLoader()); - assertThat(RuntimeHintsPredicates.reflection().onType(WebEndpointFilter.class) - .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(runtimeHints); - - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/WebEndpointDiscovererTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/WebEndpointDiscovererTests.java index 552c7a09cb..526eee134a 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/WebEndpointDiscovererTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/annotation/WebEndpointDiscovererTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,6 +31,9 @@ import java.util.stream.Stream; import org.assertj.core.api.Condition; import org.junit.jupiter.api.Test; +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; import org.springframework.boot.actuate.endpoint.EndpointId; import org.springframework.boot.actuate.endpoint.annotation.DeleteOperation; import org.springframework.boot.actuate.endpoint.annotation.Endpoint; @@ -47,6 +50,7 @@ import org.springframework.boot.actuate.endpoint.web.PathMapper; import org.springframework.boot.actuate.endpoint.web.WebEndpointHttpMethod; import org.springframework.boot.actuate.endpoint.web.WebOperation; import org.springframework.boot.actuate.endpoint.web.WebOperationRequestPredicate; +import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointDiscoverer.WebEndpointDiscovererRuntimeHints; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -65,6 +69,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException; * @author Andy Wilkinson * @author Stephane Nicoll * @author Phillip Webb + * @author Moritz Halbritter */ class WebEndpointDiscovererTests { @@ -216,6 +221,15 @@ class WebEndpointDiscovererTests { }); } + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + new WebEndpointDiscovererRuntimeHints().registerHints(runtimeHints, getClass().getClassLoader()); + assertThat(RuntimeHintsPredicates.reflection().onType(WebEndpointFilter.class) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)).accepts(runtimeHints); + + } + private void load(Class configuration, Consumer consumer) { load((id) -> null, EndpointId::toString, configuration, consumer); } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMappingRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMappingTests.java similarity index 83% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMappingRuntimeHintsTests.java rename to spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMappingTests.java index a33f8d0928..e234dbcfc6 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMappingRuntimeHintsTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/AbstractWebFluxEndpointHandlerMappingTests.java @@ -26,18 +26,17 @@ import org.springframework.boot.actuate.endpoint.web.reactive.AbstractWebFluxEnd import static org.assertj.core.api.Assertions.assertThat; /** - * Tests for {@link AbstractWebFluxEndpointHandlerMappingRuntimeHints}. + * Tests for {@link AbstractWebFluxEndpointHandlerMapping}. * * @author Moritz Halbritter */ -class AbstractWebFluxEndpointHandlerMappingRuntimeHintsTests { - - private final AbstractWebFluxEndpointHandlerMappingRuntimeHints sut = new AbstractWebFluxEndpointHandlerMappingRuntimeHints(); +class AbstractWebFluxEndpointHandlerMappingTests { @Test void shouldRegisterHints() { RuntimeHints runtimeHints = new RuntimeHints(); - this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + new AbstractWebFluxEndpointHandlerMappingRuntimeHints().registerHints(runtimeHints, + getClass().getClassLoader()); assertThat(RuntimeHintsPredicates.reflection().onType(TypeReference.of( "org.springframework.boot.actuate.endpoint.web.reactive.AbstractWebFluxEndpointHandlerMapping.WriteOperationHandler"))) .accepts(runtimeHints); diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointHandlerMappingRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointHandlerMappingTests.java similarity index 83% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointHandlerMappingRuntimeHintsTests.java rename to spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointHandlerMappingTests.java index 78077fc257..4d02996eaa 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointHandlerMappingRuntimeHintsTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/reactive/WebFluxEndpointHandlerMappingTests.java @@ -27,18 +27,16 @@ import org.springframework.boot.actuate.endpoint.web.reactive.WebFluxEndpointHan import static org.assertj.core.api.Assertions.assertThat; /** - * Tests for {@link WebFluxEndpointHandlerMappingRuntimeHints}. + * Tests for {@link WebFluxEndpointHandlerMapping}. * * @author Moritz Halbritter */ -class WebFluxEndpointHandlerMappingRuntimeHintsTests { - - private final WebFluxEndpointHandlerMappingRuntimeHints sut = new WebFluxEndpointHandlerMappingRuntimeHints(); +class WebFluxEndpointHandlerMappingTests { @Test void shouldRegisterHints() { RuntimeHints runtimeHints = new RuntimeHints(); - this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + new WebFluxEndpointHandlerMappingRuntimeHints().registerHints(runtimeHints, getClass().getClassLoader()); assertThat(RuntimeHintsPredicates.reflection().onMethod(WebFluxLinksHandler.class, "links")) .accepts(runtimeHints); assertThat(RuntimeHintsPredicates.reflection().onType(Link.class)).accepts(runtimeHints); diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/AbstractWebMvcEndpointHandlerMappingRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/AbstractWebMvcEndpointHandlerMappingTests.java similarity index 81% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/AbstractWebMvcEndpointHandlerMappingRuntimeHintsTests.java rename to spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/AbstractWebMvcEndpointHandlerMappingTests.java index f51743f6dc..cd5a152d83 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/AbstractWebMvcEndpointHandlerMappingRuntimeHintsTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/AbstractWebMvcEndpointHandlerMappingTests.java @@ -26,18 +26,16 @@ import org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpo import static org.assertj.core.api.Assertions.assertThat; /** - * Tests for {@link AbstractWebMvcEndpointHandlerMappingRuntimeHints}. + * Tests for {@link AbstractWebMvcEndpointHandlerMapping}. * * @author Moritz Halbritter */ -class AbstractWebMvcEndpointHandlerMappingRuntimeHintsTests { - - private final AbstractWebMvcEndpointHandlerMappingRuntimeHints sut = new AbstractWebMvcEndpointHandlerMappingRuntimeHints(); +class AbstractWebMvcEndpointHandlerMappingTests { @Test void shouldRegisterHints() { RuntimeHints runtimeHints = new RuntimeHints(); - this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + new AbstractWebMvcEndpointHandlerMappingRuntimeHints().registerHints(runtimeHints, getClass().getClassLoader()); assertThat(RuntimeHintsPredicates.reflection().onType(TypeReference.of( "org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping.OperationHandler"))) .accepts(runtimeHints); diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMappingRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMappingTests.java similarity index 83% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMappingRuntimeHintsTests.java rename to spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMappingTests.java index 6351d89e46..fcfc2d3018 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMappingRuntimeHintsTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/web/servlet/WebMvcEndpointHandlerMappingTests.java @@ -27,18 +27,16 @@ import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandl import static org.assertj.core.api.Assertions.assertThat; /** - * Tests for {@link WebMvcEndpointHandlerMappingRuntimeHints}. + * Tests for {@link WebMvcEndpointHandlerMapping}. * * @author Moritz Halbritter */ -class WebMvcEndpointHandlerMappingRuntimeHintsTests { - - private final WebMvcEndpointHandlerMappingRuntimeHints sut = new WebMvcEndpointHandlerMappingRuntimeHints(); +class WebMvcEndpointHandlerMappingTests { @Test void shouldRegisterHints() { RuntimeHints runtimeHints = new RuntimeHints(); - this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + new WebMvcEndpointHandlerMappingRuntimeHints().registerHints(runtimeHints, getClass().getClassLoader()); assertThat(RuntimeHintsPredicates.reflection().onMethod(WebMvcLinksHandler.class, "links")) .accepts(runtimeHints); assertThat(RuntimeHintsPredicates.reflection().onType(Link.class)).accepts(runtimeHints); diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointWebExtensionRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointWebExtensionRuntimeHintsTests.java deleted file mode 100644 index 89c4a260c1..0000000000 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointWebExtensionRuntimeHintsTests.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2012-2022 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.health; - -import java.util.Set; - -import org.junit.jupiter.api.Test; - -import org.springframework.aot.hint.MemberCategory; -import org.springframework.aot.hint.RuntimeHints; -import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; -import org.springframework.boot.actuate.health.HealthEndpointWebExtension.HealthEndpointWebExtensionRuntimeHints; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link HealthEndpointWebExtensionRuntimeHints}. - * - * @author Moritz Halbritter - */ -class HealthEndpointWebExtensionRuntimeHintsTests { - - private final HealthEndpointWebExtensionRuntimeHints sut = new HealthEndpointWebExtensionRuntimeHints(); - - @Test - void shouldRegisterHints() { - RuntimeHints runtimeHints = new RuntimeHints(); - this.sut.registerHints(runtimeHints, getClass().getClassLoader()); - Set> bindingTypes = Set.of(Health.class, SystemHealth.class, CompositeHealth.class); - for (Class bindingType : bindingTypes) { - assertThat(RuntimeHintsPredicates.reflection().onType(bindingType) - .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) - .accepts(runtimeHints); - } - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointWebExtensionTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointWebExtensionTests.java index 56f44169ce..eaa93b7662 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointWebExtensionTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointWebExtensionTests.java @@ -19,14 +19,19 @@ package org.springframework.boot.actuate.health; import java.time.Duration; import java.util.Collections; import java.util.Map; +import java.util.Set; import org.junit.jupiter.api.Test; +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; import org.springframework.boot.actuate.endpoint.ApiVersion; import org.springframework.boot.actuate.endpoint.SecurityContext; import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse; import org.springframework.boot.actuate.endpoint.web.WebServerNamespace; import org.springframework.boot.actuate.health.HealthEndpointSupport.HealthResult; +import org.springframework.boot.actuate.health.HealthEndpointWebExtension.HealthEndpointWebExtensionRuntimeHints; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -36,6 +41,7 @@ import static org.mockito.Mockito.mock; * * @author Phillip Webb * @author Scott Frederick + * @author Moritz Halbritter */ class HealthEndpointWebExtensionTests extends HealthEndpointSupportTests { @@ -81,6 +87,18 @@ class HealthEndpointWebExtensionTests extends assertThat(response.getStatus()).isEqualTo(200); } + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + new HealthEndpointWebExtensionRuntimeHints().registerHints(runtimeHints, getClass().getClassLoader()); + Set> bindingTypes = Set.of(Health.class, SystemHealth.class, CompositeHealth.class); + for (Class bindingType : bindingTypes) { + assertThat(RuntimeHintsPredicates.reflection().onType(bindingType) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) + .accepts(runtimeHints); + } + } + @Override protected HealthEndpointWebExtension create(HealthContributorRegistry registry, HealthEndpointGroups groups, Duration slowIndicatorLoggingThreshold) { diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/BuildInfoContributorRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/BuildInfoContributorTests.java similarity index 84% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/BuildInfoContributorRuntimeHintsTests.java rename to spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/BuildInfoContributorTests.java index aa1af63019..5c3a7e195e 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/BuildInfoContributorRuntimeHintsTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/BuildInfoContributorTests.java @@ -27,18 +27,16 @@ import org.springframework.boot.info.BuildProperties; import static org.assertj.core.api.Assertions.assertThat; /** - * Tests for {@link BuildInfoContributorRuntimeHints}. + * Tests for {@link BuildInfoContributor}. * * @author Moritz Halbritter */ -class BuildInfoContributorRuntimeHintsTests { - - private final BuildInfoContributorRuntimeHints sut = new BuildInfoContributorRuntimeHints(); +class BuildInfoContributorTests { @Test void shouldRegisterHints() { RuntimeHints runtimeHints = new RuntimeHints(); - this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + new BuildInfoContributorRuntimeHints().registerHints(runtimeHints, getClass().getClassLoader()); assertThat(RuntimeHintsPredicates.reflection().onType(BuildProperties.class) .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) .accepts(runtimeHints); diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/GitInfoContributorRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/GitInfoContributorRuntimeHintsTests.java deleted file mode 100644 index fd2e1f1c17..0000000000 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/GitInfoContributorRuntimeHintsTests.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2012-2022 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.info; - -import org.junit.jupiter.api.Test; - -import org.springframework.aot.hint.MemberCategory; -import org.springframework.aot.hint.RuntimeHints; -import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; -import org.springframework.boot.actuate.info.GitInfoContributor.GitInfoContributorRuntimeHints; -import org.springframework.boot.info.GitProperties; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests forr {@link GitInfoContributorRuntimeHints}. - * - * @author Moritz Halbritter - */ -class GitInfoContributorRuntimeHintsTests { - - private final GitInfoContributorRuntimeHints sut = new GitInfoContributorRuntimeHints(); - - @Test - void shouldRegisterHints() { - RuntimeHints runtimeHints = new RuntimeHints(); - this.sut.registerHints(runtimeHints, getClass().getClassLoader()); - assertThat(RuntimeHintsPredicates.reflection().onType(GitProperties.class) - .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) - .accepts(runtimeHints); - - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/GitInfoContributorTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/GitInfoContributorTests.java index c253472384..c29fc0a674 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/GitInfoContributorTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/GitInfoContributorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,10 @@ import java.util.Properties; import org.junit.jupiter.api.Test; +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.actuate.info.GitInfoContributor.GitInfoContributorRuntimeHints; import org.springframework.boot.actuate.info.InfoPropertiesInfoContributor.Mode; import org.springframework.boot.info.GitProperties; @@ -31,6 +35,7 @@ import static org.assertj.core.api.Assertions.assertThat; * Tests for {@link GitInfoContributor}. * * @author Stephane Nicoll + * @author Moritz Halbritter */ class GitInfoContributorTests { @@ -79,4 +84,14 @@ class GitInfoContributorTests { assertThat(id.get("abbrev")).isEqualTo("1b3cec3"); } + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + new GitInfoContributorRuntimeHints().registerHints(runtimeHints, getClass().getClassLoader()); + assertThat(RuntimeHintsPredicates.reflection().onType(GitProperties.class) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) + .accepts(runtimeHints); + + } + } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/JavaInfoContributorRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/JavaInfoContributorRuntimeHintsTests.java deleted file mode 100644 index 7490ac60a6..0000000000 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/JavaInfoContributorRuntimeHintsTests.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2012-2022 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.info; - -import org.junit.jupiter.api.Test; - -import org.springframework.aot.hint.MemberCategory; -import org.springframework.aot.hint.RuntimeHints; -import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; -import org.springframework.boot.actuate.info.JavaInfoContributor.JavaInfoContributorRuntimeHints; -import org.springframework.boot.info.JavaInfo; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link JavaInfoContributorRuntimeHints}. - * - * @author Moritz Halbritter - */ -class JavaInfoContributorRuntimeHintsTests { - - private final JavaInfoContributorRuntimeHints sut = new JavaInfoContributorRuntimeHints(); - - @Test - void shouldRegisterHints() { - RuntimeHints runtimeHints = new RuntimeHints(); - this.sut.registerHints(runtimeHints, getClass().getClassLoader()); - assertThat(RuntimeHintsPredicates.reflection().onType(JavaInfo.class) - .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) - .accepts(runtimeHints); - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/JavaInfoContributorTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/JavaInfoContributorTests.java index f431ccd90e..ec4747d998 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/JavaInfoContributorTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/JavaInfoContributorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,10 @@ package org.springframework.boot.actuate.info; import org.junit.jupiter.api.Test; +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.actuate.info.JavaInfoContributor.JavaInfoContributorRuntimeHints; import org.springframework.boot.info.JavaInfo; import static org.assertj.core.api.Assertions.assertThat; @@ -26,6 +30,7 @@ import static org.assertj.core.api.Assertions.assertThat; * Tests for {@link JavaInfoContributor} * * @author Jonatan Ivanov + * @author Moritz Halbritter */ class JavaInfoContributorTests { @@ -38,4 +43,13 @@ class JavaInfoContributorTests { assertThat(info.getDetails().get("java")).isInstanceOf(JavaInfo.class); } + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + new JavaInfoContributorRuntimeHints().registerHints(runtimeHints, getClass().getClassLoader()); + assertThat(RuntimeHintsPredicates.reflection().onType(JavaInfo.class) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) + .accepts(runtimeHints); + } + } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/OsInfoContributorRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/OsInfoContributorRuntimeHintsTests.java deleted file mode 100644 index 893daa341e..0000000000 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/OsInfoContributorRuntimeHintsTests.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2012-2022 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.info; - -import org.junit.jupiter.api.Test; - -import org.springframework.aot.hint.MemberCategory; -import org.springframework.aot.hint.RuntimeHints; -import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; -import org.springframework.boot.actuate.info.OsInfoContributor.OsInfoContributorRuntimeHints; -import org.springframework.boot.info.OsInfo; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link OsInfoContributorRuntimeHints}. - * - * @author Moritz Halbritter - */ -class OsInfoContributorRuntimeHintsTests { - - private final OsInfoContributorRuntimeHints sut = new OsInfoContributorRuntimeHints(); - - @Test - void shouldRegisterHints() { - RuntimeHints runtimeHints = new RuntimeHints(); - this.sut.registerHints(runtimeHints, getClass().getClassLoader()); - assertThat(RuntimeHintsPredicates.reflection().onType(OsInfo.class) - .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) - .accepts(runtimeHints); - - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/OsInfoContributorTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/OsInfoContributorTests.java index 333a683c46..ea85185dc6 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/OsInfoContributorTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/info/OsInfoContributorTests.java @@ -18,6 +18,10 @@ package org.springframework.boot.actuate.info; import org.junit.jupiter.api.Test; +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.actuate.info.OsInfoContributor.OsInfoContributorRuntimeHints; import org.springframework.boot.info.OsInfo; import static org.assertj.core.api.Assertions.assertThat; @@ -26,6 +30,7 @@ import static org.assertj.core.api.Assertions.assertThat; * Tests for {@link OsInfoContributor} * * @author Jonatan Ivanov + * @author Moritz Halbritter */ class OsInfoContributorTests { @@ -38,4 +43,13 @@ class OsInfoContributorTests { assertThat(info.getDetails().get("os")).isInstanceOf(OsInfo.class); } + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + new OsInfoContributorRuntimeHints().registerHints(runtimeHints, getClass().getClassLoader()); + assertThat(RuntimeHintsPredicates.reflection().onType(OsInfo.class) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) + .accepts(runtimeHints); + } + } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/integration/IntegrationGraphEndpointRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/integration/IntegrationGraphEndpointRuntimeHintsTests.java deleted file mode 100644 index 51d7e7c076..0000000000 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/integration/IntegrationGraphEndpointRuntimeHintsTests.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2012-2022 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.integration; - -import java.util.Set; - -import org.junit.jupiter.api.Test; - -import org.springframework.aot.hint.MemberCategory; -import org.springframework.aot.hint.RuntimeHints; -import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; -import org.springframework.boot.actuate.integration.IntegrationGraphEndpoint.IntegrationGraphEndpointRuntimeHints; -import org.springframework.integration.graph.CompositeMessageHandlerNode; -import org.springframework.integration.graph.DiscardingMessageHandlerNode; -import org.springframework.integration.graph.EndpointNode; -import org.springframework.integration.graph.ErrorCapableCompositeMessageHandlerNode; -import org.springframework.integration.graph.ErrorCapableDiscardingMessageHandlerNode; -import org.springframework.integration.graph.ErrorCapableEndpointNode; -import org.springframework.integration.graph.ErrorCapableMessageHandlerNode; -import org.springframework.integration.graph.ErrorCapableRoutingNode; -import org.springframework.integration.graph.Graph; -import org.springframework.integration.graph.MessageChannelNode; -import org.springframework.integration.graph.MessageGatewayNode; -import org.springframework.integration.graph.MessageHandlerNode; -import org.springframework.integration.graph.MessageProducerNode; -import org.springframework.integration.graph.MessageSourceNode; -import org.springframework.integration.graph.PollableChannelNode; -import org.springframework.integration.graph.RoutingMessageHandlerNode; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link IntegrationGraphEndpointRuntimeHints}. - * - * @author Moritz Halbritter - */ -class IntegrationGraphEndpointRuntimeHintsTests { - - private final IntegrationGraphEndpointRuntimeHints sut = new IntegrationGraphEndpointRuntimeHints(); - - @Test - void shouldRegisterHints() { - RuntimeHints runtimeHints = new RuntimeHints(); - this.sut.registerHints(runtimeHints, getClass().getClassLoader()); - Set> bindingTypes = Set.of(Graph.class, EndpointNode.class, CompositeMessageHandlerNode.class, - DiscardingMessageHandlerNode.class, ErrorCapableCompositeMessageHandlerNode.class, - ErrorCapableDiscardingMessageHandlerNode.class, ErrorCapableEndpointNode.class, - ErrorCapableMessageHandlerNode.class, ErrorCapableRoutingNode.class, MessageGatewayNode.class, - MessageProducerNode.class, PollableChannelNode.class, MessageChannelNode.class, - MessageHandlerNode.class, MessageSourceNode.class, RoutingMessageHandlerNode.class); - for (Class bindingType : bindingTypes) { - assertThat(RuntimeHintsPredicates.reflection().onType(bindingType) - .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) - .accepts(runtimeHints); - } - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/integration/IntegrationGraphEndpointTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/integration/IntegrationGraphEndpointTests.java index c832b2d054..2a8a63f50c 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/integration/IntegrationGraphEndpointTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/integration/IntegrationGraphEndpointTests.java @@ -16,10 +16,31 @@ package org.springframework.boot.actuate.integration; +import java.util.Set; + import org.junit.jupiter.api.Test; +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.actuate.integration.IntegrationGraphEndpoint.IntegrationGraphEndpointRuntimeHints; +import org.springframework.integration.graph.CompositeMessageHandlerNode; +import org.springframework.integration.graph.DiscardingMessageHandlerNode; +import org.springframework.integration.graph.EndpointNode; +import org.springframework.integration.graph.ErrorCapableCompositeMessageHandlerNode; +import org.springframework.integration.graph.ErrorCapableDiscardingMessageHandlerNode; +import org.springframework.integration.graph.ErrorCapableEndpointNode; +import org.springframework.integration.graph.ErrorCapableMessageHandlerNode; +import org.springframework.integration.graph.ErrorCapableRoutingNode; import org.springframework.integration.graph.Graph; import org.springframework.integration.graph.IntegrationGraphServer; +import org.springframework.integration.graph.MessageChannelNode; +import org.springframework.integration.graph.MessageGatewayNode; +import org.springframework.integration.graph.MessageHandlerNode; +import org.springframework.integration.graph.MessageProducerNode; +import org.springframework.integration.graph.MessageSourceNode; +import org.springframework.integration.graph.PollableChannelNode; +import org.springframework.integration.graph.RoutingMessageHandlerNode; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; @@ -30,6 +51,7 @@ import static org.mockito.Mockito.mock; * Tests for {@link IntegrationGraphEndpoint}. * * @author Tim Ysewyn + * @author Moritz Halbritter */ class IntegrationGraphEndpointTests { @@ -52,4 +74,21 @@ class IntegrationGraphEndpointTests { then(this.server).should().rebuild(); } + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + new IntegrationGraphEndpointRuntimeHints().registerHints(runtimeHints, getClass().getClassLoader()); + Set> bindingTypes = Set.of(Graph.class, EndpointNode.class, CompositeMessageHandlerNode.class, + DiscardingMessageHandlerNode.class, ErrorCapableCompositeMessageHandlerNode.class, + ErrorCapableDiscardingMessageHandlerNode.class, ErrorCapableEndpointNode.class, + ErrorCapableMessageHandlerNode.class, ErrorCapableRoutingNode.class, MessageGatewayNode.class, + MessageProducerNode.class, PollableChannelNode.class, MessageChannelNode.class, + MessageHandlerNode.class, MessageSourceNode.class, RoutingMessageHandlerNode.class); + for (Class bindingType : bindingTypes) { + assertThat(RuntimeHintsPredicates.reflection().onType(bindingType) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) + .accepts(runtimeHints); + } + } + } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/management/ThreadDumpEndpointWebExtensionTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/management/ThreadDumpEndpointWebExtensionTests.java index c073558402..a565b04919 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/management/ThreadDumpEndpointWebExtensionTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/management/ThreadDumpEndpointWebExtensionTests.java @@ -34,21 +34,21 @@ import static org.assertj.core.api.Assertions.assertThat; */ class ThreadDumpEndpointWebExtensionTests { - private ThreadDumpEndpointWebExtension sut; + private ThreadDumpEndpointWebExtension extension; private ThreadDumpEndpoint delegateMock; @BeforeEach void setUp() { this.delegateMock = Mockito.mock(ThreadDumpEndpoint.class); - this.sut = new ThreadDumpEndpointWebExtension(this.delegateMock); + this.extension = new ThreadDumpEndpointWebExtension(this.delegateMock); } @Test void shouldHandleThreadDumperUnavailable() { Mockito.when(this.delegateMock.threadDump()) .thenThrow(new ThreadDumperUnavailableException("No thread dumper available")); - WebEndpointResponse response = this.sut.threadDump(); + WebEndpointResponse response = this.extension.threadDump(); assertThat(response.getStatus()).isEqualTo(HttpStatus.SERVICE_UNAVAILABLE.value()); } @@ -56,7 +56,7 @@ class ThreadDumpEndpointWebExtensionTests { void shouldHandleThreadDumperUnavailableText() { Mockito.when(this.delegateMock.textThreadDump()) .thenThrow(new ThreadDumperUnavailableException("No thread dumper available")); - WebEndpointResponse response = this.sut.textThreadDump(); + WebEndpointResponse response = this.extension.textThreadDump(); assertThat(response.getStatus()).isEqualTo(HttpStatus.SERVICE_UNAVAILABLE.value()); } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProviderRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProviderRuntimeHintsTests.java deleted file mode 100644 index 7101421547..0000000000 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProviderRuntimeHintsTests.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2012-2022 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.metrics.cache; - -import com.hazelcast.spring.cache.HazelcastCache; -import io.micrometer.core.instrument.binder.cache.HazelcastCacheMetrics; -import org.junit.jupiter.api.Test; - -import org.springframework.aot.hint.RuntimeHints; -import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; -import org.springframework.boot.actuate.metrics.cache.HazelcastCacheMeterBinderProvider.HazelcastCacheMeterBinderProviderRuntimeHints; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link HazelcastCacheMeterBinderProviderRuntimeHints}. - * - * @author Moritz Halbritter - */ -class HazelcastCacheMeterBinderProviderRuntimeHintsTests { - - private final HazelcastCacheMeterBinderProviderRuntimeHints sut = new HazelcastCacheMeterBinderProviderRuntimeHints(); - - @Test - void shouldRegisterHints() { - RuntimeHints runtimeHints = new RuntimeHints(); - this.sut.registerHints(runtimeHints, getClass().getClassLoader()); - assertThat(RuntimeHintsPredicates.reflection().onMethod(HazelcastCache.class, "getNativeCache")) - .accepts(runtimeHints); - assertThat(RuntimeHintsPredicates.reflection().onType(HazelcastCacheMetrics.class)).accepts(runtimeHints); - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProviderTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProviderTests.java index 737e8b855b..4e3400dacc 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProviderTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/cache/HazelcastCacheMeterBinderProviderTests.java @@ -24,6 +24,10 @@ import io.micrometer.core.instrument.binder.MeterBinder; import io.micrometer.core.instrument.binder.cache.HazelcastCacheMetrics; import org.junit.jupiter.api.Test; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; +import org.springframework.boot.actuate.metrics.cache.HazelcastCacheMeterBinderProvider.HazelcastCacheMeterBinderProviderRuntimeHints; + import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; @@ -32,6 +36,7 @@ import static org.mockito.Mockito.mock; * Tests for {@link HazelcastCacheMeterBinderProvider}. * * @author Stephane Nicoll + * @author Moritz Halbritter */ class HazelcastCacheMeterBinderProviderTests { @@ -46,4 +51,13 @@ class HazelcastCacheMeterBinderProviderTests { assertThat(meterBinder).isInstanceOf(HazelcastCacheMetrics.class); } + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + new HazelcastCacheMeterBinderProviderRuntimeHints().registerHints(runtimeHints, getClass().getClassLoader()); + assertThat(RuntimeHintsPredicates.reflection().onMethod(HazelcastCache.class, "getNativeCache")) + .accepts(runtimeHints); + assertThat(RuntimeHintsPredicates.reflection().onType(HazelcastCacheMetrics.class)).accepts(runtimeHints); + } + } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/quartz/QuartzEndpointWebExtensionRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/quartz/QuartzEndpointWebExtensionTests.java similarity index 87% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/quartz/QuartzEndpointWebExtensionRuntimeHintsTests.java rename to spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/quartz/QuartzEndpointWebExtensionTests.java index 503424683a..22ba2721bc 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/quartz/QuartzEndpointWebExtensionRuntimeHintsTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/quartz/QuartzEndpointWebExtensionTests.java @@ -32,18 +32,16 @@ import org.springframework.boot.actuate.quartz.QuartzEndpointWebExtension.Quartz import static org.assertj.core.api.Assertions.assertThat; /** - * Tests for {@link QuartzEndpointWebExtensionRuntimeHints}. + * Tests for {@link QuartzEndpointWebExtension}. * * @author Moritz Halbritter */ -class QuartzEndpointWebExtensionRuntimeHintsTests { - - private final QuartzEndpointWebExtensionRuntimeHints sut = new QuartzEndpointWebExtensionRuntimeHints(); +class QuartzEndpointWebExtensionTests { @Test void shouldRegisterHints() { RuntimeHints runtimeHints = new RuntimeHints(); - this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + new QuartzEndpointWebExtensionRuntimeHints().registerHints(runtimeHints, getClass().getClassLoader()); Set> bindingTypes = Set.of(QuartzGroups.class, QuartzJobDetails.class, QuartzJobGroupSummary.class, QuartzTriggerGroupSummary.class); for (Class bindingType : bindingTypes) { diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/scheduling/ScheduledTasksEndpointRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/scheduling/ScheduledTasksEndpointRuntimeHintsTests.java deleted file mode 100644 index d227347655..0000000000 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/scheduling/ScheduledTasksEndpointRuntimeHintsTests.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2012-2022 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.scheduling; - -import java.util.Set; - -import org.junit.jupiter.api.Test; - -import org.springframework.aot.hint.MemberCategory; -import org.springframework.aot.hint.RuntimeHints; -import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; -import org.springframework.boot.actuate.scheduling.ScheduledTasksEndpoint.CronTaskDescription; -import org.springframework.boot.actuate.scheduling.ScheduledTasksEndpoint.CustomTriggerTaskDescription; -import org.springframework.boot.actuate.scheduling.ScheduledTasksEndpoint.FixedDelayTaskDescription; -import org.springframework.boot.actuate.scheduling.ScheduledTasksEndpoint.FixedRateTaskDescription; -import org.springframework.boot.actuate.scheduling.ScheduledTasksEndpoint.ScheduledTasksEndpointRuntimeHints; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link ScheduledTasksEndpointRuntimeHints}. - * - * @author Moritz Halbritter - */ -class ScheduledTasksEndpointRuntimeHintsTests { - - private final ScheduledTasksEndpointRuntimeHints sut = new ScheduledTasksEndpointRuntimeHints(); - - @Test - void shouldRegisterHints() { - RuntimeHints runtimeHints = new RuntimeHints(); - this.sut.registerHints(runtimeHints, getClass().getClassLoader()); - Set> bindingTypes = Set.of(FixedRateTaskDescription.class, FixedDelayTaskDescription.class, - CronTaskDescription.class, CustomTriggerTaskDescription.class); - for (Class bindingType : bindingTypes) { - assertThat(RuntimeHintsPredicates.reflection().onType(bindingType) - .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) - .accepts(runtimeHints); - } - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/scheduling/ScheduledTasksEndpointTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/scheduling/ScheduledTasksEndpointTests.java index 8d22b6f9c6..eaed65550d 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/scheduling/ScheduledTasksEndpointTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/scheduling/ScheduledTasksEndpointTests.java @@ -19,14 +19,19 @@ package org.springframework.boot.actuate.scheduling; import java.time.Duration; import java.time.Instant; import java.util.Collection; +import java.util.Set; import java.util.function.Consumer; import org.junit.jupiter.api.Test; +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; import org.springframework.boot.actuate.scheduling.ScheduledTasksEndpoint.CronTaskDescription; import org.springframework.boot.actuate.scheduling.ScheduledTasksEndpoint.CustomTriggerTaskDescription; import org.springframework.boot.actuate.scheduling.ScheduledTasksEndpoint.FixedDelayTaskDescription; import org.springframework.boot.actuate.scheduling.ScheduledTasksEndpoint.FixedRateTaskDescription; +import org.springframework.boot.actuate.scheduling.ScheduledTasksEndpoint.ScheduledTasksEndpointRuntimeHints; import org.springframework.boot.actuate.scheduling.ScheduledTasksEndpoint.ScheduledTasksReport; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; @@ -46,6 +51,7 @@ import static org.assertj.core.api.Assertions.assertThat; * Tests for {@link ScheduledTasksEndpoint}. * * @author Andy Wilkinson + * @author Moritz Halbritter */ class ScheduledTasksEndpointTests { @@ -149,6 +155,19 @@ class ScheduledTasksEndpointTests { }); } + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + new ScheduledTasksEndpointRuntimeHints().registerHints(runtimeHints, getClass().getClassLoader()); + Set> bindingTypes = Set.of(FixedRateTaskDescription.class, FixedDelayTaskDescription.class, + CronTaskDescription.class, CustomTriggerTaskDescription.class); + for (Class bindingType : bindingTypes) { + assertThat(RuntimeHintsPredicates.reflection().onType(bindingType) + .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) + .accepts(runtimeHints); + } + } + private void run(Class configuration, Consumer consumer) { this.contextRunner.withUserConfiguration(configuration) .run((context) -> consumer.accept(context.getBean(ScheduledTasksEndpoint.class).scheduledTasks())); diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/startup/StartupEndpointRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/startup/StartupEndpointRuntimeHintsTests.java deleted file mode 100644 index bc65478ab7..0000000000 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/startup/StartupEndpointRuntimeHintsTests.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2012-2022 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.actuate.startup; - -import java.util.Set; - -import org.junit.jupiter.api.Test; - -import org.springframework.aot.hint.MemberCategory; -import org.springframework.aot.hint.RuntimeHints; -import org.springframework.aot.hint.TypeReference; -import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; -import org.springframework.boot.actuate.startup.StartupEndpoint.StartupEndpointRuntimeHints; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link StartupEndpointRuntimeHints}. - * - * @author Moritz Halbritter - */ -class StartupEndpointRuntimeHintsTests { - - private final StartupEndpointRuntimeHints sut = new StartupEndpointRuntimeHints(); - - @Test - void shouldRegisterHints() { - RuntimeHints runtimeHints = new RuntimeHints(); - this.sut.registerHints(runtimeHints, getClass().getClassLoader()); - Set bindingTypes = Set.of( - TypeReference.of("org.springframework.boot.context.metrics.buffering.BufferedStartupStep$DefaultTag"), - TypeReference.of("org.springframework.core.metrics.jfr.FlightRecorderStartupStep$FlightRecorderTag")); - for (TypeReference bindingType : bindingTypes) { - assertThat(RuntimeHintsPredicates.reflection().onType(bindingType) - .withMemberCategories(MemberCategory.INVOKE_PUBLIC_METHODS)).accepts(runtimeHints); - } - } - -} diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/startup/StartupEndpointTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/startup/StartupEndpointTests.java index 6e9ae9e5b2..206d6151bd 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/startup/StartupEndpointTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/startup/StartupEndpointTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,11 +16,17 @@ package org.springframework.boot.actuate.startup; +import java.util.Set; import java.util.function.Consumer; import org.junit.jupiter.api.Test; +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.TypeReference; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; import org.springframework.boot.SpringBootVersion; +import org.springframework.boot.actuate.startup.StartupEndpoint.StartupEndpointRuntimeHints; import org.springframework.boot.actuate.startup.StartupEndpoint.StartupResponse; import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -35,6 +41,7 @@ import static org.assertj.core.api.Assertions.assertThat; * * @author Brian Clozel * @author Chris Bono + * @author Moritz Halbritter */ class StartupEndpointTests { @@ -69,6 +76,19 @@ class StartupEndpointTests { }); } + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + new StartupEndpointRuntimeHints().registerHints(runtimeHints, getClass().getClassLoader()); + Set bindingTypes = Set.of( + TypeReference.of("org.springframework.boot.context.metrics.buffering.BufferedStartupStep$DefaultTag"), + TypeReference.of("org.springframework.core.metrics.jfr.FlightRecorderStartupStep$FlightRecorderTag")); + for (TypeReference bindingType : bindingTypes) { + assertThat(RuntimeHintsPredicates.reflection().onType(bindingType) + .withMemberCategories(MemberCategory.INVOKE_PUBLIC_METHODS)).accepts(runtimeHints); + } + } + private void testStartupEndpoint(ApplicationStartup applicationStartup, Consumer startupEndpoint) { ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withInitializer((context) -> context.setApplicationStartup(applicationStartup)) diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/reactive/DispatcherHandlersMappingDescriptionProviderRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/reactive/DispatcherHandlersMappingDescriptionProviderTests.java similarity index 83% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/reactive/DispatcherHandlersMappingDescriptionProviderRuntimeHintsTests.java rename to spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/reactive/DispatcherHandlersMappingDescriptionProviderTests.java index 990d9aa85b..6d5dcac318 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/reactive/DispatcherHandlersMappingDescriptionProviderRuntimeHintsTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/reactive/DispatcherHandlersMappingDescriptionProviderTests.java @@ -26,18 +26,17 @@ import org.springframework.boot.actuate.web.mappings.reactive.DispatcherHandlers import static org.assertj.core.api.Assertions.assertThat; /** - * Tests for {@link DispatcherHandlersMappingDescriptionProviderRuntimeHints}. + * Tests for {@link DispatcherHandlersMappingDescriptionProvider}. * * @author Moritz Halbritter */ -class DispatcherHandlersMappingDescriptionProviderRuntimeHintsTests { - - private final DispatcherHandlersMappingDescriptionProviderRuntimeHints sut = new DispatcherHandlersMappingDescriptionProviderRuntimeHints(); +class DispatcherHandlersMappingDescriptionProviderTests { @Test void shouldRegisterHints() { RuntimeHints runtimeHints = new RuntimeHints(); - this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + new DispatcherHandlersMappingDescriptionProviderRuntimeHints().registerHints(runtimeHints, + getClass().getClassLoader()); assertThat(RuntimeHintsPredicates.reflection().onType(DispatcherHandlerMappingDescription.class) .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) .accepts(runtimeHints); diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/DispatcherServletsMappingDescriptionProviderRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/DispatcherServletsMappingDescriptionProviderTests.java similarity index 83% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/DispatcherServletsMappingDescriptionProviderRuntimeHintsTests.java rename to spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/DispatcherServletsMappingDescriptionProviderTests.java index b7b58cc135..1cb0f46126 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/DispatcherServletsMappingDescriptionProviderRuntimeHintsTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/DispatcherServletsMappingDescriptionProviderTests.java @@ -26,18 +26,17 @@ import org.springframework.boot.actuate.web.mappings.servlet.DispatcherServletsM import static org.assertj.core.api.Assertions.assertThat; /** - * Tests for {@link DispatcherServletsMappingDescriptionProviderRuntimeHints}. + * Tests for {@link DispatcherServletsMappingDescriptionProvider}. * * @author Moritz Halbritter */ -class DispatcherServletsMappingDescriptionProviderRuntimeHintsTests { - - private final DispatcherServletsMappingDescriptionProviderRuntimeHints sut = new DispatcherServletsMappingDescriptionProviderRuntimeHints(); +class DispatcherServletsMappingDescriptionProviderTests { @Test void shouldRegisterHints() { RuntimeHints runtimeHints = new RuntimeHints(); - this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + new DispatcherServletsMappingDescriptionProviderRuntimeHints().registerHints(runtimeHints, + getClass().getClassLoader()); assertThat(RuntimeHintsPredicates.reflection().onType(DispatcherServletMappingDescription.class) .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) .accepts(runtimeHints); diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/FiltersMappingDescriptionProviderRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/FiltersMappingDescriptionProviderTests.java similarity index 82% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/FiltersMappingDescriptionProviderRuntimeHintsTests.java rename to spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/FiltersMappingDescriptionProviderTests.java index 81e6ae5f07..62fb4e8846 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/FiltersMappingDescriptionProviderRuntimeHintsTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/FiltersMappingDescriptionProviderTests.java @@ -26,18 +26,16 @@ import org.springframework.boot.actuate.web.mappings.servlet.FiltersMappingDescr import static org.assertj.core.api.Assertions.assertThat; /** - * Tests for {@link FiltersMappingDescriptionProviderRuntimeHints}. + * Tests for {@link FiltersMappingDescriptionProvider}. * * @author Moritz Halbritter */ -class FiltersMappingDescriptionProviderRuntimeHintsTests { - - private final FiltersMappingDescriptionProviderRuntimeHints sut = new FiltersMappingDescriptionProviderRuntimeHints(); +class FiltersMappingDescriptionProviderTests { @Test void shouldRegisterHints() { RuntimeHints runtimeHints = new RuntimeHints(); - this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + new FiltersMappingDescriptionProviderRuntimeHints().registerHints(runtimeHints, getClass().getClassLoader()); assertThat(RuntimeHintsPredicates.reflection().onType(FilterRegistrationMappingDescription.class) .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) .accepts(runtimeHints); diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/ServletsMappingDescriptionProviderRuntimeHintsTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/ServletsMappingDescriptionProviderTests.java similarity index 82% rename from spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/ServletsMappingDescriptionProviderRuntimeHintsTests.java rename to spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/ServletsMappingDescriptionProviderTests.java index aa19dadc42..912f8151b1 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/ServletsMappingDescriptionProviderRuntimeHintsTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/web/mappings/servlet/ServletsMappingDescriptionProviderTests.java @@ -26,18 +26,16 @@ import org.springframework.boot.actuate.web.mappings.servlet.ServletsMappingDesc import static org.assertj.core.api.Assertions.assertThat; /** - * Tests for {@link ServletsMappingDescriptionProviderRuntimeHints}. + * Tests for {@link ServletsMappingDescriptionProvider}. * * @author Moritz Halbritter */ -class ServletsMappingDescriptionProviderRuntimeHintsTests { - - private final ServletsMappingDescriptionProviderRuntimeHints sut = new ServletsMappingDescriptionProviderRuntimeHints(); +class ServletsMappingDescriptionProviderTests { @Test void shouldRegisterHints() { RuntimeHints runtimeHints = new RuntimeHints(); - this.sut.registerHints(runtimeHints, getClass().getClassLoader()); + new ServletsMappingDescriptionProviderRuntimeHints().registerHints(runtimeHints, getClass().getClassLoader()); assertThat(RuntimeHintsPredicates.reflection().onType(ServletRegistrationMappingDescription.class) .withMemberCategories(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) .accepts(runtimeHints); diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/info/BuildPropertiesRuntimeHintsTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/info/BuildPropertiesRuntimeHintsTests.java deleted file mode 100644 index e8be5ba690..0000000000 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/info/BuildPropertiesRuntimeHintsTests.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2012-2022 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.info; - -import org.junit.jupiter.api.Test; - -import org.springframework.aot.hint.RuntimeHints; -import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; -import org.springframework.boot.info.BuildProperties.BuildPropertiesRuntimeHints; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link BuildPropertiesRuntimeHints}. - * - * @author Moritz Halbritter - */ -class BuildPropertiesRuntimeHintsTests { - - private final BuildPropertiesRuntimeHints sut = new BuildPropertiesRuntimeHints(); - - @Test - void shouldRegisterHints() { - RuntimeHints runtimeHints = new RuntimeHints(); - this.sut.registerHints(runtimeHints, getClass().getClassLoader()); - assertThat(RuntimeHintsPredicates.resource().forResource("META-INF/build-info.properties")) - .accepts(runtimeHints); - } - -} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/info/BuildPropertiesTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/info/BuildPropertiesTests.java index 809d0e8eba..276539a8b9 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/info/BuildPropertiesTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/info/BuildPropertiesTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,12 +23,16 @@ import java.util.Properties; import org.junit.jupiter.api.Test; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; + import static org.assertj.core.api.Assertions.assertThat; /** * Tests for {@link BuildProperties}. * * @author Stephane Nicoll + * @author Moritz Halbritter */ class BuildPropertiesTests { @@ -53,6 +57,14 @@ class BuildPropertiesTests { assertThat(properties.getTime()).isNull(); } + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + new BuildProperties.BuildPropertiesRuntimeHints().registerHints(runtimeHints, getClass().getClassLoader()); + assertThat(RuntimeHintsPredicates.resource().forResource("META-INF/build-info.properties")) + .accepts(runtimeHints); + } + private static Properties createProperties(String group, String artifact, String version, String buildTime) { Properties properties = new Properties(); properties.put("group", group); diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/info/GitPropertiesRuntimeHintsTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/info/GitPropertiesRuntimeHintsTests.java deleted file mode 100644 index 93de2c71a4..0000000000 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/info/GitPropertiesRuntimeHintsTests.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2012-2022 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.boot.info; - -import org.junit.jupiter.api.Test; - -import org.springframework.aot.hint.RuntimeHints; -import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; -import org.springframework.boot.info.GitProperties.GitPropertiesRuntimeHints; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link GitPropertiesRuntimeHints}. - * - * @author Moritz Halbritter - */ -class GitPropertiesRuntimeHintsTests { - - private final GitPropertiesRuntimeHints sut = new GitPropertiesRuntimeHints(); - - @Test - void shouldRegisterHints() { - RuntimeHints runtimeHints = new RuntimeHints(); - this.sut.registerHints(runtimeHints, getClass().getClassLoader()); - assertThat(RuntimeHintsPredicates.resource().forResource("git.properties")).accepts(runtimeHints); - } - -} diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/info/GitPropertiesTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/info/GitPropertiesTests.java index b00b8fb269..0a6d583d8e 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/info/GitPropertiesTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/info/GitPropertiesTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,12 +20,16 @@ import java.util.Properties; import org.junit.jupiter.api.Test; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; + import static org.assertj.core.api.Assertions.assertThat; /** * Tests for {@link GitProperties}. * * @author Stephane Nicoll + * @author Moritz Halbritter */ class GitPropertiesTests { @@ -94,6 +98,13 @@ class GitPropertiesTests { assertThat(properties.getShortCommitId()).isEqualTo("abcdefg"); } + @Test + void shouldRegisterHints() { + RuntimeHints runtimeHints = new RuntimeHints(); + new GitProperties.GitPropertiesRuntimeHints().registerHints(runtimeHints, getClass().getClassLoader()); + assertThat(RuntimeHintsPredicates.resource().forResource("git.properties")).accepts(runtimeHints); + } + private static Properties createProperties(String branch, String commitId, String commitIdAbbrev, String commitTime) { Properties properties = new Properties();