From 0f8d1d67238c68b371ae7e9231c8db8450a3f682 Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Sun, 8 May 2022 08:09:25 -0700 Subject: [PATCH] Fix bug of removed Venue and dangling board. --- build | 2 +- src/VenueCoordinator.cpp | 82 ++++++++++++++++++++++++++++++---------- src/VenueCoordinator.h | 4 ++ src/sdks/SDK_prov.cpp | 42 +++++++++++++++++++- src/sdks/SDK_prov.h | 4 +- 5 files changed, 110 insertions(+), 24 deletions(-) diff --git a/build b/build index f0b5c72..4800c7d 100644 --- a/build +++ b/build @@ -1 +1 @@ -57 \ No newline at end of file +58 \ No newline at end of file diff --git a/src/VenueCoordinator.cpp b/src/VenueCoordinator.cpp index 4fec3ec..7886552 100644 --- a/src/VenueCoordinator.cpp +++ b/src/VenueCoordinator.cpp @@ -11,15 +11,19 @@ namespace OpenWifi { int VenueCoordinator::Start() { + GetBoardList(); + Worker_.start(*this); + return 0; + } + void VenueCoordinator::GetBoardList() { + BoardsToWatch_.clear(); auto F = [&](const AnalyticsObjects::BoardInfo &B) ->bool { BoardsToWatch_.insert(B); Logger().information(fmt::format("Starting watch for {}.", B.info.name)); return true; }; StorageService()->BoardsDB().Iterate(F); - Worker_.start(*this); - return 0; } void VenueCoordinator::Stop() { @@ -37,32 +41,45 @@ namespace OpenWifi { break; std::lock_guard G(Mutex_); + + GetBoardList(); + if(!BoardsToWatch_.empty()) { - for(auto board_to_start=BoardsToWatch_.begin(); board_to_start!=BoardsToWatch_.end(); ) { - if(StartBoard(*board_to_start)) { - board_to_start = BoardsToWatch_.erase(board_to_start); - } else { - ++board_to_start; + for(const auto &board_to_start:BoardsToWatch_) { + bool VenueExists = true; + if(!Watching(board_to_start.info.id)) { + StartBoard(board_to_start); + } else if(SDK::Prov::Venue::Exists(nullptr,board_to_start.info.id,VenueExists) && !VenueExists) { + RetireBoard(board_to_start); } } } - } } - bool GetDevicesForBoard(const AnalyticsObjects::BoardInfo &B, std::vector & Devices) { + void VenueCoordinator::RetireBoard(const AnalyticsObjects::BoardInfo &B) { + StopBoard(B.info.id); + StorageService()->BoardsDB().DeleteRecord("id",B.info.id); + } + + bool VenueCoordinator::GetDevicesForBoard(const AnalyticsObjects::BoardInfo &B, std::vector & Devices, bool & VenueExists) { ProvObjects::VenueDeviceList VDL; - if(SDK::Prov::Venue::GetDevices(nullptr,B.venueList[0].id,B.venueList[0].monitorSubVenues, VDL)) { + if(SDK::Prov::Venue::GetDevices(nullptr,B.venueList[0].id,B.venueList[0].monitorSubVenues, VDL, VenueExists)) { Devices.clear(); - for(const auto &device:VDL.devices) { + for (const auto &device: VDL.devices) { Devices.push_back(Utils::SerialNumberToInt(device)); } - - std::sort(Devices.begin(),Devices.end()); - auto LastDevice = std::unique(Devices.begin(),Devices.end()); - Devices.erase(LastDevice,Devices.end()); + std::sort(Devices.begin(), Devices.end()); + auto LastDevice = std::unique(Devices.begin(), Devices.end()); + Devices.erase(LastDevice, Devices.end()); return true; } + + if(!VenueExists) { + Logger().error(fmt::format("Venue {} is no longer in the system. Removing its associated board.", B.venueList[0].id)); + RetireBoard(B); + } + return false; } @@ -70,14 +87,24 @@ namespace OpenWifi { if(B.venueList.empty()) return true; + bool VenueExists=true; std::vector Devices; - if(GetDevicesForBoard(B,Devices)) { + if(GetDevicesForBoard(B,Devices,VenueExists)) { + std::lock_guard G(Mutex_); ExistingBoards_[B.info.id] = Devices; - Watchers_[B.info.id] = std::make_shared(B.info.id,Logger(),Devices); + Watchers_[B.info.id] = std::make_shared(B.info.id, Logger(), Devices); Watchers_[B.info.id]->Start(); - Logger().information(fmt::format("Started board {}",B.info.name)); + Logger().information(fmt::format("Started board {}", B.info.name)); return true; } + + if(!VenueExists) { + Logger().error(fmt::format("Venue {} is no longer in the system. Removing its associated board.", B.venueList[0].id)); + StopBoard(B.info.id); + StorageService()->BoardsDB().DeleteRecord("id",B.info.id); + return false; + } + Logger().information(fmt::format("Could not start board {}",B.info.name)); return false; } @@ -96,8 +123,9 @@ namespace OpenWifi { AnalyticsObjects::BoardInfo B; if(StorageService()->BoardsDB().GetRecord("id",id,B)) { std::vector Devices; - if(GetDevicesForBoard(B,Devices)) { - + bool VenueExists=true; + if(GetDevicesForBoard(B,Devices,VenueExists)) { + std::lock_guard G(Mutex_); auto it = ExistingBoards_.find(id); if(it!=ExistingBoards_.end()) { if(it->second!=Devices) { @@ -113,10 +141,22 @@ namespace OpenWifi { Logger().information(fmt::format("Modified board {}",B.info.name)); return; } - Logger().information(fmt::format("Could not start board {}",B.info.name)); + + if(!VenueExists) { + Logger().error(fmt::format("Venue {} is no longer in the system. Removing its associated board.", B.venueList[0].id)); + RetireBoard(B); + return; + } + + Logger().information(fmt::format("Could not modify board {}",B.info.name)); } } + bool VenueCoordinator::Watching(const std::string &id) { + std::lock_guard G(Mutex_); + return (ExistingBoards_.find(id) != ExistingBoards_.end()); + } + void VenueCoordinator::AddBoard(const std::string &id) { std::lock_guard G(Mutex_); diff --git a/src/VenueCoordinator.h b/src/VenueCoordinator.h index a961a5d..19fa17a 100644 --- a/src/VenueCoordinator.h +++ b/src/VenueCoordinator.h @@ -24,7 +24,11 @@ namespace OpenWifi { void ModifyBoard(const std::string &id); void AddBoard(const std::string &id); + bool GetDevicesForBoard(const AnalyticsObjects::BoardInfo &B, std::vector & Devices, bool & VenueExists); void GetDevices(std::string &id, AnalyticsObjects::DeviceInfoList & DIL); + void GetBoardList(); + bool Watching(const std::string &id); + void RetireBoard(const AnalyticsObjects::BoardInfo &B); private: Poco::Thread Worker_; diff --git a/src/sdks/SDK_prov.cpp b/src/sdks/SDK_prov.cpp index 608ca89..288e7f8 100644 --- a/src/sdks/SDK_prov.cpp +++ b/src/sdks/SDK_prov.cpp @@ -8,9 +8,10 @@ namespace OpenWifi::SDK::Prov { namespace Venue { - bool GetDevices(RESTAPIHandler *client, const std::string &VenueId, bool WithChildren, ProvObjects::VenueDeviceList & DeviceList) { + bool GetDevices(RESTAPIHandler *client, const std::string &VenueId, bool WithChildren, ProvObjects::VenueDeviceList & DeviceList, bool & VenueExists ) { std::string EndPoint = "/api/v1/venue/" + VenueId ; + VenueExists = true; auto Query = WithChildren ? OpenWifi::Types::StringPairVec{{"getDevices","true"},{"getChildren","true"}} : OpenWifi::Types::StringPairVec{{"getDevices","true"}}; @@ -24,6 +25,45 @@ namespace OpenWifi::SDK::Prov { } catch (...) { return false; } + } else if (ResponseStatus == Poco::Net::HTTPResponse::HTTP_NOT_FOUND) { + VenueExists = false; + } + return false; + } + + bool Get(RESTAPIHandler *client, const std::string &VenueId, ProvObjects::Venue & Venue, bool & Exists) { + std::string EndPoint = "/api/v1/venue/" + VenueId ; + + Exists = true; + auto API = OpenAPIRequestGet(uSERVICE_PROVISIONING, EndPoint, {} , 60000); + auto CallResponse = Poco::makeShared(); + + auto ResponseStatus = API.Do(CallResponse, client==nullptr ? "" : client->UserInfo_.webtoken.access_token_); + if(ResponseStatus == Poco::Net::HTTPServerResponse::HTTP_OK) { + try { + return Venue.from_json(CallResponse); + } catch (...) { + return false; + } + } else if (ResponseStatus == Poco::Net::HTTPResponse::HTTP_NOT_FOUND) { + Exists = false; + } + return false; + } + + bool Exists(RESTAPIHandler *client, const std::string &VenueId, bool & Exists) { + std::string EndPoint = "/api/v1/venue/" + VenueId ; + + Exists = true; + auto API = OpenAPIRequestGet(uSERVICE_PROVISIONING, EndPoint, {} , 60000); + auto CallResponse = Poco::makeShared(); + + auto ResponseStatus = API.Do(CallResponse, client==nullptr ? "" : client->UserInfo_.webtoken.access_token_); + if(ResponseStatus == Poco::Net::HTTPServerResponse::HTTP_OK) { + return true; + } else if (ResponseStatus == Poco::Net::HTTPResponse::HTTP_NOT_FOUND) { + Exists = false; + return true; } return false; } diff --git a/src/sdks/SDK_prov.h b/src/sdks/SDK_prov.h index ea6091e..8a88ff7 100644 --- a/src/sdks/SDK_prov.h +++ b/src/sdks/SDK_prov.h @@ -10,7 +10,9 @@ namespace OpenWifi::SDK::Prov { namespace Venue { - bool GetDevices(RESTAPIHandler *client, const std::string &VenueId, bool WithChildren, ProvObjects::VenueDeviceList & Devices); + bool GetDevices(RESTAPIHandler *client, const std::string &VenueId, bool WithChildren, ProvObjects::VenueDeviceList & Devices, bool & VenueExists ); + bool Get(RESTAPIHandler *client, const std::string &VenueId, ProvObjects::Venue & Venue, bool & Exists); + bool Exists(RESTAPIHandler *client, const std::string &VenueId, bool & Exists); } namespace Device {