mirror of
https://github.com/Telecominfraproject/wlan-cloud-owprov.git
synced 2025-10-29 17:52:28 +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/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/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
|
||||
${Poco_LIBRARIES}
|
||||
|
||||
@@ -2443,6 +2443,12 @@ paths:
|
||||
type: boolean
|
||||
default: false
|
||||
required: false
|
||||
- in: query
|
||||
name: rebootAllDevices
|
||||
schema:
|
||||
type: boolean
|
||||
default: false
|
||||
required: false
|
||||
- in: query
|
||||
name: testUpdateOnly
|
||||
schema:
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "StorageService.h"
|
||||
#include "RESTAPI/RESTAPI_db_helpers.h"
|
||||
#include "Tasks/VenueConfigUpdater.h"
|
||||
#include "Tasks/VenueRebooter.h"
|
||||
|
||||
#include "Kafka_ProvUpdater.h"
|
||||
|
||||
@@ -231,6 +232,21 @@ namespace OpenWifi{
|
||||
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();
|
||||
ProvObjects::Venue NewObject;
|
||||
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);
|
||||
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));
|
||||
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);
|
||||
}
|
||||
|
||||
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) {
|
||||
std::string EndPoint = "/api/v1/device/" + Mac + "/leds";
|
||||
Poco::JSON::Object ObjRequest;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
namespace OpenWifi::SDK::GW {
|
||||
namespace Device {
|
||||
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 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);
|
||||
|
||||
Reference in New Issue
Block a user