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
This commit is contained in:
Stephane Nicoll 2017-12-13 17:47:18 +01:00
parent 1fdc1e373c
commit 681fdb1ee8
11 changed files with 97 additions and 35 deletions

View File

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

View File

@ -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));
}
}

View File

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

View File

@ -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.servlet.WebMvcEndpointManagementContextConfiguration,\
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.web.jersey.JerseyManagementChildContextConfiguration,\
org.springframework.boot.actuate.autoconfigure.web.reactive.ReactiveManagementChildContextConfiguration,\

View File

@ -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.web.WebEndpointAutoConfiguration;
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.endpoint.EndpointInfo;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
@ -228,7 +227,6 @@ public class ReactiveCloudFoundryActuatorAutoConfigurationTests {
public void healthEndpointInvokerShouldBeCloudFoundryWebExtension() {
setupContextWithCloudEnabled();
this.context.register(HealthEndpointAutoConfiguration.class,
HealthWebEndpointManagementContextConfiguration.class,
CloudFoundryHealthWebEndpointManagementContextConfiguration.class);
this.context.refresh();
Collection<EndpointInfo<WebOperation>> endpoints = getHandlerMapping()

View File

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

View File

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

View File

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

View File

@ -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();
}
}

View File

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

View File

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