mirror of
https://github.com/Telecominfraproject/wlan-cloud-owprov.git
synced 2025-11-01 19:17:47 +00:00
Added ability to reboot a venue.
This commit is contained in:
@@ -134,7 +134,7 @@ add_executable(owprov
|
|||||||
src/storage/storage_variables.cpp src/storage/storage_variables.h
|
src/storage/storage_variables.cpp src/storage/storage_variables.h
|
||||||
src/RESTAPI/RESTAPI_variables_handler.cpp src/RESTAPI/RESTAPI_variables_handler.h
|
src/RESTAPI/RESTAPI_variables_handler.cpp src/RESTAPI/RESTAPI_variables_handler.h
|
||||||
src/RESTAPI/RESTAPI_variables_list_handler.cpp src/RESTAPI/RESTAPI_variables_list_handler.h
|
src/RESTAPI/RESTAPI_variables_list_handler.cpp src/RESTAPI/RESTAPI_variables_list_handler.h
|
||||||
src/FileDownloader.cpp src/FileDownloader.h src/Tasks/VenueConfigUpdater.cpp src/Tasks/VenueConfigUpdater.h src/Kafka_ProvUpdater.cpp src/Kafka_ProvUpdater.h src/storage/storage_operataor.cpp src/storage/storage_operataor.h src/storage/storage_sub_devices.cpp src/storage/storage_sub_devices.h src/storage/storage_service_class.cpp src/storage/storage_service_class.h src/RESTAPI/RESTAPI_sub_devices_list_handler.cpp src/RESTAPI/RESTAPI_sub_devices_list_handler.h src/RESTAPI/RESTAPI_sub_devices_handler.cpp src/RESTAPI/RESTAPI_sub_devices_handler.h src/RESTAPI/RESTAPI_service_class_list_handler.cpp src/RESTAPI/RESTAPI_service_class_list_handler.h src/RESTAPI/RESTAPI_service_class_handler.cpp src/RESTAPI/RESTAPI_service_class_handler.h src/RESTAPI/RESTAPI_operators_list_handler.cpp src/RESTAPI/RESTAPI_operators_list_handler.h src/RESTAPI/RESTAPI_operators_handler.cpp src/RESTAPI/RESTAPI_operators_handler.h src/storage/storage_op_contacts.cpp src/storage/storage_op_contacts.h src/storage/storage_op_locations.cpp src/storage/storage_op_locations.h src/RESTAPI/RESTAPI_op_contact_list_handler.cpp src/RESTAPI/RESTAPI_op_contact_list_handler.h src/RESTAPI/RESTAPI_op_contact_handler.cpp src/RESTAPI/RESTAPI_op_contact_handler.h src/RESTAPI/RESTAPI_op_location_list_handler.cpp src/RESTAPI/RESTAPI_op_location_list_handler.h src/RESTAPI/RESTAPI_op_location_handler.cpp src/RESTAPI/RESTAPI_op_location_handler.h src/ProvWebSocketClient.cpp src/ProvWebSocketClient.h)
|
src/FileDownloader.cpp src/FileDownloader.h src/Tasks/VenueConfigUpdater.h src/Kafka_ProvUpdater.cpp src/Kafka_ProvUpdater.h src/storage/storage_operataor.cpp src/storage/storage_operataor.h src/storage/storage_sub_devices.cpp src/storage/storage_sub_devices.h src/storage/storage_service_class.cpp src/storage/storage_service_class.h src/RESTAPI/RESTAPI_sub_devices_list_handler.cpp src/RESTAPI/RESTAPI_sub_devices_list_handler.h src/RESTAPI/RESTAPI_sub_devices_handler.cpp src/RESTAPI/RESTAPI_sub_devices_handler.h src/RESTAPI/RESTAPI_service_class_list_handler.cpp src/RESTAPI/RESTAPI_service_class_list_handler.h src/RESTAPI/RESTAPI_service_class_handler.cpp src/RESTAPI/RESTAPI_service_class_handler.h src/RESTAPI/RESTAPI_operators_list_handler.cpp src/RESTAPI/RESTAPI_operators_list_handler.h src/RESTAPI/RESTAPI_operators_handler.cpp src/RESTAPI/RESTAPI_operators_handler.h src/storage/storage_op_contacts.cpp src/storage/storage_op_contacts.h src/storage/storage_op_locations.cpp src/storage/storage_op_locations.h src/RESTAPI/RESTAPI_op_contact_list_handler.cpp src/RESTAPI/RESTAPI_op_contact_list_handler.h src/RESTAPI/RESTAPI_op_contact_handler.cpp src/RESTAPI/RESTAPI_op_contact_handler.h src/RESTAPI/RESTAPI_op_location_list_handler.cpp src/RESTAPI/RESTAPI_op_location_list_handler.h src/RESTAPI/RESTAPI_op_location_handler.cpp src/RESTAPI/RESTAPI_op_location_handler.h src/ProvWebSocketClient.cpp src/ProvWebSocketClient.h src/Tasks/VenueRebooter.h)
|
||||||
|
|
||||||
target_link_libraries(owprov PUBLIC
|
target_link_libraries(owprov PUBLIC
|
||||||
${Poco_LIBRARIES}
|
${Poco_LIBRARIES}
|
||||||
|
|||||||
@@ -2443,6 +2443,12 @@ paths:
|
|||||||
type: boolean
|
type: boolean
|
||||||
default: false
|
default: false
|
||||||
required: false
|
required: false
|
||||||
|
- in: query
|
||||||
|
name: rebootAllDevices
|
||||||
|
schema:
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
required: false
|
||||||
- in: query
|
- in: query
|
||||||
name: testUpdateOnly
|
name: testUpdateOnly
|
||||||
schema:
|
schema:
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include "StorageService.h"
|
#include "StorageService.h"
|
||||||
#include "RESTAPI/RESTAPI_db_helpers.h"
|
#include "RESTAPI/RESTAPI_db_helpers.h"
|
||||||
#include "Tasks/VenueConfigUpdater.h"
|
#include "Tasks/VenueConfigUpdater.h"
|
||||||
|
#include "Tasks/VenueRebooter.h"
|
||||||
|
|
||||||
#include "Kafka_ProvUpdater.h"
|
#include "Kafka_ProvUpdater.h"
|
||||||
|
|
||||||
@@ -231,6 +232,21 @@ namespace OpenWifi{
|
|||||||
return ReturnObject(Answer);
|
return ReturnObject(Answer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto rebootAllDevices = GetBoolParameter("rebootAllDevices");
|
||||||
|
if(rebootAllDevices) {
|
||||||
|
ProvObjects::SerialNumberList SNL;
|
||||||
|
|
||||||
|
Poco::JSON::Object Answer;
|
||||||
|
SNL.serialNumbers = Existing.devices;
|
||||||
|
|
||||||
|
auto Task = new VenueRebooter(UUID,UserInfo_.userinfo,0,Logger());
|
||||||
|
auto JobId = Task->Start();
|
||||||
|
|
||||||
|
SNL.to_json(Answer);
|
||||||
|
Answer.set("jobId",JobId);
|
||||||
|
return ReturnObject(Answer);
|
||||||
|
}
|
||||||
|
|
||||||
auto RawObject = ParseStream();
|
auto RawObject = ParseStream();
|
||||||
ProvObjects::Venue NewObject;
|
ProvObjects::Venue NewObject;
|
||||||
if (!NewObject.from_json(RawObject)) {
|
if (!NewObject.from_json(RawObject)) {
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by stephane bourque on 2022-04-01.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "VenueConfigUpdater.h"
|
|
||||||
@@ -243,7 +243,7 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto Sent = WebSocketClientServer()->SendUserNotification(UI_.email,N);
|
auto Sent = WebSocketClientServer()->SendUserNotification(UI_.email,N);
|
||||||
Logger().information(fmt::format("Job {} Completed: {} updated, {} failed to update , {} bad configurations. Notification was send={}",
|
Logger().information(fmt::format("Job {} Completed: {} updated, {} failed to update , {} bad configurations. Notification was sent={}",
|
||||||
JobId_, Updated ,Failed, BadConfigs, Sent));
|
JobId_, Updated ,Failed, BadConfigs, Sent));
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|||||||
212
src/Tasks/VenueRebooter.h
Normal file
212
src/Tasks/VenueRebooter.h
Normal file
@@ -0,0 +1,212 @@
|
|||||||
|
//
|
||||||
|
// Created by stephane bourque on 2022-05-04.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "framework/MicroService.h"
|
||||||
|
#include "StorageService.h"
|
||||||
|
#include "APConfig.h"
|
||||||
|
#include "sdks/SDK_gw.h"
|
||||||
|
|
||||||
|
namespace OpenWifi {
|
||||||
|
|
||||||
|
struct WebSocketNotificationRebootList {
|
||||||
|
std::string title,
|
||||||
|
details,
|
||||||
|
jobId;
|
||||||
|
std::vector<std::string> success,
|
||||||
|
warning;
|
||||||
|
uint64_t timeStamp=OpenWifi::Now();
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
inline void WebSocketNotificationRebootList::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
RESTAPI_utils::field_to_json(Obj,"title",title);
|
||||||
|
RESTAPI_utils::field_to_json(Obj,"jobId",jobId);
|
||||||
|
RESTAPI_utils::field_to_json(Obj,"success",success);
|
||||||
|
RESTAPI_utils::field_to_json(Obj,"warning",warning);
|
||||||
|
RESTAPI_utils::field_to_json(Obj,"timeStamp",timeStamp);
|
||||||
|
RESTAPI_utils::field_to_json(Obj,"details",details);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool WebSocketNotificationRebootList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
RESTAPI_utils::field_from_json(Obj,"title",title);
|
||||||
|
RESTAPI_utils::field_from_json(Obj,"jobId",jobId);
|
||||||
|
RESTAPI_utils::field_from_json(Obj,"success",success);
|
||||||
|
RESTAPI_utils::field_from_json(Obj,"warning",warning);
|
||||||
|
RESTAPI_utils::field_from_json(Obj,"timeStamp",timeStamp);
|
||||||
|
RESTAPI_utils::field_from_json(Obj,"details",details);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
class VenueDeviceRebooter : public Poco::Runnable {
|
||||||
|
public:
|
||||||
|
VenueDeviceRebooter(const std::string &UUID, const std::string &venue, Poco::Logger &L) :
|
||||||
|
uuid_(UUID),
|
||||||
|
venue_(venue),
|
||||||
|
Logger_(L) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void run() final {
|
||||||
|
ProvObjects::InventoryTag Device;
|
||||||
|
started_=true;
|
||||||
|
if(StorageService()->InventoryDB().GetRecord("id",uuid_,Device)) {
|
||||||
|
SerialNumber = Device.serialNumber;
|
||||||
|
if (SDK::GW::Device::Reboot(Device.serialNumber, 0)) {
|
||||||
|
Logger().debug(fmt::format("{}: Rebooted.",Device.serialNumber));
|
||||||
|
rebooted_++;
|
||||||
|
} else {
|
||||||
|
Logger().information(fmt::format("{}: Not rebooted.", Device.serialNumber));
|
||||||
|
failed_++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
done_ = true;
|
||||||
|
// std::cout << "Done push for " << Device.serialNumber << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t rebooted_=0, failed_=0;
|
||||||
|
bool started_ = false,
|
||||||
|
done_ = false;
|
||||||
|
std::string SerialNumber;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string uuid_;
|
||||||
|
std::string venue_;
|
||||||
|
Poco::Logger &Logger_;
|
||||||
|
inline Poco::Logger & Logger() { return Logger_; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class VenueRebooter: public Poco::Runnable {
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string Start() {
|
||||||
|
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 {
|
||||||
|
|
||||||
|
if(When_ && When_>OpenWifi::Now())
|
||||||
|
Poco::Thread::trySleep( (long) (When_ - OpenWifi::Now()) * 1000 );
|
||||||
|
|
||||||
|
WebSocketNotification<WebSocketNotificationRebootList> N;
|
||||||
|
N.type = "venue_rebooter";
|
||||||
|
|
||||||
|
Logger().information(fmt::format("Job {} Starting.", JobId_));
|
||||||
|
|
||||||
|
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_;
|
||||||
|
|
||||||
|
std::array<tState,MaxThreads> Tasks;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
N.content.details = fmt::format("Job {} Completed: {} rebooted, {} failed to reboot.",
|
||||||
|
JobId_, rebooted_ ,failed_);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
N.content.details = fmt::format("Venue {} no longer exists.",VenueUUID_);
|
||||||
|
Logger().warning(N.content.details);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Sent = WebSocketClientServer()->SendUserNotification(UI_.email,N);
|
||||||
|
Logger().information(fmt::format("Job {} Completed: {} rebooted, {} failed to reboot. Notification was sent={}",
|
||||||
|
JobId_, rebooted_ ,failed_, Sent));
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -17,6 +17,19 @@ namespace OpenWifi::SDK::GW {
|
|||||||
PerformCommand(client,"reboot",EndPoint, ObjRequest);
|
PerformCommand(client,"reboot",EndPoint, ObjRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Reboot(const std::string & Mac, [[maybe_unused]] uint64_t When) {
|
||||||
|
std::string EndPoint = "/api/v1/device/" + Mac + "/reboot";
|
||||||
|
Poco::JSON::Object ObjRequest;
|
||||||
|
|
||||||
|
ObjRequest.set("serialNumber", Mac);
|
||||||
|
ObjRequest.set("when", When );
|
||||||
|
|
||||||
|
OpenAPIRequestPost RebootCommand( uSERVICE_GATEWAY, EndPoint, {}, ObjRequest, 30000);
|
||||||
|
|
||||||
|
Poco::JSON::Object::Ptr Response;
|
||||||
|
return RebootCommand.Do(Response) == Poco::Net::HTTPResponse::HTTP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
void LEDs(RESTAPIHandler *client, const std::string & Mac, uint64_t When, uint64_t Duration, const std::string & Pattern) {
|
void LEDs(RESTAPIHandler *client, const std::string & Mac, uint64_t When, uint64_t Duration, const std::string & Pattern) {
|
||||||
std::string EndPoint = "/api/v1/device/" + Mac + "/leds";
|
std::string EndPoint = "/api/v1/device/" + Mac + "/leds";
|
||||||
Poco::JSON::Object ObjRequest;
|
Poco::JSON::Object ObjRequest;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
namespace OpenWifi::SDK::GW {
|
namespace OpenWifi::SDK::GW {
|
||||||
namespace Device {
|
namespace Device {
|
||||||
void Reboot(RESTAPIHandler *client, const std::string & Mac, uint64_t When);
|
void Reboot(RESTAPIHandler *client, const std::string & Mac, uint64_t When);
|
||||||
|
bool Reboot(const std::string & Mac, [[maybe_unused]] uint64_t When);
|
||||||
void LEDs(RESTAPIHandler *client, const std::string & Mac, uint64_t When, uint64_t Duration, const std::string & Pattern);
|
void LEDs(RESTAPIHandler *client, const std::string & Mac, uint64_t When, uint64_t Duration, const std::string & Pattern);
|
||||||
void Factory(RESTAPIHandler *client, const std::string & Mac, uint64_t When, bool KeepRedirector);
|
void Factory(RESTAPIHandler *client, const std::string & Mac, uint64_t When, bool KeepRedirector);
|
||||||
void Upgrade(RESTAPIHandler *client, const std::string & Mac, uint64_t When, const std::string & ImageName, bool KeepRedirector);
|
void Upgrade(RESTAPIHandler *client, const std::string & Mac, uint64_t When, const std::string & ImageName, bool KeepRedirector);
|
||||||
|
|||||||
Reference in New Issue
Block a user