Skip to content

Commit 3cccbfd

Browse files
committed
Merge pull request #4965 from vpavic:health-indicator-registry
* pr/4965: Polish "Introduce HealthIndicatorRegistry" Introduce HealthIndicatorRegistry
2 parents ffdcdc0 + 23585d2 commit 3cccbfd

24 files changed

+469
-143
lines changed

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/CompositeHealthIndicatorConfiguration.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ protected HealthIndicator createHealthIndicator(Map<String, S> beans) {
4444
}
4545
CompositeHealthIndicator composite = new CompositeHealthIndicator(
4646
this.healthAggregator);
47-
beans.forEach((name, source) -> composite.addHealthIndicator(name,
47+
beans.forEach((name, source) -> composite.register(name,
4848
createHealthIndicator(source)));
4949
return composite;
5050
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointConfiguration.java

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2017 the original author or authors.
2+
* Copyright 2012-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,8 +18,9 @@
1818

1919
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnEnabledEndpoint;
2020
import org.springframework.boot.actuate.health.HealthEndpoint;
21+
import org.springframework.boot.actuate.health.HealthIndicatorRegistry;
2122
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
22-
import org.springframework.context.ApplicationContext;
23+
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
2324
import org.springframework.context.annotation.Bean;
2425
import org.springframework.context.annotation.Configuration;
2526

@@ -29,13 +30,14 @@
2930
* @author Stephane Nicoll
3031
*/
3132
@Configuration
33+
@ConditionalOnSingleCandidate(HealthIndicatorRegistry.class)
3234
class HealthEndpointConfiguration {
3335

3436
@Bean
3537
@ConditionalOnMissingBean
3638
@ConditionalOnEnabledEndpoint
37-
public HealthEndpoint healthEndpoint(ApplicationContext applicationContext) {
38-
return new HealthEndpoint(HealthIndicatorBeansComposite.get(applicationContext));
39+
public HealthEndpoint healthEndpoint(HealthIndicatorRegistry registry) {
40+
return new HealthEndpoint(registry);
3941
}
4042

4143
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointWebExtensionConfiguration.java

+2-5
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
3737
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
3838
import org.springframework.boot.context.properties.EnableConfigurationProperties;
39-
import org.springframework.context.ApplicationContext;
4039
import org.springframework.context.annotation.Bean;
4140
import org.springframework.context.annotation.Configuration;
4241

@@ -107,11 +106,9 @@ static class ServletWebHealthConfiguration {
107106
@ConditionalOnEnabledEndpoint
108107
@ConditionalOnBean(HealthEndpoint.class)
109108
public HealthEndpointWebExtension healthEndpointWebExtension(
110-
ApplicationContext applicationContext,
109+
HealthEndpoint healthEndpoint,
111110
HealthWebEndpointResponseMapper responseMapper) {
112-
return new HealthEndpointWebExtension(
113-
HealthIndicatorBeansComposite.get(applicationContext),
114-
responseMapper);
111+
return new HealthEndpointWebExtension(healthEndpoint, responseMapper);
115112
}
116113

117114
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/health/HealthIndicatorAutoConfiguration.java

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2017 the original author or authors.
2+
* Copyright 2012-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,11 +19,13 @@
1919
import org.springframework.boot.actuate.health.ApplicationHealthIndicator;
2020
import org.springframework.boot.actuate.health.HealthAggregator;
2121
import org.springframework.boot.actuate.health.HealthIndicator;
22+
import org.springframework.boot.actuate.health.HealthIndicatorRegistry;
2223
import org.springframework.boot.actuate.health.OrderedHealthAggregator;
2324
import org.springframework.boot.actuate.health.ReactiveHealthIndicator;
2425
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
2526
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
2627
import org.springframework.boot.context.properties.EnableConfigurationProperties;
28+
import org.springframework.context.ApplicationContext;
2729
import org.springframework.context.annotation.Bean;
2830
import org.springframework.context.annotation.Configuration;
2931

@@ -33,6 +35,7 @@
3335
* @author Andy Wilkinson
3436
* @author Stephane Nicoll
3537
* @author Phillip Webb
38+
* @author Vedran Pavic
3639
* @since 2.0.0
3740
*/
3841
@Configuration
@@ -61,4 +64,11 @@ public OrderedHealthAggregator healthAggregator() {
6164
return healthAggregator;
6265
}
6366

67+
@Bean
68+
@ConditionalOnMissingBean(HealthIndicatorRegistry.class)
69+
public HealthIndicatorRegistry healthIndicatorRegistry(
70+
ApplicationContext applicationContext) {
71+
return HealthIndicatorRegistryBeans.get(applicationContext);
72+
}
73+
6474
}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2017 the original author or authors.
2+
* Copyright 2012-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,36 +20,36 @@
2020
import java.util.Map;
2121

2222
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
23-
import org.springframework.boot.actuate.health.CompositeHealthIndicator;
24-
import org.springframework.boot.actuate.health.CompositeHealthIndicatorFactory;
2523
import org.springframework.boot.actuate.health.HealthAggregator;
2624
import org.springframework.boot.actuate.health.HealthIndicator;
25+
import org.springframework.boot.actuate.health.HealthIndicatorRegistry;
26+
import org.springframework.boot.actuate.health.HealthIndicatorRegistryFactory;
2727
import org.springframework.boot.actuate.health.OrderedHealthAggregator;
2828
import org.springframework.boot.actuate.health.ReactiveHealthIndicator;
2929
import org.springframework.context.ApplicationContext;
3030
import org.springframework.util.ClassUtils;
3131

3232
/**
33-
* Creates a {@link CompositeHealthIndicator} from beans in the
34-
* {@link ApplicationContext}.
33+
* Creates a {@link HealthIndicatorRegistry} from beans in the {@link ApplicationContext}.
3534
*
3635
* @author Phillip Webb
36+
* @author Stephane Nicoll
3737
*/
38-
final class HealthIndicatorBeansComposite {
38+
final class HealthIndicatorRegistryBeans {
3939

40-
private HealthIndicatorBeansComposite() {
40+
private HealthIndicatorRegistryBeans() {
4141
}
4242

43-
public static HealthIndicator get(ApplicationContext applicationContext) {
43+
public static HealthIndicatorRegistry get(ApplicationContext applicationContext) {
4444
HealthAggregator healthAggregator = getHealthAggregator(applicationContext);
4545
Map<String, HealthIndicator> indicators = new LinkedHashMap<>();
4646
indicators.putAll(applicationContext.getBeansOfType(HealthIndicator.class));
4747
if (ClassUtils.isPresent("reactor.core.publisher.Flux", null)) {
4848
new ReactiveHealthIndicators().get(applicationContext)
4949
.forEach(indicators::putIfAbsent);
5050
}
51-
CompositeHealthIndicatorFactory factory = new CompositeHealthIndicatorFactory();
52-
return factory.createHealthIndicator(healthAggregator, indicators);
51+
HealthIndicatorRegistryFactory factory = new HealthIndicatorRegistryFactory();
52+
return factory.createHealthIndicatorRegistry(healthAggregator, indicators);
5353
}
5454

5555
private static HealthAggregator getHealthAggregator(

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/CloudFoundryWebEndpointDiscovererTests.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
import org.springframework.boot.actuate.endpoint.web.WebOperation;
3636
import org.springframework.boot.actuate.endpoint.web.annotation.EndpointWebExtension;
3737
import org.springframework.boot.actuate.health.HealthEndpoint;
38-
import org.springframework.boot.actuate.health.HealthIndicator;
38+
import org.springframework.boot.actuate.health.HealthIndicatorRegistry;
3939
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
4040
import org.springframework.context.annotation.Bean;
4141
import org.springframework.context.annotation.Configuration;
@@ -109,7 +109,7 @@ public TestEndpointWebExtension testEndpointWebExtension() {
109109

110110
@Bean
111111
public HealthEndpoint healthEndpoint() {
112-
return new HealthEndpoint(mock(HealthIndicator.class));
112+
return new HealthEndpoint(mock(HealthIndicatorRegistry.class));
113113
}
114114

115115
@Bean

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/ReactiveCloudFoundryActuatorAutoConfigurationTests.java

+2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
3333
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration;
3434
import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration;
35+
import org.springframework.boot.actuate.autoconfigure.health.HealthIndicatorAutoConfiguration;
3536
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration;
3637
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
3738
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
@@ -87,6 +88,7 @@ public class ReactiveCloudFoundryActuatorAutoConfigurationTests {
8788
WebClientCustomizerConfig.class, WebClientAutoConfiguration.class,
8889
ManagementContextAutoConfiguration.class,
8990
EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class,
91+
HealthIndicatorAutoConfiguration.class,
9092
HealthEndpointAutoConfiguration.class,
9193
ReactiveCloudFoundryActuatorAutoConfiguration.class));
9294

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/servlet/CloudFoundryActuatorAutoConfigurationTests.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
2525
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration;
2626
import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration;
27+
import org.springframework.boot.actuate.autoconfigure.health.HealthIndicatorAutoConfiguration;
2728
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration;
2829
import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration;
2930
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
@@ -270,7 +271,8 @@ public void healthEndpointInvokerShouldBeCloudFoundryWebExtension() {
270271
"vcap.application.application_id:my-app-id",
271272
"vcap.application.cf_api:http://my-cloud-controller.com")
272273
.withConfiguration(
273-
AutoConfigurations.of(HealthEndpointAutoConfiguration.class))
274+
AutoConfigurations.of(HealthIndicatorAutoConfiguration.class,
275+
HealthEndpointAutoConfiguration.class))
274276
.run((context) -> {
275277
Collection<ExposableWebEndpoint> endpoints = context
276278
.getBean("cloudFoundryWebEndpointServletHandlerMapping",

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/health/HealthEndpointAutoConfigurationTests.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ public class HealthEndpointAutoConfigurationTests {
4646

4747
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
4848
.withConfiguration(
49-
AutoConfigurations.of(HealthEndpointAutoConfiguration.class));
49+
AutoConfigurations.of(HealthIndicatorAutoConfiguration.class,
50+
HealthEndpointAutoConfiguration.class));
5051

5152
@Test
5253
public void healthEndpointShowDetailsDefault() {

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/JmxEndpointIntegrationTests.java

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
3030
import org.springframework.boot.actuate.autoconfigure.endpoint.jmx.JmxEndpointAutoConfiguration;
31+
import org.springframework.boot.actuate.autoconfigure.health.HealthIndicatorAutoConfiguration;
3132
import org.springframework.boot.actuate.autoconfigure.trace.http.HttpTraceAutoConfiguration;
3233
import org.springframework.boot.autoconfigure.AutoConfigurations;
3334
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
@@ -47,6 +48,7 @@ public class JmxEndpointIntegrationTests {
4748
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()
4849
.withConfiguration(AutoConfigurations.of(JmxAutoConfiguration.class,
4950
EndpointAutoConfiguration.class, JmxEndpointAutoConfiguration.class,
51+
HealthIndicatorAutoConfiguration.class,
5052
HttpTraceAutoConfiguration.class))
5153
.withConfiguration(
5254
AutoConfigurations.of(EndpointAutoConfigurationClasses.ALL));

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebMvcEndpointExposureIntegrationTests.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
3030
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration;
31+
import org.springframework.boot.actuate.autoconfigure.health.HealthIndicatorAutoConfiguration;
3132
import org.springframework.boot.actuate.autoconfigure.trace.http.HttpTraceAutoConfiguration;
3233
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration;
3334
import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration;
@@ -73,7 +74,8 @@ public class WebMvcEndpointExposureIntegrationTests {
7374
ServletManagementContextAutoConfiguration.class,
7475
ManagementContextAutoConfiguration.class,
7576
ServletManagementContextAutoConfiguration.class,
76-
HttpTraceAutoConfiguration.class))
77+
HttpTraceAutoConfiguration.class,
78+
HealthIndicatorAutoConfiguration.class))
7779
.withConfiguration(
7880
AutoConfigurations.of(EndpointAutoConfigurationClasses.ALL))
7981
.withUserConfiguration(CustomMvcEndpoint.class,

spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/CompositeHealthIndicator.java

+15-23
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,8 @@
1616

1717
package org.springframework.boot.actuate.health;
1818

19-
import java.util.LinkedHashMap;
2019
import java.util.Map;
2120

22-
import org.springframework.util.Assert;
23-
2421
/**
2522
* {@link HealthIndicator} that returns health indications from all registered delegates.
2623
*
@@ -29,18 +26,15 @@
2926
* @author Christian Dupuis
3027
* @since 1.1.0
3128
*/
32-
public class CompositeHealthIndicator implements HealthIndicator {
33-
34-
private final Map<String, HealthIndicator> indicators;
35-
36-
private final HealthAggregator healthAggregator;
29+
public class CompositeHealthIndicator
30+
extends DefaultHealthIndicatorRegistry implements HealthIndicator {
3731

3832
/**
3933
* Create a new {@link CompositeHealthIndicator}.
4034
* @param healthAggregator the health aggregator
4135
*/
4236
public CompositeHealthIndicator(HealthAggregator healthAggregator) {
43-
this(healthAggregator, new LinkedHashMap<>());
37+
super(healthAggregator);
4438
}
4539

4640
/**
@@ -51,23 +45,21 @@ public CompositeHealthIndicator(HealthAggregator healthAggregator) {
5145
*/
5246
public CompositeHealthIndicator(HealthAggregator healthAggregator,
5347
Map<String, HealthIndicator> indicators) {
54-
Assert.notNull(healthAggregator, "HealthAggregator must not be null");
55-
Assert.notNull(indicators, "Indicators must not be null");
56-
this.indicators = new LinkedHashMap<>(indicators);
57-
this.healthAggregator = healthAggregator;
48+
super(healthAggregator, indicators);
5849
}
5950

51+
/**
52+
* Registers the given {@code healthIndicator}, associating it with the given
53+
* {@code name}.
54+
* @param name the name of the indicator
55+
* @param indicator the indicator
56+
* @throws IllegalStateException if an indicator with the given {@code name} is
57+
* already registered.
58+
* @deprecated as of 2.1.0 in favour of {@link #register(String, HealthIndicator)}
59+
*/
60+
@Deprecated
6061
public void addHealthIndicator(String name, HealthIndicator indicator) {
61-
this.indicators.put(name, indicator);
62-
}
63-
64-
@Override
65-
public Health health() {
66-
Map<String, Health> healths = new LinkedHashMap<>();
67-
for (Map.Entry<String, HealthIndicator> entry : this.indicators.entrySet()) {
68-
healths.put(entry.getKey(), entry.getValue().health());
69-
}
70-
return this.healthAggregator.aggregate(healths);
62+
register(name, indicator);
7163
}
7264

7365
}

spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/CompositeHealthIndicatorFactory.java

+5-12
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,15 @@
2727
* @author Stephane Nicoll
2828
* @since 2.0.0
2929
*/
30-
public class CompositeHealthIndicatorFactory {
31-
32-
private final Function<String, String> healthIndicatorNameFactory;
30+
public class CompositeHealthIndicatorFactory extends HealthIndicatorRegistryFactory {
3331

3432
public CompositeHealthIndicatorFactory(
3533
Function<String, String> healthIndicatorNameFactory) {
36-
this.healthIndicatorNameFactory = healthIndicatorNameFactory;
34+
super(healthIndicatorNameFactory);
3735
}
3836

3937
public CompositeHealthIndicatorFactory() {
40-
this(new HealthIndicatorNameFactory());
38+
super();
4139
}
4240

4341
/**
@@ -52,13 +50,8 @@ public CompositeHealthIndicator createHealthIndicator(
5250
Map<String, HealthIndicator> healthIndicators) {
5351
Assert.notNull(healthAggregator, "HealthAggregator must not be null");
5452
Assert.notNull(healthIndicators, "HealthIndicators must not be null");
55-
CompositeHealthIndicator healthIndicator = new CompositeHealthIndicator(
56-
healthAggregator);
57-
for (Map.Entry<String, HealthIndicator> entry : healthIndicators.entrySet()) {
58-
String name = this.healthIndicatorNameFactory.apply(entry.getKey());
59-
healthIndicator.addHealthIndicator(name, entry.getValue());
60-
}
61-
return healthIndicator;
53+
return initialize(new CompositeHealthIndicator(healthAggregator),
54+
healthIndicators);
6255
}
6356

6457
}

0 commit comments

Comments
 (0)