Commit d2d6dbdc authored by Christoph Strobl's avatar Christoph Strobl Committed by Stephane Nicoll

Upgrade to MongoDB Java Driver 4.0 beta1

See gh-19960
parent cf473eeb
...@@ -83,7 +83,7 @@ dependencies { ...@@ -83,7 +83,7 @@ dependencies {
optional("org.influxdb:influxdb-java") optional("org.influxdb:influxdb-java")
optional("org.jolokia:jolokia-core") optional("org.jolokia:jolokia-core")
optional("org.liquibase:liquibase-core") optional("org.liquibase:liquibase-core")
optional("org.mongodb:mongodb-driver-async") optional("org.mongodb:mongodb-driver-sync")
optional("org.mongodb:mongodb-driver-reactivestreams") optional("org.mongodb:mongodb-driver-reactivestreams")
optional("org.springframework:spring-jdbc") optional("org.springframework:spring-jdbc")
optional("org.springframework:spring-jms") optional("org.springframework:spring-jms")
......
...@@ -43,7 +43,7 @@ dependencies { ...@@ -43,7 +43,7 @@ dependencies {
optional("org.hibernate.validator:hibernate-validator") optional("org.hibernate.validator:hibernate-validator")
optional("org.influxdb:influxdb-java") optional("org.influxdb:influxdb-java")
optional("org.liquibase:liquibase-core") optional("org.liquibase:liquibase-core")
optional("org.mongodb:mongodb-driver-async") optional("org.mongodb:mongodb-driver-sync")
optional("org.mongodb:mongodb-driver-reactivestreams") optional("org.mongodb:mongodb-driver-reactivestreams")
optional("org.springframework:spring-jdbc") optional("org.springframework:spring-jdbc")
optional("org.springframework:spring-messaging") optional("org.springframework:spring-messaging")
......
...@@ -95,7 +95,7 @@ dependencies { ...@@ -95,7 +95,7 @@ dependencies {
optional("org.jooq:jooq") optional("org.jooq:jooq")
optional("org.liquibase:liquibase-core") optional("org.liquibase:liquibase-core")
optional("org.messaginghub:pooled-jms") optional("org.messaginghub:pooled-jms")
optional("org.mongodb:mongodb-driver-async") optional("org.mongodb:mongodb-driver-sync")
optional("org.mongodb:mongodb-driver-reactivestreams") optional("org.mongodb:mongodb-driver-reactivestreams")
optional("org.quartz-scheduler:quartz") optional("org.quartz-scheduler:quartz")
optional("org.springframework:spring-jdbc") optional("org.springframework:spring-jdbc")
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
package org.springframework.boot.autoconfigure.data.mongo; 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.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
......
...@@ -16,8 +16,6 @@ ...@@ -16,8 +16,6 @@
package org.springframework.boot.autoconfigure.data.mongo; package org.springframework.boot.autoconfigure.data.mongo;
import com.mongodb.MongoClient;
import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
...@@ -48,7 +46,7 @@ import org.springframework.data.mongodb.gridfs.GridFsTemplate; ...@@ -48,7 +46,7 @@ import org.springframework.data.mongodb.gridfs.GridFsTemplate;
* @since 1.1.0 * @since 1.1.0
*/ */
@Configuration(proxyBeanMethods = false) @Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ MongoClient.class, com.mongodb.client.MongoClient.class, MongoTemplate.class }) @ConditionalOnClass({ com.mongodb.client.MongoClient.class, MongoTemplate.class })
@EnableConfigurationProperties(MongoProperties.class) @EnableConfigurationProperties(MongoProperties.class)
@Import({ MongoDataConfiguration.class, MongoDbFactoryConfiguration.class, MongoDbFactoryDependentConfiguration.class }) @Import({ MongoDataConfiguration.class, MongoDbFactoryConfiguration.class, MongoDbFactoryDependentConfiguration.class })
@AutoConfigureAfter(MongoAutoConfiguration.class) @AutoConfigureAfter(MongoAutoConfiguration.class)
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
package org.springframework.boot.autoconfigure.data.mongo; package org.springframework.boot.autoconfigure.data.mongo;
import com.mongodb.MongoClient; import com.mongodb.client.MongoClient;
import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; import org.springframework.boot.autoconfigure.condition.AnyNestedCondition;
...@@ -27,31 +27,26 @@ import org.springframework.boot.autoconfigure.mongo.MongoProperties; ...@@ -27,31 +27,26 @@ import org.springframework.boot.autoconfigure.mongo.MongoProperties;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDbFactory; import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.core.MongoDbFactorySupport; import org.springframework.data.mongodb.core.MongoDatabaseFactorySupport;
import org.springframework.data.mongodb.core.SimpleMongoClientDbFactory; import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
/** /**
* Configuration for a {@link MongoDbFactory}. * Configuration for a {@link MongoDatabaseFactory}.
* *
* @author Andy Wilkinson * @author Andy Wilkinson
*/ */
@Configuration(proxyBeanMethods = false) @Configuration(proxyBeanMethods = false)
@ConditionalOnMissingBean(MongoDbFactory.class) @ConditionalOnMissingBean(MongoDatabaseFactory.class)
@Conditional(AnyMongoClientAvailable.class) @Conditional(AnyMongoClientAvailable.class)
class MongoDbFactoryConfiguration { class MongoDbFactoryConfiguration {
@Bean @Bean
MongoDbFactorySupport<?> mongoDbFactory(ObjectProvider<MongoClient> mongo, MongoDatabaseFactorySupport<?> mongoDbFactory(ObjectProvider<MongoClient> mongoClient, MongoProperties properties) {
ObjectProvider<com.mongodb.client.MongoClient> mongoClient, MongoProperties properties) {
MongoClient preferredClient = mongo.getIfAvailable();
if (preferredClient != null) {
return new SimpleMongoDbFactory(preferredClient, properties.getMongoClientDatabase());
}
com.mongodb.client.MongoClient fallbackClient = mongoClient.getIfAvailable(); com.mongodb.client.MongoClient fallbackClient = mongoClient.getIfAvailable();
if (fallbackClient != null) { if (fallbackClient != null) {
return new SimpleMongoClientDbFactory(fallbackClient, properties.getMongoClientDatabase()); return new SimpleMongoClientDatabaseFactory(fallbackClient, properties.getMongoClientDatabase());
} }
throw new IllegalStateException("Expected to find at least one MongoDB client."); throw new IllegalStateException("Expected to find at least one MongoDB client.");
} }
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
package org.springframework.boot.autoconfigure.data.mongo; package org.springframework.boot.autoconfigure.data.mongo;
import com.mongodb.ClientSessionOptions; import com.mongodb.ClientSessionOptions;
import com.mongodb.DB;
import com.mongodb.client.ClientSession; import com.mongodb.client.ClientSession;
import com.mongodb.client.MongoDatabase; import com.mongodb.client.MongoDatabase;
...@@ -28,7 +27,7 @@ import org.springframework.context.annotation.Bean; ...@@ -28,7 +27,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessException;
import org.springframework.dao.support.PersistenceExceptionTranslator; 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.MongoOperations;
import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.convert.DbRefResolver; import org.springframework.data.mongodb.core.convert.DbRefResolver;
...@@ -43,12 +42,12 @@ import org.springframework.util.Assert; ...@@ -43,12 +42,12 @@ import org.springframework.util.Assert;
import org.springframework.util.StringUtils; 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 * @author Andy Wilkinson
*/ */
@Configuration(proxyBeanMethods = false) @Configuration(proxyBeanMethods = false)
@ConditionalOnBean(MongoDbFactory.class) @ConditionalOnBean(MongoDatabaseFactory.class)
class MongoDbFactoryDependentConfiguration { class MongoDbFactoryDependentConfiguration {
private final MongoProperties properties; private final MongoProperties properties;
...@@ -59,13 +58,13 @@ class MongoDbFactoryDependentConfiguration { ...@@ -59,13 +58,13 @@ class MongoDbFactoryDependentConfiguration {
@Bean @Bean
@ConditionalOnMissingBean(MongoOperations.class) @ConditionalOnMissingBean(MongoOperations.class)
MongoTemplate mongoTemplate(MongoDbFactory mongoDbFactory, MongoConverter converter) { MongoTemplate mongoTemplate(MongoDatabaseFactory mongoDbFactory, MongoConverter converter) {
return new MongoTemplate(mongoDbFactory, converter); return new MongoTemplate(mongoDbFactory, converter);
} }
@Bean @Bean
@ConditionalOnMissingBean(MongoConverter.class) @ConditionalOnMissingBean(MongoConverter.class)
MappingMongoConverter mappingMongoConverter(MongoDbFactory factory, MongoMappingContext context, MappingMongoConverter mappingMongoConverter(MongoDatabaseFactory factory, MongoMappingContext context,
MongoCustomConversions conversions) { MongoCustomConversions conversions) {
DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory); DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory);
MappingMongoConverter mappingConverter = new MappingMongoConverter(dbRefResolver, context); MappingMongoConverter mappingConverter = new MappingMongoConverter(dbRefResolver, context);
...@@ -75,22 +74,22 @@ class MongoDbFactoryDependentConfiguration { ...@@ -75,22 +74,22 @@ class MongoDbFactoryDependentConfiguration {
@Bean @Bean
@ConditionalOnMissingBean(GridFsOperations.class) @ConditionalOnMissingBean(GridFsOperations.class)
GridFsTemplate gridFsTemplate(MongoDbFactory mongoDbFactory, MongoTemplate mongoTemplate) { GridFsTemplate gridFsTemplate(MongoDatabaseFactory mongoDbFactory, MongoTemplate mongoTemplate) {
return new GridFsTemplate(new GridFsMongoDbFactory(mongoDbFactory, this.properties), return new GridFsTemplate(new GridFsMongoDbFactory(mongoDbFactory, this.properties),
mongoTemplate.getConverter()); mongoTemplate.getConverter());
} }
/** /**
* {@link MongoDbFactory} decorator to respect * {@link MongoDatabaseFactory} decorator to respect
* {@link MongoProperties#getGridFsDatabase()} if set. * {@link MongoProperties#getGridFsDatabase()} if set.
*/ */
static class GridFsMongoDbFactory implements MongoDbFactory { static class GridFsMongoDbFactory implements MongoDatabaseFactory {
private final MongoDbFactory mongoDbFactory; private final MongoDatabaseFactory mongoDbFactory;
private final MongoProperties properties; private final MongoProperties properties;
GridFsMongoDbFactory(MongoDbFactory mongoDbFactory, MongoProperties properties) { GridFsMongoDbFactory(MongoDatabaseFactory mongoDbFactory, MongoProperties properties) {
Assert.notNull(mongoDbFactory, "MongoDbFactory must not be null"); Assert.notNull(mongoDbFactory, "MongoDbFactory must not be null");
Assert.notNull(properties, "Properties must not be null"); Assert.notNull(properties, "Properties must not be null");
this.mongoDbFactory = mongoDbFactory; this.mongoDbFactory = mongoDbFactory;
...@@ -98,17 +97,17 @@ class MongoDbFactoryDependentConfiguration { ...@@ -98,17 +97,17 @@ class MongoDbFactoryDependentConfiguration {
} }
@Override @Override
public MongoDatabase getDb() throws DataAccessException { public MongoDatabase getMongoDatabase() throws DataAccessException {
String gridFsDatabase = this.properties.getGridFsDatabase(); String gridFsDatabase = this.properties.getGridFsDatabase();
if (StringUtils.hasText(gridFsDatabase)) { if (StringUtils.hasText(gridFsDatabase)) {
return this.mongoDbFactory.getDb(gridFsDatabase); return this.mongoDbFactory.getMongoDatabase(gridFsDatabase);
} }
return this.mongoDbFactory.getDb(); return this.mongoDbFactory.getMongoDatabase();
} }
@Override @Override
public MongoDatabase getDb(String dbName) throws DataAccessException { public MongoDatabase getMongoDatabase(String dbName) throws DataAccessException {
return this.mongoDbFactory.getDb(dbName); return this.mongoDbFactory.getMongoDatabase(dbName);
} }
@Override @Override
...@@ -116,19 +115,13 @@ class MongoDbFactoryDependentConfiguration { ...@@ -116,19 +115,13 @@ class MongoDbFactoryDependentConfiguration {
return this.mongoDbFactory.getExceptionTranslator(); return this.mongoDbFactory.getExceptionTranslator();
} }
@Override
@Deprecated
public DB getLegacyDb() {
return this.mongoDbFactory.getLegacyDb();
}
@Override @Override
public ClientSession getSession(ClientSessionOptions options) { public ClientSession getSession(ClientSessionOptions options) {
return this.mongoDbFactory.getSession(options); return this.mongoDbFactory.getSession(options);
} }
@Override @Override
public MongoDbFactory withSession(ClientSession session) { public MongoDatabaseFactory withSession(ClientSession session) {
return this.mongoDbFactory.withSession(session); return this.mongoDbFactory.withSession(session);
} }
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
package org.springframework.boot.autoconfigure.data.mongo; 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.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
......
...@@ -16,8 +16,10 @@ ...@@ -16,8 +16,10 @@
package org.springframework.boot.autoconfigure.mongo; package org.springframework.boot.autoconfigure.mongo;
import com.mongodb.MongoClient; import java.util.stream.Collectors;
import com.mongodb.MongoClientOptions;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClient;
import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
...@@ -45,10 +47,13 @@ import org.springframework.core.env.Environment; ...@@ -45,10 +47,13 @@ import org.springframework.core.env.Environment;
public class MongoAutoConfiguration { public class MongoAutoConfiguration {
@Bean @Bean
@ConditionalOnMissingBean(type = { "com.mongodb.MongoClient", "com.mongodb.client.MongoClient" }) @ConditionalOnMissingBean(type = { "com.mongodb.client.MongoClient" })
public MongoClient mongo(MongoProperties properties, ObjectProvider<MongoClientOptions> options, public MongoClient mongo(MongoProperties properties, Environment environment,
Environment environment) { ObjectProvider<MongoClientSettingsBuilderCustomizer> builderCustomizers,
return new MongoClientFactory(properties, environment).createMongoClient(options.getIfAvailable()); ObjectProvider<MongoClientSettings> settings) {
return new MongoClientFactory(properties, environment,
builderCustomizers.orderedStream().collect(Collectors.toList()))
.createMongoClient(settings.getIfAvailable());
} }
} }
...@@ -16,15 +16,11 @@ ...@@ -16,15 +16,11 @@
package org.springframework.boot.autoconfigure.mongo; package org.springframework.boot.autoconfigure.mongo;
import java.util.Collections;
import java.util.List; import java.util.List;
import com.mongodb.MongoClient; import com.mongodb.MongoClientSettings;
import com.mongodb.MongoClientOptions; import com.mongodb.client.MongoClient;
import com.mongodb.MongoClientOptions.Builder; import com.mongodb.client.MongoClients;
import com.mongodb.MongoClientURI;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
...@@ -39,102 +35,23 @@ import org.springframework.core.env.Environment; ...@@ -39,102 +35,23 @@ import org.springframework.core.env.Environment;
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Nasko Vasilev * @author Nasko Vasilev
* @author Mark Paluch * @author Mark Paluch
* @author Christoph Strobl
* @since 2.0.0 * @since 2.0.0
*/ */
public class MongoClientFactory { public class MongoClientFactory extends MongoClientFactorySupport<MongoClient> {
private final MongoProperties properties; public MongoClientFactory(MongoProperties properties, Environment environment,
List<MongoClientSettingsBuilderCustomizer> builderCustomizers) {
private final Environment environment; super(properties, environment, builderCustomizers);
public MongoClientFactory(MongoProperties properties, Environment environment) {
this.properties = properties;
this.environment = environment;
}
/**
* 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
*/
public MongoClient createMongoClient(MongoClientOptions options) {
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) ? this.properties.getHost() : "localhost";
return new MongoClient(Collections.singletonList(new ServerAddress(host, port)), options);
}
private MongoClient createNetworkMongoClient(MongoClientOptions options) {
MongoProperties properties = this.properties;
if (properties.getUri() != null) {
return createMongoClient(properties.getUri(), options);
}
if (hasCustomAddress() || hasCustomCredentials()) {
if (options == null) {
options = MongoClientOptions.builder().build();
}
MongoCredential credentials = getCredentials(properties);
String host = getValue(properties.getHost(), "localhost");
int port = getValue(properties.getPort(), MongoProperties.DEFAULT_PORT);
List<ServerAddress> seeds = Collections.singletonList(new ServerAddress(host, port));
return (credentials != null) ? new MongoClient(seeds, credentials, options)
: new MongoClient(seeds, options);
}
return createMongoClient(MongoProperties.DEFAULT_URI, options);
}
private MongoClient createMongoClient(String uri, MongoClientOptions options) {
return new MongoClient(new MongoClientURI(uri, builder(options)));
}
private <T> T getValue(T value, T fallback) {
return (value != null) ? value : fallback;
}
private boolean hasCustomAddress() {
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() { protected MongoClient createNetworkMongoClient(MongoClientSettings settings) {
return this.properties.getUsername() != null && this.properties.getPassword() != null; return MongoClients.create(settings, driverInformation());
} }
private Builder builder(MongoClientOptions options) { @Override
if (options != null) { protected MongoClient createEmbeddedMongoClient(MongoClientSettings settings) {
return MongoClientOptions.builder(options); return MongoClients.create(settings, driverInformation());
}
return MongoClientOptions.builder();
} }
} }
/*
* Copyright 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.mongo;
import java.util.Collections;
import java.util.List;
import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.MongoClientSettings.Builder;
import com.mongodb.MongoCredential;
import com.mongodb.MongoDriverInformation;
import com.mongodb.ServerAddress;
import org.springframework.core.env.Environment;
import org.springframework.util.Assert;
/**
* Base class for common setup bits (aka {@link MongoClientSettings}) required for
* instantiating a MongoClient.
*
* @author Christoph Strobl
* @since 2.3.0
*/
public abstract class MongoClientFactorySupport<T> {
private final MongoProperties properties;
private final Environment environment;
private final List<MongoClientSettingsBuilderCustomizer> builderCustomizers;
public MongoClientFactorySupport(MongoProperties properties, Environment environment,
List<MongoClientSettingsBuilderCustomizer> builderCustomizers) {
this.properties = properties;
this.environment = environment;
this.builderCustomizers = (builderCustomizers != null) ? builderCustomizers : Collections.emptyList();
}
public T createMongoClient(MongoClientSettings settings) {
MongoClientSettings targetSettings = computeClientSettings(settings);
return (getEmbeddedPort() != null) ? createEmbeddedMongoClient(targetSettings)
: createNetworkMongoClient(targetSettings);
}
private MongoClientSettings computeClientSettings(MongoClientSettings settings) {
Builder settingsBuilder = (settings != null) ? MongoClientSettings.builder(settings)
: MongoClientSettings.builder();
applyHostAndPort(settingsBuilder);
applyCredentials(settingsBuilder);
customize(settingsBuilder);
return settingsBuilder.build();
}
private void applyHostAndPort(MongoClientSettings.Builder settings) {
if (isEmbedded()) {
settings.applyConnectionString(new ConnectionString("mongodb://localhost:" + getEmbeddedPort()));
return;
}
if (!this.properties.determineUri().equals(MongoProperties.DEFAULT_URI)) {
if (hasCustomAddress()) {
Assert.state(this.properties.getUri() == null,
"Invalid mongo configuration, either uri or host/port/credentials must be specified");
}
settings.applyConnectionString(new ConnectionString(this.properties.determineUri()));
}
else if (hasCustomAddress()) {
String host = getOrDefault(this.properties.getHost(), "localhost");
int port = getOrDefault(this.properties.getPort(), MongoProperties.DEFAULT_PORT);
ServerAddress serverAddress = new ServerAddress(host, port);
settings.applyToClusterSettings((cluster) -> cluster.hosts(Collections.singletonList(serverAddress)));
}
}
private void applyCredentials(Builder builder) {
if (hasCustomCredentials()) {
String database = (this.properties.getAuthenticationDatabase() != null)
? this.properties.getAuthenticationDatabase() : this.properties.getMongoClientDatabase();
builder.credential((MongoCredential.createCredential(this.properties.getUsername(), database,
this.properties.getPassword())));
}
}
private void customize(MongoClientSettings.Builder builder) {
for (MongoClientSettingsBuilderCustomizer customizer : this.builderCustomizers) {
customizer.customize(builder);
}
}
private <T> T getOrDefault(T value, T defaultValue) {
return (value != null) ? value : defaultValue;
}
protected abstract T createNetworkMongoClient(MongoClientSettings settings);
protected abstract T createEmbeddedMongoClient(MongoClientSettings 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 boolean isEmbedded() {
return getEmbeddedPort() != null;
}
private boolean hasCustomCredentials() {
return this.properties.getUsername() != null && this.properties.getPassword() != null;
}
private boolean hasCustomAddress() {
return this.properties.getHost() != null || this.properties.getPort() != null;
}
protected static MongoDriverInformation driverInformation() {
return MongoDriverInformation.builder(MongoDriverInformation.builder().build()).driverName("spring-boot")
.build();
}
}
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
package org.springframework.boot.autoconfigure.mongo; package org.springframework.boot.autoconfigure.mongo;
import com.mongodb.MongoClientURI; import com.mongodb.ConnectionString;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
...@@ -178,7 +178,7 @@ public class MongoProperties { ...@@ -178,7 +178,7 @@ public class MongoProperties {
if (this.database != null) { if (this.database != null) {
return this.database; return this.database;
} }
return new MongoClientURI(determineUri()).getDatabase(); return new ConnectionString(determineUri()).getDatabase();
} }
public Boolean isAutoIndexCreation() { public Boolean isAutoIndexCreation() {
......
...@@ -16,136 +16,36 @@ ...@@ -16,136 +16,36 @@
package org.springframework.boot.autoconfigure.mongo; package org.springframework.boot.autoconfigure.mongo;
import java.util.Collections;
import java.util.List; import java.util.List;
import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings; import com.mongodb.MongoClientSettings;
import com.mongodb.MongoClientSettings.Builder;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import com.mongodb.reactivestreams.client.MongoClient; import com.mongodb.reactivestreams.client.MongoClient;
import com.mongodb.reactivestreams.client.MongoClients; import com.mongodb.reactivestreams.client.MongoClients;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import org.springframework.util.Assert;
/** /**
* A factory for a reactive {@link MongoClient} that applies {@link MongoProperties}. * A factory for a reactive {@link MongoClient} that applies {@link MongoProperties}.
* *
* @author Mark Paluch * @author Mark Paluch
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Christoph Strobl
* @since 2.0.0 * @since 2.0.0
*/ */
public class ReactiveMongoClientFactory { public class ReactiveMongoClientFactory extends MongoClientFactorySupport<MongoClient> {
private final MongoProperties properties;
private final Environment environment;
private final List<MongoClientSettingsBuilderCustomizer> builderCustomizers;
public ReactiveMongoClientFactory(MongoProperties properties, Environment environment, public ReactiveMongoClientFactory(MongoProperties properties, Environment environment,
List<MongoClientSettingsBuilderCustomizer> builderCustomizers) { List<MongoClientSettingsBuilderCustomizer> builderCustomizers) {
this.properties = properties; super(properties, environment, builderCustomizers);
this.environment = environment;
this.builderCustomizers = (builderCustomizers != null) ? builderCustomizers : Collections.emptyList();
}
/**
* 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) ? this.properties.getHost() : "localhost";
builder.applyToClusterSettings(
(cluster) -> cluster.hosts(Collections.singletonList(new ServerAddress(host, port))));
return createMongoClient(builder);
}
private MongoClient createNetworkMongoClient(MongoClientSettings settings) {
if (hasCustomAddress() || hasCustomCredentials()) {
return createCredentialNetworkMongoClient(settings);
}
ConnectionString connectionString = new ConnectionString(this.properties.determineUri());
return createMongoClient(createBuilder(settings, connectionString));
}
private MongoClient createCredentialNetworkMongoClient(MongoClientSettings settings) {
Assert.state(this.properties.getUri() == null,
"Invalid mongo configuration, either uri or host/port/credentials must be specified");
Builder builder = builder(settings);
if (hasCustomCredentials()) {
applyCredentials(builder);
}
String host = getOrDefault(this.properties.getHost(), "localhost");
int port = getOrDefault(this.properties.getPort(), MongoProperties.DEFAULT_PORT);
ServerAddress serverAddress = new ServerAddress(host, port);
builder.applyToClusterSettings((cluster) -> cluster.hosts(Collections.singletonList(serverAddress)));
return createMongoClient(builder);
}
private void applyCredentials(Builder builder) {
String database = (this.properties.getAuthenticationDatabase() != null)
? this.properties.getAuthenticationDatabase() : this.properties.getMongoClientDatabase();
builder.credential((MongoCredential.createCredential(this.properties.getUsername(), database,
this.properties.getPassword())));
}
private <T> T getOrDefault(T value, T defaultValue) {
return (value != null) ? value : defaultValue;
}
private MongoClient createMongoClient(Builder builder) {
customize(builder);
return MongoClients.create(builder.build());
}
private Builder createBuilder(MongoClientSettings settings, ConnectionString connection) {
return builder(settings).applyConnectionString(connection);
}
private void customize(MongoClientSettings.Builder builder) {
for (MongoClientSettingsBuilderCustomizer customizer : this.builderCustomizers) {
customizer.customize(builder);
}
}
private boolean hasCustomAddress() {
return this.properties.getHost() != null || this.properties.getPort() != null;
} }
private boolean hasCustomCredentials() { protected MongoClient createNetworkMongoClient(MongoClientSettings settings) {
return this.properties.getUsername() != null && this.properties.getPassword() != null; return MongoClients.create(settings, driverInformation());
} }
private Builder builder(MongoClientSettings settings) { @Override
if (settings == null) { protected MongoClient createEmbeddedMongoClient(MongoClientSettings settings) {
return MongoClientSettings.builder(); return MongoClients.create(settings, driverInformation());
}
return MongoClientSettings.builder(settings);
} }
} }
...@@ -23,7 +23,7 @@ import java.util.HashMap; ...@@ -23,7 +23,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.stream.Stream; 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.Command;
import de.flapdoodle.embed.mongo.MongodExecutable; import de.flapdoodle.embed.mongo.MongodExecutable;
import de.flapdoodle.embed.mongo.MongodStarter; import de.flapdoodle.embed.mongo.MongodStarter;
......
...@@ -20,7 +20,7 @@ import java.time.LocalDateTime; ...@@ -20,7 +20,7 @@ import java.time.LocalDateTime;
import java.util.Arrays; import java.util.Arrays;
import java.util.Set; import java.util.Set;
import com.mongodb.MongoClient; import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients; import com.mongodb.client.MongoClients;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
...@@ -40,10 +40,9 @@ import org.springframework.core.convert.converter.Converter; ...@@ -40,10 +40,9 @@ import org.springframework.core.convert.converter.Converter;
import org.springframework.data.mapping.model.CamelCaseAbbreviatingFieldNamingStrategy; import org.springframework.data.mapping.model.CamelCaseAbbreviatingFieldNamingStrategy;
import org.springframework.data.mapping.model.FieldNamingStrategy; import org.springframework.data.mapping.model.FieldNamingStrategy;
import org.springframework.data.mapping.model.PropertyNameFieldNamingStrategy; 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.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoClientDbFactory; import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import org.springframework.data.mongodb.core.convert.MongoCustomConversions; import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
import org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity; import org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
...@@ -171,16 +170,16 @@ class MongoDataAutoConfigurationTests { ...@@ -171,16 +170,16 @@ class MongoDataAutoConfigurationTests {
@Test @Test
void createsMongoDbFactoryForPreferredMongoClient() { void createsMongoDbFactoryForPreferredMongoClient() {
this.contextRunner.run((context) -> { this.contextRunner.run((context) -> {
MongoDbFactory dbFactory = context.getBean(MongoDbFactory.class); MongoDatabaseFactory dbFactory = context.getBean(MongoDatabaseFactory.class);
assertThat(dbFactory).isInstanceOf(SimpleMongoDbFactory.class); assertThat(dbFactory).isInstanceOf(SimpleMongoClientDatabaseFactory.class);
}); });
} }
@Test @Test
void createsMongoDbFactoryForFallbackMongoClient() { void createsMongoDbFactoryForFallbackMongoClient() {
this.contextRunner.withUserConfiguration(FallbackMongoClientConfiguration.class).run((context) -> { this.contextRunner.withUserConfiguration(FallbackMongoClientConfiguration.class).run((context) -> {
MongoDbFactory dbFactory = context.getBean(MongoDbFactory.class); MongoDatabaseFactory dbFactory = context.getBean(MongoDatabaseFactory.class);
assertThat(dbFactory).isInstanceOf(SimpleMongoClientDbFactory.class); assertThat(dbFactory).isInstanceOf(SimpleMongoClientDatabaseFactory.class);
}); });
} }
...@@ -226,8 +225,8 @@ class MongoDataAutoConfigurationTests { ...@@ -226,8 +225,8 @@ class MongoDataAutoConfigurationTests {
static class MongoDbFactoryConfiguration { static class MongoDbFactoryConfiguration {
@Bean @Bean
MongoDbFactory mongoDbFactory() { MongoDatabaseFactory mongoDbFactory() {
return new SimpleMongoClientDbFactory(MongoClients.create(), "test"); return new SimpleMongoClientDatabaseFactory(MongoClients.create(), "test");
} }
} }
......
...@@ -18,7 +18,7 @@ package org.springframework.boot.autoconfigure.data.mongo; ...@@ -18,7 +18,7 @@ package org.springframework.boot.autoconfigure.data.mongo;
import java.util.Set; import java.util.Set;
import com.mongodb.MongoClient; import com.mongodb.client.MongoClient;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.AutoConfigurations;
......
...@@ -16,10 +16,12 @@ ...@@ -16,10 +16,12 @@
package org.springframework.boot.autoconfigure.mongo; package org.springframework.boot.autoconfigure.mongo;
import java.util.concurrent.TimeUnit;
import javax.net.SocketFactory; import javax.net.SocketFactory;
import com.mongodb.MongoClient; import com.mongodb.MongoClientSettings;
import com.mongodb.MongoClientOptions; import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients; import com.mongodb.client.MongoClients;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
...@@ -27,6 +29,7 @@ import org.springframework.boot.autoconfigure.AutoConfigurations; ...@@ -27,6 +29,7 @@ import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.test.util.ReflectionTestUtils;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
...@@ -49,43 +52,44 @@ class MongoAutoConfigurationTests { ...@@ -49,43 +52,44 @@ class MongoAutoConfigurationTests {
@Test @Test
void optionsAdded() { void optionsAdded() {
this.contextRunner.withUserConfiguration(OptionsConfig.class).run( this.contextRunner.withUserConfiguration(OptionsConfig.class)
(context) -> assertThat(context.getBean(MongoClient.class).getMongoClientOptions().getSocketTimeout()) .run((context) -> assertThat(extractClientSettings(context.getBean(MongoClient.class))
.isEqualTo(300)); .getSocketSettings().getConnectTimeout(TimeUnit.MILLISECONDS)).isEqualTo(300));
} }
@Test @Test
void optionsAddedButNoHost() { void optionsAddedButNoHost() {
this.contextRunner.withUserConfiguration(OptionsConfig.class).run( this.contextRunner.withUserConfiguration(OptionsConfig.class)
(context) -> assertThat(context.getBean(MongoClient.class).getMongoClientOptions().getSocketTimeout()) .run((context) -> assertThat(extractClientSettings(context.getBean(MongoClient.class))
.isEqualTo(300)); .getSocketSettings().getConnectTimeout(TimeUnit.MILLISECONDS)).isEqualTo(300));
} }
@Test @Test
void optionsSslConfig() { void optionsSslConfig() {
this.contextRunner.withUserConfiguration(SslOptionsConfig.class).run((context) -> { this.contextRunner.withUserConfiguration(SslOptionsConfig.class).run((context) -> {
assertThat(context).hasSingleBean(MongoClient.class); assertThat(context).hasSingleBean(MongoClient.class);
MongoClient mongo = context.getBean(MongoClient.class); MongoClientSettings options = extractClientSettings(context.getBean(MongoClient.class));
MongoClientOptions options = mongo.getMongoClientOptions(); assertThat(options.getSslSettings().isEnabled()).isTrue();
assertThat(options.isSslEnabled()).isTrue();
assertThat(options.getSocketFactory()).isSameAs(context.getBean("mySocketFactory"));
}); });
} }
@Test @Test
void doesNotCreateMongoClientWhenAlreadyDefined() { void configuresSingleClient() {
this.contextRunner.withUserConfiguration(FallbackMongoClientConfig.class).run((context) -> { this.contextRunner.withUserConfiguration(FallbackMongoClientConfig.class)
assertThat(context).doesNotHaveBean(MongoClient.class); .run((context) -> assertThat(context).hasSingleBean(MongoClient.class));
assertThat(context).hasSingleBean(com.mongodb.client.MongoClient.class); }
});
private static MongoClientSettings extractClientSettings(MongoClient client) {
return (MongoClientSettings) ReflectionTestUtils.getField(client, "settings");
} }
@Configuration(proxyBeanMethods = false) @Configuration(proxyBeanMethods = false)
static class OptionsConfig { static class OptionsConfig {
@Bean @Bean
MongoClientOptions mongoOptions() { MongoClientSettings mongoOptions() {
return MongoClientOptions.builder().socketTimeout(300).build(); return MongoClientSettings.builder()
.applyToSocketSettings((it) -> it.connectTimeout(300, TimeUnit.MILLISECONDS)).build();
} }
} }
...@@ -94,8 +98,8 @@ class MongoAutoConfigurationTests { ...@@ -94,8 +98,8 @@ class MongoAutoConfigurationTests {
static class SslOptionsConfig { static class SslOptionsConfig {
@Bean @Bean
MongoClientOptions mongoClientOptions(SocketFactory socketFactory) { MongoClientSettings mongoClientOptions(SocketFactory socketFactory) {
return MongoClientOptions.builder().sslEnabled(true).socketFactory(socketFactory).build(); return MongoClientSettings.builder().applyToSslSettings((it) -> it.enabled(true)).build();
} }
@Bean @Bean
......
...@@ -16,17 +16,20 @@ ...@@ -16,17 +16,20 @@
package org.springframework.boot.autoconfigure.mongo; package org.springframework.boot.autoconfigure.mongo;
import java.util.Collections;
import java.util.List; import java.util.List;
import com.mongodb.MongoClient; import com.mongodb.MongoClientSettings;
import com.mongodb.MongoCredential; import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress; import com.mongodb.ServerAddress;
import com.mongodb.client.MongoClient;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import org.springframework.mock.env.MockEnvironment; import org.springframework.mock.env.MockEnvironment;
import org.springframework.test.util.ReflectionTestUtils;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
...@@ -121,21 +124,22 @@ class MongoClientFactoryTests { ...@@ -121,21 +124,22 @@ class MongoClientFactoryTests {
} }
private MongoClient createMongoClient(MongoProperties properties, Environment environment) { private MongoClient createMongoClient(MongoProperties properties, Environment environment) {
return new MongoClientFactory(properties, environment).createMongoClient(null); return new MongoClientFactory(properties, environment, Collections.emptyList()).createMongoClient(null);
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
private List<ServerAddress> getAllAddresses(MongoClient client) { private List<ServerAddress> getAllAddresses(MongoClient client) {
// At some point we'll probably need to use reflection to find the address but for // At some point we'll probably need to use reflection to find the address but for
// now, we can use the deprecated getAllAddress method. // now, we can use the deprecated getAllAddress method.
return client.getAllAddress(); return client.getClusterDescription().getClusterSettings().getHosts();
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
private List<MongoCredential> getCredentials(MongoClient client) { private List<MongoCredential> getCredentials(MongoClient client) {
// At some point we'll probably need to use reflection to find the credentials but // At some point we'll probably need to use reflection to find the credentials but
// for now, we can use the deprecated getCredentialsList method. // for now, we can use the deprecated getCredentialsList method.
return client.getCredentialsList(); return Collections.singletonList(
((MongoClientSettings) ReflectionTestUtils.getField(client, "settings")).getCredential());
} }
private void assertServerAddress(ServerAddress serverAddress, String expectedHost, int expectedPort) { private void assertServerAddress(ServerAddress serverAddress, String expectedHost, int expectedPort) {
......
...@@ -16,17 +16,20 @@ ...@@ -16,17 +16,20 @@
package org.springframework.boot.autoconfigure.mongo; package org.springframework.boot.autoconfigure.mongo;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit;
import com.mongodb.MongoClient; import com.mongodb.MongoClientSettings;
import com.mongodb.MongoClientOptions;
import com.mongodb.ServerAddress; import com.mongodb.ServerAddress;
import com.mongodb.client.MongoClient;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.test.util.ReflectionTestUtils;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
...@@ -55,48 +58,43 @@ class MongoPropertiesTests { ...@@ -55,48 +58,43 @@ class MongoPropertiesTests {
@Test @Test
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
void allMongoClientOptionsCanBeSet() { void allMongoClientOptionsCanBeSet() {
MongoClientOptions.Builder builder = MongoClientOptions.builder(); MongoClientSettings.Builder builder = MongoClientSettings.builder();
builder.alwaysUseMBeans(true); builder.applyToSocketSettings((settings) -> {
builder.connectionsPerHost(101); settings.connectTimeout(1000, TimeUnit.MILLISECONDS);
builder.connectTimeout(10001); settings.readTimeout(1000, TimeUnit.MILLISECONDS);
builder.cursorFinalizerEnabled(false); }).applyToServerSettings((settings) -> {
builder.description("test"); settings.heartbeatFrequency(10001, TimeUnit.MILLISECONDS);
builder.maxWaitTime(120001); settings.minHeartbeatFrequency(501, TimeUnit.MILLISECONDS);
builder.socketKeepAlive(false); }).applyToClusterSettings((settings) -> settings.requiredReplicaSetName("testReplicaSetName"))
builder.socketTimeout(1000); .applyToConnectionPoolSettings((settings) -> {
builder.threadsAllowedToBlockForConnectionMultiplier(6); settings.maxWaitTime(120001, TimeUnit.MILLISECONDS);
builder.minConnectionsPerHost(0); settings.maxConnectionLifeTime(60000, TimeUnit.MILLISECONDS);
builder.maxConnectionIdleTime(60000); settings.maxConnectionIdleTime(60000, TimeUnit.MILLISECONDS);
builder.maxConnectionLifeTime(60000); }).applyToSslSettings((settings) -> settings.enabled(true)).applicationName("test");
builder.heartbeatFrequency(10001);
builder.minHeartbeatFrequency(501); MongoClientSettings settings = builder.build();
builder.heartbeatConnectTimeout(20001);
builder.heartbeatSocketTimeout(20001);
builder.localThreshold(20);
builder.requiredReplicaSetName("testReplicaSetName");
MongoClientOptions options = builder.build();
MongoProperties properties = new MongoProperties(); MongoProperties properties = new MongoProperties();
MongoClient client = new MongoClientFactory(properties, null).createMongoClient(options); MongoClient client = new MongoClientFactory(properties, null, Collections.emptyList())
MongoClientOptions wrapped = client.getMongoClientOptions(); .createMongoClient(settings);
assertThat(wrapped.isAlwaysUseMBeans()).isEqualTo(options.isAlwaysUseMBeans()); MongoClientSettings wrapped = (MongoClientSettings) ReflectionTestUtils.getField(client, "settings");
assertThat(wrapped.getConnectionsPerHost()).isEqualTo(options.getConnectionsPerHost()); assertThat(wrapped.getSocketSettings().getConnectTimeout(TimeUnit.MILLISECONDS))
assertThat(wrapped.getConnectTimeout()).isEqualTo(options.getConnectTimeout()); .isEqualTo(settings.getSocketSettings().getConnectTimeout(TimeUnit.MILLISECONDS));
assertThat(wrapped.isCursorFinalizerEnabled()).isEqualTo(options.isCursorFinalizerEnabled()); assertThat(wrapped.getSocketSettings().getReadTimeout(TimeUnit.MILLISECONDS))
assertThat(wrapped.getDescription()).isEqualTo(options.getDescription()); .isEqualTo(settings.getSocketSettings().getReadTimeout(TimeUnit.MILLISECONDS));
assertThat(wrapped.getMaxWaitTime()).isEqualTo(options.getMaxWaitTime()); assertThat(wrapped.getServerSettings().getHeartbeatFrequency(TimeUnit.MILLISECONDS))
assertThat(wrapped.getSocketTimeout()).isEqualTo(options.getSocketTimeout()); .isEqualTo(settings.getServerSettings().getHeartbeatFrequency(TimeUnit.MILLISECONDS));
assertThat(wrapped.isSocketKeepAlive()).isEqualTo(options.isSocketKeepAlive()); assertThat(wrapped.getServerSettings().getMinHeartbeatFrequency(TimeUnit.MILLISECONDS))
assertThat(wrapped.getThreadsAllowedToBlockForConnectionMultiplier()) .isEqualTo(settings.getServerSettings().getMinHeartbeatFrequency(TimeUnit.MILLISECONDS));
.isEqualTo(options.getThreadsAllowedToBlockForConnectionMultiplier()); assertThat(wrapped.getApplicationName()).isEqualTo(settings.getApplicationName());
assertThat(wrapped.getMinConnectionsPerHost()).isEqualTo(options.getMinConnectionsPerHost()); assertThat(wrapped.getClusterSettings().getRequiredReplicaSetName())
assertThat(wrapped.getMaxConnectionIdleTime()).isEqualTo(options.getMaxConnectionIdleTime()); .isEqualTo(settings.getClusterSettings().getRequiredReplicaSetName());
assertThat(wrapped.getMaxConnectionLifeTime()).isEqualTo(options.getMaxConnectionLifeTime()); assertThat(wrapped.getConnectionPoolSettings().getMaxWaitTime(TimeUnit.MILLISECONDS))
assertThat(wrapped.getHeartbeatFrequency()).isEqualTo(options.getHeartbeatFrequency()); .isEqualTo(settings.getConnectionPoolSettings().getMaxWaitTime(TimeUnit.MILLISECONDS));
assertThat(wrapped.getMinHeartbeatFrequency()).isEqualTo(options.getMinHeartbeatFrequency()); assertThat(wrapped.getConnectionPoolSettings().getMaxConnectionLifeTime(TimeUnit.MILLISECONDS))
assertThat(wrapped.getHeartbeatConnectTimeout()).isEqualTo(options.getHeartbeatConnectTimeout()); .isEqualTo(settings.getConnectionPoolSettings().getMaxConnectionLifeTime(TimeUnit.MILLISECONDS));
assertThat(wrapped.getHeartbeatSocketTimeout()).isEqualTo(options.getHeartbeatSocketTimeout()); assertThat(wrapped.getConnectionPoolSettings().getMaxConnectionIdleTime(TimeUnit.MILLISECONDS))
assertThat(wrapped.getLocalThreshold()).isEqualTo(options.getLocalThreshold()); .isEqualTo(settings.getConnectionPoolSettings().getMaxConnectionIdleTime(TimeUnit.MILLISECONDS));
assertThat(wrapped.getRequiredReplicaSetName()).isEqualTo(options.getRequiredReplicaSetName()); assertThat(wrapped.getSslSettings().isEnabled()).isEqualTo(settings.getSslSettings().isEnabled());
} }
@Test @Test
...@@ -105,7 +103,7 @@ class MongoPropertiesTests { ...@@ -105,7 +103,7 @@ class MongoPropertiesTests {
properties.setHost("localhost"); properties.setHost("localhost");
properties.setPort(27017); properties.setPort(27017);
properties.setUri("mongodb://mongo1.example.com:12345"); properties.setUri("mongodb://mongo1.example.com:12345");
MongoClient client = new MongoClientFactory(properties, null).createMongoClient(null); MongoClient client = new MongoClientFactory(properties, null, Collections.emptyList()).createMongoClient(null);
List<ServerAddress> allAddresses = getAllAddresses(client); List<ServerAddress> allAddresses = getAllAddresses(client);
assertThat(allAddresses).hasSize(1); assertThat(allAddresses).hasSize(1);
assertServerAddress(allAddresses.get(0), "mongo1.example.com", 12345); assertServerAddress(allAddresses.get(0), "mongo1.example.com", 12345);
...@@ -116,7 +114,7 @@ class MongoPropertiesTests { ...@@ -116,7 +114,7 @@ class MongoPropertiesTests {
MongoProperties properties = new MongoProperties(); MongoProperties properties = new MongoProperties();
properties.setHost("localhost"); properties.setHost("localhost");
properties.setPort(27017); properties.setPort(27017);
MongoClient client = new MongoClientFactory(properties, null).createMongoClient(null); MongoClient client = new MongoClientFactory(properties, null, Collections.emptyList()).createMongoClient(null);
List<ServerAddress> allAddresses = getAllAddresses(client); List<ServerAddress> allAddresses = getAllAddresses(client);
assertThat(allAddresses).hasSize(1); assertThat(allAddresses).hasSize(1);
assertServerAddress(allAddresses.get(0), "localhost", 27017); assertServerAddress(allAddresses.get(0), "localhost", 27017);
...@@ -126,7 +124,7 @@ class MongoPropertiesTests { ...@@ -126,7 +124,7 @@ class MongoPropertiesTests {
void onlyUriSetShouldUseThat() { void onlyUriSetShouldUseThat() {
MongoProperties properties = new MongoProperties(); MongoProperties properties = new MongoProperties();
properties.setUri("mongodb://mongo1.example.com:12345"); properties.setUri("mongodb://mongo1.example.com:12345");
MongoClient client = new MongoClientFactory(properties, null).createMongoClient(null); MongoClient client = new MongoClientFactory(properties, null, Collections.emptyList()).createMongoClient(null);
List<ServerAddress> allAddresses = getAllAddresses(client); List<ServerAddress> allAddresses = getAllAddresses(client);
assertThat(allAddresses).hasSize(1); assertThat(allAddresses).hasSize(1);
assertServerAddress(allAddresses.get(0), "mongo1.example.com", 12345); assertServerAddress(allAddresses.get(0), "mongo1.example.com", 12345);
...@@ -135,17 +133,17 @@ class MongoPropertiesTests { ...@@ -135,17 +133,17 @@ class MongoPropertiesTests {
@Test @Test
void noCustomAddressAndNoUriUsesDefaultUri() { void noCustomAddressAndNoUriUsesDefaultUri() {
MongoProperties properties = new MongoProperties(); MongoProperties properties = new MongoProperties();
MongoClient client = new MongoClientFactory(properties, null).createMongoClient(null); MongoClient client = new MongoClientFactory(properties, null, Collections.emptyList()).createMongoClient(null);
List<ServerAddress> allAddresses = getAllAddresses(client); List<ServerAddress> allAddresses = getAllAddresses(client);
assertThat(allAddresses).hasSize(1); assertThat(allAddresses).hasSize(1);
assertServerAddress(allAddresses.get(0), "localhost", 27017); assertServerAddress(allAddresses.get(0), "127.0.0.1", 27017);
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
private List<ServerAddress> getAllAddresses(MongoClient client) { private List<ServerAddress> getAllAddresses(MongoClient client) {
// At some point we'll probably need to use reflection to find the address but for // At some point we'll probably need to use reflection to find the address but for
// now, we can use the deprecated getAllAddress method. // now, we can use the deprecated getAllAddress method.
return client.getAllAddress(); return client.getClusterDescription().getClusterSettings().getHosts();
} }
@Test @Test
......
...@@ -25,6 +25,7 @@ import com.mongodb.connection.AsynchronousSocketChannelStreamFactoryFactory; ...@@ -25,6 +25,7 @@ import com.mongodb.connection.AsynchronousSocketChannelStreamFactoryFactory;
import com.mongodb.connection.StreamFactory; import com.mongodb.connection.StreamFactory;
import com.mongodb.connection.StreamFactoryFactory; import com.mongodb.connection.StreamFactoryFactory;
import com.mongodb.connection.netty.NettyStreamFactoryFactory; import com.mongodb.connection.netty.NettyStreamFactoryFactory;
import com.mongodb.internal.async.client.AsyncMongoClient;
import com.mongodb.reactivestreams.client.MongoClient; import com.mongodb.reactivestreams.client.MongoClient;
import io.netty.channel.EventLoopGroup; import io.netty.channel.EventLoopGroup;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
...@@ -113,7 +114,8 @@ class MongoReactiveAutoConfigurationTests { ...@@ -113,7 +114,8 @@ class MongoReactiveAutoConfigurationTests {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
private MongoClientSettings getSettings(ApplicationContext context) { private MongoClientSettings getSettings(ApplicationContext context) {
MongoClient client = context.getBean(MongoClient.class); 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) @Configuration(proxyBeanMethods = false)
......
...@@ -23,6 +23,7 @@ import com.mongodb.MongoClientSettings; ...@@ -23,6 +23,7 @@ import com.mongodb.MongoClientSettings;
import com.mongodb.MongoCredential; import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress; import com.mongodb.ServerAddress;
import com.mongodb.connection.ClusterSettings; import com.mongodb.connection.ClusterSettings;
import com.mongodb.internal.async.client.AsyncMongoClient;
import com.mongodb.reactivestreams.client.MongoClient; import com.mongodb.reactivestreams.client.MongoClient;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
...@@ -117,13 +118,13 @@ class ReactiveMongoClientFactoryTests { ...@@ -117,13 +118,13 @@ class ReactiveMongoClientFactoryTests {
} }
@Test @Test
void uriCannotBeSetWithCredentials() { void uriCanBeSetWithCredentials() {
MongoProperties properties = new MongoProperties(); MongoProperties properties = new MongoProperties();
properties.setUri("mongodb://127.0.0.1:1234/mydb"); properties.setUri("mongodb://127.0.0.1:1234/mydb");
properties.setUsername("user"); properties.setUsername("user");
properties.setPassword("secret".toCharArray()); properties.setPassword("secret".toCharArray());
assertThatIllegalStateException().isThrownBy(() -> createMongoClient(properties)).withMessageContaining( MongoCredential credential = extractMongoCredentials(createMongoClient(properties));
"Invalid mongo configuration, either uri or host/port/credentials must be specified"); assertMongoCredential(credential, "user", "secret", "mydb");
} }
@Test @Test
...@@ -195,7 +196,8 @@ class ReactiveMongoClientFactoryTests { ...@@ -195,7 +196,8 @@ class ReactiveMongoClientFactoryTests {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
private MongoClientSettings getSettings(MongoClient client) { private MongoClientSettings getSettings(MongoClient client) {
return (MongoClientSettings) ReflectionTestUtils.getField(client.getSettings(), "wrapped"); AsyncMongoClient wrapped = (AsyncMongoClient) ReflectionTestUtils.getField(client, "wrapped");
return (MongoClientSettings) ReflectionTestUtils.getField(wrapped, "settings");
} }
private void assertServerAddress(ServerAddress serverAddress, String expectedHost, int expectedPort) { private void assertServerAddress(ServerAddress serverAddress, String expectedHost, int expectedPort) {
......
...@@ -23,7 +23,8 @@ import java.util.EnumSet; ...@@ -23,7 +23,8 @@ import java.util.EnumSet;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors; 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.MongodExecutable;
import de.flapdoodle.embed.mongo.MongodStarter; import de.flapdoodle.embed.mongo.MongodStarter;
import de.flapdoodle.embed.mongo.config.IMongodConfig; import de.flapdoodle.embed.mongo.config.IMongodConfig;
...@@ -240,7 +241,7 @@ class EmbeddedMongoAutoConfigurationTests { ...@@ -240,7 +241,7 @@ class EmbeddedMongoAutoConfigurationTests {
private int getPort(MongoClient client) { private int getPort(MongoClient client) {
// At some point we'll probably need to use reflection to find the address but for // At some point we'll probably need to use reflection to find the address but for
// now, we can use the deprecated getAddress method. // now, we can use the deprecated getAddress method.
return client.getAddress().getPort(); return client.getClusterDescription().getClusterSettings().getHosts().iterator().next().getPort();
} }
@Configuration(proxyBeanMethods = false) @Configuration(proxyBeanMethods = false)
...@@ -248,7 +249,7 @@ class EmbeddedMongoAutoConfigurationTests { ...@@ -248,7 +249,7 @@ class EmbeddedMongoAutoConfigurationTests {
@Bean @Bean
MongoClient mongoClient(@Value("${local.mongo.port}") int port) { MongoClient mongoClient(@Value("${local.mongo.port}") int port) {
return new MongoClient("localhost", port); return MongoClients.create("mongodb://localhost:" + port);
} }
} }
......
...@@ -1192,21 +1192,14 @@ bom { ...@@ -1192,21 +1192,14 @@ bom {
] ]
} }
} }
library("Mongo Driver ReactiveStreams", "1.13.0") { library("MongoDB", "4.0.0-beta1") {
group("org.mongodb") {
modules = [
"mongodb-driver-reactivestreams"
]
}
}
library("MongoDB", "3.12.1") {
group("org.mongodb") { group("org.mongodb") {
modules = [ modules = [
"bson", "bson",
"mongodb-driver", "mongodb-driver-sync",
"mongodb-driver-async", "mongodb-driver-async",
"mongodb-driver-core", "mongodb-driver-core",
"mongo-java-driver" "mongodb-driver-reactivestreams"
] ]
} }
} }
...@@ -1601,7 +1594,7 @@ bom { ...@@ -1601,7 +1594,7 @@ bom {
] ]
} }
} }
library("Spring Data Releasetrain", "Neumann-M2") { library("Spring Data Releasetrain", "Neumann-BUILD-SNAPSHOT") {
group("org.springframework.data") { group("org.springframework.data") {
imports = [ imports = [
"spring-data-releasetrain" "spring-data-releasetrain"
......
...@@ -8,8 +8,7 @@ dependencies { ...@@ -8,8 +8,7 @@ dependencies {
api(platform(project(":spring-boot-project:spring-boot-dependencies"))) api(platform(project(":spring-boot-project:spring-boot-dependencies")))
api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter"))
api("io.projectreactor:reactor-core") api("io.projectreactor:reactor-core")
api("org.mongodb:mongodb-driver") api("org.mongodb:mongodb-driver-sync")
api("org.mongodb:mongodb-driver-async")
api("org.mongodb:mongodb-driver-reactivestreams") api("org.mongodb:mongodb-driver-reactivestreams")
api("org.springframework.data:spring-data-mongodb") { api("org.springframework.data:spring-data-mongodb") {
exclude group: "org.mongodb", module: "mongo-java-driver" exclude group: "org.mongodb", module: "mongo-java-driver"
......
...@@ -7,7 +7,7 @@ description = "Starter for using MongoDB document-oriented database and Spring D ...@@ -7,7 +7,7 @@ description = "Starter for using MongoDB document-oriented database and Spring D
dependencies { dependencies {
api(platform(project(":spring-boot-project:spring-boot-dependencies"))) api(platform(project(":spring-boot-project:spring-boot-dependencies")))
api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter")) api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter"))
api("org.mongodb:mongodb-driver") api("org.mongodb:mongodb-driver-core")
api("org.springframework.data:spring-data-mongodb") { api("org.springframework.data:spring-data-mongodb") {
exclude group: "org.mongodb", module: "mongo-java-driver" exclude group: "org.mongodb", module: "mongo-java-driver"
} }
......
...@@ -45,7 +45,7 @@ dependencies { ...@@ -45,7 +45,7 @@ dependencies {
optional("org.springframework.security:spring-security-config") optional("org.springframework.security:spring-security-config")
optional("org.springframework.security:spring-security-test") optional("org.springframework.security:spring-security-test")
optional("org.apache.tomcat.embed:tomcat-embed-core") optional("org.apache.tomcat.embed:tomcat-embed-core")
optional("org.mongodb:mongodb-driver-async") optional("org.mongodb:mongodb-driver-sync")
optional("org.mongodb:mongodb-driver-reactivestreams") optional("org.mongodb:mongodb-driver-reactivestreams")
testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support")) testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support"))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment