From 13971692dc9c2a407128817b1fa5034aaceffbcf Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 24 Feb 2016 12:32:09 +0000 Subject: [PATCH] Docs and actuator endpoints can be enabled when endpoints.enabled=false Previously, if endpoints.enabled was false setting endpoints.docs.enabled=true or endpoints.actuator.enabled=true would have no effect as their entire configuration class was conditional on endpoints.enabled being true. This commit updates the conditions on the configuration class so that it is conditional on either the actuator or docs endpoint being enabled. Closes gh-5007 --- ...ermediaManagementContextConfiguration.java | 28 +++++++++++++++++-- .../ConditionalOnEnabledEndpoint.java | 4 +-- .../EndpointWebMvcAutoConfigurationTests.java | 13 +++++++++ 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcHypermediaManagementContextConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcHypermediaManagementContextConfiguration.java index 94e0bff791f..594f9448e66 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcHypermediaManagementContextConfiguration.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcHypermediaManagementContextConfiguration.java @@ -32,6 +32,8 @@ import com.fasterxml.jackson.annotation.JsonUnwrapped; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.actuate.autoconfigure.EndpointWebMvcHypermediaManagementContextConfiguration.EndpointHypermediaEnabledCondition; +import org.springframework.boot.actuate.condition.ConditionalOnEnabledEndpoint; import org.springframework.boot.actuate.endpoint.mvc.DocsMvcEndpoint; import org.springframework.boot.actuate.endpoint.mvc.HalBrowserMvcEndpoint; import org.springframework.boot.actuate.endpoint.mvc.HalJsonMvcEndpoint; @@ -39,6 +41,7 @@ import org.springframework.boot.actuate.endpoint.mvc.HypermediaDisabled; import org.springframework.boot.actuate.endpoint.mvc.ManagementServletContext; import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint; import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoints; +import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -50,6 +53,7 @@ import org.springframework.boot.autoconfigure.web.ResourceProperties; import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Conditional; import org.springframework.core.MethodParameter; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.core.io.ResourceLoader; @@ -85,7 +89,7 @@ import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; @ConditionalOnClass(Link.class) @ConditionalOnWebApplication @ConditionalOnBean(HttpMessageConverters.class) -@ConditionalOnProperty(value = "endpoints.enabled", matchIfMissing = true) +@Conditional(EndpointHypermediaEnabledCondition.class) @EnableConfigurationProperties(ResourceProperties.class) public class EndpointWebMvcHypermediaManagementContextConfiguration { @@ -102,7 +106,7 @@ public class EndpointWebMvcHypermediaManagementContextConfiguration { }; } - @ConditionalOnProperty(prefix = "endpoints.actuator", name = "enabled", matchIfMissing = true) + @ConditionalOnEnabledEndpoint("actuator") @Bean public HalJsonMvcEndpoint halJsonMvcEndpoint( ManagementServletContext managementServletContext, @@ -114,7 +118,7 @@ public class EndpointWebMvcHypermediaManagementContextConfiguration { } @Bean - @ConditionalOnProperty(prefix = "endpoints.docs", name = "enabled", matchIfMissing = true) + @ConditionalOnEnabledEndpoint("docs") @ConditionalOnResource(resources = "classpath:/META-INF/resources/spring-boot-actuator/docs/index.html") public DocsMvcEndpoint docsMvcEndpoint( ManagementServletContext managementServletContext) { @@ -333,4 +337,22 @@ public class EndpointWebMvcHypermediaManagementContextConfiguration { } + static class EndpointHypermediaEnabledCondition extends AnyNestedCondition { + + public EndpointHypermediaEnabledCondition() { + super(ConfigurationPhase.REGISTER_BEAN); + } + + @ConditionalOnEnabledEndpoint("actuator") + static class ActuatorEndpointEnabled { + + } + + @ConditionalOnEnabledEndpoint("docs") + static class DocsEndpointEnabled { + + } + + } + } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/condition/ConditionalOnEnabledEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/condition/ConditionalOnEnabledEndpoint.java index 44c18ca637b..e37539d08ae 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/condition/ConditionalOnEnabledEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/condition/ConditionalOnEnabledEndpoint.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * Copyright 2012-2016 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. @@ -35,7 +35,7 @@ import org.springframework.context.annotation.Conditional; */ @Conditional(OnEnabledEndpointCondition.class) @Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) +@Target({ ElementType.METHOD, ElementType.TYPE }) public @interface ConditionalOnEnabledEndpoint { /** diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfigurationTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfigurationTests.java index f43a17bb266..3f7bfb2146b 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfigurationTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcAutoConfigurationTests.java @@ -40,6 +40,7 @@ import org.springframework.boot.actuate.endpoint.Endpoint; import org.springframework.boot.actuate.endpoint.mvc.EndpointHandlerMapping; import org.springframework.boot.actuate.endpoint.mvc.EndpointHandlerMappingCustomizer; import org.springframework.boot.actuate.endpoint.mvc.EnvironmentMvcEndpoint; +import org.springframework.boot.actuate.endpoint.mvc.HalJsonMvcEndpoint; import org.springframework.boot.actuate.endpoint.mvc.HealthMvcEndpoint; import org.springframework.boot.actuate.endpoint.mvc.MetricsMvcEndpoint; import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint; @@ -455,6 +456,18 @@ public class EndpointWebMvcAutoConfigurationTests { is(equalTo(1))); } + @Test + public void actuatorEndpointEnabledIndividually() { + this.applicationContext.register(RootConfig.class, BaseConfiguration.class, + ServerPortConfig.class, EndpointWebMvcAutoConfiguration.class); + EnvironmentTestUtils.addEnvironment(this.applicationContext, + "endpoints.enabled:false", "endpoints.actuator.enabled:true"); + this.applicationContext.refresh(); + assertThat( + this.applicationContext.getBeansOfType(HalJsonMvcEndpoint.class).size(), + is(equalTo(1))); + } + private void endpointDisabled(String name, Class type) { this.applicationContext.register(RootConfig.class, BaseConfiguration.class, ServerPortConfig.class, EndpointWebMvcAutoConfiguration.class);