DB Creation completed.

This commit is contained in:
stephb9959
2021-08-16 22:51:01 -07:00
parent 3f14f54134
commit 5b5749d56c
41 changed files with 2526 additions and 155 deletions

View File

@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.13)
project(ucentraltopo VERSION 0.1.0)
project(owprov VERSION 2.1.0)
set(CMAKE_CXX_STANDARD 17)
@@ -48,7 +48,7 @@ endif()
include_directories(/usr/local/include /usr/local/opt/openssl/include src include/kafka /usr/local/opt/mysql-client/include)
add_executable( ucentraltopo
add_executable(owprov
build
src/Daemon.cpp src/Daemon.h
src/Dashboard.h src/Dashboard.cpp
@@ -56,7 +56,6 @@ add_executable( ucentraltopo
src/Utils.h src/Utils.cpp
src/RESTAPI_utils.cpp src/RESTAPI_utils.h
src/RESTAPI_SecurityObjects.h src/RESTAPI_SecurityObjects.h
src/RESTAPI_TopoObjects.cpp src/RESTAPI_TopoObjects.h
src/ALBHealthCheckServer.h
src/AuthClient.cpp src/AuthClient.h
src/KafkaManager.cpp src/KafkaManager.h
@@ -69,12 +68,18 @@ add_executable( ucentraltopo
src/RESTAPI_InternalServer.h src/RESTAPI_InternalServer.cpp
src/StorageService.cpp src/StorageService.h
src/SubSystemServer.cpp src/SubSystemServer.h
src/RESTAPI_ProvObjects.cpp src/RESTAPI_ProvObjects.h
src/storage_pgql.cpp src/storage_mysql.cpp src/storage_sqlite.cpp
src/storage_tables.cpp
src/storage_entity.cpp src/storage_entity.h
src/storage_policies.cpp src/storage_policies.h
src/uCentralTypes.h
)
src/storage_venue.cpp src/storage_venue.h
src/storage_location.cpp src/storage_location.h
src/storage_contact.cpp src/storage_contact.h
src/RESTAPI_entity_handler.cpp src/RESTAPI_entity_handler.h
src/storage_inventory.cpp src/storage_inventory.h)
target_link_libraries(ucentraltopo PUBLIC
target_link_libraries(owprov PUBLIC
${Poco_LIBRARIES} ${MySQL_LIBRARIES}
${Boost_LIBRARIES}
${ZLIB_LIBRARIES} ${AWSSDK_LINK_LIBRARIES}

View File

@@ -1 +1,2 @@
# ucentral-topo
# OpenWiFi Provisioning

1
build Normal file
View File

@@ -0,0 +1 @@
1

539
openapi/ow_prov.yaml Normal file
View File

@@ -0,0 +1,539 @@
openapi: 3.0.1
info:
title: OpenWiFi Provisioning Model
description: Definitions and APIs to manages an OpenWiFi network.
version: 2.1.0
license:
name: BSD3
servers:
- url: 'https://localhost:16005/api/v1'
security:
- bearerAuth: []
- ApiKeyAuth: []
components:
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: X-API-KEY
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
responses:
NotFound:
description: The specified resource was not found.
content:
application/json:
schema:
properties:
ErrorCode:
type: integer
ErrorDetails:
type: string
ErrorDescription:
type: string
Unauthorized:
description: The requested does not have sufficient rights to perform the operation.
content:
application/json:
schema:
properties:
ErrorCode:
type: integer
ErrorDetails:
type: string
ErrorDescription:
type: string
Success:
description: The requested operation was performed.
content:
application/json:
schema:
properties:
Operation:
type: string
Details:
type: string
Code:
type: integer
schemas:
ObjectInfo:
type: object
properties:
id:
type: string
format: uuid
name:
type: string
description:
type: string
notes:
type: array
items:
$ref: '#/components/schemas/NoteInfo'
created:
type: integer
format: int64
modified:
type: integer
format: int64
# uuids: mpe:<uuid>
ManagementPolicyEntry:
type: object
properties:
users:
type: array
items:
type: string
resources:
description: this is a list of UUID and UUID Patterns to control by this policy
type: array
items:
type: string
access:
type: array
items:
type: string
enum:
- NOACCESS
- READ
- MODIFY
- DELETE
- LIST
- CREATE
- FULL
policy:
description: A JSON document describing the policy
type: string
# uuids: mpp:<uuid>
ManagementPolicy:
type: object
properties:
allOf:
$ref: '#/components/schemas/ObjectInfo'
entries:
type: array
items:
$ref: '#/components/schemas/ManagementPolicyEntry'
# uuids: ent:<uuid>
Entity:
type: object
properties:
allOf:
$ref: '#/components/schemas/ObjectInfo'
parent:
description: If empty, then this is the root entity, otherwise this points to a parent entity
type: string
format: uuid
children:
type: array
items:
type: string
format: uuid
managers:
description: The list of UUID of the management groups allowed to manage this entity
type: array
items:
type: string
format: uuid
contacts:
description: The list of UUID of the contacts for the entity
type: array
items:
type: string
format: uuid
locations:
description: The list of UUID of the locations associated with thit entiry
type: array
items:
type: string
format: uuid
managementPolicy:
type: string
format: uuid
DiGraphEntry:
type: object
properties:
parent:
type: string
format: uuid
child:
type: string
format: uuid
DiGraph:
type: array
items:
$ref: '#/components/schemas/DiGraphEntry'
# uuids: ven:<uuid>
Venue:
type: object
properties:
allOf:
$ref: '#/components/schemas/ObjectInfo'
owner:
type: string
format: uuid
parent:
type: string
format: uuid
children:
type: array
items:
type: string
format: uuid
managers:
type: array
items:
type: string
format: uuid
managementPolicy:
type: string
format: uuid
devices:
type: array
items:
type: string
format: uuid
topology:
$ref: '#/components/schemas/DiGraph'
design:
type: string
# uuids: mgg:<uuid>
ManagementGroup:
type: object
properties:
allOf:
$ref: '#/components/schemas/ObjectInfo'
managementPolicy:
$ref: '#/components/schemas/ManagementPolicy'
managers:
type: array
items:
type: string
format: uuid
# uuids: loc:<uuid>
Location:
type: object
properties:
allOf:
$ref: '#/components/schemas/ObjectInfo'
type:
type: string
enum:
- SERVICE
- EQUIPMENT
- AUTO
- MANUAL
- SPECIAL
- UNKNOWN
- CORPORATE
buildingName:
type: string
addressLines:
type: array
items:
type: string
city:
type: string
state:
type: string
postal:
type: string
country:
type: string
telephones:
type: array
items:
type: string
contact:
type: string
format: uuid
# uuids: con:<uuid>
Contact:
type: object
properties:
allOf:
$ref: '#/components/schemas/ObjectInfo'
type:
type: string
enum:
- SUBSCRIBER
- USER
- INSTALLER
- CSR
- MANAGER
- BUSINESSOWNER
- TECHNICIAN
- CORPORATE
title:
type: string
salutation:
type: string
firstname:
type: string
lastname:
type: string
initials:
type: string
visual:
type: string
mobiles:
type: array
items:
type: string
phones:
type: array
items:
type: string
location:
type: string
format: uuid
primaryEmail:
type: string
secondaryEmail:
type: string
accessPIN:
type: string
# uuids: svc:<uuid>
ServiceConfiguration:
type: object
properties:
id:
type: string
format: uuid
managementPolicy:
$ref: '#/components/schemas/ManagementPolicy'
# uuids: cfg:<uuid>
DeviceConfiguration:
type: object
properties:
id:
type: string
format: uuid
managementPolicy:
$ref: '#/components/schemas/ManagementPolicy'
deviceTypes:
type: array
items:
type: string
configuration:
type: string
InventoryTag:
type: object
properties:
allOf:
$ref: '#/components/schemas/ObjectInfo'
serialNumber:
type: string
venue:
type: string
format: uuid
entity:
type: string
format: uuid
subEntity:
type: string
format: uuid
subVenue:
type: string
format: uuid
#########################################################################################
##
## These are endpoints that all services in the OPenWiFI stack must provide
##
#########################################################################################
AnyPayload:
type: object
properties:
Document:
type: string
StringList:
type: object
properties:
list:
type: array
items:
type: string
TagValuePair:
type: object
properties:
tag:
type: string
value:
type: string
TagValuePairList:
type: object
properties:
tagList:
type: array
items:
$ref: '#/components/schemas/TagValuePair'
TagIntPair:
type: object
properties:
tag:
type: string
value:
type: integer
format: int64
TagIntPairList:
type: object
properties:
tagList:
type: array
items:
$ref: '#/components/schemas/TagIntPair'
SystemCommandDetails:
type: object
properties:
command:
type: string
enum:
- setloglevels
- getloglevels
- getSubSystemNames
- getLogLevelNames
- stats
parameters:
oneOf:
- $ref: '#/components/schemas/StringList'
- $ref: '#/components/schemas/TagValuePairList'
SystemCommandResults:
type: object
oneOf:
- $ref: '#/components/schemas/StringList'
- $ref: '#/components/schemas/TagValuePairList'
NoteInfo:
type: object
properties:
created:
type: integer
format: int64
createdBy:
type: string
note:
type: string
Dashboard:
type: object
properties:
snapshot:
type: integer
format: int64
tenants:
$ref: '#/components/schemas/TagIntPairList'
paths:
/entity:
get:
tags:
- Entities
operationId: getEntities
summary: Retrieve the list of entities
#########################################################################################
##
## These are endpoints that all services in the OpenWiFi stack must provide
##
#########################################################################################
/dashboard:
get:
tags:
- Dashboards
summary: Get the last version of the dashboard
operationId: getDeviceDashboard
responses:
200:
$ref: '#/components/schemas/Dashboard'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
/system:
post:
tags:
- System Commands
summary: Perform some systeme wide commands
operationId: systemCommand
requestBody:
description: Command details
content:
application/json:
schema:
$ref: '#/components/schemas/SystemCommandDetails'
responses:
200:
description: Successfull command execution
content:
application/json:
schema:
$ref: '#/components/schemas/SystemCommandResults'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
get:
tags:
- System Commands
summary: Retrieve different values from the running service.
operationId: getSystemCommand
parameters:
- in: query
description: Get a value
name: command
schema:
type: string
enum:
- version
- times
required: true
responses:
200:
description: Successfull command execution
content:
application/json:
schema:
$ref: '#/components/schemas/TagValuePair'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'

View File

@@ -1,35 +1,34 @@
#
# uCentral protocol server for devices. This is where you point
# all your devices. You can replace the * for address by the specific
# address of one of your interfaces
#
#
# REST API access
#
ucentralfws.restapi.host.0.backlog = 100
ucentralfws.restapi.host.0.security = relaxed
ucentralfws.restapi.host.0.rootca = $UCENTRALTOPO_ROOT/certs/restapi-ca.pem
ucentralfws.restapi.host.0.address = *
ucentralfws.restapi.host.0.port = 16005
ucentralfws.restapi.host.0.cert = $UCENTRALTOPO_ROOT/certs/restapi-cert.pem
ucentralfws.restapi.host.0.key = $UCENTRALTOPO_ROOT/certs/restapi-key.pem
ucentralfws.restapi.host.0.key.password = mypassword
owprov.restapi.host.0.backlog = 100
owprov.restapi.host.0.security = relaxed
owprov.restapi.host.0.rootca = $OWPROV_ROOT/certs/restapi-ca.pem
owprov.restapi.host.0.address = *
owprov.restapi.host.0.port = 16005
owprov.restapi.host.0.cert = $OWPROV_ROOT/certs/restapi-cert.pem
owprov.restapi.host.0.key = $OWPROV_ROOT/certs/restapi-key.pem
owprov.restapi.host.0.key.password = mypassword
ucentral.internal.restapi.host.0.backlog = 100
ucentral.internal.restapi.host.0.security = relaxed
ucentral.internal.restapi.host.0.rootca = $UCENTRALTOPO_ROOT/certs/restapi-ca.pem
ucentral.internal.restapi.host.0.address = *
ucentral.internal.restapi.host.0.port = 17005
ucentral.internal.restapi.host.0.cert = $UCENTRALTOPO_ROOT/certs/restapi-cert.pem
ucentral.internal.restapi.host.0.key = $UCENTRALTOPO_ROOT/certs/restapi-key.pem
ucentral.internal.restapi.host.0.key.password = mypassword
owprov.internal.restapi.host.0.backlog = 100
owprov.internal.restapi.host.0.security = relaxed
owprov.internal.restapi.host.0.rootca = $OWPROV_ROOT/certs/restapi-ca.pem
owprov.internal.restapi.host.0.address = *
owprov.internal.restapi.host.0.port = 17005
owprov.internal.restapi.host.0.cert = $OWPROV_ROOT/certs/restapi-cert.pem
owprov.internal.restapi.host.0.key = $OWPROV_ROOT/certs/restapi-key.pem
owprov.internal.restapi.host.0.key.password = mypassword
#
# Generic section that all microservices must have
#
ucentral.service.key = $UCENTRALTOPO_ROOT/certs/restapi-key.pem
ucentral.service.key = $OWPROV_ROOT/certs/restapi-key.pem
ucentral.service.key.password = mypassword
ucentral.system.data = $UCENTRALTOPO_ROOT/data
ucentral.system.data = $OWPROV_ROOT/data
ucentral.system.debug = false
ucentral.system.uri.private = https://localhost:17005
ucentral.system.uri.public = https://ucentral.dpaas.arilia.com:16005
@@ -48,8 +47,8 @@ alb.port = 16104
#
# Kafka
#
ucentral.kafka.group.id = topology
ucentral.kafka.client.id = topology1
ucentral.kafka.group.id = prov
ucentral.kafka.client.id = prov1
ucentral.kafka.enable = true
ucentral.kafka.brokerlist = a1.arilia.com:9092
# ucentral.kafka.brokerlist = debfarm1-node-c.arilia.com:9092
@@ -66,7 +65,7 @@ storage.type = sqlite
#storage.type = mysql
#storage.type = odbc
storage.type.sqlite.db = firmware.db
storage.type.sqlite.db = prov.db
storage.type.sqlite.idletime = 120
storage.type.sqlite.maxsessions = 128
@@ -103,7 +102,7 @@ logging.channels.c1.formatter = f1
# This is where the logs will be written. This path MUST exist
logging.channels.c2.class = FileChannel
logging.channels.c2.path = $UCENTRALTOPO_ROOT/logs/log
logging.channels.c2.path = $OWPROV_ROOT/logs/log
logging.channels.c2.formatter.class = PatternFormatter
logging.channels.c2.formatter.pattern = %Y-%m-%d %H:%M:%S %s: [%p] %t
logging.channels.c2.rotation = 20 M

View File

@@ -1,4 +1,4 @@
#!/bin/bash
export UCENTRALPROV_CONFIG=`pwd`
export UCENTRALPROV_ROOT=`pwd`
export OWPROV_CONFIG=`pwd`
export OWPROV_ROOT=`pwd`

View File

@@ -31,10 +31,10 @@
namespace uCentral {
static const char * vDAEMON_PROPERTIES_FILENAME = "ucentraltopo.properties";
static const char * vDAEMON_ROOT_ENV_VAR = "UCENTRALTOPO_ROOT";
static const char * vDAEMON_CONFIG_ENV_VAR = "UCENTRALTOPO_CONFIG";
static const char * vDAEMON_APP_NAME = uSERVICE_TOPOLOGY.c_str();
static const char * vDAEMON_PROPERTIES_FILENAME = "ow_prov.properties";
static const char * vDAEMON_ROOT_ENV_VAR = "OWPROV_ROOT";
static const char * vDAEMON_CONFIG_ENV_VAR = "OWPROV_CONFIG";
static const char * vDAEMON_APP_NAME = uSERVICE_PROVISIONING.c_str();
static const uint64_t vDAEMON_BUS_TIMER = 10000;
class Daemon : public MicroService {
@@ -49,10 +49,10 @@ namespace uCentral {
void initialize(Poco::Util::Application &self);
static Daemon *instance();
inline TopoDashboard & GetDashboard() { return DB_; }
inline OpenWifi::TopoDashboard & GetDashboard() { return DB_; }
private:
static Daemon *instance_;
TopoDashboard DB_;
OpenWifi::TopoDashboard DB_;
};

View File

@@ -5,7 +5,7 @@
#include "Dashboard.h"
#include "StorageService.h"
namespace uCentral {
namespace OpenWifi {
void TopoDashboard::Create() {
uint64_t Now = std::time(nullptr);
if(LastRun_==0 || (Now-LastRun_)>120) {

View File

@@ -6,16 +6,16 @@
#define UCENTRALGW_DASHBOARD_H
#include "uCentralTypes.h"
#include "RESTAPI_TopoObjects.h"
#include "RESTAPI_ProvObjects.h"
namespace uCentral {
namespace OpenWifi {
class TopoDashboard {
public:
void Create();
const TopoObjects::Report & Report() const { return DB_;}
const ProvObjects::Report & Report() const { return DB_;}
inline void Reset() { LastRun_=0; DB_.reset(); }
private:
TopoObjects::Report DB_;
ProvObjects::Report DB_;
uint64_t LastRun_=0;
};
}

View File

@@ -33,7 +33,7 @@ namespace uCentral {
static const std::string uSERVICE_GATEWAY{"ucentralgw"};
static const std::string uSERVICE_FIRMWARE{ "ucentralfws"};
static const std::string uSERVICE_TOPOLOGY{ "ucentraltopo"};
static const std::string uSERVICE_PROVISIONING{ "ucentralprov"};
static const std::string uSERVICE_PROVISIONING{ "owprov"};
class MyErrorHandler : public Poco::ErrorHandler {
public:

View File

@@ -14,7 +14,7 @@ namespace uCentral {
class RESTAPI_InternalServer *RESTAPI_InternalServer::instance_ = nullptr;
RESTAPI_InternalServer::RESTAPI_InternalServer() noexcept: SubSystemServer("RESTAPIInternalServer", "REST-ISRV", "ucentral.internal.restapi")
RESTAPI_InternalServer::RESTAPI_InternalServer() noexcept: SubSystemServer("RESTAPIInternalServer", "REST-ISRV", "owprov.internal.restapi")
{
}

314
src/RESTAPI_ProvObjects.cpp Normal file
View File

@@ -0,0 +1,314 @@
//
// Created by stephane bourque on 2021-08-04.
//
#include "RESTAPI_ProvObjects.h"
#include "RESTAPI_utils.h"
using uCentral::RESTAPI_utils::field_from_json;
using uCentral::RESTAPI_utils::field_to_json;
namespace OpenWifi::ProvObjects {
void ObjectInfo::to_json(Poco::JSON::Object &Obj) const {
uCentral::RESTAPI_utils::field_to_json(Obj,"id",id);
uCentral::RESTAPI_utils::field_to_json(Obj,"name",name);
uCentral::RESTAPI_utils::field_to_json(Obj,"description",description);
uCentral::RESTAPI_utils::field_to_json(Obj,"created",created);
uCentral::RESTAPI_utils::field_to_json(Obj,"modified",modified);
uCentral::RESTAPI_utils::field_to_json(Obj,"notes",notes);
}
bool ObjectInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
uCentral::RESTAPI_utils::field_from_json(Obj,"id",id);
uCentral::RESTAPI_utils::field_from_json(Obj,"name",name);
uCentral::RESTAPI_utils::field_from_json(Obj,"description",description);
uCentral::RESTAPI_utils::field_from_json(Obj,"created",created);
uCentral::RESTAPI_utils::field_from_json(Obj,"modified",modified);
uCentral::RESTAPI_utils::field_from_json(Obj,"notes",notes);
return true;
} catch(...) {
}
return false;
}
void ManagementPolicyEntry::to_json(Poco::JSON::Object &Obj) const {
uCentral::RESTAPI_utils::field_to_json( Obj,"users",users);
uCentral::RESTAPI_utils::field_to_json( Obj,"resources",resources);
uCentral::RESTAPI_utils::field_to_json( Obj,"access",access);
uCentral::RESTAPI_utils::field_to_json( Obj,"policy",policy);
}
bool ManagementPolicyEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
uCentral::RESTAPI_utils::field_from_json( Obj,"users",users);
uCentral::RESTAPI_utils::field_from_json( Obj,"resources",resources);
uCentral::RESTAPI_utils::field_from_json( Obj,"access",access);
uCentral::RESTAPI_utils::field_from_json( Obj,"policy",policy);
return true;
} catch(...) {
}
return false;
}
void ManagementPolicy::to_json(Poco::JSON::Object &Obj) const {
info.to_json(Obj);
uCentral::RESTAPI_utils::field_to_json(Obj, "entries", entries);
}
bool ManagementPolicy::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
info.from_json(Obj);
uCentral::RESTAPI_utils::field_from_json(Obj, "entries", entries);
return true;
} catch(...) {
}
return false;
}
void Entity::to_json(Poco::JSON::Object &Obj) const {
info.to_json(Obj);
uCentral::RESTAPI_utils::field_to_json( Obj,"parent",parent);
uCentral::RESTAPI_utils::field_to_json( Obj,"venues",venues);
uCentral::RESTAPI_utils::field_to_json( Obj,"children",children);
uCentral::RESTAPI_utils::field_to_json( Obj,"managers",managers);
uCentral::RESTAPI_utils::field_to_json( Obj,"contacts",contacts);
uCentral::RESTAPI_utils::field_to_json( Obj,"locations",locations);
uCentral::RESTAPI_utils::field_to_json( Obj,"managementPolicy",managementPolicy);
}
bool Entity::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
info.from_json(Obj);
uCentral::RESTAPI_utils::field_from_json( Obj,"parent",parent);
uCentral::RESTAPI_utils::field_from_json( Obj,"venues",venues);
uCentral::RESTAPI_utils::field_from_json( Obj,"children",children);
uCentral::RESTAPI_utils::field_from_json( Obj,"managers",managers);
uCentral::RESTAPI_utils::field_from_json( Obj,"contacts",contacts);
uCentral::RESTAPI_utils::field_from_json( Obj,"locations",locations);
uCentral::RESTAPI_utils::field_from_json( Obj,"managementPolicy",managementPolicy);
return true;
} catch(...) {
}
return false;
}
void DiGraphEntry::to_json(Poco::JSON::Object &Obj) const {
uCentral::RESTAPI_utils::field_to_json( Obj,"parent",parent);
uCentral::RESTAPI_utils::field_to_json( Obj,"child",child);
}
bool DiGraphEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
uCentral::RESTAPI_utils::field_from_json( Obj,"parent",parent);
uCentral::RESTAPI_utils::field_from_json( Obj,"child",child);
return true;
} catch (...) {
}
return false;
}
void Venue::to_json(Poco::JSON::Object &Obj) const {
info.to_json(Obj);
uCentral::RESTAPI_utils::field_to_json( Obj,"parent",parent);
uCentral::RESTAPI_utils::field_to_json( Obj,"owner",owner);
uCentral::RESTAPI_utils::field_to_json( Obj,"children",children);
uCentral::RESTAPI_utils::field_to_json( Obj,"managers",managers);
uCentral::RESTAPI_utils::field_to_json( Obj,"devices",devices);
uCentral::RESTAPI_utils::field_to_json( Obj,"topology",topology);
uCentral::RESTAPI_utils::field_to_json( Obj,"parent",parent);
uCentral::RESTAPI_utils::field_to_json( Obj,"design",design);
uCentral::RESTAPI_utils::field_to_json( Obj,"managementPolicy",managementPolicy);
}
bool Venue::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
info.from_json(Obj);
uCentral::RESTAPI_utils::field_from_json( Obj,"parent",parent);
uCentral::RESTAPI_utils::field_from_json( Obj,"owner",owner);
uCentral::RESTAPI_utils::field_from_json( Obj,"children",children);
uCentral::RESTAPI_utils::field_from_json( Obj,"managers",managers);
uCentral::RESTAPI_utils::field_from_json( Obj,"devices",devices);
uCentral::RESTAPI_utils::field_from_json( Obj,"topology",topology);
uCentral::RESTAPI_utils::field_from_json( Obj,"parent",parent);
uCentral::RESTAPI_utils::field_from_json( Obj,"design",design);
uCentral::RESTAPI_utils::field_from_json( Obj,"managementPolicy",managementPolicy);
return true;
} catch (...) {
}
return false;
}
void ManagementGroup::to_json(Poco::JSON::Object &Obj) const {
info.to_json(Obj);
uCentral::RESTAPI_utils::field_to_json( Obj,"managers",managers);
managementPolicy.to_json(Obj);
}
bool ManagementGroup::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
info.from_json(Obj);
uCentral::RESTAPI_utils::field_from_json( Obj,"managers",managers);
managementPolicy.from_json(Obj);
return true;
} catch (...) {
}
return false;
}
void Location::to_json(Poco::JSON::Object &Obj) const {
info.to_json(Obj);
uCentral::RESTAPI_utils::field_to_json( Obj,"type",OpenWifi::ProvObjects::to_string(type));
uCentral::RESTAPI_utils::field_to_json( Obj,"buildingName",buildingName);
uCentral::RESTAPI_utils::field_to_json( Obj,"addressLines",addressLines);
uCentral::RESTAPI_utils::field_to_json( Obj,"city",city);
uCentral::RESTAPI_utils::field_to_json( Obj,"state",state);
uCentral::RESTAPI_utils::field_to_json( Obj,"postal",postal);
uCentral::RESTAPI_utils::field_to_json( Obj,"country",country);
uCentral::RESTAPI_utils::field_to_json( Obj,"telephones",telephones);
uCentral::RESTAPI_utils::field_to_json( Obj,"contact",contact);
}
bool Location::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
info.from_json(Obj);
std::string tmp_type;
uCentral::RESTAPI_utils::field_from_json( Obj,"type", tmp_type);
type = location_from_string(tmp_type);
uCentral::RESTAPI_utils::field_from_json( Obj,"buildingName",buildingName);
uCentral::RESTAPI_utils::field_from_json( Obj,"addressLines",addressLines);
uCentral::RESTAPI_utils::field_from_json( Obj,"city",city);
uCentral::RESTAPI_utils::field_from_json( Obj,"state",state);
uCentral::RESTAPI_utils::field_from_json( Obj,"postal",postal);
uCentral::RESTAPI_utils::field_from_json( Obj,"country",country);
uCentral::RESTAPI_utils::field_from_json( Obj,"telephones",telephones);
uCentral::RESTAPI_utils::field_from_json( Obj,"contact",contact);
return true;
} catch (...) {
}
return false;
}
void Contact::to_json(Poco::JSON::Object &Obj) const {
info.to_json(Obj);
uCentral::RESTAPI_utils::field_to_json( Obj,"type", to_string(type));
uCentral::RESTAPI_utils::field_to_json( Obj,"title",title);
uCentral::RESTAPI_utils::field_to_json( Obj,"salutation",salutation);
uCentral::RESTAPI_utils::field_to_json( Obj,"firstname",firstname);
uCentral::RESTAPI_utils::field_to_json( Obj,"lastname",lastname);
uCentral::RESTAPI_utils::field_to_json( Obj,"initials",initials);
uCentral::RESTAPI_utils::field_to_json( Obj,"visual",visual);
uCentral::RESTAPI_utils::field_to_json( Obj,"mobiles",mobiles);
uCentral::RESTAPI_utils::field_to_json( Obj,"phones",phones);
uCentral::RESTAPI_utils::field_to_json( Obj,"location",location);
uCentral::RESTAPI_utils::field_to_json( Obj,"primaryEmail",primaryEmail);
uCentral::RESTAPI_utils::field_to_json( Obj,"secondaryEmail",secondaryEmail);
uCentral::RESTAPI_utils::field_to_json( Obj,"accessPIN",accessPIN);
}
bool Contact::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
info.from_json(Obj);
std::string tmp_type;
uCentral::RESTAPI_utils::field_from_json( Obj,"type", tmp_type);
type = contact_from_string(tmp_type);
uCentral::RESTAPI_utils::field_from_json( Obj,"title",title);
uCentral::RESTAPI_utils::field_from_json( Obj,"salutation",salutation);
uCentral::RESTAPI_utils::field_from_json( Obj,"firstname",firstname);
uCentral::RESTAPI_utils::field_from_json( Obj,"lastname",lastname);
uCentral::RESTAPI_utils::field_from_json( Obj,"initials",initials);
uCentral::RESTAPI_utils::field_from_json( Obj,"visual",visual);
uCentral::RESTAPI_utils::field_from_json( Obj,"mobiles",mobiles);
uCentral::RESTAPI_utils::field_from_json( Obj,"phones",phones);
uCentral::RESTAPI_utils::field_from_json( Obj,"location",location);
uCentral::RESTAPI_utils::field_from_json( Obj,"primaryEmail",primaryEmail);
uCentral::RESTAPI_utils::field_from_json( Obj,"secondaryEmail",secondaryEmail);
uCentral::RESTAPI_utils::field_from_json( Obj,"accessPIN",accessPIN);
return true;
} catch (...) {
}
return false;
}
void ServiceConfiguration::to_json(Poco::JSON::Object &Obj) const {
info.to_json(Obj);
managementPolicy.to_json(Obj);
}
bool ServiceConfiguration::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
info.from_json(Obj);
managementPolicy.from_json(Obj);
return true;
} catch(...) {
}
return false;
}
void InventoryTag::to_json(Poco::JSON::Object &Obj) const {
info.to_json(Obj);
uCentral::RESTAPI_utils::field_to_json(Obj, "serialNumber", serialNumber);
uCentral::RESTAPI_utils::field_to_json(Obj, "venue", venue);
uCentral::RESTAPI_utils::field_to_json(Obj, "entity", entity);
uCentral::RESTAPI_utils::field_to_json(Obj, "subEntity", subEntity);
uCentral::RESTAPI_utils::field_to_json(Obj, "subVenue", subVenue);
uCentral::RESTAPI_utils::field_to_json(Obj, "subscriber", subscriber);
}
bool InventoryTag::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
info.from_json(Obj);
uCentral::RESTAPI_utils::field_from_json( Obj,"serialNumber",serialNumber);
uCentral::RESTAPI_utils::field_from_json( Obj,"venue",venue);
uCentral::RESTAPI_utils::field_from_json( Obj,"entity",entity);
uCentral::RESTAPI_utils::field_from_json( Obj,"subEntity",subEntity);
uCentral::RESTAPI_utils::field_from_json( Obj,"subVenue",subVenue);
uCentral::RESTAPI_utils::field_from_json( Obj,"subscriber",subscriber);
return true;
} catch(...) {
}
return false;
}
void DeviceConfiguration::to_json(Poco::JSON::Object &Obj) const {
info.to_json(Obj);
managementPolicy.to_json(Obj);
uCentral::RESTAPI_utils::field_to_json( Obj,"deviceTypes",deviceTypes);
uCentral::RESTAPI_utils::field_to_json( Obj,"configuration",configuration);
}
bool DeviceConfiguration::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
info.from_json(Obj);
managementPolicy.from_json(Obj);
uCentral::RESTAPI_utils::field_from_json( Obj,"deviceTypes",deviceTypes);
uCentral::RESTAPI_utils::field_from_json( Obj,"configuration",configuration);
return true;
} catch(...) {
}
return false;
}
void Report::to_json(Poco::JSON::Object &Obj) const {
uCentral::RESTAPI_utils::field_to_json(Obj, "snapshot", snapShot);
uCentral::RESTAPI_utils::field_to_json(Obj, "devices", tenants);
};
void Report::reset() {
tenants.clear();
}
};

250
src/RESTAPI_ProvObjects.h Normal file
View File

@@ -0,0 +1,250 @@
//
// Created by stephane bourque on 2021-08-04.
//
#ifndef OWPROV_RESTAPI_PROVOBJECTS_H
#define OWPROV_RESTAPI_PROVOBJECTS_H
#include <string>
#include "RESTAPI_SecurityObjects.h"
namespace OpenWifi::ProvObjects {
struct ObjectInfo {
uCentral::Types::UUID_t id;
std::string name;
std::string description;
uCentral::SecurityObjects::NoteInfoVec notes;
uint64_t created;
uint64_t modified;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct ManagementPolicyEntry {
uCentral::Types::UUIDvec_t users;
uCentral::Types::UUIDvec_t resources;
uCentral::Types::StringVec access;
std::string policy;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct ManagementPolicy {
ObjectInfo info;
std::vector<ManagementPolicyEntry> entries;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct Entity {
ObjectInfo info;
uCentral::Types::UUID_t parent;
uCentral::Types::UUIDvec_t children;
uCentral::Types::UUIDvec_t venues;
uCentral::Types::UUIDvec_t managers;
uCentral::Types::UUIDvec_t contacts;
uCentral::Types::UUIDvec_t locations;
uCentral::Types::UUID_t managementPolicy;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct DiGraphEntry {
uCentral::Types::UUID_t parent;
uCentral::Types::UUID_t child;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
typedef std::vector<DiGraphEntry> DiGraph;
struct Venue {
ObjectInfo info;
uCentral::Types::UUID_t owner;
uCentral::Types::UUID_t parent;
uCentral::Types::UUIDvec_t children;
uCentral::Types::UUIDvec_t managers;
uCentral::Types::UUID_t managementPolicy;
uCentral::Types::UUIDvec_t devices;
DiGraph topology;
std::string design;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct ManagementGroup {
ObjectInfo info;
ManagementPolicy managementPolicy;
uCentral::Types::UUIDvec_t managers;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
enum LocationType {
LT_SERVICE, LT_EQUIPMENT, LT_AUTO, LT_MANUAL,
LT_SPECIAL, LT_UNKNOWN, LT_CORPORATE
};
inline std::string to_string(LocationType L) {
switch(L) {
case LT_SERVICE: return "SERVICE";
case LT_EQUIPMENT: return "EQUIPMENT";
case LT_AUTO: return "AUTO";
case LT_MANUAL: return "MANUAL";
case LT_SPECIAL: return "SPECIAL";
case LT_UNKNOWN: return "UNKNOWN";
case LT_CORPORATE: return "CORPORATE";
default: return "UNKNOWN";
}
}
inline LocationType location_from_string(const std::string &S) {
if(!Poco::icompare(S,"SERVICE"))
return LT_SERVICE;
else if(!Poco::icompare(S,"EQUIPMENT"))
return LT_EQUIPMENT;
else if(!Poco::icompare(S,"AUTO"))
return LT_AUTO;
else if(!Poco::icompare(S,"MANUAL"))
return LT_MANUAL;
else if(!Poco::icompare(S,"SPECIAL"))
return LT_SPECIAL;
else if(!Poco::icompare(S,"UNKNOWN"))
return LT_UNKNOWN;
else if(!Poco::icompare(S,"CORPORATE"))
return LT_CORPORATE;
return LT_UNKNOWN;
}
struct LocationTypeS {
LocationType type;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct Location {
ObjectInfo info;
LocationType type;
std::string buildingName;
uCentral::Types::StringVec addressLines;
std::string city;
std::string state;
std::string postal;
std::string country;
uCentral::Types::StringVec telephones;
uCentral::Types::UUID_t contact;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
enum ContactType {
CT_SUBSCRIBER, CT_USER, CT_INSTALLER, CT_CSR, CT_MANAGER,
CT_BUSINESSOWNER, CT_TECHNICIAN, CT_CORPORATE, CT_UNKNOWN
};
inline std::string to_string(ContactType L) {
switch(L) {
case CT_SUBSCRIBER: return "SUBSCRIBER";
case CT_USER: return "USER";
case CT_INSTALLER: return "INSTALLER";
case CT_CSR: return "CSR";
case CT_MANAGER: return "MANAGER";
case CT_BUSINESSOWNER: return "BUSINESSOWNER";
case CT_TECHNICIAN: return "TECHNICIAN";
case CT_CORPORATE: return "CORPORATE";
case CT_UNKNOWN: return "UNKNOWN";
default: return "UNKNOWN";
}
}
inline ContactType contact_from_string(const std::string &S) {
if(!Poco::icompare(S,"SUBSCRIBER"))
return CT_SUBSCRIBER;
else if(!Poco::icompare(S,"USER"))
return CT_USER;
else if(!Poco::icompare(S,"INSTALLER"))
return CT_INSTALLER;
else if(!Poco::icompare(S,"CSR"))
return CT_CSR;
else if(!Poco::icompare(S,"BUSINESSOWNER"))
return CT_BUSINESSOWNER;
else if(!Poco::icompare(S,"TECHNICIAN"))
return CT_TECHNICIAN;
else if(!Poco::icompare(S,"CORPORATE"))
return CT_CORPORATE;
else if(!Poco::icompare(S,"UNKNOWN"))
return CT_UNKNOWN;
return CT_UNKNOWN;
}
struct Contact {
ObjectInfo info;
ContactType type;
std::string title;
std::string salutation;
std::string firstname;
std::string lastname;
std::string initials;
std::string visual;
uCentral::Types::StringVec mobiles;
uCentral::Types::StringVec phones;
uCentral::Types::UUID_t location;
std::string primaryEmail;
std::string secondaryEmail;
std::string accessPIN;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct ServiceConfiguration {
ObjectInfo info;
ManagementPolicy managementPolicy;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct DeviceConfiguration {
ObjectInfo info;
ManagementPolicy managementPolicy;
uCentral::Types::StringVec deviceTypes;
std::string configuration;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct InventoryTag {
ObjectInfo info;
std::string serialNumber;
std::string venue;
std::string entity;
std::string subEntity;
std::string subVenue;
std::string subscriber;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct Report {
uint64_t snapShot;
uCentral::Types::CountedMap tenants;
void reset();
void to_json(Poco::JSON::Object &Obj) const;
};
};
#endif //OWPROV_RESTAPI_PROVOBJECTS_H

View File

@@ -1,10 +0,0 @@
//
// Created by stephane bourque on 2021-07-25.
//
#include "RESTAPI_TopoObjects.h"
namespace uCentral::TopoObjects {
void Report::reset() {
}
}

View File

@@ -1,19 +0,0 @@
//
// Created by stephane bourque on 2021-07-25.
//
#ifndef UCENTRAL_TOPO_RESTAPI_TOPOOBJECTS_H
#define UCENTRAL_TOPO_RESTAPI_TOPOOBJECTS_H
#include "Poco/JSON/Object.h"
namespace uCentral::TopoObjects {
struct Report {
void to_json(Poco::JSON::Object &Obj) const;
void reset();
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
}
#endif //UCENTRAL_TOPO_RESTAPI_TOPOOBJECTS_H

View File

@@ -0,0 +1,41 @@
//
// Created by stephane bourque on 2021-08-16.
//
#include "RESTAPI_entity_handler.h"
namespace OpenWifi{
void RESTAPI_entity_handler::handleRequest(Poco::Net::HTTPServerRequest &Request,
Poco::Net::HTTPServerResponse &Response) {
if (!ContinueProcessing(Request, Response))
return;
if (!IsAuthorized(Request, Response))
return;
ParseParameters(Request);
if(Request.getMethod() == Poco::Net::HTTPRequest::HTTP_GET)
DoGet(Request, Response);
else if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_POST)
DoPost(Request, Response);
else if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_DELETE)
DoDelete(Request, Response);
else if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_PUT)
DoPut(Request, Response);
else
BadRequest(Request, Response, "Unknown HTTP Method");
}
void RESTAPI_entity_handler::DoGet(Poco::Net::HTTPServerRequest &Request,
Poco::Net::HTTPServerResponse &Response) {}
void RESTAPI_entity_handler::DoDelete(Poco::Net::HTTPServerRequest &Request,
Poco::Net::HTTPServerResponse &Response) {}
void RESTAPI_entity_handler::DoPost(Poco::Net::HTTPServerRequest &Request,
Poco::Net::HTTPServerResponse &Response) {}
void RESTAPI_entity_handler::DoPut(Poco::Net::HTTPServerRequest &Request,
Poco::Net::HTTPServerResponse &Response) {}
}

View File

@@ -0,0 +1,38 @@
//
// Created by stephane bourque on 2021-08-16.
//
#ifndef OWPROV_RESTAPI_ENTITY_HANDLER_H
#define OWPROV_RESTAPI_ENTITY_HANDLER_H
#include "RESTAPI_handler.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "Poco/Net/HTTPServerResponse.h"
namespace OpenWifi {
class RESTAPI_entity_handler : public uCentral::RESTAPIHandler {
public:
RESTAPI_entity_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{
Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_POST,
Poco::Net::HTTPRequest::HTTP_PUT, Poco::Net::HTTPRequest::HTTP_DELETE,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Internal) {}
void handleRequest(Poco::Net::HTTPServerRequest &request,
Poco::Net::HTTPServerResponse &response) override final;
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/entity/{uuid}"}; };
void DoGet(Poco::Net::HTTPServerRequest &Request,
Poco::Net::HTTPServerResponse &Response);
void DoPost(Poco::Net::HTTPServerRequest &Request,
Poco::Net::HTTPServerResponse &Response);
void DoPut(Poco::Net::HTTPServerRequest &Request,
Poco::Net::HTTPServerResponse &Response);
void DoDelete(Poco::Net::HTTPServerRequest &Request,
Poco::Net::HTTPServerResponse &Response);
};
}
#endif //OWPROV_RESTAPI_ENTITY_HANDLER_H

View File

@@ -364,11 +364,11 @@ namespace uCentral {
Poco::JSON::Stringifier::stringify(Object, Answer);
}
void RESTAPIHandler::InitQueryBlock() {
bool RESTAPIHandler::InitQueryBlock() {
QB_.SerialNumber = GetParameter(uCentral::RESTAPI::Protocol::SERIALNUMBER, "");
QB_.StartDate = GetParameter(uCentral::RESTAPI::Protocol::STARTDATE, 0);
QB_.EndDate = GetParameter(uCentral::RESTAPI::Protocol::ENDDATE, 0);
QB_.Offset = GetParameter(uCentral::RESTAPI::Protocol::OFFSET, 0);
QB_.Offset = GetParameter(uCentral::RESTAPI::Protocol::OFFSET, 1);
QB_.Limit = GetParameter(uCentral::RESTAPI::Protocol::LIMIT, 100);
QB_.Filter = GetParameter(uCentral::RESTAPI::Protocol::FILTER, "");
QB_.Select = GetParameter(uCentral::RESTAPI::Protocol::SELECT, "");
@@ -376,6 +376,9 @@ namespace uCentral {
QB_.LogType = GetParameter(uCentral::RESTAPI::Protocol::LOGTYPE,0);
QB_.LastOnly = GetBoolParameter(uCentral::RESTAPI::Protocol::LASTONLY,false);
QB_.Newest = GetBoolParameter(uCentral::RESTAPI::Protocol::NEWEST,false);
if(QB_.Offset<1) return false;
return true;
}
[[nodiscard]] uint64_t RESTAPIHandler::Get(const char *Parameter,const Poco::JSON::Object::Ptr &Obj, uint64_t Default){

View File

@@ -140,7 +140,7 @@ namespace uCentral {
void SendFile(Poco::File & File, Poco::Net::HTTPServerRequest &Request, Poco::Net::HTTPServerResponse &Response);
const std::string &GetBinding(const std::string &Name, const std::string &Default);
void InitQueryBlock();
bool InitQueryBlock();
[[nodiscard]] static uint64_t Get(const char *Parameter,const Poco::JSON::Object::Ptr &Obj, uint64_t Default=0);
[[nodiscard]] static std::string GetS(const char *Parameter,const Poco::JSON::Object::Ptr &Obj, const std::string & Default="");
@@ -166,7 +166,7 @@ namespace uCentral {
Poco::Net::HTTPServerResponse &Response) override {
if (!IsAuthorized(Request, Response))
return;
BadRequest(Request, Response);
BadRequest(Request, Response, "Unknown API endpoint");
}
};

View File

@@ -9,13 +9,14 @@
#include "RESTAPI_handler.h"
#include "RESTAPI_system_command.h"
#include "RESTAPI_entity_handler.h"
namespace uCentral {
class RESTAPI_server *RESTAPI_server::instance_ = nullptr;
RESTAPI_server::RESTAPI_server() noexcept:
SubSystemServer("RESTAPIServer", "RESTAPIServer", "ucentralfws.restapi")
SubSystemServer("RESTAPIServer", "RESTAPIServer", "owprov.restapi")
{
}
@@ -60,7 +61,8 @@ namespace uCentral {
// std::cout << "Path: " << Request.getURI() << std::endl;
return RESTAPI_Router<
RESTAPI_system_command
RESTAPI_system_command,
OpenWifi::RESTAPI_entity_handler
>(Path,Bindings,Logger_);
}

View File

@@ -27,8 +27,8 @@ namespace uCentral {
DoPost(Request, Response);
else if(Request.getMethod()==Poco::Net::HTTPRequest::HTTP_GET)
DoGet(Request, Response);
BadRequest(Request, Response);
else
BadRequest(Request, Response, "Unsupported method.");
}
void RESTAPI_system_command::DoPost(Poco::Net::HTTPServerRequest &Request, Poco::Net::HTTPServerResponse &Response) {
@@ -94,7 +94,7 @@ namespace uCentral {
} catch(const Poco::Exception &E) {
Logger_.log(E);
}
BadRequest(Request, Response);
BadRequest(Request, Response, "Unsupported or missing parameters.");
}
void RESTAPI_system_command::DoGet(Poco::Net::HTTPServerRequest &Request, Poco::Net::HTTPServerResponse &Response) {
@@ -126,7 +126,7 @@ namespace uCentral {
} catch (const Poco::Exception &E) {
Logger_.log(E);
}
BadRequest(Request, Response);
BadRequest(Request, Response, "Unsupported or missing parameters.");
}
}

View File

@@ -6,9 +6,10 @@
// Arilia Wireless Inc.
//
#include "Poco/Util/Application.h"
#include "StorageService.h"
#include "Daemon.h"
#include "Poco/Util/Application.h"
#include "Utils.h"
namespace uCentral {
@@ -20,28 +21,6 @@ namespace uCentral {
{
}
std::string Storage::ConvertParams(const std::string & S) const {
std::string R;
R.reserve(S.size()*2+1);
if(dbType_==pgsql) {
auto Idx=1;
for(auto const & i:S)
{
if(i=='?') {
R += '$';
R.append(std::to_string(Idx++));
} else {
R += i;
}
}
} else {
R = S;
}
return R;
}
int Storage::Start() {
SubMutexGuard Guard(Mutex_);
@@ -50,14 +29,32 @@ namespace uCentral {
std::string DBType = Daemon()->ConfigGetString("storage.type");
if (DBType == "sqlite") {
DBType_ = ORM::DBType::sqlite;
Setup_SQLite();
} else if (DBType == "postgresql") {
DBType_ = ORM::DBType::postgresql;
Setup_PostgreSQL();
} else if (DBType == "mysql") {
DBType_ = ORM::DBType::mysql;
Setup_MySQL();
}
Create_Tables();
EntityDB_ = std::make_unique<OpenWifi::EntityDB>(DBType_,*Pool_, Logger_);
PolicyDB_ = std::make_unique<OpenWifi::PolicyDB>(DBType_, *Pool_, Logger_);
VenueDB_ = std::make_unique<OpenWifi::VenueDB>(DBType_, *Pool_, Logger_);
LocationDB_ = std::make_unique<OpenWifi::LocationDB>(DBType_, *Pool_, Logger_);
ContactDB_ = std::make_unique<OpenWifi::ContactDB>(DBType_, *Pool_, Logger_);
InventoryDB_ = std::make_unique<OpenWifi::InventoryDB>(DBType_, *Pool_, Logger_);
EntityDB_->Create();
PolicyDB_->Create();
VenueDB_->Create();
LocationDB_->Create();
ContactDB_->Create();
InventoryDB_->Create();
OpenWifi::ProvObjects::Entity R;
EntityDB_->GetRecord("id","xxx",R);
return 0;
}
@@ -65,5 +62,7 @@ namespace uCentral {
void Storage::Stop() {
Logger_.notice("Stopping.");
}
}
// namespace

View File

@@ -13,31 +13,23 @@
#include "Poco/Data/SessionPool.h"
#include "Poco/Data/SQLite/Connector.h"
#ifndef SMALL_BUILD
#include "Poco/Data/PostgreSQL/Connector.h"
#include "Poco/Data/MySQL/Connector.h"
#endif
#include "RESTAPI_TopoObjects.h"
#include "SubSystemServer.h"
#include "orm.h"
#include "storage_entity.h"
#include "storage_policies.h"
#include "storage_venue.h"
#include "storage_location.h"
#include "storage_contact.h"
#include "storage_inventory.h"
namespace uCentral {
class Storage : public SubSystemServer {
public:
enum StorageType {
sqlite,
pgsql,
mysql
};
enum CommandExecutionType {
COMMAND_PENDING,
COMMAND_EXECUTED,
COMMAND_COMPLETED
};
static Storage *instance() {
if (instance_ == nullptr) {
instance_ = new Storage;
@@ -45,28 +37,37 @@ namespace uCentral {
return instance_;
}
int Create_Tables();
int Start() override;
void Stop() override;
int Setup_SQLite();
[[nodiscard]] std::string ConvertParams(const std::string &S) const;
#ifndef SMALL_BUILD
int Setup_SQLite();
int Setup_MySQL();
int Setup_PostgreSQL();
#endif
OpenWifi::EntityDB & EntityDB() { return *EntityDB_; };
OpenWifi::PolicyDB & PolicyDB() { return *PolicyDB_; };
OpenWifi::VenueDB & VenueDB() { return *VenueDB_; };
OpenWifi::LocationDB & LocationDB() { return *LocationDB_; };
OpenWifi::ContactDB & ContactDB() { return *ContactDB_;};
OpenWifi::InventoryDB & InventoryDB() { return *InventoryDB_; };
private:
static Storage *instance_;
std::unique_ptr<Poco::Data::SessionPool> Pool_= nullptr;
StorageType dbType_ = sqlite;
std::unique_ptr<Poco::Data::SQLite::Connector> SQLiteConn_= nullptr;
#ifndef SMALL_BUILD
std::unique_ptr<Poco::Data::PostgreSQL::Connector> PostgresConn_= nullptr;
std::unique_ptr<Poco::Data::MySQL::Connector> MySQLConn_= nullptr;
#endif
ORM::DBType DBType_ = ORM::DBType::sqlite;
std::unique_ptr<OpenWifi::EntityDB> EntityDB_;
std::unique_ptr<OpenWifi::PolicyDB> PolicyDB_;
std::unique_ptr<OpenWifi::VenueDB> VenueDB_;
std::unique_ptr<OpenWifi::LocationDB> LocationDB_;
std::unique_ptr<OpenWifi::ContactDB> ContactDB_;
std::unique_ptr<OpenWifi::InventoryDB> InventoryDB_;
Storage() noexcept;
};

514
src/orm.h Normal file
View File

@@ -0,0 +1,514 @@
#ifndef __OPENWIFI_ORM_H__
#define __OPENWIFI_ORM_H__
#include <string>
#include <memory>
#include <iostream>
#include <fstream>
#include <map>
#include <vector>
#include <array>
#include "Poco/Tuple.h"
#include "Poco/Data/SessionPool.h"
#include "Poco/Data/Statement.h"
#include "Poco/Data/RecordSet.h"
#include "Poco/Data/SQLite/Connector.h"
#include "Poco/Logger.h"
namespace ORM {
enum DBType {
sqlite,
postgresql,
mysql
};
enum FieldType {
FT_INT,
FT_BIGINT,
FT_TEXT,
FT_VARCHAR,
FT_BLOB
};
enum Indextype {
ASC,
DESC
};
struct Field {
std::string Name;
FieldType Type;
int Size=0;
bool Index=false;
Field(std::string & N) {
Name = N;
Type = FT_TEXT;
}
Field(std::string N, int S) {
Name = N;
Type = FT_TEXT;
Size = S;
}
Field(std::string N, int S, bool I) {
Name = N;
Type = FT_TEXT;
Size = S;
Index = I;
}
};
typedef std::vector<Field> FieldVec;
struct IndexEntry {
std::string FieldName;
Indextype Type;
};
typedef std::vector<IndexEntry> IndexEntryVec;
struct Index {
std::string Name;
IndexEntryVec Entries;
};
typedef std::vector<Index> IndexVec;
inline std::string FieldTypeToChar(DBType Type, FieldType T, int Size=0) {
switch(T) {
case FT_INT: return "INT";
case FT_BIGINT: return "BIGINT";
case FT_TEXT: return "TEXT";
case FT_VARCHAR:
if(Size)
return std::string("VARCHAR(") + std::to_string(Size) + std::string(")");
else
return "TEXT";
case FT_BLOB:
if(Type==DBType::mysql)
return "LONGBLOB";
else if(Type==DBType::postgresql)
return "BYTEA";
else if(Type==DBType::sqlite)
return "BLOB";
default:
assert(false);
return "";
}
assert(false);
return "";
}
enum CompareOperations {
EQUAL,
LESS,
LESS_OR_EQUAL,
GREATER,
GREATER_OR_EQUAL,
NOT_EQUAL
};
inline std::string to_string(ORM::CompareOperations O) {
switch(O) {
case EQUAL: return "=";
case LESS: return "<";
case LESS_OR_EQUAL: return "<=";
case GREATER: return ">";
case GREATER_OR_EQUAL: return ">=";
case NOT_EQUAL: return "!=";
}
}
inline std::string to_string(uint64_t V) {
return std::to_string(V);
}
inline std::string to_string(int V) {
return std::to_string(V);
}
inline std::string to_string(bool V) {
return std::to_string(V);
}
inline std::string to_string(const std::string &S) {
return S;
}
inline std::string to_string(const char * S) {
return S;
}
template <typename ValueType> struct Comparison {
std::string Name;
ValueType Value;
ORM::CompareOperations Operation;
Comparison(const std::string & N, ORM::CompareOperations Op, ValueType & V) :
Name(N), Operation(Op), Value(V) {}
std::string OP() {
return Name + " " + to_string(Operation) + " " + to_string(Value);
}
};
template <typename RecordTuple, typename RecordType> class DB {
public:
DB( DBType dbtype,
const char *TableName,
const FieldVec & Fields,
const IndexVec & Indexes,
Poco::Data::SessionPool & Pool,
Poco::Logger &L):
Type(dbtype),
DBName(TableName),
Pool_(Pool),
Logger_(L)
{
bool first = true;
int Place=0;
assert( RecordTuple::length == Fields.size());
for(const auto &i:Fields) {
FieldNames_[i.Name] = Place;
if(!first) {
CreateFields_ += ", ";
SelectFields_ += ", ";
UpdateFields_ += ", ";
SelectList_ += ", ";
} else {
SelectList_ += "(";
}
CreateFields_ += i.Name + " " + FieldTypeToChar(Type, i.Type,i.Size) + (i.Index ? " unique primary key" : "");
SelectFields_ += i.Name ;
UpdateFields_ += i.Name + "=?";
SelectList_ += "?";
first = false;
Place++;
}
SelectList_ += ")";
if(!Indexes.empty()) {
if(Type==sqlite || Type==postgresql) {
for(const auto &j:Indexes) {
std::string IndexLine;
IndexLine = std::string("CREATE INDEX IF NOT EXISTS ") + j.Name + std::string(" ON ") + DBName + " (";
bool first_entry=true;
for(const auto &k:j.Entries) {
assert(FieldNames_.find(k.FieldName) != FieldNames_.end());
if(!first_entry) {
IndexLine += " , ";
}
first_entry = false;
IndexLine += k.FieldName + std::string(" ") + std::string(k.Type == Indextype::ASC ? "ASC" : "DESC") ;
}
IndexLine += " );";
IndexCreation += IndexLine;
}
} else if(Type==mysql) {
bool firstIndex = true;
std::string IndexLine;
for(const auto &j:Indexes) {
if(!firstIndex)
IndexLine += ", ";
firstIndex = false;
IndexLine += " INDEX " + j.Name + " ( " ;
bool first_entry=true;
for(const auto &k:j.Entries) {
assert(FieldNames_.find(k.FieldName) != FieldNames_.end());
if(!first_entry) {
IndexLine += " ,";
}
first_entry = false;
IndexLine += k.FieldName + std::string(k.Type == Indextype::ASC ? " ASC" : " DESC");
}
IndexLine += " ) ";
}
IndexCreation = IndexLine;
}
}
}
[[nodiscard]] const std::string & CreateFields() const { return CreateFields_; };
[[nodiscard]] const std::string & SelectFields() const { return SelectFields_; };
[[nodiscard]] const std::string & SelectList() const { return SelectList_; };
[[nodiscard]] const std::string & UpdateFields() const { return UpdateFields_; };
static std::string Escape(const std::string &S) {
std::string R;
for(const auto &i:S)
if(i=='\'')
R += "''";
else
R += i;
return R;
}
inline bool Create() {
std::string S;
if(Type==mysql) {
if(IndexCreation.empty())
S = "create table if not exists " + DBName +" ( " + CreateFields_ + " )" ;
else
S = "create table if not exists " + DBName +" ( " + CreateFields_ + " ), " + IndexCreation + " )";
} else if (Type==postgresql || Type==sqlite) {
S = "create table if not exists " + DBName + " ( " + CreateFields_ + " ); " + IndexCreation ;
}
// std::cout << "CREATE-DB: " << S << std::endl;
try {
Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement CreateStatement(Session);
CreateStatement << S;
CreateStatement.execute();
return true;
} catch (const Poco::Exception &E) {
std::cout << "Exception while creating DB: " << E.name() << std::endl;
}
return false;
}
std::string ConvertParams(const std::string & S) const {
std::string R;
R.reserve(S.size()*2+1);
if(Type==postgresql) {
auto Idx=1;
for(auto const & i:S)
{
if(i=='?') {
R += '$';
R.append(std::to_string(Idx++));
} else {
R += i;
}
}
} else {
R = S;
}
return R;
}
virtual void Convert( RecordTuple &in , RecordType &out);
virtual void Convert( RecordType &in , RecordTuple &out);
bool CreateRecord( RecordType & R) {
try {
Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Insert(Session);
RecordTuple RT;
ConvertParams(R, RT);
std::string St = "insert into " + DBName + " ( " + SelectFields_ + " ) values " + SelectList_;
Insert << ConvertParams(St) ,
Poco::Data::Keywords::use(RT),
Insert.execute();
return true;
} catch (const Poco::Exception &E) {
// Logger_.log(E);
}
return false;
}
template <typename T> bool GetRecord( const std::string &FieldName, T Value, RecordType & R) {
try {
Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Select(Session);
RecordTuple RT;
std::string St = "select " + SelectFields_ + " from " + DBName + " where " + FieldName + "=?" ;
Select << ConvertParams(St) ,
Poco::Data::Keywords::into(RT),
Poco::Data::Keywords::use(Value);
Select.execute();
Convert(RT,R);
return true;
} catch (const Poco::Exception &E) {
// Logger_.log(E);
}
return false;
}
typedef std::vector<std::string> StringVec;
template < typename T,
typename T0, typename T1> bool GR(const StringVec &FieldName, T & R,T0 &V0, T1 &V1) {
try {
Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Select(Session);
RecordTuple RT;
std::string St = "select " + SelectFields_ + " from " + DBName
+ " where " + FieldName[0] + "=? and " + FieldName[1] + "=?" ;
Select << ConvertParams(St) ,
Poco::Data::Keywords::into(RT),
Poco::Data::Keywords::use(V0),
Poco::Data::Keywords::use(V1);
Select.execute();
Convert(RT,R);
return true;
} catch (const Poco::Exception &E) {
// Logger_.log(E);
}
return false;
}
typedef std::vector<RecordTuple> RecordList;
bool GetRecords( uint64_t Offset, uint64_t HowMany, std::vector<RecordType> & Records, std::string Where = "") {
try {
Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Select(Session);
RecordList RL;
std::string St = "select " + SelectFields_ + " from " + DBName + ComputeRange(Offset, HowMany) ;
Select << ConvertParams(St) ,
Poco::Data::Keywords::into(RL);
Select.execute();
for(const auto &i:RL) {
RecordType R;
Convert(i, R);
Records.template emplace_back(R);
}
return true;
} catch (const Poco::Exception &E) {
// Logger_.log(E);
}
return false;
}
template <typename T> bool UpdateRecord( const std::string &FieldName, T & Value, RecordType & R) {
try {
Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Update(Session);
RecordTuple RT;
Convert(R, RT);
std::string St = "update " + DBName + " set " + UpdateFields_ + " where " + FieldName + "=?" ;
Update << ConvertParams(St) ,
Poco::Data::Keywords::use(RT),
Poco::Data::Keywords::use(Value);
Update.execute();
return true;
} catch (const Poco::Exception &E) {
// Logger_.log(E);
}
return false;
}
template <typename T> bool DeleteRecord( const std::string &FieldName, T Value) {
try {
Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Delete(Session);
std::string St = "delete from " + DBName + " where " + FieldName + "=?" ;
Delete << ConvertParams(St) ,
Poco::Data::Keywords::use(Value);
Delete.execute();
return true;
} catch (const Poco::Exception &E) {
// Logger_.log(E);
}
return false;
}
bool DeleteRecords( const std::string & WhereClause ) {
try {
assert( !WhereClause.empty());
Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Delete(Session);
std::string St = "delete from " + DBName + " " + WhereClause;
Delete << ConvertParams(St);
Delete.execute();
return true;
} catch (const Poco::Exception &E) {
// Logger_.log(E);
}
return false;
}
[[nodiscard]] inline std::string ComputeRange(uint64_t From, uint64_t HowMany) {
if(From<1) From=1;
if(Type==ORM::sqlite) {
return " LIMIT " + std::to_string(From-1) + ", " + std::to_string(HowMany) + " ";
} else if(Type==ORM::postgresql) {
return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From-1) + " ";
} else if(Type==ORM::mysql) {
return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From-1) + " ";
}
return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From-1) + " ";
}
private:
DBType Type;
std::string DBName;
std::string CreateFields_;
std::string SelectFields_;
std::string SelectList_;
std::string UpdateFields_;
std::string IndexCreation;
std::map<std::string,int> FieldNames_;
Poco::Data::SessionPool &Pool_;
Poco::Logger &Logger_;
};
}
/*
int main(int, char**)
{
auto SQLiteConn_ = std::make_unique<Poco::Data::SQLite::Connector>();
SQLiteConn_->registerConnector();
auto Pool_ = std::make_unique<Poco::Data::SessionPool>(SQLiteConn_->name(), "test.db", 4, 64, 60);
ORM::FieldVec DB1Fields{ ORM::Field{"id",40, true},
ORM::Field{"name", ORM::FT_INT} };
ORM::IndexVec Indexes{
{ std::string("name_index"), ORM::IndexEntryVec{ {std::string("name"), ORM::Indextype::ASC} } } };
ORM::DB<DB1_record, Rec1> DB1(ORM::sqlite ,
"tab1",
ORM::FieldVec{
ORM::Field{"id",40, true},
ORM::Field{"name", ORM::FT_INT} },
ORM::IndexVec{{ std::string("name_index"), ORM::IndexEntryVec{ {std::string("name"), ORM::Indextype::ASC} } }},
*Pool_);
std::cout << DB1.CreateFields() << std::endl;
std::cout << DB1.SelectFields() << std::endl;
std::cout << DB1.SelectList() << std::endl;
std::cout << DB1.UpdateFields() << std::endl;
std::cout << DB1.Create() << std::endl;
User U1{ 25, "steph"};
auto SS = &User::Name;
std::cout << (typeid( User::Name ) == typeid( std::string )) << std::endl;
std::cout << "Name: " << U1.*SS << std::endl;
auto RR = ORM::Escape("I'm a \"cool\" dude");
std::cout << "RR: " << RR << std::endl;
return 0;
}
*/
#endif

89
src/storage_contact.cpp Normal file
View File

@@ -0,0 +1,89 @@
//
// Created by stephane bourque on 2021-08-16.
//
#include "storage_contact.h"
#include "Utils.h"
#include "uCentralTypes.h"
#include "RESTAPI_utils.h"
#include "RESTAPI_SecurityObjects.h"
namespace OpenWifi {
static ORM::FieldVec ContactDB_Fields{
// object info
ORM::Field{"id",64, true},
ORM::Field{"name",ORM::FieldType::FT_TEXT},
ORM::Field{"description",ORM::FieldType::FT_TEXT},
ORM::Field{"notes",ORM::FieldType::FT_TEXT},
ORM::Field{"created",ORM::FieldType::FT_BIGINT},
ORM::Field{"modified",ORM::FieldType::FT_BIGINT},
ORM::Field{"type",ORM::FieldType::FT_TEXT},
ORM::Field{"title",ORM::FieldType::FT_TEXT},
ORM::Field{"salutation",ORM::FieldType::FT_TEXT},
ORM::Field{"firstname",ORM::FieldType::FT_TEXT},
ORM::Field{"lastname",ORM::FieldType::FT_TEXT},
ORM::Field{"initials",ORM::FieldType::FT_TEXT},
ORM::Field{"visual",ORM::FieldType::FT_TEXT},
ORM::Field{"mobiles",ORM::FieldType::FT_TEXT},
ORM::Field{"phones",ORM::FieldType::FT_TEXT},
ORM::Field{"location",ORM::FieldType::FT_TEXT},
ORM::Field{"primaryEmail",ORM::FieldType::FT_TEXT},
ORM::Field{"secondaryEmail",ORM::FieldType::FT_TEXT},
ORM::Field{"accessPIN",ORM::FieldType::FT_TEXT}
};
static ORM::IndexVec ContactDB_Indexes{
{ std::string("contact_name_index"),
ORM::IndexEntryVec{
{std::string("name"),
ORM::Indextype::ASC} } }
};
ContactDB::ContactDB( ORM::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L) :
DB(T, "contacts", ContactDB_Fields, ContactDB_Indexes, P, L) {}
}
template<> void ORM::DB< OpenWifi::ContactDBRecordType, OpenWifi::ProvObjects::Contact>::Convert(OpenWifi::ContactDBRecordType &In, OpenWifi::ProvObjects::Contact &Out) {
Out.info.id = In.get<0>();
Out.info.name = In.get<1>();
Out.info.description = In.get<2>();
Out.info.notes = uCentral::RESTAPI_utils::to_object_array<uCentral::SecurityObjects::NoteInfo>(In.get<3>());
Out.info.created = In.get<4>();
Out.info.modified = In.get<5>();
Out.type = OpenWifi::ProvObjects::contact_from_string(In.get<6>());
Out.title = In.get<7>();
Out.salutation = In.get<8>();
Out.firstname = In.get<9>();
Out.lastname = In.get<10>();
Out.initials = In.get<11>();
Out.visual = In.get<12>();
uCentral::Types::from_string(In.get<13>(), Out.mobiles);
uCentral::Types::from_string(In.get<14>(), Out.phones);
Out.primaryEmail = In.get<15>();
Out.secondaryEmail = In.get<16>();
Out.accessPIN = In.get<17>();
}
template<> void ORM::DB< OpenWifi::ContactDBRecordType, OpenWifi::ProvObjects::Contact>::Convert(OpenWifi::ProvObjects::Contact &In, OpenWifi::ContactDBRecordType &Out) {
Out.set<0>(In.info.id);
Out.set<1>(In.info.name);
Out.set<2>(In.info.description);
Out.set<3>(uCentral::RESTAPI_utils::to_string(In.info.notes));
Out.set<4>(In.info.created);
Out.set<5>(In.info.modified);
Out.set<6>(to_string(In.type));
Out.set<7>(In.title);
Out.set<8>(In.salutation);
Out.set<9>(In.firstname);
Out.set<10>(In.lastname);
Out.set<11>(In.initials);
Out.set<12>(In.visual);
Out.set<13>(uCentral::Types::to_string(In.mobiles));
Out.set<14>(uCentral::Types::to_string(In.phones));
Out.set<15>(In.primaryEmail);
Out.set<16>(In.secondaryEmail);
Out.set<17>(In.accessPIN);
}

42
src/storage_contact.h Normal file
View File

@@ -0,0 +1,42 @@
//
// Created by stephane bourque on 2021-08-16.
//
#ifndef OWPROV_STORAGE_CONTACT_H
#define OWPROV_STORAGE_CONTACT_H
#include "orm.h"
#include "RESTAPI_ProvObjects.h"
namespace OpenWifi {
typedef Poco::Tuple<
std::string,
std::string,
std::string,
std::string,
uint64_t,
uint64_t,
std::string,
std::string,
std::string,
std::string,
std::string,
std::string,
std::string,
std::string,
std::string,
std::string,
std::string,
std::string,
std::string
> ContactDBRecordType;
class ContactDB : public ORM::DB<ContactDBRecordType, ProvObjects::Contact> {
public:
ContactDB( ORM::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L);
private:
};
}
#endif //OWPROV_STORAGE_CONTACT_H

69
src/storage_entity.cpp Normal file
View File

@@ -0,0 +1,69 @@
//
// Created by stephane bourque on 2021-08-15.
//
#include "storage_entity.h"
#include "Utils.h"
#include "uCentralTypes.h"
#include "RESTAPI_utils.h"
#include "RESTAPI_SecurityObjects.h"
namespace OpenWifi {
static ORM::FieldVec EntityDB_Fields{
// object info
ORM::Field{"id",64, true},
ORM::Field{"name",ORM::FieldType::FT_TEXT},
ORM::Field{"description",ORM::FieldType::FT_TEXT},
ORM::Field{"notes",ORM::FieldType::FT_TEXT},
ORM::Field{"created",ORM::FieldType::FT_BIGINT},
ORM::Field{"modified",ORM::FieldType::FT_BIGINT},
ORM::Field{"parent",ORM::FieldType::FT_TEXT},
ORM::Field{"children",ORM::FieldType::FT_TEXT},
ORM::Field{"managers",ORM::FieldType::FT_TEXT},
ORM::Field{"contacts",ORM::FieldType::FT_TEXT},
ORM::Field{"locations",ORM::FieldType::FT_TEXT},
ORM::Field{"managementPolicy",ORM::FieldType::FT_TEXT}
};
static ORM::IndexVec EntityDB_Indexes{
{ std::string("entity_name_index"),
ORM::IndexEntryVec{
{std::string("name"),
ORM::Indextype::ASC} } }
};
EntityDB::EntityDB( ORM::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L) :
DB(T, "entities", EntityDB_Fields, EntityDB_Indexes, P, L) {}
}
template<> void ORM::DB< OpenWifi::EntityDBRecordType, OpenWifi::ProvObjects::Entity>::Convert(OpenWifi::EntityDBRecordType &In, OpenWifi::ProvObjects::Entity &Out) {
Out.info.id = In.get<0>();
Out.info.name = In.get<1>();
Out.info.description = In.get<2>();
Out.info.notes = uCentral::RESTAPI_utils::to_object_array<uCentral::SecurityObjects::NoteInfo>(In.get<3>());
Out.info.created = In.get<4>();
Out.info.modified = In.get<5>();
Out.parent = In.get<6>();
uCentral::Types::from_string(In.get<7>(), Out.children);
uCentral::Types::from_string(In.get<8>(), Out.managers);
uCentral::Types::from_string(In.get<9>(), Out.contacts);
uCentral::Types::from_string(In.get<10>(), Out.locations);
Out.managementPolicy = In.get<11>();
}
template<> void ORM::DB< OpenWifi::EntityDBRecordType, OpenWifi::ProvObjects::Entity>::Convert(OpenWifi::ProvObjects::Entity &In, OpenWifi::EntityDBRecordType &Out) {
Out.set<0>(In.info.id);
Out.set<1>(In.info.name);
Out.set<2>(In.info.description);
Out.set<3>(uCentral::RESTAPI_utils::to_string(In.info.notes));
Out.set<4>(In.info.created);
Out.set<5>(In.info.modified);
Out.set<6>(In.parent);
Out.set<7>(uCentral::Types::to_string(In.children));
Out.set<8>(uCentral::Types::to_string(In.managers));
Out.set<9>(uCentral::Types::to_string(In.contacts));
Out.set<10>(uCentral::Types::to_string(In.locations));
Out.set<11>(In.managementPolicy);
}

50
src/storage_entity.h Normal file
View File

@@ -0,0 +1,50 @@
//
// Created by stephane bourque on 2021-08-15.
//
#ifndef OWPROV_STORAGE_ENTITY_H
#define OWPROV_STORAGE_ENTITY_H
#include "orm.h"
#include "RESTAPI_ProvObjects.h"
namespace OpenWifi {
/*
ORM::Field{"id",64, true},
ORM::Field{"name",ORM::FieldType::FT_TEXT},
ORM::Field{"description",ORM::FieldType::FT_TEXT},
ORM::Field{"notes",ORM::FieldType::FT_TEXT},
ORM::Field{"created",ORM::FieldType::FT_BIGINT},
ORM::Field{"modified",ORM::FieldType::FT_BIGINT},
ORM::Field{"parent",ORM::FieldType::FT_TEXT},
ORM::Field{"children",ORM::FieldType::FT_TEXT},
ORM::Field{"managers",ORM::FieldType::FT_TEXT},
ORM::Field{"contacts",ORM::FieldType::FT_TEXT},
ORM::Field{"locations",ORM::FieldType::FT_TEXT},
ORM::Field{"managementPolicy",ORM::FieldType::FT_TEXT}
*/
typedef Poco::Tuple<
std::string,
std::string,
std::string,
std::string,
uint64_t,
uint64_t,
std::string,
std::string,
std::string,
std::string,
std::string,
std::string
> EntityDBRecordType;
class EntityDB : public ORM::DB<EntityDBRecordType, ProvObjects::Entity> {
public:
EntityDB( ORM::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L);
private:
};
}
#endif //OWPROV_STORAGE_ENTITY_H

70
src/storage_inventory.cpp Normal file
View File

@@ -0,0 +1,70 @@
//
// Created by stephane bourque on 2021-08-16.
//
#include "storage_inventory.h"
#include "Utils.h"
#include "uCentralTypes.h"
#include "RESTAPI_utils.h"
#include "RESTAPI_SecurityObjects.h"
namespace OpenWifi {
static ORM::FieldVec InventoryDB_Fields{
// object info
ORM::Field{"id",64, true},
ORM::Field{"name",ORM::FieldType::FT_TEXT},
ORM::Field{"description",ORM::FieldType::FT_TEXT},
ORM::Field{"notes",ORM::FieldType::FT_TEXT},
ORM::Field{"created",ORM::FieldType::FT_BIGINT},
ORM::Field{"modified",ORM::FieldType::FT_BIGINT},
ORM::Field{"serialNumber",ORM::FieldType::FT_TEXT},
ORM::Field{"venue",ORM::FieldType::FT_TEXT},
ORM::Field{"entity",ORM::FieldType::FT_TEXT},
ORM::Field{"subEntity",ORM::FieldType::FT_TEXT},
ORM::Field{"subVenue",ORM::FieldType::FT_TEXT}
};
static ORM::IndexVec InventoryDB_Indexes{
{ std::string("inventory_name_index"),
ORM::IndexEntryVec{
{std::string("name"),
ORM::Indextype::ASC} } },
{ std::string("serial_index"),
ORM::IndexEntryVec{
{std::string("serialNumber"),
ORM::Indextype::ASC} } }
};
InventoryDB::InventoryDB( ORM::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L) :
DB(T, "inventory", InventoryDB_Fields, InventoryDB_Indexes, P, L) {}
}
template<> void ORM::DB< OpenWifi::InventoryDBRecordType, OpenWifi::ProvObjects::InventoryTag>::Convert(OpenWifi::InventoryDBRecordType &In, OpenWifi::ProvObjects::InventoryTag &Out) {
Out.info.id = In.get<0>();
Out.info.name = In.get<1>();
Out.info.description = In.get<2>();
Out.info.notes = uCentral::RESTAPI_utils::to_object_array<uCentral::SecurityObjects::NoteInfo>(In.get<3>());
Out.info.created = In.get<4>();
Out.info.modified = In.get<5>();
Out.serialNumber = In.get<6>();
Out.venue = In.get<7>();
Out.entity = In.get<8>();
Out.subEntity = In.get<9>();
Out.subVenue = In.get<10>();
}
template<> void ORM::DB< OpenWifi::InventoryDBRecordType, OpenWifi::ProvObjects::InventoryTag>::Convert(OpenWifi::ProvObjects::InventoryTag &In, OpenWifi::InventoryDBRecordType &Out) {
Out.set<0>(In.info.id);
Out.set<1>(In.info.name);
Out.set<2>(In.info.description);
Out.set<3>(uCentral::RESTAPI_utils::to_string(In.info.notes));
Out.set<4>(In.info.created);
Out.set<5>(In.info.modified);
Out.set<6>(In.serialNumber);
Out.set<7>(In.venue);
Out.set<8>(In.entity);
Out.set<9>(In.subEntity);
Out.set<10>(In.subVenue);
}

33
src/storage_inventory.h Normal file
View File

@@ -0,0 +1,33 @@
//
// Created by stephane bourque on 2021-08-16.
//
#ifndef OWPROV_STORAGE_INVENTORY_H
#define OWPROV_STORAGE_INVENTORY_H
#include "orm.h"
#include "RESTAPI_ProvObjects.h"
namespace OpenWifi {
typedef Poco::Tuple<
std::string,
std::string,
std::string,
std::string,
uint64_t,
uint64_t,
std::string,
std::string,
std::string,
std::string,
std::string
> InventoryDBRecordType;
class InventoryDB : public ORM::DB<InventoryDBRecordType, ProvObjects::InventoryTag> {
public:
InventoryDB( ORM::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L);
private:
};
}
#endif //OWPROV_STORAGE_INVENTORY_H

78
src/storage_location.cpp Normal file
View File

@@ -0,0 +1,78 @@
//
// Created by stephane bourque on 2021-08-16.
//
#include "storage_location.h"
#include "Utils.h"
#include "uCentralTypes.h"
#include "RESTAPI_utils.h"
#include "RESTAPI_SecurityObjects.h"
namespace OpenWifi {
static ORM::FieldVec LocationDB_Fields{
// object info
ORM::Field{"id",64, true},
ORM::Field{"name",ORM::FieldType::FT_TEXT},
ORM::Field{"description",ORM::FieldType::FT_TEXT},
ORM::Field{"notes",ORM::FieldType::FT_TEXT},
ORM::Field{"created",ORM::FieldType::FT_BIGINT},
ORM::Field{"modified",ORM::FieldType::FT_BIGINT},
ORM::Field{"type",ORM::FieldType::FT_TEXT},
ORM::Field{"buildingName",ORM::FieldType::FT_TEXT},
ORM::Field{"addressLines",ORM::FieldType::FT_TEXT},
ORM::Field{"city",ORM::FieldType::FT_TEXT},
ORM::Field{"state",ORM::FieldType::FT_TEXT},
ORM::Field{"postal",ORM::FieldType::FT_TEXT},
ORM::Field{"country",ORM::FieldType::FT_TEXT},
ORM::Field{"telephones",ORM::FieldType::FT_TEXT},
ORM::Field{"contact",ORM::FieldType::FT_TEXT}
};
static ORM::IndexVec LocationDB_Indexes{
{ std::string("location_name_index"),
ORM::IndexEntryVec{
{std::string("name"),
ORM::Indextype::ASC} } }
};
LocationDB::LocationDB( ORM::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L) :
DB(T, "locations", LocationDB_Fields, LocationDB_Indexes, P, L) {}
}
template<> void ORM::DB< OpenWifi::LocationDBRecordType, OpenWifi::ProvObjects::Location>::Convert(OpenWifi::LocationDBRecordType &In, OpenWifi::ProvObjects::Location &Out) {
Out.info.id = In.get<0>();
Out.info.name = In.get<1>();
Out.info.description = In.get<2>();
Out.info.notes = uCentral::RESTAPI_utils::to_object_array<uCentral::SecurityObjects::NoteInfo>(In.get<3>());
Out.info.created = In.get<4>();
Out.info.modified = In.get<5>();
Out.type = OpenWifi::ProvObjects::location_from_string(In.get<6>());
Out.buildingName = In.get<7>();
uCentral::Types::from_string(In.get<8>(), Out.addressLines);
Out.city = In.get<9>();
Out.state = In.get<10>();
Out.postal = In.get<11>();
Out.country = In.get<12>();
uCentral::Types::from_string(In.get<13>(), Out.telephones);
Out.contact = In.get<14>();
}
template<> void ORM::DB< OpenWifi::LocationDBRecordType, OpenWifi::ProvObjects::Location>::Convert(OpenWifi::ProvObjects::Location &In, OpenWifi::LocationDBRecordType &Out) {
Out.set<0>(In.info.id);
Out.set<1>(In.info.name);
Out.set<2>(In.info.description);
Out.set<3>(uCentral::RESTAPI_utils::to_string(In.info.notes));
Out.set<4>(In.info.created);
Out.set<5>(In.info.modified);
Out.set<6>(OpenWifi::ProvObjects::to_string(In.type));
Out.set<7>(In.buildingName);
Out.set<8>(uCentral::Types::to_string(In.addressLines));
Out.set<9>(In.city);
Out.set<10>(In.state);
Out.set<11>(In.postal);
Out.set<12>(In.country);
Out.set<13>(uCentral::Types::to_string(In.telephones));
Out.set<14>(In.contact);
}

38
src/storage_location.h Normal file
View File

@@ -0,0 +1,38 @@
//
// Created by stephane bourque on 2021-08-16.
//
#ifndef OWPROV_STORAGE_LOCATION_H
#define OWPROV_STORAGE_LOCATION_H
#include "orm.h"
#include "RESTAPI_ProvObjects.h"
namespace OpenWifi {
typedef Poco::Tuple<
std::string,
std::string,
std::string,
std::string,
uint64_t,
uint64_t,
std::string,
std::string,
std::string,
std::string,
std::string,
std::string,
std::string,
std::string,
std::string
> LocationDBRecordType;
class LocationDB : public ORM::DB<LocationDBRecordType, ProvObjects::Location> {
public:
LocationDB( ORM::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L);
private:
};
}
#endif //OWPROV_STORAGE_LOCATION_H

View File

@@ -17,8 +17,6 @@ namespace uCentral {
int Storage::Setup_MySQL() {
dbType_ = mysql ;
Logger_.notice("MySQL Storage enabled.");
auto NumSessions = Daemon()->ConfigGetInt("storage.type.mysql.maxsessions", 64);
auto IdleTime = Daemon()->ConfigGetInt("storage.type.mysql.idletime", 60);

View File

@@ -17,8 +17,6 @@ namespace uCentral {
int Storage::Setup_PostgreSQL() {
Logger_.notice("PostgreSQL Storage enabled.");
dbType_ = pgsql ;
auto NumSessions = Daemon()->ConfigGetInt("storage.type.postgresql.maxsessions", 64);
auto IdleTime = Daemon()->ConfigGetInt("storage.type.postgresql.idletime", 60);
auto Host = Daemon()->ConfigGetString("storage.type.postgresql.host");

54
src/storage_policies.cpp Normal file
View File

@@ -0,0 +1,54 @@
//
// Created by stephane bourque on 2021-08-16.
//
#include "storage_policies.h"
#include "Utils.h"
#include "uCentralTypes.h"
#include "RESTAPI_utils.h"
#include "RESTAPI_SecurityObjects.h"
namespace OpenWifi {
static ORM::FieldVec PolicyDB_Fields{
// object info
ORM::Field{"id",64, true},
ORM::Field{"name",ORM::FieldType::FT_TEXT},
ORM::Field{"description",ORM::FieldType::FT_TEXT},
ORM::Field{"notes",ORM::FieldType::FT_TEXT},
ORM::Field{"created",ORM::FieldType::FT_BIGINT},
ORM::Field{"modified",ORM::FieldType::FT_BIGINT},
ORM::Field{"entries",ORM::FieldType::FT_TEXT}
};
static ORM::IndexVec PolicyDB_Indexes{
{ std::string("policy_name_index"),
ORM::IndexEntryVec{
{std::string("name"),
ORM::Indextype::ASC} } }
};
PolicyDB::PolicyDB( ORM::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L) :
DB(T, "policies", PolicyDB_Fields, PolicyDB_Indexes, P, L) {}
}
template<> void ORM::DB< OpenWifi::PolicyDBRecordType, OpenWifi::ProvObjects::ManagementPolicy>::Convert(OpenWifi::PolicyDBRecordType &In, OpenWifi::ProvObjects::ManagementPolicy &Out) {
Out.info.id = In.get<0>();
Out.info.name = In.get<1>();
Out.info.description = In.get<2>();
Out.info.notes = uCentral::RESTAPI_utils::to_object_array<uCentral::SecurityObjects::NoteInfo>(In.get<3>());
Out.info.created = In.get<4>();
Out.info.modified = In.get<5>();
Out.entries = uCentral::RESTAPI_utils::to_object_array<OpenWifi::ProvObjects::ManagementPolicyEntry>(In.get<6>());
}
template<> void ORM::DB< OpenWifi::PolicyDBRecordType, OpenWifi::ProvObjects::ManagementPolicy>::Convert(OpenWifi::ProvObjects::ManagementPolicy &In, OpenWifi::PolicyDBRecordType &Out) {
Out.set<0>(In.info.id);
Out.set<1>(In.info.name);
Out.set<2>(In.info.description);
Out.set<3>(uCentral::RESTAPI_utils::to_string(In.info.notes));
Out.set<4>(In.info.created);
Out.set<5>(In.info.modified);
Out.set<6>(uCentral::RESTAPI_utils::to_string(In.entries));
}

30
src/storage_policies.h Normal file
View File

@@ -0,0 +1,30 @@
//
// Created by stephane bourque on 2021-08-16.
//
#ifndef OWPROV_STORAGE_POLICIES_H
#define OWPROV_STORAGE_POLICIES_H
#include "orm.h"
#include "RESTAPI_ProvObjects.h"
namespace OpenWifi {
typedef Poco::Tuple<
std::string,
std::string,
std::string,
std::string,
uint64_t,
uint64_t,
std::string
> PolicyDBRecordType;
class PolicyDB : public ORM::DB<PolicyDBRecordType, ProvObjects::ManagementPolicy> {
public:
PolicyDB( ORM::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L);
private:
};
}
#endif //OWPROV_STORAGE_POLICIES_H

View File

@@ -1,17 +0,0 @@
//
// License type: BSD 3-Clause License
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
//
// Created by Stephane Bourque on 2021-03-04.
// Arilia Wireless Inc.
//
#include "StorageService.h"
namespace uCentral {
int Storage::Create_Tables() {
return 0;
}
}

73
src/storage_venue.cpp Normal file
View File

@@ -0,0 +1,73 @@
//
// Created by stephane bourque on 2021-08-16.
//
#include "storage_venue.h"
#include "Utils.h"
#include "uCentralTypes.h"
#include "RESTAPI_utils.h"
#include "RESTAPI_SecurityObjects.h"
namespace OpenWifi {
static ORM::FieldVec VenueDB_Fields{
// object info
ORM::Field{"id",64, true},
ORM::Field{"name",ORM::FieldType::FT_TEXT},
ORM::Field{"description",ORM::FieldType::FT_TEXT},
ORM::Field{"notes",ORM::FieldType::FT_TEXT},
ORM::Field{"created",ORM::FieldType::FT_BIGINT},
ORM::Field{"modified",ORM::FieldType::FT_BIGINT},
ORM::Field{"owner",ORM::FieldType::FT_TEXT},
ORM::Field{"parent",ORM::FieldType::FT_TEXT},
ORM::Field{"children",ORM::FieldType::FT_TEXT},
ORM::Field{"managers",ORM::FieldType::FT_TEXT},
ORM::Field{"managementPolicy",ORM::FieldType::FT_TEXT},
ORM::Field{"devices",ORM::FieldType::FT_TEXT},
ORM::Field{"topology",ORM::FieldType::FT_TEXT},
ORM::Field{"design",ORM::FieldType::FT_TEXT}
};
static ORM::IndexVec VenueDB_Indexes{
{ std::string("venue_name_index"),
ORM::IndexEntryVec{
{std::string("name"),
ORM::Indextype::ASC} } }
};
VenueDB::VenueDB( ORM::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L) :
DB(T, "venues", VenueDB_Fields, VenueDB_Indexes, P, L) {}
}
template<> void ORM::DB< OpenWifi::VenueDBRecordType, OpenWifi::ProvObjects::Venue>::Convert(OpenWifi::VenueDBRecordType &In, OpenWifi::ProvObjects::Venue &Out) {
Out.info.id = In.get<0>();
Out.info.name = In.get<1>();
Out.info.description = In.get<2>();
Out.info.notes = uCentral::RESTAPI_utils::to_object_array<uCentral::SecurityObjects::NoteInfo>(In.get<3>());
Out.info.created = In.get<4>();
Out.info.modified = In.get<5>();
Out.owner = In.get<6>();
Out.parent = In.get<7>();
uCentral::Types::from_string(In.get<8>(), Out.children);
uCentral::Types::from_string(In.get<9>(), Out.managers);
uCentral::Types::from_string(In.get<10>(), Out.devices);
Out.topology = uCentral::RESTAPI_utils::to_object_array<OpenWifi::ProvObjects::DiGraphEntry>(In.get<11>());
Out.design = In.get<12>();
}
template<> void ORM::DB< OpenWifi::VenueDBRecordType, OpenWifi::ProvObjects::Venue>::Convert(OpenWifi::ProvObjects::Venue &In, OpenWifi::VenueDBRecordType &Out) {
Out.set<0>(In.info.id);
Out.set<1>(In.info.name);
Out.set<2>(In.info.description);
Out.set<3>(uCentral::RESTAPI_utils::to_string(In.info.notes));
Out.set<4>(In.info.created);
Out.set<5>(In.info.modified);
Out.set<6>(In.owner);
Out.set<7>(In.parent);
Out.set<8>(uCentral::Types::to_string(In.children));
Out.set<9>(uCentral::Types::to_string(In.managers));
Out.set<10>(uCentral::Types::to_string(In.devices));
Out.set<11>(uCentral::RESTAPI_utils::to_string(In.topology));
Out.set<12>(In.design);
}

38
src/storage_venue.h Normal file
View File

@@ -0,0 +1,38 @@
//
// Created by stephane bourque on 2021-08-16.
//
#ifndef OWPROV_STORAGE_VENUE_H
#define OWPROV_STORAGE_VENUE_H
#include "orm.h"
#include "RESTAPI_ProvObjects.h"
namespace OpenWifi {
typedef Poco::Tuple<
std::string,
std::string,
std::string,
std::string,
uint64_t,
uint64_t,
std::string,
std::string,
std::string,
std::string,
std::string,
std::string,
std::string,
std::string
> VenueDBRecordType;
class VenueDB : public ORM::DB<VenueDBRecordType, ProvObjects::Venue> {
public:
VenueDB( ORM::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L);
private:
};
}
#endif //OWPROV_STORAGE_VENUE_H

View File

@@ -15,6 +15,8 @@
#include <utility>
#include <queue>
#include "Poco/StringTokenizer.h"
namespace uCentral::Types {
typedef std::pair<std::string,std::string> StringPair;
typedef std::vector<StringPair> StringPairVec;
@@ -28,6 +30,9 @@ namespace uCentral::Types {
typedef std::map<std::string, TopicNotifyFunctionList> NotifyTable;
typedef std::map<std::string,uint64_t> CountedMap;
typedef std::string UUID_t;
typedef std::vector<UUID_t> UUIDvec_t;
inline void UpdateCountedMap(CountedMap &M, const std::string &S ) {
auto it = M.find(S);
if(it==M.end())
@@ -35,6 +40,29 @@ namespace uCentral::Types {
else
it->second += 1;
}
inline std::string to_string( const StringVec &V) {
std::string Result;
bool first=true;
for(const auto &i:V) {
if(first) {
Result += i;
first = false;
} else {
Result += ",";
Result += i;
}
}
return Result;
}
inline void from_string(const std::string &S, StringVec &V) {
Poco::StringTokenizer Tokens(S,",",Poco::StringTokenizer::TOK_TRIM | Poco::StringTokenizer::TOK_IGNORE_EMPTY);
for(auto const &i:Tokens)
V.emplace_back(i);
}
};
#endif // UCENTRALGW_UCENTRALTYPES_H

22
ucentralgw.service Normal file
View File

@@ -0,0 +1,22 @@
[Unit]
Description=OpenWiFi Provisioning Service
After=network-online.target docker.service
Wants=network-online.target
[Service]
Type=simple
Environment="$OWPROV_ROOT=/home/admin/dev/ow-prov"
ExecStart=/home/admin/dev/ow-prov/cmake-build/owprov
WorkingDirectory=/home/admin/dev/ow-prov
# ExecReload=/bin/kill -s HUP $MAINPID
User=admin
# TimeoutSec=0
RestartSec=2
Restart=always
StartLimitBurst=3
# KillMode=process
LimitNOFILE=500000
LimitNPROC=500000
[Install]
WantedBy=multi-user.target