Commit 1fdcc3d0 authored by Stephane Nicoll's avatar Stephane Nicoll

Merge pull request #8230 from mp911de:issue/8051-reactive-mongo

* pr/8230:
  Polish contribution
  Provide a starter for reactive Spring Data MongoDB
parents 13791cad b30d4303
...@@ -299,6 +299,16 @@ ...@@ -299,6 +299,16 @@
<artifactId>jboss-transaction-spi</artifactId> <artifactId>jboss-transaction-spi</artifactId>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-async</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-reactivestreams</artifactId>
<optional>true</optional>
</dependency>
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId> <artifactId>spring-jdbc</artifactId>
......
/*
* Copyright 2012-2017 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
*
* http://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.reactivestreams.client.MongoClient;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
import org.springframework.boot.autoconfigure.mongo.ReactiveMongoAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.ReactiveMongoDatabaseFactory;
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
import org.springframework.data.mongodb.core.SimpleReactiveMongoDatabaseFactory;
import org.springframework.data.mongodb.core.convert.MongoConverter;
/**
* {@link EnableAutoConfiguration Auto-configuration} for Spring Data's reactive mongo
* support.
* <p>
* Registers a {@link ReactiveMongoTemplate} bean if no other bean of the same type is
* configured.
* <P>
* Honors the {@literal spring.data.mongodb.database} property if set, otherwise connects
* to the {@literal test} database.
*
* @author Mark Paluch
* @since 2.0.0
*/
@Configuration
@ConditionalOnClass({ MongoClient.class, ReactiveMongoTemplate.class })
@EnableConfigurationProperties(MongoProperties.class)
@AutoConfigureAfter(ReactiveMongoAutoConfiguration.class)
public class ReactiveMongoDataAutoConfiguration {
private final MongoProperties properties;
public ReactiveMongoDataAutoConfiguration(MongoProperties properties) {
this.properties = properties;
}
@Bean
@ConditionalOnMissingBean(ReactiveMongoDatabaseFactory.class)
public SimpleReactiveMongoDatabaseFactory reactiveMongoDatabaseFactory(
MongoClient mongo) throws Exception {
String database = this.properties.getMongoClientDatabase();
return new SimpleReactiveMongoDatabaseFactory(mongo, database);
}
@Bean
@ConditionalOnMissingBean
public ReactiveMongoTemplate reactiveMongoTemplate(
ReactiveMongoDatabaseFactory reactiveMongoDatabaseFactory,
MongoConverter converter) {
return new ReactiveMongoTemplate(reactiveMongoDatabaseFactory, converter);
}
}
/*
* Copyright 2012-2017 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
*
* http://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.reactivestreams.client.MongoClient;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
import org.springframework.data.mongodb.repository.config.EnableReactiveMongoRepositories;
import org.springframework.data.mongodb.repository.config.ReactiveMongoRepositoryConfigurationExtension;
import org.springframework.data.mongodb.repository.support.MongoRepositoryFactoryBean;
/**
* {@link EnableAutoConfiguration Auto-configuration} for Spring Data's Mongo Reactive
* Repositories.
* <p>
* Activates when there is no bean of type
* {@link org.springframework.data.mongodb.repository.support.ReactiveMongoRepositoryFactoryBean}
* configured in the context, the Spring Data Mongo {@link ReactiveMongoRepository} type
* is on the classpath, the ReactiveStreams Mongo client driver API is on the classpath,
* and there is no other configured {@link ReactiveMongoRepository}.
* <p>
* Once in effect, the auto-configuration is the equivalent of enabling Mongo repositories
* using the {@link EnableReactiveMongoRepositories} annotation.
*
* @author Mark Paluch
* @since 2.0.0
* @see EnableReactiveMongoRepositories
*/
@Configuration
@ConditionalOnClass({ MongoClient.class, ReactiveMongoRepository.class })
@ConditionalOnMissingBean({ MongoRepositoryFactoryBean.class,
ReactiveMongoRepositoryConfigurationExtension.class })
@ConditionalOnProperty(prefix = "spring.data.mongodb.reactive-repositories", name = "enabled", havingValue = "true", matchIfMissing = true)
@Import(ReactiveMongoRepositoriesAutoConfigureRegistrar.class)
@AutoConfigureAfter(ReactiveMongoDataAutoConfiguration.class)
public class ReactiveMongoRepositoriesAutoConfiguration {
}
/*
* Copyright 2012-2017 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
*
* http://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 java.lang.annotation.Annotation;
import org.springframework.boot.autoconfigure.data.AbstractRepositoryConfigurationSourceSupport;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.data.mongodb.repository.config.EnableReactiveMongoRepositories;
import org.springframework.data.mongodb.repository.config.ReactiveMongoRepositoryConfigurationExtension;
import org.springframework.data.repository.config.RepositoryConfigurationExtension;
/**
* {@link ImportBeanDefinitionRegistrar} used to auto-configure Spring Data Mongo Reactive
* Repositories.
*
* @author Mark Paluch
* @since 2.0.0
*/
class ReactiveMongoRepositoriesAutoConfigureRegistrar extends
AbstractRepositoryConfigurationSourceSupport {
@Override
protected Class<? extends Annotation> getAnnotation() {
return EnableReactiveMongoRepositories.class;
}
@Override
protected Class<?> getConfiguration() {
return EnableReactiveMongoRepositoriesConfiguration.class;
}
@Override
protected RepositoryConfigurationExtension getRepositoryConfigurationExtension() {
return new ReactiveMongoRepositoryConfigurationExtension();
}
@EnableReactiveMongoRepositories
private static class EnableReactiveMongoRepositoriesConfiguration {
}
}
/*
* Copyright 2012-2017 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
*
* http://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.reactivestreams.client.MongoClient;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.boot.autoconfigure.AbstractDependsOnBeanFactoryPostProcessor;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.data.mongodb.core.ReactiveMongoClientFactoryBean;
/**
* {@link BeanFactoryPostProcessor} to automatically set up the recommended
* {@link BeanDefinition#setDependsOn(String[]) dependsOn} configuration for Mongo clients
* when used embedded Mongo.
*
* @author Mark Paluch
* @since 2.0.0
*/
@Order(Ordered.LOWEST_PRECEDENCE)
public class ReactiveStreamsMongoClientDependsOnBeanFactoryPostProcessor extends
AbstractDependsOnBeanFactoryPostProcessor {
public ReactiveStreamsMongoClientDependsOnBeanFactoryPostProcessor(
String... dependsOn) {
super(MongoClient.class, ReactiveMongoClientFactoryBean.class, dependsOn);
}
}
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -38,6 +38,8 @@ import org.springframework.core.env.Environment; ...@@ -38,6 +38,8 @@ import org.springframework.core.env.Environment;
* @author Dave Syer * @author Dave Syer
* @author Oliver Gierke * @author Oliver Gierke
* @author Phillip Webb * @author Phillip Webb
* @author Mark Paluch
* @author Stephane Nicoll
*/ */
@Configuration @Configuration
@ConditionalOnClass(MongoClient.class) @ConditionalOnClass(MongoClient.class)
...@@ -45,19 +47,16 @@ import org.springframework.core.env.Environment; ...@@ -45,19 +47,16 @@ import org.springframework.core.env.Environment;
@ConditionalOnMissingBean(type = "org.springframework.data.mongodb.MongoDbFactory") @ConditionalOnMissingBean(type = "org.springframework.data.mongodb.MongoDbFactory")
public class MongoAutoConfiguration { public class MongoAutoConfiguration {
private final MongoProperties properties;
private final MongoClientOptions options; private final MongoClientOptions options;
private final Environment environment; private final MongoClientFactory factory;
private MongoClient mongo; private MongoClient mongo;
public MongoAutoConfiguration(MongoProperties properties, public MongoAutoConfiguration(MongoProperties properties,
ObjectProvider<MongoClientOptions> options, Environment environment) { ObjectProvider<MongoClientOptions> options, Environment environment) {
this.properties = properties;
this.options = options.getIfAvailable(); this.options = options.getIfAvailable();
this.environment = environment; this.factory = new MongoClientFactory(properties, environment);
} }
@PreDestroy @PreDestroy
...@@ -70,7 +69,7 @@ public class MongoAutoConfiguration { ...@@ -70,7 +69,7 @@ public class MongoAutoConfiguration {
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
public MongoClient mongo() throws UnknownHostException { public MongoClient mongo() throws UnknownHostException {
this.mongo = this.properties.createMongoClient(this.options, this.environment); this.mongo = this.factory.createMongoClient(this.options);
return this.mongo; return this.mongo;
} }
......
/*
* Copyright 2012-2017 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
*
* http://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.net.UnknownHostException;
import java.util.ArrayList;
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.MongoCredential;
import com.mongodb.ServerAddress;
import org.springframework.core.env.Environment;
/**
* A factory for a blocking {@link MongoClient} that applies {@link MongoProperties}.
*
* @author Dave Syer
* @author Phillip Webb
* @author Josh Long
* @author Andy Wilkinson
* @author Eddú Meléndez
* @author Stephane Nicoll
* @author Nasko Vasilev
* @author Mark Paluch
* @since 2.0.0
*/
public class MongoClientFactory {
private final MongoProperties properties;
private final Environment environment;
public MongoClientFactory(MongoProperties properties, Environment environment) {
this.properties = properties;
this.environment = environment;
}
/**
* Creates a {@link MongoClient} using the given {@code options}. If the configured
* port is zero, the value of the {@code local.mongo.port} property is used to
* configure the client.
* @param options the options
* @return the Mongo client
* @throws UnknownHostException if the configured host is unknown
*/
public MongoClient createMongoClient(MongoClientOptions options)
throws UnknownHostException {
if (hasCustomAddress() || hasCustomCredentials()) {
if (this.properties.getUri() != null) {
throw new IllegalStateException("Invalid mongo configuration, "
+ "either uri or host/port/credentials must be specified");
}
if (options == null) {
options = MongoClientOptions.builder().build();
}
List<MongoCredential> credentials = new ArrayList<MongoCredential>();
if (hasCustomCredentials()) {
String database = this.properties.getAuthenticationDatabase() == null ? this.properties
.getMongoClientDatabase() : this.properties
.getAuthenticationDatabase();
credentials.add(MongoCredential.createCredential(
this.properties.getUsername(), database,
this.properties.getPassword()));
}
String host = this.properties.getHost() == null ? "localhost"
: this.properties.getHost();
int port = determinePort();
return new MongoClient(
Collections.singletonList(new ServerAddress(host, port)),
credentials, options);
}
// The options and credentials are in the URI
return new MongoClient(new MongoClientURI(this.properties.determineUri(),
builder(options)));
}
private boolean hasCustomAddress() {
return this.properties.getHost() != null || this.properties.getPort() != null;
}
private boolean hasCustomCredentials() {
return this.properties.getUsername() != null
&& this.properties.getPassword() != null;
}
private int determinePort() {
if (this.properties.getPort() == null) {
return MongoProperties.DEFAULT_PORT;
}
if (this.properties.getPort() == 0) {
if (this.environment != null) {
String localPort = this.environment.getProperty("local.mongo.port");
if (localPort != null) {
return Integer.valueOf(localPort);
}
}
throw new IllegalStateException(
"spring.data.mongodb.port=0 and no local mongo port configuration "
+ "is available");
}
return this.properties.getPort();
}
private Builder builder(MongoClientOptions options) {
if (options != null) {
return MongoClientOptions.builder(options);
}
return MongoClientOptions.builder();
}
}
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -16,20 +16,9 @@ ...@@ -16,20 +16,9 @@
package org.springframework.boot.autoconfigure.mongo; package org.springframework.boot.autoconfigure.mongo;
import java.net.UnknownHostException;
import java.util.ArrayList;
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.MongoClientURI;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.core.env.Environment;
/** /**
* Configuration properties for Mongo. * Configuration properties for Mongo.
...@@ -41,6 +30,7 @@ import org.springframework.core.env.Environment; ...@@ -41,6 +30,7 @@ import org.springframework.core.env.Environment;
* @author Eddú Meléndez * @author Eddú Meléndez
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Nasko Vasilev * @author Nasko Vasilev
* @author Mark Paluch
*/ */
@ConfigurationProperties(prefix = "spring.data.mongodb") @ConfigurationProperties(prefix = "spring.data.mongodb")
public class MongoProperties { public class MongoProperties {
...@@ -145,15 +135,6 @@ public class MongoProperties { ...@@ -145,15 +135,6 @@ public class MongoProperties {
this.fieldNamingStrategy = fieldNamingStrategy; this.fieldNamingStrategy = fieldNamingStrategy;
} }
public void clearPassword() {
if (this.password == null) {
return;
}
for (int i = 0; i < this.password.length; i++) {
this.password[i] = 0;
}
}
public String getUri() { public String getUri() {
return this.uri; return this.uri;
} }
...@@ -189,79 +170,4 @@ public class MongoProperties { ...@@ -189,79 +170,4 @@ public class MongoProperties {
return new MongoClientURI(determineUri()).getDatabase(); return new MongoClientURI(determineUri()).getDatabase();
} }
/**
* Creates a {@link MongoClient} using the given {@code options} and
* {@code environment}. If the configured port is zero, the value of the
* {@code local.mongo.port} property retrieved from the {@code environment} is used to
* configure the client.
* @param options the options
* @param environment the environment
* @return the Mongo client
* @throws UnknownHostException if the configured host is unknown
*/
public MongoClient createMongoClient(MongoClientOptions options,
Environment environment) throws UnknownHostException {
try {
if (hasCustomAddress() || hasCustomCredentials()) {
if (this.uri != null) {
throw new IllegalStateException("Invalid mongo configuration, "
+ "either uri or host/port/credentials must be specified");
}
if (options == null) {
options = MongoClientOptions.builder().build();
}
List<MongoCredential> credentials = new ArrayList<MongoCredential>();
if (hasCustomCredentials()) {
String database = this.authenticationDatabase == null
? getMongoClientDatabase() : this.authenticationDatabase;
credentials.add(MongoCredential.createCredential(this.username,
database, this.password));
}
String host = this.host == null ? "localhost" : this.host;
int port = determinePort(environment);
return new MongoClient(
Collections.singletonList(new ServerAddress(host, port)),
credentials, options);
}
// The options and credentials are in the URI
return new MongoClient(new MongoClientURI(determineUri(), builder(options)));
}
finally {
clearPassword();
}
}
private boolean hasCustomAddress() {
return this.host != null || this.port != null;
}
private boolean hasCustomCredentials() {
return this.username != null && this.password != null;
}
private int determinePort(Environment environment) {
if (this.port == null) {
return DEFAULT_PORT;
}
if (this.port == 0) {
if (environment != null) {
String localPort = environment.getProperty("local.mongo.port");
if (localPort != null) {
return Integer.valueOf(localPort);
}
}
throw new IllegalStateException(
"spring.data.mongodb.port=0 and no local mongo port configuration "
+ "is available");
}
return this.port;
}
private Builder builder(MongoClientOptions options) {
if (options != null) {
return MongoClientOptions.builder(options);
}
return MongoClientOptions.builder();
}
} }
/*
* Copyright 2012-2017 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
*
* http://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 javax.annotation.PreDestroy;
import com.mongodb.async.client.MongoClientSettings;
import com.mongodb.reactivestreams.client.MongoClient;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
/**
* {@link EnableAutoConfiguration Auto-configuration} for Reactive Mongo.
*
* @author Mark Paluch
* @author Stephane Nicoll
* @since 2.0.0
*/
@Configuration
@ConditionalOnClass(MongoClient.class)
@EnableConfigurationProperties(MongoProperties.class)
public class ReactiveMongoAutoConfiguration {
private final MongoClientSettings settings;
private final ReactiveMongoClientFactory factory;
private MongoClient mongo;
public ReactiveMongoAutoConfiguration(MongoProperties properties,
ObjectProvider<MongoClientSettings> settings, Environment environment) {
this.settings = settings.getIfAvailable();
this.factory = new ReactiveMongoClientFactory(properties, environment);
}
@PreDestroy
public void close() {
if (this.mongo != null) {
this.mongo.close();
}
}
@Bean
@ConditionalOnMissingBean
public MongoClient reactiveStreamsMongoClient() {
this.mongo = this.factory.createMongoClient(this.settings);
return this.mongo;
}
}
/*
* Copyright 2012-2017 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
*
* http://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.ArrayList;
import java.util.Collections;
import java.util.List;
import com.mongodb.ConnectionString;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import com.mongodb.async.client.MongoClientSettings;
import com.mongodb.async.client.MongoClientSettings.Builder;
import com.mongodb.connection.ClusterSettings;
import com.mongodb.connection.ConnectionPoolSettings;
import com.mongodb.connection.ServerSettings;
import com.mongodb.connection.SocketSettings;
import com.mongodb.connection.SslSettings;
import com.mongodb.reactivestreams.client.MongoClient;
import com.mongodb.reactivestreams.client.MongoClients;
import org.springframework.core.env.Environment;
/**
* A factory for a reactive {@link MongoClient} that applies {@link MongoProperties}.
*
* @author Mark Paluch
* @author Stephane Nicoll
* @since 2.0.0
*/
public class ReactiveMongoClientFactory {
private final MongoProperties properties;
private final Environment environment;
public ReactiveMongoClientFactory(MongoProperties properties,
Environment environment) {
this.properties = properties;
this.environment = environment;
}
/**
* Creates a {@link MongoClient} using the given {@code options}. If the configured
* port is zero, the value of the {@code local.mongo.port} property is used to
* configure the client.
* @param settings the settings
* @return the Mongo client
*/
public MongoClient createMongoClient(MongoClientSettings settings) {
if (hasCustomAddress() || hasCustomCredentials()) {
if (this.properties.getUri() != null) {
throw new IllegalStateException("Invalid mongo configuration, "
+ "either uri or host/port/credentials must be specified");
}
Builder builder = builder(settings);
if (hasCustomCredentials()) {
List<MongoCredential> credentials = new ArrayList<MongoCredential>();
String database = this.properties.getAuthenticationDatabase() == null ? this.properties
.getMongoClientDatabase() : this.properties
.getAuthenticationDatabase();
credentials.add(MongoCredential.createCredential(
this.properties.getUsername(), database,
this.properties.getPassword()));
builder.credentialList(credentials);
}
String host = this.properties.getHost() == null ? "localhost"
: this.properties.getHost();
int port = determinePort();
ClusterSettings clusterSettings = ClusterSettings.builder()
.hosts(Collections.singletonList(new ServerAddress(host, port)))
.build();
builder.clusterSettings(clusterSettings);
return MongoClients.create(builder.build());
}
ConnectionString connectionString = new ConnectionString(
this.properties.determineUri());
return MongoClients.create(createBuilder(settings, connectionString).build());
}
private Builder createBuilder(MongoClientSettings settings,
ConnectionString connectionString) {
Builder builder = builder(settings)
.clusterSettings(
ClusterSettings.builder().applyConnectionString(connectionString)
.build())
.connectionPoolSettings(
ConnectionPoolSettings.builder()
.applyConnectionString(connectionString).build())
.serverSettings(
ServerSettings.builder().applyConnectionString(connectionString)
.build())
.credentialList(connectionString.getCredentialList())
.sslSettings(
SslSettings.builder().applyConnectionString(connectionString)
.build())
.socketSettings(
SocketSettings.builder().applyConnectionString(connectionString)
.build());
if (connectionString.getReadPreference() != null) {
builder.readPreference(connectionString.getReadPreference());
}
if (connectionString.getReadConcern() != null) {
builder.readConcern(connectionString.getReadConcern());
}
if (connectionString.getWriteConcern() != null) {
builder.writeConcern(connectionString.getWriteConcern());
}
if (connectionString.getApplicationName() != null) {
builder.applicationName(connectionString.getApplicationName());
}
return builder;
}
private boolean hasCustomAddress() {
return this.properties.getHost() != null || this.properties.getPort() != null;
}
private boolean hasCustomCredentials() {
return this.properties.getUsername() != null
&& this.properties.getPassword() != null;
}
private int determinePort() {
if (this.properties.getPort() == null) {
return MongoProperties.DEFAULT_PORT;
}
if (this.properties.getPort() == 0) {
if (this.environment != null) {
String localPort = this.environment.getProperty("local.mongo.port");
if (localPort != null) {
return Integer.valueOf(localPort);
}
}
throw new IllegalStateException(
"spring.data.mongodb.port=0 and no local mongo port configuration "
+ "is available");
}
return this.properties.getPort();
}
private Builder builder(MongoClientSettings settings) {
if (settings == null) {
return MongoClientSettings.builder();
}
return MongoClientSettings.builder(settings);
}
}
...@@ -53,6 +53,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; ...@@ -53,6 +53,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.data.mongo.MongoClientDependsOnBeanFactoryPostProcessor; import org.springframework.boot.autoconfigure.data.mongo.MongoClientDependsOnBeanFactoryPostProcessor;
import org.springframework.boot.autoconfigure.data.mongo.ReactiveStreamsMongoClientDependsOnBeanFactoryPostProcessor;
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
import org.springframework.boot.autoconfigure.mongo.MongoProperties; import org.springframework.boot.autoconfigure.mongo.MongoProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
...@@ -64,6 +65,7 @@ import org.springframework.core.env.MapPropertySource; ...@@ -64,6 +65,7 @@ import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.MutablePropertySources; import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource; import org.springframework.core.env.PropertySource;
import org.springframework.data.mongodb.core.MongoClientFactoryBean; import org.springframework.data.mongodb.core.MongoClientFactoryBean;
import org.springframework.data.mongodb.core.ReactiveMongoClientFactoryBean;
import org.springframework.util.Assert; import org.springframework.util.Assert;
/** /**
...@@ -72,6 +74,7 @@ import org.springframework.util.Assert; ...@@ -72,6 +74,7 @@ import org.springframework.util.Assert;
* @author Henryk Konsek * @author Henryk Konsek
* @author Andy Wilkinson * @author Andy Wilkinson
* @author Yogesh Lonkar * @author Yogesh Lonkar
* @author Mark Paluch
* @since 1.3.0 * @since 1.3.0
*/ */
@Configuration @Configuration
...@@ -226,6 +229,22 @@ public class EmbeddedMongoAutoConfiguration { ...@@ -226,6 +229,22 @@ public class EmbeddedMongoAutoConfiguration {
} }
/**
* Additional configuration to ensure that {@link MongoClient} beans depend on the
* {@code embeddedMongoServer} bean.
*/
@Configuration
@ConditionalOnClass({ com.mongodb.reactivestreams.client.MongoClient.class,
ReactiveMongoClientFactoryBean.class })
protected static class EmbeddedReactiveMongoDependencyConfiguration extends
ReactiveStreamsMongoClientDependsOnBeanFactoryPostProcessor {
public EmbeddedReactiveMongoDependencyConfiguration() {
super("embeddedMongoServer");
}
}
/** /**
* A workaround for the lack of a {@code toString} implementation on * A workaround for the lack of a {@code toString} implementation on
* {@code GenericFeatureAwareVersion}. * {@code GenericFeatureAwareVersion}.
......
...@@ -112,6 +112,12 @@ ...@@ -112,6 +112,12 @@
"description": "Enable LDAP repositories.", "description": "Enable LDAP repositories.",
"defaultValue": true "defaultValue": true
}, },
{
"name": "spring.data.mongodb.reactive-repositories.enabled",
"type": "java.lang.Boolean",
"description": "Enable Mongo reactive repositories.",
"defaultValue": true
},
{ {
"name": "spring.data.mongodb.repositories.enabled", "name": "spring.data.mongodb.repositories.enabled",
"type": "java.lang.Boolean", "type": "java.lang.Boolean",
......
...@@ -41,6 +41,8 @@ org.springframework.boot.autoconfigure.data.ldap.LdapDataAutoConfiguration,\ ...@@ -41,6 +41,8 @@ org.springframework.boot.autoconfigure.data.ldap.LdapDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.ReactiveMongoDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.ReactiveMongoRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
...@@ -83,6 +85,7 @@ org.springframework.boot.autoconfigure.mobile.DeviceDelegatingViewResolverAutoCo ...@@ -83,6 +85,7 @@ org.springframework.boot.autoconfigure.mobile.DeviceDelegatingViewResolverAutoCo
org.springframework.boot.autoconfigure.mobile.SitePreferenceAutoConfiguration,\ org.springframework.boot.autoconfigure.mobile.SitePreferenceAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\ org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\ org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.ReactiveMongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\ org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\ org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.reactor.core.ReactorCoreAutoConfiguration,\ org.springframework.boot.autoconfigure.reactor.core.ReactorCoreAutoConfiguration,\
......
/*
* Copyright 2012-2017 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
*
* http://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.alt.mongo;
import org.springframework.boot.autoconfigure.data.mongo.city.City;
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
public interface ReactiveCityMongoDbRepository
extends ReactiveCrudRepository<City, Long> {
}
/*
* Copyright 2012-2017 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
*
* http://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 java.util.ArrayList;
import java.util.List;
import org.junit.After;
import org.junit.Test;
import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
import org.springframework.boot.autoconfigure.data.mongo.city.CityRepository;
import org.springframework.boot.autoconfigure.data.mongo.city.ReactiveCityRepository;
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfigurationTests;
import org.springframework.boot.autoconfigure.mongo.ReactiveMongoAutoConfiguration;
import org.springframework.boot.test.util.EnvironmentTestUtils;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import org.springframework.data.mongodb.repository.config.EnableReactiveMongoRepositories;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link MongoRepositoriesAutoConfiguration} and
* {@link ReactiveMongoRepositoriesAutoConfiguration}.
*
* @author Mark Paluch
*/
public class ReactiveAndBlockingMongoRepositoriesAutoConfigurationTests {
private AnnotationConfigApplicationContext context;
@After
public void close() {
this.context.close();
}
@Test
public void shouldCreateInstancesForReactiveAndBlockingRepositories()
throws Exception {
this.context = new AnnotationConfigApplicationContext();
EnvironmentTestUtils.addEnvironment(this.context,
"spring.datasource.initialize:false");
this.context.register(BlockingAndReactiveConfiguration.class,
BaseConfiguration.class);
this.context.refresh();
assertThat(this.context.getBean(CityRepository.class)).isNotNull();
assertThat(this.context.getBean(ReactiveCityRepository.class)).isNotNull();
}
@Configuration
@TestAutoConfigurationPackage(MongoAutoConfigurationTests.class)
@EnableMongoRepositories(basePackageClasses = ReactiveCityRepository.class)
@EnableReactiveMongoRepositories(basePackageClasses = ReactiveCityRepository.class)
protected static class BlockingAndReactiveConfiguration {
}
@Configuration
@Import(Registrar.class)
protected static class BaseConfiguration {
}
protected static class Registrar implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
List<String> names = new ArrayList<String>();
for (Class<?> type : new Class<?>[] { MongoAutoConfiguration.class,
ReactiveMongoAutoConfiguration.class,
MongoDataAutoConfiguration.class,
MongoRepositoriesAutoConfiguration.class,
ReactiveMongoDataAutoConfiguration.class,
ReactiveMongoRepositoriesAutoConfiguration.class }) {
names.add(type.getName());
}
return names.toArray(new String[0]);
}
}
}
/*
* Copyright 2012-2017 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
*
* http://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 org.junit.After;
import org.junit.Test;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
import org.springframework.boot.autoconfigure.mongo.ReactiveMongoAutoConfiguration;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link ReactiveMongoDataAutoConfiguration}.
*
* @author Mark Paluch
*/
public class ReactiveMongoDataAutoConfigurationTests {
private AnnotationConfigApplicationContext context;
@After
public void close() {
if (this.context != null) {
this.context.close();
}
}
@Test
public void templateExists() {
this.context = new AnnotationConfigApplicationContext(
PropertyPlaceholderAutoConfiguration.class, MongoAutoConfiguration.class,
MongoDataAutoConfiguration.class, ReactiveMongoAutoConfiguration.class,
ReactiveMongoDataAutoConfiguration.class);
assertThat(this.context.getBeanNamesForType(ReactiveMongoTemplate.class))
.hasSize(1);
}
}
/*
* Copyright 2012-2017 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
*
* http://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 java.util.Set;
import com.mongodb.reactivestreams.client.MongoClient;
import org.junit.After;
import org.junit.Test;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.data.alt.mongo.CityMongoDbRepository;
import org.springframework.boot.autoconfigure.data.alt.mongo.ReactiveCityMongoDbRepository;
import org.springframework.boot.autoconfigure.data.empty.EmptyDataPackage;
import org.springframework.boot.autoconfigure.data.mongo.city.City;
import org.springframework.boot.autoconfigure.data.mongo.city.ReactiveCityRepository;
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
import org.springframework.boot.autoconfigure.mongo.ReactiveMongoAutoConfiguration;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import org.springframework.data.mongodb.repository.config.EnableReactiveMongoRepositories;
import org.springframework.test.util.ReflectionTestUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link ReactiveMongoRepositoriesAutoConfiguration}.
*
* @author Mark Paluch
*/
public class ReactiveMongoRepositoriesAutoConfigurationTests {
private AnnotationConfigApplicationContext context;
@After
public void close() {
if (this.context != null) {
this.context.close();
}
}
@Test
public void testDefaultRepositoryConfiguration() throws Exception {
prepareApplicationContext(TestConfiguration.class);
assertThat(this.context.getBean(ReactiveCityRepository.class)).isNotNull();
MongoClient client = this.context.getBean(MongoClient.class);
assertThat(client).isInstanceOf(MongoClient.class);
MongoMappingContext mappingContext = this.context
.getBean(MongoMappingContext.class);
@SuppressWarnings("unchecked")
Set<? extends Class<?>> entities = (Set<? extends Class<?>>) ReflectionTestUtils
.getField(mappingContext, "initialEntitySet");
assertThat(entities).hasSize(1);
}
@Test
public void testNoRepositoryConfiguration() throws Exception {
prepareApplicationContext(EmptyConfiguration.class);
MongoClient client = this.context.getBean(MongoClient.class);
assertThat(client).isInstanceOf(MongoClient.class);
}
@Test
public void doesNotTriggerDefaultRepositoryDetectionIfCustomized() {
prepareApplicationContext(CustomizedConfiguration.class);
assertThat(this.context.getBeansOfType(ReactiveCityMongoDbRepository.class)).isEmpty();
}
@Test(expected = NoSuchBeanDefinitionException.class)
public void autoConfigurationShouldNotKickInEvenIfManualConfigDidNotCreateAnyRepositories() {
prepareApplicationContext(SortOfInvalidCustomConfiguration.class);
this.context.getBean(ReactiveCityRepository.class);
}
private void prepareApplicationContext(Class<?>... configurationClasses) {
this.context = new AnnotationConfigApplicationContext();
this.context.register(configurationClasses);
this.context.register(MongoAutoConfiguration.class,
MongoDataAutoConfiguration.class,
ReactiveMongoAutoConfiguration.class,
ReactiveMongoDataAutoConfiguration.class,
ReactiveMongoRepositoriesAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
this.context.refresh();
}
@Configuration
@TestAutoConfigurationPackage(City.class)
protected static class TestConfiguration {
}
@Configuration
@TestAutoConfigurationPackage(EmptyDataPackage.class)
protected static class EmptyConfiguration {
}
@Configuration
@TestAutoConfigurationPackage(ReactiveMongoRepositoriesAutoConfigurationTests.class)
@EnableMongoRepositories(basePackageClasses = CityMongoDbRepository.class)
protected static class CustomizedConfiguration {
}
@Configuration
// To not find any repositories
@EnableReactiveMongoRepositories("foo.bar")
@TestAutoConfigurationPackage(ReactiveMongoRepositoriesAutoConfigurationTests.class)
protected static class SortOfInvalidCustomConfiguration {
}
}
/*
* Copyright 2012-2017 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
*
* http://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.city;
import reactor.core.publisher.Flux;
import org.springframework.data.repository.Repository;
public interface ReactiveCityRepository extends Repository<City, Long> {
Flux<City> findAll();
}
/*
* Copyright 2012-2017 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
*
* http://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.net.UnknownHostException;
import java.util.List;
import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import com.mongodb.connection.Cluster;
import com.mongodb.connection.ClusterSettings;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.util.ReflectionTestUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link MongoClientFactory}.
*
* @author Phillip Webb
* @author Andy Wilkinson
* @author Stephane Nicoll
* @author Mark Paluch
*/
public class MongoClientFactoryTests {
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test
public void portCanBeCustomized() throws UnknownHostException {
MongoProperties properties = new MongoProperties();
properties.setPort(12345);
MongoClient client = createMongoClient(properties);
List<ServerAddress> allAddresses = extractServerAddresses(client);
assertThat(allAddresses).hasSize(1);
assertServerAddress(allAddresses.get(0), "localhost", 12345);
}
@Test
public void hostCanBeCustomized() throws UnknownHostException {
MongoProperties properties = new MongoProperties();
properties.setHost("mongo.example.com");
MongoClient client = createMongoClient(properties);
List<ServerAddress> allAddresses = extractServerAddresses(client);
assertThat(allAddresses).hasSize(1);
assertServerAddress(allAddresses.get(0), "mongo.example.com", 27017);
}
@Test
public void credentialsCanBeCustomized() throws UnknownHostException {
MongoProperties properties = new MongoProperties();
properties.setUsername("user");
properties.setPassword("secret".toCharArray());
MongoClient client = createMongoClient(properties);
assertMongoCredential(client.getCredentialsList().get(0), "user", "secret",
"test");
}
@Test
public void databaseCanBeCustomized() throws UnknownHostException {
MongoProperties properties = new MongoProperties();
properties.setDatabase("foo");
properties.setUsername("user");
properties.setPassword("secret".toCharArray());
MongoClient client = createMongoClient(properties);
assertMongoCredential(client.getCredentialsList().get(0), "user", "secret",
"foo");
}
@Test
public void authenticationDatabaseCanBeCustomized() throws UnknownHostException {
MongoProperties properties = new MongoProperties();
properties.setAuthenticationDatabase("foo");
properties.setUsername("user");
properties.setPassword("secret".toCharArray());
MongoClient client = createMongoClient(properties);
assertMongoCredential(client.getCredentialsList().get(0), "user", "secret",
"foo");
}
@Test
public void uriCanBeCustomized() throws UnknownHostException {
MongoProperties properties = new MongoProperties();
properties.setUri("mongodb://user:secret@mongo1.example.com:12345,"
+ "mongo2.example.com:23456/test");
MongoClient client = createMongoClient(properties);
List<ServerAddress> allAddresses = extractServerAddresses(client);
assertThat(allAddresses).hasSize(2);
assertServerAddress(allAddresses.get(0), "mongo1.example.com", 12345);
assertServerAddress(allAddresses.get(1), "mongo2.example.com", 23456);
List<MongoCredential> credentialsList = client.getCredentialsList();
assertThat(credentialsList).hasSize(1);
assertMongoCredential(credentialsList.get(0), "user", "secret", "test");
}
@Test
public void uriCannotBeSetWithCredentials() throws UnknownHostException {
MongoProperties properties = new MongoProperties();
properties.setUri("mongodb://127.0.0.1:1234/mydb");
properties.setUsername("user");
properties.setPassword("secret".toCharArray());
this.thrown.expect(IllegalStateException.class);
this.thrown.expectMessage("Invalid mongo configuration, "
+ "either uri or host/port/credentials must be specified");
createMongoClient(properties);
}
@Test
public void uriCannotBeSetWithHostPort() throws UnknownHostException {
MongoProperties properties = new MongoProperties();
properties.setUri("mongodb://127.0.0.1:1234/mydb");
properties.setHost("localhost");
properties.setPort(4567);
this.thrown.expect(IllegalStateException.class);
this.thrown.expectMessage("Invalid mongo configuration, "
+ "either uri or host/port/credentials must be specified");
createMongoClient(properties);
}
private MongoClient createMongoClient(MongoProperties properties)
throws UnknownHostException {
return new MongoClientFactory(properties, null).createMongoClient(null);
}
private List<ServerAddress> extractServerAddresses(MongoClient client) {
Cluster cluster = (Cluster) ReflectionTestUtils.getField(client, "cluster");
ClusterSettings clusterSettings = (ClusterSettings) ReflectionTestUtils
.getField(cluster, "settings");
List<ServerAddress> allAddresses = clusterSettings.getHosts();
return allAddresses;
}
private void assertServerAddress(ServerAddress serverAddress, String expectedHost,
int expectedPort) {
assertThat(serverAddress.getHost()).isEqualTo(expectedHost);
assertThat(serverAddress.getPort()).isEqualTo(expectedPort);
}
private void assertMongoCredential(MongoCredential credentials,
String expectedUsername, String expectedPassword, String expectedSource) {
assertThat(credentials.getUserName()).isEqualTo(expectedUsername);
assertThat(credentials.getPassword()).isEqualTo(expectedPassword.toCharArray());
assertThat(credentials.getSource()).isEqualTo(expectedSource);
}
@Configuration
@EnableConfigurationProperties(MongoProperties.class)
static class Config {
}
}
/* /*
* Copyright 2012-2016 the original author or authors. * Copyright 2012-2017 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -17,14 +17,9 @@ ...@@ -17,14 +17,9 @@
package org.springframework.boot.autoconfigure.mongo; package org.springframework.boot.autoconfigure.mongo;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.List;
import com.mongodb.MongoClient; import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions; import com.mongodb.MongoClientOptions;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import com.mongodb.connection.Cluster;
import com.mongodb.connection.ClusterSettings;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.ExpectedException; import org.junit.rules.ExpectedException;
...@@ -33,7 +28,6 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties ...@@ -33,7 +28,6 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.boot.test.util.EnvironmentTestUtils; import org.springframework.boot.test.util.EnvironmentTestUtils;
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;
...@@ -43,6 +37,7 @@ import static org.assertj.core.api.Assertions.assertThat; ...@@ -43,6 +37,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Phillip Webb * @author Phillip Webb
* @author Andy Wilkinson * @author Andy Wilkinson
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Mark Paluch
*/ */
public class MongoPropertiesTests { public class MongoPropertiesTests {
...@@ -60,97 +55,6 @@ public class MongoPropertiesTests { ...@@ -60,97 +55,6 @@ public class MongoPropertiesTests {
assertThat(properties.getPassword()).isEqualTo("word".toCharArray()); assertThat(properties.getPassword()).isEqualTo("word".toCharArray());
} }
@Test
public void portCanBeCustomized() throws UnknownHostException {
MongoProperties properties = new MongoProperties();
properties.setPort(12345);
MongoClient client = properties.createMongoClient(null, null);
List<ServerAddress> allAddresses = extractServerAddresses(client);
assertThat(allAddresses).hasSize(1);
assertServerAddress(allAddresses.get(0), "localhost", 12345);
}
@Test
public void hostCanBeCustomized() throws UnknownHostException {
MongoProperties properties = new MongoProperties();
properties.setHost("mongo.example.com");
MongoClient client = properties.createMongoClient(null, null);
List<ServerAddress> allAddresses = extractServerAddresses(client);
assertThat(allAddresses).hasSize(1);
assertServerAddress(allAddresses.get(0), "mongo.example.com", 27017);
}
@Test
public void credentialsCanBeCustomized() throws UnknownHostException {
MongoProperties properties = new MongoProperties();
properties.setUsername("user");
properties.setPassword("secret".toCharArray());
MongoClient client = properties.createMongoClient(null, null);
assertMongoCredential(client.getCredentialsList().get(0), "user", "secret",
"test");
}
@Test
public void databaseCanBeCustomized() throws UnknownHostException {
MongoProperties properties = new MongoProperties();
properties.setDatabase("foo");
properties.setUsername("user");
properties.setPassword("secret".toCharArray());
MongoClient client = properties.createMongoClient(null, null);
assertMongoCredential(client.getCredentialsList().get(0), "user", "secret",
"foo");
}
@Test
public void authenticationDatabaseCanBeCustomized() throws UnknownHostException {
MongoProperties properties = new MongoProperties();
properties.setAuthenticationDatabase("foo");
properties.setUsername("user");
properties.setPassword("secret".toCharArray());
MongoClient client = properties.createMongoClient(null, null);
assertMongoCredential(client.getCredentialsList().get(0), "user", "secret",
"foo");
}
@Test
public void uriCanBeCustomized() throws UnknownHostException {
MongoProperties properties = new MongoProperties();
properties.setUri("mongodb://user:secret@mongo1.example.com:12345,"
+ "mongo2.example.com:23456/test");
MongoClient client = properties.createMongoClient(null, null);
List<ServerAddress> allAddresses = extractServerAddresses(client);
assertThat(allAddresses).hasSize(2);
assertServerAddress(allAddresses.get(0), "mongo1.example.com", 12345);
assertServerAddress(allAddresses.get(1), "mongo2.example.com", 23456);
List<MongoCredential> credentialsList = client.getCredentialsList();
assertThat(credentialsList).hasSize(1);
assertMongoCredential(credentialsList.get(0), "user", "secret", "test");
}
@Test
public void uriCannotBeSetWithCredentials() throws UnknownHostException {
MongoProperties properties = new MongoProperties();
properties.setUri("mongodb://127.0.0.1:1234/mydb");
properties.setUsername("user");
properties.setPassword("secret".toCharArray());
this.thrown.expect(IllegalStateException.class);
this.thrown.expectMessage("Invalid mongo configuration, "
+ "either uri or host/port/credentials must be specified");
properties.createMongoClient(null, null);
}
@Test
public void uriCannotBeSetWithHostPort() throws UnknownHostException {
MongoProperties properties = new MongoProperties();
properties.setUri("mongodb://127.0.0.1:1234/mydb");
properties.setHost("localhost");
properties.setPort(4567);
this.thrown.expect(IllegalStateException.class);
this.thrown.expectMessage("Invalid mongo configuration, "
+ "either uri or host/port/credentials must be specified");
properties.createMongoClient(null, null);
}
@Test @Test
public void allMongoClientOptionsCanBeSet() throws UnknownHostException { public void allMongoClientOptionsCanBeSet() throws UnknownHostException {
MongoClientOptions.Builder builder = MongoClientOptions.builder(); MongoClientOptions.Builder builder = MongoClientOptions.builder();
...@@ -174,7 +78,8 @@ public class MongoPropertiesTests { ...@@ -174,7 +78,8 @@ public class MongoPropertiesTests {
builder.requiredReplicaSetName("testReplicaSetName"); builder.requiredReplicaSetName("testReplicaSetName");
MongoClientOptions options = builder.build(); MongoClientOptions options = builder.build();
MongoProperties properties = new MongoProperties(); MongoProperties properties = new MongoProperties();
MongoClient client = properties.createMongoClient(options, null); MongoClient client = new MongoClientFactory(properties, null)
.createMongoClient(options);
MongoClientOptions wrapped = client.getMongoClientOptions(); MongoClientOptions wrapped = client.getMongoClientOptions();
assertThat(wrapped.isAlwaysUseMBeans()).isEqualTo(options.isAlwaysUseMBeans()); assertThat(wrapped.isAlwaysUseMBeans()).isEqualTo(options.isAlwaysUseMBeans());
assertThat(wrapped.getConnectionsPerHost()) assertThat(wrapped.getConnectionsPerHost())
...@@ -207,27 +112,6 @@ public class MongoPropertiesTests { ...@@ -207,27 +112,6 @@ public class MongoPropertiesTests {
.isEqualTo(options.getRequiredReplicaSetName()); .isEqualTo(options.getRequiredReplicaSetName());
} }
private List<ServerAddress> extractServerAddresses(MongoClient client) {
Cluster cluster = (Cluster) ReflectionTestUtils.getField(client, "cluster");
ClusterSettings clusterSettings = (ClusterSettings) ReflectionTestUtils
.getField(cluster, "settings");
List<ServerAddress> allAddresses = clusterSettings.getHosts();
return allAddresses;
}
private void assertServerAddress(ServerAddress serverAddress, String expectedHost,
int expectedPort) {
assertThat(serverAddress.getHost()).isEqualTo(expectedHost);
assertThat(serverAddress.getPort()).isEqualTo(expectedPort);
}
private void assertMongoCredential(MongoCredential credentials,
String expectedUsername, String expectedPassword, String expectedSource) {
assertThat(credentials.getUserName()).isEqualTo(expectedUsername);
assertThat(credentials.getPassword()).isEqualTo(expectedPassword.toCharArray());
assertThat(credentials.getSource()).isEqualTo(expectedSource);
}
@Configuration @Configuration
@EnableConfigurationProperties(MongoProperties.class) @EnableConfigurationProperties(MongoProperties.class)
static class Config { static class Config {
......
/*
* Copyright 2012-2017 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
*
* http://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.concurrent.TimeUnit;
import com.mongodb.ReadPreference;
import com.mongodb.async.client.MongoClientSettings;
import com.mongodb.connection.SocketSettings;
import com.mongodb.connection.StreamFactory;
import com.mongodb.connection.StreamFactoryFactory;
import com.mongodb.reactivestreams.client.MongoClient;
import org.junit.After;
import org.junit.Test;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.util.EnvironmentTestUtils;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
/**
* Tests for {@link ReactiveMongoAutoConfiguration}.
*
* @author Mark Paluch
*/
public class ReactiveMongoAutoConfigurationTests {
private AnnotationConfigApplicationContext context;
@After
public void close() {
if (this.context != null) {
this.context.close();
}
}
@Test
public void clientExists() {
this.context = new AnnotationConfigApplicationContext(
PropertyPlaceholderAutoConfiguration.class,
ReactiveMongoAutoConfiguration.class);
assertThat(this.context.getBeanNamesForType(MongoClient.class).length).isEqualTo(1);
}
@Test
public void optionsAdded() {
this.context = new AnnotationConfigApplicationContext();
EnvironmentTestUtils.addEnvironment(this.context,
"spring.data.mongodb.host:localhost");
this.context.register(OptionsConfig.class,
PropertyPlaceholderAutoConfiguration.class,
ReactiveMongoAutoConfiguration.class);
this.context.refresh();
assertThat(this.context.getBean(MongoClient.class).getSettings()
.getSocketSettings().getReadTimeout(TimeUnit.SECONDS)).isEqualTo(300);
}
@Test
public void optionsAddedButNoHost() {
this.context = new AnnotationConfigApplicationContext();
EnvironmentTestUtils.addEnvironment(this.context,
"spring.data.mongodb.uri:mongodb://localhost/test");
this.context.register(OptionsConfig.class,
PropertyPlaceholderAutoConfiguration.class,
ReactiveMongoAutoConfiguration.class);
this.context.refresh();
assertThat(this.context.getBean(MongoClient.class).getSettings()
.getReadPreference()).isEqualTo(ReadPreference.nearest());
}
@Test
public void optionsSslConfig() {
this.context = new AnnotationConfigApplicationContext();
EnvironmentTestUtils.addEnvironment(this.context,
"spring.data.mongodb.uri:mongodb://localhost/test");
this.context.register(SslOptionsConfig.class,
PropertyPlaceholderAutoConfiguration.class,
ReactiveMongoAutoConfiguration.class);
this.context.refresh();
MongoClient mongo = this.context.getBean(MongoClient.class);
MongoClientSettings settings = mongo.getSettings();
assertThat(settings.getApplicationName()).isEqualTo("test-config");
assertThat(settings.getStreamFactoryFactory())
.isSameAs(this.context.getBean("myStreamFactoryFactory"));
}
@Configuration
static class OptionsConfig {
@Bean
public MongoClientSettings mongoClientSettings() {
return MongoClientSettings
.builder()
.readPreference(ReadPreference.nearest())
.socketSettings(
SocketSettings.builder().readTimeout(300, TimeUnit.SECONDS)
.build()).build();
}
}
@Configuration
static class SslOptionsConfig {
@Bean
public MongoClientSettings mongoClientSettings() {
return MongoClientSettings.builder().applicationName("test-config")
.streamFactoryFactory(myStreamFactoryFactory()).build();
}
@Bean
public StreamFactoryFactory myStreamFactoryFactory() {
StreamFactoryFactory streamFactoryFactory = mock(StreamFactoryFactory.class);
given(streamFactoryFactory.create(any(), any())).willReturn(mock(StreamFactory.class));
return streamFactoryFactory;
}
}
}
/*
* Copyright 2012-2017 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
*
* http://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.net.UnknownHostException;
import java.util.List;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import com.mongodb.async.client.MongoClientSettings;
import com.mongodb.connection.ClusterSettings;
import com.mongodb.reactivestreams.client.MongoClient;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link ReactiveMongoClientFactory}.
*
* @author Mark Paluch
*/
public class ReactiveMongoClientFactoryTests {
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test
public void portCanBeCustomized() throws UnknownHostException {
MongoProperties properties = new MongoProperties();
properties.setPort(12345);
MongoClient client = createMongoClient(properties);
List<ServerAddress> allAddresses = extractServerAddresses(client);
assertThat(allAddresses).hasSize(1);
assertServerAddress(allAddresses.get(0), "localhost", 12345);
}
@Test
public void hostCanBeCustomized() throws UnknownHostException {
MongoProperties properties = new MongoProperties();
properties.setHost("mongo.example.com");
MongoClient client = createMongoClient(properties);
List<ServerAddress> allAddresses = extractServerAddresses(client);
assertThat(allAddresses).hasSize(1);
assertServerAddress(allAddresses.get(0), "mongo.example.com", 27017);
}
@Test
public void credentialsCanBeCustomized() throws UnknownHostException {
MongoProperties properties = new MongoProperties();
properties.setUsername("user");
properties.setPassword("secret".toCharArray());
MongoClient client = createMongoClient(properties);
assertMongoCredential(extractMongoCredentials(client).get(0), "user", "secret",
"test");
}
@Test
public void databaseCanBeCustomized() throws UnknownHostException {
MongoProperties properties = new MongoProperties();
properties.setDatabase("foo");
properties.setUsername("user");
properties.setPassword("secret".toCharArray());
MongoClient client = createMongoClient(properties);
assertMongoCredential(extractMongoCredentials(client).get(0), "user", "secret",
"foo");
}
@Test
public void authenticationDatabaseCanBeCustomized() throws UnknownHostException {
MongoProperties properties = new MongoProperties();
properties.setAuthenticationDatabase("foo");
properties.setUsername("user");
properties.setPassword("secret".toCharArray());
MongoClient client = createMongoClient(properties);
assertMongoCredential(extractMongoCredentials(client).get(0), "user", "secret",
"foo");
}
@Test
public void uriCanBeCustomized() throws UnknownHostException {
MongoProperties properties = new MongoProperties();
properties.setUri("mongodb://user:secret@mongo1.example.com:12345,"
+ "mongo2.example.com:23456/test");
MongoClient client = createMongoClient(properties);
List<ServerAddress> allAddresses = extractServerAddresses(client);
assertThat(allAddresses).hasSize(2);
assertServerAddress(allAddresses.get(0), "mongo1.example.com", 12345);
assertServerAddress(allAddresses.get(1), "mongo2.example.com", 23456);
List<MongoCredential> credentialsList = extractMongoCredentials(client);
assertThat(credentialsList).hasSize(1);
assertMongoCredential(credentialsList.get(0), "user", "secret", "test");
}
@Test
public void uriCannotBeSetWithCredentials() throws UnknownHostException {
MongoProperties properties = new MongoProperties();
properties.setUri("mongodb://127.0.0.1:1234/mydb");
properties.setUsername("user");
properties.setPassword("secret".toCharArray());
this.thrown.expect(IllegalStateException.class);
this.thrown.expectMessage("Invalid mongo configuration, "
+ "either uri or host/port/credentials must be specified");
createMongoClient(properties);
}
@Test
public void uriCannotBeSetWithHostPort() throws UnknownHostException {
MongoProperties properties = new MongoProperties();
properties.setUri("mongodb://127.0.0.1:1234/mydb");
properties.setHost("localhost");
properties.setPort(4567);
this.thrown.expect(IllegalStateException.class);
this.thrown.expectMessage("Invalid mongo configuration, "
+ "either uri or host/port/credentials must be specified");
createMongoClient(properties);
}
private MongoClient createMongoClient(MongoProperties properties) {
return new ReactiveMongoClientFactory(properties, null).createMongoClient(null);
}
private List<ServerAddress> extractServerAddresses(MongoClient client) {
MongoClientSettings settings = client.getSettings();
ClusterSettings clusterSettings = settings.getClusterSettings();
List<ServerAddress> allAddresses = clusterSettings.getHosts();
return allAddresses;
}
private List<MongoCredential> extractMongoCredentials(MongoClient client) {
MongoClientSettings settings = client.getSettings();
return settings.getCredentialList();
}
private void assertServerAddress(ServerAddress serverAddress, String expectedHost,
int expectedPort) {
assertThat(serverAddress.getHost()).isEqualTo(expectedHost);
assertThat(serverAddress.getPort()).isEqualTo(expectedPort);
}
private void assertMongoCredential(MongoCredential credentials,
String expectedUsername, String expectedPassword, String expectedSource) {
assertThat(credentials.getUserName()).isEqualTo(expectedUsername);
assertThat(credentials.getPassword()).isEqualTo(expectedPassword.toCharArray());
assertThat(credentials.getSource()).isEqualTo(expectedSource);
}
}
...@@ -376,6 +376,11 @@ ...@@ -376,6 +376,11 @@
<artifactId>spring-boot-starter-data-mongodb</artifactId> <artifactId>spring-boot-starter-data-mongodb</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version> <version>2.0.0.BUILD-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId> <artifactId>spring-boot-starter-data-redis</artifactId>
......
...@@ -589,6 +589,7 @@ content into your application; rather pick only the properties that you need. ...@@ -589,6 +589,7 @@ content into your application; rather pick only the properties that you need.
spring.data.mongodb.host=localhost # Mongo server host. Cannot be set with uri. spring.data.mongodb.host=localhost # Mongo server host. Cannot be set with uri.
spring.data.mongodb.password= # Login password of the mongo server. Cannot be set with uri. spring.data.mongodb.password= # Login password of the mongo server. Cannot be set with uri.
spring.data.mongodb.port=27017 # Mongo server port. Cannot be set with uri. spring.data.mongodb.port=27017 # Mongo server port. Cannot be set with uri.
spring.data.mongodb.reactive-repositories.enabled=true # Enable Mongo reactive repositories.
spring.data.mongodb.repositories.enabled=true # Enable Mongo repositories. spring.data.mongodb.repositories.enabled=true # Enable Mongo repositories.
spring.data.mongodb.uri=mongodb://localhost/test # Mongo database URI. Cannot be set with host, port and credentials. spring.data.mongodb.uri=mongodb://localhost/test # Mongo database URI. Cannot be set with host, port and credentials.
spring.data.mongodb.username= # Login user of the mongo server. Cannot be set with uri. spring.data.mongodb.username= # Login user of the mongo server. Cannot be set with uri.
......
...@@ -3299,7 +3299,8 @@ pooled connection factory by default. ...@@ -3299,7 +3299,8 @@ pooled connection factory by default.
http://www.mongodb.com/[MongoDB] is an open-source NoSQL document database that uses a http://www.mongodb.com/[MongoDB] is an open-source NoSQL document database that uses a
JSON-like schema instead of traditional table-based relational data. Spring Boot offers JSON-like schema instead of traditional table-based relational data. Spring Boot offers
several conveniences for working with MongoDB, including the several conveniences for working with MongoDB, including the
`spring-boot-starter-data-mongodb` '`Starter`'. `spring-boot-starter-data-mongodb` and `spring-boot-starter-data-mongodb-reactive`
'`Starters`'.
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
<module>spring-boot-starter-data-jpa</module> <module>spring-boot-starter-data-jpa</module>
<module>spring-boot-starter-data-ldap</module> <module>spring-boot-starter-data-ldap</module>
<module>spring-boot-starter-data-mongodb</module> <module>spring-boot-starter-data-mongodb</module>
<module>spring-boot-starter-data-mongodb-reactive</module>
<module>spring-boot-starter-data-neo4j</module> <module>spring-boot-starter-data-neo4j</module>
<module>spring-boot-starter-data-redis</module> <module>spring-boot-starter-data-redis</module>
<module>spring-boot-starter-data-rest</module> <module>spring-boot-starter-data-rest</module>
......
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starters</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
</parent>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
<name>Spring Boot Data MongoDB Reactive Starter</name>
<description>Starter for using MongoDB document-oriented database and Spring Data
MongoDB Reactive</description>
<url>http://projects.spring.io/spring-boot/</url>
<organization>
<name>Pivotal Software, Inc.</name>
<url>http://www.spring.io</url>
</organization>
<properties>
<main.basedir>${basedir}/../..</main.basedir>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<exclusions>
<exclusion>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver</artifactId>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-async</artifactId>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-reactivestreams</artifactId>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
</dependency>
</dependencies>
</project>
provides: spring-data-mongodb,mongodb-driver-async,mongodb-driver-reactivestreams
\ No newline at end of file
provides: spring-data-mongodb provides: spring-data-mongodb,mongodb-driver
\ No newline at end of file \ No newline at end of file
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