Extend JSON API to shutdown retroshare gracefully

This commit is contained in:
Gioacchino Mazzurco 2018-06-28 15:04:06 +02:00
parent 0ff80baed3
commit d511b6648e
No known key found for this signature in database
GPG key ID: A1FBCA3872E87051
5 changed files with 74 additions and 17 deletions

View file

@ -21,8 +21,16 @@
// Generated at compile time // Generated at compile time
#include "jsonapi-wrappers.h" #include "jsonapi-wrappers.h"
JsonApiServer::JsonApiServer(uint16_t port) : mPort(port) JsonApiServer::JsonApiServer(
uint16_t port, const std::function<void(int)> shutdownCallback) :
mPort(port), mShutdownCallback(shutdownCallback)
{ {
registerHandler("/jsonApiServer/shutdown",
[this](const std::shared_ptr<restbed::Session>)
{
shutdown();
});
// Generated at compile time // Generated at compile time
#include "jsonapi-register.inl" #include "jsonapi-register.inl"
} }
@ -32,14 +40,22 @@ void JsonApiServer::run()
std::shared_ptr<rb::Settings> settings(new rb::Settings); std::shared_ptr<rb::Settings> settings(new rb::Settings);
settings->set_port(mPort); settings->set_port(mPort);
settings->set_default_header("Connection", "close"); settings->set_default_header("Connection", "close");
service.start(settings); mService.start(settings);
} }
void JsonApiServer::registerHandler(const std::string& path, const std::function<void (const std::shared_ptr<restbed::Session>)>& handler) void JsonApiServer::registerHandler(
const std::string& path,
const std::function<void (const std::shared_ptr<restbed::Session>)>& handler)
{ {
std::shared_ptr<restbed::Resource> resource(new rb::Resource); std::shared_ptr<restbed::Resource> resource(new rb::Resource);
resource->set_path(path); resource->set_path(path);
resource->set_method_handler("GET", handler); resource->set_method_handler("GET", handler);
resource->set_method_handler("POST", handler); resource->set_method_handler("POST", handler);
service.publish(resource); mService.publish(resource);
}
void JsonApiServer::shutdown(int exitCode)
{
mService.stop();
mShutdownCallback(exitCode);
} }

View file

@ -39,12 +39,15 @@ void createChannelHandler(const std::shared_ptr<rb::Session> session);
*/ */
struct JsonApiServer : RsSingleJobThread struct JsonApiServer : RsSingleJobThread
{ {
JsonApiServer(uint16_t port); JsonApiServer(
uint16_t port,
const std::function<void(int)> shutdownCallback = [](int){} );
/// @see RsSingleJobThread /// @see RsSingleJobThread
virtual void run(); virtual void run();
/** /**
* @param[in] path Path itno which publish the API call
* @param[in] handler function which will be called to handle the requested * @param[in] handler function which will be called to handle the requested
* path, the function must be declared like: * path, the function must be declared like:
* \code{.cpp} * \code{.cpp}
@ -55,8 +58,21 @@ struct JsonApiServer : RsSingleJobThread
const std::string& path, const std::string& path,
const std::function<void(const std::shared_ptr<rb::Session>)>& handler ); const std::function<void(const std::shared_ptr<rb::Session>)>& handler );
/**
* @brief Shutdown the JSON API server and call shutdownCallback
* @jsonapi{development}
* Beware that this method shout down only the JSON API server instance not
* the whole RetroShare instance, this behaviour can be altered via
* shutdownCallback paramether of @see JsonApiServer::JsonApiServer
* This method is made available also via JSON API with path
* /jsonApiServer/shutdown
* @param exitCode just passed down to the shutdownCallback
*/
void shutdown(int exitCode = 0);
private: private:
uint16_t mPort; uint16_t mPort;
rb::Service service; rb::Service mService;
const std::function<void(int)> mShutdownCallback;
}; };

View file

@ -229,6 +229,12 @@ struct RsLoginHelper
bool createLocation( RsLoginHelper::Location& location, bool createLocation( RsLoginHelper::Location& location,
const std::string& password, const std::string& password,
std::string& errorMessage ); std::string& errorMessage );
/**
* @brief Close RetroShare session
* @jsonapi{development}
*/
void closeSession();
}; };
#endif #endif

View file

@ -1969,6 +1969,11 @@ bool RsLoginHelper::createLocation(
return ret; return ret;
} }
void RsLoginHelper::closeSession()
{
RsControl::instance()->rsGlobalShutDown();
}
void RsLoginHelper::Location::serial_process( void RsLoginHelper::Location::serial_process(
RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx ) RsGenericSerializer::SerializeContext& ctx )

View file

@ -30,7 +30,21 @@
#include "api/ApiServerLocal.h" #include "api/ApiServerLocal.h"
#include "api/RsControlModule.h" #include "api/RsControlModule.h"
#include "jsonapi/jsonapi.h" #ifdef RS_JSONAPI
# include "jsonapi/jsonapi.h"
# include "retroshare/rsiface.h"
JsonApiServer jas(9092, [](int ec)
{
RsControl::instance()->rsGlobalShutDown();
QCoreApplication::exit(ec);
});
void exitGracefully(int ec) { jas.shutdown(ec); }
#else // ifdef RS_JSONAPI
void exitGracefully(int ec) { QCoreApplication::exit(ec); }
#endif // ifdef RS_JSONAPI
using namespace resource_api; using namespace resource_api;
@ -42,11 +56,11 @@ int main(int argc, char *argv[])
QCoreApplication app(argc, argv); QCoreApplication app(argc, argv);
signal(SIGINT, &QCoreApplication::exit); signal(SIGINT, exitGracefully);
signal(SIGTERM, &QCoreApplication::exit); signal(SIGTERM, exitGracefully);
#ifdef SIGBREAK #ifdef SIGBREAK
signal(SIGBREAK, &QCoreApplication::exit); signal(SIGBREAK, exitGracefully);
#endif // def SIGBREAK #endif // ifdef SIGBREAK
ApiServer api; ApiServer api;
RsControlModule ctrl_mod(argc, argv, api.getStateTokenServer(), &api, true); RsControlModule ctrl_mod(argc, argv, api.getStateTokenServer(), &api, true);
@ -55,23 +69,23 @@ int main(int argc, char *argv[])
dynamic_cast<resource_api::ResourceRouter*>(&ctrl_mod), dynamic_cast<resource_api::ResourceRouter*>(&ctrl_mod),
&resource_api::RsControlModule::handleRequest); &resource_api::RsControlModule::handleRequest);
QString sockPath = QDir::homePath() + "/.retroshare"; QString sockPath = QDir::homePath() + "/.retroshare";
sockPath.append("/libresapi.sock"); sockPath.append("/libresapi.sock");
qDebug() << "Listening on:" << sockPath; qDebug() << "Listening on:" << sockPath;
ApiServerLocal apiServerLocal(&api, sockPath); (void) apiServerLocal; ApiServerLocal apiServerLocal(&api, sockPath); (void) apiServerLocal;
JsonApiServer jas(9092);
jas.start("JsonApiServer");
// This ugly but RsControlModule has no other way to callback for stop // This ugly but RsControlModule has no other way to callback for stop
QTimer shouldExitTimer; QTimer shouldExitTimer;
shouldExitTimer.setTimerType(Qt::VeryCoarseTimer); shouldExitTimer.setTimerType(Qt::VeryCoarseTimer);
shouldExitTimer.setInterval(1000); shouldExitTimer.setInterval(1000);
QObject::connect( &shouldExitTimer, &QTimer::timeout, [&](){ QObject::connect( &shouldExitTimer, &QTimer::timeout, [&]()
if(ctrl_mod.processShouldExit()) app.quit(); } ); { if(ctrl_mod.processShouldExit()) exitGracefully(0); } );
shouldExitTimer.start(); shouldExitTimer.start();
#ifdef RS_JSONAPI
jas.start();
#endif
return app.exec(); return app.exec();
} }