mirror of
https://github.com/Telecominfraproject/wlan-cloud-ucentralgw.git
synced 2025-11-02 11:47:47 +00:00
Compare commits
246 Commits
v2.1.0-RC2
...
release/v2
Author | SHA1 | Date | |
---|---|---|---|
![]() |
079b9f77a1 | ||
![]() |
124f941a10 | ||
![]() |
fa6a00cf99 | ||
![]() |
e58fa4b0fb | ||
![]() |
645f484d1d | ||
![]() |
1e0f43bd4b | ||
![]() |
09a1e5d429 | ||
![]() |
a0beee77aa | ||
![]() |
04c221784b | ||
![]() |
544d6babe5 | ||
![]() |
5d16414bb2 | ||
![]() |
925a48929f | ||
![]() |
816bc9c799 | ||
![]() |
7f0148a33d | ||
![]() |
e2f07d6d05 | ||
![]() |
c708ffd23a | ||
![]() |
9db5b5f39a | ||
![]() |
e47feab9ad | ||
![]() |
f673cdc1ba | ||
![]() |
4fa59fdfd2 | ||
![]() |
1d6bafa75a | ||
![]() |
aa0a9aabce | ||
![]() |
2a0b45fde1 | ||
![]() |
816f0a6e7c | ||
![]() |
02e8c59052 | ||
![]() |
b26509c8b7 | ||
![]() |
cd3b663f0a | ||
![]() |
9172ec6532 | ||
![]() |
eab9557f51 | ||
![]() |
ee1d0fbde9 | ||
![]() |
352e4c3857 | ||
![]() |
80cf939503 | ||
![]() |
60c0d83a95 | ||
![]() |
1de5d2902d | ||
![]() |
62e5060204 | ||
![]() |
e317f1c0e2 | ||
![]() |
e87d9efd09 | ||
![]() |
a92601b285 | ||
![]() |
6fa7165171 | ||
![]() |
7703955b0e | ||
![]() |
20bfda45bc | ||
![]() |
53d914f58a | ||
![]() |
b91ddf5272 | ||
![]() |
621b1953d9 | ||
![]() |
63d78d5c14 | ||
![]() |
e32bf08ef8 | ||
![]() |
bc7d291262 | ||
![]() |
28e1da2f08 | ||
![]() |
f7d6487306 | ||
![]() |
b8448355db | ||
![]() |
b26dd1b709 | ||
![]() |
7eed435e68 | ||
![]() |
29ddc81814 | ||
![]() |
6dd1ee63a0 | ||
![]() |
a28904ba62 | ||
![]() |
bc4bcd7a5c | ||
![]() |
01cc10bd63 | ||
![]() |
2961b7bb42 | ||
![]() |
ee2df31e51 | ||
![]() |
2717ed9d23 | ||
![]() |
942e99cf41 | ||
![]() |
7340abf40e | ||
![]() |
1d1d744d67 | ||
![]() |
8656cac16e | ||
![]() |
d9552b3971 | ||
![]() |
1685224cba | ||
![]() |
1ab94d0b78 | ||
![]() |
35cc18b1dc | ||
![]() |
35fbf1d5ca | ||
![]() |
d29876f948 | ||
![]() |
d8b4d4a173 | ||
![]() |
ff577f2aa3 | ||
![]() |
6b871a27e2 | ||
![]() |
b4b2707f3f | ||
![]() |
153477b649 | ||
![]() |
f73389af3c | ||
![]() |
eb361cad14 | ||
![]() |
0e7dcf88a3 | ||
![]() |
7726c8b346 | ||
![]() |
b3a0593f8e | ||
![]() |
cd047f8d38 | ||
![]() |
96b09eacc3 | ||
![]() |
cafb26e13d | ||
![]() |
007d034a54 | ||
![]() |
6d578193b6 | ||
![]() |
0d63f9882d | ||
![]() |
1ea2542a00 | ||
![]() |
87054cfaa3 | ||
![]() |
b4fd04ef9c | ||
![]() |
0e1bd681d8 | ||
![]() |
3919c95250 | ||
![]() |
e85e00a5db | ||
![]() |
1ef2a62b06 | ||
![]() |
95ce12fabc | ||
![]() |
408183eada | ||
![]() |
b7d42c76dc | ||
![]() |
7ee0aa57a9 | ||
![]() |
51dd6dbc13 | ||
![]() |
7f4e6303c7 | ||
![]() |
3b59a36012 | ||
![]() |
3ca43225ae | ||
![]() |
119638f108 | ||
![]() |
dd8265c1c7 | ||
![]() |
f2f413dbfe | ||
![]() |
271d97e152 | ||
![]() |
cda780bbca | ||
![]() |
a739f1e48c | ||
![]() |
7881e4297b | ||
![]() |
0fa0af3159 | ||
![]() |
3ea4e5a641 | ||
![]() |
75fda33eaf | ||
![]() |
1d9e30ab0f | ||
![]() |
771ea62a3e | ||
![]() |
c89bee14c0 | ||
![]() |
f9e52526b4 | ||
![]() |
ed7ecc0eff | ||
![]() |
79128169c2 | ||
![]() |
557538e30d | ||
![]() |
5d5bdd99d8 | ||
![]() |
d1b2524632 | ||
![]() |
2eb3238cdc | ||
![]() |
b7bc615d05 | ||
![]() |
222f7df0e4 | ||
![]() |
c93459bf18 | ||
![]() |
8d2173a046 | ||
![]() |
efd8b81625 | ||
![]() |
24163b5fce | ||
![]() |
f50ce2f816 | ||
![]() |
cc4ba61c15 | ||
![]() |
bbc0255ad4 | ||
![]() |
1e0628abf4 | ||
![]() |
5d8e9355b1 | ||
![]() |
3eaedf4752 | ||
![]() |
da38f204b6 | ||
![]() |
ab29614b99 | ||
![]() |
881015331c | ||
![]() |
16ce257dc5 | ||
![]() |
8b63e5a873 | ||
![]() |
3b690b1878 | ||
![]() |
c9157f1df4 | ||
![]() |
d5f6c7a976 | ||
![]() |
c9528b7c1d | ||
![]() |
cf1b5c019f | ||
![]() |
ee075fff67 | ||
![]() |
348f30a05f | ||
![]() |
c0930929d9 | ||
![]() |
cbd2b3ccb9 | ||
![]() |
c53d98282a | ||
![]() |
871063e029 | ||
![]() |
94c6f89f4a | ||
![]() |
24f1561847 | ||
![]() |
61472453a1 | ||
![]() |
4031c94fb9 | ||
![]() |
25079004b8 | ||
![]() |
61f89fb005 | ||
![]() |
5b51a097b2 | ||
![]() |
417b82ce70 | ||
![]() |
6ca66e313f | ||
![]() |
45a7d5066e | ||
![]() |
000a01ab09 | ||
![]() |
fca3fcf6a8 | ||
![]() |
f3ff04c185 | ||
![]() |
5d96d5f572 | ||
![]() |
7fc45c160e | ||
![]() |
83c1bb305b | ||
![]() |
63ac9d2c72 | ||
![]() |
0ee5c56d33 | ||
![]() |
f6cd8bd73e | ||
![]() |
d49b89b775 | ||
![]() |
7183767a50 | ||
![]() |
b38c657a27 | ||
![]() |
2ea8fdf57f | ||
![]() |
b8d5b86b3e | ||
![]() |
0aa5837ea2 | ||
![]() |
187f1669cf | ||
![]() |
faebf38a3f | ||
![]() |
488d5d0a24 | ||
![]() |
461094d883 | ||
![]() |
bf00fa34f4 | ||
![]() |
2d283ffd32 | ||
![]() |
5ec8523b46 | ||
![]() |
a78c2f6961 | ||
![]() |
14f2ea79e1 | ||
![]() |
fcb3f2efbc | ||
![]() |
2061a3a699 | ||
![]() |
8e4c528da5 | ||
![]() |
8277f8dd92 | ||
![]() |
6a1f844631 | ||
![]() |
0ba02f1c70 | ||
![]() |
79e0304841 | ||
![]() |
5fa7a2d766 | ||
![]() |
1d1caa7270 | ||
![]() |
d740167972 | ||
![]() |
bf93257343 | ||
![]() |
2286a9063f | ||
![]() |
1e35473b82 | ||
![]() |
17f0dc4de9 | ||
![]() |
8c21b86d5c | ||
![]() |
f6780d545d | ||
![]() |
6a63a252d5 | ||
![]() |
51f8bd7342 | ||
![]() |
c0d199a12e | ||
![]() |
06a997c6cb | ||
![]() |
c2ead350aa | ||
![]() |
9941b9a15c | ||
![]() |
ef58d30ae3 | ||
![]() |
aa6e4e6350 | ||
![]() |
6e03253aac | ||
![]() |
79c37e3e71 | ||
![]() |
44fca56806 | ||
![]() |
7d0571269a | ||
![]() |
0734e93b7c | ||
![]() |
5986d34e24 | ||
![]() |
0edd85e991 | ||
![]() |
1d4995641b | ||
![]() |
3be56ada41 | ||
![]() |
a1160f7de5 | ||
![]() |
17971d1dd0 | ||
![]() |
7a762ab3f2 | ||
![]() |
1a9ddd2df9 | ||
![]() |
f3ae6de093 | ||
![]() |
219e8fc59e | ||
![]() |
389fcb9f3b | ||
![]() |
e40abd2a91 | ||
![]() |
ee11dc8d91 | ||
![]() |
a9ec2e7821 | ||
![]() |
b6b1c99c86 | ||
![]() |
31f96968b2 | ||
![]() |
1e845a6ff2 | ||
![]() |
0e9ddee588 | ||
![]() |
6e167372b5 | ||
![]() |
1e1f0c37e9 | ||
![]() |
4cf10b0f3a | ||
![]() |
314fef87e2 | ||
![]() |
e4e2075021 | ||
![]() |
314ae21d6a | ||
![]() |
8ad0da5781 | ||
![]() |
935cc78bb4 | ||
![]() |
5bc7508d96 | ||
![]() |
498e8f880c | ||
![]() |
e9e5d8be41 | ||
![]() |
319e8918b1 | ||
![]() |
0d6471acae | ||
![]() |
41a04c9108 | ||
![]() |
95cc17bb16 | ||
![]() |
9f9e1b4cdb |
19
.github/workflows/ci.yml
vendored
19
.github/workflows/ci.yml
vendored
@@ -28,7 +28,7 @@ jobs:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Build Docker image
|
||||
run: docker build -t wlan-cloud-ucentralgw:${{ github.sha }} .
|
||||
run: docker build -t wlan-cloud-owgw:${{ github.sha }} .
|
||||
|
||||
- name: Tag Docker image
|
||||
run: |
|
||||
@@ -52,7 +52,7 @@ jobs:
|
||||
echo "Result tags: $TAGS"
|
||||
|
||||
for tag in $TAGS; do
|
||||
docker tag wlan-cloud-ucentralgw:${{ github.sha }} ${{ env.DOCKER_REGISTRY_URL }}/ucentralgw:$tag
|
||||
docker tag wlan-cloud-owgw:${{ github.sha }} ${{ env.DOCKER_REGISTRY_URL }}/owgw:$tag
|
||||
done
|
||||
|
||||
- name: Log into Docker registry
|
||||
@@ -66,7 +66,7 @@ jobs:
|
||||
- name: Push Docker images
|
||||
if: startsWith(github.ref, 'refs/tags/') || startsWith(github.ref, 'refs/pull/') || github.ref == 'refs/heads/master'
|
||||
run: |
|
||||
docker images | grep ${{ env.DOCKER_REGISTRY_URL }}/ucentralgw | awk -F ' ' '{print $1":"$2}' | xargs -I {} docker push {}
|
||||
docker images | grep ${{ env.DOCKER_REGISTRY_URL }}/owgw | awk -F ' ' '{print $1":"$2}' | xargs -I {} docker push {}
|
||||
|
||||
docker-compose:
|
||||
if: startsWith(github.ref, 'refs/tags/') || startsWith(github.ref, 'refs/pull/') || github.ref == 'refs/heads/master'
|
||||
@@ -82,11 +82,11 @@ jobs:
|
||||
- name: Instantiate Docker Compose deployment
|
||||
working-directory: ./wlan-cloud-ucentral-deploy/docker-compose
|
||||
env:
|
||||
UCENTRALGW_TAG: ${{ github.sha }}
|
||||
OWGW_TAG: ${{ github.sha }}
|
||||
run: |
|
||||
docker-compose up -d
|
||||
|
||||
- name: Wait for uCentralSec to be alive and kicking
|
||||
- name: Wait for OWSec to be alive and kicking
|
||||
run: |
|
||||
n=0
|
||||
until [ "$n" -ge 3 ]
|
||||
@@ -100,11 +100,6 @@ jobs:
|
||||
fi
|
||||
done
|
||||
|
||||
- name: Add self-signed certificates to system trust store of containers
|
||||
working-directory: ./wlan-cloud-ucentral-deploy/docker-compose
|
||||
run: |
|
||||
./add-ca-cert.sh
|
||||
|
||||
- name: Check out wlan-cloud-ucentralgw repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
@@ -112,8 +107,8 @@ jobs:
|
||||
|
||||
- name: Check functionality of microservices
|
||||
env:
|
||||
UCENTRALSEC: "ucentral.wlan.local:16001"
|
||||
FLAGS: "-s --cacert ./wlan-cloud-ucentral-deploy/docker-compose/certs/restapi-ca.pem --resolve ucentral.wlan.local:16001:127.0.0.1"
|
||||
OWSEC: "openwifi.wlan.local:16001"
|
||||
FLAGS: "-s --cacert ./wlan-cloud-ucentral-deploy/docker-compose/certs/restapi-ca.pem --resolve openwifi.wlan.local:16001:127.0.0.1"
|
||||
run: |
|
||||
./wlan-cloud-ucentralgw/test_scripts/curl/cli listdevices
|
||||
|
||||
|
2
.github/workflows/cleanup.yml
vendored
2
.github/workflows/cleanup.yml
vendored
@@ -17,4 +17,4 @@ jobs:
|
||||
- name: Cleanup Docker image with PR branch tag
|
||||
run: |
|
||||
export PR_BRANCH_TAG=$(echo ${GITHUB_HEAD_REF#refs/heads/} | tr '/' '-')
|
||||
curl -uucentral:${{ secrets.DOCKER_REGISTRY_PASSWORD }} -X DELETE "https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral/ucentralgw/$PR_BRANCH_TAG"
|
||||
curl -uucentral:${{ secrets.DOCKER_REGISTRY_PASSWORD }} -X DELETE "https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral/owgw/$PR_BRANCH_TAG"
|
||||
|
@@ -82,6 +82,9 @@ Do wifiscan for a device.
|
||||
- `serial`: device serial number
|
||||
- `verbose`: verbose=true/false
|
||||
|
||||
### telemetry <serial>
|
||||
Start `telemetry` stream for a device.
|
||||
|
||||
### trace <serial> <duration> <network>
|
||||
Launch a remote trace for a device.
|
||||
- `serial`: device serial number
|
||||
@@ -161,12 +164,23 @@ Get a list of devices based on a list.
|
||||
### deviceswithstatus
|
||||
Get devices with their status.
|
||||
|
||||
### setloglevel <sys> <level>
|
||||
Set the logging system level for individual subsystems.
|
||||
- `sys`: ufileuploader/websocket/storage/restapi/commandmanager/auth/deviceregistry/all
|
||||
- `level`: level:none/fatal/critical/error/warning/notice/information/debug/trace
|
||||
### setloglevel <subsystem> <loglevel>
|
||||
Set the log level for s specific subsystem.
|
||||
|
||||
### getfile <uuid>
|
||||
### getloglevels
|
||||
Get the current log levels for all subsystems.
|
||||
|
||||
### getloglevelnames
|
||||
Get the log level names available.
|
||||
|
||||
### getsubsystemnames
|
||||
Get the list of subsystems.
|
||||
|
||||
### systeminfo
|
||||
Get basic system information.
|
||||
|
||||
### reloadsubsystem <subsystem name>
|
||||
Reload the configuration for a subsystem.### getfile <uuid>
|
||||
Get the file associated with trace command <uuid>.
|
||||
- `uuid`: UUID of file to retrieve
|
||||
|
116
CMakeLists.txt
116
CMakeLists.txt
@@ -1,5 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
project(ucentralgw VERSION 2.1.0)
|
||||
project(owgw VERSION 2.3.0)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
@@ -38,6 +38,8 @@ set(Boost_USE_STATIC_RUNTIME OFF)
|
||||
find_package(Boost REQUIRED system)
|
||||
find_package(OpenSSL REQUIRED)
|
||||
find_package(ZLIB REQUIRED)
|
||||
find_package(nlohmann_json REQUIRED)
|
||||
find_package(nlohmann_json_schema_validator REQUIRED)
|
||||
|
||||
if(SMALL_BUILD)
|
||||
find_package(Poco REQUIRED COMPONENTS Crypto JWT Net Util NetSSL Data DataSQLite)
|
||||
@@ -50,69 +52,77 @@ endif()
|
||||
|
||||
include_directories(/usr/local/include /usr/local/opt/openssl/include src include/kafka /usr/local/opt/mysql-client/include)
|
||||
|
||||
add_executable( ucentralgw
|
||||
build
|
||||
src/Daemon.cpp src/Daemon.h
|
||||
src/RESTAPI_server.cpp src/RESTAPI_server.h
|
||||
src/WebSocketServer.cpp src/WebSocketServer.h
|
||||
src/SubSystemServer.cpp src/SubSystemServer.h
|
||||
src/StorageService.cpp src/StorageService.h
|
||||
src/RESTAPI_SecurityObjects.cpp src/RESTAPI_SecurityObjects.h
|
||||
src/DeviceRegistry.cpp src/DeviceRegistry.h
|
||||
src/RESTAPI_devices_handler.cpp src/RESTAPI_devices_handler.h
|
||||
src/RESTAPI_device_handler.cpp src/RESTAPI_device_handler.h
|
||||
src/RESTAPI_handler.cpp src/RESTAPI_handler.h
|
||||
src/RESTAPI_device_commandHandler.cpp src/RESTAPI_device_commandHandler.h
|
||||
src/RESTAPI_GWobjects.h src/RESTAPI_GWobjects.cpp
|
||||
src/CentralConfig.cpp src/CentralConfig.h
|
||||
src/RESTAPI_default_configuration.cpp
|
||||
src/RESTAPI_InternalServer.cpp src/RESTAPI_InternalServer.h
|
||||
src/RESTAPI_default_configuration.h src/RESTAPI_default_configurations.cpp src/RESTAPI_default_configurations.h
|
||||
src/RESTAPI_commands.cpp src/RESTAPI_commands.h
|
||||
src/CommandManager.cpp src/CommandManager.h
|
||||
src/RESTAPI_command.cpp src/RESTAPI_command.h
|
||||
src/FileUploader.cpp src/FileUploader.h
|
||||
src/RESTAPI_file.cpp src/RESTAPI_file.h
|
||||
src/RESTAPI_system_command.cpp src/RESTAPI_system_command.h
|
||||
src/RESTAPI_BlackList.cpp src/RESTAPI_BlackList.h
|
||||
src/Utils.h src/Utils.cpp src/storage_blacklist.cpp
|
||||
src/storage_command.cpp src/storage_healthcheck.cpp src/storage_statistics.cpp src/storage_logs.cpp
|
||||
src/storage_device.cpp src/storage_capabilities.cpp src/storage_defconfig.cpp
|
||||
src/storage_tables.cpp
|
||||
src/storage_setup.cpp
|
||||
src/StateProcessor.cpp src/StateProcessor.h
|
||||
src/storage_lifetime_stats.cpp src/uCentralProtocol.h src/RESTAPI_protocol.h
|
||||
src/ALBHealthCheckServer.h src/Kafka_topics.h
|
||||
src/OUIServer.cpp src/OUIServer.h
|
||||
src/RESTAPI_ouis.cpp src/RESTAPI_ouis.h
|
||||
src/MicroService.cpp src/MicroService.h
|
||||
src/RESTAPI_RPC.cpp src/RESTAPI_RPC.h
|
||||
src/AuthClient.cpp src/AuthClient.h
|
||||
src/OpenAPIRequest.cpp src/OpenAPIRequest.h
|
||||
src/RESTAPI_utils.h src/RESTAPI_utils.cpp
|
||||
src/StorageArchiver.cpp src/StorageArchiver.h
|
||||
src/Dashboard.cpp src/Dashboard.h
|
||||
src/RESTAPI_deviceDashboardHandler.cpp src/RESTAPI_deviceDashboardHandler.h
|
||||
src/SerialNumberCache.cpp src/SerialNumberCache.h
|
||||
src/RESTAPI_webSocketServer.cpp src/RESTAPI_webSocketServer.h
|
||||
src/OpenWifiTypes.h)
|
||||
add_executable( owgw
|
||||
build
|
||||
src/framework/CountryCodes.h
|
||||
src/framework/KafkaTopics.h
|
||||
src/framework/MicroService.h
|
||||
src/framework/OpenWifiTypes.h
|
||||
src/framework/orm.h
|
||||
src/framework/RESTAPI_errors.h
|
||||
src/framework/RESTAPI_protocol.h
|
||||
src/framework/StorageClass.h
|
||||
src/framework/uCentral_Protocol.h
|
||||
src/RESTObjects/RESTAPI_SecurityObjects.h src/RESTObjects/RESTAPI_SecurityObjects.cpp
|
||||
src/RESTObjects/RESTAPI_ProvObjects.cpp src/RESTObjects/RESTAPI_ProvObjects.h
|
||||
src/RESTObjects/RESTAPI_GWobjects.h src/RESTObjects/RESTAPI_GWobjects.cpp
|
||||
src/RESTObjects/RESTAPI_FMSObjects.h src/RESTObjects/RESTAPI_FMSObjects.cpp
|
||||
src/RESTAPI/RESTAPI_devices_handler.cpp src/RESTAPI/RESTAPI_devices_handler.h
|
||||
src/RESTAPI/RESTAPI_device_handler.cpp src/RESTAPI/RESTAPI_device_handler.h
|
||||
src/RESTAPI/RESTAPI_device_commandHandler.cpp src/RESTAPI/RESTAPI_device_commandHandler.h
|
||||
src/RESTAPI/RESTAPI_default_configuration.cpp
|
||||
src/RESTAPI/RESTAPI_default_configuration.h src/RESTAPI/RESTAPI_default_configurations.cpp src/RESTAPI/RESTAPI_default_configurations.h
|
||||
src/RESTAPI/RESTAPI_commands.cpp src/RESTAPI/RESTAPI_commands.h
|
||||
src/RESTAPI/RESTAPI_command.cpp src/RESTAPI/RESTAPI_command.h
|
||||
src/RESTAPI/RESTAPI_file.cpp src/RESTAPI/RESTAPI_file.h
|
||||
src/RESTAPI/RESTAPI_blacklist.cpp src/RESTAPI/RESTAPI_blacklist.h
|
||||
src/RESTAPI/RESTAPI_ouis.cpp src/RESTAPI/RESTAPI_ouis.h
|
||||
src/RESTAPI/RESTAPI_blacklist_list.cpp src/RESTAPI/RESTAPI_blacklist_list.h
|
||||
src/RESTAPI/RESTAPI_capabilities_handler.cpp src/RESTAPI/RESTAPI_capabilities_handler.h
|
||||
src/RESTAPI/RESTAPI_RPC.cpp src/RESTAPI/RESTAPI_RPC.h
|
||||
src/RESTAPI/RESTAPI_deviceDashboardHandler.cpp src/RESTAPI/RESTAPI_deviceDashboardHandler.h
|
||||
src/RESTAPI/RESTAPI_TelemetryWebSocket.cpp src/RESTAPI/RESTAPI_TelemetryWebSocket.h
|
||||
src/RESTAPI/RESTAPI_webSocketServer.cpp src/RESTAPI/RESTAPI_webSocketServer.h
|
||||
src/storage/storage_blacklist.cpp src/storage/storage_tables.cpp src/storage/storage_logs.cpp
|
||||
src/storage/storage_command.cpp src/storage/storage_healthcheck.cpp src/storage/storage_statistics.cpp
|
||||
src/storage/storage_device.cpp src/storage/storage_capabilities.cpp src/storage/storage_defconfig.cpp
|
||||
src/storage/storage_tables.cpp
|
||||
src/APIServers.cpp
|
||||
src/Daemon.cpp src/Daemon.h
|
||||
src/StateProcessor.cpp src/StateProcessor.h
|
||||
src/storage/storage_lifetime_stats.cpp
|
||||
src/WebSocketServer.cpp src/WebSocketServer.h
|
||||
src/StorageService.cpp src/StorageService.h
|
||||
src/DeviceRegistry.cpp src/DeviceRegistry.h
|
||||
src/CommandManager.cpp src/CommandManager.h
|
||||
src/CentralConfig.cpp src/CentralConfig.h
|
||||
src/FileUploader.cpp src/FileUploader.h
|
||||
src/OUIServer.cpp src/OUIServer.h
|
||||
src/StorageArchiver.cpp src/StorageArchiver.h
|
||||
src/Dashboard.cpp src/Dashboard.h
|
||||
src/SerialNumberCache.cpp src/SerialNumberCache.h
|
||||
src/TelemetryStream.cpp src/TelemetryStream.h
|
||||
src/ConfigurationValidator.cpp src/ConfigurationValidator.h
|
||||
src/ConfigurationCache.cpp src/ConfigurationCache.h
|
||||
)
|
||||
|
||||
if(NOT SMALL_BUILD)
|
||||
target_sources(ucentralgw PUBLIC src/KafkaManager.cpp src/KafkaManager.h)
|
||||
|
||||
endif()
|
||||
|
||||
INSTALL(TARGETS ucentralgw
|
||||
INSTALL(TARGETS owgw
|
||||
RUNTIME DESTINATION /usr/bin
|
||||
)
|
||||
|
||||
target_link_libraries(ucentralgw PUBLIC
|
||||
target_link_libraries(owgw PUBLIC
|
||||
${Poco_LIBRARIES} ${Boost_LIBRARIES} ${ZLIB_LIBRARIES})
|
||||
if(NOT SMALL_BUILD)
|
||||
target_link_libraries(ucentralgw PUBLIC
|
||||
target_link_libraries(owgw PUBLIC
|
||||
${MySQL_LIBRARIES} ${ZLIB_LIBRARIES}
|
||||
CppKafka::cppkafka
|
||||
CppKafka::cppkafka
|
||||
nlohmann_json_schema_validator
|
||||
)
|
||||
if(UNIX AND NOT APPLE)
|
||||
target_link_libraries(ucentralgw PUBLIC PocoJSON)
|
||||
target_link_libraries(owgw PUBLIC PocoJSON)
|
||||
endif()
|
||||
endif()
|
51
Dockerfile
51
Dockerfile
@@ -7,10 +7,12 @@ RUN apk add --update --no-cache \
|
||||
make cmake gcc g++ libstdc++ libgcc git zlib-dev yaml-cpp-dev \
|
||||
openssl-dev boost-dev unixodbc-dev postgresql-dev mariadb-dev \
|
||||
apache2-utils yaml-dev apr-util-dev \
|
||||
lua-dev librdkafka-dev
|
||||
lua-dev librdkafka-dev \
|
||||
nlohmann-json
|
||||
|
||||
RUN git clone https://github.com/stephb9959/poco /poco
|
||||
RUN git clone https://github.com/stephb9959/cppkafka /cppkafka
|
||||
RUN git clone https://github.com/pboettch/json-schema-validator /json-schema-validator
|
||||
|
||||
WORKDIR /cppkafka
|
||||
RUN mkdir cmake-build
|
||||
@@ -26,36 +28,49 @@ RUN cmake ..
|
||||
RUN cmake --build . --config Release -j8
|
||||
RUN cmake --build . --target install
|
||||
|
||||
ADD CMakeLists.txt build /ucentralgw/
|
||||
ADD cmake /ucentralgw/cmake
|
||||
ADD src /ucentralgw/src
|
||||
|
||||
WORKDIR /ucentralgw
|
||||
WORKDIR /json-schema-validator
|
||||
RUN mkdir cmake-build
|
||||
WORKDIR /ucentralgw/cmake-build
|
||||
WORKDIR cmake-build
|
||||
RUN cmake ..
|
||||
RUN make
|
||||
RUN make install
|
||||
|
||||
ADD CMakeLists.txt build /owgw/
|
||||
ADD cmake /owgw/cmake
|
||||
ADD src /owgw/src
|
||||
|
||||
WORKDIR /owgw
|
||||
RUN mkdir cmake-build
|
||||
WORKDIR /owgw/cmake-build
|
||||
RUN cmake ..
|
||||
RUN cmake --build . --config Release -j8
|
||||
|
||||
FROM alpine
|
||||
|
||||
ENV UCENTRALGW_USER=ucentralgw \
|
||||
UCENTRALGW_ROOT=/ucentralgw-data \
|
||||
UCENTRALGW_CONFIG=/ucentralgw-data
|
||||
ENV OWGW_USER=owgw \
|
||||
OWGW_ROOT=/owgw-data \
|
||||
OWGW_CONFIG=/owgw-data
|
||||
|
||||
RUN addgroup -S "$UCENTRALGW_USER" && \
|
||||
adduser -S -G "$UCENTRALGW_USER" "$UCENTRALGW_USER"
|
||||
RUN addgroup -S "$OWGW_USER" && \
|
||||
adduser -S -G "$OWGW_USER" "$OWGW_USER"
|
||||
|
||||
RUN mkdir /ucentral
|
||||
RUN mkdir -p "$UCENTRALGW_ROOT" "$UCENTRALGW_CONFIG" && \
|
||||
chown "$UCENTRALGW_USER": "$UCENTRALGW_ROOT" "$UCENTRALGW_CONFIG"
|
||||
RUN apk add --update --no-cache librdkafka mariadb-connector-c libpq unixodbc su-exec
|
||||
RUN mkdir /openwifi
|
||||
RUN mkdir -p "$OWGW_ROOT" "$OWGW_CONFIG" && \
|
||||
chown "$OWGW_USER": "$OWGW_ROOT" "$OWGW_CONFIG"
|
||||
RUN apk add --update --no-cache librdkafka mariadb-connector-c libpq unixodbc su-exec gettext ca-certificates bash jq curl
|
||||
|
||||
COPY --from=builder /ucentralgw/cmake-build/ucentralgw /ucentral/ucentralgw
|
||||
COPY --from=builder /owgw/cmake-build/owgw /openwifi/owgw
|
||||
COPY --from=builder /cppkafka/cmake-build/src/lib/* /lib/
|
||||
COPY --from=builder /poco/cmake-build/lib/* /lib/
|
||||
|
||||
COPY owgw.properties.tmpl /
|
||||
COPY docker-entrypoint.sh /
|
||||
RUN wget https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentral-deploy/main/docker-compose/certs/restapi-ca.pem \
|
||||
-O /usr/local/share/ca-certificates/restapi-ca-selfsigned.pem
|
||||
|
||||
COPY readiness_check /readiness_check
|
||||
|
||||
EXPOSE 15002 16002 16003 17002 16102
|
||||
|
||||
ENTRYPOINT ["/docker-entrypoint.sh"]
|
||||
CMD ["/ucentral/ucentralgw"]
|
||||
CMD ["/openwifi/owgw"]
|
||||
|
@@ -2,7 +2,7 @@
|
||||
This document will describe how the API is built and how to use it.
|
||||
|
||||
## Where is the OpenAPI.
|
||||
This uses OpenAPI definition 3.0 and can be found [here](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/main/openapi/ucentral/ucentral.yaml).
|
||||
This uses OpenAPI definition 3.0 and can be found [here](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/main/openapi/ucentral/owgw.yaml).
|
||||
All endpoints begin with `/api/v1`.
|
||||
|
||||
## The flow
|
||||
|
58
PROTOCOL.md
58
PROTOCOL.md
@@ -155,6 +155,22 @@ which version it is running. The Controller may decide to send the device a newe
|
||||
}
|
||||
```
|
||||
|
||||
#### Recovery Event
|
||||
Device may decide it has to do into recovery mode. This event should be used.
|
||||
```
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "recovery" ,
|
||||
"params" : {
|
||||
"serial" : <serial number> ,
|
||||
"uuid" : <the UUID of the configuration that generated the crash log>,
|
||||
"firmware: <the string describing the current firmware>,
|
||||
"reboot" : true/false (shoudld the device be instructed to reboot after loggin the information),
|
||||
"loglines" : [ an array of strings representing the logs from the log file ]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Controller commands
|
||||
Most controller commands include a `when` member. This is a UTC clock time asking the AP
|
||||
to perform the command at that time. This is a suggestion only. The AP may ignore this
|
||||
@@ -518,6 +534,48 @@ The device should answer:
|
||||
}
|
||||
```
|
||||
|
||||
#### Controller requesting telemetry stream information
|
||||
Controller sends this command when it needs the device to telemetry streaming.
|
||||
```
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "telemetry" ,
|
||||
"params" : {
|
||||
"serial" : <serial number> ,
|
||||
"interval" : 0-60, # number of seconds for polling information. 0 means to shutdown the stream
|
||||
"types" : [ "dhcp", "rrm"], <this must be an array: array of 1 or 2 elements, right now only "rrm" and "dhcp" are supported
|
||||
},
|
||||
"id" : <some number>
|
||||
}
|
||||
```
|
||||
|
||||
The device should answer:
|
||||
```
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"result" : {
|
||||
"serial" : <serial number> ,
|
||||
"status" : {
|
||||
"error" : 0 or an error number,
|
||||
"text" : <description of the error or success>
|
||||
}
|
||||
},
|
||||
"id" : <same number>
|
||||
}
|
||||
```
|
||||
|
||||
When the interval is greater than 0, the gateway will start to receive messages
|
||||
```
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "telemetry" ,
|
||||
"params" : {
|
||||
"serial" : <serial number> ,
|
||||
"data" : <A JSON document describing the information coming from the device>
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The device will stop sending data after 30 minutes or if it receives a `telemetry` command with an interval of 0.
|
||||
|
||||
|
||||
#### Controller requesting an `rtty` session
|
||||
Controller sends this command an administrator requests to start an `rtty` session with the AP.
|
||||
```
|
||||
|
112
README.md
112
README.md
@@ -179,7 +179,7 @@ You should now have the following:
|
||||
+-- test_scripts
|
||||
+-- openapi
|
||||
+-- uploads
|
||||
+-- ucentralgw.properties
|
||||
+-- owgw.properties
|
||||
```
|
||||
|
||||
### Certificates
|
||||
@@ -218,14 +218,14 @@ document. Once you have these files, you need to renamed them `restapi-key.pem`,
|
||||
in your browner
|
||||
|
||||
#### Configuration
|
||||
The configuration for this service is kept in a properties file. This file is called `ucentralgw.properties` and you can
|
||||
see the latest version [here](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/main/ucentralgw.properties). The file will be loaded from
|
||||
The configuration for this service is kept in a properties file. This file is called `owgw.properties` and you can
|
||||
see the latest version [here](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/main/owgw.properties). The file will be loaded from
|
||||
the directory set by the environment variable `UCENTRALGW_CONFIG`. To use environment variables in the configuration,
|
||||
you must use `$<varname>`. Only `path names` support the use of environment variables. The sample configuration requires very
|
||||
little changes if you keep the suggested directory structure. For the sample configuration to work, you need to define 2
|
||||
environment variables.
|
||||
```
|
||||
export UCENTRALGW_ROOT=`pwd`
|
||||
export OWGW_ROOT=`pwd`
|
||||
export UCENTRALGW_CONFIG=`pwd`
|
||||
```
|
||||
If you current working directory is the root of the project, this will set the variables properly. Otherwise, you can set the variables
|
||||
@@ -234,7 +234,7 @@ to point to wherever is necessary.
|
||||
##### Important config entries
|
||||
###### This is the logging directory
|
||||
```
|
||||
logging.channels.c2.path = $UCENTRALGW_ROOT/logs/sample.log
|
||||
logging.channels.c2.path = $OWGW_ROOT/logs/sample.log
|
||||
```
|
||||
|
||||
###### This is the type of storage in use
|
||||
@@ -244,23 +244,23 @@ storage.type = sqlite
|
||||
|
||||
###### Autoprovisioning settings
|
||||
```asm
|
||||
ucentral.autoprovisioning = true
|
||||
ucentral.devicetypes.0 = AP:linksys_ea8300,edgecore_eap101,linksys_e8450-ubi
|
||||
ucentral.devicetypes.1 = SWITCH:edgecore_ecs4100-12ph
|
||||
ucentral.devicetypes.2 = IOT:esp32
|
||||
openwifi.autoprovisioning = true
|
||||
openwifi.devicetypes.0 = AP:linksys_ea8300,edgecore_eap101,linksys_e8450-ubi
|
||||
openwifi.devicetypes.1 = SWITCH:edgecore_ecs4100-12ph
|
||||
openwifi.devicetypes.2 = IOT:esp32
|
||||
```
|
||||
|
||||
###### This is the RESTAPI endpoint
|
||||
|
||||
```asm
|
||||
ucentral.restapi.host.0.backlog = 100
|
||||
ucentral.restapi.host.0.security = relaxed
|
||||
ucentral.restapi.host.0.rootca = $UCENTRALGW_ROOT/certs/restapi-ca.pem
|
||||
ucentral.restapi.host.0.address = *
|
||||
ucentral.restapi.host.0.port = 16002
|
||||
ucentral.restapi.host.0.cert = $UCENTRALGW_ROOT/certs/restapi-cert.pem
|
||||
ucentral.restapi.host.0.key = $UCENTRALGW_ROOT/certs/restapi-key.pem
|
||||
ucentral.restapi.host.0.key.password = mypassword
|
||||
openwifi.restapi.host.0.backlog = 100
|
||||
openwifi.restapi.host.0.security = relaxed
|
||||
openwifi.restapi.host.0.rootca = $OWGW_ROOT/certs/restapi-ca.pem
|
||||
openwifi.restapi.host.0.address = *
|
||||
openwifi.restapi.host.0.port = 16002
|
||||
openwifi.restapi.host.0.cert = $OWGW_ROOT/certs/restapi-cert.pem
|
||||
openwifi.restapi.host.0.key = $OWGW_ROOT/certs/restapi-key.pem
|
||||
openwifi.restapi.host.0.key.password = mypassword
|
||||
```
|
||||
|
||||
##### This is the end point for the devices to connect with
|
||||
@@ -309,12 +309,12 @@ You will need to get the `cert.pem` and `key.pem` from Digicert. The rest is her
|
||||
|
||||
```asm
|
||||
ucentral.websocket.host.0.backlog = 500
|
||||
ucentral.websocket.host.0.rootca = $UCENTRALGW_ROOT/certs/root.pem
|
||||
ucentral.websocket.host.0.issuer = $UCENTRALGW_ROOT/certs/issuer.pem
|
||||
ucentral.websocket.host.0.cert = $UCENTRALGW_ROOT/certs/websocket-cert.pem
|
||||
ucentral.websocket.host.0.key = $UCENTRALGW_ROOT/certs/websocket-key.pem
|
||||
ucentral.websocket.host.0.clientcas = $UCENTRALGW_ROOT/certs/clientcas.pem
|
||||
ucentral.websocket.host.0.cas = $UCENTRALGW_ROOT/certs/cas
|
||||
ucentral.websocket.host.0.rootca = $OWGW_ROOT/certs/root.pem
|
||||
ucentral.websocket.host.0.issuer = $OWGW_ROOT/certs/issuer.pem
|
||||
ucentral.websocket.host.0.cert = $OWGW_ROOT/certs/websocket-cert.pem
|
||||
ucentral.websocket.host.0.key = $OWGW_ROOT/certs/websocket-key.pem
|
||||
ucentral.websocket.host.0.clientcas = $OWGW_ROOT/certs/clientcas.pem
|
||||
ucentral.websocket.host.0.cas = $OWGW_ROOT/certs/cas
|
||||
ucentral.websocket.host.0.address = *
|
||||
ucentral.websocket.host.0.port = 15002
|
||||
ucentral.websocket.host.0.security = strict
|
||||
@@ -324,17 +324,17 @@ ucentral.websocket.maxreactors = 20
|
||||
|
||||
###### This is the end point for the devices when uploading files
|
||||
```asm
|
||||
ucentral.fileuploader.host.0.backlog = 100
|
||||
ucentral.fileuploader.host.0.rootca = $UCENTRALGW_ROOT/certs/restapi-ca.pem
|
||||
ucentral.fileuploader.host.0.security = relaxed
|
||||
ucentral.fileuploader.host.0.address = *
|
||||
ucentral.fileuploader.host.0.name = 192.168.1.176
|
||||
ucentral.fileuploader.host.0.port = 16003
|
||||
ucentral.fileuploader.host.0.cert = $UCENTRALGW_ROOT/certs/restapi-cert.pem
|
||||
ucentral.fileuploader.host.0.key = $UCENTRALGW_ROOT/certs/restapi-key.pem
|
||||
ucentral.fileuploader.host.0.key.password = mypassword
|
||||
ucentral.fileuploader.path = $UCENTRALGW_ROOT/uploads
|
||||
ucentral.fileuploader.maxsize = 10000
|
||||
openwifi.fileuploader.host.0.backlog = 100
|
||||
openwifi.fileuploader.host.0.rootca = $OWGW_ROOT/certs/restapi-ca.pem
|
||||
openwifi.fileuploader.host.0.security = relaxed
|
||||
openwifi.fileuploader.host.0.address = *
|
||||
openwifi.fileuploader.host.0.name = 192.168.1.176
|
||||
openwifi.fileuploader.host.0.port = 16003
|
||||
openwifi.fileuploader.host.0.cert = $OWGW_ROOT/certs/restapi-cert.pem
|
||||
openwifi.fileuploader.host.0.key = $OWGW_ROOT/certs/restapi-key.pem
|
||||
openwifi.fileuploader.host.0.key.password = mypassword
|
||||
openwifi.fileuploader.path = $OWGW_ROOT/uploads
|
||||
openwifi.fileuploader.maxsize = 10000
|
||||
```
|
||||
|
||||
###### host.0.address entries
|
||||
@@ -343,7 +343,7 @@ the `*`. Using the `*` means all interfaces will be able to accept connections.
|
||||
by changing the `0` to another index. You need to repeat the whole configuration block for each index. Indexes must be sequential
|
||||
start at `0`.
|
||||
|
||||
###### ucentral.fileuploader.host.0.name
|
||||
###### openwifi.fileuploader.host.0.name
|
||||
This must point to the IP or FQDN of your uCentralGW.
|
||||
|
||||
#### Running the gateway
|
||||
@@ -369,7 +369,7 @@ can be any of the keys you are already using. You must keep that keep secret and
|
||||
this is the entry
|
||||
|
||||
```asm
|
||||
ucentral.service.key = $UCENTRALGW_ROOT/certs/websocket-key.pem
|
||||
openwifi.service.key = $OWGW_ROOT/certs/websocket-key.pem
|
||||
```
|
||||
|
||||
#### Command line options
|
||||
@@ -440,9 +440,9 @@ then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -f ucentralgw.properties ]]
|
||||
if [[ ! -f owgw.properties ]]
|
||||
then
|
||||
echo "Configuration file ucentralgw.properties is missing in the current directory"
|
||||
echo "Configuration file owgw.properties is missing in the current directory"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
@@ -458,9 +458,9 @@ docker run -d -p 15002:15002 \
|
||||
```
|
||||
|
||||
Create yourself a directory and copy that script which you can also get from [here](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/main/docker_run.sh).
|
||||
You must have the basic configuration file copied in the directory. This file must be called `ucentralgw.properties`. You can bring your own or
|
||||
copy it from [here](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/main/ucentralgw.properties). Please look at [this](#certificates-with-docker) to have the right
|
||||
certificates. You need to make sure that the names match the content of the `ucentralgw.properties`
|
||||
You must have the basic configuration file copied in the directory. This file must be called `owgw.properties`. You can bring your own or
|
||||
copy it from [here](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/main/owgw.properties). Please look at [this](#certificates-with-docker) to have the right
|
||||
certificates. You need to make sure that the names match the content of the `owgw.properties`
|
||||
file. Once all this is done, you can simply run `docker_run.sh`.
|
||||
|
||||
#### Docker installation directory layout
|
||||
@@ -472,15 +472,15 @@ Run-time root
|
||||
----- certs (same as above)
|
||||
+---- logs (dir)
|
||||
+---- uploads (dir)
|
||||
+---- ucentralgw.properties (file)
|
||||
+---- owgw.properties (file)
|
||||
```
|
||||
|
||||
#### `ucentralgw.properties` for Docker
|
||||
#### `owgw.properties` for Docker
|
||||
If you use the pre-made configuration file, and you follow the directory layout, the only line you must change
|
||||
is the following line:
|
||||
|
||||
```asm
|
||||
ucentral.fileuploader.host.0.name = 192.168.1.176
|
||||
openwifi.fileuploader.host.0.name = 192.168.1.176
|
||||
```
|
||||
|
||||
This line should reflect the IP of your gateway or its FQDN. You must make sure that this name or IP is accessible
|
||||
@@ -491,8 +491,8 @@ Please refer to the `certs` directory from the sections above.
|
||||
|
||||
#### Configuration with Docker
|
||||
The configuration for this service is kept in a properties file. Currently, this configuration file must be kept in the
|
||||
current directory of uCentral or one level up. This file is called `ucentralgw.properties` and you can see the latest version
|
||||
[here](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/main/ucentralgw.properties). The file will be loaded from
|
||||
current directory of uCentral or one level up. This file is called `owgw.properties` and you can see the latest version
|
||||
[here](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/main/owgw.properties). The file will be loaded from
|
||||
the directory set by the environment variable `UCENTRALGW_CONFIG`. To use environment variables in the configuration,
|
||||
you must use `$<varname>`. The path for the logs for the service must exist prior to starting the
|
||||
service. The path is defined under `logging.channels.c2.path`. Only `path names` support the use of
|
||||
@@ -502,34 +502,34 @@ environment variables. Here is a sample configuration:
|
||||
The communication protocol between the device and the controller is detailed in this [document](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/main/PROTOCOL.md).
|
||||
|
||||
## OpenAPI
|
||||
The service supports an OpenAPI REST based interface for management. You can find the [definition here](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/main/openapi/ucentral/ucentral.yaml).
|
||||
The service supports an OpenAPI REST based interface for management. You can find the [definition here](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/main/openapi/ucentral/owgw.yaml).
|
||||
And here is [how to use it](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/main/OPENAPI.md)
|
||||
|
||||
## Using the API
|
||||
In the `test_scripts` directory, you will find a series of scripts that will show you how to use the API
|
||||
with [curl](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/main/TEST_CURL.md)
|
||||
with [curl](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/main/CLI.md)
|
||||
or [python](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/main/TEST_PYTHON.md).
|
||||
More scripts will be added in the future.
|
||||
|
||||
## Firewall Considerations
|
||||
- The protocol uses TCP port 15002 between the devices and the gateway. This port must be opened.
|
||||
- Devices use the TCP port 16003 to upload files. This port is configurable in the `ucentralgw.properties` file. Look for `ucentral.fileuploader.host.0.port`.
|
||||
- The RESTAPI is accessed through TCP port 16002 by default. This port is configurable in the `ucentralgw.properties` file. Look for the entry `ucentral.restapi.host.0.port`.
|
||||
- Devices use the TCP port 16003 to upload files. This port is configurable in the `owgw.properties` file. Look for `openwifi.fileuploader.host.0.port`.
|
||||
- The RESTAPI is accessed through TCP port 16002 by default. This port is configurable in the `owgw.properties` file. Look for the entry `openwifi.restapi.host.0.port`.
|
||||
|
||||
## Kafka integration
|
||||
So what about Kafka? Well, the gateway has basic integration with Kafka. It is turned off by default, to turn it on, in the configuration:
|
||||
|
||||
```asm
|
||||
ucentral.kafka.enable = false
|
||||
ucentral.kafka.brokerlist = 127.0.0.1:9092
|
||||
ucentral.kafka.commit = false
|
||||
ucentral.kafka.queue.buffering.max.ms = 50
|
||||
openwifi.kafka.enable = false
|
||||
openwifi.kafka.brokerlist = 127.0.0.1:9092
|
||||
openwifi.kafka.commit = false
|
||||
openwifi.kafka.queue.buffering.max.ms = 50
|
||||
```
|
||||
|
||||
#### `ucentral.kafka.enable`
|
||||
#### `openwifi.kafka.enable`
|
||||
Kind of obvious but hey, set `true` or `false`. Default is `false`
|
||||
|
||||
#### `ucentral.kafka.brokerlist`
|
||||
#### `openwifi.kafka.brokerlist`
|
||||
This is a comma separator list of the brokers in your `kafka` deployment.
|
||||
|
||||
#### Kafka topics
|
||||
|
@@ -1,11 +1,70 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
if [ "$1" = '/ucentral/ucentralgw' -a "$(id -u)" = '0' ]; then
|
||||
if [ "$SELFSIGNED_CERTS" = 'true' ]; then
|
||||
update-ca-certificates
|
||||
fi
|
||||
|
||||
if [[ "$TEMPLATE_CONFIG" = 'true' && ! -f "$OWGW_CONFIG"/owgw.properties ]]; then
|
||||
WEBSOCKET_HOST_ROOTCA=${WEBSOCKET_HOST_ROOTCA:-"\$OWGW_ROOT/certs/root.pem"} \
|
||||
WEBSOCKET_HOST_ISSUER=${WEBSOCKET_HOST_ISSUER:-"\$OWGW_ROOT/certs/issuer.pem"} \
|
||||
WEBSOCKET_HOST_CERT=${WEBSOCKET_HOST_CERT:-"\$OWGW_ROOT/certs/websocket-cert.pem"} \
|
||||
WEBSOCKET_HOST_KEY=${WEBSOCKET_HOST_KEY:-"\$OWGW_ROOT/certs/websocket-key.pem"} \
|
||||
WEBSOCKET_HOST_CLIENTCAS=${WEBSOCKET_HOST_CLIENTCAS:-"\$OWGW_ROOT/certs/clientcas.pem"} \
|
||||
WEBSOCKET_HOST_CAS=${WEBSOCKET_HOST_CAS:-"\$OWGW_ROOT/certs/cas"} \
|
||||
WEBSOCKET_HOST_PORT=${WEBSOCKET_HOST_PORT:-"15002"} \
|
||||
WEBSOCKET_HOST_KEY_PASSWORD=${WEBSOCKET_HOST_KEY_PASSWORD:-"mypassword"} \
|
||||
RESTAPI_HOST_ROOTCA=${RESTAPI_HOST_ROOTCA:-"\$OWGW_ROOT/certs/restapi-ca.pem"} \
|
||||
RESTAPI_HOST_PORT=${RESTAPI_HOST_PORT:-"16002"} \
|
||||
RESTAPI_HOST_CERT=${RESTAPI_HOST_CERT:-"\$OWGW_ROOT/certs/restapi-cert.pem"} \
|
||||
RESTAPI_HOST_KEY=${RESTAPI_HOST_KEY:-"\$OWGW_ROOT/certs/restapi-key.pem"} \
|
||||
RESTAPI_HOST_KEY_PASSWORD=${RESTAPI_HOST_KEY_PASSWORD:-"mypassword"} \
|
||||
INTERNAL_RESTAPI_HOST_ROOTCA=${INTERNAL_RESTAPI_HOST_ROOTCA:-"\$OWGW_ROOT/certs/restapi-ca.pem"} \
|
||||
INTERNAL_RESTAPI_HOST_PORT=${INTERNAL_RESTAPI_HOST_PORT:-"17002"} \
|
||||
INTERNAL_RESTAPI_HOST_CERT=${INTERNAL_RESTAPI_HOST_CERT:-"\$OWGW_ROOT/certs/restapi-cert.pem"} \
|
||||
INTERNAL_RESTAPI_HOST_KEY=${INTERNAL_RESTAPI_HOST_KEY:-"\$OWGW_ROOT/certs/restapi-key.pem"} \
|
||||
INTERNAL_RESTAPI_HOST_KEY_PASSWORD=${INTERNAL_RESTAPI_HOST_KEY_PASSWORD:-"mypassword"} \
|
||||
FILEUPLOADER_HOST_ROOTCA=${FILEUPLOADER_HOST_ROOTCA:-"\$OWGW_ROOT/certs/restapi-ca.pem"} \
|
||||
FILEUPLOADER_HOST_NAME=${FILEUPLOADER_HOST_NAME:-"localhost"} \
|
||||
FILEUPLOADER_HOST_PORT=${FILEUPLOADER_HOST_PORT:-"16003"} \
|
||||
FILEUPLOADER_HOST_CERT=${FILEUPLOADER_HOST_CERT:-"\$OWGW_ROOT/certs/restapi-cert.pem"} \
|
||||
FILEUPLOADER_HOST_KEY=${FILEUPLOADER_HOST_KEY:-"\$OWGW_ROOT/certs/restapi-key.pem"} \
|
||||
FILEUPLOADER_HOST_KEY_PASSWORD=${FILEUPLOADER_HOST_KEY_PASSWORD:-"mypassword"} \
|
||||
FILEUPLOADER_PATH=${FILEUPLOADER_PATH:-"\$OWGW_ROOT/uploads"} \
|
||||
FILEUPLOADER_URI=${FILEUPLOADER_URI:-"https://localhost:16003"} \
|
||||
SERVICE_KEY=${SERVICE_KEY:-"\$OWGW_ROOT/certs/restapi-key.pem"} \
|
||||
SERVICE_KEY_PASSWORD=${SERVICE_KEY_PASSWORD:-"mypassword"} \
|
||||
SYSTEM_DATA=${SYSTEM_DATA:-"\$OWGW_ROOT/data"} \
|
||||
SYSTEM_URI_PRIVATE=${SYSTEM_URI_PRIVATE:-"https://localhost:17002"} \
|
||||
SYSTEM_URI_PUBLIC=${SYSTEM_URI_PUBLIC:-"https://localhost:16002"} \
|
||||
SYSTEM_URI_UI=${SYSTEM_URI_UI:-"http://localhost"} \
|
||||
RTTY_ENABLED=${RTTY_ENABLED:-"false"} \
|
||||
RTTY_SERVER=${RTTY_SERVER:-"localhost"} \
|
||||
RTTY_PORT=${RTTY_PORT:-"5912"} \
|
||||
RTTY_TOKEN=${RTTY_TOKEN:-"96181c567b4d0d98c50f127230068fa8"} \
|
||||
RTTY_TIMEOUT=${RTTY_TIMEOUT:-"60"} \
|
||||
RTTY_VIEWPORT=${RTTY_VIEWPORT:-"5913"} \
|
||||
KAFKA_ENABLE=${KAFKA_ENABLE:-"true"} \
|
||||
KAFKA_BROKERLIST=${KAFKA_BROKERLIST:-"localhost:9092"} \
|
||||
STORAGE_TYPE=${STORAGE_TYPE:-"sqlite"} \
|
||||
STORAGE_TYPE_POSTGRESQL_HOST=${STORAGE_TYPE_POSTGRESQL_HOST:-"localhost"} \
|
||||
STORAGE_TYPE_POSTGRESQL_USERNAME=${STORAGE_TYPE_POSTGRESQL_USERNAME:-"owgw"} \
|
||||
STORAGE_TYPE_POSTGRESQL_PASSWORD=${STORAGE_TYPE_POSTGRESQL_PASSWORD:-"owgw"} \
|
||||
STORAGE_TYPE_POSTGRESQL_DATABASE=${STORAGE_TYPE_POSTGRESQL_DATABASE:-"owgw"} \
|
||||
STORAGE_TYPE_POSTGRESQL_PORT=${STORAGE_TYPE_POSTGRESQL_PORT:-"5432"} \
|
||||
STORAGE_TYPE_MYSQL_HOST=${STORAGE_TYPE_MYSQL_HOST:-"localhost"} \
|
||||
STORAGE_TYPE_MYSQL_USERNAME=${STORAGE_TYPE_MYSQL_USERNAME:-"owgw"} \
|
||||
STORAGE_TYPE_MYSQL_PASSWORD=${STORAGE_TYPE_MYSQL_PASSWORD:-"owgw"} \
|
||||
STORAGE_TYPE_MYSQL_DATABASE=${STORAGE_TYPE_MYSQL_DATABASE:-"owgw"} \
|
||||
STORAGE_TYPE_MYSQL_PORT=${STORAGE_TYPE_MYSQL_PORT:-"3306"} \
|
||||
envsubst < /owgw.properties.tmpl > $OWGW_CONFIG/owgw.properties
|
||||
fi
|
||||
|
||||
if [ "$1" = '/openwifi/owgw' -a "$(id -u)" = '0' ]; then
|
||||
if [ "$RUN_CHOWN" = 'true' ]; then
|
||||
chown -R "$UCENTRALGW_USER": "$UCENTRALGW_ROOT" "$UCENTRALGW_CONFIG"
|
||||
chown -R "$OWGW_USER": "$OWGW_ROOT" "$OWGW_CONFIG"
|
||||
fi
|
||||
exec su-exec "$UCENTRALGW_USER" "$@"
|
||||
exec su-exec "$OWGW_USER" "$@"
|
||||
fi
|
||||
|
||||
exec "$@"
|
||||
|
@@ -26,7 +26,7 @@ then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -f ucentralgw.properties ]]
|
||||
if [[ ! -f owgw.properties ]]
|
||||
then
|
||||
echo "Configuration file ucentral.properties is missing in the current directory"
|
||||
exit 2
|
||||
|
@@ -1,7 +1,7 @@
|
||||
apiVersion: v2
|
||||
appVersion: "1.0"
|
||||
description: A Helm chart for Kubernetes
|
||||
name: ucentralgw
|
||||
name: owgw
|
||||
version: 0.1.0
|
||||
dependencies:
|
||||
- name: postgresql
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# ucentralgw
|
||||
# owgw
|
||||
|
||||
This Helm chart helps to deploy uCentralGW to the Kubernetes clusters. It is mainly used in [assembly chart](https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/tree/main/chart) as uCentralGW requires other services as dependencies that are considered in that Helm chart. This chart is purposed to define deployment logic close to the application code itself and define default values that could be overriden during deployment.
|
||||
This Helm chart helps to deploy OpenWIFI Gateway (further on refered as __Gateway__) to the Kubernetes clusters. It is mainly used in [assembly chart](https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/tree/main/chart) as Gateway requires other services as dependencies that are considered in that Helm chart. This chart is purposed to define deployment logic close to the application code itself and define default values that could be overriden during deployment.
|
||||
|
||||
|
||||
## TL;DR;
|
||||
@@ -11,7 +11,7 @@ $ helm install .
|
||||
|
||||
## Introduction
|
||||
|
||||
This chart bootstraps an ucentralgw on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager.
|
||||
This chart bootstraps the Gateway on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager.
|
||||
|
||||
## Installing the Chart
|
||||
|
||||
@@ -20,10 +20,10 @@ Currently this chart is not assembled in charts archives, so [helm-git](https://
|
||||
To install the chart with the release name `my-release`:
|
||||
|
||||
```bash
|
||||
$ helm install --name my-release git+https://github.com/Telecominfraproject/wlan-cloud-ucentralgw@helm?ref=master
|
||||
$ helm install --name my-release git+https://github.com/Telecominfraproject/wlan-cloud-ucentralgw@helm/owgw-0.1.0.tgz?ref=master
|
||||
```
|
||||
|
||||
The command deploys ucentralgw on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation.
|
||||
The command deploys the Gateway on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation.
|
||||
|
||||
> **Tip**: List all releases using `helm list`
|
||||
|
||||
@@ -47,40 +47,40 @@ The following table lists the configurable parameters of the chart and their def
|
||||
| strategyType | string | Application deployment strategy | `'Recreate'` |
|
||||
| nameOverride | string | Override to be used for application deployment | |
|
||||
| fullnameOverride | string | Override to be used for application deployment (has priority over nameOverride) | |
|
||||
| images.ucentralgw.repository | string | Docker image repository | |
|
||||
| images.ucentralgw.tag | string | Docker image tag | `'master'` |
|
||||
| images.ucentralgw.pullPolicy | string | Docker image pull policy | `'Always'` |
|
||||
| services.ucentralgw.type | string | uCentralGW service type | `'LoadBalancer'` |
|
||||
| services.ucentralgw.ports.websocket.servicePort | number | Websocket endpoint port to be exposed on service | `15002` |
|
||||
| services.ucentralgw.ports.websocket.targetPort | number | Websocket endpoint port to be targeted by service | `15002` |
|
||||
| services.ucentralgw.ports.websocket.protocol | string | Websocket endpoint protocol | `'TCP'` |
|
||||
| services.ucentralgw.ports.restapi.servicePort | number | REST API endpoint port to be exposed on service | `16002` |
|
||||
| services.ucentralgw.ports.restapi.targetPort | number | REST API endpoint port to be targeted by service | `16002` |
|
||||
| services.ucentralgw.ports.restapi.protocol | string | REST API endpoint protocol | `'TCP'` |
|
||||
| services.ucentralgw.ports.restapiinternal.servicePort | string | Internal REST API endpoint port to be exposed on service | `17002` |
|
||||
| services.ucentralgw.ports.restapiinternal.targetPort | number | Internal REST API endpoint port to be targeted by service | `17002` |
|
||||
| services.ucentralgw.ports.restapiinternal.protocol | string | Internal REST API endpoint protocol | `'TCP'` |
|
||||
| services.ucentralgw.ports.fileuploader.servicePort | string | Fileuploader endpoint port to be exposed on service | `16003` |
|
||||
| services.ucentralgw.ports.fileuploader.targetPort | number | Fileuploader endpoint port to be targeted by service | `16003` |
|
||||
| services.ucentralgw.ports.fileuploader.protocol | string | Fileuploader endpoint protocol | `'TCP'` |
|
||||
| checks.ucentralgw.liveness.httpGet.path | string | Liveness check path to be used | `'/'` |
|
||||
| checks.ucentralgw.liveness.httpGet.port | number | Liveness check port to be used (should be pointint to ALB endpoint) | `16102` |
|
||||
| checks.ucentralgw.readiness.httpGet.path | string | Readiness check path to be used | `'/'` |
|
||||
| checks.ucentralgw.readiness.httpGet.port | number | Readiness check port to be used (should be pointint to ALB endpoint) | `16102` |
|
||||
| images.owgw.repository | string | Docker image repository | |
|
||||
| images.owgw.tag | string | Docker image tag | `'master'` |
|
||||
| images.owgw.pullPolicy | string | Docker image pull policy | `'Always'` |
|
||||
| services.owgw.type | string | OpenWIFI Gateway service type | `'LoadBalancer'` |
|
||||
| services.owgw.ports.websocket.servicePort | number | Websocket endpoint port to be exposed on service | `15002` |
|
||||
| services.owgw.ports.websocket.targetPort | number | Websocket endpoint port to be targeted by service | `15002` |
|
||||
| services.owgw.ports.websocket.protocol | string | Websocket endpoint protocol | `'TCP'` |
|
||||
| services.owgw.ports.restapi.servicePort | number | REST API endpoint port to be exposed on service | `16002` |
|
||||
| services.owgw.ports.restapi.targetPort | number | REST API endpoint port to be targeted by service | `16002` |
|
||||
| services.owgw.ports.restapi.protocol | string | REST API endpoint protocol | `'TCP'` |
|
||||
| services.owgw.ports.restapiinternal.servicePort | string | Internal REST API endpoint port to be exposed on service | `17002` |
|
||||
| services.owgw.ports.restapiinternal.targetPort | number | Internal REST API endpoint port to be targeted by service | `17002` |
|
||||
| services.owgw.ports.restapiinternal.protocol | string | Internal REST API endpoint protocol | `'TCP'` |
|
||||
| services.owgw.ports.fileuploader.servicePort | string | Fileuploader endpoint port to be exposed on service | `16003` |
|
||||
| services.owgw.ports.fileuploader.targetPort | number | Fileuploader endpoint port to be targeted by service | `16003` |
|
||||
| services.owgw.ports.fileuploader.protocol | string | Fileuploader endpoint protocol | `'TCP'` |
|
||||
| checks.owgw.liveness.httpGet.path | string | Liveness check path to be used | `'/'` |
|
||||
| checks.owgw.liveness.httpGet.port | number | Liveness check port to be used (should be pointint to ALB endpoint) | `16102` |
|
||||
| checks.owgw.readiness.httpGet.path | string | Readiness check path to be used | `'/'` |
|
||||
| checks.owgw.readiness.httpGet.port | number | Readiness check port to be used (should be pointint to ALB endpoint) | `16102` |
|
||||
| ingresses.restapi.enabled | boolean | Defines if REST API endpoint should be exposed via Ingress controller | `False` |
|
||||
| ingresses.restapi.hosts | array | List of hosts for exposed REST API | |
|
||||
| ingresses.restapi.paths | array | List of paths to be exposed for REST API | |
|
||||
| ingresses.fileuploader.enabled | boolean | Defines if Fileuploader endpoint should be exposed via Ingress controller | `False` |
|
||||
| ingresses.fileuploader.hosts | array | List of hosts for exposed Fileuploader | |
|
||||
| ingresses.fileuploader.paths | array | List of paths for exposed Fileuploader | |
|
||||
| volumes.ucentralgw | array | Defines list of volumes to be attached to uCentralGW | |
|
||||
| persistence.enabled | boolean | Defines if uCentralGW requires Persistent Volume (required for permanent files storage and SQLite DB if enabled) | `True` |
|
||||
| volumes.owgw | array | Defines list of volumes to be attached to the Gateway | |
|
||||
| persistence.enabled | boolean | Defines if the Gateway requires Persistent Volume (required for permanent files storage and SQLite DB if enabled) | `True` |
|
||||
| persistence.accessModes | array | Defines PV access modes | |
|
||||
| persistence.size | string | Defines PV size | `'10Gi'` |
|
||||
| public_env_variables | hash | Defines list of environment variables to be passed to uCentralGW | |
|
||||
| configProperties | hash | Configuration properties that should be passed to the application in `ucentralgw.properties`. May be passed by key in set (i.e. `configProperties."rtty\.token"`) | |
|
||||
| certs | hash | Defines files (keys and certificates) that should be passed to uCentralGW (PEM format is adviced to be used) (see `volumes.ucentralgw` on where it is mounted) | |
|
||||
| certsCAs | hash | Defines files with CAs that should be passed to uCentralGW (see `volumes.ucentralgw` on where it is mounted) | |
|
||||
| public_env_variables | hash | Defines list of environment variables to be passed to the Gateway | |
|
||||
| configProperties | hash | Configuration properties that should be passed to the application in `owgw.properties`. May be passed by key in set (i.e. `configProperties."rtty\.token"`) | |
|
||||
| certs | hash | Defines files (keys and certificates) that should be passed to the Gateway (PEM format is adviced to be used) (see `volumes.owgw` on where it is mounted) | |
|
||||
| certsCAs | hash | Defines files with CAs that should be passed to the Gateway (see `volumes.owgw` on where it is mounted) | |
|
||||
|
||||
|
||||
Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example,
|
||||
@@ -100,5 +100,3 @@ $ helm install --name my-release -f values.yaml .
|
||||
```
|
||||
|
||||
> **Tip**: You can use the default [values.yaml](values.yaml) as a base for customization.
|
||||
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
{{- define "ucentralgw.config" -}}
|
||||
{{- define "owgw.config" -}}
|
||||
{{- range $key, $value := .Values.configProperties }}
|
||||
{{ $key }} = {{ $value }}
|
||||
{{- end }}
|
||||
|
@@ -2,7 +2,7 @@
|
||||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{- define "ucentralgw.name" -}}
|
||||
{{- define "owgw.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
|
||||
@@ -11,7 +11,7 @@ Create a default fully qualified app name.
|
||||
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
||||
If release name contains chart name it will be used as a full name.
|
||||
*/}}
|
||||
{{- define "ucentralgw.fullname" -}}
|
||||
{{- define "owgw.fullname" -}}
|
||||
{{- if .Values.fullnameOverride -}}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
|
||||
{{- else -}}
|
||||
@@ -27,6 +27,6 @@ If release name contains chart name it will be used as a full name.
|
||||
{{/*
|
||||
Create chart name and version as used by the chart label.
|
||||
*/}}
|
||||
{{- define "ucentralgw.chart" -}}
|
||||
{{- define "owgw.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
|
@@ -3,10 +3,10 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "ucentralgw.fullname" . }}
|
||||
name: {{ include "owgw.fullname" . }}
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ include "ucentralgw.name" . }}
|
||||
helm.sh/chart: {{ include "ucentralgw.chart" . }}
|
||||
app.kubernetes.io/name: {{ include "owgw.name" . }}
|
||||
helm.sh/chart: {{ include "owgw.chart" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
spec:
|
||||
@@ -15,28 +15,28 @@ spec:
|
||||
type: {{ .Values.strategyType }}
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: {{ include "ucentralgw.name" . }}
|
||||
app.kubernetes.io/name: {{ include "owgw.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- with .Values.services.ucentralgw.labels }}
|
||||
{{- with .Values.services.owgw.labels }}
|
||||
{{- toYaml . | nindent 6 }}
|
||||
{{- end }}
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
checksum/config: {{ include "ucentralgw.config" . | sha256sum }}
|
||||
checksum/config: {{ include "owgw.config" . | sha256sum }}
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ include "ucentralgw.name" . }}
|
||||
app.kubernetes.io/name: {{ include "owgw.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- with .Values.services.ucentralgw.labels }}
|
||||
{{- with .Values.services.owgw.labels }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
|
||||
containers:
|
||||
|
||||
- name: ucentralgw
|
||||
image: "{{ .Values.images.ucentralgw.repository }}:{{ .Values.images.ucentralgw.tag }}"
|
||||
imagePullPolicy: {{ .Values.images.ucentralgw.pullPolicy }}
|
||||
- name: owgw
|
||||
image: "{{ .Values.images.owgw.repository }}:{{ .Values.images.owgw.tag }}"
|
||||
imagePullPolicy: {{ .Values.images.owgw.pullPolicy }}
|
||||
|
||||
env:
|
||||
- name: KUBERNETES_DEPLOYED
|
||||
@@ -49,19 +49,19 @@ spec:
|
||||
- name: {{ $key }}
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "ucentralgw.fullname" $root }}-env
|
||||
name: {{ include "owgw.fullname" $root }}-env
|
||||
key: {{ $key }}
|
||||
{{- end }}
|
||||
|
||||
ports:
|
||||
{{- range $port, $portValue := .Values.services.ucentralgw.ports }}
|
||||
{{- range $port, $portValue := .Values.services.owgw.ports }}
|
||||
- name: {{ $port }}
|
||||
containerPort: {{ $portValue.targetPort }}
|
||||
protocol: {{ $portValue.protocol }}
|
||||
{{- end }}
|
||||
|
||||
volumeMounts:
|
||||
{{- range .Values.volumes.ucentralgw }}
|
||||
{{- range .Values.volumes.owgw }}
|
||||
- name: {{ .name }}
|
||||
mountPath: {{ .mountPath }}
|
||||
{{- if .subPath }}
|
||||
@@ -69,13 +69,13 @@ spec:
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- if .Values.checks.ucentralgw.liveness }}
|
||||
{{- if .Values.checks.owgw.liveness }}
|
||||
livenessProbe:
|
||||
{{- toYaml .Values.checks.ucentralgw.liveness | nindent 12 }}
|
||||
{{- toYaml .Values.checks.owgw.liveness | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- if .Values.checks.ucentralgw.readiness }}
|
||||
{{- if .Values.checks.owgw.readiness }}
|
||||
readinessProbe:
|
||||
{{- toYaml .Values.checks.ucentralgw.readiness | nindent 12 }}
|
||||
{{- toYaml .Values.checks.owgw.readiness | nindent 12 }}
|
||||
{{- end }}
|
||||
|
||||
{{- with .Values.resources }}
|
||||
@@ -91,7 +91,7 @@ spec:
|
||||
imagePullSecrets:
|
||||
{{- range $image, $imageValue := .Values.images }}
|
||||
{{- if $imageValue.regcred }}
|
||||
- name: {{ include "ucentralgw.fullname" $root }}-{{ $image }}-regcred
|
||||
- name: {{ include "owgw.fullname" $root }}-{{ $image }}-regcred
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
|
@@ -5,10 +5,10 @@
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ include "ucentralgw.fullname" $root }}-{{ $ingress }}
|
||||
name: {{ include "owgw.fullname" $root }}-{{ $ingress }}
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ include "ucentralgw.name" $root }}
|
||||
helm.sh/chart: {{ include "ucentralgw.chart" $root }}
|
||||
app.kubernetes.io/name: {{ include "owgw.name" $root }}
|
||||
helm.sh/chart: {{ include "owgw.chart" $root }}
|
||||
app.kubernetes.io/instance: {{ $root.Release.Name }}
|
||||
app.kubernetes.io/managed-by: {{ $root.Release.Service }}
|
||||
{{- with $ingressValue.annotations }}
|
||||
@@ -37,7 +37,7 @@ spec:
|
||||
{{- range $ingressValue.paths }}
|
||||
- path: {{ .path }}
|
||||
backend:
|
||||
serviceName: {{ include "ucentralgw.fullname" $root }}-{{ .serviceName }}
|
||||
serviceName: {{ include "owgw.fullname" $root }}-{{ .serviceName }}
|
||||
servicePort: {{ .servicePort }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
@@ -3,10 +3,10 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ template "ucentralgw.fullname" . }}-pvc
|
||||
name: {{ template "owgw.fullname" . }}-pvc
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ include "ucentralgw.name" . }}
|
||||
helm.sh/chart: {{ include "ucentralgw.chart" . }}
|
||||
app.kubernetes.io/name: {{ include "owgw.name" . }}
|
||||
helm.sh/chart: {{ include "owgw.chart" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- with .Values.persistence.annotations }}
|
||||
|
@@ -2,11 +2,11 @@
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
labels:
|
||||
app.kuberentes.io/name: {{ include "ucentralgw.name" . }}
|
||||
helm.sh/chart: {{ include "ucentralgw.chart" . }}
|
||||
app.kuberentes.io/name: {{ include "owgw.name" . }}
|
||||
helm.sh/chart: {{ include "owgw.chart" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
name: {{ include "ucentralgw.fullname" . }}-certs-cas
|
||||
name: {{ include "owgw.fullname" . }}-certs-cas
|
||||
kind: Secret
|
||||
type: Opaque
|
||||
data:
|
||||
|
@@ -2,11 +2,11 @@
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
labels:
|
||||
app.kuberentes.io/name: {{ include "ucentralgw.name" . }}
|
||||
helm.sh/chart: {{ include "ucentralgw.chart" . }}
|
||||
app.kuberentes.io/name: {{ include "owgw.name" . }}
|
||||
helm.sh/chart: {{ include "owgw.chart" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
name: {{ include "ucentralgw.fullname" . }}-certs
|
||||
name: {{ include "owgw.fullname" . }}-certs
|
||||
kind: Secret
|
||||
type: Opaque
|
||||
data:
|
||||
|
@@ -2,12 +2,12 @@
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
labels:
|
||||
app.kuberentes.io/name: {{ include "ucentralgw.name" . }}
|
||||
helm.sh/chart: {{ include "ucentralgw.chart" . }}
|
||||
app.kuberentes.io/name: {{ include "owgw.name" . }}
|
||||
helm.sh/chart: {{ include "owgw.chart" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
name: {{ include "ucentralgw.fullname" . }}-config
|
||||
name: {{ include "owgw.fullname" . }}-config
|
||||
kind: Secret
|
||||
type: Opaque
|
||||
data:
|
||||
ucentralgw.properties: {{ include "ucentralgw.config" . | b64enc }}
|
||||
owgw.properties: {{ include "owgw.config" . | b64enc }}
|
||||
|
@@ -2,11 +2,11 @@
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
labels:
|
||||
app.kuberentes.io/name: {{ include "ucentralgw.name" . }}
|
||||
helm.sh/chart: {{ include "ucentralgw.chart" . }}
|
||||
app.kuberentes.io/name: {{ include "owgw.name" . }}
|
||||
helm.sh/chart: {{ include "owgw.chart" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
name: {{ include "ucentralgw.fullname" . }}-env
|
||||
name: {{ include "owgw.fullname" . }}-env
|
||||
kind: Secret
|
||||
type: Opaque
|
||||
data:
|
||||
|
@@ -10,11 +10,11 @@ kind: Secret
|
||||
type: kubernetes.io/dockerconfigjson
|
||||
metadata:
|
||||
labels:
|
||||
app.kuberentes.io/name: {{ include "ucentralgw.name" $root }}
|
||||
helm.sh/chart: {{ include "ucentralgw.chart" $root }}
|
||||
app.kuberentes.io/name: {{ include "owgw.name" $root }}
|
||||
helm.sh/chart: {{ include "owgw.chart" $root }}
|
||||
app.kubernetes.io/instance: {{ $root.Release.Name }}
|
||||
app.kubernetes.io/managed-by: {{ $root.Release.Service }}
|
||||
name: {{ include "ucentralgw.fullname" $root }}-{{ $image }}-regcred
|
||||
name: {{ include "owgw.fullname" $root }}-{{ $image }}-regcred
|
||||
data:
|
||||
.dockerconfigjson: {{ template "imagePullSecret" $imageValue.regcred }}
|
||||
{{- end }}
|
||||
|
@@ -4,14 +4,14 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "ucentralgw.fullname" $root }}-{{ $service }}
|
||||
name: {{ include "owgw.fullname" $root }}-{{ $service }}
|
||||
{{- with $serviceValue.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ include "ucentralgw.name" $root }}
|
||||
helm.sh/chart: {{ include "ucentralgw.chart" $root }}
|
||||
app.kubernetes.io/name: {{ include "owgw.name" $root }}
|
||||
helm.sh/chart: {{ include "owgw.chart" $root }}
|
||||
app.kubernetes.io/instance: {{ $root.Release.Name }}
|
||||
app.kubernetes.io/managed-by: {{ $root.Release.Service }}
|
||||
|
||||
@@ -39,7 +39,7 @@ spec:
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
selector:
|
||||
app.kubernetes.io/name: {{ include "ucentralgw.name" $root }}
|
||||
app.kubernetes.io/name: {{ include "owgw.name" $root }}
|
||||
app.kubernetes.io/instance: {{ $root.Release.Name }}
|
||||
{{- with $serviceValue.labels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
|
197
helm/values.yaml
197
helm/values.yaml
@@ -6,9 +6,9 @@ nameOverride: ""
|
||||
fullnameOverride: ""
|
||||
|
||||
images:
|
||||
ucentralgw:
|
||||
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/ucentralgw
|
||||
tag: master
|
||||
owgw:
|
||||
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owgw
|
||||
tag: v2.3.0-RC1
|
||||
pullPolicy: Always
|
||||
# regcred:
|
||||
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io
|
||||
@@ -16,7 +16,7 @@ images:
|
||||
# password: password
|
||||
|
||||
services:
|
||||
ucentralgw:
|
||||
owgw:
|
||||
type: LoadBalancer
|
||||
ports:
|
||||
websocket:
|
||||
@@ -37,15 +37,16 @@ services:
|
||||
protocol: TCP
|
||||
|
||||
checks:
|
||||
ucentralgw:
|
||||
owgw:
|
||||
liveness:
|
||||
httpGet:
|
||||
path: /
|
||||
port: 16102
|
||||
readiness:
|
||||
httpGet:
|
||||
path: /
|
||||
port: 16102
|
||||
exec:
|
||||
command:
|
||||
- /readiness_check
|
||||
failureThreshold: 1
|
||||
|
||||
ingresses:
|
||||
restapi:
|
||||
@@ -57,7 +58,7 @@ ingresses:
|
||||
- restapi.chart-example.local
|
||||
paths:
|
||||
- path: /
|
||||
serviceName: ucentralgw
|
||||
serviceName: owgw
|
||||
servicePort: restapi
|
||||
fileuploader:
|
||||
enabled: false
|
||||
@@ -68,34 +69,34 @@ ingresses:
|
||||
- fileuploader.chart-example.local
|
||||
paths:
|
||||
- path: /
|
||||
serviceName: ucentralgw
|
||||
serviceName: owgw
|
||||
servicePort: fileuploader
|
||||
|
||||
volumes:
|
||||
ucentralgw:
|
||||
owgw:
|
||||
- name: config
|
||||
mountPath: /ucentralgw-data/ucentralgw.properties
|
||||
subPath: ucentralgw.properties
|
||||
mountPath: /owgw-data/owgw.properties
|
||||
subPath: owgw.properties
|
||||
# Template below will be rendered in template
|
||||
volumeDefinition: |
|
||||
secret:
|
||||
secretName: {{ include "ucentralgw.fullname" . }}-config
|
||||
secretName: {{ include "owgw.fullname" . }}-config
|
||||
- name: certs
|
||||
mountPath: /ucentralgw-data/certs
|
||||
mountPath: /owgw-data/certs
|
||||
volumeDefinition: |
|
||||
secret:
|
||||
secretName: {{ include "ucentralgw.fullname" . }}-certs
|
||||
secretName: {{ include "owgw.fullname" . }}-certs
|
||||
- name: certs-cas
|
||||
mountPath: /ucentralgw-data/certs/cas
|
||||
mountPath: /owgw-data/certs/cas
|
||||
volumeDefinition: |
|
||||
secret:
|
||||
secretName: {{ include "ucentralgw.fullname" . }}-certs-cas
|
||||
secretName: {{ include "owgw.fullname" . }}-certs-cas
|
||||
# Change this if you want to use another volume type
|
||||
- name: persist
|
||||
mountPath: /ucentralgw-data/persist
|
||||
mountPath: /owgw-data/persist
|
||||
volumeDefinition: |
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ template "ucentralgw.fullname" . }}-pvc
|
||||
claimName: {{ template "owgw.fullname" . }}-pvc
|
||||
|
||||
resources: {}
|
||||
# We usually recommend not to specify default resources and to leave this as a conscious
|
||||
@@ -128,63 +129,71 @@ persistence:
|
||||
|
||||
# Application
|
||||
public_env_variables:
|
||||
UCENTRALGW_ROOT: /ucentralgw-data
|
||||
UCENTRALGW_CONFIG: /ucentralgw-data
|
||||
OWGW_ROOT: /owgw-data
|
||||
OWGW_CONFIG: /owgw-data
|
||||
# Environment variables required for the readiness checks using script
|
||||
FLAGS: "-s --connect-timeout 3"
|
||||
# NOTE in order for readiness check to use system info you need to set READINESS_METHOD to "systeminfo" and set OWSEC to the OWSEC's REST API endpoint
|
||||
#READINESS_METHOD: systeminfo
|
||||
#OWSEC: gw-qa01.cicd.lab.wlan.tip.build:16001
|
||||
|
||||
secret_env_variables: {}
|
||||
secret_env_variables:
|
||||
# NOTE in order for readiness check to use system info method you need to override these values to the real OWSEC credentials
|
||||
OWSEC_USERNAME: tip@ucentral.com
|
||||
OWSEC_PASSWORD: openwifi
|
||||
|
||||
configProperties:
|
||||
# -> Public part
|
||||
# Websocket
|
||||
ucentral.websocket.host.0.backlog: 500
|
||||
ucentral.websocket.host.0.rootca: $UCENTRALGW_ROOT/certs/root.pem
|
||||
ucentral.websocket.host.0.issuer: $UCENTRALGW_ROOT/certs/issuer.pem
|
||||
ucentral.websocket.host.0.cert: $UCENTRALGW_ROOT/certs/websocket-cert.pem
|
||||
ucentral.websocket.host.0.key: $UCENTRALGW_ROOT/certs/websocket-key.pem
|
||||
ucentral.websocket.host.0.clientcas: $UCENTRALGW_ROOT/certs/clientcas.pem
|
||||
ucentral.websocket.host.0.cas: $UCENTRALGW_ROOT/certs/cas
|
||||
ucentral.websocket.host.0.rootca: $OWGW_ROOT/certs/root.pem
|
||||
ucentral.websocket.host.0.issuer: $OWGW_ROOT/certs/issuer.pem
|
||||
ucentral.websocket.host.0.cert: $OWGW_ROOT/certs/websocket-cert.pem
|
||||
ucentral.websocket.host.0.key: $OWGW_ROOT/certs/websocket-key.pem
|
||||
ucentral.websocket.host.0.clientcas: $OWGW_ROOT/certs/clientcas.pem
|
||||
ucentral.websocket.host.0.cas: $OWGW_ROOT/certs/cas
|
||||
ucentral.websocket.host.0.address: "*"
|
||||
ucentral.websocket.host.0.port: 15002
|
||||
ucentral.websocket.host.0.security: strict
|
||||
ucentral.websocket.maxreactors: 20
|
||||
# REST API
|
||||
ucentral.restapi.host.0.backlog: 100
|
||||
ucentral.restapi.host.0.security: relaxed
|
||||
ucentral.restapi.host.0.rootca: $UCENTRALGW_ROOT/certs/restapi-ca.pem
|
||||
ucentral.restapi.host.0.address: "*"
|
||||
ucentral.restapi.host.0.port: 16002
|
||||
ucentral.restapi.host.0.cert: $UCENTRALGW_ROOT/certs/restapi-cert.pem
|
||||
ucentral.restapi.host.0.key: $UCENTRALGW_ROOT/certs/restapi-key.pem
|
||||
ucentral.internal.restapi.host.0.backlog: 100
|
||||
ucentral.internal.restapi.host.0.security: relaxed
|
||||
ucentral.internal.restapi.host.0.rootca: $UCENTRALGW_ROOT/certs/restapi-ca.pem
|
||||
ucentral.internal.restapi.host.0.address: "*"
|
||||
ucentral.internal.restapi.host.0.port: 17002
|
||||
ucentral.internal.restapi.host.0.cert: $UCENTRALGW_ROOT/certs/restapi-cert.pem
|
||||
ucentral.internal.restapi.host.0.key: $UCENTRALGW_ROOT/certs/restapi-key.pem
|
||||
openwifi.restapi.host.0.backlog: 100
|
||||
openwifi.restapi.host.0.security: relaxed
|
||||
openwifi.restapi.host.0.rootca: $OWGW_ROOT/certs/restapi-ca.pem
|
||||
openwifi.restapi.host.0.address: "*"
|
||||
openwifi.restapi.host.0.port: 16002
|
||||
openwifi.restapi.host.0.cert: $OWGW_ROOT/certs/restapi-cert.pem
|
||||
openwifi.restapi.host.0.key: $OWGW_ROOT/certs/restapi-key.pem
|
||||
openwifi.internal.restapi.host.0.backlog: 100
|
||||
openwifi.internal.restapi.host.0.security: relaxed
|
||||
openwifi.internal.restapi.host.0.rootca: $OWGW_ROOT/certs/restapi-ca.pem
|
||||
openwifi.internal.restapi.host.0.address: "*"
|
||||
openwifi.internal.restapi.host.0.port: 17002
|
||||
openwifi.internal.restapi.host.0.cert: $OWGW_ROOT/certs/restapi-cert.pem
|
||||
openwifi.internal.restapi.host.0.key: $OWGW_ROOT/certs/restapi-key.pem
|
||||
# File uploader
|
||||
ucentral.fileuploader.host.0.backlog: 100
|
||||
ucentral.fileuploader.host.0.rootca: $UCENTRALGW_ROOT/certs/restapi-ca.pem
|
||||
ucentral.fileuploader.host.0.security: relaxed
|
||||
ucentral.fileuploader.host.0.address: "*"
|
||||
ucentral.fileuploader.host.0.name: localhost
|
||||
ucentral.fileuploader.host.0.port: 16003
|
||||
ucentral.fileuploader.host.0.cert: $UCENTRALGW_ROOT/certs/restapi-cert.pem
|
||||
ucentral.fileuploader.host.0.key: $UCENTRALGW_ROOT/certs/restapi-key.pem
|
||||
ucentral.fileuploader.path: $UCENTRALGW_ROOT/persist/uploads
|
||||
ucentral.fileuploader.maxsize: 10000
|
||||
openwifi.fileuploader.host.0.backlog: 100
|
||||
openwifi.fileuploader.host.0.rootca: $OWGW_ROOT/certs/restapi-ca.pem
|
||||
openwifi.fileuploader.host.0.security: relaxed
|
||||
openwifi.fileuploader.host.0.address: "*"
|
||||
openwifi.fileuploader.host.0.name: localhost
|
||||
openwifi.fileuploader.host.0.port: 16003
|
||||
openwifi.fileuploader.host.0.cert: $OWGW_ROOT/certs/restapi-cert.pem
|
||||
openwifi.fileuploader.host.0.key: $OWGW_ROOT/certs/restapi-key.pem
|
||||
openwifi.fileuploader.path: $OWGW_ROOT/uploads
|
||||
openwifi.fileuploader.maxsize: 10000
|
||||
# Auto provisioning
|
||||
ucentral.autoprovisioning: "true"
|
||||
ucentral.devicetypes.0: AP:linksys_ea8300,edgecore_eap101,linksys_e8450-ubi
|
||||
ucentral.devicetypes.1: SWITCH:edgecore_ecs4100-12ph
|
||||
ucentral.devicetypes.2: IOT:esp32
|
||||
openwifi.autoprovisioning: "true"
|
||||
openwifi.devicetypes.0: AP:linksys_ea8300,edgecore_eap101,linksys_e8450-ubi
|
||||
openwifi.devicetypes.1: SWITCH:edgecore_ecs4100-12ph
|
||||
openwifi.devicetypes.2: IOT:esp32
|
||||
oui.download.uri: https://linuxnet.ca/ieee/oui.txt
|
||||
firmware.autoupdate.policy.default: auto
|
||||
# Callback
|
||||
ucentral.callback.enable: "false"
|
||||
ucentral.callback.0.local: localhost:16001
|
||||
ucentral.callback.0.remote: localhost:15055
|
||||
ucentral.callback.0.topics: ucentralfws
|
||||
openwifi.callback.enable: "false"
|
||||
openwifi.callback.0.local: localhost:16001
|
||||
openwifi.callback.0.remote: localhost:15055
|
||||
openwifi.callback.0.topics: owfws
|
||||
# rtty
|
||||
rtty.enabled: "true"
|
||||
rtty.server: localhost
|
||||
@@ -195,12 +204,12 @@ configProperties:
|
||||
alb.enable: "true"
|
||||
alb.port: 16102
|
||||
# Kafka
|
||||
ucentral.kafka.enable: "false"
|
||||
ucentral.kafka.group.id: gateway
|
||||
ucentral.kafka.client.id: gateway1
|
||||
ucentral.kafka.brokerlist: localhost:9092
|
||||
ucentral.kafka.auto.commit: false
|
||||
ucentral.kafka.queue.buffering.max.ms: 50
|
||||
openwifi.kafka.enable: "false"
|
||||
openwifi.kafka.group.id: gateway
|
||||
openwifi.kafka.client.id: gateway1
|
||||
openwifi.kafka.brokerlist: localhost:9092
|
||||
openwifi.kafka.auto.commit: false
|
||||
openwifi.kafka.queue.buffering.max.ms: 50
|
||||
# Storage
|
||||
storage.type: sqlite # (sqlite|postgresql|mysql|odbc)
|
||||
## SQLite
|
||||
@@ -211,23 +220,23 @@ configProperties:
|
||||
storage.type.postgresql.maxsessions: 64
|
||||
storage.type.postgresql.idletime: 60
|
||||
storage.type.postgresql.host: localhost
|
||||
storage.type.postgresql.database: ucentral
|
||||
storage.type.postgresql.database: owgw
|
||||
storage.type.postgresql.port: 5432
|
||||
storage.type.postgresql.connectiontimeout: 60
|
||||
## MySQL
|
||||
storage.type.mysql.maxsessions: 64
|
||||
storage.type.mysql.idletime: 60
|
||||
storage.type.mysql.host: localhost
|
||||
storage.type.mysql.database: ucentral
|
||||
storage.type.mysql.database: owgw
|
||||
storage.type.mysql.port: 3306
|
||||
storage.type.mysql.connectiontimeout: 60
|
||||
# System
|
||||
ucentral.service.key: $UCENTRALGW_ROOT/certs/restapi-key.pem
|
||||
ucentral.system.data: $UCENTRALGW_ROOT/persist
|
||||
ucentral.system.debug: "true"
|
||||
ucentral.system.uri.private: https://localhost:17002
|
||||
ucentral.system.uri.public: https://localhost:16002
|
||||
ucentral.system.commandchannel: /tmp/app_ucentralgw
|
||||
openwifi.service.key: $OWGW_ROOT/certs/restapi-key.pem
|
||||
openwifi.system.data: $OWGW_ROOT/persist
|
||||
openwifi.system.debug: "true"
|
||||
openwifi.system.uri.private: https://localhost:17002
|
||||
openwifi.system.uri.public: https://localhost:16002
|
||||
openwifi.system.commandchannel: /tmp/app_owgw
|
||||
# Logging
|
||||
logging.formatters.f1.class: PatternFormatter
|
||||
logging.formatters.f1.pattern: "%Y-%m-%d %H:%M:%S %s: [%p] %t"
|
||||
@@ -235,7 +244,7 @@ configProperties:
|
||||
logging.channels.c1.class: ConsoleChannel
|
||||
logging.channels.c1.formatter: f1
|
||||
logging.channels.c2.class: FileChannel
|
||||
logging.channels.c2.path: /tmp/log_ucentralgw
|
||||
logging.channels.c2.path: /tmp/log_owgw
|
||||
logging.channels.c2.formatter.class: PatternFormatter
|
||||
logging.channels.c2.formatter.pattern: "%Y-%m-%d %H:%M:%S %s: [%p] %t"
|
||||
logging.channels.c2.rotation: "20 M"
|
||||
@@ -250,14 +259,14 @@ configProperties:
|
||||
# Websocket
|
||||
ucentral.websocket.host.0.key.password: mypassword
|
||||
# REST API
|
||||
ucentral.restapi.host.0.key.password: mypassword
|
||||
ucentral.internal.restapi.host.0.key.password: mypassword
|
||||
openwifi.restapi.host.0.key.password: mypassword
|
||||
openwifi.internal.restapi.host.0.key.password: mypassword
|
||||
# File uploader
|
||||
ucentral.fileuploader.host.0.key.password: mypassword
|
||||
openwifi.fileuploader.host.0.key.password: mypassword
|
||||
# Callback
|
||||
ucentral.callback.id: qblat6dfDHxQAZ6yMe6MrypBpgRDhQrhUtTOovOXAKAWU8qOvjjKKiUai4t9hGjA
|
||||
ucentral.callback.0.localkey: t2dEOc88OIxVDb94mw7SLcLocgnCzZzzFoQ4JJv3OCU9UO6Ou5ds5Dh4CfBnHgrk
|
||||
ucentral.callback.0.remotekey: t2dEOc88OIxVDb94mw7SLcLocgnCzZzzFoQ4JJv3OCU9UO6Ou5ds5Dh4CfBnHgrk
|
||||
openwifi.callback.id: qblat6dfDHxQAZ6yMe6MrypBpgRDhQrhUtTOovOXAKAWU8qOvjjKKiUai4t9hGjA
|
||||
openwifi.callback.0.localkey: t2dEOc88OIxVDb94mw7SLcLocgnCzZzzFoQ4JJv3OCU9UO6Ou5ds5Dh4CfBnHgrk
|
||||
openwifi.callback.0.remotekey: t2dEOc88OIxVDb94mw7SLcLocgnCzZzzFoQ4JJv3OCU9UO6Ou5ds5Dh4CfBnHgrk
|
||||
# rtty
|
||||
rtty.token: 96181c567b4d0d98c50f127230068fa8
|
||||
# Storage
|
||||
@@ -438,10 +447,10 @@ postgresql:
|
||||
repository: bitnami/postgresql
|
||||
tag: 11.13.0-debian-10-r0
|
||||
|
||||
postgresqlPostgresPassword: ""
|
||||
postgresqlUsername: postgres
|
||||
postgresqlPassword: ""
|
||||
postgresqlDatabase: ""
|
||||
postgresqlPostgresPassword: "rootPassword"
|
||||
postgresqlUsername: stephb
|
||||
postgresqlPassword: snoopy99
|
||||
postgresqlDatabase: owgw
|
||||
|
||||
persistence:
|
||||
enabled: true
|
||||
@@ -458,10 +467,10 @@ mysql:
|
||||
tag: 8.0.26-debian-10-r10
|
||||
|
||||
auth:
|
||||
rootPassword: ""
|
||||
database: my_database
|
||||
username: ""
|
||||
password: ""
|
||||
rootPassword: rootPassword
|
||||
database: owgw
|
||||
username: stephb
|
||||
password: snoopy99
|
||||
|
||||
primary:
|
||||
persistence:
|
||||
@@ -479,10 +488,10 @@ mariadb:
|
||||
tag: 10.5.12-debian-10-r0
|
||||
|
||||
auth:
|
||||
rootPassword: ""
|
||||
database: my_database
|
||||
username: ""
|
||||
password: ""
|
||||
rootPassword: rootPassword
|
||||
database: owgw
|
||||
username: stephb
|
||||
password: snoopy99
|
||||
|
||||
primary:
|
||||
persistence:
|
||||
|
@@ -91,6 +91,9 @@ components:
|
||||
location:
|
||||
type: string
|
||||
format: uuid
|
||||
venue:
|
||||
type: string
|
||||
format: uuid
|
||||
serialNumber:
|
||||
type: string
|
||||
deviceType:
|
||||
@@ -631,6 +634,42 @@ components:
|
||||
associations:
|
||||
$ref: '#/components/schemas/TagIntPairList'
|
||||
|
||||
TelemetryStreamRequest:
|
||||
type: object
|
||||
properties:
|
||||
serialNumber:
|
||||
type: string
|
||||
interval:
|
||||
type: integer
|
||||
example:
|
||||
0 - means to stop streaming, values 1-120 in seconds.
|
||||
types:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
enum:
|
||||
- dhcp-snooping
|
||||
- wire-frames
|
||||
- state
|
||||
uuid:
|
||||
type: string
|
||||
example:
|
||||
only valid when terminating a stream
|
||||
|
||||
TelemetryStreamResponse:
|
||||
type: object
|
||||
properties:
|
||||
serialNumber:
|
||||
type: string
|
||||
uuid:
|
||||
type: string
|
||||
format: uuid
|
||||
uri:
|
||||
type: string
|
||||
format: uri
|
||||
example:
|
||||
wss://host.domain:port/endpoint
|
||||
|
||||
#########################################################################################
|
||||
##
|
||||
## These are endpoints that all services in the uCentral stack must provide
|
||||
@@ -716,6 +755,107 @@ components:
|
||||
note:
|
||||
type: string
|
||||
|
||||
SystemInfoResults:
|
||||
type: object
|
||||
properties:
|
||||
version:
|
||||
type: string
|
||||
uptime:
|
||||
type: integer
|
||||
format: integer64
|
||||
start:
|
||||
type: integer
|
||||
format: integer64
|
||||
os:
|
||||
type: string
|
||||
processors:
|
||||
type: integer
|
||||
hostname:
|
||||
type: string
|
||||
certificates:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
filename:
|
||||
type: string
|
||||
expires:
|
||||
type: integer
|
||||
format: int64
|
||||
|
||||
SystemCommandSetLogLevel:
|
||||
type: object
|
||||
properties:
|
||||
command:
|
||||
type: string
|
||||
enum:
|
||||
- setloglevel
|
||||
subsystems:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/TagValuePair'
|
||||
|
||||
SystemCommandReload:
|
||||
type: object
|
||||
properties:
|
||||
command:
|
||||
type: string
|
||||
enum:
|
||||
- reload
|
||||
subsystems:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
example: these are the SubSystems names retrieve with the GetSubSystemsNamesResult.
|
||||
|
||||
SystemCommandGetLogLevels:
|
||||
type: object
|
||||
properties:
|
||||
command:
|
||||
type: string
|
||||
enum:
|
||||
- getloglevels
|
||||
|
||||
SystemGetLogLevelsResult:
|
||||
type: object
|
||||
properties:
|
||||
taglist:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/TagValuePair'
|
||||
|
||||
SystemCommandGetLogLevelNames:
|
||||
type: object
|
||||
properties:
|
||||
command:
|
||||
type: string
|
||||
enum:
|
||||
- getloglevelnames
|
||||
|
||||
SystemCommandGetSubsystemNames:
|
||||
type: object
|
||||
properties:
|
||||
command:
|
||||
type: string
|
||||
enum:
|
||||
- getsubsystemnames
|
||||
|
||||
SystemCommandGetLogLevelNamesResult:
|
||||
type: object
|
||||
properties:
|
||||
list:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
|
||||
SystemGetSubSystemNamesResult:
|
||||
type: object
|
||||
properties:
|
||||
taglist:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/TagValuePair'
|
||||
|
||||
#########################################################################################
|
||||
##
|
||||
## End of uCentral system wide values
|
||||
@@ -829,6 +969,22 @@ components:
|
||||
password:
|
||||
type: string
|
||||
|
||||
CapabilitiesModel:
|
||||
type: object
|
||||
properties:
|
||||
deviceType:
|
||||
type: string
|
||||
capabilities:
|
||||
type: string
|
||||
|
||||
CapabilitiesModelList:
|
||||
type: object
|
||||
properties:
|
||||
devices:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/CapabilitiesModel'
|
||||
|
||||
paths:
|
||||
/devices:
|
||||
get:
|
||||
@@ -986,7 +1142,7 @@ paths:
|
||||
get:
|
||||
tags:
|
||||
- Commands
|
||||
summary: Returns a specific command
|
||||
summary: Returns a specific command.
|
||||
description: Returns a specific command
|
||||
operationId: getACommandDetails
|
||||
parameters:
|
||||
@@ -1011,7 +1167,7 @@ paths:
|
||||
delete:
|
||||
tags:
|
||||
- Commands
|
||||
summary: Delete a specific command
|
||||
summary: Delete a specific command.
|
||||
description: Delete a specific command
|
||||
operationId: deleteACommand
|
||||
parameters:
|
||||
@@ -1037,8 +1193,8 @@ paths:
|
||||
get:
|
||||
tags:
|
||||
- Configurations
|
||||
summary: Retrieve the lists of all default configurations
|
||||
description: Retrieve the lists of all default configurations
|
||||
summary: Retrieve the lists of all default configurations.
|
||||
description: Retrieve the lists of all default configurations.
|
||||
operationId: getDefaultConfigurations
|
||||
|
||||
responses:
|
||||
@@ -1057,8 +1213,8 @@ paths:
|
||||
get:
|
||||
tags:
|
||||
- Configurations
|
||||
summary: Retrieve a default configuration
|
||||
description: Retrieve a default configuration
|
||||
summary: Retrieve a default configuration.
|
||||
description: Retrieve a default configuration.
|
||||
operationId: getDefaultConfiguration
|
||||
parameters:
|
||||
- in: path
|
||||
@@ -1081,8 +1237,8 @@ paths:
|
||||
post:
|
||||
tags:
|
||||
- Configurations
|
||||
summary: Create a default configuration
|
||||
description: Create a default configuration
|
||||
summary: Create a default configuration.
|
||||
description: Create a default configuration.
|
||||
operationId: createDefaultConfiguration
|
||||
parameters:
|
||||
- in: path
|
||||
@@ -1154,7 +1310,7 @@ paths:
|
||||
get:
|
||||
tags:
|
||||
- Devices
|
||||
summary: Retrieve information for a single device
|
||||
summary: Retrieve information for a single device.
|
||||
description: Retrieve all the inforamtion about a single device
|
||||
operationId: getDeviceInformation
|
||||
parameters:
|
||||
@@ -1178,7 +1334,7 @@ paths:
|
||||
post:
|
||||
tags:
|
||||
- Devices
|
||||
summary: Creating a new device
|
||||
summary: Create a new device.
|
||||
operationId: createNewDevice
|
||||
parameters:
|
||||
- in: path
|
||||
@@ -1186,6 +1342,11 @@ paths:
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
- in: query
|
||||
name: validateOnly
|
||||
schema:
|
||||
type: boolean
|
||||
required: false
|
||||
requestBody:
|
||||
description: Information used to create the new device
|
||||
content:
|
||||
@@ -1207,7 +1368,7 @@ paths:
|
||||
put:
|
||||
tags:
|
||||
- Devices
|
||||
summary: Updating a new device
|
||||
summary: Update a device.
|
||||
operationId: updateNewDevice
|
||||
parameters:
|
||||
- in: path
|
||||
@@ -1236,7 +1397,7 @@ paths:
|
||||
delete:
|
||||
tags:
|
||||
- Devices
|
||||
summary: Deleting a single device
|
||||
summary: Delete a single device.
|
||||
operationId: deleteDevice
|
||||
parameters:
|
||||
- in: path
|
||||
@@ -1313,7 +1474,7 @@ paths:
|
||||
delete:
|
||||
tags:
|
||||
- Commands
|
||||
summary: Delete some device logs
|
||||
summary: Delete some device logs.
|
||||
operationId: deleteDeviceLogs
|
||||
parameters:
|
||||
- in: path
|
||||
@@ -1355,7 +1516,7 @@ paths:
|
||||
get:
|
||||
tags:
|
||||
- Commands
|
||||
summary: Get the latest health checks for a given device
|
||||
summary: Get the latest health checks for a given device.
|
||||
operationId: getDeviceHealthChecks
|
||||
parameters:
|
||||
- in: path
|
||||
@@ -1402,7 +1563,7 @@ paths:
|
||||
|
||||
responses:
|
||||
200:
|
||||
description: Array of device health checks for this device
|
||||
description: Array of device health checks for this device
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
@@ -1415,7 +1576,7 @@ paths:
|
||||
delete:
|
||||
tags:
|
||||
- Commands
|
||||
summary: Delete some device health checks
|
||||
summary: Delete some device health checks.
|
||||
operationId: deleteDeviceHealthChecks
|
||||
parameters:
|
||||
- in: path
|
||||
@@ -1452,7 +1613,7 @@ paths:
|
||||
get:
|
||||
tags:
|
||||
- Commands
|
||||
summary: Get the latest capabilities for a given device
|
||||
summary: Get the latest capabilities for a given device.
|
||||
operationId: getDeviceCapabilities
|
||||
parameters:
|
||||
- in: path
|
||||
@@ -1475,7 +1636,7 @@ paths:
|
||||
delete:
|
||||
tags:
|
||||
- Commands
|
||||
summary: Delete the capabilities for a given device
|
||||
summary: Delete the capabilities for a given device.
|
||||
operationId: deleteDeviceCapabilities
|
||||
parameters:
|
||||
- in: path
|
||||
@@ -1499,7 +1660,7 @@ paths:
|
||||
get:
|
||||
tags:
|
||||
- Commands
|
||||
summary: Get the latest statistics for a given device
|
||||
summary: Get the latest statistics for a given device.
|
||||
operationId: getDeviceStats
|
||||
parameters:
|
||||
- in: path
|
||||
@@ -1567,7 +1728,7 @@ paths:
|
||||
delete:
|
||||
tags:
|
||||
- Commands
|
||||
summary: Get the latest statistics for a given device
|
||||
summary: Get the latest statistics for a given device.
|
||||
operationId: deleteDeviceStats
|
||||
parameters:
|
||||
- in: path
|
||||
@@ -1604,7 +1765,7 @@ paths:
|
||||
get:
|
||||
tags:
|
||||
- Commands
|
||||
summary: Get the latest status for a given device
|
||||
summary: Get the latest status for a given device.
|
||||
operationId: getDeviceStatus
|
||||
parameters:
|
||||
- in: path
|
||||
@@ -1654,7 +1815,7 @@ paths:
|
||||
post:
|
||||
tags:
|
||||
- Commands
|
||||
summary: Configura a device
|
||||
summary: Configure a device.
|
||||
operationId: updateConfigurationForADevice
|
||||
parameters:
|
||||
- in: path
|
||||
@@ -1680,7 +1841,7 @@ paths:
|
||||
post:
|
||||
tags:
|
||||
- Commands
|
||||
summary: Upgrade a device
|
||||
summary: Upgrade a device.
|
||||
operationId: UpgradeDeviceFirmware
|
||||
parameters:
|
||||
- in: path
|
||||
@@ -1706,7 +1867,7 @@ paths:
|
||||
post:
|
||||
tags:
|
||||
- Commands
|
||||
summary: Upgrade a device
|
||||
summary: Reboot a device.
|
||||
operationId: rebootDevice
|
||||
parameters:
|
||||
- in: path
|
||||
@@ -1732,7 +1893,7 @@ paths:
|
||||
post:
|
||||
tags:
|
||||
- Commands
|
||||
summary: Factory reset a device a device
|
||||
summary: Factory reset a device.
|
||||
operationId: factoryReset
|
||||
parameters:
|
||||
- in: path
|
||||
@@ -1758,7 +1919,7 @@ paths:
|
||||
post:
|
||||
tags:
|
||||
- Commands
|
||||
summary: Blink the LEDs on a device
|
||||
summary: Blink the LEDs on a device.
|
||||
operationId: ledsRequest
|
||||
parameters:
|
||||
- in: path
|
||||
@@ -1784,7 +1945,7 @@ paths:
|
||||
post:
|
||||
tags:
|
||||
- Commands
|
||||
summary: Launch a trace for a device
|
||||
summary: Launch a trace for a device.
|
||||
operationId: traceRequest
|
||||
parameters:
|
||||
- in: path
|
||||
@@ -1810,7 +1971,7 @@ paths:
|
||||
post:
|
||||
tags:
|
||||
- Commands
|
||||
summary: Launch a wifi scan for a device
|
||||
summary: Launch a wifi scan for a device.
|
||||
operationId: wifiscanRequest
|
||||
parameters:
|
||||
- in: path
|
||||
@@ -1862,7 +2023,7 @@ paths:
|
||||
post:
|
||||
tags:
|
||||
- Commands
|
||||
summary: Request a list of queued events
|
||||
summary: Request a list of queued events.
|
||||
operationId: eventQueueRequest
|
||||
parameters:
|
||||
- in: path
|
||||
@@ -1884,12 +2045,38 @@ paths:
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/device/{serialNumber}/telemetry:
|
||||
post:
|
||||
tags:
|
||||
- Commands
|
||||
summary: Request a telemetry stream.
|
||||
operationId: eventTelemetryStreamRequest
|
||||
parameters:
|
||||
- in: path
|
||||
name: serialNumber
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
requestBody:
|
||||
description: Message request details
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TelemetryStreamRequest'
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/schemas/TelemetryStreamResponse'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/ouis:
|
||||
get:
|
||||
tags:
|
||||
- OUIs
|
||||
operationId: getOUIs
|
||||
summary: Get a list of OUIs
|
||||
summary: Get a list of OUIs.
|
||||
parameters:
|
||||
- in: query
|
||||
name: macList
|
||||
@@ -1908,7 +2095,7 @@ paths:
|
||||
get:
|
||||
tags:
|
||||
- Commands
|
||||
summary: Get the rtty parameters to initiate a session
|
||||
summary: Get the rtty parameters to initiate a session.
|
||||
operationId: getRttySessionInfo
|
||||
parameters:
|
||||
- in: path
|
||||
@@ -1932,7 +2119,7 @@ paths:
|
||||
get:
|
||||
tags:
|
||||
- Files
|
||||
summary: Get a file from the upload directory
|
||||
summary: Get a file from the upload directory.
|
||||
operationId: getUploadFile
|
||||
parameters:
|
||||
- in: path
|
||||
@@ -1962,7 +2149,7 @@ paths:
|
||||
delete:
|
||||
tags:
|
||||
- Files
|
||||
summary: Delete a file from the upload directory
|
||||
summary: Delete a file from the upload directory.
|
||||
operationId: deleteUploadFidelete
|
||||
parameters:
|
||||
- in: path
|
||||
@@ -1989,7 +2176,7 @@ paths:
|
||||
tags:
|
||||
- Blacklist
|
||||
summary: Returns a list blacklisted devices.
|
||||
description: Get a list of blacklisteddevices.
|
||||
description: Get a list of blacklisted devices.
|
||||
operationId: getBlacklistDeviceList
|
||||
parameters:
|
||||
- in: query
|
||||
@@ -2022,17 +2209,76 @@ paths:
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/blacklist/{serialNumber}:
|
||||
get:
|
||||
tags:
|
||||
- Blacklist
|
||||
summary: Returns a blacklist entry.
|
||||
description: Get a list of blacklisted devices.
|
||||
operationId: getBlacklistDevice
|
||||
parameters:
|
||||
- in: path
|
||||
description: Pagination start (starts at 1. If not specified, 1 is assumed)
|
||||
name: serialNumber
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
responses:
|
||||
200:
|
||||
description: List blacklisted devices
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/BlackDeviceInfo'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
post:
|
||||
tags:
|
||||
- Blacklist
|
||||
summary: Adds to the blacklist
|
||||
operationId: addToBlackList
|
||||
summary: Create to the blacklist.
|
||||
operationId: createBlackListDevice
|
||||
parameters:
|
||||
- in: path
|
||||
description: Pagination start (starts at 1. If not specified, 1 is assumed)
|
||||
name: serialNumber
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
requestBody:
|
||||
description: Add blacklisted device
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/BlackDeviceInfo'
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/responses/Success'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
put:
|
||||
tags:
|
||||
- Blacklist
|
||||
summary: Modify to the blacklist.
|
||||
operationId: modifyBlackList
|
||||
parameters:
|
||||
- in: path
|
||||
description: Pagination start (starts at 1. If not specified, 1 is assumed)
|
||||
name: serialNumber
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
requestBody:
|
||||
description: Add blacklisted devices
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/BlackDeviceList'
|
||||
$ref: '#/components/schemas/BlackDeviceInfo'
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/responses/Success'
|
||||
@@ -2044,11 +2290,10 @@ paths:
|
||||
delete:
|
||||
tags:
|
||||
- Blacklist
|
||||
summary: Delete from the blacklist
|
||||
summary: Delete from the blacklist.
|
||||
operationId: deleteFromBlackList
|
||||
parameters:
|
||||
- in: query
|
||||
description: Serial Number
|
||||
- in: path
|
||||
name: serialNumber
|
||||
schema:
|
||||
type: string
|
||||
@@ -2061,11 +2306,29 @@ paths:
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/capabilities:
|
||||
get:
|
||||
tags:
|
||||
- Devices
|
||||
summary: Get the list of device types and capabilities.
|
||||
operationId: getCapabilitiesList
|
||||
responses:
|
||||
200:
|
||||
description: Successful command execution
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/CapabilitiesModelList'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/deviceDashboard:
|
||||
get:
|
||||
tags:
|
||||
- Dashboards
|
||||
summary: Get the last version of the dashboard
|
||||
summary: Get the last version of the dashboard.
|
||||
operationId: getDeviceDashboard
|
||||
responses:
|
||||
200:
|
||||
@@ -2080,26 +2343,33 @@ paths:
|
||||
## These are endpoints that all services in the uCentral stack must provide
|
||||
##
|
||||
#########################################################################################
|
||||
|
||||
/system:
|
||||
post:
|
||||
tags:
|
||||
- System Commands
|
||||
summary: Perform some systeme wide commands
|
||||
summary: Perform some system wide commands.
|
||||
operationId: systemCommand
|
||||
requestBody:
|
||||
description: Command details
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SystemCommandDetails'
|
||||
oneOf:
|
||||
- $ref: '#/components/schemas/SystemCommandSetLogLevel'
|
||||
- $ref: '#/components/schemas/SystemCommandReload'
|
||||
- $ref: '#/components/schemas/SystemCommandGetLogLevels'
|
||||
- $ref: '#/components/schemas/SystemCommandGetLogLevelNames'
|
||||
- $ref: '#/components/schemas/SystemCommandGetSubsystemNames'
|
||||
responses:
|
||||
200:
|
||||
description: Successfull command execution
|
||||
description: Successful command execution
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SystemCommandResults'
|
||||
oneOf:
|
||||
- $ref: '#/components/schemas/SystemGetLogLevelsResult'
|
||||
- $ref: '#/components/schemas/SystemCommandGetLogLevelNamesResult'
|
||||
- $ref: '#/components/schemas/SystemGetSubSystemNamesResult'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
@@ -2116,18 +2386,18 @@ paths:
|
||||
schema:
|
||||
type: string
|
||||
enum:
|
||||
- version
|
||||
- times
|
||||
- info
|
||||
required: true
|
||||
|
||||
responses:
|
||||
200:
|
||||
description: Successfull command execution
|
||||
description: Successful command execution
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TagValuePair'
|
||||
oneOf:
|
||||
- $ref: '#/components/schemas/SystemInfoResults'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
$ref: '#/components/responses/NotFound'
|
@@ -4,12 +4,12 @@
|
||||
# address of one of your interfaces
|
||||
#
|
||||
ucentral.websocket.host.0.backlog = 500
|
||||
ucentral.websocket.host.0.rootca = $UCENTRALGW_ROOT/certs/root.pem
|
||||
ucentral.websocket.host.0.issuer = $UCENTRALGW_ROOT/certs/issuer.pem
|
||||
ucentral.websocket.host.0.cert = $UCENTRALGW_ROOT/certs/websocket-cert.pem
|
||||
ucentral.websocket.host.0.key = $UCENTRALGW_ROOT/certs/websocket-key.pem
|
||||
ucentral.websocket.host.0.clientcas = $UCENTRALGW_ROOT/certs/clientcas.pem
|
||||
ucentral.websocket.host.0.cas = $UCENTRALGW_ROOT/certs/cas
|
||||
ucentral.websocket.host.0.rootca = $OWGW_ROOT/certs/root.pem
|
||||
ucentral.websocket.host.0.issuer = $OWGW_ROOT/certs/issuer.pem
|
||||
ucentral.websocket.host.0.cert = $OWGW_ROOT/certs/websocket-cert.pem
|
||||
ucentral.websocket.host.0.key = $OWGW_ROOT/certs/websocket-key.pem
|
||||
ucentral.websocket.host.0.clientcas = $OWGW_ROOT/certs/clientcas.pem
|
||||
ucentral.websocket.host.0.cas = $OWGW_ROOT/certs/cas
|
||||
ucentral.websocket.host.0.address = *
|
||||
ucentral.websocket.host.0.port = 15002
|
||||
ucentral.websocket.host.0.security = strict
|
||||
@@ -19,60 +19,61 @@ ucentral.websocket.maxreactors = 20
|
||||
#
|
||||
# REST API access
|
||||
#
|
||||
ucentral.restapi.host.0.backlog = 100
|
||||
ucentral.restapi.host.0.security = relaxed
|
||||
ucentral.restapi.host.0.rootca = $UCENTRALGW_ROOT/certs/restapi-ca.pem
|
||||
ucentral.restapi.host.0.address = *
|
||||
ucentral.restapi.host.0.port = 16002
|
||||
ucentral.restapi.host.0.cert = $UCENTRALGW_ROOT/certs/restapi-cert.pem
|
||||
ucentral.restapi.host.0.key = $UCENTRALGW_ROOT/certs/restapi-key.pem
|
||||
ucentral.restapi.host.0.key.password = mypassword
|
||||
openwifi.restapi.host.0.backlog = 100
|
||||
openwifi.restapi.host.0.security = relaxed
|
||||
openwifi.restapi.host.0.rootca = $OWGW_ROOT/certs/restapi-ca.pem
|
||||
openwifi.restapi.host.0.address = *
|
||||
openwifi.restapi.host.0.port = 16002
|
||||
openwifi.restapi.host.0.cert = $OWGW_ROOT/certs/restapi-cert.pem
|
||||
openwifi.restapi.host.0.key = $OWGW_ROOT/certs/restapi-key.pem
|
||||
openwifi.restapi.host.0.key.password = mypassword
|
||||
|
||||
ucentral.internal.restapi.host.0.backlog = 100
|
||||
ucentral.internal.restapi.host.0.security = relaxed
|
||||
ucentral.internal.restapi.host.0.rootca = $UCENTRALGW_ROOT/certs/restapi-ca.pem
|
||||
ucentral.internal.restapi.host.0.address = *
|
||||
ucentral.internal.restapi.host.0.port = 17002
|
||||
ucentral.internal.restapi.host.0.cert = $UCENTRALGW_ROOT/certs/restapi-cert.pem
|
||||
ucentral.internal.restapi.host.0.key = $UCENTRALGW_ROOT/certs/restapi-key.pem
|
||||
ucentral.internal.restapi.host.0.key.password = mypassword
|
||||
openwifi.internal.restapi.host.0.backlog = 100
|
||||
openwifi.internal.restapi.host.0.security = relaxed
|
||||
openwifi.internal.restapi.host.0.rootca = $OWGW_ROOT/certs/restapi-ca.pem
|
||||
openwifi.internal.restapi.host.0.address = *
|
||||
openwifi.internal.restapi.host.0.port = 17002
|
||||
openwifi.internal.restapi.host.0.cert = $OWGW_ROOT/certs/restapi-cert.pem
|
||||
openwifi.internal.restapi.host.0.key = $OWGW_ROOT/certs/restapi-key.pem
|
||||
openwifi.internal.restapi.host.0.key.password = mypassword
|
||||
|
||||
#
|
||||
# Used to upload files to the service.
|
||||
# You should replace the 'name' vaalue with the IP address of your gateway or an FQDN
|
||||
# that your devices can reach
|
||||
#
|
||||
ucentral.fileuploader.host.0.backlog = 100
|
||||
ucentral.fileuploader.host.0.rootca = $UCENTRALGW_ROOT/certs/restapi-ca.pem
|
||||
ucentral.fileuploader.host.0.security = relaxed
|
||||
ucentral.fileuploader.host.0.address = *
|
||||
ucentral.fileuploader.host.0.name = ucentral.dpaas.arilia.com
|
||||
ucentral.fileuploader.host.0.port = 16003
|
||||
ucentral.fileuploader.host.0.cert = $UCENTRALGW_ROOT/certs/restapi-cert.pem
|
||||
ucentral.fileuploader.host.0.key = $UCENTRALGW_ROOT/certs/restapi-key.pem
|
||||
ucentral.fileuploader.host.0.key.password = mypassword
|
||||
ucentral.fileuploader.path = $UCENTRALGW_ROOT/uploads
|
||||
ucentral.fileuploader.maxsize = 10000
|
||||
openwifi.fileuploader.host.0.backlog = 100
|
||||
openwifi.fileuploader.host.0.rootca = $OWGW_ROOT/certs/restapi-ca.pem
|
||||
openwifi.fileuploader.host.0.security = relaxed
|
||||
openwifi.fileuploader.host.0.address = *
|
||||
openwifi.fileuploader.host.0.name = ucentral.dpaas.arilia.com
|
||||
openwifi.fileuploader.host.0.port = 16003
|
||||
openwifi.fileuploader.host.0.cert = $OWGW_ROOT/certs/restapi-cert.pem
|
||||
openwifi.fileuploader.host.0.key = $OWGW_ROOT/certs/restapi-key.pem
|
||||
openwifi.fileuploader.host.0.key.password = mypassword
|
||||
openwifi.fileuploader.path = $OWGW_ROOT/uploads
|
||||
openwifi.fileuploader.maxsize = 10000
|
||||
openwifi.fileuploader.uri = https://ucentral.dpaas.arilia.com:16003
|
||||
|
||||
#
|
||||
# Generic section that all microservices must have
|
||||
#
|
||||
ucentral.service.key = $UCENTRALGW_ROOT/certs/restapi-key.pem
|
||||
ucentral.service.key.password = mypassword
|
||||
ucentral.system.data = $UCENTRALGW_ROOT/data
|
||||
ucentral.system.debug = true
|
||||
ucentral.system.uri.private = https://localhost:17002
|
||||
ucentral.system.uri.public = https://local.dpaas.arilia.com:16002
|
||||
ucentral.system.uri.ui = https://ucentral-ui.arilia.com
|
||||
ucentral.system.commandchannel = /tmp/app.ucentralgw
|
||||
openwifi.service.key = $OWGW_ROOT/certs/restapi-key.pem
|
||||
openwifi.service.key.password = mypassword
|
||||
openwifi.system.data = $OWGW_ROOT/data
|
||||
openwifi.system.debug = true
|
||||
openwifi.system.uri.private = https://localhost:17002
|
||||
openwifi.system.uri.public = https://ucentral.dpaas.arilia.com:16002
|
||||
openwifi.system.uri.ui = https://ucentral-ui.arilia.com
|
||||
openwifi.system.commandchannel = /tmp/app.ucentralgw
|
||||
|
||||
#
|
||||
# Gateway Microservice Specific Section
|
||||
#
|
||||
ucentral.autoprovisioning = true
|
||||
ucentral.devicetypes.0 = AP:linksys_ea8300,edgecore_eap101,linksys_e8450-ubi
|
||||
ucentral.devicetypes.1 = SWITCH:edgecore_ecs4100-12ph
|
||||
ucentral.devicetypes.2 = IOT:esp32
|
||||
openwifi.autoprovisioning = true
|
||||
openwifi.devicetypes.0 = AP:linksys_ea8300,edgecore_eap101,linksys_e8450-ubi
|
||||
openwifi.devicetypes.1 = SWITCH:edgecore_ecs4100-12ph
|
||||
openwifi.devicetypes.2 = IOT:esp32
|
||||
oui.download.uri = https://linuxnet.ca/ieee/oui.txt
|
||||
firmware.autoupdate.policy.default = auto
|
||||
|
||||
@@ -98,13 +99,12 @@ alb.port = 16102
|
||||
#
|
||||
# Kafka
|
||||
#
|
||||
ucentral.kafka.group.id = gateway
|
||||
ucentral.kafka.client.id = gateway1
|
||||
ucentral.kafka.enable = true
|
||||
# ucentral.kafka.brokerlist = a1.arilia.com:9092
|
||||
ucentral.kafka.brokerlist = debfarm1-node-c.arilia.com:9092
|
||||
ucentral.kafka.auto.commit = false
|
||||
ucentral.kafka.queue.buffering.max.ms = 50
|
||||
openwifi.kafka.group.id = gateway
|
||||
openwifi.kafka.client.id = gateway1
|
||||
openwifi.kafka.enable = true
|
||||
openwifi.kafka.brokerlist = a1.arilia.com:9092
|
||||
openwifi.kafka.auto.commit = false
|
||||
openwifi.kafka.queue.buffering.max.ms = 50
|
||||
|
||||
#
|
||||
# This section select which form of persistence you need
|
||||
@@ -164,7 +164,7 @@ logging.channels.c1.formatter = f1
|
||||
|
||||
# This is where the logs will be written. This path MUST exist
|
||||
logging.channels.c2.class = FileChannel
|
||||
logging.channels.c2.path = $UCENTRALGW_ROOT/logs/log
|
||||
logging.channels.c2.path = $OWGW_ROOT/logs/log
|
||||
logging.channels.c2.formatter.class = PatternFormatter
|
||||
logging.channels.c2.formatter.pattern = %Y-%m-%d %H:%M:%S %s: [%p] %t
|
||||
logging.channels.c2.rotation = 20 M
|
189
owgw.properties.tmpl
Normal file
189
owgw.properties.tmpl
Normal file
@@ -0,0 +1,189 @@
|
||||
#
|
||||
# uCentral protocol server for devices. This is where you point
|
||||
# all your devices. You can replace the * for address by the specific
|
||||
# address of one of your interfaces
|
||||
#
|
||||
ucentral.websocket.host.0.backlog = 500
|
||||
ucentral.websocket.host.0.rootca = ${WEBSOCKET_HOST_ROOTCA}
|
||||
ucentral.websocket.host.0.issuer = ${WEBSOCKET_HOST_ISSUER}
|
||||
ucentral.websocket.host.0.cert = ${WEBSOCKET_HOST_CERT}
|
||||
ucentral.websocket.host.0.key = ${WEBSOCKET_HOST_KEY}
|
||||
ucentral.websocket.host.0.clientcas = ${WEBSOCKET_HOST_CLIENTCAS}
|
||||
ucentral.websocket.host.0.cas = ${WEBSOCKET_HOST_CAS}
|
||||
ucentral.websocket.host.0.address = *
|
||||
ucentral.websocket.host.0.port = ${WEBSOCKET_HOST_PORT}
|
||||
ucentral.websocket.host.0.security = strict
|
||||
ucentral.websocket.host.0.key.password = ${WEBSOCKET_HOST_KEY_PASSWORD}
|
||||
ucentral.websocket.maxreactors = 20
|
||||
|
||||
#
|
||||
# REST API access
|
||||
#
|
||||
openwifi.restapi.host.0.backlog = 100
|
||||
openwifi.restapi.host.0.security = relaxed
|
||||
openwifi.restapi.host.0.rootca = ${RESTAPI_HOST_ROOTCA}
|
||||
openwifi.restapi.host.0.address = *
|
||||
openwifi.restapi.host.0.port = ${RESTAPI_HOST_PORT}
|
||||
openwifi.restapi.host.0.cert = ${RESTAPI_HOST_CERT}
|
||||
openwifi.restapi.host.0.key = ${RESTAPI_HOST_KEY}
|
||||
openwifi.restapi.host.0.key.password = ${RESTAPI_HOST_KEY_PASSWORD}
|
||||
|
||||
openwifi.internal.restapi.host.0.backlog = 100
|
||||
openwifi.internal.restapi.host.0.security = relaxed
|
||||
openwifi.internal.restapi.host.0.rootca = ${INTERNAL_RESTAPI_HOST_ROOTCA}
|
||||
openwifi.internal.restapi.host.0.address = *
|
||||
openwifi.internal.restapi.host.0.port = ${INTERNAL_RESTAPI_HOST_PORT}
|
||||
openwifi.internal.restapi.host.0.cert = ${INTERNAL_RESTAPI_HOST_CERT}
|
||||
openwifi.internal.restapi.host.0.key = ${INTERNAL_RESTAPI_HOST_KEY}
|
||||
openwifi.internal.restapi.host.0.key.password = ${INTERNAL_RESTAPI_HOST_KEY_PASSWORD}
|
||||
|
||||
#
|
||||
# Used to upload files to the service.
|
||||
# You should replace the 'name' vaalue with the IP address of your gateway or an FQDN
|
||||
# that your devices can reach
|
||||
#
|
||||
openwifi.fileuploader.host.0.backlog = 100
|
||||
openwifi.fileuploader.host.0.rootca = ${FILEUPLOADER_HOST_ROOTCA}
|
||||
openwifi.fileuploader.host.0.security = relaxed
|
||||
openwifi.fileuploader.host.0.address = *
|
||||
openwifi.fileuploader.host.0.name = ${FILEUPLOADER_HOST_NAME}
|
||||
openwifi.fileuploader.host.0.port = ${FILEUPLOADER_HOST_PORT}
|
||||
openwifi.fileuploader.host.0.cert = ${FILEUPLOADER_HOST_CERT}
|
||||
openwifi.fileuploader.host.0.key = ${FILEUPLOADER_HOST_KEY}
|
||||
openwifi.fileuploader.host.0.key.password = ${FILEUPLOADER_HOST_KEY_PASSWORD}
|
||||
openwifi.fileuploader.path = ${FILEUPLOADER_PATH}
|
||||
openwifi.fileuploader.uri = ${FILEUPLOADER_URI}
|
||||
openwifi.fileuploader.maxsize = 10000
|
||||
|
||||
#
|
||||
# Generic section that all microservices must have
|
||||
#
|
||||
openwifi.service.key = ${SERVICE_KEY}
|
||||
openwifi.service.key.password = ${SERVICE_KEY_PASSWORD}
|
||||
openwifi.system.data = ${SYSTEM_DATA}
|
||||
openwifi.system.debug = true
|
||||
openwifi.system.uri.private = ${SYSTEM_URI_PRIVATE}
|
||||
openwifi.system.uri.public = ${SYSTEM_URI_PUBLIC}
|
||||
openwifi.system.uri.ui = ${SYSTEM_URI_UI}
|
||||
openwifi.system.commandchannel = /tmp/app.ucentralgw
|
||||
|
||||
#
|
||||
# Gateway Microservice Specific Section
|
||||
#
|
||||
openwifi.autoprovisioning = true
|
||||
openwifi.devicetypes.0 = AP:linksys_ea8300,edgecore_eap101,linksys_e8450-ubi
|
||||
openwifi.devicetypes.1 = SWITCH:edgecore_ecs4100-12ph
|
||||
openwifi.devicetypes.2 = IOT:esp32
|
||||
oui.download.uri = https://linuxnet.ca/ieee/oui.txt
|
||||
firmware.autoupdate.policy.default = auto
|
||||
|
||||
#
|
||||
# rtty
|
||||
#
|
||||
rtty.enabled = ${RTTY_ENABLED}
|
||||
rtty.server = ${RTTY_SERVER}
|
||||
rtty.port = ${RTTY_PORT}
|
||||
rtty.token = ${RTTY_TOKEN}
|
||||
rtty.timeout = ${RTTY_TIMEOUT}
|
||||
rtty.viewport = ${RTTY_VIEWPORT}
|
||||
|
||||
#############################
|
||||
# Generic information for all micro services
|
||||
#############################
|
||||
#
|
||||
# NLB Support
|
||||
#
|
||||
alb.enable = true
|
||||
alb.port = 16102
|
||||
|
||||
#
|
||||
# Kafka
|
||||
#
|
||||
openwifi.kafka.group.id = gateway
|
||||
openwifi.kafka.client.id = gateway1
|
||||
openwifi.kafka.enable = ${KAFKA_ENABLE}
|
||||
openwifi.kafka.brokerlist = ${KAFKA_BROKERLIST}
|
||||
openwifi.kafka.auto.commit = false
|
||||
openwifi.kafka.queue.buffering.max.ms = 50
|
||||
|
||||
#
|
||||
# This section select which form of persistence you need
|
||||
# Only one selected at a time. If you select multiple, this service will die if a horrible
|
||||
# death and might make your beer flat.
|
||||
#
|
||||
storage.type = ${STORAGE_TYPE}
|
||||
|
||||
storage.type.sqlite.db = devices.db
|
||||
storage.type.sqlite.idletime = 120
|
||||
storage.type.sqlite.maxsessions = 128
|
||||
|
||||
storage.type.postgresql.maxsessions = 64
|
||||
storage.type.postgresql.idletime = 60
|
||||
storage.type.postgresql.host = ${STORAGE_TYPE_POSTGRESQL_HOST}
|
||||
storage.type.postgresql.username = ${STORAGE_TYPE_POSTGRESQL_USERNAME}
|
||||
storage.type.postgresql.password = ${STORAGE_TYPE_POSTGRESQL_PASSWORD}
|
||||
storage.type.postgresql.database = ${STORAGE_TYPE_POSTGRESQL_DATABASE}
|
||||
storage.type.postgresql.port = ${STORAGE_TYPE_POSTGRESQL_PORT}
|
||||
storage.type.postgresql.connectiontimeout = 60
|
||||
|
||||
storage.type.mysql.maxsessions = 64
|
||||
storage.type.mysql.idletime = 60
|
||||
storage.type.mysql.host = ${STORAGE_TYPE_MYSQL_HOST}
|
||||
storage.type.mysql.username = ${STORAGE_TYPE_MYSQL_USERNAME}
|
||||
storage.type.mysql.password = ${STORAGE_TYPE_MYSQL_PASSWORD}
|
||||
storage.type.mysql.database = ${STORAGE_TYPE_MYSQL_DATABASE}
|
||||
storage.type.mysql.port = ${STORAGE_TYPE_MYSQL_PORT}
|
||||
storage.type.mysql.connectiontimeout = 60
|
||||
|
||||
archiver.enabled = true
|
||||
archiver.schedule = 03:00
|
||||
archiver.db.0.name = healthchecks
|
||||
archiver.db.0.keep = 7
|
||||
archiver.db.1.name = statistics
|
||||
archiver.db.1.keep = 7
|
||||
archiver.db.2.name = devicelogs
|
||||
archiver.db.2.keep = 7
|
||||
archiver.db.3.name = commandlist
|
||||
archiver.db.3.keep = 7
|
||||
|
||||
########################################################################
|
||||
########################################################################
|
||||
#
|
||||
# Logging: please leave as is for now.
|
||||
#
|
||||
########################################################################
|
||||
|
||||
logging.formatters.f1.class = PatternFormatter
|
||||
logging.formatters.f1.pattern = %Y-%m-%d %H:%M:%S %s: [%p] %t
|
||||
logging.formatters.f1.times = UTC
|
||||
logging.channels.c1.class = ConsoleChannel
|
||||
logging.channels.c1.formatter = f1
|
||||
|
||||
# This is where the logs will be written. This path MUST exist
|
||||
logging.channels.c2.class = FileChannel
|
||||
logging.channels.c2.path = $OWGW_ROOT/logs/log
|
||||
logging.channels.c2.formatter.class = PatternFormatter
|
||||
logging.channels.c2.formatter.pattern = %Y-%m-%d %H:%M:%S %s: [%p] %t
|
||||
logging.channels.c2.rotation = 20 M
|
||||
logging.channels.c2.archive = timestamp
|
||||
logging.channels.c2.purgeCount = 20
|
||||
logging.channels.c3.class = ConsoleChannel
|
||||
logging.channels.c3.pattern = %s: [%p] %t
|
||||
|
||||
# External Channel
|
||||
logging.loggers.root.channel = c1
|
||||
logging.loggers.root.level = debug
|
||||
|
||||
# Inline Channel with PatternFormatter
|
||||
# logging.loggers.l1.name = logger1
|
||||
# logging.loggers.l1.channel.class = ConsoleChannel
|
||||
# logging.loggers.l1.channel.pattern = %s: [%p] %t
|
||||
# logging.loggers.l1.level = information
|
||||
# SplitterChannel
|
||||
# logging.channels.splitter.class = SplitterChannel
|
||||
# logging.channels.splitter.channels = l1,l2
|
||||
# logging.loggers.l2.name = logger2
|
||||
# logging.loggers.l2.channel = splitter
|
||||
|
||||
|
||||
|
@@ -5,8 +5,8 @@ Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
Environment="UCENTRALGW_ROOT=/home/admin/dev/wlan-cloud-ucentralgw"
|
||||
ExecStart=/home/admin/dev/wlan-cloud-ucentralgw/cmake-build/ucentralgw
|
||||
Environment="OWGW_ROOT=/home/admin/dev/wlan-cloud-ucentralgw"
|
||||
ExecStart=/home/admin/dev/wlan-cloud-ucentralgw/cmake-build/owgw
|
||||
WorkingDirectory=/home/admin/dev/wlan-cloud-ucentralgw
|
||||
# ExecReload=/bin/kill -s HUP $MAINPID
|
||||
User=admin
|
65
readiness_check
Executable file
65
readiness_check
Executable file
@@ -0,0 +1,65 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
if [[ "$(which jq)" == "" ]]
|
||||
then
|
||||
echo "You need the package jq installed to use this script."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "$(which curl)" == "" ]]
|
||||
then
|
||||
echo "You need the package curl installed to use this script."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "${OWSEC}" == "" ]]
|
||||
then
|
||||
echo "You must set the variable OWSEC in order to use this script. Something like"
|
||||
echo "OWSEC=security.isp.com:16001"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "${OWSEC_USERNAME}" == "" ]]
|
||||
then
|
||||
echo "You must set the variable OWSEC_USERNAME in order to use this script. Something like"
|
||||
echo "OWSEC_USERNAME=tip@ucentral.com"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "${OWSEC_PASSWORD}" == "" ]]
|
||||
then
|
||||
echo "You must set the variable OWSEC_PASSWORD in order to use this script. Something like"
|
||||
echo "OWSEC_PASSWORD=openwifi"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "${READINESS_METHOD}" == "systeminfo" ]]
|
||||
then
|
||||
# Get OAuth token from OWSEC and cache it or use cached one
|
||||
payload="{ \"userId\" : \"$OWSEC_USERNAME\" , \"password\" : \"$OWSEC_PASSWORD\" }"
|
||||
if [[ -f "/tmp/token" ]]
|
||||
then
|
||||
token=$(cat /tmp/token)
|
||||
else
|
||||
token=$(curl ${FLAGS} -X POST -H "Content-Type: application/json" -d "$payload" "https://${OWSEC}/api/v1/oauth2" | jq -r '.access_token')
|
||||
fi
|
||||
if [[ "${token}" == "" ]]
|
||||
then
|
||||
echo "Could not login. Please verify the host and username/password."
|
||||
exit 13
|
||||
fi
|
||||
echo -n $token > /tmp/token
|
||||
|
||||
# Make systeminfo request to the local owgw instance
|
||||
export RESTAPI_PORT=$(grep 'openwifi.restapi.host.0.port' $OWGW_CONFIG/owgw.properties | awk -F '=' '{print $2}' | xargs | envsubst)
|
||||
curl ${FLAGS} -k -X GET "https://localhost:$RESTAPI_PORT/api/v1/system?command=info" \
|
||||
-H "accept: application/json" \
|
||||
-H "Authorization: Bearer ${token}" > /tmp/result.json
|
||||
exit_code=$?
|
||||
jq < /tmp/result.json
|
||||
exit $exit_code
|
||||
else
|
||||
export ALB_PORT=$(grep 'alb.port' $OWGW_CONFIG/owgw.properties | awk -F '=' '{print $2}' | xargs | envsubst)
|
||||
curl localhost:$ALB_PORT
|
||||
fi
|
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
export UCENTRALGW_CONFIG=`pwd`
|
||||
export UCENTRALGW_ROOT=`pwd`
|
||||
export OWGW_CONFIG=`pwd`
|
||||
export OWGW_ROOT=`pwd`
|
||||
|
@@ -1,114 +0,0 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-06-04.
|
||||
//
|
||||
|
||||
#ifndef UCENTRALGW_ALBHEALTHCHECKSERVER_H
|
||||
#define UCENTRALGW_ALBHEALTHCHECKSERVER_H
|
||||
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#include "Poco/Thread.h"
|
||||
#include "Poco/Net/HTTPServer.h"
|
||||
#include "Poco/Net/HTTPServerRequest.h"
|
||||
#include "Poco/Net/HTTPServerResponse.h"
|
||||
#include "Poco/Net/HTTPRequestHandler.h"
|
||||
#include "Poco/Logger.h"
|
||||
|
||||
#include "Daemon.h"
|
||||
#include "SubSystemServer.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class ALBRequestHandler: public Poco::Net::HTTPRequestHandler
|
||||
/// Return a HTML document with the current date and time.
|
||||
{
|
||||
public:
|
||||
ALBRequestHandler(Poco::Logger & L)
|
||||
: Logger_(L)
|
||||
{
|
||||
}
|
||||
|
||||
void handleRequest(Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response)
|
||||
{
|
||||
Logger_.information(Poco::format("ALB-REQUEST(%s): New ALB request.",Request.clientAddress().toString()));
|
||||
Response.setChunkedTransferEncoding(true);
|
||||
Response.setContentType("text/html");
|
||||
Response.setDate(Poco::Timestamp());
|
||||
Response.setStatus(Poco::Net::HTTPResponse::HTTP_OK);
|
||||
Response.setKeepAlive(true);
|
||||
Response.set("Connection","keep-alive");
|
||||
Response.setVersion(Poco::Net::HTTPMessage::HTTP_1_1);
|
||||
std::ostream &Answer = Response.send();
|
||||
Answer << "uCentralGW Alive and kicking!" ;
|
||||
}
|
||||
|
||||
private:
|
||||
Poco::Logger & Logger_;
|
||||
};
|
||||
|
||||
class ALBRequestHandlerFactory: public Poco::Net::HTTPRequestHandlerFactory
|
||||
{
|
||||
public:
|
||||
explicit ALBRequestHandlerFactory(Poco::Logger & L):
|
||||
Logger_(L)
|
||||
{
|
||||
}
|
||||
|
||||
ALBRequestHandler* createRequestHandler(const Poco::Net::HTTPServerRequest& request) override
|
||||
{
|
||||
if (request.getURI() == "/")
|
||||
return new ALBRequestHandler(Logger_);
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
Poco::Logger &Logger_;
|
||||
};
|
||||
|
||||
class ALBHealthCheckServer : public SubSystemServer {
|
||||
public:
|
||||
ALBHealthCheckServer() noexcept:
|
||||
SubSystemServer("ALBHealthCheckServer", "ALB-SVR", "alb")
|
||||
{
|
||||
}
|
||||
|
||||
static ALBHealthCheckServer *instance() {
|
||||
if (instance_ == nullptr) {
|
||||
instance_ = new ALBHealthCheckServer;
|
||||
}
|
||||
return instance_;
|
||||
}
|
||||
|
||||
int Start() {
|
||||
if(Daemon()->ConfigGetBool("alb.enable",false)) {
|
||||
Port_ = (int)Daemon()->ConfigGetInt("alb.port",15015);
|
||||
Socket_ = std::make_unique<Poco::Net::ServerSocket>(Port_);
|
||||
auto Params = new Poco::Net::HTTPServerParams;
|
||||
Server_ = std::make_unique<Poco::Net::HTTPServer>(new ALBRequestHandlerFactory(Logger_), *Socket_, Params);
|
||||
Server_->start();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Stop() {
|
||||
if(Server_)
|
||||
Server_->stop();
|
||||
}
|
||||
|
||||
private:
|
||||
static ALBHealthCheckServer *instance_;
|
||||
std::unique_ptr<Poco::Net::HTTPServer> Server_;
|
||||
std::unique_ptr<Poco::Net::ServerSocket> Socket_;
|
||||
int Port_ = 0;
|
||||
};
|
||||
|
||||
inline ALBHealthCheckServer * ALBHealthCheckServer() { return ALBHealthCheckServer::instance(); }
|
||||
inline class ALBHealthCheckServer * ALBHealthCheckServer::instance_ = nullptr;
|
||||
}
|
||||
|
||||
#endif // UCENTRALGW_ALBHEALTHCHECKSERVER_H
|
61
src/APIServers.cpp
Normal file
61
src/APIServers.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-10-23.
|
||||
//
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
#include "RESTAPI/RESTAPI_blacklist.h"
|
||||
#include "RESTAPI/RESTAPI_blacklist_list.h"
|
||||
#include "RESTAPI/RESTAPI_command.h"
|
||||
#include "RESTAPI/RESTAPI_commands.h"
|
||||
#include "RESTAPI/RESTAPI_default_configuration.h"
|
||||
#include "RESTAPI/RESTAPI_default_configurations.h"
|
||||
#include "RESTAPI/RESTAPI_deviceDashboardHandler.h"
|
||||
#include "RESTAPI/RESTAPI_device_commandHandler.h"
|
||||
#include "RESTAPI/RESTAPI_device_handler.h"
|
||||
#include "RESTAPI/RESTAPI_devices_handler.h"
|
||||
#include "RESTAPI/RESTAPI_file.h"
|
||||
#include "RESTAPI/RESTAPI_ouis.h"
|
||||
|
||||
#include "RESTAPI/RESTAPI_capabilities_handler.h"
|
||||
#include "RESTAPI/RESTAPI_TelemetryWebSocket.h"
|
||||
#include "RESTAPI/RESTAPI_webSocketServer.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
Poco::Net::HTTPRequestHandler * RESTAPI_external_server(const char *Path, RESTAPIHandler::BindingMap &Bindings,
|
||||
Poco::Logger & L, RESTAPI_GenericServer & S) {
|
||||
return RESTAPI_Router<
|
||||
RESTAPI_devices_handler,
|
||||
RESTAPI_device_handler,
|
||||
RESTAPI_device_commandHandler,
|
||||
RESTAPI_default_configurations,
|
||||
RESTAPI_default_configuration,
|
||||
RESTAPI_command,
|
||||
RESTAPI_commands,
|
||||
RESTAPI_ouis,
|
||||
RESTAPI_file,
|
||||
RESTAPI_system_command,
|
||||
RESTAPI_deviceDashboardHandler,
|
||||
RESTAPI_webSocketServer,
|
||||
RESTAPI_blacklist,
|
||||
RESTAPI_blacklist_list,
|
||||
RESTAPI_capabilities_handler,
|
||||
RESTAPI_TelemetryWebSocket>(Path,Bindings,L, S);
|
||||
}
|
||||
|
||||
Poco::Net::HTTPRequestHandler * RESTAPI_internal_server(const char *Path, RESTAPIHandler::BindingMap &Bindings,
|
||||
Poco::Logger & L, RESTAPI_GenericServer & S) {
|
||||
return RESTAPI_Router_I<
|
||||
RESTAPI_devices_handler,
|
||||
RESTAPI_device_handler,
|
||||
RESTAPI_device_commandHandler,
|
||||
RESTAPI_default_configurations,
|
||||
RESTAPI_default_configuration,
|
||||
RESTAPI_command,
|
||||
RESTAPI_commands,
|
||||
RESTAPI_ouis,
|
||||
RESTAPI_file, RESTAPI_blacklist,
|
||||
RESTAPI_blacklist_list>(Path,Bindings,L, S);
|
||||
}
|
||||
}
|
@@ -1,88 +0,0 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-06-30.
|
||||
//
|
||||
#include <utility>
|
||||
|
||||
#include "AuthClient.h"
|
||||
#include "RESTAPI_SecurityObjects.h"
|
||||
#include "Daemon.h"
|
||||
#include "OpenAPIRequest.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class AuthClient * AuthClient::instance_ = nullptr;
|
||||
|
||||
int AuthClient::Start() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AuthClient::Stop() {
|
||||
|
||||
}
|
||||
|
||||
void AuthClient::RemovedCachedToken(const std::string &Token) {
|
||||
SubMutexGuard G(Mutex_);
|
||||
UserCache_.erase(Token);
|
||||
}
|
||||
|
||||
bool IsTokenExpired(const SecurityObjects::WebToken &T) {
|
||||
return ((T.expires_in_+T.created_)<std::time(nullptr));
|
||||
}
|
||||
|
||||
bool AuthClient::IsAuthorized(Poco::Net::HTTPServerRequest & Request, std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo ) {
|
||||
SubMutexGuard G(Mutex_);
|
||||
|
||||
auto User = UserCache_.find(SessionToken);
|
||||
if(User != UserCache_.end() && !IsTokenExpired(User->second.webtoken)) {
|
||||
UInfo = User->second;
|
||||
return true;
|
||||
} else {
|
||||
Types::StringPairVec QueryData;
|
||||
QueryData.push_back(std::make_pair("token",SessionToken));
|
||||
OpenAPIRequestGet Req( uSERVICE_SECURITY,
|
||||
"/api/v1/validateToken",
|
||||
QueryData,
|
||||
5000);
|
||||
Poco::JSON::Object::Ptr Response;
|
||||
if(Req.Do(Response)==Poco::Net::HTTPResponse::HTTP_OK) {
|
||||
if(Response->has("tokenInfo") && Response->has("userInfo")) {
|
||||
SecurityObjects::UserInfoAndPolicy P;
|
||||
P.from_json(Response);
|
||||
UserCache_[SessionToken] = P;
|
||||
UInfo = P;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AuthClient::IsTokenAuthorized(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo) {
|
||||
SubMutexGuard G(Mutex_);
|
||||
|
||||
auto User = UserCache_.find(SessionToken);
|
||||
if(User != UserCache_.end() && !IsTokenExpired(User->second.webtoken)) {
|
||||
UInfo = User->second;
|
||||
return true;
|
||||
} else {
|
||||
Types::StringPairVec QueryData;
|
||||
QueryData.push_back(std::make_pair("token",SessionToken));
|
||||
OpenAPIRequestGet Req(uSERVICE_SECURITY,
|
||||
"/api/v1/validateToken",
|
||||
QueryData,
|
||||
5000);
|
||||
Poco::JSON::Object::Ptr Response;
|
||||
if(Req.Do(Response)==Poco::Net::HTTPResponse::HTTP_OK) {
|
||||
if(Response->has("tokenInfo") && Response->has("userInfo")) {
|
||||
SecurityObjects::UserInfoAndPolicy P;
|
||||
P.from_json(Response);
|
||||
UserCache_[SessionToken] = P;
|
||||
UInfo = P;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@@ -1,45 +0,0 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-06-30.
|
||||
//
|
||||
|
||||
#ifndef UCENTRALGW_AUTHCLIENT_H
|
||||
#define UCENTRALGW_AUTHCLIENT_H
|
||||
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include "Poco/Net/HTTPServerRequest.h"
|
||||
#include "Poco/Net/HTTPServerResponse.h"
|
||||
#include "Poco/JWT/Signer.h"
|
||||
#include "Poco/SHA2Engine.h"
|
||||
#include "RESTAPI_SecurityObjects.h"
|
||||
#include "SubSystemServer.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class AuthClient : public SubSystemServer {
|
||||
public:
|
||||
explicit AuthClient() noexcept:
|
||||
SubSystemServer("Authentication", "AUTH-CLNT", "authentication")
|
||||
{
|
||||
}
|
||||
|
||||
static AuthClient *instance() {
|
||||
if (instance_ == nullptr) {
|
||||
instance_ = new AuthClient;
|
||||
}
|
||||
return instance_;
|
||||
}
|
||||
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
bool IsAuthorized(Poco::Net::HTTPServerRequest & Request, std::string &SessionToken, OpenWifi::SecurityObjects::UserInfoAndPolicy & UInfo );
|
||||
void RemovedCachedToken(const std::string &Token);
|
||||
bool IsTokenAuthorized(const std::string &Token, SecurityObjects::UserInfoAndPolicy & UInfo);
|
||||
private:
|
||||
static AuthClient *instance_;
|
||||
OpenWifi::SecurityObjects::UserInfoCache UserCache_;
|
||||
};
|
||||
|
||||
inline AuthClient * AuthClient() { return AuthClient::instance(); }
|
||||
}
|
||||
|
||||
#endif // UCENTRALGW_AUTHCLIENT_H
|
@@ -7,13 +7,14 @@
|
||||
//
|
||||
#include <fstream>
|
||||
|
||||
#include "CentralConfig.h"
|
||||
#include "Daemon.h"
|
||||
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include "Poco/JSON/Parser.h"
|
||||
#include "Poco/File.h"
|
||||
|
||||
#include "CentralConfig.h"
|
||||
#include "framework/MicroService.h"
|
||||
#include "Daemon.h"
|
||||
|
||||
namespace OpenWifi::Config {
|
||||
|
||||
static std::string DefaultConfiguration;
|
||||
@@ -119,7 +120,7 @@ namespace OpenWifi::Config {
|
||||
})lit"};
|
||||
|
||||
void SetBasicConfigFile() {
|
||||
Poco::File DefaultConfigFileName{Daemon()->DataDir()+"/default_config.json"};
|
||||
Poco::File DefaultConfigFileName{MicroService::instance().DataDir()+"/default_config.json"};
|
||||
DefaultConfiguration = BasicConfig;
|
||||
std::ofstream F;
|
||||
F.open(DefaultConfigFileName.path(),std::ios::binary);
|
||||
@@ -134,7 +135,7 @@ namespace OpenWifi::Config {
|
||||
void Config::Init() {
|
||||
if(DefaultConfiguration.empty()) {
|
||||
// open the file
|
||||
Poco::File DefaultConfigFileName{Daemon()->DataDir()+"/default_config.json"};
|
||||
Poco::File DefaultConfigFileName{MicroService::instance().DataDir()+"/default_config.json"};
|
||||
try {
|
||||
if (!DefaultConfigFileName.exists()) {
|
||||
SetBasicConfigFile();
|
||||
@@ -232,7 +233,7 @@ namespace OpenWifi::Config {
|
||||
}
|
||||
catch ( const Poco::Exception & E )
|
||||
{
|
||||
Daemon::instance()->logger().warning(Poco::format("%s: Failed with: %s", std::string(__func__) , E.displayText()));
|
||||
Daemon()->logger().log(E);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -6,27 +6,22 @@
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
#include "CommandManager.h"
|
||||
#include <algorithm>
|
||||
|
||||
#include "Poco/JSON/Parser.h"
|
||||
|
||||
#include "CommandManager.h"
|
||||
#include "DeviceRegistry.h"
|
||||
#include "RESTAPI_GWobjects.h"
|
||||
#include "RESTAPI_handler.h"
|
||||
#include "RESTObjects//RESTAPI_GWobjects.h"
|
||||
#include "StorageService.h"
|
||||
#include "uCentralProtocol.h"
|
||||
#include "framework/MicroService.h"
|
||||
#include "framework/uCentral_Protocol.h"
|
||||
|
||||
#include "Poco/JSON/Parser.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class CommandManager * CommandManager::instance_ = nullptr;
|
||||
|
||||
CommandManager::CommandManager() noexcept:
|
||||
SubSystemServer("CommandManager", "CMD_MGR", "command.manager")
|
||||
{
|
||||
}
|
||||
|
||||
void CommandManager::run() {
|
||||
Running_ = true;
|
||||
while(Running_)
|
||||
@@ -34,16 +29,27 @@ namespace OpenWifi {
|
||||
Poco::Thread::trySleep(30000);
|
||||
if(!Running_)
|
||||
break;
|
||||
std::vector<GWObjects::CommandDetails> Commands;
|
||||
|
||||
if(Storage()->GetReadyToExecuteCommands(1,200,Commands))
|
||||
std::vector<GWObjects::CommandDetails> Commands;
|
||||
if(StorageService()->GetReadyToExecuteCommands(1,200,Commands))
|
||||
{
|
||||
for(auto & Cmd: Commands)
|
||||
{
|
||||
if(!Running_)
|
||||
break;
|
||||
|
||||
if(!SendCommand(Cmd)) {
|
||||
uint64_t RPC_Id;
|
||||
Poco::JSON::Parser P;
|
||||
|
||||
auto Params = P.parse(Cmd.Details).extract<Poco::JSON::Object::Ptr>();
|
||||
if(SendCommand( Cmd.SerialNumber,
|
||||
Cmd.Command,
|
||||
*Params,
|
||||
Cmd.UUID,
|
||||
RPC_Id)) {
|
||||
StorageService()->SetCommandExecuted(Cmd.UUID);
|
||||
Logger_.information(Poco::format("Sent command '%s' to '%s'",Cmd.Command,Cmd.SerialNumber));
|
||||
} else {
|
||||
Logger_.information(Poco::format("Failed to send command '%s' to %s",Cmd.Command,Cmd.SerialNumber));
|
||||
}
|
||||
}
|
||||
@@ -71,105 +77,85 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
void CommandManager::Janitor() {
|
||||
SubMutexGuard G(SubMutex);
|
||||
std::lock_guard G(Mutex_);
|
||||
uint64_t Now = time(nullptr);
|
||||
for(auto i = Age_.begin(); i!= Age_.end();)
|
||||
if((Now-i->first)>300)
|
||||
Age_.erase(i++);
|
||||
Logger_.information("Janitor starting.");
|
||||
for(auto i=OutStandingRequests_.begin();i!=OutStandingRequests_.end();) {
|
||||
if((Now-i->second.Submitted)>120)
|
||||
i = OutStandingRequests_.erase(i);
|
||||
else
|
||||
++i;
|
||||
}
|
||||
Logger_.information("Janitor finished.");
|
||||
}
|
||||
|
||||
bool CommandManager::SendCommand(const std::string &SerialNumber,
|
||||
const std::string &Method,
|
||||
const Poco::JSON::Object &Params,
|
||||
std::shared_ptr<std::promise<Poco::JSON::Object::Ptr>> Promise,
|
||||
const std::string &UUID) {
|
||||
bool CommandManager::GetCommand(uint64_t Id, const std::string &SerialNumber, CommandTag &T) {
|
||||
std::lock_guard G(Mutex_);
|
||||
CommandTagIndex TI{.Id=Id,.SerialNumber=SerialNumber};
|
||||
auto Hint=OutStandingRequests_.find(TI);
|
||||
if(Hint==OutStandingRequests_.end() || Hint->second.Completed==0)
|
||||
return false;
|
||||
T = Hint->second;
|
||||
OutStandingRequests_.erase(Hint);
|
||||
return true;
|
||||
}
|
||||
|
||||
SubMutexGuard G(SubMutex);
|
||||
bool CommandManager::SendCommand( const std::string &SerialNumber,
|
||||
const std::string &Method,
|
||||
const Poco::JSON::Object &Params,
|
||||
const std::string &UUID,
|
||||
uint64_t & Id,
|
||||
bool oneway_rpc) {
|
||||
|
||||
Poco::JSON::Object CompleteRPC;
|
||||
CompleteRPC.set(uCentralProtocol::JSONRPC, uCentralProtocol::JSONRPC_VERSION);
|
||||
CompleteRPC.set(uCentralProtocol::ID, Id_);
|
||||
CompleteRPC.set(uCentralProtocol::METHOD, Method );
|
||||
CompleteRPC.set(uCentralProtocol::PARAMS, Params);
|
||||
std::stringstream ToSend;
|
||||
std::unique_lock G(Mutex_);
|
||||
if(oneway_rpc)
|
||||
Id = 1;
|
||||
else
|
||||
Id = ++Id_;
|
||||
Poco::JSON::Object CompleteRPC;
|
||||
CompleteRPC.set(uCentralProtocol::JSONRPC, uCentralProtocol::JSONRPC_VERSION);
|
||||
CompleteRPC.set(uCentralProtocol::ID, Id);
|
||||
CompleteRPC.set(uCentralProtocol::METHOD, Method);
|
||||
CompleteRPC.set(uCentralProtocol::PARAMS, Params);
|
||||
Poco::JSON::Stringifier::stringify(CompleteRPC, ToSend);
|
||||
|
||||
OutStandingRequests_[Id_] = std::make_pair(std::move(Promise),UUID);
|
||||
Age_[Id_] = time(nullptr);
|
||||
Id_++;
|
||||
Logger_.information(
|
||||
Poco::format("(%s): Sending command '%s', ID: %lu", SerialNumber, Method, Id));
|
||||
CommandTagIndex Idx{.Id = Id, .SerialNumber = SerialNumber};
|
||||
CommandTag Tag;
|
||||
Tag.UUID = UUID;
|
||||
Tag.Submitted = std::time(nullptr);
|
||||
Tag.Completed = 0;
|
||||
Tag.Result = Poco::makeShared<Poco::JSON::Object>();
|
||||
OutStandingRequests_[Idx] = Tag;
|
||||
G.unlock();
|
||||
return DeviceRegistry()->SendFrame(SerialNumber, ToSend.str());
|
||||
}
|
||||
|
||||
bool CommandManager::SendCommand(GWObjects::CommandDetails & Command) {
|
||||
SubMutexGuard G(SubMutex);
|
||||
|
||||
Logger_.debug(Poco::format("Sending command to %s",Command.SerialNumber));
|
||||
try {
|
||||
Poco::JSON::Object Obj;
|
||||
|
||||
Obj.set(uCentralProtocol::JSONRPC,uCentralProtocol::JSONRPC_VERSION);
|
||||
Obj.set(uCentralProtocol::ID,Id_);
|
||||
Obj.set(uCentralProtocol::METHOD, Command.Custom ? uCentralProtocol::PERFORM : Command.Command );
|
||||
|
||||
bool FullCommand = true;
|
||||
if(Command.Command==uCentralProtocol::REQUEST)
|
||||
FullCommand = false;
|
||||
|
||||
// the params section was composed earlier... just include it here
|
||||
Poco::JSON::Parser parser;
|
||||
auto ParsedMessage = parser.parse(Command.Details);
|
||||
const auto & ParamsObj = ParsedMessage.extract<Poco::JSON::Object::Ptr>();
|
||||
Obj.set(uCentralProtocol::PARAMS,ParamsObj);
|
||||
std::stringstream ToSend;
|
||||
Poco::JSON::Stringifier::stringify(Obj,ToSend);
|
||||
|
||||
if(DeviceRegistry()->SendFrame(Command.SerialNumber, ToSend.str())) {
|
||||
Storage()->SetCommandExecuted(Command.UUID);
|
||||
OutStandingRequests_[Id_] = std::make_pair(nullptr,Command.UUID);
|
||||
Age_[Id_] = time(nullptr);
|
||||
return true;
|
||||
} else {
|
||||
|
||||
}
|
||||
Id_++;
|
||||
}
|
||||
catch( const Poco::Exception & E )
|
||||
{
|
||||
Logger_.warning(Poco::format("COMMAND(%s): Exception while sending a command.",Command.SerialNumber));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void CommandManager::PostCommandResult(const std::string &SerialNumber, Poco::JSON::Object::Ptr Obj) {
|
||||
|
||||
if(!Obj->has(uCentralProtocol::ID)){
|
||||
Logger_.error("Invalid RPC response.");
|
||||
Logger_.error(Poco::format("(%s): Invalid RPC response.",SerialNumber));
|
||||
return;
|
||||
}
|
||||
|
||||
SubMutexGuard G(SubMutex);
|
||||
|
||||
uint64_t ID = Obj->get(uCentralProtocol::ID);
|
||||
auto RPC = OutStandingRequests_.find(ID);
|
||||
Age_.erase(ID);
|
||||
if(RPC != OutStandingRequests_.end()) {
|
||||
if(RPC->second.first.use_count() > 1) {
|
||||
try {
|
||||
RPC->second.first->set_value(std::move(Obj));
|
||||
} catch (...) {
|
||||
Logger_.error(Poco::format("COMPLETING-RPC(%Lu): future was lost", ID));
|
||||
Storage()->CommandCompleted(RPC->second.second, Obj, true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Storage()->CommandCompleted(RPC->second.second, Obj, true);
|
||||
}
|
||||
OutStandingRequests_.erase(RPC);
|
||||
} else {
|
||||
Logger_.warning(Poco::format("OUTDATED-RPC(%lu): Nothing waiting for this RPC.",ID));
|
||||
if(ID<2) {
|
||||
Logger_.error(Poco::format("(%s): Ignoring RPC response.",SerialNumber));
|
||||
return;
|
||||
}
|
||||
std::unique_lock G(Mutex_);
|
||||
auto Idx = CommandTagIndex{.Id = ID, .SerialNumber = SerialNumber};
|
||||
auto RPC = OutStandingRequests_.find(Idx);
|
||||
if (RPC == OutStandingRequests_.end()) {
|
||||
Logger_.warning(Poco::format("(%s): Outdated RPC %lu", SerialNumber, ID));
|
||||
return;
|
||||
}
|
||||
RPC->second.Completed = std::time(nullptr);
|
||||
RPC->second.Result = Obj;
|
||||
Logger_.information(Poco::format("(%s): Received RPC answer %lu", SerialNumber, ID));
|
||||
G.unlock();
|
||||
StorageService()->CommandCompleted(RPC->second.UUID, Obj, true);
|
||||
}
|
||||
|
||||
} // namespace
|
@@ -19,11 +19,37 @@
|
||||
#include "Poco/Net/HTTPServerRequest.h"
|
||||
#include "Poco/Net/HTTPServerResponse.h"
|
||||
|
||||
#include "RESTAPI_GWobjects.h"
|
||||
#include "SubSystemServer.h"
|
||||
#include "RESTObjects//RESTAPI_GWobjects.h"
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
struct CommandTagIndex {
|
||||
uint64_t Id=0;
|
||||
std::string SerialNumber;
|
||||
};
|
||||
|
||||
inline bool operator <(const CommandTagIndex& lhs, const CommandTagIndex& rhs) {
|
||||
if(lhs.Id<rhs.Id)
|
||||
return true;
|
||||
if(lhs.Id>rhs.Id)
|
||||
return false;
|
||||
return lhs.SerialNumber<rhs.SerialNumber;
|
||||
}
|
||||
|
||||
inline bool operator ==(const CommandTagIndex& lhs, const CommandTagIndex& rhs) {
|
||||
if(lhs.Id == rhs.Id && lhs.SerialNumber == rhs.SerialNumber)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
struct CommandTag {
|
||||
std::string UUID;
|
||||
Poco::JSON::Object::Ptr Result;
|
||||
uint64_t Submitted=0;
|
||||
uint64_t Completed=0;
|
||||
};
|
||||
|
||||
class CommandManager : public SubSystemServer, Poco::Runnable {
|
||||
public:
|
||||
int Start() override;
|
||||
@@ -31,34 +57,35 @@ namespace OpenWifi {
|
||||
void WakeUp();
|
||||
void PostCommandResult(const std::string &SerialNumber, Poco::JSON::Object::Ptr Obj);
|
||||
bool SendCommand( const std::string &SerialNumber,
|
||||
const std::string &Method,
|
||||
const Poco::JSON::Object &Params,
|
||||
std::shared_ptr<std::promise<Poco::JSON::Object::Ptr>> Promise,
|
||||
const std::string &UUID);
|
||||
bool SendCommand( const std::string & SerialNumber,
|
||||
const std::string & Method,
|
||||
const Poco::JSON::Object &Params,
|
||||
const std::string & UUID);
|
||||
bool SendCommand(GWObjects::CommandDetails & Command);
|
||||
const std::string &Method,
|
||||
const Poco::JSON::Object &Params,
|
||||
const std::string &UUID,
|
||||
uint64_t & Id,
|
||||
bool oneway_rpc=false);
|
||||
void Janitor();
|
||||
void run() override;
|
||||
|
||||
bool GetCommand(uint64_t Id, const std::string & SerialNumber, CommandTag &T);
|
||||
|
||||
static CommandManager *instance() {
|
||||
if (instance_ == nullptr) {
|
||||
instance_ = new CommandManager;
|
||||
}
|
||||
return instance_;
|
||||
}
|
||||
inline bool Running() const { return Running_; }
|
||||
|
||||
private:
|
||||
static CommandManager * instance_;
|
||||
std::atomic_bool Running_ = false;
|
||||
Poco::Thread ManagerThread;
|
||||
uint64_t Id_=1;
|
||||
std::map< uint64_t , std::pair< std::shared_ptr<std::promise<Poco::JSON::Object::Ptr>>, std::string> > OutStandingRequests_;
|
||||
std::map< uint64_t , uint64_t > Age_;
|
||||
std::atomic_bool Running_ = false;
|
||||
Poco::Thread ManagerThread;
|
||||
uint64_t Id_=2; // do not start @1. We ignore ID=1 & 0 is illegal..
|
||||
std::map<CommandTagIndex,CommandTag> OutStandingRequests_;
|
||||
|
||||
CommandManager() noexcept;
|
||||
CommandManager() noexcept:
|
||||
SubSystemServer("CommandManager", "CMD-MGR", "command.manager")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
inline CommandManager * CommandManager() { return CommandManager::instance(); }
|
||||
|
9
src/ConfigurationCache.cpp
Normal file
9
src/ConfigurationCache.cpp
Normal file
@@ -0,0 +1,9 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-09-21.
|
||||
//
|
||||
|
||||
#include "ConfigurationCache.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class ConfigurationCache * ConfigurationCache::instance_ = nullptr;
|
||||
}
|
44
src/ConfigurationCache.h
Normal file
44
src/ConfigurationCache.h
Normal file
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-09-21.
|
||||
//
|
||||
|
||||
#ifndef OWGW_CONFIGURATIONCACHE_H
|
||||
#define OWGW_CONFIGURATIONCACHE_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
|
||||
namespace OpenWifi {
|
||||
class ConfigurationCache {
|
||||
public:
|
||||
|
||||
static ConfigurationCache &instance() {
|
||||
if(instance_== nullptr)
|
||||
instance_ = new ConfigurationCache;
|
||||
return *instance_;
|
||||
}
|
||||
|
||||
inline uint64_t CurrentConfig(const std::string &SerialNumber) {
|
||||
std::lock_guard G(Mutex_);
|
||||
const auto Hint = Cache_.find(SerialNumber);
|
||||
if(Hint==end(Cache_))
|
||||
return 0;
|
||||
return Hint->second;
|
||||
}
|
||||
|
||||
void Add(const std::string &SerialNumber, uint64_t Id) {
|
||||
std::lock_guard G(Mutex_);
|
||||
Cache_[SerialNumber]=Id;
|
||||
}
|
||||
|
||||
private:
|
||||
static ConfigurationCache *instance_;
|
||||
std::mutex Mutex_;
|
||||
std::map<std::string,uint64_t> Cache_;
|
||||
};
|
||||
|
||||
inline uint64_t GetCurrentConfigurationID(const std::string &S) { return ConfigurationCache::instance().CurrentConfig(S); }
|
||||
inline void SetCurrentConfigurationID(const std::string &S, uint64_t ID) { ConfigurationCache::instance().Add(S,ID); }
|
||||
}
|
||||
#endif // OWGW_CONFIGURATIONCACHE_H
|
2215
src/ConfigurationValidator.cpp
Normal file
2215
src/ConfigurationValidator.cpp
Normal file
File diff suppressed because it is too large
Load Diff
70
src/ConfigurationValidator.h
Normal file
70
src/ConfigurationValidator.h
Normal file
@@ -0,0 +1,70 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-09-14.
|
||||
//
|
||||
|
||||
#ifndef OWPROV_CONFIGURATIONVALIDATOR_H
|
||||
#define OWPROV_CONFIGURATIONVALIDATOR_H
|
||||
|
||||
#include "Poco/Logger.h"
|
||||
#include "framework/MicroService.h"
|
||||
#include <nlohmann/json-schema.hpp>
|
||||
|
||||
using nlohmann::json;
|
||||
using nlohmann::json_schema::json_validator;
|
||||
|
||||
namespace OpenWifi {
|
||||
class ConfigurationValidator : public SubSystemServer {
|
||||
public:
|
||||
|
||||
static ConfigurationValidator *instance() {
|
||||
if(instance_== nullptr)
|
||||
instance_ = new ConfigurationValidator;
|
||||
return instance_;
|
||||
}
|
||||
|
||||
bool Validate(const std::string &C);
|
||||
static void my_format_checker(const std::string &format, const std::string &value)
|
||||
{
|
||||
/*
|
||||
"format": "uc-mac"
|
||||
"format": "uc-timeout",
|
||||
"format": "uc-cidr4",
|
||||
"format": "uc-cidr6",
|
||||
"uc-format": "cidr",
|
||||
"format": "fqdn",
|
||||
"format": "uc-host",
|
||||
"format": "uri"
|
||||
"format": "hostname"
|
||||
"format": "uc-base64"
|
||||
|
||||
|
||||
if (format == "something") {
|
||||
return;
|
||||
if (!check_value_for_something(value))
|
||||
throw std::invalid_argument("value is not a good something");
|
||||
} else
|
||||
throw std::logic_error("Don't know how to validate " + format);
|
||||
*/
|
||||
}
|
||||
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
void reinitialize(Poco::Util::Application &self) override;
|
||||
|
||||
private:
|
||||
static ConfigurationValidator * instance_;
|
||||
bool Initialized_=false;
|
||||
bool Working_=false;
|
||||
void Init();
|
||||
std::unique_ptr<json_validator> Validator_=std::make_unique<json_validator>(nullptr, my_format_checker);
|
||||
|
||||
ConfigurationValidator():
|
||||
SubSystemServer("configvalidator", "CFG-VALIDATOR", "config.validator") {
|
||||
}
|
||||
};
|
||||
|
||||
inline ConfigurationValidator * ConfigurationValidator() { return ConfigurationValidator::instance(); }
|
||||
inline bool ValidateUCentralConfiguration(const std::string &C) { return ConfigurationValidator::instance()->Validate(C); }
|
||||
}
|
||||
|
||||
#endif //OWPROV_CONFIGURATIONVALIDATOR_H
|
@@ -10,24 +10,20 @@
|
||||
#include "Poco/Util/Application.h"
|
||||
#include "Poco/Util/Option.h"
|
||||
#include "Poco/Environment.h"
|
||||
#include "Poco/Net/HTTPStreamFactory.h"
|
||||
|
||||
#include "Daemon.h"
|
||||
|
||||
#include "CentralConfig.h"
|
||||
#include "CommandManager.h"
|
||||
#include "ConfigurationValidator.h"
|
||||
#include "DeviceRegistry.h"
|
||||
#include "FileUploader.h"
|
||||
#include "RESTAPI_server.h"
|
||||
#include "StorageService.h"
|
||||
#include "WebSocketServer.h"
|
||||
#include "CentralConfig.h"
|
||||
#include "OUIServer.h"
|
||||
#include "StateProcessor.h"
|
||||
#include "Utils.h"
|
||||
#include "RESTAPI_InternalServer.h"
|
||||
#include "AuthClient.h"
|
||||
#include "StorageArchiver.h"
|
||||
#include "SerialNumberCache.h"
|
||||
#include "StorageArchiver.h"
|
||||
#include "StorageService.h"
|
||||
#include "TelemetryStream.h"
|
||||
#include "WebSocketServer.h"
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class Daemon *Daemon::instance_ = nullptr;
|
||||
@@ -39,34 +35,32 @@ namespace OpenWifi {
|
||||
vDAEMON_CONFIG_ENV_VAR,
|
||||
vDAEMON_APP_NAME,
|
||||
vDAEMON_BUS_TIMER,
|
||||
Types::SubSystemVec{
|
||||
Storage(),
|
||||
SubSystemVec{
|
||||
StorageService(),
|
||||
SerialNumberCache(),
|
||||
AuthClient(),
|
||||
ConfigurationValidator(),
|
||||
DeviceRegistry(),
|
||||
RESTAPI_server(),
|
||||
RESTAPI_InternalServer(),
|
||||
WebSocketServer(),
|
||||
CommandManager(),
|
||||
FileUploader(),
|
||||
OUIServer(),
|
||||
StorageArchiver(),
|
||||
TelemetryStream()
|
||||
});
|
||||
}
|
||||
return instance_;
|
||||
}
|
||||
|
||||
void Daemon::initialize(Poco::Util::Application &self) {
|
||||
MicroService::initialize(*this);
|
||||
void Daemon::initialize() {
|
||||
Config::Config::Init();
|
||||
AutoProvisioning_ = config().getBool("ucentral.autoprovisioning",false);
|
||||
AutoProvisioning_ = config().getBool("openwifi.autoprovisioning",false);
|
||||
|
||||
// DeviceTypeIdentifications_
|
||||
Types::StringVec Keys;
|
||||
config().keys("ucentral.devicetypes",Keys);
|
||||
config().keys("openwifi.devicetypes",Keys);
|
||||
for(const auto & i:Keys)
|
||||
{
|
||||
std::string Line = config().getString("ucentral.devicetypes."+i);
|
||||
std::string Line = config().getString("openwifi.devicetypes."+i);
|
||||
auto P1 = Line.find_first_of(':');
|
||||
auto Type = Line.substr(0, P1);
|
||||
auto List = Line.substr(P1+1);
|
||||
@@ -84,6 +78,10 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
|
||||
void MicroServicePostInitialization() {
|
||||
Daemon()->initialize();
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string Daemon::IdentifyDevice(const std::string & Id ) const {
|
||||
for(const auto &[Type,List]:DeviceTypeIdentifications_)
|
||||
{
|
||||
@@ -94,6 +92,7 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
try {
|
||||
auto App = OpenWifi::Daemon::instance();
|
||||
|
23
src/Daemon.h
23
src/Daemon.h
@@ -26,32 +26,33 @@
|
||||
#include "Poco/Crypto/Cipher.h"
|
||||
|
||||
#include "Dashboard.h"
|
||||
#include "MicroService.h"
|
||||
#include "OpenWifiTypes.h"
|
||||
#include "framework/MicroService.h"
|
||||
#include "framework/OpenWifiTypes.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
static const char * vDAEMON_PROPERTIES_FILENAME = "ucentralgw.properties";
|
||||
static const char * vDAEMON_ROOT_ENV_VAR = "UCENTRALGW_ROOT";
|
||||
static const char * vDAEMON_CONFIG_ENV_VAR = "UCENTRALGW_CONFIG";
|
||||
static const char * vDAEMON_PROPERTIES_FILENAME = "owgw.properties";
|
||||
static const char * vDAEMON_ROOT_ENV_VAR = "OWGW_ROOT";
|
||||
static const char * vDAEMON_CONFIG_ENV_VAR = "OWGW_CONFIG";
|
||||
static const char * vDAEMON_APP_NAME = uSERVICE_GATEWAY.c_str();
|
||||
static const uint64_t vDAEMON_BUS_TIMER = 10000;
|
||||
|
||||
class Daemon : public MicroService {
|
||||
public:
|
||||
explicit Daemon(std::string PropFile,
|
||||
std::string RootEnv,
|
||||
std::string ConfigEnv,
|
||||
std::string AppName,
|
||||
explicit Daemon(const std::string & PropFile,
|
||||
const std::string & RootEnv,
|
||||
const std::string & ConfigEnv,
|
||||
const std::string & AppName,
|
||||
uint64_t BusTimer,
|
||||
Types::SubSystemVec SubSystems) :
|
||||
const SubSystemVec & SubSystems) :
|
||||
MicroService( PropFile, RootEnv, ConfigEnv, AppName, BusTimer, SubSystems) {};
|
||||
|
||||
bool AutoProvisioning() const { return AutoProvisioning_ ; }
|
||||
[[nodiscard]] std::string IdentifyDevice(const std::string & Compatible) const;
|
||||
void initialize(Poco::Util::Application &self);
|
||||
void initialize();
|
||||
static Daemon *instance();
|
||||
inline DeviceDashboard & GetDashboard() { return DB_; }
|
||||
Poco::Logger & Log() { return Poco::Logger::get(AppName()); }
|
||||
private:
|
||||
static Daemon *instance_;
|
||||
bool AutoProvisioning_ = false;
|
||||
|
@@ -12,9 +12,8 @@ namespace OpenWifi {
|
||||
|
||||
if(LastRun_==0 || (Now-LastRun_)>120) {
|
||||
DB_.reset();
|
||||
Storage()->AnalyzeCommands(DB_.commands);
|
||||
// DeviceRegistry()->AnalyzeRegistry(DB_);
|
||||
Storage()->AnalyzeDevices(DB_);
|
||||
StorageService()->AnalyzeCommands(DB_.commands);
|
||||
StorageService()->AnalyzeDevices(DB_);
|
||||
LastRun_ = Now;
|
||||
}
|
||||
}
|
||||
|
@@ -5,14 +5,15 @@
|
||||
#ifndef UCENTRALGW_DASHBOARD_H
|
||||
#define UCENTRALGW_DASHBOARD_H
|
||||
|
||||
#include "OpenWifiTypes.h"
|
||||
#include "RESTAPI_GWobjects.h"
|
||||
#include "RESTObjects//RESTAPI_GWobjects.h"
|
||||
#include "framework/OpenWifiTypes.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class DeviceDashboard {
|
||||
public:
|
||||
DeviceDashboard() { DB_.reset(); }
|
||||
void Create();
|
||||
const GWObjects::Dashboard & Report() const { return DB_;}
|
||||
[[nodiscard]] const GWObjects::Dashboard & Report() const { return DB_;}
|
||||
private:
|
||||
GWObjects::Dashboard DB_;
|
||||
uint64_t LastRun_=0;
|
||||
|
@@ -6,16 +6,14 @@
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
#include "DeviceRegistry.h"
|
||||
|
||||
#include "RESTAPI_handler.h"
|
||||
#include "WebSocketServer.h"
|
||||
|
||||
#include "DeviceRegistry.h"
|
||||
#include "OUIServer.h"
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include "Poco/JSON/Parser.h"
|
||||
|
||||
#include "DeviceRegistry.h"
|
||||
#include "WebSocketServer.h"
|
||||
#include "framework/MicroService.h"
|
||||
#include "OUIServer.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class DeviceRegistry *DeviceRegistry::instance_ = nullptr;
|
||||
|
||||
@@ -24,29 +22,29 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
int DeviceRegistry::Start() {
|
||||
SubMutexGuard Guard(Mutex_);
|
||||
std::lock_guard Guard(Mutex_);
|
||||
Logger_.notice("Starting ");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DeviceRegistry::Stop() {
|
||||
SubMutexGuard Guard(Mutex_);
|
||||
std::lock_guard Guard(Mutex_);
|
||||
Logger_.notice("Stopping ");
|
||||
}
|
||||
|
||||
bool DeviceRegistry::GetStatistics(const std::string &SerialNumber, std::string & Statistics) {
|
||||
SubMutexGuard Guard(Mutex_);
|
||||
std::lock_guard Guard(Mutex_);
|
||||
|
||||
auto Device = Devices_.find(SerialNumber);
|
||||
if(Device != Devices_.end()) {
|
||||
Statistics = Device->second->LastStats;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
if(Device == Devices_.end())
|
||||
return false;
|
||||
|
||||
Statistics = Device->second->LastStats;
|
||||
return true;
|
||||
}
|
||||
|
||||
void DeviceRegistry::SetStatistics(const std::string &SerialNumber, const std::string &Statistics) {
|
||||
SubMutexGuard Guard(Mutex_);
|
||||
std::lock_guard Guard(Mutex_);
|
||||
|
||||
auto Device = Devices_.find(SerialNumber);
|
||||
|
||||
@@ -58,22 +56,18 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
bool DeviceRegistry::GetState(const std::string &SerialNumber, GWObjects::ConnectionState & State) {
|
||||
SubMutexGuard Guard(Mutex_);
|
||||
|
||||
std::lock_guard Guard(Mutex_);
|
||||
auto Device = Devices_.find(SerialNumber);
|
||||
if(Device != Devices_.end())
|
||||
{
|
||||
State = Device->second->Conn_;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
if(Device == Devices_.end())
|
||||
return false;
|
||||
|
||||
State = Device->second->Conn_;
|
||||
return true;
|
||||
}
|
||||
|
||||
void DeviceRegistry::SetState(const std::string & SerialNumber, GWObjects::ConnectionState & State) {
|
||||
SubMutexGuard Guard(Mutex_);
|
||||
|
||||
std::lock_guard Guard(Mutex_);
|
||||
auto Device = Devices_.find(SerialNumber);
|
||||
|
||||
if(Device != Devices_.end())
|
||||
{
|
||||
Device->second->Conn_.LastContact = time(nullptr);
|
||||
@@ -82,7 +76,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
bool DeviceRegistry::GetHealthcheck(const std::string &SerialNumber, GWObjects::HealthCheck & CheckData) {
|
||||
SubMutexGuard Guard(Mutex_);
|
||||
std::lock_guard Guard(Mutex_);
|
||||
|
||||
auto Device = Devices_.find(SerialNumber);
|
||||
if(Device != Devices_.end()) {
|
||||
@@ -93,7 +87,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
void DeviceRegistry::SetHealthcheck(const std::string &SerialNumber, const GWObjects::HealthCheck & CheckData) {
|
||||
SubMutexGuard Guard(Mutex_);
|
||||
std::lock_guard Guard(Mutex_);
|
||||
|
||||
auto Device = Devices_.find(SerialNumber);
|
||||
|
||||
@@ -105,7 +99,7 @@ namespace OpenWifi {
|
||||
|
||||
GWObjects::ConnectionState * DeviceRegistry::Register(const std::string & SerialNumber, WSConnection *Ptr)
|
||||
{
|
||||
SubMutexGuard Guard(Mutex_);
|
||||
std::lock_guard Guard(Mutex_);
|
||||
|
||||
auto Device = Devices_.find(SerialNumber);
|
||||
if( Device == Devices_.end()) {
|
||||
@@ -136,7 +130,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
bool DeviceRegistry::Connected(const std::string & SerialNumber) {
|
||||
SubMutexGuard Guard(Mutex_);
|
||||
std::lock_guard Guard(Mutex_);
|
||||
|
||||
auto Device = Devices_.find(SerialNumber);
|
||||
|
||||
@@ -147,7 +141,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
void DeviceRegistry::UnRegister(const std::string & SerialNumber, WSConnection *Ptr) {
|
||||
SubMutexGuard Guard(Mutex_);
|
||||
std::lock_guard Guard(Mutex_);
|
||||
|
||||
auto Device = Devices_.find(SerialNumber);
|
||||
|
||||
@@ -157,22 +151,27 @@ namespace OpenWifi {
|
||||
Device->second->Conn_.Connected = false;
|
||||
Device->second->Conn_.VerifiedCertificate = GWObjects::NO_CERTIFICATE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool DeviceRegistry::SendFrame(const std::string & SerialNumber, const std::string & Payload) {
|
||||
SubMutexGuard Guard(Mutex_);
|
||||
std::lock_guard Guard(Mutex_);
|
||||
auto Device = Devices_.find(SerialNumber);
|
||||
if(Device!=Devices_.end() && Device->second->WSConn_!= nullptr) {
|
||||
auto *WSConn =
|
||||
static_cast<WSConnection *>(Device->second->WSConn_);
|
||||
return WSConn->Send(Payload);
|
||||
try {
|
||||
return Device->second->WSConn_->Send(Payload);
|
||||
} catch (...) {
|
||||
Logger_.debug(Poco::format("Could not send data to device '%s'", SerialNumber));
|
||||
Device->second->Conn_.Address = "";
|
||||
Device->second->WSConn_ = nullptr;
|
||||
Device->second->Conn_.Connected = false;
|
||||
Device->second->Conn_.VerifiedCertificate = GWObjects::NO_CERTIFICATE;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DeviceRegistry::SetPendingUUID(const std::string & SerialNumber, uint64_t PendingUUID) {
|
||||
SubMutexGuard Guard(Mutex_);
|
||||
std::lock_guard Guard(Mutex_);
|
||||
auto Device = Devices_.find(SerialNumber);
|
||||
if(Device!=Devices_.end()) {
|
||||
Device->second->Conn_.PendingUUID = PendingUUID;
|
||||
@@ -237,7 +236,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
bool DeviceRegistry::AnalyzeRegistry(GWObjects::Dashboard &D) {
|
||||
SubMutexGuard Guard(Mutex_);
|
||||
std::lock_guard Guard(Mutex_);
|
||||
|
||||
for(auto const &[SerialNumber,Connection]:Devices_) {
|
||||
Types::UpdateCountedMap(D.status, Connection->Conn_.Connected ? "connected" : "not connected");
|
||||
|
@@ -11,8 +11,8 @@
|
||||
|
||||
#include "Poco/JSON/Object.h"
|
||||
|
||||
#include "RESTAPI_GWobjects.h"
|
||||
#include "SubSystemServer.h"
|
||||
#include "RESTObjects//RESTAPI_GWobjects.h"
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
// class uCentral::WebSocket::WSConnection;
|
||||
|
||||
|
@@ -10,10 +10,6 @@
|
||||
#include <fstream>
|
||||
#include <cstdio>
|
||||
|
||||
#include "Daemon.h"
|
||||
#include "FileUploader.h"
|
||||
#include "StorageService.h"
|
||||
|
||||
#include "Poco/Net/HTTPServerParams.h"
|
||||
#include "Poco/Net/HTTPServerResponse.h"
|
||||
#include "Poco/DynamicAny.h"
|
||||
@@ -24,7 +20,9 @@
|
||||
#include "Poco/StreamCopier.h"
|
||||
#include "Poco/Exception.h"
|
||||
|
||||
#include "Utils.h"
|
||||
#include "FileUploader.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class FileUploader *FileUploader::instance_ = nullptr;
|
||||
@@ -34,25 +32,23 @@ namespace OpenWifi {
|
||||
int FileUploader::Start() {
|
||||
Logger_.notice("Starting.");
|
||||
|
||||
Poco::File UploadsDir(MicroService::instance().ConfigPath("openwifi.fileuploader.path","/tmp"));
|
||||
Path_ = UploadsDir.path();
|
||||
if(!UploadsDir.exists()) {
|
||||
try {
|
||||
UploadsDir.createDirectory();
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
Path_ = "/tmp";
|
||||
}
|
||||
}
|
||||
for(const auto & Svr: ConfigServersList_) {
|
||||
std::string l{"Starting: " +
|
||||
Svr.Address() + ":" + std::to_string(Svr.Port()) +
|
||||
" key:" + Svr.KeyFile() +
|
||||
" cert:" + Svr.CertFile()};
|
||||
|
||||
Logger_.information(l);
|
||||
|
||||
Poco::File UploadsDir(Daemon()->ConfigPath("ucentral.fileuploader.path","/tmp"));
|
||||
Path_ = UploadsDir.path();
|
||||
if(!UploadsDir.exists()) {
|
||||
try {
|
||||
UploadsDir.createDirectory();
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
Path_ = "/tmp";
|
||||
}
|
||||
}
|
||||
|
||||
auto Sock{Svr.CreateSecureSocket(Logger_)};
|
||||
|
||||
Svr.LogCert(Logger_);
|
||||
@@ -64,26 +60,40 @@ namespace OpenWifi {
|
||||
Params->setMaxQueued(100);
|
||||
|
||||
if(FullName_.empty()) {
|
||||
FullName_ = "https://" + Svr.Name() + ":" + std::to_string(Svr.Port()) + URI_BASE;
|
||||
Logger_.information(Poco::format("Uploader URI base is '%s'", FullName_));
|
||||
std::string TmpName = MicroService::instance().ConfigGetString("openwifi.fileuploader.uri","");
|
||||
if(TmpName.empty()) {
|
||||
FullName_ =
|
||||
"https://" + Svr.Name() + ":" + std::to_string(Svr.Port()) + URI_BASE;
|
||||
} else {
|
||||
FullName_ = TmpName + URI_BASE ;
|
||||
}
|
||||
Logger_.information(Poco::format("Uploader URI base is '%s'", FullName_));
|
||||
}
|
||||
|
||||
auto NewServer = std::make_unique<Poco::Net::HTTPServer>(new FileUpLoaderRequestHandlerFactory(Logger_), Pool_, Sock, Params);
|
||||
NewServer->start();
|
||||
Servers_.push_back(std::move(NewServer));
|
||||
}
|
||||
|
||||
MaxSize_ = 1000 * Daemon()->ConfigGetInt("ucentral.fileuploader.maxsize", 10000);
|
||||
MaxSize_ = 1000 * MicroService::instance().ConfigGetInt("openwifi.fileuploader.maxsize", 10000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FileUploader::reinitialize(Poco::Util::Application &self) {
|
||||
MicroService::instance().LoadConfigurationFile();
|
||||
Logger_.information("Reinitializing.");
|
||||
Stop();
|
||||
Start();
|
||||
}
|
||||
|
||||
const std::string & FileUploader::FullName() {
|
||||
return FullName_;
|
||||
}
|
||||
|
||||
// if you pass in an empty UUID, it will just clean the list and not add it.
|
||||
bool FileUploader::AddUUID( const std::string & UUID) {
|
||||
SubMutexGuard Guard(Mutex_);
|
||||
std::lock_guard Guard(Mutex_);
|
||||
|
||||
uint64_t Now = time(nullptr) ;
|
||||
|
||||
@@ -102,13 +112,13 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
bool FileUploader::ValidRequest(const std::string &UUID) {
|
||||
SubMutexGuard Guard(Mutex_);
|
||||
std::lock_guard Guard(Mutex_);
|
||||
|
||||
return OutStandingUploads_.find(UUID)!=OutStandingUploads_.end();
|
||||
}
|
||||
|
||||
void FileUploader::RemoveRequest(const std::string &UUID) {
|
||||
SubMutexGuard Guard(Mutex_);
|
||||
std::lock_guard Guard(Mutex_);
|
||||
OutStandingUploads_.erase(UUID);
|
||||
}
|
||||
|
||||
@@ -133,19 +143,19 @@ namespace OpenWifi {
|
||||
Name_ = Parameters.get("filename", "(unnamed)");
|
||||
}
|
||||
|
||||
Poco::TemporaryFile TmpFile;
|
||||
std::string FinalFileName = FileUploader()->Path() + "/" + UUID_;
|
||||
Logger_.information(Poco::format("FILE-UPLOADER: uploading trace for %s", UUID_));
|
||||
|
||||
Logger_.information(Poco::format("FILE-UPLOADER: uploading trace for %s", FinalFileName));
|
||||
Poco::CountingInputStream InputStream(Stream);
|
||||
std::ofstream OutputStream(TmpFile.path(), std::ofstream::out);
|
||||
std::ofstream OutputStream(FinalFileName, std::ofstream::out);
|
||||
Poco::StreamCopier::copyStream(InputStream, OutputStream);
|
||||
Length_ = TmpFile.getSize();
|
||||
|
||||
Poco::File TmpFile(FinalFileName);
|
||||
Length_ = TmpFile.getSize();
|
||||
if (Length_ < FileUploader()->MaxSize()) {
|
||||
rename(TmpFile.path().c_str(), FinalFileName.c_str());
|
||||
Good_=true;
|
||||
} else {
|
||||
TmpFile.remove();
|
||||
Error_ = "File is too large.";
|
||||
}
|
||||
return;
|
||||
@@ -193,12 +203,12 @@ namespace OpenWifi {
|
||||
if (partHandler.Good()) {
|
||||
Answer.set("filename", UUID_);
|
||||
Answer.set("error", 0);
|
||||
Storage()->AttachFileToCommand(UUID_);
|
||||
StorageService()->AttachFileToCommand(UUID_);
|
||||
} else {
|
||||
Answer.set("filename", UUID_);
|
||||
Answer.set("error", 13);
|
||||
Answer.set("errorText", partHandler.Error() );
|
||||
Storage()->CancelWaitFile(UUID_, partHandler.Error() );
|
||||
StorageService()->CancelWaitFile(UUID_, partHandler.Error() );
|
||||
}
|
||||
std::ostream &ResponseStream = Response.send();
|
||||
Poco::JSON::Stringifier::stringify(Answer, ResponseStream);
|
||||
@@ -245,6 +255,7 @@ namespace OpenWifi {
|
||||
Logger_.notice("Stopping ");
|
||||
for( const auto & svr : Servers_ )
|
||||
svr->stop();
|
||||
Servers_.clear();
|
||||
}
|
||||
|
||||
} // Namespace
|
@@ -9,13 +9,12 @@
|
||||
#ifndef UCENTRAL_UFILEUPLOADER_H
|
||||
#define UCENTRAL_UFILEUPLOADER_H
|
||||
|
||||
#include "SubSystemServer.h"
|
||||
|
||||
#include "Poco/Net/HTTPServer.h"
|
||||
#include "Poco/Net/HTTPRequestHandler.h"
|
||||
#include "Poco/Net/HTTPRequestHandlerFactory.h"
|
||||
#include "Poco/Net/HTTPServer.h"
|
||||
#include "Poco/Net/HTTPServerRequest.h"
|
||||
#include "RESTAPI_handler.h"
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
@@ -23,6 +22,7 @@ namespace OpenWifi {
|
||||
public:
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
void reinitialize(Poco::Util::Application &self) override;
|
||||
const std::string & FullName();
|
||||
bool AddUUID( const std::string & UUID);
|
||||
bool ValidRequest(const std::string & UUID);
|
||||
@@ -48,9 +48,8 @@ namespace OpenWifi {
|
||||
uint64_t MaxSize_=10000000;
|
||||
|
||||
explicit FileUploader() noexcept:
|
||||
SubSystemServer("FileUploader", "FILE-UPLOAD", "ucentral.fileuploader")
|
||||
SubSystemServer("FileUploader", "FILE-UPLOAD", "openwifi.fileuploader")
|
||||
{
|
||||
SubMutexGuard Guard(Mutex_);
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -1,221 +0,0 @@
|
||||
//
|
||||
// License type: BSD 3-Clause License
|
||||
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
|
||||
//
|
||||
// Created by Stephane Bourque on 2021-03-04.
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
#include <thread>
|
||||
|
||||
#include "KafkaManager.h"
|
||||
|
||||
#include "Daemon.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class KafkaManager *KafkaManager::instance_ = nullptr;
|
||||
|
||||
KafkaManager::KafkaManager() noexcept:
|
||||
SubSystemServer("KafkaManager", "KAFKA-SVR", "ucentral.kafka")
|
||||
{
|
||||
}
|
||||
|
||||
void KafkaManager::initialize(Poco::Util::Application & self) {
|
||||
SubSystemServer::initialize(self);
|
||||
KafkaEnabled_ = Daemon()->ConfigGetBool("ucentral.kafka.enable",false);
|
||||
}
|
||||
|
||||
#ifdef SMALL_BUILD
|
||||
|
||||
int KafkaManager::Start() {
|
||||
return 0;
|
||||
}
|
||||
void KafkaManager::Stop() {
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int KafkaManager::Start() {
|
||||
if(!KafkaEnabled_)
|
||||
return 0;
|
||||
ProducerThr_ = std::make_unique<std::thread>([this]() { this->ProducerThr(); });
|
||||
ConsumerThr_ = std::make_unique<std::thread>([this]() { this->ConsumerThr(); });
|
||||
return 0;
|
||||
}
|
||||
|
||||
void KafkaManager::Stop() {
|
||||
if(KafkaEnabled_) {
|
||||
ProducerRunning_ = ConsumerRunning_ = false;
|
||||
ProducerThr_->join();
|
||||
ConsumerThr_->join();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void KafkaManager::ProducerThr() {
|
||||
cppkafka::Configuration Config({
|
||||
{ "client.id", Daemon()->ConfigGetString("ucentral.kafka.client.id") },
|
||||
{ "metadata.broker.list", Daemon()->ConfigGetString("ucentral.kafka.brokerlist") }
|
||||
});
|
||||
SystemInfoWrapper_ = R"lit({ "system" : { "id" : )lit" +
|
||||
std::to_string(Daemon()->ID()) +
|
||||
R"lit( , "host" : ")lit" + Daemon()->PrivateEndPoint() +
|
||||
R"lit(" } , "payload" : )lit" ;
|
||||
cppkafka::Producer Producer(Config);
|
||||
ProducerRunning_ = true;
|
||||
while(ProducerRunning_) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||
try
|
||||
{
|
||||
SubMutexGuard G(ProducerMutex_);
|
||||
auto Num=0;
|
||||
while (!Queue_.empty()) {
|
||||
const auto M = Queue_.front();
|
||||
Producer.produce(
|
||||
cppkafka::MessageBuilder(M.Topic).key(M.Key).payload(M.PayLoad));
|
||||
Queue_.pop();
|
||||
Num++;
|
||||
}
|
||||
if(Num)
|
||||
Producer.flush();
|
||||
} catch (const cppkafka::HandleException &E ) {
|
||||
Logger_.warning(Poco::format("Caught a Kafka exception (producer): %s",std::string{E.what()}));
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KafkaManager::PartitionAssignment(const cppkafka::TopicPartitionList& partitions) {
|
||||
Logger_.information(Poco::format("Partition assigned: %Lu...",(uint64_t )partitions.front().get_partition()));
|
||||
}
|
||||
void KafkaManager::PartitionRevocation(const cppkafka::TopicPartitionList& partitions) {
|
||||
Logger_.information(Poco::format("Partition revocation: %Lu...",(uint64_t )partitions.front().get_partition()));
|
||||
}
|
||||
|
||||
void KafkaManager::ConsumerThr() {
|
||||
cppkafka::Configuration Config({
|
||||
{ "client.id", Daemon()->ConfigGetString("ucentral.kafka.client.id") },
|
||||
{ "metadata.broker.list", Daemon()->ConfigGetString("ucentral.kafka.brokerlist") },
|
||||
{ "group.id", Daemon()->ConfigGetString("ucentral.kafka.group.id") },
|
||||
{ "enable.auto.commit", Daemon()->ConfigGetBool("ucentral.kafka.auto.commit",false) },
|
||||
{ "auto.offset.reset", "latest" } ,
|
||||
{ "enable.partition.eof", false }
|
||||
});
|
||||
|
||||
cppkafka::TopicConfiguration topic_config = {
|
||||
{ "auto.offset.reset", "smallest" }
|
||||
};
|
||||
|
||||
// Now configure it to be the default topic config
|
||||
Config.set_default_topic_configuration(topic_config);
|
||||
|
||||
cppkafka::Consumer Consumer(Config);
|
||||
Consumer.set_assignment_callback([this](cppkafka::TopicPartitionList& partitions) {
|
||||
if(!partitions.empty()) {
|
||||
Logger_.information(Poco::format("Partition assigned: %Lu...",
|
||||
(uint64_t)partitions.front().get_partition()));
|
||||
}
|
||||
});
|
||||
Consumer.set_revocation_callback([this](const cppkafka::TopicPartitionList& partitions) {
|
||||
if(!partitions.empty()) {
|
||||
Logger_.information(Poco::format("Partition revocation: %Lu...",
|
||||
(uint64_t)partitions.front().get_partition()));
|
||||
}
|
||||
});
|
||||
|
||||
bool AutoCommit = Daemon()->ConfigGetBool("ucentral.kafka.auto.commit",false);
|
||||
auto BatchSize = Daemon()->ConfigGetInt("ucentral.kafka.consumer.batchsize",20);
|
||||
|
||||
Types::StringVec Topics;
|
||||
for(const auto &i:Notifiers_)
|
||||
Topics.push_back(i.first);
|
||||
|
||||
Consumer.subscribe(Topics);
|
||||
|
||||
ConsumerRunning_ = true;
|
||||
while(ConsumerRunning_) {
|
||||
try {
|
||||
std::vector<cppkafka::Message> MsgVec = Consumer.poll_batch(BatchSize, std::chrono::milliseconds(200));
|
||||
for(auto const &Msg:MsgVec) {
|
||||
if (!Msg)
|
||||
continue;
|
||||
if (Msg.get_error()) {
|
||||
if (!Msg.is_eof()) {
|
||||
Logger_.error(Poco::format("Error: %s", Msg.get_error().to_string()));
|
||||
}if(!AutoCommit)
|
||||
Consumer.async_commit(Msg);
|
||||
continue;
|
||||
}
|
||||
SubMutexGuard G(ConsumerMutex_);
|
||||
auto It = Notifiers_.find(Msg.get_topic());
|
||||
if (It != Notifiers_.end()) {
|
||||
Types::TopicNotifyFunctionList &FL = It->second;
|
||||
std::string Key{Msg.get_key()};
|
||||
std::string Payload{Msg.get_payload()};
|
||||
for (auto &F : FL) {
|
||||
std::thread T(F.first, Key, Payload);
|
||||
T.detach();
|
||||
}
|
||||
}
|
||||
if (!AutoCommit)
|
||||
Consumer.async_commit(Msg);
|
||||
}
|
||||
} catch (const cppkafka::HandleException &E) {
|
||||
Logger_.warning(Poco::format("Caught a Kafka exception (consumer): %s",std::string{E.what()}));
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string KafkaManager::WrapSystemId(const std::string & PayLoad) {
|
||||
return std::move( SystemInfoWrapper_ + PayLoad + "}");
|
||||
}
|
||||
|
||||
void KafkaManager::PostMessage(std::string topic, std::string key, std::string PayLoad, bool WrapMessage ) {
|
||||
if(KafkaEnabled_) {
|
||||
SubMutexGuard G(Mutex_);
|
||||
KMessage M{
|
||||
.Topic = topic,
|
||||
.Key = key,
|
||||
.PayLoad = WrapMessage ? WrapSystemId(PayLoad) : PayLoad };
|
||||
Queue_.push(M);
|
||||
}
|
||||
}
|
||||
|
||||
int KafkaManager::RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F) {
|
||||
if(KafkaEnabled_) {
|
||||
SubMutexGuard G(Mutex_);
|
||||
auto It = Notifiers_.find(Topic);
|
||||
if(It == Notifiers_.end()) {
|
||||
Types::TopicNotifyFunctionList L;
|
||||
L.emplace(L.end(),std::make_pair(F,FunctionId_));
|
||||
Notifiers_[Topic] = std::move(L);
|
||||
} else {
|
||||
It->second.emplace(It->second.end(),std::make_pair(F,FunctionId_));
|
||||
}
|
||||
return FunctionId_++;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void KafkaManager::UnregisterTopicWatcher(const std::string &Topic, int Id) {
|
||||
if(KafkaEnabled_) {
|
||||
SubMutexGuard G(Mutex_);
|
||||
auto It = Notifiers_.find(Topic);
|
||||
if(It != Notifiers_.end()) {
|
||||
Types::TopicNotifyFunctionList & L = It->second;
|
||||
for(auto it=L.begin(); it!=L.end(); it++)
|
||||
if(it->second == Id) {
|
||||
L.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
} // namespace
|
@@ -1,74 +0,0 @@
|
||||
//
|
||||
// License type: BSD 3-Clause License
|
||||
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
|
||||
//
|
||||
// Created by Stephane Bourque on 2021-03-04.
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
#ifndef UCENTRALGW_KAFKAMANAGER_H
|
||||
#define UCENTRALGW_KAFKAMANAGER_H
|
||||
|
||||
#include <queue>
|
||||
#include <thread>
|
||||
|
||||
#include "SubSystemServer.h"
|
||||
#include "OpenWifiTypes.h"
|
||||
|
||||
#include "cppkafka/cppkafka.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class KafkaManager : public SubSystemServer {
|
||||
public:
|
||||
|
||||
struct KMessage {
|
||||
std::string Topic,
|
||||
Key,
|
||||
PayLoad;
|
||||
};
|
||||
|
||||
void initialize(Poco::Util::Application & self) override;
|
||||
static KafkaManager *instance() {
|
||||
if(instance_== nullptr)
|
||||
instance_ = new KafkaManager;
|
||||
return instance_;
|
||||
}
|
||||
|
||||
void ProducerThr();
|
||||
void ConsumerThr();
|
||||
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
|
||||
void PostMessage(std::string topic, std::string key, std::string payload, bool WrapMessage = true);
|
||||
[[nodiscard]] std::string WrapSystemId(const std::string & PayLoad);
|
||||
[[nodiscard]] bool Enabled() { return KafkaEnabled_; }
|
||||
int RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction & F);
|
||||
void UnregisterTopicWatcher(const std::string &Topic, int FunctionId);
|
||||
void WakeUp();
|
||||
void PartitionAssignment(const cppkafka::TopicPartitionList& partitions);
|
||||
void PartitionRevocation(const cppkafka::TopicPartitionList& partitions);
|
||||
|
||||
private:
|
||||
static KafkaManager *instance_;
|
||||
SubMutex ProducerMutex_;
|
||||
SubMutex ConsumerMutex_;
|
||||
bool KafkaEnabled_ = false;
|
||||
std::atomic_bool ProducerRunning_ = false;
|
||||
std::atomic_bool ConsumerRunning_ = false;
|
||||
std::queue<KMessage> Queue_;
|
||||
std::string SystemInfoWrapper_;
|
||||
std::unique_ptr<std::thread> ConsumerThr_;
|
||||
std::unique_ptr<std::thread> ProducerThr_;
|
||||
int FunctionId_=1;
|
||||
Types::NotifyTable Notifiers_;
|
||||
std::unique_ptr<cppkafka::Configuration> Config_;
|
||||
|
||||
KafkaManager() noexcept;
|
||||
};
|
||||
|
||||
inline KafkaManager * KafkaManager() { return KafkaManager::instance(); }
|
||||
} // NameSpace
|
||||
|
||||
#endif // UCENTRALGW_KAFKAMANAGER_H
|
@@ -1,501 +0,0 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-06-22.
|
||||
//
|
||||
#include <cstdlib>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include "Poco/Util/Application.h"
|
||||
#include "Poco/Util/ServerApplication.h"
|
||||
#include "Poco/Util/Option.h"
|
||||
#include "Poco/Util/OptionSet.h"
|
||||
#include "Poco/Util/HelpFormatter.h"
|
||||
#include "Poco/Environment.h"
|
||||
#include "Poco/Net/HTTPSStreamFactory.h"
|
||||
#include "Poco/Net/HTTPStreamFactory.h"
|
||||
#include "Poco/Net/FTPSStreamFactory.h"
|
||||
#include "Poco/Net/FTPStreamFactory.h"
|
||||
#include "Poco/Path.h"
|
||||
#include "Poco/File.h"
|
||||
#include "Poco/String.h"
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include "Poco/JSON/Parser.h"
|
||||
#include "Poco/JSON/Stringifier.h"
|
||||
|
||||
#include "ALBHealthCheckServer.h"
|
||||
#ifndef SMALL_BUILD
|
||||
#include "KafkaManager.h"
|
||||
#endif
|
||||
#include "Kafka_topics.h"
|
||||
|
||||
#include "MicroService.h"
|
||||
#include "Utils.h"
|
||||
|
||||
#ifndef TIP_SECURITY_SERVICE
|
||||
#include "AuthClient.h"
|
||||
#endif
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
void MyErrorHandler::exception(const Poco::Exception & E) {
|
||||
Poco::Thread * CurrentThread = Poco::Thread::current();
|
||||
App_.logger().log(E);
|
||||
App_.logger().error(Poco::format("Exception occurred in %s",CurrentThread->getName()));
|
||||
}
|
||||
|
||||
void MyErrorHandler::exception(const std::exception & E) {
|
||||
Poco::Thread * CurrentThread = Poco::Thread::current();
|
||||
App_.logger().warning(Poco::format("std::exception on %s",CurrentThread->getName()));
|
||||
}
|
||||
|
||||
void MyErrorHandler::exception() {
|
||||
Poco::Thread * CurrentThread = Poco::Thread::current();
|
||||
App_.logger().warning(Poco::format("exception on %s",CurrentThread->getName()));
|
||||
}
|
||||
|
||||
void MicroService::Exit(int Reason) {
|
||||
std::exit(Reason);
|
||||
}
|
||||
|
||||
void MicroService::BusMessageReceived(const std::string &Key, const std::string & Message) {
|
||||
SubMutexGuard G(InfraMutex_);
|
||||
try {
|
||||
Poco::JSON::Parser P;
|
||||
auto Object = P.parse(Message).extract<Poco::JSON::Object::Ptr>();
|
||||
if (Object->has(KafkaTopics::ServiceEvents::Fields::ID) &&
|
||||
Object->has(KafkaTopics::ServiceEvents::Fields::EVENT)) {
|
||||
uint64_t ID = Object->get(KafkaTopics::ServiceEvents::Fields::ID);
|
||||
auto Event = Object->get(KafkaTopics::ServiceEvents::Fields::EVENT).toString();
|
||||
if (ID != ID_) {
|
||||
if( Event==KafkaTopics::ServiceEvents::EVENT_JOIN ||
|
||||
Event==KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE ||
|
||||
Event==KafkaTopics::ServiceEvents::EVENT_LEAVE ) {
|
||||
if( Object->has(KafkaTopics::ServiceEvents::Fields::TYPE) &&
|
||||
Object->has(KafkaTopics::ServiceEvents::Fields::PUBLIC) &&
|
||||
Object->has(KafkaTopics::ServiceEvents::Fields::PRIVATE) &&
|
||||
Object->has(KafkaTopics::ServiceEvents::Fields::VRSN) &&
|
||||
Object->has(KafkaTopics::ServiceEvents::Fields::KEY)) {
|
||||
|
||||
if (Event == KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE && Services_.find(ID) != Services_.end()) {
|
||||
Services_[ID].LastUpdate = std::time(nullptr);
|
||||
} else if (Event == KafkaTopics::ServiceEvents::EVENT_LEAVE) {
|
||||
Services_.erase(ID);
|
||||
logger().information(Poco::format("Service %s ID=%Lu leaving system.",Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString(),ID));
|
||||
} else if (Event == KafkaTopics::ServiceEvents::EVENT_JOIN || Event == KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE) {
|
||||
logger().information(Poco::format("Service %s ID=%Lu joining system.",Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString(),ID));
|
||||
Services_[ID] = MicroServiceMeta{
|
||||
.Id = ID,
|
||||
.Type = Poco::toLower(Object->get(KafkaTopics::ServiceEvents::Fields::TYPE).toString()),
|
||||
.PrivateEndPoint = Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString(),
|
||||
.PublicEndPoint = Object->get(KafkaTopics::ServiceEvents::Fields::PUBLIC).toString(),
|
||||
.AccessKey = Object->get(KafkaTopics::ServiceEvents::Fields::KEY).toString(),
|
||||
.Version = Object->get(KafkaTopics::ServiceEvents::Fields::VRSN).toString(),
|
||||
.LastUpdate = (uint64_t)std::time(nullptr)};
|
||||
for (const auto &[Id, Svc] : Services_) {
|
||||
logger().information(Poco::format("ID: %Lu Type: %s EndPoint: %s",Id,Svc.Type,Svc.PrivateEndPoint));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger().error(Poco::format("KAFKA-MSG: invalid event '%s', missing a field.",Event));
|
||||
}
|
||||
} else if (Event==KafkaTopics::ServiceEvents::EVENT_REMOVE_TOKEN) {
|
||||
if(Object->has(KafkaTopics::ServiceEvents::Fields::TOKEN)) {
|
||||
#ifndef TIP_SECURITY_SERVICE
|
||||
AuthClient()->RemovedCachedToken(Object->get(KafkaTopics::ServiceEvents::Fields::TOKEN).toString());
|
||||
#endif
|
||||
} else {
|
||||
logger().error(Poco::format("KAFKA-MSG: invalid event '%s', missing token",Event));
|
||||
}
|
||||
} else {
|
||||
logger().error(Poco::format("Unknown Event: %s Source: %Lu", Event, ID));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger().error("Bad bus message.");
|
||||
}
|
||||
|
||||
auto i=Services_.begin();
|
||||
auto Now = (uint64_t )std::time(nullptr);
|
||||
for(;i!=Services_.end();) {
|
||||
if((Now - i->second.LastUpdate)>60) {
|
||||
i = Services_.erase(i);
|
||||
} else
|
||||
++i;
|
||||
}
|
||||
|
||||
} catch (const Poco::Exception &E) {
|
||||
logger().log(E);
|
||||
}
|
||||
}
|
||||
|
||||
MicroServiceMetaVec MicroService::GetServices(const std::string & Type) {
|
||||
SubMutexGuard G(InfraMutex_);
|
||||
|
||||
auto T = Poco::toLower(Type);
|
||||
MicroServiceMetaVec Res;
|
||||
for(const auto &[Id,ServiceRec]:Services_) {
|
||||
if(ServiceRec.Type==T)
|
||||
Res.push_back(ServiceRec);
|
||||
}
|
||||
return Res;
|
||||
}
|
||||
|
||||
MicroServiceMetaVec MicroService::GetServices() {
|
||||
SubMutexGuard G(InfraMutex_);
|
||||
|
||||
MicroServiceMetaVec Res;
|
||||
for(const auto &[Id,ServiceRec]:Services_) {
|
||||
Res.push_back(ServiceRec);
|
||||
}
|
||||
return Res;
|
||||
}
|
||||
|
||||
void MicroService::initialize(Poco::Util::Application &self) {
|
||||
// add the default services
|
||||
SubSystems_.push_back(KafkaManager());
|
||||
SubSystems_.push_back(ALBHealthCheckServer());
|
||||
|
||||
Poco::Net::initializeSSL();
|
||||
Poco::Net::HTTPStreamFactory::registerFactory();
|
||||
Poco::Net::HTTPSStreamFactory::registerFactory();
|
||||
Poco::Net::FTPStreamFactory::registerFactory();
|
||||
Poco::Net::FTPSStreamFactory::registerFactory();
|
||||
std::string Location = Poco::Environment::get(DAEMON_CONFIG_ENV_VAR,".");
|
||||
Poco::Path ConfigFile;
|
||||
|
||||
ConfigFile = ConfigFileName_.empty() ? Location + "/" + DAEMON_PROPERTIES_FILENAME : ConfigFileName_;
|
||||
|
||||
if(!ConfigFile.isFile())
|
||||
{
|
||||
std::cerr << DAEMON_APP_NAME << ": Configuration "
|
||||
<< ConfigFile.toString() << " does not seem to exist. Please set " + DAEMON_CONFIG_ENV_VAR
|
||||
+ " env variable the path of the " + DAEMON_PROPERTIES_FILENAME + " file." << std::endl;
|
||||
std::exit(Poco::Util::Application::EXIT_CONFIG);
|
||||
}
|
||||
|
||||
static const char * LogFilePathKey = "logging.channels.c2.path";
|
||||
|
||||
loadConfiguration(ConfigFile.toString());
|
||||
|
||||
if(LogDir_.empty()) {
|
||||
std::string OriginalLogFileValue = ConfigPath(LogFilePathKey);
|
||||
config().setString(LogFilePathKey, OriginalLogFileValue);
|
||||
} else {
|
||||
config().setString(LogFilePathKey, LogDir_);
|
||||
}
|
||||
Poco::File DataDir(ConfigPath("ucentral.system.data"));
|
||||
DataDir_ = DataDir.path();
|
||||
if(!DataDir.exists()) {
|
||||
try {
|
||||
DataDir.createDirectory();
|
||||
} catch (const Poco::Exception &E) {
|
||||
logger().log(E);
|
||||
}
|
||||
}
|
||||
std::string KeyFile = ConfigPath("ucentral.service.key");
|
||||
std::string KeyFilePassword = ConfigPath("ucentral.service.key.password" , "" );
|
||||
AppKey_ = Poco::SharedPtr<Poco::Crypto::RSAKey>(new Poco::Crypto::RSAKey("", KeyFile, KeyFilePassword));
|
||||
Cipher_ = CipherFactory_.createCipher(*AppKey_);
|
||||
ID_ = Utils::GetSystemId();
|
||||
if(!DebugMode_)
|
||||
DebugMode_ = ConfigGetBool("ucentral.system.debug",false);
|
||||
MyPrivateEndPoint_ = ConfigGetString("ucentral.system.uri.private");
|
||||
MyPublicEndPoint_ = ConfigGetString("ucentral.system.uri.public");
|
||||
UIURI_ = ConfigGetString("ucentral.system.uri.ui");
|
||||
MyHash_ = CreateHash(MyPublicEndPoint_);
|
||||
InitializeSubSystemServers();
|
||||
ServerApplication::initialize(self);
|
||||
|
||||
Types::TopicNotifyFunction F = [this](std::string s1,std::string s2) { this->BusMessageReceived(s1,s2); };
|
||||
KafkaManager()->RegisterTopicWatcher(KafkaTopics::SERVICE_EVENTS, F);
|
||||
}
|
||||
|
||||
void MicroService::uninitialize() {
|
||||
// add your own uninitialization code here
|
||||
ServerApplication::uninitialize();
|
||||
}
|
||||
|
||||
void MicroService::reinitialize(Poco::Util::Application &self) {
|
||||
ServerApplication::reinitialize(self);
|
||||
// add your own reinitialization code here
|
||||
}
|
||||
|
||||
void MicroService::defineOptions(Poco::Util::OptionSet &options) {
|
||||
ServerApplication::defineOptions(options);
|
||||
|
||||
options.addOption(
|
||||
Poco::Util::Option("help", "", "display help information on command line arguments")
|
||||
.required(false)
|
||||
.repeatable(false)
|
||||
.callback(Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleHelp)));
|
||||
|
||||
options.addOption(
|
||||
Poco::Util::Option("file", "", "specify the configuration file")
|
||||
.required(false)
|
||||
.repeatable(false)
|
||||
.argument("file")
|
||||
.callback(Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleConfig)));
|
||||
|
||||
options.addOption(
|
||||
Poco::Util::Option("debug", "", "to run in debug, set to true")
|
||||
.required(false)
|
||||
.repeatable(false)
|
||||
.callback(Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleDebug)));
|
||||
|
||||
options.addOption(
|
||||
Poco::Util::Option("logs", "", "specify the log directory and file (i.e. dir/file.log)")
|
||||
.required(false)
|
||||
.repeatable(false)
|
||||
.argument("dir")
|
||||
.callback(Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleLogs)));
|
||||
|
||||
options.addOption(
|
||||
Poco::Util::Option("version", "", "get the version and quit.")
|
||||
.required(false)
|
||||
.repeatable(false)
|
||||
.callback(Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleVersion)));
|
||||
|
||||
}
|
||||
|
||||
void MicroService::handleHelp(const std::string &name, const std::string &value) {
|
||||
HelpRequested_ = true;
|
||||
displayHelp();
|
||||
stopOptionsProcessing();
|
||||
}
|
||||
|
||||
void MicroService::handleVersion(const std::string &name, const std::string &value) {
|
||||
HelpRequested_ = true;
|
||||
std::cout << Version() << std::endl;
|
||||
stopOptionsProcessing();
|
||||
}
|
||||
|
||||
void MicroService::handleDebug(const std::string &name, const std::string &value) {
|
||||
if(value == "true")
|
||||
DebugMode_ = true ;
|
||||
}
|
||||
|
||||
void MicroService::handleLogs(const std::string &name, const std::string &value) {
|
||||
LogDir_ = value;
|
||||
}
|
||||
|
||||
void MicroService::handleConfig(const std::string &name, const std::string &value) {
|
||||
ConfigFileName_ = value;
|
||||
}
|
||||
|
||||
void MicroService::displayHelp() {
|
||||
Poco::Util::HelpFormatter helpFormatter(options());
|
||||
helpFormatter.setCommand(commandName());
|
||||
helpFormatter.setUsage("OPTIONS");
|
||||
helpFormatter.setHeader("A " + DAEMON_APP_NAME + " implementation for TIP.");
|
||||
helpFormatter.format(std::cout);
|
||||
}
|
||||
|
||||
void MicroService::InitializeSubSystemServers() {
|
||||
for(auto i:SubSystems_)
|
||||
addSubsystem(i);
|
||||
}
|
||||
|
||||
void MicroService::StartSubSystemServers() {
|
||||
for(auto i:SubSystems_) {
|
||||
i->Start();
|
||||
}
|
||||
BusEventManager_.Start();
|
||||
}
|
||||
|
||||
void MicroService::StopSubSystemServers() {
|
||||
BusEventManager_.Stop();
|
||||
for(auto i=SubSystems_.rbegin(); i!=SubSystems_.rend(); ++i)
|
||||
(*i)->Stop();
|
||||
}
|
||||
|
||||
std::string MicroService::CreateUUID() {
|
||||
return UUIDGenerator_.create().toString();
|
||||
}
|
||||
|
||||
bool MicroService::SetSubsystemLogLevel(const std::string &SubSystem, const std::string &Level) {
|
||||
try {
|
||||
auto P = Poco::Logger::parseLevel(Level);
|
||||
auto Sub = Poco::toLower(SubSystem);
|
||||
|
||||
if (Sub == "all") {
|
||||
for (auto i : SubSystems_) {
|
||||
i->Logger().setLevel(P);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
// std::cout << "Sub:" << SubSystem << " Level:" << Level << std::endl;
|
||||
for (auto i : SubSystems_) {
|
||||
if (Sub == Poco::toLower(i->Name())) {
|
||||
i->Logger().setLevel(P);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (const Poco::Exception & E) {
|
||||
std::cout << "Exception" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Types::StringVec MicroService::GetSubSystems() const {
|
||||
Types::StringVec Result;
|
||||
for(auto i:SubSystems_)
|
||||
Result.push_back(i->Name());
|
||||
return Result;
|
||||
}
|
||||
|
||||
Types::StringPairVec MicroService::GetLogLevels() const {
|
||||
Types::StringPairVec Result;
|
||||
|
||||
for(auto &i:SubSystems_) {
|
||||
auto P = std::make_pair( i->Name(), Utils::LogLevelToString(i->GetLoggingLevel()));
|
||||
Result.push_back(P);
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
const Types::StringVec & MicroService::GetLogLevelNames() const {
|
||||
static Types::StringVec LevelNames{"none", "fatal", "critical", "error", "warning", "notice", "information", "debug", "trace" };
|
||||
return LevelNames;
|
||||
}
|
||||
|
||||
uint64_t MicroService::ConfigGetInt(const std::string &Key,uint64_t Default) {
|
||||
return (uint64_t) config().getInt64(Key,Default);
|
||||
}
|
||||
|
||||
uint64_t MicroService::ConfigGetInt(const std::string &Key) {
|
||||
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) {
|
||||
return config().getBool(Key);
|
||||
}
|
||||
|
||||
std::string MicroService::ConfigGetString(const std::string &Key,const std::string & Default) {
|
||||
return config().getString(Key, Default);
|
||||
}
|
||||
|
||||
std::string MicroService::ConfigGetString(const std::string &Key) {
|
||||
return config().getString(Key);
|
||||
}
|
||||
|
||||
std::string MicroService::ConfigPath(const std::string &Key,const std::string & Default) {
|
||||
std::string R = config().getString(Key, Default);
|
||||
return Poco::Path::expand(R);
|
||||
}
|
||||
|
||||
std::string MicroService::ConfigPath(const std::string &Key) {
|
||||
std::string R = config().getString(Key);
|
||||
return Poco::Path::expand(R);
|
||||
}
|
||||
|
||||
std::string MicroService::Encrypt(const std::string &S) {
|
||||
return Cipher_->encryptString(S, Poco::Crypto::Cipher::Cipher::ENC_BASE64);;
|
||||
}
|
||||
|
||||
std::string MicroService::Decrypt(const std::string &S) {
|
||||
return Cipher_->decryptString(S, Poco::Crypto::Cipher::Cipher::ENC_BASE64);;
|
||||
}
|
||||
|
||||
std::string MicroService::CreateHash(const std::string &S) {
|
||||
SHA2_.update(S);
|
||||
return Utils::ToHex(SHA2_.digest());
|
||||
}
|
||||
|
||||
std::string MicroService::MakeSystemEventMessage( const std::string & Type ) const {
|
||||
Poco::JSON::Object Obj;
|
||||
Obj.set(KafkaTopics::ServiceEvents::Fields::EVENT,Type);
|
||||
Obj.set(KafkaTopics::ServiceEvents::Fields::ID,ID_);
|
||||
Obj.set(KafkaTopics::ServiceEvents::Fields::TYPE,Poco::toLower(DAEMON_APP_NAME));
|
||||
Obj.set(KafkaTopics::ServiceEvents::Fields::PUBLIC,MyPublicEndPoint_);
|
||||
Obj.set(KafkaTopics::ServiceEvents::Fields::PRIVATE,MyPrivateEndPoint_);
|
||||
Obj.set(KafkaTopics::ServiceEvents::Fields::KEY,MyHash_);
|
||||
Obj.set(KafkaTopics::ServiceEvents::Fields::VRSN,Version_);
|
||||
std::stringstream ResultText;
|
||||
Poco::JSON::Stringifier::stringify(Obj, ResultText);
|
||||
return ResultText.str();
|
||||
}
|
||||
|
||||
void BusEventManager::run() {
|
||||
Running_ = true;
|
||||
auto Msg = Daemon()->MakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_JOIN);
|
||||
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,Daemon()->PrivateEndPoint(),Msg, false);
|
||||
while(Running_) {
|
||||
Poco::Thread::trySleep((unsigned long)Daemon()->DaemonBusTimer());
|
||||
if(!Running_)
|
||||
break;
|
||||
auto Msg = Daemon()->MakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE);
|
||||
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,Daemon()->PrivateEndPoint(),Msg, false);
|
||||
}
|
||||
Msg = Daemon()->MakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_LEAVE);
|
||||
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,Daemon()->PrivateEndPoint(),Msg, false);
|
||||
};
|
||||
|
||||
void BusEventManager::Start() {
|
||||
if(KafkaManager()->Enabled()) {
|
||||
Thread_.start(*this);
|
||||
}
|
||||
}
|
||||
|
||||
void BusEventManager::Stop() {
|
||||
if(KafkaManager()->Enabled()) {
|
||||
Running_ = false;
|
||||
Thread_.wakeUp();
|
||||
Thread_.join();
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] bool MicroService::IsValidAPIKEY(const Poco::Net::HTTPServerRequest &Request) {
|
||||
try {
|
||||
auto APIKEY = Request.get("X-API-KEY");
|
||||
return APIKEY == MyHash_;
|
||||
} catch (const Poco::Exception &E) {
|
||||
logger().log(E);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MicroService::SavePID() {
|
||||
try {
|
||||
std::ofstream O;
|
||||
O.open(Daemon()->DataDir() + "/pidfile",std::ios::binary | std::ios::trunc);
|
||||
O << Poco::Process::id();
|
||||
O.close();
|
||||
} catch (...)
|
||||
{
|
||||
std::cout << "Could not save system ID" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
int MicroService::main(const ArgVec &args) {
|
||||
|
||||
MyErrorHandler ErrorHandler(*this);
|
||||
Poco::ErrorHandler::set(&ErrorHandler);
|
||||
|
||||
if (!HelpRequested_) {
|
||||
SavePID();
|
||||
Poco::Logger &logger = Poco::Logger::get(DAEMON_APP_NAME);
|
||||
logger.notice(Poco::format("Starting %s version %s.",DAEMON_APP_NAME, Version()));
|
||||
|
||||
if(Poco::Net::Socket::supportsIPv6())
|
||||
logger.information("System supports IPv6.");
|
||||
else
|
||||
logger.information("System does NOT support IPv6.");
|
||||
|
||||
if (config().getBool("application.runAsDaemon", false)) {
|
||||
logger.information("Starting as a daemon.");
|
||||
}
|
||||
logger.information(Poco::format("System ID set to %Lu",ID_));
|
||||
StartSubSystemServers();
|
||||
waitForTerminationRequest();
|
||||
StopSubSystemServers();
|
||||
|
||||
logger.notice(Poco::format("Stopped %s...",DAEMON_APP_NAME));
|
||||
}
|
||||
|
||||
return Application::EXIT_OK;
|
||||
}
|
||||
}
|
@@ -1,174 +0,0 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-06-22.
|
||||
//
|
||||
|
||||
#ifndef UCENTRALGW_MICROSERVICE_H
|
||||
#define UCENTRALGW_MICROSERVICE_H
|
||||
|
||||
#include <array>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
#include "Poco/Util/Application.h"
|
||||
#include "Poco/Util/ServerApplication.h"
|
||||
#include "Poco/Util/Option.h"
|
||||
#include "Poco/Util/OptionSet.h"
|
||||
#include "Poco/UUIDGenerator.h"
|
||||
#include "Poco/ErrorHandler.h"
|
||||
#include "Poco/Crypto/RSAKey.h"
|
||||
#include "Poco/Crypto/CipherFactory.h"
|
||||
#include "Poco/Crypto/Cipher.h"
|
||||
#include "Poco/SHA2Engine.h"
|
||||
#include "Poco/Net/HTTPServerRequest.h"
|
||||
#include "Poco/Process.h"
|
||||
|
||||
#include "OpenWifiTypes.h"
|
||||
#include "SubSystemServer.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
static const std::string uSERVICE_SECURITY{"ucentralsec"};
|
||||
static const std::string uSERVICE_GATEWAY{"ucentralgw"};
|
||||
static const std::string uSERVICE_FIRMWARE{ "ucentralfms"};
|
||||
static const std::string uSERVICE_TOPOLOGY{ "owtopo"};
|
||||
static const std::string uSERVICE_PROVISIONING{ "owprov"};
|
||||
|
||||
class MyErrorHandler : public Poco::ErrorHandler {
|
||||
public:
|
||||
explicit MyErrorHandler(Poco::Util::Application &App) : App_(App) {}
|
||||
void exception(const Poco::Exception & E) override;
|
||||
void exception(const std::exception & E) override;
|
||||
void exception() override;
|
||||
private:
|
||||
Poco::Util::Application &App_;
|
||||
};
|
||||
|
||||
class BusEventManager : public Poco::Runnable {
|
||||
public:
|
||||
void run() override;
|
||||
void Start();
|
||||
void Stop();
|
||||
private:
|
||||
std::atomic_bool Running_ = false;
|
||||
Poco::Thread Thread_;
|
||||
};
|
||||
|
||||
struct MicroServiceMeta {
|
||||
uint64_t Id=0;
|
||||
std::string Type;
|
||||
std::string PrivateEndPoint;
|
||||
std::string PublicEndPoint;
|
||||
std::string AccessKey;
|
||||
std::string Version;
|
||||
uint64_t LastUpdate=0;
|
||||
};
|
||||
|
||||
typedef std::map<uint64_t, MicroServiceMeta> MicroServiceMetaMap;
|
||||
typedef std::vector<MicroServiceMeta> MicroServiceMetaVec;
|
||||
|
||||
class MicroService : public Poco::Util::ServerApplication {
|
||||
public:
|
||||
explicit MicroService( std::string PropFile,
|
||||
std::string RootEnv,
|
||||
std::string ConfigVar,
|
||||
std::string AppName,
|
||||
uint64_t BusTimer,
|
||||
Types::SubSystemVec Subsystems) :
|
||||
DAEMON_PROPERTIES_FILENAME(std::move(PropFile)),
|
||||
DAEMON_ROOT_ENV_VAR(std::move(RootEnv)),
|
||||
DAEMON_CONFIG_ENV_VAR(std::move(ConfigVar)),
|
||||
DAEMON_APP_NAME(std::move(AppName)),
|
||||
DAEMON_BUS_TIMER(BusTimer),
|
||||
SubSystems_(std::move(Subsystems)) {
|
||||
std::string V{APP_VERSION};
|
||||
std::string B{BUILD_NUMBER};
|
||||
Version_ = V + "(" + B + ")";
|
||||
}
|
||||
|
||||
int main(const ArgVec &args) override;
|
||||
void initialize(Application &self) override;
|
||||
void uninitialize() override;
|
||||
void reinitialize(Application &self) override;
|
||||
void defineOptions(Poco::Util::OptionSet &options) override;
|
||||
void handleHelp(const std::string &name, const std::string &value);
|
||||
void handleVersion(const std::string &name, const std::string &value);
|
||||
void handleDebug(const std::string &name, const std::string &value);
|
||||
void handleLogs(const std::string &name, const std::string &value);
|
||||
void handleConfig(const std::string &name, const std::string &value);
|
||||
void displayHelp();
|
||||
|
||||
void InitializeSubSystemServers();
|
||||
void StartSubSystemServers();
|
||||
void StopSubSystemServers();
|
||||
void Exit(int Reason);
|
||||
bool SetSubsystemLogLevel(const std::string & SubSystem, const std::string & Level);
|
||||
[[nodiscard]] std::string Version() { return Version_; }
|
||||
[[nodiscard]] const Poco::SharedPtr<Poco::Crypto::RSAKey> & Key() { return AppKey_; }
|
||||
[[nodiscard]] inline const std::string & DataDir() { return DataDir_; }
|
||||
[[nodiscard]] std::string CreateUUID();
|
||||
[[nodiscard]] bool Debug() const { return DebugMode_; }
|
||||
[[nodiscard]] uint64_t ID() const { return ID_; }
|
||||
[[nodiscard]] Types::StringVec GetSubSystems() const;
|
||||
[[nodiscard]] Types::StringPairVec GetLogLevels() const;
|
||||
[[nodiscard]] const Types::StringVec & GetLogLevelNames() const;
|
||||
[[nodiscard]] std::string ConfigGetString(const std::string &Key,const std::string & Default);
|
||||
[[nodiscard]] std::string ConfigGetString(const std::string &Key);
|
||||
[[nodiscard]] std::string ConfigPath(const std::string &Key,const std::string & Default);
|
||||
[[nodiscard]] std::string ConfigPath(const std::string &Key);
|
||||
[[nodiscard]] uint64_t ConfigGetInt(const std::string &Key,uint64_t Default);
|
||||
[[nodiscard]] uint64_t ConfigGetInt(const std::string &Key);
|
||||
[[nodiscard]] uint64_t ConfigGetBool(const std::string &Key,bool Default);
|
||||
[[nodiscard]] uint64_t ConfigGetBool(const std::string &Key);
|
||||
[[nodiscard]] std::string Encrypt(const std::string &S);
|
||||
[[nodiscard]] std::string Decrypt(const std::string &S);
|
||||
[[nodiscard]] std::string CreateHash(const std::string &S);
|
||||
[[nodiscard]] std::string Hash() const { return MyHash_; };
|
||||
[[nodiscard]] std::string ServiceType() const { return DAEMON_APP_NAME; };
|
||||
[[nodiscard]] std::string PrivateEndPoint() const { return MyPrivateEndPoint_; };
|
||||
[[nodiscard]] std::string PublicEndPoint() const { return MyPublicEndPoint_; };
|
||||
[[nodiscard]] std::string MakeSystemEventMessage( const std::string & Type ) const ;
|
||||
inline uint64_t DaemonBusTimer() const { return DAEMON_BUS_TIMER; };
|
||||
|
||||
void BusMessageReceived( const std::string & Key, const std::string & Message);
|
||||
[[nodiscard]] MicroServiceMetaVec GetServices(const std::string & type);
|
||||
[[nodiscard]] MicroServiceMetaVec GetServices();
|
||||
[[nodiscard]] bool IsValidAPIKEY(const Poco::Net::HTTPServerRequest &Request);
|
||||
|
||||
void SavePID();
|
||||
inline uint64_t GetPID() { return Poco::Process::id(); };
|
||||
[[nodiscard]] inline const std::string GetPublicAPIEndPoint() const { return MyPublicEndPoint_ + "/api/v1"; };
|
||||
[[nodiscard]] inline const std::string & GetUIURI() const { return UIURI_;};
|
||||
|
||||
private:
|
||||
bool HelpRequested_ = false;
|
||||
std::string LogDir_;
|
||||
std::string ConfigFileName_;
|
||||
Poco::UUIDGenerator UUIDGenerator_;
|
||||
uint64_t ID_ = 1;
|
||||
Poco::SharedPtr<Poco::Crypto::RSAKey> AppKey_ = nullptr;
|
||||
bool DebugMode_ = false;
|
||||
std::string DataDir_;
|
||||
Types::SubSystemVec SubSystems_;
|
||||
Poco::Crypto::CipherFactory & CipherFactory_ = Poco::Crypto::CipherFactory::defaultFactory();
|
||||
Poco::Crypto::Cipher * Cipher_ = nullptr;
|
||||
Poco::SHA2Engine SHA2_;
|
||||
MicroServiceMetaMap Services_;
|
||||
std::string MyHash_;
|
||||
std::string MyPrivateEndPoint_;
|
||||
std::string MyPublicEndPoint_;
|
||||
std::string UIURI_;
|
||||
std::string Version_;
|
||||
BusEventManager BusEventManager_;
|
||||
SubMutex InfraMutex_;
|
||||
|
||||
std::string DAEMON_PROPERTIES_FILENAME;
|
||||
std::string DAEMON_ROOT_ENV_VAR;
|
||||
std::string DAEMON_CONFIG_ENV_VAR;
|
||||
std::string DAEMON_APP_NAME;
|
||||
uint64_t DAEMON_BUS_TIMER;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // UCENTRALGW_MICROSERVICE_H
|
@@ -6,7 +6,6 @@
|
||||
#include <vector>
|
||||
|
||||
#include "OUIServer.h"
|
||||
#include "Daemon.h"
|
||||
|
||||
#include "Poco/String.h"
|
||||
#include "Poco/StringTokenizer.h"
|
||||
@@ -15,7 +14,8 @@
|
||||
#include "Poco/URI.h"
|
||||
#include "Poco/File.h"
|
||||
|
||||
#include "Utils.h"
|
||||
#include "OUIServer.h"
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class OUIServer * OUIServer::instance_;
|
||||
@@ -38,10 +38,17 @@ namespace OpenWifi {
|
||||
Updater.detach();
|
||||
}
|
||||
|
||||
void OUIServer::reinitialize(Poco::Util::Application &self) {
|
||||
MicroService::instance().LoadConfigurationFile();
|
||||
Logger_.information("Reinitializing.");
|
||||
Stop();
|
||||
Start();
|
||||
}
|
||||
|
||||
bool OUIServer::GetFile(const std::string &FileName) {
|
||||
try {
|
||||
std::unique_ptr<std::istream> pStr(
|
||||
Poco::URIStreamOpener::defaultOpener().open(Daemon()->ConfigGetString("oui.download.uri")));
|
||||
Poco::URIStreamOpener::defaultOpener().open(MicroService::instance().ConfigGetString("oui.download.uri")));
|
||||
std::ofstream OS;
|
||||
Poco::File F(FileName);
|
||||
if(F.exists())
|
||||
@@ -97,12 +104,12 @@ namespace OpenWifi {
|
||||
Updating_ = true;
|
||||
|
||||
// fetch data from server, if not available, just use the file we already have.
|
||||
std::string LatestOUIFileName{ Daemon()->DataDir() + "/newOUIFile.txt"};
|
||||
std::string CurrentOUIFileName{ Daemon()->DataDir() + "/current_oui.txt"};
|
||||
std::string LatestOUIFileName{ MicroService::instance().DataDir() + "/newOUIFile.txt"};
|
||||
std::string CurrentOUIFileName{ MicroService::instance().DataDir() + "/current_oui.txt"};
|
||||
|
||||
OUIMap TmpOUIs;
|
||||
if(GetFile(LatestOUIFileName) && ProcessFile(LatestOUIFileName, TmpOUIs)) {
|
||||
SubMutexGuard G(Mutex_);
|
||||
std::lock_guard G(Mutex_);
|
||||
OUIs_ = std::move(TmpOUIs);
|
||||
LastUpdate_ = time(nullptr);
|
||||
Poco::File F1(CurrentOUIFileName);
|
||||
@@ -114,7 +121,7 @@ namespace OpenWifi {
|
||||
} else if(OUIs_.empty()) {
|
||||
if(ProcessFile(CurrentOUIFileName, TmpOUIs)) {
|
||||
LastUpdate_ = time(nullptr);
|
||||
SubMutexGuard G(Mutex_);
|
||||
std::lock_guard G(Mutex_);
|
||||
OUIs_ = std::move(TmpOUIs);
|
||||
}
|
||||
}
|
||||
@@ -122,7 +129,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
std::string OUIServer::GetManufacturer(const std::string &MAC) {
|
||||
SubMutexGuard Guard(Mutex_);
|
||||
std::lock_guard Guard(Mutex_);
|
||||
auto Manufacturer = OUIs_.find(Utils::SerialNumberToOUI(MAC));
|
||||
if(Manufacturer != OUIs_.end())
|
||||
return Manufacturer->second;
|
||||
|
@@ -5,7 +5,7 @@
|
||||
#ifndef UCENTRALGW_OUISERVER_H
|
||||
#define UCENTRALGW_OUISERVER_H
|
||||
|
||||
#include "SubSystemServer.h"
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
@@ -23,6 +23,9 @@ namespace OpenWifi {
|
||||
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
|
||||
void reinitialize(Poco::Util::Application &self) override;
|
||||
|
||||
void Update();
|
||||
void UpdateImpl();
|
||||
[[nodiscard]] std::string GetManufacturer(const std::string &MAC);
|
||||
|
@@ -1,68 +0,0 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-07-01.
|
||||
//
|
||||
#include <iostream>
|
||||
|
||||
#include "OpenAPIRequest.h"
|
||||
|
||||
#include "Poco/Net/HTTPSClientSession.h"
|
||||
#include <Poco/Net/HTTPClientSession.h>
|
||||
#include <Poco/Net/HTTPRequest.h>
|
||||
#include <Poco/Net/HTTPResponse.h>
|
||||
#include <Poco/StreamCopier.h>
|
||||
#include <Poco/JSON/Parser.h>
|
||||
#include <Poco/Path.h>
|
||||
#include <Poco/URI.h>
|
||||
#include <Poco/Exception.h>
|
||||
#include "Utils.h"
|
||||
#include "Daemon.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
OpenAPIRequestGet::OpenAPIRequestGet( const std::string & ServiceType,
|
||||
const std::string & EndPoint,
|
||||
Types::StringPairVec & QueryData,
|
||||
uint64_t msTimeout):
|
||||
Type_(ServiceType),
|
||||
EndPoint_(EndPoint),
|
||||
QueryData_(QueryData),
|
||||
msTimeout_(msTimeout) {
|
||||
|
||||
}
|
||||
|
||||
int OpenAPIRequestGet::Do(Poco::JSON::Object::Ptr &ResponseObject) {
|
||||
try {
|
||||
auto Services = Daemon()->GetServices(Type_);
|
||||
for(auto const &Svc:Services) {
|
||||
Poco::URI URI(Svc.PrivateEndPoint);
|
||||
Poco::Net::HTTPSClientSession Session(URI.getHost(), URI.getPort());
|
||||
|
||||
URI.setPath(EndPoint_);
|
||||
for (const auto &qp : QueryData_)
|
||||
URI.addQueryParameter(qp.first, qp.second);
|
||||
|
||||
std::string Path(URI.getPathAndQuery());
|
||||
Session.setTimeout(Poco::Timespan(msTimeout_/1000, msTimeout_ % 1000));
|
||||
|
||||
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Path,
|
||||
Poco::Net::HTTPMessage::HTTP_1_1);
|
||||
Request.add("X-API-KEY", Svc.AccessKey);
|
||||
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)
|
||||
{
|
||||
std::cerr << E.displayText() << std::endl;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
@@ -1,29 +0,0 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-07-01.
|
||||
//
|
||||
|
||||
#ifndef UCENTRALGW_OPENAPIREQUEST_H
|
||||
#define UCENTRALGW_OPENAPIREQUEST_H
|
||||
|
||||
#include "Poco/JSON/Object.h"
|
||||
|
||||
#include "OpenWifiTypes.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class OpenAPIRequestGet {
|
||||
public:
|
||||
explicit OpenAPIRequestGet( const std::string & Type,
|
||||
const std::string & EndPoint,
|
||||
Types::StringPairVec & QueryData,
|
||||
uint64_t msTimeout);
|
||||
int Do(Poco::JSON::Object::Ptr &ResponseObject);
|
||||
private:
|
||||
std::string Type_;
|
||||
std::string EndPoint_;
|
||||
Types::StringPairVec QueryData_;
|
||||
uint64_t msTimeout_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // UCENTRALGW_OPENAPIREQUEST_H
|
@@ -1,68 +0,0 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-06-13.
|
||||
//
|
||||
|
||||
#ifndef UCENTRALGW_UCENTRALTYPES_H
|
||||
#define UCENTRALGW_UCENTRALTYPES_H
|
||||
|
||||
#include "SubSystemServer.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <utility>
|
||||
#include <queue>
|
||||
|
||||
#include "Poco/StringTokenizer.h"
|
||||
|
||||
namespace OpenWifi::Types {
|
||||
typedef std::pair<std::string,std::string> StringPair;
|
||||
typedef std::vector<StringPair> StringPairVec;
|
||||
typedef std::queue<StringPair> StringPairQueue;
|
||||
typedef std::vector<std::string> StringVec;
|
||||
typedef std::set<std::string> StringSet;
|
||||
typedef std::vector<SubSystemServer*> SubSystemVec;
|
||||
typedef std::map<std::string,std::set<std::string>> StringMapStringSet;
|
||||
typedef std::function<void(std::string, std::string)> TopicNotifyFunction;
|
||||
typedef std::list<std::pair<TopicNotifyFunction,int>> TopicNotifyFunctionList;
|
||||
typedef std::map<std::string, TopicNotifyFunctionList> NotifyTable;
|
||||
typedef std::map<std::string,uint64_t> CountedMap;
|
||||
|
||||
typedef std::string UUID_t;
|
||||
typedef std::vector<UUID_t> UUIDvec_t;
|
||||
|
||||
inline void UpdateCountedMap(CountedMap &M, const std::string &S, uint64_t Increment=1) {
|
||||
auto it = M.find(S);
|
||||
if(it==M.end())
|
||||
M[S] = Increment;
|
||||
else
|
||||
it->second += Increment;
|
||||
}
|
||||
|
||||
inline std::string to_string( const StringVec &V) {
|
||||
std::string Result;
|
||||
|
||||
bool first=true;
|
||||
for(const auto &i:V) {
|
||||
if(first) {
|
||||
Result += i;
|
||||
first = false;
|
||||
} else {
|
||||
Result += ",";
|
||||
Result += i;
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
inline void from_string(const std::string &S, StringVec &V) {
|
||||
Poco::StringTokenizer Tokens(S,",",Poco::StringTokenizer::TOK_TRIM | Poco::StringTokenizer::TOK_IGNORE_EMPTY);
|
||||
|
||||
for(auto const &i:Tokens)
|
||||
V.emplace_back(i);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // UCENTRALGW_UCENTRALTYPES_H
|
118
src/RESTAPI/RESTAPI_RPC.cpp
Normal file
118
src/RESTAPI/RESTAPI_RPC.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-06-28.
|
||||
//
|
||||
#include <cctype>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <future>
|
||||
#include <numeric>
|
||||
#include <chrono>
|
||||
#include "RESTAPI_RPC.h"
|
||||
|
||||
#include "CommandManager.h"
|
||||
#include "DeviceRegistry.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/uCentral_Protocol.h"
|
||||
|
||||
namespace OpenWifi::RESTAPI_RPC {
|
||||
void SetCommandStatus(GWObjects::CommandDetails &Cmd,
|
||||
Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response,
|
||||
RESTAPIHandler *Handler,
|
||||
OpenWifi::Storage::CommandExecutionType Status,
|
||||
Poco::Logger &Logger) {
|
||||
if (StorageService()->AddCommand(Cmd.SerialNumber, Cmd, Status)) {
|
||||
Poco::JSON::Object RetObj;
|
||||
Cmd.to_json(RetObj);
|
||||
Handler->ReturnObject(RetObj);
|
||||
return;
|
||||
} else {
|
||||
Handler->ReturnStatus(Poco::Net::HTTPResponse::HTTP_INTERNAL_SERVER_ERROR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void WaitForCommand(GWObjects::CommandDetails &Cmd,
|
||||
Poco::JSON::Object & Params,
|
||||
Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response,
|
||||
int64_t WaitTimeInMs,
|
||||
Poco::JSON::Object * ObjectToReturn,
|
||||
RESTAPIHandler * Handler,
|
||||
Poco::Logger &Logger) {
|
||||
|
||||
// if the command should be executed in the future, or if the device is not connected, then we should just add the command to
|
||||
// the DB and let it figure out when to deliver the command.
|
||||
if(Cmd.RunAt || !DeviceRegistry()->Connected(Cmd.SerialNumber)) {
|
||||
SetCommandStatus(Cmd, Request, Response, Handler, Storage::COMMAND_PENDING, Logger);
|
||||
return;
|
||||
}
|
||||
|
||||
Cmd.Executed = std::time(nullptr);
|
||||
|
||||
uint64_t RPC_Id=0;
|
||||
if (CommandManager()->SendCommand(Cmd.SerialNumber, Cmd.Command, Params, Cmd.UUID, RPC_Id)) {
|
||||
CommandTag T;
|
||||
while (CommandManager()->Running() && WaitTimeInMs > 0) {
|
||||
if (CommandManager()->GetCommand(RPC_Id, Cmd.SerialNumber, T)) {
|
||||
auto Answer = T.Result;
|
||||
if (Answer->has("result") && Answer->isObject("result")) {
|
||||
auto ResultFields =
|
||||
Answer->get("result").extract<Poco::JSON::Object::Ptr>();
|
||||
if (ResultFields->has("status") && ResultFields->isObject("status")) {
|
||||
auto StatusInnerObj =
|
||||
ResultFields->get("status").extract<Poco::JSON::Object::Ptr>();
|
||||
if (StatusInnerObj->has("error"))
|
||||
Cmd.ErrorCode = StatusInnerObj->get("error");
|
||||
if (StatusInnerObj->has("text"))
|
||||
Cmd.ErrorText = StatusInnerObj->get("text").toString();
|
||||
std::stringstream ResultText;
|
||||
Poco::JSON::Stringifier::stringify(Answer->get("result"), ResultText);
|
||||
Cmd.Results = ResultText.str();
|
||||
Cmd.Status = "completed";
|
||||
Cmd.Completed = time(nullptr);
|
||||
|
||||
if (Cmd.ErrorCode && Cmd.Command == uCentralProtocol::TRACE) {
|
||||
Cmd.WaitingForFile = 0;
|
||||
Cmd.AttachDate = Cmd.AttachSize = 0;
|
||||
Cmd.AttachType = "";
|
||||
}
|
||||
|
||||
// Add the completed command to the database...
|
||||
StorageService()->AddCommand(Cmd.SerialNumber, Cmd,
|
||||
Storage::COMMAND_COMPLETED);
|
||||
|
||||
if (ObjectToReturn) {
|
||||
Handler->ReturnObject(*ObjectToReturn);
|
||||
} else {
|
||||
Poco::JSON::Object O;
|
||||
Cmd.to_json(O);
|
||||
Handler->ReturnObject(O);
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
SetCommandStatus(Cmd, Request, Response, Handler, Storage::COMMAND_FAILED, Logger);
|
||||
Logger.information(Poco::format("Invalid response for command '%s'. Missing status.", Cmd.UUID));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
SetCommandStatus(Cmd, Request, Response, Handler, Storage::COMMAND_FAILED, Logger);
|
||||
Logger.information(Poco::format("Invalid response for command '%s'. Missing result.", Cmd.UUID));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
Poco::Thread::trySleep(100);
|
||||
WaitTimeInMs -= 100;
|
||||
}
|
||||
}
|
||||
if(WaitTimeInMs<0)
|
||||
SetCommandStatus(Cmd, Request, Response, Handler, Storage::COMMAND_TIMEDOUT, Logger);
|
||||
else
|
||||
SetCommandStatus(Cmd, Request, Response, Handler, Storage::COMMAND_PENDING, Logger);
|
||||
} else {
|
||||
SetCommandStatus(Cmd, Request, Response, Handler, Storage::COMMAND_PENDING, Logger);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -15,29 +15,27 @@
|
||||
#include "Poco/File.h"
|
||||
#include "Poco/JSON/Object.h"
|
||||
|
||||
#include "RESTAPI_GWobjects.h"
|
||||
#include "RESTAPI_handler.h"
|
||||
#include "RESTObjects//RESTAPI_GWobjects.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
namespace OpenWifi::RESTAPI_RPC {
|
||||
|
||||
bool WaitForRPC(GWObjects::CommandDetails &Cmd,
|
||||
Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response,
|
||||
uint64_t Timeout,
|
||||
bool ReturnObject,
|
||||
RESTAPIHandler * Handler);
|
||||
|
||||
void WaitForCommand( GWObjects::CommandDetails &Cmd,
|
||||
void WaitForCommand( GWObjects::CommandDetails &Cmd,
|
||||
Poco::JSON::Object & Params,
|
||||
Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response,
|
||||
std::chrono::milliseconds D,
|
||||
int64_t WaitTimeInMs,
|
||||
Poco::JSON::Object * ObjectToReturn,
|
||||
RESTAPIHandler * Handler);
|
||||
RESTAPIHandler * Handler,
|
||||
Poco::Logger &Logger);
|
||||
|
||||
void SetCommandStatus( GWObjects::CommandDetails &Cmd,
|
||||
Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response, RESTAPIHandler * handler,
|
||||
OpenWifi::Storage::CommandExecutionType Status,
|
||||
Poco::Logger &Logger);
|
||||
|
||||
void SetCommandAsPending(GWObjects::CommandDetails &Cmd,
|
||||
Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response, RESTAPIHandler * handler);
|
||||
|
||||
}
|
||||
#endif // UCENTRALGW_RESTAPI_RPC_H
|
48
src/RESTAPI/RESTAPI_TelemetryWebSocket.cpp
Normal file
48
src/RESTAPI/RESTAPI_TelemetryWebSocket.cpp
Normal file
@@ -0,0 +1,48 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-09-16.
|
||||
//
|
||||
|
||||
#include "RESTAPI_TelemetryWebSocket.h"
|
||||
#include "Poco/Net/WebSocket.h"
|
||||
#include "Poco/Net/NetException.h"
|
||||
#include "TelemetryStream.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
void RESTAPI_TelemetryWebSocket::DoGet() {
|
||||
// try and upgrade this session to websocket...
|
||||
if (Request->find("Upgrade") != Request->end() &&
|
||||
Poco::icompare((*Request)["Upgrade"], "websocket") == 0) {
|
||||
try {
|
||||
Poco::URI U(Request->getURI());
|
||||
std::string UUID, SerialNumber;
|
||||
auto Parameters = U.getQueryParameters();
|
||||
for (const auto &i : Parameters) {
|
||||
if (i.first == "serialNumber") {
|
||||
SerialNumber = i.second;
|
||||
} else if(i.first=="uuid") {
|
||||
UUID = i.second;
|
||||
}
|
||||
}
|
||||
auto WS = Poco::SharedPtr<Poco::Net::WebSocket>( new Poco::Net::WebSocket(*Request, *Response));
|
||||
new TelemetryClient(UUID, SerialNumber, WS, TelemetryStream()->NextReactor(), Logger_);
|
||||
} catch (const Poco::Net::WebSocketException &E) {
|
||||
Logger_.log(E);
|
||||
switch (E.code()) {
|
||||
case Poco::Net::WebSocket::WS_ERR_HANDSHAKE_UNSUPPORTED_VERSION:
|
||||
Response->set("Sec-WebSocket-Version", Poco::Net::WebSocket::WEBSOCKET_VERSION);
|
||||
// fallthrough
|
||||
case Poco::Net::WebSocket::WS_ERR_NO_HANDSHAKE:
|
||||
case Poco::Net::WebSocket::WS_ERR_HANDSHAKE_NO_VERSION:
|
||||
case Poco::Net::WebSocket::WS_ERR_HANDSHAKE_NO_KEY:
|
||||
Response->setStatusAndReason(Poco::Net::HTTPResponse::HTTP_BAD_REQUEST);
|
||||
Response->setContentLength(0);
|
||||
Response->send();
|
||||
break;
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
28
src/RESTAPI/RESTAPI_TelemetryWebSocket.h
Normal file
28
src/RESTAPI/RESTAPI_TelemetryWebSocket.h
Normal file
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-09-16.
|
||||
//
|
||||
|
||||
#ifndef OWGW_RESTAPI_TELEMETRYWEBSOCKET_H
|
||||
#define OWGW_RESTAPI_TELEMETRYWEBSOCKET_H
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_TelemetryWebSocket : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_TelemetryWebSocket(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{ Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server, Internal,false) {}
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/ws_telemetry"};}
|
||||
void DoGet() final;
|
||||
void DoDelete() final {};
|
||||
void DoPost() final {};
|
||||
void DoPut() final {};
|
||||
private:
|
||||
void Process(const Poco::JSON::Object::Ptr &O, std::string &Answer);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // OWGW_RESTAPI_TELEMETRYWEBSOCKET_H
|
120
src/RESTAPI/RESTAPI_blacklist.cpp
Normal file
120
src/RESTAPI/RESTAPI_blacklist.cpp
Normal file
@@ -0,0 +1,120 @@
|
||||
//
|
||||
// License type: BSD 3-Clause License
|
||||
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
|
||||
//
|
||||
// Created by Stephane Bourque on 2021-03-04.
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
#include <ctime>
|
||||
|
||||
#include "Poco/JSON/Parser.h"
|
||||
#include "Poco/JSON/Stringifier.h"
|
||||
#include "RESTAPI_blacklist.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/RESTAPI_errors.h"
|
||||
#include "framework/RESTAPI_protocol.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_blacklist::DoDelete() {
|
||||
auto SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
|
||||
if(SerialNumber.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::MissingSerialNumber);
|
||||
}
|
||||
|
||||
GWObjects::BlackListedDevice D;
|
||||
if(!StorageService()->GetBlackListDevice(SerialNumber, D)) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
if (StorageService()->DeleteBlackListDevice(SerialNumber)) {
|
||||
return OK();
|
||||
}
|
||||
BadRequest(RESTAPI::Errors::CouldNotBeDeleted);
|
||||
}
|
||||
|
||||
void RESTAPI_blacklist::DoGet() {
|
||||
auto SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
|
||||
if(SerialNumber.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::MissingSerialNumber);
|
||||
}
|
||||
|
||||
GWObjects::BlackListedDevice D;
|
||||
if(!StorageService()->GetBlackListDevice(SerialNumber, D)) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
Poco::JSON::Object Answer;
|
||||
D.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
|
||||
void RESTAPI_blacklist::DoPost() {
|
||||
auto Obj = ParseStream();
|
||||
|
||||
GWObjects::BlackListedDevice D;
|
||||
if(!D.from_json(Obj)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
|
||||
if(D.serialNumber.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::MissingSerialNumber);
|
||||
}
|
||||
|
||||
Poco::toLowerInPlace(D.serialNumber);
|
||||
if(StorageService()->IsBlackListed(D.serialNumber)) {
|
||||
return BadRequest(RESTAPI::Errors::SerialNumberExists);
|
||||
}
|
||||
|
||||
D.author = UserInfo_.userinfo.email;
|
||||
D.created = std::time(nullptr);
|
||||
|
||||
if(StorageService()->AddBlackListDevice(D)) {
|
||||
GWObjects::BlackListedDevice CreatedDevice;
|
||||
|
||||
StorageService()->GetBlackListDevice(D.serialNumber,CreatedDevice);
|
||||
Poco::JSON::Object Answer;
|
||||
|
||||
CreatedDevice.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
void RESTAPI_blacklist::DoPut() {
|
||||
auto SerialNumber = Poco::toLower(GetBinding(RESTAPI::Protocol::SERIALNUMBER, ""));
|
||||
|
||||
if(SerialNumber.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::MissingSerialNumber);
|
||||
}
|
||||
|
||||
auto Obj = ParseStream();
|
||||
|
||||
GWObjects::BlackListedDevice Existing;
|
||||
if(!StorageService()->GetBlackListDevice(SerialNumber, Existing)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
|
||||
GWObjects::BlackListedDevice NewDevice;
|
||||
if(!NewDevice.from_json(Obj)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
|
||||
Existing.reason = NewDevice.reason;
|
||||
Existing.author = UserInfo_.userinfo.email;
|
||||
|
||||
if(StorageService()->UpdateBlackListDevice(SerialNumber, Existing)) {
|
||||
GWObjects::BlackListedDevice CreatedDevice;
|
||||
|
||||
StorageService()->GetBlackListDevice(SerialNumber,CreatedDevice);
|
||||
Poco::JSON::Object Answer;
|
||||
|
||||
CreatedDevice.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
}
|
@@ -9,25 +9,25 @@
|
||||
#ifndef UCENTRALGW_RESTAPI_BLACKLIST_H
|
||||
#define UCENTRALGW_RESTAPI_BLACKLIST_H
|
||||
|
||||
#include "RESTAPI_handler.h"
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_BlackList : public RESTAPIHandler {
|
||||
class RESTAPI_blacklist : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_BlackList(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
|
||||
RESTAPI_blacklist(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_POST,
|
||||
Poco::Net::HTTPRequest::HTTP_PUT,
|
||||
Poco::Net::HTTPRequest::HTTP_DELETE,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server,
|
||||
Internal) {}
|
||||
void handleRequest(Poco::Net::HTTPServerRequest &request,
|
||||
Poco::Net::HTTPServerResponse &response) override;
|
||||
|
||||
void DoGet(Poco::Net::HTTPServerRequest &request, Poco::Net::HTTPServerResponse &response);
|
||||
void DoDelete(Poco::Net::HTTPServerRequest &request, Poco::Net::HTTPServerResponse &response);
|
||||
void DoPost(Poco::Net::HTTPServerRequest &request, Poco::Net::HTTPServerResponse &response);
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/blacklist"};}
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/blacklist/{serialNumber}"};}
|
||||
void DoGet() final;
|
||||
void DoDelete() final;
|
||||
void DoPost() final;
|
||||
void DoPut() final;
|
||||
};
|
||||
}
|
||||
|
28
src/RESTAPI/RESTAPI_blacklist_list.cpp
Normal file
28
src/RESTAPI/RESTAPI_blacklist_list.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-10-14.
|
||||
//
|
||||
|
||||
#include "RESTAPI_blacklist_list.h"
|
||||
#include "Poco/JSON/Parser.h"
|
||||
#include "Poco/JSON/Stringifier.h"
|
||||
#include "StorageService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_blacklist_list::DoGet() {
|
||||
|
||||
std::vector<GWObjects::BlackListedDevice> Devices;
|
||||
|
||||
Poco::JSON::Array Arr;
|
||||
Poco::JSON::Object Answer;
|
||||
|
||||
if(StorageService()->GetBlackListDevices(QB_.Offset, QB_.Limit, Devices)) {
|
||||
for(const auto &i:Devices) {
|
||||
Poco::JSON::Object O;
|
||||
i.to_json(O);
|
||||
Arr.add(O);
|
||||
}
|
||||
}
|
||||
Answer.set("devices", Arr);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
}
|
27
src/RESTAPI/RESTAPI_blacklist_list.h
Normal file
27
src/RESTAPI/RESTAPI_blacklist_list.h
Normal file
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-10-14.
|
||||
//
|
||||
|
||||
#ifndef UCENTRALGW_RESTAPI_BLACKLIST_LIST_H
|
||||
#define UCENTRALGW_RESTAPI_BLACKLIST_LIST_H
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_blacklist_list : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_blacklist_list(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server,
|
||||
Internal) {}
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/blacklist"};}
|
||||
void DoGet() final;
|
||||
void DoDelete() final {};
|
||||
void DoPost() final {};
|
||||
void DoPut() final {};
|
||||
};
|
||||
}
|
||||
|
||||
#endif // UCENTRALGW_RESTAPI_BLACKLIST_LIST_H
|
28
src/RESTAPI/RESTAPI_capabilities_handler.cpp
Normal file
28
src/RESTAPI/RESTAPI_capabilities_handler.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-10-17.
|
||||
//
|
||||
|
||||
#include "RESTAPI_capabilities_handler.h"
|
||||
#include "StorageService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
void RESTAPI_capabilities_handler::DoGet() {
|
||||
Storage::DeviceCapabilitiesCache DevCaps;
|
||||
|
||||
StorageService()->GetDeviceCapabilitiesCache(DevCaps);
|
||||
Poco::JSON::Array ObjArr;
|
||||
for(const auto &[deviceType,capabilities]:DevCaps) {
|
||||
Poco::JSON::Object Inner;
|
||||
Inner.set("deviceType",deviceType);
|
||||
Poco::JSON::Parser P;
|
||||
auto R = P.parse(capabilities).extract<Poco::JSON::Object::Ptr>();
|
||||
Inner.set("capabilities", R);
|
||||
ObjArr.add(Inner);
|
||||
}
|
||||
Poco::JSON::Object Answer;
|
||||
|
||||
Answer.set("devices",ObjArr);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
}
|
26
src/RESTAPI/RESTAPI_capabilities_handler.h
Normal file
26
src/RESTAPI/RESTAPI_capabilities_handler.h
Normal file
@@ -0,0 +1,26 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-10-17.
|
||||
//
|
||||
|
||||
#ifndef UCENTRALGW_RESTAPI_CAPABILITIES_HANDLER_H
|
||||
#define UCENTRALGW_RESTAPI_CAPABILITIES_HANDLER_H
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_capabilities_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_capabilities_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server,
|
||||
Internal) {}
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/capabilities"};}
|
||||
void DoGet() final;
|
||||
void DoDelete() final {};
|
||||
void DoPost() final {};
|
||||
void DoPut() final {};
|
||||
};
|
||||
}
|
||||
#endif // UCENTRALGW_RESTAPI_CAPABILITIES_HANDLER_H
|
44
src/RESTAPI/RESTAPI_command.cpp
Normal file
44
src/RESTAPI/RESTAPI_command.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// License type: BSD 3-Clause License
|
||||
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
|
||||
//
|
||||
// Created by Stephane Bourque on 2021-03-04.
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
#include "RESTAPI_command.h"
|
||||
|
||||
#include "StorageService.h"
|
||||
#include "framework/RESTAPI_errors.h"
|
||||
#include "framework/RESTAPI_protocol.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_command::DoGet() {
|
||||
auto CommandUUID = GetBinding(RESTAPI::Protocol::COMMANDUUID, "");
|
||||
GWObjects::CommandDetails Command;
|
||||
if (StorageService()->GetCommand(CommandUUID, Command)) {
|
||||
Poco::JSON::Object RetObj;
|
||||
Command.to_json(RetObj);
|
||||
return ReturnObject(RetObj);
|
||||
}
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
void RESTAPI_command::DoDelete() {
|
||||
auto UUID = GetBinding(RESTAPI::Protocol::COMMANDUUID, "");
|
||||
|
||||
if(UUID.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::MissingUUID);
|
||||
}
|
||||
|
||||
GWObjects::CommandDetails C;
|
||||
if(!StorageService()->GetCommand(UUID, C)) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
if (StorageService()->DeleteCommand(UUID)) {
|
||||
return OK();
|
||||
}
|
||||
return InternalError();
|
||||
}
|
||||
}
|
@@ -9,21 +9,24 @@
|
||||
#ifndef UCENTRAL_RESTAPI_COMMAND_H
|
||||
#define UCENTRAL_RESTAPI_COMMAND_H
|
||||
|
||||
#include "RESTAPI_handler.h"
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_command : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_command(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
|
||||
RESTAPI_command(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_DELETE,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server,
|
||||
Internal) {}
|
||||
void handleRequest(Poco::Net::HTTPServerRequest &request,
|
||||
Poco::Net::HTTPServerResponse &response) override;
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/command/{commandUUID}"};}
|
||||
};
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/command/{commandUUID}"};}
|
||||
void DoGet() final;
|
||||
void DoDelete() final;
|
||||
void DoPost() final {};
|
||||
void DoPut() final {};
|
||||
};
|
||||
}
|
||||
|
||||
#endif //UCENTRAL_RESTAPI_COMMAND_H
|
46
src/RESTAPI/RESTAPI_commands.cpp
Normal file
46
src/RESTAPI/RESTAPI_commands.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
//
|
||||
// License type: BSD 3-Clause License
|
||||
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
|
||||
//
|
||||
// Created by Stephane Bourque on 2021-03-04.
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
#include "RESTAPI_commands.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/RESTAPI_errors.h"
|
||||
#include "framework/RESTAPI_protocol.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_commands::DoGet() {
|
||||
auto SerialNumber = GetParameter(RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
std::vector<GWObjects::CommandDetails> Commands;
|
||||
if (QB_.Newest) {
|
||||
StorageService()->GetNewestCommands(SerialNumber, QB_.Limit, Commands);
|
||||
} else {
|
||||
StorageService()->GetCommands(SerialNumber, QB_.StartDate, QB_.EndDate, QB_.Offset, QB_.Limit,
|
||||
Commands);
|
||||
}
|
||||
Poco::JSON::Array ArrayObj;
|
||||
for (const auto &i : Commands) {
|
||||
Poco::JSON::Object Obj;
|
||||
i.to_json(Obj);
|
||||
ArrayObj.add(Obj);
|
||||
}
|
||||
Poco::JSON::Object RetObj;
|
||||
RetObj.set(RESTAPI::Protocol::COMMANDS, ArrayObj);
|
||||
ReturnObject(RetObj);
|
||||
}
|
||||
|
||||
void RESTAPI_commands::DoDelete() {
|
||||
auto SerialNumber = GetParameter(RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
|
||||
if(SerialNumber.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::MissingSerialNumber);
|
||||
}
|
||||
if (StorageService()->DeleteCommands(SerialNumber, QB_.StartDate, QB_.EndDate)) {
|
||||
return OK();
|
||||
}
|
||||
InternalError();
|
||||
}
|
||||
}
|
@@ -9,20 +9,23 @@
|
||||
#ifndef UCENTRAL_RESTAPI_COMMANDS_H
|
||||
#define UCENTRAL_RESTAPI_COMMANDS_H
|
||||
|
||||
#include "RESTAPI_handler.h"
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_commands : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_commands(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
|
||||
RESTAPI_commands(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_DELETE,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server,
|
||||
Internal) {}
|
||||
void handleRequest(Poco::Net::HTTPServerRequest &request,
|
||||
Poco::Net::HTTPServerResponse &response) override;
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/commands"};}
|
||||
void DoGet() final;
|
||||
void DoDelete() final;
|
||||
void DoPost() final {};
|
||||
void DoPut() final {};
|
||||
};
|
||||
}
|
||||
#endif //UCENTRAL_RESTAPI_COMMANDS_H
|
76
src/RESTAPI/RESTAPI_default_configuration.cpp
Normal file
76
src/RESTAPI/RESTAPI_default_configuration.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
//
|
||||
// License type: BSD 3-Clause License
|
||||
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
|
||||
//
|
||||
// Created by Stephane Bourque on 2021-03-04.
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
#include "Poco/JSON/Parser.h"
|
||||
|
||||
#include "RESTAPI_default_configuration.h"
|
||||
|
||||
#include "RESTObjects/RESTAPI_GWobjects.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/RESTAPI_errors.h"
|
||||
#include "framework/RESTAPI_protocol.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_default_configuration::DoGet() {
|
||||
std::string Name = GetBinding(RESTAPI::Protocol::NAME, "");
|
||||
GWObjects::DefaultConfiguration DefConfig;
|
||||
if (StorageService()->GetDefaultConfiguration(Name, DefConfig)) {
|
||||
Poco::JSON::Object Obj;
|
||||
DefConfig.to_json(Obj);
|
||||
return ReturnObject(Obj);
|
||||
}
|
||||
NotFound();
|
||||
}
|
||||
|
||||
void RESTAPI_default_configuration::DoDelete() {
|
||||
std::string Name = GetBinding(RESTAPI::Protocol::NAME, "");
|
||||
if(Name.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
if (StorageService()->DeleteDefaultConfiguration(Name)) {
|
||||
return OK();
|
||||
}
|
||||
BadRequest(RESTAPI::Errors::CouldNotBeDeleted);
|
||||
}
|
||||
|
||||
void RESTAPI_default_configuration::DoPost() {
|
||||
std::string Name = GetBinding(RESTAPI::Protocol::NAME, "");
|
||||
|
||||
if(Name.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
auto Obj = ParseStream();
|
||||
GWObjects::DefaultConfiguration DefConfig;
|
||||
if (!DefConfig.from_json(Obj)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
|
||||
if (StorageService()->CreateDefaultConfiguration(Name, DefConfig)) {
|
||||
return OK();
|
||||
}
|
||||
BadRequest(RESTAPI::Errors::RecordNotCreated);
|
||||
}
|
||||
|
||||
void RESTAPI_default_configuration::DoPut() {
|
||||
std::string Name = GetBinding(RESTAPI::Protocol::NAME, "");
|
||||
|
||||
auto Obj = ParseStream();
|
||||
GWObjects::DefaultConfiguration DefConfig;
|
||||
|
||||
if (!DefConfig.from_json(Obj)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
|
||||
if (StorageService()->UpdateDefaultConfiguration(Name, DefConfig)) {
|
||||
return OK();
|
||||
}
|
||||
BadRequest(RESTAPI::Errors::RecordNotUpdated);
|
||||
}
|
||||
}
|
@@ -9,21 +9,24 @@
|
||||
#ifndef UCENTRAL_RESTAPI_DEFAULT_CONFIGURATION_H
|
||||
#define UCENTRAL_RESTAPI_DEFAULT_CONFIGURATION_H
|
||||
|
||||
#include "RESTAPI_handler.h"
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_default_configuration : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_default_configuration(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
|
||||
RESTAPI_default_configuration(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{
|
||||
Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_POST,
|
||||
Poco::Net::HTTPRequest::HTTP_PUT, Poco::Net::HTTPRequest::HTTP_DELETE,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server,
|
||||
Internal) {}
|
||||
void handleRequest(Poco::Net::HTTPServerRequest &request,
|
||||
Poco::Net::HTTPServerResponse &response) override;
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/default_configuration/{name}"};}
|
||||
void DoGet() final;
|
||||
void DoDelete() final;
|
||||
void DoPost() final;
|
||||
void DoPut() final;
|
||||
};
|
||||
}
|
||||
#endif //UCENTRAL_RESTAPI_DEFAULT_CONFIGURATION_H
|
32
src/RESTAPI/RESTAPI_default_configurations.cpp
Normal file
32
src/RESTAPI/RESTAPI_default_configurations.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
//
|
||||
// License type: BSD 3-Clause License
|
||||
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
|
||||
//
|
||||
// Created by Stephane Bourque on 2021-03-04.
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
#include "Poco/Array.h"
|
||||
#include "Poco/JSON/Stringifier.h"
|
||||
|
||||
#include "RESTAPI_default_configurations.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/RESTAPI_protocol.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_default_configurations::DoGet() {
|
||||
std::vector<GWObjects::DefaultConfiguration> DefConfigs;
|
||||
StorageService()->GetDefaultConfigurations(QB_.Offset, QB_.Limit, DefConfigs);
|
||||
|
||||
Poco::JSON::Array Objects;
|
||||
for (const auto &i : DefConfigs) {
|
||||
Poco::JSON::Object Obj;
|
||||
i.to_json(Obj);
|
||||
Objects.add(Obj);
|
||||
}
|
||||
|
||||
Poco::JSON::Object RetObj;
|
||||
RetObj.set(RESTAPI::Protocol::CONFIGURATIONS, Objects);
|
||||
ReturnObject(RetObj);
|
||||
}
|
||||
}
|
@@ -9,19 +9,22 @@
|
||||
#ifndef UCENTRAL_RESTAPI_DEFAULT_CONFIGURATIONS_H
|
||||
#define UCENTRAL_RESTAPI_DEFAULT_CONFIGURATIONS_H
|
||||
|
||||
#include "RESTAPI_handler.h"
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_default_configurations : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_default_configurations(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
|
||||
RESTAPI_default_configurations(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server,
|
||||
Internal){};
|
||||
void handleRequest(Poco::Net::HTTPServerRequest &request,
|
||||
Poco::Net::HTTPServerResponse &response) override;
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/default_configurations"};}
|
||||
void DoGet() final;
|
||||
void DoDelete() final {};
|
||||
void DoPost() final {};
|
||||
void DoPut() final {};
|
||||
};
|
||||
}
|
||||
#endif //UCENTRAL_RESTAPI_DEFAULT_CONFIGURATIONS_H
|
16
src/RESTAPI/RESTAPI_deviceDashboardHandler.cpp
Normal file
16
src/RESTAPI/RESTAPI_deviceDashboardHandler.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-07-21.
|
||||
//
|
||||
|
||||
#include "RESTAPI_deviceDashboardHandler.h"
|
||||
#include "Daemon.h"
|
||||
#include "Dashboard.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_deviceDashboardHandler::DoGet() {
|
||||
Daemon()->GetDashboard().Create();
|
||||
Poco::JSON::Object Answer;
|
||||
Daemon()->GetDashboard().Report().to_json(Answer);
|
||||
ReturnObject(Answer);
|
||||
}
|
||||
}
|
@@ -5,21 +5,21 @@
|
||||
#ifndef UCENTRALGW_RESTAPI_DEVICEDASHBOARDHANDLER_H
|
||||
#define UCENTRALGW_RESTAPI_DEVICEDASHBOARDHANDLER_H
|
||||
|
||||
#include "RESTAPI_handler.h"
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_deviceDashboardHandler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_deviceDashboardHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
|
||||
RESTAPI_deviceDashboardHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{
|
||||
Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_POST,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS}, Internal) {}
|
||||
void handleRequest(Poco::Net::HTTPServerRequest &request,
|
||||
Poco::Net::HTTPServerResponse &response) override;
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS}, Server, Internal) {}
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/deviceDashboard"};}
|
||||
void DoGet(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response);
|
||||
void DoGet() final;
|
||||
void DoDelete() final {};
|
||||
void DoPost() final {};
|
||||
void DoPut() final {};
|
||||
};
|
||||
}
|
||||
|
799
src/RESTAPI/RESTAPI_device_commandHandler.cpp
Normal file
799
src/RESTAPI/RESTAPI_device_commandHandler.cpp
Normal file
@@ -0,0 +1,799 @@
|
||||
//
|
||||
// License type: BSD 3-Clause License
|
||||
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
|
||||
//
|
||||
// Created by Stephane Bourque on 2021-03-04.
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
#include <chrono>
|
||||
#include <algorithm>
|
||||
|
||||
#include "Poco/UUIDGenerator.h"
|
||||
#include "Poco/JSON/Parser.h"
|
||||
|
||||
#include "CentralConfig.h"
|
||||
#include "DeviceRegistry.h"
|
||||
#include "FileUploader.h"
|
||||
#include "RESTObjects/RESTAPI_GWobjects.h"
|
||||
#include "RESTAPI_device_commandHandler.h"
|
||||
#include "StorageService.h"
|
||||
#include "RESTAPI_RPC.h"
|
||||
#include "CommandManager.h"
|
||||
#include "TelemetryStream.h"
|
||||
#include "framework/RESTAPI_protocol.h"
|
||||
#include "framework/uCentral_Protocol.h"
|
||||
#include "framework/KafkaTopics.h"
|
||||
#include "framework/RESTAPI_errors.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
void RESTAPI_device_commandHandler::DoGet() {
|
||||
if(!ValidateParameters()) {
|
||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
if (Command_ == RESTAPI::Protocol::CAPABILITIES){
|
||||
return GetCapabilities();
|
||||
} else if (Command_ == RESTAPI::Protocol::LOGS) {
|
||||
return GetLogs();
|
||||
} else if (Command_ == RESTAPI::Protocol::HEALTHCHECKS) {
|
||||
return GetChecks();
|
||||
} else if (Command_ == RESTAPI::Protocol::STATISTICS) {
|
||||
return GetStatistics();
|
||||
} else if (Command_ == RESTAPI::Protocol::STATUS) {
|
||||
return GetStatus();
|
||||
} else if (Command_ == RESTAPI::Protocol::RTTY) {
|
||||
return Rtty();
|
||||
} else {
|
||||
return BadRequest(RESTAPI::Errors::InvalidCommand);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RESTAPI_device_commandHandler::DoDelete() {
|
||||
if(!ValidateParameters()) {
|
||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
if (Command_ == RESTAPI::Protocol::CAPABILITIES) {
|
||||
return DeleteCapabilities();
|
||||
} else if (Command_ == RESTAPI::Protocol::LOGS){
|
||||
return DeleteLogs();
|
||||
} else if (Command_ == RESTAPI::Protocol::HEALTHCHECKS){
|
||||
return DeleteChecks();
|
||||
} else if (Command_ == RESTAPI::Protocol::STATISTICS) {
|
||||
return DeleteStatistics();
|
||||
} else {
|
||||
return BadRequest(RESTAPI::Errors::InvalidCommand);
|
||||
}
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::DoPost() {
|
||||
if(!ValidateParameters()) {
|
||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
if (Command_ == RESTAPI::Protocol::PERFORM) {
|
||||
return ExecuteCommand();
|
||||
} else if (Command_ == RESTAPI::Protocol::CONFIGURE) {
|
||||
return Configure();
|
||||
} else if (Command_ == RESTAPI::Protocol::UPGRADE) {
|
||||
return Upgrade();
|
||||
} else if (Command_ == RESTAPI::Protocol::REBOOT) {
|
||||
return Reboot();
|
||||
} else if (Command_ == RESTAPI::Protocol::FACTORY) {
|
||||
return Factory();
|
||||
} else if (Command_ == RESTAPI::Protocol::LEDS) {
|
||||
return LEDs();
|
||||
} else if (Command_ == RESTAPI::Protocol::TRACE) {
|
||||
return Trace();
|
||||
} else if (Command_ == RESTAPI::Protocol::REQUEST) {
|
||||
return MakeRequest();
|
||||
} else if (Command_ == RESTAPI::Protocol::WIFISCAN) {
|
||||
return WifiScan();
|
||||
} else if (Command_ == RESTAPI::Protocol::EVENTQUEUE) {
|
||||
return EventQueue();
|
||||
} else if (Command_ == RESTAPI::Protocol::TELEMETRY) {
|
||||
return Telemetry();
|
||||
} else {
|
||||
return BadRequest(RESTAPI::Errors::InvalidCommand);
|
||||
}
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::GetCapabilities() {
|
||||
GWObjects::Capabilities Caps;
|
||||
if (StorageService()->GetDeviceCapabilities(SerialNumber_, Caps)) {
|
||||
Poco::JSON::Object RetObj;
|
||||
Caps.to_json(RetObj);
|
||||
RetObj.set(RESTAPI::Protocol::SERIALNUMBER, SerialNumber_);
|
||||
return ReturnObject(RetObj);
|
||||
}
|
||||
NotFound();
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::DeleteCapabilities() {
|
||||
Logger_.information(Poco::format("DELETE-CAPABILITIES: user=%s serial=%s", UserInfo_.userinfo.email,SerialNumber_));
|
||||
if (StorageService()->DeleteDeviceCapabilities(SerialNumber_)) {
|
||||
return OK();
|
||||
}
|
||||
NotFound();
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::GetStatistics() {
|
||||
if (QB_.Lifetime) {
|
||||
std::string Stats;
|
||||
StorageService()->GetLifetimeStats(SerialNumber_, Stats);
|
||||
Poco::JSON::Parser P;
|
||||
if (Stats.empty())
|
||||
Stats = uCentralProtocol::EMPTY_JSON_DOC;
|
||||
auto Obj = P.parse(Stats).extract<Poco::JSON::Object::Ptr>();
|
||||
return ReturnObject(*Obj);
|
||||
} else if (QB_.LastOnly) {
|
||||
std::string Stats;
|
||||
if (DeviceRegistry()->GetStatistics(SerialNumber_, Stats)) {
|
||||
Poco::JSON::Parser P;
|
||||
if (Stats.empty())
|
||||
Stats = uCentralProtocol::EMPTY_JSON_DOC;
|
||||
auto Obj = P.parse(Stats).extract<Poco::JSON::Object::Ptr>();
|
||||
return ReturnObject(*Obj);
|
||||
} else {
|
||||
return NotFound();
|
||||
}
|
||||
} else {
|
||||
std::vector<GWObjects::Statistics> Stats;
|
||||
if (QB_.Newest) {
|
||||
StorageService()->GetNewestStatisticsData(SerialNumber_, QB_.Limit, Stats);
|
||||
} else {
|
||||
StorageService()->GetStatisticsData(SerialNumber_, QB_.StartDate, QB_.EndDate,
|
||||
QB_.Offset, QB_.Limit, Stats);
|
||||
}
|
||||
Poco::JSON::Array ArrayObj;
|
||||
for (auto i : Stats) {
|
||||
Poco::JSON::Object Obj;
|
||||
i.to_json(Obj);
|
||||
ArrayObj.add(Obj);
|
||||
}
|
||||
Poco::JSON::Object RetObj;
|
||||
RetObj.set(RESTAPI::Protocol::DATA, ArrayObj);
|
||||
RetObj.set(RESTAPI::Protocol::SERIALNUMBER, SerialNumber_);
|
||||
return ReturnObject(RetObj);
|
||||
}
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::DeleteStatistics() {
|
||||
Logger_.information(Poco::format("DELETE-STATISTICS: user=%s serial=%s", UserInfo_.userinfo.email,SerialNumber_));
|
||||
if (QB_.Lifetime) {
|
||||
if (StorageService()->ResetLifetimeStats(SerialNumber_)) {
|
||||
return OK();
|
||||
}
|
||||
} else {
|
||||
if (StorageService()->DeleteStatisticsData(SerialNumber_, QB_.StartDate, QB_.EndDate)) {
|
||||
return OK();
|
||||
}
|
||||
}
|
||||
NotFound();
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::GetStatus() {
|
||||
GWObjects::ConnectionState State;
|
||||
|
||||
if (DeviceRegistry()->GetState(SerialNumber_, State)) {
|
||||
Poco::JSON::Object RetObject;
|
||||
State.to_json(RetObject);
|
||||
return ReturnObject(RetObject);
|
||||
}
|
||||
NotFound();
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::Configure() {
|
||||
// get the configuration from the body of the message
|
||||
Logger_.information(Poco::format("CONFIGURE: user=%s serial=%s", UserInfo_.userinfo.email,SerialNumber_));
|
||||
auto Obj = ParseStream();
|
||||
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER) &&
|
||||
Obj->has(RESTAPI::Protocol::UUID) &&
|
||||
Obj->has(RESTAPI::Protocol::CONFIGURATION)) {
|
||||
|
||||
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
if (SerialNumber_ != SNum) {
|
||||
return BadRequest(RESTAPI::Errors::SerialNumberMismatch);
|
||||
}
|
||||
|
||||
auto Configuration = GetS(RESTAPI::Protocol::CONFIGURATION, Obj,uCentralProtocol::EMPTY_JSON_DOC);
|
||||
auto When = GetWhen(Obj);
|
||||
uint64_t NewUUID;
|
||||
if (StorageService()->UpdateDeviceConfiguration(SerialNumber_, Configuration, NewUUID)) {
|
||||
GWObjects::CommandDetails Cmd;
|
||||
|
||||
Cmd.SerialNumber = SerialNumber_;
|
||||
Cmd.UUID = MicroService::instance().CreateUUID();
|
||||
Cmd.SubmittedBy = UserInfo_.webtoken.username_;
|
||||
Cmd.Command = uCentralProtocol::CONFIGURE;
|
||||
Cmd.RunAt = When;
|
||||
|
||||
Config::Config Cfg(Configuration);
|
||||
|
||||
Poco::JSON::Object Params;
|
||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentralProtocol::UUID, NewUUID);
|
||||
Params.set(uCentralProtocol::WHEN, When);
|
||||
Params.set(uCentralProtocol::CONFIG, Cfg.to_json());
|
||||
std::stringstream ParamStream;
|
||||
Params.stringify(ParamStream);
|
||||
Cmd.Details = ParamStream.str();
|
||||
|
||||
DeviceRegistry()->SetPendingUUID(SerialNumber_, NewUUID);
|
||||
return RESTAPI_RPC::WaitForCommand(Cmd, Params, *Request, *Response, 60000, nullptr, this, Logger_);
|
||||
}
|
||||
return BadRequest(RESTAPI::Errors::RecordNotUpdated);
|
||||
}
|
||||
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::Upgrade() {
|
||||
Logger_.information(Poco::format("UPGRADE: user=%s serial=%s", UserInfo_.userinfo.email,SerialNumber_));
|
||||
auto Obj = ParseStream();
|
||||
|
||||
if (Obj->has(RESTAPI::Protocol::URI) &&
|
||||
Obj->has(RESTAPI::Protocol::SERIALNUMBER)) {
|
||||
|
||||
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
if (SerialNumber_ != SNum) {
|
||||
return BadRequest(RESTAPI::Errors::SerialNumberMismatch);
|
||||
}
|
||||
|
||||
auto URI = GetS(RESTAPI::Protocol::URI, Obj);
|
||||
auto When = GetWhen(Obj);
|
||||
|
||||
GWObjects::CommandDetails Cmd;
|
||||
|
||||
Cmd.SerialNumber = SerialNumber_;
|
||||
Cmd.UUID = MicroService::instance().CreateUUID();
|
||||
Cmd.SubmittedBy = UserInfo_.webtoken.username_;
|
||||
Cmd.Command = uCentralProtocol::UPGRADE;
|
||||
Cmd.RunAt = When;
|
||||
|
||||
Poco::JSON::Object Params;
|
||||
|
||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentralProtocol::URI, URI);
|
||||
Params.set(uCentralProtocol::WHEN, When);
|
||||
|
||||
std::stringstream ParamStream;
|
||||
Params.stringify(ParamStream);
|
||||
Cmd.Details = ParamStream.str();
|
||||
|
||||
return RESTAPI_RPC::WaitForCommand(Cmd, Params, *Request, *Response, 60000, nullptr, this, Logger_);
|
||||
}
|
||||
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::GetLogs() {
|
||||
std::vector<GWObjects::DeviceLog> Logs;
|
||||
if (QB_.Newest) {
|
||||
StorageService()->GetNewestLogData(SerialNumber_, QB_.Limit, Logs, QB_.LogType);
|
||||
} else {
|
||||
StorageService()->GetLogData(SerialNumber_, QB_.StartDate, QB_.EndDate, QB_.Offset,
|
||||
QB_.Limit, Logs, QB_.LogType);
|
||||
}
|
||||
|
||||
Poco::JSON::Array ArrayObj;
|
||||
for (auto i : Logs) {
|
||||
Poco::JSON::Object Obj;
|
||||
i.to_json(Obj);
|
||||
ArrayObj.add(Obj);
|
||||
}
|
||||
Poco::JSON::Object RetObj;
|
||||
RetObj.set(RESTAPI::Protocol::VALUES, ArrayObj);
|
||||
RetObj.set(RESTAPI::Protocol::SERIALNUMBER, SerialNumber_);
|
||||
ReturnObject(RetObj);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::DeleteLogs() {
|
||||
Logger_.information(Poco::format("DELETE-LOGS: user=%s serial=%s", UserInfo_.userinfo.email,SerialNumber_));
|
||||
if (StorageService()->DeleteLogData(SerialNumber_, QB_.StartDate, QB_.EndDate,
|
||||
QB_.LogType)) {
|
||||
return OK();
|
||||
}
|
||||
BadRequest(RESTAPI::Errors::NoRecordsDeleted);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::GetChecks() {
|
||||
std::vector<GWObjects::HealthCheck> Checks;
|
||||
|
||||
if (QB_.LastOnly) {
|
||||
GWObjects::HealthCheck HC;
|
||||
if (DeviceRegistry()->GetHealthcheck(SerialNumber_, HC)) {
|
||||
Poco::JSON::Object Answer;
|
||||
HC.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
} else {
|
||||
return NotFound();
|
||||
}
|
||||
} else {
|
||||
if (QB_.Newest) {
|
||||
StorageService()->GetNewestHealthCheckData(SerialNumber_, QB_.Limit, Checks);
|
||||
} else {
|
||||
StorageService()->GetHealthCheckData(SerialNumber_, QB_.StartDate, QB_.EndDate,
|
||||
QB_.Offset, QB_.Limit, Checks);
|
||||
}
|
||||
|
||||
Poco::JSON::Array ArrayObj;
|
||||
for (auto i : Checks) {
|
||||
Poco::JSON::Object Obj;
|
||||
i.to_json(Obj);
|
||||
ArrayObj.add(Obj);
|
||||
}
|
||||
|
||||
Poco::JSON::Object RetObj;
|
||||
RetObj.set(RESTAPI::Protocol::VALUES, ArrayObj);
|
||||
RetObj.set(RESTAPI::Protocol::SERIALNUMBER, SerialNumber_);
|
||||
ReturnObject(RetObj);
|
||||
}
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::DeleteChecks() {
|
||||
Logger_.information(Poco::format("DELETE-HEALTHCHECKS: user=%s serial=%s", UserInfo_.userinfo.email,SerialNumber_));
|
||||
if (StorageService()->DeleteHealthCheckData(SerialNumber_, QB_.StartDate, QB_.EndDate)) {
|
||||
return OK();
|
||||
}
|
||||
BadRequest(RESTAPI::Errors::NoRecordsDeleted);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::ExecuteCommand() {
|
||||
Logger_.information(Poco::format("EXECUTE: user=%s serial=%s", UserInfo_.userinfo.email,SerialNumber_));
|
||||
auto Obj = ParseStream();
|
||||
if (Obj->has(RESTAPI::Protocol::COMMAND) &&
|
||||
Obj->has(RESTAPI::Protocol::SERIALNUMBER) &&
|
||||
Obj->has(RESTAPI::Protocol::PAYLOAD)) {
|
||||
|
||||
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
if (SerialNumber_ != SNum) {
|
||||
return BadRequest("Missing serial number.");
|
||||
}
|
||||
|
||||
auto Command = GetS(RESTAPI::Protocol::COMMAND, Obj);
|
||||
auto Payload = GetS(RESTAPI::Protocol::PAYLOAD, Obj);
|
||||
auto When = GetWhen(Obj);
|
||||
|
||||
GWObjects::CommandDetails Cmd;
|
||||
|
||||
Cmd.SerialNumber = SerialNumber_;
|
||||
Cmd.UUID = MicroService::instance().CreateUUID();
|
||||
Cmd.SubmittedBy = UserInfo_.webtoken.username_;
|
||||
Cmd.Command = Command;
|
||||
Cmd.Custom = 1;
|
||||
Cmd.RunAt = When;
|
||||
|
||||
Poco::JSON::Parser parser2;
|
||||
|
||||
Poco::Dynamic::Var result = parser2.parse(Payload);
|
||||
const auto &PayloadObject = result.extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
Poco::JSON::Object Params;
|
||||
|
||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentralProtocol::COMMAND, Command);
|
||||
Params.set(uCentralProtocol::WHEN, When);
|
||||
Params.set(uCentralProtocol::PAYLOAD, PayloadObject);
|
||||
|
||||
std::stringstream ParamStream;
|
||||
Params.stringify(ParamStream);
|
||||
Cmd.Details = ParamStream.str();
|
||||
|
||||
return RESTAPI_RPC::WaitForCommand(Cmd, Params, *Request, *Response, 60000, nullptr, this, Logger_);
|
||||
}
|
||||
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::Reboot() {
|
||||
Logger_.information(Poco::format("REBOOT: user=%s serial=%s", UserInfo_.userinfo.email,SerialNumber_));
|
||||
auto Obj = ParseStream();
|
||||
|
||||
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER)) {
|
||||
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
if (SerialNumber_ != SNum) {
|
||||
return BadRequest(RESTAPI::Errors::SerialNumberMismatch);
|
||||
}
|
||||
|
||||
uint64_t When = GetWhen(Obj);
|
||||
GWObjects::CommandDetails Cmd;
|
||||
Cmd.SerialNumber = SerialNumber_;
|
||||
Cmd.UUID = MicroService::instance().CreateUUID();
|
||||
Cmd.SubmittedBy = UserInfo_.webtoken.username_;
|
||||
Cmd.Command = uCentralProtocol::REBOOT;
|
||||
Cmd.RunAt = When;
|
||||
|
||||
Poco::JSON::Object Params;
|
||||
|
||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentralProtocol::WHEN, When);
|
||||
|
||||
std::stringstream ParamStream;
|
||||
Params.stringify(ParamStream);
|
||||
Cmd.Details = ParamStream.str();
|
||||
|
||||
return RESTAPI_RPC::WaitForCommand(Cmd, Params, *Request, *Response, 60000, nullptr, this, Logger_);
|
||||
}
|
||||
BadRequest(RESTAPI::Errors::MissingSerialNumber);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::Factory() {
|
||||
Logger_.information(Poco::format("FACTORY-RESET: user=%s serial=%s", UserInfo_.userinfo.email,SerialNumber_));
|
||||
Poco::JSON::Object::Ptr Obj = ParseStream();
|
||||
if (Obj->has(RESTAPI::Protocol::KEEPREDIRECTOR) &&
|
||||
Obj->has(RESTAPI::Protocol::SERIALNUMBER)) {
|
||||
|
||||
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
|
||||
if (SerialNumber_ != SNum) {
|
||||
return BadRequest(RESTAPI::Errors::SerialNumberMismatch);
|
||||
}
|
||||
|
||||
auto KeepRedirector = GetB(RESTAPI::Protocol::KEEPREDIRECTOR, Obj, true);
|
||||
uint64_t When = GetWhen(Obj);
|
||||
|
||||
GWObjects::CommandDetails Cmd;
|
||||
|
||||
Cmd.SerialNumber = SerialNumber_;
|
||||
Cmd.UUID = MicroService::instance().CreateUUID();
|
||||
Cmd.SubmittedBy = UserInfo_.webtoken.username_;
|
||||
Cmd.Command = uCentralProtocol::FACTORY;
|
||||
Cmd.RunAt = When;
|
||||
|
||||
Poco::JSON::Object Params;
|
||||
|
||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentralProtocol::KEEP_REDIRECTOR, KeepRedirector ? 1 : 0);
|
||||
Params.set(uCentralProtocol::WHEN, When);
|
||||
|
||||
std::stringstream ParamStream;
|
||||
Params.stringify(ParamStream);
|
||||
Cmd.Details = ParamStream.str();
|
||||
|
||||
return RESTAPI_RPC::WaitForCommand(Cmd, Params, *Request, *Response, 60000, nullptr, this, Logger_);
|
||||
}
|
||||
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::LEDs() {
|
||||
Logger_.information(Poco::format("LEDS: user=%s serial=%s", UserInfo_.userinfo.email,SerialNumber_));
|
||||
auto Obj = ParseStream();
|
||||
|
||||
if (Obj->has(uCentralProtocol::PATTERN) &&
|
||||
Obj->has(RESTAPI::Protocol::SERIALNUMBER)) {
|
||||
|
||||
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
if (SerialNumber_ != SNum) {
|
||||
return BadRequest(RESTAPI::Errors::SerialNumberMismatch);
|
||||
}
|
||||
|
||||
auto Pattern =
|
||||
GetS(uCentralProtocol::PATTERN, Obj, uCentralProtocol::BLINK);
|
||||
if (Pattern != uCentralProtocol::ON &&
|
||||
Pattern != uCentralProtocol::OFF &&
|
||||
Pattern != uCentralProtocol::BLINK) {
|
||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
auto Duration = Get(uCentralProtocol::DURATION, Obj, 30);
|
||||
auto When = GetWhen(Obj);
|
||||
|
||||
GWObjects::CommandDetails Cmd;
|
||||
|
||||
Cmd.SerialNumber = SerialNumber_;
|
||||
Cmd.UUID = MicroService::instance().CreateUUID();
|
||||
Cmd.SubmittedBy = UserInfo_.webtoken.username_;
|
||||
Cmd.Command = uCentralProtocol::LEDS;
|
||||
Cmd.RunAt = When;
|
||||
Poco::JSON::Object Params;
|
||||
|
||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentralProtocol::DURATION, Duration);
|
||||
Params.set(uCentralProtocol::WHEN, When);
|
||||
Params.set(uCentralProtocol::PATTERN, Pattern);
|
||||
|
||||
std::stringstream ParamStream;
|
||||
Params.stringify(ParamStream);
|
||||
Cmd.Details = ParamStream.str();
|
||||
|
||||
return RESTAPI_RPC::WaitForCommand(Cmd, Params, *Request, *Response, 60000, nullptr, this, Logger_);
|
||||
}
|
||||
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::Trace() {
|
||||
Logger_.information(Poco::format("TRACE: user=%s serial=%s", UserInfo_.userinfo.email,SerialNumber_));
|
||||
auto Obj = ParseStream();
|
||||
|
||||
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER) &&
|
||||
(Obj->has(RESTAPI::Protocol::NETWORK) ||
|
||||
Obj->has(RESTAPI::Protocol::INTERFACE))) {
|
||||
|
||||
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
if (SerialNumber_ != SNum) {
|
||||
return BadRequest(RESTAPI::Errors::SerialNumberMismatch);
|
||||
}
|
||||
|
||||
auto Duration = Get(RESTAPI::Protocol::DURATION, Obj, 30);
|
||||
auto When = GetWhen(Obj);
|
||||
auto NumberOfPackets = Get(RESTAPI::Protocol::NUMBEROFPACKETS, Obj, 100);
|
||||
|
||||
auto Network = GetS(RESTAPI::Protocol::NETWORK, Obj);
|
||||
auto Interface = GetS(RESTAPI::Protocol::INTERFACE, Obj);
|
||||
auto UUID = MicroService::instance().CreateUUID();
|
||||
auto URI = FileUploader()->FullName() + UUID;
|
||||
|
||||
GWObjects::CommandDetails Cmd;
|
||||
Cmd.SerialNumber = SerialNumber_;
|
||||
Cmd.UUID = UUID;
|
||||
Cmd.SubmittedBy = UserInfo_.webtoken.username_;
|
||||
Cmd.Command = uCentralProtocol::TRACE;
|
||||
Cmd.RunAt = When;
|
||||
Cmd.WaitingForFile = 1;
|
||||
Cmd.AttachType = RESTAPI::Protocol::PCAP_FILE_TYPE;
|
||||
|
||||
Poco::JSON::Object Params;
|
||||
|
||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentralProtocol::DURATION, Duration);
|
||||
Params.set(uCentralProtocol::WHEN, When);
|
||||
Params.set(uCentralProtocol::PACKETS, NumberOfPackets);
|
||||
Params.set(uCentralProtocol::NETWORK, Network);
|
||||
Params.set(uCentralProtocol::INTERFACE, Interface);
|
||||
Params.set(uCentralProtocol::URI, URI);
|
||||
|
||||
std::stringstream ParamStream;
|
||||
Params.stringify(ParamStream);
|
||||
Cmd.Details = ParamStream.str();
|
||||
|
||||
FileUploader()->AddUUID(UUID);
|
||||
return RESTAPI_RPC::WaitForCommand(Cmd, Params, *Request, *Response, 60000, nullptr, this, Logger_);
|
||||
}
|
||||
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::WifiScan() {
|
||||
Logger_.information(Poco::format("WIFISCAN: user=%s serial=%s", UserInfo_.userinfo.email,SerialNumber_));
|
||||
auto Obj = ParseStream();
|
||||
|
||||
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
if (SerialNumber_ != SNum) {
|
||||
return BadRequest(RESTAPI::Errors::SerialNumberMismatch);
|
||||
}
|
||||
|
||||
if ((Obj->has(RESTAPI::Protocol::BANDS) &&
|
||||
Obj->isArray(RESTAPI::Protocol::BANDS) ||
|
||||
(Obj->has(RESTAPI::Protocol::CHANNELS) &&
|
||||
Obj->isArray(RESTAPI::Protocol::CHANNELS)) ||
|
||||
(!Obj->has(RESTAPI::Protocol::BANDS) &&
|
||||
!Obj->has(RESTAPI::Protocol::CHANNELS)))) {
|
||||
bool Verbose = GetB(RESTAPI::Protocol::VERBOSE, Obj);
|
||||
auto UUID = MicroService::instance().CreateUUID();
|
||||
GWObjects::CommandDetails Cmd;
|
||||
|
||||
Cmd.SerialNumber = SerialNumber_;
|
||||
Cmd.UUID = UUID;
|
||||
Cmd.SubmittedBy = UserInfo_.webtoken.username_;
|
||||
Cmd.Command = uCentralProtocol::WIFISCAN;
|
||||
|
||||
Poco::JSON::Object Params;
|
||||
|
||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentralProtocol::VERBOSE, Verbose);
|
||||
|
||||
if (Obj->has(uCentralProtocol::BANDS)) {
|
||||
Params.set(uCentralProtocol::BANDS, Obj->get(RESTAPI::Protocol::BANDS));
|
||||
} else if (Obj->has(uCentralProtocol::CHANNELS)) {
|
||||
Params.set(uCentralProtocol::CHANNELS, Obj->get(RESTAPI::Protocol::CHANNELS));
|
||||
}
|
||||
|
||||
if (Obj->has(RESTAPI::Protocol::ACTIVESCAN)) {
|
||||
Params.set(uCentralProtocol::ACTIVE,
|
||||
(int)(Obj->get(RESTAPI::Protocol::ACTIVESCAN).toString() == "true") ? 1 : 0);
|
||||
} else {
|
||||
Params.set(uCentralProtocol::ACTIVE, 0);
|
||||
}
|
||||
|
||||
std::stringstream ParamStream;
|
||||
Params.stringify(ParamStream);
|
||||
Cmd.Details = ParamStream.str();
|
||||
RESTAPI_RPC::WaitForCommand(Cmd, Params, *Request, *Response, 60000, nullptr, this, Logger_);
|
||||
if (Cmd.ErrorCode == 0) {
|
||||
KafkaManager()->PostMessage(KafkaTopics::WIFISCAN, SerialNumber_, Cmd.Results);
|
||||
}
|
||||
return;
|
||||
}
|
||||
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::EventQueue() {
|
||||
Logger_.information(Poco::format("EVENT-QUEUE: user=%s serial=%s", UserInfo_.userinfo.email,SerialNumber_));
|
||||
auto Obj = ParseStream();
|
||||
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER) &&
|
||||
Obj->isArray(RESTAPI::Protocol::TYPES)) {
|
||||
|
||||
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
if (SerialNumber_ != SNum) {
|
||||
return BadRequest(RESTAPI::Errors::SerialNumberMismatch);
|
||||
}
|
||||
|
||||
auto Types = Obj->getArray(RESTAPI::Protocol::TYPES);
|
||||
|
||||
auto UUID = MicroService::instance().CreateUUID();
|
||||
GWObjects::CommandDetails Cmd;
|
||||
|
||||
Cmd.SerialNumber = SerialNumber_;
|
||||
Cmd.UUID = UUID;
|
||||
Cmd.SubmittedBy = UserInfo_.webtoken.username_;
|
||||
Cmd.Command = uCentralProtocol::EVENT;
|
||||
|
||||
Poco::JSON::Object Params;
|
||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentralProtocol::TYPES, Types);
|
||||
|
||||
std::stringstream ParamStream;
|
||||
Params.stringify(ParamStream);
|
||||
Cmd.Details = ParamStream.str();
|
||||
|
||||
RESTAPI_RPC::WaitForCommand(Cmd, Params, *Request, *Response, 60000, nullptr, this, Logger_);
|
||||
if(Cmd.ErrorCode==0) {
|
||||
KafkaManager()->PostMessage(KafkaTopics::DEVICE_EVENT_QUEUE, SerialNumber_,
|
||||
Cmd.Results);
|
||||
}
|
||||
return;
|
||||
}
|
||||
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::MakeRequest() {
|
||||
Logger_.information(Poco::format("FORCE-REQUEST: user=%s serial=%s", UserInfo_.userinfo.email,SerialNumber_));
|
||||
auto Obj = ParseStream();
|
||||
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER) &&
|
||||
Obj->has(uCentralProtocol::MESSAGE)) {
|
||||
|
||||
auto SNum = GetS(RESTAPI::Protocol::SERIALNUMBER, Obj);
|
||||
auto MessageType = GetS(uCentralProtocol::MESSAGE, Obj);
|
||||
|
||||
if ((SerialNumber_ != SNum) ||
|
||||
(MessageType != uCentralProtocol::STATE &&
|
||||
MessageType != uCentralProtocol::HEALTHCHECK)) {
|
||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
auto When = GetWhen(Obj);
|
||||
GWObjects::CommandDetails Cmd;
|
||||
|
||||
Cmd.SerialNumber = SerialNumber_;
|
||||
Cmd.SubmittedBy = UserInfo_.webtoken.username_;
|
||||
Cmd.UUID = MicroService::instance().CreateUUID();
|
||||
Cmd.Command = uCentralProtocol::REQUEST;
|
||||
Cmd.RunAt = When;
|
||||
|
||||
Poco::JSON::Object Params;
|
||||
|
||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentralProtocol::WHEN, When);
|
||||
Params.set(uCentralProtocol::MESSAGE, MessageType);
|
||||
Params.set(uCentralProtocol::REQUEST_UUID, Cmd.UUID);
|
||||
|
||||
std::stringstream ParamStream;
|
||||
Params.stringify(ParamStream);
|
||||
Cmd.Details = ParamStream.str();
|
||||
|
||||
return RESTAPI_RPC::WaitForCommand(Cmd, Params, *Request, *Response, 60000, nullptr, this, Logger_ );
|
||||
}
|
||||
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::Rtty() {
|
||||
Logger_.information(Poco::format("RTTY: user=%s serial=%s", UserInfo_.userinfo.email,SerialNumber_));
|
||||
if (MicroService::instance().ConfigGetString("rtty.enabled", "false") == "true") {
|
||||
GWObjects::Device Device;
|
||||
if (StorageService()->GetDevice(SerialNumber_, Device)) {
|
||||
auto CommandUUID = MicroService::instance().CreateUUID();
|
||||
|
||||
GWObjects::RttySessionDetails Rtty{
|
||||
.SerialNumber = SerialNumber_,
|
||||
.Server = MicroService::instance().ConfigGetString("rtty.server", "localhost"),
|
||||
.Port = MicroService::instance().ConfigGetInt("rtty.port", 5912),
|
||||
.Token = MicroService::instance().ConfigGetString("rtty.token", "nothing"),
|
||||
.TimeOut = MicroService::instance().ConfigGetInt("rtty.timeout", 60),
|
||||
.ConnectionId = CommandUUID,
|
||||
.Started = (uint64_t)time(nullptr),
|
||||
.CommandUUID = CommandUUID,
|
||||
.ViewPort = MicroService::instance().ConfigGetInt("rtty.viewport", 5913),
|
||||
|
||||
};
|
||||
|
||||
Poco::JSON::Object ReturnedObject;
|
||||
Rtty.to_json(ReturnedObject);
|
||||
|
||||
// let's create the command for this request
|
||||
GWObjects::CommandDetails Cmd;
|
||||
Cmd.SerialNumber = SerialNumber_;
|
||||
Cmd.SubmittedBy = UserInfo_.webtoken.username_;
|
||||
Cmd.UUID = CommandUUID;
|
||||
Cmd.Command = uCentralProtocol::RTTY;
|
||||
|
||||
Poco::JSON::Object Params;
|
||||
|
||||
Params.set(uCentralProtocol::METHOD, uCentralProtocol::RTTY);
|
||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentralProtocol::ID, Rtty.ConnectionId);
|
||||
Params.set(uCentralProtocol::TOKEN, Rtty.Token);
|
||||
Params.set(uCentralProtocol::SERVER, Rtty.Server);
|
||||
Params.set(uCentralProtocol::PORT, Rtty.Port);
|
||||
Params.set(uCentralProtocol::USER, UserInfo_.webtoken.username_);
|
||||
Params.set(uCentralProtocol::TIMEOUT, Rtty.TimeOut);
|
||||
Params.set(uCentralProtocol::PASSWORD, Device.DevicePassword);
|
||||
|
||||
std::stringstream ParamStream;
|
||||
Params.stringify(ParamStream);
|
||||
Cmd.Details = ParamStream.str();
|
||||
return RESTAPI_RPC::WaitForCommand(Cmd, Params, *Request, *Response, 60000, &ReturnedObject, this, Logger_);
|
||||
}
|
||||
return NotFound();
|
||||
}
|
||||
ReturnStatus(Poco::Net::HTTPResponse::HTTP_SERVICE_UNAVAILABLE);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::Telemetry(){
|
||||
Logger_.information(Poco::format("TELEMETRY: user=%s serial=%s", UserInfo_.userinfo.email,SerialNumber_));
|
||||
auto Obj = ParseStream();
|
||||
|
||||
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER) &&
|
||||
Obj->has(RESTAPI::Protocol::INTERVAL) && Obj->has(RESTAPI::Protocol::TYPES)) {
|
||||
|
||||
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
if (SerialNumber_ != SNum) {
|
||||
return BadRequest(RESTAPI::Errors::SerialNumberMismatch);
|
||||
}
|
||||
|
||||
GWObjects::Device Device;
|
||||
if (!StorageService()->GetDevice(SerialNumber_, Device)) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
if (!DeviceRegistry()->Connected(SerialNumber_)) {
|
||||
return BadRequest(RESTAPI::Errors::DeviceNotConnected);
|
||||
}
|
||||
|
||||
auto Interval = Obj->get(RESTAPI::Protocol::INTERVAL);
|
||||
std::string UUID;
|
||||
if (Obj->has(RESTAPI::Protocol::UUID))
|
||||
UUID = Obj->get(RESTAPI::Protocol::UUID).toString();
|
||||
|
||||
GWObjects::CommandDetails Cmd;
|
||||
|
||||
Cmd.SerialNumber = SerialNumber_;
|
||||
Cmd.SubmittedBy = UserInfo_.webtoken.username_;
|
||||
Cmd.Command = uCentralProtocol::TELEMETRY;
|
||||
Poco::JSON::Object Params;
|
||||
|
||||
Params.set(RESTAPI::Protocol::SERIALNUMBER, SerialNumber_);
|
||||
Params.set(RESTAPI::Protocol::INTERVAL, Interval);
|
||||
if (Interval > 0)
|
||||
Params.set(RESTAPI::Protocol::TYPES, Obj->getArray(RESTAPI::Protocol::TYPES));
|
||||
|
||||
std::string Endpoint, NewUUID;
|
||||
Poco::JSON::Object Answer;
|
||||
if (Interval) {
|
||||
if (TelemetryStream()->CreateEndpoint(SerialNumber_, Endpoint, NewUUID)) {
|
||||
Answer.set("serialNumber", SerialNumber_);
|
||||
Answer.set("uuid", NewUUID);
|
||||
Answer.set("uri", Endpoint);
|
||||
}
|
||||
} else {
|
||||
return BadRequest(RESTAPI::Errors::CannotCreateWS);
|
||||
}
|
||||
|
||||
Cmd.UUID = NewUUID;
|
||||
std::stringstream ParamStream;
|
||||
Params.stringify(ParamStream);
|
||||
Cmd.Details = ParamStream.str();
|
||||
|
||||
return RESTAPI_RPC::WaitForCommand(Cmd, Params, *Request, *Response,
|
||||
60000, &Answer, this, Logger_);
|
||||
}
|
||||
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
}
|
71
src/RESTAPI/RESTAPI_device_commandHandler.h
Normal file
71
src/RESTAPI/RESTAPI_device_commandHandler.h
Normal file
@@ -0,0 +1,71 @@
|
||||
//
|
||||
// License type: BSD 3-Clause License
|
||||
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
|
||||
//
|
||||
// Created by Stephane Bourque on 2021-03-04.
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
#ifndef UCENTRAL_RESTAPI_DEVICECOMMANDHANDLER_H
|
||||
#define UCENTRAL_RESTAPI_DEVICECOMMANDHANDLER_H
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
#include "framework/RESTAPI_protocol.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_device_commandHandler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_device_commandHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{
|
||||
Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_POST,
|
||||
Poco::Net::HTTPRequest::HTTP_DELETE,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server,
|
||||
Internal) {}
|
||||
|
||||
void GetCapabilities();
|
||||
void DeleteCapabilities();
|
||||
void GetLogs();
|
||||
void DeleteLogs();
|
||||
void GetStatistics();
|
||||
void DeleteStatistics();
|
||||
void GetStatus();
|
||||
void ExecuteCommand();
|
||||
void Configure();
|
||||
void GetChecks();
|
||||
void DeleteChecks();
|
||||
void Upgrade();
|
||||
void Reboot();
|
||||
void Factory();
|
||||
void LEDs();
|
||||
void Trace();
|
||||
void MakeRequest();
|
||||
void WifiScan();
|
||||
void EventQueue();
|
||||
void Rtty();
|
||||
void Telemetry();
|
||||
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/device/{serialNumber}/{command}"}; };
|
||||
void DoGet() final;
|
||||
void DoDelete() final;
|
||||
void DoPost() final;
|
||||
void DoPut() final {};
|
||||
|
||||
inline bool ValidateParameters() {
|
||||
Command_ = GetBinding(RESTAPI::Protocol::COMMAND, "");
|
||||
if (Command_.empty()) {
|
||||
return false;
|
||||
}
|
||||
SerialNumber_ = GetBinding(RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
if (SerialNumber_.empty()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string SerialNumber_, Command_;
|
||||
};
|
||||
}
|
||||
#endif //UCENTRAL_RESTAPI_DEVICECOMMANDHANDLER_H
|
155
src/RESTAPI/RESTAPI_device_handler.cpp
Normal file
155
src/RESTAPI/RESTAPI_device_handler.cpp
Normal file
@@ -0,0 +1,155 @@
|
||||
//
|
||||
// License type: BSD 3-Clause License
|
||||
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
|
||||
//
|
||||
// Created by Stephane Bourque on 2021-03-04.
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
#include "RESTAPI_device_handler.h"
|
||||
#include "CentralConfig.h"
|
||||
#include "ConfigurationCache.h"
|
||||
#include "ConfigurationValidator.h"
|
||||
#include "Poco/JSON/Parser.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/RESTAPI_errors.h"
|
||||
#include "framework/RESTAPI_protocol.h"
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_device_handler::DoGet() {
|
||||
std::string SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
|
||||
if(SerialNumber.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::MissingSerialNumber);
|
||||
}
|
||||
|
||||
GWObjects::Device Device;
|
||||
|
||||
if (StorageService()->GetDevice(SerialNumber, Device)) {
|
||||
Poco::JSON::Object Obj;
|
||||
Device.to_json(Obj);
|
||||
return ReturnObject(Obj);
|
||||
}
|
||||
NotFound();
|
||||
}
|
||||
|
||||
void RESTAPI_device_handler::DoDelete() {
|
||||
std::string SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
|
||||
if(SerialNumber.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::MissingSerialNumber);
|
||||
}
|
||||
|
||||
if (StorageService()->DeleteDevice(SerialNumber)) {
|
||||
return OK();
|
||||
}
|
||||
NotFound();
|
||||
}
|
||||
|
||||
void RESTAPI_device_handler::DoPost() {
|
||||
|
||||
std::string SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
if(SerialNumber.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::MissingSerialNumber);
|
||||
}
|
||||
|
||||
std::string Arg;
|
||||
if(HasParameter("validateOnly",Arg) && Arg=="true") {
|
||||
auto Body = ParseStream();
|
||||
if(!Body->has("configuration")) {
|
||||
return BadRequest("Must have 'configuration' element.");
|
||||
}
|
||||
auto Config=Body->get("configuration").toString();
|
||||
Poco::JSON::Object Answer;
|
||||
auto Res = ValidateUCentralConfiguration(Config);
|
||||
Answer.set("valid",Res);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
|
||||
if (!Utils::ValidSerialNumber(SerialNumber)) {
|
||||
Logger_.warning(Poco::format("CREATE-DEVICE(%s): Illegal serial number.", SerialNumber));
|
||||
return BadRequest( RESTAPI::Errors::InvalidSerialNumber);
|
||||
}
|
||||
|
||||
auto Obj = ParseStream();
|
||||
GWObjects::Device Device;
|
||||
if (!Device.from_json(Obj)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
|
||||
if(SerialNumber!=Device.SerialNumber) {
|
||||
return BadRequest(RESTAPI::Errors::SerialNumberMismatch);
|
||||
}
|
||||
|
||||
if(Device.Configuration.empty() || (!Device.Configuration.empty() && !ValidateUCentralConfiguration(Device.Configuration))) {
|
||||
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid);
|
||||
}
|
||||
|
||||
for(auto &i:Device.Notes)
|
||||
i.createdBy = UserInfo_.userinfo.email;
|
||||
|
||||
Config::Config NewConfig(Device.Configuration);
|
||||
Device.UUID = std::time(nullptr);
|
||||
NewConfig.SetUUID(Device.UUID);
|
||||
Device.Configuration = NewConfig.get();
|
||||
|
||||
Poco::toLowerInPlace(Device.SerialNumber);
|
||||
|
||||
if (StorageService()->CreateDevice(Device)) {
|
||||
SetCurrentConfigurationID(SerialNumber, Device.UUID);
|
||||
Poco::JSON::Object DevObj;
|
||||
Device.to_json(DevObj);
|
||||
return ReturnObject(DevObj);
|
||||
}
|
||||
InternalError(RESTAPI::Errors::RecordNotCreated);
|
||||
}
|
||||
|
||||
void RESTAPI_device_handler::DoPut() {
|
||||
std::string SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
|
||||
if(SerialNumber.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::MissingSerialNumber);
|
||||
}
|
||||
|
||||
auto Obj = ParseStream();
|
||||
GWObjects::Device NewDevice;
|
||||
if (!NewDevice.from_json(Obj)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
|
||||
GWObjects::Device Existing;
|
||||
if(!StorageService()->GetDevice(SerialNumber, Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
if(!NewDevice.Configuration.empty()) {
|
||||
if (!ValidateUCentralConfiguration(NewDevice.Configuration)) {
|
||||
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid);
|
||||
}
|
||||
Config::Config NewConfig(NewDevice.Configuration);
|
||||
uint64_t NewConfigUUID = std::time(nullptr);
|
||||
NewConfig.SetUUID(NewConfigUUID);
|
||||
Existing.Configuration = NewConfig.get();
|
||||
Existing.UUID = NewConfigUUID;
|
||||
}
|
||||
|
||||
AssignIfPresent(Obj, "venue", Existing.Venue);
|
||||
AssignIfPresent(Obj, "owner", Existing.Owner);
|
||||
AssignIfPresent(Obj, "location", Existing.Location);
|
||||
|
||||
for(auto &i:NewDevice.Notes) {
|
||||
i.createdBy = UserInfo_.userinfo.email;
|
||||
Existing.Notes.push_back(i);
|
||||
}
|
||||
|
||||
Existing.LastConfigurationChange = std::time(nullptr);
|
||||
if (StorageService()->UpdateDevice(Existing)) {
|
||||
SetCurrentConfigurationID(SerialNumber, Existing.UUID);
|
||||
Poco::JSON::Object DevObj;
|
||||
NewDevice.to_json(DevObj);
|
||||
return ReturnObject(DevObj);
|
||||
}
|
||||
InternalError(RESTAPI::Errors::RecordNotUpdated);
|
||||
}
|
||||
}
|
@@ -9,23 +9,26 @@
|
||||
#ifndef UCENTRAL_RESTAPI_DEVICEHANDLER_H
|
||||
#define UCENTRAL_RESTAPI_DEVICEHANDLER_H
|
||||
|
||||
#include "RESTAPI_handler.h"
|
||||
#include "Poco/Net/HTTPServerRequest.h"
|
||||
#include "Poco/Net/HTTPServerResponse.h"
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_device_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_device_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
|
||||
RESTAPI_device_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{
|
||||
Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_POST,
|
||||
Poco::Net::HTTPRequest::HTTP_PUT, Poco::Net::HTTPRequest::HTTP_DELETE,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server,
|
||||
Internal) {}
|
||||
void handleRequest(Poco::Net::HTTPServerRequest &request,
|
||||
Poco::Net::HTTPServerResponse &response) override;
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/device/{serialNumber}"}; };
|
||||
void DoGet() final;
|
||||
void DoDelete() final;
|
||||
void DoPost() final;
|
||||
void DoPut() final;
|
||||
|
||||
};
|
||||
}
|
78
src/RESTAPI/RESTAPI_devices_handler.cpp
Normal file
78
src/RESTAPI/RESTAPI_devices_handler.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
//
|
||||
// License type: BSD 3-Clause License
|
||||
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
|
||||
//
|
||||
// Created by Stephane Bourque on 2021-03-04.
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
#include "Poco/Array.h"
|
||||
#include "Poco/JSON/Stringifier.h"
|
||||
|
||||
#include "RESTAPI_devices_handler.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/RESTAPI_protocol.h"
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_devices_handler::DoGet() {
|
||||
|
||||
auto serialOnly = GetBoolParameter(RESTAPI::Protocol::SERIALONLY, false);
|
||||
auto deviceWithStatus = GetBoolParameter(RESTAPI::Protocol::DEVICEWITHSTATUS, false);
|
||||
|
||||
Poco::JSON::Object RetObj;
|
||||
if (!QB_.Select.empty()) {
|
||||
Poco::JSON::Array Objects;
|
||||
std::vector<std::string> Numbers = Utils::Split(QB_.Select);
|
||||
for (auto &i : Numbers) {
|
||||
GWObjects::Device D;
|
||||
if (StorageService()->GetDevice(i, D)) {
|
||||
Poco::JSON::Object Obj;
|
||||
if (deviceWithStatus)
|
||||
D.to_json_with_status(Obj);
|
||||
else
|
||||
D.to_json(Obj);
|
||||
Objects.add(Obj);
|
||||
} else {
|
||||
Logger_.error(
|
||||
Poco::format("DEVICE(%s): device in select cannot be found.", i));
|
||||
}
|
||||
}
|
||||
if (deviceWithStatus)
|
||||
RetObj.set(RESTAPI::Protocol::DEVICESWITHSTATUS, Objects);
|
||||
else
|
||||
RetObj.set(RESTAPI::Protocol::DEVICES, Objects);
|
||||
|
||||
} else if (QB_.CountOnly == true) {
|
||||
uint64_t Count = 0;
|
||||
if (StorageService()->GetDeviceCount(Count)) {
|
||||
return ReturnCountOnly(Count);
|
||||
}
|
||||
} else if (serialOnly) {
|
||||
std::vector<std::string> SerialNumbers;
|
||||
StorageService()->GetDeviceSerialNumbers(QB_.Offset, QB_.Limit, SerialNumbers);
|
||||
Poco::JSON::Array Objects;
|
||||
for (const auto &i : SerialNumbers) {
|
||||
Objects.add(i);
|
||||
}
|
||||
RetObj.set(RESTAPI::Protocol::SERIALNUMBERS, Objects);
|
||||
} else {
|
||||
std::vector<GWObjects::Device> Devices;
|
||||
StorageService()->GetDevices(QB_.Offset, QB_.Limit, Devices);
|
||||
Poco::JSON::Array Objects;
|
||||
for (const auto &i : Devices) {
|
||||
Poco::JSON::Object Obj;
|
||||
if (deviceWithStatus)
|
||||
i.to_json_with_status(Obj);
|
||||
else
|
||||
i.to_json(Obj);
|
||||
Objects.add(Obj);
|
||||
}
|
||||
if (deviceWithStatus)
|
||||
RetObj.set(RESTAPI::Protocol::DEVICESWITHSTATUS, Objects);
|
||||
else
|
||||
RetObj.set(RESTAPI::Protocol::DEVICES, Objects);
|
||||
}
|
||||
ReturnObject(RetObj);
|
||||
}
|
||||
}
|
@@ -9,19 +9,22 @@
|
||||
#ifndef UCENTRAL_RESTAPI_DEVICESHANDLER_H
|
||||
#define UCENTRAL_RESTAPI_DEVICESHANDLER_H
|
||||
|
||||
#include "RESTAPI_handler.h"
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_devices_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_devices_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
|
||||
RESTAPI_devices_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server,
|
||||
Internal){};
|
||||
void handleRequest(Poco::Net::HTTPServerRequest &request,
|
||||
Poco::Net::HTTPServerResponse &response) override;
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/devices"}; };
|
||||
void DoGet() final;
|
||||
void DoDelete() final {};
|
||||
void DoPost() final {};
|
||||
void DoPut() final {};
|
||||
};
|
||||
}
|
||||
|
47
src/RESTAPI/RESTAPI_file.cpp
Normal file
47
src/RESTAPI/RESTAPI_file.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
//
|
||||
// License type: BSD 3-Clause License
|
||||
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
|
||||
//
|
||||
// Created by Stephane Bourque on 2021-03-04.
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
#include "RESTAPI_file.h"
|
||||
|
||||
#include "FileUploader.h"
|
||||
#include "Poco/File.h"
|
||||
#include "StorageService.h"
|
||||
|
||||
#include "framework/RESTAPI_errors.h"
|
||||
#include "framework/RESTAPI_protocol.h"
|
||||
#include <fstream>
|
||||
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_file::DoGet() {
|
||||
auto UUID = GetBinding(RESTAPI::Protocol::FILEUUID, "");
|
||||
auto SerialNumber = GetParameter(RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
|
||||
// does the file exist
|
||||
Poco::File DownloadFile(FileUploader()->Path() + "/" + UUID);
|
||||
|
||||
std::string FileType;
|
||||
if (!StorageService()->GetAttachedFile(UUID, SerialNumber, DownloadFile.path(), FileType)) {
|
||||
return NotFound();
|
||||
}
|
||||
SendFile(DownloadFile, UUID);
|
||||
DownloadFile.remove();
|
||||
}
|
||||
|
||||
void RESTAPI_file::DoDelete() {
|
||||
auto UUID = GetBinding(RESTAPI::Protocol::FILEUUID, "");
|
||||
|
||||
if (UUID.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::MissingUUID);
|
||||
}
|
||||
|
||||
if (StorageService()->RemoveAttachedFile(UUID)) {
|
||||
return OK();
|
||||
}
|
||||
BadRequest(RESTAPI::Errors::CouldNotBeDeleted);
|
||||
}
|
||||
}
|
@@ -9,20 +9,23 @@
|
||||
#ifndef UCENTRAL_RESTAPI_FILE_H
|
||||
#define UCENTRAL_RESTAPI_FILE_H
|
||||
|
||||
#include "RESTAPI_handler.h"
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_file : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_file(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
|
||||
RESTAPI_file(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_DELETE,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server,
|
||||
Internal) {}
|
||||
void handleRequest(Poco::Net::HTTPServerRequest &request,
|
||||
Poco::Net::HTTPServerResponse &response) override;
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/file/{uuid}"};}
|
||||
void DoGet() final;
|
||||
void DoDelete() final;
|
||||
void DoPost() final {};
|
||||
void DoPut() final {};
|
||||
};
|
||||
}
|
||||
|
24
src/RESTAPI/RESTAPI_ouis.cpp
Normal file
24
src/RESTAPI/RESTAPI_ouis.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-06-17.
|
||||
//
|
||||
|
||||
#include "RESTAPI_ouis.h"
|
||||
#include "OUIServer.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_ouis::DoGet() {
|
||||
Poco::JSON::Array Objects;
|
||||
auto Select = GetParameter("macList","");
|
||||
std::vector<std::string> Macs = Utils::Split(Select);
|
||||
for (auto &i : Macs) {
|
||||
Poco::JSON::Object O;
|
||||
auto Manufacturer = OUIServer()->GetManufacturer(i);
|
||||
O.set("tag", i);
|
||||
O.set("value", Manufacturer);
|
||||
Objects.add(O);
|
||||
}
|
||||
Poco::JSON::Object RetObj;
|
||||
RetObj.set("tagList",Objects);
|
||||
ReturnObject(RetObj);
|
||||
}
|
||||
}
|
@@ -5,19 +5,21 @@
|
||||
#ifndef UCENTRALGW_RESTAPI_OUIS_H
|
||||
#define UCENTRALGW_RESTAPI_OUIS_H
|
||||
|
||||
#include "RESTAPI_handler.h"
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_ouis : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_ouis(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
|
||||
RESTAPI_ouis(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{
|
||||
Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_POST,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS}, Internal) {}
|
||||
void handleRequest(Poco::Net::HTTPServerRequest &request,
|
||||
Poco::Net::HTTPServerResponse &response) override;
|
||||
Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS}, Server, Internal) {}
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/ouis"};}
|
||||
void DoGet() final;
|
||||
void DoDelete() final {};
|
||||
void DoPost() final {};
|
||||
void DoPut() final {};
|
||||
};
|
||||
}
|
||||
|
@@ -2,38 +2,25 @@
|
||||
// Created by stephane bourque on 2021-08-12.
|
||||
//
|
||||
|
||||
#include "RESTAPI_webSocketServer.h"
|
||||
#include "Poco/Net/WebSocket.h"
|
||||
#include "Poco/Net/NetException.h"
|
||||
#include "Poco/Net/HTTPResponse.h"
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include "Poco/JSON/Parser.h"
|
||||
#include "Poco/JSON/Stringifier.h"
|
||||
|
||||
#include "RESTAPI_webSocketServer.h"
|
||||
#include "SerialNumberCache.h"
|
||||
|
||||
#include "Utils.h"
|
||||
#include "AuthClient.h"
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
void RESTAPI_webSocketServer::handleRequest(Poco::Net::HTTPServerRequest &Request, Poco::Net::HTTPServerResponse &Response) {
|
||||
|
||||
if (!ContinueProcessing(Request, Response))
|
||||
return;
|
||||
|
||||
if(Request.getMethod()==Poco::Net::HTTPRequest::HTTP_GET)
|
||||
DoGet(Request,Response);
|
||||
else
|
||||
BadRequest(Request, Response, "Can only do get for WebSocket.");
|
||||
}
|
||||
|
||||
void RESTAPI_webSocketServer::DoGet(Poco::Net::HTTPServerRequest &Request, Poco::Net::HTTPServerResponse &Response) {
|
||||
void RESTAPI_webSocketServer::DoGet() {
|
||||
|
||||
// try and upgrade this session to websocket...
|
||||
if(Request.find("Upgrade") != Request.end() && Poco::icompare(Request["Upgrade"], "websocket") == 0) {
|
||||
if(Request->find("Upgrade") != Request->end() && Poco::icompare((*Request)["Upgrade"], "websocket") == 0) {
|
||||
try
|
||||
{
|
||||
Poco::Net::WebSocket WS(Request, Response);
|
||||
Poco::Net::WebSocket WS(*Request, *Response);
|
||||
Logger_.information("WebSocket connection established.");
|
||||
int flags;
|
||||
int n;
|
||||
@@ -102,14 +89,14 @@ namespace OpenWifi {
|
||||
switch (E.code())
|
||||
{
|
||||
case Poco::Net::WebSocket::WS_ERR_HANDSHAKE_UNSUPPORTED_VERSION:
|
||||
Response.set("Sec-WebSocket-Version", Poco::Net::WebSocket::WEBSOCKET_VERSION);
|
||||
Response->set("Sec-WebSocket-Version", Poco::Net::WebSocket::WEBSOCKET_VERSION);
|
||||
// fallthrough
|
||||
case Poco::Net::WebSocket::WS_ERR_NO_HANDSHAKE:
|
||||
case Poco::Net::WebSocket::WS_ERR_HANDSHAKE_NO_VERSION:
|
||||
case Poco::Net::WebSocket::WS_ERR_HANDSHAKE_NO_KEY:
|
||||
Response.setStatusAndReason(Poco::Net::HTTPResponse::HTTP_BAD_REQUEST);
|
||||
Response.setContentLength(0);
|
||||
Response.send();
|
||||
Response->setStatusAndReason(Poco::Net::HTTPResponse::HTTP_BAD_REQUEST);
|
||||
Response->setContentLength(0);
|
||||
Response->send();
|
||||
break;
|
||||
}
|
||||
}
|
@@ -5,23 +5,21 @@
|
||||
#ifndef UCENTRALGW_RESTAPI_WEBSOCKETSERVER_H
|
||||
#define UCENTRALGW_RESTAPI_WEBSOCKETSERVER_H
|
||||
|
||||
class RESTAPI_webSocketServer {};
|
||||
|
||||
#include "RESTAPI_handler.h"
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_webSocketServer : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_webSocketServer(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
|
||||
RESTAPI_webSocketServer(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Internal) {}
|
||||
void handleRequest(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response) override final;
|
||||
std::vector<std::string>{ Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server, Internal,false) {}
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/ws"};}
|
||||
void DoGet(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response);
|
||||
void DoGet() final;
|
||||
void DoDelete() final {};
|
||||
void DoPost() final {};
|
||||
void DoPut() final {};
|
||||
private:
|
||||
void Process(const Poco::JSON::Object::Ptr &O, std::string &Answer);
|
||||
};
|
@@ -1,128 +0,0 @@
|
||||
//
|
||||
// License type: BSD 3-Clause License
|
||||
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
|
||||
//
|
||||
// Created by Stephane Bourque on 2021-03-04.
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
#include <ctime>
|
||||
|
||||
#include "Poco/JSON/Parser.h"
|
||||
#include "Poco/JSON/Stringifier.h"
|
||||
#include "RESTAPI_BlackList.h"
|
||||
#include "RESTAPI_protocol.h"
|
||||
#include "StorageService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_BlackList::handleRequest(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response) {
|
||||
|
||||
if (!ContinueProcessing(Request, Response))
|
||||
return;
|
||||
|
||||
if (!IsAuthorized(Request, Response))
|
||||
return;
|
||||
|
||||
ParseParameters(Request);
|
||||
|
||||
try {
|
||||
if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_DELETE)
|
||||
DoDelete(Request, Response);
|
||||
else if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_GET)
|
||||
DoGet(Request, Response);
|
||||
else if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_POST)
|
||||
DoPost(Request, Response);
|
||||
return;
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.error(Poco::format("%s: failed with %s", std::string(__func__), E.displayText()));
|
||||
}
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
|
||||
void RESTAPI_BlackList::DoDelete(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response) {
|
||||
|
||||
try {
|
||||
auto SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
|
||||
if (!SerialNumber.empty()) {
|
||||
if (Storage()->DeleteBlackListDevice(SerialNumber)) {
|
||||
OK(Request, Response);
|
||||
} else {
|
||||
NotFound(Request, Response);
|
||||
}
|
||||
return;
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
}
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
|
||||
void RESTAPI_BlackList::DoGet(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response) {
|
||||
try {
|
||||
if(!InitQueryBlock()) {
|
||||
BadRequest(Request, Response, "Illegal parameter value.");
|
||||
return;
|
||||
}
|
||||
std::vector<GWObjects::BlackListedDevice> Devices;
|
||||
|
||||
Poco::JSON::Array Objects;
|
||||
if (Storage()->GetBlackListDevices(QB_.Offset, QB_.Limit, Devices)) {
|
||||
for (const auto &i : Devices) {
|
||||
Poco::JSON::Object Obj;
|
||||
i.to_json(Obj);
|
||||
Objects.add(Obj);
|
||||
}
|
||||
}
|
||||
Poco::JSON::Object RetObj;
|
||||
RetObj.set(RESTAPI::Protocol::DEVICES, Objects);
|
||||
ReturnObject(Request, RetObj, Response);
|
||||
return;
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
}
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
|
||||
void RESTAPI_BlackList::DoPost(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response) {
|
||||
try {
|
||||
Poco::JSON::Parser parser;
|
||||
Poco::JSON::Object::Ptr Obj =
|
||||
parser.parse(Request.stream()).extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
if (Obj->has(RESTAPI::Protocol::DEVICES) &&
|
||||
Obj->isArray(RESTAPI::Protocol::DEVICES)) {
|
||||
std::vector<GWObjects::BlackListedDevice> Devices;
|
||||
auto DeviceArray = Obj->getArray(RESTAPI::Protocol::DEVICES);
|
||||
for (const auto &i : *DeviceArray) {
|
||||
Poco::JSON::Parser pp;
|
||||
auto InnerObj = pp.parse(i).extract<Poco::JSON::Object::Ptr>();
|
||||
Poco::DynamicStruct Vars = *InnerObj;
|
||||
if (Vars.contains(RESTAPI::Protocol::SERIALNUMBER) &&
|
||||
Vars.contains(RESTAPI::Protocol::REASON)) {
|
||||
auto SerialNumber = Vars[RESTAPI::Protocol::SERIALNUMBER].toString();
|
||||
auto Reason = Vars[RESTAPI::Protocol::REASON].toString();
|
||||
GWObjects::BlackListedDevice D{.SerialNumber = SerialNumber,
|
||||
.Reason = Reason,
|
||||
.Author = UserInfo_.webtoken.username_,
|
||||
.Created = (uint64_t)time(nullptr)};
|
||||
Devices.push_back(D);
|
||||
}
|
||||
}
|
||||
if (!Devices.empty()) {
|
||||
if (Storage()->AddBlackListDevices(Devices)) {
|
||||
OK(Request, Response);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
}
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
}
|
@@ -1,80 +0,0 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-06-29.
|
||||
//
|
||||
|
||||
#include "RESTAPI_InternalServer.h"
|
||||
|
||||
#include "Poco/URI.h"
|
||||
|
||||
#include "RESTAPI_BlackList.h"
|
||||
#include "RESTAPI_command.h"
|
||||
#include "RESTAPI_commands.h"
|
||||
#include "RESTAPI_default_configuration.h"
|
||||
#include "RESTAPI_default_configurations.h"
|
||||
#include "RESTAPI_device_commandHandler.h"
|
||||
#include "RESTAPI_device_handler.h"
|
||||
#include "RESTAPI_devices_handler.h"
|
||||
#include "RESTAPI_file.h"
|
||||
#include "RESTAPI_ouis.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class RESTAPI_InternalServer *RESTAPI_InternalServer::instance_ = nullptr;
|
||||
|
||||
RESTAPI_InternalServer::RESTAPI_InternalServer() noexcept: SubSystemServer("RESTAPIInternalServer", "REST-ISRV", "ucentral.internal.restapi")
|
||||
{
|
||||
}
|
||||
|
||||
int RESTAPI_InternalServer::Start() {
|
||||
Logger_.information("Starting.");
|
||||
|
||||
for(const auto & Svr: ConfigServersList_) {
|
||||
Logger_.information(Poco::format("Starting: %s:%s Keyfile:%s CertFile: %s", Svr.Address(), std::to_string(Svr.Port()),
|
||||
Svr.KeyFile(),Svr.CertFile()));
|
||||
|
||||
auto Sock{Svr.CreateSecureSocket(Logger_)};
|
||||
|
||||
Svr.LogCert(Logger_);
|
||||
if(!Svr.RootCA().empty())
|
||||
Svr.LogCas(Logger_);
|
||||
auto Params = new Poco::Net::HTTPServerParams;
|
||||
Params->setMaxThreads(50);
|
||||
Params->setMaxQueued(200);
|
||||
Params->setKeepAlive(true);
|
||||
|
||||
auto NewServer = std::make_unique<Poco::Net::HTTPServer>(new InternalRequestHandlerFactory, Pool_, Sock, Params);
|
||||
NewServer->start();
|
||||
RESTServers_.push_back(std::move(NewServer));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RESTAPI_InternalServer::Stop() {
|
||||
Logger_.information("Stopping ");
|
||||
for( const auto & svr : RESTServers_ )
|
||||
svr->stop();
|
||||
}
|
||||
|
||||
Poco::Net::HTTPRequestHandler *InternalRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest & Request) {
|
||||
|
||||
Logger_.debug(Poco::format("REQUEST(%s): %s %s", Utils::FormatIPv6(Request.clientAddress().toString()), Request.getMethod(), Request.getURI()));
|
||||
|
||||
Poco::URI uri(Request.getURI());
|
||||
const auto & Path = uri.getPath();
|
||||
RESTAPIHandler::BindingMap Bindings;
|
||||
|
||||
return RESTAPI_Router_I<
|
||||
RESTAPI_devices_handler,
|
||||
RESTAPI_device_handler,
|
||||
RESTAPI_device_commandHandler,
|
||||
RESTAPI_default_configurations,
|
||||
RESTAPI_default_configuration,
|
||||
RESTAPI_command,
|
||||
RESTAPI_commands,
|
||||
RESTAPI_ouis,
|
||||
RESTAPI_file,
|
||||
RESTAPI_BlackList>(Path,Bindings,Logger_); }
|
||||
|
||||
}
|
@@ -1,53 +0,0 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-06-29.
|
||||
//
|
||||
|
||||
#ifndef UCENTRALSEC_RESTAPI_INTERNALSERVER_H
|
||||
#define UCENTRALSEC_RESTAPI_INTERNALSERVER_H
|
||||
|
||||
#include "SubSystemServer.h"
|
||||
#include "Poco/Net/HTTPServer.h"
|
||||
#include "Poco/Net/HTTPRequestHandler.h"
|
||||
#include "Poco/Net/HTTPRequestHandlerFactory.h"
|
||||
#include "Poco/Net/HTTPServerRequest.h"
|
||||
#include "Poco/Net/NetException.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class RESTAPI_InternalServer : public SubSystemServer {
|
||||
|
||||
public:
|
||||
RESTAPI_InternalServer() noexcept;
|
||||
|
||||
static RESTAPI_InternalServer *instance() {
|
||||
if (instance_ == nullptr) {
|
||||
instance_ = new RESTAPI_InternalServer;
|
||||
}
|
||||
return instance_;
|
||||
}
|
||||
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
|
||||
private:
|
||||
static RESTAPI_InternalServer *instance_;
|
||||
std::vector<std::unique_ptr<Poco::Net::HTTPServer>> RESTServers_;
|
||||
Poco::ThreadPool Pool_;
|
||||
};
|
||||
|
||||
inline RESTAPI_InternalServer * RESTAPI_InternalServer() { return RESTAPI_InternalServer::instance(); };
|
||||
|
||||
class InternalRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
|
||||
public:
|
||||
InternalRequestHandlerFactory() :
|
||||
Logger_(RESTAPI_InternalServer()->Logger()){}
|
||||
|
||||
Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &request) override;
|
||||
private:
|
||||
Poco::Logger & Logger_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif //UCENTRALSEC_RESTAPI_INTERNALSERVER_H
|
@@ -1,139 +0,0 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-06-28.
|
||||
//
|
||||
#include <cctype>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <future>
|
||||
#include <numeric>
|
||||
#include <chrono>
|
||||
#include "RESTAPI_RPC.h"
|
||||
|
||||
#include "StorageService.h"
|
||||
#include "DeviceRegistry.h"
|
||||
#include "CommandManager.h"
|
||||
#include "uCentralProtocol.h"
|
||||
|
||||
namespace OpenWifi::RESTAPI_RPC {
|
||||
void SetCommandAsPending(GWObjects::CommandDetails &Cmd,
|
||||
Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response, RESTAPIHandler *Handler) {
|
||||
if (Storage()->AddCommand(Cmd.SerialNumber, Cmd, Storage::COMMAND_PENDING)) {
|
||||
Poco::JSON::Object RetObj;
|
||||
Cmd.to_json(RetObj);
|
||||
Handler->ReturnObject(Request, RetObj, Response);
|
||||
return;
|
||||
} else {
|
||||
Handler->ReturnStatus(Request, Response,
|
||||
Poco::Net::HTTPResponse::HTTP_INTERNAL_SERVER_ERROR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void WaitForCommand(GWObjects::CommandDetails &Cmd,
|
||||
Poco::JSON::Object & Params,
|
||||
Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response,
|
||||
std::chrono::milliseconds D,
|
||||
Poco::JSON::Object * ObjectToReturn,
|
||||
RESTAPIHandler * Handler) {
|
||||
|
||||
// if the command should be executed in the future, or if the device is not connected, then we should just add the command to
|
||||
// the DB and let it figure out when to deliver the command.
|
||||
if(Cmd.RunAt || !DeviceRegistry()->Connected(Cmd.SerialNumber)) {
|
||||
SetCommandAsPending(Cmd, Request, Response, Handler);
|
||||
return;
|
||||
} else if(Cmd.RunAt==0 && DeviceRegistry()->Connected(Cmd.SerialNumber)) {
|
||||
auto Promise = std::make_shared<std::promise<Poco::JSON::Object::Ptr>>();
|
||||
std::future<Poco::JSON::Object::Ptr> Future = Promise->get_future();
|
||||
|
||||
Cmd.Executed = time(nullptr);
|
||||
|
||||
if (CommandManager()->SendCommand(Cmd.SerialNumber, Cmd.Command, Params, Promise, Cmd.UUID)) {
|
||||
auto Status = Future.wait_for(D);
|
||||
if (Status == std::future_status::ready) {
|
||||
auto Answer = Future.get();
|
||||
|
||||
if (Answer->has("result") && Answer->isObject("result")) {
|
||||
auto ResultFields =
|
||||
Answer->get("result").extract<Poco::JSON::Object::Ptr>();
|
||||
if (ResultFields->has("status") && ResultFields->isObject("status")) {
|
||||
auto StatusInnerObj =
|
||||
ResultFields->get("status").extract<Poco::JSON::Object::Ptr>();
|
||||
if (StatusInnerObj->has("error"))
|
||||
Cmd.ErrorCode = StatusInnerObj->get("error");
|
||||
if (StatusInnerObj->has("text"))
|
||||
Cmd.ErrorText = StatusInnerObj->get("text").toString();
|
||||
std::stringstream ResultText;
|
||||
Poco::JSON::Stringifier::stringify(Answer->get("result"), ResultText);
|
||||
Cmd.Results = ResultText.str();
|
||||
Cmd.Status = "completed";
|
||||
Cmd.Completed = time(nullptr);
|
||||
|
||||
if(Cmd.ErrorCode && Cmd.Command==uCentralProtocol::TRACE) {
|
||||
Cmd.WaitingForFile = 0;
|
||||
Cmd.AttachDate = Cmd.AttachSize = 0 ;
|
||||
Cmd.AttachType = "";
|
||||
}
|
||||
|
||||
// Add the completed command to the database...
|
||||
Storage()->AddCommand(Cmd.SerialNumber, Cmd,Storage::COMMAND_COMPLETED);
|
||||
|
||||
if(ObjectToReturn) {
|
||||
Handler->ReturnObject(Request, *ObjectToReturn, Response);
|
||||
} else {
|
||||
Poco::JSON::Object O;
|
||||
Cmd.to_json(O);
|
||||
Handler->ReturnObject(Request, O, Response);
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
SetCommandAsPending(Cmd, Request, Response, Handler);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
SetCommandAsPending(Cmd, Request, Response, Handler);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
SetCommandAsPending(Cmd, Request, Response, Handler);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool WaitForRPC(GWObjects::CommandDetails &Cmd,
|
||||
Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response, uint64_t Timeout,
|
||||
bool ReturnValue,
|
||||
RESTAPIHandler * Handler) {
|
||||
|
||||
if (DeviceRegistry()->Connected(Cmd.SerialNumber)) {
|
||||
GWObjects::CommandDetails ResCmd;
|
||||
while (Timeout > 0) {
|
||||
Timeout -= 1000;
|
||||
Poco::Thread::sleep(1000);
|
||||
if (Storage()->GetCommand(Cmd.UUID, ResCmd)) {
|
||||
if (ResCmd.Completed) {
|
||||
if (ReturnValue) {
|
||||
Poco::JSON::Object RetObj;
|
||||
ResCmd.to_json(RetObj);
|
||||
Handler->ReturnObject(Request, RetObj, Response);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ReturnValue) {
|
||||
Poco::JSON::Object RetObj;
|
||||
Cmd.to_json(RetObj);
|
||||
Handler->ReturnObject(Request, RetObj, Response);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -1,49 +0,0 @@
|
||||
//
|
||||
// License type: BSD 3-Clause License
|
||||
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
|
||||
//
|
||||
// Created by Stephane Bourque on 2021-03-04.
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
#include "RESTAPI_command.h"
|
||||
|
||||
#include "RESTAPI_protocol.h"
|
||||
#include "StorageService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_command::handleRequest(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response) {
|
||||
if (!ContinueProcessing(Request, Response))
|
||||
return;
|
||||
|
||||
if (!IsAuthorized(Request, Response))
|
||||
return;
|
||||
|
||||
try {
|
||||
ParseParameters(Request);
|
||||
|
||||
if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_GET) {
|
||||
auto CommandUUID = GetBinding(RESTAPI::Protocol::COMMANDUUID, "");
|
||||
GWObjects::CommandDetails Command;
|
||||
if (Storage()->GetCommand(CommandUUID, Command)) {
|
||||
Poco::JSON::Object RetObj;
|
||||
Command.to_json(RetObj);
|
||||
ReturnObject(Request, RetObj, Response);
|
||||
} else
|
||||
NotFound(Request, Response);
|
||||
} else if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_DELETE) {
|
||||
auto CommandUUID = GetBinding(RESTAPI::Protocol::COMMANDUUID, "");
|
||||
if (Storage()->DeleteCommand(CommandUUID)) {
|
||||
OK(Request, Response);
|
||||
} else {
|
||||
NotFound(Request, Response);
|
||||
}
|
||||
}
|
||||
return;
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.error(Poco::format("%s: failed with %s", std::string(__func__), E.displayText()));
|
||||
}
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
}
|
@@ -1,63 +0,0 @@
|
||||
//
|
||||
// License type: BSD 3-Clause License
|
||||
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
|
||||
//
|
||||
// Created by Stephane Bourque on 2021-03-04.
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
#include "RESTAPI_commands.h"
|
||||
#include "RESTAPI_protocol.h"
|
||||
#include "StorageService.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_commands::handleRequest(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response) {
|
||||
if (!ContinueProcessing(Request, Response))
|
||||
return;
|
||||
|
||||
if (!IsAuthorized(Request, Response))
|
||||
return;
|
||||
|
||||
try {
|
||||
ParseParameters(Request);
|
||||
if(!InitQueryBlock()) {
|
||||
BadRequest(Request, Response, "Illegal parameter value.");
|
||||
return;
|
||||
}
|
||||
|
||||
auto SerialNumber = GetParameter(RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
|
||||
if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_GET) {
|
||||
std::vector<GWObjects::CommandDetails> Commands;
|
||||
if (QB_.Newest) {
|
||||
Storage()->GetNewestCommands(SerialNumber, QB_.Limit, Commands);
|
||||
} else {
|
||||
Storage()->GetCommands(SerialNumber, QB_.StartDate, QB_.EndDate, QB_.Offset,
|
||||
QB_.Limit, Commands);
|
||||
}
|
||||
Poco::JSON::Array ArrayObj;
|
||||
for (const auto &i : Commands) {
|
||||
Poco::JSON::Object Obj;
|
||||
i.to_json(Obj);
|
||||
ArrayObj.add(Obj);
|
||||
}
|
||||
Poco::JSON::Object RetObj;
|
||||
RetObj.set(RESTAPI::Protocol::COMMANDS, ArrayObj);
|
||||
ReturnObject(Request, RetObj, Response);
|
||||
return;
|
||||
|
||||
} else if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_DELETE) {
|
||||
if (Storage()->DeleteCommands(SerialNumber, QB_.StartDate, QB_.EndDate))
|
||||
OK(Request, Response);
|
||||
else
|
||||
BadRequest(Request, Response);
|
||||
return;
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.error(Poco::format("%s: failed with %s", std::string(__func__), E.displayText()));
|
||||
}
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
}
|
@@ -1,80 +0,0 @@
|
||||
//
|
||||
// License type: BSD 3-Clause License
|
||||
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
|
||||
//
|
||||
// Created by Stephane Bourque on 2021-03-04.
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
#include "Poco/JSON/Parser.h"
|
||||
|
||||
#include "RESTAPI_default_configuration.h"
|
||||
|
||||
#include "RESTAPI_GWobjects.h"
|
||||
#include "RESTAPI_protocol.h"
|
||||
#include "StorageService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_default_configuration::handleRequest(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response) {
|
||||
if (!ContinueProcessing(Request, Response))
|
||||
return;
|
||||
|
||||
if (!IsAuthorized(Request, Response))
|
||||
return;
|
||||
|
||||
std::string Name = GetBinding(RESTAPI::Protocol::NAME, "");
|
||||
ParseParameters(Request);
|
||||
|
||||
if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_GET) {
|
||||
GWObjects::DefaultConfiguration DefConfig;
|
||||
if (Storage()->GetDefaultConfiguration(Name, DefConfig)) {
|
||||
Poco::JSON::Object Obj;
|
||||
DefConfig.to_json(Obj);
|
||||
ReturnObject(Request, Obj, Response);
|
||||
} else {
|
||||
NotFound(Request, Response);
|
||||
}
|
||||
} else if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_DELETE) {
|
||||
if (Storage()->DeleteDefaultConfiguration(Name)) {
|
||||
OK(Request, Response);
|
||||
} else {
|
||||
NotFound(Request, Response);
|
||||
}
|
||||
} else if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_POST) {
|
||||
Poco::JSON::Parser IncomingParser;
|
||||
Poco::JSON::Object::Ptr Obj =
|
||||
IncomingParser.parse(Request.stream()).extract<Poco::JSON::Object::Ptr>();
|
||||
GWObjects::DefaultConfiguration DefConfig;
|
||||
|
||||
if (!DefConfig.from_json(Obj)) {
|
||||
BadRequest(Request, Response);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Storage()->CreateDefaultConfiguration(Name, DefConfig)) {
|
||||
OK(Request, Response);
|
||||
} else {
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
} else if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_PUT) {
|
||||
Poco::JSON::Parser IncomingParser;
|
||||
Poco::JSON::Object::Ptr Obj =
|
||||
IncomingParser.parse(Request.stream()).extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
GWObjects::DefaultConfiguration DefConfig;
|
||||
if (!DefConfig.from_json(Obj)) {
|
||||
BadRequest(Request, Response);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Storage()->UpdateDefaultConfiguration(Name, DefConfig)) {
|
||||
OK(Request, Response);
|
||||
} else {
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
} else {
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,61 +0,0 @@
|
||||
//
|
||||
// License type: BSD 3-Clause License
|
||||
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
|
||||
//
|
||||
// Created by Stephane Bourque on 2021-03-04.
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
#include "Poco/Array.h"
|
||||
#include "Poco/JSON/Stringifier.h"
|
||||
|
||||
#include "RESTAPI_default_configurations.h"
|
||||
#include "RESTAPI_protocol.h"
|
||||
#include "StorageService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_default_configurations::handleRequest(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response) {
|
||||
if (!ContinueProcessing(Request, Response))
|
||||
return;
|
||||
|
||||
if (!IsAuthorized(Request, Response))
|
||||
return;
|
||||
|
||||
try {
|
||||
if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_GET) {
|
||||
ParseParameters(Request);
|
||||
if(!InitQueryBlock()) {
|
||||
BadRequest(Request, Response, "Illegal parameter value.");
|
||||
return;
|
||||
}
|
||||
|
||||
Logger_.information(
|
||||
Poco::format("DEFAULT_CONFIGURATIONS: from %Lu, limit of %Lu, filter=%s.",
|
||||
(int64_t)QB_.Offset, (int64_t)QB_.Limit, QB_.Filter));
|
||||
RESTAPIHandler::PrintBindings();
|
||||
|
||||
std::vector<GWObjects::DefaultConfiguration> DefConfigs;
|
||||
|
||||
Storage()->GetDefaultConfigurations(QB_.Offset, QB_.Limit, DefConfigs);
|
||||
|
||||
Poco::JSON::Array Objects;
|
||||
for (const auto &i : DefConfigs) {
|
||||
Poco::JSON::Object Obj;
|
||||
i.to_json(Obj);
|
||||
Objects.add(Obj);
|
||||
}
|
||||
|
||||
Poco::JSON::Object RetObj;
|
||||
RetObj.set(RESTAPI::Protocol::CONFIGURATIONS, Objects);
|
||||
ReturnObject(Request, RetObj, Response);
|
||||
} else
|
||||
BadRequest(Request, Response);
|
||||
return;
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.warning(
|
||||
Poco::format("%s: Failed with: %s", std::string(__func__), E.displayText()));
|
||||
}
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
}
|
@@ -1,32 +0,0 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-07-21.
|
||||
//
|
||||
|
||||
#include "RESTAPI_deviceDashboardHandler.h"
|
||||
#include "Daemon.h"
|
||||
#include "Dashboard.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_deviceDashboardHandler::handleRequest(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response) {
|
||||
|
||||
if (!ContinueProcessing(Request, Response))
|
||||
return;
|
||||
|
||||
if (!IsAuthorized(Request, Response))
|
||||
return;
|
||||
|
||||
if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_GET) {
|
||||
DoGet(Request, Response);
|
||||
} else {
|
||||
BadRequest(Request, Response, "Unsupported method.");
|
||||
}
|
||||
}
|
||||
|
||||
void RESTAPI_deviceDashboardHandler::DoGet(Poco::Net::HTTPServerRequest &Request, Poco::Net::HTTPServerResponse &Response) {
|
||||
Daemon()->GetDashboard().Create();
|
||||
Poco::JSON::Object Answer;
|
||||
Daemon()->GetDashboard().Report().to_json(Answer);
|
||||
ReturnObject(Request, Answer, Response);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user