From 0021fd14bdf5762e708329703598d932bcec5e2e Mon Sep 17 00:00:00 2001 From: Benjamin Einaudi Date: Mon, 7 Mar 2022 23:10:06 +0100 Subject: [PATCH] [config-server] Allow specification of down health status (#2056) Allow developer to set the property 'spring.cloud.config.server.health.down-health-status' to a custom value --- .../main/asciidoc/spring-cloud-config.adoc | 2 ++ .../config/ConfigServerHealthIndicator.java | 15 +++++++-- .../ConfigServerHealthIndicatorTests.java | 12 ++++++- ...vironmentRepositoryConfigurationTests.java | 33 +++++++++++++++++-- 4 files changed, 56 insertions(+), 6 deletions(-) diff --git a/docs/src/main/asciidoc/spring-cloud-config.adoc b/docs/src/main/asciidoc/spring-cloud-config.adoc index b67a9754..b5331728 100644 --- a/docs/src/main/asciidoc/spring-cloud-config.adoc +++ b/docs/src/main/asciidoc/spring-cloud-config.adoc @@ -1338,6 +1338,8 @@ spring: You can disable the Health Indicator by setting `management.health.config.enabled=false`. +Also, you can provide a custom `down` status of your own by setting property `spring.cloud.config.server.health.down-health-status` (valued to `"DOWN'` by default). + === Security You can secure your Config Server in any way that makes sense to you (from physical network security to OAuth2 bearer tokens), because Spring Security and Spring Boot offer support for many security arrangements. diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/ConfigServerHealthIndicator.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/ConfigServerHealthIndicator.java index 0f0c9a1f..a57ae7c1 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/ConfigServerHealthIndicator.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/config/ConfigServerHealthIndicator.java @@ -30,6 +30,7 @@ import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.actuate.health.AbstractHealthIndicator; import org.springframework.boot.actuate.health.Health; +import org.springframework.boot.actuate.health.Status; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.cloud.config.environment.Environment; import org.springframework.cloud.config.environment.PropertySource; @@ -48,6 +49,8 @@ public class ConfigServerHealthIndicator extends AbstractHealthIndicator { private Map repositories = new LinkedHashMap<>(); + private String downHealthStatus = Status.DOWN.getCode(); + // autowired required or boot constructor binding produces an error @Autowired public ConfigServerHealthIndicator(EnvironmentRepository environmentRepository) { @@ -62,7 +65,7 @@ public class ConfigServerHealthIndicator extends AbstractHealthIndicator { } @Override - protected void doHealthCheck(Health.Builder builder) throws Exception { + protected void doHealthCheck(Health.Builder builder) { builder.up(); List> details = new ArrayList<>(); for (String name : this.repositories.keySet()) { @@ -96,7 +99,7 @@ public class ConfigServerHealthIndicator extends AbstractHealthIndicator { map.put("application", application); map.put("profiles", profiles); builder.withDetail("repository", map); - builder.down(e); + builder.status(this.downHealthStatus).withException(e); return; } } @@ -112,6 +115,14 @@ public class ConfigServerHealthIndicator extends AbstractHealthIndicator { this.repositories = repositories; } + public String getDownHealthStatus() { + return downHealthStatus; + } + + public void setDownHealthStatus(String downHealthStatus) { + this.downHealthStatus = downHealthStatus; + } + /** * Repository properties. */ diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/config/ConfigServerHealthIndicatorTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/config/ConfigServerHealthIndicatorTests.java index 092e4432..7452a2ce 100644 --- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/config/ConfigServerHealthIndicatorTests.java +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/config/ConfigServerHealthIndicatorTests.java @@ -28,6 +28,7 @@ import org.springframework.boot.actuate.health.Status; import org.springframework.cloud.config.environment.Environment; import org.springframework.cloud.config.server.config.ConfigServerHealthIndicator.Repository; import org.springframework.cloud.config.server.environment.EnvironmentRepository; +import org.springframework.test.util.ReflectionTestUtils; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.anyBoolean; @@ -63,12 +64,21 @@ public class ConfigServerHealthIndicatorTests { } @Test - public void exceptionStatusIsDown() { + public void exceptionStatusIsDownByDefault() { when(this.repository.findOne(anyString(), anyString(), Mockito.isNull(), anyBoolean())) .thenThrow(new RuntimeException()); assertThat(this.indicator.health().getStatus()).as("wrong exception status").isEqualTo(Status.DOWN); } + @Test + public void exceptionDownStatusMayBeCustomized() { + ReflectionTestUtils.setField(this.indicator, "downHealthStatus", "CUSTOM"); + when(this.repository.findOne(anyString(), anyString(), Mockito.isNull(), anyBoolean())) + .thenThrow(new RuntimeException()); + assertThat(this.indicator.health().getStatus()).as("wrong exception status").isEqualTo(new Status(("CUSTOM"))); + } + + @Test public void customLabelWorks() { Repository repo = new Repository(); diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/config/EnvironmentRepositoryConfigurationTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/config/EnvironmentRepositoryConfigurationTests.java index ae59cf8b..a497cf7e 100644 --- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/config/EnvironmentRepositoryConfigurationTests.java +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/config/EnvironmentRepositoryConfigurationTests.java @@ -20,14 +20,18 @@ import org.junit.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.test.context.TestConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.cloud.config.server.environment.ConfigTokenProvider; import org.springframework.cloud.config.server.environment.EnvironmentConfigTokenProvider; +import org.springframework.cloud.config.server.environment.EnvironmentRepository; import org.springframework.cloud.config.server.support.GitCredentialsProviderFactory; import org.springframework.context.annotation.Bean; +import org.springframework.test.util.ReflectionTestUtils; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; public class EnvironmentRepositoryConfigurationTests { @@ -64,13 +68,25 @@ public class EnvironmentRepositoryConfigurationTests { }); } + @Test + public void configServerActuatorConfigurationWithCustomHealthStatus() { + new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(EnvironmentRepositoryConfigurationTests.EnableConfigurationPropertiesBeans.class, + EnvironmentRepositoryConfiguration.ConfigServerActuatorConfiguration.class)) + .withPropertyValues("spring.cloud.config.server.health.down-health-status=CUSTOMIZED") + .run((context) -> { + ConfigServerHealthIndicator healthIndicator = context.getBean(ConfigServerHealthIndicator.class); + assertThat(ReflectionTestUtils.getField(healthIndicator, "downHealthStatus")) + .isEqualTo("CUSTOMIZED"); + }); + } + @TestConfiguration public static class TestBeans { @Bean - public ConfigServerProperties vaultConfigServerProperties() { - ConfigServerProperties configServerProperties = new ConfigServerProperties(); - return configServerProperties; + public ConfigServerProperties configServerProperties() { + return new ConfigServerProperties(); } } @@ -90,4 +106,15 @@ public class EnvironmentRepositoryConfigurationTests { } + @TestConfiguration + @EnableConfigurationProperties + public static class EnableConfigurationPropertiesBeans { + + @Bean + public EnvironmentRepository environmentRepository() { + return mock(EnvironmentRepository.class); + } + + } + }