Skip to content

Commit 8d2c090

Browse files
committed
Move MongoDB health support into spring-boot-mongodb
Previously the MongoDB health indicates used Spring Data's templates (imperative and reactive) to access MongoDB. This prevented health information from being available in apps using Mongo's Java Driver directly. This commit updates the health indicates so that they no longer depend upon Spring Data MongoDB and instead using MongoDB's Java Driver directly. As they no longer depend on Spring Data MongoDB, the indicators have also moved from spring-boot-data-mongodb to spring-boot-mongodb. Closes gh-47051
1 parent a977d26 commit 8d2c090

File tree

17 files changed

+199
-139
lines changed

17 files changed

+199
-139
lines changed

module/spring-boot-data-mongodb/build.gradle

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ plugins {
1919
id "org.springframework.boot.auto-configuration"
2020
id "org.springframework.boot.configuration-properties"
2121
id "org.springframework.boot.deployed"
22-
id "org.springframework.boot.docker-test"
2322
id "org.springframework.boot.optional-dependencies"
2423
}
2524

@@ -35,18 +34,10 @@ dependencies {
3534
compileOnly("com.google.code.findbugs:jsr305")
3635

3736
optional(project(":core:spring-boot-autoconfigure"))
38-
optional(project(":module:spring-boot-health"))
3937
optional(project(":module:spring-boot-reactor"))
4038
optional("org.mongodb:mongodb-driver-reactivestreams")
4139
optional("org.mongodb:mongodb-driver-sync")
4240

43-
dockerTestImplementation(project(":core:spring-boot-test"))
44-
dockerTestImplementation(project(":test-support:spring-boot-docker-test-support"))
45-
dockerTestImplementation("ch.qos.logback:logback-classic")
46-
dockerTestImplementation("org.junit.jupiter:junit-jupiter")
47-
dockerTestImplementation("org.testcontainers:junit-jupiter")
48-
dockerTestImplementation("org.testcontainers:mongodb")
49-
5041
testCompileOnly("com.fasterxml.jackson.core:jackson-annotations")
5142

5243
testImplementation(project(":core:spring-boot-test"))

module/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/health/MongoReactiveHealthIndicator.java

Lines changed: 0 additions & 54 deletions
This file was deleted.

module/spring-boot-data-mongodb/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,3 @@ org.springframework.boot.data.mongodb.autoconfigure.MongoDataAutoConfiguration
22
org.springframework.boot.data.mongodb.autoconfigure.MongoReactiveDataAutoConfiguration
33
org.springframework.boot.data.mongodb.autoconfigure.MongoReactiveRepositoriesAutoConfiguration
44
org.springframework.boot.data.mongodb.autoconfigure.MongoRepositoriesAutoConfiguration
5-
org.springframework.boot.data.mongodb.autoconfigure.health.MongoHealthContributorAutoConfiguration
6-
org.springframework.boot.data.mongodb.autoconfigure.health.MongoReactiveHealthContributorAutoConfiguration

module/spring-boot-mongodb/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ dependencies {
3333
optional(project(":core:spring-boot-autoconfigure"))
3434
optional(project(":core:spring-boot-docker-compose"))
3535
optional(project(":core:spring-boot-testcontainers"))
36+
optional(project(":module:spring-boot-health"))
3637
optional(project(":module:spring-boot-micrometer-metrics"))
3738
optional(project(":module:spring-boot-reactor"))
3839
optional("io.netty:netty-transport")
@@ -49,6 +50,7 @@ dependencies {
4950
testImplementation(project(":core:spring-boot-test"))
5051
testImplementation(project(":test-support:spring-boot-test-support"))
5152
testImplementation(testFixtures(project(":core:spring-boot-testcontainers")))
53+
testImplementation("io.projectreactor:reactor-test")
5254
testImplementation("org.springframework.data:spring-data-mongodb")
5355

5456
testRuntimeOnly("ch.qos.logback:logback-classic")

module/spring-boot-data-mongodb/src/dockerTest/java/org/springframework/boot/data/mongodb/health/MongoHealthIndicatorIntegrationTests.java renamed to module/spring-boot-mongodb/src/dockerTest/java/org/springframework/boot/mongodb/health/MongoHealthIndicatorIntegrationTests.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
package org.springframework.boot.data.mongodb.health;
17+
package org.springframework.boot.mongodb.health;
1818

1919
import com.mongodb.ConnectionString;
2020
import com.mongodb.MongoClientSettings;
@@ -23,6 +23,7 @@
2323
import com.mongodb.ServerApiVersion;
2424
import com.mongodb.client.MongoClient;
2525
import com.mongodb.client.MongoClients;
26+
import org.assertj.core.api.InstanceOfAssertFactories;
2627
import org.junit.jupiter.api.Test;
2728
import org.testcontainers.containers.MongoDBContainer;
2829
import org.testcontainers.junit.jupiter.Container;
@@ -31,7 +32,6 @@
3132
import org.springframework.boot.health.contributor.Health;
3233
import org.springframework.boot.health.contributor.Status;
3334
import org.springframework.boot.testsupport.container.TestImage;
34-
import org.springframework.data.mongodb.core.MongoTemplate;
3535

3636
import static org.assertj.core.api.Assertions.assertThat;
3737

@@ -49,13 +49,21 @@ class MongoHealthIndicatorIntegrationTests {
4949
@Test
5050
void standardApi() {
5151
Health health = mongoHealth();
52-
assertThat(health.getStatus()).isEqualTo(Status.UP);
52+
assertHealth(health);
5353
}
5454

5555
@Test
5656
void strictV1Api() {
5757
Health health = mongoHealth(ServerApi.builder().strict(true).version(ServerApiVersion.V1).build());
58+
assertHealth(health);
59+
}
60+
61+
private void assertHealth(Health health) {
5862
assertThat(health.getStatus()).isEqualTo(Status.UP);
63+
assertThat(health.getDetails()).containsKey("maxWireVersion");
64+
assertThat(health.getDetails()).hasEntrySatisfying("databases",
65+
(databases) -> assertThat(databases).asInstanceOf(InstanceOfAssertFactories.LIST)
66+
.containsExactlyInAnyOrder("local", "admin", "config"));
5967
}
6068

6169
private Health mongoHealth() {
@@ -70,7 +78,7 @@ private Health mongoHealth(ServerApi serverApi) {
7078
}
7179
MongoClientSettings settings = settingsBuilder.build();
7280
MongoClient mongoClient = MongoClients.create(settings);
73-
MongoHealthIndicator healthIndicator = new MongoHealthIndicator(new MongoTemplate(mongoClient, "db"));
81+
MongoHealthIndicator healthIndicator = new MongoHealthIndicator(mongoClient);
7482
return healthIndicator.health(true);
7583
}
7684

module/spring-boot-data-mongodb/src/dockerTest/java/org/springframework/boot/data/mongodb/health/MongoReactiveHealthIndicatorIntegrationTests.java renamed to module/spring-boot-mongodb/src/dockerTest/java/org/springframework/boot/mongodb/health/MongoReactiveHealthIndicatorIntegrationTests.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
package org.springframework.boot.data.mongodb.health;
17+
package org.springframework.boot.mongodb.health;
1818

1919
import java.time.Duration;
2020

@@ -25,6 +25,7 @@
2525
import com.mongodb.ServerApiVersion;
2626
import com.mongodb.reactivestreams.client.MongoClient;
2727
import com.mongodb.reactivestreams.client.MongoClients;
28+
import org.assertj.core.api.InstanceOfAssertFactories;
2829
import org.junit.jupiter.api.Test;
2930
import org.testcontainers.containers.MongoDBContainer;
3031
import org.testcontainers.junit.jupiter.Container;
@@ -33,7 +34,6 @@
3334
import org.springframework.boot.health.contributor.Health;
3435
import org.springframework.boot.health.contributor.Status;
3536
import org.springframework.boot.testsupport.container.TestImage;
36-
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
3737

3838
import static org.assertj.core.api.Assertions.assertThat;
3939

@@ -51,13 +51,13 @@ class MongoReactiveHealthIndicatorIntegrationTests {
5151
@Test
5252
void standardApi() {
5353
Health health = mongoHealth();
54-
assertThat(health.getStatus()).isEqualTo(Status.UP);
54+
assertHealth(health);
5555
}
5656

5757
@Test
5858
void strictV1Api() {
5959
Health health = mongoHealth(ServerApi.builder().strict(true).version(ServerApiVersion.V1).build());
60-
assertThat(health.getStatus()).isEqualTo(Status.UP);
60+
assertHealth(health);
6161
}
6262

6363
private Health mongoHealth() {
@@ -72,9 +72,16 @@ private Health mongoHealth(ServerApi serverApi) {
7272
}
7373
MongoClientSettings settings = settingsBuilder.build();
7474
MongoClient mongoClient = MongoClients.create(settings);
75-
MongoReactiveHealthIndicator healthIndicator = new MongoReactiveHealthIndicator(
76-
new ReactiveMongoTemplate(mongoClient, "db"));
75+
MongoReactiveHealthIndicator healthIndicator = new MongoReactiveHealthIndicator(mongoClient);
7776
return healthIndicator.health(true).block(Duration.ofSeconds(30));
7877
}
7978

79+
private void assertHealth(Health health) {
80+
assertThat(health.getStatus()).isEqualTo(Status.UP);
81+
assertThat(health.getDetails()).containsKey("maxWireVersion");
82+
assertThat(health.getDetails()).hasEntrySatisfying("databases",
83+
(databases) -> assertThat(databases).asInstanceOf(InstanceOfAssertFactories.LIST)
84+
.containsExactlyInAnyOrder("local", "admin", "config"));
85+
}
86+
8087
}

module/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/health/MongoHealthContributorAutoConfiguration.java renamed to module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/health/MongoHealthContributorAutoConfiguration.java

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,36 +14,35 @@
1414
* limitations under the License.
1515
*/
1616

17-
package org.springframework.boot.data.mongodb.autoconfigure.health;
17+
package org.springframework.boot.mongodb.autoconfigure.health;
18+
19+
import com.mongodb.client.MongoClient;
1820

1921
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
2022
import org.springframework.boot.autoconfigure.AutoConfiguration;
2123
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
2224
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
2325
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
2426
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
25-
import org.springframework.boot.data.mongodb.autoconfigure.MongoDataAutoConfiguration;
26-
import org.springframework.boot.data.mongodb.health.MongoHealthIndicator;
2727
import org.springframework.boot.health.autoconfigure.contributor.CompositeHealthContributorConfiguration;
2828
import org.springframework.boot.health.autoconfigure.contributor.ConditionalOnEnabledHealthIndicator;
2929
import org.springframework.boot.health.contributor.HealthContributor;
3030
import org.springframework.boot.mongodb.autoconfigure.MongoAutoConfiguration;
31+
import org.springframework.boot.mongodb.health.MongoHealthIndicator;
3132
import org.springframework.context.annotation.Bean;
32-
import org.springframework.data.mongodb.core.MongoTemplate;
3333

3434
/**
3535
* {@link EnableAutoConfiguration Auto-configuration} for {@link MongoHealthIndicator}.
3636
*
3737
* @author Stephane Nicoll
3838
* @since 4.0.0
3939
*/
40-
@AutoConfiguration(after = { MongoReactiveHealthContributorAutoConfiguration.class, MongoDataAutoConfiguration.class,
41-
MongoAutoConfiguration.class })
42-
@ConditionalOnClass({ MongoTemplate.class, MongoHealthIndicator.class, ConditionalOnEnabledHealthIndicator.class })
43-
@ConditionalOnBean(MongoTemplate.class)
40+
@AutoConfiguration(after = { MongoReactiveHealthContributorAutoConfiguration.class, MongoAutoConfiguration.class })
41+
@ConditionalOnClass({ MongoClient.class, MongoHealthIndicator.class, ConditionalOnEnabledHealthIndicator.class })
42+
@ConditionalOnBean(MongoClient.class)
4443
@ConditionalOnEnabledHealthIndicator("mongodb")
4544
public final class MongoHealthContributorAutoConfiguration
46-
extends CompositeHealthContributorConfiguration<MongoHealthIndicator, MongoTemplate> {
45+
extends CompositeHealthContributorConfiguration<MongoHealthIndicator, MongoClient> {
4746

4847
MongoHealthContributorAutoConfiguration() {
4948
super(MongoHealthIndicator::new);
@@ -52,7 +51,7 @@ public final class MongoHealthContributorAutoConfiguration
5251
@Bean
5352
@ConditionalOnMissingBean(name = { "mongoHealthIndicator", "mongoHealthContributor" })
5453
HealthContributor mongoHealthContributor(ConfigurableListableBeanFactory beanFactory) {
55-
return createContributor(beanFactory, MongoTemplate.class);
54+
return createContributor(beanFactory, MongoClient.class);
5655
}
5756

5857
}

module/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/health/MongoReactiveHealthContributorAutoConfiguration.java renamed to module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/health/MongoReactiveHealthContributorAutoConfiguration.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@
1414
* limitations under the License.
1515
*/
1616

17-
package org.springframework.boot.data.mongodb.autoconfigure.health;
17+
package org.springframework.boot.mongodb.autoconfigure.health;
1818

19+
import com.mongodb.reactivestreams.client.MongoClient;
1920
import reactor.core.publisher.Flux;
2021

2122
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
@@ -24,13 +25,12 @@
2425
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
2526
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
2627
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
27-
import org.springframework.boot.data.mongodb.autoconfigure.MongoReactiveDataAutoConfiguration;
28-
import org.springframework.boot.data.mongodb.health.MongoReactiveHealthIndicator;
2928
import org.springframework.boot.health.autoconfigure.contributor.CompositeReactiveHealthContributorConfiguration;
3029
import org.springframework.boot.health.autoconfigure.contributor.ConditionalOnEnabledHealthIndicator;
3130
import org.springframework.boot.health.contributor.ReactiveHealthContributor;
31+
import org.springframework.boot.mongodb.autoconfigure.MongoReactiveAutoConfiguration;
32+
import org.springframework.boot.mongodb.health.MongoReactiveHealthIndicator;
3233
import org.springframework.context.annotation.Bean;
33-
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
3434

3535
/**
3636
* {@link EnableAutoConfiguration Auto-configuration} for
@@ -39,13 +39,13 @@
3939
* @author Stephane Nicoll
4040
* @since 4.0.0
4141
*/
42-
@AutoConfiguration(after = MongoReactiveDataAutoConfiguration.class)
43-
@ConditionalOnClass({ ReactiveMongoTemplate.class, Flux.class, MongoReactiveHealthIndicator.class,
42+
@AutoConfiguration(after = MongoReactiveAutoConfiguration.class)
43+
@ConditionalOnClass({ MongoClient.class, Flux.class, MongoReactiveHealthIndicator.class,
4444
ConditionalOnEnabledHealthIndicator.class })
45-
@ConditionalOnBean(ReactiveMongoTemplate.class)
45+
@ConditionalOnBean(MongoClient.class)
4646
@ConditionalOnEnabledHealthIndicator("mongodb")
4747
public final class MongoReactiveHealthContributorAutoConfiguration
48-
extends CompositeReactiveHealthContributorConfiguration<MongoReactiveHealthIndicator, ReactiveMongoTemplate> {
48+
extends CompositeReactiveHealthContributorConfiguration<MongoReactiveHealthIndicator, MongoClient> {
4949

5050
MongoReactiveHealthContributorAutoConfiguration() {
5151
super(MongoReactiveHealthIndicator::new);
@@ -54,7 +54,7 @@ public final class MongoReactiveHealthContributorAutoConfiguration
5454
@Bean
5555
@ConditionalOnMissingBean(name = { "mongoHealthIndicator", "mongoHealthContributor" })
5656
ReactiveHealthContributor mongoHealthContributor(ConfigurableListableBeanFactory beanFactory) {
57-
return createContributor(beanFactory, ReactiveMongoTemplate.class);
57+
return createContributor(beanFactory, MongoClient.class);
5858
}
5959

6060
}

module/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/autoconfigure/health/package-info.java renamed to module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/autoconfigure/health/package-info.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,6 @@
1818
* Auto-configuration for Spring Data MongoDB health.
1919
*/
2020
@NullMarked
21-
package org.springframework.boot.data.mongodb.autoconfigure.health;
21+
package org.springframework.boot.mongodb.autoconfigure.health;
2222

2323
import org.jspecify.annotations.NullMarked;

module/spring-boot-data-mongodb/src/main/java/org/springframework/boot/data/mongodb/health/MongoHealthIndicator.java renamed to module/spring-boot-mongodb/src/main/java/org/springframework/boot/mongodb/health/MongoHealthIndicator.java

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,37 +14,51 @@
1414
* limitations under the License.
1515
*/
1616

17-
package org.springframework.boot.data.mongodb.health;
17+
package org.springframework.boot.mongodb.health;
1818

19+
import java.util.ArrayList;
20+
import java.util.LinkedHashMap;
21+
import java.util.List;
22+
import java.util.Map;
23+
24+
import com.mongodb.client.MongoClient;
1925
import org.bson.Document;
2026

2127
import org.springframework.boot.health.contributor.AbstractHealthIndicator;
2228
import org.springframework.boot.health.contributor.Health;
2329
import org.springframework.boot.health.contributor.HealthIndicator;
24-
import org.springframework.data.mongodb.core.MongoTemplate;
2530
import org.springframework.util.Assert;
2631

2732
/**
2833
* Simple implementation of a {@link HealthIndicator} returning status information for
29-
* Mongo data stores.
34+
* MongoDB.
3035
*
3136
* @author Christian Dupuis
3237
* @since 4.0.0
3338
*/
3439
public class MongoHealthIndicator extends AbstractHealthIndicator {
3540

36-
private final MongoTemplate mongoTemplate;
41+
private static final Document HELLO_COMMAND = Document.parse("{ hello: 1 }");
42+
43+
private final MongoClient mongoClient;
3744

38-
public MongoHealthIndicator(MongoTemplate mongoTemplate) {
45+
public MongoHealthIndicator(MongoClient mongoClient) {
3946
super("MongoDB health check failed");
40-
Assert.notNull(mongoTemplate, "'mongoTemplate' must not be null");
41-
this.mongoTemplate = mongoTemplate;
47+
Assert.notNull(mongoClient, "'mongoClient' must not be null");
48+
this.mongoClient = mongoClient;
4249
}
4350

4451
@Override
4552
protected void doHealthCheck(Health.Builder builder) throws Exception {
46-
Document result = this.mongoTemplate.executeCommand("{ hello: 1 }");
47-
builder.up().withDetail("maxWireVersion", result.getInteger("maxWireVersion"));
53+
Map<String, Object> details = new LinkedHashMap<>();
54+
List<String> databases = new ArrayList<>();
55+
details.put("databases", databases);
56+
this.mongoClient.listDatabaseNames().forEach((database) -> {
57+
Document result = this.mongoClient.getDatabase(database).runCommand(HELLO_COMMAND);
58+
databases.add(database);
59+
details.putIfAbsent("maxWireVersion", result.getInteger("maxWireVersion"));
60+
});
61+
builder.up().withDetails(details);
4862
}
4963

5064
}

0 commit comments

Comments
 (0)