From f32a37e289d781b66df55eaf9c5d3eddcbaaf95c Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Mon, 13 Apr 2020 15:33:15 -0700 Subject: [PATCH] Support `management.health.probes.enabled=false` Update `AvailabilityProbesAutoConfiguration` to allow the `management.health.probes.enabled` property to override the platform detection logic. Prior to this commit, it was possible to use the property to enable the probes, but it was not possible to disable them when deploying to Kubernates. See gh-20962 --- .../AvailabilityProbesAutoConfiguration.java | 44 +++++++++++-------- ...ilabilityProbesAutoConfigurationTests.java | 23 +++++++++- 2 files changed, 47 insertions(+), 20 deletions(-) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/availability/AvailabilityProbesAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/availability/AvailabilityProbesAutoConfiguration.java index 4370770912..5b130eee37 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/availability/AvailabilityProbesAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/availability/AvailabilityProbesAutoConfiguration.java @@ -16,7 +16,7 @@ package org.springframework.boot.actuate.autoconfigure.availability; -import org.springframework.boot.actuate.autoconfigure.availability.AvailabilityProbesAutoConfiguration.KubernetesOrPropertyCondition; +import org.springframework.boot.actuate.autoconfigure.availability.AvailabilityProbesAutoConfiguration.ProbesCondition; import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; import org.springframework.boot.actuate.availability.LivenessStateHealthIndicator; import org.springframework.boot.actuate.availability.ReadinessStateHealthIndicator; @@ -24,15 +24,18 @@ import org.springframework.boot.actuate.health.HealthEndpointGroupsRegistryCusto import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; -import org.springframework.boot.autoconfigure.condition.ConditionalOnCloudPlatform; +import org.springframework.boot.autoconfigure.condition.ConditionMessage; +import org.springframework.boot.autoconfigure.condition.ConditionOutcome; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.condition.SpringBootCondition; import org.springframework.boot.availability.ApplicationAvailability; import org.springframework.boot.cloud.CloudPlatform; import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ConditionContext; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.core.type.AnnotatedTypeMetadata; /** * {@link EnableAutoConfiguration Auto-configuration} for @@ -43,7 +46,7 @@ import org.springframework.context.annotation.Configuration; * @since 2.3.0 */ @Configuration(proxyBeanMethods = false) -@Conditional(KubernetesOrPropertyCondition.class) +@Conditional(ProbesCondition.class) @AutoConfigureAfter(ApplicationAvailabilityAutoConfiguration.class) public class AvailabilityProbesAutoConfiguration { @@ -67,20 +70,25 @@ public class AvailabilityProbesAutoConfiguration { return new AvailabilityProbesHealthEndpointGroupsRegistrar(); } - static class KubernetesOrPropertyCondition extends AnyNestedCondition { - - KubernetesOrPropertyCondition() { - super(ConfigurationPhase.PARSE_CONFIGURATION); - } - - @ConditionalOnCloudPlatform(CloudPlatform.KUBERNETES) - static class Kubernetes { - - } - - @ConditionalOnProperty(prefix = "management.health.probes", name = "enabled") - static class ProbesIndicatorsEnabled { + /** + * {@link SpringBootCondition} to enable or disable probes. + */ + static class ProbesCondition extends SpringBootCondition { + @Override + public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) { + Environment environment = context.getEnvironment(); + ConditionMessage.Builder message = ConditionMessage.forCondition("Health probes"); + String enabled = environment.getProperty("management.health.probes.enabled"); + if (enabled != null) { + boolean match = !"false".equalsIgnoreCase(enabled); + return new ConditionOutcome(match, + message.because("'management.health.probes.enabled' set to '" + enabled + "'")); + } + if (CloudPlatform.getActive(environment) == CloudPlatform.KUBERNETES) { + return ConditionOutcome.match(message.because("running on Kubernetes")); + } + return ConditionOutcome.noMatch(message.because("not running on a supported cloud platform")); } } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/availability/AvailabilityProbesAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/availability/AvailabilityProbesAutoConfigurationTests.java index 02129c50d9..939edbbc86 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/availability/AvailabilityProbesAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/availability/AvailabilityProbesAutoConfigurationTests.java @@ -39,7 +39,7 @@ class AvailabilityProbesAutoConfigurationTests { .of(ApplicationAvailabilityAutoConfiguration.class, AvailabilityProbesAutoConfiguration.class)); @Test - void probesNotConfiguredIfNotKubernetes() { + void probesWhenNotKubernetesAddsNoBeans() { this.contextRunner.run((context) -> assertThat(context).hasSingleBean(ApplicationAvailability.class) .doesNotHaveBean(LivenessStateHealthIndicator.class) .doesNotHaveBean(ReadinessStateHealthIndicator.class) @@ -47,7 +47,16 @@ class AvailabilityProbesAutoConfigurationTests { } @Test - void probesConfiguredIfProperty() { + void probesWhenKubernetesAddsBeans() { + this.contextRunner.withPropertyValues("spring.main.cloud-platform=kubernetes") + .run((context) -> assertThat(context).hasSingleBean(ApplicationAvailability.class) + .hasSingleBean(LivenessStateHealthIndicator.class) + .hasSingleBean(ReadinessStateHealthIndicator.class) + .hasSingleBean(HealthEndpointGroupsRegistryCustomizer.class)); + } + + @Test + void probesWhenPropertyEnabledAddsBeans() { this.contextRunner.withPropertyValues("management.health.probes.enabled=true") .run((context) -> assertThat(context).hasSingleBean(ApplicationAvailability.class) .hasSingleBean(LivenessStateHealthIndicator.class) @@ -55,4 +64,14 @@ class AvailabilityProbesAutoConfigurationTests { .hasSingleBean(HealthEndpointGroupsRegistryCustomizer.class)); } + @Test + void probesWhenKuberntesAndPropertyDisabledAddsNotBeans() { + this.contextRunner + .withPropertyValues("spring.main.cloud-platform=kubernetes", "management.health.probes.enabled=false") + .run((context) -> assertThat(context).hasSingleBean(ApplicationAvailability.class) + .doesNotHaveBean(LivenessStateHealthIndicator.class) + .doesNotHaveBean(ReadinessStateHealthIndicator.class) + .doesNotHaveBean(HealthEndpointGroupsRegistryCustomizer.class)); + } + }