From eee269464815bc385bd5c07b8ac2799b942c99bf Mon Sep 17 00:00:00 2001 From: Yulin Qin Date: Sat, 10 Feb 2018 12:30:30 +0800 Subject: [PATCH 1/2] Add health indicator for reactive MongoDB See gh-11997 --- .../pom.xml | 10 +++ ...ctiveHealthIndicatorAutoConfiguration.java | 67 ++++++++++++++++++ .../main/resources/META-INF/spring.factories | 1 + ...HealthIndicatorAutoConfigurationTests.java | 67 ++++++++++++++++++ .../mongo/MongoReactiveHealthIndicator.java | 55 +++++++++++++++ .../MongoReactiveHealthIndicatorTest.java | 70 +++++++++++++++++++ .../MongoReactiveDataAutoConfiguration.java | 5 +- 7 files changed, 273 insertions(+), 2 deletions(-) create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/mongo/MongoReactiveHealthIndicatorAutoConfiguration.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/mongo/MongoReactiveHealthIndicatorAutoConfigurationTests.java create mode 100644 spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/mongo/MongoReactiveHealthIndicator.java create mode 100644 spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/mongo/MongoReactiveHealthIndicatorTest.java diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml b/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml index e7294407ea0..9e458ae80b5 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/pom.xml @@ -248,6 +248,16 @@ liquibase-core true + + org.mongodb + mongodb-driver-async + true + + + org.mongodb + mongodb-driver-reactivestreams + true + org.springframework spring-jdbc diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/mongo/MongoReactiveHealthIndicatorAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/mongo/MongoReactiveHealthIndicatorAutoConfiguration.java new file mode 100644 index 00000000000..9a0fa531724 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/mongo/MongoReactiveHealthIndicatorAutoConfiguration.java @@ -0,0 +1,67 @@ +/* + * Copyright 2012-2018 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.mongo; + +import java.util.Map; + +import org.springframework.boot.actuate.autoconfigure.health.CompositeReactiveHealthIndicatorConfiguration; +import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; +import org.springframework.boot.actuate.autoconfigure.health.HealthIndicatorAutoConfiguration; +import org.springframework.boot.actuate.health.ReactiveHealthIndicator; +import org.springframework.boot.actuate.mongo.MongoReactiveHealthIndicator; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.mongodb.core.ReactiveMongoTemplate; + + + +/** + * {@link EnableAutoConfiguration Auto-configuration} for {@link MongoReactiveHealthIndicator}. + * + * @author Yulin Qin + * @since 2.0.0 + */ +@Configuration +@ConditionalOnClass(ReactiveMongoTemplate.class) +@ConditionalOnBean(ReactiveMongoTemplate.class) +@ConditionalOnEnabledHealthIndicator("mongo") +@AutoConfigureBefore(HealthIndicatorAutoConfiguration.class) +@AutoConfigureAfter(MongoReactiveDataAutoConfiguration.class) +public class MongoReactiveHealthIndicatorAutoConfiguration extends + CompositeReactiveHealthIndicatorConfiguration { + + private final Map reactiveMongoTemplate; + + public MongoReactiveHealthIndicatorAutoConfiguration( + Map reactiveMongoTemplate) { + this.reactiveMongoTemplate = reactiveMongoTemplate; + } + + @Bean + @ConditionalOnMissingBean(name = "mongoReactiveHealthIndicator") + public ReactiveHealthIndicator mongoReactiveHealthIndicator() { + return createHealthIndicator(this.reactiveMongoTemplate); + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring.factories index e7732a33623..f73755a50b8 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring.factories @@ -53,6 +53,7 @@ org.springframework.boot.actuate.autoconfigure.metrics.web.client.RestTemplateMe org.springframework.boot.actuate.autoconfigure.metrics.web.reactive.WebFluxMetricsAutoConfiguration,\ org.springframework.boot.actuate.autoconfigure.metrics.web.servlet.WebMvcMetricsAutoConfiguration,\ org.springframework.boot.actuate.autoconfigure.mongo.MongoHealthIndicatorAutoConfiguration,\ +org.springframework.boot.actuate.autoconfigure.mongo.MongoReactiveHealthIndicatorAutoConfiguration,\ org.springframework.boot.actuate.autoconfigure.neo4j.Neo4jHealthIndicatorAutoConfiguration,\ org.springframework.boot.actuate.autoconfigure.redis.RedisHealthIndicatorAutoConfiguration,\ org.springframework.boot.actuate.autoconfigure.scheduling.ScheduledTasksEndpointAutoConfiguration,\ diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/mongo/MongoReactiveHealthIndicatorAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/mongo/MongoReactiveHealthIndicatorAutoConfigurationTests.java new file mode 100644 index 00000000000..0491753c770 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/mongo/MongoReactiveHealthIndicatorAutoConfigurationTests.java @@ -0,0 +1,67 @@ +/* + * Copyright 2012-2018 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.mongo; + +import org.junit.Test; + +import org.springframework.boot.actuate.autoconfigure.health.HealthIndicatorAutoConfiguration; +import org.springframework.boot.actuate.health.ApplicationHealthIndicator; +import org.springframework.boot.actuate.mongo.MongoHealthIndicator; +import org.springframework.boot.actuate.mongo.MongoReactiveHealthIndicator; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration; +import org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration; +import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; +import org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link MongoReactiveHealthIndicatorAutoConfiguration} + * + * @author Yulin Qin + */ +public class MongoReactiveHealthIndicatorAutoConfigurationTests { + + private ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of( + MongoAutoConfiguration.class, + MongoDataAutoConfiguration.class, + MongoReactiveAutoConfiguration.class, + MongoReactiveDataAutoConfiguration.class, + MongoReactiveHealthIndicatorAutoConfiguration.class, + HealthIndicatorAutoConfiguration.class)); + + @Test + public void runShouldCreateIndicator() { + this.contextRunner.run( + (context) -> assertThat(context).hasSingleBean(MongoReactiveHealthIndicator.class) + .doesNotHaveBean(MongoHealthIndicator.class) + .doesNotHaveBean(ApplicationHealthIndicator.class)); + } + + @Test + public void runWhenDisabledShouldNotCreateIndicator() { + this.contextRunner.withPropertyValues("management.health.mongo.enabled:false") + .run((context) -> assertThat(context) + .doesNotHaveBean(MongoReactiveHealthIndicator.class) + .doesNotHaveBean(MongoHealthIndicator.class) + .hasSingleBean(ApplicationHealthIndicator.class)); + } + +} diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/mongo/MongoReactiveHealthIndicator.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/mongo/MongoReactiveHealthIndicator.java new file mode 100644 index 00000000000..d70c1139bb8 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/mongo/MongoReactiveHealthIndicator.java @@ -0,0 +1,55 @@ +/* + * Copyright 2012-2018 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.mongo; + +import org.bson.Document; +import reactor.core.publisher.Mono; + +import org.springframework.boot.actuate.health.AbstractReactiveHealthIndicator; +import org.springframework.boot.actuate.health.Health; +import org.springframework.boot.actuate.health.ReactiveHealthIndicator; +import org.springframework.data.mongodb.core.ReactiveMongoTemplate; +import org.springframework.util.Assert; + + + +/** + * A {@link ReactiveHealthIndicator} for Mongo. + * + * @author Yulin Qin + * @since 2.0.0 + */ +public class MongoReactiveHealthIndicator extends AbstractReactiveHealthIndicator { + + private final ReactiveMongoTemplate reactiveMongoTemplate; + + public MongoReactiveHealthIndicator(ReactiveMongoTemplate reactiveMongoTemplate) { + Assert.notNull(reactiveMongoTemplate, "ReactiveMongoTemplate must not be null"); + this.reactiveMongoTemplate = reactiveMongoTemplate; + } + + @Override + protected Mono doHealthCheck(Health.Builder builder) { + Mono documentMono = this.reactiveMongoTemplate.executeCommand("{ buildInfo: 1 }"); + return documentMono.map(document -> up(builder, document)); + } + + private Health up(Health.Builder builder, Document document) { + return builder.up().withDetail("version", document.getString("version")).build(); + } +} + diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/mongo/MongoReactiveHealthIndicatorTest.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/mongo/MongoReactiveHealthIndicatorTest.java new file mode 100644 index 00000000000..fc9035d45dc --- /dev/null +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/mongo/MongoReactiveHealthIndicatorTest.java @@ -0,0 +1,70 @@ +/* + * Copyright 2012-2018 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.mongo; + +import com.mongodb.MongoException; +import org.bson.Document; +import org.junit.Test; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +import org.springframework.boot.actuate.health.Health; +import org.springframework.boot.actuate.health.Status; +import org.springframework.data.mongodb.core.ReactiveMongoTemplate; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link MongoReactiveHealthIndicator}. + * + * @author Yulin Qin + */ +public class MongoReactiveHealthIndicatorTest { + + @Test + public void testMongoIsUp() throws Exception { + Document document = mock(Document.class); + ReactiveMongoTemplate reactiveMongoTemplate = mock(ReactiveMongoTemplate.class); + given(reactiveMongoTemplate.executeCommand("{ buildInfo: 1 }")).willReturn(Mono.just(document)); + given(document.getString("version")).willReturn("2.6.4"); + + MongoReactiveHealthIndicator mongoReactiveHealthIndicator = new MongoReactiveHealthIndicator(reactiveMongoTemplate); + Mono health = mongoReactiveHealthIndicator.health(); + StepVerifier.create(health).consumeNextWith((h) -> { + assertThat(h.getStatus()).isEqualTo(Status.UP); + assertThat(h.getDetails()).containsOnlyKeys("version"); + assertThat(h.getDetails().get("version")).isEqualTo("2.6.4"); + }).verifyComplete(); + } + + @Test + public void testMongoIsDown() throws Exception { + ReactiveMongoTemplate reactiveMongoTemplate = mock(ReactiveMongoTemplate.class); + given(reactiveMongoTemplate.executeCommand("{ buildInfo: 1 }")).willThrow(new MongoException("Connection failed")); + + MongoReactiveHealthIndicator mongoReactiveHealthIndicator = new MongoReactiveHealthIndicator(reactiveMongoTemplate); + Mono health = mongoReactiveHealthIndicator.health(); + StepVerifier.create(health).consumeNextWith((h) -> { + assertThat(h.getStatus()).isEqualTo(Status.DOWN); + assertThat(h.getDetails()).containsOnlyKeys("error"); + assertThat(h.getDetails().get("error")).isEqualTo("Connection failed"); + }).verifyComplete(); + + } +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveDataAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveDataAutoConfiguration.java index de16566c56e..22f15dafc61 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveDataAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveDataAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2018 the original author or authors. + * 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. @@ -32,6 +32,7 @@ import org.springframework.data.mongodb.core.ReactiveMongoTemplate; import org.springframework.data.mongodb.core.SimpleReactiveMongoDatabaseFactory; import org.springframework.data.mongodb.core.convert.MongoConverter; + /** * {@link EnableAutoConfiguration Auto-configuration} for Spring Data's reactive mongo * support. @@ -43,6 +44,7 @@ import org.springframework.data.mongodb.core.convert.MongoConverter; * to the {@literal test} database. * * @author Mark Paluch + * @author Yulin Qin * @since 2.0.0 */ @Configuration @@ -73,5 +75,4 @@ public class MongoReactiveDataAutoConfiguration { MongoConverter converter) { return new ReactiveMongoTemplate(reactiveMongoDatabaseFactory, converter); } - } From 28f5392787dba92354d652a21cdc62fe3565af4a Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Tue, 13 Feb 2018 11:17:37 +0100 Subject: [PATCH 2/2] Polish "Add health indicator for reactive MongoDB" Closes gh-11997 --- ...MongoHealthIndicatorAutoConfiguration.java | 35 +++--------- .../MongoHealthIndicatorConfiguration.java | 55 +++++++++++++++++++ ...ReactiveHealthIndicatorConfiguration.java} | 24 ++------ .../main/resources/META-INF/spring.factories | 1 - .../SpringApplicationHierarchyTests.java | 19 ++++--- ...intsAutoConfigurationIntegrationTests.java | 6 +- ...iveHealthIndicatorConfigurationTests.java} | 6 +- .../spring-boot-actuator/pom.xml | 10 ++++ .../mongo/MongoReactiveHealthIndicator.java | 8 +-- .../MongoReactiveHealthIndicatorTest.java | 16 +++--- .../MongoReactiveDataAutoConfiguration.java | 5 +- .../asciidoc/production-ready-features.adoc | 3 + 12 files changed, 116 insertions(+), 72 deletions(-) create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/mongo/MongoHealthIndicatorConfiguration.java rename spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/mongo/{MongoReactiveHealthIndicatorAutoConfiguration.java => MongoReactiveHealthIndicatorConfiguration.java} (64%) rename spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/mongo/{MongoReactiveHealthIndicatorAutoConfigurationTests.java => MongoReactiveHealthIndicatorConfigurationTests.java} (93%) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/mongo/MongoHealthIndicatorAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/mongo/MongoHealthIndicatorAutoConfiguration.java index 92ac844f24f..047e9b4608e 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/mongo/MongoHealthIndicatorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/mongo/MongoHealthIndicatorAutoConfiguration.java @@ -16,51 +16,32 @@ package org.springframework.boot.actuate.autoconfigure.mongo; -import java.util.Map; - -import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthIndicatorConfiguration; import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; import org.springframework.boot.actuate.autoconfigure.health.HealthIndicatorAutoConfiguration; -import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.boot.actuate.mongo.MongoHealthIndicator; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration; +import org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration; import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.context.annotation.Import; /** * {@link EnableAutoConfiguration Auto-configuration} for {@link MongoHealthIndicator}. * * @author Christian Dupuis + * @author Stephane Nicoll * @since 2.0.0 */ @Configuration -@ConditionalOnClass(MongoTemplate.class) -@ConditionalOnBean(MongoTemplate.class) @ConditionalOnEnabledHealthIndicator("mongo") @AutoConfigureBefore(HealthIndicatorAutoConfiguration.class) -@AutoConfigureAfter({ MongoAutoConfiguration.class, MongoDataAutoConfiguration.class }) -public class MongoHealthIndicatorAutoConfiguration extends - CompositeHealthIndicatorConfiguration { - - private final Map mongoTemplates; - - public MongoHealthIndicatorAutoConfiguration( - Map mongoTemplates) { - this.mongoTemplates = mongoTemplates; - } - - @Bean - @ConditionalOnMissingBean(name = "mongoHealthIndicator") - public HealthIndicator mongoHealthIndicator() { - return createHealthIndicator(this.mongoTemplates); - } +@AutoConfigureAfter({ MongoAutoConfiguration.class, MongoDataAutoConfiguration.class, + MongoReactiveDataAutoConfiguration.class }) +@Import({ MongoReactiveHealthIndicatorConfiguration.class, + MongoHealthIndicatorConfiguration.class }) +public class MongoHealthIndicatorAutoConfiguration { } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/mongo/MongoHealthIndicatorConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/mongo/MongoHealthIndicatorConfiguration.java new file mode 100644 index 00000000000..2fbd31598a4 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/mongo/MongoHealthIndicatorConfiguration.java @@ -0,0 +1,55 @@ +/* + * Copyright 2012-2018 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.mongo; + +import java.util.Map; + +import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthIndicatorConfiguration; +import org.springframework.boot.actuate.health.HealthIndicator; +import org.springframework.boot.actuate.mongo.MongoHealthIndicator; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.mongodb.core.MongoTemplate; + +/** + * Configuration for {@link MongoHealthIndicator}. + * + * @author Stephane Nicoll + */ +@Configuration +@ConditionalOnClass(MongoTemplate.class) +@ConditionalOnBean(MongoTemplate.class) +class MongoHealthIndicatorConfiguration extends + CompositeHealthIndicatorConfiguration { + + private final Map mongoTemplates; + + MongoHealthIndicatorConfiguration( + Map mongoTemplates) { + this.mongoTemplates = mongoTemplates; + } + + @Bean + @ConditionalOnMissingBean(name = "mongoHealthIndicator") + public HealthIndicator mongoHealthIndicator() { + return createHealthIndicator(this.mongoTemplates); + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/mongo/MongoReactiveHealthIndicatorAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/mongo/MongoReactiveHealthIndicatorConfiguration.java similarity index 64% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/mongo/MongoReactiveHealthIndicatorAutoConfiguration.java rename to spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/mongo/MongoReactiveHealthIndicatorConfiguration.java index 9a0fa531724..ffc6735b319 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/mongo/MongoReactiveHealthIndicatorAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/mongo/MongoReactiveHealthIndicatorConfiguration.java @@ -19,48 +19,36 @@ package org.springframework.boot.actuate.autoconfigure.mongo; import java.util.Map; import org.springframework.boot.actuate.autoconfigure.health.CompositeReactiveHealthIndicatorConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; -import org.springframework.boot.actuate.autoconfigure.health.HealthIndicatorAutoConfiguration; import org.springframework.boot.actuate.health.ReactiveHealthIndicator; import org.springframework.boot.actuate.mongo.MongoReactiveHealthIndicator; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.mongodb.core.ReactiveMongoTemplate; - - /** - * {@link EnableAutoConfiguration Auto-configuration} for {@link MongoReactiveHealthIndicator}. + * Configuration for {@link MongoReactiveHealthIndicator}. * - * @author Yulin Qin - * @since 2.0.0 + * @author Stephane Nicoll */ @Configuration @ConditionalOnClass(ReactiveMongoTemplate.class) @ConditionalOnBean(ReactiveMongoTemplate.class) -@ConditionalOnEnabledHealthIndicator("mongo") -@AutoConfigureBefore(HealthIndicatorAutoConfiguration.class) -@AutoConfigureAfter(MongoReactiveDataAutoConfiguration.class) -public class MongoReactiveHealthIndicatorAutoConfiguration extends +class MongoReactiveHealthIndicatorConfiguration extends CompositeReactiveHealthIndicatorConfiguration { private final Map reactiveMongoTemplate; - public MongoReactiveHealthIndicatorAutoConfiguration( + MongoReactiveHealthIndicatorConfiguration( Map reactiveMongoTemplate) { this.reactiveMongoTemplate = reactiveMongoTemplate; } @Bean - @ConditionalOnMissingBean(name = "mongoReactiveHealthIndicator") - public ReactiveHealthIndicator mongoReactiveHealthIndicator() { + @ConditionalOnMissingBean(name = "mongoHealthIndicator") + public ReactiveHealthIndicator mongoHealthIndicator() { return createHealthIndicator(this.reactiveMongoTemplate); } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring.factories index f73755a50b8..e7732a33623 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring.factories @@ -53,7 +53,6 @@ org.springframework.boot.actuate.autoconfigure.metrics.web.client.RestTemplateMe org.springframework.boot.actuate.autoconfigure.metrics.web.reactive.WebFluxMetricsAutoConfiguration,\ org.springframework.boot.actuate.autoconfigure.metrics.web.servlet.WebMvcMetricsAutoConfiguration,\ org.springframework.boot.actuate.autoconfigure.mongo.MongoHealthIndicatorAutoConfiguration,\ -org.springframework.boot.actuate.autoconfigure.mongo.MongoReactiveHealthIndicatorAutoConfiguration,\ org.springframework.boot.actuate.autoconfigure.neo4j.Neo4jHealthIndicatorAutoConfiguration,\ org.springframework.boot.actuate.autoconfigure.redis.RedisHealthIndicatorAutoConfiguration,\ org.springframework.boot.actuate.autoconfigure.scheduling.ScheduledTasksEndpointAutoConfiguration,\ diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/SpringApplicationHierarchyTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/SpringApplicationHierarchyTests.java index ce85a8c05d3..7913ec31792 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/SpringApplicationHierarchyTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/SpringApplicationHierarchyTests.java @@ -26,6 +26,7 @@ import org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoCo import org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration; import org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration; import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration; +import org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration; import org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration; import org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration; import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; @@ -69,10 +70,11 @@ public class SpringApplicationHierarchyTests { @EnableAutoConfiguration(exclude = { ElasticsearchDataAutoConfiguration.class, ElasticsearchRepositoriesAutoConfiguration.class, CassandraAutoConfiguration.class, CassandraDataAutoConfiguration.class, - MongoDataAutoConfiguration.class, Neo4jDataAutoConfiguration.class, - Neo4jRepositoriesAutoConfiguration.class, RedisAutoConfiguration.class, - RedisRepositoriesAutoConfiguration.class, FlywayAutoConfiguration.class, - JestAutoConfiguration.class, MetricsAutoConfiguration.class }, excludeName = { + MongoDataAutoConfiguration.class, MongoReactiveDataAutoConfiguration.class, + Neo4jDataAutoConfiguration.class, Neo4jRepositoriesAutoConfiguration.class, + RedisAutoConfiguration.class, RedisRepositoriesAutoConfiguration.class, + FlywayAutoConfiguration.class, JestAutoConfiguration.class, + MetricsAutoConfiguration.class }, excludeName = { "org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration" }) public static class Child { @@ -81,10 +83,11 @@ public class SpringApplicationHierarchyTests { @EnableAutoConfiguration(exclude = { ElasticsearchDataAutoConfiguration.class, ElasticsearchRepositoriesAutoConfiguration.class, CassandraAutoConfiguration.class, CassandraDataAutoConfiguration.class, - MongoDataAutoConfiguration.class, Neo4jDataAutoConfiguration.class, - Neo4jRepositoriesAutoConfiguration.class, RedisAutoConfiguration.class, - RedisRepositoriesAutoConfiguration.class, FlywayAutoConfiguration.class, - JestAutoConfiguration.class, MetricsAutoConfiguration.class }, excludeName = { + MongoDataAutoConfiguration.class, MongoReactiveDataAutoConfiguration.class, + Neo4jDataAutoConfiguration.class, Neo4jRepositoriesAutoConfiguration.class, + RedisAutoConfiguration.class, RedisRepositoriesAutoConfiguration.class, + FlywayAutoConfiguration.class, JestAutoConfiguration.class, + MetricsAutoConfiguration.class }, excludeName = { "org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration" }) public static class Parent { diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebEndpointsAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebEndpointsAutoConfigurationIntegrationTests.java index ede529436fe..430629b867a 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebEndpointsAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/integrationtest/WebEndpointsAutoConfigurationIntegrationTests.java @@ -28,6 +28,7 @@ import org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoCo import org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration; import org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration; import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration; +import org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration; import org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration; import org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration; import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; @@ -39,6 +40,7 @@ import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; import org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration; import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration; import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; +import org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration; import org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration; import org.springframework.boot.context.annotation.UserConfigurations; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; @@ -81,8 +83,10 @@ public class WebEndpointsAutoConfigurationIntegrationTests { LiquibaseAutoConfiguration.class, CassandraAutoConfiguration.class, CassandraDataAutoConfiguration.class, Neo4jDataAutoConfiguration.class, Neo4jRepositoriesAutoConfiguration.class, MongoAutoConfiguration.class, + MongoDataAutoConfiguration.class, MongoReactiveAutoConfiguration.class, + MongoReactiveDataAutoConfiguration.class, RepositoryRestMvcAutoConfiguration.class, HazelcastAutoConfiguration.class, - MongoDataAutoConfiguration.class, ElasticsearchAutoConfiguration.class, + ElasticsearchAutoConfiguration.class, ElasticsearchDataAutoConfiguration.class, JestAutoConfiguration.class, SolrRepositoriesAutoConfiguration.class, SolrAutoConfiguration.class, RedisAutoConfiguration.class, RedisRepositoriesAutoConfiguration.class, diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/mongo/MongoReactiveHealthIndicatorAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/mongo/MongoReactiveHealthIndicatorConfigurationTests.java similarity index 93% rename from spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/mongo/MongoReactiveHealthIndicatorAutoConfigurationTests.java rename to spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/mongo/MongoReactiveHealthIndicatorConfigurationTests.java index 0491753c770..58cc1fd0a7e 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/mongo/MongoReactiveHealthIndicatorAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/mongo/MongoReactiveHealthIndicatorConfigurationTests.java @@ -32,11 +32,11 @@ import org.springframework.boot.test.context.runner.ApplicationContextRunner; import static org.assertj.core.api.Assertions.assertThat; /** - * Tests for {@link MongoReactiveHealthIndicatorAutoConfiguration} + * Tests for {@link MongoReactiveHealthIndicatorConfiguration}. * * @author Yulin Qin */ -public class MongoReactiveHealthIndicatorAutoConfigurationTests { +public class MongoReactiveHealthIndicatorConfigurationTests { private ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of( @@ -44,7 +44,7 @@ public class MongoReactiveHealthIndicatorAutoConfigurationTests { MongoDataAutoConfiguration.class, MongoReactiveAutoConfiguration.class, MongoReactiveDataAutoConfiguration.class, - MongoReactiveHealthIndicatorAutoConfiguration.class, + MongoHealthIndicatorAutoConfiguration.class, HealthIndicatorAutoConfiguration.class)); @Test diff --git a/spring-boot-project/spring-boot-actuator/pom.xml b/spring-boot-project/spring-boot-actuator/pom.xml index 1bf30d2522c..60644d6aa24 100644 --- a/spring-boot-project/spring-boot-actuator/pom.xml +++ b/spring-boot-project/spring-boot-actuator/pom.xml @@ -142,6 +142,16 @@ liquibase-core true + + org.mongodb + mongodb-driver-async + true + + + org.mongodb + mongodb-driver-reactivestreams + true + org.springframework spring-jdbc diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/mongo/MongoReactiveHealthIndicator.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/mongo/MongoReactiveHealthIndicator.java index d70c1139bb8..310c1260384 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/mongo/MongoReactiveHealthIndicator.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/mongo/MongoReactiveHealthIndicator.java @@ -25,8 +25,6 @@ import org.springframework.boot.actuate.health.ReactiveHealthIndicator; import org.springframework.data.mongodb.core.ReactiveMongoTemplate; import org.springframework.util.Assert; - - /** * A {@link ReactiveHealthIndicator} for Mongo. * @@ -44,12 +42,14 @@ public class MongoReactiveHealthIndicator extends AbstractReactiveHealthIndicato @Override protected Mono doHealthCheck(Health.Builder builder) { - Mono documentMono = this.reactiveMongoTemplate.executeCommand("{ buildInfo: 1 }"); - return documentMono.map(document -> up(builder, document)); + Mono buildInfo = this.reactiveMongoTemplate.executeCommand( + "{ buildInfo: 1 }"); + return buildInfo.map(document -> up(builder, document)); } private Health up(Health.Builder builder, Document document) { return builder.up().withDetail("version", document.getString("version")).build(); } + } diff --git a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/mongo/MongoReactiveHealthIndicatorTest.java b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/mongo/MongoReactiveHealthIndicatorTest.java index fc9035d45dc..6c48b9cf760 100644 --- a/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/mongo/MongoReactiveHealthIndicatorTest.java +++ b/spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/mongo/MongoReactiveHealthIndicatorTest.java @@ -38,11 +38,12 @@ import static org.mockito.Mockito.mock; public class MongoReactiveHealthIndicatorTest { @Test - public void testMongoIsUp() throws Exception { - Document document = mock(Document.class); + public void testMongoIsUp() { + Document buildInfo = mock(Document.class); + given(buildInfo.getString("version")).willReturn("2.6.4"); ReactiveMongoTemplate reactiveMongoTemplate = mock(ReactiveMongoTemplate.class); - given(reactiveMongoTemplate.executeCommand("{ buildInfo: 1 }")).willReturn(Mono.just(document)); - given(document.getString("version")).willReturn("2.6.4"); + given(reactiveMongoTemplate.executeCommand("{ buildInfo: 1 }")).willReturn( + Mono.just(buildInfo)); MongoReactiveHealthIndicator mongoReactiveHealthIndicator = new MongoReactiveHealthIndicator(reactiveMongoTemplate); Mono health = mongoReactiveHealthIndicator.health(); @@ -54,9 +55,10 @@ public class MongoReactiveHealthIndicatorTest { } @Test - public void testMongoIsDown() throws Exception { + public void testMongoIsDown() { ReactiveMongoTemplate reactiveMongoTemplate = mock(ReactiveMongoTemplate.class); - given(reactiveMongoTemplate.executeCommand("{ buildInfo: 1 }")).willThrow(new MongoException("Connection failed")); + given(reactiveMongoTemplate.executeCommand("{ buildInfo: 1 }")).willThrow( + new MongoException("Connection failed")); MongoReactiveHealthIndicator mongoReactiveHealthIndicator = new MongoReactiveHealthIndicator(reactiveMongoTemplate); Mono health = mongoReactiveHealthIndicator.health(); @@ -65,6 +67,6 @@ public class MongoReactiveHealthIndicatorTest { assertThat(h.getDetails()).containsOnlyKeys("error"); assertThat(h.getDetails().get("error")).isEqualTo("Connection failed"); }).verifyComplete(); - } + } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveDataAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveDataAutoConfiguration.java index 22f15dafc61..de16566c56e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveDataAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoReactiveDataAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 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. @@ -32,7 +32,6 @@ import org.springframework.data.mongodb.core.ReactiveMongoTemplate; import org.springframework.data.mongodb.core.SimpleReactiveMongoDatabaseFactory; import org.springframework.data.mongodb.core.convert.MongoConverter; - /** * {@link EnableAutoConfiguration Auto-configuration} for Spring Data's reactive mongo * support. @@ -44,7 +43,6 @@ import org.springframework.data.mongodb.core.convert.MongoConverter; * to the {@literal test} database. * * @author Mark Paluch - * @author Yulin Qin * @since 2.0.0 */ @Configuration @@ -75,4 +73,5 @@ public class MongoReactiveDataAutoConfiguration { MongoConverter converter) { return new ReactiveMongoTemplate(reactiveMongoDatabaseFactory, converter); } + } diff --git a/spring-boot-project/spring-boot-docs/src/main/asciidoc/production-ready-features.adoc b/spring-boot-project/spring-boot-docs/src/main/asciidoc/production-ready-features.adoc index 01966d5b42d..2ebc8da37fd 100644 --- a/spring-boot-project/spring-boot-docs/src/main/asciidoc/production-ready-features.adoc +++ b/spring-boot-project/spring-boot-docs/src/main/asciidoc/production-ready-features.adoc @@ -723,6 +723,9 @@ appropriate: |=== |Name |Description +|{sc-spring-boot-actuator}/mongo/MongoReactiveHealthIndicator.{sc-ext}[`MongoReactiveHealthIndicator`] +|Checks that a Mongo database is up. + |{sc-spring-boot-actuator}/redis/RedisReactiveHealthIndicator.{sc-ext}[`RedisReactiveHealthIndicator`] |Checks that a Redis server is up. |===