From 0bb998c42f078cc1060bb7d1731f9c9894ec32cb Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Wed, 20 Oct 2021 14:20:51 -0700 Subject: [PATCH] Added serialnumber cache, address completion. --- CMakeLists.txt | 1 + build | 2 +- owprov.properties | 3 + src/Daemon.cpp | 2 + src/RESTAPI/RESTAPI_inventory_handler.cpp | 5 +- src/RESTAPI/RESTAPI_server.cpp | 9 ++- src/RESTAPI/RESTAPI_webSocketServer.cpp | 66 ++++++++++++++++++--- src/RESTAPI/RESTAPI_webSocketServer.h | 27 +++------ src/SerialNumberCache.cpp | 72 +++++++++++++++++++++++ src/SerialNumberCache.h | 44 ++++++++++++++ src/StorageService.cpp | 2 + src/storage/storage_inventory.cpp | 7 +++ src/storage/storage_inventory.h | 1 + 13 files changed, 209 insertions(+), 32 deletions(-) create mode 100644 src/SerialNumberCache.cpp create mode 100644 src/SerialNumberCache.h diff --git a/CMakeLists.txt b/CMakeLists.txt index d5d825c..061fe5c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -88,6 +88,7 @@ add_executable(owprov src/RESTAPI/RESTAPI_entity_list_handler.cpp src/RESTAPI/RESTAPI_entity_list_handler.h src/storage/storage_management_roles.cpp src/storage/storage_management_roles.h src/framework/storage_setup.cpp + src/SerialNumberCache.h src/SerialNumberCache.cpp src/storage/storage_configurations.cpp src/storage/storage_configurations.h src/RESTAPI/RESTAPI_configurations_handler.cpp src/RESTAPI/RESTAPI_configurations_handler.h src/RESTAPI/RESTAPI_webSocketServer.h src/RESTAPI/RESTAPI_webSocketServer.cpp src/RESTAPI/RESTAPI_contact_list_handler.cpp src/RESTAPI/RESTAPI_contact_list_handler.h src/RESTAPI/RESTAPI_location_list_handler.cpp src/RESTAPI/RESTAPI_location_list_handler.h src/RESTAPI/RESTAPI_venue_list_handler.cpp src/RESTAPI/RESTAPI_venue_list_handler.h src/RESTAPI/RESTAPI_managementPolicy_list_handler.cpp src/RESTAPI/RESTAPI_managementPolicy_list_handler.h src/RESTAPI/RESTAPI_managementRole_handler.cpp src/RESTAPI/RESTAPI_managementRole_handler.h src/RESTAPI/RESTAPI_managementRole_list_handler.cpp src/RESTAPI/RESTAPI_managementRole_list_handler.h src/RESTAPI/RESTAPI_configurations_list_handler.cpp src/RESTAPI/RESTAPI_configurations_list_handler.h src/SecurityDBProxy.cpp src/SecurityDBProxy.h src/APConfig.cpp src/APConfig.h src/framework/RESTAPI_errors.h src/ConfigurationValidator.cpp src/ConfigurationValidator.h src/framework/RESTAPI_GenericServer.cpp src/framework/RESTAPI_GenericServer.h src/AutoDiscovery.cpp src/AutoDiscovery.h src/framework/CIDRUtils.cpp src/framework/CIDRUtils.h src/SDK_stubs.cpp src/SDK_stubs.h src/ConfigSanityChecker.cpp src/ConfigSanityChecker.h src/storage/storage_tags.cpp src/storage/storage_tags.h src/TagServer.cpp src/TagServer.h src/framework/Storage.h diff --git a/build b/build index d35d5f7..0dbf139 100644 --- a/build +++ b/build @@ -1 +1 @@ -347 \ No newline at end of file +350 \ No newline at end of file diff --git a/owprov.properties b/owprov.properties index 62cd042..08aaa51 100644 --- a/owprov.properties +++ b/owprov.properties @@ -38,6 +38,9 @@ openwifi.system.uri.ui = owprov-ui.arilia.com firmware.updater.upgrade = yes firmware.updater.rconly = no +geocodeapi = google +google.apikey = ********************************** + ############################# # Generic information for all micro services ############################# diff --git a/src/Daemon.cpp b/src/Daemon.cpp index bac10e9..ac444e3 100644 --- a/src/Daemon.cpp +++ b/src/Daemon.cpp @@ -21,6 +21,7 @@ #include "SecurityDBProxy.h" #include "AutoDiscovery.h" #include "ConfigurationValidator.h" +#include "SerialNumberCache.h" namespace OpenWifi { class Daemon *Daemon::instance_ = nullptr; @@ -36,6 +37,7 @@ namespace OpenWifi { OpenWifi::Storage(), ConfigurationValidator(), AuthClient(), + SerialNumberCache(), RESTAPI_server(), RESTAPI_InternalServer(), SecurityDBProxy(), diff --git a/src/RESTAPI/RESTAPI_inventory_handler.cpp b/src/RESTAPI/RESTAPI_inventory_handler.cpp index b5d1b7b..f9288be 100644 --- a/src/RESTAPI/RESTAPI_inventory_handler.cpp +++ b/src/RESTAPI/RESTAPI_inventory_handler.cpp @@ -18,6 +18,7 @@ #include "AutoDiscovery.h" #include "SDK_stubs.h" #include "RESTAPI/RESTAPI_db_helpers.h" +#include "SerialNumberCache.h" namespace OpenWifi{ @@ -127,7 +128,8 @@ namespace OpenWifi{ if(DB_.DeleteRecord("id", Existing.info.id)) { DB_.DeleteRecord(RESTAPI::Protocol::ID, Existing.info.id); - OK(); + SerialNumberCache()->DeleteSerialNumber(SerialNumber); + return OK(); } InternalError(RESTAPI::Errors::CouldNotBeDeleted); } @@ -193,6 +195,7 @@ namespace OpenWifi{ NewObject.info.id = Daemon()->CreateUUID(); if(DB_.CreateRecord(NewObject)) { + SerialNumberCache()->AddSerialNumber(SerialNumber); if (!NewObject.venue.empty()) Storage()->VenueDB().AddDevice("id",NewObject.venue,NewObject.info.id); if (!NewObject.entity.empty()) diff --git a/src/RESTAPI/RESTAPI_server.cpp b/src/RESTAPI/RESTAPI_server.cpp index a918be6..2c799eb 100644 --- a/src/RESTAPI/RESTAPI_server.cpp +++ b/src/RESTAPI/RESTAPI_server.cpp @@ -9,16 +9,15 @@ #include "Poco/URI.h" -#include "RESTAPI_server.h" #include "framework/Utils.h" #include "framework/RESTAPI_handler.h" - #include "framework/RESTAPI_system_command.h" +#include "RESTAPI/RESTAPI_server.h" #include "RESTAPI/RESTAPI_entity_handler.h" #include "RESTAPI/RESTAPI_contact_handler.h" #include "RESTAPI/RESTAPI_location_handler.h" -#include "RESTAPI_venue_handler.h" +#include "RESTAPI/RESTAPI_venue_handler.h" #include "RESTAPI/RESTAPI_inventory_handler.h" #include "RESTAPI/RESTAPI_managementPolicy_handler.h" #include "RESTAPI/RESTAPI_managementPolicy_list_handler.h" @@ -26,10 +25,10 @@ #include "RESTAPI/RESTAPI_entity_list_handler.h" #include "RESTAPI/RESTAPI_configurations_handler.h" #include "RESTAPI/RESTAPI_configurations_list_handler.h" -#include "RESTAPI_webSocketServer.h" +#include "RESTAPI/RESTAPI_webSocketServer.h" #include "RESTAPI/RESTAPI_contact_list_handler.h" #include "RESTAPI/RESTAPI_location_list_handler.h" -#include "RESTAPI_venue_list_handler.h" +#include "RESTAPI/RESTAPI_venue_list_handler.h" #include "RESTAPI/RESTAPI_managementRole_list_handler.h" namespace OpenWifi { diff --git a/src/RESTAPI/RESTAPI_webSocketServer.cpp b/src/RESTAPI/RESTAPI_webSocketServer.cpp index 6470b65..b6390d8 100644 --- a/src/RESTAPI/RESTAPI_webSocketServer.cpp +++ b/src/RESTAPI/RESTAPI_webSocketServer.cpp @@ -9,9 +9,11 @@ #include "Poco/JSON/Parser.h" #include "Poco/JSON/Stringifier.h" -#include "framework/Utils.h" +#include "SerialNumberCache.h" + #include "framework/AuthClient.h" -#include "framework/RESTAPI_errors.h" +#include "framework/Utils.h" +#include "Poco/Net/HTTPSClientSession.h" namespace OpenWifi { @@ -27,6 +29,9 @@ namespace OpenWifi { int n; bool Authenticated=false; bool Done=false; + GoogleApiKey_ = Daemon()->ConfigGetString("google.apikey",""); + GeoCodeEnabled_ = !GoogleApiKey_.empty(); + do { Poco::Buffer IncomingFrame(0); @@ -104,8 +109,6 @@ namespace OpenWifi { catch (const Poco::Exception &E) { Logger_.log(E); } - } else { - BadRequest(RESTAPI::Errors::OnlyWSSupported); } } @@ -113,12 +116,61 @@ namespace OpenWifi { try { if (O->has("command")) { auto Command = O->get("command").toString(); - auto It = CommandProcessors_.find(Command); - if(It!=CommandProcessors_.end()) - It->second(O,Answer,UserInfo_); + if (Command == "serial_number_search" && O->has("serial_prefix")) { + auto Prefix = O->get("serial_prefix").toString(); + uint64_t HowMany = 32; + if (O->has("howMany")) + HowMany = O->get("howMany"); + Logger_.information(Poco::format("serial_number_search: %s", Prefix)); + if (!Prefix.empty() && Prefix.length() < 13) { + std::vector Numbers; + SerialNumberCache()->FindNumbers(Prefix, 50, Numbers); + Poco::JSON::Array A; + for (const auto &i : Numbers) + A.add(Utils::int_to_hex(i)); + Poco::JSON::Object AO; + AO.set("serialNumbers", A); + AO.set("command","serial_number_search"); + std::ostringstream SS; + Poco::JSON::Stringifier::stringify(AO, SS); + Answer = SS.str(); + } + } else if(GeoCodeEnabled_ && Command == "address_completion" && O->has("address")) { + auto Address = O->get("address").toString(); + Answer = GoogleGeoCodeCall(Address); + } } } catch (const Poco::Exception &E) { Logger_.log(E); } } + + std::string RESTAPI_webSocketServer::GoogleGeoCodeCall(const std::string &A) { + try { + std::string URI = { "https://maps.googleapis.com/maps/api/geocode/json"}; + Poco::URI uri(URI); + + uri.addQueryParameter("address",A); + uri.addQueryParameter("key", GoogleApiKey_); + + Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort()); + Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, uri.getPath(), Poco::Net::HTTPMessage::HTTP_1_1); + session.sendRequest(req); + Poco::Net::HTTPResponse res; + std::istream& rs = session.receiveResponse(res); + + if(res.getStatus()==Poco::Net::HTTPResponse::HTTP_OK) { + std::ostringstream os; + Poco::StreamCopier::copyStream(rs,os); + return os.str(); + } else { + std::ostringstream os; + Poco::StreamCopier::copyStream(rs,os); + return "{ \"error\" : " + os.str() + " }"; + } + } catch(...) { + + } + return "{ \"error\" : \"No call made\" }"; + } } \ No newline at end of file diff --git a/src/RESTAPI/RESTAPI_webSocketServer.h b/src/RESTAPI/RESTAPI_webSocketServer.h index 7e963ab..c94dc0a 100644 --- a/src/RESTAPI/RESTAPI_webSocketServer.h +++ b/src/RESTAPI/RESTAPI_webSocketServer.h @@ -5,36 +5,27 @@ #ifndef UCENTRALGW_RESTAPI_WEBSOCKETSERVER_H #define UCENTRALGW_RESTAPI_WEBSOCKETSERVER_H -#include - #include "framework/RESTAPI_handler.h" namespace OpenWifi { - - typedef std::function ws_processor_func; - class RESTAPI_webSocketServer : public RESTAPIHandler { public: - RESTAPI_webSocketServer(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, bool Internal) + RESTAPI_webSocketServer(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, bool Internal) : RESTAPIHandler(bindings, L, - std::vector{Poco::Net::HTTPRequest::HTTP_GET, - Poco::Net::HTTPRequest::HTTP_OPTIONS}, - Server, - Internal) {} + std::vector{ Poco::Net::HTTPRequest::HTTP_GET, + Poco::Net::HTTPRequest::HTTP_OPTIONS}, + Server, Internal,false) {} static const std::list PathName() { return std::list{"/api/v1/ws"};} - void DoGet() final; + void DoDelete() final {}; void DoPost() final {}; void DoPut() final {}; - void DoDelete() final {}; - - inline void RegisterProcessor(const std::string &Command, ws_processor_func & f) { - CommandProcessors_[Command] = f; - } - private: void Process(const Poco::JSON::Object::Ptr &O, std::string &Answer); - std::map CommandProcessors_; + std::string GoogleGeoCodeCall(const std::string &A); + bool GeoCodeEnabled_=false; + std::string GoogleApiKey_; + }; } diff --git a/src/SerialNumberCache.cpp b/src/SerialNumberCache.cpp new file mode 100644 index 0000000..6d4f6f8 --- /dev/null +++ b/src/SerialNumberCache.cpp @@ -0,0 +1,72 @@ +// +// Created by stephane bourque on 2021-08-11. +// + +#include "SerialNumberCache.h" +#include + +#include "StorageService.h" +#include "framework/Utils.h" + +namespace OpenWifi { + + class SerialNumberCache * SerialNumberCache::instance_ = nullptr; + + int SerialNumberCache::Start() { + return 0; + } + + void SerialNumberCache::Stop() { + + } + + void SerialNumberCache::AddSerialNumber(const std::string &S) { + std::lock_guard G(M_); + + uint64_t SN = std::stoull(S,0,16); + if(std::find(SNs_.begin(),SNs_.end(),SN) == SNs_.end()) { + if(SNs_.size()+1 == SNs_.capacity()) + SNs_.resize(SNs_.capacity()+2000); + SNs_.push_back(SN); + std::sort(SNs_.begin(),SNs_.end()); + } + } + + void SerialNumberCache::DeleteSerialNumber(const std::string &S) { + std::lock_guard G(M_); + + uint64_t SN = std::stoull(S,0,16); + auto It = std::find(SNs_.begin(),SNs_.end(),SN); + if(It != SNs_.end()) { + SNs_.erase(It); + } + } + + void SerialNumberCache::FindNumbers(const std::string &S, uint HowMany, std::vector &A) { + std::lock_guard G(M_); + + if(S.length()==12) { + uint64_t SN = std::stoull(S,0,16); + auto It = std::find(SNs_.begin(),SNs_.end(),SN); + if(It != SNs_.end()) { + A.push_back(*It); + } + } else if (S.length()<12){ + std::string SS{S}; + SS.insert(SS.end(), 12 - SS.size(), '0'); + uint64_t SN = std::stoull(SS,0,16); + + auto LB = std::lower_bound(SNs_.begin(),SNs_.end(),SN); + if(LB!=SNs_.end()) { + for(;LB!=SNs_.end() && HowMany;++LB,--HowMany) { + std::string TSN = Utils::int_to_hex(*LB); + if(S == TSN.substr(0,S.size())) { + A.emplace_back(*LB); + } else { + break; + } + } + } + } + } +} \ No newline at end of file diff --git a/src/SerialNumberCache.h b/src/SerialNumberCache.h new file mode 100644 index 0000000..a57817f --- /dev/null +++ b/src/SerialNumberCache.h @@ -0,0 +1,44 @@ +// +// Created by stephane bourque on 2021-08-11. +// + +#ifndef UCENTRALGW_SERIALNUMBERCACHE_H +#define UCENTRALGW_SERIALNUMBERCACHE_H + +#include "framework/SubSystemServer.h" + +namespace OpenWifi { + class SerialNumberCache : public SubSystemServer { + public: + + static SerialNumberCache *instance() { + if (instance_ == nullptr) { + instance_ = new SerialNumberCache; + } + return instance_; + } + + int Start() override; + void Stop() override; + void AddSerialNumber(const std::string &S); + void DeleteSerialNumber(const std::string &S); + void FindNumbers(const std::string &S, uint HowMany, std::vector &A); + + private: + static SerialNumberCache * instance_; + uint64_t LastUpdate_ = 0 ; + std::vector SNs_; + std::mutex M_; + + SerialNumberCache() noexcept: + SubSystemServer("SerialNumberCache", "SNCACHE-SVR", "serialcache") + { + SNs_.reserve(2000); + } + }; + + inline SerialNumberCache * SerialNumberCache() { return SerialNumberCache::instance(); } + +} // namespace OpenWiFi + +#endif // UCENTRALGW_SERIALNUMBERCACHE_H diff --git a/src/StorageService.cpp b/src/StorageService.cpp index d31a7b7..0a793a9 100644 --- a/src/StorageService.cpp +++ b/src/StorageService.cpp @@ -82,6 +82,8 @@ namespace OpenWifi { ExpandFunc_[TagsObjectDB_->Prefix()] = [=](const char *F, std::string &V, std::string &Name, std::string & Description) ->bool { return TagsObjectDB_->Exists(F,V);; }; EntityDB_->CheckForRoot(); + InventoryDB_->InitializeSerialCache(); + Updater_.start(*this); return 0; diff --git a/src/storage/storage_inventory.cpp b/src/storage/storage_inventory.cpp index f0644dd..c5888f1 100644 --- a/src/storage/storage_inventory.cpp +++ b/src/storage/storage_inventory.cpp @@ -15,6 +15,7 @@ #include "StorageService.h" #include "SDK_stubs.h" #include "AutoDiscovery.h" +#include "SerialNumberCache.h" namespace OpenWifi { @@ -82,6 +83,7 @@ namespace OpenWifi { } if(CreateRecord(NewDevice)) { + SerialNumberCache()->AddSerialNumber(SerialNumber); std::string FullUUID; if(!NewDevice.entity.empty()) { Storage()->EntityDB().AddDevice("id",NewDevice.entity,NewDevice.info.id); @@ -218,6 +220,11 @@ namespace OpenWifi { return false; } + void InventoryDB::InitializeSerialCache() { + auto F = []( const ProvObjects::InventoryTag & T) ->bool { SerialNumberCache()->AddSerialNumber(T.serialNumber); return true;}; + Iterate(F); + } + } template<> void ORM::DB< OpenWifi::InventoryDBRecordType, OpenWifi::ProvObjects::InventoryTag>::Convert(OpenWifi::InventoryDBRecordType &In, OpenWifi::ProvObjects::InventoryTag &Out) { diff --git a/src/storage/storage_inventory.h b/src/storage/storage_inventory.h index 7f0e6b6..235ccbd 100644 --- a/src/storage/storage_inventory.h +++ b/src/storage/storage_inventory.h @@ -43,6 +43,7 @@ namespace OpenWifi { bool FindFirmwareOptions(std::string & SerialNumber, std::string &firmwareUpgrade, bool &firmwareRCOnly); static bool FindFirmwareOptionsForEntity(const std::string & EntityUUID, std::string &firmwareUpgrade, bool &firmwareRCOnly); static bool FindFirmwareOptionsForVenue(const std::string & VenueUUID, std::string &firmwareUpgrade, bool &firmwareRCOnly); + void InitializeSerialCache(); private: }; }