Commit 333452ee authored by Alessio Netti's avatar Alessio Netti
Browse files

Adding MetadataStore class

parent baa00cee
//================================================================================
// Name : metadatastore.h
// Author : Alessio Netti
// Contact : info@dcdb.it
// Copyright : Leibniz Supercomputing Centre
// Description : A meta-data store for sensors
//================================================================================
//================================================================================
// This file is part of DCDB (DataCenter DataBase)
// Copyright (C) 2011-2019 Leibniz Supercomputing Centre
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//================================================================================
#ifndef PROJECT_METADATASTORE_H
#define PROJECT_METADATASTORE_H
#include <vector>
#include <map>
#include <string>
#include <boost/property_tree/ptree.hpp>
#include <boost/foreach.hpp>
#include <boost/property_tree/info_parser.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/algorithm/string.hpp>
#include "globalconfiguration.h"
using namespace std;
class sensorMetadata_t {
public:
bool isVirtual = false;
bool integrable = false;
bool monotonic = false;
string publicName = "";
string unit = "";
uint64_t scale = 1;
uint64_t ttl = 0;
uint64_t interval = 1000000000;
vector<string> operations;
};
class MetadataStore {
public:
/**
* @brief Public class constructor.
*/
MetadataStore() {}
/**
* @brief Class destructor.
*/
~MetadataStore() {}
/**
* @brief Clears the internal metadata map.
*/
void clear() { _metadata.clear(); }
/**
* @brief Returns the internal metadata map.
*
* @return A string to Metadata_t map
*/
const map<string, sensorMetadata_t>& getMap() { return _metadata; }
/**
* @brief Stores a sensorMetadata_t object in the internal map.
*
* If the input key already exists in the map, the entry is overwritten.
*
* @param key Sensor key under which metadata must be stored
* @param s Object containing sensor metadata
* @return True if "key" is unique, False if there was a collision
*/
bool store(const string& key, const sensorMetadata_t& s);
/**
* @brief Stores a sensorMetadata_t object in the internal map, after parsing it from a JSON string.
*
* If the input key already exists in the map, the entry is overwritten. If parsing fails,
* a InvalidArgument exception is thrown.
*
* @param key Sensor key under which metadata must be stored
* @param payload JSON-encoded string containing metadata information
* @return True if "key" is unique, False if there was a collision
*/
bool storeFromJSON(const string& key, const string& payload);
/**
* @brief Stores a sensorMetadata_t object in the internal map, after parsing it from a INFO block.
*
* If the input key already exists in the map, the entry is overwritten. If parsing fails,
* a InvalidArgument exception is thrown.
*
* @param key Sensor key under which metadata must be stored
* @param config PTREE block containing metadata
* @return True if "key" is unique, False if there was a collision
*/
bool storeFromPTREE(const string& key, boost::property_tree::iptree& config);
/**
* @brief Returns a sensorMetadata_t object from the internal map.
*
* If the input key does not exist in the map, a InvalidArgument exception is thrown.
*
* @param key Sensor key to be queried
* @return A reference to a sensorMetadata_t object
*/
const sensorMetadata_t& get(const string& key);
/**
* @brief Returns a sensorMetadata_t object from the internal map, converted into JSON format.
*
* If the input key does not exist in the map, a InvalidArgument exception is thrown.
*
* @param key Sensor key to be queried
* @return String containing the JSON representation of the sensorMetadata_t object
*/
string getJSON(const string& key);
/**
* @brief Returns a sensorMetadata_t object from the internal map, converted into PTREE format.
*
* If the input key does not exist in the map, a InvalidArgument exception is thrown.
*
* @param key Sensor key to be queried
* @return A PTREE object representing the sensorMetadata_t object
*/
boost::property_tree::ptree getPTREE(const string& key);
protected:
map<string, sensorMetadata_t> _metadata;
// Parses the "config" iptree block and stores the result in "s"
void _parsePTREE(boost::property_tree::iptree& config, sensorMetadata_t& s);
// Dumps the contents of "s" in "config"
void _dumpPTREE(boost::property_tree::ptree& config, const sensorMetadata_t& s);
// Parses a string and splits it according to a separator
void _parseVector(const string& str, vector<string>& v, const char sep=',');
// Dumps the content of a vector into a string with an arbitrary separator
void _dumpVector(string& str, const vector<string>& v, const char sep=',');
};
#endif //PROJECT_METADATASTORE_H
//================================================================================
// Name : metadatastore.cpp
// Author : Alessio Netti
// Contact : info@dcdb.it
// Copyright : Leibniz Supercomputing Centre
// Description : A meta-data store for sensors
//================================================================================
//================================================================================
// This file is part of DCDB (DataCenter DataBase)
// Copyright (C) 2011-2019 Leibniz Supercomputing Centre
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//================================================================================
#include "metadatastore.h"
const sensorMetadata_t& MetadataStore::get(const string& key) {
if(!_metadata.count(key))
throw invalid_argument("MetadataStore: key " + key + " does not exist!");
return _metadata[key];
}
bool MetadataStore::store(const string& key, const sensorMetadata_t& s) {
bool overwritten = !_metadata.count(key);
_metadata[key] = s;
return overwritten;
}
bool MetadataStore::storeFromPTREE(const string& key, boost::property_tree::iptree& config) {
sensorMetadata_t metadata;
_parsePTREE(config, metadata);
return store(key, metadata);
}
boost::property_tree::ptree MetadataStore::getPTREE(const string& key) {
boost::property_tree::ptree config;
_dumpPTREE(config, get(key));
return config;
}
bool MetadataStore::storeFromJSON(const string& key, const string& payload) {
boost::property_tree::iptree config;
std::istringstream str(payload);
boost::property_tree::read_json(str, config);
return storeFromPTREE(key, config);
}
string MetadataStore::getJSON(const string& key) {
boost::property_tree::ptree config;
std::ostringstream output;
_dumpPTREE(config, get(key));
boost::property_tree::write_json(output, config, true);
return output.str();
}
void MetadataStore::_parsePTREE(boost::property_tree::iptree& config, sensorMetadata_t& s) {
// The isVirtual and publicName properties are NOT parsed
BOOST_FOREACH(boost::property_tree::iptree::value_type &val, config) {
if (boost::iequals(val.first, "monotonic")) {
s.monotonic = to_bool(val.second.data());
} else if (boost::iequals(val.first, "isVirtual")) {
s.isVirtual = to_bool(val.second.data());
} else if (boost::iequals(val.first, "integrable")) {
s.integrable = to_bool(val.second.data());
} else if (boost::iequals(val.first, "unit")) {
s.unit = val.second.data();
} else if (boost::iequals(val.first, "publicName")) {
s.publicName = val.second.data();
} else if (boost::iequals(val.first, "scale")) {
s.scale = stoull(val.second.data());
} else if (boost::iequals(val.first, "interval")) {
s.interval = stoull(val.second.data()) * 1000000;
} else if (boost::iequals(val.first, "operations")) {
_parseVector(val.second.data(), s.operations);
}
}
}
void MetadataStore::_dumpPTREE(boost::property_tree::ptree& config, const sensorMetadata_t& s) {
string ops="";
_dumpVector(ops, s.operations);
config.clear();
config.push_back(boost::property_tree::ptree::value_type("isVirtual", boost::property_tree::ptree(s.isVirtual ? "true" : "false")));
config.push_back(boost::property_tree::ptree::value_type("monotonic", boost::property_tree::ptree(s.monotonic ? "true" : "false")));
config.push_back(boost::property_tree::ptree::value_type("integrable", boost::property_tree::ptree(s.integrable ? "true" : "false")));
config.push_back(boost::property_tree::ptree::value_type("unit", boost::property_tree::ptree(s.unit)));
config.push_back(boost::property_tree::ptree::value_type("publicName", boost::property_tree::ptree(s.publicName)));
config.push_back(boost::property_tree::ptree::value_type("scale", boost::property_tree::ptree(to_string(s.scale))));
config.push_back(boost::property_tree::ptree::value_type("interval", boost::property_tree::ptree(to_string(s.interval / 1000000))));
config.push_back(boost::property_tree::ptree::value_type("operations", boost::property_tree::ptree(ops)));
}
void MetadataStore::_parseVector(const string& str, vector<string>& v, const char sep) {
v.clear();
std::stringstream ss(str);
std::string token;
while (std::getline(ss, token, sep)) {
if(!token.empty()) {
boost::algorithm::trim(token);
v.push_back(token);
}
}
}
void MetadataStore::_dumpVector(string& str, const vector<string>& v, const char sep) {
str = "";
string sepStr = string(sep,1);
for(const auto& el : v)
str += el + sepStr;
if(!str.empty() && str.back() == sep)
str.erase(str.size()-1, 1);
}
\ No newline at end of file
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