Git Product home page Git Product logo

entity-persistence-service's Introduction

Introduction

Entity Persistence Service provides a NoSQL abstraction over RDBMS to store entities as schema-less bags of properties (e.g., JSON objects or Java Maps). Entities have a GUID and can have multiple versions. The rest of the entity is opaque as far as the datastore is concerned. From a service consumer's perspective, the "schema" of the datastore can be changed simply by storing new properties. In addition, Entity Persistence Service indexes entity properties by flattening them out and persisting them in a different datastore which enables primitive search capabilities.

See http://backchannel.org/blog/friendfeed-schemaless-mysql for technical inspiration.

Concept

The Entity Persistence Service consists of the following:

Entity Persistence Service Concept

Workspace

A Workspace object is the entry point to the API. A Workspace has a name which is used to provide namespace isolation. Furthermore, a Workspace provides Entity CRUD methods.

Restrictions:

  • name must be a valid moniker
  • name must be less than 256 characters

Collection

A Collection is a group of Entities. A Collection must have a unique name within a Workspace. Collections don't enforce a schema on Entities which means that Entities in the same Collection can contain a different set of properties.

Restrictions:

  • name must be a valid moniker
  • name must be less than 256 characters

Entity

The Entity interface encapsulates the actual data that gets persisted.

An Entity binds a globally unique identifier (guid) to a Map of properties. An Entity's guid can be used to perform quick lookups within the specified Collection. All Entities have a version (think of it as an etag) which is created whenever an Entity is created or updated. Finally, a combination of Workspace + Collection + guid can be used to uniquely identify an Entity globally.

Here is the relevant snippet from the Entity API:

public interface Entity {
    /**
     * Collection the {@link Entity} is part of. Must validate the following
     * regex: [a-zA-Z0-9-/]+
     *
     * @return
     */
    String getCollection();
    /**
     * GUID. Automatically generated by Java. Example:
     * 751f0ac8-c6fe-4adb-b75c-e211e4462b76
     *
     * @return
     */
    String getId();
    /**
     * Tracks the version of the {@link Entity}. This is automatically updated
     * whenever the {@link Entity} is created or updated.
     *
     * @return
     */
    Long getVersion();
    Map<String, String> getProperties();
    // ... other methods ...
}

API

The following APIs can be accessed via the Workspace Object.

CRUD API

/**
 * Create a new {@link Entity} in the specified collection with the
 * specified properties. By default, all properties in the <code>Map</code>
 * will be indexed.
 *
 * @param collection
 * @param properties
 * @return
 * @throws PersistenceServiceException
 * @throws EntityExistsException
 */
Entity create(String collection, Map<String, String> properties)
        throws PersistenceServiceException, EntityExistsException;
/**
 * Create a new {@link Entity} in the specified collection with the
 * specified properties. All properties in the {@link IndexConfiguration}
 * will be indexed.
 *
 * @param collection
 * @param properties
 * @param indexConfiguration
 * @return
 * @throws PersistenceServiceException
 * @throws EntityExistsException
 */
Entity create(String collection, Map<String, String> properties,
        IndexConfiguration indexConfiguration) throws PersistenceServiceException,
        EntityExistsException;
/**
 * Returns the latest version of an {@link Entity} that is part of the
 * specified collection and has the specified id. Returns null otherwise.
 *
 * @param collection
 * @param id
 * @return
 * @throws PersistenceServiceException
 */
Entity read(String collection, String id) throws PersistenceServiceException;
/**
 * Updates an existing {@link Entity} by creating and persisting a new
 * version of itself. All properties in the {@link IndexConfiguration} will
 * be indexed. Will throw {@link StaleEntityException} if the {@link Entity}
 * that's being updated is not the latest version.
 *
 * @param e
 * @return
 * @throws PersistenceServiceException
 * @throws EntityNotFoundException
 * @throws StaleEntityException
 */
Entity update(Entity e) throws PersistenceServiceException,
        EntityNotFoundException, StaleEntityException;
/**
 * Updates an existing {@link Entity} by creating and persisting a new
 * version of itself. By default, all properties in the <code>Map</code>
 * will be indexed. Will throw {@link StaleEntityException} if the
 * {@link Entity} that's being updated is not the latest version.
 *
 * @param e
 * @param indexConfiguration
 * @return
 * @throws PersistenceServiceException
 * @throws EntityNotFoundException
 * @throws StaleEntityException
 */
Entity update(Entity e, IndexConfiguration indexConfiguration)
        throws PersistenceServiceException, EntityNotFoundException, StaleEntityException;
/**
 * Deletes (logical delete) an {@link Entity}. Will throw
 * {@link StaleEntityException} if the {@link Entity} that's being deleted
 * is not the latest version.
 *
 * @param e
 * @throws PersistenceServiceException
 * @throws EntityNotFoundException
 * @throws StaleEntityException
 */
void delete(Entity e) throws PersistenceServiceException,
        EntityNotFoundException, StaleEntityException;

Index Configuration

IndexConfiguration lets you control the behavior of the List API. Only those properties specified in the index configuration will be indexed, and therefore, searchable. By default, all properties are indexed. You can specify the IndexConfiguration as part of the create() and update() method.

List API

/**
 * Returns a list of {@link Entity} in the specified collection
 *
 * @param collection
 * @return
 * @throws PersistenceServiceException
 */
List<Entity> list(final String collection) throws PersistenceServiceException;

Examples

Please refer to com.akamai.open.moonlighting.persistence.service.impl.dao.EntityDaoTest.java for the latest example.

Create an Entity

final Map<String, String> props = new HashMap<>();
props.put("hello", "world");
props.put("now", new Date().toString());
props.put("accessed", "1");
 
try {
    final Entity e = persistenceService.getDefaultWorkspace().create("example", props);
    // do something with entity
} catch (PersistenceServiceException | EntityExistsException ex) {
    // do something
}

Read, Update and Delete

final Workspace w = persistenceService.getDefaultWorkspace();
try {
    // list api
    List<Entity> entities = w.list(TYPE);
    for (Entity e : entities) {
        Map<String, String> props = e.getProperties();
        Integer accessed;
        try {
            accessed = Integer.valueOf(props.get("accessed"));
        } catch (NumberFormatException ex) {
            accessed = 0;
        }
        if (accessed >= 25) {
            // delete api
            w.delete(e);
        } else {
            props.put("accessed", (accessed + 1) + "");
            e.setProperties(props);
            // update api with indexConfiguration
            w.update(e, new IndexConfiguration("accessed"));
        }
    }
} catch (PersistenceServiceException | EntityNotFoundException | StaleEntityException ex) {
    // do something
}

Dependencies

This component has a dependency on com.akamai.open.moonlighting.rdbms-connection-service. You can remove this dependency and implement the following interface instead:

import java.sql.Connection;
import java.sql.SQLException;

public interface RdbmsConnectionService {
    Connection getConnection() throws SQLException;
}

It is up to your implementation to provide a reference to a valid java.sql.Connection.

entity-persistence-service's People

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.