diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactorySupport.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactorySupport.java index a990015733b..a529f36a2ac 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactorySupport.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactorySupport.java @@ -68,14 +68,15 @@ public abstract class MongoClientFactorySupport { applyUuidRepresentation(settingsBuilder); applyHostAndPort(settingsBuilder); applyCredentials(settingsBuilder); + applyReplicaSet(settingsBuilder); customize(settingsBuilder); return settingsBuilder.build(); } private void validateConfiguration() { - if (hasCustomAddress() || hasCustomCredentials()) { + if (hasCustomAddress() || hasCustomCredentials() || hasReplicaSet()) { Assert.state(this.properties.getUri() == null, - "Invalid mongo configuration, either uri or host/port/credentials must be specified"); + "Invalid mongo configuration, either uri or host/port/credentials/replicaSet must be specified"); } } @@ -109,6 +110,13 @@ public abstract class MongoClientFactorySupport { } } + private void applyReplicaSet(Builder builder) { + if (hasReplicaSet()) { + builder.applyToClusterSettings( + (cluster) -> cluster.requiredReplicaSetName(this.properties.getReplicaSetName())); + } + } + private void customize(MongoClientSettings.Builder builder) { for (MongoClientSettingsBuilderCustomizer customizer : this.builderCustomizers) { customizer.customize(builder); @@ -137,6 +145,10 @@ public abstract class MongoClientFactorySupport { return this.properties.getUsername() != null && this.properties.getPassword() != null; } + private boolean hasReplicaSet() { + return this.properties.getReplicaSetName() != null; + } + private boolean hasCustomAddress() { return this.properties.getHost() != null || this.properties.getPort() != null; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoProperties.java index 50963326008..0224d9b12ec 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoProperties.java @@ -59,7 +59,8 @@ public class MongoProperties { private Integer port = null; /** - * Mongo database URI. Cannot be set with host, port and credentials. + * Mongo database URI. Cannot be set with host, port, credentials and replica set + * name. */ private String uri; @@ -81,7 +82,6 @@ public class MongoProperties { /** * Login user of the mongo server. Cannot be set with URI. */ - private String username; /** @@ -89,6 +89,11 @@ public class MongoProperties { */ private char[] password; + /** + * Required replica set name for the cluster. Cannot be set with URI. + */ + private String replicaSetName; + /** * Fully qualified name of the FieldNamingStrategy to use. */ @@ -144,6 +149,14 @@ public class MongoProperties { this.password = password; } + public String getReplicaSetName() { + return this.replicaSetName; + } + + public void setReplicaSetName(String replicaSetName) { + this.replicaSetName = replicaSetName; + } + public Class getFieldNamingStrategy() { return this.fieldNamingStrategy; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactorySupportTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactorySupportTests.java index 510dfbbb465..bf49f3c4bcd 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactorySupportTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactorySupportTests.java @@ -51,9 +51,9 @@ import static org.mockito.Mockito.verify; */ abstract class MongoClientFactorySupportTests { - private MongoProperties properties = new MongoProperties(); + private final MongoProperties properties = new MongoProperties(); - private MockEnvironment environment = new MockEnvironment(); + private final MockEnvironment environment = new MockEnvironment(); @Test void canBindCharArrayPassword() { @@ -128,6 +128,13 @@ abstract class MongoClientFactorySupportTests { assertMongoCredential(getClientSettings(client).getCredential(), "user", "secret", "test"); } + @Test + void replicaSetCanBeCustomized() { + this.properties.setReplicaSetName("test"); + T client = createMongoClient(); + assertThat(getClientSettings(client).getClusterSettings().getRequiredReplicaSetName()).isEqualTo("test"); + } + @Test void databaseCanBeCustomized() { this.properties.setDatabase("foo"); @@ -193,7 +200,15 @@ abstract class MongoClientFactorySupportTests { this.properties.setUsername("user"); this.properties.setPassword("secret".toCharArray()); assertThatIllegalStateException().isThrownBy(this::createMongoClient).withMessageContaining( - "Invalid mongo configuration, either uri or host/port/credentials must be specified"); + "Invalid mongo configuration, either uri or host/port/credentials/replicaSet must be specified"); + } + + @Test + void uriCannotBeSetWithReplicaSetName() { + this.properties.setUri("mongodb://127.0.0.1:1234/mydb"); + this.properties.setReplicaSetName("test"); + assertThatIllegalStateException().isThrownBy(this::createMongoClient).withMessageContaining( + "Invalid mongo configuration, either uri or host/port/credentials/replicaSet must be specified"); } @Test @@ -202,7 +217,7 @@ abstract class MongoClientFactorySupportTests { this.properties.setHost("localhost"); this.properties.setPort(4567); assertThatIllegalStateException().isThrownBy(this::createMongoClient).withMessageContaining( - "Invalid mongo configuration, either uri or host/port/credentials must be specified"); + "Invalid mongo configuration, either uri or host/port/credentials/replicaSet must be specified"); } @Test @@ -265,6 +280,10 @@ abstract class MongoClientFactorySupportTests { assertThat(properties.isAutoIndexCreation()).isTrue(); } + private List getAllAddresses(T client) { + return getClientSettings(client).getClusterSettings().getHosts(); + } + protected T createMongoClient() { return createMongoClient(this.properties, this.environment, null, null); } @@ -283,8 +302,6 @@ abstract class MongoClientFactorySupportTests { protected abstract MongoClientSettings getClientSettings(T client); - protected abstract List getAllAddresses(T client); - protected void assertServerAddress(ServerAddress serverAddress, String expectedHost, int expectedPort) { assertThat(serverAddress.getHost()).isEqualTo(expectedHost); assertThat(serverAddress.getPort()).isEqualTo(expectedPort); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactoryTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactoryTests.java index 2f2c99e4e68..baafeedce19 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactoryTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactoryTests.java @@ -19,7 +19,6 @@ package org.springframework.boot.autoconfigure.mongo; import java.util.List; import com.mongodb.MongoClientSettings; -import com.mongodb.ServerAddress; import com.mongodb.client.MongoClient; import org.springframework.core.env.Environment; @@ -42,11 +41,6 @@ class MongoClientFactoryTests extends MongoClientFactorySupportTests getAllAddresses(MongoClient client) { - return client.getClusterDescription().getClusterSettings().getHosts(); - } - @Override protected MongoClientSettings getClientSettings(MongoClient client) { return (MongoClientSettings) ReflectionTestUtils.getField(client, "settings"); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/ReactiveMongoClientFactoryTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/ReactiveMongoClientFactoryTests.java index cdf98065315..7cac14aa41e 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/ReactiveMongoClientFactoryTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/ReactiveMongoClientFactoryTests.java @@ -19,8 +19,6 @@ package org.springframework.boot.autoconfigure.mongo; import java.util.List; import com.mongodb.MongoClientSettings; -import com.mongodb.ServerAddress; -import com.mongodb.connection.ClusterSettings; import com.mongodb.internal.async.client.AsyncMongoClient; import com.mongodb.reactivestreams.client.MongoClient; @@ -42,13 +40,6 @@ class ReactiveMongoClientFactoryTests extends MongoClientFactorySupportTests getAllAddresses(MongoClient client) { - MongoClientSettings settings = getClientSettings(client); - ClusterSettings clusterSettings = settings.getClusterSettings(); - return clusterSettings.getHosts(); - } - @Override protected MongoClientSettings getClientSettings(MongoClient client) { AsyncMongoClient wrapped = (AsyncMongoClient) ReflectionTestUtils.getField(client, "wrapped");