Skip to content

Commit d829d52

Browse files
vpavicsnicoll
authored andcommitted
Introduce HealthIndicatorRegistry
This commit introduces HealthIndicatorRegistry which handles registration of HealthIndicator instances. Registering new HealthIndicator instances is now possible in runtime. See gh-4965
1 parent ffdcdc0 commit d829d52

File tree

19 files changed

+346
-127
lines changed

19 files changed

+346
-127
lines changed

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

+19-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.
@@ -16,26 +16,41 @@
1616

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

19+
import org.springframework.beans.factory.ObjectProvider;
1920
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnEnabledEndpoint;
21+
import org.springframework.boot.actuate.health.HealthAggregator;
2022
import org.springframework.boot.actuate.health.HealthEndpoint;
23+
import org.springframework.boot.actuate.health.HealthIndicatorRegistry;
24+
import org.springframework.boot.actuate.health.OrderedHealthAggregator;
2125
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
22-
import org.springframework.context.ApplicationContext;
2326
import org.springframework.context.annotation.Bean;
2427
import org.springframework.context.annotation.Configuration;
2528

2629
/**
2730
* Configuration for {@link HealthEndpoint}.
2831
*
2932
* @author Stephane Nicoll
33+
* @author Vedran Pavic
3034
*/
3135
@Configuration
3236
class HealthEndpointConfiguration {
3337

38+
private final HealthAggregator healthAggregator;
39+
40+
private final HealthIndicatorRegistry healthIndicatorRegistry;
41+
42+
HealthEndpointConfiguration(ObjectProvider<HealthAggregator> healthAggregator,
43+
ObjectProvider<HealthIndicatorRegistry> healthIndicatorRegistry) {
44+
this.healthAggregator = healthAggregator
45+
.getIfAvailable(OrderedHealthAggregator::new);
46+
this.healthIndicatorRegistry = healthIndicatorRegistry.getObject();
47+
}
48+
3449
@Bean
3550
@ConditionalOnMissingBean
3651
@ConditionalOnEnabledEndpoint
37-
public HealthEndpoint healthEndpoint(ApplicationContext applicationContext) {
38-
return new HealthEndpoint(HealthIndicatorBeansComposite.get(applicationContext));
52+
public HealthEndpoint healthEndpoint() {
53+
return new HealthEndpoint(this.healthAggregator, this.healthIndicatorRegistry);
3954
}
4055

4156
}

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

+39-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.
@@ -16,23 +16,31 @@
1616

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

19+
import java.util.LinkedHashMap;
20+
import java.util.Map;
21+
1922
import org.springframework.boot.actuate.health.ApplicationHealthIndicator;
23+
import org.springframework.boot.actuate.health.DefaultHealthIndicatorRegistry;
2024
import org.springframework.boot.actuate.health.HealthAggregator;
2125
import org.springframework.boot.actuate.health.HealthIndicator;
26+
import org.springframework.boot.actuate.health.HealthIndicatorRegistry;
2227
import org.springframework.boot.actuate.health.OrderedHealthAggregator;
2328
import org.springframework.boot.actuate.health.ReactiveHealthIndicator;
2429
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
2530
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
2631
import org.springframework.boot.context.properties.EnableConfigurationProperties;
32+
import org.springframework.context.ApplicationContext;
2733
import org.springframework.context.annotation.Bean;
2834
import org.springframework.context.annotation.Configuration;
35+
import org.springframework.util.ClassUtils;
2936

3037
/**
3138
* {@link EnableAutoConfiguration Auto-configuration} for {@link HealthIndicator}s.
3239
*
3340
* @author Andy Wilkinson
3441
* @author Stephane Nicoll
3542
* @author Phillip Webb
43+
* @author Vedran Pavic
3644
* @since 2.0.0
3745
*/
3846
@Configuration
@@ -61,4 +69,34 @@ public OrderedHealthAggregator healthAggregator() {
6169
return healthAggregator;
6270
}
6371

72+
@Bean
73+
@ConditionalOnMissingBean(HealthIndicatorRegistry.class)
74+
public HealthIndicatorRegistry healthIndicatorRegistry(
75+
ApplicationContext applicationContext) {
76+
HealthIndicatorRegistry registry = new DefaultHealthIndicatorRegistry();
77+
Map<String, HealthIndicator> indicators = new LinkedHashMap<>();
78+
indicators.putAll(applicationContext.getBeansOfType(HealthIndicator.class));
79+
if (ClassUtils.isPresent("reactor.core.publisher.Flux", null)) {
80+
new ReactiveHealthIndicators().get(applicationContext)
81+
.forEach(indicators::putIfAbsent);
82+
}
83+
indicators.forEach(registry::register);
84+
return registry;
85+
}
86+
87+
private static class ReactiveHealthIndicators {
88+
89+
public Map<String, HealthIndicator> get(ApplicationContext applicationContext) {
90+
Map<String, HealthIndicator> indicators = new LinkedHashMap<>();
91+
applicationContext.getBeansOfType(ReactiveHealthIndicator.class)
92+
.forEach((name, indicator) -> indicators.put(name, adapt(indicator)));
93+
return indicators;
94+
}
95+
96+
private HealthIndicator adapt(ReactiveHealthIndicator indicator) {
97+
return () -> indicator.health().block();
98+
}
99+
100+
}
101+
64102
}

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

-80
This file was deleted.

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

+4-2
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,9 @@
3434
import org.springframework.boot.actuate.endpoint.web.PathMapper;
3535
import org.springframework.boot.actuate.endpoint.web.WebOperation;
3636
import org.springframework.boot.actuate.endpoint.web.annotation.EndpointWebExtension;
37+
import org.springframework.boot.actuate.health.HealthAggregator;
3738
import org.springframework.boot.actuate.health.HealthEndpoint;
38-
import org.springframework.boot.actuate.health.HealthIndicator;
39+
import org.springframework.boot.actuate.health.HealthIndicatorRegistry;
3940
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
4041
import org.springframework.context.annotation.Bean;
4142
import org.springframework.context.annotation.Configuration;
@@ -109,7 +110,8 @@ public TestEndpointWebExtension testEndpointWebExtension() {
109110

110111
@Bean
111112
public HealthEndpoint healthEndpoint() {
112-
return new HealthEndpoint(mock(HealthIndicator.class));
113+
return new HealthEndpoint(mock(HealthAggregator.class),
114+
mock(HealthIndicatorRegistry.class));
113115
}
114116

115117
@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/endpoint/web/documentation/HealthEndpointDocumentationTests.java

+5-3
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,10 @@
2323

2424
import org.junit.Test;
2525

26-
import org.springframework.boot.actuate.health.CompositeHealthIndicator;
26+
import org.springframework.boot.actuate.health.DefaultHealthIndicatorRegistry;
2727
import org.springframework.boot.actuate.health.HealthEndpoint;
2828
import org.springframework.boot.actuate.health.HealthIndicator;
29+
import org.springframework.boot.actuate.health.HealthIndicatorRegistry;
2930
import org.springframework.boot.actuate.health.OrderedHealthAggregator;
3031
import org.springframework.boot.actuate.jdbc.DataSourceHealthIndicator;
3132
import org.springframework.boot.actuate.system.DiskSpaceHealthIndicator;
@@ -72,8 +73,9 @@ static class TestConfiguration {
7273

7374
@Bean
7475
public HealthEndpoint endpoint(Map<String, HealthIndicator> healthIndicators) {
75-
return new HealthEndpoint(new CompositeHealthIndicator(
76-
new OrderedHealthAggregator(), healthIndicators));
76+
HealthIndicatorRegistry registry = new DefaultHealthIndicatorRegistry();
77+
healthIndicators.forEach(registry::register);
78+
return new HealthEndpoint(new OrderedHealthAggregator(), registry);
7779
}
7880

7981
@Bean

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-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.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,7 +48,7 @@ public class JmxEndpointIntegrationTests {
4748
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()
4849
.withConfiguration(AutoConfigurations.of(JmxAutoConfiguration.class,
4950
EndpointAutoConfiguration.class, JmxEndpointAutoConfiguration.class,
50-
HttpTraceAutoConfiguration.class))
51+
HttpTraceAutoConfiguration.class, HealthIndicatorAutoConfiguration.class))
5152
.withConfiguration(
5253
AutoConfigurations.of(EndpointAutoConfigurationClasses.ALL));
5354

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,

0 commit comments

Comments
 (0)