diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactory.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactory.java index 4acd20772b..d66f11acbf 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactory.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactory.java @@ -54,15 +54,45 @@ public class MongoClientFactory { } /** - * Creates a {@link MongoClient} using the given {@code options}. If the configured - * port is zero, the value of the {@code local.mongo.port} property is used to - * configure the client. + * Creates a {@link MongoClient} using the given {@code options}. If the environment + * contains a {@code local.mongo.port} property, it is used to configure a client + * to an embedded MongoDB instance. * @param options the options * @return the Mongo client * @throws UnknownHostException if the configured host is unknown */ public MongoClient createMongoClient(MongoClientOptions options) throws UnknownHostException { + Integer embeddedPort = getEmbeddedPort(); + if (embeddedPort != null) { + return createEmbeddedMongoClient(options, embeddedPort); + } + return createNetworkMongoClient(options); + } + + private Integer getEmbeddedPort() { + if (this.environment != null) { + String localPort = this.environment.getProperty("local.mongo.port"); + if (localPort != null) { + return Integer.valueOf(localPort); + } + } + return null; + } + + private MongoClient createEmbeddedMongoClient(MongoClientOptions options, int port) { + if (options == null) { + options = MongoClientOptions.builder().build(); + } + String host = this.properties.getHost() == null ? "localhost" + : this.properties.getHost(); + return new MongoClient( + Collections.singletonList(new ServerAddress(host, port)), + Collections.emptyList(), options); + } + + private MongoClient createNetworkMongoClient(MongoClientOptions options) + throws UnknownHostException { if (hasCustomAddress() || hasCustomCredentials()) { if (this.properties.getUri() != null) { @@ -83,7 +113,8 @@ public class MongoClientFactory { } String host = this.properties.getHost() == null ? "localhost" : this.properties.getHost(); - int port = determinePort(); + int port = this.properties.getPort() != null ? this.properties.getPort() + : MongoProperties.DEFAULT_PORT; return new MongoClient( Collections.singletonList(new ServerAddress(host, port)), credentials, options); @@ -102,24 +133,6 @@ public class MongoClientFactory { && this.properties.getPassword() != null; } - private int determinePort() { - if (this.properties.getPort() == null) { - return MongoProperties.DEFAULT_PORT; - } - if (this.properties.getPort() == 0) { - if (this.environment != null) { - String localPort = this.environment.getProperty("local.mongo.port"); - if (localPort != null) { - return Integer.valueOf(localPort); - } - } - throw new IllegalStateException( - "spring.data.mongodb.port=0 and no local mongo port configuration " - + "is available"); - } - return this.properties.getPort(); - } - private Builder builder(MongoClientOptions options) { if (options != null) { return MongoClientOptions.builder(options); diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/ReactiveMongoClientFactory.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/ReactiveMongoClientFactory.java index 1a38ce47e4..dade96cf5e 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/ReactiveMongoClientFactory.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/ReactiveMongoClientFactory.java @@ -55,13 +55,43 @@ public class ReactiveMongoClientFactory { } /** - * Creates a {@link MongoClient} using the given {@code options}. If the configured - * port is zero, the value of the {@code local.mongo.port} property is used to - * configure the client. + * Creates a {@link MongoClient} using the given {@code settings}. If the environment + * contains a {@code local.mongo.port} property, it is used to configure a client + * to an embedded MongoDB instance. * @param settings the settings * @return the Mongo client */ public MongoClient createMongoClient(MongoClientSettings settings) { + Integer embeddedPort = getEmbeddedPort(); + if (embeddedPort != null) { + return createEmbeddedMongoClient(settings, embeddedPort); + } + return createNetworkMongoClient(settings); + } + + private Integer getEmbeddedPort() { + if (this.environment != null) { + String localPort = this.environment.getProperty("local.mongo.port"); + if (localPort != null) { + return Integer.valueOf(localPort); + } + } + return null; + } + + private MongoClient createEmbeddedMongoClient(MongoClientSettings settings, + int port) { + Builder builder = builder(settings); + String host = this.properties.getHost() == null ? "localhost" + : this.properties.getHost(); + ClusterSettings clusterSettings = ClusterSettings.builder() + .hosts(Collections.singletonList(new ServerAddress(host, port))) + .build(); + builder.clusterSettings(clusterSettings); + return MongoClients.create(builder.build()); + } + + private MongoClient createNetworkMongoClient(MongoClientSettings settings) { if (hasCustomAddress() || hasCustomCredentials()) { if (this.properties.getUri() != null) { throw new IllegalStateException("Invalid mongo configuration, " @@ -81,7 +111,8 @@ public class ReactiveMongoClientFactory { } String host = this.properties.getHost() == null ? "localhost" : this.properties.getHost(); - int port = determinePort(); + int port = this.properties.getPort() != null ? this.properties.getPort() + : MongoProperties.DEFAULT_PORT; ClusterSettings clusterSettings = ClusterSettings.builder() .hosts(Collections.singletonList(new ServerAddress(host, port))) .build(); @@ -136,24 +167,6 @@ public class ReactiveMongoClientFactory { && this.properties.getPassword() != null; } - private int determinePort() { - if (this.properties.getPort() == null) { - return MongoProperties.DEFAULT_PORT; - } - if (this.properties.getPort() == 0) { - if (this.environment != null) { - String localPort = this.environment.getProperty("local.mongo.port"); - if (localPort != null) { - return Integer.valueOf(localPort); - } - } - throw new IllegalStateException( - "spring.data.mongodb.port=0 and no local mongo port configuration " - + "is available"); - } - return this.properties.getPort(); - } - private Builder builder(MongoClientSettings settings) { if (settings == null) { return MongoClientSettings.builder(); diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoAutoConfiguration.java index d576c1d93d..406d65c147 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoAutoConfiguration.java @@ -161,7 +161,6 @@ public class EmbeddedMongoAutoConfiguration { } private void setEmbeddedPort(int port) { - this.properties.setPort(port); setPortProperty(this.context, port); } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactoryTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactoryTests.java index 6126d68474..4cae1b91fd 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactoryTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactoryTests.java @@ -30,6 +30,8 @@ import org.junit.rules.ExpectedException; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.mock.env.MockEnvironment; import org.springframework.test.util.ReflectionTestUtils; import static org.assertj.core.api.Assertions.assertThat; @@ -47,6 +49,8 @@ public class MongoClientFactoryTests { @Rule public ExpectedException thrown = ExpectedException.none(); + private MockEnvironment environment = new MockEnvironment(); + @Test public void portCanBeCustomized() throws UnknownHostException { MongoProperties properties = new MongoProperties(); @@ -138,9 +142,26 @@ public class MongoClientFactoryTests { createMongoClient(properties); } + @Test + public void uriIsIgnoredInEmbeddedMode() throws UnknownHostException { + MongoProperties properties = new MongoProperties(); + properties.setUri("mongodb://mongo.example.com:1234/mydb"); + this.environment.setProperty("local.mongo.port", "4000"); + MongoClient client = createMongoClient(properties, this.environment); + List allAddresses = extractServerAddresses(client); + assertThat(allAddresses).hasSize(1); + assertServerAddress(allAddresses.get(0), "localhost", 4000); + } + private MongoClient createMongoClient(MongoProperties properties) throws UnknownHostException { - return new MongoClientFactory(properties, null).createMongoClient(null); + return createMongoClient(properties, null); + } + + private MongoClient createMongoClient(MongoProperties properties, + Environment environment) + throws UnknownHostException { + return new MongoClientFactory(properties, environment).createMongoClient(null); } private List extractServerAddresses(MongoClient client) { diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/ReactiveMongoClientFactoryTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/ReactiveMongoClientFactoryTests.java index 651d733ef2..ac36e7a207 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/ReactiveMongoClientFactoryTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/ReactiveMongoClientFactoryTests.java @@ -28,18 +28,24 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import org.springframework.core.env.Environment; +import org.springframework.mock.env.MockEnvironment; + import static org.assertj.core.api.Assertions.assertThat; /** * Tests for {@link ReactiveMongoClientFactory}. * * @author Mark Paluch + * @author Stephane Nicoll */ public class ReactiveMongoClientFactoryTests { @Rule public ExpectedException thrown = ExpectedException.none(); + private MockEnvironment environment = new MockEnvironment(); + @Test public void portCanBeCustomized() throws UnknownHostException { MongoProperties properties = new MongoProperties(); @@ -131,8 +137,24 @@ public class ReactiveMongoClientFactoryTests { createMongoClient(properties); } + @Test + public void uriIsIgnoredInEmbeddedMode() throws UnknownHostException { + MongoProperties properties = new MongoProperties(); + properties.setUri("mongodb://mongo.example.com:1234/mydb"); + this.environment.setProperty("local.mongo.port", "4000"); + MongoClient client = createMongoClient(properties, this.environment); + List allAddresses = extractServerAddresses(client); + assertThat(allAddresses).hasSize(1); + assertServerAddress(allAddresses.get(0), "localhost", 4000); + } + private MongoClient createMongoClient(MongoProperties properties) { - return new ReactiveMongoClientFactory(properties, null).createMongoClient(null); + return createMongoClient(properties, this.environment); + } + + private MongoClient createMongoClient(MongoProperties properties, + Environment environment) { + return new ReactiveMongoClientFactory(properties, environment).createMongoClient(null); } private List extractServerAddresses(MongoClient client) {