Commit ef2bdc63 authored by Axel Auweter's avatar Axel Auweter
Browse files

Finalized the documentation effort of DCDBLib and updated the Makefile to do...

Finalized the documentation effort of DCDBLib and updated the Makefile to do dependency checking for the make docs target.
parent bd0c9cd7
......@@ -7,7 +7,7 @@ CXXFLAGS = -O0 -g -Wall -Werror -Wno-unused-local-typedefs -Wno-unknown-warning-
# List of object files to build and the derived list of corresponding source files
OBJS = src/sensordatastore.o \
src/cassandraBackend.o \
src/cassandraBackend.o \
cassandra/Cassandra.o \
cassandra/cassandra_constants.o \
cassandra/cassandra_types.o
......@@ -16,6 +16,9 @@ SRC = $(patsubst cassandra/%,,$(OBJS:.o=.cpp))
# List of public header files necessary to use this libray
PUBHEADERS = $(shell find include -type f -iname "*.h")
# List of non-public headers
PRIVHEADERS = $(shell find include_internal -type f -iname "*.h")
# External libraries to link against
LIBS = -L$(DCDBDEPLOYPATH)/lib -lthrift -lssl -lcrypto -lpthread -lboost_system -lboost_thread
......@@ -85,7 +88,7 @@ cassandra/Cassandra.h:
@rm cassandra/cassandra_constants.h_newline
# Build the documentation
docs:
docs: $(PUBHEADERS) $(PRIVHEADERS) $(SRC)
@echo "Creating documentation..."
doxygen
......
......@@ -37,17 +37,17 @@
* - knc_id
*/
typedef union {
uint64_t raw; /** The raw bit-field representing the DeviceLocation */
struct {
uint8_t knc_id;
uint8_t bnc_id;
uint8_t bic_id;
uint8_t chassis_id;
uint8_t rack_id_lsb;
uint8_t rack_id_msb;
uint8_t cluster_id;
uint8_t datacenter_id;
};
uint64_t raw; /**< The raw bit-field representing the DeviceLocation */
struct {
uint8_t knc_id;
uint8_t bnc_id;
uint8_t bic_id;
uint8_t chassis_id;
uint8_t rack_id_lsb;
uint8_t rack_id_msb;
uint8_t cluster_id;
uint8_t datacenter_id;
};
} DeviceLocation;
/**
......@@ -61,9 +61,9 @@ typedef union {
* approach is, for example, to use MAC addresses as the device_id.
*/
typedef struct {
uint64_t sensor_number : 16; /** The sensor_number of the sensor */
uint64_t rsvd : 16; /** Reserved */
uint64_t device_id : 32; /** The location-independent device_id */
uint64_t sensor_number : 16; /**< The sensor_number of the sensor */
uint64_t rsvd : 16; /**< Reserved */
uint64_t device_id : 32; /**< The location-independent device_id */
} DeviceSensorId;
/**
......@@ -78,11 +78,11 @@ typedef struct {
* DeviceSensorId.
*/
typedef union {
uint64_t raw[2];
struct {
DeviceLocation dl;
DeviceSensorId dsid;
};
uint64_t raw[2]; /**< The raw bit-field representation of a sensor */
struct {
DeviceLocation dl;
DeviceSensorId dsid;
};
} SensorId;
#pragma pack(pop)
......
......@@ -5,6 +5,13 @@
* Author: Axel Auweter
*/
/*
* @file
* @brief This file defines the CassandraBackend class and related
* things that provide a low-level abstraction to the
* Cassandra key-value store.
*/
#ifndef CASSANDRA_BACKEND_H
#define CASSANDRA_BACKEND_H
......@@ -30,36 +37,116 @@ using namespace apache::thrift::protocol;
using namespace org::apache::cassandra;
using namespace std;
/**
* @brief The CassandraBackend class provides low-level
* access to the Cassandra key-value store using
* the THRIFT API.
*/
class CassandraBackend
{
protected:
CassandraClient *myClient;
std::vector<KsDef> keySpaces;
string clusterName;
boost::shared_ptr<TSocket> sock;
boost::shared_ptr<TTransport> tr;
boost::shared_ptr<TProtocol> prot;
CassandraClient *myClient; /**< The main object provided by the Thrift API for us */
std::vector<KsDef> keySpaces; /**< A vector containing a local copy of the keyspace definitions */
string clusterName; /**< The name of the cluster that we're connecting to */
boost::shared_ptr<TSocket> sock; /**< A boost TSocket object for our connection */
boost::shared_ptr<TTransport> tr; /**< A boost TTransport object sitting on top of the TSocket sock */
boost::shared_ptr<TProtocol> prot; /**< A boost TProtocol object sitting on top of the TTransport tr */
/**
* @brief This function validates a name to ensure that
* it only consists of alphanumeric characters.
* @param name A string to check
* @return True if the name is alphanumeric, false otherwise
*/
bool validateName(string name);
/**
* @brief This function converts a uint64_t into a big-endian
* byte array represented as std::string.
* @param n The value to convert
* @return The string containing the big-endian byte array.
*/
string int64Convert(uint64_t n);
public:
/* FIXME - make currentKeySpace protected! */
KsDef currentKeySpace;
KsDef currentKeySpace; /**< The keyspace defniition of the currently selected keyspace */
/* Database meta operations */
/**
* @brief Starts a connection to a Cassandra front-end node.
* @param hostname The hostname to connect to.
* @param port The TCP port number on which Cassandra is listening for Thrift clients.
*/
void connect(string hostname, int port);
/**
* @brief Fetch the list of Key Spaces from the Cassandra server.
*/
void updateKeySpaces();
/**
* @brief Check if a keyspace with a given name exists.
* @param name The name of the keyspace to look for.
* @return True if the keyspace exists, false otherwise.
*/
bool existsKeyspace(string name);
/**
* @brief Create a new keyspace.
* @param name The name of the new keyspace
* @param replicationFactor The Cassandra replication factor
*/
void createKeyspace(string name, int replicationFactor);
/**
* @brief Specify a keyspace to use in this connection.
* @param name The name of the keyspace to select.
*/
void selectKeyspace(string name);
/**
* @brief Check if a column family with a given name
* exists in the currently selected keyspace.
* @param name The name of the column family to look for.
* @return True if the column family exists in the current keyspace, false otherwise.
*/
bool existsColumnFamily(string name);
/**
* @brief Create a new column family in the currently
* selected keyspace.
* @param name The name of the keyspace
* @param fields A comma separated list of field names and types
* @param primaryKey A primary key definition (one or more fields)
* @param options A Cassandra WITH statement for keyspace generation
*/
void createColumnFamily(string name, string fields, string primaryKey, string options);
/* Database data access operations */
/**
* @brief Insert a data into the database
* @param columnFamily The name of the column family
* @param key The name of the row key
* @param ts The data time stamp (used for column name and time information in Cassandra
* @param value The data itself
*/
void insert(string columnFamily, string key, uint64_t ts, uint64_t value);
/* Class constructor / desctructor */
/**
* @brief The standard constructor for CassandraBackend
*/
CassandraBackend();
/**
* @brief The standard desctructor for CassandraBackend
*/
virtual ~CassandraBackend();
};
......
......@@ -5,6 +5,13 @@
*
*/
/*
* @file
* @brief This file contains the internal functions of the
* Sensor Data Store which are provided by the
* SensorDataStoreImpl class.
*/
#ifndef DCDB_INTERNAL_H
#define DCDB_INTERNAL_H
......@@ -17,10 +24,16 @@
#define CF_SENSORDATA "sensordata"
#define CF_SETTINGS "settings"
/**
* @brief The SensorDataStoreImpl class contains all protected
* functions belonging to SensorDataStore which are
* hidden from the user of the DCDBLib library.
*/
class SensorDataStoreImpl
{
protected:
CassandraBackend* csBackend;
CassandraBackend* csBackend; /**< The CassandraBackend object that does the low-level stuff for us. */
/**
* @brief This function returns a "key" string which
* corresponds to the supplied SensorId object.
......
......@@ -7,6 +7,15 @@
#include "cassandraBackend.h"
/**
* @details
* This function connects to a Cassandra front end node
* using the Thrift API and Boost's TBinaryProtocol over
* TFramedTransport over TSocket.
*
* It also fetches some information about the database
* cluster.
*/
void CassandraBackend::connect(string hostname, int port)
{
sock = boost::shared_ptr<TSocket>(new TSocket(hostname, port));
......@@ -20,11 +29,23 @@ void CassandraBackend::connect(string hostname, int port)
cout << "Connected to cluster: " << clusterName << "\n";
}
/**
* @details
* This function updates the local copy of the list
* of available keyspaces. It will be called any time
* a existsKeyspace query is performed to take note
* of recently added keyspaces.
*/
void CassandraBackend::updateKeySpaces()
{
myClient->describe_keyspaces(keySpaces);
}
/**
* @details
* This function iterates all known keyspaces to check
* if a keyspace with a given name can be found.
*/
bool CassandraBackend::existsKeyspace(string name)
{
updateKeySpaces();
......@@ -35,8 +56,11 @@ bool CassandraBackend::existsKeyspace(string name)
return false;
}
/*
* Create the keyspace that contains all the sensor data.
/**
* @details
* This function creates a new keyspace with a given name and
* replication factor.
*
* We are using CQL3 to do this as its syntax is less likely
* to change in future versions than the native API.
*/
......@@ -52,6 +76,12 @@ void CassandraBackend::createKeyspace(string name, int replicationFactor)
}
}
/**
* @details
* This function sets the current keyspace by issuing a CQL USE
* statement and setting the currentKeySpace class member to point
* to the newly selected keyspace.
*/
void CassandraBackend::selectKeyspace(string name)
{
CqlResult res;
......@@ -69,6 +99,12 @@ void CassandraBackend::selectKeyspace(string name)
}
}
/**
* @details
* This function iterates over all column families in the key
* space that was selected by selectKeyspace to check if a
* column family with the given name exists.
*/
bool CassandraBackend::existsColumnFamily(string name)
{
for (std::vector<CfDef>::iterator it = currentKeySpace.cf_defs.begin(); it != currentKeySpace.cf_defs.end(); ++it) {
......@@ -78,6 +114,11 @@ bool CassandraBackend::existsColumnFamily(string name)
return false;
}
/**
* @details
* This functions assembles the parameters into a CQL CREATE
* TABLE query and submits the query to the server.
*/
void CassandraBackend::createColumnFamily(string name, string fields, string primaryKey, string options)
{
CqlResult res;
......@@ -91,6 +132,11 @@ void CassandraBackend::createColumnFamily(string name, string fields, string pri
myClient->execute_cql3_query(res, query.str(), Compression::NONE, ConsistencyLevel::ONE);
}
/**
* @details
* The validation for alphanumeric is implemented by using C++ STL's
* find_if function. Pretty nice piece of C++!
*/
bool CassandraBackend::validateName(string name)
{
/*
......@@ -109,12 +155,24 @@ bool CassandraBackend::validateName(string name)
return false;
}
/**
* @details
* The endianess conversion is implemented in the global
* dcdbendian.h header file. Conversion to std::string
* is straightforward.
*/
string CassandraBackend::int64Convert(uint64_t n)
{
n = Endian::hostToBE(n);
return string((char*)&n, 8);
}
/**
* @details
* Since Cassandra uses manly strings to communicate in Thrift,
* this function converts the ts and value parameters to big-endian
* byte arrays using the int64convert function.
*/
void CassandraBackend::insert(string columnFamily, string key, uint64_t ts, uint64_t value)
{
try {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment