Compare commits

..

71 Commits

Author SHA1 Message Date
TIP Automation User
80d731d7a9 Chg: update image tag in helm values to v2.11.0 2023-10-04 14:03:48 +00:00
TIP Automation User
71ab63e9f6 Chg: update image tag in helm values to v2.11.0-RC2 2023-09-26 14:44:56 +00:00
Stephane Bourque
25dc25c6e9 Merge pull request #91 from Telecominfraproject/main
Updating 2.11
2023-09-24 12:01:44 -07:00
stephb9959
e71b83ced7 https://telecominfraproject.atlassian.net/browse/WIFI-12954
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-24 10:54:45 -07:00
stephb9959
1d077b945d https://telecominfraproject.atlassian.net/browse/WIFI-12954
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-23 15:23:13 -07:00
stephb9959
ba46c1558c https://telecominfraproject.atlassian.net/browse/WIFI-12945
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-22 22:28:07 -07:00
stephb9959
ca1cf64fa2 https://telecominfraproject.atlassian.net/browse/WIFI-12945
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-22 22:06:17 -07:00
stephb9959
1948c50ad4 https://telecominfraproject.atlassian.net/browse/WIFI-12945
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-22 22:04:27 -07:00
stephb9959
c5737de2fc https://telecominfraproject.atlassian.net/browse/WIFI-12945
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-22 21:59:18 -07:00
stephb9959
5a3ce59073 https://telecominfraproject.atlassian.net/browse/WIFI-12945
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-22 13:57:30 -07:00
stephb9959
26fc29ac12 https://telecominfraproject.atlassian.net/browse/WIFI-12945
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-22 13:42:19 -07:00
stephb9959
19314815cd https://telecominfraproject.atlassian.net/browse/WIFI-12945
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-22 13:37:54 -07:00
stephb9959
5b040d132f https://telecominfraproject.atlassian.net/browse/WIFI-12945
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-19 21:52:26 -07:00
stephb9959
5bdcbe8423 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-18 11:26:19 -07:00
stephb9959
1ce856f222 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-18 10:17:21 -07:00
stephb9959
9068eb32b7 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-18 10:14:42 -07:00
stephb9959
4c9dbd76e1 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-18 09:36:24 -07:00
stephb9959
4c2ba2ec28 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-18 07:12:22 -07:00
stephb9959
a1176e7f4d https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-17 23:34:14 -07:00
stephb9959
f2b1169d8c https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-17 23:20:45 -07:00
stephb9959
5650e0decc https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-15 15:48:07 -07:00
stephb9959
98f37d4748 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-13 13:11:18 -07:00
stephb9959
2065bd872d https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-13 13:09:37 -07:00
stephb9959
96cfaf5051 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-13 12:11:37 -07:00
stephb9959
63f49db54c https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-13 11:04:43 -07:00
stephb9959
7b524aa974 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-13 10:49:18 -07:00
stephb9959
7d995e7cb1 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-13 10:12:44 -07:00
stephb9959
94ce329143 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 23:17:59 -07:00
stephb9959
f9af051ce9 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 23:15:59 -07:00
stephb9959
87653e1e4b https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 23:13:30 -07:00
stephb9959
4b78e64eb5 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 23:12:05 -07:00
stephb9959
3dadc191d5 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 23:00:56 -07:00
stephb9959
8a12becd2b https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 15:18:18 -07:00
stephb9959
74de9188d2 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 15:14:37 -07:00
stephb9959
cb7ad596e2 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 15:12:15 -07:00
stephb9959
19528133a3 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 15:09:18 -07:00
stephb9959
043c167d3d https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 15:04:43 -07:00
stephb9959
1d14018470 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 14:59:44 -07:00
stephb9959
5660689d68 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 14:51:54 -07:00
stephb9959
4fecee46ac https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 14:49:12 -07:00
stephb9959
797a7f20bc https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 14:24:14 -07:00
stephb9959
5390d1fcec https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 13:51:08 -07:00
stephb9959
bf20fc27eb https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 11:08:39 -07:00
stephb9959
69dce68d1a https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 10:54:35 -07:00
stephb9959
ca7c618c16 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 09:00:59 -07:00
stephb9959
8826031939 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 07:45:44 -07:00
stephb9959
21f8742bd8 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-11 22:35:44 -07:00
stephb9959
5cc00a2e72 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-11 14:43:30 -07:00
stephb9959
b950694753 https://telecominfraproject.atlassian.net/browse/WIFI-12868
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-01 09:26:06 -07:00
TIP Automation User
e3d63cc90d Chg: update image tag in helm values to v2.11.0-RC1 2023-09-01 16:09:04 +00:00
stephb9959
3ce14e5efe https://telecominfraproject.atlassian.net/browse/WIFI-12868
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-08-28 11:48:32 -07:00
stephb9959
7f860eb633 https://telecominfraproject.atlassian.net/browse/WIFI-12868
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-08-03 22:29:48 -07:00
stephb9959
2628fe1b6a https://telecominfraproject.atlassian.net/browse/WIFI-12868
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-08-03 11:03:21 -07:00
stephb9959
29a48f6753 https://telecominfraproject.atlassian.net/browse/WIFI-12868
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-08-03 10:43:40 -07:00
stephb9959
f8220e3a5e https://telecominfraproject.atlassian.net/browse/WIFI-12738
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-07-10 13:13:59 -07:00
stephb9959
8dde169148 https://telecominfraproject.atlassian.net/browse/WIFI-12738
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-07-10 13:13:05 -07:00
Stephane Bourque
0437031d78 Merge pull request #89 from pcosmo/patch-1
Update owprov.yaml
2023-06-20 09:00:19 -07:00
stephb9959
2242b02f0f https://telecominfraproject.atlassian.net/browse/WIFI-12689
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-06-20 08:42:15 -07:00
pcosmo
8287628583 Update owprov.yaml
Fixed typo in configuration commands, e.g.:

 getCponfiguration -> getConfiguration
2023-06-15 11:29:11 -04:00
stephb9959
7b3de5d5ef https://telecominfraproject.atlassian.net/browse/WIFI-12525
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-05-18 09:01:31 -07:00
stephb9959
6007c1f06f https://telecominfraproject.atlassian.net/browse/WIFI-12597
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-05-11 07:32:22 -07:00
stephb9959
74916abdbd https://telecominfraproject.atlassian.net/browse/WIFI-12525
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-05-03 07:50:37 -07:00
stephb9959
0899c6f2d9 https://telecominfraproject.atlassian.net/browse/WIFI-12525
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-04-19 14:09:37 -07:00
stephb9959
f51b2bd11e https://telecominfraproject.atlassian.net/browse/WIFI-12525
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-04-19 14:03:43 -07:00
stephb9959
8b21ef16a1 https://telecominfraproject.atlassian.net/browse/WIFI-12525
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-04-19 14:03:31 -07:00
stephb9959
7ad4de4960 https://telecominfraproject.atlassian.net/browse/WIFI-12361
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-03-08 09:32:14 -08:00
stephb9959
c5e63ce95b https://telecominfraproject.atlassian.net/browse/WIFI-12068
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-03-02 11:12:46 -08:00
stephb9959
ba3607bd87 https://telecominfraproject.atlassian.net/browse/WIFI-12068
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-03-02 09:54:00 -08:00
stephb9959
ba526f85a8 https://telecominfraproject.atlassian.net/browse/WIFI-12068
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-03-02 09:16:14 -08:00
stephb9959
ecea2a1fb4 https://telecominfraproject.atlassian.net/browse/WIFI-12068
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-03-02 09:10:29 -08:00
stephb9959
e2e5687b47 https://telecominfraproject.atlassian.net/browse/WIFI-12068
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-03-01 10:11:06 -08:00
98 changed files with 9061 additions and 5903 deletions

View File

@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.13) cmake_minimum_required(VERSION 3.13)
project(owprov VERSION 2.9.0) project(owprov VERSION 2.11.0)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 17)
@@ -37,7 +37,7 @@ if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
string(REGEX REPLACE "\n$" "" GIT_HASH "${GIT_HASH}") string(REGEX REPLACE "\n$" "" GIT_HASH "${GIT_HASH}")
endif() endif()
add_definitions(-DAWS_CUSTOM_MEMORY_MANAGEMENT) add_definitions(-DAWS_CUSTOM_MEMORY_MANAGEMENT -DBOOST_NO_CXX98_FUNCTION_BASE=1)
find_package(OpenSSL REQUIRED) find_package(OpenSSL REQUIRED)
find_package(ZLIB REQUIRED) find_package(ZLIB REQUIRED)
@@ -117,6 +117,7 @@ add_executable(owprov
src/framework/MicroServiceExtra.h src/framework/MicroServiceExtra.h
src/framework/ConfigurationValidator.cpp src/framework/ConfigurationValidator.cpp
src/framework/ConfigurationValidator.h src/framework/ConfigurationValidator.h
src/framework/default_device_types.h
src/UI_Prov_WebSocketNotifications.h src/UI_Prov_WebSocketNotifications.h
src/UI_Prov_WebSocketNotifications.cpp src/UI_Prov_WebSocketNotifications.cpp
src/RESTObjects/RESTAPI_SecurityObjects.h src/RESTObjects/RESTAPI_SecurityObjects.cpp src/RESTObjects/RESTAPI_SecurityObjects.h src/RESTObjects/RESTAPI_SecurityObjects.cpp
@@ -208,7 +209,7 @@ add_executable(owprov
src/ProvWebSocketClient.cpp src/ProvWebSocketClient.h src/ProvWebSocketClient.cpp src/ProvWebSocketClient.h
src/Tasks/VenueRebooter.h src/Tasks/VenueUpgrade.h src/Tasks/VenueRebooter.h src/Tasks/VenueUpgrade.h
src/sdks/SDK_fms.cpp src/sdks/SDK_fms.h src/sdks/SDK_fms.cpp src/sdks/SDK_fms.h
src/RESTAPI/RESTAPI_overrides_handler.cpp src/RESTAPI/RESTAPI_overrides_handler.h) src/RESTAPI/RESTAPI_overrides_handler.cpp src/RESTAPI/RESTAPI_overrides_handler.h src/OpenRoamin_GlobalReach.cpp src/OpenRoamin_GlobalReach.h src/storage/storage_glblraccounts.cpp src/storage/storage_glblraccounts.h src/storage/storage_glblrcerts.cpp src/storage/storage_glblrcerts.h src/RESTAPI/RESTAPI_openroaming_gr_list_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_gr_list_acct_handler.h src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.h src/RESTAPI/RESTAPI_openroaming_gr_list_certificates.cpp src/RESTAPI/RESTAPI_openroaming_gr_list_certificates.h src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.cpp src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.h src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.h src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.h src/storage/storage_orion_accounts.cpp src/storage/storage_orion_accounts.h)
target_link_libraries(owprov PUBLIC target_link_libraries(owprov PUBLIC
${Poco_LIBRARIES} ${Poco_LIBRARIES}

2
build
View File

@@ -1 +1 @@
19 32

View File

@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<array>
<dict>
<key>AutoJoin</key>
<true/>
<key>CaptiveBypass</key>
<false/>
<key>DisableAssociationMACRandomization</key>
<false/>
<key>DisplayedOperatorName</key>
<string>OpenRo.am</string>
<key>DomainName</key>
<string>openro.am</string>
<key>EAPClientConfiguration</key>
<dict>
<key>AcceptEAPTypes</key>
<array>
<integer>21</integer>
</array>
<key>OuterIdentity</key>
<string>anonymous@openro.am</string>
<key>TLSMaximumVersion</key>
<string>1.2</string>
<key>TLSMinimumVersion</key>
<string>1.2</string>
<key>TTLSInnerAuthentication</key>
<string>MSCHAPv2</string>
<key>UserName</key>
<string>420a5371-47d4-4d1d-b234-d17be4e54bb3@openro.am</string>
<key>UserPassword</key>
<string>XaHBCFhgGxi-mCK9XXdQ8</string>
</dict>
<key>EncryptionType</key>
<string>WPA2</string>
<key>HIDDEN_NETWORK</key>
<false/>
<key>IsHotspot</key>
<true/>
<key>NAIRealmNames</key>
<array>
<string>openro.am</string>
</array>
<key>PayloadDescription</key>
<string>Configures Wi-Fi settings</string>
<key>PayloadDisplayName</key>
<string>Wi-Fi</string>
<key>PayloadIdentifier</key>
<string>com.apple.wifi.managed.12788EED-2E0C-4370-9411-4EEFC8D9ABB0</string>
<key>PayloadType</key>
<string>com.apple.wifi.managed</string>
<key>PayloadUUID</key>
<string>12788EED-2E0C-4370-9411-4EEFC8D9ABB0</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>ProxyType</key>
<string>None</string>
<key>RoamingConsortiumOIs</key>
<array>
<string>5A03BA0000</string>
</array>
<key>ServiceProviderRoamingEnabled</key>
<true/>
</dict>
</array>
<key>PayloadDisplayName</key>
<string>OpenRo.am Test</string>
<key>PayloadIdentifier</key>
<string>openroam.44A21054-2F3F-437F-822A-C2F6766A2A23</string>
<key>PayloadOrganization</key>
<string>OpenRo.am</string>
<key>PayloadRemovalDisallowed</key>
<false/>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>1D460B0F-9311-4FD2-A75D-BADA866BC31C</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>

View File

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

View File

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

View File

@@ -0,0 +1,372 @@
openapi: 3.0.1
info:
title: OpenWiFi OpenRoaming Provisioning Model for Global Reach
description: Definitions and APIs to Open Roaming WiFi.
version: 2.5.0
license:
name: BSD3
url: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
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:
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/NotFound'
Unauthorized:
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Unauthorized'
Success:
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Success'
BadRequest:
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/BadRequest'
schemas:
GLBLRAccountInfo:
type: object
properties:
allOf:
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-owprov/blob/main/openpapi/owprov.yaml#/components/schemas/ObjectInfo'
privateKey:
type: string
country:
type: string
province:
type: string
city:
type: string
organization:
type: string
commonName:
type: string
CSR:
type: string
CSRPrivateKey:
type: string
CSRPublicKey:
type: string
GlobalReachAcctId:
type: string
GLBLRCertificateInfo:
type: object
properties:
id:
type: string
format: uuid
name:
type: string
accountId:
type: string
format: uuid
csr:
type: string
certificate:
type: string
certificateChain:
type: string
certificateId:
type: string
expiresAt:
type: integer
format: int64
created:
type: integer
format: int64
paths:
/openroaming/globalreach/accounts:
get:
tags:
- OpenRoaming-Global Reach
operationId: getOpenRoamingGlobalReachAccountList
summary: Retrieve account list.
parameters:
- in: query
description: Pagination start (starts at 1. If not specified, 1 is assumed)
name: offset
schema:
type: integer
required: false
- in: query
description: Maximum number of entries to return (if absent, no limit is assumed)
name: limit
schema:
type: integer
required: false
- in: query
description: return the number of accounts
name: countOnly
schema:
type: boolean
required: false
responses:
200:
description: The list of accounts
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/GLBLRAccountInfo'
$ref: '#/components/responses/Success'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
/openroaming/globalreach/account/{name}:
get:
tags:
- OpenRoaming-Global Reach
operationId: getOpenRoamingGlobalReachAccount
summary: Retrieve account information.
parameters:
- in: path
description: The account name
name: name
schema:
type: string
required: true
responses:
200:
$ref: '#/components/schemas/GLBLRAccountInfo'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
delete:
tags:
- OpenRoaming-Global Reach
operationId: deleteOpenRoamingGlobalReachAccount
summary: Delete account information.
parameters:
- in: path
description: The account name
name: name
schema:
type: string
required: true
responses:
200:
$ref: '#/components/responses/Success'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
post:
tags:
- OpenRoaming-Global Reach
operationId: createOpenRoamingGlobalReachAccount
summary: Create account information.
parameters:
- in: path
description: The account name
name: name
schema:
type: string
required: true
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/GLBLRAccountInfo'
responses:
200:
$ref: '#/components/schemas/GLBLRAccountInfo'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
put:
tags:
- OpenRoaming-Global Reach
operationId: modifyOpenRoamingGlobalReachAccount
summary: Modify account information.
parameters:
- in: path
description: The account name
name: name
schema:
type: string
required: true
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/GLBLRAccountInfo'
responses:
200:
$ref: '#/components/schemas/GLBLRAccountInfo'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
/openroaming/globalreach/certificates/{account}:
get:
tags:
- OpenRoaming-Global Reach Certificate
operationId: getOpenRoamingGlobalReachCertificateList
summary: Retrieve certificate list.
parameters:
- in: path
description: The account name
name: account
schema:
type: string
required: true
- in: query
description: Pagination start (starts at 1. If not specified, 1 is assumed)
name: offset
schema:
type: integer
required: false
- in: query
description: Maximum number of entries to return (if absent, no limit is assumed)
name: limit
schema:
type: integer
required: false
- in: query
description: return the number of certificates
name: countOnly
schema:
type: boolean
required: false
responses:
200:
description: The list of certificates
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/GLBLRCertificateInfo'
$ref: '#/components/responses/Success'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
/openroaming/globalreach/certificate/{account}/{id}:
get:
tags:
- OpenRoaming-Global Reach Certificate
operationId: getOpenRoamingGlobalReachCertificate
summary: Retrieve certificate information.
parameters:
- in: path
description: The account name - this is the provisioning ID for the account. Not the GlobalReach ID.
name: account
schema:
type: string
required: true
- in: path
description: The certificate id in provisioning - not the certificate_id from GlobalReach
name: id
schema:
type: string
required: true
responses:
200:
$ref: '#/components/schemas/GLBLRCertificateInfo'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
delete:
tags:
- OpenRoaming-Global Reach Certificate
operationId: deleteOpenRoamingGlobalReachCertificate
summary: Delete certificate information.
parameters:
- in: path
description: The account name - this is the provisioning ID for the account. Not the GlobalReach ID.
name: account
schema:
type: string
required: true
- in: path
description: The certificate id in provisioning - not the certificate_id from GlobalReach
name: id
schema:
type: string
required: true
responses:
200:
$ref: '#/components/responses/Success'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
post:
tags:
- OpenRoaming-Global Reach Certificate
operationId: createOpenRoamingGlobalReachCertificate
summary: Create certificate information.
parameters:
- in: path
description: The account name - this is the provisioning ID for the account. Not the GlobalReach ID.
name: account
schema:
type: string
required: true
- in: path
description: Must be set to "0"
name: id
schema:
type: string
required: true
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/GLBLRCertificateInfo'
responses:
200:
$ref: '#/components/schemas/GLBLRCertificateInfo'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'

View File

@@ -0,0 +1,195 @@
openapi: 3.0.1
info:
title: OpenWiFi OpenRoaming Provisioning Model for Google Orion
description: Definitions and APIs to Open Roaming WiFi.
version: 2.5.0
license:
name: BSD3
url: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
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:
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/NotFound'
Unauthorized:
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Unauthorized'
Success:
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Success'
BadRequest:
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/BadRequest'
schemas:
GooglOrionAccountInfo:
type: object
properties:
allOf:
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-owprov/blob/main/openpapi/owprov.yaml#/components/schemas/ObjectInfo'
privateKey:
type: string
certificate:
type: string
cacerts:
type: array
items:
type: string
paths:
/openroaming/orion/accounts:
get:
tags:
- OpenRoaming-Google Orion
operationId: getOpenRoamingGlobalReachAccountList
summary: Retrieve account list.
parameters:
- in: query
description: Pagination start (starts at 1. If not specified, 1 is assumed)
name: offset
schema:
type: integer
required: false
- in: query
description: Maximum number of entries to return (if absent, no limit is assumed)
name: limit
schema:
type: integer
required: false
- in: query
description: return the number of accounts
name: countOnly
schema:
type: boolean
required: false
responses:
200:
description: The list of accounts
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/GooglOrionAccountInfo'
$ref: '#/components/responses/Success'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
/openroaming/orion/account/{id}:
get:
tags:
- OpenRoaming-Google Orion
operationId: getOpenRoamingGlobalReachAccount
summary: Retrieve account information.
parameters:
- in: path
description: The account name
name: name
schema:
type: string
required: true
responses:
200:
$ref: '#/components/schemas/GooglOrionAccountInfo'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
delete:
tags:
- OpenRoaming-Google Orion
operationId: deleteOpenRoamingGlobalReachAccount
summary: Delete account information.
parameters:
- in: path
description: The account name
name: name
schema:
type: string
required: true
responses:
200:
$ref: '#/components/responses/Success'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
post:
tags:
- OpenRoaming-Google Orion
operationId: createOpenRoamingGlobalReachAccount
summary: Create account information.
parameters:
- in: path
description: The account name
name: name
schema:
type: string
required: true
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/GooglOrionAccountInfo'
responses:
200:
$ref: '#/components/schemas/GooglOrionAccountInfo'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
put:
tags:
- OpenRoaming-Google Orion
operationId: modifyOpenRoamingGlobalReachAccount
summary: Modify account information.
parameters:
- in: path
description: The account name
name: name
schema:
type: string
required: true
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/GooglOrionAccountInfo'
responses:
200:
$ref: '#/components/schemas/GooglOrionAccountInfo'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'

View File

@@ -1,268 +0,0 @@
openapi: 3.0.1
info:
title: OpenWiFi Open roaming Ameriband Provisioning Model
description: Registration of an OpenRoaming profile with Ameriband for TIP OpenWifi.
version: 1.0.0
license:
name: BSD3
url: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
servers:
- url: 'https://tip.regiatration.ameriband.com:8001/api/v1'
security:
- bearerAuth: []
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
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
enum:
- 0 # Success
- 8 # INVALID_TOKEN
- 9 # EXPIRED_TOKEN
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
BadRequest:
description: The requested operation failed.
content:
application/json:
schema:
properties:
ErrorCode:
type: integer
ErrorDetails:
type: string
ErrorDescription:
type: integer
schemas:
RegistrationRequest:
type: object
properties:
orgRequestId:
type: string
format: uuid
minLength: 36
maxLength: 36
example:
Client will generate a UUID that must be returned in the response.
orgAcceptedTermsAndConditions:
type: boolean
default: false
orgLegalName:
type: string
minLength: 1
orgWebSite:
type: string
format: url
minLength: 1
orgContact:
type: string
minLength: 1
example:
John Smith
orgEmail:
type: string
format: email
minLength: 1
orgPhone:
type: string
example:
(607)555-1234 or +1(223)555-1222
orgLocation:
type: string
example:
Boston, NH - LA, CA
orgCertificate:
type: string
minLength: 1
example:
This must be the entire PEM file content of the certificate, encoded using base64
RegistrationResponse:
type: object
properties:
orgRequestId:
type: string
format: uuid
minLength: 36
maxLength: 36
example:
This should be the same orgRequestId passed during registration.
orgNASID:
type: string
minLength: 10
description:
This is the NASID generated by Ameriband. It will be used by the operator as NASID when contacting Ameriband.
ameribandCertificate:
type: string
minLength: 1
example:
This must be the entire PEM file content of the certificate, encoded using base64
RegistrationInformationRequest:
type: object
properties:
link:
description: This should be the link where a potential registrant can read the terms and conditions of registering with Ameriband.
type: string
format: url
minLength: 1
example:
https://ameriband.com/romain-registration.html
paths:
/termsAndConditions:
get:
summary: The registrant must be given a chance to view the terms and conditions of the relationship they are entering into
operationId: getTermsAndConditions
responses:
200:
description: Sucessfully retrieved Terms and Conditions
content:
application/json:
schema:
$ref: '#/components/schemas/RegistrationInformationRequest'
404:
$ref: '#/components/responses/Unauthorized'
/registration:
get:
tags:
- Registration
operationId: getRegistrationInformation
summary: This should return the information from a registration based on the NASID
parameters:
- in: query
name: orgNASID
schema:
type: string
required: true
example:
This is the orgNASID returned during registration.
responses:
200:
$ref: '#/components/schemas/RegistrationResponse'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
post:
summary: Called when the registrant ahs read the T&Cs and iw willing to submit their information to enter in a partnership
tags:
- Registration
operationId: createRegistration
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/RegistrationRequest'
responses:
200:
description: Succesfully registered
content:
application/json:
schema:
$ref: '#/components/schemas/RegistrationResponse'
400:
description: Registration failed due to missing or incomplete information
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
put:
summary: Called when the registrant needs to update its information with Ameriband. The does not generate a new NASID.
tags:
- Registration
operationId: updateRegistration
parameters:
- in: query
name: orgNASID
schema:
type: string
required: true
example:
This is the orgNASID returned during registration.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/RegistrationRequest'
responses:
200:
description: Succesfully found the information based on the orgNASID
content:
application/json:
schema:
$ref: '#/components/schemas/RegistrationResponse'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
delete:
tags:
- Registration
summary: When a registrant wants to terminate a relationship with Ameriband. Ameriband should also delete all information from the registrant
operationId: deleteRegistration
parameters:
- in: query
name: orgNASID
schema:
type: string
required: true
example:
This is the orgNASID returned during registration.
responses:
204:
$ref: '#/components/responses/Success'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'

View File

@@ -1331,12 +1331,6 @@ components:
- $ref: '#/components/schemas/StringList' - $ref: '#/components/schemas/StringList'
- $ref: '#/components/schemas/TagValuePairList' - $ref: '#/components/schemas/TagValuePairList'
SystemCommandResults:
type: object
oneOf:
- $ref: '#/components/schemas/StringList'
- $ref: '#/components/schemas/TagValuePairList'
NoteInfo: NoteInfo:
type: object type: object
properties: properties:
@@ -1376,6 +1370,33 @@ components:
type: integer type: integer
format: int64 format: int64
SystemResources:
type: object
properties:
numberOfFileDescriptors:
type: integer
format: int64
currRealMem:
type: integer
format: int64
peakRealMem:
type: integer
format: int64
currVirtMem:
type: integer
format: int64
peakVirtMem:
type: integer
format: int64
SystemCommandResults:
type: object
oneOf:
- $ref: '#/components/schemas/SystemResources'
- $ref: '#/components/schemas/SystemInfoResults'
- $ref: '#/components/schemas/StringList'
- $ref: '#/components/schemas/TagValuePairList'
Dashboard: Dashboard:
type: object type: object
properties: properties:
@@ -2066,19 +2087,12 @@ paths:
default: false default: false
required: false required: false
- in: query - in: query
description: return the list of devices under RRM description: return the list of devices for a subscriber
name: subscriber name: subscriber
schema: schema:
type: string type: string
format: uuid format: uuid
required: false required: false
- in: query
description: return RRM settings for a specific device
name: rrmSettings
schema:
type: boolean
default: false
required: false
- in: query - in: query
description: return the resolved configuration for a specific device description: return the resolved configuration for a specific device
name: resolveConfig name: resolveConfig
@@ -2144,6 +2158,13 @@ paths:
type: string type: string
format: uuid format: uuid
required: false required: false
- in: query
description: return RRM settings for a specific device
name: rrmSettings
schema:
type: boolean
default: false
required: false
responses: responses:
200: 200:
description: Succesful retrieve configuratiopn or part of the configuration description: Succesful retrieve configuratiopn or part of the configuration
@@ -2258,7 +2279,7 @@ paths:
get: get:
tags: tags:
- Configuration Overrides - Configuration Overrides
operationId: getCponfigurationOverrides operationId: getConfigurationOverrides
summary: retrieve a list of configuration overrides for a given device summary: retrieve a list of configuration overrides for a given device
parameters: parameters:
- in: path - in: path
@@ -2282,7 +2303,7 @@ paths:
delete: delete:
tags: tags:
- Configuration Overrides - Configuration Overrides
operationId: deleteCponfigurationOverrides operationId: deleteConfigurationOverrides
summary: delete all configuration overrides for a given device from a given source summary: delete all configuration overrides for a given device from a given source
parameters: parameters:
- in: path - in: path
@@ -2416,6 +2437,14 @@ paths:
type: boolean type: boolean
default: false default: false
required: false required: false
- in: query
description: list venues that use a specific RRM vendor
name: RRMvendor
schema:
type: string
example:
- this is the shortname of the RRM vendor
required: false
responses: responses:
200: 200:
description: Return a list of venues. description: Return a list of venues.
@@ -4415,15 +4444,12 @@ paths:
type: string type: string
enum: enum:
- info - info
- extraConfiguration
- resources
required: true required: true
responses: responses:
200: 200:
description: Successful command execution $ref: '#/components/schemas/SystemCommandResults'
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/SystemInfoResults'
403: 403:
$ref: '#/components/responses/Unauthorized' $ref: '#/components/responses/Unauthorized'
404: 404:

View File

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

View File

@@ -132,11 +132,10 @@ namespace OpenWifi {
if (StorageService()->InventoryDB().GetRecord("serialNumber", SerialNumber_, if (StorageService()->InventoryDB().GetRecord("serialNumber", SerialNumber_,
D)) { D)) {
if (!D.deviceConfiguration.empty()) { if (!D.deviceConfiguration.empty()) {
std::cout << "Adding device specific configuration: " // std::cout << "Adding device specific configuration: " << D.deviceConfiguration.size() << std::endl;
<< D.deviceConfiguration.size() << std::endl;
AddConfiguration(D.deviceConfiguration); AddConfiguration(D.deviceConfiguration);
} else { } else {
std::cout << "No device specific configuration." << std::endl; // std::cout << "No device specific configuration." << std::endl;
} }
if (!D.entity.empty()) { if (!D.entity.empty()) {
AddEntityConfig(D.entity); AddEntityConfig(D.entity);
@@ -196,8 +195,7 @@ namespace OpenWifi {
ReplaceVariablesInObject(OriginalSection, ExpandedSection); ReplaceVariablesInObject(OriginalSection, ExpandedSection);
Configuration->set(SectionName, ExpandedSection); Configuration->set(SectionName, ExpandedSection);
} else { } else {
std::cout << " --- unknown element type --- " poco_warning(Logger(), fmt::format("Unknown config element type: {}",O->get(SectionName).toString()));
<< O->get(SectionName).toString() << std::endl;
} }
} else { } else {
if (Explain_) { if (Explain_) {
@@ -248,8 +246,7 @@ namespace OpenWifi {
"channel", "channel",
std::strtoull(col.parameterValue.c_str(), nullptr, 10)); std::strtoull(col.parameterValue.c_str(), nullptr, 10));
} }
std::cout << "Setting channel in radio " << RadioIndex // std::cout << "Setting channel in radio " << RadioIndex << std::endl;
<< std::endl;
if (Explain_) { if (Explain_) {
Poco::JSON::Object ExObj; Poco::JSON::Object ExObj;
ExObj.set("from-name", "overrides"); ExObj.set("from-name", "overrides");

View File

@@ -31,7 +31,49 @@ namespace OpenWifi {
poco_information(Logger(), "Stopped..."); poco_information(Logger(), "Stopped...");
}; };
void AutoDiscovery::run() { void AutoDiscovery::ProcessPing(const Poco::JSON::Object::Ptr & P, std::string &FW, std::string &SN,
std::string &Compat, std::string &Conn, std::string &locale) {
if (P->has(uCentralProtocol::CONNECTIONIP))
Conn = P->get(uCentralProtocol::CONNECTIONIP).toString();
if (P->has(uCentralProtocol::FIRMWARE))
FW = P->get(uCentralProtocol::FIRMWARE).toString();
if (P->has(uCentralProtocol::SERIALNUMBER))
SN = P->get(uCentralProtocol::SERIALNUMBER).toString();
if (P->has(uCentralProtocol::COMPATIBLE))
Compat = P->get(uCentralProtocol::COMPATIBLE).toString();
if (P->has("locale")) {
locale = P->get("locale").toString();
}
}
void AutoDiscovery::ProcessConnect(const Poco::JSON::Object::Ptr &P, std::string &FW, std::string &SN,
std::string &Compat, std::string &Conn, std::string &locale) {
if (P->has(uCentralProtocol::CONNECTIONIP))
Conn = P->get(uCentralProtocol::CONNECTIONIP).toString();
if (P->has(uCentralProtocol::FIRMWARE))
FW = P->get(uCentralProtocol::FIRMWARE).toString();
if (P->has(uCentralProtocol::SERIALNUMBER))
SN = P->get(uCentralProtocol::SERIALNUMBER).toString();
if (P->has("locale")) {
locale = P->get("locale").toString();
}
if(P->has(uCentralProtocol::CAPABILITIES)) {
auto CapObj = P->getObject(uCentralProtocol::CAPABILITIES);
if (CapObj->has(uCentralProtocol::COMPATIBLE))
Compat = CapObj->get(uCentralProtocol::COMPATIBLE).toString();
}
}
void AutoDiscovery::ProcessDisconnect(const Poco::JSON::Object::Ptr &P, [[maybe_unused]] std::string &FW,
std::string &SN,
[[maybe_unused]] std::string &Compat,
[[maybe_unused]] std::string &Conn,
[[maybe_unused]] std::string &locale) {
if (P->has(uCentralProtocol::SERIALNUMBER))
SN = P->get(uCentralProtocol::SERIALNUMBER).toString();
}
void AutoDiscovery::run() {
Poco::AutoPtr<Poco::Notification> Note(Queue_.waitDequeueNotification()); Poco::AutoPtr<Poco::Notification> Note(Queue_.waitDequeueNotification());
Utils::SetThreadName("auto-discovery"); Utils::SetThreadName("auto-discovery");
while (Note && Running_) { while (Note && Running_) {
@@ -40,43 +82,31 @@ namespace OpenWifi {
try { try {
Poco::JSON::Parser Parser; Poco::JSON::Parser Parser;
auto Object = Parser.parse(Msg->Payload()).extract<Poco::JSON::Object::Ptr>(); auto Object = Parser.parse(Msg->Payload()).extract<Poco::JSON::Object::Ptr>();
bool Connected=true;
if (Object->has(uCentralProtocol::PAYLOAD)) { if (Object->has(uCentralProtocol::PAYLOAD)) {
auto PayloadObj = Object->getObject(uCentralProtocol::PAYLOAD); auto PayloadObj = Object->getObject(uCentralProtocol::PAYLOAD);
std::string ConnectedIP, SerialNumber, DeviceType; std::string ConnectedIP, SerialNumber, Compatible, Firmware, Locale ;
if (PayloadObj->has(uCentralProtocol::CONNECTIONIP)) if (PayloadObj->has(uCentralProtocol::PING)) {
ConnectedIP = auto PingObj = PayloadObj->getObject("ping");
PayloadObj->get(uCentralProtocol::CONNECTIONIP).toString(); ProcessPing(PingObj, Firmware, SerialNumber, Compatible, ConnectedIP, Locale);
if (PayloadObj->has(uCentralProtocol::CAPABILITIES)) { } else if(PayloadObj->has("capabilities")) {
auto CapObj = PayloadObj->getObject(uCentralProtocol::CAPABILITIES); ProcessConnect(PayloadObj, Firmware, SerialNumber, Compatible, ConnectedIP, Locale);
if (CapObj->has(uCentralProtocol::COMPATIBLE)) { } else if(PayloadObj->has("disconnection")) {
DeviceType = CapObj->get(uCentralProtocol::COMPATIBLE).toString(); // we ignore disconnection in provisioning
SerialNumber = PayloadObj->get(uCentralProtocol::SERIAL).toString(); Connected=false;
} ProcessConnect(PayloadObj, Firmware, SerialNumber, Compatible, ConnectedIP, Locale);
} else if (PayloadObj->has(uCentralProtocol::PING)) { } else {
auto PingMessage = PayloadObj->getObject(uCentralProtocol::PING); poco_debug(Logger(),fmt::format("Unknown message on 'connection' topic: {}",Msg->Payload()));
if (PingMessage->has(uCentralProtocol::FIRMWARE) && }
PingMessage->has(uCentralProtocol::SERIALNUMBER) &&
PingMessage->has(uCentralProtocol::COMPATIBLE)) {
if (PingMessage->has(uCentralProtocol::CONNECTIONIP))
ConnectedIP =
PingMessage->get(uCentralProtocol::CONNECTIONIP).toString();
SerialNumber =
PingMessage->get(uCentralProtocol::SERIALNUMBER).toString();
DeviceType =
PingMessage->get(uCentralProtocol::COMPATIBLE).toString();
}
}
std::string Locale;
if (PayloadObj->has("locale"))
Locale = PayloadObj->get("locale").toString();
if (!SerialNumber.empty()) { if (!SerialNumber.empty() && Connected) {
StorageService()->InventoryDB().CreateFromConnection( StorageService()->InventoryDB().CreateFromConnection(
SerialNumber, ConnectedIP, DeviceType, Locale); SerialNumber, ConnectedIP, Compatible, Locale);
} }
} }
} catch (const Poco::Exception &E) { } catch (const Poco::Exception &E) {
std::cout << "EX:" << Msg->Payload() << std::endl;
Logger().log(E); Logger().log(E);
} catch (...) { } catch (...) {
} }

View File

@@ -9,6 +9,7 @@
#include "Poco/Notification.h" #include "Poco/Notification.h"
#include "Poco/NotificationQueue.h" #include "Poco/NotificationQueue.h"
#include "Poco/JSON/Object.h"
namespace OpenWifi { namespace OpenWifi {
@@ -46,7 +47,14 @@ namespace OpenWifi {
Poco::Thread Worker_; Poco::Thread Worker_;
std::atomic_bool Running_ = false; std::atomic_bool Running_ = false;
AutoDiscovery() noexcept void ProcessPing(const Poco::JSON::Object::Ptr & P, std::string &FW, std::string &SN,
std::string &Compat, std::string &Conn, std::string &locale) ;
void ProcessConnect(const Poco::JSON::Object::Ptr & P, std::string &FW, std::string &SN,
std::string &Compat, std::string &Conn, std::string &locale) ;
void ProcessDisconnect(const Poco::JSON::Object::Ptr & P, std::string &FW, std::string &SN,
std::string &Compat, std::string &Conn, std::string &locale) ;
AutoDiscovery() noexcept
: SubSystemServer("AutoDiscovery", "AUTO-DISCOVERY", "discovery") {} : SubSystemServer("AutoDiscovery", "AUTO-DISCOVERY", "discovery") {}
}; };

View File

@@ -23,6 +23,7 @@
#include "UI_Prov_WebSocketNotifications.h" #include "UI_Prov_WebSocketNotifications.h"
#include "framework/ConfigurationValidator.h" #include "framework/ConfigurationValidator.h"
#include "framework/UI_WebSocketClientServer.h" #include "framework/UI_WebSocketClientServer.h"
#include "OpenRoamin_GlobalReach.h"
namespace OpenWifi { namespace OpenWifi {
class Daemon *Daemon::instance_ = nullptr; class Daemon *Daemon::instance_ = nullptr;
@@ -35,7 +36,9 @@ namespace OpenWifi {
ConfigurationValidator(), SerialNumberCache(), ConfigurationValidator(), SerialNumberCache(),
AutoDiscovery(), JobController(), AutoDiscovery(), JobController(),
UI_WebSocketClientServer(), FindCountryFromIP(), UI_WebSocketClientServer(), FindCountryFromIP(),
Signup(), FileDownloader()}); Signup(), FileDownloader(),
OpenRoaming_GlobalReach()
});
} }
return instance_; return instance_;
} }

View File

@@ -24,9 +24,8 @@ namespace OpenWifi {
void FileDownloader::onTimer([[maybe_unused]] Poco::Timer &timer) { void FileDownloader::onTimer([[maybe_unused]] Poco::Timer &timer) {
const static std::vector<std::pair<std::string, std::string>> Files{ const static std::vector<std::pair<std::string, std::string>> Files{
{"https://raw.githubusercontent.com/blogic/ucentral-schema/main/ucentral.schema.json", { "https://raw.githubusercontent.com/Telecominfraproject/wlan-ucentral-schema/main/ucentral.schema.json",
"ucentral.schema.json"}, "ucentral.schema.json"} };
{"https://ucentral.io/ucentral.schema.pretty.json", "ucentral.schema.pretty.json"}};
Utils::SetThreadName("file-dmnldr"); Utils::SetThreadName("file-dmnldr");

View File

@@ -39,9 +39,7 @@ namespace OpenWifi {
Poco::JSON::Object Payload; Poco::JSON::Object Payload;
obj.to_json(Payload); obj.to_json(Payload);
Payload.set("ObjectType", OT); Payload.set("ObjectType", OT);
std::ostringstream OS; KafkaManager()->PostMessage(KafkaTopics::PROVISIONING_CHANGE, Ops[op], Payload);
Payload.stringify(OS);
KafkaManager()->PostMessage(KafkaTopics::PROVISIONING_CHANGE, Ops[op], OS.str());
return true; return true;
} }

View File

@@ -0,0 +1,196 @@
//
// Created by stephane bourque on 2023-09-11.
//
#include "OpenRoamin_GlobalReach.h"
#include <Poco/JWT/Token.h>
#include <Poco/JWT/Signer.h>
#include <Poco/Net/HTTPSClientSession.h>
#include <Poco/URI.h>
#include <Poco/TemporaryFile.h>
#include <Poco/JSON/Object.h>
#include <Poco/JSON/Parser.h>
#include <framework/RESTAPI_Handler.h>
#include <framework/MicroServiceFuncs.h>
#include <StorageService.h>
namespace OpenWifi {
int OpenRoaming_GlobalReach::Start() {
poco_information(Logger(), "Starting...");
InitCache();
return 0;
}
void OpenRoaming_GlobalReach::Stop() {
poco_information(Logger(), "Stopping...");
poco_information(Logger(), "Stopped...");
}
void OpenRoaming_GlobalReach::InitCache() {
auto F=[&](const ProvObjects::GLBLRAccountInfo &Info) {
poco_information(Logger(),fmt::format("Adding {} to cache.",Info.info.name));
if(!Info.privateKey.empty() && !Info.GlobalReachAcctId.empty() ) {
MakeToken(Info.GlobalReachAcctId, Info.privateKey);
}
return true;
};
StorageService()->GLBLRAccountInfoDB().Iterate(F);
}
bool OpenRoaming_GlobalReach::CreateRADSECCertificate(
const std::string &GlobalReachAccountId,
const std::string &Name,
const std::string &CSR,
ProvObjects::GLBLRCertificateInfo &NewCertificate) {
try {
std::cout << __LINE__ << ":" << GlobalReachAccountId << std::endl;
auto BearerToken = MakeToken(GlobalReachAccountId);
Poco::URI URI{"https://config.openro.am/v1/radsec/issue"};
std::string Path(URI.getPathAndQuery());
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_POST, Path,
Poco::Net::HTTPMessage::HTTP_1_1);
Request.add("Authorization", "Bearer " + BearerToken);
Poco::Net::HTTPSClientSession Session(URI.getHost(), URI.getPort());
Session.setTimeout(Poco::Timespan(10000, 10000));
Poco::JSON::Object CertRequestBody;
CertRequestBody.set("name", Name);
CertRequestBody.set("csr", CSR);
std::ostringstream os;
CertRequestBody.stringify(os);
Request.setContentType("application/json");
Request.setContentLength((long) os.str().size());
auto &Body = Session.sendRequest(Request);
Body << os.str();
Poco::Net::HTTPResponse Response;
std::istream &is = Session.receiveResponse(Response);
if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) {
Poco::JSON::Parser P;
auto Result = P.parse(is).extract<Poco::JSON::Object::Ptr>();
RESTAPIHandler::AssignIfPresent(Result,"certificate",NewCertificate.certificate);
RESTAPIHandler::AssignIfPresent(Result,"certificate_chain",NewCertificate.certificateChain);
RESTAPIHandler::AssignIfPresent(Result,"certificate_id",NewCertificate.certificateId);
RESTAPIHandler::AssignIfPresent(Result,"expires_at",NewCertificate.expiresAt);
return true;
}
Poco::JSON::Parser P;
std::ostringstream oos;
auto Result = P.parse(is).extract<Poco::JSON::Object::Ptr>();
Result->stringify(oos);
} catch( const Poco::Exception &E) {
poco_error(Logger(),fmt::format("Could not create a new RADSEC certificate: {},{}",E.name(),E.displayText()));
}
return false;
}
bool OpenRoaming_GlobalReach::GetRADSECCertificate(
const std::string &GlobalReachAccountId,
std::string &CertificateId,
ProvObjects::GLBLRCertificateInfo &NewCertificate) {
try {
Poco::URI URI{fmt::format("https://config.openro.am/v1/radsec/cert/{}", CertificateId)};
std::string Path(URI.getPathAndQuery());
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_GET, Path,
Poco::Net::HTTPMessage::HTTP_1_1);
auto BearerToken = MakeToken(GlobalReachAccountId);
Request.add("Authorization", "Bearer " + BearerToken);
Poco::Net::HTTPSClientSession Session(URI.getHost(), URI.getPort());
Session.setTimeout(Poco::Timespan(10000, 10000));
Session.sendRequest(Request);
Poco::Net::HTTPResponse Response;
std::istream &is = Session.receiveResponse(Response);
if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) {
Poco::JSON::Parser P;
auto Result = P.parse(is).extract<Poco::JSON::Object::Ptr>();
RESTAPIHandler::AssignIfPresent(Result,"certificate",NewCertificate.certificate);
RESTAPIHandler::AssignIfPresent(Result,"certificate_chain",NewCertificate.certificateChain);
RESTAPIHandler::AssignIfPresent(Result,"certificate_id",NewCertificate.certificateId);
RESTAPIHandler::AssignIfPresent(Result,"expires_at",NewCertificate.expiresAt);
return true;
}
} catch( const Poco::Exception &E) {
poco_error(Logger(),fmt::format("Could not retrieve the certificate from GlobalReach: {},{}",E.name(),E.displayText()));
}
return false;
}
std::string OpenRoaming_GlobalReach::MakeToken(const std::string &GlobalReachAccountId, const std::string &PrivateKey) {
try {
Poco::JWT::Token token;
token.setType("JWT");
token.setAlgorithm("ES256");
token.setIssuedAt(std::time(nullptr));
token.payload().set("iss", GlobalReachAccountId);
token.payload().set("iat", (unsigned long) std::time(nullptr));
Poco::SharedPtr<Poco::Crypto::ECKey> Key;
auto KeyHash = Utils::ComputeHash(PrivateKey);
auto KeyHint = PrivateKeys_.find(GlobalReachAccountId);
if (KeyHint != PrivateKeys_.end() && PrivateKey.empty() ) {
Key = KeyHint->second.second;
} else {
if (PrivateKey.empty()) {
return "";
}
Poco::TemporaryFile F;
std::ofstream ofs(F.path().c_str(), std::ios_base::trunc | std::ios_base::out | std::ios_base::binary);
ofs << PrivateKey;
ofs.close();
auto NewKey = Poco::SharedPtr<Poco::Crypto::ECKey>(
new Poco::Crypto::ECKey("", F.path(), ""));
Key = NewKey;
PrivateKeys_[GlobalReachAccountId] = std::make_pair(KeyHash, NewKey);
}
Poco::JWT::Signer Signer;
Signer.setECKey(Key);
Signer.addAllAlgorithms();
return Signer.sign(token, Poco::JWT::Signer::ALGO_ES256);
} catch (const Poco::Exception &E) {
poco_error(Logger(),fmt::format("Cannot create a Global Reach token: {},{}",E.name(),E.displayText()));
}
return "";
}
bool OpenRoaming_GlobalReach::VerifyAccount(const std::string &GlobalReachAccountId, const std::string &PrivateKey, std::string &Name) {
auto BearerToken = MakeToken(GlobalReachAccountId, PrivateKey);
Poco::URI URI{"https://config.openro.am/v1/config"};
std::string Path(URI.getPathAndQuery());
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_GET, Path,
Poco::Net::HTTPMessage::HTTP_1_1);
Request.add("Authorization", "Bearer " + BearerToken);
Poco::Net::HTTPSClientSession Session(URI.getHost(), URI.getPort());
Session.setTimeout(Poco::Timespan(10000, 10000));
Session.sendRequest(Request);
Poco::Net::HTTPResponse Response;
std::istream &is = Session.receiveResponse(Response);
if(Response.getStatus()==Poco::Net::HTTPResponse::HTTP_OK) {
Poco::JSON::Parser P;
auto Result = P.parse(is).extract<Poco::JSON::Object::Ptr>();
if(Result->has("name")) {
Name = Result->get("name").toString();
}
return true;
}
return false;
}
} // OpenWifi

View File

@@ -0,0 +1,43 @@
//
// Created by stephane bourque on 2023-09-11.
//
#pragma once
#include "framework/SubSystemServer.h"
#include "Poco/JSON/Object.h"
#include "RESTObjects/RESTAPI_ProvObjects.h"
namespace OpenWifi {
class OpenRoaming_GlobalReach : public SubSystemServer {
public:
static auto instance() {
static auto instance_ = new OpenRoaming_GlobalReach;
return instance_;
}
int Start() override;
void Stop() override;
bool CreateRADSECCertificate(const std::string &AccountName,
const std::string &Name,
const std::string &CSR,
ProvObjects::GLBLRCertificateInfo &NewCertificate);
bool GetRADSECCertificate(const std::string &AccountName, std::string & CertificateId, ProvObjects::GLBLRCertificateInfo &NewCertificate);
bool VerifyAccount(const std::string &GlobalReachAccountId, const std::string &PrivateKey, std::string &Name);
void InitCache();
private:
std::string MakeToken(const std::string &GlobalReachAccountId, const std::string &PrivateKey="");
std::map<std::string,std::pair<std::string,Poco::SharedPtr<Poco::Crypto::ECKey>>> PrivateKeys_;
OpenRoaming_GlobalReach() noexcept
: SubSystemServer("OpenRoaming_GlobalReach", "GLBL-REACH", "globalreach") {
}
};
inline auto OpenRoaming_GlobalReach() { return OpenRoaming_GlobalReach::instance(); }
} // OpenWifi

View File

@@ -0,0 +1,125 @@
//
// Created by stephane bourque on 2023-09-11.
//
#include "RESTAPI_openroaming_gr_acct_handler.h"
#include "OpenRoamin_GlobalReach.h"
namespace OpenWifi {
void RESTAPI_openroaming_gr_acct_handler::DoGet() {
auto Account = GetBinding("id","");
if(Account.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
ProvObjects::GLBLRAccountInfo Record;
if(DB_.GetRecord("id",Account,Record)) {
return ReturnObject(Record);
}
return NotFound();
}
void RESTAPI_openroaming_gr_acct_handler::DoDelete() {
auto Account = GetBinding("id","");
if(Account.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
ProvObjects::GLBLRAccountInfo Record;
if(!DB_.GetRecord("id",Account,Record)) {
return NotFound();
}
StorageService()->GLBLRCertsDB().DeleteRecords(fmt::format(" accountId='{}' ", Account));
DB_.DeleteRecord("id", Account);
return OK();
}
void RESTAPI_openroaming_gr_acct_handler::DoPost() {
auto Account = GetBinding("id","");
if(Account.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
const auto &RawObject = ParsedBody_;
ProvObjects::GLBLRAccountInfo NewObject;
if( !NewObject.from_json(RawObject)) {
return BadRequest(OpenWifi::RESTAPI::Errors::InvalidJSONDocument);
}
if(NewObject.privateKey.empty() || NewObject.GlobalReachAcctId.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
if(!NewObject.privateKey.empty() && !Utils::VerifyECKey(NewObject.privateKey)) {
return BadRequest(RESTAPI::Errors::NotAValidECKey);
}
std::string GlobalReachName;
if(!OpenRoaming_GlobalReach()->VerifyAccount(NewObject.GlobalReachAcctId,NewObject.privateKey,GlobalReachName)) {
return BadRequest(RESTAPI::Errors::InvalidGlobalReachAccount);
}
if( NewObject.commonName.empty() || NewObject.organization.empty() ||
NewObject.city.empty() || NewObject.province.empty() || NewObject.country.empty() ) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
Utils::CSRCreationParameters P;
P.Country = NewObject.country;
P.CommonName = NewObject.commonName;
P.Province = NewObject.province;
P.City = NewObject.city;
P.Organization = NewObject.organization;
Utils::CSRCreationResults R;
if(!Utils::CreateX509CSR(P,R)) {
return BadRequest(RESTAPI::Errors::CannotCreateCSR);
}
NewObject.CSR = R.CSR;
NewObject.CSRPublicKey = R.PublicKey;
NewObject.CSRPrivateKey = R.PrivateKey;
ProvObjects::CreateObjectInfo(RawObject,UserInfo_.userinfo,NewObject.info);
if(DB_.CreateRecord(NewObject)) {
ProvObjects::GLBLRAccountInfo StoredObject;
DB_.GetRecord("id",NewObject.info.id,StoredObject);
return ReturnObject(StoredObject);
}
return BadRequest(RESTAPI::Errors::RecordNotCreated);
}
void RESTAPI_openroaming_gr_acct_handler::DoPut() {
auto Account = GetBinding("account","");
if(Account.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
const auto &RawObject = ParsedBody_;
ProvObjects::GLBLRAccountInfo Modify;
if(!Modify.from_json(RawObject)) {
return BadRequest(OpenWifi::RESTAPI::Errors::InvalidJSONDocument);
}
ProvObjects::GLBLRAccountInfo Existing;
if(!DB_.GetRecord("id",Account,Existing)) {
return NotFound();
}
if(!ProvObjects::UpdateObjectInfo(RawObject,UserInfo_.userinfo,Existing.info)) {
return BadRequest(OpenWifi::RESTAPI::Errors::InvalidJSONDocument);
}
if(DB_.UpdateRecord("id",Existing.info.id,Existing)) {
ProvObjects::GLBLRAccountInfo StoredObject;
DB_.GetRecord("id",Existing.info.id,StoredObject);
return ReturnObject(StoredObject);
}
return BadRequest(RESTAPI::Errors::RecordNotUpdated);
}
} // OpenWifi

View File

@@ -0,0 +1,31 @@
//
// Created by stephane bourque on 2023-09-11.
//
#pragma once
#include "StorageService.h"
#include "framework/RESTAPI_Handler.h"
namespace OpenWifi {
class RESTAPI_openroaming_gr_acct_handler : public RESTAPIHandler {
public:
RESTAPI_openroaming_gr_acct_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId,
bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_DELETE,
Poco::Net::HTTPRequest::HTTP_PUT,
Poco::Net::HTTPRequest::HTTP_POST,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal) {}
static auto PathName() { return std::list<std::string>{"/api/v1/openroaming/globalreach/account/{id}"}; };
private:
GLBLRAccountInfoDB &DB_ = StorageService()->GLBLRAccountInfoDB();
void DoGet() final;
void DoPost() final;
void DoPut() final;
void DoDelete() final;
};
} // namespace OpenWifi

View File

@@ -0,0 +1,82 @@
//
// Created by stephane bourque on 2023-09-11.
//
#include "RESTAPI_openroaming_gr_cert_handler.h"
#include <OpenRoamin_GlobalReach.h>
namespace OpenWifi {
void RESTAPI_openroaming_gr_cert_handler::DoGet() {
auto Account = GetBinding("account","");
auto Id = GetBinding("id","");
if(Account.empty() || Id.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
if(!StorageService()->GLBLRAccountInfoDB().Exists("id",Account)) {
return NotFound();
}
std::vector<ProvObjects::GLBLRCertificateInfo> Certificates;
DB_.GetRecords(0,1,Certificates,fmt::format(" accountId='{}' and id='{}' ", Account, Id));
if(Certificates.empty()) {
return NotFound();
}
return ReturnObject(Certificates[0]);
}
void RESTAPI_openroaming_gr_cert_handler::DoDelete() {
auto Account = GetBinding("account","");
auto Id = GetBinding("id","");
if(Account.empty() || Id.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
if(!StorageService()->GLBLRAccountInfoDB().Exists("id",Account)) {
return NotFound();
}
DB_.DeleteRecords(fmt::format(" accountId='{}' and id='{}' ", Account, Id));
return OK();
}
void RESTAPI_openroaming_gr_cert_handler::DoPost() {
auto Account = GetBinding("account","");
auto Id = GetBinding("id","");
if(Account.empty() || Id.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
const auto &RawObject = ParsedBody_;
ProvObjects::GLBLRCertificateInfo NewObject;
if( !NewObject.from_json(RawObject)) {
return BadRequest(OpenWifi::RESTAPI::Errors::InvalidJSONDocument);
}
if(NewObject.name.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
ProvObjects::GLBLRAccountInfo AccountInfo;
if(!StorageService()->GLBLRAccountInfoDB().GetRecord("id",Account, AccountInfo)) {
return BadRequest(RESTAPI::Errors::InvalidGlobalReachAccount);
}
if(OpenRoaming_GlobalReach()->CreateRADSECCertificate(AccountInfo.GlobalReachAcctId,NewObject.name,AccountInfo.CSR, NewObject)) {
NewObject.id = MicroServiceCreateUUID();
NewObject.accountId = Account;
NewObject.created = Utils::Now();
NewObject.csr = AccountInfo.CSR;
DB_.CreateRecord(NewObject);
ProvObjects::GLBLRCertificateInfo CreatedObject;
DB_.GetRecord("id",NewObject.id,CreatedObject);
return ReturnObject(CreatedObject);
}
return BadRequest(RESTAPI::Errors::RecordNotCreated);
}
} // OpenWifi

View File

@@ -0,0 +1,30 @@
//
// Created by stephane bourque on 2023-09-11.
//
#pragma once
#include "StorageService.h"
#include "framework/RESTAPI_Handler.h"
namespace OpenWifi {
class RESTAPI_openroaming_gr_cert_handler : public RESTAPIHandler {
public:
RESTAPI_openroaming_gr_cert_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId,
bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_DELETE,
Poco::Net::HTTPRequest::HTTP_POST,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal) {}
static auto PathName() { return std::list<std::string>{"/api/v1/openroaming/globalreach/certificate/{account}/{id}"}; };
private:
GLBLRCertsDB &DB_ = StorageService()->GLBLRCertsDB();
void DoGet() final;
void DoPost() final;
void DoPut() final {};
void DoDelete() final;
};
} // namespace OpenWifi

View File

@@ -0,0 +1,20 @@
//
// Created by stephane bourque on 2023-09-11.
//
#include "RESTAPI_openroaming_gr_list_acct_handler.h"
namespace OpenWifi {
void RESTAPI_openroaming_gr_list_acct_handler::DoGet() {
if(GetBoolParameter("countOnly")) {
return ReturnCountOnly(DB_.Count());
}
std::vector<ProvObjects::GLBLRAccountInfo> Accounts;
DB_.GetRecords(QB_.Offset,QB_.Limit,Accounts);
return ReturnObject(Accounts);
}
} // OpenWifi

View File

@@ -0,0 +1,29 @@
//
// Created by stephane bourque on 2023-09-11.
//
#pragma once
#include "StorageService.h"
#include "framework/RESTAPI_Handler.h"
namespace OpenWifi {
class RESTAPI_openroaming_gr_list_acct_handler : public RESTAPIHandler {
public:
RESTAPI_openroaming_gr_list_acct_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId,
bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal) {}
static auto PathName() { return std::list<std::string>{"/api/v1/openroaming/globalreach/accounts"}; };
private:
GLBLRAccountInfoDB &DB_ = StorageService()->GLBLRAccountInfoDB();
void DoGet() final;
void DoPost() final{};
void DoPut() final{};
void DoDelete() final{};
};
} // namespace OpenWifi

View File

@@ -0,0 +1,27 @@
//
// Created by stephane bourque on 2023-09-11.
//
#include "RESTAPI_openroaming_gr_list_certificates.h"
namespace OpenWifi {
void RESTAPI_openroaming_gr_list_certificates::DoGet() {
auto Account = GetBinding("account","");
if(Account.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
auto Where = fmt::format(" accountId='{}'", Account);
if(GetBoolParameter("countOnly")) {
return ReturnCountOnly(DB_.Count(Where));
}
std::vector<ProvObjects::GLBLRCertificateInfo> Certificates;
DB_.GetRecords(QB_.Offset,QB_.Limit,Certificates, Where);
return ReturnObject(Certificates);
}
} // OpenWifi

View File

@@ -0,0 +1,29 @@
//
// Created by stephane bourque on 2023-09-11.
//
#pragma once
#include "StorageService.h"
#include "framework/RESTAPI_Handler.h"
namespace OpenWifi {
class RESTAPI_openroaming_gr_list_certificates : public RESTAPIHandler {
public:
RESTAPI_openroaming_gr_list_certificates(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId,
bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal) {}
static auto PathName() { return std::list<std::string>{"/api/v1/openroaming/globalreach/certificates/{account}"}; };
private:
GLBLRCertsDB &DB_ = StorageService()->GLBLRCertsDB();
void DoGet() final;
void DoPost() final{};
void DoPut() final{};
void DoDelete() final{};
};
} // namespace OpenWifi

View File

@@ -0,0 +1,100 @@
//
// Created by stephane bourque on 2023-09-15.
//
#include "RESTAPI_openroaming_orion_acct_handler.h"
#include "OpenRoamin_GlobalReach.h"
namespace OpenWifi {
void RESTAPI_openroaming_orion_acct_handler::DoGet() {
auto Account = GetBinding("id","");
if(Account.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
ProvObjects::GooglOrionAccountInfo Record;
if(DB_.GetRecord("id",Account,Record)) {
return ReturnObject(Record);
}
return NotFound();
}
void RESTAPI_openroaming_orion_acct_handler::DoDelete() {
auto Account = GetBinding("id","");
if(Account.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
ProvObjects::GooglOrionAccountInfo Record;
if(!DB_.GetRecord("id",Account,Record)) {
return NotFound();
}
DB_.DeleteRecord("id", Account);
return OK();
}
void RESTAPI_openroaming_orion_acct_handler::DoPost() {
auto Account = GetBinding("id","");
if(Account.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
const auto &RawObject = ParsedBody_;
ProvObjects::GooglOrionAccountInfo NewObject;
if( !NewObject.from_json(RawObject)) {
return BadRequest(OpenWifi::RESTAPI::Errors::InvalidJSONDocument);
}
if( NewObject.privateKey.empty() ||
NewObject.certificate.empty() ||
NewObject.cacerts.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
if( !Utils::VerifyECKey(NewObject.privateKey) ||
!Utils::ValidX509Certificate(NewObject.certificate) ||
!Utils::ValidX509Certificate(NewObject.cacerts)) {
return BadRequest(RESTAPI::Errors::NotAValidECKey);
}
ProvObjects::CreateObjectInfo(RawObject,UserInfo_.userinfo,NewObject.info);
if(DB_.CreateRecord(NewObject)) {
ProvObjects::GooglOrionAccountInfo StoredObject;
DB_.GetRecord("id",NewObject.info.id,StoredObject);
return ReturnObject(StoredObject);
}
return BadRequest(RESTAPI::Errors::RecordNotCreated);
}
void RESTAPI_openroaming_orion_acct_handler::DoPut() {
auto Account = GetBinding("id","");
if(Account.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
const auto &RawObject = ParsedBody_;
ProvObjects::GLBLRAccountInfo Modify;
if(!Modify.from_json(RawObject)) {
return BadRequest(OpenWifi::RESTAPI::Errors::InvalidJSONDocument);
}
ProvObjects::GooglOrionAccountInfo Existing;
if(!DB_.GetRecord("id",Account,Existing)) {
return NotFound();
}
if(!ProvObjects::UpdateObjectInfo(RawObject,UserInfo_.userinfo,Existing.info)) {
return BadRequest(OpenWifi::RESTAPI::Errors::InvalidJSONDocument);
}
if(DB_.UpdateRecord("id",Existing.info.id,Existing)) {
ProvObjects::GooglOrionAccountInfo StoredObject;
DB_.GetRecord("id",Existing.info.id,StoredObject);
return ReturnObject(StoredObject);
}
return BadRequest(RESTAPI::Errors::RecordNotUpdated);
}
} // OpenWifi

View File

@@ -0,0 +1,31 @@
//
// Created by stephane bourque on 2023-09-15.
//
#pragma once
#include "StorageService.h"
#include "framework/RESTAPI_Handler.h"
namespace OpenWifi {
class RESTAPI_openroaming_orion_acct_handler : public RESTAPIHandler {
public:
RESTAPI_openroaming_orion_acct_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId,
bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_DELETE,
Poco::Net::HTTPRequest::HTTP_POST,
Poco::Net::HTTPRequest::HTTP_PUT,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal) {}
static auto PathName() { return std::list<std::string>{"/api/v1/openroaming/orion/account/{id}"}; };
private:
OrionAccountsDB &DB_ = StorageService()->OrionAccountsDB();
void DoGet() final;
void DoPost() final;
void DoPut() final;
void DoDelete() final;
};
} // namespace OpenWifi

View File

@@ -0,0 +1,21 @@
//
// Created by stephane bourque on 2023-09-15.
//
#include "RESTAPI_openroaming_orion_list_acct_handler.h"
namespace OpenWifi {
void RESTAPI_openroaming_orion_list_acct_handler::DoGet() {
if(GetBoolParameter("countOnly")) {
return ReturnCountOnly(DB_.Count());
}
std::vector<ProvObjects::GooglOrionAccountInfo> Accounts;
DB_.GetRecords(QB_.Offset,QB_.Limit,Accounts);
return ReturnObject(Accounts);
}
} // OpenWifi

View File

@@ -0,0 +1,29 @@
//
// Created by stephane bourque on 2023-09-15.
//
#pragma once
#include "StorageService.h"
#include "framework/RESTAPI_Handler.h"
namespace OpenWifi {
class RESTAPI_openroaming_orion_list_acct_handler : public RESTAPIHandler {
public:
RESTAPI_openroaming_orion_list_acct_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId,
bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal) {}
static auto PathName() { return std::list<std::string>{"/api/v1/openroaming/orion/accounts"}; };
private:
OrionAccountsDB &DB_ = StorageService()->OrionAccountsDB();
void DoGet() final;
void DoPost() final{};
void DoPut() final{};
void DoDelete() final{};
};
} // namespace OpenWifi

View File

@@ -35,6 +35,12 @@
#include "RESTAPI/RESTAPI_variables_list_handler.h" #include "RESTAPI/RESTAPI_variables_list_handler.h"
#include "RESTAPI/RESTAPI_venue_handler.h" #include "RESTAPI/RESTAPI_venue_handler.h"
#include "RESTAPI/RESTAPI_venue_list_handler.h" #include "RESTAPI/RESTAPI_venue_list_handler.h"
#include "RESTAPI/RESTAPI_openroaming_gr_acct_handler.h"
#include "RESTAPI/RESTAPI_openroaming_gr_list_acct_handler.h"
#include "RESTAPI/RESTAPI_openroaming_gr_cert_handler.h"
#include "RESTAPI/RESTAPI_openroaming_gr_list_certificates.h"
#include "RESTAPI/RESTAPI_openroaming_orion_acct_handler.h"
#include "RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.h"
#include "framework/RESTAPI_SystemCommand.h" #include "framework/RESTAPI_SystemCommand.h"
#include "framework/RESTAPI_WebSocketServer.h" #include "framework/RESTAPI_WebSocketServer.h"
@@ -60,7 +66,10 @@ namespace OpenWifi {
RESTAPI_operators_list_handler, RESTAPI_service_class_handler, RESTAPI_operators_list_handler, RESTAPI_service_class_handler,
RESTAPI_service_class_list_handler, RESTAPI_op_contact_handler, RESTAPI_service_class_list_handler, RESTAPI_op_contact_handler,
RESTAPI_op_contact_list_handler, RESTAPI_op_location_handler, RESTAPI_op_contact_list_handler, RESTAPI_op_location_handler,
RESTAPI_op_location_list_handler, RESTAPI_asset_server, RESTAPI_overrides_handler>( RESTAPI_op_location_list_handler, RESTAPI_asset_server, RESTAPI_overrides_handler,
RESTAPI_openroaming_gr_acct_handler, RESTAPI_openroaming_gr_list_acct_handler,
RESTAPI_openroaming_gr_cert_handler, RESTAPI_openroaming_gr_list_certificates,
RESTAPI_openroaming_orion_acct_handler, RESTAPI_openroaming_orion_list_acct_handler>(
Path, Bindings, L, S, TransactionId); Path, Bindings, L, S, TransactionId);
} }
@@ -82,7 +91,10 @@ namespace OpenWifi {
RESTAPI_operators_list_handler, RESTAPI_service_class_handler, RESTAPI_operators_list_handler, RESTAPI_service_class_handler,
RESTAPI_service_class_list_handler, RESTAPI_op_contact_handler, RESTAPI_service_class_list_handler, RESTAPI_op_contact_handler,
RESTAPI_op_contact_list_handler, RESTAPI_op_location_handler, RESTAPI_op_contact_list_handler, RESTAPI_op_location_handler,
RESTAPI_op_location_list_handler, RESTAPI_overrides_handler>(Path, Bindings, L, S, RESTAPI_op_location_list_handler, RESTAPI_overrides_handler,
RESTAPI_openroaming_gr_acct_handler, RESTAPI_openroaming_gr_list_acct_handler,
RESTAPI_openroaming_gr_cert_handler, RESTAPI_openroaming_gr_list_certificates,
RESTAPI_openroaming_orion_acct_handler, RESTAPI_openroaming_orion_list_acct_handler>(Path, Bindings, L, S,
TransactionId); TransactionId);
} }
} // namespace OpenWifi } // namespace OpenWifi

View File

@@ -90,9 +90,9 @@ namespace OpenWifi {
} }
if (!Existing.contacts.empty()) { if (!Existing.contacts.empty()) {
for (const auto &i : Existing.contacts) for (const auto &contact_uuid : Existing.contacts)
StorageService()->ContactDB().DeleteInUse( StorageService()->ContactDB().DeleteInUse(
"id", i, StorageService()->VenueDB().Prefix(), UUID); "id", contact_uuid, StorageService()->VenueDB().Prefix(), UUID);
} }
if (!Existing.location.empty()) if (!Existing.location.empty())
StorageService()->LocationDB().DeleteInUse("id", Existing.location, StorageService()->LocationDB().DeleteInUse("id", Existing.location,
@@ -101,9 +101,9 @@ namespace OpenWifi {
StorageService()->PolicyDB().DeleteInUse("id", Existing.managementPolicy, StorageService()->PolicyDB().DeleteInUse("id", Existing.managementPolicy,
StorageService()->VenueDB().Prefix(), UUID); StorageService()->VenueDB().Prefix(), UUID);
if (!Existing.deviceConfiguration.empty()) { if (!Existing.deviceConfiguration.empty()) {
for (auto &i : Existing.deviceConfiguration) for (auto &configuration_uuid : Existing.deviceConfiguration)
StorageService()->ConfigurationDB().DeleteInUse( StorageService()->ConfigurationDB().DeleteInUse(
"id", i, StorageService()->VenueDB().Prefix(), UUID); "id", configuration_uuid, StorageService()->VenueDB().Prefix(), UUID);
} }
if (!Existing.parent.empty()) if (!Existing.parent.empty())
StorageService()->VenueDB().DeleteChild("id", Existing.parent, UUID); StorageService()->VenueDB().DeleteChild("id", Existing.parent, UUID);
@@ -157,6 +157,10 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::EntityMustExist); return BadRequest(RESTAPI::Errors::EntityMustExist);
} }
if(StorageService()->VenueDB().DoesVenueNameAlreadyExist(NewObject.info.name,NewObject.entity, NewObject.parent)) {
return BadRequest(RESTAPI::Errors::VenuesNameAlreadyExists);
}
if (!NewObject.contacts.empty()) { if (!NewObject.contacts.empty()) {
for (const auto &i : NewObject.contacts) { for (const auto &i : NewObject.contacts) {
if (!StorageService()->ContactDB().Exists("id", i)) { if (!StorageService()->ContactDB().Exists("id", i)) {
@@ -432,7 +436,7 @@ namespace OpenWifi {
std::string MoveFromEntity, MoveToEntity; std::string MoveFromEntity, MoveToEntity;
if (AssignIfPresent(RawObject, "entity", MoveToEntity)) { if (AssignIfPresent(RawObject, "entity", MoveToEntity)) {
if (!MoveToEntity.empty() && !StorageService()->EntityDB().Exists("id", MoveToEntity)) { if (MoveToEntity.empty() || !StorageService()->EntityDB().Exists("id", MoveToEntity)) {
return BadRequest(RESTAPI::Errors::EntityMustExist); return BadRequest(RESTAPI::Errors::EntityMustExist);
} }
MoveFromEntity = Existing.entity; MoveFromEntity = Existing.entity;
@@ -441,7 +445,7 @@ namespace OpenWifi {
std::string MoveToVenue, MoveFromVenue; std::string MoveToVenue, MoveFromVenue;
if (AssignIfPresent(RawObject, "venue", MoveToVenue)) { if (AssignIfPresent(RawObject, "venue", MoveToVenue)) {
if (!MoveToVenue.empty() && !StorageService()->VenueDB().Exists("id", MoveToVenue)) { if (MoveToVenue.empty() || !StorageService()->VenueDB().Exists("id", MoveToVenue)) {
return BadRequest(RESTAPI::Errors::VenueMustExist); return BadRequest(RESTAPI::Errors::VenueMustExist);
} }
MoveFromVenue = Existing.parent; MoveFromVenue = Existing.parent;
@@ -450,7 +454,7 @@ namespace OpenWifi {
std::string MoveFromLocation, MoveToLocation; std::string MoveFromLocation, MoveToLocation;
if (AssignIfPresent(RawObject, "location", MoveToLocation)) { if (AssignIfPresent(RawObject, "location", MoveToLocation)) {
if (!MoveToLocation.empty() && if (MoveToLocation.empty() ||
!StorageService()->LocationDB().Exists("id", MoveToLocation)) { !StorageService()->LocationDB().Exists("id", MoveToLocation)) {
return BadRequest(RESTAPI::Errors::LocationMustExist); return BadRequest(RESTAPI::Errors::LocationMustExist);
} }
@@ -460,8 +464,8 @@ namespace OpenWifi {
Types::UUIDvec_t MoveFromContacts, MoveToContacts; Types::UUIDvec_t MoveFromContacts, MoveToContacts;
if (AssignIfPresent(RawObject, "contacts", MoveToContacts)) { if (AssignIfPresent(RawObject, "contacts", MoveToContacts)) {
for (const auto &i : NewObject.contacts) { for (const auto &contact : NewObject.contacts) {
if (!StorageService()->ContactDB().Exists("id", i)) { if (!StorageService()->ContactDB().Exists("id", contact)) {
return BadRequest(RESTAPI::Errors::ContactMustExist); return BadRequest(RESTAPI::Errors::ContactMustExist);
} }
} }
@@ -471,7 +475,7 @@ namespace OpenWifi {
std::string MoveFromPolicy, MoveToPolicy; std::string MoveFromPolicy, MoveToPolicy;
if (AssignIfPresent(RawObject, "managementPolicy", MoveToPolicy)) { if (AssignIfPresent(RawObject, "managementPolicy", MoveToPolicy)) {
if (!MoveToPolicy.empty() && !StorageService()->PolicyDB().Exists("id", MoveToPolicy)) { if (MoveToPolicy.empty() || !StorageService()->PolicyDB().Exists("id", MoveToPolicy)) {
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID); return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
} }
MoveFromPolicy = Existing.managementPolicy; MoveFromPolicy = Existing.managementPolicy;
@@ -481,8 +485,8 @@ namespace OpenWifi {
Types::UUIDvec_t MoveToConfigurations, MoveFromConfigurations; Types::UUIDvec_t MoveToConfigurations, MoveFromConfigurations;
if (RawObject->has("deviceConfiguration")) { if (RawObject->has("deviceConfiguration")) {
MoveToConfigurations = NewObject.deviceConfiguration; MoveToConfigurations = NewObject.deviceConfiguration;
for (auto &i : MoveToConfigurations) { for (auto &configuration : MoveToConfigurations) {
if (!StorageService()->ConfigurationDB().Exists("id", i)) { if (!StorageService()->ConfigurationDB().Exists("id", configuration)) {
return BadRequest(RESTAPI::Errors::ConfigurationMustExist); return BadRequest(RESTAPI::Errors::ConfigurationMustExist);
} }
} }

View File

@@ -7,5 +7,14 @@
#include "StorageService.h" #include "StorageService.h"
namespace OpenWifi { namespace OpenWifi {
void RESTAPI_venue_list_handler::DoGet() { return ListHandler<VenueDB>("venues", DB_, *this); } void RESTAPI_venue_list_handler::DoGet() {
auto RRMvendor = GetParameter("RRMvendor","");
if(RRMvendor.empty()) {
return ListHandler<VenueDB>("venues", DB_, *this);
}
VenueDB::RecordVec Venues;
auto Where = fmt::format(" deviceRules LIKE '%{}%' ", RRMvendor);
DB_.GetRecords(QB_.Offset, QB_.Limit, Venues, Where, " ORDER BY name ");
return ReturnObject("venues",Venues);
}
} // namespace OpenWifi } // namespace OpenWifi

View File

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

View File

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

View File

@@ -1194,4 +1194,89 @@ namespace OpenWifi::ProvObjects {
return false; return false;
} }
void GLBLRAccountInfo::to_json(Poco::JSON::Object &Obj) const {
info.to_json(Obj);
field_to_json(Obj, "privateKey", privateKey);
field_to_json(Obj, "country", country);
field_to_json(Obj, "province", province);
field_to_json(Obj, "city", city);
field_to_json(Obj, "organization", organization);
field_to_json(Obj, "commonName", commonName);
field_to_json(Obj, "CSR", CSR);
field_to_json(Obj, "CSRPrivateKey", CSRPrivateKey);
field_to_json(Obj, "CSRPublicKey", CSRPublicKey);
field_to_json(Obj, "GlobalReachAcctId", GlobalReachAcctId);
}
bool GLBLRAccountInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
info.from_json(Obj);
field_from_json(Obj, "privateKey", privateKey);
field_from_json(Obj, "country", country);
field_from_json(Obj, "province", province);
field_from_json(Obj, "city", city);
field_from_json(Obj, "organization", organization);
field_from_json(Obj, "commonName", commonName);
field_from_json(Obj, "CSR", CSR);
field_from_json(Obj, "CSRPrivateKey", CSRPrivateKey);
field_from_json(Obj, "CSRPublicKey", CSRPublicKey);
field_from_json(Obj, "GlobalReachAcctId", GlobalReachAcctId);
return true;
} catch (const Poco::Exception &E) {
}
return false;
}
void GLBLRCertificateInfo::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "id", id);
field_to_json(Obj, "name", name);
field_to_json(Obj, "accountId", accountId);
field_to_json(Obj, "csr", csr);
field_to_json(Obj, "certificate", certificate);
field_to_json(Obj, "certificateChain", certificateChain);
field_to_json(Obj, "certificateId", certificateId);
field_to_json(Obj, "expiresAt", expiresAt);
field_to_json(Obj, "created", created);
}
bool GLBLRCertificateInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "id", id);
field_from_json(Obj, "name", name);
field_from_json(Obj, "accountId", accountId);
field_from_json(Obj, "csr", csr);
field_from_json(Obj, "certificate", certificate);
field_from_json(Obj, "certificateChain", certificateChain);
field_from_json(Obj, "certificateId", certificateId);
field_from_json(Obj, "expiresAt", expiresAt);
field_from_json(Obj, "created", created);
return true;
} catch (const Poco::Exception &E) {
}
return false;
}
void GooglOrionAccountInfo::to_json(Poco::JSON::Object &Obj) const {
info.to_json(Obj);
field_to_json(Obj, "privateKey", privateKey);
field_to_json(Obj, "certificate", certificate);
field_to_json(Obj, "cacerts", cacerts);
}
bool GooglOrionAccountInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
info.from_json(Obj);
field_from_json(Obj, "privateKey", privateKey);
field_from_json(Obj, "certificate", certificate);
field_from_json(Obj, "cacerts", cacerts);
return true;
} catch (const Poco::Exception &E) {
}
return false;
}
} // namespace OpenWifi::ProvObjects } // namespace OpenWifi::ProvObjects

View File

@@ -746,4 +746,41 @@ namespace OpenWifi::ProvObjects {
bool CreateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, bool CreateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U,
ObjectInfo &I); ObjectInfo &I);
bool CreateObjectInfo(const SecurityObjects::UserInfo &U, ObjectInfo &I); bool CreateObjectInfo(const SecurityObjects::UserInfo &U, ObjectInfo &I);
struct GLBLRAccountInfo {
ObjectInfo info;
std::string privateKey;
std::string country, province, city, organization, commonName;
std::string CSR, CSRPrivateKey, CSRPublicKey;
std::string GlobalReachAcctId;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct GLBLRCertificateInfo {
std::string id;
std::string name;
std::string accountId;
std::string csr;
std::string certificate;
std::string certificateChain;
std::string certificateId;
std::uint64_t expiresAt=0;
std::uint64_t created=0;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct GooglOrionAccountInfo {
ObjectInfo info;
std::string privateKey;
std::string certificate;
std::vector<std::string> cacerts;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
}; // namespace OpenWifi::ProvObjects }; // namespace OpenWifi::ProvObjects

View File

@@ -39,6 +39,9 @@ namespace OpenWifi {
OpLocationDB_ = std::make_unique<OpenWifi::OpLocationDB>(dbType_, *Pool_, Logger()); OpLocationDB_ = std::make_unique<OpenWifi::OpLocationDB>(dbType_, *Pool_, Logger());
OpContactDB_ = std::make_unique<OpenWifi::OpContactDB>(dbType_, *Pool_, Logger()); OpContactDB_ = std::make_unique<OpenWifi::OpContactDB>(dbType_, *Pool_, Logger());
OverridesDB_ = std::make_unique<OpenWifi::OverridesDB>(dbType_, *Pool_, Logger()); OverridesDB_ = std::make_unique<OpenWifi::OverridesDB>(dbType_, *Pool_, Logger());
GLBLRAccountInfoDB_ = std::make_unique<OpenWifi::GLBLRAccountInfoDB>(dbType_, *Pool_, Logger());
GLBLRCertsDB_ = std::make_unique<OpenWifi::GLBLRCertsDB>(dbType_, *Pool_, Logger());
OrionAccountsDB_ = std::make_unique<OpenWifi::OrionAccountsDB>(dbType_, *Pool_, Logger());
EntityDB_->Create(); EntityDB_->Create();
PolicyDB_->Create(); PolicyDB_->Create();
@@ -59,6 +62,9 @@ namespace OpenWifi {
OpLocationDB_->Create(); OpLocationDB_->Create();
OpContactDB_->Create(); OpContactDB_->Create();
OverridesDB_->Create(); OverridesDB_->Create();
GLBLRAccountInfoDB_->Create();
GLBLRCertsDB_->Create();
OrionAccountsDB_->Create();
ExistFunc_[EntityDB_->Prefix()] = [=](const char *F, std::string &V) -> bool { ExistFunc_[EntityDB_->Prefix()] = [=](const char *F, std::string &V) -> bool {
return EntityDB_->Exists(F, V); return EntityDB_->Exists(F, V);
@@ -117,8 +123,19 @@ namespace OpenWifi {
ExistFunc_[OverridesDB_->Prefix()] = [=](const char *F, std::string &V) -> bool { ExistFunc_[OverridesDB_->Prefix()] = [=](const char *F, std::string &V) -> bool {
return OverridesDB_->Exists(F, V); return OverridesDB_->Exists(F, V);
}; };
ExistFunc_[GLBLRAccountInfoDB_->Prefix()] = [=](const char *F, std::string &V) -> bool {
return GLBLRAccountInfoDB_->Exists(F, V);
};
ExistFunc_[GLBLRCertsDB_->Prefix()] = [=](const char *F, std::string &V) -> bool {
return GLBLRCertsDB_->Exists(F, V);
};
ExistFunc_[GLBLRCertsDB_->Prefix()] = [=](const char *F, std::string &V) -> bool {
return OrionAccountsDB_->Exists(F, V);
};
ExpandFunc_[EntityDB_->Prefix()] = [=](const char *F, std::string &V, std::string &Name,
ExpandFunc_[EntityDB_->Prefix()] = [=](const char *F, std::string &V, std::string &Name,
std::string &Description) -> bool { std::string &Description) -> bool {
return EntityDB_->GetNameAndDescription(F, V, Name, Description); return EntityDB_->GetNameAndDescription(F, V, Name, Description);
}; };
@@ -206,9 +223,24 @@ namespace OpenWifi {
[=]([[maybe_unused]] const char *F, [[maybe_unused]] std::string &V, [=]([[maybe_unused]] const char *F, [[maybe_unused]] std::string &V,
[[maybe_unused]] std::string &Name, [[maybe_unused]] std::string &Name,
[[maybe_unused]] std::string &Description) -> bool { return false; }; [[maybe_unused]] std::string &Description) -> bool { return false; };
ExpandFunc_[GLBLRAccountInfoDB_->Prefix()] =
[=]([[maybe_unused]] const char *F, [[maybe_unused]] std::string &V,
[[maybe_unused]] std::string &Name,
[[maybe_unused]] std::string &Description) -> bool { return false; };
ExpandFunc_[OverridesDB_->Prefix()] =
[=]([[maybe_unused]] const char *F, [[maybe_unused]] std::string &V,
[[maybe_unused]] std::string &Name,
[[maybe_unused]] std::string &Description) -> bool { return false; };
ExpandFunc_[GLBLRCertsDB_->Prefix()] =
[=]([[maybe_unused]] const char *F, [[maybe_unused]] std::string &V,
[[maybe_unused]] std::string &Name,
[[maybe_unused]] std::string &Description) -> bool { return false; };
ExpandFunc_[OrionAccountsDB_->Prefix()] =
[=]([[maybe_unused]] const char *F, [[maybe_unused]] std::string &V,
[[maybe_unused]] std::string &Name,
[[maybe_unused]] std::string &Description) -> bool { return false; };
InventoryDB_->InitializeSerialCache(); InventoryDB_->InitializeSerialCache();
ConsistencyCheck(); ConsistencyCheck();
InitializeSystemDBs(); InitializeSystemDBs();

View File

@@ -28,6 +28,9 @@
#include "storage/storage_tags.h" #include "storage/storage_tags.h"
#include "storage/storage_variables.h" #include "storage/storage_variables.h"
#include "storage/storage_venue.h" #include "storage/storage_venue.h"
#include "storage/storage_glblraccounts.h"
#include "storage/storage_glblrcerts.h"
#include "storage/storage_orion_accounts.h"
#include "Poco/URI.h" #include "Poco/URI.h"
#include "framework/ow_constants.h" #include "framework/ow_constants.h"
@@ -47,25 +50,28 @@ namespace OpenWifi {
typedef std::list<ProvObjects::ExpandedUseEntry> ExpandedInUseList; typedef std::list<ProvObjects::ExpandedUseEntry> ExpandedInUseList;
typedef std::map<std::string, ProvObjects::ExpandedUseEntryList> ExpandedListMap; typedef std::map<std::string, ProvObjects::ExpandedUseEntryList> ExpandedListMap;
OpenWifi::EntityDB &EntityDB() { return *EntityDB_; }; inline OpenWifi::EntityDB &EntityDB() { return *EntityDB_; };
OpenWifi::PolicyDB &PolicyDB() { return *PolicyDB_; }; inline OpenWifi::PolicyDB &PolicyDB() { return *PolicyDB_; };
OpenWifi::VenueDB &VenueDB() { return *VenueDB_; }; inline OpenWifi::VenueDB &VenueDB() { return *VenueDB_; };
OpenWifi::LocationDB &LocationDB() { return *LocationDB_; }; inline OpenWifi::LocationDB &LocationDB() { return *LocationDB_; };
OpenWifi::ContactDB &ContactDB() { return *ContactDB_; }; inline OpenWifi::ContactDB &ContactDB() { return *ContactDB_; };
OpenWifi::InventoryDB &InventoryDB() { return *InventoryDB_; }; inline OpenWifi::InventoryDB &InventoryDB() { return *InventoryDB_; };
OpenWifi::ManagementRoleDB &RolesDB() { return *RolesDB_; }; inline OpenWifi::ManagementRoleDB &RolesDB() { return *RolesDB_; };
OpenWifi::ConfigurationDB &ConfigurationDB() { return *ConfigurationDB_; }; inline OpenWifi::ConfigurationDB &ConfigurationDB() { return *ConfigurationDB_; };
OpenWifi::TagsDictionaryDB &TagsDictionaryDB() { return *TagsDictionaryDB_; }; inline OpenWifi::TagsDictionaryDB &TagsDictionaryDB() { return *TagsDictionaryDB_; };
OpenWifi::TagsObjectDB &TagsObjectDB() { return *TagsObjectDB_; }; inline OpenWifi::TagsObjectDB &TagsObjectDB() { return *TagsObjectDB_; };
OpenWifi::MapDB &MapDB() { return *MapDB_; }; inline OpenWifi::MapDB &MapDB() { return *MapDB_; };
OpenWifi::SignupDB &SignupDB() { return *SignupDB_; }; inline OpenWifi::SignupDB &SignupDB() { return *SignupDB_; };
OpenWifi::VariablesDB &VariablesDB() { return *VariablesDB_; }; inline OpenWifi::VariablesDB &VariablesDB() { return *VariablesDB_; };
OpenWifi::OperatorDB &OperatorDB() { return *OperatorDB_; }; inline OpenWifi::OperatorDB &OperatorDB() { return *OperatorDB_; };
OpenWifi::ServiceClassDB &ServiceClassDB() { return *ServiceClassDB_; }; inline OpenWifi::ServiceClassDB &ServiceClassDB() { return *ServiceClassDB_; };
OpenWifi::SubscriberDeviceDB &SubscriberDeviceDB() { return *SubscriberDeviceDB_; }; inline OpenWifi::SubscriberDeviceDB &SubscriberDeviceDB() { return *SubscriberDeviceDB_; };
OpenWifi::OpLocationDB &OpLocationDB() { return *OpLocationDB_; }; inline OpenWifi::OpLocationDB &OpLocationDB() { return *OpLocationDB_; };
OpenWifi::OpContactDB &OpContactDB() { return *OpContactDB_; }; inline OpenWifi::OpContactDB &OpContactDB() { return *OpContactDB_; };
OpenWifi::OverridesDB &OverridesDB() { return *OverridesDB_; }; inline OpenWifi::OverridesDB &OverridesDB() { return *OverridesDB_; };
inline OpenWifi::GLBLRAccountInfoDB &GLBLRAccountInfoDB() { return *GLBLRAccountInfoDB_; }
inline OpenWifi::GLBLRCertsDB &GLBLRCertsDB() { return *GLBLRCertsDB_; }
inline OpenWifi::OrionAccountsDB &OrionAccountsDB() { return *OrionAccountsDB_; }
bool Validate(const Poco::URI::QueryParameters &P, RESTAPI::Errors::msg &Error); bool Validate(const Poco::URI::QueryParameters &P, RESTAPI::Errors::msg &Error);
bool Validate(const Types::StringVec &P, std::string &Error); bool Validate(const Types::StringVec &P, std::string &Error);
@@ -125,6 +131,9 @@ namespace OpenWifi {
std::unique_ptr<OpenWifi::OpLocationDB> OpLocationDB_; std::unique_ptr<OpenWifi::OpLocationDB> OpLocationDB_;
std::unique_ptr<OpenWifi::OpContactDB> OpContactDB_; std::unique_ptr<OpenWifi::OpContactDB> OpContactDB_;
std::unique_ptr<OpenWifi::OverridesDB> OverridesDB_; std::unique_ptr<OpenWifi::OverridesDB> OverridesDB_;
std::unique_ptr<OpenWifi::GLBLRAccountInfoDB> GLBLRAccountInfoDB_;
std::unique_ptr<OpenWifi::GLBLRCertsDB> GLBLRCertsDB_;
std::unique_ptr<OpenWifi::OrionAccountsDB> OrionAccountsDB_;
std::string DefaultOperator_; std::string DefaultOperator_;
typedef std::function<bool(const char *FieldName, std::string &Value)> exist_func; typedef std::function<bool(const char *FieldName, std::string &Value)> exist_func;

View File

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

View File

@@ -7,37 +7,38 @@
#include "framework/SubSystemServer.h" #include "framework/SubSystemServer.h"
#include "Poco/Net/HTTPRequestHandler.h" #include "Poco/Net/HTTPRequestHandler.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "Poco/Net/HTTPServerResponse.h"
#include "Poco/Net/HTTPRequestHandlerFactory.h" #include "Poco/Net/HTTPRequestHandlerFactory.h"
#include "Poco/Net/HTTPServer.h" #include "Poco/Net/HTTPServer.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "Poco/Net/HTTPServerResponse.h"
namespace OpenWifi { namespace OpenWifi {
class ALBRequestHandler: public Poco::Net::HTTPRequestHandler { class ALBRequestHandler : public Poco::Net::HTTPRequestHandler {
public: public:
explicit ALBRequestHandler(Poco::Logger & L, uint64_t id) explicit ALBRequestHandler(Poco::Logger &L, uint64_t id) : Logger_(L), id_(id) {}
: Logger_(L), id_(id) {
}
void handleRequest([[maybe_unused]] Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response) override; void handleRequest([[maybe_unused]] Poco::Net::HTTPServerRequest &Request,
Poco::Net::HTTPServerResponse &Response) override;
private: private:
Poco::Logger & Logger_; Poco::Logger &Logger_;
uint64_t id_; uint64_t id_;
}; };
class ALBRequestHandlerFactory: public Poco::Net::HTTPRequestHandlerFactory class ALBRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
{
public: public:
explicit ALBRequestHandlerFactory(Poco::Logger & L); explicit ALBRequestHandlerFactory(Poco::Logger &L);
ALBRequestHandler* createRequestHandler(const Poco::Net::HTTPServerRequest& request) override; ALBRequestHandler *
createRequestHandler(const Poco::Net::HTTPServerRequest &request) override;
private: private:
Poco::Logger &Logger_; Poco::Logger &Logger_;
inline static std::atomic_uint64_t req_id_=1; inline static std::atomic_uint64_t req_id_ = 1;
}; };
typedef std::string ALBHealthMessageCallback();
class ALBHealthCheckServer : public SubSystemServer { class ALBHealthCheckServer : public SubSystemServer {
public: public:
ALBHealthCheckServer(); ALBHealthCheckServer();
@@ -49,15 +50,26 @@ namespace OpenWifi {
int Start() override; int Start() override;
void Stop() override; void Stop() override;
inline void RegisterExtendedHealthMessage(ALBHealthMessageCallback *F) {
Callback_=F;
};
inline std::string CallbackText() {
if(Callback_== nullptr) {
return "process Alive and kicking!";
} else {
return Callback_();
}
}
private: private:
std::unique_ptr<Poco::Net::HTTPServer> Server_; std::unique_ptr<Poco::Net::HTTPServer> Server_;
std::unique_ptr<Poco::Net::ServerSocket> Socket_; std::unique_ptr<Poco::Net::ServerSocket> Socket_;
int Port_ = 0; ALBHealthMessageCallback *Callback_= nullptr;
mutable std::atomic_bool Running_=false; int Port_ = 0;
mutable std::atomic_bool Running_ = false;
}; };
inline auto ALBHealthCheckServer() { return ALBHealthCheckServer::instance(); } inline auto ALBHealthCheckServer() { return ALBHealthCheckServer::instance(); }
} // namespace OpenWifi } // namespace OpenWifi

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -10,13 +10,13 @@ namespace OpenWifi {
static const std::string uSERVICE_SECURITY{"owsec"}; static const std::string uSERVICE_SECURITY{"owsec"};
static const std::string uSERVICE_GATEWAY{"owgw"}; static const std::string uSERVICE_GATEWAY{"owgw"};
static const std::string uSERVICE_FIRMWARE{ "owfms"}; static const std::string uSERVICE_FIRMWARE{"owfms"};
static const std::string uSERVICE_TOPOLOGY{ "owtopo"}; static const std::string uSERVICE_TOPOLOGY{"owtopo"};
static const std::string uSERVICE_PROVISIONING{ "owprov"}; static const std::string uSERVICE_PROVISIONING{"owprov"};
static const std::string uSERVICE_OWLS{ "owls"}; static const std::string uSERVICE_OWLS{"owls"};
static const std::string uSERVICE_SUBCRIBER{ "owsub"}; static const std::string uSERVICE_SUBCRIBER{"owsub"};
static const std::string uSERVICE_INSTALLER{ "owinst"}; static const std::string uSERVICE_INSTALLER{"owinst"};
static const std::string uSERVICE_ANALYTICS{ "owanalytics"}; static const std::string uSERVICE_ANALYTICS{"owanalytics"};
static const std::string uSERVICE_OWRRM{ "owrrm"}; static const std::string uSERVICE_OWRRM{"owrrm"};
} } // namespace OpenWifi

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -4,145 +4,144 @@
#pragma once #pragma once
#include <string>
#include <fstream> #include <fstream>
#include <iostream>
#include <iomanip> #include <iomanip>
#include <iostream>
#include <random> #include <random>
#include <regex> #include <regex>
#include <thread>
#include <shared_mutex> #include <shared_mutex>
#include <string>
#include <thread>
#include <dirent.h>
#include "Poco/Thread.h"
#include "Poco/StringTokenizer.h"
#include "Poco/String.h"
#include "Poco/SHA2Engine.h"
#include "Poco/Message.h"
#include "Poco/StreamCopier.h"
#include "Poco/File.h"
#include "Poco/Net/NetworkInterface.h"
#include "Poco/URI.h"
#include "Poco/Net/HTTPRequest.h"
#include "Poco/Net/HTTPClientSession.h"
#include "Poco/Net/HTTPSClientSession.h"
#include "Poco/Net/HTTPResponse.h"
#include "Poco/Base64Decoder.h" #include "Poco/Base64Decoder.h"
#include "Poco/Base64Encoder.h" #include "Poco/Base64Encoder.h"
#include "Poco/File.h"
#include "Poco/Message.h"
#include "Poco/Net/HTTPClientSession.h"
#include "Poco/Net/HTTPRequest.h"
#include "Poco/Net/HTTPResponse.h"
#include "Poco/Net/HTTPSClientSession.h"
#include "Poco/Net/NetworkInterface.h"
#include "Poco/SHA2Engine.h"
#include "Poco/StreamCopier.h"
#include "Poco/String.h"
#include "Poco/StringTokenizer.h"
#include "Poco/Thread.h"
#include "Poco/URI.h"
#include "Poco/zlib.h" #include "Poco/zlib.h"
#include "framework/ow_constants.h"
#include "framework/OpenWifiTypes.h" #include "framework/OpenWifiTypes.h"
#include "framework/ow_constants.h"
namespace OpenWifi::Utils { namespace OpenWifi::Utils {
inline uint64_t Now() { return std::time(nullptr); }; inline uint64_t Now() { return std::time(nullptr); };
bool NormalizeMac(std::string & Mac); bool NormalizeMac(std::string &Mac);
inline void SetThreadName(const char *name) { inline void SetThreadName(const char *name) {
#ifdef __linux__ #ifdef __linux__
Poco::Thread::current()->setName(name); Poco::Thread::current()->setName(name);
pthread_setname_np(pthread_self(), name); pthread_setname_np(pthread_self(), name);
#endif #endif
#ifdef __APPLE__ #ifdef __APPLE__
Poco::Thread::current()->setName(name); Poco::Thread::current()->setName(name);
pthread_setname_np(name); pthread_setname_np(name);
#endif #endif
} }
inline void SetThreadName(Poco::Thread &thr, const char *name) { inline void SetThreadName(Poco::Thread &thr, const char *name) {
#ifdef __linux__ #ifdef __linux__
thr.setName(name); thr.setName(name);
pthread_setname_np(thr.tid(), name); pthread_setname_np(thr.tid(), name);
#endif #endif
#ifdef __APPLE__ #ifdef __APPLE__
thr.setName(name); thr.setName(name);
#endif #endif
} }
enum MediaTypeEncodings { enum MediaTypeEncodings { PLAIN, BINARY, BASE64 };
PLAIN,
BINARY,
BASE64
};
struct MediaTypeEncoding { struct MediaTypeEncoding {
MediaTypeEncodings Encoding=PLAIN; MediaTypeEncodings Encoding = PLAIN;
std::string ContentType; std::string ContentType;
}; };
[[nodiscard]] bool ValidSerialNumber(const std::string &Serial); [[nodiscard]] bool ValidSerialNumber(const std::string &Serial);
[[nodiscard]] bool ValidSerialNumbers(const std::vector<std::string> &Serial);
[[nodiscard]] bool ValidUUID(const std::string &UUID); [[nodiscard]] bool ValidUUID(const std::string &UUID);
[[nodiscard]] bool ValidHostname(const std::string &hostname); [[nodiscard]] bool ValidHostname(const std::string &hostname);
[[nodiscard]] bool ValidNumber(const std::string &number, bool isSigned);
template <typename ...Args> std::string ComputeHash(Args&&... args) { template <typename... Args> std::string ComputeHash(Args &&...args) {
Poco::SHA2Engine E; Poco::SHA2Engine E;
auto as_string = [](auto p) { auto as_string = [](auto p) {
if constexpr(std::is_arithmetic_v<decltype(p)>) { if constexpr (std::is_arithmetic_v<decltype(p)>) {
return std::to_string(p); return std::to_string(p);
} else { } else {
return p; return p;
} }
}; };
(E.update(as_string(args)),...); (E.update(as_string(args)), ...);
return Poco::SHA2Engine::digestToHex(E.digest()); return Poco::SHA2Engine::digestToHex(E.digest());
} }
[[nodiscard]] std::vector<std::string> Split(const std::string &List, char Delimiter=',' ); [[nodiscard]] std::vector<std::string> Split(const std::string &List, char Delimiter = ',');
[[nodiscard]] std::string FormatIPv6(const std::string & I ); [[nodiscard]] std::string FormatIPv6(const std::string &I);
void padTo(std::string& str, size_t num, char paddingChar = '\0'); void padTo(std::string &str, size_t num, char paddingChar = '\0');
[[nodiscard]] std::string SerialToMAC(const std::string &Serial); [[nodiscard]] std::string SerialToMAC(const std::string &Serial);
uint64_t MACToInt(const std::string &MAC); uint64_t MACToInt(const std::string &MAC);
[[nodiscard]] std::string ToHex(const std::vector<unsigned char> & B); [[nodiscard]] std::string ToHex(const std::vector<unsigned char> &B);
using byte = std::uint8_t; using byte = std::uint8_t;
[[nodiscard]] std::string base64encode(const byte *input, uint32_t size); [[nodiscard]] std::string base64encode(const byte *input, uint32_t size);
[[nodiscard]] std::vector<byte> base64decode(const std::string& input);; [[nodiscard]] std::vector<byte> base64decode(const std::string &input);
bool ParseTime(const std::string &Time, int & Hours, int & Minutes, int & Seconds); ;
bool ParseDate(const std::string &Time, int & Year, int & Month, int & Day); bool ParseTime(const std::string &Time, int &Hours, int &Minutes, int &Seconds);
bool CompareTime( int H1, int H2, int M1, int M2, int S1, int S2); bool ParseDate(const std::string &Time, int &Year, int &Month, int &Day);
bool CompareTime(int H1, int H2, int M1, int M2, int S1, int S2);
[[nodiscard]] std::string LogLevelToString(int Level); [[nodiscard]] std::string LogLevelToString(int Level);
[[nodiscard]] uint64_t SerialNumberToInt(const std::string & S); [[nodiscard]] uint64_t SerialNumberToInt(const std::string &S);
[[nodiscard]] std::string IntToSerialNumber(uint64_t S); [[nodiscard]] std::string IntToSerialNumber(uint64_t S);
[[nodiscard]] bool SerialNumberMatch(const std::string &S1, const std::string &S2, int Bits=2); [[nodiscard]] bool SerialNumberMatch(const std::string &S1, const std::string &S2,
[[nodiscard]] uint64_t SerialNumberToOUI(const std::string & S); int Bits = 2);
[[nodiscard]] uint64_t SerialNumberToOUI(const std::string &S);
[[nodiscard]] uint64_t GetDefaultMacAsInt64(); [[nodiscard]] uint64_t GetDefaultMacAsInt64();
[[nodiscard]] uint64_t InitializeSystemId(); [[nodiscard]] uint64_t InitializeSystemId();
[[nodiscard]] uint64_t GetSystemId(); [[nodiscard]] uint64_t GetSystemId();
[[nodiscard]] bool ValidEMailAddress(const std::string &email); [[nodiscard]] bool ValidEMailAddress(const std::string &email);
[[nodiscard]] std::string LoadFile( const Poco::File & F); [[nodiscard]] std::string LoadFile(const Poco::File &F);
void ReplaceVariables( std::string & Content , const Types::StringPairVec & P); void ReplaceVariables(std::string &Content, const Types::StringPairVec &P);
[[nodiscard]] MediaTypeEncoding FindMediaType(const Poco::File &F); [[nodiscard]] MediaTypeEncoding FindMediaType(const Poco::File &F);
[[nodiscard]] std::string BinaryFileToHexString(const Poco::File &F); [[nodiscard]] std::string BinaryFileToHexString(const Poco::File &F);
[[nodiscard]] std::string SecondsToNiceText(uint64_t Seconds); [[nodiscard]] std::string SecondsToNiceText(uint64_t Seconds);
[[nodiscard]] bool wgets(const std::string &URL, std::string &Response); [[nodiscard]] bool wgets(const std::string &URL, std::string &Response);
[[nodiscard]] bool wgetfile(const Poco::URI &uri, const std::string &FileName); [[nodiscard]] bool wgetfile(const Poco::URI &uri, const std::string &FileName);
[[nodiscard]] bool IsAlphaNumeric(const std::string &s); [[nodiscard]] bool IsAlphaNumeric(const std::string &s);
[[nodiscard]] std::string SanitizeToken(const std::string &Token); [[nodiscard]] std::string SanitizeToken(const std::string &Token);
[[nodiscard]] bool ValidateURI(const std::string &uri); [[nodiscard]] bool ValidateURI(const std::string &uri);
[[nodiscard]] std::uint64_t ConvertDate(const std::string &d); [[nodiscard]] std::uint64_t ConvertDate(const std::string &d);
template< typename T > template <typename T> std::string int_to_hex(T i) {
std::string int_to_hex( T i )
{
std::stringstream stream; std::stringstream stream;
stream << std::setfill ('0') << std::setw(12) stream << std::setfill('0') << std::setw(12) << std::hex << i;
<< std::hex << i;
return stream.str(); return stream.str();
} }
inline bool SpinLock_Read(std::shared_mutex &M, volatile bool &Flag, uint64_t wait_ms=100) { inline bool SpinLock_Read(std::shared_mutex &M, volatile bool &Flag, uint64_t wait_ms = 100) {
while(!M.try_lock_shared() && Flag) { while (!M.try_lock_shared() && Flag) {
Poco::Thread::yield(); Poco::Thread::yield();
Poco::Thread::trySleep((long)wait_ms); Poco::Thread::trySleep((long)wait_ms);
} }
return Flag; return Flag;
} }
inline bool SpinLock_Write(std::shared_mutex &M, volatile bool &Flag, uint64_t wait_ms=100) { inline bool SpinLock_Write(std::shared_mutex &M, volatile bool &Flag, uint64_t wait_ms = 100) {
while(!M.try_lock() && Flag) { while (!M.try_lock() && Flag) {
Poco::Thread::yield(); Poco::Thread::yield();
Poco::Thread::trySleep(wait_ms); Poco::Thread::trySleep(wait_ms);
} }
@@ -150,5 +149,119 @@ namespace OpenWifi::Utils {
} }
bool ExtractBase64CompressedData(const std::string &CompressedData, bool ExtractBase64CompressedData(const std::string &CompressedData,
std::string &UnCompressedData, uint64_t compress_sz ); std::string &UnCompressedData, uint64_t compress_sz);
}
inline bool match(const char* first, const char* second)
{
// If we reach at the end of both strings, we are done
if (*first == '\0' && *second == '\0')
return true;
// Make sure to eliminate consecutive '*'
if (*first == '*') {
while (*(first + 1) == '*')
first++;
}
// Make sure that the characters after '*' are present
// in second string. This function assumes that the
// first string will not contain two consecutive '*'
if (*first == '*' && *(first + 1) != '\0'
&& *second == '\0')
return false;
// If the first string contains '?', or current
// characters of both strings match
if (*first == '?' || *first == *second)
return match(first + 1, second + 1);
// If there is *, then there are two possibilities
// a) We consider current character of second string
// b) We ignore current character of second string.
if (*first == '*')
return match(first + 1, second)
|| match(first, second + 1);
return false;
}
static inline std::uint64_t GetValue(FILE *file) {
unsigned long v=0;
char factor[32];
if(fscanf(file, " %lu %31s", &v, factor)==2) {
switch (factor[0]) {
case 'k':
return v * 1000;
case 'M':
return v * 1000000;
case 'G':
return v * 1000000000;
}
}
return v;
}
inline bool getMemory(
std::uint64_t &currRealMem, std::uint64_t &peakRealMem,
std::uint64_t &currVirtMem, std::uint64_t &peakVirtMem) {
// stores each word in status file
char buffer[1024] = "";
currRealMem = peakRealMem = currVirtMem = peakVirtMem = 0;
// linux file contains this-process info
FILE * file = std::fopen("/proc/self/status", "r");
if (file == nullptr) {
return false;
}
// read the entire file, recording mems in kB
while (fscanf(file, " %1023s", buffer) == 1) {
if (strcmp(buffer, "VmRSS:") == 0) {
currRealMem= GetValue(file);
} else if (strcmp(buffer, "VmHWM:") == 0) {
peakRealMem= GetValue(file);
} else if (strcmp(buffer, "VmSize:") == 0) {
currVirtMem= GetValue(file);
} else if (strcmp(buffer, "VmPeak:") == 0) {
peakVirtMem= GetValue(file);
}
}
fclose(file);
return true;
}
inline int get_open_fds() {
DIR *dp = opendir("/proc/self/fd");
struct dirent *de;
int count = -3; // '.', '..', dp
if (dp == nullptr)
return -1;
while ((de = readdir(dp)) != nullptr)
count++;
(void)closedir(dp);
return count;
}
struct CSRCreationParameters {
std::string Country, Province, City,
Organization, CommonName;
int bits=2048;
};
struct CSRCreationResults {
std::string CSR, PublicKey, PrivateKey;
};
bool CreateX509CSR(const CSRCreationParameters & Parameters, CSRCreationResults & Results);
std::string generateStrongPassword(int minLength, int maxLength, int numDigits, int minLowercase, int minSpecial, int minUppercase);
bool VerifyECKey(const std::string &key);
bool VerifyRSAKey(const std::string &key);
bool ValidX509Certificate(const std::string &Cert);
bool ValidX509Certificate(const std::vector<std::string> &Certs);
} // namespace OpenWifi::Utils

View File

@@ -0,0 +1,97 @@
//
// Created by stephane bourque on 2023-09-11.
//
#include "storage_glblraccounts.h"
#include <framework/orm.h>
#include "framework/OpenWifiTypes.h"
#include "framework/RESTAPI_utils.h"
#include "RESTObjects/RESTAPI_SecurityObjects.h"
namespace OpenWifi {
static ORM::FieldVec GLBLRAccountInfoDB_Fields{
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{"privateKey", ORM::FieldType::FT_TEXT},
ORM::Field{"country", ORM::FieldType::FT_TEXT},
ORM::Field{"province", ORM::FieldType::FT_TEXT},
ORM::Field{"city", ORM::FieldType::FT_TEXT},
ORM::Field{"organization", ORM::FieldType::FT_TEXT},
ORM::Field{"commonName", ORM::FieldType::FT_TEXT},
ORM::Field{"CSR", ORM::FieldType::FT_TEXT},
ORM::Field{"CSRPrivateKey", ORM::FieldType::FT_TEXT},
ORM::Field{"CSRPublicKey", ORM::FieldType::FT_TEXT},
ORM::Field{"GlobalReachAcctId", ORM::FieldType::FT_TEXT}
};
static ORM::IndexVec GLBLRAccountInfoDB_Indexes{
{std::string("glblr_name_index"),
ORM::IndexEntryVec{{std::string("name"), ORM::Indextype::ASC}}}};
GLBLRAccountInfoDB::GLBLRAccountInfoDB(OpenWifi::DBType T, Poco::Data::SessionPool &P, Poco::Logger &L)
: DB(T, "glblr_accts", GLBLRAccountInfoDB_Fields, GLBLRAccountInfoDB_Indexes, P, L, "glr") {}
bool GLBLRAccountInfoDB::Upgrade([[maybe_unused]] uint32_t from, uint32_t &to) {
to = Version();
std::vector<std::string> Script{};
for (const auto &i : Script) {
try {
auto Session = Pool_.get();
Session << i, Poco::Data::Keywords::now;
} catch (...) {
}
}
return true;
}
} // namespace OpenWifi
template <>
void ORM::DB<OpenWifi::GLBLRAccountsDBRecordType, OpenWifi::ProvObjects::GLBLRAccountInfo>::Convert(
const OpenWifi::GLBLRAccountsDBRecordType &In, OpenWifi::ProvObjects::GLBLRAccountInfo &Out) {
Out.info.id = In.get<0>();
Out.info.name = In.get<1>();
Out.info.description = In.get<2>();
Out.info.notes =
OpenWifi::RESTAPI_utils::to_object_array<OpenWifi::SecurityObjects::NoteInfo>(In.get<3>());
Out.info.created = In.get<4>();
Out.info.modified = In.get<5>();
Out.privateKey =In.get<6>();
Out.country = In.get<7>();
Out.province = In.get<8>();
Out.city = In.get<9>();
Out.organization = In.get<10>();
Out.commonName = In.get<11>();
Out.CSR = In.get<12>();
Out.CSRPrivateKey = In.get<13>();
Out.CSRPublicKey = In.get<14>();
Out.GlobalReachAcctId = In.get<15>();
}
template <>
void ORM::DB<OpenWifi::GLBLRAccountsDBRecordType, OpenWifi::ProvObjects::GLBLRAccountInfo>::Convert(
const OpenWifi::ProvObjects::GLBLRAccountInfo &In, OpenWifi::GLBLRAccountsDBRecordType &Out) {
Out.set<0>(In.info.id);
Out.set<1>(In.info.name);
Out.set<2>(In.info.description);
Out.set<3>(OpenWifi::RESTAPI_utils::to_string(In.info.notes));
Out.set<4>(In.info.created);
Out.set<5>(In.info.modified);
Out.set<6>(In.privateKey);
Out.set<7>(In.country);
Out.set<8>(In.province);
Out.set<9>(In.city);
Out.set<10>(In.organization);
Out.set<11>(In.commonName);
Out.set<12>(In.CSR);
Out.set<13>(In.CSRPrivateKey);
Out.set<14>(In.CSRPublicKey);
Out.set<15>(In.GlobalReachAcctId);
}

View File

@@ -0,0 +1,35 @@
//
// Created by stephane bourque on 2023-09-11.
//
#pragma once
#include "RESTObjects/RESTAPI_ProvObjects.h"
#include "framework/orm.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>
GLBLRAccountsDBRecordType;
class GLBLRAccountInfoDB : public ORM::DB<GLBLRAccountsDBRecordType, ProvObjects::GLBLRAccountInfo> {
public:
GLBLRAccountInfoDB(OpenWifi::DBType T, Poco::Data::SessionPool &P, Poco::Logger &L);
virtual ~GLBLRAccountInfoDB(){};
bool Upgrade(uint32_t from, uint32_t &to) override;
private:
};
} // namespace OpenWifi

View File

@@ -0,0 +1,76 @@
//
// Created by stephane bourque on 2023-09-11.
//
#include "storage_glblrcerts.h"
#include <framework/orm.h>
#include "framework/OpenWifiTypes.h"
#include "framework/RESTAPI_utils.h"
#include "RESTObjects/RESTAPI_SecurityObjects.h"
namespace OpenWifi {
static ORM::FieldVec GLBLRCertsDB_Fields{// object info
ORM::Field{"id", 64, true},
ORM::Field{"name", ORM::FieldType::FT_TEXT},
ORM::Field{"accountId", ORM::FieldType::FT_TEXT},
ORM::Field{"csr", ORM::FieldType::FT_TEXT},
ORM::Field{"certificate", ORM::FieldType::FT_TEXT},
ORM::Field{"certificateChain", ORM::FieldType::FT_TEXT},
ORM::Field{"certificateId", ORM::FieldType::FT_TEXT},
ORM::Field{"expiresAt", ORM::FieldType::FT_BIGINT},
ORM::Field{"created", ORM::FieldType::FT_BIGINT}
};
static ORM::IndexVec GLBLRCertsDB_Indexes{
{std::string("glblr_cert_id_index"),
ORM::IndexEntryVec{{std::string("name"), ORM::Indextype::ASC}}}};
GLBLRCertsDB::GLBLRCertsDB(OpenWifi::DBType T, Poco::Data::SessionPool &P, Poco::Logger &L)
: DB(T, "glblr_certs", GLBLRCertsDB_Fields, GLBLRCertsDB_Indexes, P, L, "glc") {}
bool GLBLRCertsDB::Upgrade([[maybe_unused]] uint32_t from, uint32_t &to) {
to = Version();
std::vector<std::string> Script{};
for (const auto &i : Script) {
try {
auto Session = Pool_.get();
Session << i, Poco::Data::Keywords::now;
} catch (...) {
}
}
return true;
}
} // namespace OpenWifi
template <>
void ORM::DB<OpenWifi::GLBLRCertsDBRecordType, OpenWifi::ProvObjects::GLBLRCertificateInfo>::Convert(
const OpenWifi::GLBLRCertsDBRecordType &In, OpenWifi::ProvObjects::GLBLRCertificateInfo &Out) {
Out.id = In.get<0>();
Out.name = In.get<1>();
Out.accountId = In.get<2>();
Out.csr = In.get<3>();
Out.certificate = In.get<4>();
Out.certificateChain = In.get<5>();
Out.certificateId = In.get<6>();
Out.expiresAt = In.get<7>();
Out.created = In.get<8>();
}
template <>
void ORM::DB<OpenWifi::GLBLRCertsDBRecordType, OpenWifi::ProvObjects::GLBLRCertificateInfo>::Convert(
const OpenWifi::ProvObjects::GLBLRCertificateInfo &In, OpenWifi::GLBLRCertsDBRecordType &Out) {
Out.set<0>(In.id);
Out.set<1>(In.name);
Out.set<2>(In.accountId);
Out.set<3>(In.csr);
Out.set<4>(In.certificate);
Out.set<5>(In.certificateChain);
Out.set<6>(In.certificateId);
Out.set<7>(In.expiresAt);
Out.set<8>(In.created);
}

View File

@@ -0,0 +1,37 @@
//
// Created by stephane bourque on 2023-09-11.
//
//
// Created by stephane bourque on 2023-09-11.
//
#pragma once
#include "RESTObjects/RESTAPI_ProvObjects.h"
#include "framework/orm.h"
namespace OpenWifi {
typedef Poco::Tuple<
std::string,
std::string,
std::string,
std::string,
std::string,
std::string,
std::string,
uint64_t,
uint64_t>
GLBLRCertsDBRecordType;
class GLBLRCertsDB : public ORM::DB<GLBLRCertsDBRecordType, ProvObjects::GLBLRCertificateInfo> {
public:
GLBLRCertsDB(OpenWifi::DBType T, Poco::Data::SessionPool &P, Poco::Logger &L);
virtual ~GLBLRCertsDB(){};
bool Upgrade(uint32_t from, uint32_t &to) override;
private:
};
} // namespace OpenWifi

View File

@@ -85,7 +85,7 @@ namespace OpenWifi {
ProvObjects::InventoryTag ExistingDevice; ProvObjects::InventoryTag ExistingDevice;
auto SerialNumber = Poco::toLower(SerialNumberRaw); auto SerialNumber = Poco::toLower(SerialNumberRaw);
if (!GetRecord("serialNumber", SerialNumber, ExistingDevice)) { if (!GetRecord("serialNumber", SerialNumber, ExistingDevice)) {
ProvObjects::InventoryTag NewDevice; ProvObjects::InventoryTag NewDevice;
uint64_t Now = Utils::Now(); uint64_t Now = Utils::Now();
auto Tokens = Poco::StringTokenizer(ConnectionInfo, "@:"); auto Tokens = Poco::StringTokenizer(ConnectionInfo, "@:");
@@ -127,11 +127,9 @@ namespace OpenWifi {
if (!FullUUID.empty()) { if (!FullUUID.empty()) {
if (SDK::GW::Device::SetVenue(nullptr, NewDevice.serialNumber, FullUUID)) { if (SDK::GW::Device::SetVenue(nullptr, NewDevice.serialNumber, FullUUID)) {
// std::cout << "Set GW done " << SerialNumber << std::endl;
Logger().information(Poco::format("%s: GW set entity/venue property.", Logger().information(Poco::format("%s: GW set entity/venue property.",
NewDevice.serialNumber)); NewDevice.serialNumber));
} else { } else {
// std::cout << "Could not set GW " << SerialNumber << std::endl;
Logger().information(Poco::format( Logger().information(Poco::format(
"%s: could not set GW entity/venue property.", NewDevice.serialNumber)); "%s: could not set GW entity/venue property.", NewDevice.serialNumber));
} }
@@ -178,7 +176,7 @@ namespace OpenWifi {
if (modified) { if (modified) {
ExistingDevice.info.modified = Utils::Now(); ExistingDevice.info.modified = Utils::Now();
StorageService()->InventoryDB().UpdateRecord("serialNumber", SerialNumber, StorageService()->InventoryDB().UpdateRecord("id", ExistingDevice.info.id,
ExistingDevice); ExistingDevice);
} }
} }

View File

@@ -0,0 +1,76 @@
//
// Created by stephane bourque on 2023-09-17.
//
#include "storage_orion_accounts.h"
#include <framework/orm.h>
#include "framework/OpenWifiTypes.h"
#include "framework/RESTAPI_utils.h"
#include "RESTObjects/RESTAPI_SecurityObjects.h"
namespace OpenWifi {
static ORM::FieldVec OrionAccountsDB_Fields{
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{"privateKey", ORM::FieldType::FT_TEXT},
ORM::Field{"certificate", ORM::FieldType::FT_TEXT},
ORM::Field{"cacerts", ORM::FieldType::FT_TEXT}
};
static ORM::IndexVec OrionAccountsDB_Indexes{
{std::string("orion_name_index"),
ORM::IndexEntryVec{{std::string("name"), ORM::Indextype::ASC}}}};
OrionAccountsDB::OrionAccountsDB(OpenWifi::DBType T, Poco::Data::SessionPool &P, Poco::Logger &L)
: DB(T, "orion_accts", OrionAccountsDB_Fields, OrionAccountsDB_Indexes, P, L, "oat") {}
bool OrionAccountsDB::Upgrade([[maybe_unused]] uint32_t from, uint32_t &to) {
to = Version();
std::vector<std::string> Script{};
for (const auto &i : Script) {
try {
auto Session = Pool_.get();
Session << i, Poco::Data::Keywords::now;
} catch (...) {
}
}
return true;
}
} // namespace OpenWifi
template <>
void ORM::DB<OpenWifi::OrionAccountsDBRecordType, OpenWifi::ProvObjects::GooglOrionAccountInfo>::Convert(
const OpenWifi::OrionAccountsDBRecordType &In, OpenWifi::ProvObjects::GooglOrionAccountInfo &Out) {
Out.info.id = In.get<0>();
Out.info.name = In.get<1>();
Out.info.description = In.get<2>();
Out.info.notes =
OpenWifi::RESTAPI_utils::to_object_array<OpenWifi::SecurityObjects::NoteInfo>(In.get<3>());
Out.info.created = In.get<4>();
Out.info.modified = In.get<5>();
Out.privateKey =In.get<6>();
Out.certificate = In.get<7>();
Out.cacerts = OpenWifi::RESTAPI_utils::to_object_array(In.get<8>());
}
template <>
void ORM::DB<OpenWifi::OrionAccountsDBRecordType, OpenWifi::ProvObjects::GooglOrionAccountInfo>::Convert(
const OpenWifi::ProvObjects::GooglOrionAccountInfo &In, OpenWifi::OrionAccountsDBRecordType &Out) {
Out.set<0>(In.info.id);
Out.set<1>(In.info.name);
Out.set<2>(In.info.description);
Out.set<3>(OpenWifi::RESTAPI_utils::to_string(In.info.notes));
Out.set<4>(In.info.created);
Out.set<5>(In.info.modified);
Out.set<6>(In.privateKey);
Out.set<7>(In.certificate);
Out.set<8>(OpenWifi::RESTAPI_utils::to_string(In.cacerts));
}

View File

@@ -0,0 +1,32 @@
//
// Created by stephane bourque on 2023-09-17.
//
#pragma once
#include "RESTObjects/RESTAPI_ProvObjects.h"
#include "framework/orm.h"
namespace OpenWifi {
typedef Poco::Tuple<std::string,
std::string,
std::string,
std::string,
uint64_t,
uint64_t,
std::string,
std::string,
std::string>
OrionAccountsDBRecordType;
class OrionAccountsDB : public ORM::DB<OrionAccountsDBRecordType, ProvObjects::GooglOrionAccountInfo> {
public:
OrionAccountsDB(OpenWifi::DBType T, Poco::Data::SessionPool &P, Poco::Logger &L);
virtual ~OrionAccountsDB(){};
bool Upgrade(uint32_t from, uint32_t &to) override;
private:
};
} // namespace OpenWifi

View File

@@ -112,6 +112,31 @@ namespace OpenWifi {
return true; return true;
} }
bool VenueDB::DoesVenueNameAlreadyExist(const std::string &name, const std::string &entity_uuid, const std::string &parent_uuid) {
std::string Statement;
if(!entity_uuid.empty()) {
Statement = fmt::format("select count(*) from venues where entity='{}' and upper(name)='{}'",
entity_uuid, Poco::toUpper(name));
} else {
Statement = fmt::format("select count(*) from venues where parent='{}' and upper(name)='{}'",
parent_uuid, Poco::toUpper(name));
}
std::uint64_t RecordCount = 0;
try {
Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Command(Session);
Command << Statement,
Poco::Data::Keywords::into(RecordCount);
Command.execute();
} catch (...) {
}
return RecordCount!=0;
}
} // namespace OpenWifi } // namespace OpenWifi
template <> template <>

View File

@@ -26,6 +26,7 @@ namespace OpenWifi {
bool GetByIP(const std::string &IP, std::string &uuid); bool GetByIP(const std::string &IP, std::string &uuid);
bool Upgrade(uint32_t from, uint32_t &to) override; bool Upgrade(uint32_t from, uint32_t &to) override;
bool EvaluateDeviceRules(const std::string &id, ProvObjects::DeviceRules &Rules); bool EvaluateDeviceRules(const std::string &id, ProvObjects::DeviceRules &Rules);
bool DoesVenueNameAlreadyExist(const std::string &name, const std::string &entity_uuid, const std::string &parent_uuid);
private: private:
}; };

View File

@@ -528,6 +528,14 @@ getvenuedevices() {
jq < ${result_file} jq < ${result_file}
} }
getvenuesperrrm() {
curl ${FLAGS} -X GET "https://${OWPROV}/api/v1/venue?RRMvendor=$1" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${token}" \
-H "Accept: application/json" > ${result_file}
jq < ${result_file}
}
listrrmalgos() { listrrmalgos() {
setrrm setrrm
curl ${FLAGS} -X GET "http://${OWRRM}/api/v1/algorithms" \ curl ${FLAGS} -X GET "http://${OWRRM}/api/v1/algorithms" \
@@ -546,6 +554,7 @@ rrmprovider() {
jq < ${result_file} jq < ${result_file}
} }
notifications() { notifications() {
if [[ -z "$1" ]] if [[ -z "$1" ]]
then then
@@ -608,6 +617,51 @@ getsystemconfiguration() {
jq < ${result_file} jq < ${result_file}
} }
creategraccount() {
payload="{ \"name\" : \"Test account\" , \"country\" : \"CA\", \"province\" : \"BC\" , \"city\" : \"Vancouver\", \"organization\" : \"Arilia Wireless Inc.\", \"commonName\" : \"arilia.com\", \"GlobalReachAcctId\" : \"bd63aaa7-b14d-4cdb-85ae-8de6cf2cfa31\", \"privateKey\" : \"-----BEGIN PRIVATE KEY-----\nMIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgl1FpARtuOtw1F9sR2DD82jh6sZFGRn619IY0rmNIFEuhRANCAATB7ji6OF/+heGRCocgVNhw4QGvaL9Kp8F6ZqqZ3aMewRMOfzi3TQaXN12FNBsvXnptx5vk8GAzZk6UAzzvMBVK\n-----END PRIVATE KEY-----\" }"
curl ${FLAGS} -X POST "https://${OWPROV}/api/v1/openroaming/globalreach/account/0" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${token}" \
-H "Accept: application/json" \
-d "$payload" > ${result_file}
jq < ${result_file}
}
getgraccount() {
curl ${FLAGS} -X GET "https://${OWPROV}/api/v1/openroaming/globalreach/account/$1" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${token}" \
-H "Accept: application/json" > ${result_file}
jq < ${result_file}
}
deletegraccount() {
curl ${FLAGS} -X DELETE "https://${OWPROV}/api/v1/openroaming/globalreach/account/$1" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${token}" \
-H "Accept: application/json" > ${result_file}
jq < ${result_file}
}
getgraccounts() {
curl ${FLAGS} -X GET "https://${OWPROV}/api/v1/openroaming/globalreach/accounts" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${token}" \
-H "Accept: application/json" > ${result_file}
jq < ${result_file}
}
creategrcert() {
payload="{ \"name\" : \"$2\" }"
curl ${FLAGS} -X POST "https://${OWPROV}/api/v1/openroaming/globalreach/certificate/$1/0" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${token}" \
-H "Accept: application/json" \
-d "$payload" > ${result_file}
jq < ${result_file}
}
shopt -s nocasematch shopt -s nocasematch
case "$1" in case "$1" in
"login") login; echo "You are logged in..." ; logout ;; "login") login; echo "You are logged in..." ; logout ;;
@@ -664,6 +718,12 @@ case "$1" in
"deleteoverride") login; deleteoverride "$2"; logout;; "deleteoverride") login; deleteoverride "$2"; logout;;
"venueupgraderevisions") login; venueupgraderevisions "$2"; logout;; "venueupgraderevisions") login; venueupgraderevisions "$2"; logout;;
"getsystemconfiguration") login; getsystemconfiguration "$2"; logout;; "getsystemconfiguration") login; getsystemconfiguration "$2"; logout;;
"creategraccount") login; creategraccount ; logout;;
"getgraccount") login; getgraccount "$2"; logout;;
"getgraccounts") login; getgraccounts ; logout;;
"creategrcert") login; creategrcert "$2" "$3"; logout;;
"deletegraccount") login; deletegraccount "$2"; logout;;
"getvenuesperrrm") login; getvenuesperrrm "$2"; logout;;
*) help ;; *) help ;;
esac esac