mirror of
https://github.com/Telecominfraproject/wlan-cloud-owprov.git
synced 2025-11-01 19:17:47 +00:00
Compare commits
52 Commits
v2.6.0-RC2
...
v2.6.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7fcf2ca41b | ||
|
|
3c2017859b | ||
|
|
eecf9a49c2 | ||
|
|
5945d02b3d | ||
|
|
0ac192cdc0 | ||
|
|
1b5eb87eef | ||
|
|
46db18d7cd | ||
|
|
30b8665d7d | ||
|
|
c8b3a3b060 | ||
|
|
944500dea9 | ||
|
|
a5e0dcb210 | ||
|
|
096da35ff4 | ||
|
|
bd7f3af11c | ||
|
|
2a06021c4a | ||
|
|
bf18bb25ba | ||
|
|
656562c691 | ||
|
|
e93f899b76 | ||
|
|
eda73038f6 | ||
|
|
953ca155a4 | ||
|
|
898806f232 | ||
|
|
7d97b19b85 | ||
|
|
d6c587fde6 | ||
|
|
58c9a7805b | ||
|
|
94dd4c84e9 | ||
|
|
2636715f6f | ||
|
|
f9f4624add | ||
|
|
cf441de197 | ||
|
|
2ea7e3dcc5 | ||
|
|
158455a528 | ||
|
|
4d2ccec1a8 | ||
|
|
7dad5a9bdb | ||
|
|
cd2ac84c5b | ||
|
|
205343619b | ||
|
|
9735f709e9 | ||
|
|
ae5fd31818 | ||
|
|
aa1136e55b | ||
|
|
2b46ad4a66 | ||
|
|
439aa1d07a | ||
|
|
a9293a7717 | ||
|
|
43d7078cb7 | ||
|
|
18f5d42f00 | ||
|
|
70622b2bb8 | ||
|
|
5b24aea47c | ||
|
|
e97617a0db | ||
|
|
ba63a7033f | ||
|
|
e9db2e1a0d | ||
|
|
d85fef7725 | ||
|
|
543c46bf68 | ||
|
|
73eec53fe4 | ||
|
|
8ad2d67c2c | ||
|
|
442f810688 | ||
|
|
2dca5204ea |
9
.github/workflows/cleanup.yml
vendored
9
.github/workflows/cleanup.yml
vendored
@@ -4,6 +4,7 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
|
- 'release/*'
|
||||||
types: [ closed ]
|
types: [ closed ]
|
||||||
|
|
||||||
defaults:
|
defaults:
|
||||||
@@ -16,4 +17,10 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- run: |
|
- run: |
|
||||||
export PR_BRANCH_TAG=$(echo ${GITHUB_HEAD_REF#refs/heads/} | tr '/' '-')
|
export PR_BRANCH_TAG=$(echo ${GITHUB_HEAD_REF#refs/heads/} | tr '/' '-')
|
||||||
curl -uucentral:${{ secrets.DOCKER_REGISTRY_PASSWORD }} -X DELETE "https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral/owprov/$PR_BRANCH_TAG"
|
|
||||||
|
if [[ ! $PR_BRANCH_TAG =~ (main|master|release-*) ]]; then
|
||||||
|
echo "PR branch is $PR_BRANCH_TAG, deleting Docker image"
|
||||||
|
curl -s -uucentral:${{ secrets.DOCKER_REGISTRY_PASSWORD }} -X DELETE "https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral/owprov/$PR_BRANCH_TAG"
|
||||||
|
else
|
||||||
|
echo "PR branch is $PR_BRANCH_TAG, not deleting Docker image"
|
||||||
|
fi
|
||||||
|
|||||||
@@ -125,7 +125,6 @@ add_executable(owprov
|
|||||||
src/RESTAPI/RESTAPI_db_helpers.h
|
src/RESTAPI/RESTAPI_db_helpers.h
|
||||||
src/JobController.cpp src/JobController.h
|
src/JobController.cpp src/JobController.h
|
||||||
src/JobRegistrations.cpp
|
src/JobRegistrations.cpp
|
||||||
src/storage/storage_jobs.cpp src/storage/storage_jobs.h
|
|
||||||
src/storage/storage_maps.cpp src/storage/storage_maps.h
|
src/storage/storage_maps.cpp src/storage/storage_maps.h
|
||||||
src/RESTAPI/RESTAPI_map_handler.cpp src/RESTAPI/RESTAPI_map_handler.h
|
src/RESTAPI/RESTAPI_map_handler.cpp src/RESTAPI/RESTAPI_map_handler.h
|
||||||
src/RESTAPI/RESTAPI_map_list_handler.cpp src/RESTAPI/RESTAPI_map_list_handler.h
|
src/RESTAPI/RESTAPI_map_list_handler.cpp src/RESTAPI/RESTAPI_map_list_handler.h
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ if [ "$SELFSIGNED_CERTS" = 'true' ]; then
|
|||||||
update-ca-certificates
|
update-ca-certificates
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "$TEMPLATE_CONFIG" = 'true' && ! -f "$OWPROV_CONFIG"/owprov.properties ]]; then
|
if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then
|
||||||
RESTAPI_HOST_ROOTCA=${RESTAPI_HOST_ROOTCA:-"\$OWPROV_ROOT/certs/restapi-ca.pem"} \
|
RESTAPI_HOST_ROOTCA=${RESTAPI_HOST_ROOTCA:-"\$OWPROV_ROOT/certs/restapi-ca.pem"} \
|
||||||
RESTAPI_HOST_PORT=${RESTAPI_HOST_PORT:-"16005"} \
|
RESTAPI_HOST_PORT=${RESTAPI_HOST_PORT:-"16005"} \
|
||||||
RESTAPI_HOST_CERT=${RESTAPI_HOST_CERT:-"\$OWPROV_ROOT/certs/restapi-cert.pem"} \
|
RESTAPI_HOST_CERT=${RESTAPI_HOST_CERT:-"\$OWPROV_ROOT/certs/restapi-cert.pem"} \
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ fullnameOverride: ""
|
|||||||
images:
|
images:
|
||||||
owprov:
|
owprov:
|
||||||
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owprov
|
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owprov
|
||||||
tag: v2.6.0-RC2
|
tag: v2.6.0
|
||||||
pullPolicy: Always
|
pullPolicy: Always
|
||||||
# regcred:
|
# regcred:
|
||||||
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io
|
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io
|
||||||
|
|||||||
@@ -27,71 +27,13 @@ components:
|
|||||||
|
|
||||||
responses:
|
responses:
|
||||||
NotFound:
|
NotFound:
|
||||||
description: The specified resource was not found.
|
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/NotFound'
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
properties:
|
|
||||||
ErrorCode:
|
|
||||||
type: integer
|
|
||||||
ErrorDetails:
|
|
||||||
type: string
|
|
||||||
ErrorDescription:
|
|
||||||
type: string
|
|
||||||
|
|
||||||
Unauthorized:
|
Unauthorized:
|
||||||
description: The requested does not have sufficient rights to perform the operation.
|
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Unauthorized'
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
properties:
|
|
||||||
ErrorCode:
|
|
||||||
type: integer
|
|
||||||
enum:
|
|
||||||
- 0 # Success
|
|
||||||
- 1 # PASSWORD_CHANGE_REQUIRED,
|
|
||||||
- 2 # INVALID_CREDENTIALS,
|
|
||||||
- 3 # PASSWORD_ALREADY_USED,
|
|
||||||
- 4 # USERNAME_PENDING_VERIFICATION,
|
|
||||||
- 5 # PASSWORD_INVALID,
|
|
||||||
- 6 # INTERNAL_ERROR,
|
|
||||||
- 7 # ACCESS_DENIED,
|
|
||||||
- 8 # INVALID_TOKEN
|
|
||||||
- 9 # EXPIRED_TOKEN
|
|
||||||
- 10 # RATE_LIMIT_EXCEEDED
|
|
||||||
- 11 # BAD_MFA_TRANSACTION
|
|
||||||
- 12 # MFA_FAILURE
|
|
||||||
- 13 # SECURITY_SERVICE_UNREACHABLE
|
|
||||||
ErrorDetails:
|
|
||||||
type: string
|
|
||||||
ErrorDescription:
|
|
||||||
type: string
|
|
||||||
|
|
||||||
Success:
|
Success:
|
||||||
description: The requested operation was performed.
|
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Success'
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
properties:
|
|
||||||
Operation:
|
|
||||||
type: string
|
|
||||||
Details:
|
|
||||||
type: string
|
|
||||||
Code:
|
|
||||||
type: integer
|
|
||||||
|
|
||||||
BadRequest:
|
BadRequest:
|
||||||
description: The requested operation failed.
|
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/BadRequest'
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
properties:
|
|
||||||
ErrorCode:
|
|
||||||
type: integer
|
|
||||||
ErrorDetails:
|
|
||||||
type: string
|
|
||||||
ErrorDescription:
|
|
||||||
type: integer
|
|
||||||
|
|
||||||
schemas:
|
schemas:
|
||||||
|
|
||||||
|
|||||||
@@ -153,60 +153,62 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<std::string> Sections;
|
try {
|
||||||
for(const auto &i:Config_) {
|
std::set<std::string> Sections;
|
||||||
Poco::JSON::Parser P;
|
for (const auto &i: Config_) {
|
||||||
auto O = P.parse(i.element.configuration).extract<Poco::JSON::Object::Ptr>();
|
Poco::JSON::Parser P;
|
||||||
auto Names = O->getNames();
|
auto O = P.parse(i.element.configuration).extract<Poco::JSON::Object::Ptr>();
|
||||||
for(const auto &SectionName:Names) {
|
auto Names = O->getNames();
|
||||||
auto InsertInfo = Sections.insert(SectionName);
|
for (const auto &SectionName: Names) {
|
||||||
if (InsertInfo.second) {
|
auto InsertInfo = Sections.insert(SectionName);
|
||||||
if (O->isArray(SectionName)) {
|
if (InsertInfo.second) {
|
||||||
auto OriginalArray = O->getArray(SectionName);
|
if (O->isArray(SectionName)) {
|
||||||
if (Explain_) {
|
auto OriginalArray = O->getArray(SectionName);
|
||||||
Poco::JSON::Object ExObj;
|
if (Explain_) {
|
||||||
ExObj.set("from-uuid", i.info.id);
|
Poco::JSON::Object ExObj;
|
||||||
ExObj.set("from-name", i.info.name);
|
ExObj.set("from-uuid", i.info.id);
|
||||||
ExObj.set("action", "added");
|
ExObj.set("from-name", i.info.name);
|
||||||
ExObj.set("element", OriginalArray);
|
ExObj.set("action", "added");
|
||||||
Explanation_.add(ExObj);
|
ExObj.set("element", OriginalArray);
|
||||||
|
Explanation_.add(ExObj);
|
||||||
|
}
|
||||||
|
auto ExpandedArray = Poco::makeShared<Poco::JSON::Array>();
|
||||||
|
ReplaceVariablesInArray(OriginalArray, ExpandedArray);
|
||||||
|
Configuration->set(SectionName, ExpandedArray);
|
||||||
|
} else if (O->isObject(SectionName)) {
|
||||||
|
auto OriginalSection = O->get(SectionName).extract<Poco::JSON::Object::Ptr>();
|
||||||
|
if (Explain_) {
|
||||||
|
Poco::JSON::Object ExObj;
|
||||||
|
ExObj.set("from-uuid", i.info.id);
|
||||||
|
ExObj.set("from-name", i.info.name);
|
||||||
|
ExObj.set("action", "added");
|
||||||
|
ExObj.set("element", OriginalSection);
|
||||||
|
Explanation_.add(ExObj);
|
||||||
|
}
|
||||||
|
auto ExpandedSection = Poco::makeShared<Poco::JSON::Object>();
|
||||||
|
ReplaceVariablesInObject(OriginalSection, ExpandedSection);
|
||||||
|
Configuration->set(SectionName, ExpandedSection);
|
||||||
|
} else {
|
||||||
|
std::cout << " --- unknown element type --- " << O->get(SectionName).toString()
|
||||||
|
<< std::endl;
|
||||||
}
|
}
|
||||||
auto ExpandedArray = Poco::makeShared<Poco::JSON::Array>();
|
|
||||||
ReplaceVariablesInArray(OriginalArray, ExpandedArray);
|
|
||||||
Configuration->set(SectionName, ExpandedArray);
|
|
||||||
} else if (O->isObject(SectionName)) {
|
|
||||||
auto OriginalSection = O->get(SectionName).extract<Poco::JSON::Object::Ptr>();
|
|
||||||
if (Explain_) {
|
|
||||||
Poco::JSON::Object ExObj;
|
|
||||||
ExObj.set("from-uuid", i.info.id);
|
|
||||||
ExObj.set("from-name", i.info.name);
|
|
||||||
ExObj.set("action", "added");
|
|
||||||
ExObj.set("element", OriginalSection);
|
|
||||||
Explanation_.add(ExObj);
|
|
||||||
}
|
|
||||||
auto ExpandedSection = Poco::makeShared<Poco::JSON::Object>();
|
|
||||||
ReplaceVariablesInObject(OriginalSection, ExpandedSection);
|
|
||||||
Configuration->set(SectionName, ExpandedSection);
|
|
||||||
} else {
|
} else {
|
||||||
std::cout << " --- unknown element type --- " << O->get(SectionName).toString() << std::endl;
|
if (Explain_) {
|
||||||
}
|
Poco::JSON::Object ExObj;
|
||||||
} else {
|
ExObj.set("from-uuid", i.info.id);
|
||||||
if (Explain_) {
|
ExObj.set("from-name", i.info.name);
|
||||||
Poco::JSON::Object ExObj;
|
ExObj.set("action", "ignored");
|
||||||
ExObj.set("from-uuid", i.info.id);
|
ExObj.set("reason", "weight insufficient");
|
||||||
ExObj.set("from-name", i.info.name);
|
ExObj.set("element", O->get(SectionName));
|
||||||
ExObj.set("action", "ignored");
|
Explanation_.add(ExObj);
|
||||||
ExObj.set("reason", "weight insufficient");
|
}
|
||||||
ExObj.set("element", O->get(SectionName));
|
|
||||||
Explanation_.add(ExObj);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} catch (...) {
|
||||||
if(Config_.empty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
}
|
||||||
|
return !Config_.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool DeviceTypeMatch(const std::string &DeviceType, const Types::StringVec & Types) {
|
static bool DeviceTypeMatch(const std::string &DeviceType, const Types::StringVec & Types) {
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
void AutoDiscovery::run() {
|
void AutoDiscovery::run() {
|
||||||
Poco::AutoPtr<Poco::Notification> Note(Queue_.waitDequeueNotification());
|
Poco::AutoPtr<Poco::Notification> Note(Queue_.waitDequeueNotification());
|
||||||
|
Utils::SetThreadName("auto-discovery");
|
||||||
while(Note && Running_) {
|
while(Note && Running_) {
|
||||||
auto Msg = dynamic_cast<DiscoveryMessage *>(Note.get());
|
auto Msg = dynamic_cast<DiscoveryMessage *>(Note.get());
|
||||||
if(Msg!= nullptr) {
|
if(Msg!= nullptr) {
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ namespace OpenWifi {
|
|||||||
void Stop() override;
|
void Stop() override;
|
||||||
void ConnectionReceived( const std::string & Key, const std::string & Payload) {
|
void ConnectionReceived( const std::string & Key, const std::string & Payload) {
|
||||||
std::lock_guard G(Mutex_);
|
std::lock_guard G(Mutex_);
|
||||||
Logger().information(Poco::format("Device(%s): Connection/Ping message.", Key));
|
poco_debug(Logger(),Poco::format("Device(%s): Connection/Ping message.", Key));
|
||||||
Queue_.enqueueNotification( new DiscoveryMessage(Key,Payload));
|
Queue_.enqueueNotification( new DiscoveryMessage(Key,Payload));
|
||||||
}
|
}
|
||||||
void run() override;
|
void run() override;
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ namespace OpenWifi {
|
|||||||
{"https://ucentral.io/ucentral.schema.pretty.json", "ucentral.schema.pretty.json" }
|
{"https://ucentral.io/ucentral.schema.pretty.json", "ucentral.schema.pretty.json" }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Utils::SetThreadName("file-dmnldr");
|
||||||
|
|
||||||
for(const auto &[url,filename]:Files) {
|
for(const auto &[url,filename]:Files) {
|
||||||
try {
|
try {
|
||||||
std::string FileContent;
|
std::string FileContent;
|
||||||
|
|||||||
@@ -27,11 +27,32 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
void JobController::run() {
|
void JobController::run() {
|
||||||
Running_ = true ;
|
Running_ = true ;
|
||||||
|
Utils::SetThreadName("job-controller");
|
||||||
while(Running_) {
|
while(Running_) {
|
||||||
Poco::Thread::trySleep(2000);
|
Poco::Thread::trySleep(2000);
|
||||||
|
|
||||||
|
std::lock_guard G(Mutex_);
|
||||||
|
|
||||||
|
for(auto ¤t_job:jobs_) {
|
||||||
|
if(current_job!=nullptr) {
|
||||||
|
if(current_job->Started()==0 && Pool_.used()<Pool_.available()) {
|
||||||
|
current_job->Logger().information(fmt::format("Starting {}: {}",current_job->JobId(),current_job->Name()));
|
||||||
|
current_job->Start();
|
||||||
|
Pool_.start(*current_job);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(auto it = jobs_.begin(); it!=jobs_.end();) {\
|
||||||
|
auto current_job = *it;
|
||||||
|
if(current_job!=nullptr && current_job->Completed()!=0) {
|
||||||
|
current_job->Logger().information(fmt::format("Completed {}: {}",current_job->JobId(),current_job->Name()));
|
||||||
|
it = jobs_.erase(it);
|
||||||
|
delete current_job;
|
||||||
|
} else {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -7,99 +7,45 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <list>
|
||||||
#include "framework/MicroService.h"
|
#include "framework/MicroService.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
class Job {
|
class Job : public Poco::Runnable {
|
||||||
public:
|
public:
|
||||||
struct Parameter {
|
Job(const std::string &JobID, const std::string &name, const std::vector<std::string> & parameters, uint64_t when, const SecurityObjects::UserInfo &UI, Poco::Logger &L) :
|
||||||
std::string name;
|
jobId_(JobID),
|
||||||
std::string value;
|
name_(name),
|
||||||
inline void to_json(Poco::JSON::Object &Obj) const {
|
parameters_(parameters),
|
||||||
RESTAPI_utils::field_to_json(Obj,"name",name);
|
when_(when),
|
||||||
RESTAPI_utils::field_to_json(Obj,"value",value);
|
userinfo_(UI),
|
||||||
}
|
Logger_(L)
|
||||||
|
{};
|
||||||
|
|
||||||
inline bool from_json(const Poco::JSON::Object::Ptr &Obj) {
|
virtual void run() = 0;
|
||||||
try {
|
[[nodiscard]] std::string Name() const { return name_; }
|
||||||
RESTAPI_utils::field_from_json(Obj,"name",name);
|
const SecurityObjects::UserInfo & UserInfo() const { return userinfo_; }
|
||||||
RESTAPI_utils::field_from_json(Obj,"value",value);
|
Poco::Logger & Logger() { return Logger_; }
|
||||||
return true;
|
const std::string & JobId() const { return jobId_; }
|
||||||
} catch (...) {
|
const std::string & Parameter(int x) const { return parameters_[x];}
|
||||||
|
uint64_t When() const { return when_; }
|
||||||
|
void Start() { started_ = OpenWifi::Now(); }
|
||||||
|
uint64_t Started() const { return started_; }
|
||||||
|
uint64_t Completed() const { return completed_;}
|
||||||
|
void Complete() { completed_ = OpenWifi::Now(); }
|
||||||
|
|
||||||
}
|
private:
|
||||||
return false;
|
std::string jobId_;
|
||||||
}
|
std::string name_;
|
||||||
};
|
std::vector<std::string> parameters_;
|
||||||
|
uint64_t when_=0;
|
||||||
struct Status {
|
SecurityObjects::UserInfo userinfo_;
|
||||||
Types::UUID_t UUID;
|
Poco::Logger & Logger_;
|
||||||
uint64_t Start = 0 ;
|
uint64_t started_=0;
|
||||||
uint64_t Progress = 0 ;
|
uint64_t completed_=0;
|
||||||
uint64_t Completed = 0 ;
|
|
||||||
std::string CurrentDisplay;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Result {
|
|
||||||
int Error=0;
|
|
||||||
std::string Reason;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::vector<Parameter> Parameters;
|
|
||||||
typedef std::vector<Parameters> ParametersVec;
|
|
||||||
typedef std::function<bool(const Parameters &Parameters, Result &Result, bool &Retry)> WorkerFunction;
|
|
||||||
typedef std::vector<Status> Statuses;
|
|
||||||
|
|
||||||
Job(std::string Title,
|
|
||||||
std::string Description,
|
|
||||||
std::string RegisteredName,
|
|
||||||
ParametersVec Parameters,
|
|
||||||
[[maybe_unused]] bool Parallel=true) :
|
|
||||||
Title_(std::move(Title)),
|
|
||||||
Description_(std::move(Description)),
|
|
||||||
RegisteredName_(std::move(RegisteredName)),
|
|
||||||
Parameters_(std::move(Parameters))
|
|
||||||
{
|
|
||||||
UUID_ = MicroService::instance().CreateUUID();
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] inline const Types::UUID_t & ID() const { return UUID_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
Types::UUID_t UUID_;
|
|
||||||
std::string Title_;
|
|
||||||
std::string Description_;
|
|
||||||
std::string RegisteredName_;
|
|
||||||
ParametersVec Parameters_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class JobRegistry {
|
|
||||||
public:
|
|
||||||
static auto instance() {
|
|
||||||
static auto instance_ = new JobRegistry;
|
|
||||||
return instance_;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void RegisterJobType( const std::string & JobType, Job::WorkerFunction Function) {
|
|
||||||
JobTypes_[JobType] = std::move(Function);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool Execute(const std::string &JobType, const Job::Parameters & Params, Job::Result &Result, bool & Retry) {
|
|
||||||
auto Hint = JobTypes_.find(JobType);
|
|
||||||
if(Hint != end(JobTypes_)) {
|
|
||||||
Hint->second(Params, Result, Retry);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::map<std::string,Job::WorkerFunction> JobTypes_;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline auto JobRegistry() { return JobRegistry::instance(); }
|
|
||||||
|
|
||||||
class JobController : public SubSystemServer, Poco::Runnable {
|
class JobController : public SubSystemServer, Poco::Runnable {
|
||||||
public:
|
public:
|
||||||
static auto instance() {
|
static auto instance() {
|
||||||
@@ -112,11 +58,16 @@ namespace OpenWifi {
|
|||||||
void run() override;
|
void run() override;
|
||||||
inline void wakeup() { Thr_.wakeUp(); }
|
inline void wakeup() { Thr_.wakeUp(); }
|
||||||
|
|
||||||
bool JobList(Job::Statuses & Statuses);
|
void AddJob( Job* newJob ) {
|
||||||
|
std::lock_guard G(Mutex_);
|
||||||
|
jobs_.push_back(newJob);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Poco::Thread Thr_;
|
Poco::Thread Thr_;
|
||||||
std::atomic_bool Running_=false;
|
std::atomic_bool Running_=false;
|
||||||
|
std::list<Job *> jobs_;
|
||||||
|
Poco::ThreadPool Pool_;
|
||||||
|
|
||||||
JobController() noexcept:
|
JobController() noexcept:
|
||||||
SubSystemServer("JobController", "JOB-SVR", "job")
|
SubSystemServer("JobController", "JOB-SVR", "job")
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ namespace OpenWifi{
|
|||||||
for (const auto &i: V.children) {
|
for (const auto &i: V.children) {
|
||||||
ProvObjects::Venue V2;
|
ProvObjects::Venue V2;
|
||||||
if (StorageService()->VenueDB().GetRecord("id", i, V2)) {
|
if (StorageService()->VenueDB().GetRecord("id", i, V2)) {
|
||||||
|
std::copy(V2.devices.begin(),V2.devices.end(),std::back_inserter(R));
|
||||||
auto LowerDevs = GetDevices(V2, GetChildren);
|
auto LowerDevs = GetDevices(V2, GetChildren);
|
||||||
std::copy(LowerDevs.begin(), LowerDevs.end(), std::back_inserter(R));
|
std::copy(LowerDevs.begin(), LowerDevs.end(), std::back_inserter(R));
|
||||||
}
|
}
|
||||||
@@ -227,10 +228,10 @@ namespace OpenWifi{
|
|||||||
|
|
||||||
Poco::JSON::Object Answer;
|
Poco::JSON::Object Answer;
|
||||||
SNL.serialNumbers = Existing.devices;
|
SNL.serialNumbers = Existing.devices;
|
||||||
|
auto JobId = MicroService::instance().CreateUUID();
|
||||||
auto Task = new VenueConfigUpdater(UUID,UserInfo_.userinfo,0,Logger());
|
Types::StringVec Parameters{UUID};;
|
||||||
auto JobId = Task->Start();
|
auto NewJob = new VenueConfigUpdater(JobId,"VenueConfigurationUpdater", Parameters, 0, UserInfo_.userinfo, Logger());
|
||||||
|
JobController()->AddJob(dynamic_cast<Job*>(NewJob));
|
||||||
SNL.to_json(Answer);
|
SNL.to_json(Answer);
|
||||||
Answer.set("jobId",JobId);
|
Answer.set("jobId",JobId);
|
||||||
return ReturnObject(Answer);
|
return ReturnObject(Answer);
|
||||||
@@ -241,10 +242,10 @@ namespace OpenWifi{
|
|||||||
|
|
||||||
Poco::JSON::Object Answer;
|
Poco::JSON::Object Answer;
|
||||||
SNL.serialNumbers = Existing.devices;
|
SNL.serialNumbers = Existing.devices;
|
||||||
|
auto JobId = MicroService::instance().CreateUUID();
|
||||||
auto Task = new VenueUpgrade(UUID,UserInfo_.userinfo,0,Logger());
|
Types::StringVec Parameters{UUID};;
|
||||||
auto JobId = Task->Start();
|
auto NewJob = new VenueUpgrade(JobId,"VenueFirmwareUpgrade", Parameters, 0, UserInfo_.userinfo, Logger());
|
||||||
|
JobController()->AddJob(dynamic_cast<Job*>(NewJob));
|
||||||
SNL.to_json(Answer);
|
SNL.to_json(Answer);
|
||||||
Answer.set("jobId",JobId);
|
Answer.set("jobId",JobId);
|
||||||
return ReturnObject(Answer);
|
return ReturnObject(Answer);
|
||||||
@@ -255,10 +256,10 @@ namespace OpenWifi{
|
|||||||
|
|
||||||
Poco::JSON::Object Answer;
|
Poco::JSON::Object Answer;
|
||||||
SNL.serialNumbers = Existing.devices;
|
SNL.serialNumbers = Existing.devices;
|
||||||
|
auto JobId = MicroService::instance().CreateUUID();
|
||||||
auto Task = new VenueRebooter(UUID,UserInfo_.userinfo,0,Logger());
|
Types::StringVec Parameters{UUID};;
|
||||||
auto JobId = Task->Start();
|
auto NewJob = new VenueRebooter(JobId,"VenueRebooter", Parameters, 0, UserInfo_.userinfo, Logger());
|
||||||
|
JobController()->AddJob(dynamic_cast<Job*>(NewJob));
|
||||||
SNL.to_json(Answer);
|
SNL.to_json(Answer);
|
||||||
Answer.set("jobId",JobId);
|
Answer.set("jobId",JobId);
|
||||||
return ReturnObject(Answer);
|
return ReturnObject(Answer);
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
void Signup::run() {
|
void Signup::run() {
|
||||||
Running_ = true;
|
Running_ = true;
|
||||||
|
Utils::SetThreadName("signup-mgr");
|
||||||
while(Running_) {
|
while(Running_) {
|
||||||
Poco::Thread::trySleep(5000);
|
Poco::Thread::trySleep(5000);
|
||||||
|
|
||||||
|
|||||||
@@ -105,6 +105,7 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Storage::onTimer([[maybe_unused]] Poco::Timer &timer) {
|
void Storage::onTimer([[maybe_unused]] Poco::Timer &timer) {
|
||||||
|
Utils::SetThreadName("strg-janitor");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Storage::Stop() {
|
void Storage::Stop() {
|
||||||
@@ -213,31 +214,109 @@ namespace OpenWifi {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto FixEntityDevices = [&](const ProvObjects::Entity &E) -> bool {
|
auto FixEntity = [&](const ProvObjects::Entity &E) -> bool {
|
||||||
Types::UUIDvec_t NewDevices;
|
Types::UUIDvec_t NewDevices;
|
||||||
|
bool Modified=false;
|
||||||
for(const auto &device:E.devices) {
|
for(const auto &device:E.devices) {
|
||||||
ProvObjects::InventoryTag T;
|
ProvObjects::InventoryTag T;
|
||||||
if(InventoryDB().GetRecord("id", device, T)) {
|
if(InventoryDB().GetRecord("id", device, T)) {
|
||||||
NewDevices.emplace_back(device);
|
NewDevices.emplace_back(device);
|
||||||
} else {
|
} else {
|
||||||
|
Modified=true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(NewDevices!=E.devices) {
|
Types::UUIDvec_t NewContacts;
|
||||||
|
for(const auto &contact:E.contacts) {
|
||||||
|
ProvObjects::Contact C;
|
||||||
|
if(ContactDB().GetRecord("id", contact, C)) {
|
||||||
|
NewContacts.emplace_back(contact);
|
||||||
|
} else {
|
||||||
|
Modified=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Types::UUIDvec_t NewLocations;
|
||||||
|
for(const auto &location:E.locations) {
|
||||||
|
ProvObjects::Location L;
|
||||||
|
if(LocationDB().GetRecord("id", location, L)) {
|
||||||
|
NewLocations.emplace_back(location);
|
||||||
|
} else {
|
||||||
|
Modified=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Types::UUIDvec_t NewVenues;
|
||||||
|
for(const auto &venue:E.venues) {
|
||||||
|
ProvObjects::Venue V;
|
||||||
|
if(VenueDB().GetRecord("id", venue, V)) {
|
||||||
|
NewVenues.emplace_back(venue);
|
||||||
|
} else {
|
||||||
|
Modified=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Types::UUIDvec_t NewVariables;
|
||||||
|
for(const auto &variable:E.variables) {
|
||||||
|
ProvObjects::VariableBlock V;
|
||||||
|
if(VariablesDB().GetRecord("id", variable, V)) {
|
||||||
|
NewVariables.emplace_back(variable);
|
||||||
|
} else {
|
||||||
|
Modified=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Modified)
|
||||||
|
{
|
||||||
Logger().warning(fmt::format(" fixing entity: {}",E.info.name));
|
Logger().warning(fmt::format(" fixing entity: {}",E.info.name));
|
||||||
ProvObjects::Entity NewEntity = E;
|
ProvObjects::Entity NewEntity = E;
|
||||||
NewEntity.devices = NewDevices;
|
NewEntity.devices = NewDevices;
|
||||||
|
NewEntity.contacts = NewContacts;
|
||||||
|
NewEntity.locations = NewLocations;
|
||||||
|
NewEntity.venues = NewVenues;
|
||||||
|
NewEntity.variables = NewVariables;
|
||||||
EntityDB().UpdateRecord("id", E.info.id, NewEntity);
|
EntityDB().UpdateRecord("id", E.info.id, NewEntity);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto FixInventory = [&](const ProvObjects::InventoryTag &T) -> bool {
|
||||||
|
// check the venue/entity for this device.
|
||||||
|
ProvObjects::InventoryTag NewTag{T};
|
||||||
|
bool modified=false;
|
||||||
|
if(!T.venue.empty() && !VenueDB().Exists("id",T.venue)) {
|
||||||
|
NewTag.venue.clear();
|
||||||
|
modified=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!T.entity.empty() && !EntityDB().Exists("id",T.entity)) {
|
||||||
|
NewTag.entity.clear();
|
||||||
|
modified=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!T.location.empty() && !LocationDB().Exists("id",T.location)) {
|
||||||
|
NewTag.location.clear();
|
||||||
|
modified=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!T.contact.empty() && !ContactDB().Exists("id",T.contact)) {
|
||||||
|
NewTag.contact.clear();
|
||||||
|
modified=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(modified) {
|
||||||
|
Logger().warning(fmt::format(" fixing entity: {}",T.info.name));
|
||||||
|
InventoryDB().UpdateRecord("id", T.info.id, NewTag);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
Logger().information("Checking DB consistency: venues");
|
Logger().information("Checking DB consistency: venues");
|
||||||
VenueDB().Iterate(FixVenueDevices);
|
VenueDB().Iterate(FixVenueDevices);
|
||||||
Logger().information("Checking DB consistency: entities");
|
Logger().information("Checking DB consistency: entities");
|
||||||
EntityDB().Iterate(FixEntityDevices);
|
EntityDB().Iterate(FixEntity);
|
||||||
|
Logger().information("Checking DB consistency: inventory");
|
||||||
|
InventoryDB().Iterate(FixInventory);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Storage::InitializeSystemDBs() {
|
void Storage::InitializeSystemDBs() {
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TagServer::run() {
|
void TagServer::run() {
|
||||||
|
Utils::SetThreadName("tag-server");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "APConfig.h"
|
#include "APConfig.h"
|
||||||
#include "sdks/SDK_gw.h"
|
#include "sdks/SDK_gw.h"
|
||||||
#include "framework/WebSocketClientNotifications.h"
|
#include "framework/WebSocketClientNotifications.h"
|
||||||
|
#include "JobController.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
@@ -19,8 +20,6 @@ namespace OpenWifi {
|
|||||||
auto Status = Results->get("status").extract<Poco::JSON::Object::Ptr>();
|
auto Status = Results->get("status").extract<Poco::JSON::Object::Ptr>();
|
||||||
auto Rejected = Status->getArray("rejected");
|
auto Rejected = Status->getArray("rejected");
|
||||||
std::transform(Rejected->begin(),Rejected->end(),std::back_inserter(Warnings), [](auto i) -> auto { return i.toString(); });
|
std::transform(Rejected->begin(),Rejected->end(),std::back_inserter(Warnings), [](auto i) -> auto { return i.toString(); });
|
||||||
// for(const auto &i:*Rejected)
|
|
||||||
// Warnings.push_back(i.toString());
|
|
||||||
}
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
}
|
}
|
||||||
@@ -37,35 +36,42 @@ namespace OpenWifi {
|
|||||||
void run() final {
|
void run() final {
|
||||||
ProvObjects::InventoryTag Device;
|
ProvObjects::InventoryTag Device;
|
||||||
started_=true;
|
started_=true;
|
||||||
|
Utils::SetThreadName("venue-cfg");
|
||||||
if(StorageService()->InventoryDB().GetRecord("id",uuid_,Device)) {
|
if(StorageService()->InventoryDB().GetRecord("id",uuid_,Device)) {
|
||||||
SerialNumber = Device.serialNumber;
|
SerialNumber = Device.serialNumber;
|
||||||
// std::cout << "Starting push for " << Device.serialNumber << std::endl;
|
// std::cout << "Starting push for " << Device.serialNumber << std::endl;
|
||||||
Logger().debug(fmt::format("{}: Computing configuration.",Device.serialNumber));
|
Logger().debug(fmt::format("{}: Computing configuration.",Device.serialNumber));
|
||||||
auto DeviceConfig = std::make_shared<APConfig>(Device.serialNumber, Device.deviceType, Logger(), false);
|
auto DeviceConfig = std::make_shared<APConfig>(Device.serialNumber, Device.deviceType, Logger(), false);
|
||||||
auto Configuration = Poco::makeShared<Poco::JSON::Object>();
|
auto Configuration = Poco::makeShared<Poco::JSON::Object>();
|
||||||
if (DeviceConfig->Get(Configuration)) {
|
try {
|
||||||
std::ostringstream OS;
|
if (DeviceConfig->Get(Configuration)) {
|
||||||
Configuration->stringify(OS);
|
std::ostringstream OS;
|
||||||
auto Response=Poco::makeShared<Poco::JSON::Object>();
|
Configuration->stringify(OS);
|
||||||
Logger().debug(fmt::format("{}: Pushing configuration.",Device.serialNumber));
|
auto Response = Poco::makeShared<Poco::JSON::Object>();
|
||||||
if (SDK::GW::Device::Configure(nullptr, Device.serialNumber, Configuration, Response)) {
|
Logger().debug(fmt::format("{}: Pushing configuration.", Device.serialNumber));
|
||||||
Logger().debug(fmt::format("{}: Configuration pushed.",Device.serialNumber));
|
if (SDK::GW::Device::Configure(nullptr, Device.serialNumber, Configuration, Response)) {
|
||||||
Logger().information(fmt::format("{}: Updated.", Device.serialNumber));
|
Logger().debug(fmt::format("{}: Configuration pushed.", Device.serialNumber));
|
||||||
// std::cout << Device.serialNumber << ": Updated" << std::endl;
|
Logger().information(fmt::format("{}: Updated.", Device.serialNumber));
|
||||||
updated_++;
|
// std::cout << Device.serialNumber << ": Updated" << std::endl;
|
||||||
|
updated_++;
|
||||||
|
} else {
|
||||||
|
Logger().information(fmt::format("{}: Not updated.", Device.serialNumber));
|
||||||
|
// std::cout << Device.serialNumber << ": Failed" << std::endl;
|
||||||
|
failed_++;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Logger().information(fmt::format("{}: Not updated.", Device.serialNumber));
|
Logger().debug(fmt::format("{}: Configuration is bad.", Device.serialNumber));
|
||||||
// std::cout << Device.serialNumber << ": Failed" << std::endl;
|
bad_config_++;
|
||||||
failed_++;
|
// std::cout << Device.serialNumber << ": Bad config" << std::endl;
|
||||||
}
|
}
|
||||||
} else {
|
} catch (...) {
|
||||||
Logger().debug(fmt::format("{}: Configuration is bad.",Device.serialNumber));
|
Logger().debug(fmt::format("{}: Configuration is bad (caused an exception).", Device.serialNumber));
|
||||||
bad_config_++;
|
bad_config_++;
|
||||||
// std::cout << Device.serialNumber << ": Bad config" << std::endl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
done_ = true;
|
done_ = true;
|
||||||
// std::cout << "Done push for " << Device.serialNumber << std::endl;
|
// std::cout << "Done push for " << Device.serialNumber << std::endl;
|
||||||
|
Utils::SetThreadName("free");
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t updated_=0, failed_=0, bad_config_=0;
|
uint64_t updated_=0, failed_=0, bad_config_=0;
|
||||||
@@ -80,133 +86,101 @@ namespace OpenWifi {
|
|||||||
inline Poco::Logger & Logger() { return Logger_; }
|
inline Poco::Logger & Logger() { return Logger_; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class VenueConfigUpdater: public Poco::Runnable {
|
class VenueConfigUpdater: public Job {
|
||||||
public:
|
public:
|
||||||
explicit VenueConfigUpdater(const std::string & VenueUUID, const SecurityObjects::UserInfo &UI, uint64_t When, Poco::Logger &L) :
|
VenueConfigUpdater(const std::string &JobID, const std::string &name, const std::vector<std::string> & parameters, uint64_t when, const SecurityObjects::UserInfo &UI, Poco::Logger &L) :
|
||||||
VenueUUID_(VenueUUID),
|
Job(JobID, name, parameters, when, UI, L) {
|
||||||
UI_(UI),
|
|
||||||
When_(When),
|
|
||||||
Logger_(L)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string Start() {
|
inline virtual void run() {
|
||||||
JobId_ = MicroService::CreateUUID();
|
std::string VenueUUID_;
|
||||||
Worker_.start(*this);
|
|
||||||
return JobId_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
Utils::SetThreadName("venue-update");
|
||||||
std::string VenueUUID_;
|
VenueUUID_ = Parameter(0);
|
||||||
SecurityObjects::UserInfo UI_;
|
|
||||||
uint64_t When_;
|
|
||||||
Poco::Logger &Logger_;
|
|
||||||
Poco::Thread Worker_;
|
|
||||||
std::string JobId_;
|
|
||||||
Poco::ThreadPool Pool_{2,16,300};
|
|
||||||
|
|
||||||
inline Poco::Logger & Logger() { return Logger_; }
|
|
||||||
|
|
||||||
inline void run() final {
|
|
||||||
|
|
||||||
if(When_ && When_>OpenWifi::Now())
|
|
||||||
Poco::Thread::trySleep( (long) (When_ - OpenWifi::Now()) * 1000 );
|
|
||||||
|
|
||||||
WebSocketNotification<WebSocketNotificationJobContent> N;
|
WebSocketNotification<WebSocketNotificationJobContent> N;
|
||||||
|
|
||||||
Logger().information(fmt::format("Job {} Starting.", JobId_));
|
|
||||||
|
|
||||||
ProvObjects::Venue Venue;
|
ProvObjects::Venue Venue;
|
||||||
uint64_t Updated = 0, Failed = 0 , BadConfigs = 0 ;
|
uint64_t Updated = 0, Failed = 0 , BadConfigs = 0 ;
|
||||||
if(StorageService()->VenueDB().GetRecord("id",VenueUUID_,Venue)) {
|
if(StorageService()->VenueDB().GetRecord("id",VenueUUID_,Venue)) {
|
||||||
const std::size_t MaxThreads=16;
|
|
||||||
struct tState {
|
|
||||||
Poco::Thread thr_;
|
|
||||||
VenueDeviceConfigUpdater *task= nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
N.content.title = fmt::format("Updating {} configurations", Venue.info.name);
|
N.content.title = fmt::format("Updating {} configurations", Venue.info.name);
|
||||||
N.content.jobId = JobId_;
|
N.content.jobId = JobId();
|
||||||
|
|
||||||
|
Poco::ThreadPool Pool_;
|
||||||
|
std::list<VenueDeviceConfigUpdater*> JobList;
|
||||||
|
|
||||||
std::array<tState,MaxThreads> Tasks;
|
|
||||||
|
|
||||||
for(const auto &uuid:Venue.devices) {
|
for(const auto &uuid:Venue.devices) {
|
||||||
auto NewTask = new VenueDeviceConfigUpdater(uuid, Venue.info.name, Logger());
|
auto NewTask = new VenueDeviceConfigUpdater(uuid, Venue.info.name, Logger());
|
||||||
// std::cout << "Scheduling config push for " << uuid << std::endl;
|
bool TaskAdded=false;
|
||||||
bool found_slot = false;
|
while(!TaskAdded) {
|
||||||
while (!found_slot) {
|
if (Pool_.available()) {
|
||||||
for (auto &cur_task: Tasks) {
|
JobList.push_back(NewTask);
|
||||||
if (cur_task.task == nullptr) {
|
Pool_.start(*NewTask);
|
||||||
cur_task.task = NewTask;
|
TaskAdded = true;
|
||||||
cur_task.thr_.start(*NewTask);
|
continue;
|
||||||
found_slot = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Let's look for a slot...
|
for(auto job_it = JobList.begin(); job_it !=JobList.end();) {
|
||||||
if (!found_slot) {
|
VenueDeviceConfigUpdater * current_job = *job_it;
|
||||||
for (auto &cur_task: Tasks) {
|
if(current_job!= nullptr && current_job->done_) {
|
||||||
if (cur_task.task != nullptr && cur_task.task->started_) {
|
Updated += current_job->updated_;
|
||||||
if (cur_task.thr_.isRunning())
|
Failed += current_job->failed_;
|
||||||
continue;
|
BadConfigs += current_job->bad_config_;
|
||||||
if (!cur_task.thr_.isRunning() && cur_task.task->done_) {
|
if(current_job->updated_) {
|
||||||
cur_task.thr_.join();
|
N.content.success.push_back(current_job->SerialNumber);
|
||||||
Updated += cur_task.task->updated_;
|
} else if(current_job->failed_) {
|
||||||
Failed += cur_task.task->failed_;
|
N.content.warning.push_back(current_job->SerialNumber);
|
||||||
BadConfigs += cur_task.task->bad_config_;
|
} else {
|
||||||
cur_task.task->started_ = cur_task.task->done_ = false;
|
N.content.error.push_back(current_job->SerialNumber);
|
||||||
delete cur_task.task;
|
|
||||||
cur_task.task = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
job_it = JobList.erase(job_it);
|
||||||
|
delete current_job;
|
||||||
|
} else {
|
||||||
|
++job_it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger().debug("Waiting for outstanding update threads to finish.");
|
Logger().debug("Waiting for outstanding update threads to finish.");
|
||||||
bool stillTasksRunning=true;
|
Pool_.joinAll();
|
||||||
while(stillTasksRunning) {
|
for(auto job_it = JobList.begin(); job_it !=JobList.end();) {
|
||||||
stillTasksRunning = false;
|
VenueDeviceConfigUpdater * current_job = *job_it;
|
||||||
for(auto &cur_task:Tasks) {
|
if(current_job!= nullptr && current_job->done_) {
|
||||||
if(cur_task.task!= nullptr && cur_task.task->started_) {
|
Updated += current_job->updated_;
|
||||||
if(cur_task.thr_.isRunning()) {
|
Failed += current_job->failed_;
|
||||||
stillTasksRunning = true;
|
BadConfigs += current_job->bad_config_;
|
||||||
continue;
|
if(current_job->updated_) {
|
||||||
}
|
N.content.success.push_back(current_job->SerialNumber);
|
||||||
if(!cur_task.thr_.isRunning() && cur_task.task->done_) {
|
} else if(current_job->failed_) {
|
||||||
cur_task.thr_.join();
|
N.content.warning.push_back(current_job->SerialNumber);
|
||||||
if(cur_task.task->updated_) {
|
} else {
|
||||||
Updated++;
|
N.content.error.push_back(current_job->SerialNumber);
|
||||||
N.content.success.push_back(cur_task.task->SerialNumber);
|
|
||||||
} else if(cur_task.task->failed_) {
|
|
||||||
Failed++;
|
|
||||||
N.content.warning.push_back(cur_task.task->SerialNumber);
|
|
||||||
} else {
|
|
||||||
BadConfigs++;
|
|
||||||
N.content.error.push_back(cur_task.task->SerialNumber);
|
|
||||||
}
|
|
||||||
cur_task.task->started_ = cur_task.task->done_ = false;
|
|
||||||
delete cur_task.task;
|
|
||||||
cur_task.task = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
job_it = JobList.erase(job_it);
|
||||||
|
delete current_job;
|
||||||
|
} else {
|
||||||
|
++job_it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
N.content.details = fmt::format("Job {} Completed: {} updated, {} failed to update, {} bad configurations. ",
|
N.content.details = fmt::format("Job {} Completed: {} updated, {} failed to update, {} bad configurations. ",
|
||||||
JobId_, Updated ,Failed, BadConfigs);
|
JobId(), Updated ,Failed, BadConfigs);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
N.content.details = fmt::format("Venue {} no longer exists.",VenueUUID_);
|
N.content.details = fmt::format("Venue {} no longer exists.",VenueUUID_);
|
||||||
Logger().warning(N.content.details);
|
Logger().warning(N.content.details);
|
||||||
}
|
}
|
||||||
|
|
||||||
WebSocketClientNotificationVenueUpdateJobCompletionToUser(UI_.email, N);
|
// std::cout << N.content.details << std::endl;
|
||||||
|
WebSocketClientNotificationVenueUpdateJobCompletionToUser(UserInfo().email, N);
|
||||||
Logger().information(fmt::format("Job {} Completed: {} updated, {} failed to update , {} bad configurations.",
|
Logger().information(fmt::format("Job {} Completed: {} updated, {} failed to update , {} bad configurations.",
|
||||||
JobId_, Updated ,Failed, BadConfigs));
|
JobId(), Updated ,Failed, BadConfigs));
|
||||||
delete this;
|
Utils::SetThreadName("free");
|
||||||
|
Complete();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include "StorageService.h"
|
#include "StorageService.h"
|
||||||
#include "APConfig.h"
|
#include "APConfig.h"
|
||||||
#include "sdks/SDK_gw.h"
|
#include "sdks/SDK_gw.h"
|
||||||
|
#include "JobController.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
@@ -48,129 +49,90 @@ namespace OpenWifi {
|
|||||||
inline Poco::Logger & Logger() { return Logger_; }
|
inline Poco::Logger & Logger() { return Logger_; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class VenueRebooter: public Poco::Runnable {
|
class VenueRebooter: public Job {
|
||||||
public:
|
public:
|
||||||
explicit VenueRebooter(const std::string & VenueUUID, const SecurityObjects::UserInfo &UI, uint64_t When, Poco::Logger &L) :
|
VenueRebooter(const std::string &JobID, const std::string &name, const std::vector<std::string> & parameters, uint64_t when, const SecurityObjects::UserInfo &UI, Poco::Logger &L) :
|
||||||
VenueUUID_(VenueUUID),
|
Job(JobID, name, parameters, when, UI, L) {
|
||||||
UI_(UI),
|
|
||||||
When_(When),
|
|
||||||
Logger_(L)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string Start() {
|
inline virtual void run() final {
|
||||||
JobId_ = MicroService::CreateUUID();
|
|
||||||
Worker_.start(*this);
|
|
||||||
return JobId_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
Utils::SetThreadName("venue-reboot");
|
||||||
std::string VenueUUID_;
|
|
||||||
SecurityObjects::UserInfo UI_;
|
|
||||||
uint64_t When_;
|
|
||||||
Poco::Logger &Logger_;
|
|
||||||
Poco::Thread Worker_;
|
|
||||||
std::string JobId_;
|
|
||||||
Poco::ThreadPool Pool_{2,16,300};
|
|
||||||
|
|
||||||
inline Poco::Logger & Logger() { return Logger_; }
|
|
||||||
|
|
||||||
inline void run() final {
|
|
||||||
|
|
||||||
if(When_ && When_>OpenWifi::Now())
|
|
||||||
Poco::Thread::trySleep( (long) (When_ - OpenWifi::Now()) * 1000 );
|
|
||||||
|
|
||||||
WebSocketClientNotificationVenueRebootList_t N;
|
WebSocketClientNotificationVenueRebootList_t N;
|
||||||
|
auto VenueUUID_ = Parameter(0);
|
||||||
Logger().information(fmt::format("Job {} Starting.", JobId_));
|
|
||||||
|
|
||||||
ProvObjects::Venue Venue;
|
ProvObjects::Venue Venue;
|
||||||
uint64_t rebooted_ = 0, failed_ = 0;
|
uint64_t rebooted_ = 0, failed_ = 0;
|
||||||
if(StorageService()->VenueDB().GetRecord("id",VenueUUID_,Venue)) {
|
if(StorageService()->VenueDB().GetRecord("id",VenueUUID_,Venue)) {
|
||||||
const std::size_t MaxThreads=16;
|
|
||||||
struct tState {
|
|
||||||
Poco::Thread thr_;
|
|
||||||
VenueDeviceRebooter *task= nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
N.content.title = fmt::format("Rebooting {} devices.", Venue.info.name);
|
N.content.title = fmt::format("Rebooting {} devices.", Venue.info.name);
|
||||||
N.content.jobId = JobId_;
|
N.content.jobId = JobId();
|
||||||
|
|
||||||
std::array<tState,MaxThreads> Tasks;
|
Poco::ThreadPool Pool_;
|
||||||
|
std::list<VenueDeviceRebooter*> JobList;
|
||||||
|
|
||||||
for(const auto &uuid:Venue.devices) {
|
for(const auto &uuid:Venue.devices) {
|
||||||
auto NewTask = new VenueDeviceRebooter(uuid, Venue.info.name, Logger());
|
auto NewTask = new VenueDeviceRebooter(uuid, Venue.info.name, Logger());
|
||||||
// std::cout << "Scheduling config push for " << uuid << std::endl;
|
bool TaskAdded=false;
|
||||||
bool found_slot = false;
|
while(!TaskAdded) {
|
||||||
while (!found_slot) {
|
if (Pool_.available()) {
|
||||||
for (auto &cur_task: Tasks) {
|
JobList.push_back(NewTask);
|
||||||
if (cur_task.task == nullptr) {
|
Pool_.start(*NewTask);
|
||||||
cur_task.task = NewTask;
|
TaskAdded = true;
|
||||||
cur_task.thr_.start(*NewTask);
|
continue;
|
||||||
found_slot = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Let's look for a slot...
|
for(auto job_it = JobList.begin(); job_it !=JobList.end();) {
|
||||||
if (!found_slot) {
|
VenueDeviceRebooter * current_job = *job_it;
|
||||||
for (auto &cur_task: Tasks) {
|
if(current_job!= nullptr && current_job->done_) {
|
||||||
if (cur_task.task != nullptr && cur_task.task->started_) {
|
if(current_job->rebooted_)
|
||||||
if (cur_task.thr_.isRunning())
|
N.content.success.push_back(current_job->SerialNumber);
|
||||||
continue;
|
else
|
||||||
if (!cur_task.thr_.isRunning() && cur_task.task->done_) {
|
N.content.warning.push_back(current_job->SerialNumber);
|
||||||
cur_task.thr_.join();
|
rebooted_ += current_job->rebooted_;
|
||||||
rebooted_ += cur_task.task->rebooted_;
|
failed_ += current_job->failed_;
|
||||||
failed_ += cur_task.task->failed_;
|
job_it = JobList.erase(job_it);
|
||||||
cur_task.task->started_ = cur_task.task->done_ = false;
|
delete current_job;
|
||||||
delete cur_task.task;
|
} else {
|
||||||
cur_task.task = nullptr;
|
++job_it;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger().debug("Waiting for outstanding update threads to finish.");
|
Logger().debug("Waiting for outstanding update threads to finish.");
|
||||||
bool stillTasksRunning=true;
|
Pool_.joinAll();
|
||||||
while(stillTasksRunning) {
|
for(auto job_it = JobList.begin(); job_it !=JobList.end();) {
|
||||||
stillTasksRunning = false;
|
VenueDeviceRebooter * current_job = *job_it;
|
||||||
for(auto &cur_task:Tasks) {
|
if(current_job!= nullptr && current_job->done_) {
|
||||||
if(cur_task.task!= nullptr && cur_task.task->started_) {
|
if(current_job->rebooted_)
|
||||||
if(cur_task.thr_.isRunning()) {
|
N.content.success.push_back(current_job->SerialNumber);
|
||||||
stillTasksRunning = true;
|
else
|
||||||
continue;
|
N.content.warning.push_back(current_job->SerialNumber);
|
||||||
}
|
rebooted_ += current_job->rebooted_;
|
||||||
if(!cur_task.thr_.isRunning() && cur_task.task->done_) {
|
failed_ += current_job->failed_;
|
||||||
cur_task.thr_.join();
|
job_it = JobList.erase(job_it);
|
||||||
if(cur_task.task->rebooted_) {
|
delete current_job;
|
||||||
rebooted_++;
|
} else {
|
||||||
N.content.success.push_back(cur_task.task->SerialNumber);
|
++job_it;
|
||||||
} else if(cur_task.task->failed_) {
|
|
||||||
failed_++;
|
|
||||||
N.content.warning.push_back(cur_task.task->SerialNumber);
|
|
||||||
}
|
|
||||||
cur_task.task->started_ = cur_task.task->done_ = false;
|
|
||||||
delete cur_task.task;
|
|
||||||
cur_task.task = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
N.content.details = fmt::format("Job {} Completed: {} rebooted, {} failed to reboot.",
|
N.content.details = fmt::format("Job {} Completed: {} rebooted, {} failed to reboot.",
|
||||||
JobId_, rebooted_ ,failed_);
|
JobId(), rebooted_ ,failed_);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
N.content.details = fmt::format("Venue {} no longer exists.",VenueUUID_);
|
N.content.details = fmt::format("Venue {} no longer exists.",VenueUUID_);
|
||||||
Logger().warning(N.content.details);
|
Logger().warning(N.content.details);
|
||||||
}
|
}
|
||||||
|
|
||||||
WebSocketClientNotificationVenueRebootCompletionToUser(UI_.email,N);
|
// std::cout << N.content.details << std::endl;
|
||||||
|
WebSocketClientNotificationVenueRebootCompletionToUser(UserInfo().email,N);
|
||||||
Logger().information(fmt::format("Job {} Completed: {} rebooted, {} failed to reboot.",
|
Logger().information(fmt::format("Job {} Completed: {} rebooted, {} failed to reboot.",
|
||||||
JobId_, rebooted_ ,failed_));
|
JobId(), rebooted_ ,failed_));
|
||||||
delete this;
|
Utils::SetThreadName("free");
|
||||||
|
Complete();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include "APConfig.h"
|
#include "APConfig.h"
|
||||||
#include "sdks/SDK_gw.h"
|
#include "sdks/SDK_gw.h"
|
||||||
#include "sdks/SDK_fms.h"
|
#include "sdks/SDK_fms.h"
|
||||||
|
#include "JobController.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
class VenueDeviceUpgrade : public Poco::Runnable {
|
class VenueDeviceUpgrade : public Poco::Runnable {
|
||||||
@@ -30,7 +31,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
Storage::ApplyRules(rules_,Device.deviceRules);
|
Storage::ApplyRules(rules_,Device.deviceRules);
|
||||||
if(Device.deviceRules.firmwareUpgrade=="no") {
|
if(Device.deviceRules.firmwareUpgrade=="no") {
|
||||||
std::cout << "Skipped Upgrade:" << Device.serialNumber << std::endl;
|
poco_debug(Logger(),fmt::format("Skipped Upgrade: {}", Device.serialNumber));
|
||||||
skipped_++;
|
skipped_++;
|
||||||
done_=true;
|
done_=true;
|
||||||
return;
|
return;
|
||||||
@@ -39,16 +40,14 @@ namespace OpenWifi {
|
|||||||
FMSObjects::Firmware F;
|
FMSObjects::Firmware F;
|
||||||
if(SDK::FMS::Firmware::GetLatest(Device.deviceType,Device.deviceRules.rcOnly=="yes",F)) {
|
if(SDK::FMS::Firmware::GetLatest(Device.deviceType,Device.deviceRules.rcOnly=="yes",F)) {
|
||||||
if (SDK::GW::Device::Upgrade(nullptr, Device.serialNumber, 0, F.uri)) {
|
if (SDK::GW::Device::Upgrade(nullptr, Device.serialNumber, 0, F.uri)) {
|
||||||
std::cout << "Upgraded:" << Device.serialNumber << " to " << F.uri << std::endl;
|
|
||||||
Logger().debug(fmt::format("{}: Upgraded.",Device.serialNumber));
|
Logger().debug(fmt::format("{}: Upgraded.",Device.serialNumber));
|
||||||
upgraded_++;
|
upgraded_++;
|
||||||
} else {
|
} else {
|
||||||
std::cout << "Did not Upgrade:" << Device.serialNumber << " to " << F.uri << std::endl;
|
|
||||||
Logger().information(fmt::format("{}: Not Upgraded.", Device.serialNumber));
|
Logger().information(fmt::format("{}: Not Upgraded.", Device.serialNumber));
|
||||||
failed_++;
|
failed_++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
std::cout << "Did not Upgrade:" << Device.serialNumber << " to <unknown>" << std::endl;
|
Logger().information(fmt::format("{}: Not Upgraded. No firmware available.", Device.serialNumber));
|
||||||
failed_++;
|
failed_++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,132 +68,94 @@ namespace OpenWifi {
|
|||||||
inline Poco::Logger & Logger() { return Logger_; }
|
inline Poco::Logger & Logger() { return Logger_; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class VenueUpgrade: public Poco::Runnable {
|
class VenueUpgrade: public Job {
|
||||||
public:
|
public:
|
||||||
explicit VenueUpgrade(const std::string & VenueUUID, const SecurityObjects::UserInfo &UI, uint64_t When, Poco::Logger &L) :
|
VenueUpgrade(const std::string &JobID, const std::string &name, const std::vector<std::string> & parameters, uint64_t when, const SecurityObjects::UserInfo &UI, Poco::Logger &L) :
|
||||||
VenueUUID_(VenueUUID),
|
Job(JobID, name, parameters, when, UI, L) {
|
||||||
UI_(UI),
|
|
||||||
When_(When),
|
|
||||||
Logger_(L)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string Start() {
|
inline virtual void run() final {
|
||||||
JobId_ = MicroService::CreateUUID();
|
|
||||||
Worker_.start(*this);
|
|
||||||
return JobId_;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
Utils::SetThreadName("venue-upgr");
|
||||||
std::string VenueUUID_;
|
auto VenueUUID_ = Parameter(0);
|
||||||
SecurityObjects::UserInfo UI_;
|
|
||||||
uint64_t When_;
|
|
||||||
Poco::Logger &Logger_;
|
|
||||||
Poco::Thread Worker_;
|
|
||||||
std::string JobId_;
|
|
||||||
Poco::ThreadPool Pool_{2,16,300};
|
|
||||||
|
|
||||||
inline Poco::Logger & Logger() { return Logger_; }
|
|
||||||
|
|
||||||
inline void run() final {
|
|
||||||
|
|
||||||
if(When_ && When_>OpenWifi::Now())
|
|
||||||
Poco::Thread::trySleep( (long) (When_ - OpenWifi::Now()) * 1000 );
|
|
||||||
|
|
||||||
WebSocketClientNotificationVenueRebootList_t N;
|
WebSocketClientNotificationVenueRebootList_t N;
|
||||||
|
|
||||||
Logger().information(fmt::format("Job {} Starting.", JobId_));
|
|
||||||
|
|
||||||
ProvObjects::Venue Venue;
|
ProvObjects::Venue Venue;
|
||||||
uint64_t upgraded_ = 0, failed_ = 0;
|
uint64_t upgraded_ = 0, failed_ = 0;
|
||||||
if(StorageService()->VenueDB().GetRecord("id",VenueUUID_,Venue)) {
|
if(StorageService()->VenueDB().GetRecord("id",VenueUUID_,Venue)) {
|
||||||
const std::size_t MaxThreads=16;
|
|
||||||
struct tState {
|
|
||||||
Poco::Thread thr_;
|
|
||||||
VenueDeviceUpgrade *task= nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
N.content.title = fmt::format("Upgrading {} devices.", Venue.info.name);
|
N.content.title = fmt::format("Upgrading {} devices.", Venue.info.name);
|
||||||
N.content.jobId = JobId_;
|
N.content.jobId = JobId();
|
||||||
|
|
||||||
std::array<tState,MaxThreads> Tasks;
|
Poco::ThreadPool Pool_;
|
||||||
ProvObjects::DeviceRules Rules;
|
std::list<VenueDeviceUpgrade*> JobList;
|
||||||
|
ProvObjects::DeviceRules Rules;
|
||||||
|
|
||||||
StorageService()->VenueDB().EvaluateDeviceRules(Venue.info.id, Rules);
|
StorageService()->VenueDB().EvaluateDeviceRules(Venue.info.id, Rules);
|
||||||
|
|
||||||
for(const auto &uuid:Venue.devices) {
|
for(const auto &uuid:Venue.devices) {
|
||||||
auto NewTask = new VenueDeviceUpgrade(uuid, Venue.info.name, Rules,Logger());
|
auto NewTask = new VenueDeviceUpgrade(uuid, Venue.info.name, Rules, Logger());
|
||||||
// std::cout << "Scheduling config push for " << uuid << std::endl;
|
bool TaskAdded = false;
|
||||||
bool found_slot = false;
|
while (!TaskAdded) {
|
||||||
while (!found_slot) {
|
if (Pool_.available()) {
|
||||||
for (auto &cur_task: Tasks) {
|
JobList.push_back(NewTask);
|
||||||
if (cur_task.task == nullptr) {
|
Pool_.start(*NewTask);
|
||||||
cur_task.task = NewTask;
|
TaskAdded = true;
|
||||||
cur_task.thr_.start(*NewTask);
|
continue;
|
||||||
found_slot = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Let's look for a slot...
|
for (auto job_it = JobList.begin(); job_it != JobList.end();) {
|
||||||
if (!found_slot) {
|
VenueDeviceUpgrade *current_job = *job_it;
|
||||||
for (auto &cur_task: Tasks) {
|
if (current_job != nullptr && current_job->done_) {
|
||||||
if (cur_task.task != nullptr && cur_task.task->started_) {
|
if (current_job->upgraded_)
|
||||||
if (cur_task.thr_.isRunning())
|
N.content.success.push_back(current_job->SerialNumber);
|
||||||
continue;
|
else
|
||||||
if (!cur_task.thr_.isRunning() && cur_task.task->done_) {
|
N.content.warning.push_back(current_job->SerialNumber);
|
||||||
cur_task.thr_.join();
|
upgraded_ += current_job->upgraded_;
|
||||||
upgraded_ += cur_task.task->upgraded_;
|
failed_ += current_job->failed_;
|
||||||
failed_ += cur_task.task->failed_;
|
job_it = JobList.erase(job_it);
|
||||||
cur_task.task->started_ = cur_task.task->done_ = false;
|
delete current_job;
|
||||||
delete cur_task.task;
|
} else {
|
||||||
cur_task.task = nullptr;
|
++job_it;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Logger().debug("Waiting for outstanding update threads to finish.");
|
|
||||||
bool stillTasksRunning=true;
|
Logger().debug("Waiting for outstanding upgrade threads to finish.");
|
||||||
while(stillTasksRunning) {
|
Pool_.joinAll();
|
||||||
stillTasksRunning = false;
|
for(auto job_it = JobList.begin(); job_it !=JobList.end();) {
|
||||||
for(auto &cur_task:Tasks) {
|
VenueDeviceUpgrade * current_job = *job_it;
|
||||||
if(cur_task.task!= nullptr && cur_task.task->started_) {
|
if(current_job!= nullptr && current_job->done_) {
|
||||||
if(cur_task.thr_.isRunning()) {
|
if(current_job->upgraded_)
|
||||||
stillTasksRunning = true;
|
N.content.success.push_back(current_job->SerialNumber);
|
||||||
continue;
|
else
|
||||||
}
|
N.content.warning.push_back(current_job->SerialNumber);
|
||||||
if(!cur_task.thr_.isRunning() && cur_task.task->done_) {
|
upgraded_ += current_job->upgraded_;
|
||||||
cur_task.thr_.join();
|
failed_ += current_job->failed_;
|
||||||
if(cur_task.task->upgraded_) {
|
job_it = JobList.erase(job_it);
|
||||||
upgraded_++;
|
delete current_job;
|
||||||
N.content.success.push_back(cur_task.task->SerialNumber);
|
} else {
|
||||||
} else if(cur_task.task->failed_) {
|
++job_it;
|
||||||
failed_++;
|
|
||||||
N.content.warning.push_back(cur_task.task->SerialNumber);
|
|
||||||
}
|
|
||||||
cur_task.task->started_ = cur_task.task->done_ = false;
|
|
||||||
delete cur_task.task;
|
|
||||||
cur_task.task = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
N.content.details = fmt::format("Job {} Completed: {} upgraded, {} failed to upgrade.",
|
N.content.details = fmt::format("Job {} Completed: {} upgraded, {} failed to upgrade.",
|
||||||
JobId_, upgraded_ ,failed_);
|
JobId(), upgraded_ ,failed_);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
N.content.details = fmt::format("Venue {} no longer exists.",VenueUUID_);
|
N.content.details = fmt::format("Venue {} no longer exists.",VenueUUID_);
|
||||||
Logger().warning(N.content.details);
|
Logger().warning(N.content.details);
|
||||||
}
|
}
|
||||||
|
|
||||||
WebSocketClientNotificationVenueRebootCompletionToUser(UI_.email,N);
|
// std::cout << N.content.details << std::endl;
|
||||||
|
WebSocketClientNotificationVenueRebootCompletionToUser(UserInfo().email,N);
|
||||||
Logger().information(fmt::format("Job {} Completed: {} upgraded, {} failed to upgrade.",
|
Logger().information(fmt::format("Job {} Completed: {} upgraded, {} failed to upgrade.",
|
||||||
JobId_, upgraded_ ,failed_));
|
JobId(), upgraded_ ,failed_));
|
||||||
delete this;
|
Utils::SetThreadName("free");
|
||||||
|
|
||||||
|
Complete();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -643,6 +643,27 @@ namespace OpenWifi::RESTAPI_utils {
|
|||||||
|
|
||||||
namespace OpenWifi::Utils {
|
namespace OpenWifi::Utils {
|
||||||
|
|
||||||
|
inline void SetThreadName(const char *name) {
|
||||||
|
#ifdef __linux__
|
||||||
|
Poco::Thread::current()->setName(name);
|
||||||
|
pthread_setname_np(pthread_self(), name);
|
||||||
|
#endif
|
||||||
|
#ifdef __APPLE__
|
||||||
|
Poco::Thread::current()->setName(name);
|
||||||
|
pthread_setname_np(name);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void SetThreadName(Poco::Thread &thr, const char *name) {
|
||||||
|
#ifdef __linux__
|
||||||
|
thr.setName(name);
|
||||||
|
pthread_setname_np(thr.tid(), name);
|
||||||
|
#endif
|
||||||
|
#ifdef __APPLE__
|
||||||
|
thr.setName(name);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
enum MediaTypeEncodings {
|
enum MediaTypeEncodings {
|
||||||
PLAIN,
|
PLAIN,
|
||||||
BINARY,
|
BINARY,
|
||||||
@@ -1167,6 +1188,7 @@ namespace OpenWifi {
|
|||||||
static const std::string uSERVICE_SUBCRIBER{ "owsub"};
|
static const std::string uSERVICE_SUBCRIBER{ "owsub"};
|
||||||
static const std::string uSERVICE_INSTALLER{ "owinst"};
|
static const std::string uSERVICE_INSTALLER{ "owinst"};
|
||||||
static const std::string uSERVICE_ANALYTICS{ "owanalytics"};
|
static const std::string uSERVICE_ANALYTICS{ "owanalytics"};
|
||||||
|
static const std::string uSERVICE_OWRRM{ "owrrm"};
|
||||||
|
|
||||||
class ConfigurationEntry {
|
class ConfigurationEntry {
|
||||||
public:
|
public:
|
||||||
@@ -1315,7 +1337,7 @@ namespace OpenWifi {
|
|||||||
inline void Start();
|
inline void Start();
|
||||||
inline void Stop();
|
inline void Stop();
|
||||||
private:
|
private:
|
||||||
std::atomic_bool Running_ = false;
|
mutable std::atomic_bool Running_ = false;
|
||||||
Poco::Thread Thread_;
|
Poco::Thread Thread_;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1846,7 +1868,8 @@ namespace OpenWifi {
|
|||||||
Request = &RequestIn;
|
Request = &RequestIn;
|
||||||
Response = &ResponseIn;
|
Response = &ResponseIn;
|
||||||
|
|
||||||
Poco::Thread::current()->setName("WebServerThread_" + std::to_string(TransactionId_));
|
std::string th_name = "restsvr_" + std::to_string(TransactionId_);
|
||||||
|
Utils::SetThreadName(th_name.c_str());
|
||||||
|
|
||||||
if(Request->getContentLength()>0) {
|
if(Request->getContentLength()>0) {
|
||||||
if(Request->getContentType().find("application/json")!=std::string::npos) {
|
if(Request->getContentType().find("application/json")!=std::string::npos) {
|
||||||
@@ -1895,36 +1918,32 @@ namespace OpenWifi {
|
|||||||
[[nodiscard]] inline bool NeedAdditionalInfo() const { return QB_.AdditionalInfo; }
|
[[nodiscard]] inline bool NeedAdditionalInfo() const { return QB_.AdditionalInfo; }
|
||||||
[[nodiscard]] inline const std::vector<std::string> & SelectedRecords() const { return QB_.Select; }
|
[[nodiscard]] inline const std::vector<std::string> & SelectedRecords() const { return QB_.Select; }
|
||||||
|
|
||||||
/* [[nodiscard]] inline const Poco::JSON::Object::Ptr ParseStream() {
|
inline static bool ParseBindings(const std::string & Request, const std::list<std::string> & EndPoints, BindingMap &bindings) {
|
||||||
return IncomingParser_.parse(Request->stream()).extract<Poco::JSON::Object::Ptr>();
|
bindings.clear();
|
||||||
}
|
auto PathItems = Poco::StringTokenizer(Request, "/");
|
||||||
*/
|
|
||||||
|
|
||||||
inline static bool ParseBindings(const std::string & Request, const std::list<std::string> & EndPoints, BindingMap &bindings) {
|
for(const auto &EndPoint:EndPoints) {
|
||||||
bindings.clear();
|
auto ParamItems = Poco::StringTokenizer(EndPoint, "/");
|
||||||
std::vector<std::string> PathItems = Utils::Split(Request, '/');
|
if (PathItems.count() != ParamItems.count())
|
||||||
|
continue;
|
||||||
|
|
||||||
for(const auto &EndPoint:EndPoints) {
|
bool Matched = true;
|
||||||
std::vector<std::string> ParamItems = Utils::Split(EndPoint, '/');
|
for (size_t i = 0; i < PathItems.count(); i++) {
|
||||||
if (PathItems.size() != ParamItems.size())
|
if (PathItems[i] != ParamItems[i]) {
|
||||||
continue;
|
if (ParamItems[i][0] == '{') {
|
||||||
|
auto ParamName = ParamItems[i].substr(1, ParamItems[i].size() - 2);
|
||||||
bool Matched = true;
|
bindings[Poco::toLower(ParamName)] = PathItems[i];
|
||||||
for (size_t i = 0; i != PathItems.size() && Matched; i++) {
|
} else {
|
||||||
if (PathItems[i] != ParamItems[i]) {
|
Matched = false;
|
||||||
if (ParamItems[i][0] == '{') {
|
break;
|
||||||
auto ParamName = ParamItems[i].substr(1, ParamItems[i].size() - 2);
|
}
|
||||||
bindings[Poco::toLower(ParamName)] = PathItems[i];
|
}
|
||||||
} else {
|
}
|
||||||
Matched = false;
|
if(Matched)
|
||||||
}
|
return true;
|
||||||
}
|
}
|
||||||
}
|
return false;
|
||||||
if(Matched)
|
}
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void PrintBindings() {
|
inline void PrintBindings() {
|
||||||
for (const auto &[key, value] : Bindings_)
|
for (const auto &[key, value] : Bindings_)
|
||||||
@@ -2582,7 +2601,7 @@ namespace OpenWifi {
|
|||||||
private:
|
private:
|
||||||
std::recursive_mutex Mutex_;
|
std::recursive_mutex Mutex_;
|
||||||
Poco::Thread Worker_;
|
Poco::Thread Worker_;
|
||||||
std::atomic_bool Running_=false;
|
mutable std::atomic_bool Running_=false;
|
||||||
Poco::NotificationQueue Queue_;
|
Poco::NotificationQueue Queue_;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2608,7 +2627,7 @@ namespace OpenWifi {
|
|||||||
private:
|
private:
|
||||||
std::recursive_mutex Mutex_;
|
std::recursive_mutex Mutex_;
|
||||||
Poco::Thread Worker_;
|
Poco::Thread Worker_;
|
||||||
std::atomic_bool Running_=false;
|
mutable std::atomic_bool Running_=false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class KafkaDispatcher : public Poco::Runnable {
|
class KafkaDispatcher : public Poco::Runnable {
|
||||||
@@ -2665,6 +2684,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
inline void run() override {
|
inline void run() override {
|
||||||
Poco::AutoPtr<Poco::Notification> Note(Queue_.waitDequeueNotification());
|
Poco::AutoPtr<Poco::Notification> Note(Queue_.waitDequeueNotification());
|
||||||
|
Utils::SetThreadName("kafka-dispatch");
|
||||||
while(Note && Running_) {
|
while(Note && Running_) {
|
||||||
auto Msg = dynamic_cast<KafkaMessage*>(Note.get());
|
auto Msg = dynamic_cast<KafkaMessage*>(Note.get());
|
||||||
if(Msg!= nullptr) {
|
if(Msg!= nullptr) {
|
||||||
@@ -2690,7 +2710,7 @@ namespace OpenWifi {
|
|||||||
std::recursive_mutex Mutex_;
|
std::recursive_mutex Mutex_;
|
||||||
Types::NotifyTable Notifiers_;
|
Types::NotifyTable Notifiers_;
|
||||||
Poco::Thread Worker_;
|
Poco::Thread Worker_;
|
||||||
std::atomic_bool Running_=false;
|
mutable std::atomic_bool Running_=false;
|
||||||
uint64_t FunctionId_=1;
|
uint64_t FunctionId_=1;
|
||||||
Poco::NotificationQueue Queue_;
|
Poco::NotificationQueue Queue_;
|
||||||
};
|
};
|
||||||
@@ -2885,6 +2905,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
void handleRequest(Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response) override
|
void handleRequest(Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response) override
|
||||||
{
|
{
|
||||||
|
Utils::SetThreadName("alb-request");
|
||||||
try {
|
try {
|
||||||
if((id_ % 100) == 0) {
|
if((id_ % 100) == 0) {
|
||||||
Logger_.debug(fmt::format("ALB-REQUEST({}): ALB Request {}.",
|
Logger_.debug(fmt::format("ALB-REQUEST({}): ALB Request {}.",
|
||||||
@@ -2953,7 +2974,7 @@ namespace OpenWifi {
|
|||||||
std::unique_ptr<Poco::Net::HTTPServer> Server_;
|
std::unique_ptr<Poco::Net::HTTPServer> Server_;
|
||||||
std::unique_ptr<Poco::Net::ServerSocket> Socket_;
|
std::unique_ptr<Poco::Net::ServerSocket> Socket_;
|
||||||
int Port_ = 0;
|
int Port_ = 0;
|
||||||
std::atomic_bool Running_=false;
|
mutable std::atomic_bool Running_=false;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline auto ALBHealthCheckServer() { return ALBHealthCheckServer::instance(); }
|
inline auto ALBHealthCheckServer() { return ALBHealthCheckServer::instance(); }
|
||||||
@@ -2985,7 +3006,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
inline Poco::Net::HTTPRequestHandler *CallServer(const std::string &Path, uint64_t Id) {
|
inline Poco::Net::HTTPRequestHandler *CallServer(const std::string &Path, uint64_t Id) {
|
||||||
RESTAPIHandler::BindingMap Bindings;
|
RESTAPIHandler::BindingMap Bindings;
|
||||||
Poco::Thread::current()->setName(fmt::format("RESTAPI_ExtServer_{}",Id));
|
Utils::SetThreadName(fmt::format("rest_ext_{}",Id).c_str());
|
||||||
return RESTAPI_ExtRouter(Path, Bindings, Logger(), Server_, Id);
|
return RESTAPI_ExtRouter(Path, Bindings, Logger(), Server_, Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3009,7 +3030,7 @@ namespace OpenWifi {
|
|||||||
inline Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override {
|
inline Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override {
|
||||||
try {
|
try {
|
||||||
Poco::URI uri(Request.getURI());
|
Poco::URI uri(Request.getURI());
|
||||||
Poco::Thread::current()->setName(fmt::format("ExtWebServer_{}",TransactionId_));
|
Utils::SetThreadName(fmt::format("rest_ext_{}",TransactionId_).c_str());
|
||||||
return RESTAPI_ExtServer()->CallServer(uri.getPath(), TransactionId_++);
|
return RESTAPI_ExtServer()->CallServer(uri.getPath(), TransactionId_++);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
|
||||||
@@ -3118,7 +3139,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
inline Poco::Net::HTTPRequestHandler *CallServer(const std::string &Path, uint64_t Id) {
|
inline Poco::Net::HTTPRequestHandler *CallServer(const std::string &Path, uint64_t Id) {
|
||||||
RESTAPIHandler::BindingMap Bindings;
|
RESTAPIHandler::BindingMap Bindings;
|
||||||
Poco::Thread::current()->setName(fmt::format("RESTAPI_IntServer_{}",Id));
|
Utils::SetThreadName(fmt::format("rest_int_{}",Id).c_str());
|
||||||
return RESTAPI_IntRouter(Path, Bindings, Logger(), Server_, Id);
|
return RESTAPI_IntRouter(Path, Bindings, Logger(), Server_, Id);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
@@ -3527,7 +3548,9 @@ namespace OpenWifi {
|
|||||||
void DaemonPostInitialization(Poco::Util::Application &self);
|
void DaemonPostInitialization(Poco::Util::Application &self);
|
||||||
|
|
||||||
inline void MicroService::initialize(Poco::Util::Application &self) {
|
inline void MicroService::initialize(Poco::Util::Application &self) {
|
||||||
// add the default services
|
// Utils::SetThreadName("microservice");
|
||||||
|
|
||||||
|
// add the default services
|
||||||
LoadConfigurationFile();
|
LoadConfigurationFile();
|
||||||
InitializeLoggingSystem();
|
InitializeLoggingSystem();
|
||||||
|
|
||||||
@@ -3922,6 +3945,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
inline int MicroService::main([[maybe_unused]] const ArgVec &args) {
|
inline int MicroService::main([[maybe_unused]] const ArgVec &args) {
|
||||||
|
|
||||||
|
// Utils::SetThreadName("main");
|
||||||
MyErrorHandler ErrorHandler(*this);
|
MyErrorHandler ErrorHandler(*this);
|
||||||
Poco::ErrorHandler::set(&ErrorHandler);
|
Poco::ErrorHandler::set(&ErrorHandler);
|
||||||
|
|
||||||
@@ -4037,6 +4061,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
inline void BusEventManager::run() {
|
inline void BusEventManager::run() {
|
||||||
Running_ = true;
|
Running_ = true;
|
||||||
|
Utils::SetThreadName("BusEventManager");
|
||||||
auto Msg = MicroService::instance().MakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_JOIN);
|
auto Msg = MicroService::instance().MakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_JOIN);
|
||||||
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,MicroService::instance().PrivateEndPoint(),Msg, false);
|
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,MicroService::instance().PrivateEndPoint(),Msg, false);
|
||||||
while(Running_) {
|
while(Running_) {
|
||||||
@@ -4122,6 +4147,8 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline void KafkaProducer::run() {
|
inline void KafkaProducer::run() {
|
||||||
|
|
||||||
|
Utils::SetThreadName("KafkaProducer");
|
||||||
cppkafka::Configuration Config({
|
cppkafka::Configuration Config({
|
||||||
{ "client.id", MicroService::instance().ConfigGetString("openwifi.kafka.client.id") },
|
{ "client.id", MicroService::instance().ConfigGetString("openwifi.kafka.client.id") },
|
||||||
{ "metadata.broker.list", MicroService::instance().ConfigGetString("openwifi.kafka.brokerlist") }
|
{ "metadata.broker.list", MicroService::instance().ConfigGetString("openwifi.kafka.brokerlist") }
|
||||||
@@ -4160,6 +4187,8 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline void KafkaConsumer::run() {
|
inline void KafkaConsumer::run() {
|
||||||
|
Utils::SetThreadName("KafkaConsumer");
|
||||||
|
|
||||||
cppkafka::Configuration Config({
|
cppkafka::Configuration Config({
|
||||||
{ "client.id", MicroService::instance().ConfigGetString("openwifi.kafka.client.id") },
|
{ "client.id", MicroService::instance().ConfigGetString("openwifi.kafka.client.id") },
|
||||||
{ "metadata.broker.list", MicroService::instance().ConfigGetString("openwifi.kafka.brokerlist") },
|
{ "metadata.broker.list", MicroService::instance().ConfigGetString("openwifi.kafka.brokerlist") },
|
||||||
@@ -4818,7 +4847,7 @@ namespace OpenWifi {
|
|||||||
[[nodiscard]] bool SendToUser(const std::string &userName, const std::string &Payload);
|
[[nodiscard]] bool SendToUser(const std::string &userName, const std::string &Payload);
|
||||||
void SendToAll(const std::string &Payload);
|
void SendToAll(const std::string &Payload);
|
||||||
private:
|
private:
|
||||||
std::atomic_bool Running_ = false;
|
mutable std::atomic_bool Running_ = false;
|
||||||
Poco::Thread Thr_;
|
Poco::Thread Thr_;
|
||||||
// std::unique_ptr<MyParallelSocketReactor> ReactorPool_;
|
// std::unique_ptr<MyParallelSocketReactor> ReactorPool_;
|
||||||
Poco::Net::SocketReactor Reactor_;
|
Poco::Net::SocketReactor Reactor_;
|
||||||
@@ -4915,6 +4944,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
inline void WebSocketClientServer::run() {
|
inline void WebSocketClientServer::run() {
|
||||||
Running_ = true ;
|
Running_ = true ;
|
||||||
|
Utils::SetThreadName("ws:clnt-svr");
|
||||||
while(Running_) {
|
while(Running_) {
|
||||||
Poco::Thread::trySleep(2000);
|
Poco::Thread::trySleep(2000);
|
||||||
|
|
||||||
@@ -4962,8 +4992,12 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
for(const auto &client:Clients_) {
|
for(const auto &client:Clients_) {
|
||||||
if(client.second.second == UserName) {
|
if(client.second.second == UserName) {
|
||||||
if(client.second.first->Send(Payload))
|
try {
|
||||||
Sent++;
|
if (client.second.first->Send(Payload))
|
||||||
|
Sent++;
|
||||||
|
} catch (...) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Sent>0;
|
return Sent>0;
|
||||||
@@ -4985,70 +5019,70 @@ namespace OpenWifi {
|
|||||||
int flags;
|
int flags;
|
||||||
int n;
|
int n;
|
||||||
bool Done=false;
|
bool Done=false;
|
||||||
Poco::Buffer<char> IncomingFrame(0);
|
try {
|
||||||
n = WS_->receiveFrame(IncomingFrame, flags);
|
Poco::Buffer<char> IncomingFrame(0);
|
||||||
auto Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK;
|
n = WS_->receiveFrame(IncomingFrame, flags);
|
||||||
|
auto Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK;
|
||||||
|
|
||||||
if(n==0) {
|
if (n == 0) {
|
||||||
return delete this;
|
return delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(Op) {
|
switch (Op) {
|
||||||
case Poco::Net::WebSocket::FRAME_OP_PING: {
|
case Poco::Net::WebSocket::FRAME_OP_PING: {
|
||||||
WS_->sendFrame("", 0,
|
WS_->sendFrame("", 0,
|
||||||
(int)Poco::Net::WebSocket::FRAME_OP_PONG |
|
(int)Poco::Net::WebSocket::FRAME_OP_PONG |
|
||||||
(int)Poco::Net::WebSocket::FRAME_FLAG_FIN);
|
(int)Poco::Net::WebSocket::FRAME_FLAG_FIN);
|
||||||
}
|
} break;
|
||||||
break;
|
case Poco::Net::WebSocket::FRAME_OP_PONG: {
|
||||||
case Poco::Net::WebSocket::FRAME_OP_PONG: {
|
} break;
|
||||||
}
|
case Poco::Net::WebSocket::FRAME_OP_CLOSE: {
|
||||||
break;
|
Logger().warning(Poco::format("CLOSE(%s): Client is closing its connection.", Id_));
|
||||||
case Poco::Net::WebSocket::FRAME_OP_CLOSE: {
|
Done = true;
|
||||||
Logger().warning(Poco::format("CLOSE(%s): Client is closing its connection.",Id_));
|
} break;
|
||||||
Done=true;
|
case Poco::Net::WebSocket::FRAME_OP_TEXT: {
|
||||||
}
|
IncomingFrame.append(0);
|
||||||
break;
|
if (!Authenticated_) {
|
||||||
case Poco::Net::WebSocket::FRAME_OP_TEXT: {
|
std::string Frame{IncomingFrame.begin()};
|
||||||
IncomingFrame.append(0);
|
auto Tokens = Utils::Split(Frame, ':');
|
||||||
if(!Authenticated_) {
|
bool Expired = false, Contacted = false;
|
||||||
std::string Frame{IncomingFrame.begin()};
|
if (Tokens.size() == 2 &&
|
||||||
auto Tokens = Utils::Split(Frame,':');
|
AuthClient()->IsAuthorized(Tokens[1], UserInfo_, Expired, Contacted)) {
|
||||||
bool Expired = false, Contacted = false;
|
Authenticated_ = true;
|
||||||
if(Tokens.size()==2 && AuthClient()->IsAuthorized(Tokens[1], UserInfo_, Expired, Contacted)) {
|
std::string S{"Welcome! Bienvenue! Bienvenidos!"};
|
||||||
Authenticated_=true;
|
WS_->sendFrame(S.c_str(), S.size());
|
||||||
std::string S{"Welcome! Bienvenue! Bienvenidos!"};
|
WebSocketClientServer()->SetUser(Id_, UserInfo_.userinfo.email);
|
||||||
WS_->sendFrame(S.c_str(),S.size());
|
} else {
|
||||||
WebSocketClientServer()->SetUser(Id_,UserInfo_.userinfo.email);
|
std::string S{"Invalid token. Closing connection."};
|
||||||
} else {
|
WS_->sendFrame(S.c_str(), S.size());
|
||||||
std::string S{"Invalid token. Closing connection."};
|
Done = true;
|
||||||
WS_->sendFrame(S.c_str(),S.size());
|
}
|
||||||
Done=true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
Poco::JSON::Parser P;
|
Poco::JSON::Parser P;
|
||||||
auto Obj = P.parse(IncomingFrame.begin())
|
auto Obj =
|
||||||
.extract<Poco::JSON::Object::Ptr>();
|
P.parse(IncomingFrame.begin()).extract<Poco::JSON::Object::Ptr>();
|
||||||
std::string Answer;
|
std::string Answer;
|
||||||
if(Processor_!= nullptr)
|
if (Processor_ != nullptr)
|
||||||
Processor_->Processor(Obj, Answer, Done);
|
Processor_->Processor(Obj, Answer, Done);
|
||||||
if (!Answer.empty())
|
if (!Answer.empty())
|
||||||
WS_->sendFrame(Answer.c_str(), (int) Answer.size());
|
WS_->sendFrame(Answer.c_str(), (int)Answer.size());
|
||||||
else {
|
else {
|
||||||
WS_->sendFrame("{}", 2);
|
WS_->sendFrame("{}", 2);
|
||||||
}
|
}
|
||||||
} catch (const Poco::JSON::JSONException & E) {
|
} catch (const Poco::JSON::JSONException &E) {
|
||||||
Logger().log(E);
|
Logger().log(E);
|
||||||
}
|
Done=true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
} break;
|
||||||
default:
|
default: {
|
||||||
{
|
}
|
||||||
|
}
|
||||||
}
|
} catch (...) {
|
||||||
}
|
Done=true;
|
||||||
|
}
|
||||||
|
|
||||||
if(Done) {
|
if(Done) {
|
||||||
delete this;
|
delete this;
|
||||||
|
|||||||
@@ -133,6 +133,37 @@ namespace ORM {
|
|||||||
return R;
|
return R;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline std::string WHERE_AND_(std::string Result) {
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename... Args> std::string WHERE_AND_(std::string Result, const char *fieldName, const T &Value, Args... args) {
|
||||||
|
if constexpr(std::is_same_v<T,std::string>)
|
||||||
|
{
|
||||||
|
if(!Value.empty()) {
|
||||||
|
if(!Result.empty())
|
||||||
|
Result += " and ";
|
||||||
|
Result += fieldName;
|
||||||
|
Result += '=';
|
||||||
|
Result += "'";
|
||||||
|
Result += Escape(Value);
|
||||||
|
Result += "'";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(!Result.empty())
|
||||||
|
Result += " and ";
|
||||||
|
Result += fieldName ;
|
||||||
|
Result += '=';
|
||||||
|
Result += std::to_string(Value);
|
||||||
|
}
|
||||||
|
return WHERE_AND_(Result,args...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... Args> std::string WHERE_AND(Args... args) {
|
||||||
|
std::string Result;
|
||||||
|
return WHERE_AND_(Result, args...);
|
||||||
|
}
|
||||||
|
|
||||||
enum SqlComparison { EQ = 0, NEQ, LT, LTE, GT, GTE };
|
enum SqlComparison { EQ = 0, NEQ, LT, LTE, GT, GTE };
|
||||||
enum SqlBinaryOp { AND = 0 , OR };
|
enum SqlBinaryOp { AND = 0 , OR };
|
||||||
|
|
||||||
|
|||||||
13
src/ow_version.h
Normal file
13
src/ow_version.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
//
|
||||||
|
// Created by stephane bourque on 2021-12-06.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace OW_VERSION {
|
||||||
|
inline static const std::string VERSION{"2.6.0"};
|
||||||
|
inline static const std::string BUILD{"128"};
|
||||||
|
inline static const std::string HASH{"3b0f2a0"};
|
||||||
|
}
|
||||||
@@ -96,40 +96,42 @@ namespace OpenWifi {
|
|||||||
void EntityDB::AddVenues(Poco::JSON::Object &Tree, const std::string & Node) {
|
void EntityDB::AddVenues(Poco::JSON::Object &Tree, const std::string & Node) {
|
||||||
ProvObjects::Venue E;
|
ProvObjects::Venue E;
|
||||||
// std::cout << "Adding venue:" << Node << std::endl;
|
// std::cout << "Adding venue:" << Node << std::endl;
|
||||||
StorageService()->VenueDB().GetRecord("id",Node,E);
|
if(StorageService()->VenueDB().GetRecord("id",Node,E)) {
|
||||||
Poco::JSON::Array Venues;
|
Poco::JSON::Array Venues;
|
||||||
for(const auto &i:E.children) {
|
for (const auto &i: E.children) {
|
||||||
Poco::JSON::Object Venue;
|
Poco::JSON::Object Venue;
|
||||||
AddVenues(Venue, i);
|
AddVenues(Venue, i);
|
||||||
Venues.add(Venue);
|
Venues.add(Venue);
|
||||||
|
}
|
||||||
|
Tree.set("type", "venue");
|
||||||
|
Tree.set("name", E.info.name);
|
||||||
|
Tree.set("uuid", E.info.id);
|
||||||
|
Tree.set("children", Venues);
|
||||||
}
|
}
|
||||||
Tree.set("type","venue");
|
|
||||||
Tree.set("name",E.info.name);
|
|
||||||
Tree.set("uuid",E.info.id);
|
|
||||||
Tree.set("children",Venues);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityDB::BuildTree(Poco::JSON::Object &Tree, const std::string & Node) {
|
void EntityDB::BuildTree(Poco::JSON::Object &Tree, const std::string & Node) {
|
||||||
ProvObjects::Entity E;
|
ProvObjects::Entity E;
|
||||||
// std::cout << "Adding node:" << Node << std::endl;
|
// std::cout << "Adding node:" << Node << std::endl;
|
||||||
StorageService()->EntityDB().GetRecord("id",Node,E);
|
if(StorageService()->EntityDB().GetRecord("id",Node,E)) {
|
||||||
Poco::JSON::Array Children;
|
Poco::JSON::Array Children;
|
||||||
for(const auto &i:E.children) {
|
for (const auto &i: E.children) {
|
||||||
Poco::JSON::Object Child;
|
Poco::JSON::Object Child;
|
||||||
BuildTree(Child,i);
|
BuildTree(Child, i);
|
||||||
Children.add(Child);
|
Children.add(Child);
|
||||||
|
}
|
||||||
|
Poco::JSON::Array Venues;
|
||||||
|
for (const auto &i: E.venues) {
|
||||||
|
Poco::JSON::Object Venue;
|
||||||
|
AddVenues(Venue, i);
|
||||||
|
Venues.add(Venue);
|
||||||
|
}
|
||||||
|
Tree.set("type", "entity");
|
||||||
|
Tree.set("name", E.info.name);
|
||||||
|
Tree.set("uuid", E.info.id);
|
||||||
|
Tree.set("children", Children);
|
||||||
|
Tree.set("venues", Venues);
|
||||||
}
|
}
|
||||||
Poco::JSON::Array Venues;
|
|
||||||
for(const auto &i:E.venues) {
|
|
||||||
Poco::JSON::Object Venue;
|
|
||||||
AddVenues(Venue, i);
|
|
||||||
Venues.add(Venue);
|
|
||||||
}
|
|
||||||
Tree.set("type","entity");
|
|
||||||
Tree.set("name",E.info.name);
|
|
||||||
Tree.set("uuid",E.info.id);
|
|
||||||
Tree.set("children",Children);
|
|
||||||
Tree.set("venues", Venues);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityDB::ImportVenues(const Poco::JSON::Object::Ptr &O, const std::string &Parent) {
|
void EntityDB::ImportVenues(const Poco::JSON::Object::Ptr &O, const std::string &Parent) {
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by stephane bourque on 2021-10-28.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "storage_jobs.h"
|
|
||||||
#include "framework/OpenWifiTypes.h"
|
|
||||||
#include "framework/MicroService.h"
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
|
||||||
|
|
||||||
static ORM::FieldVec JobDB_Fields{
|
|
||||||
// object info
|
|
||||||
ORM::Field{"id",64, true},
|
|
||||||
ORM::Field{"name",ORM::FieldType::FT_TEXT},
|
|
||||||
ORM::Field{"description",ORM::FieldType::FT_TEXT},
|
|
||||||
ORM::Field{"type",ORM::FieldType::FT_TEXT},
|
|
||||||
ORM::Field{"progress",ORM::FieldType::FT_BIGINT},
|
|
||||||
ORM::Field{"total",ORM::FieldType::FT_BIGINT},
|
|
||||||
ORM::Field{"parameters",ORM::FieldType::FT_TEXT}
|
|
||||||
};
|
|
||||||
|
|
||||||
static ORM::IndexVec JobDB_Indexes{
|
|
||||||
{ std::string("job_name_index"),
|
|
||||||
ORM::IndexEntryVec{
|
|
||||||
{std::string("name"),
|
|
||||||
ORM::Indextype::ASC} } }
|
|
||||||
};
|
|
||||||
|
|
||||||
JobDB::JobDB( OpenWifi::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L) :
|
|
||||||
DB(T, "jobs", JobDB_Fields, JobDB_Indexes, P, L, "job") {}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> void ORM::DB<OpenWifi::JobDBRecordType, OpenWifi::JobRecord>::Convert(const OpenWifi::JobDBRecordType &In, OpenWifi::JobRecord &Out) {
|
|
||||||
Out.id = In.get<0>();
|
|
||||||
Out.name = In.get<1>();
|
|
||||||
Out.description = In.get<2>();
|
|
||||||
Out.type = In.get<3>();
|
|
||||||
Out.progress = In.get<4>();
|
|
||||||
Out.total = In.get<5>();
|
|
||||||
Out.parameters = OpenWifi::RESTAPI_utils::to_array_of_array_of_object<OpenWifi::Job::Parameter>(In.get<3>());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<> void ORM::DB<OpenWifi::JobDBRecordType, OpenWifi::JobRecord>::Convert(const OpenWifi::JobRecord &In, OpenWifi::JobDBRecordType &Out) {
|
|
||||||
Out.set<0>(In.id);
|
|
||||||
Out.set<1>(In.name);
|
|
||||||
Out.set<2>(In.description);
|
|
||||||
Out.set<3>(In.type);
|
|
||||||
Out.set<4>(In.progress);
|
|
||||||
Out.set<5>(In.total);
|
|
||||||
Out.set<6>(OpenWifi::RESTAPI_utils::to_string(In.parameters));
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by stephane bourque on 2021-10-28.
|
|
||||||
//
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "framework/orm.h"
|
|
||||||
#include "JobController.h"
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
|
||||||
typedef Poco::Tuple<
|
|
||||||
std::string,
|
|
||||||
std::string,
|
|
||||||
std::string,
|
|
||||||
std::string,
|
|
||||||
uint64_t,
|
|
||||||
uint64_t,
|
|
||||||
std::string
|
|
||||||
> JobDBRecordType;
|
|
||||||
|
|
||||||
struct JobRecord {
|
|
||||||
Types::UUID_t id;
|
|
||||||
std::string name;
|
|
||||||
std::string description;
|
|
||||||
std::string type;
|
|
||||||
uint64_t progress;
|
|
||||||
uint64_t total;
|
|
||||||
Job::ParametersVec parameters;
|
|
||||||
|
|
||||||
// void from_string(const std::string &S);
|
|
||||||
// std::string to_string() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
class JobDB : public ORM::DB<JobDBRecordType, JobRecord> {
|
|
||||||
public:
|
|
||||||
JobDB( OpenWifi::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L);
|
|
||||||
virtual ~JobDB() {};
|
|
||||||
private:
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -499,6 +499,14 @@ listvenues() {
|
|||||||
jq < ${result_file}
|
jq < ${result_file}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getvenuedevices() {
|
||||||
|
curl ${FLAGS} -X GET "https://${OWPROV}/api/v1/venue/$1?getDevices=true&getChildren=true" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "Authorization: Bearer ${token}" \
|
||||||
|
-H "Accept: application/json" > ${result_file}
|
||||||
|
jq < ${result_file}
|
||||||
|
}
|
||||||
|
|
||||||
shopt -s nocasematch
|
shopt -s nocasematch
|
||||||
case "$1" in
|
case "$1" in
|
||||||
"login") login; echo "You are logged in..." ; logout ;;
|
"login") login; echo "You are logged in..." ; logout ;;
|
||||||
@@ -546,6 +554,7 @@ case "$1" in
|
|||||||
"getsignup") login; getsignup $2; logout;;
|
"getsignup") login; getsignup $2; logout;;
|
||||||
"getsubdevs") login; getsubdevs $2; logout;;
|
"getsubdevs") login; getsubdevs $2; logout;;
|
||||||
"listvenues") login; listvenues $2; logout;;
|
"listvenues") login; listvenues $2; logout;;
|
||||||
|
"getvenuedevices") login; getvenuedevices $2; logout;;
|
||||||
*) help ;;
|
*) help ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user