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
pull/20966/head
Phillip Webb 5 years ago
parent 82cfd7c6c9
commit f32a37e289

@ -16,7 +16,7 @@
package org.springframework.boot.actuate.autoconfigure.availability; 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.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
import org.springframework.boot.actuate.availability.LivenessStateHealthIndicator; import org.springframework.boot.actuate.availability.LivenessStateHealthIndicator;
import org.springframework.boot.actuate.availability.ReadinessStateHealthIndicator; 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.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration; import org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; import org.springframework.boot.autoconfigure.condition.ConditionMessage;
import org.springframework.boot.autoconfigure.condition.ConditionalOnCloudPlatform; import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 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.availability.ApplicationAvailability;
import org.springframework.boot.cloud.CloudPlatform; import org.springframework.boot.cloud.CloudPlatform;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;
/** /**
* {@link EnableAutoConfiguration Auto-configuration} for * {@link EnableAutoConfiguration Auto-configuration} for
@ -43,7 +46,7 @@ import org.springframework.context.annotation.Configuration;
* @since 2.3.0 * @since 2.3.0
*/ */
@Configuration(proxyBeanMethods = false) @Configuration(proxyBeanMethods = false)
@Conditional(KubernetesOrPropertyCondition.class) @Conditional(ProbesCondition.class)
@AutoConfigureAfter(ApplicationAvailabilityAutoConfiguration.class) @AutoConfigureAfter(ApplicationAvailabilityAutoConfiguration.class)
public class AvailabilityProbesAutoConfiguration { public class AvailabilityProbesAutoConfiguration {
@ -67,20 +70,25 @@ public class AvailabilityProbesAutoConfiguration {
return new AvailabilityProbesHealthEndpointGroupsRegistrar(); return new AvailabilityProbesHealthEndpointGroupsRegistrar();
} }
static class KubernetesOrPropertyCondition extends AnyNestedCondition { /**
* {@link SpringBootCondition} to enable or disable probes.
KubernetesOrPropertyCondition() { */
super(ConfigurationPhase.PARSE_CONFIGURATION); static class ProbesCondition extends SpringBootCondition {
}
@ConditionalOnCloudPlatform(CloudPlatform.KUBERNETES)
static class Kubernetes {
}
@ConditionalOnProperty(prefix = "management.health.probes", name = "enabled")
static class ProbesIndicatorsEnabled {
@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"));
} }
} }

@ -39,7 +39,7 @@ class AvailabilityProbesAutoConfigurationTests {
.of(ApplicationAvailabilityAutoConfiguration.class, AvailabilityProbesAutoConfiguration.class)); .of(ApplicationAvailabilityAutoConfiguration.class, AvailabilityProbesAutoConfiguration.class));
@Test @Test
void probesNotConfiguredIfNotKubernetes() { void probesWhenNotKubernetesAddsNoBeans() {
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(ApplicationAvailability.class) this.contextRunner.run((context) -> assertThat(context).hasSingleBean(ApplicationAvailability.class)
.doesNotHaveBean(LivenessStateHealthIndicator.class) .doesNotHaveBean(LivenessStateHealthIndicator.class)
.doesNotHaveBean(ReadinessStateHealthIndicator.class) .doesNotHaveBean(ReadinessStateHealthIndicator.class)
@ -47,7 +47,16 @@ class AvailabilityProbesAutoConfigurationTests {
} }
@Test @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") this.contextRunner.withPropertyValues("management.health.probes.enabled=true")
.run((context) -> assertThat(context).hasSingleBean(ApplicationAvailability.class) .run((context) -> assertThat(context).hasSingleBean(ApplicationAvailability.class)
.hasSingleBean(LivenessStateHealthIndicator.class) .hasSingleBean(LivenessStateHealthIndicator.class)
@ -55,4 +64,14 @@ class AvailabilityProbesAutoConfigurationTests {
.hasSingleBean(HealthEndpointGroupsRegistryCustomizer.class)); .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));
}
} }

Loading…
Cancel
Save