Fixing configuration change prediction engine.

This commit is contained in:
stephb9959
2021-10-31 11:37:47 -07:00
parent 5ef004932f
commit 2f2045c5c4
6 changed files with 71 additions and 32 deletions

2
build
View File

@@ -1 +1 @@
21 23

View File

@@ -194,7 +194,7 @@ namespace OpenWifi{
} }
if(DB_.CreateRecord(NewObject)) { if(DB_.CreateRecord(NewObject)) {
SerialNumberCache()->AddSerialNumber(SerialNumber); SerialNumberCache()->AddSerialNumber(SerialNumber,NewObject.deviceType);
if (!NewObject.venue.empty()) if (!NewObject.venue.empty())
StorageService()->VenueDB().AddDevice("id",NewObject.venue,NewObject.info.id); StorageService()->VenueDB().AddDevice("id",NewObject.venue,NewObject.info.id);
if (!NewObject.entity.empty()) if (!NewObject.entity.empty())

View File

@@ -20,15 +20,25 @@ namespace OpenWifi {
} }
void SerialNumberCache::AddSerialNumber(const std::string &S) { void SerialNumberCache::AddSerialNumber(const std::string &S, const std::string &DeviceType) {
std::lock_guard G(M_); std::lock_guard G(M_);
auto Hint = DeviceTypeDictionary_.find(DeviceType);
int Index;
if(Hint == end(DeviceTypeDictionary_)) {
Index = DeviceTypeIndex_;
DeviceTypeDictionary_[DeviceType] = DeviceTypeIndex_++;
} else {
Index = Hint->second;
}
uint64_t SN = std::stoull(S,0,16); uint64_t SN = std::stoull(S,0,16);
if(std::find(SNs_.begin(),SNs_.end(),SN) == SNs_.end()) { if(std::find_if(SNs_.begin(),SNs_.end(),[SN](DeviceTypeCacheEntry &E) { return E.SerialNumber == SN; }) == SNs_.end()) {
auto NE = DeviceTypeCacheEntry{ .SerialNumber = SN, .DeviceType = Index };
if(SNs_.size()+1 == SNs_.capacity()) if(SNs_.size()+1 == SNs_.capacity())
SNs_.resize(SNs_.capacity()+2000); SNs_.resize(SNs_.capacity()+2000);
SNs_.push_back(SN); SNs_.push_back(NE);
std::sort(SNs_.begin(),SNs_.end()); std::sort(SNs_.begin(),SNs_.end(), [](const DeviceTypeCacheEntry &E1, const DeviceTypeCacheEntry &E2) { return E1.SerialNumber < E2.SerialNumber ; });
} }
} }
@@ -36,7 +46,7 @@ namespace OpenWifi {
std::lock_guard G(M_); std::lock_guard G(M_);
uint64_t SN = std::stoull(S,0,16); uint64_t SN = std::stoull(S,0,16);
auto It = std::find(SNs_.begin(),SNs_.end(),SN); auto It = std::find_if(SNs_.begin(),SNs_.end(),[SN](const DeviceTypeCacheEntry &E) { return E.SerialNumber == SN; });
if(It != SNs_.end()) { if(It != SNs_.end()) {
SNs_.erase(It); SNs_.erase(It);
} }
@@ -47,21 +57,21 @@ namespace OpenWifi {
if(S.length()==12) { if(S.length()==12) {
uint64_t SN = std::stoull(S,0,16); uint64_t SN = std::stoull(S,0,16);
auto It = std::find(SNs_.begin(),SNs_.end(),SN); auto It = std::find_if(SNs_.begin(),SNs_.end(), [SN](const DeviceTypeCacheEntry &E) { return E.SerialNumber == SN; } );
if(It != SNs_.end()) { if(It != SNs_.end()) {
A.push_back(*It); A.push_back(It->SerialNumber);
} }
} else if (S.length()<12){ } else if (S.length()<12){
std::string SS{S}; std::string SS{S};
SS.insert(SS.end(), 12 - SS.size(), '0'); SS.insert(SS.end(), 12 - SS.size(), '0');
uint64_t SN = std::stoull(SS,0,16); uint64_t SN = std::stoull(SS,0,16);
auto LB = std::lower_bound(SNs_.begin(),SNs_.end(),SN); auto LB = std::lower_bound(SNs_.begin(),SNs_.end(),SN, [](const DeviceTypeCacheEntry &E1,uint64_t V) { return E1.SerialNumber < V ; });
if(LB!=SNs_.end()) { if(LB!=SNs_.end()) {
for(;LB!=SNs_.end() && HowMany;++LB,--HowMany) { for(;LB!=SNs_.end() && HowMany;++LB,--HowMany) {
std::string TSN = Utils::int_to_hex(*LB); std::string TSN = Utils::int_to_hex(LB->SerialNumber);
if(S == TSN.substr(0,S.size())) { if(S == TSN.substr(0,S.size())) {
A.emplace_back(*LB); A.emplace_back(LB->SerialNumber);
} else { } else {
break; break;
} }
@@ -69,4 +79,18 @@ namespace OpenWifi {
} }
} }
} }
bool SerialNumberCache::FindDevice(const std::string &SerialNumber, std::string & DeviceType) {
uint64_t SN = std::stoull(SerialNumber,0,16);
auto It = std::find_if(SNs_.begin(),SNs_.end(),[SN](const DeviceTypeCacheEntry &E) { return E.SerialNumber == SN; });
if(It != SNs_.end()) {
for(const auto &i:DeviceTypeDictionary_)
if(i.second==It->DeviceType) {
DeviceType = i.first;
return true;
}
}
return false;
}
} }

View File

@@ -11,6 +11,10 @@ namespace OpenWifi {
class SerialNumberCache : public SubSystemServer { class SerialNumberCache : public SubSystemServer {
public: public:
struct DeviceTypeCacheEntry {
uint64_t SerialNumber;
int DeviceType;
};
static SerialNumberCache *instance() { static SerialNumberCache *instance() {
if (instance_ == nullptr) { if (instance_ == nullptr) {
instance_ = new SerialNumberCache; instance_ = new SerialNumberCache;
@@ -20,14 +24,17 @@ namespace OpenWifi {
int Start() override; int Start() override;
void Stop() override; void Stop() override;
void AddSerialNumber(const std::string &S); void AddSerialNumber(const std::string &SerialNumber, const std::string &DeviceType);
void DeleteSerialNumber(const std::string &S); void DeleteSerialNumber(const std::string &S);
void FindNumbers(const std::string &S, uint HowMany, std::vector<uint64_t> &A); void FindNumbers(const std::string &S, uint HowMany, std::vector<uint64_t> &A);
bool FindDevice(const std::string &SerialNumber, std::string & DeviceType);
private: private:
static SerialNumberCache * instance_; static SerialNumberCache * instance_;
int DeviceTypeIndex_=0;
uint64_t LastUpdate_ = 0 ; uint64_t LastUpdate_ = 0 ;
std::vector<uint64_t> SNs_; std::vector<DeviceTypeCacheEntry> SNs_;
std::map<std::string,int> DeviceTypeDictionary_;
std::mutex M_; std::mutex M_;
SerialNumberCache() noexcept: SerialNumberCache() noexcept:

View File

@@ -44,36 +44,43 @@ namespace OpenWifi {
ConfigurationDB::ConfigurationDB( OpenWifi::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L) : ConfigurationDB::ConfigurationDB( OpenWifi::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L) :
DB(T, "configurations", ConfigurationDB_Fields, ConfigurationDB_Indexes, P, L, "cfg") {} DB(T, "configurations", ConfigurationDB_Fields, ConfigurationDB_Indexes, P, L, "cfg") {}
static bool AddDevicesFromVenue( const std::string & UUID, std::set<std::string> & Devices) { static bool AddIfAffected( const std::string & UUID,const std::vector<std::string> & DeviceTypes, std::set<std::string> & Devices ) {
ProvObjects::InventoryTag T;
if(!StorageService()->InventoryDB().GetRecord("id",UUID,T))
return false;
for(const auto &i:DeviceTypes) {
if(i=="*" || i==T.deviceType) {
Devices.insert(T.serialNumber);
return true;
}
}
return false;
}
static bool AddDevicesFromVenue( const std::string & UUID, const std::vector<std::string> & DeviceTypes, std::set<std::string> & Devices) {
ProvObjects::Venue V; ProvObjects::Venue V;
if(!StorageService()->VenueDB().GetRecord("id",UUID,V)) if(!StorageService()->VenueDB().GetRecord("id",UUID,V))
return false; return false;
for(const auto &j:V.devices) { for(const auto &j:V.devices) {
ProvObjects::InventoryTag T; AddIfAffected(j, DeviceTypes, Devices);
if(!StorageService()->InventoryDB().GetRecord("id",j,T))
continue;
Devices.insert(T.serialNumber);
} }
for(const auto &j:V.children) for(const auto &j:V.children)
AddDevicesFromVenue(j,Devices); AddDevicesFromVenue(j,DeviceTypes,Devices);
return true; return true;
} }
static bool AddDevicesFromEntity( const std::string & UUID, std::set<std::string> & Devices) { static bool AddDevicesFromEntity( const std::string & UUID, const std::vector<std::string> & DeviceTypes, std::set<std::string> & Devices) {
ProvObjects::Entity E; ProvObjects::Entity E;
if(!StorageService()->EntityDB().GetRecord("id",UUID,E)) if(!StorageService()->EntityDB().GetRecord("id",UUID,E))
return false; return false;
for(const auto &j:E.devices) { for(const auto &j:E.devices) {
ProvObjects::InventoryTag T; AddIfAffected(j, DeviceTypes, Devices);
if(!StorageService()->InventoryDB().GetRecord("id",j,T))
continue;
Devices.insert(T.serialNumber);
} }
for(const auto &j:E.children) for(const auto &j:E.children)
AddDevicesFromEntity(j, Devices); AddDevicesFromEntity(j,DeviceTypes, Devices);
for(const auto &j:E.venues) for(const auto &j:E.venues)
AddDevicesFromVenue(j, Devices); AddDevicesFromVenue(j,DeviceTypes, Devices);
return true; return true;
} }
@@ -89,14 +96,15 @@ namespace OpenWifi {
return true; return true;
std::set<std::string> SerialNumbers; std::set<std::string> SerialNumbers;
auto DeviceTypes = Config.deviceTypes;
for(const auto &i:Config.inUse) { for(const auto &i:Config.inUse) {
auto Tokens = Poco::StringTokenizer(i,":"); auto Tokens = Poco::StringTokenizer(i,":");
if(Tokens.count()!=2) if(Tokens.count()!=2)
continue; continue;
if(Tokens[0] == "ent") { if(Tokens[0] == "ent") {
AddDevicesFromEntity(Tokens[1], SerialNumbers); AddDevicesFromEntity(Tokens[1], DeviceTypes, SerialNumbers);
} else if (Tokens[0] == "ven") { } else if (Tokens[0] == "ven") {
AddDevicesFromVenue(Tokens[1], SerialNumbers); AddDevicesFromVenue(Tokens[1], DeviceTypes, SerialNumbers);
} else if (Tokens[0] == "inv") { } else if (Tokens[0] == "inv") {
ProvObjects::InventoryTag T; ProvObjects::InventoryTag T;
if(!StorageService()->InventoryDB().GetRecord("id",Tokens[1],T)) if(!StorageService()->InventoryDB().GetRecord("id",Tokens[1],T))

View File

@@ -83,7 +83,7 @@ namespace OpenWifi {
} }
if(CreateRecord(NewDevice)) { if(CreateRecord(NewDevice)) {
SerialNumberCache()->AddSerialNumber(SerialNumber); SerialNumberCache()->AddSerialNumber(SerialNumber, DeviceType);
std::string FullUUID; std::string FullUUID;
if(!NewDevice.entity.empty()) { if(!NewDevice.entity.empty()) {
StorageService()->EntityDB().AddDevice("id",NewDevice.entity,NewDevice.info.id); StorageService()->EntityDB().AddDevice("id",NewDevice.entity,NewDevice.info.id);
@@ -219,7 +219,7 @@ namespace OpenWifi {
} }
void InventoryDB::InitializeSerialCache() { void InventoryDB::InitializeSerialCache() {
auto F = []( const ProvObjects::InventoryTag & T) ->bool { SerialNumberCache()->AddSerialNumber(T.serialNumber); return true;}; auto F = []( const ProvObjects::InventoryTag & T) ->bool { SerialNumberCache()->AddSerialNumber(T.serialNumber, T.deviceType); return true;};
Iterate(F); Iterate(F);
} }