Compare commits

...

8 Commits

Author SHA1 Message Date
TIP Automation User
f925ce12be Chg: update image tag in helm values to v2.10.0-RC1 2023-06-09 13:34:31 +00:00
stephb9959
7b3de5d5ef https://telecominfraproject.atlassian.net/browse/WIFI-12525
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-05-18 09:01:31 -07:00
stephb9959
6007c1f06f https://telecominfraproject.atlassian.net/browse/WIFI-12597
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-05-11 07:32:22 -07:00
stephb9959
74916abdbd https://telecominfraproject.atlassian.net/browse/WIFI-12525
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-05-03 07:50:37 -07:00
stephb9959
0899c6f2d9 https://telecominfraproject.atlassian.net/browse/WIFI-12525
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-04-19 14:09:37 -07:00
stephb9959
f51b2bd11e https://telecominfraproject.atlassian.net/browse/WIFI-12525
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-04-19 14:03:43 -07:00
stephb9959
8b21ef16a1 https://telecominfraproject.atlassian.net/browse/WIFI-12525
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-04-19 14:03:31 -07:00
stephb9959
7ad4de4960 https://telecominfraproject.atlassian.net/browse/WIFI-12361
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-03-08 09:32:14 -08:00
57 changed files with 5763 additions and 5116 deletions

View File

@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.13)
project(owprov VERSION 2.9.0)
project(owprov VERSION 2.10.0)
set(CMAKE_CXX_STANDARD 17)
@@ -117,6 +117,7 @@ add_executable(owprov
src/framework/MicroServiceExtra.h
src/framework/ConfigurationValidator.cpp
src/framework/ConfigurationValidator.h
src/framework/default_device_types.h
src/UI_Prov_WebSocketNotifications.h
src/UI_Prov_WebSocketNotifications.cpp
src/RESTObjects/RESTAPI_SecurityObjects.h src/RESTObjects/RESTAPI_SecurityObjects.cpp

2
build
View File

@@ -1 +1 @@
21
28

View File

@@ -42,6 +42,7 @@ if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then
STORAGE_TYPE_MYSQL_PASSWORD=${STORAGE_TYPE_MYSQL_PASSWORD:-"owprov"} \
STORAGE_TYPE_MYSQL_DATABASE=${STORAGE_TYPE_MYSQL_DATABASE:-"owprov"} \
STORAGE_TYPE_MYSQL_PORT=${STORAGE_TYPE_MYSQL_PORT:-"3306"} \
RRM_PROVIDERS=${RRM_PROVIDERS:-"owrrm"} \
envsubst < /owprov.properties.tmpl > $OWPROV_CONFIG/owprov.properties
fi

View File

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

View File

@@ -37,10 +37,12 @@ openwifi.system.data = ${SYSTEM_DATA}
openwifi.system.debug = false
openwifi.system.uri.private = ${SYSTEM_URI_PRIVATE}
openwifi.system.uri.public = ${SYSTEM_URI_PUBLIC}
openwifi.system.commandchannel = /tmp/app.ucentralfms
openwifi.system.commandchannel = /tmp/app.owprov
openwifi.system.uri.ui = ${SYSTEM_URI_UI}
openwifi.security.restapi.disable = ${SECURITY_RESTAPI_DISABLE}
rrm.providers = ${RRM_PROVIDERS}
#############################
# Generic information for all micro services
#############################

View File

@@ -41,7 +41,7 @@ namespace OpenWifi {
Payload.set("ObjectType", OT);
std::ostringstream OS;
Payload.stringify(OS);
KafkaManager()->PostMessage(KafkaTopics::PROVISIONING_CHANGE, Ops[op], OS.str());
KafkaManager()->PostMessage(KafkaTopics::PROVISIONING_CHANGE, Ops[op], std::make_shared<std::string>(OS.str()));
return true;
}

View File

@@ -13,6 +13,7 @@
#ifdef TIP_GATEWAY_SERVICE
#include "AP_WS_Server.h"
#include "CapabilitiesCache.h"
#include "RADIUSSessionTracker.h"
#endif
#include "RESTAPI_GWobjects.h"
@@ -29,6 +30,7 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj, "serialNumber", SerialNumber);
#ifdef TIP_GATEWAY_SERVICE
field_to_json(Obj, "deviceType", CapabilitiesCache::instance()->GetPlatform(Compatible));
field_to_json(Obj, "hasRADIUSSessions", RADIUSSessionTracker()->HasSessions(SerialNumber));
#endif
field_to_json(Obj, "macAddress", MACAddress);
field_to_json(Obj, "manufacturer", Manufacturer);
@@ -54,6 +56,9 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj, "pendingConfiguration", pendingConfiguration);
field_to_json(Obj, "pendingConfigurationCmd", pendingConfigurationCmd);
field_to_json(Obj, "restrictionDetails", restrictionDetails);
field_to_json(Obj, "pendingUUID", pendingUUID);
field_to_json(Obj, "simulated", simulated);
field_to_json(Obj, "lastRecordedContact", lastRecordedContact);
}
void Device::to_json_with_status(Poco::JSON::Object &Obj) const {
@@ -63,7 +68,7 @@ namespace OpenWifi::GWObjects {
ConnectionState ConState;
if (AP_WS_Server()->GetState(SerialNumber, ConState)) {
ConState.to_json(Obj);
ConState.to_json(SerialNumber,Obj);
} else {
field_to_json(Obj, "ipAddress", "");
field_to_json(Obj, "txBytes", (uint64_t)0);
@@ -75,6 +80,13 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj, "associations_2G", (uint64_t)0);
field_to_json(Obj, "associations_5G", (uint64_t)0);
field_to_json(Obj, "associations_6G", (uint64_t)0);
field_to_json(Obj, "hasRADIUSSessions", false);
field_to_json(Obj, "hasGPS", ConState.hasGPS);
field_to_json(Obj, "sanity", ConState.sanity);
field_to_json(Obj, "memoryUsed", ConState.memoryUsed);
field_to_json(Obj, "sanity", ConState.sanity);
field_to_json(Obj, "load", ConState.load);
field_to_json(Obj, "temperature", ConState.temperature);
}
#endif
}
@@ -84,20 +96,32 @@ namespace OpenWifi::GWObjects {
field_from_json(Obj, "serialNumber", SerialNumber);
field_from_json(Obj, "deviceType", DeviceType);
field_from_json(Obj, "macAddress", MACAddress);
field_from_json(Obj, "manufacturer", Manufacturer);
field_from_json(Obj, "UUID", UUID);
field_from_json(Obj, "configuration", Configuration);
field_from_json(Obj, "notes", Notes);
field_from_json(Obj, "manufacturer", Manufacturer);
field_from_json(Obj, "createdTimestamp", CreationTimestamp);
field_from_json(Obj, "lastConfigurationChange", LastConfigurationChange);
field_from_json(Obj, "lastConfigurationDownload", LastConfigurationDownload);
field_from_json(Obj, "lastFWUpdate", LastFWUpdate);
field_from_json(Obj, "owner", Owner);
field_from_json(Obj, "location", Location);
field_from_json(Obj, "venue", Venue);
field_from_json(Obj, "firmware", Firmware);
field_from_json(Obj, "compatible", Compatible);
field_from_json(Obj, "fwUpdatePolicy", FWUpdatePolicy);
field_from_json(Obj, "devicePassword", DevicePassword);
field_from_json(Obj, "subscriber", subscriber);
field_from_json(Obj, "entity", entity);
field_from_json(Obj, "modified", modified);
field_from_json(Obj, "locale", locale);
field_from_json(Obj, "restrictedDevice", restrictedDevice);
field_from_json(Obj, "pendingConfiguration", pendingConfiguration);
field_from_json(Obj, "pendingConfigurationCmd", pendingConfigurationCmd);
field_from_json(Obj, "restrictionDetails", restrictionDetails);
field_from_json(Obj, "pendingUUID", pendingUUID);
field_from_json(Obj, "simulated", simulated);
field_from_json(Obj, "lastRecordedContact", lastRecordedContact);
return true;
} catch (const Poco::Exception &E) {
}
@@ -165,6 +189,8 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj, "waitingForFile", WaitingForFile);
field_to_json(Obj, "attachFile", AttachDate);
field_to_json(Obj, "executionTime", executionTime);
field_to_json(Obj, "lastTry", lastTry);
field_to_json(Obj, "deferred", deferred);
}
bool DefaultConfiguration::from_json(const Poco::JSON::Object::Ptr &Obj) {
@@ -198,7 +224,7 @@ namespace OpenWifi::GWObjects {
return false;
}
void ConnectionState::to_json(Poco::JSON::Object &Obj) const {
void ConnectionState::to_json([[maybe_unused]] const std::string &SerialNumber, Poco::JSON::Object &Obj) {
field_to_json(Obj, "ipAddress", Address);
field_to_json(Obj, "txBytes", TX);
field_to_json(Obj, "rxBytes", RX);
@@ -220,6 +246,20 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj, "connectionCompletionTime", connectionCompletionTime);
field_to_json(Obj, "totalConnectionTime", Utils::Now() - started);
field_to_json(Obj, "certificateExpiryDate", certificateExpiryDate);
#ifdef TIP_GATEWAY_SERVICE
hasRADIUSSessions = RADIUSSessionTracker()->HasSessions(SerialNumber);
AP_WS_Server()->ExtendedAttributes(SerialNumber, hasGPS, sanity,
memoryUsed,
load,
temperature);
#endif
field_to_json(Obj, "hasRADIUSSessions", hasRADIUSSessions );
field_to_json(Obj, "hasGPS", hasGPS);
field_to_json(Obj, "sanity", sanity);
field_to_json(Obj, "memoryUsed", memoryUsed);
field_to_json(Obj, "sanity", sanity);
field_to_json(Obj, "load", load);
field_to_json(Obj, "temperature", temperature);
switch (VerifiedCertificate) {
case NO_CERTIFICATE:
@@ -234,6 +274,9 @@ namespace OpenWifi::GWObjects {
case VERIFIED:
field_to_json(Obj, "verifiedCertificate", "VERIFIED");
break;
case SIMULATED:
field_to_json(Obj, "verifiedCertificate", "SIMULATED");
break;
default:
field_to_json(Obj, "verifiedCertificate", "NO_CERTIFICATE");
break;
@@ -490,6 +533,29 @@ namespace OpenWifi::GWObjects {
return false;
}
void RangeOptions::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "NO_IR", NO_IR);
field_to_json(Obj, "AUTO_BW", AUTO_BW);
field_to_json(Obj, "DFS", DFS);
field_to_json(Obj, "NO_OUTDOOR", NO_OUTDOOR);
field_to_json(Obj, "wmmrule_ETSI", wmmrule_ETSI);
field_to_json(Obj, "NO_OFDM", NO_OFDM);
}
void FrequencyRange::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "from", from);
field_to_json(Obj, "to", to);
field_to_json(Obj, "channelWidth", channelWidth);
field_to_json(Obj, "powerDb", powerDb);
field_to_json(Obj, "options", options);
}
void RegulatoryCountryInfo::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "country", country);
field_to_json(Obj, "domain", domain);
field_to_json(Obj, "ranges", ranges);
}
void DeviceRestrictionsKeyInfo::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "vendor", vendor);
field_to_json(Obj, "algo", algo);
@@ -544,4 +610,42 @@ namespace OpenWifi::GWObjects {
(T.commands != commands) || (T.developer != developer) || (T.ssh != ssh) ||
(T.key_info != key_info) || (T.country != country));
}
void RADIUSSession::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "started", started);
field_to_json(Obj, "lastTransaction", lastTransaction);
field_to_json(Obj, "destination", destination);
field_to_json(Obj, "serialNumber", serialNumber);
field_to_json(Obj, "userName", userName);
field_to_json(Obj, "accountingSessionId", accountingSessionId);
field_to_json(Obj, "accountingMultiSessionId", accountingMultiSessionId);
field_to_json(Obj, "inputPackets", inputPackets);
field_to_json(Obj, "outputPackets", outputPackets);
field_to_json(Obj, "inputOctets", inputOctets);
field_to_json(Obj, "outputOctets", outputOctets);
field_to_json(Obj, "inputGigaWords", inputGigaWords);
field_to_json(Obj, "outputGigaWords", outputGigaWords);
field_to_json(Obj, "sessionTime", sessionTime);
field_to_json(Obj, "callingStationId", callingStationId);
field_to_json(Obj, "chargeableUserIdentity", chargeableUserIdentity);
field_to_json(Obj, "interface", interface);
field_to_json(Obj, "secret", secret);
}
void RADIUSSessionList::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "sessions", sessions);
}
bool RadiusCoADMParameters::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "accountingSessionId", accountingSessionId);
field_from_json(Obj, "accountingMultiSessionId", accountingMultiSessionId);
field_from_json(Obj, "callingStationId", callingStationId);
field_from_json(Obj, "chargeableUserIdentity", chargeableUserIdentity);
return true;
} catch (const Poco::Exception &E) {
}
return false;
}
} // namespace OpenWifi::GWObjects

View File

@@ -11,9 +11,13 @@
#include "Poco/JSON/Object.h"
#include "RESTAPI_SecurityObjects.h"
#ifdef TIP_GATEWAY_SERVICE
#include <RADIUS_helpers.h>
#endif
namespace OpenWifi::GWObjects {
enum CertificateValidation { NO_CERTIFICATE, VALID_CERTIFICATE, MISMATCH_SERIAL, VERIFIED };
enum CertificateValidation { NO_CERTIFICATE, VALID_CERTIFICATE, MISMATCH_SERIAL, VERIFIED, SIMULATED };
struct ConnectionState {
uint64_t MessageCount = 0;
@@ -38,8 +42,14 @@ namespace OpenWifi::GWObjects {
uint64_t sessionId = 0;
double connectionCompletionTime = 0.0;
std::uint64_t certificateExpiryDate = 0;
bool hasRADIUSSessions = false;
bool hasGPS = false;
std::uint64_t sanity=0;
std::double_t memoryUsed=0.0;
std::double_t load=0.0;
std::double_t temperature=0.0;
void to_json(Poco::JSON::Object &Obj) const;
void to_json(const std::string &SerialNumber, Poco::JSON::Object &Obj) ;
};
struct DeviceRestrictionsKeyInfo {
@@ -96,6 +106,9 @@ namespace OpenWifi::GWObjects {
std::string pendingConfiguration;
std::string pendingConfigurationCmd;
DeviceRestrictions restrictionDetails;
std::uint64_t pendingUUID = 0;
bool simulated=false;
std::uint64_t lastRecordedContact=0;
void to_json(Poco::JSON::Object &Obj) const;
void to_json_with_status(Poco::JSON::Object &Obj) const;
@@ -188,7 +201,11 @@ namespace OpenWifi::GWObjects {
uint64_t AttachSize = 0;
std::string AttachType;
double executionTime = 0.0;
std::uint64_t lastTry = 0;
bool deferred = false;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct BlackListedDevice {
@@ -334,4 +351,76 @@ namespace OpenWifi::GWObjects {
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct RangeOptions {
bool NO_IR=false;
bool AUTO_BW=false;
bool DFS=false;
bool NO_OUTDOOR=false;
bool wmmrule_ETSI=false;
bool NO_OFDM=false;
void to_json(Poco::JSON::Object &Obj) const;
};
struct FrequencyRange {
float from = 0.0;
float to = 0.0;
int channelWidth = 0;
int powerDb = 0;
RangeOptions options;
void to_json(Poco::JSON::Object &Obj) const;
};
struct RegulatoryCountryInfo {
std::string country;
std::string domain;
std::vector<FrequencyRange> ranges;
void to_json(Poco::JSON::Object &Obj) const;
};
using RegulatoryInfoCountryMap = std::map<std::string,RegulatoryCountryInfo>;
struct RADIUSSession {
std::uint64_t started=0,
lastTransaction=0;
std::string serialNumber,
destination,
userName,
accountingSessionId,
accountingMultiSessionId,
callingStationId,
chargeableUserIdentity,
secret,
interface;
std::uint64_t inputPackets = 0,
outputPackets = 0,
inputOctets = 0,
outputOctets = 0,
inputGigaWords = 0,
outputGigaWords = 0;
std::uint32_t sessionTime = 0;
#ifdef TIP_GATEWAY_SERVICE
RADIUS::RadiusPacket accountingPacket;
#endif
void to_json(Poco::JSON::Object &Obj) const;
};
struct RADIUSSessionList {
std::vector<RADIUSSession> sessions;
void to_json(Poco::JSON::Object &Obj) const;
};
struct RadiusCoADMParameters {
std::string accountingSessionId,
accountingMultiSessionId,
callingStationId,
chargeableUserIdentity;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
} // namespace OpenWifi::GWObjects

View File

@@ -4,17 +4,19 @@
#include "ALBserver.h"
#include "framework/utils.h"
#include "framework/MicroServiceFuncs.h"
#include "fmt/format.h"
#include "framework/MicroServiceFuncs.h"
#include "framework/utils.h"
namespace OpenWifi {
void ALBRequestHandler::handleRequest([[maybe_unused]] Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response) {
void ALBRequestHandler::handleRequest([[maybe_unused]] Poco::Net::HTTPServerRequest &Request,
Poco::Net::HTTPServerResponse &Response) {
Utils::SetThreadName("alb-request");
try {
if((id_ % 100) == 0) {
Logger_.debug(fmt::format("ALB-REQUEST({}): ALB Request {}.", Request.clientAddress().toString(), id_));
if ((id_ % 100) == 0) {
Logger_.debug(fmt::format("ALB-REQUEST({}): ALB Request {}.",
Request.clientAddress().toString(), id_));
}
Response.setChunkedTransferEncoding(true);
Response.setContentType("text/html");
@@ -26,31 +28,27 @@ namespace OpenWifi {
std::ostream &Answer = Response.send();
Answer << "process Alive and kicking!";
} catch (...) {
}
}
ALBRequestHandlerFactory::ALBRequestHandlerFactory(Poco::Logger & L):
Logger_(L) {
}
ALBRequestHandlerFactory::ALBRequestHandlerFactory(Poco::Logger &L) : Logger_(L) {}
ALBRequestHandler* ALBRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest& request) {
ALBRequestHandler *
ALBRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest &request) {
if (request.getURI() == "/")
return new ALBRequestHandler(Logger_, req_id_++);
else
return nullptr;
}
ALBHealthCheckServer::ALBHealthCheckServer() :
SubSystemServer("ALBHealthCheckServer", "ALB-SVR", "alb")
{
}
ALBHealthCheckServer::ALBHealthCheckServer()
: SubSystemServer("ALBHealthCheckServer", "ALB-SVR", "alb") {}
int ALBHealthCheckServer::Start() {
if(MicroServiceConfigGetBool("alb.enable",false)) {
poco_information(Logger(),"Starting...");
Running_=true;
Port_ = (int)MicroServiceConfigGetInt("alb.port",15015);
if (MicroServiceConfigGetBool("alb.enable", false)) {
poco_information(Logger(), "Starting...");
Running_ = true;
Port_ = (int)MicroServiceConfigGetInt("alb.port", 15015);
Poco::Net::IPAddress Addr(Poco::Net::IPAddress::wildcard(
Poco::Net::Socket::supportsIPv6() ? Poco::Net::AddressFamily::IPv6
: Poco::Net::AddressFamily::IPv4));
@@ -60,7 +58,8 @@ namespace OpenWifi {
Socket_ = std::make_unique<Poco::Net::ServerSocket>(SockAddr, Port_);
auto Params = new Poco::Net::HTTPServerParams;
Params->setName("ws:alb");
Server_ = std::make_unique<Poco::Net::HTTPServer>(new ALBRequestHandlerFactory(Logger()), *Socket_, Params);
Server_ = std::make_unique<Poco::Net::HTTPServer>(
new ALBRequestHandlerFactory(Logger()), *Socket_, Params);
Server_->start();
}
@@ -68,10 +67,10 @@ namespace OpenWifi {
}
void ALBHealthCheckServer::Stop() {
poco_information(Logger(),"Stopping...");
if(Running_)
poco_information(Logger(), "Stopping...");
if (Running_)
Server_->stopAll(true);
poco_information(Logger(),"Stopped...");
poco_information(Logger(), "Stopped...");
}
} // namespace OpenWifi

View File

@@ -7,35 +7,34 @@
#include "framework/SubSystemServer.h"
#include "Poco/Net/HTTPRequestHandler.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "Poco/Net/HTTPServerResponse.h"
#include "Poco/Net/HTTPRequestHandlerFactory.h"
#include "Poco/Net/HTTPServer.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "Poco/Net/HTTPServerResponse.h"
namespace OpenWifi {
class ALBRequestHandler: public Poco::Net::HTTPRequestHandler {
class ALBRequestHandler : public Poco::Net::HTTPRequestHandler {
public:
explicit ALBRequestHandler(Poco::Logger & L, uint64_t id)
: Logger_(L), id_(id) {
}
explicit ALBRequestHandler(Poco::Logger &L, uint64_t id) : Logger_(L), id_(id) {}
void handleRequest([[maybe_unused]] Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response) override;
void handleRequest([[maybe_unused]] Poco::Net::HTTPServerRequest &Request,
Poco::Net::HTTPServerResponse &Response) override;
private:
Poco::Logger & Logger_;
uint64_t id_;
Poco::Logger &Logger_;
uint64_t id_;
};
class ALBRequestHandlerFactory: public Poco::Net::HTTPRequestHandlerFactory
{
class ALBRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
public:
explicit ALBRequestHandlerFactory(Poco::Logger & L);
ALBRequestHandler* createRequestHandler(const Poco::Net::HTTPServerRequest& request) override;
explicit ALBRequestHandlerFactory(Poco::Logger &L);
ALBRequestHandler *
createRequestHandler(const Poco::Net::HTTPServerRequest &request) override;
private:
Poco::Logger &Logger_;
inline static std::atomic_uint64_t req_id_=1;
Poco::Logger &Logger_;
inline static std::atomic_uint64_t req_id_ = 1;
};
class ALBHealthCheckServer : public SubSystemServer {
@@ -51,13 +50,12 @@ namespace OpenWifi {
void Stop() override;
private:
std::unique_ptr<Poco::Net::HTTPServer> Server_;
std::unique_ptr<Poco::Net::ServerSocket> Socket_;
int Port_ = 0;
mutable std::atomic_bool Running_=false;
std::unique_ptr<Poco::Net::HTTPServer> Server_;
std::unique_ptr<Poco::Net::ServerSocket> Socket_;
int Port_ = 0;
mutable std::atomic_bool Running_ = false;
};
inline auto ALBHealthCheckServer() { return ALBHealthCheckServer::instance(); }
} // namespace OpenWifi

View File

@@ -4,96 +4,94 @@
#pragma once
#include "Poco/Logger.h"
#include "Poco/JSON/Parser.h"
#include "Poco/Logger.h"
#include "Poco/Net/HTTPSClientSession.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "Poco/Net/HTTPServerResponse.h"
#include "Poco/Net/HTTPSClientSession.h"
#include "Poco/URI.h"
#include "framework/MicroServiceFuncs.h"
namespace OpenWifi {
inline void API_Proxy( Poco::Logger &Logger,
Poco::Net::HTTPServerRequest *Request,
Poco::Net::HTTPServerResponse *Response,
const char * ServiceType,
const char * PathRewrite,
uint64_t msTimeout_ = 10000 ) {
try {
auto Services = MicroServiceGetServices(ServiceType);
for(auto const &Svc:Services) {
Poco::URI SourceURI(Request->getURI());
Poco::URI DestinationURI(Svc.PrivateEndPoint);
DestinationURI.setPath(PathRewrite);
DestinationURI.setQuery(SourceURI.getQuery());
inline void API_Proxy(Poco::Logger &Logger, Poco::Net::HTTPServerRequest *Request,
Poco::Net::HTTPServerResponse *Response, const char *ServiceType,
const char *PathRewrite, uint64_t msTimeout_ = 10000) {
try {
auto Services = MicroServiceGetServices(ServiceType);
for (auto const &Svc : Services) {
Poco::URI SourceURI(Request->getURI());
Poco::URI DestinationURI(Svc.PrivateEndPoint);
DestinationURI.setPath(PathRewrite);
DestinationURI.setQuery(SourceURI.getQuery());
// std::cout << " Source: " << SourceURI.toString() << std::endl;
// std::cout << "Destination: " << DestinationURI.toString() << std::endl;
// std::cout << " Source: " << SourceURI.toString() << std::endl;
// std::cout << "Destination: " << DestinationURI.toString() << std::endl;
Poco::Net::HTTPSClientSession Session(DestinationURI.getHost(), DestinationURI.getPort());
Session.setKeepAlive(true);
Session.setTimeout(Poco::Timespan(msTimeout_/1000, msTimeout_ % 1000));
Poco::Net::HTTPRequest ProxyRequest(Request->getMethod(),
DestinationURI.getPathAndQuery(),
Poco::Net::HTTPMessage::HTTP_1_1);
if(Request->has("Authorization")) {
ProxyRequest.add("Authorization", Request->get("Authorization"));
} else {
ProxyRequest.add("X-API-KEY", Svc.AccessKey);
ProxyRequest.add("X-INTERNAL-NAME", MicroServicePublicEndPoint());
}
Poco::Net::HTTPSClientSession Session(DestinationURI.getHost(),
DestinationURI.getPort());
Session.setKeepAlive(true);
Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000));
Poco::Net::HTTPRequest ProxyRequest(Request->getMethod(),
DestinationURI.getPathAndQuery(),
Poco::Net::HTTPMessage::HTTP_1_1);
if (Request->has("Authorization")) {
ProxyRequest.add("Authorization", Request->get("Authorization"));
} else {
ProxyRequest.add("X-API-KEY", Svc.AccessKey);
ProxyRequest.add("X-INTERNAL-NAME", MicroServicePublicEndPoint());
}
if(Request->getMethod() == Poco::Net::HTTPRequest::HTTP_DELETE) {
Session.sendRequest(ProxyRequest);
Poco::Net::HTTPResponse ProxyResponse;
Session.receiveResponse(ProxyResponse);
Response->setStatus(ProxyResponse.getStatus());
Response->send();
return;
} else {
Poco::JSON::Parser P;
std::stringstream SS;
try {
auto Body = P.parse(Request->stream()).extract<Poco::JSON::Object::Ptr>();
Poco::JSON::Stringifier::condense(Body,SS);
SS << "\r\n\r\n";
} catch(const Poco::Exception &E) {
Logger.log(E);
}
if (Request->getMethod() == Poco::Net::HTTPRequest::HTTP_DELETE) {
Session.sendRequest(ProxyRequest);
Poco::Net::HTTPResponse ProxyResponse;
Session.receiveResponse(ProxyResponse);
Response->setStatus(ProxyResponse.getStatus());
Response->send();
return;
} else {
Poco::JSON::Parser P;
std::stringstream SS;
try {
auto Body = P.parse(Request->stream()).extract<Poco::JSON::Object::Ptr>();
Poco::JSON::Stringifier::condense(Body, SS);
SS << "\r\n\r\n";
} catch (const Poco::Exception &E) {
Logger.log(E);
}
if(SS.str().empty()) {
Session.sendRequest(ProxyRequest);
} else {
ProxyRequest.setContentType("application/json");
ProxyRequest.setContentLength(SS.str().size());
std::ostream & os = Session.sendRequest(ProxyRequest);
os << SS.str() ;
}
if (SS.str().empty()) {
Session.sendRequest(ProxyRequest);
} else {
ProxyRequest.setContentType("application/json");
ProxyRequest.setContentLength(SS.str().size());
std::ostream &os = Session.sendRequest(ProxyRequest);
os << SS.str();
}
Poco::Net::HTTPResponse ProxyResponse;
std::stringstream SSR;
try {
std::istream &ProxyResponseStream = Session.receiveResponse(ProxyResponse);
Poco::JSON::Parser P2;
auto ProxyResponseBody = P2.parse(ProxyResponseStream).extract<Poco::JSON::Object::Ptr>();
Poco::JSON::Stringifier::condense(ProxyResponseBody,SSR);
Response->setContentType("application/json");
Response->setContentLength(SSR.str().size());
Response->setStatus(ProxyResponse.getStatus());
Response->sendBuffer(SSR.str().c_str(),SSR.str().size());
return;
} catch( const Poco::Exception & E) {
Poco::Net::HTTPResponse ProxyResponse;
std::stringstream SSR;
try {
std::istream &ProxyResponseStream = Session.receiveResponse(ProxyResponse);
Poco::JSON::Parser P2;
auto ProxyResponseBody =
P2.parse(ProxyResponseStream).extract<Poco::JSON::Object::Ptr>();
Poco::JSON::Stringifier::condense(ProxyResponseBody, SSR);
Response->setContentType("application/json");
Response->setContentLength(SSR.str().size());
Response->setStatus(ProxyResponse.getStatus());
Response->sendBuffer(SSR.str().c_str(), SSR.str().size());
return;
} catch (const Poco::Exception &E) {
}
Response->setStatus(ProxyResponse.getStatus());
Response->send();
return;
}
}
}
Response->setStatus(ProxyResponse.getStatus());
Response->send();
return;
}
}
} catch (const Poco::Exception &E) {
Logger.log(E);
}
}
}
} catch (const Poco::Exception &E) {
Logger.log(E);
}
}
} // namespace OpenWifi

View File

@@ -4,13 +4,13 @@
#pragma once
#include <string>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <string>
#include "Poco/StreamCopier.h"
#include "Poco/File.h"
#include "Poco/StreamCopier.h"
#include "framework/MicroServiceFuncs.h"
@@ -18,7 +18,6 @@
namespace OpenWifi {
class AppServiceRegistry {
public:
AppServiceRegistry() {
@@ -26,9 +25,9 @@ namespace OpenWifi {
Poco::File F(FileName);
try {
if(F.exists()) {
std::ostringstream OS;
std::ifstream IF(FileName);
if (F.exists()) {
std::ostringstream OS;
std::ifstream IF(FileName);
Poco::StreamCopier::copyStream(IF, OS);
Registry_ = nlohmann::json::parse(OS.str());
}
@@ -37,55 +36,53 @@ namespace OpenWifi {
}
}
static AppServiceRegistry & instance() {
static auto instance_= new AppServiceRegistry;
static AppServiceRegistry &instance() {
static auto instance_ = new AppServiceRegistry;
return *instance_;
}
inline ~AppServiceRegistry() {
Save();
}
inline ~AppServiceRegistry() { Save(); }
inline void Save() {
std::istringstream IS( to_string(Registry_));
std::ofstream OF;
OF.open(FileName,std::ios::binary | std::ios::trunc);
std::istringstream IS(to_string(Registry_));
std::ofstream OF;
OF.open(FileName, std::ios::binary | std::ios::trunc);
Poco::StreamCopier::copyStream(IS, OF);
}
inline void Set(const char *Key, uint64_t Value ) {
inline void Set(const char *Key, uint64_t Value) {
Registry_[Key] = Value;
Save();
}
inline void Set(const char *Key, const std::string &Value ) {
inline void Set(const char *Key, const std::string &Value) {
Registry_[Key] = Value;
Save();
}
inline void Set(const char *Key, bool Value ) {
inline void Set(const char *Key, bool Value) {
Registry_[Key] = Value;
Save();
}
inline bool Get(const char *Key, bool & Value ) {
if(Registry_[Key].is_boolean()) {
inline bool Get(const char *Key, bool &Value) {
if (Registry_[Key].is_boolean()) {
Value = Registry_[Key].get<bool>();
return true;
}
return false;
}
inline bool Get(const char *Key, uint64_t & Value ) {
if(Registry_[Key].is_number_unsigned()) {
inline bool Get(const char *Key, uint64_t &Value) {
if (Registry_[Key].is_number_unsigned()) {
Value = Registry_[Key].get<uint64_t>();
return true;
}
return false;
}
inline bool Get(const char *Key, std::string & Value ) {
if(Registry_[Key].is_string()) {
inline bool Get(const char *Key, std::string &Value) {
if (Registry_[Key].is_string()) {
Value = Registry_[Key].get<std::string>();
return true;
}
@@ -93,10 +90,10 @@ namespace OpenWifi {
}
private:
std::string FileName;
nlohmann::json Registry_;
std::string FileName;
nlohmann::json Registry_;
};
inline auto AppServiceRegistry() { return AppServiceRegistry::instance(); }
}
} // namespace OpenWifi

View File

@@ -4,41 +4,40 @@
#include "Poco/Net/HTTPServerResponse.h"
#include "fmt/format.h"
#include "framework/AuthClient.h"
#include "framework/MicroServiceNames.h"
#include "framework/OpenAPIRequests.h"
#include "framework/utils.h"
#include "fmt/format.h"
namespace OpenWifi {
bool AuthClient::RetrieveTokenInformation(const std::string & SessionToken,
SecurityObjects::UserInfoAndPolicy & UInfo,
std::uint64_t TID,
bool & Expired, bool & Contacted, bool Sub) {
bool AuthClient::RetrieveTokenInformation(const std::string &SessionToken,
SecurityObjects::UserInfoAndPolicy &UInfo,
std::uint64_t TID, bool &Expired, bool &Contacted,
bool Sub) {
try {
Types::StringPairVec QueryData;
QueryData.push_back(std::make_pair("token",SessionToken));
std::string AlternateURIForLogging = fmt::format("{}?token={}", Sub ? "/api/v1/validateSubToken" : "/api/v1/validateToken", Utils::SanitizeToken(SessionToken));
OpenAPIRequestGet Req( uSERVICE_SECURITY,
QueryData.push_back(std::make_pair("token", SessionToken));
std::string AlternateURIForLogging = fmt::format(
"{}?token={}", Sub ? "/api/v1/validateSubToken" : "/api/v1/validateToken",
Utils::SanitizeToken(SessionToken));
OpenAPIRequestGet Req(uSERVICE_SECURITY,
Sub ? "/api/v1/validateSubToken" : "/api/v1/validateToken",
QueryData,
10000,
AlternateURIForLogging
);
QueryData, 10000, AlternateURIForLogging);
Poco::JSON::Object::Ptr Response;
auto StatusCode = Req.Do(Response);
if(StatusCode==Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT) {
if (StatusCode == Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT) {
Contacted = false;
return false;
}
Contacted = true;
if(StatusCode==Poco::Net::HTTPServerResponse::HTTP_OK) {
if(Response->has("tokenInfo") && Response->has("userInfo")) {
if (StatusCode == Poco::Net::HTTPServerResponse::HTTP_OK) {
if (Response->has("tokenInfo") && Response->has("userInfo")) {
UInfo.from_json(Response);
if(IsTokenExpired(UInfo.webtoken)) {
if (IsTokenExpired(UInfo.webtoken)) {
Expired = true;
return false;
}
@@ -50,18 +49,19 @@ namespace OpenWifi {
}
}
} catch (...) {
poco_error(Logger(),fmt::format("Failed to retrieve token={} for TID={}", Utils::SanitizeToken(SessionToken), TID));
poco_error(Logger(), fmt::format("Failed to retrieve token={} for TID={}",
Utils::SanitizeToken(SessionToken), TID));
}
Expired = false;
return false;
}
bool AuthClient::IsAuthorized(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo,
std::uint64_t TID,
bool & Expired, bool & Contacted, bool Sub) {
bool AuthClient::IsAuthorized(const std::string &SessionToken,
SecurityObjects::UserInfoAndPolicy &UInfo, std::uint64_t TID,
bool &Expired, bool &Contacted, bool Sub) {
auto User = Cache_.get(SessionToken);
if(!User.isNull()) {
if(IsTokenExpired(User->webtoken)) {
if (!User.isNull()) {
if (IsTokenExpired(User->webtoken)) {
Expired = true;
Cache_.remove(SessionToken);
return false;
@@ -73,57 +73,60 @@ namespace OpenWifi {
return RetrieveTokenInformation(SessionToken, UInfo, TID, Expired, Contacted, Sub);
}
bool AuthClient::RetrieveApiKeyInformation(const std::string & SessionToken,
SecurityObjects::UserInfoAndPolicy & UInfo,
std::uint64_t TID,
bool & Expired, bool & Contacted, [[maybe_unused]] bool & Suspended) {
try {
Types::StringPairVec QueryData;
QueryData.push_back(std::make_pair("apikey",SessionToken));
std::string AlternateURIForLogging = fmt::format("/api/v1/validateApiKey?apiKey={}", Utils::SanitizeToken(SessionToken));
OpenAPIRequestGet Req( uSERVICE_SECURITY,
"/api/v1/validateApiKey" ,
QueryData,
10000,
AlternateURIForLogging);
Poco::JSON::Object::Ptr Response;
bool AuthClient::RetrieveApiKeyInformation(const std::string &SessionToken,
SecurityObjects::UserInfoAndPolicy &UInfo,
std::uint64_t TID, bool &Expired, bool &Contacted,
[[maybe_unused]] bool &Suspended) {
try {
Types::StringPairVec QueryData;
QueryData.push_back(std::make_pair("apikey", SessionToken));
std::string AlternateURIForLogging =
fmt::format("/api/v1/validateApiKey?apiKey={}", Utils::SanitizeToken(SessionToken));
OpenAPIRequestGet Req(uSERVICE_SECURITY, "/api/v1/validateApiKey", QueryData, 10000,
AlternateURIForLogging);
Poco::JSON::Object::Ptr Response;
auto StatusCode = Req.Do(Response);
if(StatusCode==Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT) {
Contacted = false;
return false;
}
auto StatusCode = Req.Do(Response);
if (StatusCode == Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT) {
Contacted = false;
return false;
}
Contacted = true;
if(StatusCode==Poco::Net::HTTPServerResponse::HTTP_OK) {
if(Response->has("tokenInfo") && Response->has("userInfo") && Response->has("expiresOn")) {
UInfo.from_json(Response);
Expired = false;
ApiKeyCache_.update(SessionToken, ApiKeyCacheEntry{ .UserInfo = UInfo, .ExpiresOn = Response->get("expiresOn")});
return true;
} else {
return false;
}
}
} catch (...) {
poco_error(Logger(),fmt::format("Failed to retrieve api key={} for TID={}", Utils::SanitizeToken(SessionToken), TID));
}
Expired = false;
return false;
}
Contacted = true;
if (StatusCode == Poco::Net::HTTPServerResponse::HTTP_OK) {
if (Response->has("tokenInfo") && Response->has("userInfo") &&
Response->has("expiresOn")) {
UInfo.from_json(Response);
Expired = false;
ApiKeyCache_.update(SessionToken,
ApiKeyCacheEntry{.UserInfo = UInfo,
.ExpiresOn = Response->get("expiresOn")});
return true;
} else {
return false;
}
}
} catch (...) {
poco_error(Logger(), fmt::format("Failed to retrieve api key={} for TID={}",
Utils::SanitizeToken(SessionToken), TID));
}
Expired = false;
return false;
}
bool AuthClient::IsValidApiKey(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy &UInfo,
std::uint64_t TID, bool &Expired, bool &Contacted, bool & Suspended) {
auto User = ApiKeyCache_.get(SessionToken);
if (!User.isNull()) {
if(User->ExpiresOn < Utils::Now()) {
Expired = false;
UInfo = User->UserInfo;
return true;
}
bool AuthClient::IsValidApiKey(const std::string &SessionToken,
SecurityObjects::UserInfoAndPolicy &UInfo, std::uint64_t TID,
bool &Expired, bool &Contacted, bool &Suspended) {
auto User = ApiKeyCache_.get(SessionToken);
if (!User.isNull()) {
if (User->ExpiresOn < Utils::Now()) {
Expired = false;
UInfo = User->UserInfo;
return true;
}
ApiKeyCache_.remove(SessionToken);
}
return RetrieveApiKeyInformation(SessionToken, UInfo, TID, Expired, Contacted, Suspended);
}
}
return RetrieveApiKeyInformation(SessionToken, UInfo, TID, Expired, Contacted, Suspended);
}
} // namespace OpenWifi

View File

@@ -4,9 +4,9 @@
#pragma once
#include "framework/SubSystemServer.h"
#include "RESTObjects/RESTAPI_SecurityObjects.h"
#include "Poco/ExpireLRUCache.h"
#include "RESTObjects/RESTAPI_SecurityObjects.h"
#include "framework/SubSystemServer.h"
#include "framework/utils.h"
namespace OpenWifi {
@@ -14,66 +14,59 @@ namespace OpenWifi {
class AuthClient : public SubSystemServer {
public:
explicit AuthClient() noexcept:
SubSystemServer("Authentication", "AUTH-CLNT", "authentication")
{
}
explicit AuthClient() noexcept
: SubSystemServer("Authentication", "AUTH-CLNT", "authentication") {}
static auto instance() {
static auto instance_ = new AuthClient;
return instance_;
}
struct ApiKeyCacheEntry {
OpenWifi::SecurityObjects::UserInfoAndPolicy UserInfo;
std::uint64_t ExpiresOn;
};
struct ApiKeyCacheEntry {
OpenWifi::SecurityObjects::UserInfoAndPolicy UserInfo;
std::uint64_t ExpiresOn;
};
inline int Start() override {
return 0;
}
inline int Start() override { return 0; }
inline void Stop() override {
poco_information(Logger(),"Stopping...");
std::lock_guard G(Mutex_);
poco_information(Logger(), "Stopping...");
std::lock_guard G(Mutex_);
Cache_.clear();
poco_information(Logger(),"Stopped...");
poco_information(Logger(), "Stopped...");
}
inline void RemovedCachedToken(const std::string &Token) {
Cache_.remove(Token);
ApiKeyCache_.remove(Token);
ApiKeyCache_.remove(Token);
}
inline static bool IsTokenExpired(const SecurityObjects::WebToken &T) {
return ((T.expires_in_+T.created_) < Utils::Now());
return ((T.expires_in_ + T.created_) < Utils::Now());
}
bool RetrieveTokenInformation(const std::string & SessionToken,
SecurityObjects::UserInfoAndPolicy & UInfo,
std::uint64_t TID,
bool & Expired, bool & Contacted, bool Sub=false);
bool RetrieveTokenInformation(const std::string &SessionToken,
SecurityObjects::UserInfoAndPolicy &UInfo, std::uint64_t TID,
bool &Expired, bool &Contacted, bool Sub = false);
bool RetrieveApiKeyInformation(const std::string & SessionToken,
SecurityObjects::UserInfoAndPolicy & UInfo,
std::uint64_t TID,
bool & Expired, bool & Contacted, bool & Suspended);
bool RetrieveApiKeyInformation(const std::string &SessionToken,
SecurityObjects::UserInfoAndPolicy &UInfo, std::uint64_t TID,
bool &Expired, bool &Contacted, bool &Suspended);
bool IsAuthorized(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo,
std::uint64_t TID,
bool & Expired, bool & Contacted, bool Sub = false);
bool IsAuthorized(const std::string &SessionToken,
SecurityObjects::UserInfoAndPolicy &UInfo, std::uint64_t TID,
bool &Expired, bool &Contacted, bool Sub = false);
bool IsValidApiKey(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo,
std::uint64_t TID,
bool & Expired, bool & Contacted, bool & Suspended) ;
bool IsValidApiKey(const std::string &SessionToken,
SecurityObjects::UserInfoAndPolicy &UInfo, std::uint64_t TID,
bool &Expired, bool &Contacted, bool &Suspended);
private:
Poco::ExpireLRUCache<std::string,OpenWifi::SecurityObjects::UserInfoAndPolicy> Cache_{512,1200000 };
Poco::ExpireLRUCache<std::string,ApiKeyCacheEntry> ApiKeyCache_{512,1200000 };
Poco::ExpireLRUCache<std::string, OpenWifi::SecurityObjects::UserInfoAndPolicy> Cache_{
512, 1200000};
Poco::ExpireLRUCache<std::string, ApiKeyCacheEntry> ApiKeyCache_{512, 1200000};
};
inline auto AuthClient() { return AuthClient::instance(); }
} // namespace OpenWifi

View File

@@ -21,13 +21,13 @@ namespace OpenWifi::CIDR {
}
static bool cidr6_match(const in6_addr &address, const in6_addr &network, uint8_t bits) {
#ifdef __linux__
#ifdef __linux__
const uint32_t *a = address.s6_addr32;
const uint32_t *n = network.s6_addr32;
#else
#else
const uint32_t *a = address.__u6_addr.__u6_addr32;
const uint32_t *n = network.__u6_addr.__u6_addr32;
#endif
#endif
int bits_whole, bits_incomplete;
bits_whole = bits >> 5; // number of whole u32
bits_incomplete = bits & 0x1F; // number of bits in incomplete u32
@@ -152,4 +152,4 @@ namespace OpenWifi::CIDR {
[[nodiscard]] inline bool ValidateIpRanges(const Types::StringVec &Ranges) {
return std::all_of(cbegin(Ranges), cend(Ranges), ValidateRange);
}
}
} // namespace OpenWifi::CIDR

View File

@@ -2,8 +2,8 @@
// Created by stephane bourque on 2021-09-14.
//
#include <iostream>
#include <fstream>
#include <iostream>
#include <regex>
#include "ConfigurationValidator.h"
@@ -17,14 +17,15 @@
#include "fmt/format.h"
#include <valijson/adapters/poco_json_adapter.hpp>
#include <valijson/utils/poco_json_utils.hpp>
#include <valijson/constraints/constraint.hpp>
#include <valijson/schema.hpp>
#include <valijson/schema_parser.hpp>
#include <valijson/utils/poco_json_utils.hpp>
#include <valijson/validator.hpp>
#include <valijson/constraints/constraint.hpp>
static const std::string GitUCentralJSONSchemaFile{
"https://raw.githubusercontent.com/Telecominfraproject/wlan-ucentral-schema/main/ucentral.schema.json"};
"https://raw.githubusercontent.com/Telecominfraproject/wlan-ucentral-schema/main/"
"ucentral.schema.json"};
static std::string DefaultUCentralSchema = R"foo(
@@ -3091,6 +3092,20 @@ static std::string DefaultUCentralSchema = R"foo(
}
}
},
"metrics.wifi-scan": {
"type": "object",
"properties": {
"interval": {
"type": "integer"
},
"verbose": {
"type": "boolean"
},
"information-elements": {
"type": "boolean"
}
}
},
"metrics.telemetry": {
"type": "object",
"properties": {
@@ -3100,7 +3115,27 @@ static std::string DefaultUCentralSchema = R"foo(
"types": {
"type": "array",
"items": {
"type": "string"
"type": "string",
"enum": [
"ssh",
"health",
"health.dns",
"health.dhcp",
"health.radius",
"health.memory",
"client",
"client.join",
"client.leave",
"client.key-mismatch",
"wifi",
"wifi.start",
"wifi.stop",
"wired",
"wired.carrier-up",
"wired.carrier-down",
"unit",
"unit.boot-up"
]
}
}
}
@@ -3111,7 +3146,27 @@ static std::string DefaultUCentralSchema = R"foo(
"types": {
"type": "array",
"items": {
"type": "string"
"type": "string",
"enum": [
"ssh",
"health",
"health.dns",
"health.dhcp",
"health.radius",
"health.memory",
"client",
"client.join",
"client.leave",
"client.key-mismatch",
"wifi",
"wifi.start",
"wifi.stop",
"wired",
"wired.carrier-up",
"wired.carrier-down",
"unit",
"unit.boot-up"
]
}
}
}
@@ -3131,6 +3186,9 @@ static std::string DefaultUCentralSchema = R"foo(
"dhcp-snooping": {
"$ref": "#/$defs/metrics.dhcp-snooping"
},
"wifi-scan": {
"$ref": "#/$defs/metrics.wifi-scan"
},
"telemetry": {
"$ref": "#/$defs/metrics.telemetry"
},
@@ -3184,7 +3242,6 @@ static std::string DefaultUCentralSchema = R"foo(
)foo";
static inline bool IsIPv4(const std::string &value) {
Poco::Net::IPAddress A;
return ((Poco::Net::IPAddress::tryParse(value, A) && A.family() == Poco::Net::IPAddress::IPv4));
@@ -3242,57 +3299,68 @@ bool ExternalValijsonFormatChecker(const std::string &format, const std::string
if (format == "uc-cidr4") {
if (IsCIDRv4(value))
return true;
if(results) results->pushError(context,fmt::format("{} is not a valid CIDR IPv4 block",value));
if (results)
results->pushError(context, fmt::format("{} is not a valid CIDR IPv4 block", value));
} else if (format == "uc-cidr6") {
if (IsCIDRv6(value))
return true;
if(results) results->pushError(context,fmt::format("{} is not a valid CIDR IPv6 block",value));
if (results)
results->pushError(context, fmt::format("{} is not a valid CIDR IPv6 block", value));
} else if (format == "uc-cidr") {
if (IsCIDR(value))
return true;
if(results) results->pushError(context,fmt::format("{} is not a valid CIDR block",value));
if (results)
results->pushError(context, fmt::format("{} is not a valid CIDR block", value));
} else if (format == "uc-mac") {
if (std::regex_match(value, mac_regex))
return true;
if(results) results->pushError(context,fmt::format("{} is not a valid MAC address",value));
if (results)
results->pushError(context, fmt::format("{} is not a valid MAC address", value));
} else if (format == "uc-timeout") {
if (std::regex_match(value, uc_timeout_regex))
return true;
if(results) results->pushError(context,fmt::format("{} is not a valid timeout value",value));
if (results)
results->pushError(context, fmt::format("{} is not a valid timeout value", value));
} else if (format == "uc-host") {
if (IsIP(value))
return true;
if (std::regex_match(value, host_regex))
return true;
if(results) results->pushError(context,fmt::format("{} is not a valid hostname",value));
if (results)
results->pushError(context, fmt::format("{} is not a valid hostname", value));
} else if (format == "fqdn" || format == "uc-fqdn") {
if (std::regex_match(value, host_regex))
return true;
if(results) results->pushError(context,fmt::format("{} is not a valid FQDN",value));
if (results)
results->pushError(context, fmt::format("{} is not a valid FQDN", value));
} else if (format == "uc-base64") {
std::string s{value};
Poco::trimInPlace(s);
if ((s.size() % 4 == 0) && std::regex_match(s, b64_regex))
return true;
if(results) results->pushError(context,fmt::format("{} is not a valid base 64 value",value));
if (results)
results->pushError(context, fmt::format("{} is not a valid base 64 value", value));
} else if (format == "uri") {
try {
Poco::URI uri(value);
return true;
} catch (...) {
}
if(results) results->pushError(context,fmt::format("{} is not a valid URL",value));
if (results)
results->pushError(context, fmt::format("{} is not a valid URL", value));
} else if (format == "uc-portrange") {
try {
if (IsPortRangeIsValid(value))
return true;
} catch (...) {
}
if(results) results->pushError(context,fmt::format("{} is not a valid post range",value));
if (results)
results->pushError(context, fmt::format("{} is not a valid post range", value));
} else if (format == "ip") {
if (IsIP(value))
return true;
if(results) results->pushError(context,fmt::format("{} is not a valid IP address",value));
if (results)
results->pushError(context, fmt::format("{} is not a valid IP address", value));
}
return true;
}
@@ -3304,9 +3372,7 @@ namespace OpenWifi {
return 0;
}
void ConfigurationValidator::Stop() {
}
void ConfigurationValidator::Stop() {}
bool ConfigurationValidator::SetSchema(const std::string &SchemaStr) {
try {
@@ -3318,9 +3384,9 @@ namespace OpenWifi {
SchemaParser_->populateSchema(*PocoJsonAdapter_, *RootSchema_);
Initialized_ = Working_ = true;
return true;
} catch(const Poco::Exception &E) {
} catch (const Poco::Exception &E) {
Logger().log(E);
} catch(...) {
} catch (...) {
Logger().error("Validation schema is invalid, falling back.");
}
return false;
@@ -3331,7 +3397,7 @@ namespace OpenWifi {
return;
std::string GitSchema;
if(MicroServiceConfigGetBool("ucentral.datamodel.internal",true)) {
if (MicroServiceConfigGetBool("ucentral.datamodel.internal", true)) {
SetSchema(DefaultUCentralSchema);
poco_information(Logger(), "Using uCentral validation from built-in default.");
return;
@@ -3339,34 +3405,35 @@ namespace OpenWifi {
try {
auto GitURI =
MicroServiceConfigGetString("ucentral.datamodel.uri",GitUCentralJSONSchemaFile);
if(Utils::wgets(GitURI, GitSchema) && SetSchema(GitSchema)) {
poco_information(Logger(),"Using uCentral data model validation schema from GIT.");
MicroServiceConfigGetString("ucentral.datamodel.uri", GitUCentralJSONSchemaFile);
if (Utils::wgets(GitURI, GitSchema) && SetSchema(GitSchema)) {
poco_information(Logger(), "Using uCentral data model validation schema from GIT.");
return;
} else {
std::string FileName{MicroServiceDataDirectory() + "/ucentral.schema.json"};
std::ifstream input(FileName);
std::stringstream schema_file;
schema_file << input.rdbuf();
input.close();
if (SetSchema(schema_file.str())) {
poco_information(
Logger(), "Using uCentral data model validation schema from local file.");
return;
} else {
std::string FileName{ MicroServiceDataDirectory() + "/ucentral.schema.json" };
std::ifstream input(FileName);
std::stringstream schema_file;
schema_file << input.rdbuf();
input.close();
if(SetSchema(schema_file.str())) {
poco_information(Logger(),
"Using uCentral data model validation schema from local file.");
return;
}
}
}
} catch (const Poco::Exception &E) {
} catch (...) {
}
SetSchema(DefaultUCentralSchema);
poco_information(Logger(),"Using uCentral data model validation schema from built-in default.");
poco_information(Logger(),
"Using uCentral data model validation schema from built-in default.");
}
bool ConfigurationValidator::Validate(const std::string &C, std::vector<std::string> &Errors, bool Strict) {
if(Working_) {
try {
bool ConfigurationValidator::Validate(const std::string &C, std::vector<std::string> &Errors,
bool Strict) {
if (Working_) {
try {
Poco::JSON::Parser P;
auto Doc = P.parse(C).extract<Poco::JSON::Object::Ptr>();
valijson::adapters::PocoJsonAdapter Tester(Doc);
@@ -3375,27 +3442,28 @@ namespace OpenWifi {
if (Validator.validate(*RootSchema_, Tester, &Results)) {
return true;
}
for(const auto &error:Results) {
for (const auto &error : Results) {
Errors.push_back(error.description);
}
return false;
} catch(const Poco::Exception &E) {
} catch (const Poco::Exception &E) {
Logger().log(E);
} catch(const std::exception &E) {
Logger().warning(fmt::format("Error wile validating a configuration (1): {}", E.what()));
} catch(...) {
} catch (const std::exception &E) {
Logger().warning(
fmt::format("Error wile validating a configuration (1): {}", E.what()));
} catch (...) {
Logger().warning("Error wile validating a configuration (2)");
}
}
if(Strict)
}
}
if (Strict)
return false;
return true;
}
return true;
}
void ConfigurationValidator::reinitialize([[maybe_unused]] Poco::Util::Application &self) {
poco_information(Logger(),"Reinitializing.");
Working_ = Initialized_ = false;
Init();
}
void ConfigurationValidator::reinitialize([[maybe_unused]] Poco::Util::Application &self) {
poco_information(Logger(), "Reinitializing.");
Working_ = Initialized_ = false;
Init();
}
}
} // namespace OpenWifi

View File

@@ -7,43 +7,43 @@
#include "framework/SubSystemServer.h"
#include <valijson/adapters/poco_json_adapter.hpp>
#include <valijson/utils/poco_json_utils.hpp>
#include <valijson/schema.hpp>
#include <valijson/schema_parser.hpp>
#include <valijson/validator.hpp>
#include <valijson/constraints/constraint.hpp>
#include <valijson/constraints/constraint_visitor.hpp>
#include <valijson/schema.hpp>
#include <valijson/schema_parser.hpp>
#include <valijson/utils/poco_json_utils.hpp>
#include <valijson/validator.hpp>
namespace OpenWifi {
class ConfigurationValidator : public SubSystemServer {
public:
class ConfigurationValidator : public SubSystemServer {
public:
static auto instance() {
static auto instance_ = new ConfigurationValidator;
return instance_;
}
static auto instance() {
static auto instance_ = new ConfigurationValidator;
return instance_;
}
bool Validate(const std::string &C, std::vector<std::string> &Errors, bool Strict);
int Start() override;
void Stop() override;
void reinitialize(Poco::Util::Application &self) override;
bool Validate(const std::string &C, std::vector<std::string> &Errors, bool Strict);
int Start() override;
void Stop() override;
void reinitialize(Poco::Util::Application &self) override;
private:
bool Initialized_ = false;
bool Working_ = false;
void Init();
std::unique_ptr<valijson::Schema> RootSchema_;
std::unique_ptr<valijson::SchemaParser> SchemaParser_;
std::unique_ptr<valijson::adapters::PocoJsonAdapter> PocoJsonAdapter_;
Poco::JSON::Object::Ptr SchemaDocPtr_;
bool SetSchema(const std::string &SchemaStr);
private:
bool Initialized_=false;
bool Working_=false;
void Init();
std::unique_ptr<valijson::Schema> RootSchema_;
std::unique_ptr<valijson::SchemaParser> SchemaParser_;
std::unique_ptr<valijson::adapters::PocoJsonAdapter> PocoJsonAdapter_;
Poco::JSON::Object::Ptr SchemaDocPtr_;
bool SetSchema(const std::string &SchemaStr);
ConfigurationValidator():
SubSystemServer("ConfigValidator", "CFG-VALIDATOR", "config.validator") {
}
};
inline auto ConfigurationValidator() { return ConfigurationValidator::instance(); }
inline bool ValidateUCentralConfiguration(const std::string &C, std::vector<std::string> &Error, bool strict) { return ConfigurationValidator::instance()->Validate(C, Error, strict); }
}
ConfigurationValidator()
: SubSystemServer("ConfigValidator", "CFG-VALIDATOR", "config.validator") {}
};
inline auto ConfigurationValidator() { return ConfigurationValidator::instance(); }
inline bool ValidateUCentralConfiguration(const std::string &C, std::vector<std::string> &Error,
bool strict) {
return ConfigurationValidator::instance()->Validate(C, Error, strict);
}
} // namespace OpenWifi

View File

@@ -4,268 +4,266 @@
#pragma once
#include <vector>
#include <string>
#include <utility>
#include <vector>
namespace OpenWifi {
struct CountryInfo {
std::string code;
std::string name;
};
inline static const std::vector<CountryInfo> CountryCodes {
{ .code= "US", .name= "United States" },
{ .code= "GB", .name= "United Kingdom" },
{ .code= "CA", .name= "Canada" },
{ .code= "AF", .name= "Afghanistan" },
{ .code= "AX", .name= "Aland Islands" },
{ .code= "AL", .name= "Albania" },
{ .code= "DZ", .name= "Algeria" },
{ .code= "AS", .name= "American Samoa" },
{ .code= "AD", .name= "Andorra" },
{ .code= "AO", .name= "Angola" },
{ .code= "AI", .name= "Anguilla" },
{ .code= "AQ", .name= "Antarctica" },
{ .code= "AG", .name= "Antigua And Barbuda" },
{ .code= "AR", .name= "Argentina" },
{ .code= "AM", .name= "Armenia" },
{ .code= "AN", .name= "Netherlands Antilles" },
{ .code= "AW", .name= "Aruba" },
{ .code= "AU", .name= "Australia" },
{ .code= "AT", .name= "Austria" },
{ .code= "AZ", .name= "Azerbaijan" },
{ .code= "BS", .name= "Bahamas" },
{ .code= "BH", .name= "Bahrain" },
{ .code= "BD", .name= "Bangladesh" },
{ .code= "BB", .name= "Barbados" },
{ .code= "BY", .name= "Belarus" },
{ .code= "BE", .name= "Belgium" },
{ .code= "BZ", .name= "Belize" },
{ .code= "BJ", .name= "Benin" },
{ .code= "BM", .name= "Bermuda" },
{ .code= "BT", .name= "Bhutan" },
{ .code= "BO", .name= "Bolivia" },
{ .code= "BA", .name= "Bosnia And Herzegovina" },
{ .code= "BW", .name= "Botswana" },
{ .code= "BV", .name= "Bouvet Island" },
{ .code= "BR", .name= "Brazil" },
{ .code= "IO", .name= "British Indian Ocean Territory" },
{ .code= "BN", .name= "Brunei Darussalam" },
{ .code= "BG", .name= "Bulgaria" },
{ .code= "BF", .name= "Burkina Faso" },
{ .code= "BI", .name= "Burundi" },
{ .code= "KH", .name= "Cambodia" },
{ .code= "CM", .name= "Cameroon" },
{ .code= "CA", .name= "Canada" },
{ .code= "CV", .name= "Cape Verde" },
{ .code= "KY", .name= "Cayman Islands" },
{ .code= "CF", .name= "Central African Republic" },
{ .code= "TD", .name= "Chad" },
{ .code= "CL", .name= "Chile" },
{ .code= "CN", .name= "China" },
{ .code= "CX", .name= "Christmas Island" },
{ .code= "CC", .name= "Cocos (Keeling) Islands" },
{ .code= "CO", .name= "Colombia" },
{ .code= "KM", .name= "Comoros" },
{ .code= "CG", .name= "Congo" },
{ .code= "CD", .name= "Congo, Democratic Republic" },
{ .code= "CK", .name= "Cook Islands" },
{ .code= "CR", .name= "Costa Rica" },
{ .code= "CI", .name= "Cote D\"Ivoire" },
{ .code= "HR", .name= "Croatia" },
{ .code= "CU", .name= "Cuba" },
{ .code= "CY", .name= "Cyprus" },
{ .code= "CZ", .name= "Czech Republic" },
{ .code= "DK", .name= "Denmark" },
{ .code= "DJ", .name= "Djibouti" },
{ .code= "DM", .name= "Dominica" },
{ .code= "DO", .name= "Dominican Republic" },
{ .code= "EC", .name= "Ecuador" },
{ .code= "EG", .name= "Egypt" },
{ .code= "SV", .name= "El Salvador" },
{ .code= "GQ", .name= "Equatorial Guinea" },
{ .code= "ER", .name= "Eritrea" },
{ .code= "EE", .name= "Estonia" },
{ .code= "ET", .name= "Ethiopia" },
{ .code= "FK", .name= "Falkland Islands (Malvinas)" },
{ .code= "FO", .name= "Faroe Islands" },
{ .code= "FJ", .name= "Fiji" },
{ .code= "FI", .name= "Finland" },
{ .code= "FR", .name= "France" },
{ .code= "GF", .name= "French Guiana" },
{ .code= "PF", .name= "French Polynesia" },
{ .code= "TF", .name= "French Southern Territories" },
{ .code= "GA", .name= "Gabon" },
{ .code= "GM", .name= "Gambia" },
{ .code= "GE", .name= "Georgia" },
{ .code= "DE", .name= "Germany" },
{ .code= "GH", .name= "Ghana" },
{ .code= "GI", .name= "Gibraltar" },
{ .code= "GR", .name= "Greece" },
{ .code= "GL", .name= "Greenland" },
{ .code= "GD", .name= "Grenada" },
{ .code= "GP", .name= "Guadeloupe" },
{ .code= "GU", .name= "Guam" },
{ .code= "GT", .name= "Guatemala" },
{ .code= "GG", .name= "Guernsey" },
{ .code= "GN", .name= "Guinea" },
{ .code= "GW", .name= "Guinea-Bissau" },
{ .code= "GY", .name= "Guyana" },
{ .code= "HT", .name= "Haiti" },
{ .code= "HM", .name= "Heard Island & Mcdonald Islands" },
{ .code= "VA", .name= "Holy See (Vatican City State)" },
{ .code= "HN", .name= "Honduras" },
{ .code= "HK", .name= "Hong Kong" },
{ .code= "HU", .name= "Hungary" },
{ .code= "IS", .name= "Iceland" },
{ .code= "IN", .name= "India" },
{ .code= "ID", .name= "Indonesia" },
{ .code= "IR", .name= "Iran, Islamic Republic Of" },
{ .code= "IQ", .name= "Iraq" },
{ .code= "IE", .name= "Ireland" },
{ .code= "IM", .name= "Isle Of Man" },
{ .code= "IL", .name= "Israel" },
{ .code= "IT", .name= "Italy" },
{ .code= "JM", .name= "Jamaica" },
{ .code= "JP", .name= "Japan" },
{ .code= "JE", .name= "Jersey" },
{ .code= "JO", .name= "Jordan" },
{ .code= "KZ", .name= "Kazakhstan" },
{ .code= "KE", .name= "Kenya" },
{ .code= "KI", .name= "Kiribati" },
{ .code= "KR", .name= "Korea" },
{ .code= "KW", .name= "Kuwait" },
{ .code= "KG", .name= "Kyrgyzstan" },
{ .code= "LA", .name= "Lao People\"s Democratic Republic" },
{ .code= "LV", .name= "Latvia" },
{ .code= "LB", .name= "Lebanon" },
{ .code= "LS", .name= "Lesotho" },
{ .code= "LR", .name= "Liberia" },
{ .code= "LY", .name= "Libyan Arab Jamahiriya" },
{ .code= "LI", .name= "Liechtenstein" },
{ .code= "LT", .name= "Lithuania" },
{ .code= "LU", .name= "Luxembourg" },
{ .code= "MO", .name= "Macao" },
{ .code= "MK", .name= "Macedonia" },
{ .code= "MG", .name= "Madagascar" },
{ .code= "MW", .name= "Malawi" },
{ .code= "MY", .name= "Malaysia" },
{ .code= "MV", .name= "Maldives" },
{ .code= "ML", .name= "Mali" },
{ .code= "MT", .name= "Malta" },
{ .code= "MH", .name= "Marshall Islands" },
{ .code= "MQ", .name= "Martinique" },
{ .code= "MR", .name= "Mauritania" },
{ .code= "MU", .name= "Mauritius" },
{ .code= "YT", .name= "Mayotte" },
{ .code= "MX", .name= "Mexico" },
{ .code= "FM", .name= "Micronesia, Federated States Of" },
{ .code= "MD", .name= "Moldova" },
{ .code= "MC", .name= "Monaco" },
{ .code= "MN", .name= "Mongolia" },
{ .code= "ME", .name= "Montenegro" },
{ .code= "MS", .name= "Montserrat" },
{ .code= "MA", .name= "Morocco" },
{ .code= "MZ", .name= "Mozambique" },
{ .code= "MM", .name= "Myanmar" },
{ .code= "NA", .name= "Namibia" },
{ .code= "NR", .name= "Nauru" },
{ .code= "NP", .name= "Nepal" },
{ .code= "NL", .name= "Netherlands" },
{ .code= "AN", .name= "Netherlands Antilles" },
{ .code= "NC", .name= "New Caledonia" },
{ .code= "NZ", .name= "New Zealand" },
{ .code= "NI", .name= "Nicaragua" },
{ .code= "NE", .name= "Niger" },
{ .code= "NG", .name= "Nigeria" },
{ .code= "NU", .name= "Niue" },
{ .code= "NF", .name= "Norfolk Island" },
{ .code= "MP", .name= "Northern Mariana Islands" },
{ .code= "NO", .name= "Norway" },
{ .code= "OM", .name= "Oman" },
{ .code= "PK", .name= "Pakistan" },
{ .code= "PW", .name= "Palau" },
{ .code= "PS", .name= "Palestinian Territory, Occupied" },
{ .code= "PA", .name= "Panama" },
{ .code= "PG", .name= "Papua New Guinea" },
{ .code= "PY", .name= "Paraguay" },
{ .code= "PE", .name= "Peru" },
{ .code= "PH", .name= "Philippines" },
{ .code= "PN", .name= "Pitcairn" },
{ .code= "PL", .name= "Poland" },
{ .code= "PT", .name= "Portugal" },
{ .code= "PR", .name= "Puerto Rico" },
{ .code= "QA", .name= "Qatar" },
{ .code= "RE", .name= "Reunion" },
{ .code= "RO", .name= "Romania" },
{ .code= "RU", .name= "Russian Federation" },
{ .code= "RW", .name= "Rwanda" },
{ .code= "BL", .name= "Saint Barthelemy" },
{ .code= "SH", .name= "Saint Helena" },
{ .code= "KN", .name= "Saint Kitts And Nevis" },
{ .code= "LC", .name= "Saint Lucia" },
{ .code= "MF", .name= "Saint Martin" },
{ .code= "PM", .name= "Saint Pierre And Miquelon" },
{ .code= "VC", .name= "Saint Vincent And Grenadines" },
{ .code= "WS", .name= "Samoa" },
{ .code= "SM", .name= "San Marino" },
{ .code= "ST", .name= "Sao Tome And Principe" },
{ .code= "SA", .name= "Saudi Arabia" },
{ .code= "SN", .name= "Senegal" },
{ .code= "RS", .name= "Serbia" },
{ .code= "SC", .name= "Seychelles" },
{ .code= "SL", .name= "Sierra Leone" },
{ .code= "SG", .name= "Singapore" },
{ .code= "SK", .name= "Slovakia" },
{ .code= "SI", .name= "Slovenia" },
{ .code= "SB", .name= "Solomon Islands" },
{ .code= "SO", .name= "Somalia" },
{ .code= "ZA", .name= "South Africa" },
{ .code= "GS", .name= "South Georgia And Sandwich Isl." },
{ .code= "ES", .name= "Spain" },
{ .code= "LK", .name= "Sri Lanka" },
{ .code= "SD", .name= "Sudan" },
{ .code= "SR", .name= "Suriname" },
{ .code= "SJ", .name= "Svalbard And Jan Mayen" },
{ .code= "SZ", .name= "Swaziland" },
{ .code= "SE", .name= "Sweden" },
{ .code= "CH", .name= "Switzerland" },
{ .code= "SY", .name= "Syrian Arab Republic" },
{ .code= "TW", .name= "Taiwan" },
{ .code= "TJ", .name= "Tajikistan" },
{ .code= "TZ", .name= "Tanzania" },
{ .code= "TH", .name= "Thailand" },
{ .code= "TL", .name= "Timor-Leste" },
{ .code= "TG", .name= "Togo" },
{ .code= "TK", .name= "Tokelau" },
{ .code= "TO", .name= "Tonga" },
{ .code= "TT", .name= "Trinidad And Tobago" },
{ .code= "TN", .name= "Tunisia" },
{ .code= "TR", .name= "Turkey" },
{ .code= "TM", .name= "Turkmenistan" },
{ .code= "TC", .name= "Turks And Caicos Islands" },
{ .code= "TV", .name= "Tuvalu" },
{ .code= "UG", .name= "Uganda" },
{ .code= "UA", .name= "Ukraine" },
{ .code= "AE", .name= "United Arab Emirates" },
{ .code= "GB", .name= "United Kingdom" },
{ .code= "US", .name= "United States" },
{ .code= "UM", .name= "United States Outlying Islands" },
{ .code= "UY", .name= "Uruguay" },
{ .code= "UZ", .name= "Uzbekistan" },
{ .code= "VU", .name= "Vanuatu" },
{ .code= "VE", .name= "Venezuela" },
{ .code= "VN", .name= "Viet Nam" },
{ .code= "VG", .name= "Virgin Islands, British" },
{ .code= "VI", .name= "Virgin Islands, U.S." },
{ .code= "WF", .name= "Wallis And Futuna" },
{ .code= "EH", .name= "Western Sahara" },
{ .code= "YE", .name= "Yemen" },
{ .code= "ZM", .name= "Zambia" },
{ .code= "ZW", .name= "Zimbabwe" }
};
}
struct CountryInfo {
std::string code;
std::string name;
};
inline static const std::vector<CountryInfo> CountryCodes{
{.code = "US", .name = "United States"},
{.code = "GB", .name = "United Kingdom"},
{.code = "CA", .name = "Canada"},
{.code = "AF", .name = "Afghanistan"},
{.code = "AX", .name = "Aland Islands"},
{.code = "AL", .name = "Albania"},
{.code = "DZ", .name = "Algeria"},
{.code = "AS", .name = "American Samoa"},
{.code = "AD", .name = "Andorra"},
{.code = "AO", .name = "Angola"},
{.code = "AI", .name = "Anguilla"},
{.code = "AQ", .name = "Antarctica"},
{.code = "AG", .name = "Antigua And Barbuda"},
{.code = "AR", .name = "Argentina"},
{.code = "AM", .name = "Armenia"},
{.code = "AN", .name = "Netherlands Antilles"},
{.code = "AW", .name = "Aruba"},
{.code = "AU", .name = "Australia"},
{.code = "AT", .name = "Austria"},
{.code = "AZ", .name = "Azerbaijan"},
{.code = "BS", .name = "Bahamas"},
{.code = "BH", .name = "Bahrain"},
{.code = "BD", .name = "Bangladesh"},
{.code = "BB", .name = "Barbados"},
{.code = "BY", .name = "Belarus"},
{.code = "BE", .name = "Belgium"},
{.code = "BZ", .name = "Belize"},
{.code = "BJ", .name = "Benin"},
{.code = "BM", .name = "Bermuda"},
{.code = "BT", .name = "Bhutan"},
{.code = "BO", .name = "Bolivia"},
{.code = "BA", .name = "Bosnia And Herzegovina"},
{.code = "BW", .name = "Botswana"},
{.code = "BV", .name = "Bouvet Island"},
{.code = "BR", .name = "Brazil"},
{.code = "IO", .name = "British Indian Ocean Territory"},
{.code = "BN", .name = "Brunei Darussalam"},
{.code = "BG", .name = "Bulgaria"},
{.code = "BF", .name = "Burkina Faso"},
{.code = "BI", .name = "Burundi"},
{.code = "KH", .name = "Cambodia"},
{.code = "CM", .name = "Cameroon"},
{.code = "CA", .name = "Canada"},
{.code = "CV", .name = "Cape Verde"},
{.code = "KY", .name = "Cayman Islands"},
{.code = "CF", .name = "Central African Republic"},
{.code = "TD", .name = "Chad"},
{.code = "CL", .name = "Chile"},
{.code = "CN", .name = "China"},
{.code = "CX", .name = "Christmas Island"},
{.code = "CC", .name = "Cocos (Keeling) Islands"},
{.code = "CO", .name = "Colombia"},
{.code = "KM", .name = "Comoros"},
{.code = "CG", .name = "Congo"},
{.code = "CD", .name = "Congo, Democratic Republic"},
{.code = "CK", .name = "Cook Islands"},
{.code = "CR", .name = "Costa Rica"},
{.code = "CI", .name = "Cote D\"Ivoire"},
{.code = "HR", .name = "Croatia"},
{.code = "CU", .name = "Cuba"},
{.code = "CY", .name = "Cyprus"},
{.code = "CZ", .name = "Czech Republic"},
{.code = "DK", .name = "Denmark"},
{.code = "DJ", .name = "Djibouti"},
{.code = "DM", .name = "Dominica"},
{.code = "DO", .name = "Dominican Republic"},
{.code = "EC", .name = "Ecuador"},
{.code = "EG", .name = "Egypt"},
{.code = "SV", .name = "El Salvador"},
{.code = "GQ", .name = "Equatorial Guinea"},
{.code = "ER", .name = "Eritrea"},
{.code = "EE", .name = "Estonia"},
{.code = "ET", .name = "Ethiopia"},
{.code = "FK", .name = "Falkland Islands (Malvinas)"},
{.code = "FO", .name = "Faroe Islands"},
{.code = "FJ", .name = "Fiji"},
{.code = "FI", .name = "Finland"},
{.code = "FR", .name = "France"},
{.code = "GF", .name = "French Guiana"},
{.code = "PF", .name = "French Polynesia"},
{.code = "TF", .name = "French Southern Territories"},
{.code = "GA", .name = "Gabon"},
{.code = "GM", .name = "Gambia"},
{.code = "GE", .name = "Georgia"},
{.code = "DE", .name = "Germany"},
{.code = "GH", .name = "Ghana"},
{.code = "GI", .name = "Gibraltar"},
{.code = "GR", .name = "Greece"},
{.code = "GL", .name = "Greenland"},
{.code = "GD", .name = "Grenada"},
{.code = "GP", .name = "Guadeloupe"},
{.code = "GU", .name = "Guam"},
{.code = "GT", .name = "Guatemala"},
{.code = "GG", .name = "Guernsey"},
{.code = "GN", .name = "Guinea"},
{.code = "GW", .name = "Guinea-Bissau"},
{.code = "GY", .name = "Guyana"},
{.code = "HT", .name = "Haiti"},
{.code = "HM", .name = "Heard Island & Mcdonald Islands"},
{.code = "VA", .name = "Holy See (Vatican City State)"},
{.code = "HN", .name = "Honduras"},
{.code = "HK", .name = "Hong Kong"},
{.code = "HU", .name = "Hungary"},
{.code = "IS", .name = "Iceland"},
{.code = "IN", .name = "India"},
{.code = "ID", .name = "Indonesia"},
{.code = "IR", .name = "Iran, Islamic Republic Of"},
{.code = "IQ", .name = "Iraq"},
{.code = "IE", .name = "Ireland"},
{.code = "IM", .name = "Isle Of Man"},
{.code = "IL", .name = "Israel"},
{.code = "IT", .name = "Italy"},
{.code = "JM", .name = "Jamaica"},
{.code = "JP", .name = "Japan"},
{.code = "JE", .name = "Jersey"},
{.code = "JO", .name = "Jordan"},
{.code = "KZ", .name = "Kazakhstan"},
{.code = "KE", .name = "Kenya"},
{.code = "KI", .name = "Kiribati"},
{.code = "KR", .name = "Korea"},
{.code = "KW", .name = "Kuwait"},
{.code = "KG", .name = "Kyrgyzstan"},
{.code = "LA", .name = "Lao People\"s Democratic Republic"},
{.code = "LV", .name = "Latvia"},
{.code = "LB", .name = "Lebanon"},
{.code = "LS", .name = "Lesotho"},
{.code = "LR", .name = "Liberia"},
{.code = "LY", .name = "Libyan Arab Jamahiriya"},
{.code = "LI", .name = "Liechtenstein"},
{.code = "LT", .name = "Lithuania"},
{.code = "LU", .name = "Luxembourg"},
{.code = "MO", .name = "Macao"},
{.code = "MK", .name = "Macedonia"},
{.code = "MG", .name = "Madagascar"},
{.code = "MW", .name = "Malawi"},
{.code = "MY", .name = "Malaysia"},
{.code = "MV", .name = "Maldives"},
{.code = "ML", .name = "Mali"},
{.code = "MT", .name = "Malta"},
{.code = "MH", .name = "Marshall Islands"},
{.code = "MQ", .name = "Martinique"},
{.code = "MR", .name = "Mauritania"},
{.code = "MU", .name = "Mauritius"},
{.code = "YT", .name = "Mayotte"},
{.code = "MX", .name = "Mexico"},
{.code = "FM", .name = "Micronesia, Federated States Of"},
{.code = "MD", .name = "Moldova"},
{.code = "MC", .name = "Monaco"},
{.code = "MN", .name = "Mongolia"},
{.code = "ME", .name = "Montenegro"},
{.code = "MS", .name = "Montserrat"},
{.code = "MA", .name = "Morocco"},
{.code = "MZ", .name = "Mozambique"},
{.code = "MM", .name = "Myanmar"},
{.code = "NA", .name = "Namibia"},
{.code = "NR", .name = "Nauru"},
{.code = "NP", .name = "Nepal"},
{.code = "NL", .name = "Netherlands"},
{.code = "AN", .name = "Netherlands Antilles"},
{.code = "NC", .name = "New Caledonia"},
{.code = "NZ", .name = "New Zealand"},
{.code = "NI", .name = "Nicaragua"},
{.code = "NE", .name = "Niger"},
{.code = "NG", .name = "Nigeria"},
{.code = "NU", .name = "Niue"},
{.code = "NF", .name = "Norfolk Island"},
{.code = "MP", .name = "Northern Mariana Islands"},
{.code = "NO", .name = "Norway"},
{.code = "OM", .name = "Oman"},
{.code = "PK", .name = "Pakistan"},
{.code = "PW", .name = "Palau"},
{.code = "PS", .name = "Palestinian Territory, Occupied"},
{.code = "PA", .name = "Panama"},
{.code = "PG", .name = "Papua New Guinea"},
{.code = "PY", .name = "Paraguay"},
{.code = "PE", .name = "Peru"},
{.code = "PH", .name = "Philippines"},
{.code = "PN", .name = "Pitcairn"},
{.code = "PL", .name = "Poland"},
{.code = "PT", .name = "Portugal"},
{.code = "PR", .name = "Puerto Rico"},
{.code = "QA", .name = "Qatar"},
{.code = "RE", .name = "Reunion"},
{.code = "RO", .name = "Romania"},
{.code = "RU", .name = "Russian Federation"},
{.code = "RW", .name = "Rwanda"},
{.code = "BL", .name = "Saint Barthelemy"},
{.code = "SH", .name = "Saint Helena"},
{.code = "KN", .name = "Saint Kitts And Nevis"},
{.code = "LC", .name = "Saint Lucia"},
{.code = "MF", .name = "Saint Martin"},
{.code = "PM", .name = "Saint Pierre And Miquelon"},
{.code = "VC", .name = "Saint Vincent And Grenadines"},
{.code = "WS", .name = "Samoa"},
{.code = "SM", .name = "San Marino"},
{.code = "ST", .name = "Sao Tome And Principe"},
{.code = "SA", .name = "Saudi Arabia"},
{.code = "SN", .name = "Senegal"},
{.code = "RS", .name = "Serbia"},
{.code = "SC", .name = "Seychelles"},
{.code = "SL", .name = "Sierra Leone"},
{.code = "SG", .name = "Singapore"},
{.code = "SK", .name = "Slovakia"},
{.code = "SI", .name = "Slovenia"},
{.code = "SB", .name = "Solomon Islands"},
{.code = "SO", .name = "Somalia"},
{.code = "ZA", .name = "South Africa"},
{.code = "GS", .name = "South Georgia And Sandwich Isl."},
{.code = "ES", .name = "Spain"},
{.code = "LK", .name = "Sri Lanka"},
{.code = "SD", .name = "Sudan"},
{.code = "SR", .name = "Suriname"},
{.code = "SJ", .name = "Svalbard And Jan Mayen"},
{.code = "SZ", .name = "Swaziland"},
{.code = "SE", .name = "Sweden"},
{.code = "CH", .name = "Switzerland"},
{.code = "SY", .name = "Syrian Arab Republic"},
{.code = "TW", .name = "Taiwan"},
{.code = "TJ", .name = "Tajikistan"},
{.code = "TZ", .name = "Tanzania"},
{.code = "TH", .name = "Thailand"},
{.code = "TL", .name = "Timor-Leste"},
{.code = "TG", .name = "Togo"},
{.code = "TK", .name = "Tokelau"},
{.code = "TO", .name = "Tonga"},
{.code = "TT", .name = "Trinidad And Tobago"},
{.code = "TN", .name = "Tunisia"},
{.code = "TR", .name = "Turkey"},
{.code = "TM", .name = "Turkmenistan"},
{.code = "TC", .name = "Turks And Caicos Islands"},
{.code = "TV", .name = "Tuvalu"},
{.code = "UG", .name = "Uganda"},
{.code = "UA", .name = "Ukraine"},
{.code = "AE", .name = "United Arab Emirates"},
{.code = "GB", .name = "United Kingdom"},
{.code = "US", .name = "United States"},
{.code = "UM", .name = "United States Outlying Islands"},
{.code = "UY", .name = "Uruguay"},
{.code = "UZ", .name = "Uzbekistan"},
{.code = "VU", .name = "Vanuatu"},
{.code = "VE", .name = "Venezuela"},
{.code = "VN", .name = "Viet Nam"},
{.code = "VG", .name = "Virgin Islands, British"},
{.code = "VI", .name = "Virgin Islands, U.S."},
{.code = "WF", .name = "Wallis And Futuna"},
{.code = "EH", .name = "Western Sahara"},
{.code = "YE", .name = "Yemen"},
{.code = "ZM", .name = "Zambia"},
{.code = "ZW", .name = "Zimbabwe"}};
} // namespace OpenWifi

View File

@@ -4,45 +4,46 @@
#include "framework/EventBusManager.h"
#include "framework/KafkaManager.h"
#include "framework/utils.h"
#include "framework/MicroServiceFuncs.h"
#include "framework/utils.h"
namespace OpenWifi {
EventBusManager::EventBusManager(Poco::Logger &L) :
Logger_(L) {
}
EventBusManager::EventBusManager(Poco::Logger &L) : Logger_(L) {}
void EventBusManager::run() {
Running_ = true;
Utils::SetThreadName("fmwk:EventMgr");
auto Msg = MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_JOIN);
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,MicroServicePrivateEndPoint(),Msg, false);
while(Running_) {
auto Msg = std::make_shared<std::string>(MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_JOIN));
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroServicePrivateEndPoint(), Msg,
false);
while (Running_) {
Poco::Thread::trySleep((unsigned long)MicroServiceDaemonBusTimer());
if(!Running_)
if (!Running_)
break;
Msg = MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE);
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,MicroServicePrivateEndPoint(),Msg, false);
Msg = std::make_shared<std::string>(MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE));
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroServicePrivateEndPoint(),
Msg, false);
}
Msg = MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_LEAVE);
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,MicroServicePrivateEndPoint(),Msg, false);
Msg = std::make_shared<std::string>(MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_LEAVE));
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroServicePrivateEndPoint(), Msg,
false);
};
void EventBusManager::Start() {
poco_information(Logger(),"Starting...");
if(KafkaManager()->Enabled()) {
poco_information(Logger(), "Starting...");
if (KafkaManager()->Enabled()) {
Thread_.start(*this);
}
}
void EventBusManager::Stop() {
if(KafkaManager()->Enabled()) {
poco_information(Logger(),"Stopping...");
if (KafkaManager()->Enabled()) {
poco_information(Logger(), "Stopping...");
Running_ = false;
Thread_.wakeUp();
Thread_.join();
poco_information(Logger(),"Stopped...");
poco_information(Logger(), "Stopped...");
}
}

View File

@@ -4,8 +4,8 @@
#pragma once
#include "Poco/Runnable.h"
#include "Poco/Logger.h"
#include "Poco/Runnable.h"
#include "Poco/Thread.h"
namespace OpenWifi {
@@ -16,13 +16,12 @@ namespace OpenWifi {
void run() final;
void Start();
void Stop();
inline Poco::Logger & Logger() { return Logger_; }
inline Poco::Logger &Logger() { return Logger_; }
private:
mutable std::atomic_bool Running_ = false;
Poco::Thread Thread_;
Poco::Logger &Logger_;
mutable std::atomic_bool Running_ = false;
Poco::Thread Thread_;
Poco::Logger &Logger_;
};
} // namespace OpenWifi

View File

@@ -4,251 +4,260 @@
#include "KafkaManager.h"
#include "framework/MicroServiceFuncs.h"
#include "fmt/format.h"
#include "framework/MicroServiceFuncs.h"
namespace OpenWifi {
void KafkaLoggerFun([[maybe_unused]] cppkafka::KafkaHandleBase & handle, int level, const std::string & facility, const std::string &message) {
switch ((cppkafka::LogLevel) level) {
void KafkaLoggerFun([[maybe_unused]] cppkafka::KafkaHandleBase &handle, int level,
const std::string &facility, const std::string &message) {
switch ((cppkafka::LogLevel)level) {
case cppkafka::LogLevel::LogNotice: {
poco_notice(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message));
}
break;
poco_notice(KafkaManager()->Logger(),
fmt::format("kafka-log: facility: {} message: {}", facility, message));
} break;
case cppkafka::LogLevel::LogDebug: {
poco_debug(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message));
}
break;
poco_debug(KafkaManager()->Logger(),
fmt::format("kafka-log: facility: {} message: {}", facility, message));
} break;
case cppkafka::LogLevel::LogInfo: {
poco_information(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message));
}
break;
poco_information(KafkaManager()->Logger(),
fmt::format("kafka-log: facility: {} message: {}", facility, message));
} break;
case cppkafka::LogLevel::LogWarning: {
poco_warning(KafkaManager()->Logger(), fmt::format("kafka-log: facility: {} message: {}",facility, message));
}
break;
poco_warning(KafkaManager()->Logger(),
fmt::format("kafka-log: facility: {} message: {}", facility, message));
} break;
case cppkafka::LogLevel::LogAlert:
case cppkafka::LogLevel::LogCrit: {
poco_critical(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message));
}
break;
poco_critical(KafkaManager()->Logger(),
fmt::format("kafka-log: facility: {} message: {}", facility, message));
} break;
case cppkafka::LogLevel::LogErr:
case cppkafka::LogLevel::LogEmerg:
default: {
poco_error(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message));
}
break;
poco_error(KafkaManager()->Logger(),
fmt::format("kafka-log: facility: {} message: {}", facility, message));
} break;
}
}
inline void KafkaErrorFun([[maybe_unused]] cppkafka::KafkaHandleBase & handle, int error, const std::string &reason) {
poco_error(KafkaManager()->Logger(),fmt::format("kafka-error: {}, reason: {}", error, reason));
inline void KafkaErrorFun([[maybe_unused]] cppkafka::KafkaHandleBase &handle, int error,
const std::string &reason) {
poco_error(KafkaManager()->Logger(),
fmt::format("kafka-error: {}, reason: {}", error, reason));
}
inline void AddKafkaSecurity(cppkafka::Configuration & Config) {
auto CA = MicroServiceConfigGetString("openwifi.kafka.ssl.ca.location","");
auto Certificate = MicroServiceConfigGetString("openwifi.kafka.ssl.certificate.location","");
auto Key = MicroServiceConfigGetString("openwifi.kafka.ssl.key.location","");
auto Password = MicroServiceConfigGetString("openwifi.kafka.ssl.key.password","");
inline void AddKafkaSecurity(cppkafka::Configuration &Config) {
auto CA = MicroServiceConfigGetString("openwifi.kafka.ssl.ca.location", "");
auto Certificate =
MicroServiceConfigGetString("openwifi.kafka.ssl.certificate.location", "");
auto Key = MicroServiceConfigGetString("openwifi.kafka.ssl.key.location", "");
auto Password = MicroServiceConfigGetString("openwifi.kafka.ssl.key.password", "");
if(CA.empty() || Certificate.empty() || Key.empty())
if (CA.empty() || Certificate.empty() || Key.empty())
return;
Config.set("ssl.ca.location", CA);
Config.set("ssl.certificate.location", Certificate);
Config.set("ssl.key.location", Key);
if(!Password.empty())
if (!Password.empty())
Config.set("ssl.key.password", Password);
}
void KafkaManager::initialize(Poco::Util::Application & self) {
void KafkaManager::initialize(Poco::Util::Application &self) {
SubSystemServer::initialize(self);
KafkaEnabled_ = MicroServiceConfigGetBool("openwifi.kafka.enable",false);
KafkaEnabled_ = MicroServiceConfigGetBool("openwifi.kafka.enable", false);
}
inline void KafkaProducer::run() {
Poco::Logger &Logger_ = Poco::Logger::create("KAFKA-PRODUCER", KafkaManager()->Logger().getChannel());
poco_information(Logger_,"Starting...");
Poco::Logger &Logger_ =
Poco::Logger::create("KAFKA-PRODUCER", KafkaManager()->Logger().getChannel());
poco_information(Logger_, "Starting...");
Utils::SetThreadName("Kafka:Prod");
cppkafka::Configuration Config({
{ "client.id", MicroServiceConfigGetString("openwifi.kafka.client.id", "") },
{ "metadata.broker.list", MicroServiceConfigGetString("openwifi.kafka.brokerlist", "") }
});
cppkafka::Configuration Config(
{{"client.id", MicroServiceConfigGetString("openwifi.kafka.client.id", "")},
{"metadata.broker.list",
MicroServiceConfigGetString("openwifi.kafka.brokerlist", "")}});
AddKafkaSecurity(Config);
Config.set_log_callback(KafkaLoggerFun);
Config.set_error_callback(KafkaErrorFun);
KafkaManager()->SystemInfoWrapper_ = R"lit({ "system" : { "id" : )lit" +
std::to_string(MicroServiceID()) +
R"lit( , "host" : ")lit" + MicroServicePrivateEndPoint() +
R"lit(" } , "payload" : )lit" ;
KafkaManager()->SystemInfoWrapper_ =
R"lit({ "system" : { "id" : )lit" + std::to_string(MicroServiceID()) +
R"lit( , "host" : ")lit" + MicroServicePrivateEndPoint() +
R"lit(" } , "payload" : )lit";
cppkafka::Producer Producer(Config);
cppkafka::Producer Producer(Config);
Running_ = true;
Poco::AutoPtr<Poco::Notification> Note(Queue_.waitDequeueNotification());
while(Note && Running_) {
Poco::AutoPtr<Poco::Notification> Note(Queue_.waitDequeueNotification());
while (Note && Running_) {
try {
auto Msg = dynamic_cast<KafkaMessage *>(Note.get());
if (Msg != nullptr) {
Producer.produce(
cppkafka::MessageBuilder(Msg->Topic()).key(Msg->Key()).payload(Msg->Payload()));
Producer.produce(cppkafka::MessageBuilder(Msg->Topic())
.key(Msg->Key())
.payload(Msg->Payload()));
}
} catch (const cppkafka::HandleException &E) {
poco_warning(Logger_,fmt::format("Caught a Kafka exception (producer): {}", E.what()));
} catch( const Poco::Exception &E) {
poco_warning(Logger_,
fmt::format("Caught a Kafka exception (producer): {}", E.what()));
} catch (const Poco::Exception &E) {
Logger_.log(E);
} catch (...) {
poco_error(Logger_,"std::exception");
poco_error(Logger_, "std::exception");
}
Note = Queue_.waitDequeueNotification();
}
poco_information(Logger_,"Stopped...");
poco_information(Logger_, "Stopped...");
}
inline void KafkaConsumer::run() {
Utils::SetThreadName("Kafka:Cons");
Poco::Logger &Logger_ = Poco::Logger::create("KAFKA-CONSUMER", KafkaManager()->Logger().getChannel());
Poco::Logger &Logger_ =
Poco::Logger::create("KAFKA-CONSUMER", KafkaManager()->Logger().getChannel());
poco_information(Logger_,"Starting...");
poco_information(Logger_, "Starting...");
cppkafka::Configuration Config({
{ "client.id", MicroServiceConfigGetString("openwifi.kafka.client.id","") },
{ "metadata.broker.list", MicroServiceConfigGetString("openwifi.kafka.brokerlist","") },
{ "group.id", MicroServiceConfigGetString("openwifi.kafka.group.id","") },
{ "enable.auto.commit", MicroServiceConfigGetBool("openwifi.kafka.auto.commit",false) },
{ "auto.offset.reset", "latest" } ,
{ "enable.partition.eof", false }
});
cppkafka::Configuration Config(
{{"client.id", MicroServiceConfigGetString("openwifi.kafka.client.id", "")},
{"metadata.broker.list", MicroServiceConfigGetString("openwifi.kafka.brokerlist", "")},
{"group.id", MicroServiceConfigGetString("openwifi.kafka.group.id", "")},
{"enable.auto.commit", MicroServiceConfigGetBool("openwifi.kafka.auto.commit", false)},
{"auto.offset.reset", "latest"},
{"enable.partition.eof", false}});
AddKafkaSecurity(Config);
Config.set_log_callback(KafkaLoggerFun);
Config.set_error_callback(KafkaErrorFun);
cppkafka::TopicConfiguration topic_config = {
{ "auto.offset.reset", "smallest" }
};
cppkafka::TopicConfiguration topic_config = {{"auto.offset.reset", "smallest"}};
// Now configure it to be the default topic config
Config.set_default_topic_configuration(topic_config);
cppkafka::Consumer Consumer(Config);
Consumer.set_assignment_callback([&](cppkafka::TopicPartitionList& partitions) {
if(!partitions.empty()) {
poco_information(Logger_,fmt::format("Partition assigned: {}...",
partitions.front().get_partition()));
Consumer.set_assignment_callback([&](cppkafka::TopicPartitionList &partitions) {
if (!partitions.empty()) {
poco_information(Logger_, fmt::format("Partition assigned: {}...",
partitions.front().get_partition()));
}
});
Consumer.set_revocation_callback([&](const cppkafka::TopicPartitionList& partitions) {
if(!partitions.empty()) {
poco_information(Logger_,fmt::format("Partition revocation: {}...",
partitions.front().get_partition()));
Consumer.set_revocation_callback([&](const cppkafka::TopicPartitionList &partitions) {
if (!partitions.empty()) {
poco_information(Logger_, fmt::format("Partition revocation: {}...",
partitions.front().get_partition()));
}
});
bool AutoCommit = MicroServiceConfigGetBool("openwifi.kafka.auto.commit",false);
auto BatchSize = MicroServiceConfigGetInt("openwifi.kafka.consumer.batchsize",20);
bool AutoCommit = MicroServiceConfigGetBool("openwifi.kafka.auto.commit", false);
auto BatchSize = MicroServiceConfigGetInt("openwifi.kafka.consumer.batchsize", 20);
Types::StringVec Topics;
Types::StringVec Topics;
KafkaManager()->Topics(Topics);
Consumer.subscribe(Topics);
Running_ = true;
while(Running_) {
while (Running_) {
try {
std::vector<cppkafka::Message> MsgVec = Consumer.poll_batch(BatchSize, std::chrono::milliseconds(100));
for(auto const &Msg:MsgVec) {
std::vector<cppkafka::Message> MsgVec =
Consumer.poll_batch(BatchSize, std::chrono::milliseconds(100));
for (auto const &Msg : MsgVec) {
if (!Msg)
continue;
if (Msg.get_error()) {
if (!Msg.is_eof()) {
poco_error(Logger_,fmt::format("Error: {}", Msg.get_error().to_string()));
poco_error(Logger_,
fmt::format("Error: {}", Msg.get_error().to_string()));
}
if(!AutoCommit)
if (!AutoCommit)
Consumer.async_commit(Msg);
continue;
}
KafkaManager()->Dispatch(Msg.get_topic(), Msg.get_key(),Msg.get_payload() );
KafkaManager()->Dispatch(Msg.get_topic().c_str(), Msg.get_key(), std::make_shared<std::string>(Msg.get_payload()));
if (!AutoCommit)
Consumer.async_commit(Msg);
}
} catch (const cppkafka::HandleException &E) {
poco_warning(Logger_,fmt::format("Caught a Kafka exception (consumer): {}", E.what()));
poco_warning(Logger_,
fmt::format("Caught a Kafka exception (consumer): {}", E.what()));
} catch (const Poco::Exception &E) {
Logger_.log(E);
} catch (...) {
poco_error(Logger_,"std::exception");
poco_error(Logger_, "std::exception");
}
}
Consumer.unsubscribe();
poco_information(Logger_,"Stopped...");
poco_information(Logger_, "Stopped...");
}
void KafkaProducer::Start() {
if(!Running_) {
Running_=true;
if (!Running_) {
Running_ = true;
Worker_.start(*this);
}
}
void KafkaProducer::Stop() {
if(Running_) {
Running_=false;
if (Running_) {
Running_ = false;
Queue_.wakeUpAll();
Worker_.join();
}
}
void KafkaProducer::Produce(const std::string &Topic, const std::string &Key, const std::string &Payload) {
std::lock_guard G(Mutex_);
Queue_.enqueueNotification( new KafkaMessage(Topic,Key,Payload));
void KafkaProducer::Produce(const char *Topic, const std::string &Key,
const std::shared_ptr<std::string> Payload) {
std::lock_guard G(Mutex_);
Queue_.enqueueNotification(new KafkaMessage(Topic, Key, Payload));
}
void KafkaConsumer::Start() {
if(!Running_) {
Running_=true;
if (!Running_) {
Running_ = true;
Worker_.start(*this);
}
}
void KafkaConsumer::Stop() {
if(Running_) {
Running_=false;
if (Running_) {
Running_ = false;
Worker_.wakeUp();
Worker_.join();
}
}
void KafkaDispatcher::Start() {
if(!Running_) {
Running_=true;
if (!Running_) {
Running_ = true;
Worker_.start(*this);
}
}
void KafkaDispatcher::Stop() {
if(Running_) {
Running_=false;
if (Running_) {
Running_ = false;
Queue_.wakeUpAll();
Worker_.join();
}
}
auto KafkaDispatcher::RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F) {
auto KafkaDispatcher::RegisterTopicWatcher(const std::string &Topic,
Types::TopicNotifyFunction &F) {
std::lock_guard G(Mutex_);
auto It = Notifiers_.find(Topic);
if(It == Notifiers_.end()) {
if (It == Notifiers_.end()) {
Types::TopicNotifyFunctionList L;
L.emplace(L.end(),std::make_pair(F,FunctionId_));
L.emplace(L.end(), std::make_pair(F, FunctionId_));
Notifiers_[Topic] = std::move(L);
} else {
It->second.emplace(It->second.end(),std::make_pair(F,FunctionId_));
It->second.emplace(It->second.end(), std::make_pair(F, FunctionId_));
}
return FunctionId_++;
}
@@ -256,110 +265,115 @@ namespace OpenWifi {
void KafkaDispatcher::UnregisterTopicWatcher(const std::string &Topic, int Id) {
std::lock_guard G(Mutex_);
auto It = Notifiers_.find(Topic);
if(It != Notifiers_.end()) {
Types::TopicNotifyFunctionList & L = It->second;
for(auto it=L.begin(); it!=L.end(); it++)
if(it->second == Id) {
if (It != Notifiers_.end()) {
Types::TopicNotifyFunctionList &L = It->second;
for (auto it = L.begin(); it != L.end(); it++)
if (it->second == Id) {
L.erase(it);
break;
}
}
}
void KafkaDispatcher::Dispatch(const std::string &Topic, const std::string &Key, const std::string &Payload) {
std::lock_guard G(Mutex_);
void KafkaDispatcher::Dispatch(const char *Topic, const std::string &Key,
const std::shared_ptr<std::string> Payload) {
std::lock_guard G(Mutex_);
auto It = Notifiers_.find(Topic);
if(It!=Notifiers_.end()) {
if (It != Notifiers_.end()) {
Queue_.enqueueNotification(new KafkaMessage(Topic, Key, Payload));
}
}
void KafkaDispatcher::run() {
Poco::Logger &Logger_ = Poco::Logger::create("KAFKA-DISPATCHER", KafkaManager()->Logger().getChannel());
poco_information(Logger_,"Starting...");
Poco::AutoPtr<Poco::Notification> Note(Queue_.waitDequeueNotification());
Poco::Logger &Logger_ =
Poco::Logger::create("KAFKA-DISPATCHER", KafkaManager()->Logger().getChannel());
poco_information(Logger_, "Starting...");
Poco::AutoPtr<Poco::Notification> Note(Queue_.waitDequeueNotification());
Utils::SetThreadName("kafka:dispatch");
while(Note && Running_) {
auto Msg = dynamic_cast<KafkaMessage*>(Note.get());
if(Msg!= nullptr) {
while (Note && Running_) {
auto Msg = dynamic_cast<KafkaMessage *>(Note.get());
if (Msg != nullptr) {
auto It = Notifiers_.find(Msg->Topic());
if (It != Notifiers_.end()) {
const auto & FL = It->second;
for(const auto &[CallbackFunc,_]:FL) {
const auto &FL = It->second;
for (const auto &[CallbackFunc, _] : FL) {
CallbackFunc(Msg->Key(), Msg->Payload());
}
}
}
Note = Queue_.waitDequeueNotification();
}
poco_information(Logger_,"Stopped...");
poco_information(Logger_, "Stopped...");
}
void KafkaDispatcher::Topics(std::vector<std::string> &T) {
T.clear();
for(const auto &[TopicName,_]:Notifiers_)
for (const auto &[TopicName, _] : Notifiers_)
T.push_back(TopicName);
}
int KafkaManager::Start() {
if(!KafkaEnabled_)
if (!KafkaEnabled_)
return 0;
ConsumerThr_.Start();
ConsumerThr_.Start();
ProducerThr_.Start();
Dispatcher_.Start();
return 0;
}
void KafkaManager::Stop() {
if(KafkaEnabled_) {
poco_information(Logger(),"Stopping...");
void KafkaManager::Stop() {
if (KafkaEnabled_) {
poco_information(Logger(), "Stopping...");
Dispatcher_.Stop();
ProducerThr_.Stop();
ConsumerThr_.Stop();
poco_information(Logger(),"Stopped...");
poco_information(Logger(), "Stopped...");
return;
}
}
void KafkaManager::PostMessage(const std::string &topic, const std::string & key, const std::string &PayLoad, bool WrapMessage ) {
if(KafkaEnabled_) {
ProducerThr_.Produce(topic,key,WrapMessage ? WrapSystemId(PayLoad) : PayLoad);
void KafkaManager::PostMessage(const char *topic, const std::string &key,
const std::shared_ptr<std::string> PayLoad, bool WrapMessage) {
if (KafkaEnabled_) {
ProducerThr_.Produce(topic, key, WrapMessage ? WrapSystemId(PayLoad) : PayLoad);
}
}
void KafkaManager::Dispatch(const std::string &Topic, const std::string & Key, const std::string &Payload) {
void KafkaManager::Dispatch(const char *Topic, const std::string &Key,
const std::shared_ptr<std::string> Payload) {
Dispatcher_.Dispatch(Topic, Key, Payload);
}
[[nodiscard]] std::string KafkaManager::WrapSystemId(const std::string & PayLoad) {
return SystemInfoWrapper_ + PayLoad + "}";
[[nodiscard]] const std::shared_ptr<std::string> KafkaManager::WrapSystemId(const std::shared_ptr<std::string> PayLoad) {
*PayLoad = SystemInfoWrapper_ + *PayLoad + "}";
return PayLoad;
}
uint64_t KafkaManager::RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F) {
if(KafkaEnabled_) {
return Dispatcher_.RegisterTopicWatcher(Topic,F);
uint64_t KafkaManager::RegisterTopicWatcher(const std::string &Topic,
Types::TopicNotifyFunction &F) {
if (KafkaEnabled_) {
return Dispatcher_.RegisterTopicWatcher(Topic, F);
} else {
return 0;
}
}
void KafkaManager::UnregisterTopicWatcher(const std::string &Topic, uint64_t Id) {
if(KafkaEnabled_) {
if (KafkaEnabled_) {
Dispatcher_.UnregisterTopicWatcher(Topic, Id);
}
}
void KafkaManager::Topics(std::vector<std::string> &T) {
Dispatcher_.Topics(T);
void KafkaManager::Topics(std::vector<std::string> &T) { Dispatcher_.Topics(T); }
void KafkaManager::PartitionAssignment(const cppkafka::TopicPartitionList &partitions) {
poco_information(
Logger(), fmt::format("Partition assigned: {}...", partitions.front().get_partition()));
}
void KafkaManager::PartitionAssignment(const cppkafka::TopicPartitionList& partitions) {
poco_information(Logger(),fmt::format("Partition assigned: {}...", partitions.front().get_partition()));
}
void KafkaManager::PartitionRevocation(const cppkafka::TopicPartitionList& partitions) {
poco_information(Logger(),fmt::format("Partition revocation: {}...",partitions.front().get_partition()));
void KafkaManager::PartitionRevocation(const cppkafka::TopicPartitionList &partitions) {
poco_information(Logger(), fmt::format("Partition revocation: {}...",
partitions.front().get_partition()));
}
} // namespace OpenWifi

View File

@@ -7,44 +7,43 @@
#include "Poco/Notification.h"
#include "Poco/NotificationQueue.h"
#include "framework/SubSystemServer.h"
#include "framework/OpenWifiTypes.h"
#include "framework/utils.h"
#include "framework/KafkaTopics.h"
#include "framework/OpenWifiTypes.h"
#include "framework/SubSystemServer.h"
#include "framework/utils.h"
#include "cppkafka/cppkafka.h"
namespace OpenWifi {
class KafkaMessage: public Poco::Notification {
class KafkaMessage : public Poco::Notification {
public:
KafkaMessage( const std::string &Topic, const std::string &Key, const std::string & Payload) :
Topic_(Topic), Key_(Key), Payload_(Payload) {
}
KafkaMessage(const char * Topic, const std::string &Key, const std::shared_ptr<std::string> Payload)
: Topic_(Topic), Key_(Key), Payload_(std::move(Payload)) {}
inline const std::string & Topic() { return Topic_; }
inline const std::string & Key() { return Key_; }
inline const std::string & Payload() { return Payload_; }
inline const char * Topic() { return Topic_; }
inline const std::string &Key() { return Key_; }
inline const std::string &Payload() { return *Payload_; }
private:
std::string Topic_;
std::string Key_;
std::string Payload_;
const char *Topic_;
std::string Key_;
std::shared_ptr<std::string> Payload_;
};
class KafkaProducer : public Poco::Runnable {
public:
void run () override;
void Start();
void Stop();
void Produce(const std::string &Topic, const std::string &Key, const std::string &Payload);
public:
void run() override;
void Start();
void Stop();
void Produce(const char *Topic, const std::string &Key, const std::shared_ptr<std::string> Payload);
private:
std::recursive_mutex Mutex_;
Poco::Thread Worker_;
mutable std::atomic_bool Running_=false;
Poco::NotificationQueue Queue_;
};
std::recursive_mutex Mutex_;
Poco::Thread Worker_;
mutable std::atomic_bool Running_ = false;
Poco::NotificationQueue Queue_;
};
class KafkaConsumer : public Poco::Runnable {
public:
@@ -53,9 +52,9 @@ namespace OpenWifi {
void Stop();
private:
std::recursive_mutex Mutex_;
Poco::Thread Worker_;
mutable std::atomic_bool Running_=false;
std::recursive_mutex Mutex_;
Poco::Thread Worker_;
mutable std::atomic_bool Running_ = false;
};
class KafkaDispatcher : public Poco::Runnable {
@@ -64,26 +63,25 @@ namespace OpenWifi {
void Stop();
auto RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F);
void UnregisterTopicWatcher(const std::string &Topic, int Id);
void Dispatch(const std::string &Topic, const std::string &Key, const std::string &Payload);
void Dispatch(const char *Topic, const std::string &Key, const std::shared_ptr<std::string> Payload);
void run() override;
void Topics(std::vector<std::string> &T);
private:
std::recursive_mutex Mutex_;
Types::NotifyTable Notifiers_;
Poco::Thread Worker_;
mutable std::atomic_bool Running_=false;
uint64_t FunctionId_=1;
Poco::NotificationQueue Queue_;
std::recursive_mutex Mutex_;
Types::NotifyTable Notifiers_;
Poco::Thread Worker_;
mutable std::atomic_bool Running_ = false;
uint64_t FunctionId_ = 1;
Poco::NotificationQueue Queue_;
};
class KafkaManager : public SubSystemServer {
public:
friend class KafkaConsumer;
friend class KafkaProducer;
inline void initialize(Poco::Util::Application & self) override;
inline void initialize(Poco::Util::Application &self) override;
static auto instance() {
static auto instance_ = new KafkaManager;
@@ -93,30 +91,28 @@ namespace OpenWifi {
int Start() override;
void Stop() override;
void PostMessage(const std::string &topic, const std::string & key, const std::string &PayLoad, bool WrapMessage = true );
void Dispatch(const std::string &Topic, const std::string & Key, const std::string &Payload);
[[nodiscard]] std::string WrapSystemId(const std::string & PayLoad);
void PostMessage(const char *topic, const std::string &key,
const std::shared_ptr<std::string> PayLoad, bool WrapMessage = true);
void Dispatch(const char *Topic, const std::string &Key, const std::shared_ptr<std::string> Payload);
[[nodiscard]] const std::shared_ptr<std::string> WrapSystemId(const std::shared_ptr<std::string> PayLoad);
[[nodiscard]] inline bool Enabled() const { return KafkaEnabled_; }
uint64_t RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F);
void UnregisterTopicWatcher(const std::string &Topic, uint64_t Id);
void Topics(std::vector<std::string> &T);
private:
bool KafkaEnabled_ = false;
std::string SystemInfoWrapper_;
KafkaProducer ProducerThr_;
KafkaConsumer ConsumerThr_;
KafkaDispatcher Dispatcher_;
bool KafkaEnabled_ = false;
std::string SystemInfoWrapper_;
KafkaProducer ProducerThr_;
KafkaConsumer ConsumerThr_;
KafkaDispatcher Dispatcher_;
void PartitionAssignment(const cppkafka::TopicPartitionList& partitions);
void PartitionRevocation(const cppkafka::TopicPartitionList& partitions);
void PartitionAssignment(const cppkafka::TopicPartitionList &partitions);
void PartitionRevocation(const cppkafka::TopicPartitionList &partitions);
KafkaManager() noexcept:
SubSystemServer("KafkaManager", "KAFKA-SVR", "openwifi.kafka") {
}
KafkaManager() noexcept : SubSystemServer("KafkaManager", "KAFKA-SVR", "openwifi.kafka") {}
};
inline auto KafkaManager() { return KafkaManager::instance(); }
} // namespace OpenWifi

View File

@@ -10,33 +10,32 @@
#include <string>
namespace OpenWifi::KafkaTopics {
static const std::string HEALTHCHECK{"healthcheck"};
static const std::string STATE{"state"};
static const std::string CONNECTION{"connection"};
static const std::string WIFISCAN{"wifiscan"};
static const std::string ALERTS{"alerts"};
static const std::string COMMAND{"command"};
static const std::string SERVICE_EVENTS{"service_events"};
static const std::string DEVICE_EVENT_QUEUE{"device_event_queue"};
static const std::string DEVICE_TELEMETRY{"device_telemetry"};
static const std::string PROVISIONING_CHANGE{"provisioning_change"};
inline const char * HEALTHCHECK = "healthcheck";
inline const char * STATE = "state";
inline const char * CONNECTION = "connection";
inline const char * WIFISCAN = "wifiscan";
inline const char * ALERTS = "alerts";
inline const char * COMMAND = "command";
inline const char * SERVICE_EVENTS = "service_events";
inline const char * DEVICE_EVENT_QUEUE = "device_event_queue";
inline const char * DEVICE_TELEMETRY = "device_telemetry";
inline const char * PROVISIONING_CHANGE = "provisioning_change";
namespace ServiceEvents {
static const std::string EVENT_JOIN{"join"};
static const std::string EVENT_LEAVE{"leave"};
static const std::string EVENT_KEEP_ALIVE{"keep-alive"};
static const std::string EVENT_REMOVE_TOKEN{"remove-token"};
inline const char * EVENT_JOIN = "join";
inline const char * EVENT_LEAVE = "leave";
inline const char * EVENT_KEEP_ALIVE = "keep-alive";
inline const char * EVENT_REMOVE_TOKEN = "remove-token";
namespace Fields {
static const std::string EVENT{"event"};
static const std::string ID{"id"};
static const std::string TYPE{"type"};
static const std::string PUBLIC{"publicEndPoint"};
static const std::string PRIVATE{"privateEndPoint"};
static const std::string KEY{"key"};
static const std::string VRSN{"version"};
static const std::string TOKEN{"token"};
}
}
}
inline const char * EVENT = "event";
inline const char * ID = "id";
inline const char * TYPE = "type";
inline const char * PUBLIC = "publicEndPoint";
inline const char * PRIVATE = "privateEndPoint";
inline const char * KEY = "key";
inline const char * VRSN = "version";
inline const char * TOKEN = "token";
} // namespace Fields
} // namespace ServiceEvents
} // namespace OpenWifi::KafkaTopics

View File

@@ -2,40 +2,39 @@
// Created by stephane bourque on 2022-10-26.
//
#include "Poco/FileChannel.h"
#include "Poco/ConsoleChannel.h"
#include "Poco/PatternFormatter.h"
#include "Poco/FormattingChannel.h"
#include "Poco/AsyncChannel.h"
#include "Poco/NullChannel.h"
#include "Poco/SplitterChannel.h"
#include "Poco/Net/HTTPStreamFactory.h"
#include "Poco/Net/HTTPSStreamFactory.h"
#include "Poco/ConsoleChannel.h"
#include "Poco/FileChannel.h"
#include "Poco/FormattingChannel.h"
#include "Poco/JSON/JSONException.h"
#include "Poco/Net/FTPSStreamFactory.h"
#include "Poco/Net/FTPStreamFactory.h"
#include "Poco/Net/HTTPSStreamFactory.h"
#include "Poco/Net/HTTPStreamFactory.h"
#include "Poco/Net/SSLManager.h"
#include "Poco/JSON/JSONException.h"
#include "Poco/NullChannel.h"
#include "Poco/PatternFormatter.h"
#include "Poco/SplitterChannel.h"
#include "framework/ALBserver.h"
#include "framework/AuthClient.h"
#include "framework/KafkaManager.h"
#include "framework/MicroService.h"
#include "framework/MicroServiceErrorHandler.h"
#include "framework/UI_WebSocketClientServer.h"
#include "framework/MicroServiceNames.h"
#include "framework/AuthClient.h"
#include "framework/ALBserver.h"
#include "framework/KafkaManager.h"
#include "framework/RESTAPI_GenericServerAccounting.h"
#include "framework/RESTAPI_ExtServer.h"
#include "framework/RESTAPI_GenericServerAccounting.h"
#include "framework/RESTAPI_IntServer.h"
#include "framework/utils.h"
#include "framework/UI_WebSocketClientServer.h"
#include "framework/WebSocketLogger.h"
#include "framework/utils.h"
namespace OpenWifi {
void MicroService::Exit(int Reason) {
std::exit(Reason);
}
void MicroService::Exit(int Reason) { std::exit(Reason); }
void MicroService::BusMessageReceived([[maybe_unused]] const std::string &Key, const std::string & Payload) {
void MicroService::BusMessageReceived([[maybe_unused]] const std::string &Key,
const std::string &Payload) {
std::lock_guard G(InfraMutex_);
try {
Poco::JSON::Parser P;
@@ -43,66 +42,99 @@ namespace OpenWifi {
if (Object->has(KafkaTopics::ServiceEvents::Fields::ID) &&
Object->has(KafkaTopics::ServiceEvents::Fields::EVENT)) {
uint64_t ID = Object->get(KafkaTopics::ServiceEvents::Fields::ID);
auto Event = Object->get(KafkaTopics::ServiceEvents::Fields::EVENT).toString();
uint64_t ID = Object->get(KafkaTopics::ServiceEvents::Fields::ID);
auto Event = Object->get(KafkaTopics::ServiceEvents::Fields::EVENT).toString();
if (ID != ID_) {
if( Event==KafkaTopics::ServiceEvents::EVENT_JOIN ||
Event==KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE ||
Event==KafkaTopics::ServiceEvents::EVENT_LEAVE ) {
if( Object->has(KafkaTopics::ServiceEvents::Fields::TYPE) &&
if (Event == KafkaTopics::ServiceEvents::EVENT_JOIN ||
Event == KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE ||
Event == KafkaTopics::ServiceEvents::EVENT_LEAVE) {
if (Object->has(KafkaTopics::ServiceEvents::Fields::TYPE) &&
Object->has(KafkaTopics::ServiceEvents::Fields::PUBLIC) &&
Object->has(KafkaTopics::ServiceEvents::Fields::PRIVATE) &&
Object->has(KafkaTopics::ServiceEvents::Fields::VRSN) &&
Object->has(KafkaTopics::ServiceEvents::Fields::KEY)) {
auto PrivateEndPoint = Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString();
if (Event == KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE && Services_.find(PrivateEndPoint) != Services_.end()) {
auto PrivateEndPoint =
Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString();
if (Event == KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE &&
Services_.find(PrivateEndPoint) != Services_.end()) {
Services_[PrivateEndPoint].LastUpdate = Utils::Now();
} else if (Event == KafkaTopics::ServiceEvents::EVENT_LEAVE) {
Services_.erase(PrivateEndPoint);
poco_debug(logger(),fmt::format("Service {} ID={} leaving system.",Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString(),ID));
} else if (Event == KafkaTopics::ServiceEvents::EVENT_JOIN || Event == KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE) {
poco_debug(logger(),fmt::format("Service {} ID={} joining system.",Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString(),ID));
poco_debug(
logger(),
fmt::format(
"Service {} ID={} leaving system.",
Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE)
.toString(),
ID));
} else if (Event == KafkaTopics::ServiceEvents::EVENT_JOIN ||
Event == KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE) {
poco_debug(
logger(),
fmt::format(
"Service {} ID={} joining system.",
Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE)
.toString(),
ID));
Services_[PrivateEndPoint] = Types::MicroServiceMeta{
.Id = ID,
.Type = Poco::toLower(Object->get(KafkaTopics::ServiceEvents::Fields::TYPE).toString()),
.PrivateEndPoint = Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString(),
.PublicEndPoint = Object->get(KafkaTopics::ServiceEvents::Fields::PUBLIC).toString(),
.AccessKey = Object->get(KafkaTopics::ServiceEvents::Fields::KEY).toString(),
.Version = Object->get(KafkaTopics::ServiceEvents::Fields::VRSN).toString(),
.LastUpdate = Utils::Now() };
.Type = Poco::toLower(
Object->get(KafkaTopics::ServiceEvents::Fields::TYPE)
.toString()),
.PrivateEndPoint =
Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE)
.toString(),
.PublicEndPoint =
Object->get(KafkaTopics::ServiceEvents::Fields::PUBLIC)
.toString(),
.AccessKey =
Object->get(KafkaTopics::ServiceEvents::Fields::KEY)
.toString(),
.Version = Object->get(KafkaTopics::ServiceEvents::Fields::VRSN)
.toString(),
.LastUpdate = Utils::Now()};
std::string SvcList;
for (const auto &Svc: Services_) {
if(SvcList.empty())
for (const auto &Svc : Services_) {
if (SvcList.empty())
SvcList = Svc.second.Type;
else
SvcList += ", " + Svc.second.Type;
}
poco_information(logger(),fmt::format("Current list of microservices: {}", SvcList));
poco_information(
logger(),
fmt::format("Current list of microservices: {}", SvcList));
}
} else {
poco_error(logger(),fmt::format("KAFKA-MSG: invalid event '{}', missing a field.",Event));
poco_error(
logger(),
fmt::format("KAFKA-MSG: invalid event '{}', missing a field.",
Event));
}
} else if (Event==KafkaTopics::ServiceEvents::EVENT_REMOVE_TOKEN) {
if(Object->has(KafkaTopics::ServiceEvents::Fields::TOKEN)) {
#ifndef TIP_SECURITY_SERVICE
AuthClient()->RemovedCachedToken(Object->get(KafkaTopics::ServiceEvents::Fields::TOKEN).toString());
#endif
} else if (Event == KafkaTopics::ServiceEvents::EVENT_REMOVE_TOKEN) {
if (Object->has(KafkaTopics::ServiceEvents::Fields::TOKEN)) {
#ifndef TIP_SECURITY_SERVICE
AuthClient()->RemovedCachedToken(
Object->get(KafkaTopics::ServiceEvents::Fields::TOKEN).toString());
#endif
} else {
poco_error(logger(),fmt::format("KAFKA-MSG: invalid event '{}', missing token",Event));
poco_error(
logger(),
fmt::format("KAFKA-MSG: invalid event '{}', missing token", Event));
}
} else {
poco_error(logger(),fmt::format("Unknown Event: {} Source: {}", Event, ID));
poco_error(logger(),
fmt::format("Unknown Event: {} Source: {}", Event, ID));
}
}
} else {
poco_error(logger(),"Bad bus message.");
poco_error(logger(), "Bad bus message.");
}
auto i=Services_.begin();
auto i = Services_.begin();
auto now = Utils::Now();
for(;i!=Services_.end();) {
if((now - i->second.LastUpdate)>60) {
for (; i != Services_.end();) {
if ((now - i->second.LastUpdate) > 60) {
i = Services_.erase(i);
} else
++i;
@@ -113,13 +145,13 @@ namespace OpenWifi {
}
}
Types::MicroServiceMetaVec MicroService::GetServices(const std::string & Type) {
Types::MicroServiceMetaVec MicroService::GetServices(const std::string &Type) {
std::lock_guard G(InfraMutex_);
auto T = Poco::toLower(Type);
Types::MicroServiceMetaVec Res;
for(const auto &[_,ServiceRec]:Services_) {
if(ServiceRec.Type==T)
Types::MicroServiceMetaVec Res;
for (const auto &[_, ServiceRec] : Services_) {
if (ServiceRec.Type == T)
Res.push_back(ServiceRec);
}
return Res;
@@ -128,23 +160,25 @@ namespace OpenWifi {
Types::MicroServiceMetaVec MicroService::GetServices() {
std::lock_guard G(InfraMutex_);
Types::MicroServiceMetaVec Res;
for(const auto &[_,ServiceRec]:Services_) {
Types::MicroServiceMetaVec Res;
for (const auto &[_, ServiceRec] : Services_) {
Res.push_back(ServiceRec);
}
return Res;
}
void MicroService::LoadConfigurationFile() {
std::string Location = Poco::Environment::get(DAEMON_CONFIG_ENV_VAR,".");
ConfigFileName_ = ConfigFileName_.empty() ? Location + "/" + DAEMON_PROPERTIES_FILENAME : ConfigFileName_;
std::string Location = Poco::Environment::get(DAEMON_CONFIG_ENV_VAR, ".");
ConfigFileName_ =
ConfigFileName_.empty() ? Location + "/" + DAEMON_PROPERTIES_FILENAME : ConfigFileName_;
Poco::Path ConfigFile(ConfigFileName_);
if(!ConfigFile.isFile())
{
std::cerr << DAEMON_APP_NAME << ": Configuration "
<< ConfigFile.toString() << " does not seem to exist. Please set " + DAEMON_CONFIG_ENV_VAR
+ " env variable the path of the " + DAEMON_PROPERTIES_FILENAME + " file." << std::endl;
if (!ConfigFile.isFile()) {
std::cerr << DAEMON_APP_NAME << ": Configuration " << ConfigFile.toString()
<< " does not seem to exist. Please set " + DAEMON_CONFIG_ENV_VAR +
" env variable the path of the " + DAEMON_PROPERTIES_FILENAME +
" file."
<< std::endl;
std::exit(Poco::Util::Application::EXIT_CONFIG);
}
@@ -159,11 +193,12 @@ namespace OpenWifi {
}
void MicroService::LoadMyConfig() {
NoAPISecurity_ = ConfigGetBool("openwifi.security.restapi.disable",false);
std::string KeyFile = ConfigPath("openwifi.service.key","");
if(!KeyFile.empty()) {
NoAPISecurity_ = ConfigGetBool("openwifi.security.restapi.disable", false);
std::string KeyFile = ConfigPath("openwifi.service.key", "");
if (!KeyFile.empty()) {
std::string KeyFilePassword = ConfigPath("openwifi.service.key.password", "");
AppKey_ = Poco::SharedPtr<Poco::Crypto::RSAKey>(new Poco::Crypto::RSAKey("", KeyFile, KeyFilePassword));
AppKey_ = Poco::SharedPtr<Poco::Crypto::RSAKey>(
new Poco::Crypto::RSAKey("", KeyFile, KeyFilePassword));
Cipher_ = CipherFactory_.createCipher(*AppKey_);
Signer_.setRSAKey(AppKey_);
Signer_.addAllAlgorithms();
@@ -173,8 +208,8 @@ namespace OpenWifi {
}
ID_ = Utils::GetSystemId();
if(!DebugMode_)
DebugMode_ = ConfigGetBool("openwifi.system.debug",false);
if (!DebugMode_)
DebugMode_ = ConfigGetBool("openwifi.system.debug", false);
MyPrivateEndPoint_ = ConfigGetString("openwifi.system.uri.private");
MyPublicEndPoint_ = ConfigGetString("openwifi.system.uri.public");
UIURI_ = ConfigGetString("openwifi.system.uri.ui");
@@ -184,151 +219,170 @@ namespace OpenWifi {
void MicroService::InitializeLoggingSystem() {
static auto initialized = false;
if(!initialized) {
if (!initialized) {
initialized = true;
LoadConfigurationFile();
auto LoggingDestination = MicroService::instance().ConfigGetString("logging.type", "file");
auto LoggingFormat = MicroService::instance().ConfigGetString("logging.format",
"%Y-%m-%d %H:%M:%S.%i %s: [%p][thr:%I] %t");
auto LoggingDestination =
MicroService::instance().ConfigGetString("logging.type", "file");
auto LoggingFormat = MicroService::instance().ConfigGetString(
"logging.format", "%Y-%m-%d %H:%M:%S.%i %s: [%p][thr:%I] %t");
auto UseAsyncLogs_ = MicroService::instance().ConfigGetBool("logging.asynch", true);
auto DisableWebSocketLogging = MicroService::instance().ConfigGetBool("logging.websocket",false);
auto DisableWebSocketLogging =
MicroService::instance().ConfigGetBool("logging.websocket", false);
if (LoggingDestination == "null") {
Poco::AutoPtr<Poco::NullChannel> DevNull(new Poco::NullChannel);
Poco::Logger::root().setChannel(DevNull);
} else if (LoggingDestination == "console") {
SetConsoleLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat);
SetConsoleLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat);
} else if (LoggingDestination == "colorconsole") {
SetColorConsoleLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat);
SetColorConsoleLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat);
} else if (LoggingDestination == "sql") {
SetSQLLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat);
SetSQLLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat);
} else if (LoggingDestination == "syslog") {
SetSyslogLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat);
SetSyslogLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat);
} else {
SetFileLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat, DAEMON_ROOT_ENV_VAR);
}
SetFileLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat,
DAEMON_ROOT_ENV_VAR);
}
auto Level = Poco::Logger::parseLevel(MicroService::instance().ConfigGetString("logging.level", "debug"));
auto Level = Poco::Logger::parseLevel(
MicroService::instance().ConfigGetString("logging.level", "debug"));
Poco::Logger::root().setLevel(Level);
if(!DisableWebSocketLogging) {
if (!DisableWebSocketLogging) {
static const UI_WebSocketClientServer::NotificationTypeIdVec Notifications = {
{1, "log"}};
UI_WebSocketClientServer()->RegisterNotifications(Notifications);
}
}
}
}
void MicroService::SetConsoleLogs(bool UseAsync, bool DisableWebSocketLogging, const std::string & FormatterPattern) {
void MicroService::SetConsoleLogs(bool UseAsync, bool DisableWebSocketLogging,
const std::string &FormatterPattern) {
Poco::AutoPtr<Poco::ConsoleChannel> Console(new Poco::ConsoleChannel);
Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
Formatter->setProperty("pattern", FormatterPattern);
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(new Poco::FormattingChannel(Formatter, Console));
Poco::AutoPtr<Poco::ConsoleChannel> Console(new Poco::ConsoleChannel);
Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
Formatter->setProperty("pattern", FormatterPattern);
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(
new Poco::FormattingChannel(Formatter, Console));
if(DisableWebSocketLogging) {
if(UseAsync) {
Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(FormattingChannel));
Poco::Logger::root().setChannel(Async);
} else {
Poco::Logger::root().setChannel(FormattingChannel);
}
} else {
Poco::AutoPtr<WebSocketLogger> WSLogger(new WebSocketLogger);
Poco::AutoPtr<Poco::SplitterChannel> Splitter(new Poco::SplitterChannel);
Splitter->addChannel(WSLogger);
Splitter->addChannel(FormattingChannel);
if(UseAsync) {
Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(Splitter));
Poco::Logger::root().setChannel(Async);
} else {
Poco::Logger::root().setChannel(Splitter);
}
}
Poco::Logger::root().information(fmt::format("Enabled console logs: asynch={} websocket={}",UseAsync,DisableWebSocketLogging));
}
if (DisableWebSocketLogging) {
if (UseAsync) {
Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(FormattingChannel));
Poco::Logger::root().setChannel(Async);
} else {
Poco::Logger::root().setChannel(FormattingChannel);
}
} else {
Poco::AutoPtr<WebSocketLogger> WSLogger(new WebSocketLogger);
Poco::AutoPtr<Poco::SplitterChannel> Splitter(new Poco::SplitterChannel);
Splitter->addChannel(WSLogger);
Splitter->addChannel(FormattingChannel);
if (UseAsync) {
Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(Splitter));
Poco::Logger::root().setChannel(Async);
} else {
Poco::Logger::root().setChannel(Splitter);
}
}
Poco::Logger::root().information(fmt::format("Enabled console logs: asynch={} websocket={}",
UseAsync, DisableWebSocketLogging));
}
void MicroService::SetColorConsoleLogs(bool UseAsync, bool DisableWebSocketLogging, const std::string & FormatterPattern) {
void MicroService::SetColorConsoleLogs(bool UseAsync, bool DisableWebSocketLogging,
const std::string &FormatterPattern) {
Poco::AutoPtr<Poco::ColorConsoleChannel> Console(new Poco::ColorConsoleChannel);
Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
Formatter->setProperty("pattern", FormatterPattern);
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(new Poco::FormattingChannel(Formatter, Console));
Poco::AutoPtr<Poco::ColorConsoleChannel> Console(new Poco::ColorConsoleChannel);
Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
Formatter->setProperty("pattern", FormatterPattern);
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(
new Poco::FormattingChannel(Formatter, Console));
if(DisableWebSocketLogging) {
if(UseAsync) {
Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(FormattingChannel));
Poco::Logger::root().setChannel(Async);
} else {
Poco::Logger::root().setChannel(FormattingChannel);
}
} else {
Poco::AutoPtr<WebSocketLogger> WSLogger(new WebSocketLogger);
Poco::AutoPtr<Poco::SplitterChannel> Splitter(new Poco::SplitterChannel);
Splitter->addChannel(WSLogger);
Splitter->addChannel(FormattingChannel);
if(UseAsync) {
Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(Splitter));
Poco::Logger::root().setChannel(Async);
} else {
Poco::Logger::root().setChannel(Splitter);
}
}
Poco::Logger::root().information(fmt::format("Enabled color console logs: asynch={} websocket={}",UseAsync,DisableWebSocketLogging));
}
if (DisableWebSocketLogging) {
if (UseAsync) {
Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(FormattingChannel));
Poco::Logger::root().setChannel(Async);
} else {
Poco::Logger::root().setChannel(FormattingChannel);
}
} else {
Poco::AutoPtr<WebSocketLogger> WSLogger(new WebSocketLogger);
Poco::AutoPtr<Poco::SplitterChannel> Splitter(new Poco::SplitterChannel);
Splitter->addChannel(WSLogger);
Splitter->addChannel(FormattingChannel);
if (UseAsync) {
Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(Splitter));
Poco::Logger::root().setChannel(Async);
} else {
Poco::Logger::root().setChannel(Splitter);
}
}
Poco::Logger::root().information(
fmt::format("Enabled color console logs: asynch={} websocket={}", UseAsync,
DisableWebSocketLogging));
}
void MicroService::SetSQLLogs([[maybe_unused]] bool UseAsync,[[maybe_unused]] bool DisableWebSocketLogging,[[maybe_unused]] const std::string & FormatterPattern) {
//"CREATE TABLE T_POCO_LOG (Source VARCHAR, Name VARCHAR, ProcessId INTEGER, Thread VARCHAR, ThreadId INTEGER, Priority INTEGER, Text VARCHAR, DateTime DATE)"
}
void MicroService::SetSQLLogs([[maybe_unused]] bool UseAsync,
[[maybe_unused]] bool DisableWebSocketLogging,
[[maybe_unused]] const std::string &FormatterPattern) {
//"CREATE TABLE T_POCO_LOG (Source VARCHAR, Name VARCHAR, ProcessId INTEGER, Thread VARCHAR,
//ThreadId INTEGER, Priority INTEGER, Text VARCHAR, DateTime DATE)"
}
void MicroService::SetSyslogLogs([[maybe_unused]] bool UseAsync,[[maybe_unused]] bool DisableWebSocketLogging,[[maybe_unused]] const std::string & FormatterPattern) {
void MicroService::SetSyslogLogs([[maybe_unused]] bool UseAsync,
[[maybe_unused]] bool DisableWebSocketLogging,
[[maybe_unused]] const std::string &FormatterPattern) {}
}
void MicroService::SetFileLogs(bool UseAsync, bool DisableWebSocketLogging,
const std::string &FormatterPattern,
const std::string &root_env_var) {
std::string DefaultLogPath = fmt::format("${}/logs", root_env_var);
auto LoggingLocationDir =
MicroService::instance().ConfigPath("logging.path", DefaultLogPath);
Poco::File LD(LoggingLocationDir);
try {
if (!LD.exists()) {
LD.createDirectory();
}
} catch (const Poco::Exception &E) {
std::cout << "Cannot create " << LD.path() << " Error: " << E.message() << std::endl;
}
auto LoggingLocationDirFilePattern = LoggingLocationDir + "/log";
void MicroService::SetFileLogs(bool UseAsync, bool DisableWebSocketLogging, const std::string & FormatterPattern, const std::string & root_env_var) {
std::string DefaultLogPath = fmt::format("${}/logs",root_env_var);
auto LoggingLocationDir = MicroService::instance().ConfigPath("logging.path", DefaultLogPath);
Poco::File LD(LoggingLocationDir);
try {
if(!LD.exists()) {
LD.createDirectory();
}
} catch(const Poco::Exception &E) {
std::cout << "Cannot create " << LD.path() << " Error: " << E.message() << std::endl;
}
auto LoggingLocationDirFilePattern = LoggingLocationDir + "/log";
Poco::AutoPtr<Poco::FileChannel> FileChannel(new Poco::FileChannel);
FileChannel->setProperty("rotation", "10 M");
FileChannel->setProperty("archive", "timestamp");
FileChannel->setProperty("purgeCount", "10");
FileChannel->setProperty("path", LoggingLocationDirFilePattern);
Poco::AutoPtr<Poco::FileChannel> FileChannel(new Poco::FileChannel);
FileChannel->setProperty("rotation", "10 M");
FileChannel->setProperty("archive", "timestamp");
FileChannel->setProperty("purgeCount", "10");
FileChannel->setProperty("path", LoggingLocationDirFilePattern);
Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
Formatter->setProperty("pattern", FormatterPattern);
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(
new Poco::FormattingChannel(Formatter, FileChannel));
Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
Formatter->setProperty("pattern", FormatterPattern);
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(new Poco::FormattingChannel(Formatter, FileChannel));
if(DisableWebSocketLogging) {
if(UseAsync) {
Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(FormattingChannel));
Poco::Logger::root().setChannel(Async);
} else {
Poco::Logger::root().setChannel(FormattingChannel);
}
} else {
Poco::AutoPtr<WebSocketLogger> WSLogger(new WebSocketLogger);
Poco::AutoPtr<Poco::SplitterChannel> Splitter(new Poco::SplitterChannel);
Splitter->addChannel(WSLogger);
Splitter->addChannel(FormattingChannel);
if(UseAsync) {
Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(Splitter));
Poco::Logger::root().setChannel(Async);
} else {
Poco::Logger::root().setChannel(Splitter);
}
}
Poco::Logger::root().information(fmt::format("Enabled file logs: asynch={} websocket={}",UseAsync,DisableWebSocketLogging));
}
if (DisableWebSocketLogging) {
if (UseAsync) {
Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(FormattingChannel));
Poco::Logger::root().setChannel(Async);
} else {
Poco::Logger::root().setChannel(FormattingChannel);
}
} else {
Poco::AutoPtr<WebSocketLogger> WSLogger(new WebSocketLogger);
Poco::AutoPtr<Poco::SplitterChannel> Splitter(new Poco::SplitterChannel);
Splitter->addChannel(WSLogger);
Splitter->addChannel(FormattingChannel);
if (UseAsync) {
Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(Splitter));
Poco::Logger::root().setChannel(Async);
} else {
Poco::Logger::root().setChannel(Splitter);
}
}
Poco::Logger::root().information(fmt::format("Enabled file logs: asynch={} websocket={}",
UseAsync, DisableWebSocketLogging));
}
void DaemonPostInitialization(Poco::Util::Application &self);
@@ -341,37 +395,39 @@ namespace OpenWifi {
SubSystems_.push_back(ALBHealthCheckServer());
SubSystems_.push_back(RESTAPI_ExtServer());
SubSystems_.push_back(RESTAPI_IntServer());
#ifndef TIP_SECURITY_SERVICE
#ifndef TIP_SECURITY_SERVICE
SubSystems_.push_back(AuthClient());
#endif
#endif
Poco::Net::initializeSSL();
Poco::Net::HTTPStreamFactory::registerFactory();
Poco::Net::HTTPSStreamFactory::registerFactory();
Poco::Net::FTPStreamFactory::registerFactory();
Poco::Net::FTPSStreamFactory::registerFactory();
Poco::File DataDir(ConfigPath("openwifi.system.data"));
Poco::File DataDir(ConfigPath("openwifi.system.data"));
DataDir_ = DataDir.path();
if(!DataDir.exists()) {
if (!DataDir.exists()) {
try {
DataDir.createDirectory();
} catch (const Poco::Exception &E) {
logger().log(E);
}
}
WWWAssetsDir_ = ConfigPath("openwifi.restapi.wwwassets","");
if(WWWAssetsDir_.empty())
WWWAssetsDir_ = ConfigPath("openwifi.restapi.wwwassets", "");
if (WWWAssetsDir_.empty())
WWWAssetsDir_ = DataDir_;
LoadMyConfig();
AllowExternalMicroServices_ = ConfigGetBool("allowexternalmicroservices",true);
AllowExternalMicroServices_ = ConfigGetBool("allowexternalmicroservices", true);
InitializeSubSystemServers();
ServerApplication::initialize(self);
DaemonPostInitialization(self);
Types::TopicNotifyFunction F = [this](const std::string &Key,const std::string &Payload) { this->BusMessageReceived(Key, Payload); };
Types::TopicNotifyFunction F = [this](const std::string &Key, const std::string &Payload) {
this->BusMessageReceived(Key, Payload);
};
KafkaManager()->RegisterTopicWatcher(KafkaTopics::SERVICE_EVENTS, F);
}
@@ -392,58 +448,64 @@ namespace OpenWifi {
Poco::Util::Option("help", "", "display help information on command line arguments")
.required(false)
.repeatable(false)
.callback(Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleHelp)));
.callback(
Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleHelp)));
options.addOption(
Poco::Util::Option("file", "", "specify the configuration file")
.required(false)
.repeatable(false)
.argument("file")
.callback(Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleConfig)));
options.addOption(Poco::Util::Option("file", "", "specify the configuration file")
.required(false)
.repeatable(false)
.argument("file")
.callback(Poco::Util::OptionCallback<MicroService>(
this, &MicroService::handleConfig)));
options.addOption(
Poco::Util::Option("debug", "", "to run in debug, set to true")
.required(false)
.repeatable(false)
.callback(Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleDebug)));
options.addOption(Poco::Util::Option("debug", "", "to run in debug, set to true")
.required(false)
.repeatable(false)
.callback(Poco::Util::OptionCallback<MicroService>(
this, &MicroService::handleDebug)));
options.addOption(
Poco::Util::Option("logs", "", "specify the log directory and file (i.e. dir/file.log)")
.required(false)
.repeatable(false)
.argument("dir")
.callback(Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleLogs)));
options.addOption(
Poco::Util::Option("version", "", "get the version and quit.")
.required(false)
.repeatable(false)
.callback(Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleVersion)));
.callback(
Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleLogs)));
options.addOption(Poco::Util::Option("version", "", "get the version and quit.")
.required(false)
.repeatable(false)
.callback(Poco::Util::OptionCallback<MicroService>(
this, &MicroService::handleVersion)));
}
void MicroService::handleHelp([[maybe_unused]] const std::string &name, [[maybe_unused]] const std::string &value) {
void MicroService::handleHelp([[maybe_unused]] const std::string &name,
[[maybe_unused]] const std::string &value) {
HelpRequested_ = true;
displayHelp();
stopOptionsProcessing();
}
void MicroService::handleVersion([[maybe_unused]] const std::string &name, [[maybe_unused]] const std::string &value) {
void MicroService::handleVersion([[maybe_unused]] const std::string &name,
[[maybe_unused]] const std::string &value) {
HelpRequested_ = true;
std::cout << Version() << std::endl;
stopOptionsProcessing();
}
void MicroService::handleDebug([[maybe_unused]] const std::string &name, const std::string &value) {
if(value == "true")
DebugMode_ = true ;
void MicroService::handleDebug([[maybe_unused]] const std::string &name,
const std::string &value) {
if (value == "true")
DebugMode_ = true;
}
void MicroService::handleLogs([[maybe_unused]] const std::string &name, const std::string &value) {
void MicroService::handleLogs([[maybe_unused]] const std::string &name,
const std::string &value) {
LogDir_ = value;
}
void MicroService::handleConfig([[maybe_unused]] const std::string &name, const std::string &value) {
void MicroService::handleConfig([[maybe_unused]] const std::string &name,
const std::string &value) {
ConfigFileName_ = value;
}
@@ -456,31 +518,32 @@ namespace OpenWifi {
}
void MicroService::InitializeSubSystemServers() {
for(auto i:SubSystems_) {
for (auto i : SubSystems_) {
addSubsystem(i);
}
}
void MicroService::StartSubSystemServers() {
AddActivity("Starting");
for(auto i:SubSystems_) {
for (auto i : SubSystems_) {
i->Start();
}
EventBusManager_ = std::make_unique<EventBusManager>(Poco::Logger::create("EventBusManager",Poco::Logger::root().getChannel(),Poco::Logger::root().getLevel()));
EventBusManager_ = std::make_unique<EventBusManager>(Poco::Logger::create(
"EventBusManager", Poco::Logger::root().getChannel(), Poco::Logger::root().getLevel()));
EventBusManager_->Start();
}
void MicroService::StopSubSystemServers() {
AddActivity("Stopping");
EventBusManager_->Stop();
for(auto i=SubSystems_.rbegin(); i!=SubSystems_.rend(); ++i) {
for (auto i = SubSystems_.rbegin(); i != SubSystems_.rend(); ++i) {
(*i)->Stop();
}
}
[[nodiscard]] std::string MicroService::CreateUUID() {
static std::random_device rd;
static std::mt19937_64 gen(rd());
static std::random_device rd;
static std::mt19937_64 gen(rd());
static std::uniform_int_distribution<> dis(0, 15);
static std::uniform_int_distribution<> dis2(8, 11);
@@ -510,7 +573,8 @@ namespace OpenWifi {
return ss.str();
}
bool MicroService::SetSubsystemLogLevel(const std::string &SubSystem, const std::string &Level) {
bool MicroService::SetSubsystemLogLevel(const std::string &SubSystem,
const std::string &Level) {
try {
auto P = Poco::Logger::parseLevel(Level);
auto Sub = Poco::toLower(SubSystem);
@@ -528,7 +592,7 @@ namespace OpenWifi {
}
}
}
} catch (const Poco::Exception & E) {
} catch (const Poco::Exception &E) {
std::cerr << "Exception" << std::endl;
}
return false;
@@ -545,7 +609,7 @@ namespace OpenWifi {
Types::StringVec MicroService::GetSubSystems() const {
Types::StringVec Result;
for(auto i:SubSystems_)
for (auto i : SubSystems_)
Result.push_back(Poco::toLower(i->Name()));
return Result;
}
@@ -553,35 +617,32 @@ namespace OpenWifi {
Types::StringPairVec MicroService::GetLogLevels() {
Types::StringPairVec Result;
for(auto &i:SubSystems_) {
auto P = std::make_pair( i->Name(), Utils::LogLevelToString(i->GetLoggingLevel()));
for (auto &i : SubSystems_) {
auto P = std::make_pair(i->Name(), Utils::LogLevelToString(i->GetLoggingLevel()));
Result.push_back(P);
}
return Result;
}
const Types::StringVec & MicroService::GetLogLevelNames() {
static Types::StringVec LevelNames{"none", "fatal", "critical", "error", "warning", "notice", "information", "debug", "trace" };
const Types::StringVec &MicroService::GetLogLevelNames() {
static Types::StringVec LevelNames{"none", "fatal", "critical", "error", "warning",
"notice", "information", "debug", "trace"};
return LevelNames;
}
uint64_t MicroService::ConfigGetInt(const std::string &Key,uint64_t Default) {
return (uint64_t) config().getInt64(Key,Default);
uint64_t MicroService::ConfigGetInt(const std::string &Key, uint64_t Default) {
return (uint64_t)config().getInt64(Key, Default);
}
uint64_t MicroService::ConfigGetInt(const std::string &Key) {
return config().getInt(Key);
uint64_t MicroService::ConfigGetInt(const std::string &Key) { return config().getInt(Key); }
uint64_t MicroService::ConfigGetBool(const std::string &Key, bool Default) {
return config().getBool(Key, Default);
}
uint64_t MicroService::ConfigGetBool(const std::string &Key,bool Default) {
return config().getBool(Key,Default);
}
uint64_t MicroService::ConfigGetBool(const std::string &Key) { return config().getBool(Key); }
uint64_t MicroService::ConfigGetBool(const std::string &Key) {
return config().getBool(Key);
}
std::string MicroService::ConfigGetString(const std::string &Key,const std::string & Default) {
std::string MicroService::ConfigGetString(const std::string &Key, const std::string &Default) {
return config().getString(Key, Default);
}
@@ -589,7 +650,7 @@ namespace OpenWifi {
return config().getString(Key);
}
std::string MicroService::ConfigPath(const std::string &Key,const std::string & Default) {
std::string MicroService::ConfigPath(const std::string &Key, const std::string &Default) {
std::string R = config().getString(Key, Default);
return Poco::Path::expand(R);
}
@@ -600,28 +661,30 @@ namespace OpenWifi {
}
std::string MicroService::Encrypt(const std::string &S) {
if(NoBuiltInCrypto_) {
if (NoBuiltInCrypto_) {
return S;
}
return Cipher_->encryptString(S, Poco::Crypto::Cipher::Cipher::ENC_BASE64);;
return Cipher_->encryptString(S, Poco::Crypto::Cipher::Cipher::ENC_BASE64);
;
}
std::string MicroService::Decrypt(const std::string &S) {
if(NoBuiltInCrypto_) {
if (NoBuiltInCrypto_) {
return S;
}
return Cipher_->decryptString(S, Poco::Crypto::Cipher::Cipher::ENC_BASE64);;
return Cipher_->decryptString(S, Poco::Crypto::Cipher::Cipher::ENC_BASE64);
;
}
std::string MicroService::MakeSystemEventMessage( const std::string & Type ) const {
Poco::JSON::Object Obj;
Obj.set(KafkaTopics::ServiceEvents::Fields::EVENT,Type);
Obj.set(KafkaTopics::ServiceEvents::Fields::ID,ID_);
Obj.set(KafkaTopics::ServiceEvents::Fields::TYPE,Poco::toLower(DAEMON_APP_NAME));
Obj.set(KafkaTopics::ServiceEvents::Fields::PUBLIC,MyPublicEndPoint_);
Obj.set(KafkaTopics::ServiceEvents::Fields::PRIVATE,MyPrivateEndPoint_);
Obj.set(KafkaTopics::ServiceEvents::Fields::KEY,MyHash_);
Obj.set(KafkaTopics::ServiceEvents::Fields::VRSN,Version_);
std::string MicroService::MakeSystemEventMessage(const std::string &Type) const {
Poco::JSON::Object Obj;
Obj.set(KafkaTopics::ServiceEvents::Fields::EVENT, Type);
Obj.set(KafkaTopics::ServiceEvents::Fields::ID, ID_);
Obj.set(KafkaTopics::ServiceEvents::Fields::TYPE, Poco::toLower(DAEMON_APP_NAME));
Obj.set(KafkaTopics::ServiceEvents::Fields::PUBLIC, MyPublicEndPoint_);
Obj.set(KafkaTopics::ServiceEvents::Fields::PRIVATE, MyPrivateEndPoint_);
Obj.set(KafkaTopics::ServiceEvents::Fields::KEY, MyHash_);
Obj.set(KafkaTopics::ServiceEvents::Fields::VRSN, Version_);
std::stringstream ResultText;
Poco::JSON::Stringifier::stringify(Obj, ResultText);
return ResultText.str();
@@ -640,75 +703,73 @@ namespace OpenWifi {
void MicroService::SavePID() {
try {
std::ofstream O;
O.open(MicroService::instance().DataDir() + "/pidfile",std::ios::binary | std::ios::trunc);
O.open(MicroService::instance().DataDir() + "/pidfile",
std::ios::binary | std::ios::trunc);
O << Poco::Process::id();
O.close();
} catch (...)
{
} catch (...) {
std::cout << "Could not save system ID" << std::endl;
}
}
int MicroService::main([[maybe_unused]] const ArgVec &args) {
MicroServiceErrorHandler ErrorHandler(*this);
MicroServiceErrorHandler ErrorHandler(*this);
Poco::ErrorHandler::set(&ErrorHandler);
if (!HelpRequested_) {
SavePID();
Poco::Logger &logger = Poco::Logger::get(DAEMON_APP_NAME);
logger.notice(fmt::format("Starting {} version {}.",DAEMON_APP_NAME, Version()));
logger.notice(fmt::format("Starting {} version {}.", DAEMON_APP_NAME, Version()));
if(Poco::Net::Socket::supportsIPv6())
poco_information(logger,"System supports IPv6.");
if (Poco::Net::Socket::supportsIPv6())
poco_information(logger, "System supports IPv6.");
else
poco_information(logger,"System does NOT support IPv6.");
poco_information(logger, "System does NOT support IPv6.");
if (config().getBool("application.runAsDaemon", false)) {
poco_information(logger,"Starting as a daemon.");
poco_information(logger, "Starting as a daemon.");
}
poco_information(logger,fmt::format("System ID set to {}",ID_));
poco_information(logger, fmt::format("System ID set to {}", ID_));
StartSubSystemServers();
waitForTerminationRequest();
StopSubSystemServers();
logger.notice(fmt::format("Stopped {}...",DAEMON_APP_NAME));
logger.notice(fmt::format("Stopped {}...", DAEMON_APP_NAME));
}
return Application::EXIT_OK;
}
void MicroService::AddActivity(const std::string &Activity) {
if(!DataDir_.empty()) {
std::string ActivityFile{ DataDir_ + "/activity.log"};
if (!DataDir_.empty()) {
std::string ActivityFile{DataDir_ + "/activity.log"};
try {
std::ofstream of(ActivityFile,std::ios_base::app | std::ios_base::out );
std::ofstream of(ActivityFile, std::ios_base::app | std::ios_base::out);
auto t = std::chrono::system_clock::now();
std::time_t now = std::chrono::system_clock::to_time_t(t);
of << Activity << " at " << std::ctime(&now) ;
of << Activity << " at " << std::ctime(&now);
} catch (...) {
}
}
}
[[nodiscard]] std::string MicroService::Sign(Poco::JWT::Token &T, const std::string &Algo) {
if(NoBuiltInCrypto_) {
if (NoBuiltInCrypto_) {
return T.toString();
} else {
return Signer_.sign(T,Algo);
return Signer_.sign(T, Algo);
}
}
void MicroService::DeleteOverrideConfiguration() {
Poco::File F(DataDir_ + ExtraConfigurationFilename);
Poco::File F(DataDir_ + ExtraConfigurationFilename);
try {
if(F.exists())
if (F.exists())
F.remove();
} catch (...) {
}
}
}
} // namespace OpenWifi

View File

@@ -9,12 +9,11 @@
#pragma once
#include <array>
#include <iostream>
#include <vector>
#include <fstream>
#include <random>
#include <ctime>
#include <fstream>
#include <iostream>
#include <random>
#include <vector>
// This must be defined for poco_debug and poco_trace macros to function.
@@ -23,97 +22,94 @@
#endif
namespace OpenWifi {
inline uint64_t Now() { return std::time(nullptr); };
}
inline uint64_t Now() { return std::time(nullptr); };
} // namespace OpenWifi
#include "Poco/Util/Application.h"
#include "Poco/Util/ServerApplication.h"
#include "Poco/Util/Option.h"
#include "Poco/Util/OptionSet.h"
#include "Poco/Crypto/RSAKey.h"
#include "Poco/Crypto/CipherFactory.h"
#include "Poco/AutoPtr.h"
#include "Poco/Crypto/Cipher.h"
#include "Poco/Crypto/CipherFactory.h"
#include "Poco/Crypto/RSAKey.h"
#include "Poco/Environment.h"
#include "Poco/JSON/Object.h"
#include "Poco/JWT/Signer.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "Poco/Process.h"
#include "Poco/Util/Application.h"
#include "Poco/Util/HelpFormatter.h"
#include "Poco/JSON/Object.h"
#include "Poco/AutoPtr.h"
#include "Poco/Util/Option.h"
#include "Poco/Util/OptionSet.h"
#include "Poco/Util/PropertyFileConfiguration.h"
#include "Poco/JWT/Signer.h"
#include "Poco/Environment.h"
#include "Poco/Util/ServerApplication.h"
#include "framework/OpenWifiTypes.h"
#include "framework/EventBusManager.h"
#include "framework/SubSystemServer.h"
#include "framework/ow_constants.h"
#include "framework/utils.h"
#include "framework/SubSystemServer.h"
#include "framework/EventBusManager.h"
#include "RESTObjects/RESTAPI_SecurityObjects.h"
#include "cppkafka/cppkafka.h"
#include "fmt/core.h"
#include "nlohmann/json.hpp"
#include "ow_version.h"
#include "fmt/core.h"
#define _OWDEBUG_ std::cout<< __FILE__ <<":" << __LINE__ << std::endl;
#define _OWDEBUG_ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
// #define _OWDEBUG_ Logger().debug(Poco::format("%s: %lu",__FILE__,__LINE__));
namespace OpenWifi {
class MicroService : public Poco::Util::ServerApplication {
public:
explicit MicroService( std::string PropFile,
std::string RootEnv,
std::string ConfigVar,
std::string AppName,
uint64_t BusTimer,
SubSystemVec Subsystems) :
DAEMON_PROPERTIES_FILENAME(std::move(PropFile)),
DAEMON_ROOT_ENV_VAR(std::move(RootEnv)),
DAEMON_CONFIG_ENV_VAR(std::move(ConfigVar)),
DAEMON_APP_NAME(std::move(AppName)),
DAEMON_BUS_TIMER(BusTimer),
SubSystems_(std::move(Subsystems)),
Logger_(Poco::Logger::get("FRAMEWORK")) {
instance_ = this;
RandomEngine_.seed(std::chrono::steady_clock::now().time_since_epoch().count());
explicit MicroService(std::string PropFile, std::string RootEnv, std::string ConfigVar,
std::string AppName, uint64_t BusTimer, SubSystemVec Subsystems)
: DAEMON_PROPERTIES_FILENAME(std::move(PropFile)),
DAEMON_ROOT_ENV_VAR(std::move(RootEnv)), DAEMON_CONFIG_ENV_VAR(std::move(ConfigVar)),
DAEMON_APP_NAME(std::move(AppName)), DAEMON_BUS_TIMER(BusTimer),
SubSystems_(std::move(Subsystems)), Logger_(Poco::Logger::get("FRAMEWORK")) {
instance_ = this;
RandomEngine_.seed(std::chrono::steady_clock::now().time_since_epoch().count());
// Logger_ = Poco::Logger::root().get("BASE-SVC");
}
inline static const char * ExtraConfigurationFilename = "/configuration_override.json";
inline static const char *ExtraConfigurationFilename = "/configuration_override.json";
inline void SaveConfig() { PropConfigurationFile_->save(ConfigFileName_); }
inline auto UpdateConfig() { return PropConfigurationFile_; }
inline bool NoAPISecurity() const { return NoAPISecurity_; }
inline Poco::ThreadPool & TimerPool() { return TimerPool_; }
inline Poco::ThreadPool &TimerPool() { return TimerPool_; }
[[nodiscard]] std::string Version() { return Version_; }
[[nodiscard]] inline const std::string & DataDir() { return DataDir_; }
[[nodiscard]] inline const std::string & WWWAssetsDir() { return WWWAssetsDir_; }
[[nodiscard]] inline const std::string &DataDir() { return DataDir_; }
[[nodiscard]] inline const std::string &WWWAssetsDir() { return WWWAssetsDir_; }
[[nodiscard]] bool Debug() const { return DebugMode_; }
[[nodiscard]] uint64_t ID() const { return ID_; }
[[nodiscard]] std::string Hash() const { return MyHash_; };
[[nodiscard]] std::string ServiceType() const { return DAEMON_APP_NAME; };
[[nodiscard]] std::string PrivateEndPoint() const { return MyPrivateEndPoint_; };
[[nodiscard]] std::string PublicEndPoint() const { return MyPublicEndPoint_; };
[[nodiscard]] const SubSystemVec & GetFullSubSystems() { return SubSystems_; }
[[nodiscard]] const SubSystemVec &GetFullSubSystems() { return SubSystems_; }
inline uint64_t DaemonBusTimer() const { return DAEMON_BUS_TIMER; };
[[nodiscard]] const std::string & AppName() { return DAEMON_APP_NAME; }
[[nodiscard]] const std::string &AppName() { return DAEMON_APP_NAME; }
static inline uint64_t GetPID() { return Poco::Process::id(); };
[[nodiscard]] inline const std::string GetPublicAPIEndPoint() { return MyPublicEndPoint_ + "/api/v1"; };
[[nodiscard]] inline const std::string & GetUIURI() const { return UIURI_;};
[[nodiscard]] inline uint64_t Random(uint64_t ceiling) { return (RandomEngine_() % ceiling); }
[[nodiscard]] inline uint64_t Random(uint64_t min, uint64_t max) {
return ((RandomEngine_() % (max-min)) + min);
[[nodiscard]] inline const std::string GetPublicAPIEndPoint() {
return MyPublicEndPoint_ + "/api/v1";
};
[[nodiscard]] inline const std::string &GetUIURI() const { return UIURI_; };
[[nodiscard]] inline uint64_t Random(uint64_t ceiling) {
return (RandomEngine_() % ceiling);
}
virtual void GetExtraConfiguration(Poco::JSON::Object & Cfg) {
Cfg.set("additionalConfiguration",false);
}
static MicroService & instance() { return *instance_; }
[[nodiscard]] inline uint64_t Random(uint64_t min, uint64_t max) {
return ((RandomEngine_() % (max - min)) + min);
}
virtual void GetExtraConfiguration(Poco::JSON::Object &Cfg) {
Cfg.set("additionalConfiguration", false);
}
static MicroService &instance() { return *instance_; }
inline void Exit(int Reason);
void BusMessageReceived(const std::string &Key, const std::string & Payload);
Types::MicroServiceMetaVec GetServices(const std::string & Type);
inline void Exit(int Reason);
void BusMessageReceived(const std::string &Key, const std::string &Payload);
Types::MicroServiceMetaVec GetServices(const std::string &Type);
Types::MicroServiceMetaVec GetServices();
void LoadConfigurationFile();
void Reload();
@@ -136,71 +132,78 @@ namespace OpenWifi {
void Reload(const std::string &Sub);
Types::StringVec GetSubSystems() const;
Types::StringPairVec GetLogLevels();
const Types::StringVec & GetLogLevelNames();
uint64_t ConfigGetInt(const std::string &Key,uint64_t Default);
const Types::StringVec &GetLogLevelNames();
uint64_t ConfigGetInt(const std::string &Key, uint64_t Default);
uint64_t ConfigGetInt(const std::string &Key);
uint64_t ConfigGetBool(const std::string &Key,bool Default);
uint64_t ConfigGetBool(const std::string &Key, bool Default);
uint64_t ConfigGetBool(const std::string &Key);
std::string ConfigGetString(const std::string &Key,const std::string & Default);
std::string ConfigGetString(const std::string &Key, const std::string &Default);
std::string ConfigGetString(const std::string &Key);
std::string ConfigPath(const std::string &Key,const std::string & Default);
std::string ConfigPath(const std::string &Key, const std::string &Default);
std::string ConfigPath(const std::string &Key);
std::string Encrypt(const std::string &S);
std::string Decrypt(const std::string &S);
std::string MakeSystemEventMessage( const std::string & Type ) const;
std::string MakeSystemEventMessage(const std::string &Type) const;
[[nodiscard]] bool IsValidAPIKEY(const Poco::Net::HTTPServerRequest &Request);
static void SavePID();
int main(const ArgVec &args) override;
void InitializeLoggingSystem();
void InitializeLoggingSystem();
void DeleteOverrideConfiguration();
[[nodiscard]] std::string Sign(Poco::JWT::Token &T, const std::string &Algo);
void AddActivity(const std::string &Activity);
static void SetConsoleLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern);
static void SetColorConsoleLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern);
static void SetSQLLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern);
static void SetSyslogLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern);
static void SetFileLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern, const std::string & root_env_var);
inline bool AllowExternalMicroServices() const { return AllowExternalMicroServices_; }
static void SetConsoleLogs(bool UseAsync, bool AllowWebSocket,
const std::string &FormatterPattern);
static void SetColorConsoleLogs(bool UseAsync, bool AllowWebSocket,
const std::string &FormatterPattern);
static void SetSQLLogs(bool UseAsync, bool AllowWebSocket,
const std::string &FormatterPattern);
static void SetSyslogLogs(bool UseAsync, bool AllowWebSocket,
const std::string &FormatterPattern);
static void SetFileLogs(bool UseAsync, bool AllowWebSocket,
const std::string &FormatterPattern,
const std::string &root_env_var);
inline bool AllowExternalMicroServices() const { return AllowExternalMicroServices_; }
private:
static MicroService * instance_;
bool HelpRequested_ = false;
std::string LogDir_;
std::string ConfigFileName_;
uint64_t ID_ = 1;
Poco::SharedPtr<Poco::Crypto::RSAKey> AppKey_;
bool DebugMode_ = false;
std::string DataDir_;
std::string WWWAssetsDir_;
Poco::Crypto::CipherFactory & CipherFactory_ = Poco::Crypto::CipherFactory::defaultFactory();
Poco::Crypto::Cipher * Cipher_ = nullptr;
Types::MicroServiceMetaMap Services_;
std::string MyHash_;
std::string MyPrivateEndPoint_;
std::string MyPublicEndPoint_;
std::string UIURI_;
std::string Version_{ OW_VERSION::VERSION + "("+ OW_VERSION::BUILD + ")" + " - " + OW_VERSION::HASH };
std::recursive_mutex InfraMutex_;
std::default_random_engine RandomEngine_;
Poco::Util::PropertyFileConfiguration * PropConfigurationFile_ = nullptr;
std::string DAEMON_PROPERTIES_FILENAME;
std::string DAEMON_ROOT_ENV_VAR;
std::string DAEMON_CONFIG_ENV_VAR;
std::string DAEMON_APP_NAME;
uint64_t DAEMON_BUS_TIMER;
SubSystemVec SubSystems_;
bool NoAPISecurity_=false;
bool NoBuiltInCrypto_=false;
bool AllowExternalMicroServices_=false;
Poco::JWT::Signer Signer_;
Poco::Logger &Logger_;
Poco::ThreadPool TimerPool_{"timer:pool",2,32};
std::unique_ptr<EventBusManager> EventBusManager_;
};
static MicroService *instance_;
bool HelpRequested_ = false;
std::string LogDir_;
std::string ConfigFileName_;
uint64_t ID_ = 1;
Poco::SharedPtr<Poco::Crypto::RSAKey> AppKey_;
bool DebugMode_ = false;
std::string DataDir_;
std::string WWWAssetsDir_;
Poco::Crypto::CipherFactory &CipherFactory_ = Poco::Crypto::CipherFactory::defaultFactory();
Poco::Crypto::Cipher *Cipher_ = nullptr;
Types::MicroServiceMetaMap Services_;
std::string MyHash_;
std::string MyPrivateEndPoint_;
std::string MyPublicEndPoint_;
std::string UIURI_;
std::string Version_{OW_VERSION::VERSION + "(" + OW_VERSION::BUILD + ")" + " - " +
OW_VERSION::HASH};
std::recursive_mutex InfraMutex_;
std::default_random_engine RandomEngine_;
Poco::Util::PropertyFileConfiguration *PropConfigurationFile_ = nullptr;
std::string DAEMON_PROPERTIES_FILENAME;
std::string DAEMON_ROOT_ENV_VAR;
std::string DAEMON_CONFIG_ENV_VAR;
std::string DAEMON_APP_NAME;
uint64_t DAEMON_BUS_TIMER;
SubSystemVec SubSystems_;
bool NoAPISecurity_ = false;
bool NoBuiltInCrypto_ = false;
bool AllowExternalMicroServices_ = false;
Poco::JWT::Signer Signer_;
Poco::Logger &Logger_;
Poco::ThreadPool TimerPool_{"timer:pool", 2, 32};
std::unique_ptr<EventBusManager> EventBusManager_;
};
inline MicroService * MicroService::instance_ = nullptr;
inline MicroService *MicroService::instance_ = nullptr;
}
} // namespace OpenWifi

View File

@@ -4,25 +4,24 @@
#pragma once
#include "fmt/format.h"
#include "Poco/Util/Application.h"
#include "Poco/ErrorHandler.h"
#include "Poco/JSON/JSONException.h"
#include "Poco/JSON/Template.h"
#include "Poco/Net/NetException.h"
#include "Poco/Net/SSLException.h"
#include "Poco/JSON/Template.h"
#include "Poco/JSON/JSONException.h"
#include "Poco/Thread.h"
#include "Poco/Util/Application.h"
#include "fmt/format.h"
namespace OpenWifi {
class MicroServiceErrorHandler : public Poco::ErrorHandler {
public:
explicit MicroServiceErrorHandler(Poco::Util::Application &App) : App_(App) {
}
explicit MicroServiceErrorHandler(Poco::Util::Application &App) : App_(App) {}
inline void exception(const Poco::Exception & Base) override {
inline void exception(const Poco::Exception &Base) override {
try {
if(Poco::Thread::current()!= nullptr) {
if (Poco::Thread::current() != nullptr) {
t_name = Poco::Thread::current()->getName();
t_id = Poco::Thread::current()->id();
} else {
@@ -34,179 +33,167 @@ namespace OpenWifi {
Base.rethrow();
} catch (const Poco::Net::InvalidCertificateException &E) {
poco_error(App_.logger(), fmt::format("Poco::Net::InvalidCertificateException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(App_.logger(),
fmt::format("Poco::Net::InvalidCertificateException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(), E.message(),
E.what()));
} catch (const Poco::Net::InvalidSocketException &E) {
poco_error(App_.logger(), fmt::format("Poco::Net::InvalidSocketException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(App_.logger(),
fmt::format("Poco::Net::InvalidSocketException thr_name={} thr_id={} "
"code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(), E.message(),
E.what()));
} catch (const Poco::Net::WebSocketException &E) {
poco_error(App_.logger(), fmt::format("Poco::Net::WebSocketException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(App_.logger(), fmt::format("Poco::Net::WebSocketException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
} catch (const Poco::Net::ConnectionResetException &E) {
poco_error(App_.logger(), fmt::format("Poco::Net::ConnectionResetException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(App_.logger(),
fmt::format("Poco::Net::ConnectionResetException thr_name={} thr_id={} "
"code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(), E.message(),
E.what()));
} catch (const Poco::Net::CertificateValidationException &E) {
poco_error(App_.logger(), fmt::format("Poco::Net::CertificateValidationException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(App_.logger(),
fmt::format("Poco::Net::CertificateValidationException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(), E.message(),
E.what()));
} catch (const Poco::Net::SSLConnectionUnexpectedlyClosedException &E) {
poco_error(App_.logger(), fmt::format("Poco::Net::SSLConnectionUnexpectedlyClosedException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(App_.logger(),
fmt::format("Poco::Net::SSLConnectionUnexpectedlyClosedException "
"thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(), E.message(),
E.what()));
} catch (const Poco::Net::SSLContextException &E) {
poco_error(App_.logger(), fmt::format("Poco::Net::SSLContextException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(App_.logger(), fmt::format("Poco::Net::SSLContextException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
} catch (const Poco::Net::SSLException &E) {
poco_error(App_.logger(), fmt::format("Poco::Net::SSLException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(App_.logger(), fmt::format("Poco::Net::SSLException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
} catch (const Poco::Net::InvalidAddressException &E) {
poco_error(App_.logger(), fmt::format("Poco::Net::InvalidAddressException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(App_.logger(),
fmt::format("Poco::Net::InvalidAddressException thr_name={} thr_id={} "
"code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(), E.message(),
E.what()));
} catch (const Poco::Net::NetException &E) {
poco_error(App_.logger(), fmt::format("Poco::Net::NetException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(App_.logger(), fmt::format("Poco::Net::NetException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
} catch (const Poco::IOException &E) {
poco_error(App_.logger(), fmt::format("Poco::IOException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(
App_.logger(),
fmt::format(
"Poco::IOException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(), E.message(), E.what()));
} catch (const Poco::TimeoutException &E) {
poco_error(App_.logger(), fmt::format("Poco::TimeoutException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(App_.logger(), fmt::format("Poco::TimeoutException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
} catch (const Poco::NoThreadAvailableException &E) {
poco_error(App_.logger(), fmt::format("Poco::NoThreadAvailableException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(App_.logger(),
fmt::format("Poco::NoThreadAvailableException thr_name={} thr_id={} "
"code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(), E.message(),
E.what()));
} catch (const Poco::OutOfMemoryException &E) {
poco_error(App_.logger(), fmt::format("Poco::OutOfMemoryException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(App_.logger(), fmt::format("Poco::OutOfMemoryException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
} catch (const Poco::BadCastException &E) {
poco_error(App_.logger(), fmt::format("Poco::BadCastException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(App_.logger(), fmt::format("Poco::BadCastException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
} catch (const Poco::DataException &E) {
poco_error(App_.logger(), fmt::format("Poco::DataException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(
App_.logger(),
fmt::format(
"Poco::DataException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(), E.message(), E.what()));
} catch (const Poco::PoolOverflowException &E) {
poco_error(App_.logger(), fmt::format("Poco::PoolOverflowException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(App_.logger(), fmt::format("Poco::PoolOverflowException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
} catch (const Poco::SystemException &E) {
poco_error(App_.logger(), fmt::format("Poco::SystemException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(App_.logger(), fmt::format("Poco::SystemException thr_name={} thr_id={} "
"code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
} catch (const Poco::RuntimeException &E) {
poco_error(App_.logger(), fmt::format("Poco::RuntimeException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(App_.logger(), fmt::format("Poco::RuntimeException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
} catch (const Poco::JSON::JSONTemplateException &E) {
poco_error(App_.logger(), fmt::format("Poco::JSON::JSONTemplateException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(App_.logger(),
fmt::format("Poco::JSON::JSONTemplateException thr_name={} thr_id={} "
"code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(), E.message(),
E.what()));
} catch (const Poco::JSON::JSONException &E) {
poco_error(App_.logger(), fmt::format("Poco::JSON::JSONException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(App_.logger(), fmt::format("Poco::JSON::JSONException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
} catch (const Poco::ApplicationException &E) {
poco_error(App_.logger(), fmt::format("Poco::ApplicationException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(App_.logger(), fmt::format("Poco::ApplicationException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
} catch (const Poco::Exception &E) {
poco_error(App_.logger(), fmt::format("Poco::Exception thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(
App_.logger(),
fmt::format(
"Poco::Exception thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(), E.message(), E.what()));
} catch (...) {
poco_error(App_.logger(), fmt::format("Poco:Generic thr_name={}",t_name, t_id));
poco_error(App_.logger(), fmt::format("Poco:Generic thr_name={}", t_name, t_id));
}
}
inline void exception(const std::exception & E) override {
if(Poco::Thread::current()!= nullptr) {
inline void exception(const std::exception &E) override {
if (Poco::Thread::current() != nullptr) {
t_name = Poco::Thread::current()->getName();
t_id = Poco::Thread::current()->id();
} else {
t_name = "startup_code";
t_id = 0;
}
poco_warning(App_.logger(), fmt::format("std::exception in {}: {} thr_id={}",
t_name,E.what(),
t_id));
poco_warning(App_.logger(),
fmt::format("std::exception in {}: {} thr_id={}", t_name, E.what(), t_id));
}
inline void exception() override {
if(Poco::Thread::current()!= nullptr) {
if (Poco::Thread::current() != nullptr) {
t_name = Poco::Thread::current()->getName();
t_id = Poco::Thread::current()->id();
} else {
t_name = "startup_code";
t_id = 0;
}
poco_warning(App_.logger(), fmt::format("generic exception in {} thr_id={}",
t_name, t_id));
poco_warning(App_.logger(),
fmt::format("generic exception in {} thr_id={}", t_name, t_id));
}
private:
Poco::Util::Application &App_;
std::string t_name;
int t_id=0;
Poco::Util::Application &App_;
std::string t_name;
int t_id = 0;
};
}
} // namespace OpenWifi

View File

@@ -4,8 +4,8 @@
#pragma once
#include <string>
#include <map>
#include <string>
#include "Poco/BasicEvent.h"
#include "Poco/ExpireLRUCache.h"
@@ -13,46 +13,40 @@
namespace OpenWifi {
class ConfigurationEntry {
public:
template <typename T> explicit ConfigurationEntry(T def) :
Default_(def),
Current_(def){
template <typename T> explicit ConfigurationEntry(T def) : Default_(def), Current_(def) {}
template <typename T>
explicit ConfigurationEntry(T def, T cur, const std::string &Hint = "")
: Default_(def), Current_(cur), Hint_(Hint) {}
inline ConfigurationEntry() = default;
inline ~ConfigurationEntry() = default;
template <typename T> explicit operator T() const { return std::get<T>(Current_); }
inline ConfigurationEntry &operator=(const char *v) {
Current_ = std::string(v);
return *this;
}
template <typename T> ConfigurationEntry &operator=(T v) {
Current_ = (T)v;
return *this;
}
template <typename T> explicit ConfigurationEntry(T def, T cur, const std::string &Hint="") :
Default_(def),
Current_(cur),
Hint_(Hint){
}
inline ConfigurationEntry()=default;
inline ~ConfigurationEntry()=default;
template <typename T> explicit operator T () const { return std::get<T>(Current_); }
inline ConfigurationEntry & operator=(const char *v) { Current_ = std::string(v); return *this;}
template <typename T> ConfigurationEntry & operator=(T v) { Current_ = (T) v; return *this;}
void reset() {
Current_ = Default_;
}
void reset() { Current_ = Default_; }
private:
std::variant<bool,uint64_t,std::string> Default_, Current_;
std::variant<bool, uint64_t, std::string> Default_, Current_;
std::string Hint_;
};
inline std::string to_string(const ConfigurationEntry &v) { return (std::string) v; }
inline std::string to_string(const ConfigurationEntry &v) { return (std::string)v; }
typedef std::map<std::string,ConfigurationEntry> ConfigurationMap_t;
typedef std::map<std::string, ConfigurationEntry> ConfigurationMap_t;
template <typename T> class FIFO {
public:
explicit FIFO(uint32_t Size) :
Size_(Size) {
Buffer_ = new T [Size_];
}
explicit FIFO(uint32_t Size) : Size_(Size) { Buffer_ = new T[Size_]; }
~FIFO() {
delete [] Buffer_;
}
~FIFO() { delete[] Buffer_; }
mutable Poco::BasicEvent<bool> Writable_;
mutable Poco::BasicEvent<bool> Readable_;
@@ -84,7 +78,7 @@ namespace OpenWifi {
Write_ = 0;
}
Used_++;
MaxEverUsed_ = std::max(Used_,MaxEverUsed_);
MaxEverUsed_ = std::max(Used_, MaxEverUsed_);
}
bool flag = true;
Readable_.notify(this, flag);
@@ -93,40 +87,32 @@ namespace OpenWifi {
inline bool isFull() {
std::lock_guard M(Mutex_);
return Used_==Buffer_->capacity();
return Used_ == Buffer_->capacity();
}
inline auto MaxEverUser() const { return MaxEverUsed_; }
private:
std::recursive_mutex Mutex_;
uint32_t Size_=0;
uint32_t Read_=0;
uint32_t Write_=0;
uint32_t Used_=0;
uint32_t MaxEverUsed_=0;
T * Buffer_ = nullptr;
std::recursive_mutex Mutex_;
uint32_t Size_ = 0;
uint32_t Read_ = 0;
uint32_t Write_ = 0;
uint32_t Used_ = 0;
uint32_t MaxEverUsed_ = 0;
T *Buffer_ = nullptr;
};
template <class Record, typename KeyType = std::string, int Size=256, int Expiry=60000> class RecordCache {
template <class Record, typename KeyType = std::string, int Size = 256, int Expiry = 60000>
class RecordCache {
public:
explicit RecordCache( KeyType Record::* Q) :
MemberOffset(Q){
};
inline auto update(const Record &R) {
return Cache_.update(R.*MemberOffset, R);
}
inline auto get(const KeyType &K) {
return Cache_.get(K);
}
inline auto remove(const KeyType &K) {
return Cache_.remove(K);
}
inline auto remove(const Record &R) {
return Cache_.remove(R.*MemberOffset);
}
explicit RecordCache(KeyType Record::*Q) : MemberOffset(Q){};
inline auto update(const Record &R) { return Cache_.update(R.*MemberOffset, R); }
inline auto get(const KeyType &K) { return Cache_.get(K); }
inline auto remove(const KeyType &K) { return Cache_.remove(K); }
inline auto remove(const Record &R) { return Cache_.remove(R.*MemberOffset); }
private:
KeyType Record::* MemberOffset;
Poco::ExpireLRUCache<KeyType,Record> Cache_{Size,Expiry};
KeyType Record::*MemberOffset;
Poco::ExpireLRUCache<KeyType, Record> Cache_{Size, Expiry};
};
}
} // namespace OpenWifi

View File

@@ -2,125 +2,125 @@
// Created by stephane bourque on 2022-10-25.
//
#include "framework/MicroService.h"
#include "framework/MicroServiceFuncs.h"
#include "framework/MicroService.h"
namespace OpenWifi {
const std::string &MicroServiceDataDirectory() { return MicroService::instance().DataDir(); }
const std::string &MicroServiceDataDirectory() { return MicroService::instance().DataDir(); }
Types::MicroServiceMetaVec MicroServiceGetServices(const std::string &Type) {
return MicroService::instance().GetServices(Type);
}
Types::MicroServiceMetaVec MicroServiceGetServices(const std::string &Type) {
return MicroService::instance().GetServices(Type);
}
Types::MicroServiceMetaVec MicroServiceGetServices() {
return MicroService::instance().GetServices();
}
Types::MicroServiceMetaVec MicroServiceGetServices() {
return MicroService::instance().GetServices();
}
std::string MicroServicePublicEndPoint() { return MicroService::instance().PublicEndPoint(); }
std::string MicroServicePublicEndPoint() { return MicroService::instance().PublicEndPoint(); }
std::string MicroServiceConfigGetString(const std::string &Key, const std::string &DefaultValue) {
return MicroService::instance().ConfigGetString(Key, DefaultValue);
}
std::string MicroServiceConfigGetString(const std::string &Key,
const std::string &DefaultValue) {
return MicroService::instance().ConfigGetString(Key, DefaultValue);
}
bool MicroServiceConfigGetBool(const std::string &Key, bool DefaultValue) {
return MicroService::instance().ConfigGetBool(Key, DefaultValue);
}
bool MicroServiceConfigGetBool(const std::string &Key, bool DefaultValue) {
return MicroService::instance().ConfigGetBool(Key, DefaultValue);
}
std::uint64_t MicroServiceConfigGetInt(const std::string &Key, std::uint64_t DefaultValue) {
return MicroService::instance().ConfigGetInt(Key, DefaultValue);
}
std::uint64_t MicroServiceConfigGetInt(const std::string &Key, std::uint64_t DefaultValue) {
return MicroService::instance().ConfigGetInt(Key, DefaultValue);
}
std::string MicroServicePrivateEndPoint() { return MicroService::instance().PrivateEndPoint(); }
std::string MicroServicePrivateEndPoint() { return MicroService::instance().PrivateEndPoint(); }
std::uint64_t MicroServiceID() { return MicroService::instance().ID(); }
std::uint64_t MicroServiceID() { return MicroService::instance().ID(); }
bool MicroServiceIsValidAPIKEY(const Poco::Net::HTTPServerRequest &Request) {
return MicroService::instance().IsValidAPIKEY(Request);
}
bool MicroServiceIsValidAPIKEY(const Poco::Net::HTTPServerRequest &Request) {
return MicroService::instance().IsValidAPIKEY(Request);
}
bool MicroServiceNoAPISecurity() { return MicroService::instance().NoAPISecurity(); }
bool MicroServiceNoAPISecurity() { return MicroService::instance().NoAPISecurity(); }
void MicroServiceLoadConfigurationFile() { MicroService::instance().LoadConfigurationFile(); }
void MicroServiceLoadConfigurationFile() { MicroService::instance().LoadConfigurationFile(); }
void MicroServiceReload() { MicroService::instance().Reload(); }
void MicroServiceReload() { MicroService::instance().Reload(); }
void MicroServiceReload(const std::string &Type) { MicroService::instance().Reload(Type); }
void MicroServiceReload(const std::string &Type) { MicroService::instance().Reload(Type); }
const Types::StringVec MicroServiceGetLogLevelNames() {
return MicroService::instance().GetLogLevelNames();
}
Types::StringVec MicroServiceGetLogLevelNames() {
return MicroService::instance().GetLogLevelNames();
}
const Types::StringVec MicroServiceGetSubSystems() {
return MicroService::instance().GetSubSystems();
}
Types::StringVec MicroServiceGetSubSystems() {
return MicroService::instance().GetSubSystems();
}
Types::StringPairVec MicroServiceGetLogLevels() { return MicroService::instance().GetLogLevels(); }
Types::StringPairVec MicroServiceGetLogLevels() {
return MicroService::instance().GetLogLevels();
}
bool MicroServiceSetSubsystemLogLevel(const std::string &SubSystem, const std::string &Level) {
return MicroService::instance().SetSubsystemLogLevel(SubSystem, Level);
}
bool MicroServiceSetSubsystemLogLevel(const std::string &SubSystem, const std::string &Level) {
return MicroService::instance().SetSubsystemLogLevel(SubSystem, Level);
}
void MicroServiceGetExtraConfiguration(Poco::JSON::Object &Answer) {
MicroService::instance().GetExtraConfiguration(Answer);
}
void MicroServiceGetExtraConfiguration(Poco::JSON::Object &Answer) {
MicroService::instance().GetExtraConfiguration(Answer);
}
std::string MicroServiceVersion() { return MicroService::instance().Version(); }
std::string MicroServiceVersion() { return MicroService::instance().Version(); }
std::uint64_t MicroServiceUptimeTotalSeconds() {
return MicroService::instance().uptime().totalSeconds();
}
std::uint64_t MicroServiceUptimeTotalSeconds() {
return MicroService::instance().uptime().totalSeconds();
}
std::uint64_t MicroServiceStartTimeEpochTime() {
return MicroService::instance().startTime().epochTime();
}
std::uint64_t MicroServiceStartTimeEpochTime() {
return MicroService::instance().startTime().epochTime();
}
std::string MicroServiceGetUIURI() { return MicroService::instance().GetUIURI(); }
std::string MicroServiceGetUIURI() { return MicroService::instance().GetUIURI(); }
const SubSystemVec MicroServiceGetFullSubSystems() {
return MicroService::instance().GetFullSubSystems();
}
SubSystemVec MicroServiceGetFullSubSystems() {
return MicroService::instance().GetFullSubSystems();
}
std::string MicroServiceCreateUUID() { return MicroService::CreateUUID(); }
std::string MicroServiceCreateUUID() { return MicroService::CreateUUID(); }
std::uint64_t MicroServiceDaemonBusTimer() { return MicroService::instance().DaemonBusTimer(); }
std::uint64_t MicroServiceDaemonBusTimer() { return MicroService::instance().DaemonBusTimer(); }
std::string MicroServiceMakeSystemEventMessage(const std::string &Type) {
return MicroService::instance().MakeSystemEventMessage(Type);
}
std::string MicroServiceMakeSystemEventMessage(const char *Type) {
return MicroService::instance().MakeSystemEventMessage(Type);
}
Poco::ThreadPool &MicroServiceTimerPool() { return MicroService::instance().TimerPool(); }
Poco::ThreadPool &MicroServiceTimerPool() { return MicroService::instance().TimerPool(); }
std::string MicroServiceConfigPath(const std::string &Key,
const std::string &DefaultValue) {
return MicroService::instance().ConfigPath(Key, DefaultValue);
}
std::string MicroServiceConfigPath(const std::string &Key, const std::string &DefaultValue) {
return MicroService::instance().ConfigPath(Key, DefaultValue);
}
std::string MicroServiceWWWAssetsDir() {
return MicroService::instance().WWWAssetsDir();
}
std::string MicroServiceWWWAssetsDir() { return MicroService::instance().WWWAssetsDir(); }
std::uint64_t MicroServiceRandom(std::uint64_t Start,std::uint64_t End) {
return MicroService::instance().Random(Start, End);
}
std::uint64_t MicroServiceRandom(std::uint64_t Start, std::uint64_t End) {
return MicroService::instance().Random(Start, End);
}
std::uint64_t MicroServiceRandom(std::uint64_t Range) {
return MicroService::instance().Random(Range);
}
std::uint64_t MicroServiceRandom(std::uint64_t Range) {
return MicroService::instance().Random(Range);
}
std::string MicroServiceSign(Poco::JWT::Token &T, const std::string &Algo) {
return MicroService::instance().Sign(T, Algo);
}
std::string MicroServiceSign(Poco::JWT::Token &T, const std::string &Algo) {
return MicroService::instance().Sign(T, Algo);
}
std::string MicroServiceGetPublicAPIEndPoint() {
return MicroService::instance().GetPublicAPIEndPoint();
}
std::string MicroServiceGetPublicAPIEndPoint() {
return MicroService::instance().GetPublicAPIEndPoint();
}
void MicroServiceDeleteOverrideConfiguration() {
return MicroService::instance().DeleteOverrideConfiguration();
}
bool AllowExternalMicroServices() {
return MicroService::instance().AllowExternalMicroServices();
}
bool AllowExternalMicroServices() {
return MicroService::instance().AllowExternalMicroServices();
}
}
} // namespace OpenWifi

View File

@@ -8,20 +8,20 @@
#include "framework/OpenWifiTypes.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "Poco/JSON/Object.h"
#include "Poco/ThreadPool.h"
#include "Poco/JWT/Token.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "Poco/ThreadPool.h"
namespace OpenWifi {
class SubSystemServer;
using SubSystemVec=std::vector<SubSystemServer *>;
const std::string & MicroServiceDataDirectory();
Types::MicroServiceMetaVec MicroServiceGetServices(const std::string & Type);
Types::MicroServiceMetaVec MicroServiceGetServices();
using SubSystemVec = std::vector<SubSystemServer *>;
const std::string &MicroServiceDataDirectory();
Types::MicroServiceMetaVec MicroServiceGetServices(const std::string &Type);
Types::MicroServiceMetaVec MicroServiceGetServices();
std::string MicroServicePublicEndPoint();
std::string MicroServiceConfigGetString(const std::string &Key, const std::string &DefaultValue);
std::string MicroServiceConfigGetString(const std::string &Key,
const std::string &DefaultValue);
bool MicroServiceConfigGetBool(const std::string &Key, bool DefaultValue);
std::uint64_t MicroServiceConfigGetInt(const std::string &Key, std::uint64_t DefaultValue);
std::string MicroServicePrivateEndPoint();
@@ -31,8 +31,8 @@ namespace OpenWifi {
void MicroServiceLoadConfigurationFile();
void MicroServiceReload();
void MicroServiceReload(const std::string &Type);
const Types::StringVec MicroServiceGetLogLevelNames();
const Types::StringVec MicroServiceGetSubSystems();
Types::StringVec MicroServiceGetLogLevelNames();
Types::StringVec MicroServiceGetSubSystems();
Types::StringPairVec MicroServiceGetLogLevels();
bool MicroServiceSetSubsystemLogLevel(const std::string &SubSystem, const std::string &Level);
void MicroServiceGetExtraConfiguration(Poco::JSON::Object &Answer);
@@ -40,18 +40,17 @@ namespace OpenWifi {
std::uint64_t MicroServiceUptimeTotalSeconds();
std::uint64_t MicroServiceStartTimeEpochTime();
std::string MicroServiceGetUIURI();
const SubSystemVec MicroServiceGetFullSubSystems();
SubSystemVec MicroServiceGetFullSubSystems();
std::string MicroServiceCreateUUID();
std::uint64_t MicroServiceDaemonBusTimer();
std::string MicroServiceMakeSystemEventMessage( const std::string & Type );
Poco::ThreadPool & MicroServiceTimerPool();
std::string MicroServiceConfigPath(const std::string &Key,
const std::string &DefaultValue);
std::string MicroServiceWWWAssetsDir();
std::uint64_t MicroServiceRandom(std::uint64_t Start,std::uint64_t End);
std::uint64_t MicroServiceRandom(std::uint64_t Range);
std::string MicroServiceSign(Poco::JWT::Token &T, const std::string &Algo);
std::string MicroServiceGetPublicAPIEndPoint();
std::string MicroServiceMakeSystemEventMessage(const char *Type);
Poco::ThreadPool &MicroServiceTimerPool();
std::string MicroServiceConfigPath(const std::string &Key, const std::string &DefaultValue);
std::string MicroServiceWWWAssetsDir();
std::uint64_t MicroServiceRandom(std::uint64_t Start, std::uint64_t End);
std::uint64_t MicroServiceRandom(std::uint64_t Range);
std::string MicroServiceSign(Poco::JWT::Token &T, const std::string &Algo);
std::string MicroServiceGetPublicAPIEndPoint();
void MicroServiceDeleteOverrideConfiguration();
bool AllowExternalMicroServices();
}
bool AllowExternalMicroServices();
} // namespace OpenWifi

View File

@@ -10,13 +10,13 @@ namespace OpenWifi {
static const std::string uSERVICE_SECURITY{"owsec"};
static const std::string uSERVICE_GATEWAY{"owgw"};
static const std::string uSERVICE_FIRMWARE{ "owfms"};
static const std::string uSERVICE_TOPOLOGY{ "owtopo"};
static const std::string uSERVICE_PROVISIONING{ "owprov"};
static const std::string uSERVICE_OWLS{ "owls"};
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"};
static const std::string uSERVICE_FIRMWARE{"owfms"};
static const std::string uSERVICE_TOPOLOGY{"owtopo"};
static const std::string uSERVICE_PROVISIONING{"owprov"};
static const std::string uSERVICE_OWLS{"owls"};
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"};
}
} // namespace OpenWifi

View File

@@ -4,286 +4,281 @@
#include "OpenAPIRequests.h"
#include "Poco/JSON/Parser.h"
#include "Poco/Logger.h"
#include "Poco/URI.h"
#include "Poco/Net/HTTPRequest.h"
#include "Poco/Net/HTTPSClientSession.h"
#include "Poco/JSON/Parser.h"
#include "Poco/URI.h"
#include "fmt/format.h"
#include "framework/MicroServiceFuncs.h"
namespace OpenWifi {
Poco::Net::HTTPServerResponse::HTTPStatus OpenAPIRequestGet::Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken) {
try {
Poco::Net::HTTPServerResponse::HTTPStatus
OpenAPIRequestGet::Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string &BearerToken) {
try {
auto Services = MicroServiceGetServices(Type_);
for(auto const &Svc:Services) {
Poco::URI URI(Svc.PrivateEndPoint);
auto Services = MicroServiceGetServices(Type_);
for (auto const &Svc : Services) {
Poco::URI URI(Svc.PrivateEndPoint);
auto Secure = (URI.getScheme() == "https");
auto Secure = (URI.getScheme() == "https");
URI.setPath(EndPoint_);
for (const auto &qp : QueryData_)
URI.addQueryParameter(qp.first, qp.second);
URI.setPath(EndPoint_);
for (const auto &qp : QueryData_)
URI.addQueryParameter(qp.first, qp.second);
std::string Path(URI.getPathAndQuery());
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_GET,
Path,
Poco::Net::HTTPMessage::HTTP_1_1);
std::string Path(URI.getPathAndQuery());
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_GET, Path,
Poco::Net::HTTPMessage::HTTP_1_1);
poco_debug(Poco::Logger::get("REST-CALLER-GET"), fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_ ) );
poco_debug(Poco::Logger::get("REST-CALLER-GET"),
fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_));
if(BearerToken.empty()) {
Request.add("X-API-KEY", Svc.AccessKey);
Request.add("X-INTERNAL-NAME", MicroServicePublicEndPoint());
} else {
// Authorization: Bearer ${token}
Request.add("Authorization", "Bearer " + BearerToken);
}
if(Secure) {
Poco::Net::HTTPSClientSession Session(URI.getHost(), URI.getPort());
Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000));
Session.sendRequest(Request);
Poco::Net::HTTPResponse Response;
std::istream &is = Session.receiveResponse(Response);
if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) {
Poco::JSON::Parser P;
ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
}
return Response.getStatus();
} else {
Poco::Net::HTTPClientSession Session(URI.getHost(), URI.getPort());
Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000));
Session.sendRequest(Request);
Poco::Net::HTTPResponse Response;
std::istream &is = Session.receiveResponse(Response);
if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) {
Poco::JSON::Parser P;
ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
}
return Response.getStatus();
}
}
}
catch (const Poco::Exception &E)
{
Poco::Logger::get("REST-CALLER-GET").log(E);
}
return Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT;
}
Poco::Net::HTTPServerResponse::HTTPStatus OpenAPIRequestPut::Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken) {
try {
auto Services = MicroServiceGetServices(Type_);
for(auto const &Svc:Services) {
Poco::URI URI(Svc.PrivateEndPoint);
auto Secure = (URI.getScheme() == "https");
URI.setPath(EndPoint_);
for (const auto &qp : QueryData_)
URI.addQueryParameter(qp.first, qp.second);
poco_debug(Poco::Logger::get("REST-CALLER-PUT"), fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_ ) );
std::string Path(URI.getPathAndQuery());
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_PUT,
Path,
Poco::Net::HTTPMessage::HTTP_1_1);
std::ostringstream obody;
Poco::JSON::Stringifier::stringify(Body_,obody);
Request.setContentType("application/json");
Request.setContentLength(obody.str().size());
if(BearerToken.empty()) {
Request.add("X-API-KEY", Svc.AccessKey);
Request.add("X-INTERNAL-NAME", MicroServicePublicEndPoint());
} else {
// Authorization: Bearer ${token}
Request.add("Authorization", "Bearer " + BearerToken);
}
if(Secure) {
Poco::Net::HTTPSClientSession Session(URI.getHost(), URI.getPort());
Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000));
std::ostream &os = Session.sendRequest(Request);
os << obody.str();
Poco::Net::HTTPResponse Response;
std::istream &is = Session.receiveResponse(Response);
if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) {
Poco::JSON::Parser P;
ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
if (BearerToken.empty()) {
Request.add("X-API-KEY", Svc.AccessKey);
Request.add("X-INTERNAL-NAME", MicroServicePublicEndPoint());
} else {
Poco::JSON::Parser P;
ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
// Authorization: Bearer ${token}
Request.add("Authorization", "Bearer " + BearerToken);
}
return Response.getStatus();
} else {
Poco::Net::HTTPClientSession Session(URI.getHost(), URI.getPort());
Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000));
std::ostream &os = Session.sendRequest(Request);
os << obody.str();
if (Secure) {
Poco::Net::HTTPSClientSession Session(URI.getHost(), URI.getPort());
Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000));
Poco::Net::HTTPResponse Response;
std::istream &is = Session.receiveResponse(Response);
if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) {
Poco::JSON::Parser P;
ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
Session.sendRequest(Request);
Poco::Net::HTTPResponse Response;
std::istream &is = Session.receiveResponse(Response);
if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) {
Poco::JSON::Parser P;
ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
}
return Response.getStatus();
} else {
Poco::JSON::Parser P;
ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
Poco::Net::HTTPClientSession Session(URI.getHost(), URI.getPort());
Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000));
Session.sendRequest(Request);
Poco::Net::HTTPResponse Response;
std::istream &is = Session.receiveResponse(Response);
if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) {
Poco::JSON::Parser P;
ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
}
return Response.getStatus();
}
return Response.getStatus();
}
} catch (const Poco::Exception &E) {
Poco::Logger::get("REST-CALLER-GET").log(E);
}
return Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT;
}
catch (const Poco::Exception &E)
{
Poco::Logger::get("REST-CALLER-PUT").log(E);
}
return Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT;
}
Poco::Net::HTTPServerResponse::HTTPStatus OpenAPIRequestPost::Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken) {
try {
auto Services = MicroServiceGetServices(Type_);
Poco::Net::HTTPServerResponse::HTTPStatus
OpenAPIRequestPut::Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string &BearerToken) {
try {
auto Services = MicroServiceGetServices(Type_);
for (auto const &Svc : Services) {
Poco::URI URI(Svc.PrivateEndPoint);
for(auto const &Svc:Services) {
Poco::URI URI(Svc.PrivateEndPoint);
auto Secure = (URI.getScheme() == "https");
URI.setPath(EndPoint_);
for (const auto &qp : QueryData_)
URI.addQueryParameter(qp.first, qp.second);
auto Secure = (URI.getScheme() == "https");
poco_debug(Poco::Logger::get("REST-CALLER-PUT"),
fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_));
URI.setPath(EndPoint_);
for (const auto &qp : QueryData_)
URI.addQueryParameter(qp.first, qp.second);
std::string Path(URI.getPathAndQuery());
poco_debug(Poco::Logger::get("REST-CALLER-POST"),fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_ ) );
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_PUT, Path,
Poco::Net::HTTPMessage::HTTP_1_1);
std::ostringstream obody;
Poco::JSON::Stringifier::stringify(Body_, obody);
std::string Path(URI.getPathAndQuery());
Request.setContentType("application/json");
Request.setContentLength(obody.str().size());
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_POST,
Path,
Poco::Net::HTTPMessage::HTTP_1_1);
std::ostringstream obody;
Poco::JSON::Stringifier::stringify(Body_,obody);
Request.setContentType("application/json");
Request.setContentLength(obody.str().size());
if(BearerToken.empty()) {
Request.add("X-API-KEY", Svc.AccessKey);
Request.add("X-INTERNAL-NAME", MicroServicePublicEndPoint());
} else {
// Authorization: Bearer ${token}
Request.add("Authorization", "Bearer " + BearerToken);
}
if(Secure) {
Poco::Net::HTTPSClientSession Session(URI.getHost(), URI.getPort());
Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000));
std::ostream &os = Session.sendRequest(Request);
os << obody.str();
Poco::Net::HTTPResponse Response;
std::istream &is = Session.receiveResponse(Response);
if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) {
Poco::JSON::Parser P;
ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
if (BearerToken.empty()) {
Request.add("X-API-KEY", Svc.AccessKey);
Request.add("X-INTERNAL-NAME", MicroServicePublicEndPoint());
} else {
Poco::JSON::Parser P;
ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
// Authorization: Bearer ${token}
Request.add("Authorization", "Bearer " + BearerToken);
}
return Response.getStatus();
} else {
Poco::Net::HTTPClientSession Session(URI.getHost(), URI.getPort());
Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000));
std::ostream &os = Session.sendRequest(Request);
os << obody.str();
Poco::Net::HTTPResponse Response;
std::istream &is = Session.receiveResponse(Response);
if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) {
Poco::JSON::Parser P;
ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
if (Secure) {
Poco::Net::HTTPSClientSession Session(URI.getHost(), URI.getPort());
Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000));
std::ostream &os = Session.sendRequest(Request);
os << obody.str();
Poco::Net::HTTPResponse Response;
std::istream &is = Session.receiveResponse(Response);
if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) {
Poco::JSON::Parser P;
ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
} else {
Poco::JSON::Parser P;
ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
}
return Response.getStatus();
} else {
Poco::JSON::Parser P;
ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
Poco::Net::HTTPClientSession Session(URI.getHost(), URI.getPort());
Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000));
std::ostream &os = Session.sendRequest(Request);
os << obody.str();
Poco::Net::HTTPResponse Response;
std::istream &is = Session.receiveResponse(Response);
if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) {
Poco::JSON::Parser P;
ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
} else {
Poco::JSON::Parser P;
ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
}
return Response.getStatus();
}
return Response.getStatus();
}
} catch (const Poco::Exception &E) {
Poco::Logger::get("REST-CALLER-PUT").log(E);
}
return Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT;
}
catch (const Poco::Exception &E)
{
Poco::Logger::get("REST-CALLER-POST").log(E);
}
return Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT;
}
Poco::Net::HTTPServerResponse::HTTPStatus OpenAPIRequestDelete::Do(const std::string & BearerToken) {
try {
auto Services = MicroServiceGetServices(Type_);
Poco::Net::HTTPServerResponse::HTTPStatus
OpenAPIRequestPost::Do(Poco::JSON::Object::Ptr &ResponseObject,
const std::string &BearerToken) {
try {
auto Services = MicroServiceGetServices(Type_);
for(auto const &Svc:Services) {
Poco::URI URI(Svc.PrivateEndPoint);
for (auto const &Svc : Services) {
Poco::URI URI(Svc.PrivateEndPoint);
auto Secure = (URI.getScheme() == "https");
auto Secure = (URI.getScheme() == "https");
URI.setPath(EndPoint_);
for (const auto &qp : QueryData_)
URI.addQueryParameter(qp.first, qp.second);
URI.setPath(EndPoint_);
for (const auto &qp : QueryData_)
URI.addQueryParameter(qp.first, qp.second);
poco_debug(Poco::Logger::get("REST-CALLER-DELETE"),fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_ ) );
poco_debug(Poco::Logger::get("REST-CALLER-POST"),
fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_));
std::string Path(URI.getPathAndQuery());
std::string Path(URI.getPathAndQuery());
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_DELETE,
Path,
Poco::Net::HTTPMessage::HTTP_1_1);
if(BearerToken.empty()) {
Request.add("X-API-KEY", Svc.AccessKey);
Request.add("X-INTERNAL-NAME", MicroServicePublicEndPoint());
} else {
// Authorization: Bearer ${token}
Request.add("Authorization", "Bearer " + BearerToken);
}
if(Secure) {
Poco::Net::HTTPSClientSession Session(URI.getHost(), URI.getPort());
Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000));
Session.sendRequest(Request);
Poco::Net::HTTPResponse Response;
Session.receiveResponse(Response);
return Response.getStatus();
} else {
Poco::Net::HTTPClientSession Session(URI.getHost(), URI.getPort());
Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000));
Session.sendRequest(Request);
Poco::Net::HTTPResponse Response;
Session.receiveResponse(Response);
return Response.getStatus();
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_POST, Path,
Poco::Net::HTTPMessage::HTTP_1_1);
std::ostringstream obody;
Poco::JSON::Stringifier::stringify(Body_, obody);
Request.setContentType("application/json");
Request.setContentLength(obody.str().size());
if (BearerToken.empty()) {
Request.add("X-API-KEY", Svc.AccessKey);
Request.add("X-INTERNAL-NAME", MicroServicePublicEndPoint());
} else {
// Authorization: Bearer ${token}
Request.add("Authorization", "Bearer " + BearerToken);
}
if (Secure) {
Poco::Net::HTTPSClientSession Session(URI.getHost(), URI.getPort());
Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000));
std::ostream &os = Session.sendRequest(Request);
os << obody.str();
Poco::Net::HTTPResponse Response;
std::istream &is = Session.receiveResponse(Response);
if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) {
Poco::JSON::Parser P;
ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
} else {
Poco::JSON::Parser P;
ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
}
return Response.getStatus();
} else {
Poco::Net::HTTPClientSession Session(URI.getHost(), URI.getPort());
Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000));
std::ostream &os = Session.sendRequest(Request);
os << obody.str();
Poco::Net::HTTPResponse Response;
std::istream &is = Session.receiveResponse(Response);
if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) {
Poco::JSON::Parser P;
ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
} else {
Poco::JSON::Parser P;
ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
}
return Response.getStatus();
}
}
} catch (const Poco::Exception &E) {
Poco::Logger::get("REST-CALLER-POST").log(E);
}
return Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT;
}
catch (const Poco::Exception &E)
{
Poco::Logger::get("REST-CALLER-DELETE").log(E);
}
return Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT;
}
Poco::Net::HTTPServerResponse::HTTPStatus
OpenAPIRequestDelete::Do(const std::string &BearerToken) {
try {
auto Services = MicroServiceGetServices(Type_);
for (auto const &Svc : Services) {
Poco::URI URI(Svc.PrivateEndPoint);
auto Secure = (URI.getScheme() == "https");
URI.setPath(EndPoint_);
for (const auto &qp : QueryData_)
URI.addQueryParameter(qp.first, qp.second);
poco_debug(Poco::Logger::get("REST-CALLER-DELETE"),
fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_));
std::string Path(URI.getPathAndQuery());
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_DELETE, Path,
Poco::Net::HTTPMessage::HTTP_1_1);
if (BearerToken.empty()) {
Request.add("X-API-KEY", Svc.AccessKey);
Request.add("X-INTERNAL-NAME", MicroServicePublicEndPoint());
} else {
// Authorization: Bearer ${token}
Request.add("Authorization", "Bearer " + BearerToken);
}
if (Secure) {
Poco::Net::HTTPSClientSession Session(URI.getHost(), URI.getPort());
Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000));
Session.sendRequest(Request);
Poco::Net::HTTPResponse Response;
Session.receiveResponse(Response);
return Response.getStatus();
} else {
Poco::Net::HTTPClientSession Session(URI.getHost(), URI.getPort());
Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000));
Session.sendRequest(Request);
Poco::Net::HTTPResponse Response;
Session.receiveResponse(Response);
return Response.getStatus();
}
}
} catch (const Poco::Exception &E) {
Poco::Logger::get("REST-CALLER-DELETE").log(E);
}
return Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT;
}
} // namespace OpenWifi

View File

@@ -15,96 +15,79 @@ namespace OpenWifi {
class OpenAPIRequestGet {
public:
explicit OpenAPIRequestGet( const std::string & Type,
const std::string & EndPoint,
const Types::StringPairVec & QueryData,
uint64_t msTimeout,
const std::string &LoggingStr=""):
Type_(Type),
EndPoint_(EndPoint),
QueryData_(QueryData),
msTimeout_(msTimeout),
LoggingStr_(LoggingStr){};
Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken = "");
explicit OpenAPIRequestGet(const std::string &Type, const std::string &EndPoint,
const Types::StringPairVec &QueryData, uint64_t msTimeout,
const std::string &LoggingStr = "")
: Type_(Type), EndPoint_(EndPoint), QueryData_(QueryData), msTimeout_(msTimeout),
LoggingStr_(LoggingStr){};
Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject,
const std::string &BearerToken = "");
private:
std::string Type_;
std::string EndPoint_;
Types::StringPairVec QueryData_;
uint64_t msTimeout_;
std::string LoggingStr_;
std::string Type_;
std::string EndPoint_;
Types::StringPairVec QueryData_;
uint64_t msTimeout_;
std::string LoggingStr_;
};
class OpenAPIRequestPut {
public:
explicit OpenAPIRequestPut( const std::string & Type,
const std::string & EndPoint,
const Types::StringPairVec & QueryData,
const Poco::JSON::Object & Body,
uint64_t msTimeout,
const std::string &LoggingStr=""):
Type_(Type),
EndPoint_(EndPoint),
QueryData_(QueryData),
msTimeout_(msTimeout),
Body_(Body),
LoggingStr_(LoggingStr){};
explicit OpenAPIRequestPut(const std::string &Type, const std::string &EndPoint,
const Types::StringPairVec &QueryData,
const Poco::JSON::Object &Body, uint64_t msTimeout,
const std::string &LoggingStr = "")
: Type_(Type), EndPoint_(EndPoint), QueryData_(QueryData), msTimeout_(msTimeout),
Body_(Body), LoggingStr_(LoggingStr){};
Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken = "");
Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject,
const std::string &BearerToken = "");
private:
std::string Type_;
std::string EndPoint_;
Types::StringPairVec QueryData_;
uint64_t msTimeout_;
Poco::JSON::Object Body_;
std::string LoggingStr_;
std::string Type_;
std::string EndPoint_;
Types::StringPairVec QueryData_;
uint64_t msTimeout_;
Poco::JSON::Object Body_;
std::string LoggingStr_;
};
class OpenAPIRequestPost {
public:
explicit OpenAPIRequestPost( const std::string & Type,
const std::string & EndPoint,
const Types::StringPairVec & QueryData,
const Poco::JSON::Object & Body,
uint64_t msTimeout,
const std::string &LoggingStr=""):
Type_(Type),
EndPoint_(EndPoint),
QueryData_(QueryData),
msTimeout_(msTimeout),
Body_(Body),
LoggingStr_(LoggingStr){};
Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken = "");
explicit OpenAPIRequestPost(const std::string &Type, const std::string &EndPoint,
const Types::StringPairVec &QueryData,
const Poco::JSON::Object &Body, uint64_t msTimeout,
const std::string &LoggingStr = "")
: Type_(Type), EndPoint_(EndPoint), QueryData_(QueryData), msTimeout_(msTimeout),
Body_(Body), LoggingStr_(LoggingStr){};
Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject,
const std::string &BearerToken = "");
private:
std::string Type_;
std::string EndPoint_;
Types::StringPairVec QueryData_;
uint64_t msTimeout_;
Poco::JSON::Object Body_;
std::string LoggingStr_;
std::string Type_;
std::string EndPoint_;
Types::StringPairVec QueryData_;
uint64_t msTimeout_;
Poco::JSON::Object Body_;
std::string LoggingStr_;
};
class OpenAPIRequestDelete {
public:
explicit OpenAPIRequestDelete( const std::string & Type,
const std::string & EndPoint,
const Types::StringPairVec & QueryData,
uint64_t msTimeout,
const std::string &LoggingStr=""):
Type_(Type),
EndPoint_(EndPoint),
QueryData_(QueryData),
msTimeout_(msTimeout),
LoggingStr_(LoggingStr){};
Poco::Net::HTTPServerResponse::HTTPStatus Do(const std::string & BearerToken = "");
explicit OpenAPIRequestDelete(const std::string &Type, const std::string &EndPoint,
const Types::StringPairVec &QueryData, uint64_t msTimeout,
const std::string &LoggingStr = "")
: Type_(Type), EndPoint_(EndPoint), QueryData_(QueryData), msTimeout_(msTimeout),
LoggingStr_(LoggingStr){};
Poco::Net::HTTPServerResponse::HTTPStatus Do(const std::string &BearerToken = "");
private:
std::string Type_;
std::string EndPoint_;
Types::StringPairVec QueryData_;
uint64_t msTimeout_;
Poco::JSON::Object Body_;
std::string LoggingStr_;
std::string Type_;
std::string EndPoint_;
Types::StringPairVec QueryData_;
uint64_t msTimeout_;
Poco::JSON::Object Body_;
std::string LoggingStr_;
};
} // namespace OpenWifi

View File

@@ -4,70 +4,71 @@
#pragma once
#include <functional>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include <functional>
#include <string>
#include <queue>
#include <list>
#include <set>
namespace OpenWifi::Types {
typedef std::pair<std::string,std::string> StringPair;
typedef std::vector<StringPair> StringPairVec;
typedef std::queue<StringPair> StringPairQueue;
typedef std::vector<std::string> StringVec;
typedef std::set<std::string> StringSet;
typedef std::map<std::string,std::set<std::string>> StringMapStringSet;
typedef std::function<void(const std::string &, const std::string &)> TopicNotifyFunction;
typedef std::list<std::pair<TopicNotifyFunction,int>> TopicNotifyFunctionList;
typedef std::map<std::string, TopicNotifyFunctionList> NotifyTable;
typedef std::map<std::string,uint64_t> CountedMap;
typedef std::vector<uint64_t> TagList;
typedef std::string UUID_t;
typedef std::vector<UUID_t> UUIDvec_t;
typedef std::map<std::string,std::map<uint32_t,uint64_t>> Counted3DMapSII;
typedef std::pair<std::string, std::string> StringPair;
typedef std::vector<StringPair> StringPairVec;
typedef std::queue<StringPair> StringPairQueue;
typedef std::vector<std::string> StringVec;
typedef std::set<std::string> StringSet;
typedef std::map<std::string, std::set<std::string>> StringMapStringSet;
typedef std::function<void(const std::string &, const std::string &)> TopicNotifyFunction;
typedef std::list<std::pair<TopicNotifyFunction, int>> TopicNotifyFunctionList;
typedef std::map<std::string, TopicNotifyFunctionList> NotifyTable;
typedef std::map<std::string, uint64_t> CountedMap;
typedef std::vector<uint64_t> TagList;
typedef std::string UUID_t;
typedef std::vector<UUID_t> UUIDvec_t;
typedef std::map<std::string, std::map<uint32_t, uint64_t>> Counted3DMapSII;
struct MicroServiceMeta {
uint64_t Id=0;
std::string Type;
std::string PrivateEndPoint;
std::string PublicEndPoint;
std::string AccessKey;
std::string Version;
uint64_t LastUpdate=0;
uint64_t Id = 0;
std::string Type;
std::string PrivateEndPoint;
std::string PublicEndPoint;
std::string AccessKey;
std::string Version;
uint64_t LastUpdate = 0;
};
typedef std::map<std::string, MicroServiceMeta> MicroServiceMetaMap;
typedef std::vector<MicroServiceMeta> MicroServiceMetaVec;
}
typedef std::map<std::string, MicroServiceMeta> MicroServiceMetaMap;
typedef std::vector<MicroServiceMeta> MicroServiceMetaVec;
} // namespace OpenWifi::Types
namespace OpenWifi {
inline void UpdateCountedMap(OpenWifi::Types::CountedMap &M, const std::string &S, uint64_t Increment=1) {
auto it = M.find(S);
if(it==M.end())
M[S] = Increment;
else
it->second += Increment;
}
inline void UpdateCountedMap(OpenWifi::Types::CountedMap &M, const std::string &S,
uint64_t Increment = 1) {
auto it = M.find(S);
if (it == M.end())
M[S] = Increment;
else
it->second += Increment;
}
inline void UpdateCountedMap(OpenWifi::Types::Counted3DMapSII &M, const std::string &S, uint32_t Index, uint64_t Increment=1) {
auto it = M.find(S);
if(it==M.end()) {
std::map<uint32_t,uint64_t> E;
E[Index] = Increment;
M[S] = E;
}
else {
std::map<uint32_t,uint64_t> & IndexMap = it->second;
auto it_index = IndexMap.find(Index);
if(it_index == IndexMap.end()) {
IndexMap[Index] = Increment;
} else {
it_index->second += Increment;
}
}
}
}
inline void UpdateCountedMap(OpenWifi::Types::Counted3DMapSII &M, const std::string &S,
uint32_t Index, uint64_t Increment = 1) {
auto it = M.find(S);
if (it == M.end()) {
std::map<uint32_t, uint64_t> E;
E[Index] = Increment;
M[S] = E;
} else {
std::map<uint32_t, uint64_t> &IndexMap = it->second;
auto it_index = IndexMap.find(Index);
if (it_index == IndexMap.end()) {
IndexMap[Index] = Increment;
} else {
it_index->second += Increment;
}
}
}
} // namespace OpenWifi

View File

@@ -6,22 +6,23 @@
namespace OpenWifi {
Poco::Net::HTTPRequestHandler *ExtRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest &Request) {
Poco::Net::HTTPRequestHandler *
ExtRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest &Request) {
try {
Poco::URI uri(Request.getURI());
auto TID = NextTransactionId_++;
Utils::SetThreadName(fmt::format("x-rest:{}",TID).c_str());
Utils::SetThreadName(fmt::format("x-rest:{}", TID).c_str());
return RESTAPI_ExtServer()->CallServer(uri.getPath(), TID);
} catch (...) {
}
return nullptr;
}
Poco::Net::HTTPRequestHandler *RESTAPI_ExtServer::CallServer(const std::string &Path, uint64_t Id) {
Poco::Net::HTTPRequestHandler *RESTAPI_ExtServer::CallServer(const std::string &Path,
uint64_t Id) {
RESTAPIHandler::BindingMap Bindings;
Utils::SetThreadName(fmt::format("x-rest:{}",Id).c_str());
Utils::SetThreadName(fmt::format("x-rest:{}", Id).c_str());
return RESTAPI_ExtRouter(Path, Bindings, Logger(), Server_, Id);
}
}
} // namespace OpenWifi

View File

@@ -6,20 +6,23 @@
#include "Poco/Net/HTTPServer.h"
#include "framework/SubSystemServer.h"
#include "framework/RESTAPI_Handler.h"
#include "framework/SubSystemServer.h"
namespace OpenWifi {
Poco::Net::HTTPRequestHandler * RESTAPI_ExtRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings,
Poco::Logger & L, RESTAPI_GenericServerAccounting & S, uint64_t Id);
Poco::Net::HTTPRequestHandler *
RESTAPI_ExtRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings,
Poco::Logger &L, RESTAPI_GenericServerAccounting &S, uint64_t Id);
class ExtRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
public:
ExtRequestHandlerFactory() = default;
Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override;
Poco::Net::HTTPRequestHandler *
createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override;
private:
static inline std::atomic_uint64_t NextTransactionId_ = 1;
static inline std::atomic_uint64_t NextTransactionId_ = 1;
};
class RESTAPI_ExtServer : public SubSystemServer {
@@ -30,16 +33,21 @@ namespace OpenWifi {
}
inline int Start() override {
poco_information(Logger(),"Starting.");
poco_information(Logger(), "Starting.");
Server_.InitLogging();
for(const auto & Svr: ConfigServersList_) {
for (const auto &Svr : ConfigServersList_) {
if(MicroServiceNoAPISecurity()) {
poco_information(Logger(),fmt::format("Starting: {}:{}. Security has been disabled for APIs.", Svr.Address(), Svr.Port()));
if (MicroServiceNoAPISecurity()) {
poco_information(
Logger(),
fmt::format("Starting: {}:{}. Security has been disabled for APIs.",
Svr.Address(), Svr.Port()));
} else {
poco_information(Logger(),fmt::format("Starting: {}:{} Keyfile:{} CertFile: {}", Svr.Address(), Svr.Port(),
Svr.KeyFile(),Svr.CertFile()));
poco_information(Logger(),
fmt::format("Starting: {}:{} Keyfile:{} CertFile: {}",
Svr.Address(), Svr.Port(), Svr.KeyFile(),
Svr.CertFile()));
Svr.LogCert(Logger());
if (!Svr.RootCA().empty())
Svr.LogCas(Logger());
@@ -49,13 +57,15 @@ namespace OpenWifi {
Params->setKeepAlive(true);
Params->setName("ws:xrest");
std::unique_ptr<Poco::Net::HTTPServer> NewServer;
if(MicroServiceNoAPISecurity()) {
std::unique_ptr<Poco::Net::HTTPServer> NewServer;
if (MicroServiceNoAPISecurity()) {
auto Sock{Svr.CreateSocket(Logger())};
NewServer = std::make_unique<Poco::Net::HTTPServer>(new ExtRequestHandlerFactory, Pool_, Sock, Params);
NewServer = std::make_unique<Poco::Net::HTTPServer>(
new ExtRequestHandlerFactory, Pool_, Sock, Params);
} else {
auto Sock{Svr.CreateSecureSocket(Logger())};
NewServer = std::make_unique<Poco::Net::HTTPServer>(new ExtRequestHandlerFactory, Pool_, Sock, Params);
NewServer = std::make_unique<Poco::Net::HTTPServer>(
new ExtRequestHandlerFactory, Pool_, Sock, Params);
};
NewServer->start();
RESTServers_.push_back(std::move(NewServer));
@@ -64,36 +74,34 @@ namespace OpenWifi {
}
inline void Stop() override {
poco_information(Logger(),"Stopping...");
for( const auto & svr : RESTServers_ )
poco_information(Logger(), "Stopping...");
for (const auto &svr : RESTServers_)
svr->stopAll(true);
Pool_.stopAll();
Pool_.joinAll();
RESTServers_.clear();
poco_information(Logger(),"Stopped...");
poco_information(Logger(), "Stopped...");
}
inline void reinitialize([[maybe_unused]] Poco::Util::Application &self) override {
MicroServiceLoadConfigurationFile();
poco_information(Logger(),"Reinitializing.");
poco_information(Logger(), "Reinitializing.");
Stop();
Start();
}
Poco::Net::HTTPRequestHandler *CallServer(const std::string &Path, uint64_t Id);
const Poco::ThreadPool & Pool() { return Pool_; }
const Poco::ThreadPool &Pool() { return Pool_; }
private:
std::vector<std::unique_ptr<Poco::Net::HTTPServer>> RESTServers_;
Poco::ThreadPool Pool_{"x-rest",8,128};
RESTAPI_GenericServerAccounting Server_;
std::vector<std::unique_ptr<Poco::Net::HTTPServer>> RESTServers_;
Poco::ThreadPool Pool_{"x-rest", 8, 128};
RESTAPI_GenericServerAccounting Server_;
RESTAPI_ExtServer() noexcept:
SubSystemServer("RESTAPI_ExtServer", "REST-XSRV", "openwifi.restapi")
{
}
RESTAPI_ExtServer() noexcept
: SubSystemServer("RESTAPI_ExtServer", "REST-XSRV", "openwifi.restapi") {}
};
inline auto RESTAPI_ExtServer() { return RESTAPI_ExtServer::instance(); };
}
} // namespace OpenWifi

View File

@@ -4,72 +4,70 @@
#pragma once
#include <string>
#include <array>
#include <string>
#include "Poco/StringTokenizer.h"
#include "Poco/String.h"
#include "Poco/Net/HTTPRequest.h"
#include "Poco/String.h"
#include "Poco/StringTokenizer.h"
#include "framework/MicroServiceFuncs.h"
namespace OpenWifi {
class RESTAPI_GenericServerAccounting {
public:
enum {
LOG_GET=0,
LOG_DELETE,
LOG_PUT,
LOG_POST
};
enum { LOG_GET = 0, LOG_DELETE, LOG_PUT, LOG_POST };
void inline SetFlags(bool External, const std::string &Methods) {
Poco::StringTokenizer Tokens(Methods,",");
Poco::StringTokenizer Tokens(Methods, ",");
auto Offset = (External ? 0 : 4);
for(const auto &i:Tokens) {
if(Poco::icompare(i,Poco::Net::HTTPRequest::HTTP_DELETE)==0)
LogFlags_[Offset+LOG_DELETE]=true;
else if(Poco::icompare(i,Poco::Net::HTTPRequest::HTTP_PUT)==0)
LogFlags_[Offset+LOG_PUT]=true;
else if(Poco::icompare(i,Poco::Net::HTTPRequest::HTTP_POST)==0)
LogFlags_[Offset+LOG_POST]=true;
else if(Poco::icompare(i,Poco::Net::HTTPRequest::HTTP_GET)==0)
LogFlags_[Offset+LOG_GET]=true;
for (const auto &i : Tokens) {
if (Poco::icompare(i, Poco::Net::HTTPRequest::HTTP_DELETE) == 0)
LogFlags_[Offset + LOG_DELETE] = true;
else if (Poco::icompare(i, Poco::Net::HTTPRequest::HTTP_PUT) == 0)
LogFlags_[Offset + LOG_PUT] = true;
else if (Poco::icompare(i, Poco::Net::HTTPRequest::HTTP_POST) == 0)
LogFlags_[Offset + LOG_POST] = true;
else if (Poco::icompare(i, Poco::Net::HTTPRequest::HTTP_GET) == 0)
LogFlags_[Offset + LOG_GET] = true;
}
}
inline void InitLogging() {
std::string Public = MicroServiceConfigGetString("apilogging.public.methods","PUT,POST,DELETE");
std::string Public =
MicroServiceConfigGetString("apilogging.public.methods", "PUT,POST,DELETE");
SetFlags(true, Public);
std::string Private = MicroServiceConfigGetString("apilogging.private.methods","PUT,POST,DELETE");
std::string Private =
MicroServiceConfigGetString("apilogging.private.methods", "PUT,POST,DELETE");
SetFlags(false, Private);
std::string PublicBadTokens = MicroServiceConfigGetString("apilogging.public.badtokens.methods","");
LogBadTokens_[0] = (Poco::icompare(PublicBadTokens,"true")==0);
std::string PrivateBadTokens = MicroServiceConfigGetString("apilogging.private.badtokens.methods","");
LogBadTokens_[1] = (Poco::icompare(PrivateBadTokens,"true")==0);
std::string PublicBadTokens =
MicroServiceConfigGetString("apilogging.public.badtokens.methods", "");
LogBadTokens_[0] = (Poco::icompare(PublicBadTokens, "true") == 0);
std::string PrivateBadTokens =
MicroServiceConfigGetString("apilogging.private.badtokens.methods", "");
LogBadTokens_[1] = (Poco::icompare(PrivateBadTokens, "true") == 0);
}
[[nodiscard]] inline bool LogIt(const std::string &Method, bool External) const {
auto Offset = (External ? 0 : 4);
if(Method == Poco::Net::HTTPRequest::HTTP_GET)
return LogFlags_[Offset+LOG_GET];
if(Method == Poco::Net::HTTPRequest::HTTP_POST)
return LogFlags_[Offset+LOG_POST];
if(Method == Poco::Net::HTTPRequest::HTTP_PUT)
return LogFlags_[Offset+LOG_PUT];
if(Method == Poco::Net::HTTPRequest::HTTP_DELETE)
return LogFlags_[Offset+LOG_DELETE];
if (Method == Poco::Net::HTTPRequest::HTTP_GET)
return LogFlags_[Offset + LOG_GET];
if (Method == Poco::Net::HTTPRequest::HTTP_POST)
return LogFlags_[Offset + LOG_POST];
if (Method == Poco::Net::HTTPRequest::HTTP_PUT)
return LogFlags_[Offset + LOG_PUT];
if (Method == Poco::Net::HTTPRequest::HTTP_DELETE)
return LogFlags_[Offset + LOG_DELETE];
return false;
};
[[nodiscard]] inline bool LogBadTokens(bool External) const {
return LogBadTokens_[ (External ? 0 : 1) ];
return LogBadTokens_[(External ? 0 : 1)];
};
private:
std::array<bool,8> LogFlags_{false};
std::array<bool,2> LogBadTokens_{false};
std::array<bool, 8> LogFlags_{false};
std::array<bool, 2> LogBadTokens_{false};
};
}
} // namespace OpenWifi

View File

@@ -4,5 +4,4 @@
#include "RESTAPI_Handler.h"
namespace OpenWifi {
} // namespace OpenWifi
namespace OpenWifi {} // namespace OpenWifi

File diff suppressed because it is too large Load Diff

View File

@@ -6,20 +6,23 @@
#include "Poco/Net/HTTPServer.h"
#include "framework/SubSystemServer.h"
#include "framework/RESTAPI_Handler.h"
#include "framework/SubSystemServer.h"
namespace OpenWifi {
Poco::Net::HTTPRequestHandler * RESTAPI_IntRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings,
Poco::Logger & L, RESTAPI_GenericServerAccounting & S, uint64_t Id);
Poco::Net::HTTPRequestHandler *
RESTAPI_IntRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings,
Poco::Logger &L, RESTAPI_GenericServerAccounting &S, uint64_t Id);
class IntRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
public:
inline IntRequestHandlerFactory() = default;
Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override;
Poco::Net::HTTPRequestHandler *
createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override;
private:
static inline std::atomic_uint64_t NextTransactionId_ = 1;
static inline std::atomic_uint64_t NextTransactionId_ = 1;
};
class RESTAPI_IntServer : public SubSystemServer {
@@ -30,16 +33,21 @@ namespace OpenWifi {
}
inline int Start() override {
poco_information(Logger(),"Starting.");
poco_information(Logger(), "Starting.");
Server_.InitLogging();
for(const auto & Svr: ConfigServersList_) {
for (const auto &Svr : ConfigServersList_) {
if(MicroServiceNoAPISecurity()) {
poco_information(Logger(),fmt::format("Starting: {}:{}. Security has been disabled for APIs.", Svr.Address(), Svr.Port()));
if (MicroServiceNoAPISecurity()) {
poco_information(
Logger(),
fmt::format("Starting: {}:{}. Security has been disabled for APIs.",
Svr.Address(), Svr.Port()));
} else {
poco_information(Logger(),fmt::format("Starting: {}:{}. Keyfile:{} CertFile: {}", Svr.Address(), Svr.Port(),
Svr.KeyFile(),Svr.CertFile()));
poco_information(Logger(),
fmt::format("Starting: {}:{}. Keyfile:{} CertFile: {}",
Svr.Address(), Svr.Port(), Svr.KeyFile(),
Svr.CertFile()));
Svr.LogCert(Logger());
if (!Svr.RootCA().empty())
Svr.LogCas(Logger());
@@ -49,13 +57,15 @@ namespace OpenWifi {
Params->setKeepAlive(true);
Params->setName("ws:irest");
std::unique_ptr<Poco::Net::HTTPServer> NewServer;
if(MicroServiceNoAPISecurity()) {
std::unique_ptr<Poco::Net::HTTPServer> NewServer;
if (MicroServiceNoAPISecurity()) {
auto Sock{Svr.CreateSocket(Logger())};
NewServer = std::make_unique<Poco::Net::HTTPServer>(new IntRequestHandlerFactory, Pool_, Sock, Params);
NewServer = std::make_unique<Poco::Net::HTTPServer>(
new IntRequestHandlerFactory, Pool_, Sock, Params);
} else {
auto Sock{Svr.CreateSecureSocket(Logger())};
NewServer = std::make_unique<Poco::Net::HTTPServer>(new IntRequestHandlerFactory, Pool_, Sock, Params);
NewServer = std::make_unique<Poco::Net::HTTPServer>(
new IntRequestHandlerFactory, Pool_, Sock, Params);
};
NewServer->start();
RESTServers_.push_back(std::move(NewServer));
@@ -65,40 +75,37 @@ namespace OpenWifi {
}
inline void Stop() override {
poco_information(Logger(),"Stopping...");
for( const auto & svr : RESTServers_ )
poco_information(Logger(), "Stopping...");
for (const auto &svr : RESTServers_)
svr->stopAll(true);
Pool_.stopAll();
Pool_.joinAll();
poco_information(Logger(),"Stopped...");
poco_information(Logger(), "Stopped...");
}
inline void reinitialize([[maybe_unused]] Poco::Util::Application &self) override {
MicroServiceLoadConfigurationFile();
poco_information(Logger(),"Reinitializing.");
poco_information(Logger(), "Reinitializing.");
Stop();
Start();
}
inline Poco::Net::HTTPRequestHandler *CallServer(const std::string &Path, uint64_t Id) {
RESTAPIHandler::BindingMap Bindings;
Utils::SetThreadName(fmt::format("i-rest:{}",Id).c_str());
Utils::SetThreadName(fmt::format("i-rest:{}", Id).c_str());
return RESTAPI_IntRouter(Path, Bindings, Logger(), Server_, Id);
}
const Poco::ThreadPool & Pool() { return Pool_; }
private:
std::vector<std::unique_ptr<Poco::Net::HTTPServer>> RESTServers_;
Poco::ThreadPool Pool_{"i-rest",4,64};
RESTAPI_GenericServerAccounting Server_;
const Poco::ThreadPool &Pool() { return Pool_; }
RESTAPI_IntServer() noexcept:
SubSystemServer("RESTAPI_IntServer", "REST-ISRV", "openwifi.internal.restapi")
{
}
private:
std::vector<std::unique_ptr<Poco::Net::HTTPServer>> RESTServers_;
Poco::ThreadPool Pool_{"i-rest", 4, 64};
RESTAPI_GenericServerAccounting Server_;
RESTAPI_IntServer() noexcept
: SubSystemServer("RESTAPI_IntServer", "REST-ISRV", "openwifi.internal.restapi") {}
};
inline auto RESTAPI_IntServer() { return RESTAPI_IntServer::instance(); };
} // namespace OpenWifi

View File

@@ -4,29 +4,26 @@
#pragma once
#include <string>
#include "Poco/Net/PartHandler.h"
#include "Poco/Net/MessageHeader.h"
#include "Poco/CountingStream.h"
#include "Poco/Net/MessageHeader.h"
#include "Poco/Net/PartHandler.h"
#include "Poco/NullStream.h"
#include "Poco/StreamCopier.h"
#include <string>
namespace OpenWifi {
class RESTAPI_PartHandler: public Poco::Net::PartHandler {
class RESTAPI_PartHandler : public Poco::Net::PartHandler {
public:
RESTAPI_PartHandler():
_length(0)
{
}
RESTAPI_PartHandler() : _length(0) {}
inline void handlePart(const Poco::Net::MessageHeader& header, std::istream& stream) override
{
inline void handlePart(const Poco::Net::MessageHeader &header,
std::istream &stream) override {
_type = header.get("Content-Type", "(unspecified)");
if (header.has("Content-Disposition"))
{
if (header.has("Content-Disposition")) {
std::string disp;
Poco::Net::NameValueCollection params;
Poco::Net::MessageHeader::splitParameters(header["Content-Disposition"], disp, params);
Poco::Net::MessageHeader::splitParameters(header["Content-Disposition"], disp,
params);
_name = params.get("name", "(unnamed)");
_fileName = params.get("filename", "(unnamed)");
}
@@ -37,25 +34,13 @@ namespace OpenWifi {
_length = (int)istr.chars();
}
[[nodiscard]] inline int length() const
{
return _length;
}
[[nodiscard]] inline int length() const { return _length; }
[[nodiscard]] inline const std::string& name() const
{
return _name;
}
[[nodiscard]] inline const std::string &name() const { return _name; }
[[nodiscard]] inline const std::string& fileName() const
{
return _fileName;
}
[[nodiscard]] inline const std::string &fileName() const { return _fileName; }
[[nodiscard]] inline const std::string& contentType() const
{
return _type;
}
[[nodiscard]] inline const std::string &contentType() const { return _type; }
private:
int _length;
@@ -63,4 +48,4 @@ namespace OpenWifi {
std::string _name;
std::string _fileName;
};
}
} // namespace OpenWifi

View File

@@ -6,9 +6,9 @@
#include "framework/SubSystemServer.h"
#include "Poco/URI.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "Poco/ExpireLRUCache.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "Poco/URI.h"
#include "fmt/format.h"
@@ -16,10 +16,9 @@ namespace OpenWifi {
class RESTAPI_RateLimiter : public SubSystemServer {
public:
struct ClientCacheEntry {
int64_t Start=0;
int Count=0;
int64_t Start = 0;
int Count = 0;
};
static auto instance() {
@@ -27,49 +26,47 @@ namespace OpenWifi {
return instance_;
}
inline int Start() final { return 0;};
inline void Stop() final { };
inline int Start() final { return 0; };
inline void Stop() final{};
inline bool IsRateLimited(const Poco::Net::HTTPServerRequest &R, int64_t Period, int64_t MaxCalls) {
Poco::URI uri(R.getURI());
inline bool IsRateLimited(const Poco::Net::HTTPServerRequest &R, int64_t Period,
int64_t MaxCalls) {
Poco::URI uri(R.getURI());
auto H = str_hash(uri.getPath() + R.clientAddress().host().toString());
auto E = Cache_.get(H);
auto Now = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
if(E.isNull()) {
Cache_.add(H,ClientCacheEntry{.Start=Now, .Count=1});
auto Now = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch())
.count();
if (E.isNull()) {
Cache_.add(H, ClientCacheEntry{.Start = Now, .Count = 1});
return false;
}
if((Now-E->Start)<Period) {
if ((Now - E->Start) < Period) {
E->Count++;
Cache_.update(H,E);
if(E->Count > MaxCalls) {
poco_warning(Logger(),fmt::format("RATE-LIMIT-EXCEEDED: from '{}'", R.clientAddress().toString()));
Cache_.update(H, E);
if (E->Count > MaxCalls) {
poco_warning(Logger(), fmt::format("RATE-LIMIT-EXCEEDED: from '{}'",
R.clientAddress().toString()));
return true;
}
return false;
}
E->Start = Now;
E->Count = 1;
Cache_.update(H,E);
Cache_.update(H, E);
return false;
}
inline void Clear() {
Cache_.clear();
}
inline void Clear() { Cache_.clear(); }
private:
Poco::ExpireLRUCache<uint64_t,ClientCacheEntry> Cache_{2048};
std::hash<std::string> str_hash;
RESTAPI_RateLimiter() noexcept:
SubSystemServer("RateLimiter", "RATE-LIMITER", "rate.limiter")
{
}
Poco::ExpireLRUCache<uint64_t, ClientCacheEntry> Cache_{2048};
std::hash<std::string> str_hash;
RESTAPI_RateLimiter() noexcept
: SubSystemServer("RateLimiter", "RATE-LIMITER", "rate.limiter") {}
};
inline auto RESTAPI_RateLimiter() { return RESTAPI_RateLimiter::instance(); }
}
} // namespace OpenWifi

View File

@@ -14,19 +14,19 @@ namespace OpenWifi {
class RESTAPI_system_command : public RESTAPIHandler {
public:
RESTAPI_system_command(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
RESTAPI_system_command(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId,
bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_POST,
Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal) {}
static auto PathName() { return std::list<std::string>{"/api/v1/system"};}
Server, TransactionId, Internal) {}
static auto PathName() { return std::list<std::string>{"/api/v1/system"}; }
inline void DoGet() {
std::string Arg;
if(HasParameter("command",Arg) && Arg=="info") {
if (HasParameter("command", Arg) && Arg == "info") {
Poco::JSON::Object Answer;
Answer.set(RESTAPI::Protocol::VERSION, MicroServiceVersion());
Answer.set(RESTAPI::Protocol::UPTIME, MicroServiceUptimeTotalSeconds());
@@ -36,19 +36,19 @@ namespace OpenWifi {
Answer.set(RESTAPI::Protocol::HOSTNAME, Poco::Environment::nodeName());
Answer.set(RESTAPI::Protocol::UI, MicroServiceGetUIURI());
Poco::JSON::Array Certificates;
Poco::JSON::Array Certificates;
auto SubSystems = MicroServiceGetFullSubSystems();
std::set<std::string> CertNames;
std::set<std::string> CertNames;
for(const auto &i:SubSystems) {
auto Hosts=i->HostSize();
for(uint64_t j=0;j<Hosts;++j) {
for (const auto &i : SubSystems) {
auto Hosts = i->HostSize();
for (uint64_t j = 0; j < Hosts; ++j) {
auto CertFileName = i->Host(j).CertFile();
if(!CertFileName.empty()) {
Poco::File F1(CertFileName);
if(F1.exists()) {
if (!CertFileName.empty()) {
Poco::File F1(CertFileName);
if (F1.exists()) {
auto InsertResult = CertNames.insert(CertFileName);
if(InsertResult.second) {
if (InsertResult.second) {
Poco::JSON::Object Inner;
Poco::Path F(CertFileName);
Inner.set("filename", F.getFileName());
@@ -64,8 +64,8 @@ namespace OpenWifi {
Answer.set("certificates", Certificates);
return ReturnObject(Answer);
}
if(GetBoolParameter("extraConfiguration")) {
Poco::JSON::Object Answer;
if (GetBoolParameter("extraConfiguration")) {
Poco::JSON::Object Answer;
MicroServiceGetExtraConfiguration(Answer);
return ReturnObject(Answer);
}
@@ -73,7 +73,7 @@ namespace OpenWifi {
}
inline void DoPost() final {
const auto & Obj = ParsedBody_;
const auto &Obj = ParsedBody_;
if (Obj->has(RESTAPI::Protocol::COMMAND)) {
auto Command = Poco::toLower(Obj->get(RESTAPI::Protocol::COMMAND).toString());
if (Command == RESTAPI::Protocol::SETLOGLEVEL) {
@@ -88,7 +88,8 @@ namespace OpenWifi {
auto Name = GetS(RESTAPI::Protocol::TAG, InnerObj);
auto Value = GetS(RESTAPI::Protocol::VALUE, InnerObj);
MicroServiceSetSubsystemLogLevel(Name, Value);
poco_information(Logger_,
poco_information(
Logger_,
fmt::format("Setting log level for {} at {}", Name, Value));
}
}
@@ -109,7 +110,7 @@ namespace OpenWifi {
} else if (Command == RESTAPI::Protocol::GETLOGLEVELNAMES) {
Poco::JSON::Object Result;
Poco::JSON::Array LevelNamesArray;
const Types::StringVec &LevelNames = MicroServiceGetLogLevelNames();
const Types::StringVec &LevelNames = MicroServiceGetLogLevelNames();
for (const auto &i : LevelNames)
LevelNamesArray.add(i);
Result.set(RESTAPI::Protocol::LIST, LevelNamesArray);
@@ -117,7 +118,7 @@ namespace OpenWifi {
} else if (Command == RESTAPI::Protocol::GETSUBSYSTEMNAMES) {
Poco::JSON::Object Result;
Poco::JSON::Array LevelNamesArray;
const Types::StringVec &SubSystemNames = MicroServiceGetSubSystems();
const Types::StringVec &SubSystemNames = MicroServiceGetSubSystems();
for (const auto &i : SubSystemNames)
LevelNamesArray.add(i);
Result.set(RESTAPI::Protocol::LIST, LevelNamesArray);
@@ -131,10 +132,10 @@ namespace OpenWifi {
std::vector<std::string> Names;
for (const auto &i : *SubSystems)
Names.push_back(i.toString());
std::thread ReloadThread([Names](){
std::thread ReloadThread([Names]() {
std::this_thread::sleep_for(10000ms);
for(const auto &i:Names) {
if(i=="daemon")
for (const auto &i : Names) {
if (i == "daemon")
MicroServiceReload();
else
MicroServiceReload(i);
@@ -150,8 +151,8 @@ namespace OpenWifi {
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
void DoPut() final {};
void DoDelete() final {};
void DoPut() final{};
void DoDelete() final{};
};
}
} // namespace OpenWifi

View File

@@ -4,42 +4,44 @@
#pragma once
#include "framework/RESTAPI_Handler.h"
#include "Poco/Net/WebSocket.h"
#include "framework/RESTAPI_Handler.h"
#include "framework/UI_WebSocketClientServer.h"
#include "framework/MicroServiceFuncs.h"
#include "framework/UI_WebSocketClientServer.h"
namespace OpenWifi {
class RESTAPI_webSocketServer : public RESTAPIHandler {
public:
inline RESTAPI_webSocketServer(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal)
inline RESTAPI_webSocketServer(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
RESTAPI_GenericServerAccounting &Server,
uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{ Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal,false) {}
static auto PathName() { return std::list<std::string>{"/api/v1/ws"};}
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal, false) {}
static auto PathName() { return std::list<std::string>{"/api/v1/ws"}; }
void DoGet() final {
try
{
if(Request->find("Upgrade") != Request->end() && Poco::icompare((*Request)["Upgrade"], "websocket") == 0) {
try
{
Poco::Net::WebSocket WS(*Request, *Response);
auto Id = MicroServiceCreateUUID();
UI_WebSocketClientServer()->NewClient(WS,Id,UserInfo_.userinfo.email, TransactionId_);
}
catch (...) {
std::cout << "Cannot create websocket client..." << std::endl;
}
try {
if (Request->find("Upgrade") != Request->end() &&
Poco::icompare((*Request)["Upgrade"], "websocket") == 0) {
try {
Poco::Net::WebSocket WS(*Request, *Response);
auto Id = MicroServiceCreateUUID();
UI_WebSocketClientServer()->NewClient(WS, Id, UserInfo_.userinfo.email,
TransactionId_);
} catch (...) {
std::cout << "Cannot create websocket client..." << std::endl;
}
} catch(...) {
std::cout << "Cannot upgrade connection..." << std::endl;
}
};
void DoDelete() final {};
void DoPost() final {};
void DoPut() final {};
} catch (...) {
std::cout << "Cannot upgrade connection..." << std::endl;
}
};
void DoDelete() final{};
void DoPost() final{};
void DoPut() final{};
private:
};
}
} // namespace OpenWifi

View File

@@ -6,9 +6,9 @@
#include <string>
#include "Poco/Data/LOB.h"
#include "Poco/JSON/Object.h"
#include "Poco/JSON/Parser.h"
#include "Poco/Data/LOB.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "framework/OpenWifiTypes.h"
@@ -16,7 +16,8 @@
namespace OpenWifi::RESTAPI_utils {
inline void EmbedDocument(const std::string & ObjName, Poco::JSON::Object & Obj, const std::string &ObjStr) {
inline void EmbedDocument(const std::string &ObjName, Poco::JSON::Object &Obj,
const std::string &ObjStr) {
std::string D = ObjStr.empty() ? "{}" : ObjStr;
Poco::JSON::Parser P;
Poco::Dynamic::Var result = P.parse(D);
@@ -25,23 +26,23 @@ namespace OpenWifi::RESTAPI_utils {
}
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, bool V) {
Obj.set(Field,V);
Obj.set(Field, V);
}
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, double V) {
Obj.set(Field,V);
Obj.set(Field, V);
}
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, float V) {
Obj.set(Field,V);
Obj.set(Field, V);
}
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const std::string & S) {
Obj.set(Field,S);
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const std::string &S) {
Obj.set(Field, S);
}
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const char * S) {
Obj.set(Field,S);
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const char *S) {
Obj.set(Field, S);
}
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, int16_t Value) {
@@ -65,87 +66,93 @@ namespace OpenWifi::RESTAPI_utils {
}
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, uint64_t Value) {
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 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) {
Poco::JSON::Array Array;
for(const auto &i:S) {
Poco::JSON::Object O;
O.set("tag",i.first);
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field,
const Types::StringPairVec &S) {
Poco::JSON::Array Array;
for (const auto &i : S) {
Poco::JSON::Object O;
O.set("tag", i.first);
O.set("value", i.second);
Array.add(O);
}
Obj.set(Field,Array);
Obj.set(Field, Array);
}
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::StringVec &V) {
Poco::JSON::Array A;
for(const auto &i:V)
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field,
const Types::StringVec &V) {
Poco::JSON::Array A;
for (const auto &i : V)
A.add(i);
Obj.set(Field,A);
Obj.set(Field, A);
}
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::TagList &V) {
Poco::JSON::Array A;
for(const auto &i:V)
Poco::JSON::Array A;
for (const auto &i : V)
A.add(i);
Obj.set(Field,A);
Obj.set(Field, A);
}
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::CountedMap &M) {
Poco::JSON::Array A;
for(const auto &[Key,Value]:M) {
Poco::JSON::Object O;
O.set("tag",Key);
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field,
const Types::CountedMap &M) {
Poco::JSON::Array A;
for (const auto &[Key, Value] : M) {
Poco::JSON::Object O;
O.set("tag", Key);
O.set("value", Value);
A.add(O);
}
Obj.set(Field,A);
Obj.set(Field, A);
}
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::Counted3DMapSII &M) {
Poco::JSON::Array A;
for(const auto &[OrgName,MonthlyNumberMap]:M) {
Poco::JSON::Object OrgObject;
OrgObject.set("tag",OrgName);
Poco::JSON::Array MonthlyArray;
for(const auto &[Month,Counter]:MonthlyNumberMap) {
Poco::JSON::Object Inner;
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field,
const Types::Counted3DMapSII &M) {
Poco::JSON::Array A;
for (const auto &[OrgName, MonthlyNumberMap] : M) {
Poco::JSON::Object OrgObject;
OrgObject.set("tag", OrgName);
Poco::JSON::Array MonthlyArray;
for (const auto &[Month, Counter] : MonthlyNumberMap) {
Poco::JSON::Object Inner;
Inner.set("value", Month);
Inner.set("counter", Counter);
MonthlyArray.add(Inner);
}
OrgObject.set("index",MonthlyArray);
OrgObject.set("index", MonthlyArray);
A.add(OrgObject);
}
Obj.set(Field, A);
}
template<typename T> void field_to_json(Poco::JSON::Object &Obj,
const char *Field,
const T &V,
template <typename T>
void field_to_json(Poco::JSON::Object &Obj, const char *Field, const T &V,
std::function<std::string(const T &)> F) {
Obj.set(Field, F(V));
}
template<class T> void field_to_json(Poco::JSON::Object &Obj, const char *Field, const std::vector<T> &Value) {
template <class T>
void field_to_json(Poco::JSON::Object &Obj, const char *Field, const std::vector<T> &Value) {
Poco::JSON::Array Arr;
for(const auto &i:Value) {
Poco::JSON::Object AO;
for (const auto &i : Value) {
Poco::JSON::Object AO;
i.to_json(AO);
Arr.add(AO);
}
Obj.set(Field, Arr);
}
template<class T> void field_to_json(Poco::JSON::Object &Obj, const char *Field, const T &Value) {
Poco::JSON::Object Answer;
template <class T>
void field_to_json(Poco::JSON::Object &Obj, const char *Field, const T &Value) {
Poco::JSON::Object Answer;
Value.to_json(Answer);
Obj.set(Field, Answer);
}
@@ -155,188 +162,207 @@ namespace OpenWifi::RESTAPI_utils {
///////////////////////////
///////////////////////////
template<typename T> bool field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, T & V,
template <typename T>
bool field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, T &V,
std::function<T(const std::string &)> F) {
if(Obj->has(Field) && !Obj->isNull(Field))
if (Obj->has(Field) && !Obj->isNull(Field))
V = F(Obj->get(Field).toString());
return true;
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, std::string &S) {
if(Obj->has(Field) && !Obj->isNull(Field))
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
std::string &S) {
if (Obj->has(Field) && !Obj->isNull(Field))
S = Obj->get(Field).toString();
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, double & Value) {
if(Obj->has(Field) && !Obj->isNull(Field))
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
double &Value) {
if (Obj->has(Field) && !Obj->isNull(Field))
Value = (double)Obj->get(Field);
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, float & Value) {
if(Obj->has(Field) && !Obj->isNull(Field))
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
float &Value) {
if (Obj->has(Field) && !Obj->isNull(Field))
Value = (float)Obj->get(Field);
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, bool &Value) {
if(Obj->has(Field) && !Obj->isNull(Field))
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
bool &Value) {
if (Obj->has(Field) && !Obj->isNull(Field))
Value = (Obj->get(Field).toString() == "true");
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, int16_t &Value) {
if(Obj->has(Field) && !Obj->isNull(Field))
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
int16_t &Value) {
if (Obj->has(Field) && !Obj->isNull(Field))
Value = (int16_t)Obj->get(Field);
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, int32_t &Value) {
if(Obj->has(Field) && !Obj->isNull(Field))
Value = (int32_t) Obj->get(Field);
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
int32_t &Value) {
if (Obj->has(Field) && !Obj->isNull(Field))
Value = (int32_t)Obj->get(Field);
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, int64_t &Value) {
if(Obj->has(Field) && !Obj->isNull(Field))
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
int64_t &Value) {
if (Obj->has(Field) && !Obj->isNull(Field))
Value = (int64_t)Obj->get(Field);
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, uint16_t &Value) {
if(Obj->has(Field) && !Obj->isNull(Field))
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
uint16_t &Value) {
if (Obj->has(Field) && !Obj->isNull(Field))
Value = (uint16_t)Obj->get(Field);
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, uint32_t &Value) {
if(Obj->has(Field) && !Obj->isNull(Field))
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
uint32_t &Value) {
if (Obj->has(Field) && !Obj->isNull(Field))
Value = (uint32_t)Obj->get(Field);
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, uint64_t &Value) {
if(Obj->has(Field) && !Obj->isNull(Field))
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
uint64_t &Value) {
if (Obj->has(Field) && !Obj->isNull(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)) {
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());
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) {
if(Obj->isArray(Field) && !Obj->isNull(Field)) {
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
Types::StringPairVec &Vec) {
if (Obj->isArray(Field) && !Obj->isNull(Field)) {
auto O = Obj->getArray(Field);
for(const auto &i:*O) {
std::string S1,S2;
for (const auto &i : *O) {
std::string S1, S2;
auto Inner = i.extract<Poco::JSON::Object::Ptr>();
if(Inner->has("tag"))
if (Inner->has("tag"))
S1 = Inner->get("tag").toString();
if(Inner->has("value"))
if (Inner->has("value"))
S2 = Inner->get("value").toString();
auto P = std::make_pair(S1,S2);
auto P = std::make_pair(S1, S2);
Vec.push_back(P);
}
}
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, Types::StringVec &Value) {
if(Obj->isArray(Field) && !Obj->isNull(Field)) {
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
Types::StringVec &Value) {
if (Obj->isArray(Field) && !Obj->isNull(Field)) {
Value.clear();
Poco::JSON::Array::Ptr A = Obj->getArray(Field);
for(const auto &i:*A) {
for (const auto &i : *A) {
Value.push_back(i.toString());
}
}
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, Types::TagList &Value) {
if(Obj->isArray(Field) && !Obj->isNull(Field)) {
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
Types::TagList &Value) {
if (Obj->isArray(Field) && !Obj->isNull(Field)) {
Value.clear();
Poco::JSON::Array::Ptr A = Obj->getArray(Field);
for(const auto &i:*A) {
for (const auto &i : *A) {
Value.push_back(i);
}
}
}
template<class T> void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, std::vector<T> &Value) {
if(Obj->isArray(Field) && !Obj->isNull(Field)) {
Poco::JSON::Array::Ptr Arr = Obj->getArray(Field);
for(auto &i:*Arr) {
template <class T>
void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
std::vector<T> &Value) {
if (Obj->isArray(Field) && !Obj->isNull(Field)) {
Poco::JSON::Array::Ptr Arr = Obj->getArray(Field);
for (auto &i : *Arr) {
auto InnerObj = i.extract<Poco::JSON::Object::Ptr>();
T NewItem;
T NewItem;
NewItem.from_json(InnerObj);
Value.push_back(NewItem);
}
}
}
template<class T> void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, T &Value) {
if(Obj->isObject(Field) && !Obj->isNull(Field)) {
Poco::JSON::Object::Ptr A = Obj->getObject(Field);
template <class T>
void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, T &Value) {
if (Obj->isObject(Field) && !Obj->isNull(Field)) {
Poco::JSON::Object::Ptr A = Obj->getObject(Field);
Value.from_json(A);
}
}
inline std::string to_string(const Types::TagList & ObjectArray) {
inline std::string to_string(const Types::TagList &ObjectArray) {
Poco::JSON::Array OutputArr;
if(ObjectArray.empty())
if (ObjectArray.empty())
return "[]";
for(auto const &i:ObjectArray) {
for (auto const &i : ObjectArray) {
OutputArr.add(i);
}
std::ostringstream OS;
Poco::JSON::Stringifier::stringify(OutputArr,OS, 0,0, Poco::JSON_PRESERVE_KEY_ORDER );
Poco::JSON::Stringifier::stringify(OutputArr, OS, 0, 0, Poco::JSON_PRESERVE_KEY_ORDER);
return OS.str();
}
inline std::string to_string(const Types::StringVec & ObjectArray) {
inline std::string to_string(const Types::StringVec &ObjectArray) {
Poco::JSON::Array OutputArr;
if(ObjectArray.empty())
if (ObjectArray.empty())
return "[]";
for(auto const &i:ObjectArray) {
for (auto const &i : ObjectArray) {
OutputArr.add(i);
}
std::ostringstream OS;
Poco::JSON::Stringifier::condense(OutputArr,OS);
Poco::JSON::Stringifier::condense(OutputArr, OS);
return OS.str();
}
inline std::string to_string(const Types::StringPairVec & ObjectArray) {
inline std::string to_string(const Types::StringPairVec &ObjectArray) {
Poco::JSON::Array OutputArr;
if(ObjectArray.empty())
if (ObjectArray.empty())
return "[]";
for(auto const &i:ObjectArray) {
for (auto const &i : ObjectArray) {
Poco::JSON::Array InnerArray;
InnerArray.add(i.first);
InnerArray.add(i.second);
OutputArr.add(InnerArray);
}
std::ostringstream OS;
Poco::JSON::Stringifier::condense(OutputArr,OS);
Poco::JSON::Stringifier::condense(OutputArr, OS);
return OS.str();
}
template<class T> std::string to_string(const std::vector<T> & ObjectArray) {
template <class T> std::string to_string(const std::vector<T> &ObjectArray) {
Poco::JSON::Array OutputArr;
if(ObjectArray.empty())
if (ObjectArray.empty())
return "[]";
for(auto const &i:ObjectArray) {
for (auto const &i : ObjectArray) {
Poco::JSON::Object O;
i.to_json(O);
OutputArr.add(O);
}
std::ostringstream OS;
Poco::JSON::Stringifier::condense(OutputArr,OS);
Poco::JSON::Stringifier::condense(OutputArr, OS);
return OS.str();
}
template<class T> std::string to_string(const std::vector<std::vector<T>> & ObjectArray) {
template <class T> std::string to_string(const std::vector<std::vector<T>> &ObjectArray) {
Poco::JSON::Array OutputArr;
if(ObjectArray.empty())
if (ObjectArray.empty())
return "[]";
for(auto const &i:ObjectArray) {
for (auto const &i : ObjectArray) {
Poco::JSON::Array InnerArr;
for(auto const &j:i) {
if constexpr(std::is_integral<T>::value) {
for (auto const &j : i) {
if constexpr (std::is_integral<T>::value) {
InnerArr.add(j);
} if constexpr(std::is_same_v<T,std::string>) {
}
if constexpr (std::is_same_v<T, std::string>) {
InnerArr.add(j);
} else {
InnerArr.add(j);
@@ -348,22 +374,22 @@ namespace OpenWifi::RESTAPI_utils {
OutputArr.add(InnerArr);
}
std::ostringstream OS;
Poco::JSON::Stringifier::condense(OutputArr,OS);
Poco::JSON::Stringifier::condense(OutputArr, OS);
return OS.str();
}
template<class T> std::string to_string(const T & Object) {
template <class T> std::string to_string(const T &Object) {
Poco::JSON::Object OutputObj;
Object.to_json(OutputObj);
std::ostringstream OS;
Poco::JSON::Stringifier::condense(OutputObj,OS);
Poco::JSON::Stringifier::condense(OutputObj, OS);
return OS.str();
}
inline Types::StringVec to_object_array(const std::string & ObjectString) {
inline Types::StringVec to_object_array(const std::string &ObjectString) {
Types::StringVec Result;
if(ObjectString.empty())
Types::StringVec Result;
if (ObjectString.empty())
return Result;
try {
@@ -373,14 +399,13 @@ namespace OpenWifi::RESTAPI_utils {
Result.push_back(i.toString());
}
} catch (...) {
}
return Result;
}
inline OpenWifi::Types::TagList to_taglist(const std::string & ObjectString) {
Types::TagList Result;
if(ObjectString.empty())
inline OpenWifi::Types::TagList to_taglist(const std::string &ObjectString) {
Types::TagList Result;
if (ObjectString.empty())
return Result;
try {
@@ -390,36 +415,34 @@ namespace OpenWifi::RESTAPI_utils {
Result.push_back(i);
}
} catch (...) {
}
return Result;
}
inline Types::StringPairVec to_stringpair_array(const std::string &S) {
Types::StringPairVec R;
if(S.empty())
Types::StringPairVec R;
if (S.empty())
return R;
try {
Poco::JSON::Parser P;
auto Object = P.parse(S).template extract<Poco::JSON::Array::Ptr>();
for (const auto &i : *Object) {
auto InnerObject = i.template extract<Poco::JSON::Array::Ptr>();
if(InnerObject->size()==2) {
if (InnerObject->size() == 2) {
auto S1 = InnerObject->getElement<std::string>(0);
auto S2 = InnerObject->getElement<std::string>(1);
R.push_back(std::make_pair(S1,S2));
R.push_back(std::make_pair(S1, S2));
}
}
} catch (...) {
}
return R;
}
template<class T> std::vector<T> to_object_array(const std::string & ObjectString) {
std::vector<T> Result;
if(ObjectString.empty())
template <class T> std::vector<T> to_object_array(const std::string &ObjectString) {
std::vector<T> Result;
if (ObjectString.empty())
return Result;
try {
@@ -432,14 +455,14 @@ namespace OpenWifi::RESTAPI_utils {
Result.push_back(Obj);
}
} catch (...) {
}
return Result;
}
template<class T> std::vector<std::vector<T>> to_array_of_array_of_object(const std::string & ObjectString) {
std::vector<std::vector<T>> Result;
if(ObjectString.empty())
template <class T>
std::vector<std::vector<T>> to_array_of_array_of_object(const std::string &ObjectString) {
std::vector<std::vector<T>> Result;
if (ObjectString.empty())
return Result;
try {
Poco::JSON::Parser P1;
@@ -447,8 +470,8 @@ namespace OpenWifi::RESTAPI_utils {
for (auto const &i : *OutterArray) {
Poco::JSON::Parser P2;
auto InnerArray = P2.parse(i).template extract<Poco::JSON::Array::Ptr>();
std::vector<T> InnerVector;
for(auto const &j: *InnerArray) {
std::vector<T> InnerVector;
for (auto const &j : *InnerArray) {
auto Object = j.template extract<Poco::JSON::Object::Ptr>();
T Obj;
Obj.from_json(Object);
@@ -457,28 +480,27 @@ namespace OpenWifi::RESTAPI_utils {
Result.push_back(InnerVector);
}
} catch (...) {
}
return Result;
}
template<class T> T to_object(const std::string & ObjectString) {
T Result;
template <class T> T to_object(const std::string &ObjectString) {
T Result;
if(ObjectString.empty())
if (ObjectString.empty())
return Result;
Poco::JSON::Parser P;
Poco::JSON::Parser P;
auto Object = P.parse(ObjectString).template extract<Poco::JSON::Object::Ptr>();
Result.from_json(Object);
return Result;
}
template<class T> bool from_request(T & Obj, Poco::Net::HTTPServerRequest &Request) {
template <class T> bool from_request(T &Obj, Poco::Net::HTTPServerRequest &Request) {
Poco::JSON::Parser IncomingParser;
auto RawObject = IncomingParser.parse(Request.stream()).extract<Poco::JSON::Object::Ptr>();
Obj.from_json(RawObject);
return true;
}
}
} // namespace OpenWifi::RESTAPI_utils

View File

@@ -4,137 +4,133 @@
#pragma once
#include "Poco/Data/SQLite/Connector.h"
#include "Poco/Data/Session.h"
#include "Poco/Data/SessionPool.h"
#include "Poco/Data/SQLite/Connector.h"
#include "Poco/JSON/Object.h"
#ifndef SMALL_BUILD
#include "Poco/Data/PostgreSQL/Connector.h"
#include "Poco/Data/MySQL/Connector.h"
#include "Poco/Data/PostgreSQL/Connector.h"
#endif
#include "framework/SubSystemServer.h"
#include "framework/MicroServiceFuncs.h"
#include "framework/SubSystemServer.h"
namespace OpenWifi {
enum DBType {
sqlite,
pgsql,
mysql
};
enum DBType { sqlite, pgsql, mysql };
class StorageClass : public SubSystemServer {
public:
StorageClass() noexcept:
SubSystemServer("StorageClass", "STORAGE-SVR", "storage")
{
}
class StorageClass : public SubSystemServer {
public:
StorageClass() noexcept : SubSystemServer("StorageClass", "STORAGE-SVR", "storage") {}
int Start() override {
std::lock_guard Guard(Mutex_);
int Start() override {
std::lock_guard Guard(Mutex_);
Logger().notice("Starting.");
std::string DBType = MicroServiceConfigGetString("storage.type","");
Logger().notice("Starting.");
std::string DBType = MicroServiceConfigGetString("storage.type", "");
if (DBType == "sqlite") {
Setup_SQLite();
} else if (DBType == "postgresql") {
Setup_PostgreSQL();
} else if (DBType == "mysql") {
Setup_MySQL();
}
return 0;
}
if (DBType == "sqlite") {
Setup_SQLite();
} else if (DBType == "postgresql") {
Setup_PostgreSQL();
} else if (DBType == "mysql") {
Setup_MySQL();
}
return 0;
}
void Stop() override {
Pool_->shutdown();
}
void Stop() override { Pool_->shutdown(); }
DBType Type() const { return dbType_; };
private:
inline int Setup_SQLite();
inline int Setup_MySQL();
inline int Setup_PostgreSQL();
DBType Type() const { return dbType_; };
protected:
std::unique_ptr<Poco::Data::SessionPool> Pool_;
Poco::Data::SQLite::Connector SQLiteConn_;
Poco::Data::PostgreSQL::Connector PostgresConn_;
Poco::Data::MySQL::Connector MySQLConn_;
DBType dbType_ = sqlite;
};
private:
inline int Setup_SQLite();
inline int Setup_MySQL();
inline int Setup_PostgreSQL();
#ifdef SMALL_BUILD
int Service::Setup_MySQL() { Daemon()->exit(Poco::Util::Application::EXIT_CONFIG); return 0; }
int Service::Setup_PostgreSQL() { Daemon()->exit(Poco::Util::Application::EXIT_CONFIG); return 0; }
protected:
std::unique_ptr<Poco::Data::SessionPool> Pool_;
Poco::Data::SQLite::Connector SQLiteConn_;
Poco::Data::PostgreSQL::Connector PostgresConn_;
Poco::Data::MySQL::Connector MySQLConn_;
DBType dbType_ = sqlite;
};
#ifdef SMALL_BUILD
int Service::Setup_MySQL() {
Daemon()->exit(Poco::Util::Application::EXIT_CONFIG);
return 0;
}
int Service::Setup_PostgreSQL() {
Daemon()->exit(Poco::Util::Application::EXIT_CONFIG);
return 0;
}
#else
inline int StorageClass::Setup_SQLite() {
Logger().notice("SQLite StorageClass enabled.");
dbType_ = sqlite;
auto DBName = MicroServiceDataDirectory() + "/" + MicroServiceConfigGetString("storage.type.sqlite.db","");
int NumSessions = (int) MicroServiceConfigGetInt("storage.type.sqlite.maxsessions", 64);
int IdleTime = (int) MicroServiceConfigGetInt("storage.type.sqlite.idletime", 60);
inline int StorageClass::Setup_SQLite() {
Logger().notice("SQLite StorageClass enabled.");
dbType_ = sqlite;
auto DBName = MicroServiceDataDirectory() + "/" +
MicroServiceConfigGetString("storage.type.sqlite.db", "");
int NumSessions = (int)MicroServiceConfigGetInt("storage.type.sqlite.maxsessions", 64);
int IdleTime = (int)MicroServiceConfigGetInt("storage.type.sqlite.idletime", 60);
Poco::Data::SQLite::Connector::registerConnector();
// Pool_ = std::make_unique<Poco::Data::SessionPool>(new Poco::Data::SessionPool(SQLiteConn_.name(), DBName, 8,
// (int)NumSessions, (int)IdleTime));
Pool_ = std::make_unique<Poco::Data::SessionPool>(SQLiteConn_.name(), DBName, 8,
(int)NumSessions, (int)IdleTime);
return 0;
}
Poco::Data::SQLite::Connector::registerConnector();
// Pool_ = std::make_unique<Poco::Data::SessionPool>(new
// Poco::Data::SessionPool(SQLiteConn_.name(), DBName, 8,
// (int)NumSessions,
// (int)IdleTime));
Pool_ = std::make_unique<Poco::Data::SessionPool>(SQLiteConn_.name(), DBName, 8,
(int)NumSessions, (int)IdleTime);
return 0;
}
inline int StorageClass::Setup_MySQL() {
Logger().notice("MySQL StorageClass enabled.");
dbType_ = mysql;
int NumSessions = (int) MicroServiceConfigGetInt("storage.type.mysql.maxsessions", 64);
int IdleTime = (int) MicroServiceConfigGetInt("storage.type.mysql.idletime", 60);
auto Host = MicroServiceConfigGetString("storage.type.mysql.host","");
auto Username = MicroServiceConfigGetString("storage.type.mysql.username","");
auto Password = MicroServiceConfigGetString("storage.type.mysql.password","");
auto Database = MicroServiceConfigGetString("storage.type.mysql.database","");
auto Port = MicroServiceConfigGetString("storage.type.mysql.port","");
inline int StorageClass::Setup_MySQL() {
Logger().notice("MySQL StorageClass enabled.");
dbType_ = mysql;
int NumSessions = (int)MicroServiceConfigGetInt("storage.type.mysql.maxsessions", 64);
int IdleTime = (int)MicroServiceConfigGetInt("storage.type.mysql.idletime", 60);
auto Host = MicroServiceConfigGetString("storage.type.mysql.host", "");
auto Username = MicroServiceConfigGetString("storage.type.mysql.username", "");
auto Password = MicroServiceConfigGetString("storage.type.mysql.password", "");
auto Database = MicroServiceConfigGetString("storage.type.mysql.database", "");
auto Port = MicroServiceConfigGetString("storage.type.mysql.port", "");
std::string ConnectionStr =
"host=" + Host +
";user=" + Username +
";password=" + Password +
";db=" + Database +
";port=" + Port +
";compress=true;auto-reconnect=true";
std::string ConnectionStr = "host=" + Host + ";user=" + Username + ";password=" + Password +
";db=" + Database + ";port=" + Port +
";compress=true;auto-reconnect=true";
Poco::Data::MySQL::Connector::registerConnector();
Pool_ = std::make_unique<Poco::Data::SessionPool>(MySQLConn_.name(), ConnectionStr, 8, NumSessions, IdleTime);
Poco::Data::MySQL::Connector::registerConnector();
Pool_ = std::make_unique<Poco::Data::SessionPool>(MySQLConn_.name(), ConnectionStr, 8,
NumSessions, IdleTime);
return 0;
}
return 0;
}
inline int StorageClass::Setup_PostgreSQL() {
Logger().notice("PostgreSQL StorageClass enabled.");
dbType_ = pgsql;
int NumSessions = (int) MicroServiceConfigGetInt("storage.type.postgresql.maxsessions", 64);
int IdleTime = (int) MicroServiceConfigGetInt("storage.type.postgresql.idletime", 60);
auto Host = MicroServiceConfigGetString("storage.type.postgresql.host", "");
auto Username = MicroServiceConfigGetString("storage.type.postgresql.username", "");
auto Password = MicroServiceConfigGetString("storage.type.postgresql.password", "");
auto Database = MicroServiceConfigGetString("storage.type.postgresql.database", "");
auto Port = MicroServiceConfigGetString("storage.type.postgresql.port", "");
auto ConnectionTimeout = MicroServiceConfigGetString("storage.type.postgresql.connectiontimeout", "");
inline int StorageClass::Setup_PostgreSQL() {
Logger().notice("PostgreSQL StorageClass enabled.");
dbType_ = pgsql;
int NumSessions = (int)MicroServiceConfigGetInt("storage.type.postgresql.maxsessions", 64);
int IdleTime = (int)MicroServiceConfigGetInt("storage.type.postgresql.idletime", 60);
auto Host = MicroServiceConfigGetString("storage.type.postgresql.host", "");
auto Username = MicroServiceConfigGetString("storage.type.postgresql.username", "");
auto Password = MicroServiceConfigGetString("storage.type.postgresql.password", "");
auto Database = MicroServiceConfigGetString("storage.type.postgresql.database", "");
auto Port = MicroServiceConfigGetString("storage.type.postgresql.port", "");
auto ConnectionTimeout =
MicroServiceConfigGetString("storage.type.postgresql.connectiontimeout", "");
std::string ConnectionStr =
"host=" + Host +
" user=" + Username +
" password=" + Password +
" dbname=" + Database +
" port=" + Port +
" connect_timeout=" + ConnectionTimeout;
std::string ConnectionStr = "host=" + Host + " user=" + Username + " password=" + Password +
" dbname=" + Database + " port=" + Port +
" connect_timeout=" + ConnectionTimeout;
Poco::Data::PostgreSQL::Connector::registerConnector();
Pool_ = std::make_unique<Poco::Data::SessionPool>(PostgresConn_.name(), ConnectionStr, 8, NumSessions, IdleTime);
Poco::Data::PostgreSQL::Connector::registerConnector();
Pool_ = std::make_unique<Poco::Data::SessionPool>(PostgresConn_.name(), ConnectionStr, 8,
NumSessions, IdleTime);
return 0;
}
return 0;
}
#endif
}
} // namespace OpenWifi

View File

@@ -6,36 +6,29 @@
#include "framework/SubSystemServer.h"
#include "Poco/Net/SSLManager.h"
#include "Poco/DateTimeFormatter.h"
#include "Poco/DateTimeFormat.h"
#include "Poco/DateTimeFormatter.h"
#include "Poco/Net/SSLManager.h"
#include "framework/MicroServiceFuncs.h"
namespace OpenWifi {
PropertiesFileServerEntry::PropertiesFileServerEntry(std::string Address, uint32_t port, std::string Key_file,
std::string Cert_file, std::string RootCa, std::string Issuer,
std::string ClientCas, std::string Cas,
std::string Key_file_password, std::string Name,
Poco::Net::Context::VerificationMode M,
int backlog)
: address_(std::move(Address)),
port_(port),
cert_file_(std::move(Cert_file)),
key_file_(std::move(Key_file)),
root_ca_(std::move(RootCa)),
key_file_password_(std::move(Key_file_password)),
issuer_cert_file_(std::move(Issuer)),
client_cas_(std::move(ClientCas)),
cas_(std::move(Cas)),
name_(std::move(Name)),
backlog_(backlog),
level_(M) {
PropertiesFileServerEntry::PropertiesFileServerEntry(
std::string Address, uint32_t port, std::string Key_file, std::string Cert_file,
std::string RootCa, std::string Issuer, std::string ClientCas, std::string Cas,
std::string Key_file_password, std::string Name, Poco::Net::Context::VerificationMode M,
int backlog)
: address_(std::move(Address)), port_(port), cert_file_(std::move(Cert_file)),
key_file_(std::move(Key_file)), root_ca_(std::move(RootCa)),
key_file_password_(std::move(Key_file_password)), issuer_cert_file_(std::move(Issuer)),
client_cas_(std::move(ClientCas)), cas_(std::move(Cas)), name_(std::move(Name)),
backlog_(backlog), level_(M){
};
};
[[nodiscard]] Poco::Net::SecureServerSocket PropertiesFileServerEntry::CreateSecureSocket(Poco::Logger &L) const {
[[nodiscard]] Poco::Net::SecureServerSocket
PropertiesFileServerEntry::CreateSecureSocket(Poco::Logger &L) const {
Poco::Net::Context::Params P;
P.verificationMode = level_;
@@ -45,11 +38,13 @@ namespace OpenWifi {
P.dhUse2048Bits = true;
P.caLocation = cas_;
auto Context = Poco::AutoPtr<Poco::Net::Context>(new Poco::Net::Context(Poco::Net::Context::TLS_SERVER_USE, P));
auto Context = Poco::AutoPtr<Poco::Net::Context>(
new Poco::Net::Context(Poco::Net::Context::TLS_SERVER_USE, P));
if(!key_file_password_.empty()) {
auto PassphraseHandler = Poco::SharedPtr<MyPrivateKeyPassphraseHandler>( new MyPrivateKeyPassphraseHandler(key_file_password_,L));
Poco::Net::SSLManager::instance().initializeServer(PassphraseHandler, nullptr,Context);
if (!key_file_password_.empty()) {
auto PassphraseHandler = Poco::SharedPtr<MyPrivateKeyPassphraseHandler>(
new MyPrivateKeyPassphraseHandler(key_file_password_, L));
Poco::Net::SSLManager::instance().initializeServer(PassphraseHandler, nullptr, Context);
}
if (!cert_file_.empty() && !key_file_.empty()) {
@@ -111,7 +106,8 @@ namespace OpenWifi {
}
}
[[nodiscard]] Poco::Net::ServerSocket PropertiesFileServerEntry::CreateSocket([[maybe_unused]] Poco::Logger &L) const {
[[nodiscard]] Poco::Net::ServerSocket
PropertiesFileServerEntry::CreateSocket([[maybe_unused]] Poco::Logger &L) const {
Poco::Net::Context::Params P;
if (address_ == "*") {
@@ -127,20 +123,25 @@ namespace OpenWifi {
}
}
void PropertiesFileServerEntry::LogCertInfo(Poco::Logger &L, const Poco::Crypto::X509Certificate &C) const {
L.information("=============================================================================================");
void PropertiesFileServerEntry::LogCertInfo(Poco::Logger &L,
const Poco::Crypto::X509Certificate &C) const {
L.information("============================================================================"
"=================");
L.information(fmt::format("> Issuer: {}", C.issuerName()));
L.information("---------------------------------------------------------------------------------------------");
L.information("----------------------------------------------------------------------------"
"-----------------");
L.information(fmt::format("> Common Name: {}",
C.issuerName(Poco::Crypto::X509Certificate::NID_COMMON_NAME)));
L.information(fmt::format("> Country: {}",
C.issuerName(Poco::Crypto::X509Certificate::NID_COUNTRY)));
L.information(fmt::format("> Locality: {}",
C.issuerName(Poco::Crypto::X509Certificate::NID_LOCALITY_NAME)));
L.information(fmt::format("> State/Prov: {}",
C.issuerName(Poco::Crypto::X509Certificate::NID_STATE_OR_PROVINCE)));
L.information(fmt::format("> Org name: {}",
C.issuerName(Poco::Crypto::X509Certificate::NID_ORGANIZATION_NAME)));
L.information(
fmt::format("> State/Prov: {}",
C.issuerName(Poco::Crypto::X509Certificate::NID_STATE_OR_PROVINCE)));
L.information(
fmt::format("> Org name: {}",
C.issuerName(Poco::Crypto::X509Certificate::NID_ORGANIZATION_NAME)));
L.information(
fmt::format("> Org unit: {}",
C.issuerName(Poco::Crypto::X509Certificate::NID_ORGANIZATION_UNIT_NAME)));
@@ -149,9 +150,11 @@ namespace OpenWifi {
C.issuerName(Poco::Crypto::X509Certificate::NID_PKCS9_EMAIL_ADDRESS)));
L.information(fmt::format("> Serial#: {}",
C.issuerName(Poco::Crypto::X509Certificate::NID_SERIAL_NUMBER)));
L.information("---------------------------------------------------------------------------------------------");
L.information("----------------------------------------------------------------------------"
"-----------------");
L.information(fmt::format("> Subject: {}", C.subjectName()));
L.information("---------------------------------------------------------------------------------------------");
L.information("----------------------------------------------------------------------------"
"-----------------");
L.information(fmt::format("> Common Name: {}",
C.subjectName(Poco::Crypto::X509Certificate::NID_COMMON_NAME)));
L.information(fmt::format("> Country: {}",
@@ -172,52 +175,66 @@ namespace OpenWifi {
C.subjectName(Poco::Crypto::X509Certificate::NID_PKCS9_EMAIL_ADDRESS)));
L.information(fmt::format("> Serial#: {}",
C.subjectName(Poco::Crypto::X509Certificate::NID_SERIAL_NUMBER)));
L.information("---------------------------------------------------------------------------------------------");
L.information("----------------------------------------------------------------------------"
"-----------------");
L.information(fmt::format("> Signature Algo: {}", C.signatureAlgorithm()));
auto From = Poco::DateTimeFormatter::format(C.validFrom(), Poco::DateTimeFormat::HTTP_FORMAT);
auto From =
Poco::DateTimeFormatter::format(C.validFrom(), Poco::DateTimeFormat::HTTP_FORMAT);
L.information(fmt::format("> Valid from: {}", From));
auto Expires =
Poco::DateTimeFormatter::format(C.expiresOn(), Poco::DateTimeFormat::HTTP_FORMAT);
L.information(fmt::format("> Expires on: {}", Expires));
L.information(fmt::format("> Version: {}", (int)C.version()));
L.information(fmt::format("> Serial #: {}", C.serialNumber()));
L.information("=============================================================================================");
L.information("============================================================================"
"=================");
}
void PropertiesFileServerEntry::LogCert(Poco::Logger &L) const {
try {
Poco::Crypto::X509Certificate C(cert_file_);
L.information("=============================================================================================");
L.information("=============================================================================================");
L.information("========================================================================"
"=====================");
L.information("========================================================================"
"=====================");
L.information(fmt::format("Certificate Filename: {}", cert_file_));
LogCertInfo(L, C);
L.information("=============================================================================================");
L.information("========================================================================"
"=====================");
if (!issuer_cert_file_.empty()) {
Poco::Crypto::X509Certificate C1(issuer_cert_file_);
L.information("=============================================================================================");
L.information("=============================================================================================");
L.information("===================================================================="
"=========================");
L.information("===================================================================="
"=========================");
L.information(fmt::format("Issues Certificate Filename: {}", issuer_cert_file_));
LogCertInfo(L, C1);
L.information("=============================================================================================");
L.information("===================================================================="
"=========================");
}
if (!client_cas_.empty()) {
std::vector<Poco::Crypto::X509Certificate> Certs =
Poco::Net::X509Certificate::readPEM(client_cas_);
L.information("=============================================================================================");
L.information("=============================================================================================");
L.information("===================================================================="
"=========================");
L.information("===================================================================="
"=========================");
L.information(fmt::format("Client CAs Filename: {}", client_cas_));
L.information("=============================================================================================");
L.information("===================================================================="
"=========================");
auto i = 1;
for (const auto &C3 : Certs) {
L.information(fmt::format(" Index: {}", i));
L.information("=============================================================================================");
L.information("================================================================"
"=============================");
LogCertInfo(L, C3);
i++;
}
L.information("=============================================================================================");
L.information("===================================================================="
"=========================");
}
} catch (const Poco::Exception &E) {
@@ -230,28 +247,31 @@ namespace OpenWifi {
std::vector<Poco::Crypto::X509Certificate> Certs =
Poco::Net::X509Certificate::readPEM(root_ca_);
L.information("=============================================================================================");
L.information("=============================================================================================");
L.information("========================================================================"
"=====================");
L.information("========================================================================"
"=====================");
L.information(fmt::format("CA Filename: {}", root_ca_));
L.information("=============================================================================================");
L.information("========================================================================"
"=====================");
auto i = 1;
for (const auto &C : Certs) {
L.information(fmt::format(" Index: {}", i));
L.information("=============================================================================================");
L.information("===================================================================="
"=========================");
LogCertInfo(L, C);
i++;
}
L.information("=============================================================================================");
L.information("========================================================================"
"=====================");
} catch (const Poco::Exception &E) {
L.log(E);
}
}
SubSystemServer::SubSystemServer(const std::string &Name, const std::string &LoggingPrefix,
const std::string &SubSystemConfigPrefix):
Name_(Name),
LoggerPrefix_(LoggingPrefix),
SubSystemConfigPrefix_(SubSystemConfigPrefix) {
const std::string &SubSystemConfigPrefix)
: Name_(Name), LoggerPrefix_(LoggingPrefix), SubSystemConfigPrefix_(SubSystemConfigPrefix) {
}
void SubSystemServer::initialize([[maybe_unused]] Poco::Util::Application &self) {
@@ -259,10 +279,13 @@ namespace OpenWifi {
bool good = true;
auto NewLevel = MicroServiceConfigGetString("logging.level." + Name_, "");
if(NewLevel.empty())
Logger_ = std::make_unique<LoggerWrapper>(Poco::Logger::create(LoggerPrefix_, Poco::Logger::root().getChannel(), Poco::Logger::root().getLevel()));
if (NewLevel.empty())
Logger_ = std::make_unique<LoggerWrapper>(Poco::Logger::create(
LoggerPrefix_, Poco::Logger::root().getChannel(), Poco::Logger::root().getLevel()));
else
Logger_ = std::make_unique<LoggerWrapper>(Poco::Logger::create(LoggerPrefix_, Poco::Logger::root().getChannel(), Poco::Logger::parseLevel(NewLevel)));
Logger_ = std::make_unique<LoggerWrapper>(
Poco::Logger::create(LoggerPrefix_, Poco::Logger::root().getChannel(),
Poco::Logger::parseLevel(NewLevel)));
ConfigServersList_.clear();
while (good) {
@@ -297,24 +320,18 @@ namespace OpenWifi {
} else if (L == "once")
M = Poco::Net::Context::VERIFY_ONCE;
PropertiesFileServerEntry entry(MicroServiceConfigGetString(address, ""),
MicroServiceConfigGetInt(port, 0),
MicroServiceConfigPath(key, ""),
MicroServiceConfigPath(cert, ""),
MicroServiceConfigPath(rootca, ""),
MicroServiceConfigPath(issuer, ""),
MicroServiceConfigPath(clientcas, ""),
MicroServiceConfigPath(cas, ""),
MicroServiceConfigGetString(key_password, ""),
MicroServiceConfigGetString(name, ""), M,
(int)MicroServiceConfigGetInt(backlog, 64));
PropertiesFileServerEntry entry(
MicroServiceConfigGetString(address, ""), MicroServiceConfigGetInt(port, 0),
MicroServiceConfigPath(key, ""), MicroServiceConfigPath(cert, ""),
MicroServiceConfigPath(rootca, ""), MicroServiceConfigPath(issuer, ""),
MicroServiceConfigPath(clientcas, ""), MicroServiceConfigPath(cas, ""),
MicroServiceConfigGetString(key_password, ""),
MicroServiceConfigGetString(name, ""), M,
(int)MicroServiceConfigGetInt(backlog, 64));
ConfigServersList_.push_back(entry);
i++;
}
}
}
} // namespace OpenWifi

View File

@@ -4,32 +4,30 @@
#pragma once
#include <string>
#include <mutex>
#include <string>
#include "Poco/Util/Application.h"
#include "Poco/Net/Context.h"
#include "Poco/Net/SecureServerSocket.h"
#include "Poco/Net/PrivateKeyPassphraseHandler.h"
#include "Poco/Net/SecureServerSocket.h"
#include "Poco/Util/Application.h"
namespace OpenWifi {
class MyPrivateKeyPassphraseHandler : public Poco::Net::PrivateKeyPassphraseHandler {
public:
explicit MyPrivateKeyPassphraseHandler(const std::string &Password, Poco::Logger & Logger):
PrivateKeyPassphraseHandler(true),
Password_(Password),
Logger_(Logger) {
}
explicit MyPrivateKeyPassphraseHandler(const std::string &Password, Poco::Logger &Logger)
: PrivateKeyPassphraseHandler(true), Password_(Password), Logger_(Logger) {}
void onPrivateKeyRequested([[maybe_unused]] const void * pSender,std::string & privateKey) {
poco_information(Logger_,"Returning key passphrase.");
void onPrivateKeyRequested([[maybe_unused]] const void *pSender, std::string &privateKey) {
poco_information(Logger_, "Returning key passphrase.");
privateKey = Password_;
};
inline Poco::Logger & Logger() { return Logger_; }
inline Poco::Logger &Logger() { return Logger_; }
private:
std::string Password_;
Poco::Logger & Logger_;
Poco::Logger &Logger_;
};
class PropertiesFileServerEntry {
@@ -76,24 +74,24 @@ namespace OpenWifi {
class SubSystemServer : public Poco::Util::Application::Subsystem {
public:
SubSystemServer(const std::string & Name, const std::string &LoggingPrefix,
const std::string & SubSystemConfigPrefix);
SubSystemServer(const std::string &Name, const std::string &LoggingPrefix,
const std::string &SubSystemConfigPrefix);
void initialize(Poco::Util::Application &self) override;
inline void uninitialize() override {
}
inline void uninitialize() override {}
inline void reinitialize([[maybe_unused]] Poco::Util::Application &self) override {
poco_information(Logger_->L_,"Reloading of this subsystem is not supported.");
poco_information(Logger_->L_, "Reloading of this subsystem is not supported.");
}
inline void defineOptions([[maybe_unused]] Poco::Util::OptionSet &options) override {
}
inline const std::string & Name() const { return Name_; };
inline const char * name() const override { return Name_.c_str(); }
inline void defineOptions([[maybe_unused]] Poco::Util::OptionSet &options) override {}
inline const std::string &Name() const { return Name_; };
inline const char *name() const override { return Name_.c_str(); }
inline const PropertiesFileServerEntry & Host(uint64_t index) { return ConfigServersList_[index]; };
inline const PropertiesFileServerEntry &Host(uint64_t index) {
return ConfigServersList_[index];
};
inline uint64_t HostSize() const { return ConfigServersList_.size(); }
inline Poco::Logger & Logger() const { return Logger_->L_; }
inline void SetLoggingLevel(const std::string & levelName) {
inline Poco::Logger &Logger() const { return Logger_->L_; }
inline void SetLoggingLevel(const std::string &levelName) {
Logger_->L_.setLevel(Poco::Logger::parseLevel(levelName));
}
inline int GetLoggingLevel() { return Logger_->L_.getLevel(); }
@@ -102,23 +100,21 @@ namespace OpenWifi {
virtual void Stop() = 0;
struct LoggerWrapper {
Poco::Logger & L_;
LoggerWrapper(Poco::Logger &L) :
L_(L) {
}
Poco::Logger &L_;
LoggerWrapper(Poco::Logger &L) : L_(L) {}
};
protected:
std::recursive_mutex Mutex_;
std::recursive_mutex Mutex_;
std::vector<PropertiesFileServerEntry> ConfigServersList_;
private:
std::unique_ptr<LoggerWrapper> Logger_;
std::string Name_;
std::string LoggerPrefix_;
std::string SubSystemConfigPrefix_;
std::unique_ptr<LoggerWrapper> Logger_;
std::string Name_;
std::string LoggerPrefix_;
std::string SubSystemConfigPrefix_;
};
typedef std::vector<SubSystemServer *> SubSystemVec;
typedef std::vector<SubSystemServer *> SubSystemVec;
} // namespace OpenWifi

View File

@@ -5,7 +5,4 @@
#include "framework/UI_WebSocketClientNotifications.h"
#include "framework/UI_WebSocketClientServer.h"
namespace OpenWifi {
}
namespace OpenWifi {}

View File

@@ -9,37 +9,35 @@
namespace OpenWifi {
template<typename ContentStruct>
template <typename ContentStruct>
struct WebSocketNotification {
inline static uint64_t xid = 1;
uint64_t notification_id = ++xid;
std::uint64_t type_id=0;
ContentStruct content;
struct WebSocketNotification {
inline static uint64_t xid = 1;
uint64_t notification_id = ++xid;
std::uint64_t type_id = 0;
ContentStruct content;
void to_json(Poco::JSON::Object &Obj) const;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
template<typename ContentStruct>
void WebSocketNotification<ContentStruct>::to_json(Poco::JSON::Object &Obj) const {
RESTAPI_utils::field_to_json(Obj, "notification_id", notification_id);
template <typename ContentStruct>
void WebSocketNotification<ContentStruct>::to_json(Poco::JSON::Object &Obj) const {
RESTAPI_utils::field_to_json(Obj, "notification_id", notification_id);
RESTAPI_utils::field_to_json(Obj, "type_id", type_id);
RESTAPI_utils::field_to_json(Obj, "content", content);
}
RESTAPI_utils::field_to_json(Obj, "content", content);
}
template<typename ContentStruct>
bool WebSocketNotification<ContentStruct>::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
RESTAPI_utils::field_from_json(Obj, "notification_id", notification_id);
template <typename ContentStruct>
bool WebSocketNotification<ContentStruct>::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
RESTAPI_utils::field_from_json(Obj, "notification_id", notification_id);
RESTAPI_utils::field_from_json(Obj, "type_id", type_id);
RESTAPI_utils::field_from_json(Obj, "content", content);
return true;
} catch (...) {
}
return false;
}
}
return true;
} catch (...) {
}
return false;
}
} // namespace OpenWifi

View File

@@ -4,14 +4,14 @@
#include <mutex>
#include "Poco/NObserver.h"
#include "Poco/JSON/JSONException.h"
#include "Poco/JSON/Parser.h"
#include "Poco/Logger.h"
#include "Poco/NObserver.h"
#include "framework/UI_WebSocketClientServer.h"
#include "framework/AuthClient.h"
#include "framework/MicroServiceFuncs.h"
#include "framework/UI_WebSocketClientServer.h"
#include "fmt/format.h"
@@ -19,80 +19,82 @@
#include "AuthService.h"
#endif
#define DBG { std::cout << __LINE__ << std::endl; }
#define DBG \
{ std::cout << __LINE__ << std::endl; }
namespace OpenWifi {
void UI_WebSocketClientServer::NewClient(Poco::Net::WebSocket & WS, const std::string &Id, const std::string &UserName, std::uint64_t TID ) {
void UI_WebSocketClientServer::NewClient(Poco::Net::WebSocket &WS, const std::string &Id,
const std::string &UserName, std::uint64_t TID) {
std::lock_guard G(LocalMutex_);
auto Client = std::make_unique<UI_WebSocketClientInfo>(WS,Id, UserName);
auto ClientSocket = Client->WS_->impl()->sockfd();
TID_ = TID;
Client->WS_->setNoDelay(true);
Client->WS_->setKeepAlive(true);
Client->WS_->setBlocking(false);
Reactor_.addEventHandler(*Client->WS_,
Poco::NObserver<UI_WebSocketClientServer, Poco::Net::ReadableNotification>(
*this, &UI_WebSocketClientServer::OnSocketReadable));
Reactor_.addEventHandler(*Client->WS_,
Poco::NObserver<UI_WebSocketClientServer, Poco::Net::ShutdownNotification>(
*this, &UI_WebSocketClientServer::OnSocketShutdown));
Reactor_.addEventHandler(*Client->WS_,
Poco::NObserver<UI_WebSocketClientServer, Poco::Net::ErrorNotification>(
*this, &UI_WebSocketClientServer::OnSocketError));
Client->SocketRegistered_ = true;
Clients_[ClientSocket] = std::move(Client);
std::lock_guard G(LocalMutex_);
auto Client = std::make_unique<UI_WebSocketClientInfo>(WS, Id, UserName);
auto ClientSocket = Client->WS_->impl()->sockfd();
TID_ = TID;
Client->WS_->setNoDelay(true);
Client->WS_->setKeepAlive(true);
Client->WS_->setBlocking(false);
Reactor_.addEventHandler(
*Client->WS_,
Poco::NObserver<UI_WebSocketClientServer, Poco::Net::ReadableNotification>(
*this, &UI_WebSocketClientServer::OnSocketReadable));
Reactor_.addEventHandler(
*Client->WS_,
Poco::NObserver<UI_WebSocketClientServer, Poco::Net::ShutdownNotification>(
*this, &UI_WebSocketClientServer::OnSocketShutdown));
Reactor_.addEventHandler(
*Client->WS_, Poco::NObserver<UI_WebSocketClientServer, Poco::Net::ErrorNotification>(
*this, &UI_WebSocketClientServer::OnSocketError));
Client->SocketRegistered_ = true;
Clients_[ClientSocket] = std::move(Client);
UsersConnected_ = Clients_.size();
}
void UI_WebSocketClientServer::SetProcessor( UI_WebSocketClientProcessor * F) {
Processor_ = F;
}
UI_WebSocketClientServer::UI_WebSocketClientServer() noexcept:
SubSystemServer("WebSocketClientServer", "UI-WSCLNT-SVR", "websocketclients")
{
}
void UI_WebSocketClientServer::SetProcessor(UI_WebSocketClientProcessor *F) { Processor_ = F; }
UI_WebSocketClientServer::UI_WebSocketClientServer() noexcept
: SubSystemServer("WebSocketClientServer", "UI-WSCLNT-SVR", "websocketclients") {}
void UI_WebSocketClientServer::run() {
Running_ = true;
while(Running_) {
while (Running_) {
Poco::Thread::trySleep(2000);
if(!Running_)
if (!Running_)
break;
std::lock_guard G(LocalMutex_);
for(const auto i:ToBeRemoved_) {
std::lock_guard G(LocalMutex_);
for (const auto i : ToBeRemoved_) {
// std::cout << "Erasing old WS UI connection..." << std::endl;
Clients_.erase(i);
}
ToBeRemoved_.clear();
ToBeRemoved_.clear();
UsersConnected_ = Clients_.size();
}
}
void UI_WebSocketClientServer::EndConnection(ClientList::iterator Client) {
if(Client->second->SocketRegistered_) {
Client->second->SocketRegistered_ = false;
Reactor_.removeEventHandler(*Client->second->WS_,
Poco::NObserver<UI_WebSocketClientServer,
Poco::Net::ReadableNotification>(*this,&UI_WebSocketClientServer::OnSocketReadable));
Reactor_.removeEventHandler(*Client->second->WS_,
Poco::NObserver<UI_WebSocketClientServer,
Poco::Net::ShutdownNotification>(*this,&UI_WebSocketClientServer::OnSocketShutdown));
Reactor_.removeEventHandler(*Client->second->WS_,
Poco::NObserver<UI_WebSocketClientServer,
Poco::Net::ErrorNotification>(*this,&UI_WebSocketClientServer::OnSocketError));
}
void UI_WebSocketClientServer::EndConnection(ClientList::iterator Client) {
if (Client->second->SocketRegistered_) {
Client->second->SocketRegistered_ = false;
Reactor_.removeEventHandler(
*Client->second->WS_,
Poco::NObserver<UI_WebSocketClientServer, Poco::Net::ReadableNotification>(
*this, &UI_WebSocketClientServer::OnSocketReadable));
Reactor_.removeEventHandler(
*Client->second->WS_,
Poco::NObserver<UI_WebSocketClientServer, Poco::Net::ShutdownNotification>(
*this, &UI_WebSocketClientServer::OnSocketShutdown));
Reactor_.removeEventHandler(
*Client->second->WS_,
Poco::NObserver<UI_WebSocketClientServer, Poco::Net::ErrorNotification>(
*this, &UI_WebSocketClientServer::OnSocketError));
}
ToBeRemoved_.push_back(Client);
}
}
int UI_WebSocketClientServer::Start() {
poco_information(Logger(),"Starting...");
GoogleApiKey_ = MicroServiceConfigGetString("google.apikey","");
poco_information(Logger(), "Starting...");
GoogleApiKey_ = MicroServiceConfigGetString("google.apikey", "");
GeoCodeEnabled_ = !GoogleApiKey_.empty();
ReactorThread_.start(Reactor_);
ReactorThread_.setName("ws:ui-reactor");
@@ -102,29 +104,31 @@ namespace OpenWifi {
};
void UI_WebSocketClientServer::Stop() {
if(Running_) {
poco_information(Logger(),"Stopping...");
Clients_.clear();
if (Running_) {
poco_information(Logger(), "Stopping...");
Clients_.clear();
Reactor_.stop();
ReactorThread_.join();
Running_ = false;
CleanerThread_.wakeUp();
CleanerThread_.join();
poco_information(Logger(),"Stopped...");
poco_information(Logger(), "Stopped...");
}
};
bool UI_WebSocketClientServer::IsFiltered(std::uint64_t id, const OpenWifi::UI_WebSocketClientInfo &Client) {
return std::find(Client.Filter_.begin(), Client.Filter_.end(),id)!=end(Client.Filter_);
bool UI_WebSocketClientServer::IsFiltered(std::uint64_t id,
const OpenWifi::UI_WebSocketClientInfo &Client) {
return std::find(Client.Filter_.begin(), Client.Filter_.end(), id) != end(Client.Filter_);
}
bool UI_WebSocketClientServer::SendToUser(const std::string &UserName, std::uint64_t id, const std::string &Payload) {
bool UI_WebSocketClientServer::SendToUser(const std::string &UserName, std::uint64_t id,
const std::string &Payload) {
std::lock_guard G(LocalMutex_);
for(const auto &Client:Clients_) {
if(Client.second->UserName_ == UserName) {
for (const auto &Client : Clients_) {
if (Client.second->UserName_ == UserName) {
try {
if(!IsFiltered(id,*Client.second) && Client.second->Authenticated_) {
if (!IsFiltered(id, *Client.second) && Client.second->Authenticated_) {
return Client.second->WS_->sendFrame(
Payload.c_str(), (int)Payload.size()) == (int)Payload.size();
} else {
@@ -141,31 +145,32 @@ namespace OpenWifi {
void UI_WebSocketClientServer::SendToAll(std::uint64_t id, const std::string &Payload) {
std::lock_guard G(LocalMutex_);
for(const auto &Client:Clients_) {
for (const auto &Client : Clients_) {
try {
if(!IsFiltered(id,*Client.second) && Client.second->Authenticated_)
Client.second->WS_->sendFrame(Payload.c_str(),(int)Payload.size());
if (!IsFiltered(id, *Client.second) && Client.second->Authenticated_)
Client.second->WS_->sendFrame(Payload.c_str(), (int)Payload.size());
} catch (...) {
}
}
}
UI_WebSocketClientServer::ClientList::iterator UI_WebSocketClientServer::FindWSClient( [[maybe_unused]] std::lock_guard<std::recursive_mutex> &G, int ClientSocket) {
return Clients_.find(ClientSocket);
}
UI_WebSocketClientServer::ClientList::iterator UI_WebSocketClientServer::FindWSClient(
[[maybe_unused]] std::lock_guard<std::recursive_mutex> &G, int ClientSocket) {
return Clients_.find(ClientSocket);
}
void UI_WebSocketClientServer::SortNotifications() {
struct {
bool operator()(const NotificationEntry &A, const NotificationEntry & B) const {
return A.id < B.id; };
bool operator()(const NotificationEntry &A, const NotificationEntry &B) const {
return A.id < B.id;
};
} CompareNotifications;
std::sort(NotificationTypes_.begin(), NotificationTypes_.end(), CompareNotifications);
NotificationTypesJSON_.clear();
Poco::JSON::Array AllNotifications;
for(const auto &notification:NotificationTypes_) {
Poco::JSON::Object Notification;
Poco::JSON::Array AllNotifications;
for (const auto &notification : NotificationTypes_) {
Poco::JSON::Object Notification;
Notification.set("id", notification.id);
Notification.set("helper", notification.helper);
AllNotifications.add(Notification);
@@ -173,52 +178,60 @@ namespace OpenWifi {
NotificationTypesJSON_.set("notificationTypes", AllNotifications);
}
void UI_WebSocketClientServer::RegisterNotifications(const OpenWifi::UI_WebSocketClientServer::NotificationTypeIdVec &Notifications) {
std::copy(Notifications.begin(), Notifications.end(), std::back_inserter(NotificationTypes_));
void UI_WebSocketClientServer::RegisterNotifications(
const OpenWifi::UI_WebSocketClientServer::NotificationTypeIdVec &Notifications) {
std::copy(Notifications.begin(), Notifications.end(),
std::back_inserter(NotificationTypes_));
SortNotifications();
}
void UI_WebSocketClientServer::OnSocketError([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf) {
std::lock_guard G(LocalMutex_);
auto Client = Clients_.find(pNf->socket().impl()->sockfd());
if(Client==end(Clients_))
return;
EndConnection(Client);
void UI_WebSocketClientServer::OnSocketError(
[[maybe_unused]] const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf) {
std::lock_guard G(LocalMutex_);
auto Client = Clients_.find(pNf->socket().impl()->sockfd());
if (Client == end(Clients_))
return;
EndConnection(Client);
}
void UI_WebSocketClientServer::OnSocketReadable([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
void UI_WebSocketClientServer::OnSocketReadable(
[[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
UI_WebSocketClientServer::ClientList::iterator Client;
std::lock_guard G(LocalMutex_);
UI_WebSocketClientServer::ClientList::iterator Client;
std::lock_guard G(LocalMutex_);
try {
Client = Clients_.find(pNf->socket().impl()->sockfd());
if( Client == end(Clients_))
return;
Client = Clients_.find(pNf->socket().impl()->sockfd());
if (Client == end(Clients_))
return;
Poco::Buffer<char> IncomingFrame(0);
int flags;
int n;
int flags;
int n;
n = Client->second->WS_->receiveFrame(IncomingFrame, flags);
auto Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK;
if (n == 0) {
poco_debug(Logger(),fmt::format("CLOSE({}): {} UI Client is closing WS connection.", Client->second->Id_, Client->second->UserName_));
poco_debug(Logger(),
fmt::format("CLOSE({}): {} UI Client is closing WS connection.",
Client->second->Id_, Client->second->UserName_));
return EndConnection(Client);
}
switch (Op) {
case Poco::Net::WebSocket::FRAME_OP_PING: {
Client->second->WS_->sendFrame("", 0,
(int)Poco::Net::WebSocket::FRAME_OP_PONG |
(int)Poco::Net::WebSocket::FRAME_FLAG_FIN);
Client->second->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: {
poco_debug(Logger(),fmt::format("CLOSE({}): {} UI Client is closing WS connection.", Client->second->Id_, Client->second->UserName_));
return EndConnection(Client);
poco_debug(Logger(),
fmt::format("CLOSE({}): {} UI Client is closing WS connection.",
Client->second->Id_, Client->second->UserName_));
return EndConnection(Client);
} break;
case Poco::Net::WebSocket::FRAME_OP_TEXT: {
constexpr const char *DropMessagesCommand = "drop-notifications";
@@ -228,80 +241,84 @@ namespace OpenWifi {
auto Tokens = Utils::Split(Frame, ':');
bool Expired = false;
#if not defined(TIP_SECURITY_SERVICE)
bool Contacted = false;
bool Contacted = false;
#endif
if (Tokens.size() == 2 &&
#if defined(TIP_SECURITY_SERVICE)
AuthService()->IsAuthorized(Tokens[1], Client->second->UserInfo_, TID_, Expired)) {
AuthService()->IsAuthorized(Tokens[1], Client->second->UserInfo_, TID_,
Expired)) {
#else
AuthClient()->IsAuthorized(Tokens[1], Client->second->UserInfo_, TID_, Expired, Contacted)) {
AuthClient()->IsAuthorized(Tokens[1], Client->second->UserInfo_, TID_,
Expired, Contacted)) {
#endif
Client->second->Authenticated_ = true;
Client->second->UserName_ = Client->second->UserInfo_.userinfo.email;
poco_debug(Logger(),fmt::format("START({}): {} UI Client is starting WS connection.", Client->second->Id_, Client->second->UserName_));
Client->second->Authenticated_ = true;
Client->second->UserName_ = Client->second->UserInfo_.userinfo.email;
poco_debug(Logger(),
fmt::format("START({}): {} UI Client is starting WS connection.",
Client->second->Id_, Client->second->UserName_));
auto WelcomeMessage = NotificationTypesJSON_;
WelcomeMessage.set("success", "Welcome! Bienvenue! Bienvenidos!");
std::ostringstream OS;
WelcomeMessage.stringify(OS);
Client->second->WS_->sendFrame(OS.str().c_str(), (int) OS.str().size());
Client->second->UserName_ = Client->second->UserInfo_.userinfo.email;
Client->second->WS_->sendFrame(OS.str().c_str(), (int)OS.str().size());
Client->second->UserName_ = Client->second->UserInfo_.userinfo.email;
} else {
Poco::JSON::Object WelcomeMessage;
Poco::JSON::Object WelcomeMessage;
WelcomeMessage.set("error", "Invalid token. Closing connection.");
std::ostringstream OS;
WelcomeMessage.stringify(OS);
Client->second->WS_->sendFrame(OS.str().c_str(), (int) OS.str().size());
return EndConnection(Client);
Client->second->WS_->sendFrame(OS.str().c_str(), (int)OS.str().size());
return EndConnection(Client);
}
} else {
Poco::JSON::Parser P;
auto Obj =
P.parse(IncomingFrame.begin()).extract<Poco::JSON::Object::Ptr>();
Poco::JSON::Parser P;
auto Obj = P.parse(IncomingFrame.begin()).extract<Poco::JSON::Object::Ptr>();
if(Obj->has(DropMessagesCommand) && Obj->isArray(DropMessagesCommand)) {
if (Obj->has(DropMessagesCommand) && Obj->isArray(DropMessagesCommand)) {
auto Filters = Obj->getArray(DropMessagesCommand);
Client->second->Filter_.clear();
for(const auto &Filter:*Filters) {
Client->second->Filter_.emplace_back( (std::uint64_t) Filter);
for (const auto &Filter : *Filters) {
Client->second->Filter_.emplace_back((std::uint64_t)Filter);
}
std::sort(begin(Client->second->Filter_),end(Client->second->Filter_));
std::sort(begin(Client->second->Filter_), end(Client->second->Filter_));
return;
}
std::string Answer;
bool CloseConnection=false;
if (Processor_ != nullptr) {
Processor_->Processor(Obj, Answer, CloseConnection,Client->second->UserInfo_.userinfo);
}
if (!Answer.empty())
Client->second->WS_->sendFrame(Answer.c_str(), (int)Answer.size());
else {
Client->second->WS_->sendFrame("{}", 2);
}
std::string Answer;
bool CloseConnection = false;
if (Processor_ != nullptr) {
Processor_->Processor(Obj, Answer, CloseConnection,
Client->second->UserInfo_.userinfo);
}
if (!Answer.empty())
Client->second->WS_->sendFrame(Answer.c_str(), (int)Answer.size());
else {
Client->second->WS_->sendFrame("{}", 2);
}
if(CloseConnection) {
return EndConnection(Client);
}
if (CloseConnection) {
return EndConnection(Client);
}
}
} break;
default: {
}
}
} catch (...) {
return EndConnection(Client);
return EndConnection(Client);
}
}
void UI_WebSocketClientServer::OnSocketShutdown([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf) {
try {
std::lock_guard G(LocalMutex_);
void UI_WebSocketClientServer::OnSocketShutdown(
[[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf) {
try {
std::lock_guard G(LocalMutex_);
auto Client = Clients_.find(pNf->socket().impl()->sockfd());
if (Client == end(Clients_))
return;
EndConnection(Client);
} catch (...) {
}
if (Client == end(Clients_))
return;
EndConnection(Client);
} catch (...) {
}
}
} // namespace OpenWifi

View File

@@ -7,11 +7,11 @@
#include <map>
#include <string>
#include "Poco/Runnable.h"
#include "Poco/Net/SocketReactor.h"
#include "Poco/Net/WebSocket.h"
#include "Poco/JSON/Object.h"
#include "Poco/Net/SocketNotification.h"
#include "Poco/Net/SocketReactor.h"
#include "Poco/Net/WebSocket.h"
#include "Poco/Runnable.h"
#include "RESTObjects/RESTAPI_SecurityObjects.h"
#include "framework/SubSystemServer.h"
@@ -21,25 +21,28 @@ namespace OpenWifi {
class UI_WebSocketClientProcessor {
public:
virtual void Processor(const Poco::JSON::Object::Ptr &O, std::string &Answer, bool &Done , const SecurityObjects::UserInfo & UserInfo) = 0;
virtual void Processor(const Poco::JSON::Object::Ptr &O, std::string &Answer, bool &Done,
const SecurityObjects::UserInfo &UserInfo) = 0;
private:
};
struct UI_WebSocketClientInfo {
std::unique_ptr<Poco::Net::WebSocket> WS_ = nullptr;
std::string Id_;
std::string UserName_;
bool Authenticated_ = false;
bool SocketRegistered_=false;
std::vector<std::uint64_t> Filter_;
SecurityObjects::UserInfoAndPolicy UserInfo_;
struct UI_WebSocketClientInfo {
std::unique_ptr<Poco::Net::WebSocket> WS_ = nullptr;
std::string Id_;
std::string UserName_;
bool Authenticated_ = false;
bool SocketRegistered_ = false;
std::vector<std::uint64_t> Filter_;
SecurityObjects::UserInfoAndPolicy UserInfo_;
UI_WebSocketClientInfo(Poco::Net::WebSocket &WS, const std::string &Id, const std::string &username) {
WS_ = std::make_unique<Poco::Net::WebSocket>(WS);
Id_ = Id;
UserName_ = username;
}
};
UI_WebSocketClientInfo(Poco::Net::WebSocket &WS, const std::string &Id,
const std::string &username) {
WS_ = std::make_unique<Poco::Net::WebSocket>(WS);
Id_ = Id;
UserName_ = username;
}
};
class UI_WebSocketClientServer : public SubSystemServer, Poco::Runnable {
@@ -49,26 +52,26 @@ namespace OpenWifi {
return instance_;
}
bool IsAnyoneConnected() {
return UsersConnected_;
}
bool IsAnyoneConnected() { return UsersConnected_; }
int Start() override;
void Stop() override;
void run() override;
Poco::Net::SocketReactor & Reactor() { return Reactor_; }
void NewClient(Poco::Net::WebSocket &WS, const std::string &Id, const std::string &UserName, std::uint64_t TID);
Poco::Net::SocketReactor &Reactor() { return Reactor_; }
void NewClient(Poco::Net::WebSocket &WS, const std::string &Id, const std::string &UserName,
std::uint64_t TID);
void SetProcessor(UI_WebSocketClientProcessor *F);
[[nodiscard]] inline bool GeoCodeEnabled() const { return GeoCodeEnabled_; }
[[nodiscard]] inline std::string GoogleApiKey() const { return GoogleApiKey_; }
template <typename T> bool
SendUserNotification(const std::string &userName, const WebSocketNotification<T> &Notification) {
template <typename T>
bool SendUserNotification(const std::string &userName,
const WebSocketNotification<T> &Notification) {
Poco::JSON::Object Payload;
Poco::JSON::Object Payload;
Notification.to_json(Payload);
Poco::JSON::Object Msg;
Msg.set("notification",Payload);
Poco::JSON::Object Msg;
Msg.set("notification", Payload);
std::ostringstream OO;
Msg.stringify(OO);
@@ -76,58 +79,59 @@ namespace OpenWifi {
}
template <typename T> void SendNotification(const WebSocketNotification<T> &Notification) {
Poco::JSON::Object Payload;
Poco::JSON::Object Payload;
Notification.to_json(Payload);
Poco::JSON::Object Msg;
Msg.set("notification",Payload);
Poco::JSON::Object Msg;
Msg.set("notification", Payload);
std::ostringstream OO;
Msg.stringify(OO);
SendToAll(Notification.type_id, OO.str());
}
[[nodiscard]] bool SendToUser(const std::string &userName, std::uint64_t id, const std::string &Payload);
[[nodiscard]] bool SendToUser(const std::string &userName, std::uint64_t id,
const std::string &Payload);
void SendToAll(std::uint64_t id, const std::string &Payload);
struct NotificationEntry {
std::uint64_t id=0;
std::string helper;
std::uint64_t id = 0;
std::string helper;
};
using ClientList = std::map<int,std::unique_ptr<UI_WebSocketClientInfo>>;
using ClientList = std::map<int, std::unique_ptr<UI_WebSocketClientInfo>>;
using NotificationTypeIdVec = std::vector<NotificationEntry>;
void RegisterNotifications(const NotificationTypeIdVec & Notifications);
void RegisterNotifications(const NotificationTypeIdVec &Notifications);
bool IsFiltered(std::uint64_t id, const UI_WebSocketClientInfo &Client);
private:
volatile bool Running_ = false;
std::atomic_uint64_t UsersConnected_=0;
Poco::Net::SocketReactor Reactor_;
Poco::Thread ReactorThread_;
Poco::Thread CleanerThread_;
std::recursive_mutex LocalMutex_;
bool GeoCodeEnabled_ = false;
std::string GoogleApiKey_;
ClientList Clients_;
UI_WebSocketClientProcessor *Processor_ = nullptr;
NotificationTypeIdVec NotificationTypes_;
Poco::JSON::Object NotificationTypesJSON_;
std::vector<ClientList::iterator> ToBeRemoved_;
std::uint64_t TID_=0;
private:
volatile bool Running_ = false;
std::atomic_uint64_t UsersConnected_ = 0;
Poco::Net::SocketReactor Reactor_;
Poco::Thread ReactorThread_;
Poco::Thread CleanerThread_;
std::recursive_mutex LocalMutex_;
bool GeoCodeEnabled_ = false;
std::string GoogleApiKey_;
ClientList Clients_;
UI_WebSocketClientProcessor *Processor_ = nullptr;
NotificationTypeIdVec NotificationTypes_;
Poco::JSON::Object NotificationTypesJSON_;
std::vector<ClientList::iterator> ToBeRemoved_;
std::uint64_t TID_ = 0;
UI_WebSocketClientServer() noexcept;
void EndConnection(ClientList::iterator Client);
void EndConnection(ClientList::iterator Client);
void OnSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf);
void OnSocketShutdown(const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf);
void OnSocketError(const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf);
void OnSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf);
void OnSocketShutdown(const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf);
void OnSocketError(const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf);
ClientList::iterator FindWSClient( std::lock_guard<std::recursive_mutex> &G, int ClientSocket);
ClientList::iterator FindWSClient(std::lock_guard<std::recursive_mutex> &G,
int ClientSocket);
void SortNotifications();
};
inline auto UI_WebSocketClientServer() { return UI_WebSocketClientServer::instance(); }
};
}; // namespace OpenWifi

View File

@@ -5,61 +5,64 @@
#pragma once
#include "framework/SubSystemServer.h"
#include "framework/UI_WebSocketClientServer.h"
#include "framework/UI_WebSocketClientNotifications.h"
#include "framework/UI_WebSocketClientServer.h"
namespace OpenWifi {
class WebSocketLogger : public Poco::Channel {
public:
WebSocketLogger() {}
WebSocketLogger() {
}
~WebSocketLogger() {}
~WebSocketLogger() {
}
std::string getProperty( [[maybe_unused]] const std::string &p ) const {
std::string getProperty([[maybe_unused]] const std::string &p) const {
std::cout << "WS getProperty" << std::endl;
return "";
}
void close() final {
}
void close() final {}
void open() final {
}
void open() final {}
static std::string to_string(Poco::Message::Priority p) {
switch(p) {
case Poco::Message::PRIO_INFORMATION: return "information";
case Poco::Message::PRIO_CRITICAL: return "critical";
case Poco::Message::PRIO_DEBUG: return "debug";
case Poco::Message::PRIO_ERROR: return "error";
case Poco::Message::PRIO_FATAL: return "fatal";
case Poco::Message::PRIO_NOTICE: return "notice";
case Poco::Message::PRIO_TRACE: return "trace";
case Poco::Message::PRIO_WARNING: return "warning";
default: return "none";
switch (p) {
case Poco::Message::PRIO_INFORMATION:
return "information";
case Poco::Message::PRIO_CRITICAL:
return "critical";
case Poco::Message::PRIO_DEBUG:
return "debug";
case Poco::Message::PRIO_ERROR:
return "error";
case Poco::Message::PRIO_FATAL:
return "fatal";
case Poco::Message::PRIO_NOTICE:
return "notice";
case Poco::Message::PRIO_TRACE:
return "trace";
case Poco::Message::PRIO_WARNING:
return "warning";
default:
return "none";
}
}
struct NotificationLogMessage {
std::string msg;
std::string level;
std::uint64_t timestamp;
std::string source;
std::string thread_name;
std::uint64_t thread_id=0;
std::string msg;
std::string level;
std::uint64_t timestamp;
std::string source;
std::string thread_name;
std::uint64_t thread_id = 0;
inline void to_json(Poco::JSON::Object &Obj) const {
RESTAPI_utils::field_to_json(Obj,"msg", msg);
RESTAPI_utils::field_to_json(Obj,"level", level);
RESTAPI_utils::field_to_json(Obj,"timestamp", timestamp);
RESTAPI_utils::field_to_json(Obj,"source", source);
RESTAPI_utils::field_to_json(Obj,"thread_name", thread_name);
RESTAPI_utils::field_to_json(Obj,"thread_id", thread_id);
RESTAPI_utils::field_to_json(Obj, "msg", msg);
RESTAPI_utils::field_to_json(Obj, "level", level);
RESTAPI_utils::field_to_json(Obj, "timestamp", timestamp);
RESTAPI_utils::field_to_json(Obj, "source", source);
RESTAPI_utils::field_to_json(Obj, "thread_name", thread_name);
RESTAPI_utils::field_to_json(Obj, "thread_id", thread_id);
}
inline bool from_json(const Poco::JSON::Object::Ptr &Obj) {
@@ -71,18 +74,18 @@ namespace OpenWifi {
RESTAPI_utils::field_from_json(Obj, "thread_name", thread_name);
RESTAPI_utils::field_from_json(Obj, "thread_id", thread_id);
return true;
} catch(...) {
} catch (...) {
}
return false;
}
};
typedef WebSocketNotification<NotificationLogMessage> WebSocketClientNotificationLogMessage_t;
typedef WebSocketNotification<NotificationLogMessage>
WebSocketClientNotificationLogMessage_t;
void log(const Poco::Message &m) final {
if(UI_WebSocketClientServer()->IsAnyoneConnected()) {
WebSocketClientNotificationLogMessage_t Msg;
if (UI_WebSocketClientServer()->IsAnyoneConnected()) {
WebSocketClientNotificationLogMessage_t Msg;
Msg.content.msg = m.getText();
Msg.content.level = WebSocketLogger::to_string(m.getPriority());
Msg.content.timestamp = m.getTime().epochTime();
@@ -94,14 +97,15 @@ namespace OpenWifi {
}
}
void setProperty([[maybe_unused]] const std::string &name, [[maybe_unused]] const std::string &value) {
void setProperty([[maybe_unused]] const std::string &name,
[[maybe_unused]] const std::string &value) {
std::cout << "WS setProperty" << std::endl;
}
private:
std::recursive_mutex Mutex_;
std::recursive_mutex Mutex_;
};
// inline auto WebSocketLogger() { return WebSocketLogger::instance(); }
// inline auto WebSocketLogger() { return WebSocketLogger::instance(); }
}
} // namespace OpenWifi

View File

@@ -0,0 +1,63 @@
//
// Created by stephane bourque on 2023-04-19.
//
#pragma once
#include <vector>
#include <string>
namespace OpenWifi {
inline const std::vector<std::pair<std::string, std::string>> DefaultDeviceTypeList{
{"actiontec_web7200", "AP"},
{"cig_wf186w", "AP"},
{"cig_wf188n", "AP"},
{"cig_wf194c4", "AP"},
{"cig_wf196", "AP"},
{"cig_wf196-ca", "AP"},
{"cig_wf196-ca-ath12", "AP"},
{"cig_wf196-us", "AP"},
{"cig_wf610d", "AP"},
{"cig_wf660a", "AP"},
{"cig_wf808", "AP"},
{"cybertan_eww622-a1", "AP"},
{"edgecore_eap101", "AP"},
{"edgecore_eap101-ath12", "AP"},
{"edgecore_eap102", "AP"},
{"edgecore_eap104", "AP"},
{"edgecore_eap104-ath12", "AP"},
{"edgecore_ecs4100-12ph", "AP"},
{"edgecore_ecw5211", "AP"},
{"edgecore_ecw5410", "AP"},
{"edgecore_oap100", "AP"},
{"edgecore_spw2ac1200", "SWITCH"},
{"edgecore_spw2ac1200-lan-poe", "SWITCH"},
{"edgecore_ssw2ac2600", "SWITCH"},
{"hfcl_ion4", "AP"},
{"hfcl_ion4x", "AP"},
{"hfcl_ion4x_2", "AP"},
{"hfcl_ion4xe", "AP"},
{"hfcl_ion4xi", "AP"},
{"indio_um-305ac", "AP"},
{"indio_um-305ax", "AP"},
{"indio_um-310ax-v1", "AP"},
{"indio_um-325ac", "AP"},
{"indio_um-510ac-v3", "AP"},
{"indio_um-510axm-v1", "AP"},
{"indio_um-510axp-v1", "AP"},
{"indio_um-550ac", "AP"},
{"linksys_e8450-ubi", "AP"},
{"linksys_ea6350-v4", "AP"},
{"linksys_ea8300", "AP"},
{"liteon_wpx8324", "AP"},
{"meshpp_s618_cp01", "AP"},
{"meshpp_s618_cp03", "AP"},
{"udaya_a5-id2", "AP"},
{"wallys_dr40x9", "AP"},
{"wallys_dr6018", "AP"},
{"wallys_dr6018_v4", "AP"},
{"x64_vm", "AP"},
{"yuncore_ax840", "AP"},
{"yuncore_fap640", "AP"},
{"yuncore_fap650", "AP"}};
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -4,145 +4,140 @@
#pragma once
#include <string>
#include <fstream>
#include <iostream>
#include <iomanip>
#include <iostream>
#include <random>
#include <regex>
#include <thread>
#include <shared_mutex>
#include <string>
#include <thread>
#include "Poco/Thread.h"
#include "Poco/StringTokenizer.h"
#include "Poco/String.h"
#include "Poco/SHA2Engine.h"
#include "Poco/Message.h"
#include "Poco/StreamCopier.h"
#include "Poco/File.h"
#include "Poco/Net/NetworkInterface.h"
#include "Poco/URI.h"
#include "Poco/Net/HTTPRequest.h"
#include "Poco/Net/HTTPClientSession.h"
#include "Poco/Net/HTTPSClientSession.h"
#include "Poco/Net/HTTPResponse.h"
#include "Poco/Base64Decoder.h"
#include "Poco/Base64Encoder.h"
#include "Poco/File.h"
#include "Poco/Message.h"
#include "Poco/Net/HTTPClientSession.h"
#include "Poco/Net/HTTPRequest.h"
#include "Poco/Net/HTTPResponse.h"
#include "Poco/Net/HTTPSClientSession.h"
#include "Poco/Net/NetworkInterface.h"
#include "Poco/SHA2Engine.h"
#include "Poco/StreamCopier.h"
#include "Poco/String.h"
#include "Poco/StringTokenizer.h"
#include "Poco/Thread.h"
#include "Poco/URI.h"
#include "Poco/zlib.h"
#include "framework/ow_constants.h"
#include "framework/OpenWifiTypes.h"
#include "framework/ow_constants.h"
namespace OpenWifi::Utils {
inline uint64_t Now() { return std::time(nullptr); };
bool NormalizeMac(std::string & Mac);
bool NormalizeMac(std::string &Mac);
inline void SetThreadName(const char *name) {
#ifdef __linux__
#ifdef __linux__
Poco::Thread::current()->setName(name);
pthread_setname_np(pthread_self(), name);
#endif
#ifdef __APPLE__
#endif
#ifdef __APPLE__
Poco::Thread::current()->setName(name);
pthread_setname_np(name);
#endif
#endif
}
inline void SetThreadName(Poco::Thread &thr, const char *name) {
#ifdef __linux__
#ifdef __linux__
thr.setName(name);
pthread_setname_np(thr.tid(), name);
#endif
#ifdef __APPLE__
#endif
#ifdef __APPLE__
thr.setName(name);
#endif
#endif
}
enum MediaTypeEncodings {
PLAIN,
BINARY,
BASE64
};
enum MediaTypeEncodings { PLAIN, BINARY, BASE64 };
struct MediaTypeEncoding {
MediaTypeEncodings Encoding=PLAIN;
std::string ContentType;
MediaTypeEncodings Encoding = PLAIN;
std::string ContentType;
};
[[nodiscard]] bool ValidSerialNumber(const std::string &Serial);
[[nodiscard]] bool ValidUUID(const std::string &UUID);
[[nodiscard]] bool ValidHostname(const std::string &hostname);
[[nodiscard]] bool ValidHostname(const std::string &hostname);
template <typename ...Args> std::string ComputeHash(Args&&... args) {
Poco::SHA2Engine E;
template <typename... Args> std::string ComputeHash(Args &&...args) {
Poco::SHA2Engine E;
auto as_string = [](auto p) {
if constexpr(std::is_arithmetic_v<decltype(p)>) {
if constexpr (std::is_arithmetic_v<decltype(p)>) {
return std::to_string(p);
} else {
return p;
}
};
(E.update(as_string(args)),...);
(E.update(as_string(args)), ...);
return Poco::SHA2Engine::digestToHex(E.digest());
}
[[nodiscard]] std::vector<std::string> Split(const std::string &List, char Delimiter=',' );
[[nodiscard]] std::string FormatIPv6(const std::string & I );
void padTo(std::string& str, size_t num, char paddingChar = '\0');
[[nodiscard]] std::vector<std::string> Split(const std::string &List, char Delimiter = ',');
[[nodiscard]] std::string FormatIPv6(const std::string &I);
void padTo(std::string &str, size_t num, char paddingChar = '\0');
[[nodiscard]] std::string SerialToMAC(const std::string &Serial);
uint64_t MACToInt(const std::string &MAC);
[[nodiscard]] std::string ToHex(const std::vector<unsigned char> & B);
[[nodiscard]] std::string ToHex(const std::vector<unsigned char> &B);
using byte = std::uint8_t;
[[nodiscard]] std::string base64encode(const byte *input, uint32_t size);
[[nodiscard]] std::vector<byte> base64decode(const std::string& input);;
bool ParseTime(const std::string &Time, int & Hours, int & Minutes, int & Seconds);
bool ParseDate(const std::string &Time, int & Year, int & Month, int & Day);
bool CompareTime( int H1, int H2, int M1, int M2, int S1, int S2);
[[nodiscard]] std::vector<byte> base64decode(const std::string &input);
;
bool ParseTime(const std::string &Time, int &Hours, int &Minutes, int &Seconds);
bool ParseDate(const std::string &Time, int &Year, int &Month, int &Day);
bool CompareTime(int H1, int H2, int M1, int M2, int S1, int S2);
[[nodiscard]] std::string LogLevelToString(int Level);
[[nodiscard]] uint64_t SerialNumberToInt(const std::string & S);
[[nodiscard]] uint64_t SerialNumberToInt(const std::string &S);
[[nodiscard]] std::string IntToSerialNumber(uint64_t S);
[[nodiscard]] bool SerialNumberMatch(const std::string &S1, const std::string &S2, int Bits=2);
[[nodiscard]] uint64_t SerialNumberToOUI(const std::string & S);
[[nodiscard]] bool SerialNumberMatch(const std::string &S1, const std::string &S2,
int Bits = 2);
[[nodiscard]] uint64_t SerialNumberToOUI(const std::string &S);
[[nodiscard]] uint64_t GetDefaultMacAsInt64();
[[nodiscard]] uint64_t InitializeSystemId();
[[nodiscard]] uint64_t GetSystemId();
[[nodiscard]] bool ValidEMailAddress(const std::string &email);
[[nodiscard]] std::string LoadFile( const Poco::File & F);
void ReplaceVariables( std::string & Content , const Types::StringPairVec & P);
[[nodiscard]] std::string LoadFile(const Poco::File &F);
void ReplaceVariables(std::string &Content, const Types::StringPairVec &P);
[[nodiscard]] MediaTypeEncoding FindMediaType(const Poco::File &F);
[[nodiscard]] std::string BinaryFileToHexString(const Poco::File &F);
[[nodiscard]] std::string SecondsToNiceText(uint64_t Seconds);
[[nodiscard]] bool wgets(const std::string &URL, std::string &Response);
[[nodiscard]] bool wgetfile(const Poco::URI &uri, const std::string &FileName);
[[nodiscard]] bool IsAlphaNumeric(const std::string &s);
[[nodiscard]] std::string SanitizeToken(const std::string &Token);
[[nodiscard]] std::string SanitizeToken(const std::string &Token);
[[nodiscard]] bool ValidateURI(const std::string &uri);
[[nodiscard]] std::uint64_t ConvertDate(const std::string &d);
[[nodiscard]] std::uint64_t ConvertDate(const std::string &d);
template< typename T >
std::string int_to_hex( T i )
{
template <typename T> std::string int_to_hex(T i) {
std::stringstream stream;
stream << std::setfill ('0') << std::setw(12)
<< std::hex << i;
stream << std::setfill('0') << std::setw(12) << std::hex << i;
return stream.str();
}
inline bool SpinLock_Read(std::shared_mutex &M, volatile bool &Flag, uint64_t wait_ms=100) {
while(!M.try_lock_shared() && Flag) {
inline bool SpinLock_Read(std::shared_mutex &M, volatile bool &Flag, uint64_t wait_ms = 100) {
while (!M.try_lock_shared() && Flag) {
Poco::Thread::yield();
Poco::Thread::trySleep((long)wait_ms);
}
return Flag;
}
inline bool SpinLock_Write(std::shared_mutex &M, volatile bool &Flag, uint64_t wait_ms=100) {
while(!M.try_lock() && Flag) {
inline bool SpinLock_Write(std::shared_mutex &M, volatile bool &Flag, uint64_t wait_ms = 100) {
while (!M.try_lock() && Flag) {
Poco::Thread::yield();
Poco::Thread::trySleep(wait_ms);
}
@@ -150,5 +145,39 @@ namespace OpenWifi::Utils {
}
bool ExtractBase64CompressedData(const std::string &CompressedData,
std::string &UnCompressedData, uint64_t compress_sz );
}
std::string &UnCompressedData, uint64_t compress_sz);
inline bool match(const char* first, const char* second)
{
// If we reach at the end of both strings, we are done
if (*first == '\0' && *second == '\0')
return true;
// Make sure to eliminate consecutive '*'
if (*first == '*') {
while (*(first + 1) == '*')
first++;
}
// Make sure that the characters after '*' are present
// in second string. This function assumes that the
// first string will not contain two consecutive '*'
if (*first == '*' && *(first + 1) != '\0'
&& *second == '\0')
return false;
// If the first string contains '?', or current
// characters of both strings match
if (*first == '?' || *first == *second)
return match(first + 1, second + 1);
// If there is *, then there are two possibilities
// a) We consider current character of second string
// b) We ignore current character of second string.
if (*first == '*')
return match(first + 1, second)
|| match(first, second + 1);
return false;
}
} // namespace OpenWifi::Utils