Over a million developers have joined DZone.

Our Own Multi-Model Database (Part 4)

DZone's Guide to

Our Own Multi-Model Database (Part 4)

As we continue to flesh out our multi-model database, let's finish setting up the HTTP server, then integrate CI, CD, and Test Coverage into the setup.

· Database Zone ·
Free Resource

Want to free your enterprise from the costs of provisioning servers? Learn about serverless architecture with Couchbase and cloud computing.


Please read parts 1, 2, and 3 before continuing or you’ll be lost.

We started adding an HTTP server to our database last time and created just a couple of endpoints. Today, we’ll finish out the rest of theend points. We’ll also be good open source developers by hooking in Continuous Integration, Test Coverage, and Continuous Deployment.

It became too complex to keep all the HTTP API routes in the Server class, but luckily, Jooby lets us break out functionality into multiple classes and include them like so:

        use(new Node());
        use(new NodeDegree());
        use(new NodeProperties());
        use(new Relationship());
        use(new RelationshipProperties());

We could have gone MVC style, but I decided to keep it simple. Here is what the “get node property” end point looks like:

                 * Get node property by key.
                 * @param id Node ID.
                 * @param key Node property
                 * @return Returns <code>200</code> with a single value or <code>404</code>
                .get("/node/:id/property/:key", req -> {
                    HashMap<String, Object> node = Server.db.getNode(req.param("id").value());
                    if (node == null) {
                        throw new Err(Status.NOT_FOUND);
                    } else {
                        if (node.containsKey(req.param("key").value())) {
                            return node.get(req.param("key").value());
                        throw new Err(Status.NOT_FOUND);

Those comments enable the Swagger integration to produce these beautiful docs:


Now to test this one endpoint, I have to create at least three tests. One for a node not being there, one for a node being there, but the property not being there, and once for actually getting a node’s property without problem. This type of scenario plays out again and again. One mistake I made early was that I was creating a new server for every test. I then realized I could make the tests faster by creating a single one per class and adding a clear method to our database so we could always start fresh. Now our tests begin with a “@ClassRule”:

    private GuancialeDB db;

    public static JoobyRule app = new JoobyRule(new Server());

And before each test, we clean up the database and add some data if we wish:

    public void setup() throws IOException {
        db = GuancialeDB.getInstance();

        HashMap<String, Object> properties = new HashMap<>();
        properties.put("name", "Max");
        properties.put("age", 37);

        db.addNode("node1", properties);

The GuancialeDB “clear” method just wipes the nodes and relationships maps, as well as sets related to a new HashMap like so:

    public void clear() {
        related = new HashMap<>();

This keeps the tests nice and speedy without too much fuss. Here are the three tests I talked about. First for the node not existing at all:

    public void integrationTestGetNodePropertyNotThere() {

Another for the node existing but the property missing:

    public void integrationTestGetNodePropertyNotThereInvalidProperty() {

Finally, one for actually getting a valid property from an existing node.

    public void integrationTestGetNodeProperty() {

There are a metric ton more of these tests in the source code and I don’t always remember to run them locally when committing, so we’re gonna hook our project up with Continuous Integration, Continuous Deployment, and Test Coverage. There are a few vendors in this space, but I am most familiar with Travis CI and Coveralls, so we’ll use those. After registering with our GitHub account and allowing them access to our GitHub repo, we just need to add a “.travis.yml” file that looks like this:

sudo: required
language: java
- oraclejdk8
- docker
- mvn test jacoco:report coveralls:report
- docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD"
- export REPO=maxdemarzi/guancialedb
- export TAG=`if [ "$TRAVIS_BRANCH" == "master" ]; then echo "latest"; else echo $TRAVIS_BRANCH
  ; fi`
- docker build -f Dockerfile -t $REPO:$COMMIT .
- docker tag $REPO:$COMMIT $REPO:$TAG
- docker push $REPO

We’ll also need to configure a couple of plugins in our pom.xml file to deal with test coverage.


I’m using JaCoCo here instead of Cobertura because Cobertura uses JavaNCSS and it won’t recognize lambda expressions from Java 8 just yet. I was getting all kinds of these weird errors, because it ran into a "->{".

[WARN] JavaNCSS got an error while parsing the java file /Users/maxdemarzi/Projects/GuancialeDB/src/main/java/com/maxdemarzi/server/RelationshipProperties.java
ParseException in STDIN
Last useful checkpoint: "com.maxdemarzi.server.RelationshipProperties"
Encountered " ">" "> "" at line 29, column 74.

I’ll also need a Dockerfile:

FROM azul/zulu-openjdk:latest
MAINTAINER Max De Marzi<maxdemarzi@gmail.com>
COPY $ROOT/conf/application.conf /conf/application.conf
COPY $ROOT/target/GuancialeDB-1.0-SNAPSHOT.jar GuancialeDB-1.0-SNAPSHOT.jar
CMD ["java", "-jar", "GuancialeDB-1.0-SNAPSHOT.jar"]

I am using zulu-openjdk because there is no issue with licensing and they do a great job of certifying their builds.

Now when we push to GitHub.com, our tests will be run on Travis CI:

Our test coverage will be reported to Coveralls:


Our docker image will be pushed to Docker Hub:


After a bit of somewhat tedious work our REST API currently looks like this:


But you don’t have to take my word for it. Grab the docker image and run it yourself right now. We’ll save metrics and the shell for another post since this one is already running long in the tooth. As always, the source code is on GitHub.

Learn how the world’s first Engagement Database can lower your costs and simplify deployments with Couchbase in the cloud.

database ,multi-model databases ,tutorial ,continuous deployment ,continuous integration

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}