nea / vertx-mod-cassandra-persistor

A Vert.x Module to query a Cassandra cluster
Apache License 2.0
9 stars 8 forks source link
cassandra cql java mod vertx

Vert.x Cassandra Persistor Build Status

This very simple Vert.x module allows to store and retrieve data from a Cassandra instance or cluster. It uses the DataStax Java Driver 2.1.6 (defaults and characteristics from the driver are implicitly used).

It is loosely based on the Vert.x MongoDB persistor and not optimized for highest performance but straight-forward integration with Cassandra.

Latest Versions

For a full version history go here.

Dependencies

This Persistor has only been developed and tested with Cassandra 2.x/CQL3. To use it you of course have to have a Cassandra instance running and accessible through the network, where this Module is running.

Repository

The module is available through the central Maven Repository

<dependency>
    <groupId>com.insanitydesign</groupId>
    <artifactId>vertx-mod-cassandra-persistor</artifactId>
    <version>0.5.0</version>
</dependency>

Configuration

The Vert.x Cassandra Persistor takes the following configuration

{
    "address": <string>,
    "hosts": [<string>],
    "port": <int>,
    "keyspace": <string>,
    "compression": "SNAPPY" | "LZ4",
    "retry": "fallthrough" | "downgrading",
    "reconnection": {
        "policy": "constant" | "exponential",
        "delay": <int>,
        "max": <int>
    },
    "credentials": {
        "username": <string>,
        "password: <string>
    },
    "ssl": <boolean>,
    "fetchSize": <int>,
    "dateFormat": <string>,
    "prepStmtCacheSize": <int>,
    "batchTimeout": <int>
}

An exemplary configuration could look like

{
    "address": "your.awesome.persistency",
    "hosts": ["192.168.172.33", "192.168.172.34"],
    "port": 9142,
    "keyspace": "yourkeyspace"
}

Fields

Operations

Raw

Please use with care!

{
    "action": "raw",
    "statement": <cql3Statement> | "statements": [<cql3BatchStatements>, ...]
}

An example could look like

{
    "action": "raw",
    "statement": "SELECT * FROM superkeyspace.tablewithinfos"
}

or

{
    "action": "raw",
    "statements": [
        "INSERT INTO superkeyspace.tablewithinfos (key, value) VALUES('Key 1', 'Value 1')",
        "INSERT INTO superkeyspace.tablewithinfos (key, value) VALUES('Key 2', 'Value 2')"
    ]
}

where statement is preferred over statements.

Fields

statement A Cassandra Query Language version 3 (CQL3) compliant query that is channeled through to the driver and Cassandra.
statements A JsonArray of Cassandra Query Language version 3 (CQL3) compliant queries that are channeled through to the driver and Cassandra. Only UPDATE, INSERT and DELETE are allowed.

Note: Do not forget the keyspace (e.g. FROM keyspace.table), even if configured, as the raw statements are not altered in any way! And use ' instead of " for strings.

Returns

The raw action returns a JsonArray of JsonObjects in the format columnName:columnValue (if any result is given). Note: Value types are not fully interpreted but generally covered as numbers, strings or collections. Complex Types are not handled at the moment!

Prepared

{
    "action": "prepared",
    "statement": <cql3Statement>,
    "values": [<valuesArray>]
}

An example could look like

{
    "action": "prepared",
    "statement": "INSERT INTO superkeyspace.tablewithinfos (id, key, value) VALUES(?, ? ,?)"
    "values": [
        ["3a708930-c005-11e3-8a33-0800200c9a66", "Key A", "Value A"],
        ["3a708931-c005-11e3-8a33-0800200c9a66", "Key B", "Value B"]
    ]
}

Fields

statement A Cassandra Query Language version 3 (CQL3) compliant prepared statement query that is channeled through to the driver and Cassandra. Only SELECT, UPDATE, INSERT and DELETE are allowed.
statements A JsonArray of Cassandra Query Language version 3 (CQL3) compliant prepared statement query that is channeled through to the driver and Cassandra. Only SELECT, UPDATE, INSERT and DELETE are allowed. values A JsonArray of JsonArrays with the values. Every value list will create its bindings and be executed in a batched statement (if not a SELECT query).

Returns

Note: Only for SELECT The prepared action returns a JsonArray of JsonObjects in the format columnName:columnValue (if any result is given) combining all results from all prepared invokes.

Prepare

{
    "action": "prepare",
    "statement": <cql3Statement> | "statements": [<cql3Statement>, ...]
}

An example could look like

{
    "action": "prepare",
    "statement": "INSERT INTO superkeyspace.tablewithinfos (id, value) VALUES(?, ?)"
}

or

{
    "action": "prepare",
    "statements": [
        "INSERT INTO superkeyspace.table (id, value) VALUES(?, ?)",
        "INSERT INTO superkeyspace.anothertable (id, value) VALUES(?, ?)"
    ]
}

where statement is preferred over statements.

Fields

statement A Cassandra Query Language version 3 (CQL3) compliant query that is added to the prepared statement cache for later use.
statements A JsonArray of Cassandra Query Language version 3 (CQL3) compliant queries, which are added to the prepared statement cache for later use.

Returns

Response as detailed in General Responses.

Batching Operations

To reduce the amount of calls from a client user, it is possible to batch multiple actions and receive all their results in one response. Batching operations results from adding all JsonObject operations into a single JsonArray and sending this to a slightly different address.

[
    {<OperationsJsonObject>}, ...
]

An example could look like

[
    {
        "action": "prepare",
        "statement": "INSERT INTO superkeyspace.tablewithinfos (id, value) VALUES(?, ?)"
    },
    {
        "action": "raw",
        "statement": "SELECT * FROM superkeyspace.tablewithinfos"
    }
]

Fields

address The address to send the batched operations to is the originally configured address plus .batch. Therefore, if the configuration is

{
    "address": "your.awesome.persistency",
    "hosts": ["192.168.172.33", "192.168.172.34"],
    "port": 9142,
    "keyspace": "yourkeyspace"
}

the address to send the JsonArray to would be your.awesome.persistency.batch. Note: If the original address ends on a ., the . won't be duplicated. If your address is just.testing. the resulting batch address would be just.testing.batch

Returns

The batched actions return their persistor operation corresponding result in one JsonArray. Note: Returned results are unordered

Note

The batched processing is another worker verticle invoked by the CassandraPersistor and splitting the input into its single actions, firing these agains the eventbus and cumulating the results for a single client response. Its calls are no direct invocation of the local CassandraPersistor verticle, but reuse the eventbus. Therefore, a batched call would also be balanced (if clustered).

General Responses

In case no resultset is given to return to the sender or in case of errors a general status in JSON will be returned. It looks like

{
    "status": "ok"
}

or in case of errors

{
    "status": "error",
    "message": <errorDescription>
}

Personal Note

I don't know if this is very useful or already developed and published by others but I used it in private to test some ideas around Vert.x and Cassandra. As I was not able to find something similar very quickly I created this project. I hope this can be useful to you... with all its Bugs and Issues ;) If you like it you can give me a shout at INsanityDesign.