diff --git a/docs/src/main/asciidoc/spring-cloud-commons.adoc b/docs/src/main/asciidoc/spring-cloud-commons.adoc index 193ae883..ac6232d9 100644 --- a/docs/src/main/asciidoc/spring-cloud-commons.adoc +++ b/docs/src/main/asciidoc/spring-cloud-commons.adoc @@ -977,7 +977,7 @@ TIP: The `HealthCheckServiceInstanceListSupplier` relies on having updated insta `HealthCheckServiceInstanceListSupplier` uses properties prefixed with `spring.cloud.loadbalancer.health-check`. You can set the `initialDelay` and `interval` for the scheduler. You can set the default path for the healthcheck URL by setting -the value of the `spring.cloud.loadbalancer.health-check.path.default` property. You can also set a specific value for any given service by setting the value of the `spring.cloud.loadbalancer.health-check.path.[SERVICE_ID]` property, substituting `[SERVICE_ID]` with the correct ID of your service. If the path is not set, `/actuator/health` is used by default. +the value of the `spring.cloud.loadbalancer.health-check.path.default` property. You can also set a specific value for any given service by setting the value of the `spring.cloud.loadbalancer.health-check.path.[SERVICE_ID]` property, substituting `[SERVICE_ID]` with the correct ID of your service. If the `[SERVICE_ID]` is not specified, `/actuator/health` is used by default. If the `[SERVICE_ID]` is set to `null` or empty as a value, then the health check will not be executed. TIP: If you rely on the default path (`/actuator/health`), make sure you add `spring-boot-starter-actuator` to your collaborator's dependencies, unless you are planning to add such an endpoint on your own. diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/HealthCheckServiceInstanceListSupplier.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/HealthCheckServiceInstanceListSupplier.java index 55d3d455..0aa33849 100644 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/HealthCheckServiceInstanceListSupplier.java +++ b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/HealthCheckServiceInstanceListSupplier.java @@ -32,6 +32,7 @@ import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; +import org.springframework.util.StringUtils; /** * A {@link ServiceInstanceListSupplier} implementation that verifies whether the @@ -126,7 +127,11 @@ public class HealthCheckServiceInstanceListSupplier extends DelegatingServiceIns } protected Mono isAlive(ServiceInstance serviceInstance) { + boolean containsService = healthCheck.getPath().containsKey(serviceInstance.getServiceId()); String healthCheckPropertyValue = healthCheck.getPath().get(serviceInstance.getServiceId()); + if (containsService && !StringUtils.hasText(healthCheckPropertyValue)) { + return Mono.just(true); + } String healthCheckPath = healthCheckPropertyValue != null ? healthCheckPropertyValue : defaultHealthCheckPath; return aliveFunction.apply(serviceInstance, healthCheckPath); } diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/HealthCheckServiceInstanceListSupplierTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/HealthCheckServiceInstanceListSupplierTests.java index ffc54acc..2dc62798 100644 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/HealthCheckServiceInstanceListSupplierTests.java +++ b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/HealthCheckServiceInstanceListSupplierTests.java @@ -52,7 +52,10 @@ import org.springframework.web.client.RestTemplate; import org.springframework.web.reactive.function.client.WebClient; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.springframework.cloud.loadbalancer.core.ServiceInstanceListSuppliersTestUtils.healthCheckFunction; @@ -113,6 +116,38 @@ class HealthCheckServiceInstanceListSupplierTests { assertThat(alive).isTrue(); } + @Test + void shouldNotCheckInstanceWithNullHealthCheckPath() { + BiFunction> mockAliveFunction = mock(BiFunction.class); + String serviceId = "no-health-check-service"; + healthCheck.getPath().put("no-health-check-service", null); + ServiceInstance serviceInstance = new DefaultServiceInstance("no-health-check-service-1", serviceId, + "127.0.0.1", port, false); + listSupplier = new HealthCheckServiceInstanceListSupplier( + ServiceInstanceListSuppliers.from(serviceId, serviceInstance), healthCheck, mockAliveFunction); + + boolean alive = listSupplier.isAlive(serviceInstance).block(); + + verify(mockAliveFunction, never()).apply(any(), any()); + assertThat(alive).isTrue(); + } + + @Test + void shouldNotCheckInstanceWithEmptyHealthCheckPath() { + BiFunction> mockAliveFunction = mock(BiFunction.class); + String serviceId = "no-health-check-service"; + healthCheck.getPath().put("no-health-check-service", ""); + ServiceInstance serviceInstance = new DefaultServiceInstance("no-health-check-service-1", serviceId, + "127.0.0.1", port, false); + listSupplier = new HealthCheckServiceInstanceListSupplier( + ServiceInstanceListSuppliers.from(serviceId, serviceInstance), healthCheck, mockAliveFunction); + + boolean alive = listSupplier.isAlive(serviceInstance).block(); + + verify(mockAliveFunction, never()).apply(any(), any()); + assertThat(alive).isTrue(); + } + @SuppressWarnings("ConstantConditions") @Test void shouldCheckInstanceWithProvidedHealthCheckPathWithRestTemplate() {