Skip to content
Andrea Gazzarini edited this page Aug 28, 2014 · 6 revisions

Framework

This section describes the relevant parts of the jena-nosql framework module. If you are an end-user you can completely skip this section.

Abstract Factory

The overall design rounds around the Abstract Factory design pattern [1].
As you can see from the following diagram, the StorageLayerFactory class plays the role of the AbstractFactory and therefore defines the contract that each concrete implementor (i.e. family) must provide in order to create concrete products for a specific kind of storage.

Framework Abstract Factory

On top of that, each binding module defines the "concrete" layer that is in charge to provide

  • an implementation of the StorageLayerFactory (i.e. the Concrete Factory);
  • a concrete implementation of each (abstract) product defined in the diagram below (i.e. the Concrete Products)

Here you can see the same diagram as above but with the "Cassandra" family members (note that only 4 members are shown in order to simplify the diagram)

Framework Abstract Factory

Data Access Objects

Data Access Objects (DAOs) are first class members of a concrete storage layer. They encapsulate all the logic needed for interacting with a specific kind of storage and therefore abstract the complexity of that interaction by offering a simple and common interface.

A StorageLayerFactory implementation must define how to create two kinds of DAOs:

  • TripleIndexDAO: which contains the logic for interacting with triple indexes;
  • MapDAO: which provides the data access / interaction logic to a persistent dictionary (see the next section);

You can find two (concrete) examples here (respectively in SOLR and Cassandra binding modules)

Note that, following the same decoupling logic, the DAO interface doesn't raise any storage-specific exception; instead, a general-purpose StorageLayerException is used there. Within DAO code, the developer should catch and wrap any (checked?) exception with that.

Dictionaries

Integration tests

As the core itself is not associated with a specific storage, a set of integration tests that run towards a (mini)instance of the target storage is required in order to make sure about the functional correctness of each binding.

Within the project there's a (maven) module dedicated to integration tests: the jena-nosql-integration-tests module. It is configured with the maven failsafe plugin [2] to run tests, during the integration-test phase, against a running instance of the target storage.

Here comes the beauty because the target storage is not predefined, but instead depends on what is the runtime binding module. So basically the same set of integration tests could be run against Cassandra, HBase, Accumulo or another storage. How can we maintain the same set of tests and at the same time start a test instance of one storage or another? Maven profiles is the answer (at least for me): within the pom.xml of the jena-nosql-integration-tests I defined one profile for each storage (at the time of writing there's just one profile). So for example the cassandra-2x profile is defining the usage of the Cassandra Maven Plugin [3] that

  • starts an embedded instance of Cassandra before all integration tests
  • stops that instance after the last test

So, at the end, if you want to run the integration test suite against Cassandra, just cd to project directory (where the top level pom.xml is located) and run Maven as follows:

   > mvn clean install -P cassandra-2x 

Generally speaking, assuming $JENA_NOSQL_HOME as the directory of the jena-nosql top level project, you can run the integration test suite against a given storage in this way :

   > cd $JENA_NOSQL_HOME
   > mvn clean install -P <available storage profile code>

Where <available storage profile code> is one of the following:

Profile | Description ----|---|---- cassandra-2x | Apache Cassandra 2.0.4 solr-4x | Apache SOLR 4.8.0

Note that

  • there's no need to previously download those products...Maven will do that for you ;)
  • there's no need to set any permission because the embedded instance will "live" within the target build folder.

[1] https://en.wikipedia.org/wiki/Abstract_factory_pattern
[2] http://maven.apache.org/surefire/maven-failsafe-plugin
[3] http://mojo.codehaus.org/cassandra-maven-plugin