From 0597c6831e7bfb262856af5017669c9f255257af Mon Sep 17 00:00:00 2001 From: Madhura Bhave Date: Wed, 26 Jan 2022 20:47:59 -0800 Subject: [PATCH] Configure health on additional path only when health exposed Prior to this commit, limiting the exposure to a specific technology in `ConditionalOnAvailableEndpoint` would not have any effect because all endpoints would be considered to be available if the app was running on Cloud Foundry. This caused issues in cases where beans were meant to be exposed only if the endpoint was actually exposed. This commit adds CLOUD_FOUNDRY to the `EndpointExposure` enum. This allows `ConditionalOnAvailableEndpoint` to limit by exposure even when the Cloud Foundry platform is active. Fixes gh-29532 --- .../CachesEndpointAutoConfiguration.java | 2 +- ...ertiesReportEndpointAutoConfiguration.java | 2 +- .../OnAvailableEndpointCondition.java | 17 +++++++++---- .../endpoint/expose/EndpointExposure.java | 8 ++++++- .../EnvironmentEndpointAutoConfiguration.java | 2 +- ...ointReactiveWebExtensionConfiguration.java | 4 +++- ...althEndpointWebExtensionConfiguration.java | 5 +++- .../QuartzEndpointAutoConfiguration.java | 2 +- .../ConditionalOnAvailableEndpointTests.java | 3 ++- ...ndpointAdditionalPathIntegrationTests.java | 24 +++++++++++++++++++ 10 files changed, 56 insertions(+), 13 deletions(-) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cache/CachesEndpointAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cache/CachesEndpointAutoConfiguration.java index e78a66e14feb..c216ee44dbdb 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cache/CachesEndpointAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/cache/CachesEndpointAutoConfiguration.java @@ -54,7 +54,7 @@ public CachesEndpoint cachesEndpoint(Map cacheManagers) { @Bean @ConditionalOnMissingBean @ConditionalOnBean(CachesEndpoint.class) - @ConditionalOnAvailableEndpoint(exposure = EndpointExposure.WEB) + @ConditionalOnAvailableEndpoint(exposure = { EndpointExposure.WEB, EndpointExposure.CLOUD_FOUNDRY }) public CachesEndpointWebExtension cachesEndpointWebExtension(CachesEndpoint cachesEndpoint) { return new CachesEndpointWebExtension(cachesEndpoint); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/context/properties/ConfigurationPropertiesReportEndpointAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/context/properties/ConfigurationPropertiesReportEndpointAutoConfiguration.java index 44536ab5abca..7fb384d6a810 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/context/properties/ConfigurationPropertiesReportEndpointAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/context/properties/ConfigurationPropertiesReportEndpointAutoConfiguration.java @@ -63,7 +63,7 @@ public ConfigurationPropertiesReportEndpoint configurationPropertiesReportEndpoi @Bean @ConditionalOnMissingBean @ConditionalOnBean(ConfigurationPropertiesReportEndpoint.class) - @ConditionalOnAvailableEndpoint(exposure = EndpointExposure.WEB) + @ConditionalOnAvailableEndpoint(exposure = { EndpointExposure.WEB, EndpointExposure.CLOUD_FOUNDRY }) public ConfigurationPropertiesReportEndpointWebExtension configurationPropertiesReportEndpointWebExtension( ConfigurationPropertiesReportEndpoint configurationPropertiesReportEndpoint) { return new ConfigurationPropertiesReportEndpointWebExtension(configurationPropertiesReportEndpoint); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/OnAvailableEndpointCondition.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/OnAvailableEndpointCondition.java index 1b185fdb4d72..ac5ad1b2e60a 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/OnAvailableEndpointCondition.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/endpoint/condition/OnAvailableEndpointCondition.java @@ -113,9 +113,6 @@ private ConditionOutcome getMatchOutcome(Environment environment, if (!enablementOutcome.isMatch()) { return enablementOutcome; } - if (CloudPlatform.CLOUD_FOUNDRY.isActive(environment)) { - return ConditionOutcome.match(message.because("application is running on Cloud Foundry")); - } Set exposuresToCheck = getExposuresToCheck(conditionAnnotation); Set exposureFilters = getExposureFilters(environment); for (ExposureFilter exposureFilter : exposureFilters) { @@ -168,6 +165,9 @@ private Set getExposureFilters(Environment environment) { if (environment.getProperty(JMX_ENABLED_KEY, Boolean.class, false)) { exposureFilters.add(new ExposureFilter(environment, EndpointExposure.JMX)); } + if (CloudPlatform.CLOUD_FOUNDRY.isActive(environment)) { + exposureFilters.add(new ExposureFilter(environment, EndpointExposure.CLOUD_FOUNDRY)); + } exposureFilters.add(new ExposureFilter(environment, EndpointExposure.WEB)); exposureFiltersCache.put(environment, exposureFilters); } @@ -181,9 +181,16 @@ static final class ExposureFilter extends IncludeExcludeEndpointFilter client.get().uri("/healthz").accept(MediaType.APPLICATION_JSON) + .exchange().expectStatus().isNotFound(), "local.server.port")); + } + + @Test + void groupsAreNotConfiguredWhenHealthEndpointIsNotExposedWithDifferentManagementPortAndCloudFoundryPlatform() { + this.runner + .withPropertyValues("spring.jmx.enabled=true", "management.endpoints.web.exposure.exclude=health", + "spring.main.cloud-platform=cloud_foundry", "management.server.port=0", + "management.endpoint.health.group.live.include=diskSpace", + "management.endpoint.health.group.live.additional-path=server:healthz", + "management.endpoint.health.group.live.show-components=always") + .withInitializer(new ConditionEvaluationReportLoggingListener()) + .run(withWebTestClient((client) -> client.get().uri("/healthz").accept(MediaType.APPLICATION_JSON) + .exchange().expectStatus().isNotFound(), "local.server.port")); + } + private void testResponse(WebTestClient client) { client.get().uri("/healthz").accept(MediaType.APPLICATION_JSON).exchange().expectStatus().isOk().expectBody() .jsonPath("status").isEqualTo("UP").jsonPath("components.diskSpace").exists();