diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpoint.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpoint.java index 54efc0813ba..ce02cfabd90 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpoint.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpoint.java @@ -62,7 +62,8 @@ public class HealthEndpoint extends HealthEndpointSupport { + static final Health DEFAULT_HEALTH = Health.up().build(); + private final ContributorRegistry registry; private final HealthEndpointGroups groups; diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpointWebExtension.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpointWebExtension.java index 499da09f9ee..034faf3a89f 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpointWebExtension.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/HealthEndpointWebExtension.java @@ -16,6 +16,7 @@ package org.springframework.boot.actuate.health; +import java.util.Arrays; import java.util.Map; import java.util.Set; @@ -79,7 +80,9 @@ public class HealthEndpointWebExtension extends HealthEndpointSupport result = getHealth(apiVersion, securityContext, showAll, path); if (result == null) { - return new WebEndpointResponse<>(WebEndpointResponse.STATUS_NOT_FOUND); + return (Arrays.equals(path, NO_PATH)) + ? new WebEndpointResponse<>(DEFAULT_HEALTH, WebEndpointResponse.STATUS_OK) + : new WebEndpointResponse<>(WebEndpointResponse.STATUS_NOT_FOUND); } HealthComponent health = result.getHealth(); HealthEndpointGroup group = result.getGroup(); diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/ReactiveHealthEndpointWebExtension.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/ReactiveHealthEndpointWebExtension.java index 5f2122da1f6..a3d16e62c17 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/ReactiveHealthEndpointWebExtension.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/ReactiveHealthEndpointWebExtension.java @@ -16,6 +16,7 @@ package org.springframework.boot.actuate.health; +import java.util.Arrays; import java.util.Map; import java.util.Set; @@ -81,7 +82,9 @@ public class ReactiveHealthEndpointWebExtension SecurityContext securityContext, boolean showAll, String... path) { HealthResult> result = getHealth(apiVersion, securityContext, showAll, path); if (result == null) { - return Mono.just(new WebEndpointResponse<>(WebEndpointResponse.STATUS_NOT_FOUND)); + return (Arrays.equals(path, NO_PATH)) + ? Mono.just(new WebEndpointResponse<>(DEFAULT_HEALTH, WebEndpointResponse.STATUS_OK)) + : Mono.just(new WebEndpointResponse<>(WebEndpointResponse.STATUS_NOT_FOUND)); } HealthEndpointGroup group = result.getGroup(); return result.getHealth().map((health) -> { diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointTests.java index bf51bdbcd04..40f8578b628 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointTests.java @@ -16,6 +16,7 @@ package org.springframework.boot.actuate.health; +import java.util.Collections; import java.util.Map; import org.junit.jupiter.api.Test; @@ -51,6 +52,15 @@ class HealthEndpointTests assertThat(health).isInstanceOf(SystemHealth.class); } + @Test + void healthWithNoContributorReturnsUp() { + assertThat(this.registry).isEmpty(); + HealthComponent health = create(this.registry, + HealthEndpointGroups.of(mock(HealthEndpointGroup.class), Collections.emptyMap())).health(); + assertThat(health.getStatus()).isEqualTo(Status.UP); + assertThat(health).isInstanceOf(Health.class); + } + @Test void healthWhenPathDoesNotExistReturnsNull() { this.registry.registerContributor("test", createContributor(this.up)); diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointWebExtensionTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointWebExtensionTests.java index 8d36fc09697..b80241cbe66 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointWebExtensionTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/HealthEndpointWebExtensionTests.java @@ -16,6 +16,7 @@ package org.springframework.boot.actuate.health; +import java.util.Collections; import java.util.Map; import org.junit.jupiter.api.Test; @@ -58,6 +59,18 @@ class HealthEndpointWebExtensionTests assertThat(response.getStatus()).isEqualTo(200); } + @Test + void healthWithNoContributorReturnsUp() { + assertThat(this.registry).isEmpty(); + WebEndpointResponse response = create(this.registry, + HealthEndpointGroups.of(mock(HealthEndpointGroup.class), Collections.emptyMap())) + .health(ApiVersion.LATEST, SecurityContext.NONE); + assertThat(response.getStatus()).isEqualTo(200); + HealthComponent health = response.getBody(); + assertThat(health.getStatus()).isEqualTo(Status.UP); + assertThat(health).isInstanceOf(Health.class); + } + @Test void healthWhenPathDoesNotExistReturnsHttp404() { this.registry.registerContributor("test", createContributor(this.up)); diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/ReactiveHealthEndpointWebExtensionTests.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/ReactiveHealthEndpointWebExtensionTests.java index 2820aa4e499..ce79a32e1fb 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/ReactiveHealthEndpointWebExtensionTests.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/health/ReactiveHealthEndpointWebExtensionTests.java @@ -16,6 +16,7 @@ package org.springframework.boot.actuate.health; +import java.util.Collections; import java.util.Map; import org.junit.jupiter.api.Test; @@ -60,6 +61,18 @@ class ReactiveHealthEndpointWebExtensionTests extends assertThat(response.getStatus()).isEqualTo(200); } + @Test + void healthWithNoContributorReturnsUp() { + assertThat(this.registry).isEmpty(); + WebEndpointResponse response = create(this.registry, + HealthEndpointGroups.of(mock(HealthEndpointGroup.class), Collections.emptyMap())) + .health(ApiVersion.LATEST, SecurityContext.NONE).block(); + assertThat(response.getStatus()).isEqualTo(200); + HealthComponent health = response.getBody(); + assertThat(health.getStatus()).isEqualTo(Status.UP); + assertThat(health).isInstanceOf(Health.class); + } + @Test void healthWhenPathDoesNotExistReturnsHttp404() { this.registry.registerContributor("test", createContributor(this.up));