diff --git a/settings.gradle b/settings.gradle index 5188957be8..f4b592b958 100644 --- a/settings.gradle +++ b/settings.gradle @@ -46,7 +46,6 @@ include "spring-boot-project:spring-boot-actuator-autoconfigure" include "spring-boot-project:spring-boot-actuator-autoconfigure-all" include "spring-boot-project:spring-boot-actuator-docs" include "spring-boot-project:spring-boot-actuator-integration-tests" -include "spring-boot-project:spring-boot-actuator-test-support" include "spring-boot-project:spring-boot-amqp" include "spring-boot-project:spring-boot-artemis" include "spring-boot-project:spring-boot-autoconfigure" diff --git a/spring-boot-project/spring-boot-actuator-integration-tests/build.gradle b/spring-boot-project/spring-boot-actuator-integration-tests/build.gradle index 1ae487abba..da58c724f9 100644 --- a/spring-boot-project/spring-boot-actuator-integration-tests/build.gradle +++ b/spring-boot-project/spring-boot-actuator-integration-tests/build.gradle @@ -7,7 +7,6 @@ description = "Spring Boot Actuator Integration Tests" dependencies { testImplementation(project(":spring-boot-project:spring-boot-actuator")) - testImplementation(project(":spring-boot-project:spring-boot-actuator-test-support")) testImplementation(project(":spring-boot-project:spring-boot-autoconfigure")) testImplementation(project(":spring-boot-project:spring-boot-http-converter")) testImplementation(project(":spring-boot-project:spring-boot-jackson")) @@ -20,6 +19,9 @@ dependencies { testImplementation(project(":spring-boot-project:spring-boot-web-server")) testImplementation(project(":spring-boot-project:spring-boot-webflux")) testImplementation(project(":spring-boot-project:spring-boot-webmvc")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-jersey"))) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-webflux"))) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-webmvc"))) testImplementation("io.micrometer:micrometer-registry-prometheus") testImplementation("io.prometheus:prometheus-metrics-exposition-formats") testImplementation("net.minidev:json-smart") diff --git a/spring-boot-project/spring-boot-actuator-test-support/build.gradle b/spring-boot-project/spring-boot-actuator-test-support/build.gradle deleted file mode 100644 index 6476e35c67..0000000000 --- a/spring-boot-project/spring-boot-actuator-test-support/build.gradle +++ /dev/null @@ -1,37 +0,0 @@ -plugins { - id "java-library" - id "org.springframework.boot.optional-dependencies" -} - -description = "Spring Boot Actuator Testing Support" - -dependencies { - api(project(":spring-boot-project:spring-boot-actuator")) - api(project(":spring-boot-project:spring-boot-autoconfigure")) - api(project(":spring-boot-project:spring-boot-http-converter")) - api(project(":spring-boot-project:spring-boot-jackson")) - api(project(":spring-boot-project:spring-boot-jersey")) - api(project(":spring-boot-project:spring-boot-reactor-netty")) - api(project(":spring-boot-project:spring-boot-test")) - api(project(":spring-boot-project:spring-boot-tomcat")) - api(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) - api(project(":spring-boot-project:spring-boot-webflux")) - api(project(":spring-boot-project:spring-boot-webmvc")) - api("com.fasterxml.jackson.datatype:jackson-datatype-jsr310") - api("com.jayway.jsonpath:json-path") - api("org.assertj:assertj-core") - api("org.awaitility:awaitility") - api("org.hamcrest:hamcrest-core") - api("org.hamcrest:hamcrest-library") - api("org.junit.jupiter:junit-jupiter") - api("org.mockito:mockito-core") - api("org.mockito:mockito-junit-jupiter") - api("org.skyscreamer:jsonassert") - api("org.springframework:spring-core") - api("org.springframework:spring-test") - api("org.springframework:spring-core-test") - - compileOnly("org.junit.platform:junit-platform-engine") - compileOnly("org.junit.platform:junit-platform-launcher") - compileOnly("org.springframework:spring-context") -} diff --git a/spring-boot-project/spring-boot-actuator/build.gradle b/spring-boot-project/spring-boot-actuator/build.gradle index c777787028..f2825a5381 100644 --- a/spring-boot-project/spring-boot-actuator/build.gradle +++ b/spring-boot-project/spring-boot-actuator/build.gradle @@ -1,5 +1,6 @@ plugins { id "java-library" + id "java-test-fixtures" id "org.springframework.boot.configuration-properties" id "org.springframework.boot.optional-dependencies" id "org.springframework.boot.deployed" @@ -45,6 +46,10 @@ dependencies { optional("org.springframework.security:spring-security-core") optional("org.springframework.security:spring-security-web") + testFixturesApi("com.fasterxml.jackson.datatype:jackson-datatype-jsr310") + testFixturesImplementation("org.junit.jupiter:junit-jupiter-api") + testFixturesImplementation("org.springframework:spring-test") + testImplementation(project(":spring-boot-project:spring-boot-autoconfigure")) testImplementation(project(":spring-boot-project:spring-boot-jackson")) testImplementation(project(":spring-boot-project:spring-boot-jsonb")) diff --git a/spring-boot-project/spring-boot-actuator/src/testFixtures/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointInfrastructureProvider.java b/spring-boot-project/spring-boot-actuator/src/testFixtures/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointInfrastructureProvider.java new file mode 100644 index 0000000000..fbc26b9a74 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/testFixtures/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointInfrastructureProvider.java @@ -0,0 +1,46 @@ +/* + * Copyright 2012-2025 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.test; + +import java.util.List; + +import org.springframework.boot.actuate.endpoint.web.test.WebEndpointTest.Infrastructure; + +/** + * Strategy interface to provide the web endpoint configuration for a target + * {@linkplain Infrastructure infrastructure}. + * + * @author Stephane Nicoll + * @since 4.0.0 + */ +public interface WebEndpointInfrastructureProvider { + + /** + * Specify if the given {@link Infrastructure} is supported. + * @param infrastructure the infrastructure to target + * @return {@code true} if this instance can provide the configuration + */ + boolean supports(Infrastructure infrastructure); + + /** + * Return the configuration to use for the given {@code infrastructure}. + * @param infrastructure the infrastructure to target + * @return the configuration for that infrastructure + */ + List> getInfrastructureConfiguration(Infrastructure infrastructure); + +} diff --git a/spring-boot-project/spring-boot-actuator-test-support/src/main/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTest.java b/spring-boot-project/spring-boot-actuator/src/testFixtures/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTest.java similarity index 77% rename from spring-boot-project/spring-boot-actuator-test-support/src/main/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTest.java rename to spring-boot-project/spring-boot-actuator/src/testFixtures/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTest.java index a34a38739d..df2951cf2e 100644 --- a/spring-boot-project/spring-boot-actuator-test-support/src/main/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTest.java +++ b/spring-boot-project/spring-boot-actuator/src/testFixtures/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTest.java @@ -53,29 +53,27 @@ public @interface WebEndpointTest { /** * Actuator running on the Jersey-based infrastructure. */ - JERSEY("Jersey", WebEndpointTestInvocationContextProvider::createJerseyContext), + JERSEY("Jersey"), /** * Actuator running on the WebMVC-based infrastructure. */ - MVC("WebMvc", WebEndpointTestInvocationContextProvider::createWebMvcContext), + MVC("WebMvc"), /** * Actuator running on the WebFlux-based infrastructure. */ - WEBFLUX("WebFlux", WebEndpointTestInvocationContextProvider::createWebFluxContext); + WEBFLUX("WebFlux"); private final String name; - private final Function>, ConfigurableApplicationContext> contextFactory; - - Infrastructure(String name, Function>, ConfigurableApplicationContext> contextFactory) { + Infrastructure(String name) { this.name = name; - this.contextFactory = contextFactory; } - WebEndpointsInvocationContext createInvocationContext() { - return new WebEndpointsInvocationContext(this.name, this.contextFactory); + WebEndpointsInvocationContext createInvocationContext( + Function>, ConfigurableApplicationContext> contextFactory) { + return new WebEndpointsInvocationContext(this.name, contextFactory); } } diff --git a/spring-boot-project/spring-boot-actuator-test-support/src/main/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTestInvocationContextProvider.java b/spring-boot-project/spring-boot-actuator/src/testFixtures/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTestInvocationContextProvider.java similarity index 53% rename from spring-boot-project/spring-boot-actuator-test-support/src/main/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTestInvocationContextProvider.java rename to spring-boot-project/spring-boot-actuator/src/testFixtures/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTestInvocationContextProvider.java index 616318e542..7354be0c6b 100644 --- a/spring-boot-project/spring-boot-actuator-test-support/src/main/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTestInvocationContextProvider.java +++ b/spring-boot-project/spring-boot-actuator/src/testFixtures/java/org/springframework/boot/actuate/endpoint/web/test/WebEndpointTestInvocationContextProvider.java @@ -18,16 +18,14 @@ package org.springframework.boot.actuate.endpoint.web.test; import java.time.Duration; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; -import java.util.HashSet; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; -import org.glassfish.jersey.server.ResourceConfig; -import org.glassfish.jersey.server.model.Resource; import org.junit.jupiter.api.extension.AfterEachCallback; import org.junit.jupiter.api.extension.BeforeEachCallback; import org.junit.jupiter.api.extension.Extension; @@ -38,29 +36,10 @@ import org.junit.jupiter.api.extension.TestTemplateInvocationContext; import org.junit.jupiter.api.extension.TestTemplateInvocationContextProvider; import org.junit.platform.commons.util.AnnotationUtils; -import org.springframework.boot.actuate.endpoint.invoke.convert.ConversionServiceParameterValueMapper; -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.annotation.WebEndpointDiscoverer; -import org.springframework.boot.actuate.endpoint.web.reactive.WebFluxEndpointHandlerMapping; -import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping; import org.springframework.boot.actuate.endpoint.web.test.WebEndpointTest.Infrastructure; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; -import org.springframework.boot.jersey.actuate.endpoint.web.JerseyEndpointResourceFactory; -import org.springframework.boot.jersey.autoconfigure.JerseyAutoConfiguration; -import org.springframework.boot.jersey.autoconfigure.ResourceConfigCustomizer; -import org.springframework.boot.reactor.netty.NettyReactiveWebServerFactory; -import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; import org.springframework.boot.web.server.context.WebServerInitializedEvent; import org.springframework.boot.web.server.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; import org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext; -import org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration; -import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration; -import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; -import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationListener; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.AnnotationConfigRegistry; @@ -68,12 +47,10 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.MergedAnnotations; import org.springframework.core.annotation.MergedAnnotations.SearchStrategy; +import org.springframework.core.io.support.SpringFactoriesLoader; import org.springframework.http.HttpMethod; -import org.springframework.http.server.reactive.HttpHandler; import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.util.ClassUtils; -import org.springframework.web.cors.CorsConfiguration; -import org.springframework.web.server.adapter.WebHttpHandlerBuilder; import org.springframework.web.util.DefaultUriBuilderFactory; import org.springframework.web.util.DefaultUriBuilderFactory.EncodingMode; @@ -81,10 +58,29 @@ import org.springframework.web.util.DefaultUriBuilderFactory.EncodingMode; * {@link TestTemplateInvocationContextProvider} for * {@link WebEndpointTest @WebEndpointTest}. * - * @author Andy Wilkinson + * @author Andy Wilkinson` + * @author Stephane Nicoll */ class WebEndpointTestInvocationContextProvider implements TestTemplateInvocationContextProvider { + private final Map>> infrastructures; + + private final Map>, ConfigurableApplicationContext>> contextFactories; + + WebEndpointTestInvocationContextProvider() { + this.infrastructures = new HashMap<>(); + List providers = SpringFactoriesLoader + .loadFactories(WebEndpointInfrastructureProvider.class, getClass().getClassLoader()); + Stream.of(Infrastructure.values()) + .forEach((infrastructure) -> providers.stream() + .filter((provider) -> provider.supports(infrastructure)) + .findFirst() + .ifPresent((provider) -> this.infrastructures.put(infrastructure, + provider.getInfrastructureConfiguration(infrastructure)))); + this.contextFactories = Map.of(Infrastructure.JERSEY, this::createJerseyContext, Infrastructure.MVC, + this::createWebMvcContext, Infrastructure.WEBFLUX, this::createWebFluxContext); + } + @Override public boolean supportsTestTemplate(ExtensionContext context) { return true; @@ -97,33 +93,49 @@ class WebEndpointTestInvocationContextProvider implements TestTemplateInvocation .findAnnotation(extensionContext.getRequiredTestMethod(), WebEndpointTest.class) .orElseThrow(() -> new IllegalStateException("Unable to find WebEndpointTest annotation on %s" .formatted(extensionContext.getRequiredTestMethod()))); - return Stream.of(webEndpointTest.infrastructure()).distinct().map(Infrastructure::createInvocationContext); + return Stream.of(webEndpointTest.infrastructure()).distinct().map(this::createInvocationContext); } - static ConfigurableApplicationContext createJerseyContext(List> classes) { + private WebEndpointsInvocationContext createInvocationContext(Infrastructure infrastructure) { + return infrastructure.createInvocationContext(this.contextFactories.get(infrastructure)); + } + + private ConfigurableApplicationContext createJerseyContext(List> classes) { AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext(); - classes.add(JerseyEndpointConfiguration.class); + classes.addAll(getEndpointInfrastructureConfiguration(Infrastructure.JERSEY)); context.register(ClassUtils.toClassArray(classes)); context.refresh(); return context; } - static ConfigurableApplicationContext createWebMvcContext(List> classes) { + private ConfigurableApplicationContext createWebMvcContext(List> classes) { AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext(); - classes.add(WebMvcEndpointConfiguration.class); + classes.addAll(getEndpointInfrastructureConfiguration(Infrastructure.MVC)); context.register(ClassUtils.toClassArray(classes)); context.refresh(); return context; } - static ConfigurableApplicationContext createWebFluxContext(List> classes) { + private ConfigurableApplicationContext createWebFluxContext(List> classes) { AnnotationConfigReactiveWebServerApplicationContext context = new AnnotationConfigReactiveWebServerApplicationContext(); - classes.add(WebFluxEndpointConfiguration.class); + classes.addAll(getEndpointInfrastructureConfiguration(Infrastructure.WEBFLUX)); context.register(ClassUtils.toClassArray(classes)); context.refresh(); return context; } + private List> getEndpointInfrastructureConfiguration(Infrastructure infrastructure) { + List> configurationClasses = new ArrayList<>(); + configurationClasses.add(EndpointBaseConfiguration.class); + List> endpointConfiguration = this.infrastructures.get(infrastructure); + if (endpointConfiguration == null) { + throw new IllegalStateException( + "No endpoint infrastructure configuration found for " + infrastructure.name()); + } + configurationClasses.addAll(endpointConfiguration); + return configurationClasses; + } + static class WebEndpointsInvocationContext implements TestTemplateInvocationContext, BeforeEachCallback, AfterEachCallback, ParameterResolver { @@ -206,69 +218,16 @@ class WebEndpointTestInvocationContextProvider implements TestTemplateInvocation } private int determinePort() { - if (this.context instanceof AnnotationConfigServletWebServerApplicationContext webServerContext) { - return webServerContext.getWebServer().getPort(); - } return this.context.getBean(PortHolder.class).getPort(); } } @Configuration(proxyBeanMethods = false) - @ImportAutoConfiguration({ JacksonAutoConfiguration.class, JerseyAutoConfiguration.class }) - static class JerseyEndpointConfiguration { - - private final ApplicationContext applicationContext; - - JerseyEndpointConfiguration(ApplicationContext applicationContext) { - this.applicationContext = applicationContext; - } - - @Bean - TomcatServletWebServerFactory tomcat() { - return new TomcatServletWebServerFactory(0); - } - - @Bean - ResourceConfig resourceConfig() { - return new ResourceConfig(); - } - - @Bean - ResourceConfigCustomizer webEndpointRegistrar() { - return this::customize; - } - - private void customize(ResourceConfig config) { - EndpointMediaTypes endpointMediaTypes = EndpointMediaTypes.DEFAULT; - WebEndpointDiscoverer discoverer = new WebEndpointDiscoverer(this.applicationContext, - new ConversionServiceParameterValueMapper(), endpointMediaTypes, null, Collections.emptyList(), - Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); - Collection resources = new JerseyEndpointResourceFactory().createEndpointResources( - new EndpointMapping("/actuator"), discoverer.getEndpoints(), endpointMediaTypes, - new EndpointLinksResolver(discoverer.getEndpoints()), true); - config.registerResources(new HashSet<>(resources)); - } - - } - - @Configuration(proxyBeanMethods = false) - @ImportAutoConfiguration({ JacksonAutoConfiguration.class, WebFluxAutoConfiguration.class }) - static class WebFluxEndpointConfiguration implements ApplicationListener { - - private final ApplicationContext applicationContext; + static class EndpointBaseConfiguration implements ApplicationListener { private final PortHolder portHolder = new PortHolder(); - WebFluxEndpointConfiguration(ApplicationContext applicationContext) { - this.applicationContext = applicationContext; - } - - @Bean - NettyReactiveWebServerFactory netty() { - return new NettyReactiveWebServerFactory(0); - } - @Bean PortHolder portHolder() { return this.portHolder; @@ -279,51 +238,6 @@ class WebEndpointTestInvocationContextProvider implements TestTemplateInvocation this.portHolder.setPort(event.getWebServer().getPort()); } - @Bean - HttpHandler httpHandler(ApplicationContext applicationContext) { - return WebHttpHandlerBuilder.applicationContext(applicationContext).build(); - } - - @Bean - WebFluxEndpointHandlerMapping webEndpointReactiveHandlerMapping() { - EndpointMediaTypes endpointMediaTypes = EndpointMediaTypes.DEFAULT; - WebEndpointDiscoverer discoverer = new WebEndpointDiscoverer(this.applicationContext, - new ConversionServiceParameterValueMapper(), endpointMediaTypes, Collections.emptyList(), - Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); - return new WebFluxEndpointHandlerMapping(new EndpointMapping("/actuator"), discoverer.getEndpoints(), - endpointMediaTypes, new CorsConfiguration(), new EndpointLinksResolver(discoverer.getEndpoints()), - true); - } - - } - - @Configuration(proxyBeanMethods = false) - @ImportAutoConfiguration({ JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, - WebMvcAutoConfiguration.class, DispatcherServletAutoConfiguration.class }) - static class WebMvcEndpointConfiguration { - - private final ApplicationContext applicationContext; - - WebMvcEndpointConfiguration(ApplicationContext applicationContext) { - this.applicationContext = applicationContext; - } - - @Bean - TomcatServletWebServerFactory tomcat() { - return new TomcatServletWebServerFactory(0); - } - - @Bean - WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping() { - EndpointMediaTypes endpointMediaTypes = EndpointMediaTypes.DEFAULT; - WebEndpointDiscoverer discoverer = new WebEndpointDiscoverer(this.applicationContext, - new ConversionServiceParameterValueMapper(), endpointMediaTypes, Collections.emptyList(), - Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); - return new WebMvcEndpointHandlerMapping(new EndpointMapping("/actuator"), discoverer.getEndpoints(), - endpointMediaTypes, new CorsConfiguration(), new EndpointLinksResolver(discoverer.getEndpoints()), - true); - } - } private static final class PortHolder { diff --git a/spring-boot-project/spring-boot-actuator-test-support/src/main/java/org/springframework/boot/actuate/endpoint/web/test/package-info.java b/spring-boot-project/spring-boot-actuator/src/testFixtures/java/org/springframework/boot/actuate/endpoint/web/test/package-info.java similarity index 100% rename from spring-boot-project/spring-boot-actuator-test-support/src/main/java/org/springframework/boot/actuate/endpoint/web/test/package-info.java rename to spring-boot-project/spring-boot-actuator/src/testFixtures/java/org/springframework/boot/actuate/endpoint/web/test/package-info.java diff --git a/spring-boot-project/spring-boot-cache/build.gradle b/spring-boot-project/spring-boot-cache/build.gradle index cfcbb700c1..01f47ad55c 100644 --- a/spring-boot-project/spring-boot-cache/build.gradle +++ b/spring-boot-project/spring-boot-cache/build.gradle @@ -44,10 +44,12 @@ dependencies { dockerTestImplementation("org.testcontainers:junit-jupiter") dockerTestImplementation("org.testcontainers:testcontainers") - testImplementation(project(":spring-boot-project:spring-boot-actuator-test-support")) testImplementation(project(":spring-boot-project:spring-boot-test")) testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) testImplementation(testFixtures(project(":spring-boot-project:spring-boot-autoconfigure"))) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-jersey"))) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-webmvc"))) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-webflux"))) testRuntimeOnly("ch.qos.logback:logback-classic") } diff --git a/spring-boot-project/spring-boot-integration/build.gradle b/spring-boot-project/spring-boot-integration/build.gradle index b2bc88a197..57897be538 100644 --- a/spring-boot-project/spring-boot-integration/build.gradle +++ b/spring-boot-project/spring-boot-integration/build.gradle @@ -23,11 +23,13 @@ dependencies { optional("org.springframework.integration:spring-integration-jmx") optional("org.springframework.integration:spring-integration-rsocket") - testImplementation(project(":spring-boot-project:spring-boot-actuator-test-support")) testImplementation(project(":spring-boot-project:spring-boot-flyway")) testImplementation(project(":spring-boot-project:spring-boot-rsocket")) testImplementation(project(":spring-boot-project:spring-boot-test")) testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-jersey"))) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-webflux"))) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-webmvc"))) testImplementation("org.springframework:spring-web") testRuntimeOnly(project(":spring-boot-project:spring-boot-reactor-netty")) diff --git a/spring-boot-project/spring-boot-jersey/build.gradle b/spring-boot-project/spring-boot-jersey/build.gradle index f88f9ebd11..da88e465d1 100644 --- a/spring-boot-project/spring-boot-jersey/build.gradle +++ b/spring-boot-project/spring-boot-jersey/build.gradle @@ -1,5 +1,6 @@ plugins { id "java-library" + id "java-test-fixtures" id "org.springframework.boot.auto-configuration" id "org.springframework.boot.configuration-properties" id "org.springframework.boot.deployed" @@ -24,6 +25,9 @@ dependencies { optional(project(":spring-boot-project:spring-boot-jackson")) optional("io.projectreactor:reactor-core") + testFixturesApi(testFixtures(project(":spring-boot-project:spring-boot-actuator"))) + testFixturesImplementation(project(":spring-boot-project:spring-boot-tomcat")) + testImplementation(project(":spring-boot-project:spring-boot-restclient")) testImplementation(project(":spring-boot-project:spring-boot-test")) testImplementation(project(":spring-boot-project:spring-boot-tomcat")) diff --git a/spring-boot-project/spring-boot-jersey/src/testFixtures/java/org/springframework/boot/jersey/actuate/endpoint/web/test/JerseyEndpointConfiguration.java b/spring-boot-project/spring-boot-jersey/src/testFixtures/java/org/springframework/boot/jersey/actuate/endpoint/web/test/JerseyEndpointConfiguration.java new file mode 100644 index 0000000000..8bad9e44e7 --- /dev/null +++ b/spring-boot-project/spring-boot-jersey/src/testFixtures/java/org/springframework/boot/jersey/actuate/endpoint/web/test/JerseyEndpointConfiguration.java @@ -0,0 +1,83 @@ +/* + * Copyright 2012-2025 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.jersey.actuate.endpoint.web.test; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; + +import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.server.model.Resource; + +import org.springframework.boot.actuate.endpoint.invoke.convert.ConversionServiceParameterValueMapper; +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.annotation.WebEndpointDiscoverer; +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.jersey.actuate.endpoint.web.JerseyEndpointResourceFactory; +import org.springframework.boot.jersey.autoconfigure.JerseyAutoConfiguration; +import org.springframework.boot.jersey.autoconfigure.ResourceConfigCustomizer; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Endpoint configuration for Jersey. + * + * @author Andy Wilkinson + * @author Stephane Nicoll + */ +@Configuration(proxyBeanMethods = false) +@ImportAutoConfiguration({ JacksonAutoConfiguration.class, JerseyAutoConfiguration.class }) +class JerseyEndpointConfiguration { + + private final ApplicationContext applicationContext; + + JerseyEndpointConfiguration(ApplicationContext applicationContext) { + this.applicationContext = applicationContext; + } + + @Bean + TomcatServletWebServerFactory tomcat() { + return new TomcatServletWebServerFactory(0); + } + + @Bean + ResourceConfig resourceConfig() { + return new ResourceConfig(); + } + + @Bean + ResourceConfigCustomizer webEndpointRegistrar() { + return this::customize; + } + + private void customize(ResourceConfig config) { + EndpointMediaTypes endpointMediaTypes = EndpointMediaTypes.DEFAULT; + WebEndpointDiscoverer discoverer = new WebEndpointDiscoverer(this.applicationContext, + new ConversionServiceParameterValueMapper(), endpointMediaTypes, null, Collections.emptyList(), + Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); + Collection resources = new JerseyEndpointResourceFactory().createEndpointResources( + new EndpointMapping("/actuator"), discoverer.getEndpoints(), endpointMediaTypes, + new EndpointLinksResolver(discoverer.getEndpoints()), true); + config.registerResources(new HashSet<>(resources)); + } + +} diff --git a/spring-boot-project/spring-boot-jersey/src/testFixtures/java/org/springframework/boot/jersey/actuate/endpoint/web/test/JerseyWebEndpointInfrastructureProvider.java b/spring-boot-project/spring-boot-jersey/src/testFixtures/java/org/springframework/boot/jersey/actuate/endpoint/web/test/JerseyWebEndpointInfrastructureProvider.java new file mode 100644 index 0000000000..5c4de91381 --- /dev/null +++ b/spring-boot-project/spring-boot-jersey/src/testFixtures/java/org/springframework/boot/jersey/actuate/endpoint/web/test/JerseyWebEndpointInfrastructureProvider.java @@ -0,0 +1,41 @@ +/* + * Copyright 2012-2025 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.jersey.actuate.endpoint.web.test; + +import java.util.List; + +import org.springframework.boot.actuate.endpoint.web.test.WebEndpointInfrastructureProvider; +import org.springframework.boot.actuate.endpoint.web.test.WebEndpointTest.Infrastructure; + +/** + * {@link WebEndpointInfrastructureProvider} for Jersey. + * + * @author Stephane Nicoll + */ +class JerseyWebEndpointInfrastructureProvider implements WebEndpointInfrastructureProvider { + + @Override + public boolean supports(Infrastructure infrastructure) { + return infrastructure == Infrastructure.JERSEY; + } + + @Override + public List> getInfrastructureConfiguration(Infrastructure infrastructure) { + return List.of(JerseyEndpointConfiguration.class); + } + +} diff --git a/spring-boot-project/spring-boot-jersey/src/testFixtures/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-jersey/src/testFixtures/resources/META-INF/spring.factories new file mode 100644 index 0000000000..7163b1dad5 --- /dev/null +++ b/spring-boot-project/spring-boot-jersey/src/testFixtures/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.actuate.endpoint.web.test.WebEndpointInfrastructureProvider=\ +org.springframework.boot.jersey.actuate.endpoint.web.test.JerseyWebEndpointInfrastructureProvider diff --git a/spring-boot-project/spring-boot-quartz/build.gradle b/spring-boot-project/spring-boot-quartz/build.gradle index 60d77c14d4..2555662ba5 100644 --- a/spring-boot-project/spring-boot-quartz/build.gradle +++ b/spring-boot-project/spring-boot-quartz/build.gradle @@ -20,11 +20,13 @@ dependencies { optional(project(":spring-boot-project:spring-boot-jdbc")) optional(project(":spring-boot-project:spring-boot-jpa")) - testImplementation(project(":spring-boot-project:spring-boot-actuator-test-support")) testImplementation(project(":spring-boot-project:spring-boot-flyway")) testImplementation(project(":spring-boot-project:spring-boot-liquibase")) testImplementation(project(":spring-boot-project:spring-boot-test")) testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-jersey"))) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-webflux"))) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-webmvc"))) testImplementation("net.minidev:json-smart") testImplementation("org.springframework:spring-web") diff --git a/spring-boot-project/spring-boot-session/build.gradle b/spring-boot-project/spring-boot-session/build.gradle index e0c32e3a1c..56be4aae13 100644 --- a/spring-boot-project/spring-boot-session/build.gradle +++ b/spring-boot-project/spring-boot-session/build.gradle @@ -28,11 +28,13 @@ dependencies { testFixturesImplementation(testFixtures(project(":spring-boot-project:spring-boot-web-server"))) testFixturesImplementation("io.projectreactor:reactor-core") - testImplementation(project(":spring-boot-project:spring-boot-actuator-test-support")) testImplementation(project(":spring-boot-project:spring-boot-test")) testImplementation(project(":spring-boot-project:spring-boot-tomcat")) testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) testImplementation(project(":spring-boot-project:spring-boot-webflux")) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-jersey"))) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-webflux"))) + testImplementation(testFixtures(project(":spring-boot-project:spring-boot-webmvc"))) testImplementation(testFixtures(project(":spring-boot-project:spring-boot-web-server"))) testImplementation("net.minidev:json-smart") testImplementation("io.projectreactor:reactor-test") diff --git a/spring-boot-project/spring-boot-webflux/build.gradle b/spring-boot-project/spring-boot-webflux/build.gradle index 337c660388..ebc7f1e03b 100644 --- a/spring-boot-project/spring-boot-webflux/build.gradle +++ b/spring-boot-project/spring-boot-webflux/build.gradle @@ -1,5 +1,6 @@ plugins { id "java-library" + id "java-test-fixtures" id "org.springframework.boot.auto-configuration" id "org.springframework.boot.configuration-properties" id "org.springframework.boot.deployed" @@ -19,6 +20,10 @@ dependencies { optional(project(":spring-boot-project:spring-boot-autoconfigure")) optional(project(":spring-boot-project:spring-boot-validation")) + testFixturesApi(testFixtures(project(":spring-boot-project:spring-boot-actuator"))) + testFixturesImplementation(project(":spring-boot-project:spring-boot-jackson")) + testFixturesImplementation(project(":spring-boot-project:spring-boot-reactor-netty")) + testImplementation(project(":spring-boot-project:spring-boot-mustache")) testImplementation(project(":spring-boot-project:spring-boot-reactor-netty")) testImplementation(project(":spring-boot-project:spring-boot-test")) diff --git a/spring-boot-project/spring-boot-webflux/src/testFixtures/java/org/springframework/boot/webflux/actuate/endpoint/web/test/WebFluxEndpointConfiguration.java b/spring-boot-project/spring-boot-webflux/src/testFixtures/java/org/springframework/boot/webflux/actuate/endpoint/web/test/WebFluxEndpointConfiguration.java new file mode 100644 index 0000000000..698545c673 --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/testFixtures/java/org/springframework/boot/webflux/actuate/endpoint/web/test/WebFluxEndpointConfiguration.java @@ -0,0 +1,75 @@ +/* + * Copyright 2012-2025 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.webflux.actuate.endpoint.web.test; + +import java.util.Collections; + +import org.springframework.boot.actuate.endpoint.invoke.convert.ConversionServiceParameterValueMapper; +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.annotation.WebEndpointDiscoverer; +import org.springframework.boot.actuate.endpoint.web.reactive.WebFluxEndpointHandlerMapping; +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.reactor.netty.NettyReactiveWebServerFactory; +import org.springframework.boot.webflux.autoconfigure.WebFluxAutoConfiguration; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.server.reactive.HttpHandler; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.server.adapter.WebHttpHandlerBuilder; + +/** + * Endpoint configuration for WebFlux. + * + * @author Andy Wilkinson + * @author Stephane Nicoll + */ +@Configuration(proxyBeanMethods = false) +@ImportAutoConfiguration({ JacksonAutoConfiguration.class, WebFluxAutoConfiguration.class }) +class WebFluxEndpointConfiguration { + + private final ApplicationContext applicationContext; + + WebFluxEndpointConfiguration(ApplicationContext applicationContext) { + this.applicationContext = applicationContext; + } + + @Bean + NettyReactiveWebServerFactory netty() { + return new NettyReactiveWebServerFactory(0); + } + + @Bean + HttpHandler httpHandler(ApplicationContext applicationContext) { + return WebHttpHandlerBuilder.applicationContext(applicationContext).build(); + } + + @Bean + WebFluxEndpointHandlerMapping webEndpointReactiveHandlerMapping() { + EndpointMediaTypes endpointMediaTypes = EndpointMediaTypes.DEFAULT; + WebEndpointDiscoverer discoverer = new WebEndpointDiscoverer(this.applicationContext, + new ConversionServiceParameterValueMapper(), endpointMediaTypes, Collections.emptyList(), + Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); + return new WebFluxEndpointHandlerMapping(new EndpointMapping("/actuator"), discoverer.getEndpoints(), + endpointMediaTypes, new CorsConfiguration(), new EndpointLinksResolver(discoverer.getEndpoints()), + true); + } + +} diff --git a/spring-boot-project/spring-boot-webflux/src/testFixtures/java/org/springframework/boot/webflux/actuate/endpoint/web/test/WebFluxWebEndpointInfrastructureProvider.java b/spring-boot-project/spring-boot-webflux/src/testFixtures/java/org/springframework/boot/webflux/actuate/endpoint/web/test/WebFluxWebEndpointInfrastructureProvider.java new file mode 100644 index 0000000000..cc23819443 --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/testFixtures/java/org/springframework/boot/webflux/actuate/endpoint/web/test/WebFluxWebEndpointInfrastructureProvider.java @@ -0,0 +1,41 @@ +/* + * Copyright 2012-2025 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.webflux.actuate.endpoint.web.test; + +import java.util.List; + +import org.springframework.boot.actuate.endpoint.web.test.WebEndpointInfrastructureProvider; +import org.springframework.boot.actuate.endpoint.web.test.WebEndpointTest.Infrastructure; + +/** + * {@link WebEndpointInfrastructureProvider} for WebFlux. + * + * @author Stephane Nicoll + */ +class WebFluxWebEndpointInfrastructureProvider implements WebEndpointInfrastructureProvider { + + @Override + public boolean supports(Infrastructure infrastructure) { + return infrastructure == Infrastructure.WEBFLUX; + } + + @Override + public List> getInfrastructureConfiguration(Infrastructure infrastructure) { + return List.of(WebFluxEndpointConfiguration.class); + } + +} diff --git a/spring-boot-project/spring-boot-webflux/src/testFixtures/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-webflux/src/testFixtures/resources/META-INF/spring.factories new file mode 100644 index 0000000000..cfd660e3b2 --- /dev/null +++ b/spring-boot-project/spring-boot-webflux/src/testFixtures/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.actuate.endpoint.web.test.WebEndpointInfrastructureProvider=\ +org.springframework.boot.webflux.actuate.endpoint.web.test.WebFluxWebEndpointInfrastructureProvider diff --git a/spring-boot-project/spring-boot-webmvc/build.gradle b/spring-boot-project/spring-boot-webmvc/build.gradle index 03b6d01703..faa1cc0320 100644 --- a/spring-boot-project/spring-boot-webmvc/build.gradle +++ b/spring-boot-project/spring-boot-webmvc/build.gradle @@ -1,5 +1,6 @@ plugins { id "java-library" + id "java-test-fixtures" id "org.springframework.boot.auto-configuration" id "org.springframework.boot.configuration-properties" id "org.springframework.boot.deployed" @@ -24,6 +25,10 @@ dependencies { optional(project(":spring-boot-project:spring-boot-validation")) optional(project(":spring-boot-project:spring-boot-web-server")) + testFixturesApi(testFixtures(project(":spring-boot-project:spring-boot-actuator"))) + testFixturesImplementation(project(":spring-boot-project:spring-boot-http-converter")) + testFixturesImplementation(project(":spring-boot-project:spring-boot-jackson")) + testImplementation(project(":spring-boot-project:spring-boot-freemarker")) testImplementation(project(":spring-boot-project:spring-boot-restclient")) testImplementation(project(":spring-boot-project:spring-boot-test")) diff --git a/spring-boot-project/spring-boot-webmvc/src/testFixtures/java/org/springframework/boot/webmvc/actuate/endpoint/web/test/WebMvcEndpointConfiguration.java b/spring-boot-project/spring-boot-webmvc/src/testFixtures/java/org/springframework/boot/webmvc/actuate/endpoint/web/test/WebMvcEndpointConfiguration.java new file mode 100644 index 0000000000..70f8380f27 --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/testFixtures/java/org/springframework/boot/webmvc/actuate/endpoint/web/test/WebMvcEndpointConfiguration.java @@ -0,0 +1,71 @@ +/* + * Copyright 2012-2025 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.webmvc.actuate.endpoint.web.test; + +import java.util.Collections; + +import org.springframework.boot.actuate.endpoint.invoke.convert.ConversionServiceParameterValueMapper; +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.annotation.WebEndpointDiscoverer; +import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping; +import org.springframework.boot.autoconfigure.ImportAutoConfiguration; +import org.springframework.boot.http.converter.autoconfigure.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.tomcat.servlet.TomcatServletWebServerFactory; +import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.cors.CorsConfiguration; + +/** + * Endpoint configuration for WebMvc. + * + * @author Andy Wilkinson + * @author Stephane Nicoll + */ +@Configuration(proxyBeanMethods = false) +@ImportAutoConfiguration({ JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, + WebMvcAutoConfiguration.class, DispatcherServletAutoConfiguration.class }) +class WebMvcEndpointConfiguration { + + private final ApplicationContext applicationContext; + + WebMvcEndpointConfiguration(ApplicationContext applicationContext) { + this.applicationContext = applicationContext; + } + + @Bean + TomcatServletWebServerFactory tomcat() { + return new TomcatServletWebServerFactory(0); + } + + @Bean + WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping() { + EndpointMediaTypes endpointMediaTypes = EndpointMediaTypes.DEFAULT; + WebEndpointDiscoverer discoverer = new WebEndpointDiscoverer(this.applicationContext, + new ConversionServiceParameterValueMapper(), endpointMediaTypes, Collections.emptyList(), + Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); + return new WebMvcEndpointHandlerMapping(new EndpointMapping("/actuator"), discoverer.getEndpoints(), + endpointMediaTypes, new CorsConfiguration(), new EndpointLinksResolver(discoverer.getEndpoints()), + true); + } + +} diff --git a/spring-boot-project/spring-boot-webmvc/src/testFixtures/java/org/springframework/boot/webmvc/actuate/endpoint/web/test/WebMvcWebEndpointInfrastructureProvider.java b/spring-boot-project/spring-boot-webmvc/src/testFixtures/java/org/springframework/boot/webmvc/actuate/endpoint/web/test/WebMvcWebEndpointInfrastructureProvider.java new file mode 100644 index 0000000000..45494c94fa --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/testFixtures/java/org/springframework/boot/webmvc/actuate/endpoint/web/test/WebMvcWebEndpointInfrastructureProvider.java @@ -0,0 +1,41 @@ +/* + * Copyright 2012-2025 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.webmvc.actuate.endpoint.web.test; + +import java.util.List; + +import org.springframework.boot.actuate.endpoint.web.test.WebEndpointInfrastructureProvider; +import org.springframework.boot.actuate.endpoint.web.test.WebEndpointTest.Infrastructure; + +/** + * {@link WebEndpointInfrastructureProvider} for MVC. + * + * @author Stephane Nicoll + */ +class WebMvcWebEndpointInfrastructureProvider implements WebEndpointInfrastructureProvider { + + @Override + public boolean supports(Infrastructure infrastructure) { + return infrastructure == Infrastructure.MVC; + } + + @Override + public List> getInfrastructureConfiguration(Infrastructure infrastructure) { + return List.of(WebMvcEndpointConfiguration.class); + } + +} diff --git a/spring-boot-project/spring-boot-webmvc/src/testFixtures/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-webmvc/src/testFixtures/resources/META-INF/spring.factories new file mode 100644 index 0000000000..5fae52b117 --- /dev/null +++ b/spring-boot-project/spring-boot-webmvc/src/testFixtures/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.actuate.endpoint.web.test.WebEndpointInfrastructureProvider=\ +org.springframework.boot.webmvc.actuate.endpoint.web.test.WebMvcWebEndpointInfrastructureProvider