Flesh out and polish Embedded MongoDB auto-configuration contribution
Embedded MongoDB is now auto-configured when it is on the classpath. The Mongo instance will listen on the port specified by the spring.data.mongodb.port property. If this property has a value of zero and randomly allocated port will be used. In such an event, the MongoClient created by MongoAutoConfiguration will be automatically configured to use the port that was allocated. By default, MongoDB 2.6.10 will be used. This can be configured using the spring.embedded-mongodb.version property. Mongo's sync delay feature is enabled by default. This can be configured using the spring.embedded-mongobd.features property. Closes gh-2002
This commit is contained in:
parent
f2b2c085e9
commit
2c81907d58
|
|
@ -25,11 +25,6 @@
|
|||
<artifactId>spring-boot</artifactId>
|
||||
</dependency>
|
||||
<!-- Optional -->
|
||||
<dependency>
|
||||
<groupId>de.flapdoodle.embed</groupId>
|
||||
<artifactId>de.flapdoodle.embed.mongo</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.atomikos</groupId>
|
||||
<artifactId>transactions-jdbc</artifactId>
|
||||
|
|
@ -85,6 +80,11 @@
|
|||
<artifactId>javax.mail</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.flapdoodle.embed</groupId>
|
||||
<artifactId>de.flapdoodle.embed.mongo</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.cache</groupId>
|
||||
<artifactId>cache-api</artifactId>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Copyright 2012-2015 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;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.ListableBeanFactory;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Abstract base class for a {@link BeanFactoryPostProcessor} that can be used to
|
||||
* dynamically declare that all beans of a specific type should depend on one or more
|
||||
* specific beans
|
||||
*
|
||||
* @author Marcel Overdijk
|
||||
* @author Dave Syer
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
* @since 1.3.0
|
||||
* @see BeanDefinition#setDependsOn(String[])
|
||||
*/
|
||||
public abstract class AbstractDependsOnBeanFactoryPostProcessor implements
|
||||
BeanFactoryPostProcessor {
|
||||
|
||||
private final Class<?> beanClass;
|
||||
|
||||
private final Class<? extends FactoryBean<?>> factoryBeanClass;
|
||||
|
||||
private final String[] dependsOn;
|
||||
|
||||
protected AbstractDependsOnBeanFactoryPostProcessor(Class<?> beanClass,
|
||||
Class<? extends FactoryBean<?>> factoryBeanClass, String... dependsOn) {
|
||||
this.beanClass = beanClass;
|
||||
this.factoryBeanClass = factoryBeanClass;
|
||||
this.dependsOn = dependsOn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
|
||||
for (String beanName : getBeanNames(beanFactory)) {
|
||||
BeanDefinition definition = getBeanDefinition(beanName, beanFactory);
|
||||
String[] dependencies = definition.getDependsOn();
|
||||
for (String bean : this.dependsOn) {
|
||||
dependencies = StringUtils.addStringToArray(dependencies, bean);
|
||||
}
|
||||
definition.setDependsOn(dependencies);
|
||||
}
|
||||
}
|
||||
|
||||
private Iterable<String> getBeanNames(ListableBeanFactory beanFactory) {
|
||||
Set<String> names = new HashSet<String>();
|
||||
names.addAll(Arrays.asList(BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
|
||||
beanFactory, this.beanClass, true, false)));
|
||||
for (String factoryBeanName : BeanFactoryUtils
|
||||
.beanNamesForTypeIncludingAncestors(beanFactory, this.factoryBeanClass,
|
||||
true, false)) {
|
||||
names.add(BeanFactoryUtils.transformedBeanName(factoryBeanName));
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
private static BeanDefinition getBeanDefinition(String beanName,
|
||||
ConfigurableListableBeanFactory beanFactory) {
|
||||
try {
|
||||
return beanFactory.getBeanDefinition(beanName);
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException ex) {
|
||||
BeanFactory parentBeanFactory = beanFactory.getParentBeanFactory();
|
||||
if (parentBeanFactory instanceof ConfigurableListableBeanFactory) {
|
||||
return getBeanDefinition(beanName,
|
||||
(ConfigurableListableBeanFactory) parentBeanFactory);
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16,79 +16,30 @@
|
|||
|
||||
package org.springframework.boot.autoconfigure.data.jpa;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||
import org.springframework.beans.factory.ListableBeanFactory;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.boot.autoconfigure.AbstractDependsOnBeanFactoryPostProcessor;
|
||||
import org.springframework.orm.jpa.AbstractEntityManagerFactoryBean;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link BeanFactoryPostProcessor} that can be used to dynamically declare that all
|
||||
* {@link EntityManagerFactory} beans should "depend on" a specific bean.
|
||||
* {@link EntityManagerFactory} beans should "depend on" one or more specific beans.
|
||||
*
|
||||
* @author Marcel Overdijk
|
||||
* @author Dave Syer
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
* @since 1.1.0
|
||||
* @see BeanDefinition#setDependsOn(String[])
|
||||
*/
|
||||
public class EntityManagerFactoryDependsOnPostProcessor implements
|
||||
BeanFactoryPostProcessor {
|
||||
|
||||
private final String[] dependsOn;
|
||||
public class EntityManagerFactoryDependsOnPostProcessor extends
|
||||
AbstractDependsOnBeanFactoryPostProcessor {
|
||||
|
||||
public EntityManagerFactoryDependsOnPostProcessor(String... dependsOn) {
|
||||
this.dependsOn = dependsOn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
|
||||
for (String beanName : getEntityManagerFactoryBeanNames(beanFactory)) {
|
||||
BeanDefinition definition = getBeanDefinition(beanName, beanFactory);
|
||||
String[] dependencies = definition.getDependsOn();
|
||||
for (String bean : this.dependsOn) {
|
||||
dependencies = StringUtils.addStringToArray(dependencies, bean);
|
||||
}
|
||||
definition.setDependsOn(dependencies);
|
||||
}
|
||||
}
|
||||
|
||||
private static BeanDefinition getBeanDefinition(String beanName,
|
||||
ConfigurableListableBeanFactory beanFactory) {
|
||||
try {
|
||||
return beanFactory.getBeanDefinition(beanName);
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException ex) {
|
||||
BeanFactory parentBeanFactory = beanFactory.getParentBeanFactory();
|
||||
if (parentBeanFactory instanceof ConfigurableListableBeanFactory) {
|
||||
return getBeanDefinition(beanName,
|
||||
(ConfigurableListableBeanFactory) parentBeanFactory);
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
private Iterable<String> getEntityManagerFactoryBeanNames(
|
||||
ListableBeanFactory beanFactory) {
|
||||
Set<String> names = new HashSet<String>();
|
||||
names.addAll(Arrays.asList(BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
|
||||
beanFactory, EntityManagerFactory.class, true, false)));
|
||||
for (String factoryBeanName : BeanFactoryUtils
|
||||
.beanNamesForTypeIncludingAncestors(beanFactory,
|
||||
AbstractEntityManagerFactoryBean.class, true, false)) {
|
||||
names.add(BeanFactoryUtils.transformedBeanName(factoryBeanName));
|
||||
}
|
||||
return names;
|
||||
super(EntityManagerFactory.class, AbstractEntityManagerFactoryBean.class,
|
||||
dependsOn);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,35 +0,0 @@
|
|||
package org.springframework.boot.autoconfigure.mongo;
|
||||
|
||||
import com.mongodb.Mongo;
|
||||
import de.flapdoodle.embed.mongo.MongodExecutable;
|
||||
import de.flapdoodle.embed.mongo.MongodStarter;
|
||||
import de.flapdoodle.embed.mongo.config.IMongodConfig;
|
||||
import de.flapdoodle.embed.mongo.config.MongodConfigBuilder;
|
||||
import de.flapdoodle.embed.mongo.config.Net;
|
||||
import de.flapdoodle.embed.mongo.distribution.Version;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static de.flapdoodle.embed.process.runtime.Network.localhostIsIPv6;
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass({ Mongo.class, MongodStarter.class})
|
||||
public class EmbedMongoAutoConfiguration {
|
||||
|
||||
@Autowired
|
||||
private MongoProperties properties;
|
||||
|
||||
@Bean(initMethod = "start", destroyMethod = "stop")
|
||||
public MongodExecutable embedMongoServer() throws IOException {
|
||||
IMongodConfig mongodConfig = new MongodConfigBuilder()
|
||||
.version(Version.Main.PRODUCTION)
|
||||
.net(new Net(properties.getPort(), localhostIsIPv6()))
|
||||
.build();
|
||||
return MongodStarter.getDefaultInstance().prepare(mongodConfig);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -27,6 +27,7 @@ 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;
|
||||
|
||||
import com.mongodb.MongoClient;
|
||||
import com.mongodb.MongoClientOptions;
|
||||
|
|
@ -50,6 +51,9 @@ public class MongoAutoConfiguration {
|
|||
@Autowired(required = false)
|
||||
private MongoClientOptions options;
|
||||
|
||||
@Autowired
|
||||
private Environment environment;
|
||||
|
||||
private MongoClient mongo;
|
||||
|
||||
@PreDestroy
|
||||
|
|
@ -62,7 +66,7 @@ public class MongoAutoConfiguration {
|
|||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public MongoClient mongo() throws UnknownHostException {
|
||||
this.mongo = this.properties.createMongoClient(this.options);
|
||||
this.mongo = this.properties.createMongoClient(this.options, this.environment);
|
||||
return this.mongo;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import java.util.Arrays;
|
|||
import java.util.List;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.data.mapping.model.FieldNamingStrategy;
|
||||
|
||||
import com.mongodb.MongoClient;
|
||||
|
|
@ -42,7 +43,10 @@ import com.mongodb.ServerAddress;
|
|||
@ConfigurationProperties(prefix = "spring.data.mongodb")
|
||||
public class MongoProperties {
|
||||
|
||||
private static final int DEFAULT_PORT = 27017;
|
||||
/**
|
||||
* Default port used when the configured port is {@code null}.
|
||||
*/
|
||||
public static final int DEFAULT_PORT = 27017;
|
||||
|
||||
/**
|
||||
* Mongo server host.
|
||||
|
|
@ -178,8 +182,34 @@ public class MongoProperties {
|
|||
return new MongoClientURI(this.uri).getDatabase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link MongoClient} using the given {@code options}
|
||||
*
|
||||
* @param options the options
|
||||
* @return the Mongo client
|
||||
* @throws UnknownHostException if the configured host is unknown
|
||||
* @deprecated Since 1.3.0 in favour of
|
||||
* {@link #createMongoClient(MongoClientOptions, Environment)}
|
||||
*/
|
||||
@Deprecated
|
||||
public MongoClient createMongoClient(MongoClientOptions options)
|
||||
throws UnknownHostException {
|
||||
return this.createMongoClient(options, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link MongoClient} using the given {@code options} and
|
||||
* {@code environment}. If the configured port is zero, the value of the
|
||||
* {@code local.server.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 (options == null) {
|
||||
|
|
@ -193,7 +223,7 @@ public class MongoProperties {
|
|||
this.username, database, this.password));
|
||||
}
|
||||
String host = this.host == null ? "localhost" : this.host;
|
||||
int port = this.port == null ? DEFAULT_PORT : this.port;
|
||||
int port = determinePort(environment);
|
||||
return new MongoClient(Arrays.asList(new ServerAddress(host, port)),
|
||||
credentials, options);
|
||||
}
|
||||
|
|
@ -213,6 +243,24 @@ public class MongoProperties {
|
|||
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) {
|
||||
Builder builder = MongoClientOptions.builder();
|
||||
if (options != null) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,259 @@
|
|||
/*
|
||||
* Copyright 2012-2015 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.embedded;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
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.MongoAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.MapPropertySource;
|
||||
import org.springframework.core.env.MutablePropertySources;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.mongodb.Mongo;
|
||||
import com.mongodb.MongoClient;
|
||||
|
||||
import de.flapdoodle.embed.mongo.Command;
|
||||
import de.flapdoodle.embed.mongo.MongodExecutable;
|
||||
import de.flapdoodle.embed.mongo.MongodStarter;
|
||||
import de.flapdoodle.embed.mongo.config.ArtifactStoreBuilder;
|
||||
import de.flapdoodle.embed.mongo.config.DownloadConfigBuilder;
|
||||
import de.flapdoodle.embed.mongo.config.IMongodConfig;
|
||||
import de.flapdoodle.embed.mongo.config.MongodConfigBuilder;
|
||||
import de.flapdoodle.embed.mongo.config.Net;
|
||||
import de.flapdoodle.embed.mongo.config.RuntimeConfigBuilder;
|
||||
import de.flapdoodle.embed.mongo.distribution.Feature;
|
||||
import de.flapdoodle.embed.mongo.distribution.IFeatureAwareVersion;
|
||||
import de.flapdoodle.embed.process.config.IRuntimeConfig;
|
||||
import de.flapdoodle.embed.process.config.io.ProcessOutput;
|
||||
import de.flapdoodle.embed.process.io.Processors;
|
||||
import de.flapdoodle.embed.process.io.Slf4jLevel;
|
||||
import de.flapdoodle.embed.process.io.progress.Slf4jProgressListener;
|
||||
|
||||
import static de.flapdoodle.embed.process.runtime.Network.localhostIsIPv6;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for Embedded Mongo.
|
||||
*
|
||||
* @author Henryk Konsek
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@Configuration
|
||||
@EnableConfigurationProperties({ MongoProperties.class, EmbeddedMongoProperties.class })
|
||||
@AutoConfigureBefore(MongoAutoConfiguration.class)
|
||||
@ConditionalOnClass({ Mongo.class, MongodStarter.class })
|
||||
public class EmbeddedMongoAutoConfiguration {
|
||||
|
||||
@Autowired
|
||||
private MongoProperties properties;
|
||||
|
||||
@Autowired
|
||||
private EmbeddedMongoProperties embeddedProperties;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@Bean(initMethod = "start", destroyMethod = "stop")
|
||||
@ConditionalOnMissingBean
|
||||
public MongodExecutable embeddedMongoServer(IMongodConfig mongodConfig,
|
||||
IRuntimeConfig runtimeConfig) throws IOException {
|
||||
return createEmbeddedMongoServer(mongodConfig, runtimeConfig);
|
||||
}
|
||||
|
||||
@Bean(initMethod = "start", destroyMethod = "stop")
|
||||
@ConditionalOnMissingBean
|
||||
public MongodExecutable embeddedMongoServer(IMongodConfig mongodConfig)
|
||||
throws IOException {
|
||||
return createEmbeddedMongoServer(mongodConfig, null);
|
||||
}
|
||||
|
||||
private MongodExecutable createEmbeddedMongoServer(IMongodConfig mongodConfig,
|
||||
IRuntimeConfig runtimeConfig) {
|
||||
if (getPort() == 0) {
|
||||
publishPortInfo(mongodConfig.net().getPort());
|
||||
}
|
||||
MongodStarter mongodStarter = runtimeConfig == null ? MongodStarter
|
||||
.getDefaultInstance() : MongodStarter.getInstance(runtimeConfig);
|
||||
return mongodStarter.prepare(mongodConfig);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnClass(Logger.class)
|
||||
public IRuntimeConfig embeddedMongoRuntimeConfig() {
|
||||
Logger logger = LoggerFactory.getLogger(getClass().getPackage().getName()
|
||||
+ ".EmbeddedMongo");
|
||||
|
||||
ProcessOutput processOutput = new ProcessOutput(
|
||||
Processors.logTo(logger, Slf4jLevel.INFO),
|
||||
Processors.logTo(logger, Slf4jLevel.ERROR),
|
||||
Processors.named("[console>]", Processors.logTo(logger, Slf4jLevel.DEBUG)));
|
||||
|
||||
return new RuntimeConfigBuilder()
|
||||
.defaultsWithLogger(Command.MongoD, logger)
|
||||
.processOutput(processOutput)
|
||||
.artifactStore(
|
||||
new ArtifactStoreBuilder().defaults(Command.MongoD).download(
|
||||
new DownloadConfigBuilder().defaultsForCommand(
|
||||
Command.MongoD).progressListener(
|
||||
new Slf4jProgressListener(logger)))).build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public IMongodConfig embeddedMongoConfiguration() throws IOException {
|
||||
IFeatureAwareVersion featureAwareVersion = new ToStringFriendlyFeatureAwareVersion(
|
||||
this.embeddedProperties.getVersion(),
|
||||
this.embeddedProperties.getFeatures());
|
||||
MongodConfigBuilder builder = new MongodConfigBuilder()
|
||||
.version(featureAwareVersion);
|
||||
if (getPort() > 0) {
|
||||
builder.net(new Net(getPort(), localhostIsIPv6()));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private int getPort() {
|
||||
return this.properties.getPort() == null ? MongoProperties.DEFAULT_PORT
|
||||
: this.properties.getPort();
|
||||
}
|
||||
|
||||
private void publishPortInfo(int port) {
|
||||
setPortProperty(this.context, port);
|
||||
}
|
||||
|
||||
private void setPortProperty(ApplicationContext context, int port) {
|
||||
if (context instanceof ConfigurableApplicationContext) {
|
||||
ConfigurableEnvironment environment = ((ConfigurableApplicationContext) context)
|
||||
.getEnvironment();
|
||||
MutablePropertySources sources = environment.getPropertySources();
|
||||
Map<String, Object> map;
|
||||
if (!sources.contains("mongo.ports")) {
|
||||
map = new HashMap<String, Object>();
|
||||
MapPropertySource source = new MapPropertySource("mongo.ports", map);
|
||||
sources.addFirst(source);
|
||||
}
|
||||
else {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> value = (Map<String, Object>) sources.get(
|
||||
"mongo.ports").getSource();
|
||||
map = value;
|
||||
}
|
||||
map.put("local.mongo.port", port);
|
||||
}
|
||||
if (this.context.getParent() != null) {
|
||||
setPortProperty(this.context.getParent(), port);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Additional configuration to ensure that {@link MongoClient} beans depend on the
|
||||
* {@code embeddedMongoServer} bean.
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass(MongoClient.class)
|
||||
protected static class EmbeddedMongoDependencyConfiguration extends
|
||||
MongoClientDependsOnBeanFactoryPostProcessor {
|
||||
|
||||
public EmbeddedMongoDependencyConfiguration() {
|
||||
super("embeddedMongoServer");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A workaround for the lack of a {@code toString} implementation on
|
||||
* {@code GenericFeatureAwareVersion}.
|
||||
*/
|
||||
private static class ToStringFriendlyFeatureAwareVersion implements
|
||||
IFeatureAwareVersion {
|
||||
|
||||
private final String version;
|
||||
|
||||
private final Set<Feature> features;
|
||||
|
||||
private ToStringFriendlyFeatureAwareVersion(String version, Set<Feature> features) {
|
||||
Assert.notNull(version, "version must not be null");
|
||||
this.version = version;
|
||||
this.features = features == null ? Collections.<Feature> emptySet()
|
||||
: features;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String asInDownloadPath() {
|
||||
return this.version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean enabled(Feature feature) {
|
||||
return this.features.contains(feature);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + this.features.hashCode();
|
||||
result = prime * result + this.version.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
ToStringFriendlyFeatureAwareVersion other = (ToStringFriendlyFeatureAwareVersion) obj;
|
||||
if (!this.features.equals(other.features)) {
|
||||
return false;
|
||||
}
|
||||
else if (!this.version.equals(other.version)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright 2012-2015 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.embedded;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
import de.flapdoodle.embed.mongo.distribution.Feature;
|
||||
|
||||
/**
|
||||
* Configuration properties for Embedded Mongo
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 1.3.0
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "spring.embedded-mongodb")
|
||||
public class EmbeddedMongoProperties {
|
||||
|
||||
/**
|
||||
* Version of Mongo to use
|
||||
*/
|
||||
private String version = "2.6.10";
|
||||
|
||||
/**
|
||||
* Comma-separated list of features to enable
|
||||
*/
|
||||
private Set<Feature> features = new HashSet<Feature>(
|
||||
Arrays.asList(Feature.SYNC_DELAY));
|
||||
|
||||
public String getVersion() {
|
||||
return this.version;
|
||||
}
|
||||
|
||||
public void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public Set<Feature> getFeatures() {
|
||||
return this.features;
|
||||
}
|
||||
|
||||
public void setFeatures(Set<Feature> features) {
|
||||
this.features = features;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright 2012-2015 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.embedded;
|
||||
|
||||
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.MongoClientFactoryBean;
|
||||
|
||||
import com.mongodb.MongoClient;
|
||||
|
||||
/**
|
||||
* {@link BeanFactoryPostProcessor} to automatically set up the recommended
|
||||
* {@link BeanDefinition#setDependsOn(String[]) dependsOn} configuration for Mongo clients
|
||||
* when used embedded Mongo.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 1.3.0
|
||||
*/
|
||||
@Order(Ordered.LOWEST_PRECEDENCE)
|
||||
public class MongoClientDependsOnBeanFactoryPostProcessor extends
|
||||
AbstractDependsOnBeanFactoryPostProcessor {
|
||||
|
||||
public MongoClientDependsOnBeanFactoryPostProcessor(String... dependsOn) {
|
||||
super(MongoClient.class, MongoClientFactoryBean.class, dependsOn);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -46,7 +46,7 @@ org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration
|
|||
org.springframework.boot.autoconfigure.mobile.DeviceResolverAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.mobile.DeviceDelegatingViewResolverAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.mobile.SitePreferenceAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.mongo.EmbedMongoAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.mongo.MongoDataAutoConfiguration,\
|
||||
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
|
||||
|
|
|
|||
|
|
@ -1,52 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-2014 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 com.mongodb.CommandResult;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.springframework.boot.test.EnvironmentTestUtils.addEnvironment;
|
||||
import static org.springframework.util.SocketUtils.findAvailableTcpPort;
|
||||
|
||||
public class EmbedMongoAutoConfigurationTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnVersionOfEmbeddedMongoServer() {
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
int mongoPort = findAvailableTcpPort();
|
||||
addEnvironment(context, "spring.data.mongodb.host=localhost", "spring.data.mongodb.port=" + mongoPort);
|
||||
context.register(MongoAutoConfiguration.class, MongoDataAutoConfiguration.class, EmbedMongoAutoConfiguration.class);
|
||||
context.refresh();
|
||||
MongoTemplate mongo = context.getBean(MongoTemplate.class);
|
||||
CommandResult buildInfo = mongo.executeCommand("{ buildInfo: 1 }");
|
||||
assertEquals("2.6.1", buildInfo.getString("version"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -57,7 +57,7 @@ public class MongoPropertiesTests {
|
|||
public void portCanBeCustomized() throws UnknownHostException {
|
||||
MongoProperties properties = new MongoProperties();
|
||||
properties.setPort(12345);
|
||||
MongoClient client = properties.createMongoClient(null);
|
||||
MongoClient client = properties.createMongoClient(null, null);
|
||||
List<ServerAddress> allAddresses = client.getAllAddress();
|
||||
assertThat(allAddresses, hasSize(1));
|
||||
assertServerAddress(allAddresses.get(0), "localhost", 12345);
|
||||
|
|
@ -67,7 +67,7 @@ public class MongoPropertiesTests {
|
|||
public void hostCanBeCustomized() throws UnknownHostException {
|
||||
MongoProperties properties = new MongoProperties();
|
||||
properties.setHost("mongo.example.com");
|
||||
MongoClient client = properties.createMongoClient(null);
|
||||
MongoClient client = properties.createMongoClient(null, null);
|
||||
List<ServerAddress> allAddresses = client.getAllAddress();
|
||||
assertThat(allAddresses, hasSize(1));
|
||||
assertServerAddress(allAddresses.get(0), "mongo.example.com", 27017);
|
||||
|
|
@ -78,7 +78,7 @@ public class MongoPropertiesTests {
|
|||
MongoProperties properties = new MongoProperties();
|
||||
properties.setUsername("user");
|
||||
properties.setPassword("secret".toCharArray());
|
||||
MongoClient client = properties.createMongoClient(null);
|
||||
MongoClient client = properties.createMongoClient(null, null);
|
||||
assertMongoCredential(client.getCredentialsList().get(0), "user", "secret",
|
||||
"test");
|
||||
}
|
||||
|
|
@ -89,7 +89,7 @@ public class MongoPropertiesTests {
|
|||
properties.setDatabase("foo");
|
||||
properties.setUsername("user");
|
||||
properties.setPassword("secret".toCharArray());
|
||||
MongoClient client = properties.createMongoClient(null);
|
||||
MongoClient client = properties.createMongoClient(null, null);
|
||||
assertMongoCredential(client.getCredentialsList().get(0), "user", "secret", "foo");
|
||||
}
|
||||
|
||||
|
|
@ -99,7 +99,7 @@ public class MongoPropertiesTests {
|
|||
properties.setAuthenticationDatabase("foo");
|
||||
properties.setUsername("user");
|
||||
properties.setPassword("secret".toCharArray());
|
||||
MongoClient client = properties.createMongoClient(null);
|
||||
MongoClient client = properties.createMongoClient(null, null);
|
||||
assertMongoCredential(client.getCredentialsList().get(0), "user", "secret", "foo");
|
||||
}
|
||||
|
||||
|
|
@ -108,7 +108,7 @@ public class MongoPropertiesTests {
|
|||
MongoProperties properties = new MongoProperties();
|
||||
properties.setUri("mongodb://user:secret@mongo1.example.com:12345,"
|
||||
+ "mongo2.example.com:23456/test");
|
||||
MongoClient client = properties.createMongoClient(null);
|
||||
MongoClient client = properties.createMongoClient(null, null);
|
||||
List<ServerAddress> allAddresses = client.getAllAddress();
|
||||
assertEquals(2, allAddresses.size());
|
||||
assertServerAddress(allAddresses.get(0), "mongo1.example.com", 12345);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* Copyright 2012-2015 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.embedded;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.mongo.MongoDataAutoConfiguration;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
|
||||
import com.mongodb.CommandResult;
|
||||
import com.mongodb.MongoClient;
|
||||
|
||||
import de.flapdoodle.embed.mongo.distribution.Feature;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.hasItems;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.springframework.boot.test.EnvironmentTestUtils.addEnvironment;
|
||||
import static org.springframework.util.SocketUtils.findAvailableTcpPort;
|
||||
|
||||
/**
|
||||
* Tests for {@link EmbeddedMongoAutoConfiguration}.
|
||||
*
|
||||
* @author Henryk Konsek
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public class EmbeddedMongoAutoConfigurationTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultVersion() {
|
||||
assertVersionConfiguration(null, "2.6.10");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customVersion() {
|
||||
assertVersionConfiguration("2.7.1", "2.7.1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customFeatures() {
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
int mongoPort = findAvailableTcpPort();
|
||||
addEnvironment(this.context, "spring.data.mongodb.port=" + mongoPort,
|
||||
"spring.embedded-mongodb.features=TEXT_SEARCH, SYNC_DELAY");
|
||||
this.context.register(EmbeddedMongoAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertThat(this.context.getBean(EmbeddedMongoProperties.class).getFeatures(),
|
||||
hasItems(Feature.TEXT_SEARCH, Feature.SYNC_DELAY));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void randomlyAllocatedPortIsAvailableWhenCreatingMongoClient() {
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
addEnvironment(this.context, "spring.data.mongodb.port=0");
|
||||
this.context.register(EmbeddedMongoAutoConfiguration.class,
|
||||
MongoClientConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertThat(
|
||||
this.context.getBean(MongoClient.class).getAddress().getPort(),
|
||||
is(equalTo(Integer.valueOf(this.context.getEnvironment().getProperty(
|
||||
"local.mongo.port")))));
|
||||
}
|
||||
|
||||
private void assertVersionConfiguration(String configuredVersion,
|
||||
String expectedVersion) {
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
int mongoPort = findAvailableTcpPort();
|
||||
addEnvironment(this.context, "spring.data.mongodb.port=" + mongoPort);
|
||||
if (configuredVersion != null) {
|
||||
addEnvironment(this.context, "spring.embedded-mongodb.version="
|
||||
+ configuredVersion);
|
||||
}
|
||||
this.context.register(MongoAutoConfiguration.class,
|
||||
MongoDataAutoConfiguration.class, EmbeddedMongoAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
MongoTemplate mongo = this.context.getBean(MongoTemplate.class);
|
||||
CommandResult buildInfo = mongo.executeCommand("{ buildInfo: 1 }");
|
||||
|
||||
assertThat(buildInfo.getString("version"), equalTo(expectedVersion));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class MongoClientConfiguration {
|
||||
|
||||
@Bean
|
||||
public MongoClient mongoClient(@Value("${local.mongo.port}") int port)
|
||||
throws UnknownHostException {
|
||||
return new MongoClient("localhost", port);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -63,7 +63,7 @@
|
|||
<derby.version>10.11.1.1</derby.version>
|
||||
<dropwizard-metrics.version>3.1.2</dropwizard-metrics.version>
|
||||
<ehcache.version>2.10.0</ehcache.version>
|
||||
<embedmongo.version>1.46.4</embedmongo.version>
|
||||
<embedded-mongo.version>1.48.0</embedded-mongo.version>
|
||||
<flyway.version>3.2.1</flyway.version>
|
||||
<freemarker.version>2.3.22</freemarker.version>
|
||||
<elasticsearch.version>1.5.2</elasticsearch.version>
|
||||
|
|
@ -474,11 +474,6 @@
|
|||
<artifactId>logback-classic</artifactId>
|
||||
<version>${logback.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.flapdoodle.embed</groupId>
|
||||
<artifactId>de.flapdoodle.embed.mongo</artifactId>
|
||||
<version>${embedmongo.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.atomikos</groupId>
|
||||
<artifactId>transactions-jdbc</artifactId>
|
||||
|
|
@ -664,6 +659,11 @@
|
|||
<artifactId>commons-pool</artifactId>
|
||||
<version>${commons-pool.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.flapdoodle.embed</groupId>
|
||||
<artifactId>de.flapdoodle.embed.mongo</artifactId>
|
||||
<version>${embedded-mongo.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.dropwizard.metrics</groupId>
|
||||
<artifactId>metrics-core</artifactId>
|
||||
|
|
|
|||
|
|
@ -334,6 +334,10 @@ content into your application; rather pick only the properties that you need.
|
|||
spring.data.mongodb.repositories.enabled=true # if spring data repository support is enabled
|
||||
spring.data.mongodb.field-naming-strategy= # fully qualified name of the FieldNamingStrategy to use
|
||||
|
||||
# EMBEDDED MONGODB ({sc-spring-boot-autoconfigure}/mongo/embedded/EmbeddedMongoProerties.{sc-ext}[EmbeddedMongoProperties])
|
||||
spring.embedded-mongodb.version=2.6.10 # version of Mongo to use
|
||||
spring.embedded-mongodb.features=SYNC_DELAY # comma-separated list of features to enable
|
||||
|
||||
# JPA ({sc-spring-boot-autoconfigure}/orm/jpa/JpaBaseConfiguration.{sc-ext}[JpaBaseConfiguration], {sc-spring-boot-autoconfigure}/orm/jpa/HibernateJpaAutoConfiguration.{sc-ext}[HibernateJpaAutoConfiguration])
|
||||
spring.jpa.properties.*= # properties to set on the JPA connection
|
||||
spring.jpa.open-in-view=true
|
||||
|
|
|
|||
|
|
@ -2478,6 +2478,26 @@ documentation].
|
|||
|
||||
|
||||
|
||||
[[boot-features-mongo-embedded]]
|
||||
==== Embedded Mongo
|
||||
Spring Boot offers auto-configuration for
|
||||
[https://github.com/flapdoodle-oss/de.flapdoodle.embed.mongo] Embedded Mongo. To use
|
||||
it in your Spring Boot application add a dependency on
|
||||
`de.flapdoodle.embed:de.flapdoodle.embed.mongo`.
|
||||
|
||||
The port that Mongo will listen on can be configured using the `spring.data.mongodb.port`
|
||||
property. To use a randomly allocated free port use a value of zero. The `MongoClient`
|
||||
created by `MongoAutoConfiguration` will be automatically configured to use the randomly
|
||||
allocated port.
|
||||
|
||||
If you have SLF4J on the classpath, output produced by Mongo will be automatically routed
|
||||
to a logger named `org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongo`.
|
||||
|
||||
You can declare your own `IMongodConfig` and `IRuntimeConfig` beans to take control of the
|
||||
Mongo instance's configuration and logging routing.
|
||||
|
||||
|
||||
|
||||
[[boot-features-gemfire]]
|
||||
=== Gemfire
|
||||
https://github.com/spring-projects/spring-data-gemfire[Spring Data Gemfire] provides
|
||||
|
|
|
|||
|
|
@ -32,6 +32,10 @@
|
|||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.flapdoodle.embed</groupId>
|
||||
<artifactId>de.flapdoodle.embed.mongo</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
spring.data.mongodb.port=0
|
||||
|
|
@ -16,14 +16,13 @@
|
|||
|
||||
package sample.data.mongo;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.IntegrationTest;
|
||||
import org.springframework.boot.test.OutputCapture;
|
||||
import org.springframework.core.NestedCheckedException;
|
||||
|
||||
import com.mongodb.MongoTimeoutException;
|
||||
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
|
|
@ -31,44 +30,21 @@ import static org.junit.Assert.assertTrue;
|
|||
* Tests for {@link SampleMongoApplication}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes = SampleMongoApplication.class)
|
||||
@IntegrationTest
|
||||
public class SampleMongoApplicationTests {
|
||||
|
||||
private static final Pattern TIMEOUT_MESSAGE_PATTERN = Pattern
|
||||
.compile("Timed out after [0-9]+ ms while waiting for a server.*");
|
||||
|
||||
@Rule
|
||||
public OutputCapture outputCapture = new OutputCapture();
|
||||
@ClassRule
|
||||
public static OutputCapture outputCapture = new OutputCapture();
|
||||
|
||||
@Test
|
||||
public void testDefaultSettings() throws Exception {
|
||||
try {
|
||||
SampleMongoApplication.main(new String[0]);
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
if (serverNotRunning(ex)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
String output = this.outputCapture.toString();
|
||||
String output = SampleMongoApplicationTests.outputCapture.toString();
|
||||
assertTrue("Wrong output: " + output,
|
||||
output.contains("firstName='Alice', lastName='Smith'"));
|
||||
}
|
||||
|
||||
private boolean serverNotRunning(IllegalStateException ex) {
|
||||
@SuppressWarnings("serial")
|
||||
NestedCheckedException nested = new NestedCheckedException("failed", ex) {
|
||||
};
|
||||
Throwable root = nested.getRootCause();
|
||||
if (root instanceof MongoTimeoutException) {
|
||||
if (root.getMessage().contains("Unable to connect to any server")) {
|
||||
return true;
|
||||
}
|
||||
if (TIMEOUT_MESSAGE_PATTERN.matcher(root.getMessage()).matches()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue