Stub implementation of MongoDB in Java that speaks the wire protocol.
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
code-style
core
examples
gradle/wrapper
h2-backend
jstests
memory-backend
postgresql-backend
test-common
.gitignore
.travis.yml
LICENSE.txt
README.md
build.gradle
gradle.properties
gradlew
gradlew.bat
release.sh
run_jstests.sh
settings.gradle

README.md

Build Status Maven Central BSD 3-Clause License

MongoDB Java Server

Stub implementation of the core MongoDB server in Java. The MongoDB Wire Protocol is implemented with Netty. Different backends are possible and can be easily extended.

Usage

Add the following Maven dependency to your project:

<dependency>
    <groupId>de.bwaldvogel</groupId>
    <artifactId>mongo-java-server</artifactId>
    <version>1.8.0</version>
</dependency>

In-Memory backend

The in-memory backend is the default, such that mongo-java-server can be used as stub in unit tests. It supports the basic CRUD operations. However, not all features are implemented, such as full-text search or map/reduce.

Example

public class SimpleTest {

    private MongoCollection<Document> collection;
    private MongoClient client;
    private MongoServer server;

    @Before
    public void setUp() {
        server = new MongoServer(new MemoryBackend());

        // bind on a random local port
        InetSocketAddress serverAddress = server.bind();

        client = new MongoClient(new ServerAddress(serverAddress));
        collection = client.getDatabase("testdb").getCollection("testcollection");
    }

    @After
    public void tearDown() {
        client.close();
        server.shutdown();
    }

    @Test
    public void testSimpleInsertQuery() throws Exception {
        assertEquals(0, collection.count());

        // creates the database and collection in memory and insert the object
        Document obj = new Document("_id", 1).append("key", "value");
        collection.insertOne(obj);

        assertEquals(1, collection.count());
        assertEquals(obj, collection.find().first());
    }

}

H2 MVStore backend

The H2 MVStore backend connects the server to a MVStore that can either be in-memory or on-disk.

<dependency>
    <groupId>de.bwaldvogel</groupId>
    <artifactId>mongo-java-server-h2-backend</artifactId>
    <version>1.8.0</version>
</dependency>

Example

public class Application {

    public static void main(String[] args) throws Exception {
        MongoServer server = new MongoServer(new H2Backend("database.mv"));
        server.bind("localhost", 27017);
    }

}

PostgreSQL backend

The PostgreSQL backend connects the server to a database in a running PostgreSQL 9.5+ instance. Each MongoDB database is mapped to a schema in Postgres and each MongoDB collection is stored as a table.

<dependency>
    <groupId>de.bwaldvogel</groupId>
    <artifactId>mongo-java-server-postgresql-backend</artifactId>
    <version>1.8.0</version>
</dependency>

For integration tests, a PostgreSQL instance can be created in a docker container:

docker run --name postgres-mongo-java-server-test -p 5432:5432 -e POSTGRES_USER=mongo-java-server-test -e POSTGRES_PASSWORD=mongo-java-server-test -e POSTGRES_DB=mongo-java-server-test -d postgres:9.6-alpine

Example

public class Application {

    public static void main(String[] args) throws Exception {
        DataSource dataSource = new org.postgresql.jdbc3.Jdbc3PoolingDataSource();
        dataSource.setDatabaseName(…);
        dataSource.setUser(…);
        dataSource.setPassword(…);
        MongoServer server = new MongoServer(new PostgresqlBackend(dataSource));
        server.bind("localhost", 27017);
    }

}

Ideas for other backends

Faulty backend

A faulty backend could randomly fail queries or cause timeouts. This could be used to test the client for error resilience.

Fuzzy backend

Fuzzing the wire protocol could be used to check the robustness of client drivers.

Related Work

  • jmockmongo

    • shares the basic idea of implementing the wire protocol with Netty
    • focus on in-memory backend for unit testing
  • fongo

    • focus on unit testing
    • no wire protocol implementation
    • intercepts the java mongo driver
    • currently used in nosql-unit