Do not expose the composite ReactiveHealthIndicator as a bean

Previously, a `ReactiveHealthIndicator` bean was exposed to define the
health indicator to use for the reactive endpoint. Having it exposed as
a bean has the side effect that the regular `HealthIndicator` composite
is picked up and a "reactive" entry is added to the health details.

This commit creates such indicator internally as it should be.

Closes gh-11222
pull/11242/merge
Stephane Nicoll 7 years ago
parent 5dc28ec446
commit a4913712cb

@ -65,12 +65,13 @@ public class HealthWebEndpointManagementContextConfiguration {
@ConditionalOnWebApplication(type = Type.REACTIVE) @ConditionalOnWebApplication(type = Type.REACTIVE)
static class ReactiveWebHealthConfiguration { static class ReactiveWebHealthConfiguration {
@Bean private final ReactiveHealthIndicator reactiveHealthIndicator;
public ReactiveHealthIndicator reactiveHealthIndicator(
ReactiveWebHealthConfiguration(
ObjectProvider<HealthAggregator> healthAggregator, ObjectProvider<HealthAggregator> healthAggregator,
ObjectProvider<Map<String, ReactiveHealthIndicator>> reactiveHealthIndicators, ObjectProvider<Map<String, ReactiveHealthIndicator>> reactiveHealthIndicators,
ObjectProvider<Map<String, HealthIndicator>> healthIndicators) { ObjectProvider<Map<String, HealthIndicator>> healthIndicators) {
return new CompositeReactiveHealthIndicatorFactory() this.reactiveHealthIndicator = new CompositeReactiveHealthIndicatorFactory()
.createReactiveHealthIndicator( .createReactiveHealthIndicator(
healthAggregator.getIfAvailable(OrderedHealthAggregator::new), healthAggregator.getIfAvailable(OrderedHealthAggregator::new),
reactiveHealthIndicators reactiveHealthIndicators
@ -83,10 +84,9 @@ public class HealthWebEndpointManagementContextConfiguration {
@ConditionalOnEnabledEndpoint @ConditionalOnEnabledEndpoint
@ConditionalOnBean(HealthEndpoint.class) @ConditionalOnBean(HealthEndpoint.class)
public ReactiveHealthEndpointWebExtension reactiveHealthEndpointWebExtension( public ReactiveHealthEndpointWebExtension reactiveHealthEndpointWebExtension(
ReactiveHealthIndicator reactiveHealthIndicator,
HealthStatusHttpMapper healthStatusHttpMapper, HealthStatusHttpMapper healthStatusHttpMapper,
HealthEndpointProperties properties) { HealthEndpointProperties properties) {
return new ReactiveHealthEndpointWebExtension(reactiveHealthIndicator, return new ReactiveHealthEndpointWebExtension(this.reactiveHealthIndicator,
healthStatusHttpMapper, properties.isShowDetails()); healthStatusHttpMapper, properties.isShowDetails());
} }

@ -19,10 +19,17 @@ package org.springframework.boot.actuate.autoconfigure.health;
import java.util.Map; import java.util.Map;
import org.junit.Test; import org.junit.Test;
import reactor.core.publisher.Mono;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthEndpoint;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.actuate.health.HealthStatusHttpMapper; import org.springframework.boot.actuate.health.HealthStatusHttpMapper;
import org.springframework.boot.actuate.health.ReactiveHealthEndpointWebExtension; import org.springframework.boot.actuate.health.ReactiveHealthEndpointWebExtension;
import org.springframework.boot.actuate.health.ReactiveHealthIndicator;
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.util.ReflectionTestUtils; import org.springframework.test.util.ReflectionTestUtils;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ -72,4 +79,36 @@ public class HealthWebEndpointReactiveManagementContextConfigurationTests {
}); });
} }
@Test
public void regularAndReactiveHealthIndicatorsMatch() {
this.contextRunner
.withUserConfiguration(HealthIndicatorsConfiguration.class)
.run((context) -> {
HealthEndpoint endpoint = context.getBean(HealthEndpoint.class);
ReactiveHealthEndpointWebExtension extension = context
.getBean(ReactiveHealthEndpointWebExtension.class);
Health endpointHealth = endpoint.health();
Health extensionHealth = extension.health(true).block().getBody();
assertThat(endpointHealth.getDetails())
.containsOnlyKeys("application", "first", "second");
assertThat(extensionHealth.getDetails())
.containsOnlyKeys("application", "first", "second");
});
}
@Configuration
static class HealthIndicatorsConfiguration {
@Bean
public HealthIndicator firstHealthIndicator() {
return () -> Health.up().build();
}
@Bean
public ReactiveHealthIndicator secondHealthIndicator() {
return () -> Mono.just(Health.up().build());
}
}
} }

Loading…
Cancel
Save