diff --git a/bin/restcpp/restclient.cpp b/bin/restcpp/restclient.cpp index 0856bd86b6bd62a5a70911c81d2addc5a4c84471..52896fb8b65ca1eaae6cfdc78c9ea254ca4b8920 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 f68d3febc68a6b51e049ed519cb93d411c0c19b5..e4f48d8b172d94f18eebdfe379200e264fd7cc9e 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 fc3164286dc37d82b06180ca42c4ee41d6d707b4..29f11c0c835265a6e553e01033bdfa857a29c1e3 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);