From c6ce97b8a90ed3291720193c1fff1209417b8baa Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Mon, 18 Jan 2021 15:27:28 +0000 Subject: [PATCH] Disable all mappings endpoint infra when endpoint is unavailable Previously, when the mappings endpoint was not available, the beans that provide mapping descriptions were still created. This resulted in unnecessary CPU and memory usage collecting and storing information that would never by used. This commit updates the auto-configuration for the mappings endpoint so that all the beans that it creates are conditional on the endpoint being available, rather than only the endpoint bean itself. Closes gh-23977 --- .../MappingsEndpointAutoConfiguration.java | 4 +- ...appingsEndpointAutoConfigurationTests.java | 73 +++++++++++++++++++ 2 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/mappings/MappingsEndpointAutoConfigurationTests.java diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/mappings/MappingsEndpointAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/mappings/MappingsEndpointAutoConfiguration.java index 4f1c30561f..72e3aab572 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/mappings/MappingsEndpointAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/mappings/MappingsEndpointAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2021 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. @@ -44,10 +44,10 @@ import org.springframework.web.servlet.DispatcherServlet; * @since 2.0.0 */ @Configuration(proxyBeanMethods = false) +@ConditionalOnAvailableEndpoint(endpoint = MappingsEndpoint.class) public class MappingsEndpointAutoConfiguration { @Bean - @ConditionalOnAvailableEndpoint public MappingsEndpoint mappingsEndpoint(ApplicationContext applicationContext, ObjectProvider descriptionProviders) { return new MappingsEndpoint(descriptionProviders.orderedStream().collect(Collectors.toList()), diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/mappings/MappingsEndpointAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/mappings/MappingsEndpointAutoConfigurationTests.java new file mode 100644 index 0000000000..ef2c0716bb --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/web/mappings/MappingsEndpointAutoConfigurationTests.java @@ -0,0 +1,73 @@ +/* + * Copyright 2012-2021 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.web.mappings; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.endpoint.web.servlet.WebMvcEndpointManagementContextConfiguration; +import org.springframework.boot.actuate.web.mappings.MappingDescriptionProvider; +import org.springframework.boot.actuate.web.mappings.MappingsEndpoint; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; +import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; +import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; +import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration; +import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link MappingsEndpointAutoConfiguration}. + * + * @author Andy Wilkinson + */ +public class MappingsEndpointAutoConfigurationTests { + + @Test + public void whenEndpointIsUnavailableThenEndpointAndDescriptionProvidersAreNotCreated() { + new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(MappingsEndpointAutoConfiguration.class, + JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, + WebMvcAutoConfiguration.class, DispatcherServletAutoConfiguration.class, + EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class, + WebMvcEndpointManagementContextConfiguration.class, PropertyPlaceholderAutoConfiguration.class)) + .run((context) -> { + assertThat(context).doesNotHaveBean(MappingsEndpoint.class); + assertThat(context).doesNotHaveBean(MappingDescriptionProvider.class); + }); + + } + + @Test + public void whenEndpointIsAvailableThenEndpointAndDescriptionProvidersAreCreated() { + new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(MappingsEndpointAutoConfiguration.class, + JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, + WebMvcAutoConfiguration.class, DispatcherServletAutoConfiguration.class, + EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class, + WebMvcEndpointManagementContextConfiguration.class, PropertyPlaceholderAutoConfiguration.class)) + .withPropertyValues("management.endpoints.web.exposure.include=mappings").run((context) -> { + assertThat(context).hasSingleBean(MappingsEndpoint.class); + assertThat(context.getBeansOfType(MappingDescriptionProvider.class)).hasSize(3); + }); + + } + +}