Skip to content

Introduce HealthIndicatorRegistry #4965

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2017 the original author or authors.
* Copyright 2012-2018 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.
Expand All @@ -16,26 +16,41 @@

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

import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnEnabledEndpoint;
import org.springframework.boot.actuate.health.HealthAggregator;
import org.springframework.boot.actuate.health.HealthEndpoint;
import org.springframework.boot.actuate.health.HealthIndicatorRegistry;
import org.springframework.boot.actuate.health.OrderedHealthAggregator;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
* Configuration for {@link HealthEndpoint}.
*
* @author Stephane Nicoll
* @author Vedran Pavic
*/
@Configuration
class HealthEndpointConfiguration {

private final HealthAggregator healthAggregator;

private final HealthIndicatorRegistry healthIndicatorRegistry;

HealthEndpointConfiguration(ObjectProvider<HealthAggregator> healthAggregator,
ObjectProvider<HealthIndicatorRegistry> healthIndicatorRegistry) {
this.healthAggregator = healthAggregator
.getIfAvailable(OrderedHealthAggregator::new);
this.healthIndicatorRegistry = healthIndicatorRegistry.getObject();
}

@Bean
@ConditionalOnMissingBean
@ConditionalOnEnabledEndpoint
public HealthEndpoint healthEndpoint(ApplicationContext applicationContext) {
return new HealthEndpoint(HealthIndicatorBeansComposite.get(applicationContext));
public HealthEndpoint healthEndpoint() {
return new HealthEndpoint(this.healthAggregator, this.healthIndicatorRegistry);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

Expand Down Expand Up @@ -107,11 +106,9 @@ static class ServletWebHealthConfiguration {
@ConditionalOnEnabledEndpoint
@ConditionalOnBean(HealthEndpoint.class)
public HealthEndpointWebExtension healthEndpointWebExtension(
ApplicationContext applicationContext,
HealthEndpoint healthEndpoint,
HealthWebEndpointResponseMapper responseMapper) {
return new HealthEndpointWebExtension(
HealthIndicatorBeansComposite.get(applicationContext),
responseMapper);
return new HealthEndpointWebExtension(healthEndpoint, responseMapper);
}

}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2017 the original author or authors.
* Copyright 2012-2018 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.
Expand All @@ -16,23 +16,31 @@

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

import java.util.LinkedHashMap;
import java.util.Map;

import org.springframework.boot.actuate.health.ApplicationHealthIndicator;
import org.springframework.boot.actuate.health.DefaultHealthIndicatorRegistry;
import org.springframework.boot.actuate.health.HealthAggregator;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.actuate.health.HealthIndicatorRegistry;
import org.springframework.boot.actuate.health.OrderedHealthAggregator;
import org.springframework.boot.actuate.health.ReactiveHealthIndicator;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ClassUtils;

/**
* {@link EnableAutoConfiguration Auto-configuration} for {@link HealthIndicator}s.
*
* @author Andy Wilkinson
* @author Stephane Nicoll
* @author Phillip Webb
* @author Vedran Pavic
* @since 2.0.0
*/
@Configuration
Expand Down Expand Up @@ -61,4 +69,34 @@ public OrderedHealthAggregator healthAggregator() {
return healthAggregator;
}

@Bean
@ConditionalOnMissingBean(HealthIndicatorRegistry.class)
public HealthIndicatorRegistry healthIndicatorRegistry(
ApplicationContext applicationContext) {
HealthIndicatorRegistry registry = new DefaultHealthIndicatorRegistry();
Map<String, HealthIndicator> indicators = new LinkedHashMap<>();
indicators.putAll(applicationContext.getBeansOfType(HealthIndicator.class));
if (ClassUtils.isPresent("reactor.core.publisher.Flux", null)) {
new ReactiveHealthIndicators().get(applicationContext)
.forEach(indicators::putIfAbsent);
}
indicators.forEach(registry::register);
return registry;
}

private static class ReactiveHealthIndicators {

public Map<String, HealthIndicator> get(ApplicationContext applicationContext) {
Map<String, HealthIndicator> indicators = new LinkedHashMap<>();
applicationContext.getBeansOfType(ReactiveHealthIndicator.class)
.forEach((name, indicator) -> indicators.put(name, adapt(indicator)));
return indicators;
}

private HealthIndicator adapt(ReactiveHealthIndicator indicator) {
return () -> indicator.health().block();
}

}

}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@
import org.springframework.boot.actuate.endpoint.web.PathMapper;
import org.springframework.boot.actuate.endpoint.web.WebOperation;
import org.springframework.boot.actuate.endpoint.web.annotation.EndpointWebExtension;
import org.springframework.boot.actuate.health.HealthAggregator;
import org.springframework.boot.actuate.health.HealthEndpoint;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.actuate.health.HealthIndicatorRegistry;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
Expand Down Expand Up @@ -109,7 +110,8 @@ public TestEndpointWebExtension testEndpointWebExtension() {

@Bean
public HealthEndpoint healthEndpoint() {
return new HealthEndpoint(mock(HealthIndicator.class));
return new HealthEndpoint(mock(HealthAggregator.class),
mock(HealthIndicatorRegistry.class));
}

@Bean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.health.HealthIndicatorAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration;
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
Expand Down Expand Up @@ -87,6 +88,7 @@ public class ReactiveCloudFoundryActuatorAutoConfigurationTests {
WebClientCustomizerConfig.class, WebClientAutoConfiguration.class,
ManagementContextAutoConfiguration.class,
EndpointAutoConfiguration.class, WebEndpointAutoConfiguration.class,
HealthIndicatorAutoConfiguration.class,
HealthEndpointAutoConfiguration.class,
ReactiveCloudFoundryActuatorAutoConfiguration.class));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.health.HealthIndicatorAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
Expand Down Expand Up @@ -270,7 +271,8 @@ public void healthEndpointInvokerShouldBeCloudFoundryWebExtension() {
"vcap.application.application_id:my-app-id",
"vcap.application.cf_api:http://my-cloud-controller.com")
.withConfiguration(
AutoConfigurations.of(HealthEndpointAutoConfiguration.class))
AutoConfigurations.of(HealthIndicatorAutoConfiguration.class,
HealthEndpointAutoConfiguration.class))
.run((context) -> {
Collection<ExposableWebEndpoint> endpoints = context
.getBean("cloudFoundryWebEndpointServletHandlerMapping",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@

import org.junit.Test;

import org.springframework.boot.actuate.health.CompositeHealthIndicator;
import org.springframework.boot.actuate.health.DefaultHealthIndicatorRegistry;
import org.springframework.boot.actuate.health.HealthEndpoint;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.actuate.health.HealthIndicatorRegistry;
import org.springframework.boot.actuate.health.OrderedHealthAggregator;
import org.springframework.boot.actuate.jdbc.DataSourceHealthIndicator;
import org.springframework.boot.actuate.system.DiskSpaceHealthIndicator;
Expand Down Expand Up @@ -72,8 +73,9 @@ static class TestConfiguration {

@Bean
public HealthEndpoint endpoint(Map<String, HealthIndicator> healthIndicators) {
return new HealthEndpoint(new CompositeHealthIndicator(
new OrderedHealthAggregator(), healthIndicators));
HealthIndicatorRegistry registry = new DefaultHealthIndicatorRegistry();
healthIndicators.forEach(registry::register);
return new HealthEndpoint(new OrderedHealthAggregator(), registry);
}

@Bean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ public class HealthEndpointAutoConfigurationTests {

private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(
AutoConfigurations.of(HealthEndpointAutoConfiguration.class));
AutoConfigurations.of(HealthIndicatorAutoConfiguration.class,
HealthEndpointAutoConfiguration.class));

@Test
public void healthEndpointShowDetailsDefault() {
Expand Down Expand Up @@ -124,4 +125,5 @@ public ReactiveHealthIndicator reactiveHealthIndicator() {
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.endpoint.jmx.JmxEndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.health.HealthIndicatorAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.trace.http.HttpTraceAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
Expand All @@ -47,7 +48,7 @@ public class JmxEndpointIntegrationTests {
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(JmxAutoConfiguration.class,
EndpointAutoConfiguration.class, JmxEndpointAutoConfiguration.class,
HttpTraceAutoConfiguration.class))
HttpTraceAutoConfiguration.class, HealthIndicatorAutoConfiguration.class))
.withConfiguration(
AutoConfigurations.of(EndpointAutoConfigurationClasses.ALL));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.health.HealthIndicatorAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.trace.http.HttpTraceAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration;
Expand Down Expand Up @@ -73,7 +74,8 @@ public class WebMvcEndpointExposureIntegrationTests {
ServletManagementContextAutoConfiguration.class,
ManagementContextAutoConfiguration.class,
ServletManagementContextAutoConfiguration.class,
HttpTraceAutoConfiguration.class))
HttpTraceAutoConfiguration.class,
HealthIndicatorAutoConfiguration.class))
.withConfiguration(
AutoConfigurations.of(EndpointAutoConfigurationClasses.ALL))
.withUserConfiguration(CustomMvcEndpoint.class,
Expand Down
Loading