Allow ConsulHealthIndicator to bypass the services query
Fixes gh-646
This commit is contained in:
@@ -33,8 +33,8 @@
|
||||
|spring.cloud.consul.discovery.health-check-url | | Custom health check url to override default.
|
||||
|spring.cloud.consul.discovery.heartbeat.enabled | false |
|
||||
|spring.cloud.consul.discovery.heartbeat.interval-ratio | |
|
||||
|spring.cloud.consul.discovery.heartbeat.ttl-unit | s |
|
||||
|spring.cloud.consul.discovery.heartbeat.ttl-value | 30 |
|
||||
|spring.cloud.consul.discovery.heartbeat.ttl-unit | s |
|
||||
|spring.cloud.consul.discovery.heartbeat.ttl-value | 30 |
|
||||
|spring.cloud.consul.discovery.hostname | | Hostname to use when accessing server.
|
||||
|spring.cloud.consul.discovery.include-hostname-in-instance-id | false | Whether hostname is included into the default instance id when registering service.
|
||||
|spring.cloud.consul.discovery.instance-group | | Service instance group.
|
||||
@@ -77,4 +77,4 @@
|
||||
|spring.cloud.consul.tls.key-store-password | | Password to an external keystore.
|
||||
|spring.cloud.consul.tls.key-store-path | | Path to an external keystore.
|
||||
|
||||
|===
|
||||
|===
|
||||
|
||||
@@ -31,7 +31,7 @@ To activate Consul Service Discovery use the starter with group `org.springframe
|
||||
|
||||
=== Registering with Consul
|
||||
|
||||
When a client registers with Consul, it provides meta-data about itself such as host and port, id, name and tags. An HTTP https://www.consul.io/docs/agent/checks.html[Check] is created by default that Consul hits the `/health` endpoint every 10 seconds. If the health check fails, the service instance is marked as critical.
|
||||
When a client registers with Consul, it provides meta-data about itself such as host and port, id, name and tags. An HTTP https://www.consul.io/docs/agent/checks.html[Check] is created by default that Consul hits the `/actuator/health` endpoint every 10 seconds. If the health check fails, the service instance is marked as critical.
|
||||
|
||||
Example Consul client:
|
||||
|
||||
@@ -149,9 +149,13 @@ spring.cloud.consul.discovery.management-suffix
|
||||
spring.cloud.consul.discovery.management-tags
|
||||
----
|
||||
|
||||
=== HTTP Health Check
|
||||
==== HTTP Health Check
|
||||
|
||||
The health check for a Consul instance defaults to "/health", which is the default locations of a useful endpoint in a Spring Boot Actuator application. You need to change these, even for an Actuator application if you use a non-default context path or servlet path (e.g. `server.servletPath=/foo`) or management endpoint path (e.g. `management.server.servlet.context-path=/admin`). The interval that Consul uses to check the health endpoint may also be configured. "10s" and "1m" represent 10 seconds and 1 minute respectively. Example:
|
||||
The health check for a Consul instance defaults to "/actuator/health", which is the default location of the health endpoint in a Spring Boot Actuator application. You need to change this, even for an Actuator application, if you use a non-default context path or servlet path (e.g. `server.servletPath=/foo`) or management endpoint path (e.g. `management.server.servlet.context-path=/admin`).
|
||||
|
||||
The interval that Consul uses to check the health endpoint may also be configured. "10s" and "1m" represent 10 seconds and 1 minute respectively.
|
||||
|
||||
This example illustrates the above (see the `spring.cloud.consul.discovery.health-check-*` properties in link:appendix.html[the appendix page] for more options).
|
||||
|
||||
.application.yml
|
||||
----
|
||||
@@ -159,11 +163,57 @@ spring:
|
||||
cloud:
|
||||
consul:
|
||||
discovery:
|
||||
healthCheckPath: ${management.server.servlet.context-path}/health
|
||||
healthCheckPath: ${management.server.servlet.context-path}/actuator/health
|
||||
healthCheckInterval: 15s
|
||||
----
|
||||
|
||||
You can disable the health check by setting `management.health.consul.enabled=false`.
|
||||
You can disable the HTTP health check entirely by setting `spring.cloud.consul.discovery.register-health-check=false`.
|
||||
|
||||
===== Applying Headers
|
||||
Headers can be applied to health check requests. For example, if you're trying to register a https://cloud.spring.io/spring-cloud-config/[Spring Cloud Config] server that uses https://github.com/spring-cloud/spring-cloud-config/blob/master/docs/src/main/asciidoc/spring-cloud-config.adoc#vault-backend[Vault Backend]:
|
||||
|
||||
.application.yml
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
consul:
|
||||
discovery:
|
||||
health-check-headers:
|
||||
X-Config-Token: 6442e58b-d1ea-182e-cfa5-cf9cddef0722
|
||||
----
|
||||
|
||||
According to the HTTP standard, each header can have more than one values, in which case, an array can be supplied:
|
||||
|
||||
.application.yml
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
consul:
|
||||
discovery:
|
||||
health-check-headers:
|
||||
X-Config-Token:
|
||||
- "6442e58b-d1ea-182e-cfa5-cf9cddef0722"
|
||||
- "Some other value"
|
||||
----
|
||||
|
||||
==== Actuator Health Indicator(s)
|
||||
If the service instance is a Spring Boot Actuator application, it may be provided the following Actuator health indicators.
|
||||
|
||||
===== DiscoveryClientHealthIndicator
|
||||
When Consul Service Discovery is active, a https://cloud.spring.io/spring-cloud-commons/2.2.x/reference/html/#health-indicator[DiscoverClientHealthIndicator] is configured and made available to the Actuator health endpoint.
|
||||
See https://cloud.spring.io/spring-cloud-commons/2.2.x/reference/html/#health-indicator[here] for configuration options.
|
||||
|
||||
===== ConsulHealthIndicator
|
||||
An indicator is configured that verifies the health of the `ConsulClient`.
|
||||
|
||||
By default, it retrieves the Consul leader node status and all registered services.
|
||||
In deployments that have many registered services it may be costly to retrieve all services on every health check.
|
||||
To skip the service retrieval and only check the leader node status set `spring.cloud.consul.health-indicator.include-services-query=false`.
|
||||
|
||||
To disable the indicator set `management.health.consul.enabled=false`.
|
||||
|
||||
WARNING: When the application runs in https://cloud.spring.io/spring-cloud-commons/2.2.x/reference/html/#the-bootstrap-application-context[bootstrap context mode] (the default),
|
||||
this indicator is loaded into the bootstrap context and is not made available to the Actuator health endpoint.
|
||||
|
||||
==== Metadata and Consul tags
|
||||
|
||||
@@ -221,34 +271,6 @@ spring:
|
||||
|
||||
With this metadata, and multiple service instances deployed on localhost, the random value will kick in there to make the instance unique. In Cloudfoundry the `vcap.application.instance_id` will be populated automatically in a Spring Boot application, so the random value will not be needed.
|
||||
|
||||
==== Applying Headers to Health Check Requests
|
||||
|
||||
Headers can be applied to health check requests. For example, if you're trying to register a https://cloud.spring.io/spring-cloud-config/[Spring Cloud Config] server that uses https://github.com/spring-cloud/spring-cloud-config/blob/master/docs/src/main/asciidoc/spring-cloud-config.adoc#vault-backend[Vault Backend]:
|
||||
|
||||
.application.yml
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
consul:
|
||||
discovery:
|
||||
health-check-headers:
|
||||
X-Config-Token: 6442e58b-d1ea-182e-cfa5-cf9cddef0722
|
||||
----
|
||||
|
||||
According to the HTTP standard, each header can have more than one values, in which case, an array can be supplied:
|
||||
|
||||
.application.yml
|
||||
----
|
||||
spring:
|
||||
cloud:
|
||||
consul:
|
||||
discovery:
|
||||
health-check-headers:
|
||||
X-Config-Token:
|
||||
- "6442e58b-d1ea-182e-cfa5-cf9cddef0722"
|
||||
- "Some other value"
|
||||
----
|
||||
|
||||
=== Looking up services
|
||||
|
||||
==== Using Load-balancer
|
||||
|
||||
@@ -71,6 +71,7 @@ public class ConsulAutoConfiguration {
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(Endpoint.class)
|
||||
@EnableConfigurationProperties(ConsulHealthIndicatorProperties.class)
|
||||
protected static class ConsulHealthConfig {
|
||||
|
||||
@Bean
|
||||
@@ -83,8 +84,9 @@ public class ConsulAutoConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnEnabledHealthIndicator("consul")
|
||||
public ConsulHealthIndicator consulHealthIndicator(ConsulClient consulClient) {
|
||||
return new ConsulHealthIndicator(consulClient);
|
||||
public ConsulHealthIndicator consulHealthIndicator(ConsulClient consulClient,
|
||||
ConsulHealthIndicatorProperties properties) {
|
||||
return new ConsulHealthIndicator(consulClient, properties);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,18 +34,24 @@ public class ConsulHealthIndicator extends AbstractHealthIndicator {
|
||||
|
||||
private ConsulClient consul;
|
||||
|
||||
public ConsulHealthIndicator(ConsulClient consul) {
|
||||
private ConsulHealthIndicatorProperties properties;
|
||||
|
||||
public ConsulHealthIndicator(ConsulClient consul,
|
||||
ConsulHealthIndicatorProperties properties) {
|
||||
this.consul = consul;
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doHealthCheck(Health.Builder builder) throws Exception {
|
||||
protected void doHealthCheck(Health.Builder builder) {
|
||||
final Response<String> leaderStatus = this.consul.getStatusLeader();
|
||||
final Response<Map<String, List<String>>> services = this.consul
|
||||
.getCatalogServices(CatalogServicesRequest.newBuilder()
|
||||
.setQueryParams(QueryParams.DEFAULT).build());
|
||||
builder.up().withDetail("leader", leaderStatus.getValue()).withDetail("services",
|
||||
services.getValue());
|
||||
builder.up().withDetail("leader", leaderStatus.getValue());
|
||||
if (properties.isIncludeServicesQuery()) {
|
||||
final Response<Map<String, List<String>>> services = this.consul
|
||||
.getCatalogServices(CatalogServicesRequest.newBuilder()
|
||||
.setQueryParams(QueryParams.DEFAULT).build());
|
||||
builder.withDetail("services", services.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.consul;
|
||||
|
||||
import com.ecwid.consul.v1.ConsulClient;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.core.style.ToStringCreator;
|
||||
|
||||
/**
|
||||
* Configuration properties for {@link ConsulHealthIndicator}.
|
||||
*
|
||||
* @author Chris Bono
|
||||
*/
|
||||
@ConfigurationProperties("spring.cloud.consul.health-indicator")
|
||||
public class ConsulHealthIndicatorProperties {
|
||||
|
||||
/**
|
||||
* Whether or not the indicator should include a query for all registered services
|
||||
* during its execution. When set to {@code false} the indicator only uses the lighter
|
||||
* {@link ConsulClient#getStatusLeader()}. This can be helpful in large deployments
|
||||
* where the number of services returned makes the operation unnecessarily heavy.
|
||||
*/
|
||||
private boolean includeServicesQuery = true;
|
||||
|
||||
boolean isIncludeServicesQuery() {
|
||||
return includeServicesQuery;
|
||||
}
|
||||
|
||||
void setIncludeServicesQuery(boolean includeServicesQuery) {
|
||||
this.includeServicesQuery = includeServicesQuery;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringCreator(this)
|
||||
.append("includeServicesQuery", this.includeServicesQuery).toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,46 +22,107 @@ import com.ecwid.consul.v1.ConsulClient;
|
||||
import com.ecwid.consul.v1.ConsulRawClient;
|
||||
import com.ecwid.consul.v1.catalog.CatalogConsulClient;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringBootConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.cloud.consul.test.ConsulTestcontainers;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(properties = { "spring.cloud.consul.tls.key-store-instance-type=JKS",
|
||||
"spring.cloud.consul.tls.key-store-path=src/test/resources/server.jks",
|
||||
"spring.cloud.consul.tls.key-store-password=letmein",
|
||||
"spring.cloud.consul.tls.certificate-path=src/test/resources/trustStore.jks",
|
||||
"spring.cloud.consul.tls.certificate-password=change_me" })
|
||||
@ContextConfiguration(initializers = ConsulTestcontainers.class)
|
||||
/**
|
||||
* Auto-configuration integration tests for {@link ConsulAutoConfiguration}.
|
||||
*
|
||||
* @author Chris Bono
|
||||
*/
|
||||
public class ConsulAutoConfigurationTests {
|
||||
|
||||
@Autowired
|
||||
private ConsulClient consulClient;
|
||||
private final ApplicationContextRunner appContextRunner = new ApplicationContextRunner()
|
||||
.withInitializer(new ConsulTestcontainers())
|
||||
.withConfiguration(AutoConfigurations.of(ConsulAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
public void defaultConfiguration() {
|
||||
appContextRunner.run(context -> assertThat(context).hasNotFailed()
|
||||
.hasSingleBean(ConsulProperties.class).hasSingleBean(ConsulClient.class)
|
||||
.hasSingleBean(ConsulHealthIndicator.class)
|
||||
.doesNotHaveBean(ConsulEndpoint.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void consulDisabled() {
|
||||
appContextRunner.withPropertyValues("spring.cloud.consul.enabled=false")
|
||||
.run(context -> assertThat(context).hasNotFailed()
|
||||
.doesNotHaveBean(ConsulProperties.class)
|
||||
.doesNotHaveBean(ConsulClient.class)
|
||||
.doesNotHaveBean(ConsulHealthIndicator.class)
|
||||
.doesNotHaveBean(ConsulEndpoint.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void tlsConfigured() {
|
||||
CatalogConsulClient client = (CatalogConsulClient) ReflectionTestUtils
|
||||
.getField(this.consulClient, "catalogClient");
|
||||
ConsulRawClient rawClient = (ConsulRawClient) ReflectionTestUtils.getField(client,
|
||||
"rawClient");
|
||||
HttpTransport httpTransport = (HttpTransport) ReflectionTestUtils
|
||||
.getField(rawClient, "httpTransport");
|
||||
assertThat(httpTransport).isInstanceOf(DefaultHttpsTransport.class);
|
||||
appContextRunner.withPropertyValues(
|
||||
"spring.cloud.consul.tls.key-store-instance-type=JKS",
|
||||
"spring.cloud.consul.tls.key-store-path=src/test/resources/server.jks",
|
||||
"spring.cloud.consul.tls.key-store-password=letmein",
|
||||
"spring.cloud.consul.tls.certificate-path=src/test/resources/trustStore.jks",
|
||||
"spring.cloud.consul.tls.certificate-password=change_me").run(context -> {
|
||||
assertThat(context).hasNotFailed().hasSingleBean(ConsulClient.class);
|
||||
|
||||
ConsulClient consulClient = context.getBean(ConsulClient.class);
|
||||
CatalogConsulClient catalogClient = (CatalogConsulClient) ReflectionTestUtils
|
||||
.getField(consulClient, "catalogClient");
|
||||
ConsulRawClient rawClient = (ConsulRawClient) ReflectionTestUtils
|
||||
.getField(catalogClient, "rawClient");
|
||||
HttpTransport httpTransport = (HttpTransport) ReflectionTestUtils
|
||||
.getField(rawClient, "httpTransport");
|
||||
assertThat(httpTransport).isInstanceOf(DefaultHttpsTransport.class);
|
||||
});
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration
|
||||
@SpringBootConfiguration
|
||||
protected static class TestConfig {
|
||||
@Test
|
||||
public void nonActuatorAppGetsNoEndpointOrHealthIndicator() {
|
||||
appContextRunner.withClassLoader(new FilteredClassLoader(Endpoint.class))
|
||||
.withPropertyValues("management.endpoints.web.exposure.include=consul")
|
||||
.run(context -> assertThat(context).hasNotFailed()
|
||||
.doesNotHaveBean(ConsulHealthIndicator.class)
|
||||
.doesNotHaveBean(ConsulEndpoint.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void consulEndpointAvailable() {
|
||||
appContextRunner
|
||||
.withPropertyValues("management.endpoints.web.exposure.include=consul")
|
||||
.run(context -> assertThat(context).hasNotFailed()
|
||||
.hasSingleBean(ConsulEndpoint.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void consulEndpointAvailableButDisabled() {
|
||||
appContextRunner
|
||||
.withPropertyValues("management.endpoints.web.exposure.include=consul",
|
||||
"management.endpoint.consul.enabled=false")
|
||||
.run(context -> assertThat(context).hasNotFailed()
|
||||
.doesNotHaveBean(ConsulEndpoint.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void consulEndpointDisabled() {
|
||||
appContextRunner.withPropertyValues("spring.cloud.consul.enabled=false")
|
||||
.run(context -> assertThat(context).hasNotFailed()
|
||||
.doesNotHaveBean(ConsulProperties.class)
|
||||
.doesNotHaveBean(ConsulClient.class)
|
||||
.doesNotHaveBean(ConsulHealthIndicator.class)
|
||||
.doesNotHaveBean(ConsulEndpoint.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void consulHealthIndicatorDisabled() {
|
||||
appContextRunner.withPropertyValues("management.health.consul.enabled=false")
|
||||
.run(context -> assertThat(context).hasNotFailed()
|
||||
.doesNotHaveBean(ConsulHealthIndicator.class));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package org.springframework.cloud.consul;
|
||||
|
||||
import com.ecwid.consul.v1.ConsulClient;
|
||||
import com.ecwid.consul.v1.Response;
|
||||
import com.ecwid.consul.v1.catalog.CatalogServicesRequest;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@@ -25,24 +28,47 @@ import org.springframework.boot.actuate.health.HealthEndpoint;
|
||||
import org.springframework.boot.actuate.health.Status;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* Integration test for {@link ConsulHealthIndicator} when its in the DOWN status.
|
||||
*
|
||||
* @author Lomesh Patel (lomeshpatel)
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(properties = "spring.cloud.consul.host=invalidhost")
|
||||
@SpringBootTest
|
||||
public class ConsulHealthIndicatorDownTest {
|
||||
|
||||
@MockBean
|
||||
private ConsulClient consulClient;
|
||||
|
||||
@Autowired
|
||||
private HealthEndpoint healthEndpoint;
|
||||
|
||||
@Test
|
||||
public void doHealthCheck() {
|
||||
public void statusIsDownWhenConsulClientFailsToGetLeaderStatus() {
|
||||
when(consulClient.getStatusLeader()).thenThrow(new RuntimeException("no leader"));
|
||||
assertThat(this.healthEndpoint.health().getStatus())
|
||||
.as("health status was not DOWN").isEqualTo(Status.DOWN);
|
||||
verify(consulClient).getStatusLeader();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void statusIsDownWhenConsulClientFailsToGetServices() {
|
||||
Response<String> leaderStatus = new Response<>("OK", 5150L, true,
|
||||
System.currentTimeMillis());
|
||||
when(consulClient.getStatusLeader()).thenReturn(leaderStatus);
|
||||
when(consulClient.getCatalogServices(any(CatalogServicesRequest.class)))
|
||||
.thenThrow(new RuntimeException("no services"));
|
||||
assertThat(this.healthEndpoint.health().getStatus())
|
||||
.as("health status was not DOWN").isEqualTo(Status.DOWN);
|
||||
verify(consulClient).getCatalogServices(any(CatalogServicesRequest.class));
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.consul;
|
||||
|
||||
import com.ecwid.consul.v1.ConsulClient;
|
||||
import com.ecwid.consul.v1.catalog.CatalogServicesRequest;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringBootConfiguration;
|
||||
import org.springframework.boot.actuate.health.HealthEndpoint;
|
||||
import org.springframework.boot.actuate.health.Status;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.SpyBean;
|
||||
import org.springframework.cloud.consul.test.ConsulTestcontainers;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* Integration test for {@link ConsulHealthIndicator} using its lightweight check when its
|
||||
* in the UP status.
|
||||
*
|
||||
* @author Lomesh Patel (lomeshpatel)
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(
|
||||
properties = "spring.cloud.consul.health-indicator.include-services-query=false")
|
||||
@ContextConfiguration(initializers = ConsulTestcontainers.class)
|
||||
public class ConsulHealthIndicatorLightweightUpTest {
|
||||
|
||||
@SpyBean
|
||||
private ConsulClient consulClient;
|
||||
|
||||
@Autowired
|
||||
private HealthEndpoint healthEndpoint;
|
||||
|
||||
@Test
|
||||
public void statusIsUp() {
|
||||
assertThat(this.healthEndpoint.health().getStatus())
|
||||
.as("health status was not UP").isEqualTo(Status.UP);
|
||||
verify(consulClient).getStatusLeader();
|
||||
verify(consulClient, never())
|
||||
.getCatalogServices(any(CatalogServicesRequest.class));
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration
|
||||
@SpringBootConfiguration
|
||||
protected static class TestConfig {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.cloud.consul;
|
||||
|
||||
import com.ecwid.consul.v1.ConsulClient;
|
||||
import com.ecwid.consul.v1.catalog.CatalogServicesRequest;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@@ -25,13 +27,18 @@ import org.springframework.boot.actuate.health.HealthEndpoint;
|
||||
import org.springframework.boot.actuate.health.Status;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.SpyBean;
|
||||
import org.springframework.cloud.consul.test.ConsulTestcontainers;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* Integration test for {@link ConsulHealthIndicator} when its in the UP status.
|
||||
*
|
||||
* @author Lomesh Patel (lomeshpatel)
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@@ -39,13 +46,18 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
@ContextConfiguration(initializers = ConsulTestcontainers.class)
|
||||
public class ConsulHealthIndicatorUpTest {
|
||||
|
||||
@SpyBean
|
||||
private ConsulClient consulClient;
|
||||
|
||||
@Autowired
|
||||
private HealthEndpoint healthEndpoint;
|
||||
|
||||
@Test
|
||||
public void doHealthCheck() {
|
||||
public void statusIsUp() {
|
||||
assertThat(this.healthEndpoint.health().getStatus())
|
||||
.as("health status was not UP").isEqualTo(Status.UP);
|
||||
verify(consulClient).getStatusLeader();
|
||||
verify(consulClient).getCatalogServices(any(CatalogServicesRequest.class));
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration
|
||||
|
||||
Reference in New Issue
Block a user