mirror of
https://github.com/Telecominfraproject/wlan-cloud-analytics.git
synced 2026-03-20 03:39:59 +00:00
Compare commits
26 Commits
WIFI-10345
...
WIFI-10547
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
67910c982a | ||
|
|
9be196ce40 | ||
|
|
222afe2858 | ||
|
|
40a02c4752 | ||
|
|
7f1577503f | ||
|
|
7ab2e6c96e | ||
|
|
639db8631e | ||
|
|
9fe9b74dea | ||
|
|
20c025f994 | ||
|
|
ee78155b68 | ||
|
|
9f9a866ad3 | ||
|
|
adbd852ccd | ||
|
|
4bb5ee0b86 | ||
|
|
06bb8cebbe | ||
|
|
dde46ce6b2 | ||
|
|
515f8a4fea | ||
|
|
8dcfe04310 | ||
|
|
5db6fc3027 | ||
|
|
6ee3cae1db | ||
|
|
33e4f8abd8 | ||
|
|
d5b4d15307 | ||
|
|
8dc3e53fc0 | ||
|
|
55b0075c0c | ||
|
|
fa434f79c3 | ||
|
|
61837a8975 | ||
|
|
10ffba95b5 |
24
Dockerfile
24
Dockerfile
@@ -9,8 +9,8 @@ RUN apk add --update --no-cache \
|
||||
|
||||
FROM build-base AS poco-build
|
||||
|
||||
ADD https://api.github.com/repos/stephb9959/poco/git/refs/heads/master version.json
|
||||
RUN git clone https://github.com/stephb9959/poco /poco
|
||||
ADD https://api.github.com/repos/AriliaWireless/poco/git/refs/tags/poco-tip-v1 version.json
|
||||
RUN git clone https://github.com/AriliaWireless/poco --branch poco-tip-v1 /poco
|
||||
|
||||
WORKDIR /poco
|
||||
RUN mkdir cmake-build
|
||||
@@ -21,8 +21,8 @@ RUN cmake --build . --target install
|
||||
|
||||
FROM build-base AS cppkafka-build
|
||||
|
||||
ADD https://api.github.com/repos/stephb9959/cppkafka/git/refs/heads/master version.json
|
||||
RUN git clone https://github.com/stephb9959/cppkafka /cppkafka
|
||||
ADD https://api.github.com/repos/AriliaWireless/cppkafka/git/refs/tags/tip-v1 version.json
|
||||
RUN git clone https://github.com/AriliaWireless/cppkafka --branch tip-v1 /cppkafka
|
||||
|
||||
WORKDIR /cppkafka
|
||||
RUN mkdir cmake-build
|
||||
@@ -31,24 +31,24 @@ RUN cmake ..
|
||||
RUN cmake --build . --config Release -j8
|
||||
RUN cmake --build . --target install
|
||||
|
||||
FROM build-base AS json-schema-validator-build
|
||||
FROM build-base AS fmtlib-build
|
||||
|
||||
ADD https://api.github.com/repos/pboettch/json-schema-validator/git/refs/heads/master version.json
|
||||
RUN git clone https://github.com/pboettch/json-schema-validator /json-schema-validator
|
||||
ADD https://api.github.com/repos/fmtlib/fmt/git/refs/tags/9.0.0 version.json
|
||||
RUN git clone https://github.com/fmtlib/fmt --branch 9.0.0 /fmtlib
|
||||
|
||||
WORKDIR /json-schema-validator
|
||||
WORKDIR /fmtlib
|
||||
RUN mkdir cmake-build
|
||||
WORKDIR cmake-build
|
||||
RUN cmake ..
|
||||
RUN make
|
||||
RUN make install
|
||||
|
||||
FROM build-base AS fmtlib-build
|
||||
FROM build-base AS json-schema-validator-build
|
||||
|
||||
ADD https://api.github.com/repos/fmtlib/fmt/git/refs/heads/master version.json
|
||||
RUN git clone https://github.com/fmtlib/fmt /fmtlib
|
||||
ADD https://api.github.com/repos/pboettch/json-schema-validator/git/refs/tags/2.1.0 version.json
|
||||
RUN git clone https://github.com/pboettch/json-schema-validator --branch 2.1.0 /json-schema-validator
|
||||
|
||||
WORKDIR /fmtlib
|
||||
WORKDIR /json-schema-validator
|
||||
RUN mkdir cmake-build
|
||||
WORKDIR cmake-build
|
||||
RUN cmake ..
|
||||
|
||||
@@ -1076,42 +1076,6 @@ paths:
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
|
||||
/iptocountry:
|
||||
get:
|
||||
tags:
|
||||
- Utility
|
||||
summary: Get the country code for an IP address
|
||||
operationId: getIpToCountry
|
||||
parameters:
|
||||
- in: query
|
||||
name: iplist
|
||||
schema:
|
||||
type: string
|
||||
example:
|
||||
10.2.2.2,10.3.4.3
|
||||
required: true
|
||||
responses:
|
||||
200:
|
||||
description: List of country codes.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
enabled:
|
||||
type: boolean
|
||||
countryCodes:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
400:
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/wifiClientHistory:
|
||||
get:
|
||||
tags:
|
||||
|
||||
@@ -90,7 +90,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
if(StorageService()->BoardsDB().UpdateRecord("id",Existing.info.id,Existing)) {
|
||||
VenueCoordinator()->ModifyBoard(Existing.info.id);
|
||||
VenueCoordinator()->UpdateBoard(Existing.info.id);
|
||||
AnalyticsObjects::BoardInfo NewBoard;
|
||||
StorageService()->BoardsDB().GetRecord("id",Existing.info.id,NewBoard);
|
||||
Poco::JSON::Object Answer;
|
||||
|
||||
@@ -5,54 +5,11 @@
|
||||
#include "RESTAPI_board_timepoint_handler.h"
|
||||
#include "StorageService.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace OpenWifi {
|
||||
static auto find_number_of_buckets(std::vector<AnalyticsObjects::DeviceTimePoint> &p) {
|
||||
uint32_t buckets=0,cur_buckets=0;
|
||||
std::string current_serialNumber;
|
||||
for(const auto &i:p) {
|
||||
if(current_serialNumber.empty()) {
|
||||
current_serialNumber = i.device_info.serialNumber;
|
||||
cur_buckets=0;
|
||||
}
|
||||
if(current_serialNumber==i.device_info.serialNumber) {
|
||||
cur_buckets++;
|
||||
} else {
|
||||
buckets = std::max(buckets,cur_buckets);
|
||||
current_serialNumber=i.device_info.serialNumber;
|
||||
cur_buckets=1;
|
||||
}
|
||||
}
|
||||
return std::max(buckets,cur_buckets);
|
||||
}
|
||||
|
||||
typedef std::vector< std::vector<AnalyticsObjects::DeviceTimePoint>> split_points;
|
||||
|
||||
static void split_in_buckets([[maybe_unused]] uint32_t buckets,std::vector<AnalyticsObjects::DeviceTimePoint> &p,split_points &sp) {
|
||||
std::string cur_sn;
|
||||
uint32_t cur_bucket=0;
|
||||
for(const auto &i:p) {
|
||||
if(cur_sn.empty()) {
|
||||
cur_bucket=1;
|
||||
cur_sn=i.device_info.serialNumber;
|
||||
}
|
||||
if(cur_sn==i.device_info.serialNumber) {
|
||||
if (cur_bucket>sp.size()) {
|
||||
std::vector<AnalyticsObjects::DeviceTimePoint> tmp_p;
|
||||
tmp_p.push_back(i);
|
||||
sp.push_back(tmp_p);
|
||||
cur_bucket++;
|
||||
} else {
|
||||
sp[cur_bucket-1].push_back(i);
|
||||
cur_bucket++;
|
||||
}
|
||||
} else {
|
||||
cur_bucket=1;
|
||||
sp[cur_bucket-1].push_back(i);
|
||||
cur_bucket++;
|
||||
cur_sn=i.device_info.serialNumber;
|
||||
}
|
||||
}
|
||||
}
|
||||
typedef std::vector<std::pair<std::uint64_t , std::uint64_t >> bucket_timespans;
|
||||
typedef std::vector< std::vector<AnalyticsObjects::DeviceTimePoint>> split_points;
|
||||
|
||||
template <typename X, typename M> void AverageAPData( X T, const std::vector<M> &Values, AnalyticsObjects::AveragePoint &P) {
|
||||
if(Values.empty())
|
||||
@@ -89,6 +46,81 @@ namespace OpenWifi {
|
||||
P.avg = 0.0;
|
||||
}
|
||||
|
||||
static void NewSort(const AnalyticsObjects::DeviceTimePointList &l,split_points &sp) {
|
||||
|
||||
struct {
|
||||
bool operator()(const AnalyticsObjects::DeviceTimePoint &lhs, const AnalyticsObjects::DeviceTimePoint &rhs) const {
|
||||
if (lhs.device_info.serialNumber < rhs.device_info.serialNumber) return true;
|
||||
if (lhs.device_info.serialNumber > rhs.device_info.serialNumber) return false;
|
||||
return lhs.timestamp < rhs.timestamp;
|
||||
}
|
||||
} sort_serial_ts;
|
||||
|
||||
// attempt at finding an interval
|
||||
AnalyticsObjects::DeviceTimePointList tmp{l};
|
||||
std::sort(tmp.points.begin(),tmp.points.end(),sort_serial_ts);
|
||||
|
||||
std::string cur_ser;
|
||||
std::uint64_t cur_int=0,start_val, last_val, first_val = 0;
|
||||
for(const auto &point:tmp.points) {
|
||||
if(cur_ser.empty()) {
|
||||
start_val = point.timestamp;
|
||||
cur_ser = point.serialNumber;
|
||||
first_val = point.timestamp;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(cur_ser==point.serialNumber) {
|
||||
auto this_int = point.timestamp - start_val;
|
||||
if(cur_int) {
|
||||
if(this_int<cur_int) {
|
||||
cur_int = this_int;
|
||||
}
|
||||
} else {
|
||||
cur_int = this_int;
|
||||
}
|
||||
start_val = point.timestamp;
|
||||
} else {
|
||||
cur_ser = point.serialNumber;
|
||||
start_val = point.timestamp;
|
||||
}
|
||||
last_val = point.timestamp;
|
||||
}
|
||||
|
||||
// std::cout << "Intervals: " << cur_int << std::endl;
|
||||
|
||||
std::vector<std::pair<std::uint64_t,std::uint64_t>> time_slots; // timeslot 0 has <t1,t2>
|
||||
std::vector<std::set<std::string>> serial_numbers; // serial number already in a timeslot.
|
||||
|
||||
|
||||
std::uint64_t cur_first=first_val,cur_end=0;
|
||||
sp.clear();
|
||||
while(cur_end<last_val) {
|
||||
std::pair<std::uint64_t,std::uint64_t> e;
|
||||
e.first = cur_first;
|
||||
e.second = e.first + cur_int-1;
|
||||
cur_first = e.second+1;
|
||||
cur_end = e.second;
|
||||
time_slots.emplace_back(e);
|
||||
std::set<std::string> q;
|
||||
serial_numbers.emplace_back(q);
|
||||
std::vector<AnalyticsObjects::DeviceTimePoint> qq;
|
||||
sp.emplace_back(qq);
|
||||
}
|
||||
|
||||
for(const auto &point:tmp.points) {
|
||||
std::uint64_t slot_index=0;
|
||||
for(const auto &slot:time_slots) {
|
||||
if(point.timestamp >= slot.first && point.timestamp <= slot.second) {
|
||||
serial_numbers[slot_index].insert(point.serialNumber);
|
||||
sp[slot_index].emplace_back(point);
|
||||
}
|
||||
slot_index++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void RESTAPI_board_timepoint_handler::DoGet() {
|
||||
auto id = GetBinding("id","");
|
||||
if(id.empty() || !Utils::ValidUUID(id)) {
|
||||
@@ -102,7 +134,12 @@ namespace OpenWifi {
|
||||
|
||||
auto fromDate = GetParameter("fromDate",0);
|
||||
auto endDate = GetParameter("endDate",0);
|
||||
auto maxRecords = GetParameter("maxRecords",1000);
|
||||
std::uint64_t maxRecords;
|
||||
if(Request->has("limit"))
|
||||
maxRecords = QB_.Limit;
|
||||
else
|
||||
maxRecords = GetParameter("maxRecords",1000);
|
||||
|
||||
auto statsOnly = GetBoolParameter("statsOnly");
|
||||
auto pointsOnly = GetBoolParameter("pointsOnly");
|
||||
auto pointsStatsOnly = GetBoolParameter("pointsStatsOnly");
|
||||
@@ -115,71 +152,39 @@ namespace OpenWifi {
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
|
||||
auto Points = std::make_unique<AnalyticsObjects::DeviceTimePointList>();
|
||||
StorageService()->TimePointsDB().SelectRecords(id,fromDate, endDate, maxRecords, Points->points);
|
||||
AnalyticsObjects::DeviceTimePointList Points;
|
||||
StorageService()->TimePointsDB().SelectRecords(id,fromDate, endDate, maxRecords, Points.points);
|
||||
std::cout << "1 MaxRecords=" << maxRecords << " retrieved=" << Points.points.size() << std::endl;
|
||||
|
||||
// sort by timestamp & serial number.
|
||||
struct {
|
||||
bool operator()(const AnalyticsObjects::DeviceTimePoint &lhs, const AnalyticsObjects::DeviceTimePoint &rhs) const {
|
||||
if(lhs.device_info.serialNumber < rhs.device_info.serialNumber) return true;
|
||||
if(lhs.device_info.serialNumber > rhs.device_info.serialNumber) return false;
|
||||
return lhs.timestamp < rhs.timestamp;
|
||||
}
|
||||
} DeviceTimePoint_sort;
|
||||
split_points sp;
|
||||
|
||||
struct {
|
||||
bool operator()(const AnalyticsObjects::SSIDTimePoint &lhs, const AnalyticsObjects::SSIDTimePoint &rhs) const {
|
||||
if(lhs.ssid < rhs.ssid) return true;
|
||||
if(lhs.ssid > rhs.ssid) return false;
|
||||
return lhs.bssid < rhs.bssid;
|
||||
}
|
||||
} SSID_sort;
|
||||
NewSort(Points,sp);
|
||||
std::cout << __LINE__ << std::endl;
|
||||
|
||||
struct {
|
||||
bool operator()(const AnalyticsObjects::UETimePoint &lhs, const AnalyticsObjects::UETimePoint &rhs) const {
|
||||
if(lhs.station < rhs.station) return true;
|
||||
return false;
|
||||
}
|
||||
} Association_sort;
|
||||
|
||||
std::sort( Points->points.begin(), Points->points.end(), DeviceTimePoint_sort);
|
||||
auto BucketsNeeded = find_number_of_buckets(Points->points);
|
||||
|
||||
auto sp = std::make_unique<split_points>();
|
||||
split_in_buckets(BucketsNeeded,Points->points, *sp);
|
||||
// must sort each bucket according to serial number.
|
||||
for(auto &i: *sp) {
|
||||
std::sort(i.begin(),i.end(),DeviceTimePoint_sort);
|
||||
// now sort according to UEs within a block
|
||||
for(auto &j:i) {
|
||||
std::sort(j.ssid_data.begin(),j.ssid_data.end(),SSID_sort);
|
||||
for(auto &k:j.ssid_data) {
|
||||
std::sort(k.associations.begin(),k.associations.end(),Association_sort);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto Answer = std::make_unique<Poco::JSON::Object>();
|
||||
Poco::JSON::Object Answer;
|
||||
if(!pointsStatsOnly) {
|
||||
auto Points_OuterArray = std::make_unique<Poco::JSON::Array>();
|
||||
for (const auto &point_list:*sp) {
|
||||
Poco::JSON::Array Points_OuterArray;
|
||||
for (const auto &point_list:sp) {
|
||||
Poco::JSON::Array Points_InnerArray;
|
||||
for (const auto &point: point_list) {
|
||||
Poco::JSON::Object O;
|
||||
point.to_json(O);
|
||||
Points_InnerArray.add(O);
|
||||
}
|
||||
Points_OuterArray->add(Points_InnerArray);
|
||||
Points_OuterArray.add(Points_InnerArray);
|
||||
}
|
||||
Answer->set("points",*Points_OuterArray);
|
||||
Answer.set("points",Points_OuterArray);
|
||||
}
|
||||
|
||||
// calculate the stats for each time slot
|
||||
if(!pointsOnly) {
|
||||
auto Stats_Array = std::make_unique<Poco::JSON::Array>();
|
||||
for (const auto &point_list:*sp) {
|
||||
Poco::JSON::Array Stats_Array;
|
||||
for (const auto &point_list:sp) {
|
||||
AnalyticsObjects::DeviceTimePointAnalysis DTPA;
|
||||
|
||||
if(point_list.empty())
|
||||
continue;
|
||||
|
||||
DTPA.timestamp = point_list[0].timestamp;
|
||||
AverageAPData(&AnalyticsObjects::APTimePoint::tx_bytes_bw, point_list, DTPA.tx_bytes_bw);
|
||||
AverageAPData(&AnalyticsObjects::APTimePoint::rx_bytes_bw, point_list, DTPA.rx_bytes_bw);
|
||||
@@ -200,12 +205,12 @@ namespace OpenWifi {
|
||||
|
||||
Poco::JSON::Object Stats_point;
|
||||
DTPA.to_json(Stats_point);
|
||||
Stats_Array->add(Stats_point);
|
||||
Stats_Array.add(Stats_point);
|
||||
}
|
||||
Answer->set("stats", *Stats_Array);
|
||||
Answer.set("stats", Stats_Array);
|
||||
}
|
||||
|
||||
return ReturnObject(*Answer);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
|
||||
void RESTAPI_board_timepoint_handler::DoDelete() {
|
||||
|
||||
@@ -13,9 +13,27 @@ namespace OpenWifi {
|
||||
int VenueCoordinator::Start() {
|
||||
GetBoardList();
|
||||
Worker_.start(*this);
|
||||
|
||||
ReconcileTimerCallback_ = std::make_unique<Poco::TimerCallback<VenueCoordinator>>(*this,&VenueCoordinator::onReconcileTimer);
|
||||
ReconcileTimerTimer_.setStartInterval( 3 * 60 * 1000 );
|
||||
ReconcileTimerTimer_.setPeriodicInterval(3 * 60 * 1000); // 1 hours
|
||||
ReconcileTimerTimer_.start(*ReconcileTimerCallback_, MicroService::instance().TimerPool());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void VenueCoordinator::onReconcileTimer([[maybe_unused]] Poco::Timer &timer) {
|
||||
std::lock_guard G(Mutex_);
|
||||
Utils::SetThreadName("brd-refresh");
|
||||
|
||||
Logger().information("Starting to reconcile board information.");
|
||||
for(const auto &[board_id, watcher]:Watchers_) {
|
||||
Logger().information(fmt::format("Updating: {}", board_id));
|
||||
UpdateBoard(board_id);
|
||||
}
|
||||
Logger().information("Finished reconciling board information.");
|
||||
}
|
||||
|
||||
void VenueCoordinator::GetBoardList() {
|
||||
BoardsToWatch_.clear();
|
||||
auto F = [&](const AnalyticsObjects::BoardInfo &B) ->bool {
|
||||
@@ -59,9 +77,11 @@ namespace OpenWifi {
|
||||
|
||||
void VenueCoordinator::RetireBoard(const AnalyticsObjects::BoardInfo &B) {
|
||||
Logger().error(fmt::format("Venue board '{}' is no longer in the system. Retiring its associated board.", B.venueList[0].name));
|
||||
/*
|
||||
StopBoard(B.info.id);
|
||||
StorageService()->BoardsDB().DeleteRecord("id",B.info.id);
|
||||
StorageService()->TimePointsDB().DeleteRecords(fmt::format(" boardId='{}' ", B.info.id));
|
||||
*/
|
||||
}
|
||||
|
||||
bool VenueCoordinator::GetDevicesForBoard(const AnalyticsObjects::BoardInfo &B, std::vector<uint64_t> & Devices, bool & VenueExists) {
|
||||
@@ -119,7 +139,7 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
|
||||
void VenueCoordinator::ModifyBoard(const std::string &id) {
|
||||
void VenueCoordinator::UpdateBoard(const std::string &id) {
|
||||
AnalyticsObjects::BoardInfo B;
|
||||
if(StorageService()->BoardsDB().GetRecord("id",id,B)) {
|
||||
std::vector<uint64_t> Devices;
|
||||
@@ -130,15 +150,15 @@ namespace OpenWifi {
|
||||
if(it!=ExistingBoards_.end()) {
|
||||
if(it->second!=Devices) {
|
||||
auto it2 = Watchers_.find(id);
|
||||
if(it2!=Watchers_.end())
|
||||
if(it2!=Watchers_.end()) {
|
||||
it2->second->ModifySerialNumbers(Devices);
|
||||
}
|
||||
ExistingBoards_[id] = Devices;
|
||||
Logger().information(fmt::format("Modified board {}",B.info.name));
|
||||
} else {
|
||||
Logger().information(fmt::format("No device changes in board {}",B.info.name));
|
||||
}
|
||||
}
|
||||
Logger().information(fmt::format("Modified board {}",B.info.name));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,12 @@
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
#include "VenueWatcher.h"
|
||||
|
||||
#include "Poco/Timer.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class VenueCoordinator : public SubSystemServer, Poco::Runnable {
|
||||
@@ -21,7 +24,7 @@ namespace OpenWifi {
|
||||
void run() override;
|
||||
|
||||
void StopBoard(const std::string &id);
|
||||
void ModifyBoard(const std::string &id);
|
||||
void UpdateBoard(const std::string &id);
|
||||
void AddBoard(const std::string &id);
|
||||
|
||||
bool GetDevicesForBoard(const AnalyticsObjects::BoardInfo &B, std::vector<uint64_t> & Devices, bool & VenueExists);
|
||||
@@ -30,13 +33,17 @@ namespace OpenWifi {
|
||||
bool Watching(const std::string &id);
|
||||
void RetireBoard(const AnalyticsObjects::BoardInfo &B);
|
||||
|
||||
private:
|
||||
Poco::Thread Worker_;
|
||||
std::atomic_bool Running_=false;
|
||||
std::set<AnalyticsObjects::BoardInfo> BoardsToWatch_;
|
||||
std::map<std::string,std::shared_ptr<VenueWatcher>> Watchers_;
|
||||
void onReconcileTimer(Poco::Timer & timer);
|
||||
|
||||
std::map<std::string,std::vector<uint64_t>> ExistingBoards_;
|
||||
private:
|
||||
Poco::Thread Worker_;
|
||||
std::atomic_bool Running_=false;
|
||||
std::set<AnalyticsObjects::BoardInfo> BoardsToWatch_;
|
||||
std::map<std::string,std::shared_ptr<VenueWatcher>> Watchers_;
|
||||
std::unique_ptr<Poco::TimerCallback<VenueCoordinator>> ReconcileTimerCallback_;
|
||||
Poco::Timer ReconcileTimerTimer_;
|
||||
|
||||
std::map<std::string,std::vector<uint64_t>> ExistingBoards_;
|
||||
|
||||
VenueCoordinator() noexcept:
|
||||
SubSystemServer("VenueCoordinator", "VENUE-COORD", "venue.coordinator")
|
||||
|
||||
@@ -69,9 +69,11 @@ namespace OpenWifi {
|
||||
void GetDevices(std::vector<AnalyticsObjects::DeviceInfo> & DI);
|
||||
|
||||
void GetBandwidth(uint64_t start, uint64_t end, uint64_t interval , AnalyticsObjects::BandwidthAnalysis & BW);
|
||||
|
||||
inline std::string Venue() const {
|
||||
return venue_id_;
|
||||
}
|
||||
private:
|
||||
std::recursive_mutex Mutex_;
|
||||
std::mutex Mutex_;
|
||||
std::string boardId_;
|
||||
std::string venue_id_;
|
||||
Poco::NotificationQueue Queue_;
|
||||
|
||||
@@ -703,6 +703,19 @@ namespace OpenWifi::Utils {
|
||||
return (std::all_of(UUID.begin(),UUID.end(),[&](auto i){ if(i=='-') dashes++; return i=='-' || std::isxdigit(i);})) && (dashes>0);
|
||||
}
|
||||
|
||||
template <typename ...Args> std::string ComputeHash(Args&&... args) {
|
||||
Poco::SHA2Engine E;
|
||||
auto as_string = [](auto p) {
|
||||
if constexpr(std::is_arithmetic_v<decltype(p)>) {
|
||||
return std::to_string(p);
|
||||
} else {
|
||||
return p;
|
||||
}
|
||||
};
|
||||
(E.update(as_string(args)),...);
|
||||
return Poco::SHA2Engine::digestToHex(E.digest());
|
||||
}
|
||||
|
||||
[[nodiscard]] inline std::vector<std::string> Split(const std::string &List, char Delimiter=',' ) {
|
||||
std::vector<std::string> ReturnList;
|
||||
|
||||
@@ -2433,6 +2446,7 @@ namespace OpenWifi {
|
||||
Poco::Net::HTTPServerResponse *Response= nullptr;
|
||||
SecurityObjects::UserInfoAndPolicy UserInfo_;
|
||||
QueryBlock QB_;
|
||||
const std::string & Requester() const { return REST_Requester_; }
|
||||
protected:
|
||||
BindingMap Bindings_;
|
||||
Poco::URI::QueryParameters Parameters_;
|
||||
@@ -2449,6 +2463,7 @@ namespace OpenWifi {
|
||||
RateLimit MyRates_;
|
||||
uint64_t TransactionId_;
|
||||
Poco::JSON::Object::Ptr ParsedBody_;
|
||||
std::string REST_Requester_;
|
||||
};
|
||||
|
||||
class RESTAPI_UnknownRequestHandler : public RESTAPIHandler {
|
||||
@@ -2736,12 +2751,12 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
private:
|
||||
std::recursive_mutex Mutex_;
|
||||
Types::NotifyTable Notifiers_;
|
||||
Poco::Thread Worker_;
|
||||
mutable std::atomic_bool Running_=false;
|
||||
uint64_t FunctionId_=1;
|
||||
Poco::NotificationQueue Queue_;
|
||||
std::recursive_mutex Mutex_;
|
||||
Types::NotifyTable Notifiers_;
|
||||
Poco::Thread Worker_;
|
||||
mutable std::atomic_bool Running_=false;
|
||||
uint64_t FunctionId_=1;
|
||||
Poco::NotificationQueue Queue_;
|
||||
};
|
||||
|
||||
class KafkaManager : public SubSystemServer {
|
||||
@@ -3023,7 +3038,7 @@ namespace OpenWifi {
|
||||
}
|
||||
int Start() override;
|
||||
inline void Stop() override {
|
||||
Logger().information("Stopping ");
|
||||
Logger().information("Stopping...");
|
||||
for( const auto & svr : RESTServers_ )
|
||||
svr->stop();
|
||||
Pool_.stopAll();
|
||||
@@ -3031,6 +3046,7 @@ namespace OpenWifi {
|
||||
RESTServers_.clear();
|
||||
}
|
||||
|
||||
|
||||
inline void reinitialize(Poco::Util::Application &self) override;
|
||||
|
||||
inline Poco::Net::HTTPRequestHandler *CallServer(const std::string &Path, uint64_t Id) {
|
||||
@@ -3038,6 +3054,7 @@ namespace OpenWifi {
|
||||
Utils::SetThreadName(fmt::format("x-rest:{}",Id).c_str());
|
||||
return RESTAPI_ExtRouter(Path, Bindings, Logger(), Server_, Id);
|
||||
}
|
||||
const Poco::ThreadPool & Pool() { return Pool_; }
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<Poco::Net::HTTPServer>> RESTServers_;
|
||||
@@ -3156,7 +3173,7 @@ namespace OpenWifi {
|
||||
|
||||
inline int Start() override;
|
||||
inline void Stop() override {
|
||||
Logger().information("Stopping ");
|
||||
Logger().information("Stopping...");
|
||||
for( const auto & svr : RESTServers_ )
|
||||
svr->stop();
|
||||
Pool_.stopAll();
|
||||
@@ -3170,6 +3187,8 @@ namespace OpenWifi {
|
||||
Utils::SetThreadName(fmt::format("i-rest:{}",Id).c_str());
|
||||
return RESTAPI_IntRouter(Path, Bindings, Logger(), Server_, Id);
|
||||
}
|
||||
|
||||
const Poco::ThreadPool & Pool() { return Pool_; }
|
||||
private:
|
||||
std::vector<std::unique_ptr<Poco::Net::HTTPServer>> RESTServers_;
|
||||
Poco::ThreadPool Pool_{"i-rest",2,16};
|
||||
@@ -3304,7 +3323,6 @@ namespace OpenWifi {
|
||||
inline std::string ConfigPath(const std::string &Key);
|
||||
inline std::string Encrypt(const std::string &S);
|
||||
inline std::string Decrypt(const std::string &S);
|
||||
inline std::string CreateHash(const std::string &S);
|
||||
inline std::string MakeSystemEventMessage( const std::string & Type ) const;
|
||||
[[nodiscard]] inline bool IsValidAPIKEY(const Poco::Net::HTTPServerRequest &Request);
|
||||
inline static void SavePID();
|
||||
@@ -3350,7 +3368,6 @@ namespace OpenWifi {
|
||||
std::string WWWAssetsDir_;
|
||||
Poco::Crypto::CipherFactory & CipherFactory_ = Poco::Crypto::CipherFactory::defaultFactory();
|
||||
Poco::Crypto::Cipher * Cipher_ = nullptr;
|
||||
Poco::SHA2Engine SHA2_;
|
||||
MicroServiceMetaMap Services_;
|
||||
std::string MyHash_;
|
||||
std::string MyPrivateEndPoint_;
|
||||
@@ -3521,7 +3538,7 @@ namespace OpenWifi {
|
||||
MyPrivateEndPoint_ = ConfigGetString("openwifi.system.uri.private");
|
||||
MyPublicEndPoint_ = ConfigGetString("openwifi.system.uri.public");
|
||||
UIURI_ = ConfigGetString("openwifi.system.uri.ui");
|
||||
MyHash_ = CreateHash(MyPublicEndPoint_);
|
||||
MyHash_ = Utils::ComputeHash(MyPublicEndPoint_);
|
||||
}
|
||||
|
||||
void MicroServicePostInitialization();
|
||||
@@ -3858,11 +3875,6 @@ namespace OpenWifi {
|
||||
return Cipher_->decryptString(S, Poco::Crypto::Cipher::Cipher::ENC_BASE64);;
|
||||
}
|
||||
|
||||
inline std::string MicroService::CreateHash(const std::string &S) {
|
||||
SHA2_.update(S);
|
||||
return Utils::ToHex(SHA2_.digest());
|
||||
}
|
||||
|
||||
inline std::string MicroService::MakeSystemEventMessage( const std::string & Type ) const {
|
||||
Poco::JSON::Object Obj;
|
||||
Obj.set(KafkaTopics::ServiceEvents::Fields::EVENT,Type);
|
||||
@@ -4739,6 +4751,7 @@ namespace OpenWifi {
|
||||
inline bool RESTAPIHandler::IsAuthorized( bool & Expired , [[maybe_unused]] bool & Contacted , bool Sub ) {
|
||||
if(Internal_ && Request->has("X-INTERNAL-NAME")) {
|
||||
auto Allowed = MicroService::instance().IsValidAPIKEY(*Request);
|
||||
Contacted = true;
|
||||
if(!Allowed) {
|
||||
if(Server_.LogBadTokens(false)) {
|
||||
Logger_.debug(fmt::format("I-REQ-DENIED({}): Method={} Path={}",
|
||||
@@ -4747,6 +4760,7 @@ namespace OpenWifi {
|
||||
}
|
||||
} else {
|
||||
auto Id = Request->get("X-INTERNAL-NAME", "unknown");
|
||||
REST_Requester_ = Id;
|
||||
if(Server_.LogIt(Request->getMethod(),true)) {
|
||||
Logger_.debug(fmt::format("I-REQ-ALLOWED({}): User='{}' Method={} Path={}",
|
||||
Utils::FormatIPv6(Request->clientAddress().toString()), Id,
|
||||
@@ -4770,6 +4784,7 @@ namespace OpenWifi {
|
||||
#else
|
||||
if (AuthClient()->IsAuthorized( SessionToken_, UserInfo_, Expired, Contacted, Sub)) {
|
||||
#endif
|
||||
REST_Requester_ = UserInfo_.userinfo.email;
|
||||
if(Server_.LogIt(Request->getMethod(),true)) {
|
||||
Logger_.debug(fmt::format("X-REQ-ALLOWED({}): User='{}@{}' Method={} Path={}",
|
||||
UserInfo_.userinfo.email,
|
||||
|
||||
@@ -71,7 +71,7 @@ namespace OpenWifi {
|
||||
} else if (LastDate) {
|
||||
WhereClause = fmt::format(" boardId='{}' and (timestamp <= {}) ", boardId, LastDate);
|
||||
}
|
||||
GetRecords(0,MaxRecords,Recs,WhereClause," order by timestamp ASC ");
|
||||
GetRecords(0,MaxRecords,Recs,WhereClause," order by timestamp, serialNumber ASC ");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user