Giter Club home page Giter Club logo

de.flapdoodle.embed.mongo's Introduction

Organization Flapdoodle OSS

Build Status Maven Central

We are now a github organization. You are invited to participate. Starting with version 2 we are going to support only java 8 or higher. If you are looking for the older version you can find it in the 1.7 branch.

Embedded MongoDB

Embedded MongoDB will provide a platform neutral way for running mongodb in unittests.

Why?

  • dropping databases causing some pains (often you have to wait long time after each test)
  • its easy, much easier as installing right version by hand
  • you can change version per test

License

We use http://www.apache.org/licenses/LICENSE-2.0

We need your help?

Poll: Which MongoDB version should stay supported?

Dependencies

Build on top of

Other ways to use Embedded MongoDB

Comments about Embedded MongoDB in the Wild

Other MongoDB Stuff

Howto

Maven

Snapshots (Repository http://oss.sonatype.org/content/repositories/snapshots)

<dependency>
	<groupId>de.flapdoodle.embed</groupId>
	<artifactId>de.flapdoodle.embed.mongo</artifactId>
	<version>2.0.4-SNAPSHOT</version>
</dependency>

Gradle

Make sure you have mavenCentral() in your repositories or that your enterprise/local server proxies the maven central repository.

dependencies {
	testCompile group: "de.flapdoodle.embed", name: "de.flapdoodle.embed.mongo", version: "2.0.1"
}

Build from source

When you fork or clone our branch you should always be able to build the library by running

mvn package

Changelog

Changelog

Supported Versions

Versions: some older, a stable and a development version Support for Linux, Windows and MacOSX.

Usage

	import de.flapdoodle.embed.mongo.config.ArtifactStoreBuilder;

	...
	MongodStarter starter = MongodStarter.getDefaultInstance();

	String bindIp = "localhost";
	int port = 12345;
	IMongodConfig mongodConfig = new MongodConfigBuilder()
		.version(Version.Main.PRODUCTION)
		.net(new Net(bindIp, port, Network.localhostIsIPv6()))
		.build();

	MongodExecutable mongodExecutable = null;
	try {
		mongodExecutable = starter.prepare(mongodConfig);
		MongodProcess mongod = mongodExecutable.start();

		MongoClient mongo = new MongoClient(bindIp, port);
		DB db = mongo.getDB("test");
		DBCollection col = db.createCollection("testCol", new BasicDBObject());
		col.save(new BasicDBObject("testDoc", new Date()));

	} finally {
		if (mongodExecutable != null)
			mongodExecutable.stop();
	}

Usage - Optimization

You should make the MongodStarter instance or the RuntimeConfig instance static (per Class or per JVM). The main purpose of that is the caching of extracted executables and library files. This is done by the ArtifactStore instance configured with the RuntimeConfig instance. Each instance uses its own cache so multiple RuntimeConfig instances will use multiple ArtifactStores an multiple caches with much less cache hits:)

Usage - custom mongod filename

If you do not restrict bindId to localhost you get windows firewall dialog popups. To avoid them you can choose a stable executable name with UserTempNaming. This way the firewall dialog only popups once. See Executable Collision

	import de.flapdoodle.embed.mongo.config.ExtractedArtifactStoreBuilder;

	...

	int port = 12345;

	Command command = Command.MongoD;

	IRuntimeConfig runtimeConfig = new RuntimeConfigBuilder()
		.defaults(command)
		.artifactStore(new ExtractedArtifactStoreBuilder()
			.defaults(command)
			.download(new DownloadConfigBuilder()
					.defaultsForCommand(command).build())
			.executableNaming(new UserTempNaming()))
		.build();

	IMongodConfig mongodConfig = new MongodConfigBuilder()
		.version(Version.Main.PRODUCTION)
		.net(new Net(port, Network.localhostIsIPv6()))
		.build();

	MongodStarter runtime = MongodStarter.getInstance(runtimeConfig);

	MongodExecutable mongodExecutable = null;
	try {
		mongodExecutable = runtime.prepare(mongodConfig);
		MongodProcess mongod = mongodExecutable.start();

		MongoClient mongo = new MongoClient("localhost", port);
		DB db = mongo.getDB("test");
		DBCollection col = db.createCollection("testCol", new BasicDBObject());
		col.save(new BasicDBObject("testDoc", new Date()));

	} finally {
		if (mongodExecutable != null)
			mongodExecutable.stop();
	}

Unit Tests

	public abstract class AbstractMongoDBTest extends TestCase {

		/**
		 * please store Starter or RuntimeConfig in a static final field
		 * if you want to use artifact store caching (or else disable caching)
		 */
		private static final MongodStarter starter = MongodStarter.getDefaultInstance();

		private MongodExecutable _mongodExe;
		private MongodProcess _mongod;

		private MongoClient _mongo;
		@Override
		protected void setUp() throws Exception {

			_mongodExe = starter.prepare(new MongodConfigBuilder()
				.version(Version.Main.PRODUCTION)
				.net(new Net("localhost", 12345, Network.localhostIsIPv6()))
				.build());
			_mongod = _mongodExe.start();

			super.setUp();

			_mongo = new MongoClient("localhost", 12345);
		}

		@Override
		protected void tearDown() throws Exception {
			super.tearDown();

			_mongod.stop();
			_mongodExe.stop();
		}

		public Mongo getMongo() {
			return _mongo;
		}

	}

... with some more help

	...
	MongodForTestsFactory factory = null;
	try {
		factory = MongodForTestsFactory.with(Version.Main.PRODUCTION);

		MongoClient mongo = factory.newMongo();
		DB db = mongo.getDB("test-" + UUID.randomUUID());
		DBCollection col = db.createCollection("testCol", new BasicDBObject());
		col.save(new BasicDBObject("testDoc", new Date()));

	} finally {
		if (factory != null)
			factory.shutdown();
	}
	...

Customize Download URL

	...
	Command command = Command.MongoD;

	IRuntimeConfig runtimeConfig = new RuntimeConfigBuilder()
		.defaults(command)
		.artifactStore(new ExtractedArtifactStoreBuilder()
			.defaults(command)
			.download(new DownloadConfigBuilder()
				.defaultsForCommand(command)
				.downloadPath("http://my.custom.download.domain/")))
		.build();
	...

Customize Proxy for Download

	...
	Command command = Command.MongoD;

	IRuntimeConfig runtimeConfig = new RuntimeConfigBuilder()
		.defaults(command)
		.artifactStore(new ExtractedArtifactStoreBuilder()
			.defaults(command)
			.download(new DownloadConfigBuilder()
				.defaultsForCommand(command)
				.proxyFactory(new HttpProxyFactory("fooo", 1234))))
			.build();
	...

Customize Artifact Storage

	...
	IDirectory artifactStorePath = new FixedPath(System.getProperty("user.home") + "/.embeddedMongodbCustomPath");
	ITempNaming executableNaming = new UUIDTempNaming();

	Command command = Command.MongoD;

	IRuntimeConfig runtimeConfig = new RuntimeConfigBuilder()
		.defaults(command)
		.artifactStore(new ExtractedArtifactStoreBuilder()
			.defaults(command)
			.download(new DownloadConfigBuilder()
				.defaultsForCommand(command)
				.artifactStorePath(artifactStorePath))
			.executableNaming(executableNaming))
		.build();

	MongodStarter runtime = MongodStarter.getInstance(runtimeConfig);
	MongodExecutable mongodExe = runtime.prepare(mongodConfig);
	...

Usage - custom mongod process output

... to console with line prefix

	...
	ProcessOutput processOutput = new ProcessOutput(Processors.namedConsole("[mongod>]"),
			Processors.namedConsole("[MONGOD>]"), Processors.namedConsole("[console>]"));

	IRuntimeConfig runtimeConfig = new RuntimeConfigBuilder()
		.defaults(Command.MongoD)
		.processOutput(processOutput)
		.build();

	MongodStarter runtime = MongodStarter.getInstance(runtimeConfig);
	...

... to file

	...
	IStreamProcessor mongodOutput = Processors.named("[mongod>]",
			new FileStreamProcessor(File.createTempFile("mongod", "log")));
	IStreamProcessor mongodError = new FileStreamProcessor(File.createTempFile("mongod-error", "log"));
	IStreamProcessor commandsOutput = Processors.namedConsole("[console>]");

	IRuntimeConfig runtimeConfig = new RuntimeConfigBuilder()
		.defaults(Command.MongoD)
		.processOutput(new ProcessOutput(mongodOutput, mongodError, commandsOutput))
		.build();

	MongodStarter runtime = MongodStarter.getInstance(runtimeConfig);
	...

	...
	public class FileStreamProcessor implements IStreamProcessor {

		private FileOutputStream outputStream;

		public FileStreamProcessor(File file) throws FileNotFoundException {
			outputStream = new FileOutputStream(file);
		}

		@Override
		public void process(String block) {
			try {
				outputStream.write(block.getBytes());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		@Override
		public void onProcessed() {
			try {
				outputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	...

... to java logging

	...
	Logger logger = Logger.getLogger(getClass().getName());

	ProcessOutput processOutput = new ProcessOutput(Processors.logTo(logger, Level.INFO), Processors.logTo(logger,
			Level.SEVERE), Processors.named("[console>]", Processors.logTo(logger, Level.FINE)));

	IRuntimeConfig runtimeConfig = new RuntimeConfigBuilder()
		.defaultsWithLogger(Command.MongoD,logger)
		.processOutput(processOutput)
		.artifactStore(new ExtractedArtifactStoreBuilder()
			.defaults(Command.MongoD)
			.download(new DownloadConfigBuilder()
				.defaultsForCommand(Command.MongoD)
				.progressListener(new LoggingProgressListener(logger, Level.FINE))))
		.build();

	MongodStarter runtime = MongodStarter.getInstance(runtimeConfig);
	...

... to default java logging (the easy way)

	...
	Logger logger = Logger.getLogger(getClass().getName());

	IRuntimeConfig runtimeConfig = new RuntimeConfigBuilder()
		.defaultsWithLogger(Command.MongoD, logger)
		.build();

	MongodStarter runtime = MongodStarter.getInstance(runtimeConfig);
	...

... to null device

	...
	Logger logger = Logger.getLogger(getClass().getName());

	IRuntimeConfig runtimeConfig = new RuntimeConfigBuilder()
		.defaultsWithLogger(Command.MongoD, logger)
		.processOutput(ProcessOutput.getDefaultInstanceSilent())
		.build();

	MongodStarter runtime = MongodStarter.getInstance(runtimeConfig);
	...

Custom Version

	...
	int port = 12345;
	IMongodConfig mongodConfig = new MongodConfigBuilder()
		.version(Versions.withFeatures(new GenericVersion("2.0.7-rc1"),Feature.SYNC_DELAY))
		.net(new Net(port, Network.localhostIsIPv6()))
		.build();

	MongodStarter runtime = MongodStarter.getDefaultInstance();
	MongodProcess mongod = null;

	MongodExecutable mongodExecutable = null;
	try {
		mongodExecutable = runtime.prepare(mongodConfig);
		mongod = mongodExecutable.start();

		...

	} finally {
		if (mongod != null) {
			mongod.stop();
		}
		if (mongodExecutable != null)
			mongodExecutable.stop();
	}
	...

Main Versions

	IVersion version = Version.V2_2_5;
	// uses latest supported 2.2.x Version
	version = Version.Main.V2_2;
	// uses latest supported production version
	version = Version.Main.PRODUCTION;
	// uses latest supported development version
	version = Version.Main.DEVELOPMENT;

Use Free Server Port

Warning: maybe not as stable, as expected.

... by hand

	...
	int port = Network.getFreeServerPort();
	...

... automagic

	...
	IMongodConfig mongodConfig = new MongodConfigBuilder().version(Version.Main.PRODUCTION).build();

	MongodStarter runtime = MongodStarter.getDefaultInstance();

	MongodExecutable mongodExecutable = null;
	MongodProcess mongod = null;
	try {
		mongodExecutable = runtime.prepare(mongodConfig);
		mongod = mongodExecutable.start();

		MongoClient mongo = new MongoClient(new ServerAddress(mongodConfig.net().getServerAddress(), mongodConfig.net().getPort()));
		...

	} finally {
		if (mongod != null) {
			mongod.stop();
		}
		if (mongodExecutable != null)
			mongodExecutable.stop();
	}
	...

... custom timeouts

	...
	IMongodConfig mongodConfig = new MongodConfigBuilder()
		.version(Version.Main.PRODUCTION)
		.timeout(new Timeout(30000))
		.build();
	...

Command Line Post Processing

	...
	ICommandLinePostProcessor postProcessor= ...

	IRuntimeConfig runtimeConfig = new RuntimeConfigBuilder()
		.defaults(Command.MongoD)
		.commandLinePostProcessor(postProcessor)
		.build();
	...

Custom Command Line Options

We changed the syncDelay to 0 which turns off sync to disc. To turn on default value used defaultSyncDelay().

	IMongodConfig mongodConfig = new MongodConfigBuilder()
	.version(Version.Main.PRODUCTION)
	.cmdOptions(new MongoCmdOptionsBuilder()
		.syncDelay(10)
		.useNoPrealloc(false)
		.useSmallFiles(false)
		.useNoJournal(false)
		.enableTextSearch(true)
		.build())
	.build();
	...

Snapshot database files from temp dir

We changed the syncDelay to 0 which turns off sync to disc. To get the files to create an snapshot you must turn on default value (use defaultSyncDelay()).

	IMongodConfig mongodConfig = new MongodConfigBuilder()
	.version(Version.Main.PRODUCTION)
	.processListener(new ProcessListenerBuilder()
		.copyDbFilesBeforeStopInto(destination)
		.build())
	.cmdOptions(new MongoCmdOptionsBuilder()
		.defaultSyncDelay()
		.build())
	.build();
	...

Custom database directory

If you set a custom database directory, it will not be deleted after shutdown

	Storage replication = new Storage("/custom/databaseDir",null,0);

	IMongodConfig mongodConfig = new MongodConfigBuilder()
			.version(Version.Main.PRODUCTION)
			.replication(replication)
			.build();
	...

Start mongos with mongod instance

this is an very easy example to use mongos and mongod

	int port = 12121;
	int defaultConfigPort = 12345;
	String defaultHost = "localhost";

	MongodProcess mongod = startMongod(defaultConfigPort);

	try {
		MongosProcess mongos = startMongos(port, defaultConfigPort, defaultHost);
		try {
			MongoClient mongoClient = new MongoClient(defaultHost, defaultConfigPort);
			System.out.println("DB Names: " + mongoClient.getDatabaseNames());
		} finally {
			mongos.stop();
		}
	} finally {
		mongod.stop();
	}

	private MongosProcess startMongos(int port, int defaultConfigPort, String defaultHost) throws UnknownHostException,
			IOException {
		IMongosConfig mongosConfig = new MongosConfigBuilder()
			.version(Version.Main.PRODUCTION)
			.net(new Net(port, Network.localhostIsIPv6()))
			.configDB(defaultHost + ":" + defaultConfigPort)
			.build();

		MongosExecutable mongosExecutable = MongosStarter.getDefaultInstance().prepare(mongosConfig);
		MongosProcess mongos = mongosExecutable.start();
		return mongos;
	}

	private MongodProcess startMongod(int defaultConfigPort) throws UnknownHostException, IOException {
		IMongodConfig mongoConfigConfig = new MongodConfigBuilder()
			.version(Version.Main.PRODUCTION)
			.net(new Net(defaultConfigPort, Network.localhostIsIPv6()))
			.configServer(true)
			.build();

		MongodExecutable mongodExecutable = MongodStarter.getDefaultInstance().prepare(mongoConfigConfig);
		MongodProcess mongod = mongodExecutable.start();
		return mongod;
	}

Import JSON file with mongoimport command

    public void testStartAndStopMongoImportAndMongod() throws UnknownHostException, IOException {
        int defaultConfigPort = 12345;
        String defaultHost = "localhost";
        String database = "importTestDB";
        String collection = "importedCollection";
        String jsonFile=filePathAsString;
        MongodProcess mongod = startMongod(defaultConfigPort);

        try {
            MongoImportProcess mongoImport = startMongoImport(defaultHost, defaultConfigPort, database,collection,jsonFile,true,true,true);
            try {
                MongoClient mongoClient = new MongoClient(defaultHost, defaultConfigPort);
                System.out.println("DB Names: " + mongoClient.getDatabaseNames());
            } finally {
                mongoImport.stop();
            }
        } finally {
            mongod.stop();
        }
    }

    private MongoImportProcess startMongoImport(String bindIp, int port, String dbName, String collection, String jsonFile, Boolean jsonArray,Boolean upsert, Boolean drop)
            throws UnknownHostException, IOException {
        IMongoImportConfig mongoImportConfig = new MongoImportConfigBuilder()
                .version(Version.Main.PRODUCTION)
                .net(new Net(bindIp, port, Network.localhostIsIPv6()))
                .db(dbName)
                .collection(collection)
                .upsert(upsert)
                .dropCollection(drop)
                .jsonArray(jsonArray)
                .importFile(jsonFile)
                .build();

        MongoImportExecutable mongoImportExecutable = MongoImportStarter.getDefaultInstance().prepare(mongoImportConfig);
        MongoImportProcess mongoImport = mongoImportExecutable.start();
        return mongoImport;
    }

Executable Collision

There is a good chance of filename collisions if you use a custom naming schema for the executable (see Usage - custom mongod filename). If you got an exception, then you should make your RuntimeConfig or MongoStarter class or jvm static (static final in your test class or singleton class for all tests).


YourKit is kindly supporting open source projects with its full-featured Java Profiler. YourKit, LLC is the creator of innovative and intelligent tools for profiling Java and .NET applications. Take a look at YourKit's leading software products: YourKit Java Profiler and YourKit .NET Profiler.

de.flapdoodle.embed.mongo's People

Contributors

bertramn avatar callegustafsson avatar canyaman avatar chrbayer84 avatar faizan-talena avatar freemo avatar gitsnaf avatar harley84 avatar iabudiab avatar jirutka avatar jochenberger avatar joelittlejohn avatar julianladisch avatar loki-afro avatar matlockx avatar mclarkdev avatar michaelmosmann avatar mrmanc avatar rdpeake avatar richardwilly98 avatar roberttaylor426 avatar santeriv avatar scottbessler avatar smecsia avatar trajano avatar tw1nk avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.