diff --git a/documentation/spring-boot-docs/src/docs/antora/modules/reference/pages/actuator/endpoints.adoc b/documentation/spring-boot-docs/src/docs/antora/modules/reference/pages/actuator/endpoints.adoc index 3170df01084..6fcbe7cfc57 100644 --- a/documentation/spring-boot-docs/src/docs/antora/modules/reference/pages/actuator/endpoints.adoc +++ b/documentation/spring-boot-docs/src/docs/antora/modules/reference/pages/actuator/endpoints.adoc @@ -672,7 +672,7 @@ TIP: The `ssl` javadoc:org.springframework.boot.actuate.health.HealthIndicator[] If an SSL certificate will be invalid within the time span defined by this threshold, the javadoc:org.springframework.boot.actuate.health.HealthIndicator[] will warn you but it will still return HTTP 200 to not disrupt the application. You can use this threshold to give yourself enough lead time to rotate the soon to be expired certificate. -Additional javadoc:org.springframework.boot.actuate.health.HealthIndicator[] beans are available but are not enabled by default: +Additional javadoc:org.springframework.boot.actuate.health.HealthIndicator[] beans are enabled by default: [cols="3,4,6"] |=== @@ -687,6 +687,8 @@ Additional javadoc:org.springframework.boot.actuate.health.HealthIndicator[] bea | Exposes the "`Readiness`" application availability state. |=== +These can be disabled by using the configprop:management.endpoint.health.probes.enabled[] configuration property. + [[actuator.endpoints.health.writing-custom-health-indicators]] @@ -952,8 +954,8 @@ readinessProbe: NOTE: `` should be set to the port that the actuator endpoints are available on. It could be the main web server port or a separate management port if the `"management.server.port"` property has been set. -These health groups are automatically enabled only if the application xref:how-to:deployment/cloud.adoc#howto.deployment.cloud.kubernetes[runs in a Kubernetes environment]. -You can enable them in any environment by using the configprop:management.endpoint.health.probes.enabled[] configuration property. +These health groups are automatically enabled. +You can disable them by using the configprop:management.endpoint.health.probes.enabled[] configuration property. NOTE: If an application takes longer to start than the configured liveness period, Kubernetes mentions the `"startupProbe"` as a possible solution. Generally speaking, the `"startupProbe"` is not necessarily needed here, as the `"readinessProbe"` fails until all startup tasks are done. diff --git a/module/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/availability/AvailabilityProbesAutoConfiguration.java b/module/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/availability/AvailabilityProbesAutoConfiguration.java index c35e1ce8146..81735684917 100644 --- a/module/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/availability/AvailabilityProbesAutoConfiguration.java +++ b/module/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/availability/AvailabilityProbesAutoConfiguration.java @@ -16,26 +16,18 @@ package org.springframework.boot.actuate.autoconfigure.availability; -import org.jspecify.annotations.Nullable; - import org.springframework.boot.actuate.availability.LivenessStateHealthIndicator; import org.springframework.boot.actuate.availability.ReadinessStateHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionMessage; -import org.springframework.boot.autoconfigure.condition.ConditionOutcome; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.SpringBootCondition; import org.springframework.boot.availability.ApplicationAvailability; -import org.springframework.boot.cloud.CloudPlatform; import org.springframework.boot.health.contributor.Health; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ConditionContext; -import org.springframework.context.annotation.Conditional; import org.springframework.core.env.Environment; -import org.springframework.core.type.AnnotatedTypeMetadata; /** * {@link EnableAutoConfiguration Auto-configuration} for availability probes. @@ -47,7 +39,7 @@ import org.springframework.core.type.AnnotatedTypeMetadata; @AutoConfiguration(after = { AvailabilityHealthContributorAutoConfiguration.class, ApplicationAvailabilityAutoConfiguration.class }) @ConditionalOnClass(Health.class) -@Conditional(AvailabilityProbesAutoConfiguration.ProbesCondition.class) +@ConditionalOnBooleanProperty(name = "management.endpoint.health.probes.enabled", matchIfMissing = true) public final class AvailabilityProbesAutoConfiguration { @Bean @@ -68,49 +60,4 @@ public final class AvailabilityProbesAutoConfiguration { return new AvailabilityProbesHealthEndpointGroupsPostProcessor(environment); } - /** - * {@link SpringBootCondition} to enable or disable probes. - *

- * Probes are enabled if the dedicated configuration property is enabled or if the - * Kubernetes cloud environment is detected/enforced. - */ - static class ProbesCondition extends SpringBootCondition { - - private static final String ENABLED_PROPERTY = "management.endpoint.health.probes.enabled"; - - private static final String DEPRECATED_ENABLED_PROPERTY = "management.health.probes.enabled"; - - @Override - public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) { - Environment environment = context.getEnvironment(); - ConditionMessage.Builder message = ConditionMessage.forCondition("Probes availability"); - ConditionOutcome outcome = onProperty(environment, message, ENABLED_PROPERTY); - if (outcome != null) { - return outcome; - } - outcome = onProperty(environment, message, DEPRECATED_ENABLED_PROPERTY); - if (outcome != null) { - return outcome; - } - if (CloudPlatform.getActive(environment) == CloudPlatform.KUBERNETES) { - return ConditionOutcome.match(message.because("running on Kubernetes")); - } - if (CloudPlatform.getActive(environment) == CloudPlatform.CLOUD_FOUNDRY) { - return ConditionOutcome.match(message.because("running on Cloud Foundry")); - } - return ConditionOutcome.noMatch(message.because("not running on a supported cloud platform")); - } - - private @Nullable ConditionOutcome onProperty(Environment environment, ConditionMessage.Builder message, - String propertyName) { - String enabled = environment.getProperty(propertyName); - if (enabled != null) { - boolean match = !"false".equalsIgnoreCase(enabled); - return new ConditionOutcome(match, message.because("'" + propertyName + "' set to '" + enabled + "'")); - } - return null; - } - - } - } diff --git a/module/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/module/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 50924edde5f..7db8b91ccae 100644 --- a/module/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/module/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -34,7 +34,7 @@ "name": "management.endpoint.health.probes.enabled", "type": "java.lang.Boolean", "description": "Whether to enable liveness and readiness probes.", - "defaultValue": false + "defaultValue": true }, { "name": "management.endpoint.health.status.order", @@ -137,6 +137,7 @@ "description": "Whether to enable liveness and readiness probes.", "defaultValue": false, "deprecation": { + "level": "error", "replacement": "management.endpoint.health.probes.enabled" } }, diff --git a/module/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/availability/AvailabilityProbesAutoConfigurationTests.java b/module/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/availability/AvailabilityProbesAutoConfigurationTests.java index f13f1291e09..6c1c6d6a042 100644 --- a/module/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/availability/AvailabilityProbesAutoConfigurationTests.java +++ b/module/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/availability/AvailabilityProbesAutoConfigurationTests.java @@ -41,18 +41,8 @@ class AvailabilityProbesAutoConfigurationTests { AvailabilityHealthContributorAutoConfiguration.class, AvailabilityProbesAutoConfiguration.class)); @Test - void probesWhenNotKubernetesAddsNoBeans() { - this.contextRunner.run(this::doesNotHaveProbeBeans); - } - - @Test - void probesWhenKubernetesAddsBeans() { - this.contextRunner.withPropertyValues("spring.main.cloud-platform=kubernetes").run(this::hasProbesBeans); - } - - @Test - void probesWhenCloudFoundryAddsBeans() { - this.contextRunner.withPropertyValues("spring.main.cloud-platform=cloud_foundry").run(this::hasProbesBeans); + void probesWhenDefaultAddsBeans() { + this.contextRunner.run(this::hasProbesBeans); } @Test @@ -62,17 +52,14 @@ class AvailabilityProbesAutoConfigurationTests { } @Test - void probesWhenPropertyEnabledButNoHealthDependencyDoesNotAddBeans() { - this.contextRunner.withPropertyValues("management.endpoint.health.probes.enabled=true") - .withClassLoader(new FilteredClassLoader("org.springframework.boot.health")) + void probesWhenNoHealthDependencyDoesNotAddBeans() { + this.contextRunner.withClassLoader(new FilteredClassLoader("org.springframework.boot.health")) .run(this::doesNotHaveProbeBeans); } @Test - void probesWhenKubernetesAndPropertyDisabledAddsNotBeans() { - this.contextRunner - .withPropertyValues("spring.main.cloud-platform=kubernetes", - "management.endpoint.health.probes.enabled=false") + void probesWhenPropertyDisabledAddsNotBeans() { + this.contextRunner.withPropertyValues("management.endpoint.health.probes.enabled=false") .run(this::doesNotHaveProbeBeans); } diff --git a/smoke-test/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/AbstractManagementPortAndPathSampleActuatorApplicationTests.java b/smoke-test/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/AbstractManagementPortAndPathSampleActuatorApplicationTests.java index 26233ef3109..1d0f36ebbbd 100644 --- a/smoke-test/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/AbstractManagementPortAndPathSampleActuatorApplicationTests.java +++ b/smoke-test/spring-boot-smoke-test-actuator/src/test/java/smoketest/actuator/AbstractManagementPortAndPathSampleActuatorApplicationTests.java @@ -67,7 +67,8 @@ abstract class AbstractManagementPortAndPathSampleActuatorApplicationTests { ResponseEntity entity = new TestRestTemplate().withBasicAuth("user", "password") .getForEntity("http://localhost:" + this.managementPort + "/admin/health", String.class); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - assertThat(entity.getBody()).isEqualTo("{\"groups\":[\"comp\",\"live\",\"ready\"],\"status\":\"UP\"}"); + assertThat(entity.getBody()) + .isEqualTo("{\"groups\":[\"comp\",\"live\",\"liveness\",\"readiness\",\"ready\"],\"status\":\"UP\"}"); } @Test diff --git a/smoke-test/spring-boot-smoke-test-secure-webflux/src/test/java/smoketest/secure/webflux/SampleSecureWebFluxApplicationTests.java b/smoke-test/spring-boot-smoke-test-secure-webflux/src/test/java/smoketest/secure/webflux/SampleSecureWebFluxApplicationTests.java index e6f3ef1bdac..1642b0d944b 100644 --- a/smoke-test/spring-boot-smoke-test-secure-webflux/src/test/java/smoketest/secure/webflux/SampleSecureWebFluxApplicationTests.java +++ b/smoke-test/spring-boot-smoke-test-secure-webflux/src/test/java/smoketest/secure/webflux/SampleSecureWebFluxApplicationTests.java @@ -87,7 +87,7 @@ class SampleSecureWebFluxApplicationTests { .header("Authorization", getBasicAuth()) .exchange() .expectBody(String.class) - .isEqualTo("{\"status\":\"UP\"}"); + .isEqualTo("{\"groups\":[\"liveness\",\"readiness\"],\"status\":\"UP\"}"); } private String getBasicAuth() {