From 708556a2836f4d03a8ebc2897eb272ff8efe2f83 Mon Sep 17 00:00:00 2001 From: Julio Gomez Diaz Date: Wed, 1 Jul 2020 23:12:00 +0200 Subject: [PATCH 1/3] =?UTF-8?q?First=20approach=20for=20=C3=B6ptionally=20?= =?UTF-8?q?ignoring=20routing=20datasources=20in=20health=20outcome?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...aSourceHealthContributorAutoConfiguration.java | 8 ++++++++ ...ceHealthContributorAutoConfigurationTests.java | 15 +++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfiguration.java index 885c4e57de5e..dcf92fb2382a 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfiguration.java @@ -64,6 +64,8 @@ public class DataSourceHealthContributorAutoConfiguration extends CompositeHealthContributorConfiguration implements InitializingBean { + private boolean ignoreRoutingDataSources = false; + private final Collection metadataProviders; private DataSourcePoolMetadataProvider poolMetadataProvider; @@ -81,6 +83,12 @@ public void afterPropertiesSet() throws Exception { @Bean @ConditionalOnMissingBean(name = { "dbHealthIndicator", "dbHealthContributor" }) public HealthContributor dbHealthContributor(Map dataSources) { + if (ignoreRoutingDataSources) { + Map filteredDatasources = dataSources.entrySet().stream() + .filter(e -> !(e.getValue() instanceof AbstractRoutingDataSource)) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + return createContributor(filteredDatasources); + } return createContributor(dataSources); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfigurationTests.java index a303852323e2..76007177188f 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfigurationTests.java @@ -82,11 +82,26 @@ void runWithRoutingAndEmbeddedDataSourceShouldIncludeRoutingDataSource() { }); } + @Test + void runWithRoutingAndEmbeddedDataSourceShouldNotIncludeRoutingDataSourceWhenIgnored() { + this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class, RoutingDatasourceConfig.class) + .run((context) -> { + CompositeHealthContributor composite = context.getBean(CompositeHealthContributor.class); + assertThat(composite.getContributor("dataSource")).isInstanceOf(DataSourceHealthIndicator.class); + assertThat(composite.getContributor("routingDataSource")).isNull(); + }); + } @Test void runWithOnlyRoutingDataSourceShouldIncludeRoutingDataSource() { this.contextRunner.withUserConfiguration(RoutingDatasourceConfig.class) .run((context) -> assertThat(context).hasSingleBean(RoutingDataSourceHealthIndicator.class)); } + @Test + void runWithOnlyRoutingDataSourceShouldBeEmptyIgnored() { + this.contextRunner.withUserConfiguration(RoutingDatasourceConfig.class).withPropertyValues("management.health.db.ignore-routing-datasources:true") + .run((context) -> assertThat(context).doesNotHaveBean(RoutingDataSourceHealthIndicator.class)); + } + @Test void runWithValidationQueryPropertyShouldUseCustomQuery() { From 41b4d1052d0b1a020ef79a51db7f6df6cffec42b Mon Sep 17 00:00:00 2001 From: Julio Gomez Diaz Date: Sat, 4 Jul 2020 14:11:06 +0200 Subject: [PATCH 2/3] Added tests and property that allows to ignore AbstractRoutingDatasource's when creatng HealthIndicator's --- ...rceHealthContributorAutoConfiguration.java | 8 +++++--- ...itional-spring-configuration-metadata.json | 6 ++++++ ...althContributorAutoConfigurationTests.java | 19 +++++++++++-------- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfiguration.java index dcf92fb2382a..b5be6ad91c45 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfiguration.java @@ -24,6 +24,7 @@ import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.ObjectProvider; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration; import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; import org.springframework.boot.actuate.health.AbstractHealthIndicator; @@ -64,7 +65,8 @@ public class DataSourceHealthContributorAutoConfiguration extends CompositeHealthContributorConfiguration implements InitializingBean { - private boolean ignoreRoutingDataSources = false; + @Value("${management.health.db.ignore-routing-datasources:false}") + private boolean ignoreRoutingDataSources; private final Collection metadataProviders; @@ -83,9 +85,9 @@ public void afterPropertiesSet() throws Exception { @Bean @ConditionalOnMissingBean(name = { "dbHealthIndicator", "dbHealthContributor" }) public HealthContributor dbHealthContributor(Map dataSources) { - if (ignoreRoutingDataSources) { + if (this.ignoreRoutingDataSources) { Map filteredDatasources = dataSources.entrySet().stream() - .filter(e -> !(e.getValue() instanceof AbstractRoutingDataSource)) + .filter((e) -> !(e.getValue() instanceof AbstractRoutingDataSource)) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); return createContributor(filteredDatasources); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 3413ac7bfb89..8fef748ce415 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -116,6 +116,12 @@ "description": "Whether to enable database health check.", "defaultValue": true }, + { + "name": "management.health.db.ignore-routing-datasources", + "type": "java.lang.Boolean", + "description": "Whether to ignore the creation of health indicators for AbstractRoutingDatasource s", + "defaultValue": false + }, { "name": "management.health.defaults.enabled", "type": "java.lang.Boolean", diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfigurationTests.java index 76007177188f..0f6669907520 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfigurationTests.java @@ -85,24 +85,27 @@ void runWithRoutingAndEmbeddedDataSourceShouldIncludeRoutingDataSource() { @Test void runWithRoutingAndEmbeddedDataSourceShouldNotIncludeRoutingDataSourceWhenIgnored() { this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class, RoutingDatasourceConfig.class) - .run((context) -> { - CompositeHealthContributor composite = context.getBean(CompositeHealthContributor.class); - assertThat(composite.getContributor("dataSource")).isInstanceOf(DataSourceHealthIndicator.class); - assertThat(composite.getContributor("routingDataSource")).isNull(); + .withPropertyValues("management.health.db.ignore-routing-datasources:true").run((context) -> { + assertThat(context).doesNotHaveBean(CompositeHealthContributor.class); + assertThat(context).hasSingleBean(DataSourceHealthIndicator.class); + assertThat(context).doesNotHaveBean(RoutingDataSourceHealthIndicator.class); }); } + @Test void runWithOnlyRoutingDataSourceShouldIncludeRoutingDataSource() { this.contextRunner.withUserConfiguration(RoutingDatasourceConfig.class) .run((context) -> assertThat(context).hasSingleBean(RoutingDataSourceHealthIndicator.class)); } + @Test - void runWithOnlyRoutingDataSourceShouldBeEmptyIgnored() { - this.contextRunner.withUserConfiguration(RoutingDatasourceConfig.class).withPropertyValues("management.health.db.ignore-routing-datasources:true") - .run((context) -> assertThat(context).doesNotHaveBean(RoutingDataSourceHealthIndicator.class)); + void runWithOnlyRoutingDataSourceShouldCrashWhenIgnored() { + this.contextRunner.withUserConfiguration(RoutingDatasourceConfig.class) + .withPropertyValues("management.health.db.ignore-routing-datasources:true") + .run((context) -> assertThat(context).hasFailed().getFailure() + .hasRootCauseInstanceOf(IllegalArgumentException.class)); } - @Test void runWithValidationQueryPropertyShouldUseCustomQuery() { this.contextRunner From 6671e9f93b2041231b9ff6312dc22b9cd5e5635f Mon Sep 17 00:00:00 2001 From: Julio Gomez Diaz Date: Mon, 6 Jul 2020 19:47:41 +0200 Subject: [PATCH 3/3] Changed to use ConfigurationProperties object --- ...rceHealthContributorAutoConfiguration.java | 11 +++-- .../DataSourceHealthIndicatorProperties.java | 44 +++++++++++++++++++ ...itional-spring-configuration-metadata.json | 6 --- 3 files changed, 49 insertions(+), 12 deletions(-) create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthIndicatorProperties.java diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfiguration.java index b5be6ad91c45..8c7e9167224c 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfiguration.java @@ -24,7 +24,6 @@ import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.ObjectProvider; -import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration; import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; import org.springframework.boot.actuate.health.AbstractHealthIndicator; @@ -38,6 +37,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.jdbc.metadata.CompositeDataSourcePoolMetadataProvider; import org.springframework.boot.jdbc.metadata.DataSourcePoolMetadata; import org.springframework.boot.jdbc.metadata.DataSourcePoolMetadataProvider; @@ -62,12 +62,10 @@ @ConditionalOnBean(DataSource.class) @ConditionalOnEnabledHealthIndicator("db") @AutoConfigureAfter(DataSourceAutoConfiguration.class) +@EnableConfigurationProperties(DataSourceHealthIndicatorProperties.class) public class DataSourceHealthContributorAutoConfiguration extends CompositeHealthContributorConfiguration implements InitializingBean { - @Value("${management.health.db.ignore-routing-datasources:false}") - private boolean ignoreRoutingDataSources; - private final Collection metadataProviders; private DataSourcePoolMetadataProvider poolMetadataProvider; @@ -84,8 +82,9 @@ public void afterPropertiesSet() throws Exception { @Bean @ConditionalOnMissingBean(name = { "dbHealthIndicator", "dbHealthContributor" }) - public HealthContributor dbHealthContributor(Map dataSources) { - if (this.ignoreRoutingDataSources) { + public HealthContributor dbHealthContributor(Map dataSources, + DataSourceHealthIndicatorProperties dataSourceHealthIndicatorProperties) { + if (dataSourceHealthIndicatorProperties.isIgnoreRoutingDataSources()) { Map filteredDatasources = dataSources.entrySet().stream() .filter((e) -> !(e.getValue() instanceof AbstractRoutingDataSource)) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthIndicatorProperties.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthIndicatorProperties.java new file mode 100644 index 000000000000..997de32b4c5d --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthIndicatorProperties.java @@ -0,0 +1,44 @@ +/* + * Copyright 2012-2020 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 + * + * https://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.jdbc; + +import org.springframework.boot.actuate.jdbc.DataSourceHealthIndicator; +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * External configuration properties for {@link DataSourceHealthIndicator}. + * + * @author Julio Gomez + * @since 2.4.0 + */ +@ConfigurationProperties(prefix = "management.health.db") +public class DataSourceHealthIndicatorProperties { + + /** + * Whether to ignore the creation of health indicators for AbstractRoutingDatasource. + */ + private boolean ignoreRoutingDataSources = false; + + public boolean isIgnoreRoutingDataSources() { + return this.ignoreRoutingDataSources; + } + + public void setIgnoreRoutingDataSources(boolean ignoreRoutingDataSources) { + this.ignoreRoutingDataSources = ignoreRoutingDataSources; + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 8fef748ce415..3413ac7bfb89 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -116,12 +116,6 @@ "description": "Whether to enable database health check.", "defaultValue": true }, - { - "name": "management.health.db.ignore-routing-datasources", - "type": "java.lang.Boolean", - "description": "Whether to ignore the creation of health indicators for AbstractRoutingDatasource s", - "defaultValue": false - }, { "name": "management.health.defaults.enabled", "type": "java.lang.Boolean",