Property detect Health web extension with management context

Previously, the Health web extension was defined in the management
context and, as a result, it wasn't found when a separate port was
required. The side effect is that anything that the health web extension
does was not active anymore in that case.

This commit makes sure that the extension is always defined as part of
the main context where operations are discovered and merged.

Closes gh-11285
pull/11120/merge
Stephane Nicoll 7 years ago
parent 1fdc1e373c
commit 681fdb1ee8

@ -16,14 +16,12 @@
package org.springframework.boot.actuate.autoconfigure.health; package org.springframework.boot.actuate.autoconfigure.health;
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnEnabledEndpoint;
import org.springframework.boot.actuate.health.HealthEndpoint; import org.springframework.boot.actuate.health.HealthEndpoint;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties; 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.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/** /**
* {@link EnableAutoConfiguration Auto-configuration} for {@link HealthEndpoint}. * {@link EnableAutoConfiguration Auto-configuration} for {@link HealthEndpoint}.
@ -34,14 +32,11 @@ import org.springframework.context.annotation.Configuration;
* @since 2.0.0 * @since 2.0.0
*/ */
@Configuration @Configuration
@EnableConfigurationProperties(HealthEndpointProperties.class) @EnableConfigurationProperties({ HealthEndpointProperties.class,
HealthIndicatorProperties.class })
@AutoConfigureAfter(HealthIndicatorAutoConfiguration.class)
@Import({ HealthEndpointConfiguration.class,
HealthEndpointWebExtensionConfiguration.class })
public class HealthEndpointAutoConfiguration { public class HealthEndpointAutoConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnEnabledEndpoint
public HealthEndpoint healthEndpoint(ApplicationContext applicationContext) {
return new HealthEndpoint(HealthIndicatorBeansComposite.get(applicationContext));
}
} }

@ -0,0 +1,42 @@
/*
* Copyright 2012-2017 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.actuate.autoconfigure.health;
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnEnabledEndpoint;
import org.springframework.boot.actuate.health.HealthEndpoint;
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
*/
@Configuration
class HealthEndpointConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnEnabledEndpoint
public HealthEndpoint healthEndpoint(ApplicationContext applicationContext) {
return new HealthEndpoint(HealthIndicatorBeansComposite.get(
applicationContext));
}
}

@ -21,7 +21,6 @@ import java.util.Map;
import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnEnabledEndpoint; import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnEnabledEndpoint;
import org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguration;
import org.springframework.boot.actuate.health.CompositeReactiveHealthIndicatorFactory; import org.springframework.boot.actuate.health.CompositeReactiveHealthIndicatorFactory;
import org.springframework.boot.actuate.health.HealthAggregator; import org.springframework.boot.actuate.health.HealthAggregator;
import org.springframework.boot.actuate.health.HealthEndpoint; import org.springframework.boot.actuate.health.HealthEndpoint;
@ -41,14 +40,13 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
/** /**
* {@link ManagementContextConfiguration} for health endpoints. * Configuration for health endpoint web extensions.
* *
* @author Stephane Nicoll * @author Stephane Nicoll
* @since 2.0.0
*/ */
@ManagementContextConfiguration @Configuration
@EnableConfigurationProperties(HealthIndicatorProperties.class) @EnableConfigurationProperties(HealthIndicatorProperties.class)
public class HealthWebEndpointManagementContextConfiguration { class HealthEndpointWebExtensionConfiguration {
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean

@ -50,7 +50,6 @@ org.springframework.boot.actuate.autoconfigure.web.ManagementContextConfiguratio
org.springframework.boot.actuate.autoconfigure.endpoint.web.reactive.WebFluxEndpointManagementContextConfiguration,\ org.springframework.boot.actuate.autoconfigure.endpoint.web.reactive.WebFluxEndpointManagementContextConfiguration,\
org.springframework.boot.actuate.autoconfigure.endpoint.web.servlet.WebMvcEndpointManagementContextConfiguration,\ org.springframework.boot.actuate.autoconfigure.endpoint.web.servlet.WebMvcEndpointManagementContextConfiguration,\
org.springframework.boot.actuate.autoconfigure.endpoint.web.jersey.JerseyWebEndpointManagementContextConfiguration,\ org.springframework.boot.actuate.autoconfigure.endpoint.web.jersey.JerseyWebEndpointManagementContextConfiguration,\
org.springframework.boot.actuate.autoconfigure.health.HealthWebEndpointManagementContextConfiguration,\
org.springframework.boot.actuate.autoconfigure.jolokia.JolokiaManagementContextConfiguration,\ org.springframework.boot.actuate.autoconfigure.jolokia.JolokiaManagementContextConfiguration,\
org.springframework.boot.actuate.autoconfigure.web.jersey.JerseyManagementChildContextConfiguration,\ org.springframework.boot.actuate.autoconfigure.web.jersey.JerseyManagementChildContextConfiguration,\
org.springframework.boot.actuate.autoconfigure.web.reactive.ReactiveManagementChildContextConfiguration,\ org.springframework.boot.actuate.autoconfigure.web.reactive.ReactiveManagementChildContextConfiguration,\

@ -29,7 +29,6 @@ import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryH
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.health.HealthWebEndpointManagementContextConfiguration;
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration;
import org.springframework.boot.actuate.endpoint.EndpointInfo; import org.springframework.boot.actuate.endpoint.EndpointInfo;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint; import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
@ -228,7 +227,6 @@ public class ReactiveCloudFoundryActuatorAutoConfigurationTests {
public void healthEndpointInvokerShouldBeCloudFoundryWebExtension() { public void healthEndpointInvokerShouldBeCloudFoundryWebExtension() {
setupContextWithCloudEnabled(); setupContextWithCloudEnabled();
this.context.register(HealthEndpointAutoConfiguration.class, this.context.register(HealthEndpointAutoConfiguration.class,
HealthWebEndpointManagementContextConfiguration.class,
CloudFoundryHealthWebEndpointManagementContextConfiguration.class); CloudFoundryHealthWebEndpointManagementContextConfiguration.class);
this.context.refresh(); this.context.refresh();
Collection<EndpointInfo<WebOperation>> endpoints = getHandlerMapping() Collection<EndpointInfo<WebOperation>> endpoints = getHandlerMapping()

@ -28,7 +28,6 @@ import org.springframework.boot.actuate.autoconfigure.cloudfoundry.CloudFoundryH
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.health.HealthWebEndpointManagementContextConfiguration;
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration;
import org.springframework.boot.actuate.endpoint.EndpointInfo; import org.springframework.boot.actuate.endpoint.EndpointInfo;
@ -250,7 +249,6 @@ public class CloudFoundryActuatorAutoConfigurationTests {
"vcap.application.cf_api:http://my-cloud-controller.com") "vcap.application.cf_api:http://my-cloud-controller.com")
.applyTo(this.context); .applyTo(this.context);
this.context.register(HealthEndpointAutoConfiguration.class, this.context.register(HealthEndpointAutoConfiguration.class,
HealthWebEndpointManagementContextConfiguration.class,
CloudFoundryHealthWebEndpointManagementContextConfiguration.class); CloudFoundryHealthWebEndpointManagementContextConfiguration.class);
this.context.refresh(); this.context.refresh();
Collection<EndpointInfo<WebOperation>> endpoints = this.context Collection<EndpointInfo<WebOperation>> endpoints = this.context

@ -20,27 +20,28 @@ import java.util.Map;
import org.junit.Test; import org.junit.Test;
import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
import org.springframework.boot.actuate.health.HealthEndpointWebExtension; import org.springframework.boot.actuate.health.HealthEndpointWebExtension;
import org.springframework.boot.actuate.health.HealthStatusHttpMapper; import org.springframework.boot.actuate.health.HealthStatusHttpMapper;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
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;
/** /**
* Tests for {@link HealthWebEndpointManagementContextConfiguration} in a servlet * Tests for {@link EndpointAutoConfiguration} in a servlet environment.
* environment.
* *
* @author Andy Wilkinson * @author Andy Wilkinson
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Phillip Webb * @author Phillip Webb
*/ */
public class HealthWebEndpointServletManagementContextConfigurationTests { public class HealthEndpointWebExtensionTests {
private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() private WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()
.withUserConfiguration(HealthIndicatorAutoConfiguration.class, .withConfiguration(AutoConfigurations.of(
HealthEndpointAutoConfiguration.class, HealthIndicatorAutoConfiguration.class,
HealthWebEndpointManagementContextConfiguration.class); HealthEndpointAutoConfiguration.class));
@Test @Test
public void runShouldCreateExtensionBeans() { public void runShouldCreateExtensionBeans() {

@ -35,19 +35,17 @@ import org.springframework.test.util.ReflectionTestUtils;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
/** /**
* Tests for {@link HealthWebEndpointManagementContextConfiguration} in a reactive * Tests for {@link HealthEndpointAutoConfiguration} in a reactive environment.
* environment.
* *
* @author Andy Wilkinson * @author Andy Wilkinson
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Phillip Webb * @author Phillip Webb
*/ */
public class HealthWebEndpointReactiveManagementContextConfigurationTests { public class ReactiveHealthEndpointWebExtensionTests {
private ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner() private ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner()
.withUserConfiguration(HealthIndicatorAutoConfiguration.class, .withUserConfiguration(HealthIndicatorAutoConfiguration.class,
HealthEndpointAutoConfiguration.class, HealthEndpointAutoConfiguration.class);
HealthWebEndpointManagementContextConfiguration.class);
@Test @Test
public void runShouldCreateExtensionBeans() { public void runShouldCreateExtensionBeans() {

@ -0,0 +1,31 @@
/*
* Copyright 2012-2017 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.actuator;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;
@Component
public class ExampleHealthIndicator implements HealthIndicator {
@Override
public Health health() {
return Health.up().withDetail("counter", 42).build();
}
}

@ -75,7 +75,7 @@ public class ManagementPortAndPathSampleActuatorApplicationTests {
.getForEntity("http://localhost:" + this.managementPort + "/admin/health", .getForEntity("http://localhost:" + this.managementPort + "/admin/health",
String.class); String.class);
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(entity.getBody()).contains("\"status\":\"UP\""); assertThat(entity.getBody()).isEqualTo("{\"status\":\"UP\"}");
} }
@Test @Test

@ -39,7 +39,7 @@ import static org.assertj.core.api.Assertions.assertThat;
*/ */
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = { @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = {
"management.server.port=0" }) "management.server.port=0", "management.endpoint.health.show-details=true" })
public class ManagementPortSampleActuatorApplicationTests { public class ManagementPortSampleActuatorApplicationTests {
@LocalServerPort @LocalServerPort
@ -77,6 +77,8 @@ public class ManagementPortSampleActuatorApplicationTests {
String.class); String.class);
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(entity.getBody()).contains("\"status\":\"UP\""); assertThat(entity.getBody()).contains("\"status\":\"UP\"");
assertThat(entity.getBody()).contains("\"example\"");
assertThat(entity.getBody()).contains("\"counter\":42");
} }
@Test @Test

Loading…
Cancel
Save