Commit 531b0a54 authored by Alessio Netti's avatar Alessio Netti
Browse files

Grafana: REST API request to rebuild the sensor navigator

parent 2733c672
......@@ -245,7 +245,7 @@ int main(int argc, char *argv[])
_configuration->readRestAPIUsers(_httpsServer);
LOG(info) << "Retrieving published sensor names and topics...";
if(!_httpsServer->initTree()) {
if(!_httpsServer->buildTree()) {
throw std::runtime_error("Unable to initialize the sensor navigator!");
}
......
......@@ -148,6 +148,16 @@ Tables with allowed ressources sorted by REST methods can be found below. A quer
</tr>
</table>
<table>
<tr>
<td colspan="2"><b>PUT /navigator</b></td>
<td colspan="2">Rebuilds the internal sensor navigator.</td>
</tr>
<tr>
<td colspan="4">No queries.</td>
</tr>
</table>
> NOTE &ensp;&ensp;&ensp;&ensp;&ensp; Opt. = Optional
### Examples <a name="restExamples"></a>
......
......@@ -41,6 +41,7 @@ RestAPI::RestAPI(serverSettings_t settings,
DCDB::Connection* cassandraConnection) :
RESTHttpsServer(settings),
_connection(cassandraConnection),
_updating(false),
_hierarchySettings(hierarchySettings) {
//Configuring endpoints
......@@ -48,54 +49,47 @@ RestAPI::RestAPI(serverSettings_t settings,
addEndpoint("/levels", {http::verb::post, stdBind(POST_levels)});
addEndpoint("/search", {http::verb::post, stdBind(POST_search)});
addEndpoint("/query", {http::verb::post, stdBind(POST_query)});
}
addEndpoint("/navigator", {http::verb::put, stdBind(PUT_navigator)});
void RestAPI::clear() {
if(_sensorConfig) {
delete _sensorConfig;
_sensorConfig = NULL;
}
if(_navigator) {
delete _navigator;
_navigator = NULL;
}
if(_sensorDataStore) {
delete _sensorDataStore;
_sensorDataStore = NULL;
}
_metadataStore.clear();
_smootherRegex = boost::regex();
_sensorConfig = new DCDB::SensorConfig(_connection);
_sensorDataStore = new DCDB::SensorDataStore(_connection);
_separator = _hierarchySettings.separator;
_smootherRegex = boost::regex(_hierarchySettings.smootherRegex);
_numRegex = boost::regex("[0-9]+");
}
//Initializes the internal sensor navigator
bool RestAPI::initTree() {
clear();
//Get the list of all public sensors and topics.
bool RestAPI::buildTree() {
std::vector<std::string> topics;
std::list<DCDB::PublicSensor> publicSensors;
_sensorConfig = new DCDB::SensorConfig(_connection);
_sensorDataStore = new DCDB::SensorDataStore(_connection);
if(_sensorConfig->getPublicSensorsVerbose(publicSensors)!=DCDB::SC_OK) {
//Spinlock to ensure that only one sensor navigator update runs at a time
while(_updating.exchange(true)) {}
//Get the list of all public sensors and topics.
if(!_sensorConfig || _sensorConfig->getPublicSensorsVerbose(publicSensors)!=DCDB::SC_OK) {
LOG(error) << "Unable to fetch list of public sensors!";
clear();
_updating.store(false);
return false;
}
std::shared_ptr<SensorNavigator> newNavigator = std::make_shared<SensorNavigator>();
std::shared_ptr<MetadataStore> newMetadataStore = std::make_shared<MetadataStore>();
for(auto& s : publicSensors) {
topics.push_back(s.pattern);
_metadataStore.store(s.pattern, DCDB::PublicSensor::publicSensorToMetadata(s));
newMetadataStore->store(s.pattern, DCDB::PublicSensor::publicSensorToMetadata(s));
}
//Build the tree navigator
LOG(info) << "Building the sensor navigator...";
_separator = _hierarchySettings.separator;
_smootherRegex = boost::regex(_hierarchySettings.smootherRegex);
_numRegex = boost::regex("[0-9]+");
_navigator = new SensorNavigator();
_navigator->setFilter(_hierarchySettings.filter);
_navigator->buildTree(_hierarchySettings.regex, &topics);
newNavigator->setFilter(_hierarchySettings.filter);
newNavigator->buildTree(_hierarchySettings.regex, &topics);
//Replacing the old navigator and metadata store
_navigator = newNavigator;
_metadataStore = newMetadataStore;
_updating.store(false);
LOG(info) << "Built a sensor navigator of size " << std::to_string(_navigator->getTreeSize()) << " and depth " << std::to_string(_navigator->getTreeDepth()) << ".";
return true;
}
......@@ -219,7 +213,7 @@ void RestAPI::POST_query(endpointArgs) {
for(auto& sensorName : sensors) {
results.clear();
try {
sm = _metadataStore.get(sensorName);
sm = _metadataStore->get(sensorName);
} catch(const std::invalid_argument &e) {}
uint64_t sInterval = sm.getInterval() ? *sm.getInterval() : 0;
......@@ -278,3 +272,13 @@ void RestAPI::POST_query(endpointArgs) {
res.result(http::status::ok);
return;
}
void RestAPI::PUT_navigator(endpointArgs) {
if(!buildTree()) {
res.body() = "Sensor navigator could not be rebuilt.";
res.result(http::status::internal_server_error);
} else {
res.body() = "Built a sensor navigator of size " + std::to_string(_navigator->getTreeSize()) + " and depth " + std::to_string(_navigator->getTreeDepth()) + ".";
res.result(http::status::ok);
}
}
......@@ -44,6 +44,7 @@
#include <boost/asio.hpp>
#include <boost/regex.hpp>
#include <atomic>
#define MAX_DATAPOINTS 100000
......@@ -59,10 +60,20 @@ public:
hierarchySettings_t hierarchySettings,
DCDB::Connection* cassandraConnection);
virtual ~RestAPI() { clear(); }
bool initTree();
virtual ~RestAPI() {
if(_sensorConfig) {
delete _sensorConfig;
_sensorConfig = NULL;
}
if(_sensorDataStore) {
delete _sensorDataStore;
_sensorDataStore = NULL;
}
}
//Builds the internal sensor navigator
bool buildTree();
private:
/******************************************************************************/
......@@ -124,6 +135,17 @@ private:
*/
void POST_query(endpointArgs);
/**
* PUT "/navigator"
*
* @brief Reloads the sensor navigator.
*
* Queries | key | possible values | explanation
* -------------------------------------------------------------------------
* Required | - | - | -
*/
void PUT_navigator(endpointArgs);
/******************************************************************************/
//Clears all internal storage
......@@ -133,11 +155,13 @@ private:
inline int64_t sign(int64_t val) { return val < 0 ? -1 : 1; }
inline int64_t abs(int64_t val) { return val < 0 ? -val : val; }
SensorNavigator* _navigator;
std::shared_ptr<SensorNavigator> _navigator;
std::shared_ptr<MetadataStore> _metadataStore;
DCDB::Connection* _connection;
DCDB::SensorConfig* _sensorConfig;
DCDB::SensorDataStore* _sensorDataStore;
MetadataStore _metadataStore;
atomic<bool> _updating;
std::string _separator;
hierarchySettings_t _hierarchySettings;
boost::regex _smootherRegex;
......
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