From 157f3ab2063c6e562c9ff1b7c1cdcbe2587daea2 Mon Sep 17 00:00:00 2001 From: stephb9959 Date: Fri, 11 Mar 2022 12:14:06 -0800 Subject: [PATCH] Initial commit --- CMakeLists.txt | 2 +- build | 2 +- src/RESTObjects/RESTAPI_AnalyticsObjects.cpp | 45 ++++++- src/RESTObjects/RESTAPI_AnalyticsObjects.h | 25 +++- src/RESTObjects/RESTAPI_ProvObjects.cpp | 36 +++-- src/RESTObjects/RESTAPI_ProvObjects.h | 11 ++ src/StorageService.cpp | 13 ++ src/StorageService.h | 6 + src/sdks/SDK_prov.cpp | 131 +++++++++++++++++++ src/sdks/SDK_prov.h | 32 +++++ src/storage/storage_boards.cpp | 68 ++++++++++ src/storage/storage_boards.h | 27 ++++ 12 files changed, 383 insertions(+), 15 deletions(-) create mode 100644 src/sdks/SDK_prov.cpp create mode 100644 src/sdks/SDK_prov.h create mode 100644 src/storage/storage_boards.cpp create mode 100644 src/storage/storage_boards.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 0193190..12cd9ba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -83,7 +83,7 @@ add_executable(owanalytics src/RESTAPI/RESTAPI_routers.cpp src/Daemon.cpp src/Daemon.h src/Dashboard.h src/Dashboard.cpp - src/StorageService.cpp src/StorageService.h src/RESTObjects/RESTAPI_AnalyticsObjects.cpp src/RESTObjects/RESTAPI_AnalyticsObjects.h src/StateReceiver.cpp src/StateReceiver.h src/VenueWatcher.cpp src/VenueWatcher.h src/VenueCoordinator.cpp src/VenueCoordinator.h) + src/StorageService.cpp src/StorageService.h src/RESTObjects/RESTAPI_AnalyticsObjects.cpp src/RESTObjects/RESTAPI_AnalyticsObjects.h src/StateReceiver.cpp src/StateReceiver.h src/VenueWatcher.cpp src/VenueWatcher.h src/VenueCoordinator.cpp src/VenueCoordinator.h src/sdks/SDK_prov.cpp src/sdks/SDK_prov.h src/storage/storage_boards.cpp src/storage/storage_boards.h) target_link_libraries(owanalytics PUBLIC ${Poco_LIBRARIES} ${MySQL_LIBRARIES} diff --git a/build b/build index 62f9457..301160a 100644 --- a/build +++ b/build @@ -1 +1 @@ -6 \ No newline at end of file +8 \ No newline at end of file diff --git a/src/RESTObjects/RESTAPI_AnalyticsObjects.cpp b/src/RESTObjects/RESTAPI_AnalyticsObjects.cpp index 1ca24a2..254467f 100644 --- a/src/RESTObjects/RESTAPI_AnalyticsObjects.cpp +++ b/src/RESTObjects/RESTAPI_AnalyticsObjects.cpp @@ -3,16 +3,57 @@ // #include "RESTAPI_AnalyticsObjects.h" +#include "RESTAPI_ProvObjects.h" +#include "framework/MicroService.h" +using OpenWifi::RESTAPI_utils::field_to_json; +using OpenWifi::RESTAPI_utils::field_from_json; namespace OpenWifi::AnalyticsObjects { void Report::reset() { - } void Report::to_json(Poco::JSON::Object &Obj) const { - } + void VenueInfo::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj,"id",id); + field_to_json(Obj,"name",name); + field_to_json(Obj,"description",description); + field_to_json(Obj,"retention",retention); + field_to_json(Obj,"interval",interval); + field_to_json(Obj,"monitorSubVenues",monitorSubVenues); + } + + bool VenueInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj,"id",id); + field_from_json(Obj,"name",name); + field_from_json(Obj,"description",description); + field_from_json(Obj,"retention",retention); + field_from_json(Obj,"interval",interval); + field_from_json(Obj,"monitorSubVenues",monitorSubVenues); + return true; + } catch(...) { + + } + return false; + } + + void BoardInfo::to_json(Poco::JSON::Object &Obj) const { + info.to_json(Obj); + field_to_json(Obj,"venueList",venueList); + } + + bool BoardInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + info.from_json(Obj); + field_from_json(Obj,"venueList",venueList); + return true; + } catch(...) { + + } + return false; + } } \ No newline at end of file diff --git a/src/RESTObjects/RESTAPI_AnalyticsObjects.h b/src/RESTObjects/RESTAPI_AnalyticsObjects.h index 609e583..3a8a35e 100644 --- a/src/RESTObjects/RESTAPI_AnalyticsObjects.h +++ b/src/RESTObjects/RESTAPI_AnalyticsObjects.h @@ -3,7 +3,8 @@ // #pragma once -#include "framework/MicroService.h" + +#include "RESTAPI_ProvObjects.h" namespace OpenWifi { @@ -12,10 +13,30 @@ namespace OpenWifi { struct Report { uint64_t snapShot=0; - void reset(); + void reset(); void to_json(Poco::JSON::Object &Obj) const; }; + struct VenueInfo { + OpenWifi::Types::UUID_t id; + std::string name; + std::string description; + uint64_t retention=0; + uint64_t interval=0; + bool monitorSubVenues=false; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct BoardInfo { + ProvObjects::ObjectInfo info; + std::vector venueList; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + } } \ No newline at end of file diff --git a/src/RESTObjects/RESTAPI_ProvObjects.cpp b/src/RESTObjects/RESTAPI_ProvObjects.cpp index 66df8eb..68a8172 100644 --- a/src/RESTObjects/RESTAPI_ProvObjects.cpp +++ b/src/RESTObjects/RESTAPI_ProvObjects.cpp @@ -328,13 +328,13 @@ namespace OpenWifi::ProvObjects { field_to_json( Obj, "geoCode", geoCode); field_to_json( Obj, "location", location); field_to_json( Obj, "contact", contact); - field_to_json( Obj,"deviceConfiguration",deviceConfiguration); - field_to_json( Obj,"rrm",rrm); - field_to_json( Obj,"managementPolicy",managementPolicy); - field_to_json( Obj,"state",state); - field_to_json( Obj,"devClass",devClass); - field_to_json( Obj,"locale",locale); - field_to_json( Obj,"realMacAddress",realMacAddress); + field_to_json( Obj, "deviceConfiguration",deviceConfiguration); + field_to_json( Obj, "rrm",rrm); + field_to_json( Obj, "managementPolicy",managementPolicy); + field_to_json( Obj, "state",state); + field_to_json( Obj, "devClass",devClass); + field_to_json( Obj, "locale",locale); + field_to_json( Obj, "realMacAddress",realMacAddress); } bool InventoryTag::from_json(const Poco::JSON::Object::Ptr &Obj) { @@ -345,7 +345,7 @@ namespace OpenWifi::ProvObjects { field_from_json( Obj,"entity",entity); field_from_json( Obj,"subscriber",subscriber); field_from_json( Obj,"deviceType",deviceType); - field_from_json( Obj, "qrCode", qrCode); + field_from_json( Obj,"qrCode", qrCode); field_from_json( Obj,"geoCode",geoCode); field_from_json( Obj,"location",location); field_from_json( Obj,"contact",contact); @@ -356,7 +356,6 @@ namespace OpenWifi::ProvObjects { field_from_json( Obj,"devClass",devClass); field_from_json( Obj,"locale",locale); field_from_json( Obj,"realMacAddress",realMacAddress); - return true; } catch(...) { @@ -771,6 +770,25 @@ namespace OpenWifi::ProvObjects { return false; } + void VenueDeviceList::to_json(Poco::JSON::Object &Obj) const { + RESTAPI_utils::field_to_json(Obj,"id",id); + RESTAPI_utils::field_to_json(Obj,"name",name); + RESTAPI_utils::field_to_json(Obj,"description",description); + RESTAPI_utils::field_to_json(Obj,"devices",devices); + } + + bool VenueDeviceList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + RESTAPI_utils::field_from_json(Obj,"id",id); + RESTAPI_utils::field_from_json(Obj,"name",name); + RESTAPI_utils::field_from_json(Obj,"description",description); + RESTAPI_utils::field_from_json(Obj,"devices",devices); + return true; + } catch(...) { + + } + return false; + } bool UpdateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I) { uint64_t Now = std::time(nullptr); diff --git a/src/RESTObjects/RESTAPI_ProvObjects.h b/src/RESTObjects/RESTAPI_ProvObjects.h index 5839221..0642484 100644 --- a/src/RESTObjects/RESTAPI_ProvObjects.h +++ b/src/RESTObjects/RESTAPI_ProvObjects.h @@ -480,6 +480,17 @@ namespace OpenWifi::ProvObjects { bool from_json(const Poco::JSON::Object::Ptr &Obj); }; + struct VenueDeviceList { + std::string id; + std::string name; + std::string description; + Types::UUIDvec_t devices; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + bool UpdateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I); bool CreateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I); bool CreateObjectInfo(const SecurityObjects::UserInfo &U, ObjectInfo &I); diff --git a/src/StorageService.cpp b/src/StorageService.cpp index 3b7b0f7..4f900d5 100644 --- a/src/StorageService.cpp +++ b/src/StorageService.cpp @@ -15,10 +15,23 @@ namespace OpenWifi { std::lock_guard Guard(Mutex_); StorageClass::Start(); + + BoardsDB_ = std::make_unique(dbType_,*Pool_, Logger()); + BoardsDB_->Create(); + Updater_.start(*this); + + TimerCallback_ = std::make_unique>(*this,&Storage::onTimer); + Timer_.setStartInterval( 20 * 1000); // first run in 20 seconds + Timer_.setPeriodicInterval(1 * 60 * 60 * 1000); // 1 hours + Timer_.start(*TimerCallback_); + return 0; } + void Storage::onTimer(Poco::Timer &timer) { + } + void Storage::run() { Running_ = true ; bool FirstRun=true; diff --git a/src/StorageService.h b/src/StorageService.h index a20fe9d..048b3bd 100644 --- a/src/StorageService.h +++ b/src/StorageService.h @@ -10,6 +10,7 @@ #include "framework/MicroService.h" #include "framework/StorageClass.h" +#include "storage/storage_boards.h" namespace OpenWifi { class Storage : public StorageClass, Poco::Runnable { @@ -23,10 +24,15 @@ namespace OpenWifi { void Stop() override; void run() final; + OpenWifi::BoardsDB & BoardsDB() { return *BoardsDB_; }; + void onTimer(Poco::Timer & timer); private: + std::unique_ptr BoardsDB_; Poco::Thread Updater_; std::atomic_bool Running_=false; + Poco::Timer Timer_; + std::unique_ptr> TimerCallback_; }; inline auto StorageService() { return Storage::instance(); } } // namespace diff --git a/src/sdks/SDK_prov.cpp b/src/sdks/SDK_prov.cpp new file mode 100644 index 0000000..1766552 --- /dev/null +++ b/src/sdks/SDK_prov.cpp @@ -0,0 +1,131 @@ +// +// Created by stephane bourque on 2022-01-11. +// + +#include "SDK_prov.h" +#include "framework/OpenWifiTypes.h" + +namespace OpenWifi::SDK::Prov { + + namespace Venue { + bool GetDevices(RESTAPIHandler *client, const std::string &VenueId, bool WithChildren, ProvObjects::VenueDeviceList & DeviceList) { + std::string EndPoint = "/api/v1/venue/" + VenueId ; + + auto Query = WithChildren ? OpenWifi::Types::StringPairVec{{"getDevices","true"},{"getChildren","true"}} : + OpenWifi::Types::StringPairVec{{"getDevices","true"}}; + + auto API = OpenAPIRequestGet(uSERVICE_PROVISIONING, EndPoint, Query , 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 DeviceList.from_json(CallResponse); + } catch (...) { + return false; + } + } + return false; + } + } + + namespace Device { + bool Get(RESTAPIHandler *client, const std::string &Mac, ProvObjects::InventoryTag & Device) { + std::string EndPoint = "/api/v1/inventory/" + Mac ; + + auto API = OpenAPIRequestGet(uSERVICE_PROVISIONING, EndPoint, {}, 60000); + auto CallResponse = Poco::makeShared(); + + auto ResponseStatus = API.Do(CallResponse, client->UserInfo_.webtoken.access_token_); + if(ResponseStatus == Poco::Net::HTTPServerResponse::HTTP_OK) { + try { + return Device.from_json(CallResponse); + } catch (...) { + return false; + } + } + return false; + } + } + + namespace Configuration { + bool Get( RESTAPIHandler *client, const std::string &ConfigUUID, ProvObjects::DeviceConfiguration & Config) { + std::string EndPoint = "/api/v1/configurations/" + ConfigUUID ; + auto API = OpenAPIRequestGet(uSERVICE_PROVISIONING, EndPoint, {}, 60000); + auto CallResponse = Poco::makeShared(); + auto ResponseStatus = API.Do(CallResponse, client->UserInfo_.webtoken.access_token_); + if(ResponseStatus == Poco::Net::HTTPServerResponse::HTTP_OK) { + try { + return Config.from_json(CallResponse); + } catch (...) { + return false; + } + } + return false; + } + + bool Delete( RESTAPIHandler *client, const std::string &ConfigUUID) { + std::string EndPoint = "/api/v1/configurations/" + ConfigUUID ; + auto API = OpenAPIRequestDelete(uSERVICE_PROVISIONING, EndPoint, {}, 60000); + auto CallResponse = Poco::makeShared(); + auto ResponseStatus = API.Do(client->UserInfo_.webtoken.access_token_); + if(ResponseStatus == Poco::Net::HTTPServerResponse::HTTP_OK) { + return true; + } + return false; + } + + bool Create( RESTAPIHandler *client, const std::string & Mac, const ProvObjects::DeviceConfiguration & Config , std::string & ConfigUUID) { + std::string EndPoint = "/api/v1/configurations/0" ; + Poco::JSON::Object Body; + Config.to_json(Body); + auto API = OpenAPIRequestPost(uSERVICE_PROVISIONING, EndPoint, {}, Body, 10000); + auto CallResponse = Poco::makeShared(); + auto ResponseStatus = API.Do(CallResponse, client->UserInfo_.webtoken.access_token_); + if(ResponseStatus != Poco::Net::HTTPResponse::HTTP_OK) { + return false; + } + + ProvObjects::DeviceConfiguration NewConfig; + NewConfig.from_json(CallResponse); + ConfigUUID = NewConfig.info.id; + + Body.clear(); + Body.set("serialNumber", Mac); + Body.set("deviceConfiguration", NewConfig.info.id); + EndPoint = "/api/v1/inventory/" + Mac ; + auto API2 = OpenAPIRequestPut(uSERVICE_PROVISIONING, EndPoint, {}, Body, 10000); + CallResponse->clear(); + ResponseStatus = API2.Do(CallResponse, client->UserInfo_.webtoken.access_token_); + if(ResponseStatus != Poco::Net::HTTPResponse::HTTP_OK) { + return false; + } + return true; + } + + bool Update( RESTAPIHandler *client, const std::string &ConfigUUID, ProvObjects::DeviceConfiguration & Config) { + + return false; + } + } + + namespace Subscriber { + bool GetDevices(RESTAPIHandler *client, const std::string &SubscriberId, ProvObjects::InventoryTagList & Devices) { + std::string EndPoint = "/api/v1/inventory"; + + auto API = OpenAPIRequestGet(uSERVICE_PROVISIONING, EndPoint, { {"subscriber",SubscriberId} }, 60000); + auto CallResponse = Poco::makeShared(); + + auto ResponseStatus = API.Do(CallResponse, client->UserInfo_.webtoken.access_token_); + if(ResponseStatus == Poco::Net::HTTPServerResponse::HTTP_OK) { + try { + return Devices.from_json(CallResponse); + } catch (...) { + return false; + } + } + return false; + } + } + +} \ No newline at end of file diff --git a/src/sdks/SDK_prov.h b/src/sdks/SDK_prov.h new file mode 100644 index 0000000..078a15e --- /dev/null +++ b/src/sdks/SDK_prov.h @@ -0,0 +1,32 @@ +// +// Created by stephane bourque on 2022-03-11. +// + +#pragma once + +#include "framework/MicroService.h" +#include "RESTObjects/RESTAPI_ProvObjects.h" + +namespace OpenWifi::SDK::Prov { + + namespace Venue { + bool GetDevices(RESTAPIHandler *client, const std::string &VenueId, bool WithChildren, ProvObjects::VenueDeviceList & Device); + } + + namespace Device { + bool Get(RESTAPIHandler *client, const std::string &Mac, ProvObjects::InventoryTagList & Device); + bool SetConfiguration(RESTAPIHandler *client, const std::string &Mac, const std::string &ConfigUUID); + } + + namespace Configuration { + bool Get( RESTAPIHandler *client, const std::string &ConfigUUID, ProvObjects::DeviceConfiguration & Config); + bool Delete( RESTAPIHandler *client, const std::string &ConfigUUID); + bool Create( RESTAPIHandler *client, const std::string & SerialNumber, const ProvObjects::DeviceConfiguration & Config , std::string & ConfigUUID); + bool Update( RESTAPIHandler *client, const std::string &ConfigUUID, ProvObjects::DeviceConfiguration & Config); + } + + namespace Subscriber { + bool GetDevices(RESTAPIHandler *client, const std::string &SubscriberId, std::vector & Devices); + } + +} \ No newline at end of file diff --git a/src/storage/storage_boards.cpp b/src/storage/storage_boards.cpp new file mode 100644 index 0000000..5173ce6 --- /dev/null +++ b/src/storage/storage_boards.cpp @@ -0,0 +1,68 @@ +// +// License type: BSD 3-Clause License +// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE +// +// Created by Stephane Bourque on 2021-03-04. +// Arilia Wireless Inc. +// + +#include "framework/MicroService.h" +#include "storage_boards.h" +#include "framework/OpenWifiTypes.h" + +namespace OpenWifi { + + static ORM::FieldVec Boards_Fields{ + // object info + ORM::Field{"id",64, true}, + ORM::Field{"name",ORM::FieldType::FT_TEXT}, + ORM::Field{"description",ORM::FieldType::FT_TEXT}, + ORM::Field{"notes",ORM::FieldType::FT_TEXT}, + ORM::Field{"created",ORM::FieldType::FT_BIGINT}, + ORM::Field{"modified",ORM::FieldType::FT_BIGINT}, + ORM::Field{"venueList",ORM::FieldType::FT_TEXT} + }; + + static ORM::IndexVec BoardsDB_Indexes{ + { std::string("boards_name_index"), + ORM::IndexEntryVec{ + {std::string("name"), + ORM::Indextype::ASC} } } + }; + + BoardsDB::BoardsDB( OpenWifi::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L) : + DB(T, "boards", Boards_Fields, BoardsDB_Indexes, P, L, "bor") {} + + bool BoardsDB::Upgrade(uint32_t from, uint32_t &to) { + std::vector Statements{ + }; + RunScript(Statements); + to = 2; + return true; + } +} + +template<> void ORM::DB::Convert(const OpenWifi::BoardDBRecordType &In, OpenWifi::AnalyticsObjects::BoardInfo &Out) { + Out.info.id = In.get<0>(); + Out.info.name = In.get<1>(); + Out.info.description = In.get<2>(); + Out.info.notes = OpenWifi::RESTAPI_utils::to_object_array(In.get<3>()); + Out.info.created = In.get<4>(); + Out.info.modified = In.get<5>(); + Out.venueList = OpenWifi::RESTAPI_utils::to_object_array(In.get<6>()); +} + +template<> void ORM::DB< OpenWifi::BoardDBRecordType, OpenWifi::AnalyticsObjects::BoardInfo>::Convert(const OpenWifi::AnalyticsObjects::BoardInfo &In, OpenWifi::BoardDBRecordType &Out) { + Out.set<0>(In.info.id); + Out.set<1>(In.info.name); + Out.set<2>(In.info.description); + Out.set<3>(OpenWifi::RESTAPI_utils::to_string(In.info.notes)); + Out.set<4>(In.info.created); + Out.set<5>(In.info.modified); + Out.set<6>(OpenWifi::RESTAPI_utils::to_string(In.venueList)); +} +// +// Created by stephane bourque on 2022-03-11. +// + +#include "storage_boards.h" diff --git a/src/storage/storage_boards.h b/src/storage/storage_boards.h new file mode 100644 index 0000000..1bc3ef5 --- /dev/null +++ b/src/storage/storage_boards.h @@ -0,0 +1,27 @@ +// +// Created by stephane bourque on 2022-03-11. +// + +#pragma once + +#include "framework/orm.h" +#include "RESTObjects/RESTAPI_AnalyticsObjects.h" + +namespace OpenWifi { + typedef Poco::Tuple< + std::string, + std::string, + std::string, + std::string, + uint64_t, + uint64_t, + std::string + > BoardDBRecordType; + + class BoardsDB : public ORM::DB { + public: + BoardsDB( OpenWifi::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L); + private: + bool Upgrade(uint32_t from, uint32_t &to) override; + }; +}