Compare commits

..

52 Commits

Author SHA1 Message Date
TIP Automation User
7fcf2ca41b Chg: update image tag in helm values to v2.6.0 2022-07-11 11:14:16 +00:00
TIP Automation User
3c2017859b Chg: update image tag in helm values to v2.6.0-RC5 2022-07-11 11:02:39 +00:00
Stephane Bourque
eecf9a49c2 Merge pull request #44 from Telecominfraproject/main
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
2022-07-10 09:22:05 -07:00
Stephane Bourque
5945d02b3d Merge pull request #43 from Telecominfraproject/WIFI-10070
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
2022-07-10 08:56:53 -07:00
stephb9959
0ac192cdc0 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-10 08:55:45 -07:00
stephb9959
1b5eb87eef Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-09 21:15:07 -07:00
stephb9959
46db18d7cd Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-09 21:13:10 -07:00
stephb9959
30b8665d7d Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-09 20:37:21 -07:00
stephb9959
c8b3a3b060 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-09 20:36:00 -07:00
TIP Automation User
944500dea9 Chg: update image tag in helm values to v2.6.0-RC4 2022-07-09 12:17:56 +00:00
Stephane Bourque
a5e0dcb210 Merge pull request #42 from Telecominfraproject/main
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
2022-07-08 22:38:25 -07:00
Stephane Bourque
096da35ff4 Merge pull request #41 from Telecominfraproject/WIFI-10070
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
2022-07-08 22:11:59 -07:00
stephb9959
bd7f3af11c Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-08 22:10:57 -07:00
Stephane Bourque
2a06021c4a Merge pull request #40 from Telecominfraproject/WIFI-10070
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
2022-07-08 21:55:15 -07:00
stephb9959
bf18bb25ba Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-08 21:54:35 -07:00
Stephane Bourque
656562c691 Merge pull request #39 from Telecominfraproject/main
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
2022-07-07 22:19:44 -07:00
Stephane Bourque
e93f899b76 Merge pull request #38 from Telecominfraproject/WIFI-10070
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
2022-07-07 21:44:36 -07:00
stephb9959
eda73038f6 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-07 21:04:13 -07:00
Stephane Bourque
953ca155a4 Merge pull request #37 from Telecominfraproject/WIFI-10070
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
2022-07-07 10:51:39 -07:00
stephb9959
898806f232 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-07 10:49:55 -07:00
stephb9959
7d97b19b85 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-07 10:47:09 -07:00
stephb9959
d6c587fde6 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-07 10:33:52 -07:00
stephb9959
58c9a7805b Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-07 10:29:15 -07:00
stephb9959
94dd4c84e9 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-07 10:26:33 -07:00
stephb9959
2636715f6f Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-07 10:24:19 -07:00
stephb9959
f9f4624add Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-07 10:23:01 -07:00
stephb9959
cf441de197 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-07 10:16:35 -07:00
Stephane Bourque
2ea7e3dcc5 Merge pull request #36 from Telecominfraproject/main
https://telecominfraproject.atlassian.net/browse/WIFI-10004
2022-07-05 20:17:02 -07:00
Stephane Bourque
158455a528 Merge pull request #35 from Telecominfraproject/WIFI-10004v2
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10004
2022-07-05 19:32:34 -07:00
stephb9959
4d2ccec1a8 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10004
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-05 15:23:04 -07:00
Stephane Bourque
7dad5a9bdb Merge pull request #34 from Telecominfraproject/WIFI-10004
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10040
2022-07-04 21:40:30 -07:00
stephb9959
cd2ac84c5b Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10040
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-04 14:02:56 -07:00
Stephane Bourque
205343619b Merge pull request #33 from Telecominfraproject/main
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10004
2022-07-01 09:51:51 -07:00
Stephane Bourque
9735f709e9 Merge pull request #32 from Telecominfraproject/WIFI-10004
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10004
2022-07-01 09:21:12 -07:00
stephb9959
ae5fd31818 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10004
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10017
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10019

Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-01 08:32:16 -07:00
Johann Hoffmann
aa1136e55b Always re-generate config file if TEMPLATE_CONFIG is set to true (#31)
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-06-24 18:30:02 +02:00
Johann Hoffmann
2b46ad4a66 Always re-generate config file if TEMPLATE_CONFIG is set to true (#30)
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-06-24 18:29:52 +02:00
TIP Automation User
439aa1d07a Chg: update image tag in helm values to v2.6.0-RC3 2022-06-23 19:01:35 +00:00
Stephane Bourque
a9293a7717 Merge pull request #29 from Telecominfraproject/main
https://telecominfraproject.atlassian.net/browse/WIFI-9553
2022-06-23 11:28:26 -07:00
stephb9959
43d7078cb7 Merge remote-tracking branch 'origin/main' 2022-06-23 10:57:05 -07:00
stephb9959
18f5d42f00 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9553
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-23 10:56:55 -07:00
stephb9959
70622b2bb8 Merge branch 'main' of github.com:Telecominfraproject/wlan-cloud-owprov 2022-06-23 10:45:09 -07:00
stephb9959
5b24aea47c Fix: https://telecominfraproject.atlassian.net/browse/WIFI-7955
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-23 10:43:59 -07:00
stephb9959
e97617a0db Fix: https://telecominfraproject.atlassian.net/browse/WIFI-7955
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-23 10:36:05 -07:00
stephb9959
ba63a7033f Merge remote-tracking branch 'origin/main' 2022-06-20 15:48:27 -07:00
stephb9959
e9db2e1a0d Fix:https://telecominfraproject.atlassian.net/browse/WIFI-7955
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-20 15:48:19 -07:00
stephb9959
d85fef7725 Merge remote-tracking branch 'origin/main' 2022-06-20 12:39:53 -07:00
stephb9959
543c46bf68 Fixing: https://telecominfraproject.atlassian.net/browse/WIFI-9466
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-20 12:39:45 -07:00
stephb9959
73eec53fe4 Merge remote-tracking branch 'origin/main' 2022-06-18 21:59:08 -07:00
stephb9959
8ad2d67c2c Framework update.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-18 21:58:59 -07:00
Johann Hoffmann
442f810688 Supress curl output in PR cleanup workflow
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-06-17 13:27:19 +02:00
Johann Hoffmann
2dca5204ea [WIFI-9534] Add condition to avoid deleting default and release branch images
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-06-17 13:24:41 +02:00
26 changed files with 642 additions and 741 deletions

View File

@@ -4,6 +4,7 @@ on:
pull_request:
branches:
- main
- 'release/*'
types: [ closed ]
defaults:
@@ -16,4 +17,10 @@ jobs:
steps:
- run: |
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

View File

@@ -125,7 +125,6 @@ add_executable(owprov
src/RESTAPI/RESTAPI_db_helpers.h
src/JobController.cpp src/JobController.h
src/JobRegistrations.cpp
src/storage/storage_jobs.cpp src/storage/storage_jobs.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_list_handler.cpp src/RESTAPI/RESTAPI_map_list_handler.h

2
build
View File

@@ -1 +1 @@
128
141

View File

@@ -5,7 +5,7 @@ if [ "$SELFSIGNED_CERTS" = 'true' ]; then
update-ca-certificates
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_PORT=${RESTAPI_HOST_PORT:-"16005"} \
RESTAPI_HOST_CERT=${RESTAPI_HOST_CERT:-"\$OWPROV_ROOT/certs/restapi-cert.pem"} \

View File

@@ -9,7 +9,7 @@ fullnameOverride: ""
images:
owprov:
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owprov
tag: v2.6.0-RC2
tag: v2.6.0
pullPolicy: Always
# regcred:
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io

View File

@@ -27,71 +27,13 @@ components:
responses:
NotFound:
description: The specified resource was not found.
content:
application/json:
schema:
properties:
ErrorCode:
type: integer
ErrorDetails:
type: string
ErrorDescription:
type: string
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/NotFound'
Unauthorized:
description: The requested does not have sufficient rights to perform the operation.
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
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Unauthorized'
Success:
description: The requested operation was performed.
content:
application/json:
schema:
properties:
Operation:
type: string
Details:
type: string
Code:
type: integer
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Success'
BadRequest:
description: The requested operation failed.
content:
application/json:
schema:
properties:
ErrorCode:
type: integer
ErrorDetails:
type: string
ErrorDescription:
type: integer
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/BadRequest'
schemas:

View File

@@ -153,60 +153,62 @@ namespace OpenWifi {
}
}
std::set<std::string> Sections;
for(const auto &i:Config_) {
Poco::JSON::Parser P;
auto O = P.parse(i.element.configuration).extract<Poco::JSON::Object::Ptr>();
auto Names = O->getNames();
for(const auto &SectionName:Names) {
auto InsertInfo = Sections.insert(SectionName);
if (InsertInfo.second) {
if (O->isArray(SectionName)) {
auto OriginalArray = O->getArray(SectionName);
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", OriginalArray);
Explanation_.add(ExObj);
try {
std::set<std::string> Sections;
for (const auto &i: Config_) {
Poco::JSON::Parser P;
auto O = P.parse(i.element.configuration).extract<Poco::JSON::Object::Ptr>();
auto Names = O->getNames();
for (const auto &SectionName: Names) {
auto InsertInfo = Sections.insert(SectionName);
if (InsertInfo.second) {
if (O->isArray(SectionName)) {
auto OriginalArray = O->getArray(SectionName);
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", 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 {
std::cout << " --- unknown element type --- " << O->get(SectionName).toString() << std::endl;
}
} else {
if (Explain_) {
Poco::JSON::Object ExObj;
ExObj.set("from-uuid", i.info.id);
ExObj.set("from-name", i.info.name);
ExObj.set("action", "ignored");
ExObj.set("reason", "weight insufficient");
ExObj.set("element", O->get(SectionName));
Explanation_.add(ExObj);
if (Explain_) {
Poco::JSON::Object ExObj;
ExObj.set("from-uuid", i.info.id);
ExObj.set("from-name", i.info.name);
ExObj.set("action", "ignored");
ExObj.set("reason", "weight insufficient");
ExObj.set("element", O->get(SectionName));
Explanation_.add(ExObj);
}
}
}
}
}
if(Config_.empty())
return false;
} catch (...) {
return true;
}
return !Config_.empty();
}
static bool DeviceTypeMatch(const std::string &DeviceType, const Types::StringVec & Types) {

View File

@@ -26,6 +26,7 @@ namespace OpenWifi {
void AutoDiscovery::run() {
Poco::AutoPtr<Poco::Notification> Note(Queue_.waitDequeueNotification());
Utils::SetThreadName("auto-discovery");
while(Note && Running_) {
auto Msg = dynamic_cast<DiscoveryMessage *>(Note.get());
if(Msg!= nullptr) {

View File

@@ -33,7 +33,7 @@ namespace OpenWifi {
void Stop() override;
void ConnectionReceived( const std::string & Key, const std::string & Payload) {
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));
}
void run() override;

View File

@@ -26,6 +26,8 @@ namespace OpenWifi {
{"https://ucentral.io/ucentral.schema.pretty.json", "ucentral.schema.pretty.json" }
};
Utils::SetThreadName("file-dmnldr");
for(const auto &[url,filename]:Files) {
try {
std::string FileContent;

View File

@@ -27,11 +27,32 @@ namespace OpenWifi {
void JobController::run() {
Running_ = true ;
Utils::SetThreadName("job-controller");
while(Running_) {
Poco::Thread::trySleep(2000);
std::lock_guard G(Mutex_);
for(auto &current_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;
}
}
}
}
}

View File

@@ -7,99 +7,45 @@
#include <vector>
#include <utility>
#include <functional>
#include <list>
#include "framework/MicroService.h"
namespace OpenWifi {
class Job {
public:
struct Parameter {
std::string name;
std::string value;
inline void to_json(Poco::JSON::Object &Obj) const {
RESTAPI_utils::field_to_json(Obj,"name",name);
RESTAPI_utils::field_to_json(Obj,"value",value);
}
class Job : public Poco::Runnable {
public:
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) :
jobId_(JobID),
name_(name),
parameters_(parameters),
when_(when),
userinfo_(UI),
Logger_(L)
{};
inline bool from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
RESTAPI_utils::field_from_json(Obj,"name",name);
RESTAPI_utils::field_from_json(Obj,"value",value);
return true;
} catch (...) {
virtual void run() = 0;
[[nodiscard]] std::string Name() const { return name_; }
const SecurityObjects::UserInfo & UserInfo() const { return userinfo_; }
Poco::Logger & Logger() { return Logger_; }
const std::string & JobId() const { return jobId_; }
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(); }
}
return false;
}
};
struct Status {
Types::UUID_t UUID;
uint64_t Start = 0 ;
uint64_t Progress = 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_;
private:
std::string jobId_;
std::string name_;
std::vector<std::string> parameters_;
uint64_t when_=0;
SecurityObjects::UserInfo userinfo_;
Poco::Logger & Logger_;
uint64_t started_=0;
uint64_t completed_=0;
};
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 {
public:
static auto instance() {
@@ -112,11 +58,16 @@ namespace OpenWifi {
void run() override;
inline void wakeup() { Thr_.wakeUp(); }
bool JobList(Job::Statuses & Statuses);
void AddJob( Job* newJob ) {
std::lock_guard G(Mutex_);
jobs_.push_back(newJob);
}
private:
Poco::Thread Thr_;
std::atomic_bool Running_=false;
Poco::Thread Thr_;
std::atomic_bool Running_=false;
std::list<Job *> jobs_;
Poco::ThreadPool Pool_;
JobController() noexcept:
SubSystemServer("JobController", "JOB-SVR", "job")

View File

@@ -27,6 +27,7 @@ namespace OpenWifi{
for (const auto &i: V.children) {
ProvObjects::Venue 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);
std::copy(LowerDevs.begin(), LowerDevs.end(), std::back_inserter(R));
}
@@ -227,10 +228,10 @@ namespace OpenWifi{
Poco::JSON::Object Answer;
SNL.serialNumbers = Existing.devices;
auto Task = new VenueConfigUpdater(UUID,UserInfo_.userinfo,0,Logger());
auto JobId = Task->Start();
auto JobId = MicroService::instance().CreateUUID();
Types::StringVec Parameters{UUID};;
auto NewJob = new VenueConfigUpdater(JobId,"VenueConfigurationUpdater", Parameters, 0, UserInfo_.userinfo, Logger());
JobController()->AddJob(dynamic_cast<Job*>(NewJob));
SNL.to_json(Answer);
Answer.set("jobId",JobId);
return ReturnObject(Answer);
@@ -241,10 +242,10 @@ namespace OpenWifi{
Poco::JSON::Object Answer;
SNL.serialNumbers = Existing.devices;
auto Task = new VenueUpgrade(UUID,UserInfo_.userinfo,0,Logger());
auto JobId = Task->Start();
auto JobId = MicroService::instance().CreateUUID();
Types::StringVec Parameters{UUID};;
auto NewJob = new VenueUpgrade(JobId,"VenueFirmwareUpgrade", Parameters, 0, UserInfo_.userinfo, Logger());
JobController()->AddJob(dynamic_cast<Job*>(NewJob));
SNL.to_json(Answer);
Answer.set("jobId",JobId);
return ReturnObject(Answer);
@@ -255,10 +256,10 @@ namespace OpenWifi{
Poco::JSON::Object Answer;
SNL.serialNumbers = Existing.devices;
auto Task = new VenueRebooter(UUID,UserInfo_.userinfo,0,Logger());
auto JobId = Task->Start();
auto JobId = MicroService::instance().CreateUUID();
Types::StringVec Parameters{UUID};;
auto NewJob = new VenueRebooter(JobId,"VenueRebooter", Parameters, 0, UserInfo_.userinfo, Logger());
JobController()->AddJob(dynamic_cast<Job*>(NewJob));
SNL.to_json(Answer);
Answer.set("jobId",JobId);
return ReturnObject(Answer);

View File

@@ -42,6 +42,7 @@ namespace OpenWifi {
void Signup::run() {
Running_ = true;
Utils::SetThreadName("signup-mgr");
while(Running_) {
Poco::Thread::trySleep(5000);

View File

@@ -105,6 +105,7 @@ namespace OpenWifi {
}
void Storage::onTimer([[maybe_unused]] Poco::Timer &timer) {
Utils::SetThreadName("strg-janitor");
}
void Storage::Stop() {
@@ -213,31 +214,109 @@ namespace OpenWifi {
return true;
};
auto FixEntityDevices = [&](const ProvObjects::Entity &E) -> bool {
auto FixEntity = [&](const ProvObjects::Entity &E) -> bool {
Types::UUIDvec_t NewDevices;
bool Modified=false;
for(const auto &device:E.devices) {
ProvObjects::InventoryTag T;
if(InventoryDB().GetRecord("id", device, T)) {
NewDevices.emplace_back(device);
} 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));
ProvObjects::Entity NewEntity = E;
NewEntity.devices = NewDevices;
NewEntity.contacts = NewContacts;
NewEntity.locations = NewLocations;
NewEntity.venues = NewVenues;
NewEntity.variables = NewVariables;
EntityDB().UpdateRecord("id", E.info.id, NewEntity);
}
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");
VenueDB().Iterate(FixVenueDevices);
Logger().information("Checking DB consistency: entities");
EntityDB().Iterate(FixEntityDevices);
EntityDB().Iterate(FixEntity);
Logger().information("Checking DB consistency: inventory");
InventoryDB().Iterate(FixInventory);
}
void Storage::InitializeSystemDBs() {

View File

@@ -21,7 +21,7 @@ namespace OpenWifi {
}
void TagServer::run() {
Utils::SetThreadName("tag-server");
}
}

View File

@@ -9,6 +9,7 @@
#include "APConfig.h"
#include "sdks/SDK_gw.h"
#include "framework/WebSocketClientNotifications.h"
#include "JobController.h"
namespace OpenWifi {
@@ -19,8 +20,6 @@ namespace OpenWifi {
auto Status = Results->get("status").extract<Poco::JSON::Object::Ptr>();
auto Rejected = Status->getArray("rejected");
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 (...) {
}
@@ -37,35 +36,42 @@ namespace OpenWifi {
void run() final {
ProvObjects::InventoryTag Device;
started_=true;
Utils::SetThreadName("venue-cfg");
if(StorageService()->InventoryDB().GetRecord("id",uuid_,Device)) {
SerialNumber = Device.serialNumber;
// std::cout << "Starting push for " << Device.serialNumber << std::endl;
Logger().debug(fmt::format("{}: Computing configuration.",Device.serialNumber));
auto DeviceConfig = std::make_shared<APConfig>(Device.serialNumber, Device.deviceType, Logger(), false);
auto Configuration = Poco::makeShared<Poco::JSON::Object>();
if (DeviceConfig->Get(Configuration)) {
std::ostringstream OS;
Configuration->stringify(OS);
auto Response=Poco::makeShared<Poco::JSON::Object>();
Logger().debug(fmt::format("{}: Pushing configuration.",Device.serialNumber));
if (SDK::GW::Device::Configure(nullptr, Device.serialNumber, Configuration, Response)) {
Logger().debug(fmt::format("{}: Configuration pushed.",Device.serialNumber));
Logger().information(fmt::format("{}: Updated.", Device.serialNumber));
// std::cout << Device.serialNumber << ": Updated" << std::endl;
updated_++;
try {
if (DeviceConfig->Get(Configuration)) {
std::ostringstream OS;
Configuration->stringify(OS);
auto Response = Poco::makeShared<Poco::JSON::Object>();
Logger().debug(fmt::format("{}: Pushing configuration.", Device.serialNumber));
if (SDK::GW::Device::Configure(nullptr, Device.serialNumber, Configuration, Response)) {
Logger().debug(fmt::format("{}: Configuration pushed.", Device.serialNumber));
Logger().information(fmt::format("{}: Updated.", Device.serialNumber));
// 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 {
Logger().information(fmt::format("{}: Not updated.", Device.serialNumber));
// std::cout << Device.serialNumber << ": Failed" << std::endl;
failed_++;
Logger().debug(fmt::format("{}: Configuration is bad.", Device.serialNumber));
bad_config_++;
// std::cout << Device.serialNumber << ": Bad config" << std::endl;
}
} else {
Logger().debug(fmt::format("{}: Configuration is bad.",Device.serialNumber));
} catch (...) {
Logger().debug(fmt::format("{}: Configuration is bad (caused an exception).", Device.serialNumber));
bad_config_++;
// std::cout << Device.serialNumber << ": Bad config" << std::endl;
}
}
done_ = true;
// std::cout << "Done push for " << Device.serialNumber << std::endl;
Utils::SetThreadName("free");
}
uint64_t updated_=0, failed_=0, bad_config_=0;
@@ -80,133 +86,101 @@ namespace OpenWifi {
inline Poco::Logger & Logger() { return Logger_; }
};
class VenueConfigUpdater: public Poco::Runnable {
class VenueConfigUpdater: public Job {
public:
explicit VenueConfigUpdater(const std::string & VenueUUID, const SecurityObjects::UserInfo &UI, uint64_t When, Poco::Logger &L) :
VenueUUID_(VenueUUID),
UI_(UI),
When_(When),
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) :
Job(JobID, name, parameters, when, UI, L) {
}
inline std::string Start() {
JobId_ = MicroService::CreateUUID();
Worker_.start(*this);
return JobId_;
}
inline virtual void run() {
std::string VenueUUID_;
private:
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 );
Utils::SetThreadName("venue-update");
VenueUUID_ = Parameter(0);
WebSocketNotification<WebSocketNotificationJobContent> N;
Logger().information(fmt::format("Job {} Starting.", JobId_));
ProvObjects::Venue Venue;
uint64_t Updated = 0, Failed = 0 , BadConfigs = 0 ;
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.jobId = JobId_;
N.content.jobId = JobId();
Poco::ThreadPool Pool_;
std::list<VenueDeviceConfigUpdater*> JobList;
std::array<tState,MaxThreads> Tasks;
for(const auto &uuid:Venue.devices) {
auto NewTask = new VenueDeviceConfigUpdater(uuid, Venue.info.name, Logger());
// std::cout << "Scheduling config push for " << uuid << std::endl;
bool found_slot = false;
while (!found_slot) {
for (auto &cur_task: Tasks) {
if (cur_task.task == nullptr) {
cur_task.task = NewTask;
cur_task.thr_.start(*NewTask);
found_slot = true;
break;
}
bool TaskAdded=false;
while(!TaskAdded) {
if (Pool_.available()) {
JobList.push_back(NewTask);
Pool_.start(*NewTask);
TaskAdded = true;
continue;
}
}
// Let's look for a slot...
if (!found_slot) {
for (auto &cur_task: Tasks) {
if (cur_task.task != nullptr && cur_task.task->started_) {
if (cur_task.thr_.isRunning())
continue;
if (!cur_task.thr_.isRunning() && cur_task.task->done_) {
cur_task.thr_.join();
Updated += cur_task.task->updated_;
Failed += cur_task.task->failed_;
BadConfigs += cur_task.task->bad_config_;
cur_task.task->started_ = cur_task.task->done_ = false;
delete cur_task.task;
cur_task.task = nullptr;
}
}
for(auto job_it = JobList.begin(); job_it !=JobList.end();) {
VenueDeviceConfigUpdater * current_job = *job_it;
if(current_job!= nullptr && current_job->done_) {
Updated += current_job->updated_;
Failed += current_job->failed_;
BadConfigs += current_job->bad_config_;
if(current_job->updated_) {
N.content.success.push_back(current_job->SerialNumber);
} else if(current_job->failed_) {
N.content.warning.push_back(current_job->SerialNumber);
} else {
N.content.error.push_back(current_job->SerialNumber);
}
job_it = JobList.erase(job_it);
delete current_job;
} else {
++job_it;
}
}
}
Logger().debug("Waiting for outstanding update threads to finish.");
bool stillTasksRunning=true;
while(stillTasksRunning) {
stillTasksRunning = false;
for(auto &cur_task:Tasks) {
if(cur_task.task!= nullptr && cur_task.task->started_) {
if(cur_task.thr_.isRunning()) {
stillTasksRunning = true;
continue;
}
if(!cur_task.thr_.isRunning() && cur_task.task->done_) {
cur_task.thr_.join();
if(cur_task.task->updated_) {
Updated++;
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;
}
Pool_.joinAll();
for(auto job_it = JobList.begin(); job_it !=JobList.end();) {
VenueDeviceConfigUpdater * current_job = *job_it;
if(current_job!= nullptr && current_job->done_) {
Updated += current_job->updated_;
Failed += current_job->failed_;
BadConfigs += current_job->bad_config_;
if(current_job->updated_) {
N.content.success.push_back(current_job->SerialNumber);
} else if(current_job->failed_) {
N.content.warning.push_back(current_job->SerialNumber);
} else {
N.content.error.push_back(current_job->SerialNumber);
}
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. ",
JobId_, Updated ,Failed, BadConfigs);
JobId(), Updated ,Failed, BadConfigs);
} else {
N.content.details = fmt::format("Venue {} no longer exists.",VenueUUID_);
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.",
JobId_, Updated ,Failed, BadConfigs));
delete this;
JobId(), Updated ,Failed, BadConfigs));
Utils::SetThreadName("free");
Complete();
}
};

View File

@@ -8,6 +8,7 @@
#include "StorageService.h"
#include "APConfig.h"
#include "sdks/SDK_gw.h"
#include "JobController.h"
namespace OpenWifi {
@@ -48,129 +49,90 @@ namespace OpenWifi {
inline Poco::Logger & Logger() { return Logger_; }
};
class VenueRebooter: public Poco::Runnable {
class VenueRebooter: public Job {
public:
explicit VenueRebooter(const std::string & VenueUUID, const SecurityObjects::UserInfo &UI, uint64_t When, Poco::Logger &L) :
VenueUUID_(VenueUUID),
UI_(UI),
When_(When),
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) :
Job(JobID, name, parameters, when, UI, L) {
}
inline std::string Start() {
JobId_ = MicroService::CreateUUID();
Worker_.start(*this);
return JobId_;
}
inline virtual void run() final {
private:
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 );
Utils::SetThreadName("venue-reboot");
WebSocketClientNotificationVenueRebootList_t N;
Logger().information(fmt::format("Job {} Starting.", JobId_));
auto VenueUUID_ = Parameter(0);
ProvObjects::Venue Venue;
uint64_t rebooted_ = 0, failed_ = 0;
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.jobId = JobId_;
N.content.jobId = JobId();
std::array<tState,MaxThreads> Tasks;
Poco::ThreadPool Pool_;
std::list<VenueDeviceRebooter*> JobList;
for(const auto &uuid:Venue.devices) {
auto NewTask = new VenueDeviceRebooter(uuid, Venue.info.name, Logger());
// std::cout << "Scheduling config push for " << uuid << std::endl;
bool found_slot = false;
while (!found_slot) {
for (auto &cur_task: Tasks) {
if (cur_task.task == nullptr) {
cur_task.task = NewTask;
cur_task.thr_.start(*NewTask);
found_slot = true;
break;
}
bool TaskAdded=false;
while(!TaskAdded) {
if (Pool_.available()) {
JobList.push_back(NewTask);
Pool_.start(*NewTask);
TaskAdded = true;
continue;
}
}
// Let's look for a slot...
if (!found_slot) {
for (auto &cur_task: Tasks) {
if (cur_task.task != nullptr && cur_task.task->started_) {
if (cur_task.thr_.isRunning())
continue;
if (!cur_task.thr_.isRunning() && cur_task.task->done_) {
cur_task.thr_.join();
rebooted_ += cur_task.task->rebooted_;
failed_ += cur_task.task->failed_;
cur_task.task->started_ = cur_task.task->done_ = false;
delete cur_task.task;
cur_task.task = nullptr;
}
}
}
for(auto job_it = JobList.begin(); job_it !=JobList.end();) {
VenueDeviceRebooter * current_job = *job_it;
if(current_job!= nullptr && current_job->done_) {
if(current_job->rebooted_)
N.content.success.push_back(current_job->SerialNumber);
else
N.content.warning.push_back(current_job->SerialNumber);
rebooted_ += current_job->rebooted_;
failed_ += current_job->failed_;
job_it = JobList.erase(job_it);
delete current_job;
} else {
++job_it;
}
}
}
Logger().debug("Waiting for outstanding update threads to finish.");
bool stillTasksRunning=true;
while(stillTasksRunning) {
stillTasksRunning = false;
for(auto &cur_task:Tasks) {
if(cur_task.task!= nullptr && cur_task.task->started_) {
if(cur_task.thr_.isRunning()) {
stillTasksRunning = true;
continue;
}
if(!cur_task.thr_.isRunning() && cur_task.task->done_) {
cur_task.thr_.join();
if(cur_task.task->rebooted_) {
rebooted_++;
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);
}
cur_task.task->started_ = cur_task.task->done_ = false;
delete cur_task.task;
cur_task.task = nullptr;
}
}
Pool_.joinAll();
for(auto job_it = JobList.begin(); job_it !=JobList.end();) {
VenueDeviceRebooter * current_job = *job_it;
if(current_job!= nullptr && current_job->done_) {
if(current_job->rebooted_)
N.content.success.push_back(current_job->SerialNumber);
else
N.content.warning.push_back(current_job->SerialNumber);
rebooted_ += current_job->rebooted_;
failed_ += current_job->failed_;
job_it = JobList.erase(job_it);
delete current_job;
} else {
++job_it;
}
}
N.content.details = fmt::format("Job {} Completed: {} rebooted, {} failed to reboot.",
JobId_, rebooted_ ,failed_);
JobId(), rebooted_ ,failed_);
} else {
N.content.details = fmt::format("Venue {} no longer exists.",VenueUUID_);
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.",
JobId_, rebooted_ ,failed_));
delete this;
JobId(), rebooted_ ,failed_));
Utils::SetThreadName("free");
Complete();
}
};

View File

@@ -11,6 +11,7 @@
#include "APConfig.h"
#include "sdks/SDK_gw.h"
#include "sdks/SDK_fms.h"
#include "JobController.h"
namespace OpenWifi {
class VenueDeviceUpgrade : public Poco::Runnable {
@@ -30,7 +31,7 @@ namespace OpenWifi {
Storage::ApplyRules(rules_,Device.deviceRules);
if(Device.deviceRules.firmwareUpgrade=="no") {
std::cout << "Skipped Upgrade:" << Device.serialNumber << std::endl;
poco_debug(Logger(),fmt::format("Skipped Upgrade: {}", Device.serialNumber));
skipped_++;
done_=true;
return;
@@ -39,16 +40,14 @@ namespace OpenWifi {
FMSObjects::Firmware F;
if(SDK::FMS::Firmware::GetLatest(Device.deviceType,Device.deviceRules.rcOnly=="yes",F)) {
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));
upgraded_++;
} else {
std::cout << "Did not Upgrade:" << Device.serialNumber << " to " << F.uri << std::endl;
Logger().information(fmt::format("{}: Not Upgraded.", Device.serialNumber));
failed_++;
}
} else {
std::cout << "Did not Upgrade:" << Device.serialNumber << " to <unknown>" << std::endl;
Logger().information(fmt::format("{}: Not Upgraded. No firmware available.", Device.serialNumber));
failed_++;
}
}
@@ -69,132 +68,94 @@ namespace OpenWifi {
inline Poco::Logger & Logger() { return Logger_; }
};
class VenueUpgrade: public Poco::Runnable {
class VenueUpgrade: public Job {
public:
explicit VenueUpgrade(const std::string & VenueUUID, const SecurityObjects::UserInfo &UI, uint64_t When, Poco::Logger &L) :
VenueUUID_(VenueUUID),
UI_(UI),
When_(When),
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) :
Job(JobID, name, parameters, when, UI, L) {
}
inline std::string Start() {
JobId_ = MicroService::CreateUUID();
Worker_.start(*this);
return JobId_;
}
inline virtual void run() final {
private:
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 );
Utils::SetThreadName("venue-upgr");
auto VenueUUID_ = Parameter(0);
WebSocketClientNotificationVenueRebootList_t N;
Logger().information(fmt::format("Job {} Starting.", JobId_));
ProvObjects::Venue Venue;
uint64_t upgraded_ = 0, failed_ = 0;
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.jobId = JobId_;
N.content.jobId = JobId();
std::array<tState,MaxThreads> Tasks;
ProvObjects::DeviceRules Rules;
Poco::ThreadPool Pool_;
std::list<VenueDeviceUpgrade*> JobList;
ProvObjects::DeviceRules Rules;
StorageService()->VenueDB().EvaluateDeviceRules(Venue.info.id, Rules);
for(const auto &uuid:Venue.devices) {
auto NewTask = new VenueDeviceUpgrade(uuid, Venue.info.name, Rules,Logger());
// std::cout << "Scheduling config push for " << uuid << std::endl;
bool found_slot = false;
while (!found_slot) {
for (auto &cur_task: Tasks) {
if (cur_task.task == nullptr) {
cur_task.task = NewTask;
cur_task.thr_.start(*NewTask);
found_slot = true;
break;
}
auto NewTask = new VenueDeviceUpgrade(uuid, Venue.info.name, Rules, Logger());
bool TaskAdded = false;
while (!TaskAdded) {
if (Pool_.available()) {
JobList.push_back(NewTask);
Pool_.start(*NewTask);
TaskAdded = true;
continue;
}
}
// Let's look for a slot...
if (!found_slot) {
for (auto &cur_task: Tasks) {
if (cur_task.task != nullptr && cur_task.task->started_) {
if (cur_task.thr_.isRunning())
continue;
if (!cur_task.thr_.isRunning() && cur_task.task->done_) {
cur_task.thr_.join();
upgraded_ += cur_task.task->upgraded_;
failed_ += cur_task.task->failed_;
cur_task.task->started_ = cur_task.task->done_ = false;
delete cur_task.task;
cur_task.task = nullptr;
}
}
}
for (auto job_it = JobList.begin(); job_it != JobList.end();) {
VenueDeviceUpgrade *current_job = *job_it;
if (current_job != nullptr && current_job->done_) {
if (current_job->upgraded_)
N.content.success.push_back(current_job->SerialNumber);
else
N.content.warning.push_back(current_job->SerialNumber);
upgraded_ += current_job->upgraded_;
failed_ += current_job->failed_;
job_it = JobList.erase(job_it);
delete current_job;
} else {
++job_it;
}
}
}
Logger().debug("Waiting for outstanding update threads to finish.");
bool stillTasksRunning=true;
while(stillTasksRunning) {
stillTasksRunning = false;
for(auto &cur_task:Tasks) {
if(cur_task.task!= nullptr && cur_task.task->started_) {
if(cur_task.thr_.isRunning()) {
stillTasksRunning = true;
continue;
}
if(!cur_task.thr_.isRunning() && cur_task.task->done_) {
cur_task.thr_.join();
if(cur_task.task->upgraded_) {
upgraded_++;
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);
}
cur_task.task->started_ = cur_task.task->done_ = false;
delete cur_task.task;
cur_task.task = nullptr;
}
}
Logger().debug("Waiting for outstanding upgrade threads to finish.");
Pool_.joinAll();
for(auto job_it = JobList.begin(); job_it !=JobList.end();) {
VenueDeviceUpgrade * current_job = *job_it;
if(current_job!= nullptr && current_job->done_) {
if(current_job->upgraded_)
N.content.success.push_back(current_job->SerialNumber);
else
N.content.warning.push_back(current_job->SerialNumber);
upgraded_ += current_job->upgraded_;
failed_ += current_job->failed_;
job_it = JobList.erase(job_it);
delete current_job;
} else {
++job_it;
}
}
N.content.details = fmt::format("Job {} Completed: {} upgraded, {} failed to upgrade.",
JobId_, upgraded_ ,failed_);
JobId(), upgraded_ ,failed_);
} else {
N.content.details = fmt::format("Venue {} no longer exists.",VenueUUID_);
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.",
JobId_, upgraded_ ,failed_));
delete this;
JobId(), upgraded_ ,failed_));
Utils::SetThreadName("free");
Complete();
}
};
}

View File

@@ -643,6 +643,27 @@ namespace OpenWifi::RESTAPI_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 {
PLAIN,
BINARY,
@@ -1167,6 +1188,7 @@ namespace OpenWifi {
static const std::string uSERVICE_SUBCRIBER{ "owsub"};
static const std::string uSERVICE_INSTALLER{ "owinst"};
static const std::string uSERVICE_ANALYTICS{ "owanalytics"};
static const std::string uSERVICE_OWRRM{ "owrrm"};
class ConfigurationEntry {
public:
@@ -1315,7 +1337,7 @@ namespace OpenWifi {
inline void Start();
inline void Stop();
private:
std::atomic_bool Running_ = false;
mutable std::atomic_bool Running_ = false;
Poco::Thread Thread_;
};
@@ -1846,7 +1868,8 @@ namespace OpenWifi {
Request = &RequestIn;
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->getContentType().find("application/json")!=std::string::npos) {
@@ -1895,36 +1918,32 @@ namespace OpenWifi {
[[nodiscard]] inline bool NeedAdditionalInfo() const { return QB_.AdditionalInfo; }
[[nodiscard]] inline const std::vector<std::string> & SelectedRecords() const { return QB_.Select; }
/* [[nodiscard]] inline const Poco::JSON::Object::Ptr ParseStream() {
return IncomingParser_.parse(Request->stream()).extract<Poco::JSON::Object::Ptr>();
}
*/
inline static bool ParseBindings(const std::string & Request, const std::list<std::string> & EndPoints, BindingMap &bindings) {
bindings.clear();
auto PathItems = Poco::StringTokenizer(Request, "/");
inline static bool ParseBindings(const std::string & Request, const std::list<std::string> & EndPoints, BindingMap &bindings) {
bindings.clear();
std::vector<std::string> PathItems = Utils::Split(Request, '/');
for(const auto &EndPoint:EndPoints) {
auto ParamItems = Poco::StringTokenizer(EndPoint, "/");
if (PathItems.count() != ParamItems.count())
continue;
for(const auto &EndPoint:EndPoints) {
std::vector<std::string> ParamItems = Utils::Split(EndPoint, '/');
if (PathItems.size() != ParamItems.size())
continue;
bool Matched = true;
for (size_t i = 0; i != PathItems.size() && Matched; i++) {
if (PathItems[i] != ParamItems[i]) {
if (ParamItems[i][0] == '{') {
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;
}
bool Matched = true;
for (size_t i = 0; i < PathItems.count(); i++) {
if (PathItems[i] != ParamItems[i]) {
if (ParamItems[i][0] == '{') {
auto ParamName = ParamItems[i].substr(1, ParamItems[i].size() - 2);
bindings[Poco::toLower(ParamName)] = PathItems[i];
} else {
Matched = false;
break;
}
}
}
if(Matched)
return true;
}
return false;
}
inline void PrintBindings() {
for (const auto &[key, value] : Bindings_)
@@ -2582,7 +2601,7 @@ namespace OpenWifi {
private:
std::recursive_mutex Mutex_;
Poco::Thread Worker_;
std::atomic_bool Running_=false;
mutable std::atomic_bool Running_=false;
Poco::NotificationQueue Queue_;
};
@@ -2608,7 +2627,7 @@ namespace OpenWifi {
private:
std::recursive_mutex Mutex_;
Poco::Thread Worker_;
std::atomic_bool Running_=false;
mutable std::atomic_bool Running_=false;
};
class KafkaDispatcher : public Poco::Runnable {
@@ -2665,6 +2684,7 @@ namespace OpenWifi {
inline void run() override {
Poco::AutoPtr<Poco::Notification> Note(Queue_.waitDequeueNotification());
Utils::SetThreadName("kafka-dispatch");
while(Note && Running_) {
auto Msg = dynamic_cast<KafkaMessage*>(Note.get());
if(Msg!= nullptr) {
@@ -2690,7 +2710,7 @@ namespace OpenWifi {
std::recursive_mutex Mutex_;
Types::NotifyTable Notifiers_;
Poco::Thread Worker_;
std::atomic_bool Running_=false;
mutable std::atomic_bool Running_=false;
uint64_t FunctionId_=1;
Poco::NotificationQueue Queue_;
};
@@ -2885,6 +2905,7 @@ namespace OpenWifi {
void handleRequest(Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response) override
{
Utils::SetThreadName("alb-request");
try {
if((id_ % 100) == 0) {
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::ServerSocket> Socket_;
int Port_ = 0;
std::atomic_bool Running_=false;
mutable std::atomic_bool Running_=false;
};
inline auto ALBHealthCheckServer() { return ALBHealthCheckServer::instance(); }
@@ -2985,7 +3006,7 @@ namespace OpenWifi {
inline Poco::Net::HTTPRequestHandler *CallServer(const std::string &Path, uint64_t Id) {
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);
}
@@ -3009,7 +3030,7 @@ namespace OpenWifi {
inline Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override {
try {
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_++);
} catch (...) {
@@ -3118,7 +3139,7 @@ namespace OpenWifi {
inline Poco::Net::HTTPRequestHandler *CallServer(const std::string &Path, uint64_t Id) {
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);
}
private:
@@ -3527,7 +3548,9 @@ namespace OpenWifi {
void DaemonPostInitialization(Poco::Util::Application &self);
inline void MicroService::initialize(Poco::Util::Application &self) {
// add the default services
// Utils::SetThreadName("microservice");
// add the default services
LoadConfigurationFile();
InitializeLoggingSystem();
@@ -3922,6 +3945,7 @@ namespace OpenWifi {
inline int MicroService::main([[maybe_unused]] const ArgVec &args) {
// Utils::SetThreadName("main");
MyErrorHandler ErrorHandler(*this);
Poco::ErrorHandler::set(&ErrorHandler);
@@ -4037,6 +4061,7 @@ namespace OpenWifi {
inline void BusEventManager::run() {
Running_ = true;
Utils::SetThreadName("BusEventManager");
auto Msg = MicroService::instance().MakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_JOIN);
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,MicroService::instance().PrivateEndPoint(),Msg, false);
while(Running_) {
@@ -4122,6 +4147,8 @@ namespace OpenWifi {
}
inline void KafkaProducer::run() {
Utils::SetThreadName("KafkaProducer");
cppkafka::Configuration Config({
{ "client.id", MicroService::instance().ConfigGetString("openwifi.kafka.client.id") },
{ "metadata.broker.list", MicroService::instance().ConfigGetString("openwifi.kafka.brokerlist") }
@@ -4160,6 +4187,8 @@ namespace OpenWifi {
}
inline void KafkaConsumer::run() {
Utils::SetThreadName("KafkaConsumer");
cppkafka::Configuration Config({
{ "client.id", MicroService::instance().ConfigGetString("openwifi.kafka.client.id") },
{ "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);
void SendToAll(const std::string &Payload);
private:
std::atomic_bool Running_ = false;
mutable std::atomic_bool Running_ = false;
Poco::Thread Thr_;
// std::unique_ptr<MyParallelSocketReactor> ReactorPool_;
Poco::Net::SocketReactor Reactor_;
@@ -4915,6 +4944,7 @@ namespace OpenWifi {
inline void WebSocketClientServer::run() {
Running_ = true ;
Utils::SetThreadName("ws:clnt-svr");
while(Running_) {
Poco::Thread::trySleep(2000);
@@ -4962,8 +4992,12 @@ namespace OpenWifi {
for(const auto &client:Clients_) {
if(client.second.second == UserName) {
if(client.second.first->Send(Payload))
Sent++;
try {
if (client.second.first->Send(Payload))
Sent++;
} catch (...) {
return false;
}
}
}
return Sent>0;
@@ -4985,70 +5019,70 @@ namespace OpenWifi {
int flags;
int n;
bool Done=false;
Poco::Buffer<char> IncomingFrame(0);
n = WS_->receiveFrame(IncomingFrame, flags);
auto Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK;
try {
Poco::Buffer<char> IncomingFrame(0);
n = WS_->receiveFrame(IncomingFrame, flags);
auto Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK;
if(n==0) {
return delete this;
}
if (n == 0) {
return delete this;
}
switch(Op) {
case Poco::Net::WebSocket::FRAME_OP_PING: {
WS_->sendFrame("", 0,
(int)Poco::Net::WebSocket::FRAME_OP_PONG |
(int)Poco::Net::WebSocket::FRAME_FLAG_FIN);
}
break;
case Poco::Net::WebSocket::FRAME_OP_PONG: {
}
break;
case Poco::Net::WebSocket::FRAME_OP_CLOSE: {
Logger().warning(Poco::format("CLOSE(%s): Client is closing its connection.",Id_));
Done=true;
}
break;
case Poco::Net::WebSocket::FRAME_OP_TEXT: {
IncomingFrame.append(0);
if(!Authenticated_) {
std::string Frame{IncomingFrame.begin()};
auto Tokens = Utils::Split(Frame,':');
bool Expired = false, Contacted = false;
if(Tokens.size()==2 && AuthClient()->IsAuthorized(Tokens[1], UserInfo_, Expired, Contacted)) {
Authenticated_=true;
std::string S{"Welcome! Bienvenue! Bienvenidos!"};
WS_->sendFrame(S.c_str(),S.size());
WebSocketClientServer()->SetUser(Id_,UserInfo_.userinfo.email);
} else {
std::string S{"Invalid token. Closing connection."};
WS_->sendFrame(S.c_str(),S.size());
Done=true;
}
switch (Op) {
case Poco::Net::WebSocket::FRAME_OP_PING: {
WS_->sendFrame("", 0,
(int)Poco::Net::WebSocket::FRAME_OP_PONG |
(int)Poco::Net::WebSocket::FRAME_FLAG_FIN);
} break;
case Poco::Net::WebSocket::FRAME_OP_PONG: {
} break;
case Poco::Net::WebSocket::FRAME_OP_CLOSE: {
Logger().warning(Poco::format("CLOSE(%s): Client is closing its connection.", Id_));
Done = true;
} break;
case Poco::Net::WebSocket::FRAME_OP_TEXT: {
IncomingFrame.append(0);
if (!Authenticated_) {
std::string Frame{IncomingFrame.begin()};
auto Tokens = Utils::Split(Frame, ':');
bool Expired = false, Contacted = false;
if (Tokens.size() == 2 &&
AuthClient()->IsAuthorized(Tokens[1], UserInfo_, Expired, Contacted)) {
Authenticated_ = true;
std::string S{"Welcome! Bienvenue! Bienvenidos!"};
WS_->sendFrame(S.c_str(), S.size());
WebSocketClientServer()->SetUser(Id_, UserInfo_.userinfo.email);
} else {
std::string S{"Invalid token. Closing connection."};
WS_->sendFrame(S.c_str(), S.size());
Done = true;
}
} else {
try {
Poco::JSON::Parser P;
auto Obj = P.parse(IncomingFrame.begin())
.extract<Poco::JSON::Object::Ptr>();
std::string Answer;
if(Processor_!= nullptr)
Processor_->Processor(Obj, Answer, Done);
if (!Answer.empty())
WS_->sendFrame(Answer.c_str(), (int) Answer.size());
else {
WS_->sendFrame("{}", 2);
}
} catch (const Poco::JSON::JSONException & E) {
Logger().log(E);
}
}
}
break;
default:
{
}
}
} else {
try {
Poco::JSON::Parser P;
auto Obj =
P.parse(IncomingFrame.begin()).extract<Poco::JSON::Object::Ptr>();
std::string Answer;
if (Processor_ != nullptr)
Processor_->Processor(Obj, Answer, Done);
if (!Answer.empty())
WS_->sendFrame(Answer.c_str(), (int)Answer.size());
else {
WS_->sendFrame("{}", 2);
}
} catch (const Poco::JSON::JSONException &E) {
Logger().log(E);
Done=true;
}
}
} break;
default: {
}
}
} catch (...) {
Done=true;
}
if(Done) {
delete this;

View File

@@ -133,6 +133,37 @@ namespace ORM {
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 SqlBinaryOp { AND = 0 , OR };

13
src/ow_version.h Normal file
View 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"};
}

View File

@@ -96,40 +96,42 @@ namespace OpenWifi {
void EntityDB::AddVenues(Poco::JSON::Object &Tree, const std::string & Node) {
ProvObjects::Venue E;
// std::cout << "Adding venue:" << Node << std::endl;
StorageService()->VenueDB().GetRecord("id",Node,E);
Poco::JSON::Array Venues;
for(const auto &i:E.children) {
Poco::JSON::Object Venue;
AddVenues(Venue, i);
Venues.add(Venue);
if(StorageService()->VenueDB().GetRecord("id",Node,E)) {
Poco::JSON::Array Venues;
for (const auto &i: E.children) {
Poco::JSON::Object Venue;
AddVenues(Venue, i);
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) {
ProvObjects::Entity E;
// std::cout << "Adding node:" << Node << std::endl;
StorageService()->EntityDB().GetRecord("id",Node,E);
Poco::JSON::Array Children;
for(const auto &i:E.children) {
Poco::JSON::Object Child;
BuildTree(Child,i);
Children.add(Child);
if(StorageService()->EntityDB().GetRecord("id",Node,E)) {
Poco::JSON::Array Children;
for (const auto &i: E.children) {
Poco::JSON::Object Child;
BuildTree(Child, i);
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) {

View File

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

View File

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

View File

@@ -499,6 +499,14 @@ listvenues() {
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
case "$1" in
"login") login; echo "You are logged in..." ; logout ;;
@@ -546,6 +554,7 @@ case "$1" in
"getsignup") login; getsignup $2; logout;;
"getsubdevs") login; getsubdevs $2; logout;;
"listvenues") login; listvenues $2; logout;;
"getvenuedevices") login; getvenuedevices $2; logout;;
*) help ;;
esac