Browse Source
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-2002pull/3494/merge
19 changed files with 710 additions and 200 deletions
@ -0,0 +1,99 @@
@@ -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; |
||||
} |
||||
} |
||||
} |
||||
@ -1,35 +0,0 @@
@@ -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); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,259 @@
@@ -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 @@
@@ -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 @@
@@ -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); |
||||
} |
||||
|
||||
} |
||||
@ -1,52 +0,0 @@
@@ -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")); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,124 @@
@@ -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); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1 @@
@@ -0,0 +1 @@
|
||||
spring.data.mongodb.port=0 |
||||
Loading…
Reference in new issue