diff --git a/CMakeLists.txt b/CMakeLists.txt index 199b5bd..e9e55c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.13) -project(owprov VERSION 2.6.0) +project(owprov VERSION 2.7.0) set(CMAKE_CXX_STANDARD 17) diff --git a/build b/build index aa59885..56a6051 100644 --- a/build +++ b/build @@ -1 +1 @@ -143 \ No newline at end of file +1 \ No newline at end of file diff --git a/openapi/rrm_provider.yaml b/openapi/rrm_provider.yaml new file mode 100644 index 0000000..3dcd440 --- /dev/null +++ b/openapi/rrm_provider.yaml @@ -0,0 +1,174 @@ +openapi: 3.0.1 +info: + title: OpenWiFi RRM Provider Model + description: Definitions and APIs to manages an OpenWiFi RRM Providers. + version: 1.0.0 + license: + name: BSD3 + url: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE + +servers: + - url: 'https://localhost:16022/api/v1' + +security: + - bearerAuth: [] + - ApiKeyAuth: [] + +components: + securitySchemes: + ApiKeyAuth: + type: apiKey + in: header + name: X-API-KEY + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT + + responses: + NotFound: + $ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/NotFound' + Unauthorized: + $ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Unauthorized' + Success: + $ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Success' + BadRequest: + $ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/BadRequest' + + schemas: + + Provider: + type: object + properties: + vendor: + description: The name of the vendor for display. + type: string + minLength: 1 + maxLength: 128 + vendorShortname: + description: A shortname for the vendor. Only letters and numbers are allowed. This is the name used internally. + type: string + minLength: 4 + maxLength: 16 + version: + description: An identifier that will help users identify the version of the RRM module they are using. + type: string + about: + description: A link to the Vendor page for this RRM Module + type: string + + + Algorithm: + type: object + properties: + name: + description: A display for this algorithm. + type: string + minLength: 1 + maxLength: 128 + description: + description: A description of the algorithm. + type: string + shortName: + description: This is the name used internally. + type: string + minLength: 4 + maxLength: 16 + parameterFormat: + description: this is a Regex used to validate the input. If this is empty, no validation will be performed. + type: string + parameterSamples: + description: These samples will be displayed in the UI to the user trying to configure the options + type: array + items: + type: string + helper: + description: A link to a web page or PDF document explaining the algorithm and its parameters + type: string + + Algorithms: + description: The list of all algorithms supported by the vendor + type: array + items: + $ref: '#/components/schemas/Algorithm' + +paths: + /provider: + get: + tags: + - RRM + operationId: getProvider + summary: Retrieve information about the provider for this RRM Module + responses: + 200: + $ref: '#/components/schemas/Provider' + 400: + $ref: '#/components/responses/BadRequest' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /algorithms: + get: + tags: + - RRM + operationId: getAlgorithms + summary: Retrieve a lists of algorithms supported in the module. + responses: + 200: + $ref: '#/components/schemas/Algorithms' + 400: + $ref: '#/components/responses/BadRequest' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + + /runRRM: + put: + tags: + - RRM + operationId: runRRMNow + summary: Run a specific or default RRM algorithm. The UI user or CLI user will have the ability to run an algorithm on demand. + parameters: + - in: query + description: + name: venue + schema: + type: string + format: uuid + required: true + - in: query + description: Perform RRM without updating anything. This may be used by an admin to see what RRM would do. + name: mock + schema: + type: boolean + default: false + required: false + - in: query + description: Specify the RRM algorithm to use. If omitted, select the default algorithm. + schema: + type: string + required: false + - in: query + description: Specify the parameters to use with the RRM algorithm to use. If omitted, select the default parameters. + schema: + type: string + required: false + responses: + 200: + description: Return the list of actions that were or would be performed. + content: + application/json: + schema: + type: array + items: + type: string + 400: + $ref: '#/components/responses/BadRequest' + 403: + $ref: '#/components/responses/Unauthorized' + 404: + $ref: '#/components/responses/NotFound' + diff --git a/src/framework/MicroService.h b/src/framework/MicroService.h index 5e2f977..9a0277e 100644 --- a/src/framework/MicroService.h +++ b/src/framework/MicroService.h @@ -1399,13 +1399,14 @@ namespace OpenWifi { [[nodiscard]] inline const std::string &Address() const { return address_; }; [[nodiscard]] inline uint32_t Port() const { return port_; }; - [[nodiscard]] inline const std::string &KeyFile() const { return key_file_; }; - [[nodiscard]] inline const std::string &CertFile() const { return cert_file_; }; - [[nodiscard]] inline const std::string &RootCA() const { return root_ca_; }; - [[nodiscard]] inline const std::string &KeyFilePassword() const { return key_file_password_; }; - [[nodiscard]] inline const std::string &IssuerCertFile() const { return issuer_cert_file_; }; - [[nodiscard]] inline const std::string &Name() const { return name_; }; + [[nodiscard]] inline auto KeyFile() const { return key_file_; }; + [[nodiscard]] inline auto CertFile() const { return cert_file_; }; + [[nodiscard]] inline auto RootCA() const { return root_ca_; }; + [[nodiscard]] inline auto KeyFilePassword() const { return key_file_password_; }; + [[nodiscard]] inline auto IssuerCertFile() const { return issuer_cert_file_; }; + [[nodiscard]] inline auto Name() const { return name_; }; [[nodiscard]] inline int Backlog() const { return backlog_; } + [[nodiscard]] inline auto Cas() const { return cas_; } [[nodiscard]] inline Poco::Net::SecureServerSocket CreateSecureSocket(Poco::Logger &L) const { Poco::Net::Context::Params P; @@ -1885,8 +1886,8 @@ namespace OpenWifi { Request = &RequestIn; Response = &ResponseIn; - std::string th_name = "restsvr_" + std::to_string(TransactionId_); - Utils::SetThreadName(th_name.c_str()); +// 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) { @@ -2712,7 +2713,7 @@ namespace OpenWifi { inline void run() override { Poco::AutoPtr Note(Queue_.waitDequeueNotification()); - Utils::SetThreadName("kafka-dispatch"); + Utils::SetThreadName("kafka:dispatch"); while(Note && Running_) { auto Msg = dynamic_cast(Note.get()); if(Msg!= nullptr) { @@ -3034,18 +3035,17 @@ namespace OpenWifi { inline Poco::Net::HTTPRequestHandler *CallServer(const std::string &Path, uint64_t Id) { RESTAPIHandler::BindingMap Bindings; - Utils::SetThreadName(fmt::format("rest_ext_{}",Id).c_str()); + Utils::SetThreadName(fmt::format("x-rest:{}",Id).c_str()); return RESTAPI_ExtRouter(Path, Bindings, Logger(), Server_, Id); } private: std::vector> RESTServers_; - Poco::ThreadPool Pool_; + Poco::ThreadPool Pool_{"x-rest",2,32}; RESTAPI_GenericServer Server_; RESTAPI_ExtServer() noexcept: - SubSystemServer("RESTAPI_ExtServer", "RESTAPIServer", "openwifi.restapi"), - Pool_("RESTAPI_ExtServer",4,50,120) + SubSystemServer("RESTAPI_ExtServer", "RESTAPIServer", "openwifi.restapi") { } }; @@ -3058,7 +3058,7 @@ namespace OpenWifi { inline Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override { try { Poco::URI uri(Request.getURI()); - Utils::SetThreadName(fmt::format("rest_ext_{}",TransactionId_).c_str()); + Utils::SetThreadName(fmt::format("x-rest:{}",TransactionId_).c_str()); return RESTAPI_ExtServer()->CallServer(uri.getPath(), TransactionId_++); } catch (...) { @@ -3167,17 +3167,16 @@ namespace OpenWifi { inline Poco::Net::HTTPRequestHandler *CallServer(const std::string &Path, uint64_t Id) { RESTAPIHandler::BindingMap Bindings; - Utils::SetThreadName(fmt::format("rest_int_{}",Id).c_str()); + Utils::SetThreadName(fmt::format("i-rest:{}",Id).c_str()); return RESTAPI_IntRouter(Path, Bindings, Logger(), Server_, Id); } private: std::vector> RESTServers_; - Poco::ThreadPool Pool_; + Poco::ThreadPool Pool_{"i-rest",2,16}; RESTAPI_GenericServer Server_; RESTAPI_IntServer() noexcept: - SubSystemServer("RESTAPI_IntServer", "REST-ISRV", "openwifi.internal.restapi"), - Pool_("RESTAPI_IntServer",4,50,120) + SubSystemServer("RESTAPI_IntServer", "REST-ISRV", "openwifi.internal.restapi") { } }; @@ -3188,6 +3187,7 @@ namespace OpenWifi { public: inline IntRequestHandlerFactory() = default; inline Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override { + Utils::SetThreadName(fmt::format("i-rest:{}",TransactionId_).c_str()); Poco::URI uri(Request.getURI()); return RESTAPI_IntServer()->CallServer(uri.getPath(), TransactionId_); } @@ -3231,7 +3231,6 @@ namespace OpenWifi { } [[nodiscard]] std::string Version() { return Version_; } - // [[nodiscard]] const Poco::SharedPtr & Key() { return AppKey_; } [[nodiscard]] inline const std::string & DataDir() { return DataDir_; } [[nodiscard]] inline const std::string & WWWAssetsDir() { return WWWAssetsDir_; } [[nodiscard]] bool Debug() const { return DebugMode_; } @@ -3264,7 +3263,12 @@ namespace OpenWifi { return Poco::Logger::get(Name); } - static inline void Exit(int Reason); + virtual void GetExtraConfiguration(Poco::JSON::Object & Cfg) { + Cfg.set("additionalConfiguration",false); + } + + + static inline void Exit(int Reason); inline void BusMessageReceived(const std::string &Key, const std::string & Payload); inline MicroServiceMetaVec GetServices(const std::string & Type); inline MicroServiceMetaVec GetServices(); @@ -3330,6 +3334,9 @@ namespace OpenWifi { return Signer_.sign(T,Algo); } } + + inline Poco::ThreadPool & TimerPool() { return TimerPool_; } + private: static MicroService * instance_; bool HelpRequested_ = false; @@ -3364,6 +3371,7 @@ namespace OpenWifi { bool NoBuiltInCrypto_=false; Poco::JWT::Signer Signer_; Poco::Logger &Logger_; + Poco::ThreadPool TimerPool_{"timer:pool",2,16}; }; inline void MicroService::Exit(int Reason) { @@ -3576,8 +3584,6 @@ namespace OpenWifi { void DaemonPostInitialization(Poco::Util::Application &self); inline void MicroService::initialize(Poco::Util::Application &self) { - // Utils::SetThreadName("microservice"); - // add the default services LoadConfigurationFile(); InitializeLoggingSystem(); @@ -3919,6 +3925,7 @@ namespace OpenWifi { Params->setMaxThreads(50); Params->setMaxQueued(200); Params->setKeepAlive(true); + Params->setName("ws:xrest"); std::unique_ptr NewServer; if(MicroService::instance().NoAPISecurity()) { @@ -3955,6 +3962,7 @@ namespace OpenWifi { Params->setMaxThreads(50); Params->setMaxQueued(200); Params->setKeepAlive(true); + Params->setName("ws:irest"); std::unique_ptr NewServer; if(MicroService::instance().NoAPISecurity()) { @@ -3972,8 +3980,6 @@ namespace OpenWifi { } inline int MicroService::main([[maybe_unused]] const ArgVec &args) { - - // Utils::SetThreadName("main"); MyErrorHandler ErrorHandler(*this); Poco::ErrorHandler::set(&ErrorHandler); @@ -4080,6 +4086,7 @@ namespace OpenWifi { Port_ = (int)MicroService::instance().ConfigGetInt("alb.port",15015); Socket_ = std::make_unique(Port_); auto Params = new Poco::Net::HTTPServerParams; + Params->setName("ws:alb"); Server_ = std::make_unique(new ALBRequestHandlerFactory(Logger()), *Socket_, Params); Server_->start(); } @@ -4089,7 +4096,7 @@ namespace OpenWifi { inline void BusEventManager::run() { Running_ = true; - Utils::SetThreadName("BusEventManager"); + Utils::SetThreadName("fmwk:EventMgr"); auto Msg = MicroService::instance().MakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_JOIN); KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,MicroService::instance().PrivateEndPoint(),Msg, false); while(Running_) { @@ -4176,7 +4183,7 @@ namespace OpenWifi { inline void KafkaProducer::run() { - Utils::SetThreadName("KafkaProducer"); + Utils::SetThreadName("Kafka:Prod"); cppkafka::Configuration Config({ { "client.id", MicroService::instance().ConfigGetString("openwifi.kafka.client.id") }, { "metadata.broker.list", MicroService::instance().ConfigGetString("openwifi.kafka.brokerlist") } @@ -4215,7 +4222,7 @@ namespace OpenWifi { } inline void KafkaConsumer::run() { - Utils::SetThreadName("KafkaConsumer"); + Utils::SetThreadName("Kafka:Cons"); cppkafka::Configuration Config({ { "client.id", MicroService::instance().ConfigGetString("openwifi.kafka.client.id") }, @@ -4355,6 +4362,11 @@ namespace OpenWifi { Answer.set("certificates", Certificates); return ReturnObject(Answer); } + if(GetBoolParameter("extraConfiguration")) { + Poco::JSON::Object Answer; + MicroService::instance().GetExtraConfiguration(Answer); + return ReturnObject(Answer); + } BadRequest(RESTAPI::Errors::InvalidCommand); } @@ -4876,7 +4888,7 @@ namespace OpenWifi { void SendToAll(const std::string &Payload); private: mutable std::atomic_bool Running_ = false; - Poco::Thread Thr_; + Poco::Thread Thr_; // std::unique_ptr ReactorPool_; Poco::Net::SocketReactor Reactor_; Poco::Thread ReactorThread_; @@ -4966,13 +4978,13 @@ namespace OpenWifi { [[nodiscard]] inline bool SendToUser(const std::string &userName, const std::string &Payload); inline WebSocketClientServer::WebSocketClientServer() noexcept: - SubSystemServer("WebSocketClientServer", "WSCLNT-SVR", "websocketclients") + SubSystemServer("WebSocketClientServer", "UI-WSCLNT-SVR", "websocketclients") { } inline void WebSocketClientServer::run() { Running_ = true ; - Utils::SetThreadName("ws:clnt-svr"); + Utils::SetThreadName("ws:uiclnt-svr"); while(Running_) { Poco::Thread::trySleep(2000); @@ -5065,7 +5077,7 @@ namespace OpenWifi { 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_)); + Logger().warning(Poco::format("CLOSE(%s): UI Client is closing its connection.", Id_)); Done = true; } break; case Poco::Net::WebSocket::FRAME_OP_TEXT: { @@ -5204,7 +5216,7 @@ namespace OpenWifi { try { Poco::Net::WebSocket WS(*Request, *Response); - Logger().information("WebSocket connection established."); + Logger().information("UI-WebSocket connection established."); auto Id = MicroService::CreateUUID(); WebSocketClientServer()->NewClient(WS,Id); }