Drop status endpoint

Drop the status endpoint and merge functionality back into the health
endpoint. The `management.endpoint.health.show-details` property can
be used to change if full details, or just the status is displayed.

Fixes gh-11113
pull/11128/head
Phillip Webb 7 years ago
parent d99625fa78
commit 31025d9f6c

@ -66,5 +66,4 @@ include::endpoints/prometheus.adoc[leveloffset=+1]
include::endpoints/scheduledtasks.adoc[leveloffset=+1] include::endpoints/scheduledtasks.adoc[leveloffset=+1]
include::endpoints/sessions.adoc[leveloffset=+1] include::endpoints/sessions.adoc[leveloffset=+1]
include::endpoints/shutdown.adoc[leveloffset=+1] include::endpoints/shutdown.adoc[leveloffset=+1]
include::endpoints/status.adoc[leveloffset=+1]
include::endpoints/threaddump.adoc[leveloffset=+1] include::endpoints/threaddump.adoc[leveloffset=+1]

@ -105,7 +105,7 @@ public class WebEndpointAutoConfiguration {
public ExposeExcludePropertyEndpointFilter<WebOperation> webIncludeExcludePropertyEndpointFilter() { public ExposeExcludePropertyEndpointFilter<WebOperation> webIncludeExcludePropertyEndpointFilter() {
return new ExposeExcludePropertyEndpointFilter<>( return new ExposeExcludePropertyEndpointFilter<>(
WebAnnotationEndpointDiscoverer.class, this.properties.getExpose(), WebAnnotationEndpointDiscoverer.class, this.properties.getExpose(),
this.properties.getExclude(), "info", "status"); this.properties.getExclude(), "info", "health");
} }
} }

@ -27,9 +27,9 @@ import org.springframework.boot.actuate.health.HealthEndpoint;
import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.actuate.health.OrderedHealthAggregator; import org.springframework.boot.actuate.health.OrderedHealthAggregator;
import org.springframework.boot.actuate.health.ReactiveHealthIndicator; import org.springframework.boot.actuate.health.ReactiveHealthIndicator;
import org.springframework.boot.actuate.health.StatusEndpoint;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -44,6 +44,7 @@ import org.springframework.util.ClassUtils;
* @since 2.0.0 * @since 2.0.0
*/ */
@Configuration @Configuration
@EnableConfigurationProperties(HealthEndpointProperties.class)
public class HealthEndpointAutoConfiguration { public class HealthEndpointAutoConfiguration {
private final HealthIndicator healthIndicator; private final HealthIndicator healthIndicator;
@ -69,15 +70,8 @@ public class HealthEndpointAutoConfiguration {
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
@ConditionalOnEnabledEndpoint @ConditionalOnEnabledEndpoint
public HealthEndpoint healthEndpoint() { public HealthEndpoint healthEndpoint(HealthEndpointProperties properties) {
return new HealthEndpoint(this.healthIndicator); return new HealthEndpoint(this.healthIndicator, properties.isShowDetails());
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnEnabledEndpoint
public StatusEndpoint statusEndpoint() {
return new StatusEndpoint(this.healthIndicator);
} }
private static class ReactiveHealthIndicators { private static class ReactiveHealthIndicators {

@ -0,0 +1,43 @@
/*
* 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.health.HealthEndpoint;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* Configuration properties for {@link HealthEndpoint}.
*
* @author Phillip Webb
*/
@ConfigurationProperties("management.endpoint.health")
public class HealthEndpointProperties {
/**
* Whether to show full health details instead of just the status.
*/
private boolean showDetails;
public boolean isShowDetails() {
return this.showDetails;
}
public void setShowDetails(boolean showDetails) {
this.showDetails = showDetails;
}
}

@ -31,9 +31,6 @@ import org.springframework.boot.actuate.health.HealthStatusHttpMapper;
import org.springframework.boot.actuate.health.OrderedHealthAggregator; import org.springframework.boot.actuate.health.OrderedHealthAggregator;
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.actuate.health.ReactiveHealthIndicator;
import org.springframework.boot.actuate.health.ReactiveStatusEndpointWebExtension;
import org.springframework.boot.actuate.health.StatusEndpoint;
import org.springframework.boot.actuate.health.StatusEndpointWebExtension;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
@ -85,19 +82,10 @@ public class HealthWebEndpointManagementContextConfiguration {
@ConditionalOnEnabledEndpoint @ConditionalOnEnabledEndpoint
@ConditionalOnBean(HealthEndpoint.class) @ConditionalOnBean(HealthEndpoint.class)
public ReactiveHealthEndpointWebExtension reactiveHealthEndpointWebExtension( public ReactiveHealthEndpointWebExtension reactiveHealthEndpointWebExtension(
HealthStatusHttpMapper healthStatusHttpMapper) { HealthStatusHttpMapper healthStatusHttpMapper,
HealthEndpointProperties properties) {
return new ReactiveHealthEndpointWebExtension(this.reactiveHealthIndicator, return new ReactiveHealthEndpointWebExtension(this.reactiveHealthIndicator,
healthStatusHttpMapper); healthStatusHttpMapper, properties.isShowDetails());
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnEnabledEndpoint
@ConditionalOnBean(StatusEndpoint.class)
public ReactiveStatusEndpointWebExtension reactiveStatusEndpointWebExtension(
HealthStatusHttpMapper healthStatusHttpMapper) {
return new ReactiveStatusEndpointWebExtension(this.reactiveHealthIndicator,
healthStatusHttpMapper);
} }
} }
@ -115,15 +103,6 @@ public class HealthWebEndpointManagementContextConfiguration {
return new HealthEndpointWebExtension(delegate, healthStatusHttpMapper); return new HealthEndpointWebExtension(delegate, healthStatusHttpMapper);
} }
@Bean
@ConditionalOnMissingBean
@ConditionalOnEnabledEndpoint
@ConditionalOnBean(StatusEndpoint.class)
public StatusEndpointWebExtension statusEndpointWebExtension(
StatusEndpoint delegate, HealthStatusHttpMapper healthStatusHttpMapper) {
return new StatusEndpointWebExtension(delegate, healthStatusHttpMapper);
}
} }
} }

@ -57,7 +57,8 @@ public class HealthEndpointDocumentationTests extends AbstractEndpointDocumentat
fieldWithPath("status").description( fieldWithPath("status").description(
"Overall status of the application."), "Overall status of the application."),
fieldWithPath("details") fieldWithPath("details")
.description("Details of the health of the application."), .description("Details of the health of the application "
+ "(only included when `management.endpoint.health.show-details` is `true`)."),
fieldWithPath("details.*.status").description( fieldWithPath("details.*.status").description(
"Status of a specific part of the application."), "Status of a specific part of the application."),
subsectionWithPath("details.*.details").description( subsectionWithPath("details.*.details").description(
@ -73,7 +74,7 @@ public class HealthEndpointDocumentationTests extends AbstractEndpointDocumentat
@Bean @Bean
public HealthEndpoint endpoint(Map<String, HealthIndicator> healthIndicators) { public HealthEndpoint endpoint(Map<String, HealthIndicator> healthIndicators) {
return new HealthEndpoint(new CompositeHealthIndicator( return new HealthEndpoint(new CompositeHealthIndicator(
new OrderedHealthAggregator(), healthIndicators)); new OrderedHealthAggregator(), healthIndicators), true);
} }
@Bean @Bean

@ -1,82 +0,0 @@
/*
* 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.endpoint.web.documentation;
import java.io.File;
import java.util.Map;
import javax.sql.DataSource;
import org.junit.Test;
import org.springframework.boot.actuate.health.CompositeHealthIndicator;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.actuate.health.OrderedHealthAggregator;
import org.springframework.boot.actuate.health.StatusEndpoint;
import org.springframework.boot.actuate.jdbc.DataSourceHealthIndicator;
import org.springframework.boot.actuate.system.DiskSpaceHealthIndicator;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for generating documentation describing the {@link StatusEndpoint}.
*
* @author Andy Wilkinson
*/
public class StatusEndpointDocumentationTests extends AbstractEndpointDocumentationTests {
@Test
public void health() throws Exception {
this.mockMvc.perform(get("/application/status")).andExpect(status().isOk())
.andDo(document("status", responseFields(fieldWithPath("status")
.description("Overall status of the application."))));
}
@Configuration
@Import(BaseDocumentationConfiguration.class)
@ImportAutoConfiguration(DataSourceAutoConfiguration.class)
static class TestConfiguration {
@Bean
public StatusEndpoint endpoint(Map<String, HealthIndicator> healthIndicators) {
return new StatusEndpoint(new CompositeHealthIndicator(
new OrderedHealthAggregator(), healthIndicators));
}
@Bean
public DiskSpaceHealthIndicator diskSpaceHealthIndicator() {
return new DiskSpaceHealthIndicator(new File("."), 1024 * 1024 * 10);
}
@Bean
public DataSourceHealthIndicator dataSourceHealthIndicator(
DataSource dataSource) {
return new DataSourceHealthIndicator(dataSource);
}
}
}

@ -24,7 +24,6 @@ import org.springframework.boot.actuate.health.HealthEndpoint;
import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.actuate.health.ReactiveHealthIndicator; import org.springframework.boot.actuate.health.ReactiveHealthIndicator;
import org.springframework.boot.actuate.health.Status; import org.springframework.boot.actuate.health.Status;
import org.springframework.boot.actuate.health.StatusEndpoint;
import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
@ -48,9 +47,25 @@ public class HealthEndpointAutoConfigurationTests {
.withConfiguration( .withConfiguration(
AutoConfigurations.of(HealthEndpointAutoConfiguration.class)); AutoConfigurations.of(HealthEndpointAutoConfiguration.class));
@Test
public void healthEndpointShowDetailsDefault() {
this.contextRunner
.withUserConfiguration(ReactiveHealthIndicatorConfiguration.class)
.run((context) -> {
ReactiveHealthIndicator indicator = context.getBean(
"reactiveHealthIndicator", ReactiveHealthIndicator.class);
verify(indicator, times(0)).health();
Health health = context.getBean(HealthEndpoint.class).health();
assertThat(health.getStatus()).isEqualTo(Status.UP);
assertThat(health.getDetails()).isEmpty();
verify(indicator, times(1)).health();
});
}
@Test @Test
public void healthEndpointAdaptReactiveHealthIndicator() { public void healthEndpointAdaptReactiveHealthIndicator() {
this.contextRunner this.contextRunner
.withPropertyValues("management.endpoint.health.show-details=true")
.withUserConfiguration(ReactiveHealthIndicatorConfiguration.class) .withUserConfiguration(ReactiveHealthIndicatorConfiguration.class)
.run((context) -> { .run((context) -> {
ReactiveHealthIndicator indicator = context.getBean( ReactiveHealthIndicator indicator = context.getBean(
@ -65,8 +80,11 @@ public class HealthEndpointAutoConfigurationTests {
@Test @Test
public void healthEndpointMergeRegularAndReactive() { public void healthEndpointMergeRegularAndReactive() {
this.contextRunner.withUserConfiguration(HealthIndicatorConfiguration.class, this.contextRunner
ReactiveHealthIndicatorConfiguration.class).run((context) -> { .withPropertyValues("management.endpoint.health.show-details=true")
.withUserConfiguration(HealthIndicatorConfiguration.class,
ReactiveHealthIndicatorConfiguration.class)
.run((context) -> {
HealthIndicator indicator = context.getBean("simpleHealthIndicator", HealthIndicator indicator = context.getBean("simpleHealthIndicator",
HealthIndicator.class); HealthIndicator.class);
ReactiveHealthIndicator reactiveHealthIndicator = context.getBean( ReactiveHealthIndicator reactiveHealthIndicator = context.getBean(
@ -82,22 +100,6 @@ public class HealthEndpointAutoConfigurationTests {
}); });
} }
@Test
public void runShouldHaveStatusEndpointBeanEvenIfDefaultIsDisabled() {
// FIXME
this.contextRunner.withPropertyValues("management.endpoint.default.enabled:false")
.run((context) -> assertThat(context)
.hasSingleBean(StatusEndpoint.class));
}
@Test
public void runWhenEnabledPropertyIsFalseShouldNotHaveStatusEndpointBean()
throws Exception {
this.contextRunner.withPropertyValues("management.endpoint.status.enabled:false")
.run((context) -> assertThat(context)
.doesNotHaveBean(StatusEndpoint.class));
}
@Configuration @Configuration
static class HealthIndicatorConfiguration { static class HealthIndicatorConfiguration {

@ -22,7 +22,6 @@ import org.junit.Test;
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.ReactiveStatusEndpointWebExtension;
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
import org.springframework.test.util.ReflectionTestUtils; import org.springframework.test.util.ReflectionTestUtils;
@ -46,7 +45,6 @@ public class HealthWebEndpointReactiveManagementContextConfigurationTests {
@Test @Test
public void runShouldCreateExtensionBeans() throws Exception { public void runShouldCreateExtensionBeans() throws Exception {
this.contextRunner.run((context) -> assertThat(context) this.contextRunner.run((context) -> assertThat(context)
.hasSingleBean(ReactiveStatusEndpointWebExtension.class)
.hasSingleBean(ReactiveHealthEndpointWebExtension.class)); .hasSingleBean(ReactiveHealthEndpointWebExtension.class));
} }
@ -58,19 +56,10 @@ public class HealthWebEndpointReactiveManagementContextConfigurationTests {
.doesNotHaveBean(ReactiveHealthEndpointWebExtension.class)); .doesNotHaveBean(ReactiveHealthEndpointWebExtension.class));
} }
@Test
public void runWhenStatusEndpointIsDisabledShouldNotCreateExtensionBeans()
throws Exception {
this.contextRunner.withPropertyValues("management.endpoint.status.enabled:false")
.run((context) -> assertThat(context)
.doesNotHaveBean(ReactiveStatusEndpointWebExtension.class));
}
@Test @Test
public void runWithCustomHealthMappingShouldMapStatusCode() throws Exception { public void runWithCustomHealthMappingShouldMapStatusCode() throws Exception {
this.contextRunner this.contextRunner
.withPropertyValues( .withPropertyValues("management.health.status.http-mapping.CUSTOM=500")
"management.health.status.http-mapping.CUSTOM=500")
.run((context) -> { .run((context) -> {
Object extension = context Object extension = context
.getBean(ReactiveHealthEndpointWebExtension.class); .getBean(ReactiveHealthEndpointWebExtension.class);
@ -83,21 +72,4 @@ public class HealthWebEndpointReactiveManagementContextConfigurationTests {
}); });
} }
@Test
public void runWithCustomStatusMappingShouldMapStatusCode() throws Exception {
this.contextRunner
.withPropertyValues(
"management.health.status.http-mapping.CUSTOM=500")
.run((context) -> {
Object extension = context
.getBean(ReactiveStatusEndpointWebExtension.class);
HealthStatusHttpMapper mapper = (HealthStatusHttpMapper) ReflectionTestUtils
.getField(extension, "statusHttpMapper");
Map<String, Integer> statusMappings = mapper.getStatusMapping();
assertThat(statusMappings).containsEntry("DOWN", 503);
assertThat(statusMappings).containsEntry("OUT_OF_SERVICE", 503);
assertThat(statusMappings).containsEntry("CUSTOM", 500);
});
}
} }

@ -22,7 +22,6 @@ import org.junit.Test;
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.actuate.health.StatusEndpointWebExtension;
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;
@ -46,7 +45,6 @@ public class HealthWebEndpointServletManagementContextConfigurationTests {
@Test @Test
public void runShouldCreateExtensionBeans() throws Exception { public void runShouldCreateExtensionBeans() throws Exception {
this.contextRunner.run((context) -> assertThat(context) this.contextRunner.run((context) -> assertThat(context)
.hasSingleBean(StatusEndpointWebExtension.class)
.hasSingleBean(HealthEndpointWebExtension.class)); .hasSingleBean(HealthEndpointWebExtension.class));
} }
@ -58,14 +56,6 @@ public class HealthWebEndpointServletManagementContextConfigurationTests {
.doesNotHaveBean(HealthEndpointWebExtension.class)); .doesNotHaveBean(HealthEndpointWebExtension.class));
} }
@Test
public void runWhenStatusEndpointIsDisabledShouldNotCreateExtensionBeans()
throws Exception {
this.contextRunner.withPropertyValues("management.endpoint.status.enabled:false")
.run((context) -> assertThat(context)
.doesNotHaveBean(StatusEndpointWebExtension.class));
}
@Test @Test
public void runWithCustomHealthMappingShouldMapStatusCode() throws Exception { public void runWithCustomHealthMappingShouldMapStatusCode() throws Exception {
this.contextRunner this.contextRunner
@ -81,19 +71,4 @@ public class HealthWebEndpointServletManagementContextConfigurationTests {
}); });
} }
@Test
public void runWithCustomStatusMappingShouldMapStatusCode() throws Exception {
this.contextRunner
.withPropertyValues("management.health.status.http-mapping.CUSTOM=500")
.run((context) -> {
Object extension = context.getBean(StatusEndpointWebExtension.class);
HealthStatusHttpMapper mapper = (HealthStatusHttpMapper) ReflectionTestUtils
.getField(extension, "statusHttpMapper");
Map<String, Integer> statusMappings = mapper.getStatusMapping();
assertThat(statusMappings).containsEntry("DOWN", 503);
assertThat(statusMappings).containsEntry("OUT_OF_SERVICE", 503);
assertThat(statusMappings).containsEntry("CUSTOM", 500);
});
}
} }

@ -55,7 +55,7 @@ public class JmxEndpointIntegrationTests {
MBeanServer mBeanServer = context.getBean(MBeanServer.class); MBeanServer mBeanServer = context.getBean(MBeanServer.class);
checkEndpointMBeans(mBeanServer, checkEndpointMBeans(mBeanServer,
new String[] { "beans", "conditions", "configprops", "env", "health", new String[] { "beans", "conditions", "configprops", "env", "health",
"info", "mappings", "status", "threaddump", "trace" }, "info", "mappings", "threaddump", "trace" },
new String[] { "shutdown" }); new String[] { "shutdown" });
}); });
} }

@ -21,8 +21,6 @@ import org.junit.Test;
import org.springframework.boot.SpringBootConfiguration; import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.actuate.health.HealthEndpointWebExtension; import org.springframework.boot.actuate.health.HealthEndpointWebExtension;
import org.springframework.boot.actuate.health.ReactiveHealthEndpointWebExtension; import org.springframework.boot.actuate.health.ReactiveHealthEndpointWebExtension;
import org.springframework.boot.actuate.health.ReactiveStatusEndpointWebExtension;
import org.springframework.boot.actuate.health.StatusEndpointWebExtension;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration; import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration;
import org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration; import org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration;
@ -62,24 +60,12 @@ public class WebEndpointsAutoConfigurationIntegrationTests {
.hasSingleBean(HealthEndpointWebExtension.class)); .hasSingleBean(HealthEndpointWebExtension.class));
} }
@Test
public void statusEndpointWebExtensionIsAutoConfigured() {
servletWebRunner().run((context) -> assertThat(context)
.hasSingleBean(StatusEndpointWebExtension.class));
}
@Test @Test
public void healthEndpointReactiveWebExtensionIsAutoConfigured() { public void healthEndpointReactiveWebExtensionIsAutoConfigured() {
reactiveWebRunner().run((context) -> assertThat(context) reactiveWebRunner().run((context) -> assertThat(context)
.hasSingleBean(ReactiveHealthEndpointWebExtension.class)); .hasSingleBean(ReactiveHealthEndpointWebExtension.class));
} }
@Test
public void statusEndpointReactiveWebExtensionIsAutoConfigured() {
reactiveWebRunner().run((context) -> assertThat(context)
.hasSingleBean(ReactiveStatusEndpointWebExtension.class));
}
private WebApplicationContextRunner servletWebRunner() { private WebApplicationContextRunner servletWebRunner() {
return new WebApplicationContextRunner() return new WebApplicationContextRunner()
.withConfiguration( .withConfiguration(

@ -69,11 +69,10 @@ public class WebMvcEndpointExposureIntegrationTests {
assertThat(isExposed(mvc, HttpMethod.GET, "conditions")).isFalse(); assertThat(isExposed(mvc, HttpMethod.GET, "conditions")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "configprops")).isFalse(); assertThat(isExposed(mvc, HttpMethod.GET, "configprops")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "env")).isFalse(); assertThat(isExposed(mvc, HttpMethod.GET, "env")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "health")).isFalse(); assertThat(isExposed(mvc, HttpMethod.GET, "health")).isTrue();
assertThat(isExposed(mvc, HttpMethod.GET, "info")).isTrue(); assertThat(isExposed(mvc, HttpMethod.GET, "info")).isTrue();
assertThat(isExposed(mvc, HttpMethod.GET, "mappings")).isFalse(); assertThat(isExposed(mvc, HttpMethod.GET, "mappings")).isFalse();
assertThat(isExposed(mvc, HttpMethod.POST, "shutdown")).isFalse(); assertThat(isExposed(mvc, HttpMethod.POST, "shutdown")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "status")).isTrue();
assertThat(isExposed(mvc, HttpMethod.GET, "threaddump")).isFalse(); assertThat(isExposed(mvc, HttpMethod.GET, "threaddump")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "trace")).isFalse(); assertThat(isExposed(mvc, HttpMethod.GET, "trace")).isFalse();
}); });
@ -93,7 +92,6 @@ public class WebMvcEndpointExposureIntegrationTests {
assertThat(isExposed(mvc, HttpMethod.GET, "info")).isTrue(); assertThat(isExposed(mvc, HttpMethod.GET, "info")).isTrue();
assertThat(isExposed(mvc, HttpMethod.GET, "mappings")).isTrue(); assertThat(isExposed(mvc, HttpMethod.GET, "mappings")).isTrue();
assertThat(isExposed(mvc, HttpMethod.POST, "shutdown")).isFalse(); assertThat(isExposed(mvc, HttpMethod.POST, "shutdown")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "status")).isTrue();
assertThat(isExposed(mvc, HttpMethod.GET, "threaddump")).isTrue(); assertThat(isExposed(mvc, HttpMethod.GET, "threaddump")).isTrue();
assertThat(isExposed(mvc, HttpMethod.GET, "trace")).isTrue(); assertThat(isExposed(mvc, HttpMethod.GET, "trace")).isTrue();
}); });
@ -113,7 +111,6 @@ public class WebMvcEndpointExposureIntegrationTests {
assertThat(isExposed(mvc, HttpMethod.GET, "info")).isFalse(); assertThat(isExposed(mvc, HttpMethod.GET, "info")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "mappings")).isFalse(); assertThat(isExposed(mvc, HttpMethod.GET, "mappings")).isFalse();
assertThat(isExposed(mvc, HttpMethod.POST, "shutdown")).isFalse(); assertThat(isExposed(mvc, HttpMethod.POST, "shutdown")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "status")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "threaddump")).isFalse(); assertThat(isExposed(mvc, HttpMethod.GET, "threaddump")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "trace")).isFalse(); assertThat(isExposed(mvc, HttpMethod.GET, "trace")).isFalse();
}); });
@ -134,7 +131,6 @@ public class WebMvcEndpointExposureIntegrationTests {
assertThat(isExposed(mvc, HttpMethod.GET, "info")).isTrue(); assertThat(isExposed(mvc, HttpMethod.GET, "info")).isTrue();
assertThat(isExposed(mvc, HttpMethod.GET, "mappings")).isTrue(); assertThat(isExposed(mvc, HttpMethod.GET, "mappings")).isTrue();
assertThat(isExposed(mvc, HttpMethod.POST, "shutdown")).isFalse(); assertThat(isExposed(mvc, HttpMethod.POST, "shutdown")).isFalse();
assertThat(isExposed(mvc, HttpMethod.GET, "status")).isTrue();
assertThat(isExposed(mvc, HttpMethod.GET, "threaddump")).isTrue(); assertThat(isExposed(mvc, HttpMethod.GET, "threaddump")).isTrue();
assertThat(isExposed(mvc, HttpMethod.GET, "trace")).isTrue(); assertThat(isExposed(mvc, HttpMethod.GET, "trace")).isTrue();
}); });

@ -20,7 +20,7 @@ import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
/** /**
* {@link Endpoint} to expose application health. * {@link Endpoint} to expose application health information.
* *
* @author Dave Syer * @author Dave Syer
* @author Christian Dupuis * @author Christian Dupuis
@ -32,17 +32,25 @@ public class HealthEndpoint {
private final HealthIndicator healthIndicator; private final HealthIndicator healthIndicator;
private final boolean showDetails;
/** /**
* Create a new {@link HealthEndpoint} instance. * Create a new {@link HealthEndpoint} instance.
* @param healthIndicator the health indicator * @param healthIndicator the health indicator
* @param showDetails if full details should be returned instead of just the status
*/ */
public HealthEndpoint(HealthIndicator healthIndicator) { public HealthEndpoint(HealthIndicator healthIndicator, boolean showDetails) {
this.healthIndicator = healthIndicator; this.healthIndicator = healthIndicator;
this.showDetails = showDetails;
} }
@ReadOperation @ReadOperation
public Health health() { public Health health() {
return this.healthIndicator.health(); Health health = this.healthIndicator.health();
if (this.showDetails) {
return health;
}
return Health.status(health.getStatus()).build();
} }
} }

@ -35,16 +35,22 @@ public class ReactiveHealthEndpointWebExtension {
private final HealthStatusHttpMapper statusHttpMapper; private final HealthStatusHttpMapper statusHttpMapper;
private final boolean showDetails;
public ReactiveHealthEndpointWebExtension(ReactiveHealthIndicator delegate, public ReactiveHealthEndpointWebExtension(ReactiveHealthIndicator delegate,
HealthStatusHttpMapper statusHttpMapper) { HealthStatusHttpMapper statusHttpMapper, boolean showDetails) {
this.delegate = delegate; this.delegate = delegate;
this.statusHttpMapper = statusHttpMapper; this.statusHttpMapper = statusHttpMapper;
this.showDetails = showDetails;
} }
@ReadOperation @ReadOperation
public Mono<WebEndpointResponse<Health>> health() { public Mono<WebEndpointResponse<Health>> health() {
return this.delegate.health().map((health) -> { return this.delegate.health().map((health) -> {
Integer status = this.statusHttpMapper.mapStatus(health.getStatus()); Integer status = this.statusHttpMapper.mapStatus(health.getStatus());
if (!this.showDetails) {
health = Health.status(health.getStatus()).build();
}
return new WebEndpointResponse<>(health, status); return new WebEndpointResponse<>(health, status);
}); });
} }

@ -1,53 +0,0 @@
/*
* 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.health;
import reactor.core.publisher.Mono;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse;
import org.springframework.boot.actuate.endpoint.web.annotation.EndpointWebExtension;
/**
* Reactive {@link EndpointWebExtension} for the {@link StatusEndpoint}.
*
* @author Stephane Nicoll
* @since 2.0.0
*/
@EndpointWebExtension(endpoint = StatusEndpoint.class)
public class ReactiveStatusEndpointWebExtension {
private final ReactiveHealthIndicator delegate;
private final HealthStatusHttpMapper statusHttpMapper;
public ReactiveStatusEndpointWebExtension(ReactiveHealthIndicator delegate,
HealthStatusHttpMapper statusHttpMapper) {
this.delegate = delegate;
this.statusHttpMapper = statusHttpMapper;
}
@ReadOperation
public Mono<WebEndpointResponse<Health>> health() {
return this.delegate.health().map((health) -> {
Integer status = this.statusHttpMapper.mapStatus(health.getStatus());
return new WebEndpointResponse<>(Health.status(health.getStatus()).build(),
status);
});
}
}

@ -1,46 +0,0 @@
/*
* 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.health;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
/**
* {@link Endpoint} to expose application {@link Status}.
*
* @author Stephane Nicoll
* @since 2.0.0
*/
@Endpoint(id = "status")
public class StatusEndpoint {
private final HealthIndicator healthIndicator;
/**
* Create a new {@link StatusEndpoint} instance.
* @param healthIndicator the health indicator
*/
public StatusEndpoint(HealthIndicator healthIndicator) {
this.healthIndicator = healthIndicator;
}
@ReadOperation
public Health health() {
return Health.status(this.healthIndicator.health().getStatus()).build();
}
}

@ -1,49 +0,0 @@
/*
* 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.health;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse;
import org.springframework.boot.actuate.endpoint.web.annotation.EndpointWebExtension;
/**
* {@link EndpointWebExtension} for the {@link StatusEndpoint}.
*
* @author Stephane Nicoll
* @since 2.0.0
*/
@EndpointWebExtension(endpoint = StatusEndpoint.class)
public class StatusEndpointWebExtension {
private final StatusEndpoint delegate;
private final HealthStatusHttpMapper statusHttpMapper;
public StatusEndpointWebExtension(StatusEndpoint delegate,
HealthStatusHttpMapper statusHttpMapper) {
this.delegate = delegate;
this.statusHttpMapper = statusHttpMapper;
}
@ReadOperation
public WebEndpointResponse<Health> getHealth() {
Health health = this.delegate.health();
Integer status = this.statusHttpMapper.mapStatus(health.getStatus());
return new WebEndpointResponse<>(health, status);
}
}

@ -41,7 +41,7 @@ public class HealthEndpointTests {
healthIndicators.put("upAgain", () -> new Health.Builder().status(Status.UP) healthIndicators.put("upAgain", () -> new Health.Builder().status(Status.UP)
.withDetail("second", "2").build()); .withDetail("second", "2").build());
HealthEndpoint endpoint = new HealthEndpoint( HealthEndpoint endpoint = new HealthEndpoint(
createHealthIndicator(healthIndicators)); createHealthIndicator(healthIndicators), true);
Health health = endpoint.health(); Health health = endpoint.health();
assertThat(health.getStatus()).isEqualTo(Status.UP); assertThat(health.getStatus()).isEqualTo(Status.UP);
assertThat(health.getDetails()).containsOnlyKeys("up", "upAgain"); assertThat(health.getDetails()).containsOnlyKeys("up", "upAgain");
@ -51,6 +51,20 @@ public class HealthEndpointTests {
assertThat(upAgainHealth.getDetails()).containsOnly(entry("second", "2")); assertThat(upAgainHealth.getDetails()).containsOnly(entry("second", "2"));
} }
@Test
public void onlyStatusIsExposed() {
Map<String, HealthIndicator> healthIndicators = new HashMap<>();
healthIndicators.put("up", () -> new Health.Builder().status(Status.UP)
.withDetail("first", "1").build());
healthIndicators.put("upAgain", () -> new Health.Builder().status(Status.UP)
.withDetail("second", "2").build());
HealthEndpoint endpoint = new HealthEndpoint(
createHealthIndicator(healthIndicators), false);
Health health = endpoint.health();
assertThat(health.getStatus()).isEqualTo(Status.UP);
assertThat(health.getDetails()).isEmpty();
}
private HealthIndicator createHealthIndicator( private HealthIndicator createHealthIndicator(
Map<String, HealthIndicator> healthIndicators) { Map<String, HealthIndicator> healthIndicators) {
return new CompositeHealthIndicatorFactory() return new CompositeHealthIndicatorFactory()

@ -67,7 +67,8 @@ public class HealthEndpointWebIntegrationTests {
Map<String, HealthIndicator> healthIndicators) { Map<String, HealthIndicator> healthIndicators) {
return new HealthEndpoint( return new HealthEndpoint(
new CompositeHealthIndicatorFactory().createHealthIndicator( new CompositeHealthIndicatorFactory().createHealthIndicator(
new OrderedHealthAggregator(), healthIndicators)); new OrderedHealthAggregator(), healthIndicators),
true);
} }
@Bean @Bean

@ -1,53 +0,0 @@
/*
* 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.health;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link StatusEndpoint}.
*
* @author Stephane Nicoll
*/
public class StatusEndpointTests {
@Test
public void onlyStatusIsExposed() {
Map<String, HealthIndicator> healthIndicators = new HashMap<>();
healthIndicators.put("up", () -> new Health.Builder().status(Status.UP)
.withDetail("first", "1").build());
healthIndicators.put("upAgain", () -> new Health.Builder().status(Status.UP)
.withDetail("second", "2").build());
StatusEndpoint endpoint = new StatusEndpoint(
createHealthIndicator(healthIndicators));
Health health = endpoint.health();
assertThat(health.getStatus()).isEqualTo(Status.UP);
assertThat(health.getDetails()).isEmpty();
}
private HealthIndicator createHealthIndicator(
Map<String, HealthIndicator> healthIndicators) {
return new CompositeHealthIndicatorFactory()
.createHealthIndicator(new OrderedHealthAggregator(), healthIndicators);
}
}

@ -1,105 +0,0 @@
/*
* 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.health;
import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.actuate.endpoint.web.test.WebEndpointRunners;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.test.web.reactive.server.WebTestClient;
/**
* Integration tests for {@link StatusEndpoint} and {@link StatusEndpointWebExtension}
* exposed by Jersey, Spring MVC, and WebFlux.
*
* @author Stephane Nicoll
*/
@RunWith(WebEndpointRunners.class)
public class StatusEndpointWebIntegrationTests {
private static WebTestClient client;
private static ConfigurableApplicationContext context;
@Test
public void whenStatusIsUp200ResponseIsReturned() throws Exception {
client.get().uri("/application/status").exchange().expectStatus().isOk()
.expectBody().json("{\"status\":\"UP\"}");
}
@Test
public void whenStatusIsDown503ResponseIsReturned() throws Exception {
context.getBean("alphaHealthIndicator", TestHealthIndicator.class)
.setHealth(Health.down().build());
client.get().uri("/application/status").exchange().expectStatus()
.isEqualTo(HttpStatus.SERVICE_UNAVAILABLE).expectBody()
.json("{\"status\":\"DOWN\"}");
}
@Configuration
public static class TestConfiguration {
@Bean
public StatusEndpoint statusEndpoint(
Map<String, HealthIndicator> healthIndicators) {
return new StatusEndpoint(
new CompositeHealthIndicatorFactory().createHealthIndicator(
new OrderedHealthAggregator(), healthIndicators));
}
@Bean
public StatusEndpointWebExtension statusWebEndpointExtension(
StatusEndpoint delegate) {
return new StatusEndpointWebExtension(delegate, new HealthStatusHttpMapper());
}
@Bean
public TestHealthIndicator alphaHealthIndicator() {
return new TestHealthIndicator();
}
@Bean
public TestHealthIndicator bravoHealthIndicator() {
return new TestHealthIndicator();
}
}
private static class TestHealthIndicator implements HealthIndicator {
private Health health = Health.up().build();
@Override
public Health health() {
Health result = this.health;
this.health = Health.up().build();
return result;
}
void setHealth(Health health) {
this.health = health;
}
}
}

@ -1165,6 +1165,7 @@ content into your application. Rather, pick only the properties that you need.
# HEALTH ENDPOINT ({sc-spring-boot-actuator}/health/HealthEndpoint.{sc-ext}[HealthEndpoint]) # HEALTH ENDPOINT ({sc-spring-boot-actuator}/health/HealthEndpoint.{sc-ext}[HealthEndpoint])
management.endpoint.health.cache.time-to-live=0ms # Maximum time that a response can be cached. management.endpoint.health.cache.time-to-live=0ms # Maximum time that a response can be cached.
management.endpoint.health.enabled= # Whether to enable the health endpoint. management.endpoint.health.enabled= # Whether to enable the health endpoint.
management.endpoint.health.show-details= # Whether to show full health details
# HEAP DUMP ENDPOINT ({sc-spring-boot-actuator}/management/HeapDumpWebEndpoint.{sc-ext}[HeapDumpWebEndpoint]) # HEAP DUMP ENDPOINT ({sc-spring-boot-actuator}/management/HeapDumpWebEndpoint.{sc-ext}[HeapDumpWebEndpoint])
management.endpoint.heapdump.cache.time-to-live=0ms # Maximum time that a response can be cached. management.endpoint.heapdump.cache.time-to-live=0ms # Maximum time that a response can be cached.

@ -111,10 +111,6 @@ The following technology-agnostic endpoints are available:
|`shutdown` |`shutdown`
|Lets the application be gracefully shutdown (not enabled by default). |Lets the application be gracefully shutdown (not enabled by default).
|`status`
|Shows application status information (that is, `health` status with no additional
details).
|`threaddump` |`threaddump`
|Performs a thread dump. |Performs a thread dump.

@ -41,7 +41,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception { protected void configure(HttpSecurity http) throws Exception {
// @formatter:off // @formatter:off
http.authorizeRequests() http.authorizeRequests()
.requestMatchers(EndpointRequest.to("status", "info")).permitAll() .requestMatchers(EndpointRequest.to("health", "info")).permitAll()
.requestMatchers(EndpointRequest.toAnyEndpoint()).hasRole("ACTUATOR") .requestMatchers(EndpointRequest.toAnyEndpoint()).hasRole("ACTUATOR")
.requestMatchers(StaticResourceRequest.toCommonLocations()).permitAll() .requestMatchers(StaticResourceRequest.toCommonLocations()).permitAll()
.antMatchers("/foo").permitAll() .antMatchers("/foo").permitAll()

@ -1 +1,2 @@
management.endpoints.web.expose=* management.endpoints.web.expose=*
management.endpoint.health.show-details=true

@ -57,9 +57,9 @@ public class ManagementPortAndPathSampleActuatorApplicationTests {
@Test @Test
public void testSecureActuator() throws Exception { public void testSecureActuator() throws Exception {
ResponseEntity<String> entity = new TestRestTemplate() ResponseEntity<String> entity = new TestRestTemplate().getForEntity(
.getForEntity("http://localhost:" + this.managementPort "http://localhost:" + this.managementPort + "/management/application/env",
+ "/management/application/health", String.class); String.class);
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
} }
@ -67,7 +67,7 @@ public class ManagementPortAndPathSampleActuatorApplicationTests {
public void testInsecureActuator() throws Exception { public void testInsecureActuator() throws Exception {
ResponseEntity<String> entity = new TestRestTemplate() ResponseEntity<String> entity = new TestRestTemplate()
.getForEntity("http://localhost:" + this.managementPort .getForEntity("http://localhost:" + this.managementPort
+ "/management/application/status", String.class); + "/management/application/health", 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\"");
} }

@ -73,7 +73,7 @@ public class SampleActuatorCustomSecurityApplicationTests {
@Test @Test
public void insecureActuator() throws Exception { public void insecureActuator() throws Exception {
ResponseEntity<String> entity = this.restTemplate ResponseEntity<String> entity = this.restTemplate
.getForEntity("/application/status", String.class); .getForEntity("/application/health", 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\"");
} }

@ -1,2 +1,3 @@
server.error.path: /oops server.error.path: /oops
management.endpoints.web.base-path: /admin management.endpoint.health.show-details: true
management.endpoints.web.base-path: /admin

@ -61,7 +61,7 @@ public class SampleJerseyApplicationTests {
@Test @Test
public void actuatorStatus() { public void actuatorStatus() {
ResponseEntity<String> entity = this.restTemplate ResponseEntity<String> entity = this.restTemplate
.getForEntity("/application/status", String.class); .getForEntity("/application/health", String.class);
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(entity.getBody()).isEqualTo("{\"status\":\"UP\"}"); assertThat(entity.getBody()).isEqualTo("{\"status\":\"UP\"}");
} }

@ -48,7 +48,7 @@ public class SampleSecureWebFluxApplicationTests {
@Test @Test
public void actuatorsSecureByDefault() { public void actuatorsSecureByDefault() {
this.webClient.get().uri("/application/status").accept(MediaType.APPLICATION_JSON) this.webClient.get().uri("/application/health").accept(MediaType.APPLICATION_JSON)
.exchange().expectStatus().isUnauthorized(); .exchange().expectStatus().isUnauthorized();
} }
@ -61,7 +61,7 @@ public class SampleSecureWebFluxApplicationTests {
@Test @Test
public void actuatorsAccessibleOnLogin() { public void actuatorsAccessibleOnLogin() {
this.webClient.get().uri("/application/status").accept(MediaType.APPLICATION_JSON) this.webClient.get().uri("/application/health").accept(MediaType.APPLICATION_JSON)
.header("Authorization", "basic " + getBasicAuth()).exchange() .header("Authorization", "basic " + getBasicAuth()).exchange()
.expectBody(String.class).isEqualTo("{\"status\":\"UP\"}"); .expectBody(String.class).isEqualTo("{\"status\":\"UP\"}");
} }

@ -55,7 +55,7 @@ public class SampleWebFluxApplicationTests {
@Test @Test
public void testActuatorStatus() { public void testActuatorStatus() {
this.webClient.get().uri("/application/status").accept(MediaType.APPLICATION_JSON) this.webClient.get().uri("/application/health").accept(MediaType.APPLICATION_JSON)
.exchange().expectStatus().isOk().expectBody() .exchange().expectStatus().isOk().expectBody()
.json("{\"status\":\"UP\"}"); .json("{\"status\":\"UP\"}");
} }

Loading…
Cancel
Save