Merge pull request #8230 from mp911de:issue/8051-reactive-mongo
* pr/8230: Polish contribution Provide a starter for reactive Spring Data MongoDB
This commit is contained in:
commit
1fdcc3d002
|
|
@ -299,6 +299,16 @@
|
|||
<artifactId>jboss-transaction-spi</artifactId>
|
||||
<optional>true</optional>
|
||||
</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>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jdbc</artifactId>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* 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 {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* 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 {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* 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");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -38,6 +38,8 @@ import org.springframework.core.env.Environment;
|
|||
* @author Dave Syer
|
||||
* @author Oliver Gierke
|
||||
* @author Phillip Webb
|
||||
* @author Mark Paluch
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass(MongoClient.class)
|
||||
|
|
@ -45,19 +47,16 @@ import org.springframework.core.env.Environment;
|
|||
@ConditionalOnMissingBean(type = "org.springframework.data.mongodb.MongoDbFactory")
|
||||
public class MongoAutoConfiguration {
|
||||
|
||||
private final MongoProperties properties;
|
||||
|
||||
private final MongoClientOptions options;
|
||||
|
||||
private final Environment environment;
|
||||
private final MongoClientFactory factory;
|
||||
|
||||
private MongoClient mongo;
|
||||
|
||||
public MongoAutoConfiguration(MongoProperties properties,
|
||||
ObjectProvider<MongoClientOptions> options, Environment environment) {
|
||||
this.properties = properties;
|
||||
this.options = options.getIfAvailable();
|
||||
this.environment = environment;
|
||||
this.factory = new MongoClientFactory(properties, environment);
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
|
|
@ -70,7 +69,7 @@ public class MongoAutoConfiguration {
|
|||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public MongoClient mongo() throws UnknownHostException {
|
||||
this.mongo = this.properties.createMongoClient(this.options, this.environment);
|
||||
this.mongo = this.factory.createMongoClient(this.options);
|
||||
return this.mongo;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* 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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* 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");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -16,20 +16,9 @@
|
|||
|
||||
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.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
/**
|
||||
* Configuration properties for Mongo.
|
||||
|
|
@ -41,6 +30,7 @@ import org.springframework.core.env.Environment;
|
|||
* @author Eddú Meléndez
|
||||
* @author Stephane Nicoll
|
||||
* @author Nasko Vasilev
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "spring.data.mongodb")
|
||||
public class MongoProperties {
|
||||
|
|
@ -145,15 +135,6 @@ public class MongoProperties {
|
|||
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() {
|
||||
return this.uri;
|
||||
}
|
||||
|
|
@ -189,79 +170,4 @@ public class MongoProperties {
|
|||
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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
* 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;
|
|||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
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.MongoProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
|
|
@ -64,6 +65,7 @@ import org.springframework.core.env.MapPropertySource;
|
|||
import org.springframework.core.env.MutablePropertySources;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.data.mongodb.core.MongoClientFactoryBean;
|
||||
import org.springframework.data.mongodb.core.ReactiveMongoClientFactoryBean;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
|
|
@ -72,6 +74,7 @@ import org.springframework.util.Assert;
|
|||
* @author Henryk Konsek
|
||||
* @author Andy Wilkinson
|
||||
* @author Yogesh Lonkar
|
||||
* @author Mark Paluch
|
||||
* @since 1.3.0
|
||||
*/
|
||||
@Configuration
|
||||
|
|
@ -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
|
||||
* {@code GenericFeatureAwareVersion}.
|
||||
|
|
|
|||
|
|
@ -112,6 +112,12 @@
|
|||
"description": "Enable LDAP repositories.",
|
||||
"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",
|
||||
"type": "java.lang.Boolean",
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ org.springframework.boot.autoconfigure.data.ldap.LdapDataAutoConfiguration,\
|
|||
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
|
||||
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.Neo4jRepositoriesAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
|
||||
|
|
@ -83,6 +85,7 @@ org.springframework.boot.autoconfigure.mobile.DeviceDelegatingViewResolverAutoCo
|
|||
org.springframework.boot.autoconfigure.mobile.SitePreferenceAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.mongo.ReactiveMongoAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.reactor.core.ReactorCoreAutoConfiguration,\
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* 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> {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* 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]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* 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 {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 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();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,173 @@
|
|||
/*
|
||||
* 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 {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* 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");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -17,14 +17,9 @@
|
|||
package org.springframework.boot.autoconfigure.mongo;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.List;
|
||||
|
||||
import com.mongodb.MongoClient;
|
||||
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.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
|
@ -33,7 +28,6 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
|
|||
import org.springframework.boot.test.util.EnvironmentTestUtils;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
|
|
@ -43,6 +37,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
* @author Stephane Nicoll
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class MongoPropertiesTests {
|
||||
|
||||
|
|
@ -60,97 +55,6 @@ public class MongoPropertiesTests {
|
|||
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
|
||||
public void allMongoClientOptionsCanBeSet() throws UnknownHostException {
|
||||
MongoClientOptions.Builder builder = MongoClientOptions.builder();
|
||||
|
|
@ -174,7 +78,8 @@ public class MongoPropertiesTests {
|
|||
builder.requiredReplicaSetName("testReplicaSetName");
|
||||
MongoClientOptions options = builder.build();
|
||||
MongoProperties properties = new MongoProperties();
|
||||
MongoClient client = properties.createMongoClient(options, null);
|
||||
MongoClient client = new MongoClientFactory(properties, null)
|
||||
.createMongoClient(options);
|
||||
MongoClientOptions wrapped = client.getMongoClientOptions();
|
||||
assertThat(wrapped.isAlwaysUseMBeans()).isEqualTo(options.isAlwaysUseMBeans());
|
||||
assertThat(wrapped.getConnectionsPerHost())
|
||||
|
|
@ -207,27 +112,6 @@ public class MongoPropertiesTests {
|
|||
.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
|
||||
@EnableConfigurationProperties(MongoProperties.class)
|
||||
static class Config {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
* 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 @@
|
|||
<artifactId>spring-boot-starter-data-mongodb</artifactId>
|
||||
<version>2.0.0.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
|
||||
<version>2.0.0.BUILD-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
|
|
|
|||
|
|
@ -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.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.reactive-repositories.enabled=true # Enable Mongo reactive 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.username= # Login user of the mongo server. Cannot be set with uri.
|
||||
|
|
|
|||
|
|
@ -3299,7 +3299,8 @@ pooled connection factory by default.
|
|||
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
|
||||
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 @@
|
|||
<module>spring-boot-starter-data-jpa</module>
|
||||
<module>spring-boot-starter-data-ldap</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-redis</module>
|
||||
<module>spring-boot-starter-data-rest</module>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
<?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>
|
||||
|
|
@ -0,0 +1 @@
|
|||
provides: spring-data-mongodb,mongodb-driver-async,mongodb-driver-reactivestreams
|
||||
|
|
@ -1 +1 @@
|
|||
provides: spring-data-mongodb
|
||||
provides: spring-data-mongodb,mongodb-driver
|
||||
Loading…
Reference in New Issue