mirror of
https://github.com/Telecominfraproject/wlan-cloud-owprov.git
synced 2025-10-30 02:02:36 +00:00
Merge pull request #39 from Telecominfraproject/main
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -30,8 +30,29 @@ namespace OpenWifi {
|
|||||||
Utils::SetThreadName("job-controller");
|
Utils::SetThreadName("job-controller");
|
||||||
while(Running_) {
|
while(Running_) {
|
||||||
Poco::Thread::trySleep(2000);
|
Poco::Thread::trySleep(2000);
|
||||||
|
|
||||||
|
std::lock_guard G(Mutex_);
|
||||||
|
|
||||||
|
for(auto &job:jobs_) {
|
||||||
|
if(job!=nullptr) {
|
||||||
|
if(job->Started()==0 && Pool_.used()<Pool_.available()) {
|
||||||
|
job->Logger().information(fmt::format("Starting {}: {}",job->JobId(),job->Name()));
|
||||||
|
job->Start();
|
||||||
|
Pool_.start(*job);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(auto it = jobs_.begin(); it!=jobs_.end();) {
|
||||||
|
if(*it!=nullptr && (*it)->Completed()!=0) {
|
||||||
|
auto tmp = it;
|
||||||
|
(*it)->Logger().information(fmt::format("Completed {}: {}",(*it)->JobId(),(*it)->Name()));
|
||||||
|
it = jobs_.erase(it);
|
||||||
|
delete *tmp;
|
||||||
|
} 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")
|
||||||
|
|||||||
@@ -228,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);
|
||||||
@@ -242,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);
|
||||||
@@ -256,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);
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|
||||||
@@ -82,45 +83,21 @@ 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:
|
|
||||||
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 {
|
|
||||||
|
|
||||||
Utils::SetThreadName("venue-update");
|
Utils::SetThreadName("venue-update");
|
||||||
|
VenueUUID_ = Parameter(0);
|
||||||
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)) {
|
||||||
@@ -131,7 +108,7 @@ namespace OpenWifi {
|
|||||||
};
|
};
|
||||||
|
|
||||||
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();
|
||||||
|
|
||||||
std::array<tState,MaxThreads> Tasks;
|
std::array<tState,MaxThreads> Tasks;
|
||||||
|
|
||||||
@@ -200,19 +177,18 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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);
|
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));
|
||||||
Utils::SetThreadName("free");
|
Utils::SetThreadName("free");
|
||||||
|
Complete();
|
||||||
delete this;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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,44 +49,19 @@ 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:
|
|
||||||
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 {
|
|
||||||
|
|
||||||
Utils::SetThreadName("venue-reboot");
|
Utils::SetThreadName("venue-reboot");
|
||||||
|
|
||||||
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;
|
||||||
@@ -97,7 +73,7 @@ namespace OpenWifi {
|
|||||||
};
|
};
|
||||||
|
|
||||||
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;
|
std::array<tState,MaxThreads> Tasks;
|
||||||
|
|
||||||
@@ -162,20 +138,18 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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);
|
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_));
|
||||||
|
|
||||||
Utils::SetThreadName("free");
|
Utils::SetThreadName("free");
|
||||||
|
Complete();
|
||||||
delete this;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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 {
|
||||||
@@ -69,45 +70,20 @@ 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:
|
|
||||||
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 {
|
|
||||||
|
|
||||||
Utils::SetThreadName("venue-upgr");
|
Utils::SetThreadName("venue-upgr");
|
||||||
|
auto VenueUUID_ = Parameter(0);
|
||||||
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)) {
|
||||||
@@ -118,7 +94,7 @@ namespace OpenWifi {
|
|||||||
};
|
};
|
||||||
|
|
||||||
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;
|
std::array<tState,MaxThreads> Tasks;
|
||||||
ProvObjects::DeviceRules Rules;
|
ProvObjects::DeviceRules Rules;
|
||||||
@@ -186,19 +162,19 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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);
|
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_));
|
||||||
Utils::SetThreadName("free");
|
Utils::SetThreadName("free");
|
||||||
|
|
||||||
delete this;
|
Complete();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -27,11 +27,6 @@ namespace OpenWifi {
|
|||||||
inline uint64_t Now() { return std::time(nullptr); };
|
inline uint64_t Now() { return std::time(nullptr); };
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace OpenWifi::Utils {
|
|
||||||
std::vector<unsigned char> base64decode(const std::string& input);
|
|
||||||
std::string base64encode(const unsigned char *input, uint32_t size);
|
|
||||||
}
|
|
||||||
|
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
#include "Poco/Util/Application.h"
|
#include "Poco/Util/Application.h"
|
||||||
@@ -243,11 +238,6 @@ namespace OpenWifi::RESTAPI_utils {
|
|||||||
Obj.set(Field,Value);
|
Obj.set(Field,Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Poco::Data::BLOB &Value) {
|
|
||||||
auto Result = Utils::base64encode((const unsigned char *)Value.rawContent(),Value.size());
|
|
||||||
Obj.set(Field,Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::StringPairVec & S) {
|
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::StringPairVec & S) {
|
||||||
Poco::JSON::Array Array;
|
Poco::JSON::Array Array;
|
||||||
for(const auto &i:S) {
|
for(const auto &i:S) {
|
||||||
@@ -344,12 +334,12 @@ namespace OpenWifi::RESTAPI_utils {
|
|||||||
|
|
||||||
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, double & Value) {
|
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, double & Value) {
|
||||||
if(Obj->has(Field) && !Obj->isNull(Field))
|
if(Obj->has(Field) && !Obj->isNull(Field))
|
||||||
Value = (double)Obj->get(Field);
|
Value = (double) Obj->get(Field);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, float & Value) {
|
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, float & Value) {
|
||||||
if(Obj->has(Field) && !Obj->isNull(Field))
|
if(Obj->has(Field) && !Obj->isNull(Field))
|
||||||
Value = (float)Obj->get(Field);
|
Value = (float) Obj->get(Field);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, bool &Value) {
|
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, bool &Value) {
|
||||||
@@ -384,14 +374,7 @@ namespace OpenWifi::RESTAPI_utils {
|
|||||||
|
|
||||||
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, uint64_t &Value) {
|
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, uint64_t &Value) {
|
||||||
if(Obj->has(Field) && !Obj->isNull(Field))
|
if(Obj->has(Field) && !Obj->isNull(Field))
|
||||||
Value = (uint64_t)Obj->get(Field);
|
Value = (uint64_t ) Obj->get(Field);
|
||||||
}
|
|
||||||
|
|
||||||
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, Poco::Data::BLOB &Value) {
|
|
||||||
if(Obj->has(Field) && !Obj->isNull(Field)) {
|
|
||||||
auto Result = Utils::base64decode(Obj->get(Field).toString());
|
|
||||||
Value.assignRaw((const unsigned char *)&Result[0],Result.size());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, Types::StringPairVec &Vec) {
|
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, Types::StringPairVec &Vec) {
|
||||||
@@ -2081,17 +2064,6 @@ namespace OpenWifi {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, Poco::Data::BLOB &Value) {
|
|
||||||
if(O->has(Field)) {
|
|
||||||
std::string Content = O->get(Field).toString();
|
|
||||||
auto DecodedBlob = Utils::base64decode(Content);
|
|
||||||
Value.assignRaw((const unsigned char *)&DecodedBlob[0],DecodedBlob.size());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T> bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, const T &value, T & assignee) {
|
template <typename T> bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, const T &value, T & assignee) {
|
||||||
if(O->has(Field)) {
|
if(O->has(Field)) {
|
||||||
assignee = value;
|
assignee = value;
|
||||||
@@ -5020,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;
|
||||||
@@ -5043,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;
|
||||||
|
|||||||
@@ -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:
|
|
||||||
};
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user