Compare commits

..

57 Commits

Author SHA1 Message Date
TIP Automation User
a568fce901 Chg: update image tag in helm values to v2.7.0-RC1 2022-09-16 19:55:07 +00:00
Stephane Bourque
6e2a21c831 Merge pull request #26 from Telecominfraproject/WIFI-10839
https://telecominfraproject.atlassian.net/browse/WIFI-10839
2022-09-14 12:28:05 -07:00
stephb9959
da8a9e14cf https://telecominfraproject.atlassian.net/browse/WIFI-10839
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-09-14 12:27:02 -07:00
stephb9959
075b83a7d5 https://telecominfraproject.atlassian.net/browse/WIFI-10839
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-09-14 12:17:36 -07:00
stephb9959
3c35ec1523 https://telecominfraproject.atlassian.net/browse/WIFI-10839
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-09-14 12:13:48 -07:00
stephb9959
b65f33c975 https://telecominfraproject.atlassian.net/browse/WIFI-10839
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-09-14 11:55:34 -07:00
stephb9959
cbd5b09cdf https://telecominfraproject.atlassian.net/browse/WIFI-10839
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-09-14 11:51:48 -07:00
stephb9959
0a145c8501 https://telecominfraproject.atlassian.net/browse/WIFI-10839
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-09-14 11:38:55 -07:00
stephb9959
2ed88569d0 https://telecominfraproject.atlassian.net/browse/WIFI-10839
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-09-14 11:27:14 -07:00
stephb9959
58c2269893 https://telecominfraproject.atlassian.net/browse/WIFI-10839
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-09-14 09:43:04 -07:00
stephb9959
a708cc2be0 https://telecominfraproject.atlassian.net/browse/WIFI-10839
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-09-14 09:34:55 -07:00
Stephane Bourque
9c8f7ed6f9 Merge pull request #25 from Telecominfraproject/WIFI-10839
https://telecominfraproject.atlassian.net/browse/WIFI-10839
2022-09-14 08:59:24 -07:00
stephb9959
b79a3b6c12 https://telecominfraproject.atlassian.net/browse/WIFI-10839
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-09-14 08:58:32 -07:00
Dmitry Dunaev
2c3b7711b3 Merge pull request #24 from Telecominfraproject/feature/wifi-10069--add-wait-postgres-initcontainer
[WIFI-10069] Add: helm - wait-postgres init container
2022-09-02 14:33:07 +03:00
Dmitry Dunaev
831e144869 [WIFI-10069] Add: helm - wait-postgres init container
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-09-02 14:32:42 +03:00
stephb9959
67910c982a https://telecominfraproject.atlassian.net/browse/WIFI-10547
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-29 23:22:00 -07:00
stephb9959
9be196ce40 https://telecominfraproject.atlassian.net/browse/WIFI-10547
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-29 23:19:28 -07:00
stephb9959
222afe2858 https://telecominfraproject.atlassian.net/browse/WIFI-10547
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-29 23:19:10 -07:00
stephb9959
40a02c4752 https://telecominfraproject.atlassian.net/browse/WIFI-10547
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-29 23:11:56 -07:00
stephb9959
7f1577503f https://telecominfraproject.atlassian.net/browse/WIFI-10547
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-29 23:08:32 -07:00
stephb9959
7ab2e6c96e https://telecominfraproject.atlassian.net/browse/WIFI-10547
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-29 14:26:45 -07:00
stephb9959
639db8631e https://telecominfraproject.atlassian.net/browse/WIFI-10547
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-29 14:24:40 -07:00
stephb9959
9fe9b74dea https://telecominfraproject.atlassian.net/browse/WIFI-10547
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-29 14:22:08 -07:00
stephb9959
20c025f994 https://telecominfraproject.atlassian.net/browse/WIFI-10547
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-29 14:18:38 -07:00
stephb9959
ee78155b68 https://telecominfraproject.atlassian.net/browse/WIFI-10547
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-29 14:13:58 -07:00
stephb9959
9f9a866ad3 https://telecominfraproject.atlassian.net/browse/WIFI-10547
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-29 14:09:13 -07:00
stephb9959
adbd852ccd https://telecominfraproject.atlassian.net/browse/WIFI-10547
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-29 14:07:43 -07:00
stephb9959
4bb5ee0b86 https://telecominfraproject.atlassian.net/browse/WIFI-10547
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-29 13:42:34 -07:00
stephb9959
06bb8cebbe https://telecominfraproject.atlassian.net/browse/WIFI-10547
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-29 13:39:18 -07:00
stephb9959
dde46ce6b2 https://telecominfraproject.atlassian.net/browse/WIFI-10547
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-29 13:34:13 -07:00
stephb9959
515f8a4fea https://telecominfraproject.atlassian.net/browse/WIFI-10547
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-29 11:13:49 -07:00
stephb9959
8dcfe04310 https://telecominfraproject.atlassian.net/browse/WIFI-10547
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-29 10:38:39 -07:00
stephb9959
5db6fc3027 https://telecominfraproject.atlassian.net/browse/WIFI-10547
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-29 10:26:11 -07:00
Dmitry Dunaev
8049291138 Merge pull request #22 from Telecominfraproject/fix/wifi-10413--cve-fix
[WIFI-10413] Fix: vulnerable base Docker image version
2022-08-15 13:31:08 +03:00
Dmitry Dunaev
613fa2e2bb [WIFI-10413] Fix: vulnerable base Docker image version
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-08-15 11:20:31 +03:00
Stephane Bourque
eb9a748836 Merge pull request #21 from Telecominfraproject/WIFI-10547
https://telecominfraproject.atlassian.net/browse/WIFI-10547Wifi 10547
2022-08-11 21:37:29 -07:00
stephb9959
6ee3cae1db https://telecominfraproject.atlassian.net/browse/WIFI-10547
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-11 21:36:17 -07:00
stephb9959
33e4f8abd8 https://telecominfraproject.atlassian.net/browse/WIFI-10547
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-10 23:16:56 -07:00
stephb9959
d5b4d15307 https://telecominfraproject.atlassian.net/browse/WIFI-10547
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-10 23:07:05 -07:00
Stephane Bourque
e01f985974 Merge pull request #20 from Telecominfraproject/WIFI-10245
https://telecominfraproject.atlassian.net/browse/WIFI-10245
2022-08-10 16:40:52 -07:00
stephb9959
8dc3e53fc0 https://telecominfraproject.atlassian.net/browse/WIFI-10245
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-10 16:40:28 -07:00
Stephane Bourque
52e1bf8817 Merge pull request #19 from Telecominfraproject/feature/wifi-10388--versioning
[WIFI-10388] Chg: use Docker build arg to define dependency version
2022-08-08 12:12:01 -07:00
Dmitry Dunaev
a8b0028af6 [WIFI-10388] Chg: use Docker build arg to define dependency version
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-08-08 17:46:38 +03:00
Stephane Bourque
7976602d17 Merge pull request #18 from Telecominfraproject/WIFI-10388
https://telecominfraproject.atlassian.net/browse/WIFI-10388
2022-08-07 22:30:59 -07:00
stephb9959
55b0075c0c https://telecominfraproject.atlassian.net/browse/WIFI-10388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-07 22:30:28 -07:00
Stephane Bourque
1da468e52c Merge pull request #17 from Telecominfraproject/WIFI-10388
https://telecominfraproject.atlassian.net/browse/WIFI-10388
2022-08-04 06:59:03 -07:00
stephb9959
fa434f79c3 https://telecominfraproject.atlassian.net/browse/WIFI-10388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-04 06:58:29 -07:00
Stephane Bourque
d396a104ff Merge pull request #16 from Telecominfraproject/WIFI-10388
https://telecominfraproject.atlassian.net/browse/WIFI-10388
2022-08-03 08:02:06 -07:00
stephb9959
61837a8975 https://telecominfraproject.atlassian.net/browse/WIFI-10388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-03 08:01:23 -07:00
Stephane Bourque
c1f06ec784 Merge pull request #15 from Telecominfraproject/WIFI-10388
https://telecominfraproject.atlassian.net/browse/WIFI-10388
2022-08-01 09:37:46 -07:00
stephb9959
10ffba95b5 https://telecominfraproject.atlassian.net/browse/WIFI-10388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-01 09:11:51 -07:00
Dmitry Dunaev
432d0ed52b Merge pull request #14 from Telecominfraproject/feature/wifi-9772--test-systeminfo
[WIFI-9772] Chg: fix test scripts to make requests to owanalytics instead of owprov
2022-07-21 15:43:52 +03:00
Dmitry Dunaev
fe247c6093 [WIFI-9772] Chg: fix test scripts to make requests to owanalytics instead of owprov
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-07-21 15:43:13 +03:00
Stephane Bourque
4c1daf84cf Merge pull request #13 from Telecominfraproject/WIFI-10040
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10040
2022-07-04 14:19:21 -07:00
Stephane Bourque
d0c4030289 Merge pull request #11 from Telecominfraproject/WIFI-10040
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10040
2022-07-01 09:58:01 -07:00
Johann Hoffmann
0856e256e9 Merge pull request #9 from Telecominfraproject/WIFI-9920-rttys-not-working-after-upgrade
[WIFI-9920] Always re-generate config file if TEMPLATE_CONFIG is set to true
2022-06-24 18:22:20 +02:00
Johann Hoffmann
228b2162bc Always re-generate config file if TEMPLATE_CONFIG is set to true
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-06-24 18:19:41 +02:00
25 changed files with 15443 additions and 261 deletions

1
.gitignore vendored
View File

@@ -32,6 +32,7 @@
*.app
test_scripts/curl/token.json
test_scripts/curl/result.json
.vscode/c_cpp_properties.json
test_scripts/curl/result.json
*.swp

View File

@@ -1,4 +1,10 @@
FROM alpine:3.15 AS build-base
ARG ALPINE_VERSION=3.16.2
ARG POCO_VERSION=poco-tip-v1
ARG FMTLIB_VERSION=9.0.0
ARG CPPKAFKA_VERSION=tip-v1
ARG JSON_VALIDATOR_VERSION=2.1.0
FROM alpine:$ALPINE_VERSION AS build-base
RUN apk add --update --no-cache \
make cmake g++ git \
@@ -9,8 +15,10 @@ 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
ARG POCO_VERSION
ADD https://api.github.com/repos/AriliaWireless/poco/git/refs/tags/${POCO_VERSION} version.json
RUN git clone https://github.com/AriliaWireless/poco --branch ${POCO_VERSION} /poco
WORKDIR /poco
RUN mkdir cmake-build
@@ -19,10 +27,26 @@ RUN cmake ..
RUN cmake --build . --config Release -j8
RUN cmake --build . --target install
FROM build-base AS fmtlib-build
ARG FMTLIB_VERSION
ADD https://api.github.com/repos/fmtlib/fmt/git/refs/tags/${FMTLIB_VERSION} version.json
RUN git clone https://github.com/fmtlib/fmt --branch ${FMTLIB_VERSION} /fmtlib
WORKDIR /fmtlib
RUN mkdir cmake-build
WORKDIR cmake-build
RUN cmake ..
RUN make
RUN make 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
ARG CPPKAFKA_VERSION
ADD https://api.github.com/repos/AriliaWireless/cppkafka/git/refs/tags/${CPPKAFKA_VERSION} version.json
RUN git clone https://github.com/AriliaWireless/cppkafka --branch ${CPPKAFKA_VERSION} /cppkafka
WORKDIR /cppkafka
RUN mkdir cmake-build
@@ -33,8 +57,10 @@ RUN cmake --build . --target install
FROM build-base AS json-schema-validator-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
ARG JSON_VALIDATOR_VERSION
ADD https://api.github.com/repos/pboettch/json-schema-validator/git/refs/tags/${JSON_VALIDATOR_VERSION} version.json
RUN git clone https://github.com/pboettch/json-schema-validator --branch ${JSON_VALIDATOR_VERSION} /json-schema-validator
WORKDIR /json-schema-validator
RUN mkdir cmake-build
@@ -43,18 +69,6 @@ RUN cmake ..
RUN make
RUN make install
FROM build-base AS fmtlib-build
ADD https://api.github.com/repos/fmtlib/fmt/git/refs/heads/master version.json
RUN git clone https://github.com/fmtlib/fmt /fmtlib
WORKDIR /fmtlib
RUN mkdir cmake-build
WORKDIR cmake-build
RUN cmake ..
RUN make
RUN make install
FROM build-base AS owanalytics-build
ADD CMakeLists.txt build /owanalytics/
@@ -77,7 +91,7 @@ WORKDIR /owanalytics/cmake-build
RUN cmake ..
RUN cmake --build . --config Release -j8
FROM alpine:3.15
FROM alpine:$ALPINE_VERSION
ENV OWANALYTICS_USER=owanalytics \
OWANALYTICS_ROOT=/owanalytics-data \

2
build
View File

@@ -1 +1 @@
3
13

View File

@@ -5,7 +5,7 @@ if [ "$SELFSIGNED_CERTS" = 'true' ]; then
update-ca-certificates
fi
if [[ "$TEMPLATE_CONFIG" = 'true' && ! -f "$OWANALYTICS_CONFIG"/owanalytics.properties ]]; then
if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then
RESTAPI_HOST_ROOTCA=${RESTAPI_HOST_ROOTCA:-"\$OWANALYTICS_ROOT/certs/restapi-ca.pem"} \
RESTAPI_HOST_PORT=${RESTAPI_HOST_PORT:-"16009"} \
RESTAPI_HOST_CERT=${RESTAPI_HOST_CERT:-"\$OWANALYTICS_ROOT/certs/restapi-cert.pem"} \

2
helm/.gitignore vendored
View File

@@ -1 +1,3 @@
*.swp
Chart.lock
charts/

View File

@@ -1,4 +1,5 @@
{{- $root := . -}}
{{- $storageType := index .Values.configProperties "storage.type" -}}
---
apiVersion: apps/v1
kind: Deployment
@@ -46,6 +47,39 @@ spec:
- -timeout
- 600s
{{- if eq $storageType "postgresql" }}
- name: wait-postgres
image: "{{ .Values.images.owanalytics.repository }}:{{ .Values.images.owanalytics.tag }}"
imagePullPolicy: {{ .Values.images.owanalytics.pullPolicy }}
command:
- /wait-for-postgres.sh
- {{ index .Values.configProperties "storage.type.postgresql.host" }}
- echo
- "PostgreSQL is ready"
env:
- name: KUBERNETES_DEPLOYED
value: "{{ now }}"
{{- range $key, $value := .Values.public_env_variables }}
- name: {{ $key }}
value: {{ $value | quote }}
{{- end }}
{{- range $key, $value := .Values.secret_env_variables }}
- name: {{ $key }}
valueFrom:
secretKeyRef:
name: {{ include "owanalytics.fullname" $root }}-env
key: {{ $key }}
{{- end }}
volumeMounts:
{{- range .Values.volumes.owanalytics }}
- name: {{ .name }}
mountPath: {{ .mountPath }}
{{- if .subPath }}
subPath: {{ .subPath }}
{{- end }}
{{- end }}
{{- end }}
containers:
- name: owanalytics

View File

@@ -9,7 +9,7 @@ fullnameOverride: ""
images:
owanalytics:
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owanalytics
tag: main
tag: v2.7.0-RC1
pullPolicy: Always
# regcred:
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io

View File

@@ -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:

View File

@@ -158,6 +158,7 @@ namespace OpenWifi {
auto interfaces = (*State)["interfaces"];
DI_.associations_2g = DI_.associations_5g = DI_.associations_6g = 0;
for(const auto &interface:interfaces) {
std::string InterfaceName = fmt::format("{}: {}", DI_.serialNumber, interface.contains("name") ? to_string(interface["name"]) : "unknown");
if(interface.contains("counters")) {
auto counters = interface["counters"];
GetJSON("collisions", counters, DTP.ap_data.collisions, (uint64_t) 0);
@@ -172,6 +173,34 @@ namespace OpenWifi {
GetJSON("tx_packets", counters, DTP.ap_data.tx_packets, (uint64_t) 0);
}
InterfaceClientEntryMap_t ICEM;
if(interface.contains("clients") && interface["clients"].is_array()) {
try {
auto Clients = interface["clients"];
for(const auto & client: Clients) {
if(client.contains("mac") && client["mac"].is_string()) {
InterfaceClientEntry E;
if(client.contains("ipv4_addresses") && client["ipv4_addresses"].is_array()) {
for(const auto &ip:client["ipv4_addresses"]) {
E.ipv4_addresses.push_back(ip);
}
}
if(client.contains("ipv6_addresses") && client["ipv6_addresses"].is_array()) {
for(const auto &ip:client["ipv6_addresses"]) {
E.ipv6_addresses.push_back(ip);
}
}
auto M = mac_filter(client["mac"]);
ICEM[M] = E;
}
}
} catch(...) {
std::cout << "Exception will parsing clients: " << InterfaceName << std::endl;
}
} else {
// std::cout <<"Interface: No clients: " << InterfaceName << std::endl;
}
if(interface.contains("ssids")) {
auto ssids = interface["ssids"];
for (const auto &ssid: ssids) {
@@ -243,8 +272,19 @@ namespace OpenWifi {
GetJSON("rx_packets",association,WFH.rx_packets,(uint64_t)0);
GetJSON("tx_packets",association,WFH.tx_packets,(uint64_t)0);
WFH.ipv4 = "---";
WFH.ipv6 = "----";
// try to locate the IP addresses
auto ClientInfo = ICEM.find(WFH.station_id);
if(ClientInfo!=end(ICEM)) {
if(!ClientInfo->second.ipv4_addresses.empty()) {
WFH.ipv4 = ClientInfo->second.ipv4_addresses[0];
}
if(!ClientInfo->second.ipv6_addresses.empty()) {
WFH.ipv6 = ClientInfo->second.ipv6_addresses[0];
}
std::cout << __LINE__ << ": " << InterfaceName << " Mac Found: " << ICEM.size() << " entries. " << WFH.station_id << std::endl;
} else {
std::cout << __LINE__ << ": " << InterfaceName << " Mac NOT found: " << ICEM.size() << " entries. " << WFH.station_id << std::endl;
}
for(const auto &rd:DTP.radio_data) {
if(rd.band == SSIDTP.band) {

View File

@@ -11,6 +11,13 @@
namespace OpenWifi {
struct InterfaceClientEntry {
std::vector<std::string> ipv4_addresses;
std::vector<std::string> ipv6_addresses;
};
using InterfaceClientEntryMap_t = std::map<std::string,InterfaceClientEntry>;
class AP {
public:
explicit AP(uint64_t mac, const std::string &venue_id, const std::string &BoardId, Poco::Logger &L) :

View File

@@ -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;

View File

@@ -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() {

View File

@@ -20,10 +20,9 @@ namespace OpenWifi {
}
if(GetBoolParameter("macsOnly")) {
auto macFilter = GetParameter("macFilter","");
std::vector<uint64_t> Macs;
WifiClientCache()->FindNumbers(venue,macFilter,500,Macs);
WifiClientCache()->FindNumbers(venue,macFilter,QB_.Offset, QB_.Limit, Macs);
Poco::JSON::Array Arr;
for(const auto &mac: Macs)
Arr.add(Utils::IntToSerialNumber(mac));

View File

@@ -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;
}

View File

@@ -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")

View File

@@ -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_;

View File

@@ -124,32 +124,36 @@ namespace OpenWifi {
}
}
void WifiClientCache::FindNumbers(const std::string &venue_id, const std::string &S, uint HowMany, std::vector<uint64_t> &A) {
void WifiClientCache::FindNumbers(const std::string &venueId, const std::string &SerialNumber, std::uint64_t StartingOffset, std::uint64_t HowMany, std::vector<uint64_t> &A) {
std::lock_guard G(Mutex_);
A.clear();
auto VenueIt = Cache_.find(venue_id);
auto VenueIt = Cache_.find(venueId);
if(VenueIt==Cache_.end())
return;
if(S.empty()) {
if(SerialNumber.empty()) {
auto Start = VenueIt->second.SNs_.begin();
std::uint64_t Offset=0;
while(HowMany && Start!=VenueIt->second.SNs_.end()) {
A.push_back(*Start);
if(Offset>=StartingOffset) {
A.push_back(*Start);
HowMany--;
}
Start++;
HowMany--;
Offset++;
}
return;
}
if (S[0] == '*') {
if (SerialNumber[0] == '*') {
std::string Reversed;
std::copy(rbegin(S), rend(S)-1, std::back_inserter(Reversed));
std::copy(rbegin(SerialNumber), rend(SerialNumber)-1, std::back_inserter(Reversed));
if(Reversed.empty())
return;
return ReturnNumbers(Reversed, HowMany, VenueIt->second.Reverse_SNs_, A, true);
} else {
return ReturnNumbers(S, HowMany, VenueIt->second.SNs_, A, false);
return ReturnNumbers(SerialNumber, HowMany, VenueIt->second.SNs_, A, false);
}
}
}

View File

@@ -20,7 +20,7 @@ namespace OpenWifi {
void Stop() override;
void AddSerialNumber(const std::string &venueId, const std::string &SerialNumber);
void DeleteSerialNumber(const std::string &venueId, const std::string &SerialNumber);
void FindNumbers(const std::string &venueId, const std::string &SerialNumber, uint HowMany, std::vector<uint64_t> &A);
void FindNumbers(const std::string &venueId, const std::string &SerialNumber, std::uint64_t start, std::uint64_t HowMany, std::vector<uint64_t> &A);
inline bool NumberExists(const std::string &venueId, uint64_t SerialNumber) {
std::lock_guard G(Mutex_);
auto It = Cache_.find(venueId);

View File

@@ -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,
@@ -4852,7 +4867,7 @@ namespace OpenWifi {
void run() override;
// MyParallelSocketReactor &ReactorPool();
Poco::Net::SocketReactor & Reactor() { return Reactor_; }
void NewClient(Poco::Net::WebSocket &WS, const std::string &Id);
void NewClient(Poco::Net::WebSocket &WS, const std::string &Id, const std::string &UserName);
bool Register(WebSocketClient *Client, const std::string &Id);
void SetProcessor(WebSocketClientProcessor *F);
void UnRegister(const std::string &Id);
@@ -4903,18 +4918,22 @@ namespace OpenWifi {
class WebSocketClient {
public:
explicit WebSocketClient(Poco::Net::WebSocket &WS, const std::string &Id, Poco::Logger &L,
WebSocketClientProcessor *Processor);
explicit WebSocketClient(Poco::Net::WebSocket &WS,
const std::string &Id,
const std::string &UserName,
Poco::Logger &L,
WebSocketClientProcessor *Processor);
virtual ~WebSocketClient();
[[nodiscard]] inline const std::string &Id();
[[nodiscard]] Poco::Logger &Logger();
inline bool Send(const std::string &Payload);
private:
std::unique_ptr<Poco::Net::WebSocket> WS_;
Poco::Net::SocketReactor &Reactor_;
std::string Id_;
Poco::Logger &Logger_;
bool Authenticated_ = false;
Poco::Net::SocketReactor &Reactor_;
std::string Id_;
std::string UserName_;
Poco::Logger &Logger_;
std::atomic_bool Authenticated_ = false;
SecurityObjects::UserInfoAndPolicy UserInfo_;
WebSocketClientProcessor *Processor_ = nullptr;
void OnSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf);
@@ -4922,33 +4941,9 @@ namespace OpenWifi {
void OnSocketError(const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf);
};
/* inline MyParallelSocketReactor::MyParallelSocketReactor(uint32_t NumReactors) :
NumReactors_(NumReactors)
{
Reactors_ = new Poco::Net::SocketReactor[NumReactors_];
for(uint32_t i=0;i<NumReactors_;i++) {
ReactorPool_.start(Reactors_[i]);
}
}
inline MyParallelSocketReactor::~MyParallelSocketReactor() {
for(uint32_t i=0;i<NumReactors_;i++) {
Reactors_[i].stop();
}
ReactorPool_.stopAll();
ReactorPool_.joinAll();
delete [] Reactors_;
}
inline Poco::Net::SocketReactor & MyParallelSocketReactor::Reactor() {
return Reactors_[ rand() % NumReactors_ ];
}
// inline MyParallelSocketReactor & WebSocketClientServer::ReactorPool() { return *ReactorPool_; }
*/
inline void WebSocketClientServer::NewClient(Poco::Net::WebSocket & WS, const std::string &Id) {
inline void WebSocketClientServer::NewClient(Poco::Net::WebSocket & WS, const std::string &Id, const std::string &UserName ) {
std::lock_guard G(Mutex_);
auto Client = new WebSocketClient(WS,Id,Logger(), Processor_);
auto Client = new WebSocketClient(WS,Id,UserName,Logger(), Processor_);
Clients_[Id] = std::make_pair(Client,"");
}
@@ -5065,6 +5060,7 @@ namespace OpenWifi {
auto Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK;
if (n == 0) {
Logger().warning(Poco::format("CLOSE(%s): %s UI Client is closing WS connection.", Id_, UserName_));
return delete this;
}
@@ -5077,7 +5073,7 @@ namespace OpenWifi {
case Poco::Net::WebSocket::FRAME_OP_PONG: {
} break;
case Poco::Net::WebSocket::FRAME_OP_CLOSE: {
Logger().warning(Poco::format("CLOSE(%s): UI Client is closing its connection.", Id_));
Logger().warning(Poco::format("CLOSE(%s): %s UI Client is closing WS connection.", Id_, UserName_));
Done = true;
} break;
case Poco::Net::WebSocket::FRAME_OP_TEXT: {
@@ -5089,6 +5085,8 @@ namespace OpenWifi {
if (Tokens.size() == 2 &&
AuthClient()->IsAuthorized(Tokens[1], UserInfo_, Expired, Contacted)) {
Authenticated_ = true;
UserName_ = UserInfo_.userinfo.email;
Logger().warning(Poco::format("START(%s): %s UI Client is starting WS connection.", Id_, UserName_));
std::string S{"Welcome! Bienvenue! Bienvenidos!"};
WS_->sendFrame(S.c_str(), S.size());
WebSocketClientServer()->SetUser(Id_, UserInfo_.userinfo.email);
@@ -5134,9 +5132,10 @@ namespace OpenWifi {
}
inline WebSocketClient::WebSocketClient( Poco::Net::WebSocket & WS , const std::string &Id, Poco::Logger & L, WebSocketClientProcessor * Processor) :
inline WebSocketClient::WebSocketClient( Poco::Net::WebSocket & WS , const std::string &Id, const std::string &UserName, Poco::Logger & L, WebSocketClientProcessor * Processor) :
Reactor_(WebSocketClientServer()->Reactor()),
Id_(Id),
UserName_(UserName),
Logger_(L),
Processor_(Processor) {
try {
@@ -5216,9 +5215,8 @@ namespace OpenWifi {
try
{
Poco::Net::WebSocket WS(*Request, *Response);
Logger().information("UI-WebSocket connection established.");
auto Id = MicroService::CreateUUID();
WebSocketClientServer()->NewClient(WS,Id);
WebSocketClientServer()->NewClient(WS,Id,UserInfo_.userinfo.email);
}
catch (...) {
std::cout << "Cannot create websocket client..." << std::endl;

View File

@@ -146,6 +146,10 @@ namespace OpenWifi {
WebSocketClientServer()->SendUserNotification(User,N);
}
/////
/////
/////
struct WebSocketNotificationRebootList {
std::string title,
details,
@@ -189,5 +193,58 @@ namespace OpenWifi {
WebSocketClientServer()->SendUserNotification(User,N);
}
/////
/////
/////
struct WebSocketNotificationUpgradeList {
std::string title,
details,
jobId;
std::vector<std::string> success,
skipped,
no_firmware,
not_connected;
uint64_t timeStamp=OpenWifi::Now();
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
typedef WebSocketNotification<WebSocketNotificationUpgradeList> WebSocketClientNotificationVenueUpgradeList_t;
inline void WebSocketNotificationUpgradeList::to_json(Poco::JSON::Object &Obj) const {
RESTAPI_utils::field_to_json(Obj,"title",title);
RESTAPI_utils::field_to_json(Obj,"jobId",jobId);
RESTAPI_utils::field_to_json(Obj,"success",success);
RESTAPI_utils::field_to_json(Obj,"notConnected",not_connected);
RESTAPI_utils::field_to_json(Obj,"noFirmware",no_firmware);
RESTAPI_utils::field_to_json(Obj,"skipped",skipped);
RESTAPI_utils::field_to_json(Obj,"timeStamp",timeStamp);
RESTAPI_utils::field_to_json(Obj,"details",details);
}
inline bool WebSocketNotificationUpgradeList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
RESTAPI_utils::field_from_json(Obj,"title",title);
RESTAPI_utils::field_from_json(Obj,"jobId",jobId);
RESTAPI_utils::field_from_json(Obj,"success",success);
RESTAPI_utils::field_from_json(Obj,"notConnected",not_connected);
RESTAPI_utils::field_from_json(Obj,"noFirmware",no_firmware);
RESTAPI_utils::field_from_json(Obj,"skipped",skipped);
RESTAPI_utils::field_from_json(Obj,"timeStamp",timeStamp);
RESTAPI_utils::field_from_json(Obj,"details",details);
return true;
} catch(...) {
}
return false;
}
inline void WebSocketClientNotificationVenueUpgradeCompletionToUser( const std::string & User, WebSocketClientNotificationVenueUpgradeList_t &N) {
N.type = "venue_upgrader";
WebSocketClientServer()->SendUserNotification(User,N);
}
} // namespace OpenWifi

View File

@@ -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;
}

File diff suppressed because it is too large Load Diff

7554
stats_sample/last_stats.json Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -144,25 +144,9 @@ logout() {
rm -rf token.json
}
venuecount() {
curl ${FLAGS} "https://${OWPROV}/api/v1/venue?countOnly=true" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${token}" \
-H "accept: application/json" > ${result_file}
jq < ${result_file}
}
contactcount() {
curl ${FLAGS} "https://${OWPROV}/api/v1/contact?countOnly=true" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${token}" \
-H "Accept: application/json" > ${result_file}
jq < ${result_file}
}
setloglevel() {
payload="{ \"command\" : \"setloglevel\" , \"subsystems\" : [ { \"tag\" : \"$1\" , \"value\" : \"$2\" } ] }"
curl ${FLAGS} -X POST "https://${OWPROV}/api/v1/system" \
curl ${FLAGS} -X POST "https://${OWANALYTICS}/api/v1/system" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${token}" \
@@ -171,7 +155,7 @@ setloglevel() {
getloglevels() {
payload="{ \"command\" : \"getloglevels\" }"
curl ${FLAGS} -X POST "https://${OWPROV}/api/v1/system" \
curl ${FLAGS} -X POST "https://${OWANALYTICS}/api/v1/system" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${token}" \
@@ -180,7 +164,7 @@ getloglevels() {
getloglevelnames() {
payload="{ \"command\" : \"getloglevelnames\" }"
curl ${FLAGS} -X POST "https://${OWPROV}/api/v1/system" \
curl ${FLAGS} -X POST "https://${OWANALYTICS}/api/v1/system" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${token}" \
@@ -189,7 +173,7 @@ getloglevelnames() {
getsubsystemnames() {
payload="{ \"command\" : \"getsubsystemnames\" }"
curl ${FLAGS} -X POST "https://${OWPROV}/api/v1/system" \
curl ${FLAGS} -X POST "https://${OWANALYTICS}/api/v1/system" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${token}" \
@@ -197,7 +181,7 @@ getsubsystemnames() {
}
systeminfo() {
curl ${FLAGS} -X GET "https://${OWPROV}/api/v1/system?command=info" \
curl ${FLAGS} -X GET "https://${OWANALYTICS}/api/v1/system?command=info" \
-H "Accept: application/json" \
-H "Authorization: Bearer ${token}" > ${result_file}
jq < ${result_file}
@@ -205,7 +189,7 @@ systeminfo() {
reloadsubsystem() {
payload="{ \"command\" : \"reload\", \"subsystems\" : [ \"$1\" ] }"
curl ${FLAGS} -X POST "https://${OWPROV}/api/v1/system" \
curl ${FLAGS} -X POST "https://${OWANALYTICS}/api/v1/system" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${token}" \

View File

@@ -1 +0,0 @@
{"children":[{"children":[{"children":[{"children":[],"name":"Ottawa Operations","type":"entity","uuid":"323054d0-3ff0-11ec-82ff-061b87871e04","venues":[{"children":[],"name":"Living Lab","type":"venue","uuid":"4159ea84-3ff0-11ec-9edb-061b87871e04"}]}],"name":"Ontario","type":"entity","uuid":"21dfa464-3ff0-11ec-9a86-061b87871e04","venues":[]},{"children":[{"children":[],"name":"Quebec","type":"entity","uuid":"27b74e1b-52d7-4414-a1b4-47574c799beb","venues":[]},{"children":[],"name":"Ontario","type":"entity","uuid":"3cb15a80-3550-11ec-9a22-061b87871e04","venues":[{"children":[],"name":"CN Tower","type":"venue","uuid":"3cb28f0e-3550-11ec-acfa-061b87871e04"},{"children":[],"name":"Rogers Center","type":"venue","uuid":"3cb3c798-3550-11ec-8c1a-061b87871e04"}]},{"children":[],"name":"BC","type":"entity","uuid":"3cb503c4-3550-11ec-b436-061b87871e04","venues":[{"children":[],"name":"BC Place","type":"venue","uuid":"3cb76452-3550-11ec-a5ab-061b87871e04"},{"children":[],"name":"Stanley Park","type":"venue","uuid":"3cb8b230-3550-11ec-bbe6-061b87871e04"},{"children":[],"name":"MegaLab","type":"venue","uuid":"a73a23c4-6f3d-4031-bc92-d28c205f2d85"},{"children":[],"name":"Bowen Development","type":"venue","uuid":"d656500b-9f00-4c09-9096-e209085c2a3e"}]}],"name":"Provinces","type":"entity","uuid":"3cac92ca-3550-11ec-b360-061b87871e04","venues":[]}],"name":"Canada","type":"entity","uuid":"3cab2c32-3550-11ec-8a03-061b87871e04","venues":[]},{"children":[],"name":"USA","type":"entity","uuid":"6392c6b3-ef48-4b81-8785-1b5b4888bbd2","venues":[]},{"children":[{"children":[],"name":"Hamburg","type":"entity","uuid":"5939f995-e059-439d-ab0c-29a6f7c0a495","venues":[]}],"name":"Germany","type":"entity","uuid":"6fb5662d-dc48-4fbd-b8f9-69d0308bb902","venues":[]},{"children":[],"name":"Test Land","type":"entity","uuid":"70161a6f-98af-45d7-b0ed-e6b15ba5d84e","venues":[{"children":[],"name":"Test","type":"venue","uuid":"1d06b289-449e-4669-abc9-1f2dcdd1fbbc"}]}],"name":"World","type":"entity","uuid":"0000-0000-0000","venues":[]}