Merge pull request #1832 from ryanjbaxter/include-propertysources-in-health-check

Get all property sources for health indicator
This commit is contained in:
Ryan Baxter
2021-03-15 20:17:28 -04:00
committed by GitHub
3 changed files with 49 additions and 18 deletions

View File

@@ -57,6 +57,11 @@ import static org.springframework.cloud.config.client.ConfigClientProperties.TOK
public class ConfigServerConfigDataLoader implements ConfigDataLoader<ConfigServerConfigDataResource>, Ordered {
/**
* PropertySource name for the config client.
*/
public static final String CONFIG_CLIENT_PROPERTYSOURCE_NAME = "configClient";
protected final Log logger;
public ConfigServerConfigDataLoader(Log logger) {
@@ -123,7 +128,7 @@ public class ConfigServerConfigDataLoader implements ConfigDataLoader<ConfigServ
}
// the existence of this property source confirms a successful
// response from config server
composite.add(0, new MapPropertySource("configClient", map));
composite.add(0, new MapPropertySource(CONFIG_CLIENT_PROPERTYSOURCE_NAME, map));
try {
return new ConfigData(composite, Option.IGNORE_IMPORTS, Option.IGNORE_PROFILES);
}
@@ -159,7 +164,8 @@ public class ConfigServerConfigDataLoader implements ConfigDataLoader<ConfigServ
throw new IllegalStateException("Could not locate PropertySource and " + reason + ", failing"
+ (errorBody == null ? "" : ": " + errorBody), error);
}
logger.warn("Could not locate PropertySource (" + resource + "): " + (error != null ? error.getMessage() : errorBody));
logger.warn("Could not locate PropertySource (" + resource + "): "
+ (error != null ? error.getMessage() : errorBody));
return null;
}

View File

@@ -18,14 +18,18 @@ package org.springframework.cloud.config.client;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
import org.springframework.boot.actuate.health.Health.Builder;
import org.springframework.core.env.CompositePropertySource;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import static org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration.BOOTSTRAP_PROPERTY_SOURCE_NAME;
import static org.springframework.cloud.config.client.ConfigServerConfigDataLoader.CONFIG_CLIENT_PROPERTYSOURCE_NAME;
import static org.springframework.cloud.config.client.ConfigServerConfigDataLocationResolver.PREFIX;
/**
* @author Spencer Gibb
* @author Marcos Barbero
@@ -38,7 +42,7 @@ public class ConfigServerHealthIndicator extends AbstractHealthIndicator {
private long lastAccess = 0;
private PropertySource<?> cached;
private List<PropertySource<?>> cached = new ArrayList<>();
public ConfigServerHealthIndicator(ConfigurableEnvironment environment, ConfigClientHealthProperties properties) {
this.environment = environment;
@@ -47,29 +51,38 @@ public class ConfigServerHealthIndicator extends AbstractHealthIndicator {
@Override
protected void doHealthCheck(Builder builder) {
PropertySource<?> propertySource = getPropertySource();
builder.up();
if (propertySource instanceof CompositePropertySource) {
List<PropertySource<?>> propertySources = getPropertySource();
if (propertySources.isEmpty()) {
builder.unknown();
builder.unknown().withDetail("error", "no property sources located");
}
else {
builder.up();
List<String> sources = new ArrayList<>();
for (PropertySource<?> ps : ((CompositePropertySource) propertySource).getPropertySources()) {
sources.add(ps.getName());
for (PropertySource<?> propertySource : propertySources) {
if (propertySource instanceof CompositePropertySource) {
for (PropertySource<?> ps : ((CompositePropertySource) propertySource).getPropertySources()) {
sources.add(ps.getName());
}
}
else if (propertySource != null) {
sources.add(propertySource.getName());
}
}
builder.withDetail("propertySources", sources);
}
else if (propertySource != null) {
builder.withDetail("propertySources", propertySource.toString());
}
else {
builder.unknown().withDetail("error", "no property sources located");
}
}
private PropertySource<?> getPropertySource() {
private List<PropertySource<?>> getPropertySource() {
long accessTime = System.currentTimeMillis();
if (isCacheStale(accessTime)) {
this.lastAccess = accessTime;
MutablePropertySources propertySources = this.environment.getPropertySources();
this.cached = propertySources.get("configClient");
this.cached = this.environment.getPropertySources().stream()
.filter(p -> p.getName().startsWith(CONFIG_CLIENT_PROPERTYSOURCE_NAME)
|| p.getName().startsWith(BOOTSTRAP_PROPERTY_SOURCE_NAME + "-")
|| p.getName().startsWith(PREFIX))
.collect(Collectors.toList());
}
return this.cached;
}

View File

@@ -17,6 +17,8 @@
package org.springframework.cloud.config.client;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
@@ -62,13 +64,23 @@ public class ConfigServerHealthIndicatorTests {
@Test
public void testServerUp() {
setupPropertySources();
Map<String, Object> details = this.indicator.getHealth(true).getDetails();
List<String> propertySources = (List) details.get("propertySources");
assertThat(propertySources.contains("bootstrapProperties-test")).isTrue();
assertThat(propertySources.contains("configserver:test")).isTrue();
assertThat(propertySources.contains("configClient")).isTrue();
assertThat(propertySources.size()).isEqualTo(3);
assertThat(this.indicator.health().getStatus()).isEqualTo(Status.UP);
}
protected void setupPropertySources() {
PropertySource<?> source = new MapPropertySource("configClient", Collections.emptyMap());
PropertySource<?> configServerSource = new MapPropertySource("configserver:test", Collections.emptyMap());
PropertySource<?> bootstrapSource = new MapPropertySource("bootstrapProperties-test", Collections.emptyMap());
MutablePropertySources sources = new MutablePropertySources();
sources.addFirst(source);
sources.addFirst(bootstrapSource);
sources.addFirst(configServerSource);
doReturn(sources).when(this.environment).getPropertySources();
}