mirror of
https://github.com/Telecominfraproject/wlan-cloud-analytics.git
synced 2026-01-27 10:22:33 +00:00
Adding kafka logging in framework.
This commit is contained in:
@@ -309,6 +309,7 @@ namespace OpenWifi::ProvObjects {
|
||||
field_to_json( Obj,"deviceConfiguration",deviceConfiguration);
|
||||
field_to_json( Obj,"rrm",rrm);
|
||||
field_to_json( Obj,"managementPolicy",managementPolicy);
|
||||
field_to_json( Obj,"state",state);
|
||||
}
|
||||
|
||||
bool InventoryTag::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
@@ -326,6 +327,7 @@ namespace OpenWifi::ProvObjects {
|
||||
field_from_json( Obj,"deviceConfiguration",deviceConfiguration);
|
||||
field_from_json( Obj,"rrm",rrm);
|
||||
field_from_json( Obj,"managementPolicy",managementPolicy);
|
||||
field_from_json( Obj,"state",state);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
@@ -333,6 +335,20 @@ namespace OpenWifi::ProvObjects {
|
||||
return false;
|
||||
}
|
||||
|
||||
void InventoryTagList::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json( Obj,"taglist",taglist);
|
||||
}
|
||||
|
||||
bool InventoryTagList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json( Obj,"taglist",taglist);
|
||||
return false;
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
void DeviceConfigurationElement::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json( Obj,"name", name);
|
||||
field_to_json( Obj,"description", description);
|
||||
|
||||
@@ -284,12 +284,22 @@ namespace OpenWifi::ProvObjects {
|
||||
std::string deviceConfiguration;
|
||||
std::string rrm;
|
||||
Types::UUID_t managementPolicy;
|
||||
std::string state;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
typedef std::vector<InventoryTag> InventoryTagVec;
|
||||
|
||||
struct InventoryTagList {
|
||||
InventoryTagVec taglist;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
|
||||
struct Report {
|
||||
uint64_t snapShot=0;
|
||||
Types::CountedMap tenants;
|
||||
|
||||
@@ -100,7 +100,8 @@ namespace OpenWifi {
|
||||
EXPIRED_TOKEN,
|
||||
RATE_LIMIT_EXCEEDED,
|
||||
BAD_MFA_TRANSACTION,
|
||||
MFA_FAILURE
|
||||
MFA_FAILURE,
|
||||
SECURITY_SERVICE_UNREACHABLE
|
||||
};
|
||||
|
||||
class AppServiceRegistry {
|
||||
@@ -238,6 +239,23 @@ namespace OpenWifi::RESTAPI_utils {
|
||||
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;
|
||||
Inner.set("value", Month);
|
||||
Inner.set("counter", Counter);
|
||||
MonthlyArray.add(Inner);
|
||||
}
|
||||
OrgObject.set("index",MonthlyArray);
|
||||
A.add(OrgObject);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T> void field_to_json(Poco::JSON::Object &Obj,
|
||||
const char *Field,
|
||||
const T &V,
|
||||
@@ -1078,6 +1096,53 @@ namespace OpenWifi {
|
||||
|
||||
typedef std::map<std::string,ConfigurationEntry> ConfigurationMap_t;
|
||||
|
||||
template <typename T> class FIFO {
|
||||
public:
|
||||
explicit FIFO(uint32_t Size) : Size_(Size) {
|
||||
Buffer_->reserve(Size_);
|
||||
}
|
||||
|
||||
mutable Poco::BasicEvent<bool> Writable_;
|
||||
mutable Poco::BasicEvent<bool> Readable_;
|
||||
|
||||
inline bool Read(T &t) {
|
||||
{
|
||||
std::lock_guard M(Mutex_);
|
||||
if (Write_ == Read_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
t = (*Buffer_)[Read_++];
|
||||
if (Read_ == Size_) {
|
||||
Read_ = 0;
|
||||
}
|
||||
}
|
||||
bool flag = true;
|
||||
Writable_.notify(this, flag);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool Write(const T &t) {
|
||||
{
|
||||
std::lock_guard M(Mutex_);
|
||||
(*Buffer_)[Write_++] = t;
|
||||
if (Write_ == Size_) {
|
||||
Write_ = 0;
|
||||
}
|
||||
}
|
||||
bool flag = true;
|
||||
Readable_.notify(this, flag);
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
std::mutex Mutex_;
|
||||
uint32_t Size_;
|
||||
uint32_t Read_=0;
|
||||
uint32_t Write_=0;
|
||||
std::unique_ptr<std::vector<T>> Buffer_=std::make_unique<std::vector<T>>();
|
||||
};
|
||||
|
||||
template <class Record, typename KeyType = std::string, int Size=256, int Expiry=60000> class RecordCache {
|
||||
public:
|
||||
explicit RecordCache( KeyType Record::* Q) :
|
||||
@@ -1643,11 +1708,14 @@ namespace OpenWifi {
|
||||
if (!ContinueProcessing())
|
||||
return;
|
||||
|
||||
bool Expired=false;
|
||||
if (AlwaysAuthorize_ && !IsAuthorized(Expired, SubOnlyService_)) {
|
||||
bool Expired=false, Contacted=false;
|
||||
if (AlwaysAuthorize_ && !IsAuthorized(Expired, Contacted, SubOnlyService_)) {
|
||||
if(Expired)
|
||||
return UnAuthorized(RESTAPI::Errors::ExpiredToken, EXPIRED_TOKEN);
|
||||
return UnAuthorized(RESTAPI::Errors::InvalidCredentials, INVALID_TOKEN);
|
||||
if(Contacted)
|
||||
return UnAuthorized(RESTAPI::Errors::InvalidCredentials, INVALID_TOKEN);
|
||||
else
|
||||
return UnAuthorized(RESTAPI::Errors::InvalidCredentials, SECURITY_SERVICE_UNREACHABLE);
|
||||
}
|
||||
|
||||
std::string Reason;
|
||||
@@ -2029,7 +2097,7 @@ namespace OpenWifi {
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool IsAuthorized(bool & Expired, bool SubOnly = false );
|
||||
inline bool IsAuthorized(bool & Expired, bool & Contacted, bool SubOnly = false );
|
||||
|
||||
inline void ReturnObject(Poco::JSON::Object &Object) {
|
||||
PrepareResponse();
|
||||
@@ -2105,20 +2173,20 @@ namespace OpenWifi {
|
||||
virtual void DoPost() = 0 ;
|
||||
virtual void DoPut() = 0 ;
|
||||
|
||||
Poco::Net::HTTPServerRequest *Request= nullptr;
|
||||
Poco::Net::HTTPServerResponse *Response= nullptr;
|
||||
SecurityObjects::UserInfoAndPolicy UserInfo_;
|
||||
protected:
|
||||
BindingMap Bindings_;
|
||||
Poco::URI::QueryParameters Parameters_;
|
||||
Poco::Logger &Logger_;
|
||||
std::string SessionToken_;
|
||||
SecurityObjects::UserInfoAndPolicy UserInfo_;
|
||||
std::vector<std::string> Methods_;
|
||||
QueryBlock QB_;
|
||||
bool Internal_=false;
|
||||
bool RateLimited_=false;
|
||||
bool QueryBlockInitialized_=false;
|
||||
bool SubOnlyService_=false;
|
||||
Poco::Net::HTTPServerRequest *Request= nullptr;
|
||||
Poco::Net::HTTPServerResponse *Response= nullptr;
|
||||
bool AlwaysAuthorize_=true;
|
||||
Poco::JSON::Parser IncomingParser_;
|
||||
RESTAPI_GenericServer & Server_;
|
||||
@@ -2239,6 +2307,26 @@ namespace OpenWifi {
|
||||
Poco::JSON::Object Body_;
|
||||
};
|
||||
|
||||
class OpenAPIRequestDelete {
|
||||
public:
|
||||
explicit OpenAPIRequestDelete( const std::string & Type,
|
||||
const std::string & EndPoint,
|
||||
const Types::StringPairVec & QueryData,
|
||||
uint64_t msTimeout):
|
||||
Type_(Type),
|
||||
EndPoint_(EndPoint),
|
||||
QueryData_(QueryData),
|
||||
msTimeout_(msTimeout){};
|
||||
inline 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_;
|
||||
};
|
||||
|
||||
class KafkaProducer : public Poco::Runnable {
|
||||
public:
|
||||
inline void run();
|
||||
@@ -2424,16 +2512,24 @@ namespace OpenWifi {
|
||||
|
||||
inline bool RetrieveTokenInformation(const std::string & SessionToken,
|
||||
SecurityObjects::UserInfoAndPolicy & UInfo,
|
||||
bool & Expired, bool Sub=false) {
|
||||
bool & Expired, bool & Contacted, bool Sub=false) {
|
||||
try {
|
||||
Types::StringPairVec QueryData;
|
||||
QueryData.push_back(std::make_pair("token",SessionToken));
|
||||
OpenAPIRequestGet Req( uSERVICE_SECURITY,
|
||||
Sub ? "/api/v1/validateSubToken" : "/api/v1/validateToken",
|
||||
QueryData,
|
||||
5000);
|
||||
10000);
|
||||
Poco::JSON::Object::Ptr Response;
|
||||
if(Req.Do(Response)==Poco::Net::HTTPServerResponse::HTTP_OK) {
|
||||
|
||||
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")) {
|
||||
UInfo.from_json(Response);
|
||||
if(IsTokenExpired(UInfo.webtoken)) {
|
||||
@@ -2444,17 +2540,18 @@ namespace OpenWifi {
|
||||
std::lock_guard G(Mutex_);
|
||||
Cache_.update(SessionToken, UInfo);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
Expired = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool IsAuthorized(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo,
|
||||
bool & Expired, bool Sub = false) {
|
||||
bool & Expired, bool & Contacted, bool Sub = false) {
|
||||
std::lock_guard G(Mutex_);
|
||||
auto User = Cache_.get(SessionToken);
|
||||
if(!User.isNull()) {
|
||||
@@ -2466,7 +2563,7 @@ namespace OpenWifi {
|
||||
UInfo = *User;
|
||||
return true;
|
||||
}
|
||||
return RetrieveTokenInformation(SessionToken, UInfo, Expired, Sub);
|
||||
return RetrieveTokenInformation(SessionToken, UInfo, Expired, Contacted, Sub);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -3519,11 +3616,51 @@ namespace OpenWifi {
|
||||
KafkaEnabled_ = MicroService::instance().ConfigGetBool("openwifi.kafka.enable",false);
|
||||
}
|
||||
|
||||
inline void KafkaLoggerFun(cppkafka::KafkaHandleBase & handle, int level, const std::string & facility, const std::string &messqge) {
|
||||
switch ((cppkafka::LogLevel) level) {
|
||||
case cppkafka::LogLevel::LogNotice: {
|
||||
KafkaManager()->Logger().notice(Poco::format("kafka-log: facility: %s message: %s",facility, messqge));
|
||||
}
|
||||
break;
|
||||
case cppkafka::LogLevel::LogDebug: {
|
||||
KafkaManager()->Logger().debug(Poco::format("kafka-log: facility: %s message: %s",facility, messqge));
|
||||
}
|
||||
break;
|
||||
case cppkafka::LogLevel::LogInfo: {
|
||||
KafkaManager()->Logger().information(Poco::format("kafka-log: facility: %s message: %s",facility, messqge));
|
||||
}
|
||||
break;
|
||||
case cppkafka::LogLevel::LogWarning: {
|
||||
KafkaManager()->Logger().warning(Poco::format("kafka-log: facility: %s message: %s",facility, messqge));
|
||||
}
|
||||
break;
|
||||
case cppkafka::LogLevel::LogAlert:
|
||||
case cppkafka::LogLevel::LogCrit: {
|
||||
KafkaManager()->Logger().critical(Poco::format("kafka-log: facility: %s message: %s",facility, messqge));
|
||||
}
|
||||
break;
|
||||
case cppkafka::LogLevel::LogErr:
|
||||
case cppkafka::LogLevel::LogEmerg:
|
||||
default: {
|
||||
KafkaManager()->Logger().error(Poco::format("kafka-log: facility: %s message: %s",facility, messqge));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
inline void KafkaErrorFun(cppkafka::KafkaHandleBase & handle, int error, const std::string &reason) {
|
||||
KafkaManager()->Logger().error(Poco::format("kafka-error: %d, reason: %s", error, reason));
|
||||
}
|
||||
|
||||
inline void KafkaProducer::run() {
|
||||
cppkafka::Configuration Config({
|
||||
{ "client.id", MicroService::instance().ConfigGetString("openwifi.kafka.client.id") },
|
||||
{ "metadata.broker.list", MicroService::instance().ConfigGetString("openwifi.kafka.brokerlist") }
|
||||
});
|
||||
|
||||
Config.set_log_callback(KafkaLoggerFun);
|
||||
Config.set_error_callback(KafkaErrorFun);
|
||||
|
||||
KafkaManager()->SystemInfoWrapper_ = R"lit({ "system" : { "id" : )lit" +
|
||||
std::to_string(MicroService::instance().ID()) +
|
||||
R"lit( , "host" : ")lit" + MicroService::instance().PrivateEndPoint() +
|
||||
@@ -3564,6 +3701,9 @@ namespace OpenWifi {
|
||||
{ "enable.partition.eof", false }
|
||||
});
|
||||
|
||||
Config.set_log_callback(KafkaLoggerFun);
|
||||
Config.set_error_callback(KafkaErrorFun);
|
||||
|
||||
cppkafka::TopicConfiguration topic_config = {
|
||||
{ "auto.offset.reset", "smallest" }
|
||||
};
|
||||
@@ -3930,6 +4070,52 @@ namespace OpenWifi {
|
||||
return Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT;
|
||||
}
|
||||
|
||||
inline Poco::Net::HTTPServerResponse::HTTPStatus OpenAPIRequestDelete::Do(const std::string & BearerToken) {
|
||||
try {
|
||||
auto Services = MicroService::instance().GetServices(Type_);
|
||||
|
||||
for(auto const &Svc:Services) {
|
||||
Poco::URI URI(Svc.PrivateEndPoint);
|
||||
Poco::Net::HTTPSClientSession Session(URI.getHost(), URI.getPort());
|
||||
|
||||
URI.setPath(EndPoint_);
|
||||
for (const auto &qp : QueryData_)
|
||||
URI.addQueryParameter(qp.first, qp.second);
|
||||
|
||||
std::string Path(URI.getPathAndQuery());
|
||||
Session.setTimeout(Poco::Timespan(msTimeout_/1000, msTimeout_ % 1000));
|
||||
|
||||
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_DELETE,
|
||||
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", MicroService::instance().PublicEndPoint());
|
||||
} else {
|
||||
// Authorization: Bearer ${token}
|
||||
Request.add("Authorization", "Bearer " + BearerToken);
|
||||
}
|
||||
|
||||
std::ostream & os = Session.sendRequest(Request);
|
||||
os << obody.str();
|
||||
|
||||
Poco::Net::HTTPResponse Response;
|
||||
Session.receiveResponse(Response);
|
||||
return Response.getStatus();
|
||||
}
|
||||
}
|
||||
catch (const Poco::Exception &E)
|
||||
{
|
||||
std::cerr << E.displayText() << std::endl;
|
||||
}
|
||||
return Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT;
|
||||
}
|
||||
|
||||
inline void RESTAPI_GenericServer::InitLogging() {
|
||||
std::string Public = MicroService::instance().ConfigGetString("apilogging.public.methods","PUT,POST,DELETE");
|
||||
@@ -3946,7 +4132,7 @@ namespace OpenWifi {
|
||||
#ifdef TIP_SECURITY_SERVICE
|
||||
[[nodiscard]] bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired , bool Sub );
|
||||
#endif
|
||||
inline bool RESTAPIHandler::IsAuthorized( bool & Expired , bool Sub ) {
|
||||
inline bool RESTAPIHandler::IsAuthorized( bool & Expired , bool & Contacted , bool Sub ) {
|
||||
if(Internal_ && Request->has("X-INTERNAL-NAME")) {
|
||||
auto Allowed = MicroService::instance().IsValidAPIKEY(*Request);
|
||||
if(!Allowed) {
|
||||
@@ -3978,7 +4164,7 @@ namespace OpenWifi {
|
||||
#ifdef TIP_SECURITY_SERVICE
|
||||
if (AuthServiceIsAuthorized(*Request, SessionToken_, UserInfo_, Expired, Sub)) {
|
||||
#else
|
||||
if (AuthClient()->IsAuthorized( SessionToken_, UserInfo_, Expired, Sub)) {
|
||||
if (AuthClient()->IsAuthorized( SessionToken_, UserInfo_, Expired, Contacted, Sub)) {
|
||||
#endif
|
||||
if(Server_.LogIt(Request->getMethod(),true)) {
|
||||
Logger_.debug(Poco::format("X-REQ-ALLOWED(%s): User='%s@%s' Method='%s' Path='%s'",
|
||||
|
||||
@@ -14,22 +14,24 @@
|
||||
#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(std::string, 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::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(std::string, 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;
|
||||
}
|
||||
|
||||
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())
|
||||
@@ -37,4 +39,22 @@ namespace OpenWifi {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace OpenWifi::RESTAPI::Errors {
|
||||
static const std::string CouldNotBeDeleted{"Element could not be deleted."};
|
||||
static const std::string NameMustBeSet{"The name property must be set."};
|
||||
static const std::string ConfigBlockInvalid{"Configuration block type invalid."};
|
||||
static const std::string UnknownId{"Unknown management policy."};
|
||||
static const std::string UnknownId{"Unknown UUID."};
|
||||
static const std::string InvalidDeviceTypes{"Unknown or invalid device type(s)."};
|
||||
static const std::string RecordNotCreated{"Record could not be created."};
|
||||
static const std::string RecordNotUpdated{"Record could not be updated."};
|
||||
@@ -59,5 +59,6 @@ namespace OpenWifi::RESTAPI::Errors {
|
||||
static const std::string MissingAuthenticationInformation{"Missing authentication information."};
|
||||
static const std::string InsufficientAccessRights{"Insufficient access rights to complete the operation."};
|
||||
static const std::string ExpiredToken{"Token has expired, user must login."};
|
||||
static const std::string SubscriberMustExist{"Subscriber must exist."};
|
||||
}
|
||||
|
||||
|
||||
@@ -171,6 +171,9 @@ namespace ORM {
|
||||
|
||||
template <typename RecordTuple, typename RecordType> class DB {
|
||||
public:
|
||||
|
||||
typedef const char * field_name_t;
|
||||
|
||||
DB( OpenWifi::DBType dbtype,
|
||||
const char *TableName,
|
||||
const FieldVec & Fields,
|
||||
@@ -258,27 +261,27 @@ namespace ORM {
|
||||
[[nodiscard]] const std::string & SelectList() const { return SelectList_; };
|
||||
[[nodiscard]] const std::string & UpdateFields() const { return UpdateFields_; };
|
||||
|
||||
inline std::string OP(const char *F, SqlComparison O , bool V) {
|
||||
inline std::string OP(field_name_t F, SqlComparison O , bool V) {
|
||||
assert( FieldNames_.find(F) != FieldNames_.end() );
|
||||
return std::string{"("} + F + SQLCOMPS[O] + (V ? "true" : "false") + ")" ;
|
||||
}
|
||||
|
||||
inline std::string OP(const char *F, SqlComparison O , int V) {
|
||||
inline std::string OP(field_name_t F, SqlComparison O , int V) {
|
||||
assert( FieldNames_.find(F) != FieldNames_.end() );
|
||||
return std::string{"("} + F + SQLCOMPS[O] + std::to_string(V) + ")" ;
|
||||
}
|
||||
|
||||
inline std::string OP(const char *F, SqlComparison O , uint64_t V) {
|
||||
inline std::string OP(field_name_t F, SqlComparison O , uint64_t V) {
|
||||
assert( FieldNames_.find(F) != FieldNames_.end() );
|
||||
return std::string{"("} + F + SQLCOMPS[O] + std::to_string(V) + ")" ;
|
||||
}
|
||||
|
||||
std::string OP(const char *F, SqlComparison O , const std::string & V) {
|
||||
std::string OP(field_name_t F, SqlComparison O , const std::string & V) {
|
||||
assert( FieldNames_.find(F) != FieldNames_.end() );
|
||||
return std::string{"("} + F + SQLCOMPS[O] + "'" + Escape(V) + "')" ;
|
||||
}
|
||||
|
||||
std::string OP(const char *F, SqlComparison O , const char * V) {
|
||||
std::string OP(field_name_t F, SqlComparison O , const char * V) {
|
||||
assert( FieldNames_.find(F) != FieldNames_.end() );
|
||||
return std::string{"("} + F + SQLCOMPS[O] + "'" + Escape(V) + "')" ;
|
||||
}
|
||||
@@ -299,9 +302,12 @@ namespace ORM {
|
||||
return std::string{"("} + P1 + BOPS[BOP] + OP(true, P2, More...);
|
||||
}
|
||||
|
||||
inline bool Create() {
|
||||
std::string S;
|
||||
bool Upgrade() {
|
||||
uint32_t To;
|
||||
return Upgrade(0, To);
|
||||
}
|
||||
|
||||
inline bool Create() {
|
||||
switch(Type_) {
|
||||
case OpenWifi::DBType::mysql: {
|
||||
try {
|
||||
@@ -309,12 +315,10 @@ namespace ORM {
|
||||
std::string Statement = IndexCreation_.empty() ? "create table if not exists " + TableName_ +" ( " + CreateFields_ + " )" :
|
||||
"create table if not exists " + TableName_ +" ( " + CreateFields_ + " ), " + IndexCreation_[0] + " )";
|
||||
Session << Statement , Poco::Data::Keywords::now;
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.error("Failure to create MySQL DB resources.");
|
||||
Logger_.log(E);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -326,7 +330,6 @@ namespace ORM {
|
||||
for(const auto &i:IndexCreation_) {
|
||||
Session << i , Poco::Data::Keywords::now;
|
||||
}
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.error("Failure to create SQLITE DB resources.");
|
||||
Logger_.log(E);
|
||||
@@ -342,7 +345,6 @@ namespace ORM {
|
||||
for(const auto &i:IndexCreation_) {
|
||||
Session << i , Poco::Data::Keywords::now;
|
||||
}
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.error("Failure to create POSTGRESQL DB resources.");
|
||||
Logger_.log(E);
|
||||
@@ -350,7 +352,7 @@ namespace ORM {
|
||||
}
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
return Upgrade();
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string ConvertParams(const std::string & S) const {
|
||||
@@ -400,7 +402,7 @@ namespace ORM {
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename T> bool GetRecord( const char * FieldName, const T & Value, RecordType & R) {
|
||||
template<typename T> bool GetRecord(field_name_t FieldName, const T & Value, RecordType & R) {
|
||||
try {
|
||||
assert( FieldNames_.find(FieldName) != FieldNames_.end() );
|
||||
|
||||
@@ -438,7 +440,7 @@ namespace ORM {
|
||||
typedef std::vector<std::string> StringVec;
|
||||
|
||||
template < typename T,
|
||||
typename T0, typename T1> bool GR(const char *FieldName, T & R,T0 &V0, T1 &V1) {
|
||||
typename T0, typename T1> bool GR(field_name_t FieldName, T & R,T0 &V0, T1 &V1) {
|
||||
try {
|
||||
|
||||
assert( FieldNames_.find(FieldName) != FieldNames_.end() );
|
||||
@@ -495,7 +497,7 @@ namespace ORM {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T> bool UpdateRecord( const char *FieldName, const T & Value, const RecordType & R) {
|
||||
template <typename T> bool UpdateRecord(field_name_t FieldName, const T & Value, const RecordType & R) {
|
||||
try {
|
||||
assert( FieldNames_.find(FieldName) != FieldNames_.end() );
|
||||
|
||||
@@ -522,7 +524,7 @@ namespace ORM {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T> bool ReplaceRecord( const char *FieldName, const T & Value, RecordType & R) {
|
||||
template <typename T> bool ReplaceRecord(field_name_t FieldName, const T & Value, RecordType & R) {
|
||||
try {
|
||||
if(Exists(FieldName, Value)) {
|
||||
return UpdateRecord(FieldName,Value,R);
|
||||
@@ -534,7 +536,7 @@ namespace ORM {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T> bool GetNameAndDescription(const char *FieldName, const T & Value, std::string & Name, std::string & Description ) {
|
||||
template <typename T> bool GetNameAndDescription(field_name_t FieldName, const T & Value, std::string & Name, std::string & Description ) {
|
||||
try {
|
||||
assert( FieldNames_.find(FieldName) != FieldNames_.end() );
|
||||
Poco::Data::Session Session = Pool_.get();
|
||||
@@ -561,7 +563,7 @@ namespace ORM {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T> bool DeleteRecord( const char *FieldName, const T & Value) {
|
||||
template <typename T> bool DeleteRecord(field_name_t FieldName, const T & Value) {
|
||||
try {
|
||||
assert( FieldNames_.find(FieldName) != FieldNames_.end() );
|
||||
|
||||
@@ -599,7 +601,7 @@ namespace ORM {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Exists(const char *FieldName, const std::string & Value) {
|
||||
bool Exists(field_name_t FieldName, const std::string & Value) {
|
||||
try {
|
||||
assert( FieldNames_.find(FieldName) != FieldNames_.end() );
|
||||
|
||||
@@ -613,15 +615,15 @@ namespace ORM {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Iterate( std::function<bool(const RecordType &R)> F) {
|
||||
bool Iterate( std::function<bool(const RecordType &R)> F, const std::string & WhereClause = "" ) {
|
||||
try {
|
||||
|
||||
uint64_t Offset=1;
|
||||
uint64_t Offset=0;
|
||||
uint64_t Batch=50;
|
||||
bool Done=false;
|
||||
while(!Done) {
|
||||
std::vector<RecordType> Records;
|
||||
if(GetRecords(Offset,Batch,Records)) {
|
||||
if(GetRecords(Offset,Batch,Records, WhereClause)) {
|
||||
for(const auto &i:Records) {
|
||||
if(!F(i))
|
||||
return true;
|
||||
@@ -691,7 +693,7 @@ namespace ORM {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename X> bool ManipulateVectorMember( X T, const char *FieldName, std::string & ParentUUID, std::string & ChildUUID, bool Add) {
|
||||
template <typename X> bool ManipulateVectorMember( X T, field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID, bool Add) {
|
||||
try {
|
||||
assert( FieldNames_.find(FieldName) != FieldNames_.end() );
|
||||
|
||||
@@ -751,89 +753,89 @@ namespace ORM {
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool AddChild( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) {
|
||||
inline bool AddChild(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::children, FieldName, ParentUUID, ChildUUID, true);
|
||||
}
|
||||
|
||||
inline bool DeleteChild( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) {
|
||||
inline bool DeleteChild(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::children, FieldName, ParentUUID, ChildUUID, false);
|
||||
}
|
||||
|
||||
inline bool AddLocation( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) {
|
||||
inline bool AddLocation(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::locations, FieldName, ParentUUID, ChildUUID, true);
|
||||
}
|
||||
|
||||
inline bool DeleteLocation( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) {
|
||||
inline bool DeleteLocation(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::locations, FieldName, ParentUUID, ChildUUID, false);
|
||||
}
|
||||
|
||||
inline bool AddContact( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) {
|
||||
inline bool AddContact(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::contacts, FieldName, ParentUUID, ChildUUID, true);
|
||||
}
|
||||
|
||||
inline bool DeleteContact( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) {
|
||||
inline bool DeleteContact(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::contacts, FieldName, ParentUUID, ChildUUID, false);
|
||||
}
|
||||
|
||||
inline bool AddVenue( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) {
|
||||
inline bool AddVenue(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::venues, FieldName, ParentUUID, ChildUUID, true);
|
||||
}
|
||||
|
||||
inline bool DeleteVenue( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) {
|
||||
inline bool DeleteVenue(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::venues, FieldName, ParentUUID, ChildUUID, false);
|
||||
}
|
||||
|
||||
inline bool AddDevice( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) {
|
||||
inline bool AddDevice(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::devices, FieldName, ParentUUID, ChildUUID, true);
|
||||
}
|
||||
|
||||
inline bool DeleteDevice( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) {
|
||||
inline bool DeleteDevice(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::devices, FieldName, ParentUUID, ChildUUID, false);
|
||||
}
|
||||
|
||||
inline bool AddEntity( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) {
|
||||
inline bool AddEntity(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::entities, FieldName, ParentUUID, ChildUUID, true);
|
||||
}
|
||||
|
||||
inline bool DeleteEntity( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) {
|
||||
inline bool DeleteEntity(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::entities, FieldName, ParentUUID, ChildUUID, false);
|
||||
}
|
||||
|
||||
inline bool AddUser( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) {
|
||||
inline bool AddUser(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::users, FieldName, ParentUUID, ChildUUID, true);
|
||||
}
|
||||
|
||||
inline bool DelUser( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) {
|
||||
inline bool DelUser(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::users, FieldName, ParentUUID, ChildUUID, false);
|
||||
}
|
||||
|
||||
inline bool AddInUse(const char *FieldName, std::string & ParentUUID, const std::string & Prefix, const std::string & ChildUUID) {
|
||||
inline bool AddInUse(field_name_t FieldName, std::string & ParentUUID, const std::string & Prefix, const std::string & ChildUUID) {
|
||||
std::string FakeUUID{ Prefix + ":" + ChildUUID};
|
||||
return ManipulateVectorMember(&RecordType::inUse,FieldName, ParentUUID, FakeUUID, true);
|
||||
}
|
||||
|
||||
inline bool DeleteInUse(const char *FieldName, std::string & ParentUUID, const std::string & Prefix, const std::string & ChildUUID) {
|
||||
inline bool DeleteInUse(field_name_t FieldName, std::string & ParentUUID, const std::string & Prefix, const std::string & ChildUUID) {
|
||||
std::string FakeUUID{ Prefix + ":" + ChildUUID};
|
||||
return ManipulateVectorMember(&RecordType::inUse,FieldName, ParentUUID, FakeUUID, false);
|
||||
}
|
||||
|
||||
inline bool DeleteContact(const char *FieldName, std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
inline bool DeleteContact(field_name_t FieldName, std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::contacts,FieldName, ParentUUID, ChildUUID, false);
|
||||
}
|
||||
|
||||
inline bool AddContact(const char *FieldName, std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
inline bool AddContact(field_name_t FieldName, std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::contacts,FieldName, ParentUUID, ChildUUID, true);
|
||||
}
|
||||
|
||||
inline bool DeleteLocation(const char *FieldName, std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
inline bool DeleteLocation(field_name_t FieldName, std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::locations,FieldName, ParentUUID, ChildUUID, false);
|
||||
}
|
||||
|
||||
inline bool AddLocation(const char *FieldName, std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
inline bool AddLocation(field_name_t FieldName, std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::locations,FieldName, ParentUUID, ChildUUID, true);
|
||||
}
|
||||
|
||||
inline bool GetInUse(const char *FieldName, std::string & UUID, std::vector<std::string> & UUIDs ) {
|
||||
inline bool GetInUse(field_name_t FieldName, const std::string & UUID, std::vector<std::string> & UUIDs ) {
|
||||
RecordType R;
|
||||
if(GetRecord(FieldName,UUID,R)) {
|
||||
UUIDs = R.inUse;
|
||||
|
||||
Reference in New Issue
Block a user