From c01f488b517c56901a2148db62bbf21c2906b046 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20B=C3=A9raud?= <adrien.beraud@savoirfairelinux.com> Date: Wed, 27 Feb 2019 15:23:21 -0500 Subject: [PATCH] daemon: added REST call to resolve name used callback in restclient.cpp to handle http request asynchronouly Change-Id: If09d19aa2b73eab2a217b9319c7a911b7c85cf76 --- bin/restcpp/restclient.cpp | 20 ++++++++++++ bin/restcpp/restconfigurationmanager.cpp | 39 +++++++++++++++++++++++- bin/restcpp/restconfigurationmanager.h | 10 +++++- 3 files changed, 67 insertions(+), 2 deletions(-) diff --git a/bin/restcpp/restclient.cpp b/bin/restcpp/restclient.cpp index 0856bd86b6..52896fb8b6 100644 --- a/bin/restcpp/restclient.cpp +++ b/bin/restcpp/restclient.cpp @@ -101,6 +101,25 @@ RestClient::initLib(int flags) #endif // Configuration event handlers + auto registeredNameFoundCb = exportable_callback<ConfigurationSignal::RegisteredNameFound>([&] + (const std::string& account_id, int state, const std::string& address, const std::string& name){ + auto remainingSessions = configurationManager_->getPendingNameResolutions(name); + + for(auto session: remainingSessions){ + const auto request = session->get_request(); + std::string body = address; + const std::multimap<std::string, std::string> headers + { + {"Content-Type", "text/html"}, + {"Content-Length", std::to_string(body.length())} + }; + if(address.size() > 0) + session->close(restbed::OK, body, headers); + else + session->close(404); + } + }); + // This is a short example of a callback using a lambda. In this case, this displays the incoming messages const std::map<std::string, SharedCallback> configEvHandlers = { @@ -113,6 +132,7 @@ RestClient::initLib(int flags) RING_INFO("%s : %s", it.first.c_str(), it.second.c_str()); }), + registeredNameFoundCb, }; if (!DRing::init(static_cast<DRing::InitFlag>(flags))) diff --git a/bin/restcpp/restconfigurationmanager.cpp b/bin/restcpp/restconfigurationmanager.cpp index f68d3febc6..e4f48d8b17 100644 --- a/bin/restcpp/restconfigurationmanager.cpp +++ b/bin/restcpp/restconfigurationmanager.cpp @@ -106,6 +106,11 @@ RestConfigurationManager::populateResources() resources_.back()->set_method_handler("POST", std::bind(&RestConfigurationManager::registerName, this, std::placeholders::_1)); + resources_.push_back(std::make_shared<restbed::Resource>()); + resources_.back()->set_path("/lookupName/{name: [a-z0-9]*}"); + resources_.back()->set_method_handler("GET", + std::bind(&RestConfigurationManager::lookupName, this, std::placeholders::_1)); + resources_.push_back(std::make_shared<restbed::Resource>()); resources_.back()->set_path("/setAccountActive/{accountID: [a-z0-9]*}/{status: (true|false)}"); resources_.back()->set_method_handler("GET", @@ -410,7 +415,7 @@ RestConfigurationManager::defaultRoute(const std::shared_ptr<restbed::Session> s body += "GET /setAccountActive/{accountID: [a-z0-9]*}/{status: (true|false)}\r\n"; body += "GET /accountTemplate/{type: [a-zA-Z]*}\r\n"; body += "POST /addAccount\r\n"; - body += "GET /removeAccount/{accountID: 3a-z0-9]*}\r\n"; + body += "GET /removeAccount/{accountID: [a-z0-9]*}\r\n"; body += "GET /accountList\r\n"; body += "GET /sendRegister/{accountID: [a-z0-9]*}/{status: (true|false)}\r\n"; body += "GET /registerAllAccounts\r\n"; @@ -600,6 +605,38 @@ RestConfigurationManager::registerName(const std::shared_ptr<restbed::Session> s } } +void +RestConfigurationManager::addPendingNameResolutions(const std::string& name, const std::shared_ptr<restbed::Session> session){ + std::lock_guard<std::mutex> lck(pendingNameResolutionMtx); + this->pendingNameResolutions.insert(std::make_pair(name, session)); +} + +std::set<std::shared_ptr<restbed::Session>> +RestConfigurationManager::getPendingNameResolutions(const std::string& name){ + std::lock_guard<std::mutex> lck(pendingNameResolutionMtx); + + auto result = this->pendingNameResolutions.equal_range(name); + std::set<std::shared_ptr<restbed::Session>> resultSet; + for (auto it = result.first; it != result.second; ++it){ + resultSet.insert(it->second); + } + this->pendingNameResolutions.erase(result.first, result.second); + + return resultSet; +} + +void +RestConfigurationManager::lookupName(const std::shared_ptr<restbed::Session> session) +{ + const auto request = session->get_request(); + const std::string name = request->get_path_parameter("name"); + + RING_WARN("[%s] GET /lookupName/%s", session->get_origin().c_str(), name.c_str()); + + addPendingNameResolutions(name, session); + DRing::lookupName("", "", name); +} + void RestConfigurationManager::setAccountActive(const std::shared_ptr<restbed::Session> session) { diff --git a/bin/restcpp/restconfigurationmanager.h b/bin/restcpp/restconfigurationmanager.h index fc3164286d..29f11c0c83 100644 --- a/bin/restcpp/restconfigurationmanager.h +++ b/bin/restcpp/restconfigurationmanager.h @@ -24,6 +24,7 @@ #include <string> #include <regex> #include <restbed> +#include <mutex> #if __GNUC__ >= 5 || (__GNUC__ >=4 && __GNUC_MINOR__ >= 6) /* This warning option only exists for gcc 4.6.0 and greater. */ @@ -54,19 +55,26 @@ class RestConfigurationManager std::vector<std::shared_ptr<restbed::Resource>> getResources(); + std::set<std::shared_ptr<restbed::Session>> getPendingNameResolutions(const std::string& name); + + private: // Attributes std::vector<std::shared_ptr<restbed::Resource>> resources_; - + std::multimap<std::string, std::shared_ptr<restbed::Session>> pendingNameResolutions; + std::mutex pendingNameResolutionMtx; // Methods std::map<std::string, std::string> parsePost(const std::string& post); void populateResources(); + void addPendingNameResolutions(const std::string& name, const std::shared_ptr<restbed::Session> session); void defaultRoute(const std::shared_ptr<restbed::Session> session); + void getAccountDetails(const std::shared_ptr<restbed::Session> session); void getVolatileAccountDetails(const std::shared_ptr<restbed::Session> session); void setAccountDetails(const std::shared_ptr<restbed::Session> session); void registerName(const std::shared_ptr<restbed::Session> session); + void lookupName(const std::shared_ptr<restbed::Session> session); void setAccountActive(const std::shared_ptr<restbed::Session> session); void getAccountTemplate(const std::shared_ptr<restbed::Session> session); void addAccount(const std::shared_ptr<restbed::Session> session); -- GitLab