diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/build.gradle b/spring-boot-project/spring-boot-actuator-autoconfigure/build.gradle index 85bda5f0e5..efe3883669 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/build.gradle +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/build.gradle @@ -83,8 +83,8 @@ dependencies { optional("org.influxdb:influxdb-java") optional("org.jolokia:jolokia-core") optional("org.liquibase:liquibase-core") - optional("org.mongodb:mongodb-driver-async") optional("org.mongodb:mongodb-driver-reactivestreams") + optional("org.mongodb:mongodb-driver-sync") optional("org.springframework:spring-jdbc") optional("org.springframework:spring-jms") optional("org.springframework:spring-messaging") diff --git a/spring-boot-project/spring-boot-actuator/build.gradle b/spring-boot-project/spring-boot-actuator/build.gradle index 3dc994b9b8..06ce49be13 100644 --- a/spring-boot-project/spring-boot-actuator/build.gradle +++ b/spring-boot-project/spring-boot-actuator/build.gradle @@ -43,8 +43,8 @@ dependencies { optional("org.hibernate.validator:hibernate-validator") optional("org.influxdb:influxdb-java") optional("org.liquibase:liquibase-core") - optional("org.mongodb:mongodb-driver-async") optional("org.mongodb:mongodb-driver-reactivestreams") + optional("org.mongodb:mongodb-driver-sync") optional("org.springframework:spring-jdbc") optional("org.springframework:spring-messaging") optional("org.springframework:spring-webflux") diff --git a/spring-boot-project/spring-boot-autoconfigure/build.gradle b/spring-boot-project/spring-boot-autoconfigure/build.gradle index 712a7e0aa4..af71bd60c2 100644 --- a/spring-boot-project/spring-boot-autoconfigure/build.gradle +++ b/spring-boot-project/spring-boot-autoconfigure/build.gradle @@ -95,8 +95,8 @@ dependencies { optional("org.jooq:jooq") optional("org.liquibase:liquibase-core") optional("org.messaginghub:pooled-jms") - optional("org.mongodb:mongodb-driver-async") optional("org.mongodb:mongodb-driver-reactivestreams") + optional("org.mongodb:mongodb-driver-sync") optional("org.quartz-scheduler:quartz") optional("org.springframework:spring-jdbc") optional("org.springframework.integration:spring-integration-core") diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoClientDependsOnBeanFactoryPostProcessor.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoClientDependsOnBeanFactoryPostProcessor.java index 5b0288ff8c..86b5674ef9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoClientDependsOnBeanFactoryPostProcessor.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoClientDependsOnBeanFactoryPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * 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. @@ -16,7 +16,7 @@ package org.springframework.boot.autoconfigure.data.mongo; -import com.mongodb.MongoClient; +import com.mongodb.client.MongoClient; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfiguration.java index 358a3f33e2..4d5cc03a71 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * 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. @@ -16,7 +16,7 @@ package org.springframework.boot.autoconfigure.data.mongo; -import com.mongodb.MongoClient; +import com.mongodb.client.MongoClient; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -48,9 +48,10 @@ import org.springframework.data.mongodb.gridfs.GridFsTemplate; * @since 1.1.0 */ @Configuration(proxyBeanMethods = false) -@ConditionalOnClass({ MongoClient.class, com.mongodb.client.MongoClient.class, MongoTemplate.class }) +@ConditionalOnClass({ MongoClient.class, MongoTemplate.class }) @EnableConfigurationProperties(MongoProperties.class) -@Import({ MongoDataConfiguration.class, MongoDbFactoryConfiguration.class, MongoDbFactoryDependentConfiguration.class }) +@Import({ MongoDataConfiguration.class, MongoDatabaseFactoryConfiguration.class, + MongoDatabaseFactoryDependentConfiguration.class }) @AutoConfigureAfter(MongoAutoConfiguration.class) public class MongoDataAutoConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryConfiguration.java new file mode 100644 index 0000000000..544bfcc17f --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryConfiguration.java @@ -0,0 +1,46 @@ +/* + * 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.autoconfigure.data.mongo; + +import com.mongodb.client.MongoClient; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; +import org.springframework.boot.autoconfigure.mongo.MongoProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.mongodb.MongoDatabaseFactory; +import org.springframework.data.mongodb.core.MongoDatabaseFactorySupport; +import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory; + +/** + * Configuration for a {@link MongoDatabaseFactory}. + * + * @author Andy Wilkinson + * @author Stephane Nicoll + */ +@Configuration(proxyBeanMethods = false) +@ConditionalOnMissingBean(MongoDatabaseFactory.class) +@ConditionalOnSingleCandidate(MongoClient.class) +class MongoDatabaseFactoryConfiguration { + + @Bean + MongoDatabaseFactorySupport mongoDatabaseFactory(MongoClient mongoClient, MongoProperties properties) { + return new SimpleMongoClientDatabaseFactory(mongoClient, properties.getMongoClientDatabase()); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDbFactoryDependentConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryDependentConfiguration.java similarity index 65% rename from spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDbFactoryDependentConfiguration.java rename to spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryDependentConfiguration.java index 9c8e7d886a..014fa4b1c9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDbFactoryDependentConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryDependentConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * 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. @@ -17,7 +17,6 @@ package org.springframework.boot.autoconfigure.data.mongo; import com.mongodb.ClientSessionOptions; -import com.mongodb.DB; import com.mongodb.client.ClientSession; import com.mongodb.client.MongoDatabase; @@ -28,7 +27,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.dao.DataAccessException; import org.springframework.dao.support.PersistenceExceptionTranslator; -import org.springframework.data.mongodb.MongoDbFactory; +import org.springframework.data.mongodb.MongoDatabaseFactory; import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.convert.DbRefResolver; @@ -43,29 +42,29 @@ import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** - * Configuration for Mongo-related beans that depend on a {@link MongoDbFactory}. + * Configuration for Mongo-related beans that depend on a {@link MongoDatabaseFactory}. * * @author Andy Wilkinson */ @Configuration(proxyBeanMethods = false) -@ConditionalOnBean(MongoDbFactory.class) -class MongoDbFactoryDependentConfiguration { +@ConditionalOnBean(MongoDatabaseFactory.class) +class MongoDatabaseFactoryDependentConfiguration { private final MongoProperties properties; - MongoDbFactoryDependentConfiguration(MongoProperties properties) { + MongoDatabaseFactoryDependentConfiguration(MongoProperties properties) { this.properties = properties; } @Bean @ConditionalOnMissingBean(MongoOperations.class) - MongoTemplate mongoTemplate(MongoDbFactory mongoDbFactory, MongoConverter converter) { - return new MongoTemplate(mongoDbFactory, converter); + MongoTemplate mongoTemplate(MongoDatabaseFactory factory, MongoConverter converter) { + return new MongoTemplate(factory, converter); } @Bean @ConditionalOnMissingBean(MongoConverter.class) - MappingMongoConverter mappingMongoConverter(MongoDbFactory factory, MongoMappingContext context, + MappingMongoConverter mappingMongoConverter(MongoDatabaseFactory factory, MongoMappingContext context, MongoCustomConversions conversions) { DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory); MappingMongoConverter mappingConverter = new MappingMongoConverter(dbRefResolver, context); @@ -75,61 +74,55 @@ class MongoDbFactoryDependentConfiguration { @Bean @ConditionalOnMissingBean(GridFsOperations.class) - GridFsTemplate gridFsTemplate(MongoDbFactory mongoDbFactory, MongoTemplate mongoTemplate) { - return new GridFsTemplate(new GridFsMongoDbFactory(mongoDbFactory, this.properties), + GridFsTemplate gridFsTemplate(MongoDatabaseFactory factory, MongoTemplate mongoTemplate) { + return new GridFsTemplate(new GridFsMongoDatabaseFactory(factory, this.properties), mongoTemplate.getConverter()); } /** - * {@link MongoDbFactory} decorator to respect + * {@link MongoDatabaseFactory} decorator to respect * {@link MongoProperties#getGridFsDatabase()} if set. */ - static class GridFsMongoDbFactory implements MongoDbFactory { + static class GridFsMongoDatabaseFactory implements MongoDatabaseFactory { - private final MongoDbFactory mongoDbFactory; + private final MongoDatabaseFactory mongoDatabaseFactory; private final MongoProperties properties; - GridFsMongoDbFactory(MongoDbFactory mongoDbFactory, MongoProperties properties) { - Assert.notNull(mongoDbFactory, "MongoDbFactory must not be null"); + GridFsMongoDatabaseFactory(MongoDatabaseFactory mongoDatabaseFactory, MongoProperties properties) { + Assert.notNull(mongoDatabaseFactory, "MongoDatabaseFactory must not be null"); Assert.notNull(properties, "Properties must not be null"); - this.mongoDbFactory = mongoDbFactory; + this.mongoDatabaseFactory = mongoDatabaseFactory; this.properties = properties; } @Override - public MongoDatabase getDb() throws DataAccessException { + public MongoDatabase getMongoDatabase() throws DataAccessException { String gridFsDatabase = this.properties.getGridFsDatabase(); if (StringUtils.hasText(gridFsDatabase)) { - return this.mongoDbFactory.getDb(gridFsDatabase); + return this.mongoDatabaseFactory.getMongoDatabase(gridFsDatabase); } - return this.mongoDbFactory.getDb(); + return this.mongoDatabaseFactory.getMongoDatabase(); } @Override - public MongoDatabase getDb(String dbName) throws DataAccessException { - return this.mongoDbFactory.getDb(dbName); + public MongoDatabase getMongoDatabase(String dbName) throws DataAccessException { + return this.mongoDatabaseFactory.getMongoDatabase(dbName); } @Override public PersistenceExceptionTranslator getExceptionTranslator() { - return this.mongoDbFactory.getExceptionTranslator(); - } - - @Override - @Deprecated - public DB getLegacyDb() { - return this.mongoDbFactory.getLegacyDb(); + return this.mongoDatabaseFactory.getExceptionTranslator(); } @Override public ClientSession getSession(ClientSessionOptions options) { - return this.mongoDbFactory.getSession(options); + return this.mongoDatabaseFactory.getSession(options); } @Override - public MongoDbFactory withSession(ClientSession session) { - return this.mongoDbFactory.withSession(session); + public MongoDatabaseFactory withSession(ClientSession session) { + return this.mongoDatabaseFactory.withSession(session); } } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDbFactoryConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDbFactoryConfiguration.java deleted file mode 100644 index e8bc2dded1..0000000000 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoDbFactoryConfiguration.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2012-2019 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.autoconfigure.data.mongo; - -import com.mongodb.MongoClient; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.data.mongo.MongoDbFactoryConfiguration.AnyMongoClientAvailable; -import org.springframework.boot.autoconfigure.mongo.MongoProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Conditional; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.mongodb.MongoDbFactory; -import org.springframework.data.mongodb.core.MongoDbFactorySupport; -import org.springframework.data.mongodb.core.SimpleMongoClientDbFactory; -import org.springframework.data.mongodb.core.SimpleMongoDbFactory; - -/** - * Configuration for a {@link MongoDbFactory}. - * - * @author Andy Wilkinson - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnMissingBean(MongoDbFactory.class) -@Conditional(AnyMongoClientAvailable.class) -class MongoDbFactoryConfiguration { - - @Bean - MongoDbFactorySupport mongoDbFactory(ObjectProvider mongo, - ObjectProvider mongoClient, MongoProperties properties) { - MongoClient preferredClient = mongo.getIfAvailable(); - if (preferredClient != null) { - return new SimpleMongoDbFactory(preferredClient, properties.getMongoClientDatabase()); - } - com.mongodb.client.MongoClient fallbackClient = mongoClient.getIfAvailable(); - if (fallbackClient != null) { - return new SimpleMongoClientDbFactory(fallbackClient, properties.getMongoClientDatabase()); - } - throw new IllegalStateException("Expected to find at least one MongoDB client."); - } - - /** - * Check if either a {@link MongoClient com.mongodb.MongoClient} or - * {@link com.mongodb.client.MongoClient com.mongodb.client.MongoClient} bean is - * available. - */ - static class AnyMongoClientAvailable extends AnyNestedCondition { - - AnyMongoClientAvailable() { - super(ConfigurationPhase.REGISTER_BEAN); - } - - @ConditionalOnBean(MongoClient.class) - static class PreferredClientAvailable { - - } - - @ConditionalOnBean(com.mongodb.client.MongoClient.class) - static class FallbackClientAvailable { - - } - - } - -} 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 a9ec8d7f5f..ac205cd7a8 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 @@ -97,9 +97,9 @@ public class MongoReactiveDataAutoConfiguration { @Bean @ConditionalOnMissingBean(ReactiveGridFsOperations.class) - public ReactiveGridFsTemplate reactiveGridFsTemplate(ReactiveMongoDatabaseFactory reactiveMongoDbFactory, + public ReactiveGridFsTemplate reactiveGridFsTemplate(ReactiveMongoDatabaseFactory reactiveMongoDatabaseFactory, MappingMongoConverter mappingMongoConverter, DataBufferFactory dataBufferFactory) { - return new ReactiveGridFsTemplate(dataBufferFactory, reactiveMongoDbFactory, mappingMongoConverter, null); + return new ReactiveGridFsTemplate(dataBufferFactory, reactiveMongoDatabaseFactory, mappingMongoConverter, null); } } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoRepositoriesAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoRepositoriesAutoConfiguration.java index 527042576c..eb0cc5f7e4 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoRepositoriesAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoRepositoriesAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * 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. @@ -16,7 +16,7 @@ package org.springframework.boot.autoconfigure.data.mongo; -import com.mongodb.MongoClient; +import com.mongodb.client.MongoClient; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoAutoConfiguration.java index 7e4d882df4..69a261920a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * 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. @@ -16,8 +16,8 @@ package org.springframework.boot.autoconfigure.mongo; -import com.mongodb.MongoClient; -import com.mongodb.MongoClientOptions; +import com.mongodb.MongoClientSettings; +import com.mongodb.client.MongoClient; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -41,14 +41,14 @@ import org.springframework.core.env.Environment; @Configuration(proxyBeanMethods = false) @ConditionalOnClass(MongoClient.class) @EnableConfigurationProperties(MongoProperties.class) -@ConditionalOnMissingBean(type = "org.springframework.data.mongodb.MongoDbFactory") +@ConditionalOnMissingBean(type = "org.springframework.data.mongodb.MongoDatabaseFactory") public class MongoAutoConfiguration { @Bean - @ConditionalOnMissingBean(type = { "com.mongodb.MongoClient", "com.mongodb.client.MongoClient" }) - public MongoClient mongo(MongoProperties properties, ObjectProvider options, + @ConditionalOnMissingBean(MongoClient.class) + public MongoClient mongo(MongoProperties properties, ObjectProvider settings, Environment environment) { - return new MongoClientFactory(properties, environment).createMongoClient(options.getIfAvailable()); + return new MongoClientFactory(properties, environment).createMongoClient(settings.getIfAvailable()); } } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactory.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactory.java index 0717a51d84..5e58435046 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactory.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/MongoClientFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * 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. @@ -19,12 +19,13 @@ package org.springframework.boot.autoconfigure.mongo; import java.util.Collections; import java.util.List; -import com.mongodb.MongoClient; -import com.mongodb.MongoClientOptions; -import com.mongodb.MongoClientOptions.Builder; -import com.mongodb.MongoClientURI; +import com.mongodb.ConnectionString; +import com.mongodb.MongoClientSettings; +import com.mongodb.MongoClientSettings.Builder; import com.mongodb.MongoCredential; import com.mongodb.ServerAddress; +import com.mongodb.client.MongoClient; +import com.mongodb.client.MongoClients; import org.springframework.core.env.Environment; @@ -53,18 +54,21 @@ public class MongoClientFactory { } /** - * 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 + * Creates a {@link MongoClient} using the given {@link MongoClientSettings 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(MongoClientOptions options) { + public MongoClient createMongoClient(MongoClientSettings settings) { + Builder settingsBuilder = (settings != null) ? MongoClientSettings.builder(settings) + : MongoClientSettings.builder(); + settingsBuilder.uuidRepresentation(this.properties.getUuidRepresentation()); Integer embeddedPort = getEmbeddedPort(); if (embeddedPort != null) { - return createEmbeddedMongoClient(options, embeddedPort); + return createEmbeddedMongoClient(settingsBuilder, embeddedPort); } - return createNetworkMongoClient(options); + return createNetworkMongoClient(settingsBuilder); } private Integer getEmbeddedPort() { @@ -77,35 +81,37 @@ public class MongoClientFactory { return null; } - private MongoClient createEmbeddedMongoClient(MongoClientOptions options, int port) { - if (options == null) { - options = MongoClientOptions.builder().build(); - } + private MongoClient createEmbeddedMongoClient(Builder settings, int port) { String host = (this.properties.getHost() != null) ? this.properties.getHost() : "localhost"; - return new MongoClient(Collections.singletonList(new ServerAddress(host, port)), options); + settings.applyToClusterSettings( + (cluster) -> cluster.hosts(Collections.singletonList(new ServerAddress(host, port)))); + return MongoClients.create(settings.build()); } - private MongoClient createNetworkMongoClient(MongoClientOptions options) { + private MongoClient createNetworkMongoClient(Builder settings) { MongoProperties properties = this.properties; if (properties.getUri() != null) { - return createMongoClient(properties.getUri(), options); + return createMongoClient(properties.getUri(), settings); } if (hasCustomAddress() || hasCustomCredentials()) { - if (options == null) { - options = MongoClientOptions.builder().build(); + if (hasCustomCredentials()) { + String database = (this.properties.getAuthenticationDatabase() != null) + ? this.properties.getAuthenticationDatabase() : this.properties.getMongoClientDatabase(); + settings.credential((MongoCredential.createCredential(this.properties.getUsername(), database, + this.properties.getPassword()))); } - MongoCredential credentials = getCredentials(properties); String host = getValue(properties.getHost(), "localhost"); int port = getValue(properties.getPort(), MongoProperties.DEFAULT_PORT); List seeds = Collections.singletonList(new ServerAddress(host, port)); - return (credentials != null) ? new MongoClient(seeds, credentials, options) - : new MongoClient(seeds, options); + settings.applyToClusterSettings((cluster) -> cluster.hosts(seeds)); + return MongoClients.create(settings.build()); } - return createMongoClient(MongoProperties.DEFAULT_URI, options); + return createMongoClient(MongoProperties.DEFAULT_URI, settings); } - private MongoClient createMongoClient(String uri, MongoClientOptions options) { - return new MongoClient(new MongoClientURI(uri, builder(options))); + private MongoClient createMongoClient(String uri, Builder settings) { + settings.applyConnectionString(new ConnectionString(uri)); + return MongoClients.create(settings.build()); } private T getValue(T value, T fallback) { @@ -116,25 +122,8 @@ public class MongoClientFactory { return this.properties.getHost() != null || this.properties.getPort() != null; } - private MongoCredential getCredentials(MongoProperties properties) { - if (!hasCustomCredentials()) { - return null; - } - String username = properties.getUsername(); - String database = getValue(properties.getAuthenticationDatabase(), properties.getMongoClientDatabase()); - char[] password = properties.getPassword(); - return MongoCredential.createCredential(username, database, password); - } - private boolean hasCustomCredentials() { return this.properties.getUsername() != null && this.properties.getPassword() != null; } - private Builder builder(MongoClientOptions options) { - if (options != null) { - return MongoClientOptions.builder(options); - } - return MongoClientOptions.builder(); - } - } 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 a19b605927..5096332600 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * 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. @@ -16,7 +16,8 @@ package org.springframework.boot.autoconfigure.mongo; -import com.mongodb.MongoClientURI; +import com.mongodb.ConnectionString; +import org.bson.UuidRepresentation; import org.springframework.boot.context.properties.ConfigurationProperties; @@ -93,6 +94,11 @@ public class MongoProperties { */ private Class fieldNamingStrategy; + /** + * Representation to use when converting a UUID to a BSON binary value. + */ + private UuidRepresentation uuidRepresentation = UuidRepresentation.JAVA_LEGACY; + /** * Whether to enable auto-index creation. */ @@ -146,6 +152,14 @@ public class MongoProperties { this.fieldNamingStrategy = fieldNamingStrategy; } + public UuidRepresentation getUuidRepresentation() { + return this.uuidRepresentation; + } + + public void setUuidRepresentation(UuidRepresentation uuidRepresentation) { + this.uuidRepresentation = uuidRepresentation; + } + public String getUri() { return this.uri; } @@ -178,7 +192,7 @@ public class MongoProperties { if (this.database != null) { return this.database; } - return new MongoClientURI(determineUri()).getDatabase(); + return new ConnectionString(determineUri()).getDatabase(); } public Boolean isAutoIndexCreation() { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/ReactiveMongoClientFactory.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/ReactiveMongoClientFactory.java index 24aa30f942..e1e83c74b6 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/ReactiveMongoClientFactory.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/ReactiveMongoClientFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * 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. @@ -119,6 +119,7 @@ public class ReactiveMongoClientFactory { } private MongoClient createMongoClient(Builder builder) { + builder.uuidRepresentation(this.properties.getUuidRepresentation()); customize(builder); return MongoClients.create(builder.build()); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoAutoConfiguration.java index b0fb3f57f2..c7198628b2 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * 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. @@ -23,7 +23,7 @@ import java.util.HashMap; import java.util.Map; import java.util.stream.Stream; -import com.mongodb.MongoClient; +import com.mongodb.client.MongoClient; import de.flapdoodle.embed.mongo.Command; import de.flapdoodle.embed.mongo.MongodExecutable; import de.flapdoodle.embed.mongo.MongodStarter; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json index b02a356bd1..932bbbc1b9 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -398,6 +398,10 @@ "name": "spring.data.mongodb.uri", "defaultValue": "mongodb://localhost/test" }, + { + "name": "spring.data.mongodb.uuid-representation", + "defaultValue": "java-legacy" + }, { "name": "spring.data.neo4j.auto-index", "defaultValue": "none" diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfigurationTests.java index 2e0a80d115..649e61f61a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoDataAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * 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. @@ -20,7 +20,7 @@ import java.time.LocalDateTime; import java.util.Arrays; import java.util.Set; -import com.mongodb.MongoClient; +import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClients; import org.junit.jupiter.api.Test; @@ -40,10 +40,9 @@ import org.springframework.core.convert.converter.Converter; import org.springframework.data.mapping.model.CamelCaseAbbreviatingFieldNamingStrategy; import org.springframework.data.mapping.model.FieldNamingStrategy; import org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy; -import org.springframework.data.mongodb.MongoDbFactory; +import org.springframework.data.mongodb.MongoDatabaseFactory; import org.springframework.data.mongodb.core.MongoTemplate; -import org.springframework.data.mongodb.core.SimpleMongoClientDbFactory; -import org.springframework.data.mongodb.core.SimpleMongoDbFactory; +import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory; import org.springframework.data.mongodb.core.convert.MongoCustomConversions; import org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; @@ -169,24 +168,24 @@ class MongoDataAutoConfigurationTests { } @Test - void createsMongoDbFactoryForPreferredMongoClient() { + void createsMongoDatabaseFactoryForPreferredMongoClient() { this.contextRunner.run((context) -> { - MongoDbFactory dbFactory = context.getBean(MongoDbFactory.class); - assertThat(dbFactory).isInstanceOf(SimpleMongoDbFactory.class); + MongoDatabaseFactory dbFactory = context.getBean(MongoDatabaseFactory.class); + assertThat(dbFactory).isInstanceOf(SimpleMongoClientDatabaseFactory.class); }); } @Test - void createsMongoDbFactoryForFallbackMongoClient() { + void createsMongoDatabaseFactoryForFallbackMongoClient() { this.contextRunner.withUserConfiguration(FallbackMongoClientConfiguration.class).run((context) -> { - MongoDbFactory dbFactory = context.getBean(MongoDbFactory.class); - assertThat(dbFactory).isInstanceOf(SimpleMongoClientDbFactory.class); + MongoDatabaseFactory dbFactory = context.getBean(MongoDatabaseFactory.class); + assertThat(dbFactory).isInstanceOf(SimpleMongoClientDatabaseFactory.class); }); } @Test - void autoConfiguresIfUserProvidesMongoDbFactoryButNoClient() { - this.contextRunner.withUserConfiguration(MongoDbFactoryConfiguration.class) + void autoConfiguresIfUserProvidesMongoDatabaseFactoryButNoClient() { + this.contextRunner.withUserConfiguration(MongoDatabaseFactoryConfiguration.class) .run((context) -> assertThat(context).hasSingleBean(MongoTemplate.class)); } @@ -223,11 +222,11 @@ class MongoDataAutoConfigurationTests { } @Configuration(proxyBeanMethods = false) - static class MongoDbFactoryConfiguration { + static class MongoDatabaseFactoryConfiguration { @Bean - MongoDbFactory mongoDbFactory() { - return new SimpleMongoClientDbFactory(MongoClients.create(), "test"); + MongoDatabaseFactory mongoDatabaseFactory() { + return new SimpleMongoClientDatabaseFactory(MongoClients.create(), "test"); } } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoRepositoriesAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoRepositoriesAutoConfigurationTests.java index a2efc5b9cb..6510680504 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoRepositoriesAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/data/mongo/MongoRepositoriesAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * 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. @@ -18,7 +18,7 @@ package org.springframework.boot.autoconfigure.data.mongo; import java.util.Set; -import com.mongodb.MongoClient; +import com.mongodb.client.MongoClient; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoAutoConfigurationTests.java index 4d64ff2a50..b539509688 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * 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. @@ -16,10 +16,10 @@ package org.springframework.boot.autoconfigure.mongo; -import javax.net.SocketFactory; +import java.util.concurrent.TimeUnit; -import com.mongodb.MongoClient; -import com.mongodb.MongoClientOptions; +import com.mongodb.MongoClientSettings; +import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClients; import org.junit.jupiter.api.Test; @@ -27,9 +27,9 @@ import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.test.util.ReflectionTestUtils; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; /** * Tests for {@link MongoAutoConfiguration}. @@ -48,59 +48,55 @@ class MongoAutoConfigurationTests { } @Test - void optionsAdded() { - this.contextRunner.withUserConfiguration(OptionsConfig.class).run( - (context) -> assertThat(context.getBean(MongoClient.class).getMongoClientOptions().getSocketTimeout()) - .isEqualTo(300)); + void settingsAdded() { + this.contextRunner.withUserConfiguration(SettingsConfig.class) + .run((context) -> assertThat(extractClientSettings(context.getBean(MongoClient.class)) + .getSocketSettings().getConnectTimeout(TimeUnit.MILLISECONDS)).isEqualTo(300)); } @Test - void optionsAddedButNoHost() { - this.contextRunner.withUserConfiguration(OptionsConfig.class).run( - (context) -> assertThat(context.getBean(MongoClient.class).getMongoClientOptions().getSocketTimeout()) - .isEqualTo(300)); + void settingsAddedButNoHost() { + this.contextRunner.withUserConfiguration(SettingsConfig.class) + .run((context) -> assertThat(extractClientSettings(context.getBean(MongoClient.class)) + .getSocketSettings().getConnectTimeout(TimeUnit.MILLISECONDS)).isEqualTo(300)); } @Test - void optionsSslConfig() { - this.contextRunner.withUserConfiguration(SslOptionsConfig.class).run((context) -> { + void settingsSslConfig() { + this.contextRunner.withUserConfiguration(SslSettingsConfig.class).run((context) -> { assertThat(context).hasSingleBean(MongoClient.class); - MongoClient mongo = context.getBean(MongoClient.class); - MongoClientOptions options = mongo.getMongoClientOptions(); - assertThat(options.isSslEnabled()).isTrue(); - assertThat(options.getSocketFactory()).isSameAs(context.getBean("mySocketFactory")); + MongoClientSettings settings = extractClientSettings(context.getBean(MongoClient.class)); + assertThat(settings.getSslSettings().isEnabled()).isTrue(); }); } @Test - void doesNotCreateMongoClientWhenAlreadyDefined() { - this.contextRunner.withUserConfiguration(FallbackMongoClientConfig.class).run((context) -> { - assertThat(context).doesNotHaveBean(MongoClient.class); - assertThat(context).hasSingleBean(com.mongodb.client.MongoClient.class); - }); + void configuresSingleClient() { + this.contextRunner.withUserConfiguration(FallbackMongoClientConfig.class) + .run((context) -> assertThat(context).hasSingleBean(MongoClient.class)); + } + + private static MongoClientSettings extractClientSettings(MongoClient client) { + return (MongoClientSettings) ReflectionTestUtils.getField(client, "settings"); } @Configuration(proxyBeanMethods = false) - static class OptionsConfig { + static class SettingsConfig { @Bean - MongoClientOptions mongoOptions() { - return MongoClientOptions.builder().socketTimeout(300).build(); + MongoClientSettings mongoClientSettings() { + return MongoClientSettings.builder().applyToSocketSettings( + (socketSettings) -> socketSettings.connectTimeout(300, TimeUnit.MILLISECONDS)).build(); } } @Configuration(proxyBeanMethods = false) - static class SslOptionsConfig { + static class SslSettingsConfig { @Bean - MongoClientOptions mongoClientOptions(SocketFactory socketFactory) { - return MongoClientOptions.builder().sslEnabled(true).socketFactory(socketFactory).build(); - } - - @Bean - SocketFactory mySocketFactory() { - return mock(SocketFactory.class); + MongoClientSettings mongoClientSettings() { + return MongoClientSettings.builder().applyToSslSettings((ssl) -> ssl.enabled(true)).build(); } } @@ -109,7 +105,7 @@ class MongoAutoConfigurationTests { static class FallbackMongoClientConfig { @Bean - com.mongodb.client.MongoClient fallbackMongoClient() { + MongoClient fallbackMongoClient() { return MongoClients.create(); } 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 b5a858d2e7..7086057deb 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * 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. @@ -18,15 +18,16 @@ package org.springframework.boot.autoconfigure.mongo; import java.util.List; -import com.mongodb.MongoClient; +import com.mongodb.MongoClientSettings; import com.mongodb.MongoCredential; import com.mongodb.ServerAddress; +import com.mongodb.client.MongoClient; +import org.bson.UuidRepresentation; import org.junit.jupiter.api.Test; -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; @@ -68,7 +69,7 @@ class MongoClientFactoryTests { properties.setUsername("user"); properties.setPassword("secret".toCharArray()); MongoClient client = createMongoClient(properties); - assertMongoCredential(getCredentials(client).get(0), "user", "secret", "test"); + assertMongoCredential(getClientSettings(client).getCredential(), "user", "secret", "test"); } @Test @@ -78,7 +79,22 @@ class MongoClientFactoryTests { properties.setUsername("user"); properties.setPassword("secret".toCharArray()); MongoClient client = createMongoClient(properties); - assertMongoCredential(getCredentials(client).get(0), "user", "secret", "foo"); + assertMongoCredential(getClientSettings(client).getCredential(), "user", "secret", "foo"); + } + + @Test + void uuidRepresentationDefaultToJavaLegacy() { + MongoProperties properties = new MongoProperties(); + MongoClient client = createMongoClient(properties); + assertThat(getClientSettings(client).getUuidRepresentation()).isEqualTo(UuidRepresentation.JAVA_LEGACY); + } + + @Test + void uuidRepresentationCanBeCustomized() { + MongoProperties properties = new MongoProperties(); + properties.setUuidRepresentation(UuidRepresentation.STANDARD); + MongoClient client = createMongoClient(properties); + assertThat(getClientSettings(client).getUuidRepresentation()).isEqualTo(UuidRepresentation.STANDARD); } @Test @@ -88,7 +104,7 @@ class MongoClientFactoryTests { properties.setUsername("user"); properties.setPassword("secret".toCharArray()); MongoClient client = createMongoClient(properties); - assertMongoCredential(getCredentials(client).get(0), "user", "secret", "foo"); + assertMongoCredential(getClientSettings(client).getCredential(), "user", "secret", "foo"); } @Test @@ -100,9 +116,7 @@ class MongoClientFactoryTests { assertThat(allAddresses).hasSize(2); assertServerAddress(allAddresses.get(0), "mongo1.example.com", 12345); assertServerAddress(allAddresses.get(1), "mongo2.example.com", 23456); - List credentialsList = getCredentials(client); - assertThat(credentialsList).hasSize(1); - assertMongoCredential(credentialsList.get(0), "user", "secret", "test"); + assertMongoCredential(getClientSettings(client).getCredential(), "user", "secret", "test"); } @Test @@ -124,18 +138,12 @@ class MongoClientFactoryTests { return new MongoClientFactory(properties, environment).createMongoClient(null); } - @SuppressWarnings("deprecation") private List getAllAddresses(MongoClient client) { - // At some point we'll probably need to use reflection to find the address but for - // now, we can use the deprecated getAllAddress method. - return client.getAllAddress(); + return client.getClusterDescription().getClusterSettings().getHosts(); } - @SuppressWarnings("deprecation") - private List getCredentials(MongoClient client) { - // At some point we'll probably need to use reflection to find the credentials but - // for now, we can use the deprecated getCredentialsList method. - return client.getCredentialsList(); + private MongoClientSettings getClientSettings(MongoClient client) { + return (MongoClientSettings) ReflectionTestUtils.getField(client, "settings"); } private void assertServerAddress(ServerAddress serverAddress, String expectedHost, int expectedPort) { @@ -150,10 +158,4 @@ class MongoClientFactoryTests { assertThat(credentials.getSource()).isEqualTo(expectedSource); } - @Configuration(proxyBeanMethods = false) - @EnableConfigurationProperties(MongoProperties.class) - static class Config { - - } - } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoPropertiesTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoPropertiesTests.java index a371783869..52a150ac4a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoPropertiesTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoPropertiesTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * 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. @@ -17,16 +17,18 @@ package org.springframework.boot.autoconfigure.mongo; import java.util.List; +import java.util.concurrent.TimeUnit; -import com.mongodb.MongoClient; -import com.mongodb.MongoClientOptions; +import com.mongodb.MongoClientSettings; import com.mongodb.ServerAddress; +import com.mongodb.client.MongoClient; import org.junit.jupiter.api.Test; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Configuration; +import org.springframework.test.util.ReflectionTestUtils; import static org.assertj.core.api.Assertions.assertThat; @@ -53,50 +55,40 @@ class MongoPropertiesTests { } @Test - @SuppressWarnings("deprecation") - void allMongoClientOptionsCanBeSet() { - MongoClientOptions.Builder builder = MongoClientOptions.builder(); - builder.alwaysUseMBeans(true); - builder.connectionsPerHost(101); - builder.connectTimeout(10001); - builder.cursorFinalizerEnabled(false); - builder.description("test"); - builder.maxWaitTime(120001); - builder.socketKeepAlive(false); - builder.socketTimeout(1000); - builder.threadsAllowedToBlockForConnectionMultiplier(6); - builder.minConnectionsPerHost(0); - builder.maxConnectionIdleTime(60000); - builder.maxConnectionLifeTime(60000); - builder.heartbeatFrequency(10001); - builder.minHeartbeatFrequency(501); - builder.heartbeatConnectTimeout(20001); - builder.heartbeatSocketTimeout(20001); - builder.localThreshold(20); - builder.requiredReplicaSetName("testReplicaSetName"); - MongoClientOptions options = builder.build(); + void allMongoClientSettingsCanBeSet() { + MongoClientSettings.Builder builder = MongoClientSettings.builder(); + builder.applyToSocketSettings((settings) -> { + settings.connectTimeout(1000, TimeUnit.MILLISECONDS); + settings.readTimeout(1000, TimeUnit.MILLISECONDS); + }).applyToServerSettings((settings) -> { + settings.heartbeatFrequency(10001, TimeUnit.MILLISECONDS); + settings.minHeartbeatFrequency(501, TimeUnit.MILLISECONDS); + }).applyToConnectionPoolSettings((settings) -> { + settings.maxWaitTime(120001, TimeUnit.MILLISECONDS); + settings.maxConnectionLifeTime(60000, TimeUnit.MILLISECONDS); + settings.maxConnectionIdleTime(60000, TimeUnit.MILLISECONDS); + }).applyToSslSettings((settings) -> settings.enabled(true)).applicationName("test"); + + MongoClientSettings settings = builder.build(); MongoProperties properties = new MongoProperties(); - MongoClient client = new MongoClientFactory(properties, null).createMongoClient(options); - MongoClientOptions wrapped = client.getMongoClientOptions(); - assertThat(wrapped.isAlwaysUseMBeans()).isEqualTo(options.isAlwaysUseMBeans()); - assertThat(wrapped.getConnectionsPerHost()).isEqualTo(options.getConnectionsPerHost()); - assertThat(wrapped.getConnectTimeout()).isEqualTo(options.getConnectTimeout()); - assertThat(wrapped.isCursorFinalizerEnabled()).isEqualTo(options.isCursorFinalizerEnabled()); - assertThat(wrapped.getDescription()).isEqualTo(options.getDescription()); - assertThat(wrapped.getMaxWaitTime()).isEqualTo(options.getMaxWaitTime()); - assertThat(wrapped.getSocketTimeout()).isEqualTo(options.getSocketTimeout()); - assertThat(wrapped.isSocketKeepAlive()).isEqualTo(options.isSocketKeepAlive()); - assertThat(wrapped.getThreadsAllowedToBlockForConnectionMultiplier()) - .isEqualTo(options.getThreadsAllowedToBlockForConnectionMultiplier()); - assertThat(wrapped.getMinConnectionsPerHost()).isEqualTo(options.getMinConnectionsPerHost()); - assertThat(wrapped.getMaxConnectionIdleTime()).isEqualTo(options.getMaxConnectionIdleTime()); - assertThat(wrapped.getMaxConnectionLifeTime()).isEqualTo(options.getMaxConnectionLifeTime()); - assertThat(wrapped.getHeartbeatFrequency()).isEqualTo(options.getHeartbeatFrequency()); - assertThat(wrapped.getMinHeartbeatFrequency()).isEqualTo(options.getMinHeartbeatFrequency()); - assertThat(wrapped.getHeartbeatConnectTimeout()).isEqualTo(options.getHeartbeatConnectTimeout()); - assertThat(wrapped.getHeartbeatSocketTimeout()).isEqualTo(options.getHeartbeatSocketTimeout()); - assertThat(wrapped.getLocalThreshold()).isEqualTo(options.getLocalThreshold()); - assertThat(wrapped.getRequiredReplicaSetName()).isEqualTo(options.getRequiredReplicaSetName()); + MongoClient client = createMongoClient(properties, settings); + MongoClientSettings wrapped = (MongoClientSettings) ReflectionTestUtils.getField(client, "settings"); + assertThat(wrapped.getSocketSettings().getConnectTimeout(TimeUnit.MILLISECONDS)) + .isEqualTo(settings.getSocketSettings().getConnectTimeout(TimeUnit.MILLISECONDS)); + assertThat(wrapped.getSocketSettings().getReadTimeout(TimeUnit.MILLISECONDS)) + .isEqualTo(settings.getSocketSettings().getReadTimeout(TimeUnit.MILLISECONDS)); + assertThat(wrapped.getServerSettings().getHeartbeatFrequency(TimeUnit.MILLISECONDS)) + .isEqualTo(settings.getServerSettings().getHeartbeatFrequency(TimeUnit.MILLISECONDS)); + assertThat(wrapped.getServerSettings().getMinHeartbeatFrequency(TimeUnit.MILLISECONDS)) + .isEqualTo(settings.getServerSettings().getMinHeartbeatFrequency(TimeUnit.MILLISECONDS)); + assertThat(wrapped.getApplicationName()).isEqualTo(settings.getApplicationName()); + assertThat(wrapped.getConnectionPoolSettings().getMaxWaitTime(TimeUnit.MILLISECONDS)) + .isEqualTo(settings.getConnectionPoolSettings().getMaxWaitTime(TimeUnit.MILLISECONDS)); + assertThat(wrapped.getConnectionPoolSettings().getMaxConnectionLifeTime(TimeUnit.MILLISECONDS)) + .isEqualTo(settings.getConnectionPoolSettings().getMaxConnectionLifeTime(TimeUnit.MILLISECONDS)); + assertThat(wrapped.getConnectionPoolSettings().getMaxConnectionIdleTime(TimeUnit.MILLISECONDS)) + .isEqualTo(settings.getConnectionPoolSettings().getMaxConnectionIdleTime(TimeUnit.MILLISECONDS)); + assertThat(wrapped.getSslSettings().isEnabled()).isEqualTo(settings.getSslSettings().isEnabled()); } @Test @@ -105,7 +97,7 @@ class MongoPropertiesTests { properties.setHost("localhost"); properties.setPort(27017); properties.setUri("mongodb://mongo1.example.com:12345"); - MongoClient client = new MongoClientFactory(properties, null).createMongoClient(null); + MongoClient client = createMongoClient(properties); List allAddresses = getAllAddresses(client); assertThat(allAddresses).hasSize(1); assertServerAddress(allAddresses.get(0), "mongo1.example.com", 12345); @@ -116,7 +108,7 @@ class MongoPropertiesTests { MongoProperties properties = new MongoProperties(); properties.setHost("localhost"); properties.setPort(27017); - MongoClient client = new MongoClientFactory(properties, null).createMongoClient(null); + MongoClient client = createMongoClient(properties); List allAddresses = getAllAddresses(client); assertThat(allAddresses).hasSize(1); assertServerAddress(allAddresses.get(0), "localhost", 27017); @@ -126,7 +118,7 @@ class MongoPropertiesTests { void onlyUriSetShouldUseThat() { MongoProperties properties = new MongoProperties(); properties.setUri("mongodb://mongo1.example.com:12345"); - MongoClient client = new MongoClientFactory(properties, null).createMongoClient(null); + MongoClient client = createMongoClient(properties); List allAddresses = getAllAddresses(client); assertThat(allAddresses).hasSize(1); assertServerAddress(allAddresses.get(0), "mongo1.example.com", 12345); @@ -135,17 +127,22 @@ class MongoPropertiesTests { @Test void noCustomAddressAndNoUriUsesDefaultUri() { MongoProperties properties = new MongoProperties(); - MongoClient client = new MongoClientFactory(properties, null).createMongoClient(null); + MongoClient client = createMongoClient(properties); List allAddresses = getAllAddresses(client); assertThat(allAddresses).hasSize(1); assertServerAddress(allAddresses.get(0), "localhost", 27017); } - @SuppressWarnings("deprecation") + private MongoClient createMongoClient(MongoProperties properties, MongoClientSettings settings) { + return new MongoClientFactory(properties, null).createMongoClient(settings); + } + + private MongoClient createMongoClient(MongoProperties properties) { + return createMongoClient(properties, null); + } + private List getAllAddresses(MongoClient client) { - // At some point we'll probably need to use reflection to find the address but for - // now, we can use the deprecated getAllAddress method. - return client.getAllAddress(); + return client.getClusterDescription().getClusterSettings().getHosts(); } @Test diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoReactiveAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoReactiveAutoConfigurationTests.java index ee7fd0c2f4..5b9d5e65f8 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoReactiveAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/MongoReactiveAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * 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. @@ -25,6 +25,7 @@ import com.mongodb.connection.AsynchronousSocketChannelStreamFactoryFactory; import com.mongodb.connection.StreamFactory; import com.mongodb.connection.StreamFactoryFactory; import com.mongodb.connection.netty.NettyStreamFactoryFactory; +import com.mongodb.internal.async.client.AsyncMongoClient; import com.mongodb.reactivestreams.client.MongoClient; import io.netty.channel.EventLoopGroup; import org.junit.jupiter.api.Test; @@ -58,25 +59,25 @@ class MongoReactiveAutoConfigurationTests { } @Test - void optionsAdded() { + void settingsAdded() { this.contextRunner.withPropertyValues("spring.data.mongodb.host:localhost") - .withUserConfiguration(OptionsConfig.class) + .withUserConfiguration(SettingsConfig.class) .run((context) -> assertThat(getSettings(context).getSocketSettings().getReadTimeout(TimeUnit.SECONDS)) .isEqualTo(300)); } @Test - void optionsAddedButNoHost() { + void settingsAddedButNoHost() { this.contextRunner.withPropertyValues("spring.data.mongodb.uri:mongodb://localhost/test") - .withUserConfiguration(OptionsConfig.class) + .withUserConfiguration(SettingsConfig.class) .run((context) -> assertThat(getSettings(context).getReadPreference()) .isEqualTo(ReadPreference.nearest())); } @Test - void optionsSslConfig() { + void settingsSslConfig() { this.contextRunner.withPropertyValues("spring.data.mongodb.uri:mongodb://localhost/test") - .withUserConfiguration(SslOptionsConfig.class).run((context) -> { + .withUserConfiguration(SslSettingsConfig.class).run((context) -> { assertThat(context).hasSingleBean(MongoClient.class); MongoClientSettings settings = getSettings(context); assertThat(settings.getApplicationName()).isEqualTo("test-config"); @@ -110,14 +111,14 @@ class MongoReactiveAutoConfigurationTests { }); } - @SuppressWarnings("deprecation") private MongoClientSettings getSettings(ApplicationContext context) { MongoClient client = context.getBean(MongoClient.class); - return (MongoClientSettings) ReflectionTestUtils.getField(client.getSettings(), "wrapped"); + AsyncMongoClient wrappedClient = (AsyncMongoClient) ReflectionTestUtils.getField(client, "wrapped"); + return (MongoClientSettings) ReflectionTestUtils.getField(wrappedClient, "settings"); } @Configuration(proxyBeanMethods = false) - static class OptionsConfig { + static class SettingsConfig { @Bean MongoClientSettings mongoClientSettings() { @@ -128,7 +129,7 @@ class MongoReactiveAutoConfigurationTests { } @Configuration(proxyBeanMethods = false) - static class SslOptionsConfig { + static class SslSettingsConfig { @Bean MongoClientSettings mongoClientSettings(StreamFactoryFactory streamFactoryFactory) { 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 aa1d9801fd..129c5456e0 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * 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. @@ -23,7 +23,9 @@ import com.mongodb.MongoClientSettings; import com.mongodb.MongoCredential; import com.mongodb.ServerAddress; import com.mongodb.connection.ClusterSettings; +import com.mongodb.internal.async.client.AsyncMongoClient; import com.mongodb.reactivestreams.client.MongoClient; +import org.bson.UuidRepresentation; import org.junit.jupiter.api.Test; import org.springframework.core.env.Environment; @@ -72,7 +74,7 @@ class ReactiveMongoClientFactoryTests { properties.setUsername("user"); properties.setPassword("secret".toCharArray()); MongoClient client = createMongoClient(properties); - assertMongoCredential(extractMongoCredentials(client), "user", "secret", "test"); + assertMongoCredential(getClientSettings(client).getCredential(), "user", "secret", "test"); } @Test @@ -82,7 +84,22 @@ class ReactiveMongoClientFactoryTests { properties.setUsername("user"); properties.setPassword("secret".toCharArray()); MongoClient client = createMongoClient(properties); - assertMongoCredential(extractMongoCredentials(client), "user", "secret", "foo"); + assertMongoCredential(getClientSettings(client).getCredential(), "user", "secret", "foo"); + } + + @Test + void uuidRepresentationDefaultToJavaLegacy() { + MongoProperties properties = new MongoProperties(); + MongoClient client = createMongoClient(properties); + assertThat(getClientSettings(client).getUuidRepresentation()).isEqualTo(UuidRepresentation.JAVA_LEGACY); + } + + @Test + void uuidRepresentationCanBeCustomized() { + MongoProperties properties = new MongoProperties(); + properties.setUuidRepresentation(UuidRepresentation.STANDARD); + MongoClient client = createMongoClient(properties); + assertThat(getClientSettings(client).getUuidRepresentation()).isEqualTo(UuidRepresentation.STANDARD); } @Test @@ -92,7 +109,7 @@ class ReactiveMongoClientFactoryTests { properties.setUsername("user"); properties.setPassword("secret".toCharArray()); MongoClient client = createMongoClient(properties); - assertMongoCredential(extractMongoCredentials(client), "user", "secret", "foo"); + assertMongoCredential(getClientSettings(client).getCredential(), "user", "secret", "foo"); } @Test @@ -104,8 +121,7 @@ class ReactiveMongoClientFactoryTests { assertThat(allAddresses).hasSize(2); assertServerAddress(allAddresses.get(0), "mongo1.example.com", 12345); assertServerAddress(allAddresses.get(1), "mongo2.example.com", 23456); - MongoCredential credential = extractMongoCredentials(client); - assertMongoCredential(credential, "user", "secret", "test"); + assertMongoCredential(getClientSettings(client).getCredential(), "user", "secret", "test"); } @Test @@ -113,7 +129,7 @@ class ReactiveMongoClientFactoryTests { MongoProperties properties = new MongoProperties(); properties.setUri("mongodb://localhost/test?retryWrites=true"); MongoClient client = createMongoClient(properties); - assertThat(getSettings(client).getRetryWrites()).isTrue(); + assertThat(getClientSettings(client).getRetryWrites()).isTrue(); } @Test @@ -184,18 +200,14 @@ class ReactiveMongoClientFactoryTests { } private List extractServerAddresses(MongoClient client) { - MongoClientSettings settings = getSettings(client); + MongoClientSettings settings = getClientSettings(client); ClusterSettings clusterSettings = settings.getClusterSettings(); return clusterSettings.getHosts(); } - private MongoCredential extractMongoCredentials(MongoClient client) { - return getSettings(client).getCredential(); - } - - @SuppressWarnings("deprecation") - private MongoClientSettings getSettings(MongoClient client) { - return (MongoClientSettings) ReflectionTestUtils.getField(client.getSettings(), "wrapped"); + private MongoClientSettings getClientSettings(MongoClient client) { + AsyncMongoClient wrapped = (AsyncMongoClient) ReflectionTestUtils.getField(client, "wrapped"); + return (MongoClientSettings) ReflectionTestUtils.getField(wrapped, "settings"); } private void assertServerAddress(ServerAddress serverAddress, String expectedHost, int expectedPort) { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoAutoConfigurationTests.java index 7f3cde68c6..b37668a548 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoAutoConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * 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. @@ -23,7 +23,8 @@ import java.util.EnumSet; import java.util.Map; import java.util.stream.Collectors; -import com.mongodb.MongoClient; +import com.mongodb.client.MongoClient; +import com.mongodb.client.MongoClients; import de.flapdoodle.embed.mongo.MongodExecutable; import de.flapdoodle.embed.mongo.MongodStarter; import de.flapdoodle.embed.mongo.config.IMongodConfig; @@ -236,11 +237,8 @@ class EmbeddedMongoAutoConfigurationTests { return File.separatorChar == '\\'; } - @SuppressWarnings("deprecation") private int getPort(MongoClient client) { - // At some point we'll probably need to use reflection to find the address but for - // now, we can use the deprecated getAddress method. - return client.getAddress().getPort(); + return client.getClusterDescription().getClusterSettings().getHosts().get(0).getPort(); } @Configuration(proxyBeanMethods = false) @@ -248,7 +246,7 @@ class EmbeddedMongoAutoConfigurationTests { @Bean MongoClient mongoClient(@Value("${local.mongo.port}") int port) { - return new MongoClient("localhost", port); + return MongoClients.create("mongodb://localhost:" + port); } } diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 0819d48056..40cf8dc348 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -1192,21 +1192,14 @@ bom { ] } } - library("Mongo Driver ReactiveStreams", "1.13.0") { - group("org.mongodb") { - modules = [ - "mongodb-driver-reactivestreams" - ] - } - } - library("MongoDB", "3.12.1") { + library("MongoDB", "4.0.0-beta1") { group("org.mongodb") { modules = [ "bson", - "mongodb-driver", - "mongodb-driver-async", "mongodb-driver-core", - "mongo-java-driver" + "mongodb-driver-legacy", + "mongodb-driver-reactivestreams", + "mongodb-driver-sync" ] } } @@ -1601,7 +1594,7 @@ bom { ] } } - library("Spring Data Releasetrain", "Neumann-M2") { + library("Spring Data Releasetrain", "Neumann-BUILD-SNAPSHOT") { group("org.springframework.data") { imports = [ "spring-data-releasetrain" diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/spring-boot-features.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/spring-boot-features.adoc index 0634d93947..845a77b1a5 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/spring-boot-features.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/spring-boot-features.adoc @@ -3833,19 +3833,19 @@ Spring Boot offers several conveniences for working with MongoDB, including the [[boot-features-connecting-to-mongodb]] ==== Connecting to a MongoDB Database -To access Mongo databases, you can inject an auto-configured `org.springframework.data.mongodb.MongoDbFactory`. +To access Mongo databases, you can inject an auto-configured `org.springframework.data.mongodb.MongoDatabaseFactory`. By default, the instance tries to connect to a MongoDB server at `mongodb://localhost/test`. The following example shows how to connect to a MongoDB database: [source,java,indent=0] ---- - import org.springframework.data.mongodb.MongoDbFactory; - import com.mongodb.DB; + import org.springframework.data.mongodb.MongoDatabaseFactory; + import com.mongodb.client.MongoDatabase; @Component public class MyBean { - private final MongoDbFactory mongo; + private final MongoDatabaseFactory mongo; @Autowired public MyBean(MongoDbFactory mongo) { @@ -3855,7 +3855,7 @@ The following example shows how to connect to a MongoDB database: // ... public void example() { - DB db = mongo.getDb(); + MongoDatabase db = mongo.getMongoDatabase(); // ... } @@ -3869,7 +3869,7 @@ You can set the configprop:spring.data.mongodb.uri[] property to change the URL spring.data.mongodb.uri=mongodb://user:secret@mongo1.example.com:12345,mongo2.example.com:23456/test ---- -Alternatively, as long as you use Mongo 2.x, you can specify a `host`/`port`. +Alternatively, you can specify a `host`/`port`. For example, you might declare the following settings in your `application.properties`: [source,properties,indent=0,configprops] @@ -3878,8 +3878,7 @@ For example, you might declare the following settings in your `application.prope spring.data.mongodb.port=27017 ---- -If you have defined your own `MongoClient`, it will be used to auto-configure a suitable `MongoDbFactory`. -Both `com.mongodb.MongoClient` and `com.mongodb.client.MongoClient` are supported. +If you have defined your own `MongoClient`, it will be used to auto-configure a suitable `MongoDatabaseFactory`. NOTE: If you use the Mongo 3.0 Java driver, `spring.data.mongodb.host` and `spring.data.mongodb.port` are not supported. In such cases, `spring.data.mongodb.uri` should be used to provide all of the configuration. @@ -3887,8 +3886,8 @@ In such cases, `spring.data.mongodb.uri` should be used to provide all of the co TIP: If `spring.data.mongodb.port` is not specified, the default of `27017` is used. You could delete this line from the example shown earlier. -TIP: If you do not use Spring Data Mongo, you can inject `com.mongodb.MongoClient` beans instead of using `MongoDbFactory`. -If you want to take complete control of establishing the MongoDB connection, you can also declare your own `MongoDbFactory` or `MongoClient` bean. +TIP: If you do not use Spring Data Mongo, you can inject a `MongoClient` bean instead of using `MongoDatabaseFactory`. +If you want to take complete control of establishing the MongoDB connection, you can also declare your own `MongoDatabaseFactory` or `MongoClient` bean. NOTE: If you are using the reactive driver, Netty is required for SSL. The auto-configuration configures this factory automatically if Netty is available and the factory to use hasn't been customized already. @@ -3902,7 +3901,6 @@ As with `JdbcTemplate`, Spring Boot auto-configures a bean for you to inject the [source,java,indent=0] ---- - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.stereotype.Component; @@ -3911,7 +3909,6 @@ As with `JdbcTemplate`, Spring Boot auto-configures a bean for you to inject the private final MongoTemplate mongoTemplate; - @Autowired public MyBean(MongoTemplate mongoTemplate) { this.mongoTemplate = mongoTemplate; } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-data-mongodb-reactive/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-data-mongodb-reactive/build.gradle index 0f7ab7bc9f..bd3706b70d 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-data-mongodb-reactive/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-data-mongodb-reactive/build.gradle @@ -8,10 +8,6 @@ dependencies { api(platform(project(":spring-boot-project:spring-boot-dependencies"))) api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) api("io.projectreactor:reactor-core") - api("org.mongodb:mongodb-driver") - api("org.mongodb:mongodb-driver-async") api("org.mongodb:mongodb-driver-reactivestreams") - api("org.springframework.data:spring-data-mongodb") { - exclude group: "org.mongodb", module: "mongo-java-driver" - } + api("org.springframework.data:spring-data-mongodb") } diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-data-mongodb/build.gradle b/spring-boot-project/spring-boot-starters/spring-boot-starter-data-mongodb/build.gradle index fbe7579212..58b753d06f 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-data-mongodb/build.gradle +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-data-mongodb/build.gradle @@ -7,8 +7,6 @@ description = "Starter for using MongoDB document-oriented database and Spring D dependencies { api(platform(project(":spring-boot-project:spring-boot-dependencies"))) api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) - api("org.mongodb:mongodb-driver") - api("org.springframework.data:spring-data-mongodb") { - exclude group: "org.mongodb", module: "mongo-java-driver" - } + api("org.mongodb:mongodb-driver-sync") + api("org.springframework.data:spring-data-mongodb") } diff --git a/spring-boot-project/spring-boot-test-autoconfigure/build.gradle b/spring-boot-project/spring-boot-test-autoconfigure/build.gradle index 21867ae113..fa04ef1f9f 100644 --- a/spring-boot-project/spring-boot-test-autoconfigure/build.gradle +++ b/spring-boot-project/spring-boot-test-autoconfigure/build.gradle @@ -45,8 +45,8 @@ dependencies { optional("org.springframework.security:spring-security-config") optional("org.springframework.security:spring-security-test") optional("org.apache.tomcat.embed:tomcat-embed-core") - optional("org.mongodb:mongodb-driver-async") optional("org.mongodb:mongodb-driver-reactivestreams") + optional("org.mongodb:mongodb-driver-sync") testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) testImplementation("ch.qos.logback:logback-classic")