From dc8685a9279406545b1f23ea8a7716555aa70741 Mon Sep 17 00:00:00 2001 From: Yogesh Lonkar Date: Wed, 6 Apr 2016 15:29:04 +0530 Subject: [PATCH 1/2] Allow embedded Mongo's storage to be configured via the environment Closes gh-5617 --- .../EmbeddedMongoAutoConfiguration.java | 4 ++ .../embedded/EmbeddedMongoProperties.java | 42 +++++++++++++++++++ .../EmbeddedMongoAutoConfigurationTests.java | 25 +++++++++++ 3 files changed, 71 insertions(+) diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoAutoConfiguration.java index cd9257f664..7ec07fe06e 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoAutoConfiguration.java @@ -125,6 +125,9 @@ public class EmbeddedMongoAutoConfiguration { this.embeddedProperties.getFeatures()); MongodConfigBuilder builder = new MongodConfigBuilder() .version(featureAwareVersion); + if (this.embeddedProperties.getStorage() != null) { + builder.replication(this.embeddedProperties.getStorage()); + } if (getPort() > 0) { builder.net(new Net(getHost().getHostAddress(), getPort(), Network.localhostIsIPv6())); @@ -136,6 +139,7 @@ public class EmbeddedMongoAutoConfiguration { return builder.build(); } + private int getPort() { if (this.properties.getPort() == null) { return MongoProperties.DEFAULT_PORT; diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoProperties.java index a006a4016f..d0f837f091 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoProperties.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoProperties.java @@ -38,6 +38,8 @@ public class EmbeddedMongoProperties { */ private String version = "2.6.10"; + private Storage storage; + /** * Comma-separated list of features to enable. */ @@ -60,4 +62,44 @@ public class EmbeddedMongoProperties { this.features = features; } + public Storage getStorage() { + return storage; + } + + public void setStorage(Storage storage) { + this.storage = storage; + } + + public static class Storage extends de.flapdoodle.embed.mongo.config.Storage { + + private int oplogSize; + private String replSetName; + private String databaseDir; + + public int getOplogSize() { + return oplogSize; + } + + public void setOplogSize(int oplogSize) { + this.oplogSize = oplogSize; + } + + public String getReplSetName() { + return replSetName; + } + + public void setReplSetName(String replSetName) { + this.replSetName = replSetName; + } + + public String getDatabaseDir() { + return databaseDir; + } + + public void setDatabaseDir(String databaseDir) { + this.databaseDir = databaseDir; + } + + } + } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoAutoConfigurationTests.java index 5adbe497cd..e659faa7dc 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoAutoConfigurationTests.java @@ -20,6 +20,7 @@ import java.net.UnknownHostException; import com.mongodb.CommandResult; import com.mongodb.MongoClient; +import de.flapdoodle.embed.mongo.config.IMongodConfig; import de.flapdoodle.embed.mongo.distribution.Feature; import org.junit.After; import org.junit.Test; @@ -112,6 +113,30 @@ public class EmbeddedMongoAutoConfigurationTests { } } + /** + * test dbpath configuration is loaded for mongodb process. + */ + @Test + public void dbPathIsAvailableInMongoConfiguration() { + ConfigurableApplicationContext parent = new AnnotationConfigApplicationContext(); + parent.refresh(); + try { + this.context = new AnnotationConfigApplicationContext(); + this.context.setParent(parent); + EnvironmentTestUtils.addEnvironment(this.context, "spring.data.mongodb.port=0", + "spring.mongodb.embedded.storage.databaseDir=/Users/yogeshlo/db", + "spring.mongodb.embedded.storage.oplogSize=0"); + this.context.register(EmbeddedMongoAutoConfiguration.class, MongoClientConfiguration.class, + PropertyPlaceholderAutoConfiguration.class); + this.context.refresh(); + IMongodConfig mongoConfig = this.context.getBean(IMongodConfig.class); + assertThat(mongoConfig.replication().getDatabaseDir()).isEqualTo("/Users/yogeshlo/db"); + } + finally { + parent.close(); + } + } + private void assertVersionConfiguration(String configuredVersion, String expectedVersion) { this.context = new AnnotationConfigApplicationContext(); From 436da1d5fd07431257a87aad225481efb11d4216 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 7 Apr 2016 15:15:31 +0100 Subject: [PATCH 2/2] Polish contribution --- .../EmbeddedMongoAutoConfiguration.java | 10 ++- .../embedded/EmbeddedMongoProperties.java | 30 ++++--- .../EmbeddedMongoAutoConfigurationTests.java | 78 ++++++++++++++----- .../appendix-application-properties.adoc | 3 + 4 files changed, 89 insertions(+), 32 deletions(-) diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoAutoConfiguration.java index 7ec07fe06e..fbbce32bc0 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoAutoConfiguration.java @@ -35,6 +35,7 @@ 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.config.Storage; import de.flapdoodle.embed.mongo.distribution.Feature; import de.flapdoodle.embed.mongo.distribution.IFeatureAwareVersion; import de.flapdoodle.embed.process.config.IRuntimeConfig; @@ -69,6 +70,7 @@ import org.springframework.util.Assert; * * @author Henryk Konsek * @author Andy Wilkinson + * @author Yogesh Lonkar * @since 1.3.0 */ @Configuration @@ -126,7 +128,12 @@ public class EmbeddedMongoAutoConfiguration { MongodConfigBuilder builder = new MongodConfigBuilder() .version(featureAwareVersion); if (this.embeddedProperties.getStorage() != null) { - builder.replication(this.embeddedProperties.getStorage()); + builder.replication( + new Storage(this.embeddedProperties.getStorage().getDatabaseDir(), + this.embeddedProperties.getStorage().getReplSetName(), + this.embeddedProperties.getStorage().getOplogSize() != null + ? this.embeddedProperties.getStorage().getOplogSize() + : 0)); } if (getPort() > 0) { builder.net(new Net(getHost().getHostAddress(), getPort(), @@ -139,7 +146,6 @@ public class EmbeddedMongoAutoConfiguration { return builder.build(); } - private int getPort() { if (this.properties.getPort() == null) { return MongoProperties.DEFAULT_PORT; diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoProperties.java index d0f837f091..1e9d6f3de0 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoProperties.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * Copyright 2012-2016 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. @@ -28,6 +28,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties; * Configuration properties for Embedded Mongo. * * @author Andy Wilkinson + * @author Yogesh Lonkar * @since 1.3.0 */ @ConfigurationProperties(prefix = "spring.mongodb.embedded") @@ -63,29 +64,40 @@ public class EmbeddedMongoProperties { } public Storage getStorage() { - return storage; + return this.storage; } public void setStorage(Storage storage) { this.storage = storage; } - public static class Storage extends de.flapdoodle.embed.mongo.config.Storage { + public static class Storage { - private int oplogSize; + /** + * Maximum size of the oplog in megabytes. + */ + private Integer oplogSize; + + /** + * Name of the replica set. + */ private String replSetName; + + /** + * Directory used for data storage. + */ private String databaseDir; - public int getOplogSize() { - return oplogSize; + public Integer getOplogSize() { + return this.oplogSize; } - public void setOplogSize(int oplogSize) { + public void setOplogSize(Integer oplogSize) { this.oplogSize = oplogSize; } public String getReplSetName() { - return replSetName; + return this.replSetName; } public void setReplSetName(String replSetName) { @@ -93,7 +105,7 @@ public class EmbeddedMongoProperties { } public String getDatabaseDir() { - return databaseDir; + return this.databaseDir; } public void setDatabaseDir(String databaseDir) { diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoAutoConfigurationTests.java index e659faa7dc..1b705158d2 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mongo/embedded/EmbeddedMongoAutoConfigurationTests.java @@ -16,11 +16,13 @@ package org.springframework.boot.autoconfigure.mongo.embedded; +import java.io.File; import java.net.UnknownHostException; import com.mongodb.CommandResult; import com.mongodb.MongoClient; import de.flapdoodle.embed.mongo.config.IMongodConfig; +import de.flapdoodle.embed.mongo.config.Storage; import de.flapdoodle.embed.mongo.distribution.Feature; import org.junit.After; import org.junit.Test; @@ -35,6 +37,7 @@ 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 org.springframework.util.FileSystemUtils; import org.springframework.util.SocketUtils; import static org.assertj.core.api.Assertions.assertThat; @@ -113,28 +116,61 @@ public class EmbeddedMongoAutoConfigurationTests { } } - /** - * test dbpath configuration is loaded for mongodb process. - */ @Test - public void dbPathIsAvailableInMongoConfiguration() { - ConfigurableApplicationContext parent = new AnnotationConfigApplicationContext(); - parent.refresh(); - try { - this.context = new AnnotationConfigApplicationContext(); - this.context.setParent(parent); - EnvironmentTestUtils.addEnvironment(this.context, "spring.data.mongodb.port=0", - "spring.mongodb.embedded.storage.databaseDir=/Users/yogeshlo/db", - "spring.mongodb.embedded.storage.oplogSize=0"); - this.context.register(EmbeddedMongoAutoConfiguration.class, MongoClientConfiguration.class, - PropertyPlaceholderAutoConfiguration.class); - this.context.refresh(); - IMongodConfig mongoConfig = this.context.getBean(IMongodConfig.class); - assertThat(mongoConfig.replication().getDatabaseDir()).isEqualTo("/Users/yogeshlo/db"); - } - finally { - parent.close(); - } + public void defaultStorageConfiguration() { + this.context = new AnnotationConfigApplicationContext(); + EnvironmentTestUtils.addEnvironment(this.context, "spring.data.mongodb.port=0"); + this.context.register(EmbeddedMongoAutoConfiguration.class, + MongoClientConfiguration.class, + PropertyPlaceholderAutoConfiguration.class); + this.context.refresh(); + Storage replication = this.context.getBean(IMongodConfig.class).replication(); + assertThat(replication.getOplogSize()).isEqualTo(0); + assertThat(replication.getDatabaseDir()).isNull(); + assertThat(replication.getReplSetName()).isNull(); + } + + @Test + public void mongoWritesToCustomDatabaseDir() { + File customDatabaseDir = new File("target/custom-database-dir"); + FileSystemUtils.deleteRecursively(customDatabaseDir); + this.context = new AnnotationConfigApplicationContext(); + EnvironmentTestUtils.addEnvironment(this.context, "spring.data.mongodb.port=0", + "spring.mongodb.embedded.storage.databaseDir=" + + customDatabaseDir.getPath()); + this.context.register(EmbeddedMongoAutoConfiguration.class, + MongoClientConfiguration.class, + PropertyPlaceholderAutoConfiguration.class); + this.context.refresh(); + assertThat(customDatabaseDir).isDirectory(); + assertThat(customDatabaseDir.listFiles()).isNotEmpty(); + } + + @Test + public void customOpLogSizeIsAppliedToConfiguration() { + this.context = new AnnotationConfigApplicationContext(); + EnvironmentTestUtils.addEnvironment(this.context, "spring.data.mongodb.port=0", + "spring.mongodb.embedded.storage.oplogSize=10"); + this.context.register(EmbeddedMongoAutoConfiguration.class, + MongoClientConfiguration.class, + PropertyPlaceholderAutoConfiguration.class); + this.context.refresh(); + assertThat(this.context.getBean(IMongodConfig.class).replication().getOplogSize()) + .isEqualTo(10); + } + + @Test + public void customReplicaSetNameIsAppliedToConfiguration() { + this.context = new AnnotationConfigApplicationContext(); + EnvironmentTestUtils.addEnvironment(this.context, "spring.data.mongodb.port=0", + "spring.mongodb.embedded.storage.replSetName=testing"); + this.context.register(EmbeddedMongoAutoConfiguration.class, + MongoClientConfiguration.class, + PropertyPlaceholderAutoConfiguration.class); + this.context.refresh(); + assertThat( + this.context.getBean(IMongodConfig.class).replication().getReplSetName()) + .isEqualTo("testing"); } private void assertVersionConfiguration(String configuredVersion, diff --git a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc index 1c1cce0c3b..4b58d908b6 100644 --- a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc +++ b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc @@ -730,6 +730,9 @@ content into your application; rather pick only the properties that you need. # EMBEDDED MONGODB ({sc-spring-boot-autoconfigure}/mongo/embedded/EmbeddedMongoProperties.{sc-ext}[EmbeddedMongoProperties]) spring.mongodb.embedded.features=SYNC_DELAY # Comma-separated list of features to enable. + spring.mongodb.embedded.storage.databaseDir= # Directory used for data storage. + spring.mongodb.embedded.storage.oplogSize= # Maximum size of the oplog in megabytes. + spring.mongodb.embedded.storage.replSetName= # Name of the replica set. spring.mongodb.embedded.version=2.6.10 # Version of Mongo to use. # REDIS ({sc-spring-boot-autoconfigure}/redis/RedisProperties.{sc-ext}[RedisProperties])