Introduction

The MongoDB component makes it easy to use MongoDB from OSGi. The component is a Managed Service Factory that enables you to configure MongoDB using Configuration Admin. This is a very light weight component and does not add APIs. The MongoDB Java Driver is already an OSGi bundle. You will use this API like normal.

How to use

Configuring a database

The PID of the Managed Service Factory to configure is org.amdatu.mongo. Because this is a Managed Service Factory you MUST provide configuration for an MongoDbService to become available.

Property

Type

Required

Description

Default value

dbName

String

no

Database to connect to

test

host

String

no

Host to connect to

localhost

port

Integer

no

Port to connect to

27017

username

String

no

Username used for connection

-

password

String

no

Password used for connection

-

mongoURI

String

no

Alternative way to provide connection info

-

autoConnectRetry

Boolean

no

See Mongo docs

false

connectionsPerHost

Integer

no

See Mongo docs

100

connectTimeout

Integer

no

See Mongo docs

10000

cursorFinalizerEnabled

Boolean

no

See Mongo docs

true

description

String

no

See Mongo docs

-

maxAutoConnectRetryTime

Integer

no

See Mongo docs

0

maxWaitTime

Integer

no

See Mongo docs

120000

socketKeepAlive

Boolean

no

See Mongo docs

false

socketTimeout

Integer

no

See Mongo docs

0

threadsAllowedToBlockForConnectionMultiplier

Integer

no

See Mongo docs

5

readPreference

String

no

See Mongo docs

primary

writeConcern

String

no

See Mongo docs

ACKNOWLEDGED

Using Object Mapping

The Mongo Java API is very low level. It works with untyped properties instead of objects. This unleashes all the advanced features of MongoDB, but is a painful when simply storing and retrieving Java objects. In these cases you can use an Object Mapping framework. There are several described on the MongoDB website.

Two popular choices for object mapping with Amdatu Mongo are Mongojack and Jongo. Both frameworks are available as OSGi bundles and can be used with Amdatu Mongo directly. Both project map objects to BSON using the Jackson JSON serialization framework. If you are also using RESTful web services you can re-use the same mappings in your RESTful web services and Mongo code.

An example with MongoJack.

import java.util.ArrayList;
import java.util.List;
import org.amdatu.mongo.MongoDBService;
import org.apache.felix.dm.annotation.api.Component;
import org.apache.felix.dm.annotation.api.ServiceDependency;
import org.apache.felix.dm.annotation.api.Start;
import org.mongojack.JacksonDBCollection;
import com.mongodb.DBCollection;

@Component
public class MongoJackExample implements CarService{

  @ServiceDependency
  private volatile MongoDBService m_mongoDbService;
  private volatile JacksonDBCollection<Car, String> m_cars;

  @Start
  public void start() {
    DBCollection collection = m_mongoDbService.getDB().getCollection("cars");
    m_cars = JacksonDBCollection.wrap(collection, Car.class, String.class);
  }

  @Override
  public List<Car> listCars(String brand) {
    List<Car> result = new ArrayList<>();

    m_cars.find().is("brand", brand).forEach(result::add);

    return result;
  }

  @Override
  public void saveCar(Car car) {
    m_cars.save(car);
  }

}

An example with Jongo

import java.util.ArrayList;
import java.util.List;
import org.amdatu.mongo.MongoDBService;
import org.apache.felix.dm.annotation.api.Component;
import org.apache.felix.dm.annotation.api.ServiceDependency;
import org.apache.felix.dm.annotation.api.Start;
import org.jongo.Jongo;
import org.jongo.MongoCollection;
import example.mongojack.Car;
import example.mongojack.CarService;

@Component
public class JongoCarService implements CarService{

  @ServiceDependency
  private volatile MongoDBService m_mongoDbService;
  private volatile MongoCollection m_cars;

  @Start
  public void start() {
    m_cars = new Jongo(m_mongoDbService.getDB()).getCollection("cars");
  }

  @Override
  public List<Car> listCars(String brand) {
    List<Car> result = new ArrayList<>();

    m_cars.find("{brand: #}", brand).as(Car.class).forEach(result::add);

    return result;
  }

  @Override
  public void saveCar(Car car) {
    m_cars.save(car);
  }
}

Using MongoDB with Amdatu Testing

When writing tests for services which need to access a MongoDBService, it is required to provide a minimal configuration specifying the database name to use. Amdatu MongoDB provides an extension for Amdatu Testing that can do this automatically for you, setting up the MongoDBService to use a temporary database, and performing automatic cleanup.

By default the database name is generated as follows:

  dbName = "test-" + System.currentTimeMillis() + "-" + testCase.getClass().getSimpleName();

The following example shows a simple test that performs this configuration and injects the MongoDBService itself:

MyTestClass.java
import org.amdatu.mongo.MongoDBService;
import org.amdatu.mongo.testing.OSGiMongoTestConfigurator;
import org.amdatu.testing.configurator.TestConfigurator;

public class MyTestClass {
    private volatile MongoDBService m_mongoDBService;

    @Before
    public void setUp() throws Exception {
        TestConfigurator.configure(this)
            .add(OSGiMongoTestConfigurator.configureMongoDb()) // configure a MongoDBService
            .add(TestConfigurator.createServiceDependency(MongoDBService.class)) // inject the mongoDBService
            .apply();

        // m_mongoDBService is now available to use within tests
    }

    @After
    public void tearDown() throws Exception {
        cleanUp(this);
    }
}

Components

Amdatu MongoDB provides the following components:

Bundle

Required

Description

org.amdatu.mongo

yes

Managed Service Factory to make a MongoDbService available that wraps a configured Mongo Driver

org.amdatu.mongo.testing

no

Amdatu Testing extension for testing serices that use MongoDB

Dependencies

The following tables provide an overview of the required and optional dependencies for Amdatu MongoDB using the various supported drivers:

Dependencies for all drivers

Bundle

Required

Description

org.apache.felix.dependencymanager

yes

Apache Felix Dependency Manager is used internally by all Amdatu components

Implementation of Config Admin (e.g. org.apache.felix.configadmin)

yes

Used to configure data sources

Dependencies for MongoJack

Bundle

Required

Description

org.mongojack

yes

The MongoJack library

com.fasterxml.jackson.core.jackson-core

yes

Used by MongoJack for serialization

com.fasterxml.jackson.core.jackson-databind

yes

Used by MongoJack for serialization

com.fasterxml.jackson.core.jackson-annotations

yes

Used by MongoJack for serialization

de.undercouch.bson4jackson

yes

Used by MongoJack for serialization

javax.persistence

yes

Used by MongoJack for serialization

Dependencies for Jongo

Bundle

Required

Description

org.jongo

yes

The Jongo library

com.fasterxml.jackson.core.jackson-core

yes

Used by Jongo for serialization

com.fasterxml.jackson.core.jackson-databind

yes

Used by Jongo for serialization

com.fasterxml.jackson.core.jackson-annotations

yes

Used by Jongo for serialization

de.undercouch.bson4jackson

yes

Used by Jongo for serialization

javax.persistence

yes

Used by Jongo for serialization

Resources