Commit 5720b46a authored by Alessio Netti's avatar Alessio Netti
Browse files

Adding "quit" REST API command

- Allows to quit the collectagent or dcdbpusher with a specified return code.
parent b3c39d1a
......@@ -42,6 +42,7 @@ CARestAPI::CARestAPI(serverSettings_t settings,
addEndpoint("/help", {http::verb::get, stdBind(GET_help)});
addEndpoint("/average", {http::verb::get, stdBind(GET_average)});
addEndpoint("/quit", {http::verb::put, stdBind(PUT_quit)});
_analyticsController->getManager()->addRestEndpoints(this);
......@@ -102,6 +103,16 @@ void CARestAPI::GET_average(endpointArgs) {
}
}
void CARestAPI::PUT_quit(endpointArgs) {
int retCode = getQuery("code", queries)=="" ? 0 : std::stoi(getQuery("code", queries));
if(retCode<0 || retCode>255)
retCode = 0;
_retCode = retCode;
raise(SIGUSR1);
res.body() = "Quitting with return code " + std::to_string(retCode) + ".\n";
res.result(http::status::ok);
}
void CARestAPI::PUT_analytics_reload(endpointArgs) {
if (_analyticsController->getManager()->getStatus() != OperatorManager::LOADED) {
res.body() = "OperatorManager is not loaded!\n";
......
......@@ -33,6 +33,7 @@
#include "analyticscontroller.h"
#include "mqttchecker.h"
#include "configuration.h"
#include <signal.h>
/**
* @brief Class providing a RESTful API to collect agent via network (HTTPs only).
......@@ -56,6 +57,9 @@ public:
" Average of last sensor readings from the last\n"
" [interval] seconds or of all cached readings\n"
" if no interval is given\n"
" -PUT: /quit?[code]\n"
" The collectagent quits with the specified\n"
" return code.\n"
"\n";
private:
......@@ -88,6 +92,18 @@ private:
*/
void GET_average(endpointArgs);
/**
* PUT "/quit"
*
* @brief Quits the collectagent with a certain return code.
*
* Queries | key | possible values | explanation
* -------------------------------------------------------------------------
* Required | - | - | -
* Optional | code | integer value | return code to be used
*/
void PUT_quit(endpointArgs);
/**
* PUT "/analytics/reload"
*
......
......@@ -86,6 +86,7 @@
using namespace std;
int keepRunning;
int retCode = EXIT_SUCCESS;
bool statistics;
uint64_t msgCtr;
uint64_t pmsgCtr;
......@@ -98,6 +99,7 @@ DCDB::JobDataStore *myJobDataStore;
DCDB::SensorConfig *mySensorConfig;
DCDB::CaliEvtDataStore *myCaliEvtDataStore;
MetadataStore *metadataStore;
CARestAPI* httpsServer = nullptr;
DCDB::SCError err;
QueryEngine& queryEngine = QueryEngine::getInstance();
logger_t lg;
......@@ -252,10 +254,16 @@ bool metadataQueryCallback(const string& name, SensorMetadata& buffer) {
void sigHandler(int sig)
{
boost::log::sources::severity_logger<boost::log::trivial::severity_level> lg;
if( sig == SIGINT )
if( sig == SIGINT ) {
LOG(fatal) << "Received SIGINT";
else if( sig == SIGTERM )
retCode = EXIT_SUCCESS;
} else if( sig == SIGTERM ) {
LOG(fatal) << "Received SIGTERM";
retCode = EXIT_SUCCESS;
} else if( sig == SIGUSR1 ) {
LOG(fatal) << "Received SIGUSR1 via REST API";
retCode = !httpsServer ? EXIT_SUCCESS : httpsServer->getReturnCode();
}
keepRunning = 0;
}
......@@ -668,6 +676,7 @@ int main(int argc, char* const argv[]) {
*/
signal(SIGINT, sigHandler);
signal(SIGTERM, sigHandler);
signal(SIGUSR1, sigHandler);
/*
* Catch critical signals to allow for backtraces
......@@ -815,7 +824,6 @@ int main(int argc, char* const argv[]) {
/*
* Start the HTTP Server for the REST API
*/
CARestAPI* httpsServer = nullptr;
if (restAPISettings.enabled) {
httpsServer = new CARestAPI(restAPISettings, &mySensorCache, analyticsController);
config.readRestAPIUsers(httpsServer);
......@@ -888,7 +896,7 @@ int main(int argc, char* const argv[]) {
abrt(EXIT_FAILURE, INTERR);
}
return EXIT_SUCCESS;
return retCode;
}
......@@ -242,6 +242,13 @@ public:
_endpoints[path] = endpoint;
return ret;
}
/**
* @brief Returns the code to be used at exit by the entity in which the server is running.
*
* @return A numerical return code.
*/
int getReturnCode() { return _retCode; }
protected:
......@@ -254,6 +261,7 @@ protected:
}
logger_t lg;
int _retCode;
private:
......
......@@ -61,6 +61,7 @@ struct send_lambda {
};
RESTHttpsServer::RESTHttpsServer(serverSettings_t settings) :
_retCode(0),
_isRunning(false) {
_io = std::unique_ptr<boost::asio::io_context>(
......
......@@ -182,6 +182,19 @@ Tables with allowed ressources sorted by REST methods can be found below. A quer
</tr>
</table>
<table>
<tr>
<td colspan="2"><b>PUT /quit</b></td>
<td colspan="2">Exits the Pusher with a user-specified return code.</td>
</tr>
<tr>
<td>code</td>
<td>Return code.</td>
<td>Yes</td>
<td>Return code to be used when exiting.</td>
</tr>
</table>
<table>
<tr>
<td colspan="2"><b>PUT /load</b></td>
......
......@@ -29,6 +29,7 @@
#include <sstream>
#include <string>
#include <signal.h>
#include <boost/property_tree/ptree.hpp>
......@@ -54,6 +55,7 @@ RestAPI::RestAPI(serverSettings_t settings,
addEndpoint("/sensors", {http::verb::get, stdBind(GET_sensors)});
addEndpoint("/average", {http::verb::get, stdBind(GET_average)});
addEndpoint("/quit", {http::verb::put, stdBind(PUT_quit)});
addEndpoint("/load", {http::verb::put, stdBind(PUT_load)});
addEndpoint("/unload", {http::verb::put, stdBind(PUT_unload)});
addEndpoint("/start", {http::verb::put, stdBind(PUT_start)});
......@@ -215,6 +217,16 @@ void RestAPI::GET_average(endpointArgs) {
}
}
void RestAPI::PUT_quit(endpointArgs) {
int retCode = getQuery("code", queries)=="" ? 0 : std::stoi(getQuery("code", queries));
if(retCode<0 || retCode>255)
retCode = 0;
_retCode = retCode;
raise(SIGUSR1);
res.body() = "Quitting with return code " + std::to_string(retCode) + ".\n";
res.result(http::status::ok);
}
void RestAPI::PUT_load(endpointArgs) {
const std::string plugin = getQuery("plugin", queries);
const std::string path = getQuery("path", queries);
......
......@@ -72,6 +72,8 @@ class RestAPI : public RESTHttpsServer {
" /start?plugin Start the sensors of the plugin.\n"
" /stop?plugin Stop the sensors of the plugin.\n"
" /reload?plugin Reload the plugin configuration.\n"
" /quit?[code] The pusher quits with the specified\n"
" return code.\n"
"\n";
private:
......@@ -131,6 +133,18 @@ class RestAPI : public RESTHttpsServer {
/******************************************************************************/
/**
* PUT "/quit"
*
* @brief Quits the pusher with a certain return code.
*
* Queries | key | possible values | explanation
* -------------------------------------------------------------------------
* Required | - | - | -
* Optional | code | integer value | return code to be used
*/
void PUT_quit(endpointArgs);
/**
* PUT "/load"
*
......
......@@ -68,6 +68,7 @@
using namespace std;
int retCode = 0;
Configuration * _configuration;
MQTTPusher * _mqttPusher;
PluginManager * _pluginManager;
......@@ -126,10 +127,16 @@ bool metadataQueryCallback(const string &name, SensorMetadata &buffer) {
void sigHandler(int sig) {
boost::log::sources::severity_logger<boost::log::trivial::severity_level> lg;
if (sig == SIGINT)
if (sig == SIGINT) {
LOG(fatal) << "Received SIGINT";
else if (sig == SIGTERM)
retCode = 0;
} else if (sig == SIGTERM) {
LOG(fatal) << "Received SIGTERM";
retCode = 0;
} else if( sig == SIGUSR1 ) {
LOG(fatal) << "Received SIGUSR1 via REST API";
retCode = !_httpsServer ? EXIT_SUCCESS : _httpsServer->getReturnCode();
}
//Stop data analytics plugins and operators
_operatorManager->stop();
......@@ -459,6 +466,7 @@ int main(int argc, char **argv) {
LOG(info) << "Registering signal handlers...";
signal(SIGINT, sigHandler); //Handle Strg+C
signal(SIGTERM, sigHandler); //Handle termination
signal(SIGUSR1, sigHandler); // Handle user-requested termination
LOG(info) << "Signal handlers registered!";
LOG(info) << "Cleaning up...";
......@@ -501,5 +509,5 @@ int main(int argc, char **argv) {
}
LOG(info) << "Exiting...Goodbye!";
return 0;
return retCode;
}
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