Compare commits

...

77 Commits

Author SHA1 Message Date
Dmitry Dunaev
889d98a162 [WIFI-10236] Fix: image building
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-07-26 15:12:59 +03:00
TIP Automation User
a46401bf87 Chg: update image tag in helm values to v2.5.2 2022-07-26 10:29:52 +00:00
Dmitry Dunaev
f0be8ffdc5 [WIFI-1998] Add: gracefull ingress deprecation
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-07-21 17:46:15 +03:00
Dmitry Dunaev
941680c0fd Merge pull request #35 from Telecominfraproject/fix/wifi-9174--dep-charts-2.5
[WIFI-9174] Fix: switch from deprecated bitnami charts to mirrored ones
2022-06-03 19:16:39 +03:00
Dmitry Dunaev
f2b64939a3 [WIFI-9174] Fix: switch from deprecated bitnami charts to mirrored ones
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-06-03 19:16:09 +03:00
TIP Automation User
bf7375c8f1 Chg: update image tag in helm values to v2.5.0 2022-03-30 13:48:21 +00:00
TIP Automation User
e516e60179 Chg: update image tag in helm values to v2.5.0-RC1 2022-02-11 16:02:43 +00:00
stephb9959
7036d960e5 Merge remote-tracking branch 'origin/main' 2022-02-08 22:12:48 -08:00
stephb9959
eb8a858e05 Update framework. 2022-02-08 22:12:40 -08:00
Johann Hoffmann
4527248545 Re-structure Dockerfile and use docker-image-build composite action (#26)
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-02-08 15:15:57 +01:00
stephb9959
783b7bd32e Update framework. 2022-02-04 11:45:22 -08:00
stephb9959
76c34c5b7e Update framework. 2022-02-04 09:56:22 -08:00
stephb9959
316e51a0e2 Update framework. 2022-02-02 11:02:47 -08:00
stephb9959
f2f8edd905 Merge remote-tracking branch 'origin/main' 2022-01-31 14:25:42 -08:00
stephb9959
68389ec1e8 Update framework. 2022-01-31 14:25:34 -08:00
Dmitry Dunaev
615408acff Merge pull request #25 from Telecominfraproject/feature/wifi-6837--chart-improvements
[WIFI-6837] Chg: modify readiness to make some envs optional, switch default helm service type to ClusterIP
2022-01-28 16:04:56 +03:00
Dmitry Dunaev
0a4bd59c56 [WIFI-6837] Chg: modify readiness to make some envs optional, switch default helm service type to ClusterIP
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-01-28 13:54:22 +03:00
stephb9959
479e3cc96c Update framework. 2022-01-27 10:00:18 -08:00
stephb9959
0e6ce5d6d9 Update framework. 2022-01-26 23:18:52 -08:00
stephb9959
507e8dadb5 Adding kafka logging in framework. 2022-01-23 22:52:48 -08:00
stephb9959
3e72a41686 Adding kafka logging in framework. 2022-01-23 10:25:28 -08:00
stephb9959
50050fe16d Merge remote-tracking branch 'origin/main' 2022-01-20 22:55:40 -08:00
stephb9959
3344f5bb13 Adding kafka logging in framework. 2022-01-20 22:55:33 -08:00
Johann Hoffmann
b4ab5192d3 [WIFI-5775] Run SDK tests on a PR level (#19)
* Trigger testing with Docker Compose deployment

Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>

* Switch to trigger-workflow-and-wait community Github action

Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>

* Switch to latest version

Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>

* Use trigger-workflow-and-wait composite action

Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>

* Pass versions as one JSON string

Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>

* Remove ref since PR was merged

Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-01-17 17:37:11 +01:00
Johann Hoffmann
707014d698 Adapt logging configuration to newest changes
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-01-17 11:53:17 +01:00
Dmitry Dunaev
e34874f68b Merge pull request #23 from Telecominfraproject/feature/wifi-6393--add-wait-kafka-initcontainer
[WIFI-6393] Add: initContainer to wait for Kafka to be ready
2022-01-13 12:18:09 +03:00
Dmitry Dunaev
2244e9fcab [WIFI-6393] Add: initContainer to wait for Kafka to be ready
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-01-13 12:15:05 +03:00
stephb9959
4f4fe39edc Config & framework update 2022-01-11 23:18:18 -08:00
stephb9959
7f143c6eaf Config & framework update 2022-01-10 22:45:07 -08:00
stephb9959
f2b6339470 Config & framework update 2022-01-10 14:15:31 -08:00
stephb9959
79622fd5ca Config & framework update 2022-01-10 12:27:57 -08:00
stephb9959
090c019175 Config & framework update 2022-01-10 09:07:06 -08:00
stephb9959
c32a7bd91f Config & framework update 2022-01-09 22:39:26 -08:00
stephb9959
00fb2bab4f ORM update 2022-01-09 10:04:36 -08:00
stephb9959
b4862aa11c ORM update 2022-01-08 22:17:48 -08:00
stephb9959
f476d4711b ORM update 2022-01-06 09:31:32 -08:00
stephb9959
ad436b0a7c Fixing typo in userinfo 2022-01-05 22:21:42 -08:00
stephb9959
5f0bf8b37f Moving to proper timers. 2022-01-04 15:42:33 -08:00
stephb9959
69d42a1074 Merge remote-tracking branch 'origin/main' 2022-01-04 15:14:14 -08:00
stephb9959
69f4ac6035 Moving to proper timers. 2022-01-04 15:13:59 -08:00
Dmitry Dunaev
27aa44ac30 Merge pull request #22 from Telecominfraproject/feature/wifi-6183--cli-review
[WIFI-6183] Chg: cli review and usage enhancement
2022-01-04 14:46:39 +03:00
Dmitry Dunaev
edc855063a [WIFI-6183] Chg: cli review and usage enhancement
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-01-04 14:08:31 +03:00
Johann Hoffmann
be520211bf Add curl cli script to Docker image
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-01-04 11:31:41 +01:00
stephb9959
506150cbee Merge remote-tracking branch 'origin/main' 2021-12-29 07:52:34 -08:00
stephb9959
64f941e9ac Moving to ORM. 2021-12-29 07:52:25 -08:00
Dmitry Dunaev
d30e1715fe Merge pull request #21 from Telecominfraproject/feature/wifi-4977--introduce-revisionHistoryLimit
[WIFI-4977] Add: helm add revisionHistoryLimit support
2021-12-23 16:27:00 +03:00
Dmitry Dunaev
be01b70d4c [WIFI-4977] Add: helm add revisionHistoryLimit support
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2021-12-23 16:05:49 +03:00
stephb9959
6f6d539a14 Framework update 2021-12-22 22:14:25 -08:00
stephb9959
6d1285cb77 Merge remote-tracking branch 'origin/main' 2021-12-22 22:02:40 -08:00
stephb9959
e170f23300 Framework update 2021-12-22 22:02:32 -08:00
Johann Hoffmann
d02a19d649 [WIFI-6170] Add OpenWifi Docker Compose deployment with PostgreSQL (#20)
* Add wait-for-postgres.sh wrapper script

Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>

* Copy wait-for-postgres.sh into Docker image

Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2021-12-16 17:22:20 +01:00
stephb9959
6546c14b3e Framework update 2021-12-11 23:30:55 -08:00
stephb9959
4a80848fd9 Framework update 2021-12-10 13:21:38 -08:00
stephb9959
935139067f Framework update 2021-12-07 20:41:13 -08:00
stephb9959
e3cceeab32 .git dir fix 2021-12-07 09:31:15 -08:00
stephb9959
d061e126bc Merge remote-tracking branch 'origin/main' 2021-12-07 08:53:21 -08:00
stephb9959
7612196acc Build number fix 2021-12-07 08:53:10 -08:00
Dmitry Dunaev
7c098c7925 Add: .git dir to build image to expose git hash for version
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2021-12-07 15:47:04 +03:00
stephb9959
814e9bf781 Merge remote-tracking branch 'origin/main' 2021-12-06 07:57:12 -08:00
stephb9959
44bb657c48 Adding git hash 2021-12-06 07:57:03 -08:00
Dmitry Dunaev
fab5e85f03 [WIFI-5840] Chg: failureThreshold for readiness_check up to 3
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2021-12-06 15:19:13 +03:00
stephb9959
3a7dae3855 Framework update 2021-12-05 10:55:05 -08:00
stephb9959
f9b14c7723 Framework update 2021-12-05 10:41:56 -08:00
stephb9959
53e2caa3cb Framework update 2021-12-05 10:19:17 -08:00
stephb9959
fcb67912b0 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	build
2021-12-05 10:08:51 -08:00
stephb9959
76376ec7c0 Framework update 2021-12-05 10:08:23 -08:00
stephb9959
31e3b5e606 Fixing Postgresql bool 2021-12-04 22:14:03 -08:00
stephb9959
266570f7d0 Framework update 2021-11-30 20:44:21 -08:00
stephb9959
8414e0386a Framework update 2021-11-30 10:26:24 -08:00
stephb9959
993405851a Merge remote-tracking branch 'origin/main' 2021-11-21 23:36:37 -08:00
stephb9959
7e0da73c54 Adding the ability to remove a device from the history and the data table. 2021-11-21 23:36:27 -08:00
Dmitry Dunaev
cd93e29a99 [WIFI-4860] Chg: apply enforce-jira-issue-key only to PRs to release branches 2021-11-19 16:24:15 +03:00
Dmitry Dunaev
049cb888c1 Merge pull request #18 from Telecominfraproject/feature/wifi-4860--add-ensure-jira-issue-key-workflow
[WIFI-4860] Add: enforce-jira-issue-key workflow
2021-11-19 15:50:05 +03:00
Dmitry Dunaev
0495bf88e8 [WIFI-4860] Add: enforce-jira-issue-key workflow
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2021-11-19 13:19:13 +03:00
stephb9959
95d8ef42ae Fixing DB offset/limit computation. 2021-11-17 15:52:29 -08:00
stephb9959
d057bacd9c Framework update 2021-11-17 07:54:37 -08:00
stephb9959
b87ee360e5 Framework update 2021-11-16 22:10:35 -08:00
87 changed files with 4106 additions and 2408 deletions

View File

@@ -25,41 +25,46 @@ jobs:
DOCKER_REGISTRY_URL: tip-tip-wlan-cloud-ucentral.jfrog.io DOCKER_REGISTRY_URL: tip-tip-wlan-cloud-ucentral.jfrog.io
DOCKER_REGISTRY_USERNAME: ucentral DOCKER_REGISTRY_USERNAME: ucentral
steps: steps:
- uses: actions/checkout@v2 - name: Checkout actions repo
uses: actions/checkout@v2
- name: Build Docker image
run: docker build -t wlan-cloud-owfms:${{ github.sha }} .
- name: Tag Docker image
run: |
TAGS="${{ github.sha }}"
if [[ ${GITHUB_REF} == "refs/heads/"* ]]
then
CURRENT_TAG=$(echo ${GITHUB_REF#refs/heads/} | tr '/' '-')
TAGS="$TAGS $CURRENT_TAG"
else
if [[ ${GITHUB_REF} == "refs/tags/"* ]]
then
CURRENT_TAG=$(echo ${GITHUB_REF#refs/tags/} | tr '/' '-')
TAGS="$TAGS $CURRENT_TAG"
else # PR build
CURRENT_TAG=$(echo ${GITHUB_HEAD_REF#refs/heads/} | tr '/' '-')
TAGS="$TAGS $CURRENT_TAG"
fi
fi
echo "Result tags: $TAGS"
for tag in $TAGS; do
docker tag wlan-cloud-owfms:${{ github.sha }} ${{ env.DOCKER_REGISTRY_URL }}/owfms:$tag
done
- name: Log into Docker registry
if: startsWith(github.ref, 'refs/tags/') || startsWith(github.ref, 'refs/pull/') || github.ref == 'refs/heads/main'
uses: docker/login-action@v1
with: with:
registry: ${{ env.DOCKER_REGISTRY_URL }} repository: Telecominfraproject/.github
username: ${{ env.DOCKER_REGISTRY_USERNAME }} path: github
password: ${{ secrets.DOCKER_REGISTRY_PASSWORD }}
- name: Push Docker images - name: Build and push Docker image
if: startsWith(github.ref, 'refs/tags/') || startsWith(github.ref, 'refs/pull/') || github.ref == 'refs/heads/main' uses: ./github/composite-actions/docker-image-build
with:
image_name: owfms
registry: tip-tip-wlan-cloud-ucentral.jfrog.io
registry_user: ucentral
registry_password: ${{ secrets.DOCKER_REGISTRY_PASSWORD }}
trigger-testing:
if: startsWith(github.ref, 'refs/pull/')
runs-on: ubuntu-latest
needs: docker
steps:
- name: Get base branch name and set as output
id: get_base_branch
run: | run: |
docker images | grep ${{ env.DOCKER_REGISTRY_URL }}/owfms | awk -F ' ' '{print $1":"$2}' | xargs -I {} docker push {} echo ::set-output name=branch::$(echo ${GITHUB_BASE_REF##*/})
echo ::set-output name=owgw_branch::$(echo ${GITHUB_BASE_REF##*/} | sed 's/main/master/g')
- name: Checkout actions repo
uses: actions/checkout@v2
with:
repository: Telecominfraproject/.github
path: github
- name: Trigger testing of OpenWifi Docker Compose deployment and wait for result
uses: ./github/composite-actions/trigger-workflow-and-wait
env:
BASE_BRANCH: ${{ steps.get_base_branch.outputs.branch }}
OWGW_BASE_BRANCH: ${{ steps.get_base_branch.outputs.owgw_branch }}
with:
owner: Telecominfraproject
repo: wlan-testing
workflow: ow_docker-compose.yml
token: ${{ secrets.WLAN_TESTING_PAT }}
ref: master
inputs: '{"owgw_version": "${{ env.OWGW_BASE_BRANCH }}", "owgwui_version": "${{ env.BASE_BRANCH }}", "owsec_version": "${{ env.BASE_BRANCH }}", "owfms_version": "${{ github.sha }}", "owprov_version": "main", "owprovui_version": "main"}'

View File

@@ -0,0 +1,24 @@
name: Ensure Jira issue is linked
on:
pull_request:
types: [opened, edited, reopened, synchronize]
branches:
- 'release/*'
jobs:
check_for_issue_key:
runs-on: ubuntu-latest
steps:
- name: Checkout actions repo
uses: actions/checkout@v2
with:
repository: Telecominfraproject/.github
path: github
- name: Run JIRA check
uses: ./github/composite-actions/enforce-jira-issue-key
with:
jira_base_url: ${{ secrets.TIP_JIRA_URL }}
jira_user_email: ${{ secrets.TIP_JIRA_USER_EMAIL }}
jira_api_token: ${{ secrets.TIP_JIRA_API_TOKEN }}

3
.gitignore vendored
View File

@@ -20,5 +20,4 @@ _deps
*.zip *.zip
result.json result.json
pidfile pidfile
test_scripts/curl/result.json

View File

@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.13) cmake_minimum_required(VERSION 3.13)
project(owfms VERSION 2.4.0) project(owfms VERSION 2.5.0)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 17)
@@ -15,18 +15,32 @@ if(UNIX AND NOT APPLE)
endif() endif()
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/build) if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/build)
file(READ build BUILD_NUM) file(READ ${CMAKE_CURRENT_SOURCE_DIR}/build BUILD_NUM)
if(BUILD_INCREMENT) if(BUILD_INCREMENT)
MATH(EXPR BUILD_NUM "${BUILD_NUM}+1") MATH(EXPR BUILD_NUM "${BUILD_NUM}+1")
file(WRITE build ${BUILD_NUM}) file(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/build ${BUILD_NUM})
endif() endif()
else() else()
set(BUILD_NUM 1) set(BUILD_NUM 1)
file(WRITE build ${BUILD_NUM}) file(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/build ${BUILD_NUM})
endif() endif()
find_package(Git QUIET)
if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
execute_process(COMMAND ${GIT_EXECUTABLE} describe --always --tags
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
RESULT_VARIABLE GIT_RESULT
OUTPUT_VARIABLE GIT_HASH)
if(NOT GIT_RESULT EQUAL "0")
message(FATAL_ERROR "git describe --always --tags failed with ${GIT_RESULT}")
endif()
string(REGEX REPLACE "\n$" "" GIT_HASH "${GIT_HASH}")
endif()
add_definitions(-DAWS_CUSTOM_MEMORY_MANAGEMENT)
set(BUILD_SHARED_LIBS 1) set(BUILD_SHARED_LIBS 1)
add_definitions(-DAPP_VERSION="${CMAKE_PROJECT_VERSION}" -DBUILD_NUMBER="${BUILD_NUM}" -DAWS_CUSTOM_MEMORY_MANAGEMENT) add_definitions(-DAWS_CUSTOM_MEMORY_MANAGEMENT)
set(Boost_USE_STATIC_LIBS OFF) set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON) set(Boost_USE_MULTITHREADED ON)
@@ -48,8 +62,11 @@ endif()
include_directories(/usr/local/include /usr/local/opt/openssl/include src include/kafka /usr/local/opt/mysql-client/include) include_directories(/usr/local/include /usr/local/opt/openssl/include src include/kafka /usr/local/opt/mysql-client/include)
configure_file(src/ow_version.h.in ${PROJECT_SOURCE_DIR}/src/ow_version.h @ONLY)
add_executable( owfms add_executable( owfms
build build
src/ow_version.h.in
src/framework/CountryCodes.h src/framework/CountryCodes.h
src/framework/KafkaTopics.h src/framework/KafkaTopics.h
src/framework/MicroService.h src/framework/MicroService.h
@@ -70,12 +87,7 @@ add_executable( owfms
src/RESTAPI/RESTAPI_connectedDevicesHandler.cpp src/RESTAPI/RESTAPI_connectedDevicesHandler.h src/RESTAPI/RESTAPI_connectedDevicesHandler.cpp src/RESTAPI/RESTAPI_connectedDevicesHandler.h
src/RESTAPI/RESTAPI_deviceReportHandler.cpp src/RESTAPI/RESTAPI_deviceReportHandler.h src/RESTAPI/RESTAPI_deviceReportHandler.cpp src/RESTAPI/RESTAPI_deviceReportHandler.h
src/RESTAPI/RESTAPI_connectedDeviceHandler.cpp src/RESTAPI/RESTAPI_connectedDeviceHandler.h src/RESTAPI/RESTAPI_connectedDeviceHandler.cpp src/RESTAPI/RESTAPI_connectedDeviceHandler.h
src/storage/storage_tables.cpp src/RESTAPI/RESTAPI_Routers.cpp
src/storage/storage_firmwares.cpp
src/storage/storage_firmwares.h src/storage/storage_history.cpp
src/storage/storage_history.h src/storage/storage_deviceTypes.cpp
src/storage/storage_deviceInfo.cpp src/storage/storage_deviceInfo.h
src/APIServers.cpp
src/Dashboard.cpp src/Dashboard.h src/Dashboard.cpp src/Dashboard.h
src/Daemon.cpp src/Daemon.h src/Daemon.cpp src/Daemon.h
src/StorageService.cpp src/StorageService.h src/StorageService.cpp src/StorageService.h
@@ -87,7 +99,10 @@ add_executable( owfms
src/FirmwareCache.cpp src/FirmwareCache.h src/FirmwareCache.cpp src/FirmwareCache.h
src/SDK/Prov_SDK.cpp src/SDK/Prov_SDK.h src/SDK/Prov_SDK.cpp src/SDK/Prov_SDK.h
src/AutoUpdater.cpp src/AutoUpdater.h src/SDK/GW_SDK.cpp src/SDK/GW_SDK.h src/AutoUpdater.cpp src/AutoUpdater.h src/SDK/GW_SDK.cpp src/SDK/GW_SDK.h
) src/NewCommandHandler.cpp src/NewCommandHandler.h
src/storage/orm_history.cpp src/storage/orm_history.h
src/storage/orm_firmwares.cpp src/storage/orm_firmwares.h
src/storage/orm_deviceInfo.cpp src/storage/orm_deviceInfo.h)
target_link_libraries(owfms PUBLIC target_link_libraries(owfms PUBLIC
${Poco_LIBRARIES} ${MySQL_LIBRARIES} ${Poco_LIBRARIES} ${MySQL_LIBRARIES}

View File

@@ -1,36 +1,16 @@
FROM alpine AS builder FROM alpine:3.15 AS build-base
RUN apk add --update --no-cache \ RUN apk add --update --no-cache \
openssl openssh \ make cmake g++ git \
ncurses-libs \
bash util-linux coreutils curl libcurl \
make cmake gcc g++ libstdc++ libgcc git zlib-dev \
openssl-dev boost-dev curl-dev util-linux-dev \
unixodbc-dev postgresql-dev mariadb-dev \ unixodbc-dev postgresql-dev mariadb-dev \
librdkafka-dev librdkafka-dev boost-dev openssl-dev \
zlib-dev nlohmann-json \
curl-dev
FROM build-base AS poco-build
ADD https://api.github.com/repos/stephb9959/poco/git/refs/heads/master version.json
RUN git clone https://github.com/stephb9959/poco /poco RUN git clone https://github.com/stephb9959/poco /poco
RUN git clone https://github.com/stephb9959/cppkafka /cppkafka
RUN git clone https://github.com/nlohmann/json /json
RUN git clone https://github.com/pboettch/json-schema-validator /json-schema-validator
RUN git clone --recurse-submodules https://github.com/aws/aws-sdk-cpp /aws-sdk-cpp
WORKDIR /aws-sdk-cpp
RUN mkdir cmake-build
WORKDIR cmake-build
RUN cmake .. -DBUILD_ONLY="s3" \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_FLAGS="-Wno-error=stringop-overflow -Wno-error=uninitialized" \
-DAUTORUN_UNIT_TESTS=OFF
RUN cmake --build . --config Release -j8
RUN cmake --build . --target install
WORKDIR /cppkafka
RUN mkdir cmake-build
WORKDIR cmake-build
RUN cmake ..
RUN cmake --build . --config Release -j8
RUN cmake --build . --target install
WORKDIR /poco WORKDIR /poco
RUN mkdir cmake-build RUN mkdir cmake-build
@@ -39,12 +19,22 @@ RUN cmake ..
RUN cmake --build . --config Release -j8 RUN cmake --build . --config Release -j8
RUN cmake --build . --target install RUN cmake --build . --target install
WORKDIR /json FROM build-base AS cppkafka-build
ADD https://api.github.com/repos/stephb9959/cppkafka/git/refs/heads/master version.json
RUN git clone https://github.com/stephb9959/cppkafka /cppkafka
WORKDIR /cppkafka
RUN mkdir cmake-build RUN mkdir cmake-build
WORKDIR cmake-build WORKDIR cmake-build
RUN cmake .. RUN cmake ..
RUN make RUN cmake --build . --config Release -j8
RUN make install RUN cmake --build . --target install
FROM build-base AS json-schema-validator-build
ADD https://api.github.com/repos/pboettch/json-schema-validator/git/refs/heads/master version.json
RUN git clone https://github.com/pboettch/json-schema-validator /json-schema-validator
WORKDIR /json-schema-validator WORKDIR /json-schema-validator
RUN mkdir cmake-build RUN mkdir cmake-build
@@ -53,17 +43,46 @@ RUN cmake ..
RUN make RUN make
RUN make install RUN make install
FROM build-base AS aws-sdk-cpp-build
ADD https://api.github.com/repos/aws/aws-sdk-cpp/git/refs/heads/main version.json
RUN git clone --recurse-submodules https://github.com/aws/aws-sdk-cpp /aws-sdk-cpp
WORKDIR /aws-sdk-cpp
RUN mkdir cmake-build
WORKDIR cmake-build
RUN cmake .. -DBUILD_ONLY="sns;s3" \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_FLAGS="-Wno-error=stringop-overflow -Wno-error=uninitialized" \
-DAUTORUN_UNIT_TESTS=OFF
RUN cmake --build . --config Release -j8
RUN cmake --build . --target install
FROM build-base AS owfms-build
ADD CMakeLists.txt build /owfms/ ADD CMakeLists.txt build /owfms/
ADD cmake /owfms/cmake ADD cmake /owfms/cmake
ADD src /owfms/src ADD src /owfms/src
ADD .git /owfms/.git
COPY --from=poco-build /usr/local/include /usr/local/include
COPY --from=poco-build /usr/local/lib /usr/local/lib
COPY --from=cppkafka-build /usr/local/include /usr/local/include
COPY --from=cppkafka-build /usr/local/lib /usr/local/lib
COPY --from=json-schema-validator-build /usr/local/include /usr/local/include
COPY --from=json-schema-validator-build /usr/local/lib /usr/local/lib
COPY --from=aws-sdk-cpp-build /usr/local/include /usr/local/include
COPY --from=aws-sdk-cpp-build /usr/local/lib /usr/local/lib
WORKDIR /owfms WORKDIR /owfms
RUN mkdir cmake-build RUN mkdir cmake-build
WORKDIR /owfms/cmake-build WORKDIR /owfms/cmake-build
RUN cmake .. RUN cmake .. \
-Dcrypto_LIBRARY=/usr/lib/libcrypto.so \
-DBUILD_SHARED_LIBS=ON
RUN cmake --build . --config Release -j8 RUN cmake --build . --config Release -j8
FROM alpine FROM alpine:3.15
ENV OWFMS_USER=owfms \ ENV OWFMS_USER=owfms \
OWFMS_ROOT=/owfms-data \ OWFMS_ROOT=/owfms-data \
@@ -75,20 +94,25 @@ RUN addgroup -S "$OWFMS_USER" && \
RUN mkdir /openwifi RUN mkdir /openwifi
RUN mkdir -p "$OWFMS_ROOT" "$OWFMS_CONFIG" && \ RUN mkdir -p "$OWFMS_ROOT" "$OWFMS_CONFIG" && \
chown "$OWFMS_USER": "$OWFMS_ROOT" "$OWFMS_CONFIG" chown "$OWFMS_USER": "$OWFMS_ROOT" "$OWFMS_CONFIG"
RUN apk add --update --no-cache librdkafka curl-dev mariadb-connector-c libpq unixodbc su-exec gettext ca-certificates bash jq curl
COPY --from=builder /owfms/cmake-build/owfms /openwifi/owfms RUN apk add --update --no-cache librdkafka su-exec gettext ca-certificates bash jq curl \
COPY --from=builder /cppkafka/cmake-build/src/lib/* /lib/ mariadb-connector-c libpq unixodbc postgresql-client
COPY --from=builder /poco/cmake-build/lib/* /lib/
COPY --from=builder /aws-sdk-cpp/cmake-build/aws-cpp-sdk-core/libaws-cpp-sdk-core.so /lib/ COPY readiness_check /readiness_check
COPY --from=builder /aws-sdk-cpp/cmake-build/aws-cpp-sdk-s3/libaws-cpp-sdk-s3.so /lib/ COPY test_scripts/curl/cli /cli
COPY owfms.properties.tmpl / COPY owfms.properties.tmpl /
COPY docker-entrypoint.sh / COPY docker-entrypoint.sh /
COPY wait-for-postgres.sh /
RUN wget https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentral-deploy/main/docker-compose/certs/restapi-ca.pem \ 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 -O /usr/local/share/ca-certificates/restapi-ca-selfsigned.pem
COPY readiness_check /readiness_check COPY --from=owfms-build /owfms/cmake-build/owfms /openwifi/owfms
COPY --from=cppkafka-build /cppkafka/cmake-build/src/lib/* /usr/local/lib
COPY --from=poco-build /poco/cmake-build/lib/* /usr/local/lib
COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-core/libaws-cpp-sdk-core.so /usr/local/lib
COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-s3/libaws-cpp-sdk-s3.so /usr/local/lib
COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-sns/libaws-cpp-sdk-sns.so /usr/local/lib
EXPOSE 16004 17004 16104 EXPOSE 16004 17004 16104

2
build
View File

@@ -1 +1 @@
24 36

View File

@@ -5,14 +5,14 @@ name: owfms
version: 0.1.0 version: 0.1.0
dependencies: dependencies:
- name: postgresql - name: postgresql
repository: https://charts.bitnami.com/bitnami repository: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
version: 10.9.2 version: 10.9.2
condition: postgresql.enabled condition: postgresql.enabled
- name: mysql - name: mysql
repository: https://charts.bitnami.com/bitnami repository: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
version: 8.8.3 version: 8.8.3
condition: mysql.enabled condition: mysql.enabled
- name: mariadb - name: mariadb
repository: https://charts.bitnami.com/bitnami repository: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
version: 9.4.2 version: 9.4.2
condition: mariadb.enabled condition: mariadb.enabled

View File

@@ -30,3 +30,13 @@ Create chart name and version as used by the chart label.
{{- define "owfms.chart" -}} {{- define "owfms.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}} {{- end -}}
{{- define "owfms.ingress.apiVersion" -}}
{{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1" -}}
{{- print "networking.k8s.io/v1" -}}
{{- else if .Capabilities.APIVersions.Has "networking.k8s.io/v1beta1" -}}
{{- print "networking.k8s.io/v1beta1" -}}
{{- else -}}
{{- print "extensions/v1beta1" -}}
{{- end -}}
{{- end -}}

View File

@@ -13,6 +13,7 @@ spec:
replicas: {{ .Values.replicaCount }} replicas: {{ .Values.replicaCount }}
strategy: strategy:
type: {{ .Values.strategyType }} type: {{ .Values.strategyType }}
revisionHistoryLimit: {{ .Values.revisionHistoryLimit }}
selector: selector:
matchLabels: matchLabels:
app.kubernetes.io/name: {{ include "owfms.name" . }} app.kubernetes.io/name: {{ include "owfms.name" . }}
@@ -35,6 +36,16 @@ spec:
{{- end }} {{- end }}
spec: spec:
initContainers:
- name: wait-kafka
image: "{{ .Values.images.dockerize.repository }}:{{ .Values.images.dockerize.tag }}"
imagePullPolicy: {{ .Values.images.dockerize.pullPolicy }}
args:
- -wait
- tcp://{{ index .Values.configProperties "openwifi.kafka.brokerlist" }}
- -timeout
- 600s
containers: containers:
- name: owfms - name: owfms

View File

@@ -2,7 +2,7 @@
{{- range $ingress, $ingressValue := .Values.ingresses }} {{- range $ingress, $ingressValue := .Values.ingresses }}
{{- if $ingressValue.enabled }} {{- if $ingressValue.enabled }}
--- ---
apiVersion: extensions/v1beta1 apiVersion: {{ include "owfms.ingress.apiVersion" $root }}
kind: Ingress kind: Ingress
metadata: metadata:
name: {{ include "owfms.fullname" $root }}-{{ $ingress }} name: {{ include "owfms.fullname" $root }}-{{ $ingress }}
@@ -36,9 +36,23 @@ spec:
paths: paths:
{{- range $ingressValue.paths }} {{- range $ingressValue.paths }}
- path: {{ .path }} - path: {{ .path }}
{{- if $root.Capabilities.APIVersions.Has "networking.k8s.io/v1" }}
pathType: {{ .pathType | default "ImplementationSpecific" }}
{{- end }}
backend: backend:
{{- if $root.Capabilities.APIVersions.Has "networking.k8s.io/v1" }}
service:
name: {{ include "owfms.fullname" $root }}-{{ .serviceName }}
port:
{{- if kindIs "string" .servicePort }}
name: {{ .servicePort }}
{{- else }}
number: {{ .servicePort }}
{{- end }}
{{- else }}
serviceName: {{ include "owfms.fullname" $root }}-{{ .serviceName }} serviceName: {{ include "owfms.fullname" $root }}-{{ .serviceName }}
servicePort: {{ .servicePort }} servicePort: {{ .servicePort }}
{{- end }}
{{- end }} {{- end }}
{{- end }} {{- end }}

View File

@@ -1,6 +1,7 @@
# System # System
replicaCount: 1 replicaCount: 1
strategyType: Recreate strategyType: Recreate
revisionHistoryLimit: 2
nameOverride: "" nameOverride: ""
fullnameOverride: "" fullnameOverride: ""
@@ -8,16 +9,20 @@ fullnameOverride: ""
images: images:
owfms: owfms:
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owfms repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owfms
tag: main tag: v2.5.2
pullPolicy: Always pullPolicy: Always
# regcred: # regcred:
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io # registry: tip-tip-wlan-cloud-ucentral.jfrog.io
# username: username # username: username
# password: password # password: password
dockerize:
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/dockerize
tag: 0.16.0
pullPolicy: IfNotPresent
services: services:
owfms: owfms:
type: LoadBalancer type: ClusterIP
ports: ports:
restapi: restapi:
servicePort: 16004 servicePort: 16004
@@ -38,8 +43,6 @@ checks:
exec: exec:
command: command:
- /readiness_check - /readiness_check
failureThreshold: 1
ingresses: ingresses:
restapi: restapi:
@@ -51,6 +54,7 @@ ingresses:
- restapi.chart-example.local - restapi.chart-example.local
paths: paths:
- path: / - path: /
pathType: ImplementationSpecific
serviceName: owfms serviceName: owfms
servicePort: restapi servicePort: restapi
@@ -180,22 +184,9 @@ configProperties:
openwifi.system.uri.ui: https://localhost openwifi.system.uri.ui: https://localhost
openwifi.system.commandchannel: /tmp/app_owfms openwifi.system.commandchannel: /tmp/app_owfms
# Logging # Logging
logging.formatters.f1.class: PatternFormatter logging.type: console
logging.formatters.f1.pattern: "%Y-%m-%d %H:%M:%S %s: [%p] %t" logging.path: $OWFMS_ROOT/logs
logging.formatters.f1.times: UTC logging.level: debug
logging.channels.c1.class: ConsoleChannel
logging.channels.c1.formatter: f1
logging.channels.c2.class: FileChannel
logging.channels.c2.path: /tmp/log_owfms
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"
logging.loggers.root.channel: c1
logging.loggers.root.level: debug
# -> Secret part # -> Secret part
# REST API # REST API

View File

@@ -2,7 +2,7 @@ openapi: 3.0.1
info: info:
title: uCentral Firmware Service API title: uCentral Firmware Service API
description: A process to manage new uCentral firmware distribution. description: A process to manage new uCentral firmware distribution.
version: 2.0.0 version: 2.5.0
license: license:
name: BSD3 name: BSD3
url: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE url: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
@@ -60,6 +60,11 @@ components:
- 6 # INTERNAL_ERROR, - 6 # INTERNAL_ERROR,
- 7 # ACCESS_DENIED, - 7 # ACCESS_DENIED,
- 8 # INVALID_TOKEN - 8 # INVALID_TOKEN
- 9 # EXPIRED_TOKEN
- 10 # RATE_LIMIT_EXCEEDED
- 11 # BAD_MFA_TRANSACTION
- 12 # MFA_FAILURE
- 13 # SECURITY_SERVICE_UNREACHABLE
ErrorDetails: ErrorDetails:
type: string type: string
ErrorDescription: ErrorDescription:

View File

@@ -35,6 +35,7 @@ openwifi.system.uri.private = https://localhost:17004
openwifi.system.uri.public = https://ucentral.dpaas.arilia.com:16004 openwifi.system.uri.public = https://ucentral.dpaas.arilia.com:16004
openwifi.system.commandchannel = /tmp/app.owfms openwifi.system.commandchannel = /tmp/app.owfms
openwifi.system.uri.ui = ucentral-ui.arilia.com openwifi.system.uri.ui = ucentral-ui.arilia.com
firmwaredb.refresh = 1800 firmwaredb.refresh = 1800
firmwaredb.maxage = 90 firmwaredb.maxage = 90
@@ -108,37 +109,9 @@ storage.type.mysql.connectiontimeout = 60
# Logging: please leave as is for now. # Logging: please leave as is for now.
# #
######################################################################## ########################################################################
logging.formatters.f1.class = PatternFormatter logging.type = file
logging.formatters.f1.pattern = %s: [%p] %t logging.path = $OWFMS_ROOT/logs
logging.formatters.f1.times = UTC logging.level = debug
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 = $OWFMS_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 = c2
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

View File

@@ -104,37 +104,6 @@ storage.type.mysql.connectiontimeout = 60
# Logging: please leave as is for now. # Logging: please leave as is for now.
# #
######################################################################## ########################################################################
logging.formatters.f1.class = PatternFormatter logging.type = console
logging.formatters.f1.pattern = %Y-%m-%d %H:%M:%S %s: [%p] %t logging.path = $OWFMS_ROOT/logs
logging.formatters.f1.times = UTC logging.level = debug
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 = $OWFMS_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

View File

@@ -13,29 +13,29 @@ then
exit 1 exit 1
fi 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" ]] if [[ "${READINESS_METHOD}" == "systeminfo" ]]
then then
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
# Get OAuth token from OWSEC and cache it or use cached one # Get OAuth token from OWSEC and cache it or use cached one
payload="{ \"userId\" : \"$OWSEC_USERNAME\" , \"password\" : \"$OWSEC_PASSWORD\" }" payload="{ \"userId\" : \"$OWSEC_USERNAME\" , \"password\" : \"$OWSEC_PASSWORD\" }"
if [[ -f "/tmp/token" ]] if [[ -f "/tmp/token" ]]

View File

@@ -11,19 +11,22 @@
namespace OpenWifi { namespace OpenWifi {
int AutoUpdater::Start() { int AutoUpdater::Start() {
Running_ = true;
AutoUpdaterFrequency_ = MicroService::instance().ConfigGetInt("autoupdater.frequency",600);
AutoUpdaterEnabled_ = MicroService::instance().ConfigGetBool("autoupdater.enabled", false); AutoUpdaterEnabled_ = MicroService::instance().ConfigGetBool("autoupdater.enabled", false);
if(AutoUpdaterEnabled_) if(AutoUpdaterEnabled_) {
Thr_.start(*this); Running_ = false;
AutoUpdaterFrequency_ = MicroService::instance().ConfigGetInt("autoupdater.frequency",600);
AutoUpdaterCallBack_ = std::make_unique<Poco::TimerCallback<AutoUpdater>>(*this, &AutoUpdater::onTimer);
Timer_.setStartInterval(5 * 60 * 1000); // first run in 5 minutes
Timer_.setPeriodicInterval(AutoUpdaterFrequency_ * 1000);
Timer_.start(*AutoUpdaterCallBack_);
}
return 0; return 0;
} }
void AutoUpdater::Stop() { void AutoUpdater::Stop() {
Running_ = false; Running_ = false;
if(AutoUpdaterEnabled_) { if(AutoUpdaterEnabled_) {
Thr_.wakeUp(); Timer_.stop();
Thr_.join();
} }
} }
@@ -34,71 +37,67 @@ namespace OpenWifi {
Queue_.emplace_back(std::make_pair(std::move(serialNumber),std::move(DeviceType))); Queue_.emplace_back(std::make_pair(std::move(serialNumber),std::move(DeviceType)));
} }
void AutoUpdater::run() { void AutoUpdater::onTimer(Poco::Timer & timer) {
while(Running_) { Running_ = true;
Poco::Thread::trySleep(2000); std::unique_lock L(Mutex_);
if(!Running_) while(!Queue_.empty() && Running_) {
break; auto Entry = Queue_.front();
std::unique_lock L(Mutex_); Queue_.pop_front();
while(!Queue_.empty() && Running_) { try {
auto Entry = Queue_.front(); Logger().debug(Poco::format("Preparing to upgrade %s",Entry.first));
Queue_.pop_front(); auto CacheEntry = Cache_.find(Entry.first);
try { uint64_t Now = std::time(nullptr);
Logger_.debug(Poco::format("Preparing to upgrade %s",Entry.first)); std::string firmwareUpgrade;
auto CacheEntry = Cache_.find(Entry.first); if(CacheEntry == Cache_.end() || (CacheEntry->second.LastCheck-Now)>300) {
uint64_t Now = std::time(nullptr); // get the firmware settings for that device.
std::string firmwareUpgrade; SerialCache C;
C.LastCheck = Now;
bool firmwareRCOnly; bool firmwareRCOnly;
if(CacheEntry == Cache_.end() || (CacheEntry->second.LastCheck-Now)>300) { if(OpenWifi::SDK::Prov::GetFirmwareOptions(Entry.first, firmwareUpgrade, firmwareRCOnly)) {
// get the firmware settings for that device. Logger().debug(Poco::format("Found firmware options for %s",Entry.first));
SerialCache C; C.firmwareRCOnly = firmwareRCOnly;
C.LastCheck = Now; C.firmwareUpgrade = firmwareUpgrade;
if(OpenWifi::SDK::Prov::GetFirmwareOptions(Entry.first, firmwareUpgrade, firmwareRCOnly)) {
Logger_.debug(Poco::format("Found firmware options for %s",Entry.first));
C.firmwareRCOnly = firmwareRCOnly;
C.firmwareUpgrade = firmwareUpgrade;
} else {
Logger_.debug(Poco::format("Found no firmware options for %s",Entry.first));
C.firmwareRCOnly = firmwareRCOnly;
C.firmwareUpgrade = firmwareUpgrade;
}
Cache_[Entry.first] = C;
} else { } else {
Logger().debug(Poco::format("Found no firmware options for %s",Entry.first));
C.firmwareRCOnly = firmwareRCOnly;
C.firmwareUpgrade = firmwareUpgrade;
} }
Cache_[Entry.first] = C;
} else {
if(firmwareUpgrade=="no") {
Logger_.information(Poco::format("Device %s not upgradable. Provisioning service settings.",Entry.first));
continue;
}
LatestFirmwareCacheEntry fwEntry;
FMSObjects::Firmware fwDetails;
auto LF = LatestFirmwareCache()->FindLatestFirmware(Entry.second, fwEntry );
if(LF) {
if(StorageService()->GetFirmware(fwEntry.Id,fwDetails)) {
// send the command to upgrade this device...
Logger_.information(Poco::format("Upgrading %s to version %s", Entry.first, fwEntry.Revision));
if(OpenWifi::SDK::GW::SendFirmwareUpgradeCommand(Entry.first,fwDetails.uri)) {
Logger_.information(Poco::format("Upgrade command sent for %s",Entry.first));
} else {
Logger_.information(Poco::format("Upgrade command not sent for %s",Entry.first));
}
} else {
Logger_.information(Poco::format("Firmware for device %s (%s) cannot be found.", Entry.first, Entry.second ));
}
} else {
Logger_.information(Poco::format("Firmware for device %s (%s) cannot be found.", Entry.first, Entry.second ));
}
} catch (...) {
Logger_.information(Poco::format("Exception during auto update for device %s.", Entry.first ));
} }
if(firmwareUpgrade=="no") {
Logger().information(Poco::format("Device %s not upgradable. Provisioning service settings.",Entry.first));
continue;
}
LatestFirmwareCacheEntry fwEntry;
FMSObjects::Firmware fwDetails;
auto LF = LatestFirmwareCache()->FindLatestFirmware(Entry.second, fwEntry );
if(LF) {
if(StorageService()->FirmwaresDB().GetFirmware(fwEntry.Id,fwDetails)) {
// send the command to upgrade this device...
Logger().information(Poco::format("Upgrading %s to version %s", Entry.first, fwEntry.Revision));
if(OpenWifi::SDK::GW::SendFirmwareUpgradeCommand(Entry.first,fwDetails.uri)) {
Logger().information(Poco::format("Upgrade command sent for %s",Entry.first));
} else {
Logger().information(Poco::format("Upgrade command not sent for %s",Entry.first));
}
} else {
Logger().information(Poco::format("Firmware for device %s (%s) cannot be found.", Entry.first, Entry.second ));
}
} else {
Logger().information(Poco::format("Firmware for device %s (%s) cannot be found.", Entry.first, Entry.second ));
}
} catch (...) {
Logger().information(Poco::format("Exception during auto update for device %s.", Entry.first ));
} }
} }
} }
void AutoUpdater::reinitialize(Poco::Util::Application &self) { void AutoUpdater::reinitialize(Poco::Util::Application &self) {
Logger_.information("Reinitializing."); Logger().information("Reinitializing.");
Reset(); Reset();
} }
} }

View File

@@ -8,9 +8,11 @@
#include "framework/MicroService.h" #include "framework/MicroService.h"
#include <deque> #include <deque>
#include "Poco/Util/Application.h" #include "Poco/Util/Application.h"
#include "Poco/Timer.h"
namespace OpenWifi { namespace OpenWifi {
class AutoUpdater : public SubSystemServer, Poco::Runnable {
class AutoUpdater : public SubSystemServer { // };, Poco::Runnable {
public: public:
struct SerialCache { struct SerialCache {
@@ -19,14 +21,13 @@ class AutoUpdater : public SubSystemServer, Poco::Runnable {
bool firmwareRCOnly=false; bool firmwareRCOnly=false;
}; };
static AutoUpdater *instance() { static auto instance() {
static AutoUpdater *instance_ = new AutoUpdater; static auto instance_ = new AutoUpdater;
return instance_; return instance_;
} }
int Start() override; int Start() override;
void Stop() override; void Stop() override;
void run() final;
void ToBeUpgraded(std::string serialNumber, std::string DeviceType); void ToBeUpgraded(std::string serialNumber, std::string DeviceType);
inline void Reset() { inline void Reset() {
std::lock_guard G(Mutex_); std::lock_guard G(Mutex_);
@@ -34,21 +35,24 @@ class AutoUpdater : public SubSystemServer, Poco::Runnable {
Queue_.clear(); Queue_.clear();
} }
void reinitialize(Poco::Util::Application &self) final; void reinitialize(Poco::Util::Application &self) final;
void onTimer(Poco::Timer & timer);
private: private:
std::atomic_bool Running_=false; std::atomic_bool Running_=false;
Poco::Thread Thr_; std::map<std::string,SerialCache> Cache_;
std::map<std::string,SerialCache> Cache_; std::deque<std::pair<std::string,std::string>> Queue_;
std::deque<std::pair<std::string,std::string>> Queue_; uint64_t AutoUpdaterFrequency_=600;
uint64_t AutoUpdaterFrequency_=600; bool AutoUpdaterEnabled_=true;
bool AutoUpdaterEnabled_=true; Poco::Timer Timer_;
std::unique_ptr<Poco::TimerCallback<AutoUpdater>> AutoUpdaterCallBack_;
explicit AutoUpdater() noexcept: explicit AutoUpdater() noexcept:
SubSystemServer("AutoUpdater", "AUTO-UPDATER", "autoupdater") SubSystemServer("AutoUpdater", "AUTO-UPDATER", "autoupdater")
{ {
} }
}; };
inline AutoUpdater * AutoUpdater() { return AutoUpdater::instance(); } inline auto AutoUpdater() { return AutoUpdater::instance(); }
} }
#endif //OWFMS_AUTOUPDATER_H #endif //OWFMS_AUTOUPDATER_H

View File

@@ -17,6 +17,7 @@
#include "DeviceCache.h" #include "DeviceCache.h"
#include "FirmwareCache.h" #include "FirmwareCache.h"
#include "AutoUpdater.h" #include "AutoUpdater.h"
#include "NewCommandHandler.h"
namespace OpenWifi { namespace OpenWifi {
class Daemon *Daemon::instance_ = nullptr; class Daemon *Daemon::instance_ = nullptr;
@@ -35,7 +36,8 @@ namespace OpenWifi {
DeviceCache(), DeviceCache(),
NewConnectionHandler(), NewConnectionHandler(),
ManifestCreator(), ManifestCreator(),
AutoUpdater() AutoUpdater(),
NewCommandHandler()
}); });
} }
return instance_; return instance_;

View File

@@ -11,7 +11,7 @@ namespace OpenWifi {
if(LastRun_==0 || (Now-LastRun_)>120) { if(LastRun_==0 || (Now-LastRun_)>120) {
DB_.reset(); DB_.reset();
StorageService()->GenerateDeviceReport(DB_); StorageService()->DevicesDB().GenerateDeviceReport(DB_);
LastRun_ = Now; LastRun_ = Now;
} }
} }

View File

@@ -19,8 +19,8 @@ namespace OpenWifi {
class DeviceCache : public SubSystemServer { class DeviceCache : public SubSystemServer {
public: public:
static DeviceCache *instance() { static auto instance() {
static DeviceCache *instance_ = new DeviceCache; static auto instance_ = new DeviceCache;
return instance_; return instance_;
} }
@@ -40,7 +40,7 @@ namespace OpenWifi {
} }
}; };
inline DeviceCache * DeviceCache() { return DeviceCache::instance(); } inline auto DeviceCache() { return DeviceCache::instance(); }
} }

View File

@@ -17,8 +17,8 @@ namespace OpenWifi {
class FirmwareCache: public SubSystemServer { class FirmwareCache: public SubSystemServer {
public: public:
static FirmwareCache *instance() { static auto instance() {
static FirmwareCache *instance_= new FirmwareCache; static auto instance_= new FirmwareCache;
return instance_; return instance_;
} }
@@ -38,7 +38,7 @@ namespace OpenWifi {
} }
}; };
inline FirmwareCache * FirmwareCache() { return FirmwareCache::instance(); } inline auto FirmwareCache() { return FirmwareCache::instance(); }
} }

View File

@@ -8,7 +8,7 @@
namespace OpenWifi { namespace OpenWifi {
int LatestFirmwareCache::Start() { int LatestFirmwareCache::Start() {
StorageService()->PopulateLatestFirmwareCache(); StorageService()->FirmwaresDB().PopulateLatestFirmwareCache();
return 0; return 0;
} }

View File

@@ -24,8 +24,8 @@ namespace OpenWifi {
class LatestFirmwareCache : public SubSystemServer { class LatestFirmwareCache : public SubSystemServer {
public: public:
static LatestFirmwareCache *instance() { static auto instance() {
static LatestFirmwareCache *instance_ = new LatestFirmwareCache; static auto instance_ = new LatestFirmwareCache;
return instance_; return instance_;
} }
@@ -49,7 +49,7 @@ namespace OpenWifi {
} }
}; };
inline LatestFirmwareCache * LatestFirmwareCache() { return LatestFirmwareCache::instance(); } inline auto LatestFirmwareCache() { return LatestFirmwareCache::instance(); }
} }

View File

@@ -16,25 +16,14 @@
namespace OpenWifi { namespace OpenWifi {
void ManifestCreator::run() { void ManifestCreator::onTimer(Poco::Timer &timer) {
Running_ = true; Logger().information("Performing DB refresh");
bool FirstRun = true; S3BucketContent BucketList;
StorageService()->FirmwaresDB().RemoveOldFirmware();
while(Running_) { ReadBucket(BucketList);
Poco::Thread::trySleep(FirstRun ? 10000 : DBRefresh_*1000); Logger().information(Poco::format("Found %Lu firmware entries in S3 repository.",(uint64_t)BucketList.size()));
if(!Running_) ComputeManifest(BucketList);
break; AddManifestToDB(BucketList);
FirstRun = false;
Logger_.information("Performing DB refresh");
S3BucketContent BucketList;
StorageService()->RemoveOldFirmware();
ReadBucket(BucketList);
if(!Running_)
break;
Logger_.information(Poco::format("Found %Lu firmware entries in S3 repository.",(uint64_t)BucketList.size()));
ComputeManifest(BucketList);
AddManifestToDB(BucketList);
}
} }
bool ManifestCreator::ComputeManifest(S3BucketContent &BucketContent) { bool ManifestCreator::ComputeManifest(S3BucketContent &BucketContent) {
@@ -59,7 +48,7 @@ namespace OpenWifi {
Entry.Image = ParsedContent->get("image").toString(); Entry.Image = ParsedContent->get("image").toString();
auto FullNme = Name + "-upgrade.bin"; auto FullNme = Name + "-upgrade.bin";
if(FullNme!=Entry.Image) { if(FullNme!=Entry.Image) {
Logger_.error(Poco::format("MANIFEST(%s): Image name does not match manifest name (%s).",Name,Entry.Image)); Logger().error(Poco::format("MANIFEST(%s): Image name does not match manifest name (%s).",Name,Entry.Image));
Entry.Valid = false; Entry.Valid = false;
BadFormat++; BadFormat++;
continue; continue;
@@ -71,19 +60,19 @@ namespace OpenWifi {
Entry.Valid = false; Entry.Valid = false;
} }
} else { } else {
Logger_.error(Poco::format("MANIFEST(%s): Entry does not have a valid JSON manifest.",Name)); Logger().error(Poco::format("MANIFEST(%s): Entry does not have a valid JSON manifest.",Name));
MissingJson++; MissingJson++;
Entry.Valid = false; Entry.Valid = false;
} }
} catch (const Poco::Exception &E ) { } catch (const Poco::Exception &E ) {
Logger_.log(E); Logger().log(E);
} }
} }
Logger_.information(Poco::format("Accepted %Lu firmwares.", Accepted)); Logger().information(Poco::format("Accepted %Lu firmwares.", Accepted));
Logger_.information(Poco::format("Rejected %Lu too old firmwares.", Rejected)); Logger().information(Poco::format("Rejected %Lu too old firmwares.", Rejected));
Logger_.information(Poco::format("Rejected %Lu bad JSON.", BadFormat)); Logger().information(Poco::format("Rejected %Lu bad JSON.", BadFormat));
Logger_.information(Poco::format("Rejected %Lu missing JSON.", MissingJson)); Logger().information(Poco::format("Rejected %Lu missing JSON.", MissingJson));
return true; return true;
} }
@@ -98,7 +87,7 @@ namespace OpenWifi {
if(BucketEntry.URI.find("-staging-")!=std::string::npos) if(BucketEntry.URI.find("-staging-")!=std::string::npos)
continue; continue;
if(BucketEntry.Valid && !StorageService()->GetFirmwareByName(R,BucketEntry.Compatible,F)) { if(BucketEntry.Valid && !StorageService()->FirmwaresDB().GetFirmwareByName(R,BucketEntry.Compatible,F)) {
F.id = MicroService::instance().CreateUUID(); F.id = MicroService::instance().CreateUUID();
F.release = Release; F.release = Release;
F.size = BucketEntry.S3Size; F.size = BucketEntry.S3Size;
@@ -108,8 +97,8 @@ namespace OpenWifi {
F.uri = BucketEntry.URI; F.uri = BucketEntry.URI;
F.revision = BucketEntry.Revision; F.revision = BucketEntry.Revision;
F.deviceType = BucketEntry.Compatible; F.deviceType = BucketEntry.Compatible;
if(StorageService()->AddFirmware(F)) { if(StorageService()->FirmwaresDB().AddFirmware(F)) {
Logger_.information(Poco::format("Adding firmware '%s'",Release)); Logger().information(Poco::format("Adding firmware '%s'",Release));
} else { } else {
} }
} }
@@ -118,6 +107,7 @@ namespace OpenWifi {
} }
int ManifestCreator::Start() { int ManifestCreator::Start() {
Running_ = true;
S3BucketName_ = MicroService::instance().ConfigGetString("s3.bucketname"); S3BucketName_ = MicroService::instance().ConfigGetString("s3.bucketname");
S3Region_ = MicroService::instance().ConfigGetString("s3.region"); S3Region_ = MicroService::instance().ConfigGetString("s3.region");
S3Secret_ = MicroService::instance().ConfigGetString("s3.secret"); S3Secret_ = MicroService::instance().ConfigGetString("s3.secret");
@@ -135,23 +125,21 @@ namespace OpenWifi {
AwsCreds_.SetAWSAccessKeyId(S3Key_); AwsCreds_.SetAWSAccessKeyId(S3Key_);
AwsCreds_.SetAWSSecretKey(S3Secret_); AwsCreds_.SetAWSSecretKey(S3Secret_);
Worker_.start(*this); ManifestCreatorCallBack_ = std::make_unique<Poco::TimerCallback<ManifestCreator>>(*this, &ManifestCreator::onTimer);
Timer_.setStartInterval(5 * 60 * 1000); // first run in 5 minutes
Timer_.setPeriodicInterval(DBRefresh_ * 1000);
Timer_.start(*ManifestCreatorCallBack_);
return 0; return 0;
} }
void ManifestCreator::Stop() { void ManifestCreator::Stop() {
if(Running_) { if(Running_) {
Running_ = false; Running_ = false;
Worker_.wakeUp(); Timer_.stop();
Worker_.join();
} }
} }
bool ManifestCreator::Update() {
Worker_.wakeUp();
return true;
}
void ManifestCreator::CloseBucket() { void ManifestCreator::CloseBucket() {
} }
@@ -196,7 +184,7 @@ namespace OpenWifi {
while(!isDone) { while(!isDone) {
Outcome = S3Client.ListObjectsV2(Request); Outcome = S3Client.ListObjectsV2(Request);
if(!Outcome.IsSuccess()) { if(!Outcome.IsSuccess()) {
Logger_.error(Poco::format("Error while doing ListObjectsV2: %s, %s", Logger().error(Poco::format("Error while doing ListObjectsV2: %s, %s",
std::string{Outcome.GetError().GetExceptionName()}, std::string{Outcome.GetError().GetExceptionName()},
std::string{Outcome.GetError().GetMessage()})); std::string{Outcome.GetError().GetMessage()}));
return false; return false;
@@ -280,7 +268,7 @@ namespace OpenWifi {
// std::cout << "Count:" << Count << " Runs:" << Runs << std::endl; // std::cout << "Count:" << Count << " Runs:" << Runs << std::endl;
if(!Outcome.IsSuccess()) { if(!Outcome.IsSuccess()) {
Logger_.error(Poco::format("Error while doing ListObjectsV2: %s, %s", Logger().error(Poco::format("Error while doing ListObjectsV2: %s, %s",
std::string{Outcome.GetError().GetExceptionName()}, std::string{Outcome.GetError().GetExceptionName()},
std::string{Outcome.GetError().GetMessage()})); std::string{Outcome.GetError().GetMessage()}));
return false; return false;

View File

@@ -10,6 +10,7 @@
#include <aws/core/auth/AWSCredentials.h> #include <aws/core/auth/AWSCredentials.h>
#include "framework/MicroService.h" #include "framework/MicroService.h"
#include "Poco/Timer.h"
namespace OpenWifi { namespace OpenWifi {
@@ -28,17 +29,15 @@ namespace OpenWifi {
}; };
typedef std::map<const std::string, S3BucketEntry> S3BucketContent; typedef std::map<const std::string, S3BucketEntry> S3BucketContent;
class ManifestCreator : public SubSystemServer, Poco::Runnable { class ManifestCreator : public SubSystemServer {
public: public:
static ManifestCreator *instance() { static auto instance() {
static ManifestCreator *instance_ = new ManifestCreator; static auto instance_ = new ManifestCreator;
return instance_; return instance_;
} }
void run() override;
int Start() override; int Start() override;
void Stop() override; void Stop() override;
bool Update();
bool ComputeManifest(S3BucketContent & BucketContent); bool ComputeManifest(S3BucketContent & BucketContent);
bool AddManifestToDB(S3BucketContent & BucketContent); bool AddManifestToDB(S3BucketContent & BucketContent);
@@ -48,10 +47,9 @@ namespace OpenWifi {
void CloseBucket(); void CloseBucket();
void Print(const S3BucketContent &B); void Print(const S3BucketContent &B);
uint64_t MaxAge() const { return MaxAge_; } uint64_t MaxAge() const { return MaxAge_; }
void onTimer(Poco::Timer & timer);
private: private:
static ManifestCreator *instance_;
Poco::Thread Worker_;
std::atomic_bool Running_ = false; std::atomic_bool Running_ = false;
Aws::String S3BucketName_; Aws::String S3BucketName_;
Aws::String S3Region_; Aws::String S3Region_;
@@ -62,13 +60,15 @@ namespace OpenWifi {
Aws::Auth::AWSCredentials AwsCreds_; Aws::Auth::AWSCredentials AwsCreds_;
uint64_t DBRefresh_ = 30 * 60; uint64_t DBRefresh_ = 30 * 60;
uint64_t MaxAge_ = 0 ; uint64_t MaxAge_ = 0 ;
Poco::Timer Timer_;
std::unique_ptr<Poco::TimerCallback<ManifestCreator>> ManifestCreatorCallBack_;
ManifestCreator() noexcept: ManifestCreator() noexcept:
SubSystemServer("ManifestCreator", "MANIFEST-MGR", "manifestcreator") { SubSystemServer("ManifestCreator", "MANIFEST-MGR", "manifestcreator") {
} }
}; };
inline ManifestCreator * ManifestCreator() { return ManifestCreator::instance(); }; inline auto ManifestCreator() { return ManifestCreator::instance(); };
} }

86
src/NewCommandHandler.cpp Normal file
View File

@@ -0,0 +1,86 @@
//
// Created by stephane bourque on 2021-11-21.
//
#include "NewCommandHandler.h"
#include "StorageService.h"
namespace OpenWifi {
void NewCommandHandler::run() {
Running_ = true ;
while(Running_) {
Poco::Thread::trySleep(2000);
if(!Running_)
break;
while(!NewCommands_.empty()) {
if(!Running_)
break;
Types::StringPair S;
{
std::lock_guard G(Mutex_);
S = NewCommands_.front();
NewCommands_.pop();
}
try {
auto SerialNumber = S.first;
auto M = nlohmann::json::parse(S.second);
std::string EndPoint;
if(M.contains(uCentralProtocol::SYSTEM)) {
auto SystemObj = M[uCentralProtocol::SYSTEM];
if(SystemObj.contains(uCentralProtocol::HOST))
EndPoint = SystemObj[uCentralProtocol::HOST];
}
if(M.contains(uCentralProtocol::PAYLOAD)) {
auto PayloadSection = M[uCentralProtocol::PAYLOAD];
if(PayloadSection.contains("command")) {
auto Command = PayloadSection["command"];
if(Command=="delete_device") {
auto pSerialNumber = PayloadSection["payload"]["serialNumber"];
if(pSerialNumber==SerialNumber) {
Logger().debug(Poco::format("Removing device '%s' from upgrade history.",SerialNumber));
StorageService()->HistoryDB().DeleteHistory(SerialNumber);
Logger().debug(Poco::format("Removing device '%s' from device table.",SerialNumber));
StorageService()->DevicesDB().DeleteDevice(SerialNumber);
}
}
}
}
} catch (const Poco::Exception &E) {
Logger().log(E);
}
}
}
};
int NewCommandHandler::Start() {
Types::TopicNotifyFunction F = [this](std::string s1,std::string s2) { this->CommandReceived(s1,s2); };
WatcherId_ = KafkaManager()->RegisterTopicWatcher(KafkaTopics::COMMAND, F);
Worker_.start(*this);
return 0;
};
void NewCommandHandler::Stop() {
KafkaManager()->UnregisterTopicWatcher(KafkaTopics::COMMAND, WatcherId_);
Running_ = false;
Worker_.wakeUp();
Worker_.join();
};
bool NewCommandHandler::Update() {
Worker_.wakeUp();
return true;
}
void NewCommandHandler::CommandReceived( const std::string & Key, const std::string & Message) {
std::lock_guard G(Mutex_);
NewCommands_.push(std::make_pair(Key,Message));
}
}

41
src/NewCommandHandler.h Normal file
View File

@@ -0,0 +1,41 @@
//
// Created by stephane bourque on 2021-11-21.
//
#ifndef OWFMS_NEWCOMMANDHANDLER_H
#define OWFMS_NEWCOMMANDHANDLER_H
#include "framework/MicroService.h"
#include "framework/OpenWifiTypes.h"
namespace OpenWifi {
class NewCommandHandler : public SubSystemServer, Poco::Runnable {
public:
static auto instance() {
static auto instance_ = new NewCommandHandler;
return instance_;
}
void run() override;
int Start() override;
void Stop() override;
bool Update();
void CommandReceived( const std::string & Key, const std::string & Message);
private:
Poco::Thread Worker_;
std::atomic_bool Running_ = false;
int WatcherId_=0;
Types::StringPairQueue NewCommands_;
NewCommandHandler() noexcept:
SubSystemServer("NewCommandHandler", "NEWCOM-MGR", "commanmdhandler") {
}
};
inline auto NewCommandHandler() { return NewCommandHandler::instance(); };
}
#endif //OWFMS_NEWCOMMANDHANDLER_H

View File

@@ -64,15 +64,15 @@ namespace OpenWifi {
auto Revision = Storage::TrimRevision(PayloadObj->get(uCentralProtocol::FIRMWARE).toString()); auto Revision = Storage::TrimRevision(PayloadObj->get(uCentralProtocol::FIRMWARE).toString());
// std::cout << "ConnectionEvent: SerialNumber: " << SerialNumber << " DeviceType: " << DeviceType << " Revision:" << Revision << std::endl; // std::cout << "ConnectionEvent: SerialNumber: " << SerialNumber << " DeviceType: " << DeviceType << " Revision:" << Revision << std::endl;
FMSObjects::FirmwareAgeDetails FA; FMSObjects::FirmwareAgeDetails FA;
if(StorageService()->ComputeFirmwareAge(DeviceType, Revision, FA)) { if(StorageService()->FirmwaresDB().ComputeFirmwareAge(DeviceType, Revision, FA)) {
StorageService()->SetDeviceRevision(SerialNumber, Revision, DeviceType, EndPoint); StorageService()->DevicesDB().SetDeviceRevision(SerialNumber, Revision, DeviceType, EndPoint);
if(FA.age) if(FA.age)
Logger_.information(Poco::format("Device %s connection. Firmware is %s older than latest.",SerialNumber, Utils::SecondsToNiceText(FA.age))); Logger().information(Poco::format("Device %s connection. Firmware is %s older than latest.",SerialNumber, Utils::SecondsToNiceText(FA.age)));
else else
Logger_.information(Poco::format("Device %s connection. Device firmware is up to date.",SerialNumber)); Logger().information(Poco::format("Device %s connection. Device firmware is up to date.",SerialNumber));
} }
else { else {
Logger_.information(Poco::format("Device %s connection. Firmware age cannot be determined",SerialNumber)); Logger().information(Poco::format("Device %s connection. Firmware age cannot be determined",SerialNumber));
} }
if(!LatestFirmwareCache()->IsLatest(DeviceType, Revision)) { if(!LatestFirmwareCache()->IsLatest(DeviceType, Revision)) {
@@ -86,7 +86,7 @@ namespace OpenWifi {
if(DisconnectMessage->has(uCentralProtocol::SERIALNUMBER) && DisconnectMessage->has(uCentralProtocol::TIMESTAMP)) { if(DisconnectMessage->has(uCentralProtocol::SERIALNUMBER) && DisconnectMessage->has(uCentralProtocol::TIMESTAMP)) {
auto SNum = DisconnectMessage->get(uCentralProtocol::SERIALNUMBER).toString(); auto SNum = DisconnectMessage->get(uCentralProtocol::SERIALNUMBER).toString();
auto Timestamp = DisconnectMessage->get(uCentralProtocol::TIMESTAMP); auto Timestamp = DisconnectMessage->get(uCentralProtocol::TIMESTAMP);
StorageService()->SetDeviceDisconnected(SNum,EndPoint); StorageService()->DevicesDB().SetDeviceDisconnected(SNum,EndPoint);
// std::cout << "DISCONNECTION:" << SerialNumber << std::endl; // std::cout << "DISCONNECTION:" << SerialNumber << std::endl;
} }
} else if(PayloadObj->has(uCentralProtocol::PING)) { } else if(PayloadObj->has(uCentralProtocol::PING)) {
@@ -98,7 +98,7 @@ namespace OpenWifi {
auto Revision = Storage::TrimRevision(PingMessage->get(uCentralProtocol::FIRMWARE).toString()); auto Revision = Storage::TrimRevision(PingMessage->get(uCentralProtocol::FIRMWARE).toString());
auto Serial = PingMessage->get( uCentralProtocol::SERIALNUMBER).toString(); auto Serial = PingMessage->get( uCentralProtocol::SERIALNUMBER).toString();
auto DeviceType = PingMessage->get( uCentralProtocol::COMPATIBLE).toString(); auto DeviceType = PingMessage->get( uCentralProtocol::COMPATIBLE).toString();
StorageService()->SetDeviceRevision(Serial, Revision, DeviceType, EndPoint); StorageService()->DevicesDB().SetDeviceRevision(Serial, Revision, DeviceType, EndPoint);
DeviceCache()->AddToCache(Serial, DeviceType, EndPoint, Revision); DeviceCache()->AddToCache(Serial, DeviceType, EndPoint, Revision);
if(!LatestFirmwareCache()->IsLatest(DeviceType, Revision)) { if(!LatestFirmwareCache()->IsLatest(DeviceType, Revision)) {
// std::cout << "Device(ping): " << SerialNumber << " to be upgraded ... " << std::endl; // std::cout << "Device(ping): " << SerialNumber << " to be upgraded ... " << std::endl;
@@ -108,7 +108,7 @@ namespace OpenWifi {
} }
} }
} catch (const Poco::Exception &E) { } catch (const Poco::Exception &E) {
Logger_.log(E); Logger().log(E);
} }
} }
} }

View File

@@ -14,8 +14,8 @@ namespace OpenWifi {
class NewConnectionHandler : public SubSystemServer, Poco::Runnable { class NewConnectionHandler : public SubSystemServer, Poco::Runnable {
public: public:
static NewConnectionHandler *instance() { static auto instance() {
static NewConnectionHandler *instance_ = new NewConnectionHandler; static auto instance_ = new NewConnectionHandler;
return instance_; return instance_;
} }
@@ -38,7 +38,7 @@ namespace OpenWifi {
} }
}; };
inline NewConnectionHandler * NewConnectionHandler() { return NewConnectionHandler::instance(); }; inline auto NewConnectionHandler() { return NewConnectionHandler::instance(); };
} }
#endif //UCENTRALFMS_NEWCONNECTIONHANDLER_H #endif //UCENTRALFMS_NEWCONNECTIONHANDLER_H

View File

@@ -14,8 +14,8 @@
namespace OpenWifi { namespace OpenWifi {
Poco::Net::HTTPRequestHandler * RESTAPI_external_server(const char *Path, RESTAPIHandler::BindingMap &Bindings, Poco::Net::HTTPRequestHandler * RESTAPI_ExtRouter(const char *Path, RESTAPIHandler::BindingMap &Bindings,
Poco::Logger & L, RESTAPI_GenericServer & S) { Poco::Logger & L, RESTAPI_GenericServer & S, uint64_t TransactionId) {
return RESTAPI_Router< return RESTAPI_Router<
RESTAPI_firmwaresHandler, RESTAPI_firmwaresHandler,
RESTAPI_firmwareHandler, RESTAPI_firmwareHandler,
@@ -25,17 +25,17 @@ namespace OpenWifi {
RESTAPI_connectedDeviceHandler, RESTAPI_connectedDeviceHandler,
RESTAPI_historyHandler, RESTAPI_historyHandler,
RESTAPI_deviceReportHandler RESTAPI_deviceReportHandler
>(Path,Bindings,L, S); >(Path,Bindings,L, S, TransactionId);
} }
Poco::Net::HTTPRequestHandler * RESTAPI_internal_server(const char *Path, RESTAPIHandler::BindingMap &Bindings, Poco::Net::HTTPRequestHandler * RESTAPI_IntRouter(const char *Path, RESTAPIHandler::BindingMap &Bindings,
Poco::Logger & L, RESTAPI_GenericServer & S) { Poco::Logger & L, RESTAPI_GenericServer & S, uint64_t TransactionId) {
return RESTAPI_Router_I< return RESTAPI_Router_I<
RESTAPI_firmwaresHandler, RESTAPI_firmwaresHandler,
RESTAPI_firmwareHandler, RESTAPI_firmwareHandler,
RESTAPI_system_command, RESTAPI_system_command,
RESTAPI_connectedDevicesHandler, RESTAPI_connectedDevicesHandler,
RESTAPI_connectedDeviceHandler RESTAPI_connectedDeviceHandler
>(Path, Bindings, L, S); >(Path, Bindings, L, S, TransactionId);
} }
} }

View File

@@ -18,7 +18,7 @@ namespace OpenWifi {
} }
FMSObjects::DeviceConnectionInformation DevInfo; FMSObjects::DeviceConnectionInformation DevInfo;
if(StorageService()->GetDevice(SerialNumber, DevInfo)) { if(StorageService()->DevicesDB().GetDevice(SerialNumber, DevInfo)) {
Poco::JSON::Object Answer; Poco::JSON::Object Answer;
DevInfo.to_json(Answer); DevInfo.to_json(Answer);
return ReturnObject(Answer); return ReturnObject(Answer);

View File

@@ -10,12 +10,13 @@
namespace OpenWifi { namespace OpenWifi {
class RESTAPI_connectedDeviceHandler : public RESTAPIHandler { class RESTAPI_connectedDeviceHandler : public RESTAPIHandler {
public: public:
RESTAPI_connectedDeviceHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, bool Internal) RESTAPI_connectedDeviceHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L, : RESTAPIHandler(bindings, L,
std::vector<std::string> std::vector<std::string>
{Poco::Net::HTTPRequest::HTTP_GET, {Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS}, Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, Server,
TransactionId,
Internal) {} Internal) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/connectedDevice/{serialNumber}"};} static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/connectedDevice/{serialNumber}"};}

View File

@@ -15,7 +15,7 @@ namespace OpenWifi {
std::vector<FMSObjects::DeviceConnectionInformation> Devices; std::vector<FMSObjects::DeviceConnectionInformation> Devices;
Poco::JSON::Object AnswerObj; Poco::JSON::Object AnswerObj;
Poco::JSON::Array AnswerArr; Poco::JSON::Array AnswerArr;
if (StorageService()->GetDevices(QB_.Offset, QB_.Limit, Devices)) { if (StorageService()->DevicesDB().GetDevices(QB_.Offset, QB_.Limit, Devices)) {
for (const auto &i:Devices) { for (const auto &i:Devices) {
Poco::JSON::Object Obj; Poco::JSON::Object Obj;
i.to_json(Obj); i.to_json(Obj);

View File

@@ -11,12 +11,13 @@
namespace OpenWifi { namespace OpenWifi {
class RESTAPI_connectedDevicesHandler : public RESTAPIHandler { class RESTAPI_connectedDevicesHandler : public RESTAPIHandler {
public: public:
RESTAPI_connectedDevicesHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, bool Internal) RESTAPI_connectedDevicesHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L, : RESTAPIHandler(bindings, L,
std::vector<std::string> std::vector<std::string>
{Poco::Net::HTTPRequest::HTTP_GET, {Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS}, Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, Server,
TransactionId,
Internal) {} Internal) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/connectedDevices"};} static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/connectedDevices"};}
void DoGet() final; void DoGet() final;

View File

@@ -10,12 +10,13 @@
namespace OpenWifi { namespace OpenWifi {
class RESTAPI_deviceReportHandler : public RESTAPIHandler { class RESTAPI_deviceReportHandler : public RESTAPIHandler {
public: public:
RESTAPI_deviceReportHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, bool Internal) RESTAPI_deviceReportHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L, : RESTAPIHandler(bindings, L,
std::vector<std::string> std::vector<std::string>
{Poco::Net::HTTPRequest::HTTP_GET, {Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS}, Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, Server,
TransactionId,
Internal) {} Internal) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/deviceReport"};} static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/deviceReport"};}
void DoGet() final; void DoGet() final;

View File

@@ -11,16 +11,16 @@
#include "framework/RESTAPI_protocol.h" #include "framework/RESTAPI_protocol.h"
#include "framework/RESTAPI_errors.h" #include "framework/RESTAPI_errors.h"
namespace OpenWifi { namespace OpenWifi {
void RESTAPI_firmwareAgeHandler::DoGet() { void RESTAPI_firmwareAgeHandler::DoGet() {
if (!QB_.Select.empty()) { if (!QB_.Select.empty()) {
Poco::JSON::Array Objects; Poco::JSON::Array Objects;
std::vector<std::string> Numbers = Utils::Split(QB_.Select); for (auto &i : SelectedRecords()) {
for (auto &i : Numbers) {
DeviceCacheEntry E; DeviceCacheEntry E;
if (DeviceCache()->GetDevice(i, E)) { if (DeviceCache()->GetDevice(i, E)) {
FMSObjects::FirmwareAgeDetails FA; FMSObjects::FirmwareAgeDetails FA;
if(StorageService()->ComputeFirmwareAge(E.deviceType,E.revision,FA)) { if(StorageService()->FirmwaresDB().ComputeFirmwareAge(E.deviceType,E.revision,FA)) {
Poco::JSON::Object O; Poco::JSON::Object O;
FA.to_json(O); FA.to_json(O);
O.set(uCentralProtocol::SERIALNUMBER,i); O.set(uCentralProtocol::SERIALNUMBER,i);
@@ -50,7 +50,7 @@ namespace OpenWifi {
Revision = Storage::TrimRevision(Revision); Revision = Storage::TrimRevision(Revision);
FMSObjects::FirmwareAgeDetails FA; FMSObjects::FirmwareAgeDetails FA;
if (StorageService()->ComputeFirmwareAge(DeviceType, Revision, FA)) { if (StorageService()->FirmwaresDB().ComputeFirmwareAge(DeviceType, Revision, FA)) {
Poco::JSON::Object Answer; Poco::JSON::Object Answer;
FA.to_json(Answer); FA.to_json(Answer);

View File

@@ -10,12 +10,13 @@
namespace OpenWifi { namespace OpenWifi {
class RESTAPI_firmwareAgeHandler : public RESTAPIHandler { class RESTAPI_firmwareAgeHandler : public RESTAPIHandler {
public: public:
RESTAPI_firmwareAgeHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, bool Internal) RESTAPI_firmwareAgeHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L, : RESTAPIHandler(bindings, L,
std::vector<std::string> std::vector<std::string>
{Poco::Net::HTTPRequest::HTTP_GET, {Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS}, Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, Server,
TransactionId,
Internal) {} Internal) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/firmwareAge"};} static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/firmwareAge"};}
void DoGet() final; void DoGet() final;

View File

@@ -19,7 +19,7 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument); return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
} }
F.id = MicroService::instance().CreateUUID(); F.id = MicroService::instance().CreateUUID();
if(StorageService()->AddFirmware(F)) { if(StorageService()->FirmwaresDB().AddFirmware(F)) {
Poco::JSON::Object Answer; Poco::JSON::Object Answer;
F.to_json(Answer); F.to_json(Answer);
return ReturnObject(Answer); return ReturnObject(Answer);
@@ -36,7 +36,7 @@ namespace OpenWifi {
} }
FMSObjects::Firmware F; FMSObjects::Firmware F;
if (StorageService()->GetFirmware(UUID, F)) { if (StorageService()->FirmwaresDB().GetFirmware(UUID, F)) {
Poco::JSON::Object Object; Poco::JSON::Object Object;
F.to_json(Object); F.to_json(Object);
return ReturnObject(Object); return ReturnObject(Object);
@@ -51,7 +51,7 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::MissingUUID); return BadRequest(RESTAPI::Errors::MissingUUID);
} }
if (StorageService()->DeleteFirmware(UUID)) { if (StorageService()->FirmwaresDB().DeleteFirmware(UUID)) {
return OK(); return OK();
} }
BadRequest(RESTAPI::Errors::CouldNotBeDeleted); BadRequest(RESTAPI::Errors::CouldNotBeDeleted);
@@ -64,7 +64,7 @@ namespace OpenWifi {
} }
FMSObjects::Firmware F; FMSObjects::Firmware F;
if(!StorageService()->GetFirmware(UUID, F)) { if(!StorageService()->FirmwaresDB().GetFirmware(UUID, F)) {
return NotFound(); return NotFound();
} }
@@ -85,7 +85,7 @@ namespace OpenWifi {
} }
} }
if(StorageService()->UpdateFirmware(UUID, F)) { if(StorageService()->FirmwaresDB().UpdateFirmware(UUID, F)) {
Poco::JSON::Object Answer; Poco::JSON::Object Answer;
F.to_json(Answer); F.to_json(Answer);
return ReturnObject(Answer); return ReturnObject(Answer);

View File

@@ -10,7 +10,7 @@
namespace OpenWifi { namespace OpenWifi {
class RESTAPI_firmwareHandler : public RESTAPIHandler { class RESTAPI_firmwareHandler : public RESTAPIHandler {
public: public:
RESTAPI_firmwareHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, bool Internal) RESTAPI_firmwareHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L, : RESTAPIHandler(bindings, L,
std::vector<std::string> std::vector<std::string>
{Poco::Net::HTTPRequest::HTTP_GET, {Poco::Net::HTTPRequest::HTTP_GET,
@@ -19,6 +19,7 @@ namespace OpenWifi {
Poco::Net::HTTPRequest::HTTP_DELETE, Poco::Net::HTTPRequest::HTTP_DELETE,
Poco::Net::HTTPRequest::HTTP_OPTIONS}, Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, Server,
TransactionId,
Internal) {} Internal) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/firmware/{id}"};} static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/firmware/{id}"};}
void DoGet() final; void DoGet() final;

View File

@@ -47,7 +47,7 @@ namespace OpenWifi {
} }
FMSObjects::Firmware F; FMSObjects::Firmware F;
if(StorageService()->GetFirmware(Entry.Id,F)) { if(StorageService()->FirmwaresDB().GetFirmware(Entry.Id,F)) {
Poco::JSON::Object Answer; Poco::JSON::Object Answer;
F.to_json(Answer); F.to_json(Answer);
return ReturnObject(Answer); return ReturnObject(Answer);
@@ -55,7 +55,7 @@ namespace OpenWifi {
return NotFound(); return NotFound();
} else { } else {
std::vector<FMSObjects::Firmware> List; std::vector<FMSObjects::Firmware> List;
if (StorageService()->GetFirmwares(QB_.Offset, QB_.Limit, DeviceType, List)) { if (StorageService()->FirmwaresDB().GetFirmwares(QB_.Offset, QB_.Limit, DeviceType, List)) {
Poco::JSON::Array ObjectArray; Poco::JSON::Array ObjectArray;
for (const auto &i:List) { for (const auto &i:List) {
if(IdOnly) { if(IdOnly) {
@@ -78,7 +78,7 @@ namespace OpenWifi {
std::vector<FMSObjects::Firmware> List; std::vector<FMSObjects::Firmware> List;
Poco::JSON::Array ObjectArray; Poco::JSON::Array ObjectArray;
Poco::JSON::Object Answer; Poco::JSON::Object Answer;
if (StorageService()->GetFirmwares(QB_.Offset, QB_.Limit, DeviceType, List)) { if (StorageService()->FirmwaresDB().GetFirmwares(QB_.Offset, QB_.Limit, DeviceType, List)) {
for (const auto &i:List) { for (const auto &i:List) {
if(IdOnly) { if(IdOnly) {
ObjectArray.add(i.id); ObjectArray.add(i.id);

View File

@@ -10,12 +10,13 @@
namespace OpenWifi { namespace OpenWifi {
class RESTAPI_firmwaresHandler : public RESTAPIHandler { class RESTAPI_firmwaresHandler : public RESTAPIHandler {
public: public:
RESTAPI_firmwaresHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, bool Internal) RESTAPI_firmwaresHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L, : RESTAPIHandler(bindings, L,
std::vector<std::string> std::vector<std::string>
{Poco::Net::HTTPRequest::HTTP_GET, {Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS}, Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, Server,
TransactionId,
Internal) {} Internal) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/firmwares"};} static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/firmwares"};}

View File

@@ -17,7 +17,7 @@ namespace OpenWifi {
} }
FMSObjects::RevisionHistoryEntryVec H; FMSObjects::RevisionHistoryEntryVec H;
if (StorageService()->GetHistory(SerialNumber, QB_.Offset, QB_.Limit, H)) { if (StorageService()->HistoryDB().GetHistory(SerialNumber, QB_.Offset, QB_.Limit, H)) {
Poco::JSON::Array A; Poco::JSON::Array A;
for (auto const &i:H) { for (auto const &i:H) {
Poco::JSON::Object O; Poco::JSON::Object O;
@@ -38,7 +38,7 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::IdOrSerialEmpty); return BadRequest(RESTAPI::Errors::IdOrSerialEmpty);
} }
if (!StorageService()->DeleteHistory(SerialNumber, Id)) { if (!StorageService()->HistoryDB().DeleteHistory(SerialNumber, Id)) {
return OK(); return OK();
} }
NotFound(); NotFound();

View File

@@ -11,13 +11,14 @@
namespace OpenWifi { namespace OpenWifi {
class RESTAPI_historyHandler : public RESTAPIHandler { class RESTAPI_historyHandler : public RESTAPIHandler {
public: public:
RESTAPI_historyHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, bool Internal) RESTAPI_historyHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L, : RESTAPIHandler(bindings, L,
std::vector<std::string> std::vector<std::string>
{Poco::Net::HTTPRequest::HTTP_GET, {Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_DELETE, Poco::Net::HTTPRequest::HTTP_DELETE,
Poco::Net::HTTPRequest::HTTP_OPTIONS}, Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, Server,
TransactionId,
Internal) {} Internal) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/revisionHistory/{serialNumber}"};} static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/revisionHistory/{serialNumber}"};}
void DoGet() final; void DoGet() final;

View File

@@ -0,0 +1,178 @@
//
// Created by stephane bourque on 2021-12-07.
//
#include "RESTAPI_CertObjects.h"
using OpenWifi::RESTAPI_utils::field_to_json;
using OpenWifi::RESTAPI_utils::field_from_json;
namespace OpenWifi {
namespace CertObjects {
void CertificateEntry::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"id", id);
field_to_json(Obj,"entity", entity);
field_to_json(Obj,"creator", creator);
field_to_json(Obj,"type", type);
field_to_json(Obj,"status", status);
field_to_json(Obj,"certificate", certificate);
field_to_json(Obj,"key", key);
field_to_json(Obj,"devid", devid);
field_to_json(Obj,"cas", cas);
field_to_json(Obj,"manufacturer", manufacturer);
field_to_json(Obj,"model", model);
field_to_json(Obj,"redirector", redirector);
field_to_json(Obj,"commonName", commonName);
field_to_json(Obj,"certificateId", certificateId);
field_to_json(Obj,"batch", batch);
field_to_json(Obj,"created", created);
field_to_json(Obj,"modified", modified);
field_to_json(Obj,"revoked", revoked);
field_to_json(Obj,"revokeCount", revokeCount);
}
bool CertificateEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"id", id);
field_from_json(Obj,"entity", entity);
field_from_json(Obj,"creator", creator);
field_from_json(Obj,"type", type);
field_from_json(Obj,"status", status);
field_from_json(Obj,"certificate", certificate);
field_from_json(Obj,"key", key);
field_from_json(Obj,"devid", devid);
field_from_json(Obj,"cas", cas);
field_from_json(Obj,"manufacturer", manufacturer);
field_from_json(Obj,"model", model);
field_from_json(Obj,"redirector", redirector);
field_from_json(Obj,"commonName", commonName);
field_from_json(Obj,"certificateId", certificateId);
field_from_json(Obj,"batch", batch);
field_from_json(Obj,"created", created);
field_from_json(Obj,"modified", modified);
field_from_json(Obj,"revoked", revoked);
field_from_json(Obj,"revokeCount", revokeCount);
return true;
} catch (...) {
}
return false;
}
void EntityEntry::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"id", id);
field_to_json(Obj,"creator", creator);
field_to_json(Obj,"name", name);
field_to_json(Obj,"description", description);
field_to_json(Obj,"defaultRedirector", defaultRedirector);
field_to_json(Obj,"apiKey", apiKey);
field_to_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile);
field_to_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile);
field_to_json(Obj,"organization", organization);
field_to_json(Obj,"created", created);
field_to_json(Obj,"modified", modified);
field_to_json(Obj,"suspended", suspended);
field_to_json(Obj,"deleted", deleted);
field_to_json(Obj,"notes", notes);
}
bool EntityEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"id", id);
field_from_json(Obj,"creator", creator);
field_from_json(Obj,"name", name);
field_from_json(Obj,"description", description);
field_from_json(Obj,"defaultRedirector", defaultRedirector);
field_from_json(Obj,"apiKey", apiKey);
field_from_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile);
field_from_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile);
field_from_json(Obj,"organization", organization);
field_from_json(Obj,"created", created);
field_from_json(Obj,"modified", modified);
field_from_json(Obj,"suspended", suspended);
field_from_json(Obj,"deleted", deleted);
field_from_json(Obj,"notes", notes);
return true;
} catch (...) {
}
return false;
}
void BatchEntry::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"id", id);
field_to_json(Obj,"entity", entity);
field_to_json(Obj,"creator", creator);
field_to_json(Obj,"name", name);
field_to_json(Obj,"description", description);
field_to_json(Obj,"manufacturer", manufacturer);
field_to_json(Obj,"model", model);
field_to_json(Obj,"redirector", redirector);
field_to_json(Obj,"commonNames", commonNames);
field_to_json(Obj,"jobHistory", jobHistory);
field_to_json(Obj,"notes", notes);
field_to_json(Obj,"submitted", submitted);
field_to_json(Obj,"started", started);
field_to_json(Obj,"completed", completed);
field_to_json(Obj,"modified", modified);
}
bool BatchEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"id", id);
field_from_json(Obj,"entity", entity);
field_from_json(Obj,"creator", creator);
field_from_json(Obj,"name", name);
field_from_json(Obj,"description", description);
field_from_json(Obj,"manufacturer", manufacturer);
field_from_json(Obj,"model", model);
field_from_json(Obj,"redirector", redirector);
field_from_json(Obj,"commonNames", commonNames);
field_from_json(Obj,"jobHistory", jobHistory);
field_from_json(Obj,"notes", notes);
field_from_json(Obj,"submitted", submitted);
field_from_json(Obj,"started", started);
field_from_json(Obj,"completed", completed);
field_from_json(Obj,"modified", modified);
return true;
} catch (...) {
}
return false;
}
void JobEntry::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"id", id);
field_to_json(Obj,"entity", entity);
field_to_json(Obj,"creator", creator);
field_to_json(Obj,"batch", batch);
field_to_json(Obj,"commonNames", commonNames);
field_to_json(Obj,"completedNames", completedNames);
field_to_json(Obj,"errorNames", errorNames);
field_to_json(Obj,"status", status);
field_to_json(Obj,"command", command);
field_to_json(Obj,"parameters", parameters);
field_to_json(Obj,"submitted", submitted);
field_to_json(Obj,"started", started);
field_to_json(Obj,"completed", completed);
}
bool JobEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"id", id);
field_from_json(Obj,"entity", entity);
field_from_json(Obj,"creator", creator);
field_from_json(Obj,"batch", batch);
field_from_json(Obj,"commonNames", commonNames);
field_from_json(Obj,"completedNames", completedNames);
field_from_json(Obj,"errorNames", errorNames);
field_from_json(Obj,"status", status);
field_from_json(Obj,"command", command);
field_from_json(Obj,"parameters", parameters);
field_from_json(Obj,"submitted", submitted);
field_from_json(Obj,"started", started);
field_from_json(Obj,"completed", completed);
return true;
} catch (...) {
}
return false;
}
}
}

View File

@@ -0,0 +1,101 @@
//
// Created by stephane bourque on 2021-12-07.
//
#pragma once
#include <string>
#include "framework/MicroService.h"
#include "framework/OpenWifiTypes.h"
#include "RESTObjects/RESTAPI_SecurityObjects.h"
namespace OpenWifi {
namespace CertObjects {
struct CertificateEntry {
OpenWifi::Types::UUID_t id;
OpenWifi::Types::UUID_t entity;
OpenWifi::Types::UUID_t creator;
std::string type;
std::string status;
std::string certificate;
std::string key;
std::string devid;
std::string cas;
std::string manufacturer;
std::string model;
std::string redirector;
std::string commonName;
std::string certificateId;
OpenWifi::Types::UUID_t batch;
uint64_t created = 0;
uint64_t modified = 0;
uint64_t revoked = 0;
uint64_t revokeCount = 0;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct EntityEntry {
OpenWifi::Types::UUID_t id;
OpenWifi::Types::UUID_t creator;
std::string name;
std::string description;
std::string defaultRedirector;
std::string apiKey;
std::string serverEnrollmentProfile;
std::string clientEnrollmentProfile;
std::string organization;
SecurityObjects::NoteInfoVec notes;
bool suspended=false;
bool deleted=false;
uint64_t created = 0 ;
uint64_t modified = 0 ;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct BatchEntry {
OpenWifi::Types::UUID_t id;
OpenWifi::Types::UUID_t entity;
OpenWifi::Types::UUID_t creator;
std::string name;
std::string description;
std::string manufacturer;
std::string model;
std::string redirector;
std::vector<std::string> commonNames;
std::vector<std::string> jobHistory;
SecurityObjects::NoteInfoVec notes;
uint64_t submitted = 0 ;
uint64_t started = 0 ;
uint64_t completed = 0 ;
uint64_t modified = 0 ;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct JobEntry {
OpenWifi::Types::UUID_t id;
OpenWifi::Types::UUID_t entity;
OpenWifi::Types::UUID_t creator;
OpenWifi::Types::UUID_t batch;
std::string command;
OpenWifi::Types::StringVec commonNames;
OpenWifi::Types::StringVec completedNames;
OpenWifi::Types::StringVec errorNames;
Types::StringPairVec parameters;
std::string status;
uint64_t submitted=0;
uint64_t started=0;
uint64_t completed=0;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
}
}

View File

@@ -29,7 +29,7 @@ namespace OpenWifi::FMSObjects {
std::string location; std::string location;
std::string uploader; std::string uploader;
std::string digest; std::string digest;
bool latest=false; bool latest=0;
SecurityObjects::NoteInfoVec notes; SecurityObjects::NoteInfoVec notes;
uint64_t created=0; uint64_t created=0;

View File

@@ -12,6 +12,7 @@
#include "Daemon.h" #include "Daemon.h"
#ifdef TIP_GATEWAY_SERVICE #ifdef TIP_GATEWAY_SERVICE
#include "DeviceRegistry.h" #include "DeviceRegistry.h"
#include "CapabilitiesCache.h"
#endif #endif
#include "RESTAPI_GWobjects.h" #include "RESTAPI_GWobjects.h"
@@ -26,7 +27,7 @@ namespace OpenWifi::GWObjects {
void Device::to_json(Poco::JSON::Object &Obj) const { void Device::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"serialNumber", SerialNumber); field_to_json(Obj,"serialNumber", SerialNumber);
#ifdef TIP_GATEWAY_SERVICE #ifdef TIP_GATEWAY_SERVICE
field_to_json(Obj,"deviceType", Daemon::instance()->IdentifyDevice(Compatible)); field_to_json(Obj,"deviceType", CapabilitiesCache::instance()->Get(Compatible));
#endif #endif
field_to_json(Obj,"macAddress", MACAddress); field_to_json(Obj,"macAddress", MACAddress);
field_to_json(Obj,"manufacturer", Manufacturer); field_to_json(Obj,"manufacturer", Manufacturer);
@@ -145,6 +146,7 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj,"custom", Custom); field_to_json(Obj,"custom", Custom);
field_to_json(Obj,"waitingForFile", WaitingForFile); field_to_json(Obj,"waitingForFile", WaitingForFile);
field_to_json(Obj,"attachFile", AttachDate); field_to_json(Obj,"attachFile", AttachDate);
field_to_json(Obj,"executionTime", executionTime);
} }
bool DefaultConfiguration::from_json(Poco::JSON::Object::Ptr &Obj) { bool DefaultConfiguration::from_json(Poco::JSON::Object::Ptr &Obj) {
@@ -179,7 +181,6 @@ namespace OpenWifi::GWObjects {
} }
void ConnectionState::to_json(Poco::JSON::Object &Obj) const { void ConnectionState::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"serialNumber", SerialNumber);
field_to_json(Obj,"ipAddress", Address); field_to_json(Obj,"ipAddress", Address);
field_to_json(Obj,"txBytes", TX); field_to_json(Obj,"txBytes", TX);
field_to_json(Obj,"rxBytes", RX); field_to_json(Obj,"rxBytes", RX);
@@ -190,6 +191,10 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj,"lastContact", LastContact); field_to_json(Obj,"lastContact", LastContact);
field_to_json(Obj,"associations_2G", Associations_2G); field_to_json(Obj,"associations_2G", Associations_2G);
field_to_json(Obj,"associations_5G", Associations_5G); field_to_json(Obj,"associations_5G", Associations_5G);
field_to_json(Obj,"webSocketClients", webSocketClients);
field_to_json(Obj,"websocketPackets", websocketPackets);
field_to_json(Obj,"kafkaClients", kafkaClients);
field_to_json(Obj,"kafkaPackets", kafkaPackets);
switch(VerifiedCertificate) { switch(VerifiedCertificate) {
case NO_CERTIFICATE: case NO_CERTIFICATE:

View File

@@ -6,8 +6,7 @@
// Arilia Wireless Inc. // Arilia Wireless Inc.
// //
#ifndef UCENTRAL_RESTAPI_OBJECTS_H #pragma once
#define UCENTRAL_RESTAPI_OBJECTS_H
#include "Poco/JSON/Object.h" #include "Poco/JSON/Object.h"
#include "RESTAPI_SecurityObjects.h" #include "RESTAPI_SecurityObjects.h"
@@ -23,7 +22,6 @@ namespace OpenWifi::GWObjects {
struct ConnectionState { struct ConnectionState {
uint64_t MessageCount = 0 ; uint64_t MessageCount = 0 ;
std::string SerialNumber;
std::string Address; std::string Address;
uint64_t UUID = 0 ; uint64_t UUID = 0 ;
uint64_t PendingUUID = 0 ; uint64_t PendingUUID = 0 ;
@@ -35,6 +33,10 @@ namespace OpenWifi::GWObjects {
std::string Firmware; std::string Firmware;
CertificateValidation VerifiedCertificate = NO_CERTIFICATE; CertificateValidation VerifiedCertificate = NO_CERTIFICATE;
std::string Compatible; std::string Compatible;
uint64_t kafkaClients=0;
uint64_t webSocketClients=0;
uint64_t kafkaPackets=0;
uint64_t websocketPackets=0;
void to_json(Poco::JSON::Object &Obj) const; void to_json(Poco::JSON::Object &Obj) const;
}; };
@@ -50,11 +52,11 @@ namespace OpenWifi::GWObjects {
std::string Firmware; std::string Firmware;
std::string Compatible; std::string Compatible;
std::string FWUpdatePolicy; std::string FWUpdatePolicy;
uint64_t UUID; uint64_t UUID = 0 ;
uint64_t CreationTimestamp; uint64_t CreationTimestamp = 0 ;
uint64_t LastConfigurationChange; uint64_t LastConfigurationChange = 0 ;
uint64_t LastConfigurationDownload; uint64_t LastConfigurationDownload = 0 ;
uint64_t LastFWUpdate; uint64_t LastFWUpdate = 0 ;
std::string Venue; std::string Venue;
std::string DevicePassword; std::string DevicePassword;
void to_json(Poco::JSON::Object &Obj) const; void to_json(Poco::JSON::Object &Obj) const;
@@ -65,25 +67,25 @@ namespace OpenWifi::GWObjects {
struct Statistics { struct Statistics {
std::string SerialNumber; std::string SerialNumber;
uint64_t UUID; uint64_t UUID = 0 ;
std::string Data; std::string Data;
uint64_t Recorded; uint64_t Recorded = 0;
void to_json(Poco::JSON::Object &Obj) const; void to_json(Poco::JSON::Object &Obj) const;
}; };
struct HealthCheck { struct HealthCheck {
std::string SerialNumber; std::string SerialNumber;
uint64_t UUID; uint64_t UUID = 0 ;
std::string Data; std::string Data;
uint64_t Recorded; uint64_t Recorded = 0 ;
uint64_t Sanity; uint64_t Sanity = 0 ;
void to_json(Poco::JSON::Object &Obj) const; void to_json(Poco::JSON::Object &Obj) const;
}; };
struct Capabilities { struct Capabilities {
std::string Capabilities; std::string Capabilities;
uint64_t FirstUpdate; uint64_t FirstUpdate = 0 ;
uint64_t LastUpdate; uint64_t LastUpdate = 0 ;
void to_json(Poco::JSON::Object &Obj) const; void to_json(Poco::JSON::Object &Obj) const;
}; };
@@ -101,17 +103,17 @@ namespace OpenWifi::GWObjects {
std::string SerialNumber; std::string SerialNumber;
std::string Log; std::string Log;
std::string Data; std::string Data;
uint64_t Severity; uint64_t Severity = 0 ;
uint64_t Recorded; uint64_t Recorded = 0 ;
uint64_t LogType; uint64_t LogType = 0 ;
uint64_t UUID; uint64_t UUID = 0 ;
void to_json(Poco::JSON::Object &Obj) const; void to_json(Poco::JSON::Object &Obj) const;
}; };
struct DefaultConfiguration { struct DefaultConfiguration {
std::string Name; std::string Name;
std::string Configuration; std::string Configuration;
std::string Models; Types::StringVec Models;
std::string Description; std::string Description;
uint64_t Created; uint64_t Created;
uint64_t LastModified; uint64_t LastModified;
@@ -138,6 +140,7 @@ namespace OpenWifi::GWObjects {
uint64_t AttachDate = 0 ; uint64_t AttachDate = 0 ;
uint64_t AttachSize = 0 ; uint64_t AttachSize = 0 ;
std::string AttachType; std::string AttachType;
double executionTime = 0.0;
void to_json(Poco::JSON::Object &Obj) const; void to_json(Poco::JSON::Object &Obj) const;
}; };
@@ -153,20 +156,20 @@ namespace OpenWifi::GWObjects {
struct RttySessionDetails { struct RttySessionDetails {
std::string SerialNumber; std::string SerialNumber;
std::string Server; std::string Server;
uint64_t Port; uint64_t Port = 0 ;
std::string Token; std::string Token;
uint64_t TimeOut; uint64_t TimeOut = 0 ;
std::string ConnectionId; std::string ConnectionId;
uint64_t Started; uint64_t Started = 0 ;
std::string CommandUUID; std::string CommandUUID;
uint64_t ViewPort; uint64_t ViewPort = 0 ;
std::string DevicePassword; std::string DevicePassword;
void to_json(Poco::JSON::Object &Obj) const; void to_json(Poco::JSON::Object &Obj) const;
}; };
struct Dashboard { struct Dashboard {
uint64_t snapshot; uint64_t snapshot = 0 ;
uint64_t numberOfDevices; uint64_t numberOfDevices = 0 ;
Types::CountedMap commands; Types::CountedMap commands;
Types::CountedMap upTimes; Types::CountedMap upTimes;
Types::CountedMap memoryUsed; Types::CountedMap memoryUsed;
@@ -191,5 +194,3 @@ namespace OpenWifi::GWObjects {
void to_json(Poco::JSON::Object &Obj) const; void to_json(Poco::JSON::Object &Obj) const;
}; };
} }
#endif //UCENTRAL_RESTAPI_OBJECTS_H

View File

@@ -309,6 +309,7 @@ namespace OpenWifi::ProvObjects {
field_to_json( Obj,"deviceConfiguration",deviceConfiguration); field_to_json( Obj,"deviceConfiguration",deviceConfiguration);
field_to_json( Obj,"rrm",rrm); field_to_json( Obj,"rrm",rrm);
field_to_json( Obj,"managementPolicy",managementPolicy); field_to_json( Obj,"managementPolicy",managementPolicy);
field_to_json( Obj,"state",state);
} }
bool InventoryTag::from_json(const Poco::JSON::Object::Ptr &Obj) { bool InventoryTag::from_json(const Poco::JSON::Object::Ptr &Obj) {
@@ -326,6 +327,7 @@ namespace OpenWifi::ProvObjects {
field_from_json( Obj,"deviceConfiguration",deviceConfiguration); field_from_json( Obj,"deviceConfiguration",deviceConfiguration);
field_from_json( Obj,"rrm",rrm); field_from_json( Obj,"rrm",rrm);
field_from_json( Obj,"managementPolicy",managementPolicy); field_from_json( Obj,"managementPolicy",managementPolicy);
field_from_json( Obj,"state",state);
return true; return true;
} catch(...) { } catch(...) {
@@ -333,6 +335,20 @@ namespace OpenWifi::ProvObjects {
return false; return false;
} }
void InventoryTagList::to_json(Poco::JSON::Object &Obj) const {
field_to_json( Obj,"taglist",taglist);
}
bool InventoryTagList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json( Obj,"taglist",taglist);
return false;
} catch (...) {
}
return false;
};
void DeviceConfigurationElement::to_json(Poco::JSON::Object &Obj) const { void DeviceConfigurationElement::to_json(Poco::JSON::Object &Obj) const {
field_to_json( Obj,"name", name); field_to_json( Obj,"name", name);
field_to_json( Obj,"description", description); field_to_json( Obj,"description", description);
@@ -440,11 +456,11 @@ namespace OpenWifi::ProvObjects {
return false; return false;
} }
void UserList::to_json(Poco::JSON::Object &Obj) const { void UuidList::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "list", list); field_to_json(Obj, "list", list);
} }
bool UserList::from_json(const Poco::JSON::Object::Ptr &Obj) { bool UuidList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try { try {
field_from_json(Obj, "list", list); field_from_json(Obj, "list", list);
return true; return true;
@@ -454,14 +470,46 @@ namespace OpenWifi::ProvObjects {
return false; return false;
} }
void field_to_json(Poco::JSON::Object &Obj, const char * FieldName, ACLACCESS A) {
switch(A) {
case READ: Obj.set(FieldName,"read"); break;
case MODIFY: Obj.set(FieldName,"modify"); break;
case CREATE: Obj.set(FieldName,"create"); break;
case DELETE: Obj.set(FieldName,"delete"); break;
case NONE:
default:
Obj.set(FieldName,"none");
}
}
void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char * FieldName, ACLACCESS &A) {
if(Obj->has(FieldName)) {
auto V = Obj->getValue<std::string>(FieldName);
if(V=="read")
A = READ;
else if(V=="modify")
A = MODIFY;
else if(V=="create")
A = CREATE;
else if(V=="delete")
A = DELETE;
else if(V=="none")
A = NONE;
else
throw Poco::Exception("invalid JSON");
}
}
void ObjectACL::to_json(Poco::JSON::Object &Obj) const { void ObjectACL::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "users", users); RESTAPI_utils::field_to_json(Obj, "users", users);
RESTAPI_utils::field_to_json(Obj, "roles", roles);
field_to_json(Obj, "access", access); field_to_json(Obj, "access", access);
} }
bool ObjectACL::from_json(const Poco::JSON::Object::Ptr &Obj) { bool ObjectACL::from_json(const Poco::JSON::Object::Ptr &Obj) {
try { try {
field_from_json(Obj, "users", users); RESTAPI_utils::field_from_json(Obj, "users", users);
RESTAPI_utils::field_from_json(Obj, "roles", roles);
field_from_json(Obj, "access", access); field_from_json(Obj, "access", access);
return true; return true;
} catch(...) { } catch(...) {
@@ -471,12 +519,12 @@ namespace OpenWifi::ProvObjects {
} }
void ObjectACLList::to_json(Poco::JSON::Object &Obj) const { void ObjectACLList::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "list", list); RESTAPI_utils::field_to_json(Obj, "list", list);
} }
bool ObjectACLList::from_json(const Poco::JSON::Object::Ptr &Obj) { bool ObjectACLList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try { try {
field_from_json(Obj, "list", list); RESTAPI_utils::field_from_json(Obj, "list", list);
return true; return true;
} catch(...) { } catch(...) {
@@ -484,23 +532,54 @@ namespace OpenWifi::ProvObjects {
return false; return false;
} }
std::string to_string(VISIBILITY A) {
switch(A) {
case PUBLIC: return "public";
case SELECT: return "select";
case PRIVATE:
default:
return "private";
}
}
void field_to_json(Poco::JSON::Object &Obj, const char * FieldName, VISIBILITY A) {
Obj.set(FieldName,to_string(A));
}
VISIBILITY visibility_from_string(const std::string &V) {
if(V=="public")
return PUBLIC;
else if(V=="select")
return SELECT;
else if(V=="private")
return PRIVATE;
throw Poco::Exception("invalid json");
}
void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char * FieldName, VISIBILITY &A) {
if(Obj->has(FieldName)) {
auto V = Obj->getValue<std::string>(FieldName);
A = visibility_from_string(V);
}
}
void Map::to_json(Poco::JSON::Object &Obj) const { void Map::to_json(Poco::JSON::Object &Obj) const {
info.to_json(Obj); info.to_json(Obj);
field_to_json( Obj,"data",data); RESTAPI_utils::field_to_json( Obj,"data",data);
field_to_json( Obj,"entity",entity); RESTAPI_utils::field_to_json( Obj,"entity",entity);
field_to_json( Obj,"creator",creator); RESTAPI_utils::field_to_json( Obj,"creator",creator);
field_to_json( Obj,"visibility",visibility); field_to_json( Obj,"visibility",visibility);
field_to_json( Obj,"access",access); RESTAPI_utils::field_to_json( Obj,"access",access);
} }
bool Map::from_json(const Poco::JSON::Object::Ptr &Obj) { bool Map::from_json(const Poco::JSON::Object::Ptr &Obj) {
try { try {
info.from_json(Obj); info.from_json(Obj);
field_from_json( Obj,"data",data); RESTAPI_utils::field_from_json( Obj,"data",data);
field_from_json( Obj,"entity",entity); RESTAPI_utils::field_from_json( Obj,"entity",entity);
field_from_json( Obj,"creator",creator); RESTAPI_utils::field_from_json( Obj,"creator",creator);
field_from_json( Obj,"visibility",visibility); field_from_json( Obj,"visibility",visibility);
field_from_json( Obj,"access",access); RESTAPI_utils::field_from_json( Obj,"access",access);
return true; return true;
} catch(...) { } catch(...) {
@@ -509,12 +588,12 @@ namespace OpenWifi::ProvObjects {
} }
void MapList::to_json(Poco::JSON::Object &Obj) const { void MapList::to_json(Poco::JSON::Object &Obj) const {
field_to_json( Obj,"list",list); RESTAPI_utils::field_to_json( Obj,"list",list);
} }
bool MapList::from_json(const Poco::JSON::Object::Ptr &Obj) { bool MapList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try { try {
field_from_json( Obj,"list",list); RESTAPI_utils::field_from_json( Obj,"list",list);
return true; return true;
} catch(...) { } catch(...) {
@@ -530,7 +609,7 @@ namespace OpenWifi::ProvObjects {
if(I.name.empty()) if(I.name.empty())
return false; return false;
if(O->has("description")) if(O->has("description"))
I.description = O->get("description").toString(); I.description = O->get("description").toString();
SecurityObjects::MergeNotes(O,U,I.notes); SecurityObjects::MergeNotes(O,U,I.notes);
SecurityObjects::NoteInfoVec N; SecurityObjects::NoteInfoVec N;
@@ -562,8 +641,9 @@ namespace OpenWifi::ProvObjects {
} }
I.notes = N; I.notes = N;
I.modified = I.created = Now; I.modified = I.created = Now;
I.id = MicroService::instance().CreateUUID(); I.id = MicroService::CreateUUID();
return true; return true;
} }
}; }

View File

@@ -6,9 +6,7 @@
// Arilia Wireless Inc. // Arilia Wireless Inc.
// //
#pragma once
#ifndef OWPROV_RESTAPI_PROVOBJECTS_H
#define OWPROV_RESTAPI_PROVOBJECTS_H
#include <string> #include <string>
#include "RESTAPI_SecurityObjects.h" #include "RESTAPI_SecurityObjects.h"
@@ -286,12 +284,22 @@ namespace OpenWifi::ProvObjects {
std::string deviceConfiguration; std::string deviceConfiguration;
std::string rrm; std::string rrm;
Types::UUID_t managementPolicy; Types::UUID_t managementPolicy;
std::string state;
void to_json(Poco::JSON::Object &Obj) const; void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj); bool from_json(const Poco::JSON::Object::Ptr &Obj);
}; };
typedef std::vector<InventoryTag> InventoryTagVec; typedef std::vector<InventoryTag> InventoryTagVec;
struct InventoryTagList {
InventoryTagVec taglist;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct Report { struct Report {
uint64_t snapShot=0; uint64_t snapShot=0;
Types::CountedMap tenants; Types::CountedMap tenants;
@@ -324,16 +332,21 @@ namespace OpenWifi::ProvObjects {
bool from_json(const Poco::JSON::Object::Ptr &Obj); bool from_json(const Poco::JSON::Object::Ptr &Obj);
}; };
struct UserList { struct UuidList {
std::vector<std::string> list; std::vector<std::string> list;
void to_json(Poco::JSON::Object &Obj) const; void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj); bool from_json(const Poco::JSON::Object::Ptr &Obj);
}; };
enum ACLACCESS {
NONE, READ, MODIFY, CREATE, DELETE
};
struct ObjectACL { struct ObjectACL {
UserList users; UuidList users;
std::string access; UuidList roles;
ACLACCESS access = NONE;
void to_json(Poco::JSON::Object &Obj) const; void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj); bool from_json(const Poco::JSON::Object::Ptr &Obj);
@@ -346,12 +359,19 @@ namespace OpenWifi::ProvObjects {
bool from_json(const Poco::JSON::Object::Ptr &Obj); bool from_json(const Poco::JSON::Object::Ptr &Obj);
}; };
enum VISIBILITY {
PUBLIC, PRIVATE, SELECT
};
std::string to_string(VISIBILITY A);
VISIBILITY visibility_from_string(const std::string &V);
struct Map { struct Map {
ObjectInfo info; ObjectInfo info;
std::string data; std::string data;
std::string entity; std::string entity;
std::string creator; std::string creator;
std::string visibility; VISIBILITY visibility = PRIVATE;
ObjectACLList access; ObjectACLList access;
void to_json(Poco::JSON::Object &Obj) const; void to_json(Poco::JSON::Object &Obj) const;
@@ -367,8 +387,4 @@ namespace OpenWifi::ProvObjects {
bool UpdateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I); bool UpdateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I);
bool CreateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I); bool CreateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I);
}; };
#endif //OWPROV_RESTAPI_PROVOBJECTS_H

View File

@@ -54,6 +54,8 @@ namespace OpenWifi::SecurityObjects {
return ADMIN; return ADMIN;
else if (!Poco::icompare(U,"subscriber")) else if (!Poco::icompare(U,"subscriber"))
return SUBSCRIBER; return SUBSCRIBER;
else if (!Poco::icompare(U,"partner"))
return PARTNER;
else if (!Poco::icompare(U,"csr")) else if (!Poco::icompare(U,"csr"))
return CSR; return CSR;
else if (!Poco::icompare(U, "system")) else if (!Poco::icompare(U, "system"))
@@ -72,6 +74,7 @@ namespace OpenWifi::SecurityObjects {
case ROOT: return "root"; case ROOT: return "root";
case ADMIN: return "admin"; case ADMIN: return "admin";
case SUBSCRIBER: return "subscriber"; case SUBSCRIBER: return "subscriber";
case PARTNER: return "partner";
case CSR: return "csr"; case CSR: return "csr";
case SYSTEM: return "system"; case SYSTEM: return "system";
case INSTALLER: return "installer"; case INSTALLER: return "installer";
@@ -169,12 +172,14 @@ namespace OpenWifi::SecurityObjects {
void UserLoginLoginExtensions::to_json(Poco::JSON::Object &Obj) const { void UserLoginLoginExtensions::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "mobiles", mobiles); field_to_json(Obj, "mobiles", mobiles);
field_to_json(Obj, "mfa", mfa); field_to_json(Obj, "mfa", mfa);
field_to_json(Obj, "authenticatorSecret", authenticatorSecret);
} }
bool UserLoginLoginExtensions::from_json(Poco::JSON::Object::Ptr &Obj) { bool UserLoginLoginExtensions::from_json(Poco::JSON::Object::Ptr &Obj) {
try { try {
field_from_json(Obj,"mobiles",mobiles); field_from_json(Obj,"mobiles",mobiles);
field_from_json(Obj,"mfa",mfa); field_from_json(Obj,"mfa",mfa);
field_from_json(Obj, "authenticatorSecret", authenticatorSecret);
return true; return true;
} catch (...) { } catch (...) {
@@ -221,7 +226,7 @@ namespace OpenWifi::SecurityObjects {
} }
void UserInfo::to_json(Poco::JSON::Object &Obj) const { void UserInfo::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"Id",Id); field_to_json(Obj,"id",id);
field_to_json(Obj,"name",name); field_to_json(Obj,"name",name);
field_to_json(Obj,"description", description); field_to_json(Obj,"description", description);
field_to_json(Obj,"avatar", avatar); field_to_json(Obj,"avatar", avatar);
@@ -251,11 +256,12 @@ namespace OpenWifi::SecurityObjects {
field_to_json(Obj,"lastPasswords",lastPasswords); field_to_json(Obj,"lastPasswords",lastPasswords);
field_to_json(Obj,"oauthType",oauthType); field_to_json(Obj,"oauthType",oauthType);
field_to_json(Obj,"oauthUserInfo",oauthUserInfo); field_to_json(Obj,"oauthUserInfo",oauthUserInfo);
field_to_json(Obj,"modified",modified);
}; };
bool UserInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { bool UserInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
try { try {
field_from_json(Obj,"Id",Id); field_from_json(Obj,"id",id);
field_from_json(Obj,"name",name); field_from_json(Obj,"name",name);
field_from_json(Obj,"description",description); field_from_json(Obj,"description",description);
field_from_json(Obj,"avatar",avatar); field_from_json(Obj,"avatar",avatar);
@@ -265,6 +271,8 @@ namespace OpenWifi::SecurityObjects {
field_from_json(Obj,"currentLoginURI",currentLoginURI); field_from_json(Obj,"currentLoginURI",currentLoginURI);
field_from_json(Obj,"locale",locale); field_from_json(Obj,"locale",locale);
field_from_json(Obj,"notes",notes); field_from_json(Obj,"notes",notes);
field_from_json(Obj,"location", location);
field_from_json(Obj,"owner", owner);
field_from_json<USER_ROLE>(Obj,"userRole",userRole, UserTypeFromString); field_from_json<USER_ROLE>(Obj,"userRole",userRole, UserTypeFromString);
field_from_json(Obj,"securityPolicy",securityPolicy); field_from_json(Obj,"securityPolicy",securityPolicy);
field_from_json(Obj,"userTypeProprietaryInfo",userTypeProprietaryInfo); field_from_json(Obj,"userTypeProprietaryInfo",userTypeProprietaryInfo);
@@ -283,6 +291,7 @@ namespace OpenWifi::SecurityObjects {
field_from_json(Obj,"lastPasswords",lastPasswords); field_from_json(Obj,"lastPasswords",lastPasswords);
field_from_json(Obj,"oauthType",oauthType); field_from_json(Obj,"oauthType",oauthType);
field_from_json(Obj,"oauthUserInfo",oauthUserInfo); field_from_json(Obj,"oauthUserInfo",oauthUserInfo);
field_from_json(Obj,"modified",modified);
return true; return true;
} catch (const Poco::Exception &E) { } catch (const Poco::Exception &E) {
@@ -491,7 +500,7 @@ namespace OpenWifi::SecurityObjects {
field_to_json(Obj,"expires",expires); field_to_json(Obj,"expires",expires);
field_to_json(Obj,"completed",completed); field_to_json(Obj,"completed",completed);
field_to_json(Obj,"canceled",canceled); field_to_json(Obj,"canceled",canceled);
field_to_json(Obj,"userAction",userAction);
} }
bool ActionLink::from_json(Poco::JSON::Object::Ptr &Obj) { bool ActionLink::from_json(Poco::JSON::Object::Ptr &Obj) {
@@ -508,11 +517,86 @@ namespace OpenWifi::SecurityObjects {
field_from_json(Obj,"expires",expires); field_from_json(Obj,"expires",expires);
field_from_json(Obj,"completed",completed); field_from_json(Obj,"completed",completed);
field_from_json(Obj,"canceled",canceled); field_from_json(Obj,"canceled",canceled);
field_from_json(Obj,"userAction",userAction);
return true; return true;
} catch(...) { } catch(...) {
} }
return false; return false;
} }
void Preferences::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"id",id);
field_to_json(Obj,"modified",modified);
field_to_json(Obj,"data",data);
}
bool Preferences::from_json(Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"id",id);
field_from_json(Obj,"modified",modified);
field_from_json(Obj,"data",data);
return true;
} catch(...) {
}
return false;
}
void SubMfaConfig::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"id",id);
field_to_json(Obj,"type",type);
field_to_json(Obj,"sms",sms);
field_to_json(Obj,"email",email);
}
bool SubMfaConfig::from_json(Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"id",id);
field_from_json(Obj,"type",type);
field_from_json(Obj,"sms",sms);
field_from_json(Obj,"email",email);
return true;
} catch(...) {
}
return false;
}
void Token::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"token",token);
field_to_json(Obj,"refreshToken",refreshToken);
field_to_json(Obj,"tokenType",tokenType);
field_to_json(Obj,"userName",userName);
field_to_json(Obj,"created",created);
field_to_json(Obj,"expires",expires);
field_to_json(Obj,"idleTimeout",idleTimeout);
field_to_json(Obj,"revocationDate",revocationDate);
}
bool Token::from_json(Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"token",token);
field_from_json(Obj,"refreshToken",refreshToken);
field_from_json(Obj,"tokenType",tokenType);
field_from_json(Obj,"userName",userName);
field_from_json(Obj,"created",created);
field_from_json(Obj,"expires",expires);
field_from_json(Obj,"idleTimeout",idleTimeout);
field_from_json(Obj,"revocationDate",revocationDate);
return true;
} catch(...) {
}
return false;
}
void LoginRecordInfo::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"sessionId",sessionId);
field_to_json(Obj,"userId",userId);
field_to_json(Obj,"email",email);
field_to_json(Obj,"login",login);
field_to_json(Obj,"logout",logout);
}
} }

View File

@@ -6,244 +6,303 @@
// Arilia Wireless Inc. // Arilia Wireless Inc.
// //
#ifndef UCENTRAL_RESTAPI_SECURITYOBJECTS_H #pragma once
#define UCENTRAL_RESTAPI_SECURITYOBJECTS_H
#include "Poco/JSON/Object.h" #include <string>
#include "framework/OpenWifiTypes.h" #include "framework/OpenWifiTypes.h"
#include "Poco/JSON/Object.h"
#include "Poco/Data/LOB.h"
#include "Poco/Data/LOBStream.h"
namespace OpenWifi::SecurityObjects { namespace OpenWifi {
namespace SecurityObjects {
struct AclTemplate { typedef std::string USER_ID_TYPE;
bool Read_ = true;
bool ReadWrite_ = true;
bool ReadWriteCreate_ = true;
bool Delete_ = true;
bool PortalLogin_ = true;
void to_json(Poco::JSON::Object &Obj) const; struct AclTemplate {
bool from_json(const Poco::JSON::Object::Ptr &Obj); }; bool Read_ = true;
bool ReadWrite_ = true;
bool ReadWriteCreate_ = true;
bool Delete_ = true;
bool PortalLogin_ = true;
struct WebToken { void to_json(Poco::JSON::Object &Obj) const;
std::string access_token_; bool from_json(const Poco::JSON::Object::Ptr &Obj); };
std::string refresh_token_;
std::string id_token_;
std::string token_type_;
std::string username_;
bool userMustChangePassword=false;
uint64_t errorCode=0;
uint64_t expires_in_=0;
uint64_t idle_timeout_=0;
AclTemplate acl_template_;
uint64_t created_=0;
void to_json(Poco::JSON::Object &Obj) const; struct WebToken {
bool from_json(const Poco::JSON::Object::Ptr &Obj); std::string access_token_;
}; std::string refresh_token_;
std::string id_token_;
std::string token_type_;
std::string username_;
bool userMustChangePassword=false;
uint64_t errorCode=0;
uint64_t expires_in_=0;
uint64_t idle_timeout_=0;
AclTemplate acl_template_;
uint64_t created_=0;
enum USER_ROLE { void to_json(Poco::JSON::Object &Obj) const;
UNKNOWN, ROOT, ADMIN, SUBSCRIBER, CSR, SYSTEM, INSTALLER, NOC, ACCOUNTING bool from_json(const Poco::JSON::Object::Ptr &Obj);
}; };
USER_ROLE UserTypeFromString(const std::string &U); enum USER_ROLE {
std::string UserTypeToString(USER_ROLE U); UNKNOWN, ROOT, ADMIN, SUBSCRIBER, CSR, SYSTEM, INSTALLER, NOC, ACCOUNTING, PARTNER
};
struct NoteInfo { USER_ROLE UserTypeFromString(const std::string &U);
uint64_t created = std::time(nullptr); std::string UserTypeToString(USER_ROLE U);
std::string createdBy;
std::string note;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(Poco::JSON::Object::Ptr &Obj);
};
typedef std::vector<NoteInfo> NoteInfoVec;
struct MobilePhoneNumber { struct NoteInfo {
std::string number; uint64_t created = std::time(nullptr);
bool verified = false; std::string createdBy;
bool primary = false; std::string note;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(Poco::JSON::Object::Ptr &Obj);
};
typedef std::vector<NoteInfo> NoteInfoVec;
void to_json(Poco::JSON::Object &Obj) const; struct MobilePhoneNumber {
bool from_json(Poco::JSON::Object::Ptr &Obj); std::string number;
}; bool verified = false;
bool primary = false;
struct MfaAuthInfo { void to_json(Poco::JSON::Object &Obj) const;
bool enabled = false; bool from_json(Poco::JSON::Object::Ptr &Obj);
std::string method; };
void to_json(Poco::JSON::Object &Obj) const; struct MfaAuthInfo {
bool from_json(Poco::JSON::Object::Ptr &Obj); bool enabled = false;
}; std::string method;
struct UserLoginLoginExtensions { void to_json(Poco::JSON::Object &Obj) const;
std::vector<MobilePhoneNumber> mobiles; bool from_json(Poco::JSON::Object::Ptr &Obj);
struct MfaAuthInfo mfa; };
void to_json(Poco::JSON::Object &Obj) const; struct UserLoginLoginExtensions {
bool from_json(Poco::JSON::Object::Ptr &Obj); std::vector<MobilePhoneNumber> mobiles;
}; struct MfaAuthInfo mfa;
std::string authenticatorSecret;
struct MFAChallengeRequest { void to_json(Poco::JSON::Object &Obj) const;
std::string uuid; bool from_json(Poco::JSON::Object::Ptr &Obj);
std::string question; };
std::string method;
uint64_t created = std::time(nullptr);
void to_json(Poco::JSON::Object &Obj) const; struct MFAChallengeRequest {
bool from_json(Poco::JSON::Object::Ptr &Obj); std::string uuid;
}; std::string question;
std::string method;
uint64_t created = std::time(nullptr);
struct MFAChallengeResponse { void to_json(Poco::JSON::Object &Obj) const;
std::string uuid; bool from_json(Poco::JSON::Object::Ptr &Obj);
std::string answer; };
void to_json(Poco::JSON::Object &Obj) const; struct MFAChallengeResponse {
bool from_json(Poco::JSON::Object::Ptr &Obj); std::string uuid;
}; std::string answer;
struct UserInfo { void to_json(Poco::JSON::Object &Obj) const;
std::string Id; bool from_json(Poco::JSON::Object::Ptr &Obj);
std::string name; };
std::string description;
std::string avatar;
std::string email;
bool validated = false;
std::string validationEmail;
uint64_t validationDate = 0;
uint64_t creationDate = 0;
std::string validationURI;
bool changePassword = false;
uint64_t lastLogin = 0;
std::string currentLoginURI;
uint64_t lastPasswordChange = 0;
uint64_t lastEmailCheck = 0;
bool waitingForEmailCheck = false;
std::string locale;
NoteInfoVec notes;
std::string location;
std::string owner;
bool suspended = false;
bool blackListed = false;
USER_ROLE userRole;
UserLoginLoginExtensions userTypeProprietaryInfo;
std::string securityPolicy;
uint64_t securityPolicyChange = 0 ;
std::string currentPassword;
Types::StringVec lastPasswords;
std::string oauthType;
std::string oauthUserInfo;
void to_json(Poco::JSON::Object &Obj) const; struct UserInfo {
bool from_json(const Poco::JSON::Object::Ptr &Obj); std::string id;
}; std::string name;
typedef std::vector<UserInfo> UserInfoVec; std::string description;
std::string avatar;
std::string email;
bool validated = false;
std::string validationEmail;
uint64_t validationDate = 0;
uint64_t creationDate = 0;
std::string validationURI;
bool changePassword = false;
uint64_t lastLogin = 0;
std::string currentLoginURI;
uint64_t lastPasswordChange = 0;
uint64_t lastEmailCheck = 0;
bool waitingForEmailCheck = false;
std::string locale;
NoteInfoVec notes;
std::string location;
std::string owner;
bool suspended = false;
bool blackListed = false;
USER_ROLE userRole;
UserLoginLoginExtensions userTypeProprietaryInfo;
std::string securityPolicy;
uint64_t securityPolicyChange = 0 ;
std::string currentPassword;
OpenWifi::Types::StringVec lastPasswords;
std::string oauthType;
std::string oauthUserInfo;
uint64_t modified;
// bool append_from_json(Poco::JSON::Object::Ptr Obj, const UserInfo &UInfo, NoteInfoVec & Notes); void to_json(Poco::JSON::Object &Obj) const;
bool MergeNotes(Poco::JSON::Object::Ptr Obj, const UserInfo &UInfo, NoteInfoVec & Notes); bool from_json(const Poco::JSON::Object::Ptr &Obj);
bool MergeNotes(const NoteInfoVec & NewNotes, const UserInfo &UInfo, NoteInfoVec & ExistingNotes); };
typedef std::vector<UserInfo> UserInfoVec;
struct InternalServiceInfo { // bool append_from_json(Poco::JSON::Object::Ptr Obj, const UserInfo &UInfo, NoteInfoVec & Notes);
std::string privateURI; bool MergeNotes(Poco::JSON::Object::Ptr Obj, const UserInfo &UInfo, NoteInfoVec & Notes);
std::string publicURI; bool MergeNotes(const NoteInfoVec & NewNotes, const UserInfo &UInfo, NoteInfoVec & ExistingNotes);
std::string token;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
typedef std::vector<InternalServiceInfo> InternalServiceInfoVec;
struct InternalSystemServices { struct InternalServiceInfo {
std::string key; std::string privateURI;
std::string version; std::string publicURI;
InternalServiceInfoVec services; std::string token;
void to_json(Poco::JSON::Object &Obj) const; void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj); bool from_json(const Poco::JSON::Object::Ptr &Obj);
}; };
typedef std::vector<InternalServiceInfo> InternalServiceInfoVec;
struct SystemEndpoint { struct InternalSystemServices {
std::string type; std::string key;
uint64_t id = 0; std::string version;
std::string vendor{"OpenWiFi"}; InternalServiceInfoVec services;
std::string uri; void to_json(Poco::JSON::Object &Obj) const;
std::string authenticationType{"internal_v1"}; bool from_json(const Poco::JSON::Object::Ptr &Obj);
void to_json(Poco::JSON::Object &Obj) const; };
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
typedef std::vector<SystemEndpoint> SystemEndpointVec;
struct SystemEndpointList { struct SystemEndpoint {
SystemEndpointVec endpoints; std::string type;
void to_json(Poco::JSON::Object &Obj) const; uint64_t id = 0;
bool from_json(const Poco::JSON::Object::Ptr &Obj); std::string vendor{"OpenWiFi"};
}; std::string uri;
std::string authenticationType{"internal_v1"};
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
typedef std::vector<SystemEndpoint> SystemEndpointVec;
struct UserInfoAndPolicy { struct SystemEndpointList {
WebToken webtoken; SystemEndpointVec endpoints;
UserInfo userinfo; void to_json(Poco::JSON::Object &Obj) const;
void to_json(Poco::JSON::Object &Obj) const; bool from_json(const Poco::JSON::Object::Ptr &Obj);
bool from_json(const Poco::JSON::Object::Ptr &Obj); };
};
typedef std::map<std::string,SecurityObjects::UserInfoAndPolicy> UserInfoCache;
enum ResourceAccessType { struct UserInfoAndPolicy {
NONE, WebToken webtoken;
READ, UserInfo userinfo;
MODIFY, void to_json(Poco::JSON::Object &Obj) const;
DELETE, bool from_json(const Poco::JSON::Object::Ptr &Obj);
CREATE, };
TEST, typedef std::map<std::string,SecurityObjects::UserInfoAndPolicy> UserInfoCache;
MOVE
};
ResourceAccessType ResourceAccessTypeFromString(const std::string &s); enum ResourceAccessType {
std::string ResourceAccessTypeToString(const ResourceAccessType & T); NONE,
READ,
MODIFY,
DELETE,
CREATE,
TEST,
MOVE
};
struct ProfileAction { ResourceAccessType ResourceAccessTypeFromString(const std::string &s);
std::string resource; std::string ResourceAccessTypeToString(const ResourceAccessType & T);
ResourceAccessType access;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(Poco::JSON::Object::Ptr &Obj);
};
typedef std::vector<ProfileAction> ProfileActionVec;
struct SecurityProfile { struct ProfileAction {
uint64_t id=0; std::string resource;
std::string name; ResourceAccessType access;
std::string description; void to_json(Poco::JSON::Object &Obj) const;
ProfileActionVec policy; bool from_json(Poco::JSON::Object::Ptr &Obj);
std::string role; };
NoteInfoVec notes; typedef std::vector<ProfileAction> ProfileActionVec;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(Poco::JSON::Object::Ptr &Obj);
};
typedef std::vector<SecurityProfile> SecurityProfileVec;
struct SecurityProfileList { struct SecurityProfile {
SecurityProfileVec profiles; uint64_t id=0;
void to_json(Poco::JSON::Object &Obj) const; std::string name;
bool from_json(Poco::JSON::Object::Ptr &Obj); std::string description;
}; ProfileActionVec policy;
std::string role;
NoteInfoVec notes;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(Poco::JSON::Object::Ptr &Obj);
};
typedef std::vector<SecurityProfile> SecurityProfileVec;
enum LinkActions { struct SecurityProfileList {
FORGOT_PASSWORD=1, SecurityProfileVec profiles;
VERIFY_EMAIL void to_json(Poco::JSON::Object &Obj) const;
}; bool from_json(Poco::JSON::Object::Ptr &Obj);
};
struct ActionLink { enum LinkActions {
std::string id; FORGOT_PASSWORD=1,
uint64_t action; VERIFY_EMAIL,
std::string userId; SUB_FORGOT_PASSWORD,
std::string actionTemplate; SUB_VERIFY_EMAIL
Types::StringPairVec variables; };
std::string locale;
std::string message;
uint64_t sent=0;
uint64_t created=std::time(nullptr);
uint64_t expires=0;
uint64_t completed=0;
uint64_t canceled=0;
void to_json(Poco::JSON::Object &Obj) const; struct ActionLink {
bool from_json(Poco::JSON::Object::Ptr &Obj); std::string id;
}; uint64_t action;
std::string userId;
std::string actionTemplate;
Types::StringPairVec variables;
std::string locale;
std::string message;
uint64_t sent=0;
uint64_t created=std::time(nullptr);
uint64_t expires=0;
uint64_t completed=0;
uint64_t canceled=0;
bool userAction=true;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(Poco::JSON::Object::Ptr &Obj);
};
struct Preferences {
std::string id;
uint64_t modified;
Types::StringPairVec data;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(Poco::JSON::Object::Ptr &Obj);
};
struct SubMfaConfig {
std::string id;
std::string type;
std::string sms;
std::string email;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(Poco::JSON::Object::Ptr &Obj);
};
struct Token {
std::string token;
std::string refreshToken;
std::string tokenType;
std::string userName;
uint64_t created=0;
uint64_t expires=0;
uint64_t idleTimeout=0;
uint64_t revocationDate=0;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(Poco::JSON::Object::Ptr &Obj);
};
struct Avatar {
std::string id;
std::string type;
uint64_t created=0;
std::string name;
Poco::Data::LOB<char> avatar;
};
struct LoginRecordInfo {
std::string sessionId;
std::string userId;
std::string email;
uint64_t login=0;
uint64_t logout=0;
void to_json(Poco::JSON::Object &Obj) const;
};
}
} }
#endif //UCENTRAL_RESTAPI_SECURITYOBJECTS_H

View File

@@ -0,0 +1,547 @@
//
// Created by stephane bourque on 2021-10-27.
//
#include "RESTAPI_SubObjects.h"
#include "framework/MicroService.h"
using OpenWifi::RESTAPI_utils::field_to_json;
using OpenWifi::RESTAPI_utils::field_from_json;
namespace OpenWifi::SubObjects {
void HomeDeviceMode::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "enableLEDS", enableLEDS);
field_to_json(Obj, "type", type);
field_to_json(Obj, "subnet", subnet);
field_to_json(Obj, "subnetMask", subnetMask);
field_to_json(Obj, "startIP", startIP);
field_to_json(Obj, "endIP", endIP);
field_to_json(Obj, "created", created);
field_to_json(Obj, "modified", modified);
field_to_json(Obj, "subnetV6", subnetV6);
field_to_json(Obj, "subnetMaskV6", subnetMaskV6);
field_to_json(Obj, "startIPV6", startIPV6);
field_to_json(Obj, "endIPV6", endIPV6);
}
bool HomeDeviceMode::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "enableLEDS", enableLEDS);
field_from_json(Obj, "type", type);
field_from_json(Obj, "subnet", subnet);
field_from_json(Obj, "subnetMask", subnetMask);
field_from_json(Obj, "startIP", startIP);
field_from_json(Obj, "endIP", endIP);
field_from_json(Obj, "created", created);
field_from_json(Obj, "modified", modified);
field_from_json(Obj, "subnetV6", subnetV6);
field_from_json(Obj, "subnetMaskV6", subnetMaskV6);
field_from_json(Obj, "startIPV6", startIPV6);
field_from_json(Obj, "endIPV6", endIPV6);
return true;
} catch (...) {
}
return false;
}
void IPReservation::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "nickname", nickname);
field_to_json(Obj, "ipAddress", ipAddress);
field_to_json(Obj, "macAddress", macAddress);
}
bool IPReservation::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "nickname", nickname);
field_from_json(Obj, "ipAddress", ipAddress);
field_from_json(Obj, "macAddress", macAddress);
return true;
} catch (...) {
}
return false;
}
void IPReservationList::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "id", id);
field_to_json(Obj, "reservations", reservations);
field_to_json(Obj, "created", created);
field_to_json(Obj, "modified", modified);
}
bool IPReservationList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "id", id);
field_from_json(Obj, "reservations", reservations);
field_from_json(Obj, "created", created);
field_from_json(Obj, "modified", modified);
return true;
} catch (...) {
}
return false;
}
void DnsConfiguration::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "ISP", ISP);
field_to_json(Obj, "custom", custom);
field_to_json(Obj, "primary", primary);
field_to_json(Obj, "secondary", secondary);
field_to_json(Obj, "primaryV6", primaryV6);
field_to_json(Obj, "secondaryV6", secondaryV6);
}
bool DnsConfiguration::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "ISP", ISP);
field_from_json(Obj, "custom", custom);
field_from_json(Obj, "primary", primary);
field_from_json(Obj, "secondary", secondary);
field_from_json(Obj, "primaryV6", primaryV6);
field_from_json(Obj, "secondaryV6", secondaryV6);
return true;
} catch (...) {
}
return false;
}
void InternetConnection::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "type", type);
field_to_json(Obj, "username", username);
field_to_json(Obj, "password", password);
field_to_json(Obj, "ipAddress", ipAddress);
field_to_json(Obj, "subnetMask", subnetMask);
field_to_json(Obj, "defaultGateway", defaultGateway);
field_to_json(Obj, "sendHostname", sendHostname);
field_to_json(Obj, "primaryDns", primaryDns);
field_to_json(Obj, "secondaryDns", secondaryDns);
field_to_json(Obj, "created", created);
field_to_json(Obj, "modified", modified);
field_to_json(Obj, "ipV6Support", ipV6Support);
field_to_json(Obj, "ipAddressV6", ipAddressV6);
field_to_json(Obj, "subnetMaskV6", subnetMaskV6);
field_to_json(Obj, "defaultGatewayV6", defaultGatewayV6);
field_to_json(Obj, "primaryDnsV6", primaryDnsV6);
field_to_json(Obj, "secondaryDnsV6", secondaryDnsV6);
}
bool InternetConnection::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "type", type);
field_from_json(Obj, "username", username);
field_from_json(Obj, "password", password);
field_from_json(Obj, "ipAddress", ipAddress);
field_from_json(Obj, "subnetMask", subnetMask);
field_from_json(Obj, "defaultGateway", defaultGateway);
field_from_json(Obj, "sendHostname", sendHostname);
field_from_json(Obj, "primaryDns", primaryDns);
field_from_json(Obj, "secondaryDns", secondaryDns);
field_from_json(Obj, "created", created);
field_from_json(Obj, "modified", modified);
field_from_json(Obj, "ipV6Support", ipV6Support);
field_from_json(Obj, "ipAddressV6", ipAddressV6);
field_from_json(Obj, "subnetMaskV6", subnetMaskV6);
field_from_json(Obj, "defaultGatewayV6", defaultGatewayV6);
field_from_json(Obj, "primaryDnsV6", primaryDnsV6);
field_from_json(Obj, "secondaryDnsV6", secondaryDnsV6);
return true;
} catch (...) {
}
return false;
}
void WifiNetwork::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "type", type);
field_to_json(Obj, "name", name);
field_to_json(Obj, "password", password);
field_to_json(Obj, "encryption", encryption);
field_to_json(Obj, "bands", bands);
}
bool WifiNetwork::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "type", type);
field_from_json(Obj, "name", name);
field_from_json(Obj, "password", password);
field_from_json(Obj, "encryption", encryption);
field_from_json(Obj, "bands", bands);
return true;
} catch (...) {
}
return false;
}
void WifiNetworkList::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "wifiNetworks", wifiNetworks);
field_to_json(Obj, "created", created);
field_to_json(Obj, "modified", modified);
}
bool WifiNetworkList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "wifiNetworks", wifiNetworks);
field_from_json(Obj, "created", created);
field_from_json(Obj, "modified", modified);
return true;
} catch (...) {
}
return false;
}
void AccessTime::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "day", day);
field_to_json(Obj, "rangeList", rangeList);
}
bool AccessTime::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "day", day);
field_from_json(Obj, "rangeList", rangeList);
return true;
} catch (...) {
}
return false;
}
void AccessTimes::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "schedule", schedule);
field_to_json(Obj, "created", created);
field_to_json(Obj, "modified", modified);
}
bool AccessTimes::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "schedule", schedule);
field_from_json(Obj, "created", created);
field_from_json(Obj, "modified", modified);
return true;
} catch (...) {
}
return false;
}
void SubscriberDevice::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "name", name);
field_to_json(Obj, "description", description);
field_to_json(Obj, "macAddress", macAddress);
field_to_json(Obj, "manufacturer", manufacturer);
field_to_json(Obj, "firstContact", firstContact);
field_to_json(Obj, "lastContact", lastContact);
field_to_json(Obj, "group", group);
field_to_json(Obj, "icon", icon);
field_to_json(Obj, "suspended", suspended);
field_to_json(Obj, "ip", ip);
field_to_json(Obj, "schedule", schedule);
}
bool SubscriberDevice::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "name", name);
field_from_json(Obj, "description", description);
field_from_json(Obj, "macAddress", macAddress);
field_from_json(Obj, "manufacturer", manufacturer);
field_from_json(Obj, "firstContact", firstContact);
field_from_json(Obj, "lastContact", lastContact);
field_from_json(Obj, "group", group);
field_from_json(Obj, "icon", icon);
field_from_json(Obj, "suspended", suspended);
field_from_json(Obj, "ip", ip);
field_from_json(Obj, "schedule", schedule);
return true;
} catch (...) {
}
return false;
}
void SubscriberDeviceList::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "devices", devices);
field_to_json(Obj, "created", created);
field_to_json(Obj, "modified", modified);
}
bool SubscriberDeviceList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "devices", devices);
field_from_json(Obj, "created", created);
field_from_json(Obj, "modified", modified);
return true;
} catch (...) {
}
return false;
}
void Association::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "name", name);
field_to_json(Obj, "ssid", ssid);
field_to_json(Obj, "macAddress", macAddress);
field_to_json(Obj, "rssi", rssi);
field_to_json(Obj, "power", power);
field_to_json(Obj, "ipv4", ipv4);
field_to_json(Obj, "ipv6", ipv6);
field_to_json(Obj, "tx", tx);
field_to_json(Obj, "rx", rx);
}
bool Association::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "name", name);
field_from_json(Obj, "ssid", ssid);
field_from_json(Obj, "macAddress", macAddress);
field_from_json(Obj, "rssi", rssi);
field_from_json(Obj, "power", power);
field_from_json(Obj, "ipv4", ipv4);
field_from_json(Obj, "ipv6", ipv6);
field_from_json(Obj, "tx", tx);
field_from_json(Obj, "rx", rx);
return true;
} catch (...) {
}
return false;
}
void AssociationList::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "associations", associations);
field_to_json(Obj, "created", created);
field_to_json(Obj, "modified", modified);
}
bool AssociationList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "associations", associations);
field_from_json(Obj, "created", created);
field_from_json(Obj, "modified", modified);
return true;
} catch (...) {
}
return false;
}
void Client::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "macAddress", macAddress);
field_to_json(Obj, "speed", speed);
field_to_json(Obj, "mode", mode);
field_to_json(Obj, "ipv4", ipv4);
field_to_json(Obj, "ipv6", ipv6);
field_to_json(Obj, "tx", tx);
field_to_json(Obj, "rx", rx);
}
bool Client::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "macAddress", macAddress);
field_from_json(Obj, "speed", speed);
field_from_json(Obj, "mode", mode);
field_from_json(Obj, "ipv4", ipv4);
field_from_json(Obj, "ipv6", ipv6);
field_from_json(Obj, "tx", tx);
field_from_json(Obj, "rx", rx);
return true;
} catch (...) {
}
return false;
}
void ClientList::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "clients", clients);
field_to_json(Obj, "created", created);
field_to_json(Obj, "modified", modified);
}
bool ClientList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "clients", clients);
field_from_json(Obj, "created", created);
field_from_json(Obj, "modified", modified);
return true;
} catch (...) {
}
return false;
}
void Location::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "buildingName", buildingName);
field_to_json(Obj, "addressLines", addressLines);
field_to_json(Obj, "city", city);
field_to_json(Obj, "state", state);
field_to_json(Obj, "postal", postal);
field_to_json(Obj, "country", country);
field_to_json(Obj, "phones", phones);
field_to_json(Obj, "mobiles", mobiles);
}
bool Location::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "buildingName", buildingName);
field_from_json(Obj, "addressLines", addressLines);
field_from_json(Obj, "city", city);
field_from_json(Obj, "state", state);
field_from_json(Obj, "postal", postal);
field_from_json(Obj, "country", country);
field_from_json(Obj, "phones", phones);
field_from_json(Obj, "mobiles", mobiles);
return true;
} catch (...) {
}
return false;
}
void RadioHE::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "multipleBSSID", multipleBSSID);
field_to_json(Obj, "ema", ema);
field_to_json(Obj, "bssColor", bssColor);
}
bool RadioHE::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "multipleBSSID", multipleBSSID);
field_from_json(Obj, "ema", ema);
field_from_json(Obj, "bssColor", bssColor);
return true;
} catch (...) {
}
return false;
}
void RadioRates::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "beacon", beacon);
field_to_json(Obj, "multicast", multicast);
}
bool RadioRates::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "beacon", beacon);
field_from_json(Obj, "multicast", multicast);
return true;
} catch (...) {
}
return false;
}
void RadioInformation::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "band", band);
field_to_json(Obj, "bandwidth", bandwidth);
field_to_json(Obj, "channel", channel);
field_to_json(Obj, "country", country);
field_to_json(Obj, "channelMode", channelMode);
field_to_json(Obj, "channelWidth", channelWidth);
field_to_json(Obj, "requireMode", requireMode);
field_to_json(Obj, "txpower", txpower);
field_to_json(Obj, "legacyRates", legacyRates);
field_to_json(Obj, "beaconInterval", beaconInterval);
field_to_json(Obj, "dtimPeriod", dtimPeriod);
field_to_json(Obj, "maximumClients", maximumClients);
field_to_json(Obj, "rates", rates);
field_to_json(Obj, "he", he);
field_to_json(Obj, "rawInfo", rawInfo);
}
bool RadioInformation::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "band", band);
field_from_json(Obj, "bandwidth", bandwidth);
field_from_json(Obj, "channel", channel);
field_from_json(Obj, "country", country);
field_from_json(Obj, "channelMode", channelMode);
field_from_json(Obj, "channelWidth", channelWidth);
field_from_json(Obj, "requireMode", requireMode);
field_from_json(Obj, "txpower", txpower);
field_from_json(Obj, "legacyRates", legacyRates);
field_from_json(Obj, "beaconInterval", beaconInterval);
field_from_json(Obj, "dtimPeriod", dtimPeriod);
field_from_json(Obj, "maximumClients", maximumClients);
field_from_json(Obj, "rates", rates);
field_from_json(Obj, "he", he);
field_from_json(Obj, "rawInfo", rawInfo);
return true;
} catch (...) {
}
return false;
}
void AccessPoint::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "id", id);
field_to_json(Obj, "macAddress", macAddress);
field_to_json(Obj, "name", name);
field_to_json(Obj, "deviceType", deviceType);
field_to_json(Obj, "subscriberDevices", subscriberDevices);
field_to_json(Obj, "ipReservations", ipReservations);
field_to_json(Obj, "address", address);
field_to_json(Obj, "wifiNetworks", wifiNetworks);
field_to_json(Obj, "internetConnection", internetConnection);
field_to_json(Obj, "deviceMode", deviceMode);
field_to_json(Obj, "dnsConfiguration", dnsConfiguration);
field_to_json(Obj, "radios", radios);
field_to_json(Obj, "automaticUpgrade", automaticUpgrade);
field_to_json(Obj, "configurationUUID", configurationUUID);
}
bool AccessPoint::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "id", id);
field_from_json(Obj, "macAddress", macAddress);
field_from_json(Obj, "name", name);
field_from_json(Obj, "deviceType", deviceType);
field_from_json(Obj, "subscriberDevices", subscriberDevices);
field_from_json(Obj, "ipReservations", ipReservations);
field_from_json(Obj, "address", address);
field_from_json(Obj, "wifiNetworks", wifiNetworks);
field_from_json(Obj, "internetConnection", internetConnection);
field_from_json(Obj, "deviceMode", deviceMode);
field_from_json(Obj, "dnsConfiguration", dnsConfiguration);
field_from_json(Obj, "radios", radios);
field_from_json(Obj, "automaticUpgrade", automaticUpgrade);
field_from_json(Obj, "configurationUUID", configurationUUID);
return true;
} catch (...) {
}
return false;
}
void AccessPointList::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "list", list);
}
bool AccessPointList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "list", list);
return true;
} catch (...) {
}
return false;
}
void SubscriberInfo::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "id", id);
field_to_json(Obj, "userId", userId);
field_to_json(Obj, "firstName", firstName);
field_to_json(Obj, "initials", initials);
field_to_json(Obj, "lastName", lastName);
field_to_json(Obj, "phoneNumber", phoneNumber);
field_to_json(Obj, "secondaryEmail", secondaryEmail);
field_to_json(Obj, "accessPoints", accessPoints);
field_to_json(Obj, "serviceAddress", serviceAddress);
field_to_json(Obj, "billingAddress", billingAddress);
field_to_json(Obj, "created", created);
field_to_json(Obj, "modified", modified);
}
bool SubscriberInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "id", id);
field_from_json(Obj, "userId", userId);
field_from_json(Obj, "firstName", firstName);
field_from_json(Obj, "initials", initials);
field_from_json(Obj, "lastName", lastName);
field_from_json(Obj, "phoneNumber", phoneNumber);
field_from_json(Obj, "secondaryEmail", secondaryEmail);
field_from_json(Obj, "accessPoints", accessPoints);
field_from_json(Obj, "serviceAddress", serviceAddress);
field_from_json(Obj, "billingAddress", billingAddress);
field_from_json(Obj, "created", created);
field_from_json(Obj, "modified", modified);
return true;
} catch (...) {
}
return false;
}
}

View File

@@ -0,0 +1,293 @@
//
// Created by stephane bourque on 2021-10-27.
//
#ifndef OWSUB_RESTAPI_SUBOBJECTS_H
#define OWSUB_RESTAPI_SUBOBJECTS_H
#include <string>
#include "Poco/JSON/Object.h"
namespace OpenWifi::SubObjects {
struct HomeDeviceMode {
bool enableLEDS = true;
std::string type; // bridge, manual, automatic
std::string subnet;
std::string subnetMask;
std::string startIP;
std::string endIP;
uint64_t created = 0 ;
uint64_t modified = 0 ;
std::string subnetV6;
int subnetMaskV6=0;
std::string startIPV6;
std::string endIPV6;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct IPReservation {
std::string nickname;
std::string ipAddress;
std::string macAddress;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct IPReservationList {
std::string id;
std::vector<IPReservation> reservations;
uint64_t created = 0 ;
uint64_t modified = 0 ;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct DnsConfiguration {
bool ISP=false;
bool custom=false;
std::string primary;
std::string secondary;
std::string primaryV6;
std::string secondaryV6;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct InternetConnection {
std::string type; // automatic, pppoe, manual
std::string username;
std::string password;
std::string ipAddress;
std::string subnetMask;
std::string defaultGateway;
bool sendHostname = true;
std::string primaryDns;
std::string secondaryDns;
uint64_t created=0;
uint64_t modified=0;
bool ipV6Support=false;
std::string ipAddressV6;
int subnetMaskV6=0;
std::string defaultGatewayV6;
std::string primaryDnsV6;
std::string secondaryDnsV6;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct WifiNetwork {
std::string type; // main, guest
std::string name;
std::string password;
std::string encryption;
std::vector<std::string> bands;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct WifiNetworkList {
std::vector<WifiNetwork> wifiNetworks;
uint64_t created=0;
uint64_t modified=0;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct AccessTime {
std::string day;
std::vector<std::string> rangeList;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct AccessTimes {
std::vector<AccessTime> schedule;
uint64_t created=0;
uint64_t modified=0;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct SubscriberDevice {
std::string name;
std::string description;
std::string macAddress;
std::string manufacturer;
uint64_t firstContact=0;
uint64_t lastContact=0;
std::string group;
std::string icon;
bool suspended=false;
std::string ip;
std::vector<AccessTimes> schedule;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct SubscriberDeviceList {
std::vector<SubscriberDevice> devices;
uint64_t created=0;
uint64_t modified=0;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct Association {
std::string name;
std::string ssid;
std::string macAddress;
int rssi=0;
int power=0;
std::string ipv4;
std::string ipv6;
uint64_t tx=0;
uint64_t rx=0;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct AssociationList {
std::vector<Association> associations;
uint64_t created=0;
uint64_t modified=0;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct Client {
std::string macAddress;
std::string speed;
std::string mode;
std::string ipv4;
std::string ipv6;
uint64_t tx=0;
uint64_t rx=0;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct ClientList {
std::vector<Client> clients;
uint64_t created=0;
uint64_t modified=0;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct Location {
std::string buildingName;
std::vector<std::string> addressLines;
std::string city;
std::string state;
std::string postal;
std::string country;
std::vector<std::string> phones;
std::vector<std::string> mobiles;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct RadioHE {
bool multipleBSSID = false;
bool ema = false;
uint64_t bssColor = 64;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct RadioRates {
uint64_t beacon = 6000;
uint64_t multicast = 24000;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct RadioInformation {
std::string band;
uint64_t bandwidth;
uint64_t channel = 0 ;
std::string country;
std::string channelMode{"HE"};
uint64_t channelWidth = 80;
std::string requireMode;
uint64_t txpower=0;
bool legacyRates = false;
uint64_t beaconInterval = 100;
uint64_t dtimPeriod = 2;
uint64_t maximumClients = 64;
RadioRates rates;
RadioHE he;
std::vector<std::string> rawInfo;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct AccessPoint {
std::string id;
std::string macAddress;
std::string name;
std::string deviceType;
SubscriberDeviceList subscriberDevices;
IPReservationList ipReservations;
Location address;
WifiNetworkList wifiNetworks;
InternetConnection internetConnection;
HomeDeviceMode deviceMode;
DnsConfiguration dnsConfiguration;
std::vector<RadioInformation> radios;
bool automaticUpgrade = true;
std::string configurationUUID;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct AccessPointList {
std::vector<AccessPoint> list;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct SubscriberInfo {
std::string id;
std::string userId;
std::string firstName;
std::string initials;
std::string lastName;
std::string phoneNumber;
std::string secondaryEmail;
AccessPointList accessPoints;
Location serviceAddress;
Location billingAddress;
uint64_t created = 0;
uint64_t modified = 0;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
}
#endif //OWSUB_RESTAPI_SUBOBJECTS_H

View File

@@ -13,18 +13,22 @@ namespace OpenWifi {
int Storage::Start() { int Storage::Start() {
std::lock_guard Guard(Mutex_); std::lock_guard Guard(Mutex_);
Logger_.setLevel(Poco::Message::PRIO_NOTICE);
StorageClass::Start(); StorageClass::Start();
Create_Tables(); HistoryDB_ = std::make_unique<OpenWifi::HistoryDB>(dbType_,*Pool_, Logger());
FirmwaresDB_ = std::make_unique<OpenWifi::FirmwaresDB>(dbType_,*Pool_, Logger());
DevicesDB_ = std::make_unique<OpenWifi::DevicesDB>(dbType_,*Pool_, Logger());
HistoryDB_->Create();
FirmwaresDB_->Create();
DevicesDB_->Create();
return 0; return 0;
} }
void Storage::Stop() { void Storage::Stop() {
std::lock_guard Guard(Mutex_); std::lock_guard Guard(Mutex_);
Logger_.notice("Stopping."); Logger().notice("Stopping.");
StorageClass::Stop(); StorageClass::Stop();
} }

View File

@@ -13,61 +13,43 @@
#include "framework/StorageClass.h" #include "framework/StorageClass.h"
#include "RESTObjects/RESTAPI_FMSObjects.h" #include "RESTObjects/RESTAPI_FMSObjects.h"
#include "storage/storage_firmwares.h"
#include "storage/storage_history.h" #include "storage/orm_history.h"
#include "storage/storage_deviceTypes.h" #include "storage/orm_firmwares.h"
#include "storage/storage_deviceInfo.h" #include "storage/orm_deviceInfo.h"
namespace OpenWifi { namespace OpenWifi {
class Storage : public StorageClass { class Storage : public StorageClass {
public: public:
int Create_Tables();
int Create_Firmwares();
int Create_History();
int Create_DeviceTypes();
int Create_DeviceInfo();
bool AddFirmware(FMSObjects::Firmware & F);
bool UpdateFirmware(std::string & UUID, FMSObjects::Firmware & C);
bool DeleteFirmware(std::string & UUID);
bool GetFirmware(std::string & UUID, FMSObjects::Firmware & C);
bool GetFirmwares(uint64_t From, uint64_t HowMany, std::string & Compatible, FMSObjects::FirmwareVec & Firmwares);
bool BuildFirmwareManifest(Poco::JSON::Object & Manifest, uint64_t & Version);
bool GetFirmwareByName(std::string & Release, std::string &DeviceType,FMSObjects::Firmware & C );
bool GetFirmwareByRevision(std::string & Revision, std::string &DeviceType,FMSObjects::Firmware & C );
bool ComputeFirmwareAge(std::string & DeviceType, std::string & Revision, FMSObjects::FirmwareAgeDetails &AgeDetails);
bool GetHistory(std::string &SerialNumber,uint64_t From, uint64_t HowMany,FMSObjects::RevisionHistoryEntryVec &History);
bool AddHistory(FMSObjects::RevisionHistoryEntry &History);
void PopulateLatestFirmwareCache();
void RemoveOldFirmware();
int Start() override; int Start() override;
void Stop() override; void Stop() override;
bool SetDeviceRevision(std::string &SerialNumber, std::string & Revision, std::string & DeviceType, std::string &EndPoint); int Create_Tables();
bool AddHistory( std::string & SerialNumber, std::string &DeviceType, std::string & PreviousRevision, std::string & NewVersion); int Create_DeviceTypes();
bool DeleteHistory( std::string & SerialNumber, std::string &Id); int Create_DeviceInfo();
bool GetDevices(uint64_t From, uint64_t HowMany, std::vector<FMSObjects::DeviceConnectionInformation> & Devices); bool BuildFirmwareManifest(Poco::JSON::Object & Manifest, uint64_t & Version);
bool GetDevice(std::string &SerialNumber, FMSObjects::DeviceConnectionInformation & Device);
bool SetDeviceDisconnected(std::string &SerialNumber, std::string &EndPoint);
bool GenerateDeviceReport(FMSObjects::DeviceReport &Report);
static std::string TrimRevision(const std::string &R); static std::string TrimRevision(const std::string &R);
static Storage *instance() { static auto instance() {
static Storage *instance_ = new Storage; static auto instance_ = new Storage;
return instance_; return instance_;
} }
OpenWifi::HistoryDB & HistoryDB() { return * HistoryDB_; }
OpenWifi::FirmwaresDB & FirmwaresDB() { return * FirmwaresDB_; }
OpenWifi::DevicesDB & DevicesDB() { return * DevicesDB_; }
private: private:
std::unique_ptr<OpenWifi::HistoryDB> HistoryDB_;
std::unique_ptr<OpenWifi::FirmwaresDB> FirmwaresDB_;
std::unique_ptr<OpenWifi::DevicesDB> DevicesDB_;
}; };
inline class Storage * StorageService() { return Storage::instance(); }; inline auto StorageService() { return Storage::instance(); };
} // namespace } // namespace

93
src/framework/API_Proxy.h Normal file
View File

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

View File

@@ -2327,7 +2327,7 @@ namespace OpenWifi {
if(Utils::wgets(GitUCentralJSONSchemaFile, GitSchema)) { if(Utils::wgets(GitUCentralJSONSchemaFile, GitSchema)) {
auto schema = json::parse(GitSchema); auto schema = json::parse(GitSchema);
Validator_->set_root_schema(schema); Validator_->set_root_schema(schema);
Logger_.information("Using uCentral validation schema from GIT."); Logger().information("Using uCentral validation schema from GIT.");
} else { } else {
std::string FileName{ MicroService::instance().DataDir() + "/ucentral.schema.json" }; std::string FileName{ MicroService::instance().DataDir() + "/ucentral.schema.json" };
std::ifstream input(FileName); std::ifstream input(FileName);
@@ -2336,11 +2336,11 @@ namespace OpenWifi {
input.close(); input.close();
auto schema = json::parse(schema_file.str()); auto schema = json::parse(schema_file.str());
Validator_->set_root_schema(schema); Validator_->set_root_schema(schema);
Logger_.information("Using uCentral validation schema from local file."); Logger().information("Using uCentral validation schema from local file.");
} }
} catch (const Poco::Exception &E) { } catch (const Poco::Exception &E) {
Validator_->set_root_schema(DefaultUCentralSchema); Validator_->set_root_schema(DefaultUCentralSchema);
Logger_.information("Using uCentral validation from built-in default."); Logger().information("Using uCentral validation from built-in default.");
} }
Initialized_ = Working_ = true; Initialized_ = Working_ = true;
} }
@@ -2471,7 +2471,7 @@ namespace OpenWifi {
} }
void ConfigurationValidator::reinitialize(Poco::Util::Application &self) { void ConfigurationValidator::reinitialize(Poco::Util::Application &self) {
Logger_.information("Reinitializing."); Logger().information("Reinitializing.");
Working_ = Initialized_ = false; Working_ = Initialized_ = false;
Init(); Init();
} }

View File

@@ -2,8 +2,7 @@
// Created by stephane bourque on 2021-09-14. // Created by stephane bourque on 2021-09-14.
// //
#ifndef OWPROV_CONFIGURATIONVALIDATOR_H #pragma once
#define OWPROV_CONFIGURATIONVALIDATOR_H
#include <nlohmann/json-schema.hpp> #include <nlohmann/json-schema.hpp>
#include "framework/MicroService.h" #include "framework/MicroService.h"
@@ -43,4 +42,3 @@ namespace OpenWifi {
inline bool ValidateUCentralConfiguration(const std::string &C, std::string &Error) { return ConfigurationValidator::instance()->Validate(C, Error); } inline bool ValidateUCentralConfiguration(const std::string &C, std::string &Error) { return ConfigurationValidator::instance()->Validate(C, Error); }
} }
#endif //OWPROV_CONFIGURATIONVALIDATOR_H

View File

@@ -2,8 +2,7 @@
// Created by stephane bourque on 2021-10-08. // Created by stephane bourque on 2021-10-08.
// //
#ifndef OWPROV_COUNTRYCODES_H #pragma once
#define OWPROV_COUNTRYCODES_H
#include <vector> #include <vector>
#include <string> #include <string>
@@ -270,4 +269,3 @@ namespace OpenWifi {
} }
#endif //OWPROV_COUNTRYCODES_H

View File

@@ -5,8 +5,8 @@
// Created by Stephane Bourque on 2021-03-04. // Created by Stephane Bourque on 2021-03-04.
// Arilia Wireless Inc. // Arilia Wireless Inc.
// //
#ifndef UCENTRALGW_KAFKA_TOPICS_H
#define UCENTRALGW_KAFKA_TOPICS_H #pragma once
namespace OpenWifi::KafkaTopics { namespace OpenWifi::KafkaTopics {
static const std::string HEALTHCHECK{"healthcheck"}; static const std::string HEALTHCHECK{"healthcheck"};
@@ -17,6 +17,7 @@ namespace OpenWifi::KafkaTopics {
static const std::string COMMAND{"command"}; static const std::string COMMAND{"command"};
static const std::string SERVICE_EVENTS{"service_events"}; static const std::string SERVICE_EVENTS{"service_events"};
static const std::string DEVICE_EVENT_QUEUE{"device_event_queue"}; static const std::string DEVICE_EVENT_QUEUE{"device_event_queue"};
static const std::string DEVICE_TELEMETRY{"device_telemetry"};
namespace ServiceEvents { namespace ServiceEvents {
static const std::string EVENT_JOIN{"join"}; static const std::string EVENT_JOIN{"join"};
@@ -37,4 +38,3 @@ namespace OpenWifi::KafkaTopics {
} }
} }
#endif // UCENTRALGW_KAFKA_TOPICS_H

File diff suppressed because it is too large Load Diff

View File

@@ -1,42 +1,38 @@
// //
// License type: BSD 3-Clause License // Created by stephane bourque on 2021-11-16.
// 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_UCENTRALTYPES_H #pragma once
#define UCENTRALGW_UCENTRALTYPES_H
#include <vector>
#include <string>
#include <map> #include <map>
#include <functional>
#include <list>
#include <utility> #include <utility>
#include <vector>
#include <functional>
#include <string>
#include <queue> #include <queue>
#include <list>
#include "Poco/StringTokenizer.h" #include <set>
#include "Poco/JSON/Parser.h"
#include "Poco/JSON/Stringifier.h"
namespace OpenWifi::Types { namespace OpenWifi::Types {
typedef std::pair<std::string,std::string> StringPair; typedef std::pair<std::string,std::string> StringPair;
typedef std::vector<StringPair> StringPairVec; typedef std::vector<StringPair> StringPairVec;
typedef std::queue<StringPair> StringPairQueue; typedef std::queue<StringPair> StringPairQueue;
typedef std::vector<std::string> StringVec; typedef std::vector<std::string> StringVec;
typedef std::set<std::string> StringSet; typedef std::set<std::string> StringSet;
typedef std::map<std::string,std::set<std::string>> StringMapStringSet; typedef std::map<std::string,std::set<std::string>> StringMapStringSet;
typedef std::function<void(std::string, std::string)> TopicNotifyFunction; typedef std::function<void(const std::string &, const std::string &)> TopicNotifyFunction;
typedef std::list<std::pair<TopicNotifyFunction,int>> TopicNotifyFunctionList; typedef std::list<std::pair<TopicNotifyFunction,int>> TopicNotifyFunctionList;
typedef std::map<std::string, TopicNotifyFunctionList> NotifyTable; typedef std::map<std::string, TopicNotifyFunctionList> NotifyTable;
typedef std::map<std::string,uint64_t> CountedMap; typedef std::map<std::string,uint64_t> CountedMap;
typedef std::vector<uint64_t> TagList; typedef std::vector<uint64_t> TagList;
typedef std::string UUID_t; typedef std::string UUID_t;
typedef std::vector<UUID_t> UUIDvec_t; typedef std::vector<UUID_t> UUIDvec_t;
typedef std::map<std::string,std::map<uint32_t,uint64_t>> Counted3DMapSII;
}
inline void UpdateCountedMap(CountedMap &M, const std::string &S, uint64_t Increment=1) { namespace OpenWifi {
inline void UpdateCountedMap(OpenWifi::Types::CountedMap &M, const std::string &S, uint64_t Increment=1) {
auto it = M.find(S); auto it = M.find(S);
if(it==M.end()) if(it==M.end())
M[S] = Increment; M[S] = Increment;
@@ -44,60 +40,21 @@ namespace OpenWifi::Types {
it->second += Increment; it->second += Increment;
} }
inline std::string to_string( const StringVec &V) { inline void UpdateCountedMap(OpenWifi::Types::Counted3DMapSII &M, const std::string &S, uint32_t Index, uint64_t Increment=1) {
Poco::JSON::Array O; auto it = M.find(S);
for(const auto &i:V) { if(it==M.end()) {
O.add(i); std::map<uint32_t,uint64_t> E;
E[Index] = Increment;
M[S] = E;
} }
std::stringstream SS; else {
Poco::JSON::Stringifier::stringify(O,SS); std::map<uint32_t,uint64_t> & IndexMap = it->second;
return SS.str(); auto it_index = IndexMap.find(Index);
} if(it_index == IndexMap.end()) {
IndexMap[Index] = Increment;
inline std::string to_string( const StringPairVec &V) { } else {
Poco::JSON::Array O; it_index->second += Increment;
for(const auto &i:V) {
Poco::JSON::Array OO;
OO.add(i.first);
OO.add(i.second);
O.add(OO);
}
std::stringstream SS;
Poco::JSON::Stringifier::stringify(O,SS);
return SS.str();
}
inline void from_string(const std::string &S, StringPairVec &V) {
try {
Poco::JSON::Parser P;
auto O = P.parse(S).extract<Poco::JSON::Array::Ptr>();
for(const auto &i:*O) {
auto Inner = i.extract<Poco::JSON::Array::Ptr>();
for(const auto &j:*Inner) {
auto S1 = i[0].toString();
auto S2 = i[1].toString();
V.push_back(std::make_pair(S1,S2));
}
} }
} catch (...) {
} }
} }
}
inline void from_string(const std::string &S, StringVec &V) {
try {
Poco::JSON::Parser P;
auto O = P.parse(S).extract<Poco::JSON::Array::Ptr>();
for(auto const &i:*O) {
V.push_back(i.toString());
}
} catch (...) {
}
}
};
#endif // UCENTRALGW_UCENTRALTYPES_H

View File

@@ -2,8 +2,7 @@
// Created by stephane bourque on 2021-09-12. // Created by stephane bourque on 2021-09-12.
// //
#ifndef OWPROV_RESTAPI_ERRORS_H #pragma once
#define OWPROV_RESTAPI_ERRORS_H
namespace OpenWifi::RESTAPI::Errors { namespace OpenWifi::RESTAPI::Errors {
static const std::string MissingUUID{"Missing UUID."}; static const std::string MissingUUID{"Missing UUID."};
@@ -15,7 +14,7 @@ namespace OpenWifi::RESTAPI::Errors {
static const std::string CouldNotBeDeleted{"Element could not be deleted."}; static const std::string CouldNotBeDeleted{"Element could not be deleted."};
static const std::string NameMustBeSet{"The name property must be set."}; static const std::string NameMustBeSet{"The name property must be set."};
static const std::string ConfigBlockInvalid{"Configuration block type invalid."}; static const std::string ConfigBlockInvalid{"Configuration block type invalid."};
static const std::string UnknownId{"Unknown management policy."}; static const std::string UnknownId{"Unknown UUID."};
static const std::string InvalidDeviceTypes{"Unknown or invalid device type(s)."}; static const std::string InvalidDeviceTypes{"Unknown or invalid device type(s)."};
static const std::string RecordNotCreated{"Record could not be created."}; static const std::string RecordNotCreated{"Record could not be created."};
static const std::string RecordNotUpdated{"Record could not be updated."}; static const std::string RecordNotUpdated{"Record could not be updated."};
@@ -60,6 +59,10 @@ namespace OpenWifi::RESTAPI::Errors {
static const std::string MissingAuthenticationInformation{"Missing authentication information."}; static const std::string MissingAuthenticationInformation{"Missing authentication information."};
static const std::string InsufficientAccessRights{"Insufficient access rights to complete the operation."}; static const std::string InsufficientAccessRights{"Insufficient access rights to complete the operation."};
static const std::string ExpiredToken{"Token has expired, user must login."}; static const std::string ExpiredToken{"Token has expired, user must login."};
static const std::string SubscriberMustExist{"Subscriber must exist."};
static const std::string AuthenticatorVerificationIncomplete{"Authenticator validation is not complete."};
static const std::string SMSCouldNotBeSentRetry{"SMS could not be sent to validate device, try later or change the phone number."};
static const std::string SMSCouldNotValidate{"Code and number could not be validated"};
static const std::string InvalidDeviceClass{"Invalid device class. Must be: any, venue, entity, or subscriber"};
} }
#endif //OWPROV_RESTAPI_ERRORS_H

View File

@@ -6,8 +6,7 @@
// Arilia Wireless Inc. // Arilia Wireless Inc.
// //
#ifndef UCENTRALGW_RESTAPI_PROTOCOL_H #pragma once
#define UCENTRALGW_RESTAPI_PROTOCOL_H
namespace OpenWifi::RESTAPI::Protocol { namespace OpenWifi::RESTAPI::Protocol {
static const char * CAPABILITIES = "capabilities"; static const char * CAPABILITIES = "capabilities";
@@ -85,11 +84,13 @@ namespace OpenWifi::RESTAPI::Protocol {
static const char * GETSUBSYSTEMNAMES = "getsubsystemnames"; static const char * GETSUBSYSTEMNAMES = "getsubsystemnames";
static const char * GETLOGLEVELNAMES = "getloglevelnames"; static const char * GETLOGLEVELNAMES = "getloglevelnames";
static const char * STATS = "stats"; static const char * STATS = "stats";
static const char * PING = "ping";
static const char * PARAMETERS = "parameters"; static const char * PARAMETERS = "parameters";
static const char * VALUE = "value"; static const char * VALUE = "value";
static const char * LASTONLY = "lastOnly"; static const char * LASTONLY = "lastOnly";
static const char * NEWEST = "newest"; static const char * NEWEST = "newest";
static const char * ACTIVESCAN = "activeScan"; static const char * ACTIVESCAN = "activeScan";
static const char * OVERRIDEDFS = "override_dfs";
static const char * LIST = "list"; static const char * LIST = "list";
static const char * TAG = "tag"; static const char * TAG = "tag";
static const char * TAGLIST = "tagList"; static const char * TAGLIST = "tagList";
@@ -136,5 +137,3 @@ namespace OpenWifi::RESTAPI::Protocol {
static const char * UI = "UI"; static const char * UI = "UI";
} }
#endif // UCENTRALGW_RESTAPI_PROTOCOL_H

View File

@@ -2,8 +2,7 @@
// Created by stephane bourque on 2021-10-06. // Created by stephane bourque on 2021-10-06.
// //
#ifndef OPENWIFI_STORAGE_H #pragma once
#define OPENWIFI_STORAGE_H
#include "Poco/Data/Session.h" #include "Poco/Data/Session.h"
#include "Poco/Data/SessionPool.h" #include "Poco/Data/SessionPool.h"
@@ -34,8 +33,8 @@ namespace OpenWifi {
int Start() override { int Start() override {
std::lock_guard Guard(Mutex_); std::lock_guard Guard(Mutex_);
Logger_.setLevel(Poco::Message::PRIO_NOTICE); Logger().setLevel(Poco::Message::PRIO_INFORMATION);
Logger_.notice("Starting."); Logger().notice("Starting.");
std::string DBType = MicroService::instance().ConfigGetString("storage.type"); std::string DBType = MicroService::instance().ConfigGetString("storage.type");
if (DBType == "sqlite") { if (DBType == "sqlite") {
@@ -52,37 +51,6 @@ namespace OpenWifi {
Pool_->shutdown(); Pool_->shutdown();
} }
[[nodiscard]] inline std::string ComputeRange(uint64_t From, uint64_t HowMany) {
if(dbType_==sqlite) {
return " LIMIT " + std::to_string(From-1) + ", " + std::to_string(HowMany) + " ";
} else if(dbType_==pgsql) {
return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From-1) + " ";
} else if(dbType_==mysql) {
return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From-1) + " ";
}
return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From-1) + " ";
}
inline std::string ConvertParams(const std::string & S) const {
std::string R;
R.reserve(S.size()*2+1);
if(dbType_==pgsql) {
auto Idx=1;
for(auto const & i:S)
{
if(i=='?') {
R += '$';
R.append(std::to_string(Idx++));
} else {
R += i;
}
}
} else {
R = S;
}
return R;
}
private: private:
inline int Setup_SQLite(); inline int Setup_SQLite();
inline int Setup_MySQL(); inline int Setup_MySQL();
@@ -102,7 +70,7 @@ namespace OpenWifi {
#else #else
inline int StorageClass::Setup_SQLite() { inline int StorageClass::Setup_SQLite() {
Logger_.notice("SQLite StorageClass enabled."); Logger().notice("SQLite StorageClass enabled.");
dbType_ = sqlite; dbType_ = sqlite;
auto DBName = MicroService::instance().DataDir() + "/" + MicroService::instance().ConfigGetString("storage.type.sqlite.db"); auto DBName = MicroService::instance().DataDir() + "/" + MicroService::instance().ConfigGetString("storage.type.sqlite.db");
auto NumSessions = MicroService::instance().ConfigGetInt("storage.type.sqlite.maxsessions", 64); auto NumSessions = MicroService::instance().ConfigGetInt("storage.type.sqlite.maxsessions", 64);
@@ -113,7 +81,7 @@ namespace OpenWifi {
} }
inline int StorageClass::Setup_MySQL() { inline int StorageClass::Setup_MySQL() {
Logger_.notice("MySQL StorageClass enabled."); Logger().notice("MySQL StorageClass enabled.");
dbType_ = mysql; dbType_ = mysql;
auto NumSessions = MicroService::instance().ConfigGetInt("storage.type.mysql.maxsessions", 64); auto NumSessions = MicroService::instance().ConfigGetInt("storage.type.mysql.maxsessions", 64);
auto IdleTime = MicroService::instance().ConfigGetInt("storage.type.mysql.idletime", 60); auto IdleTime = MicroService::instance().ConfigGetInt("storage.type.mysql.idletime", 60);
@@ -138,7 +106,7 @@ namespace OpenWifi {
} }
inline int StorageClass::Setup_PostgreSQL() { inline int StorageClass::Setup_PostgreSQL() {
Logger_.notice("PostgreSQL StorageClass enabled."); Logger().notice("PostgreSQL StorageClass enabled.");
dbType_ = pgsql; dbType_ = pgsql;
auto NumSessions = MicroService::instance().ConfigGetInt("storage.type.postgresql.maxsessions", 64); auto NumSessions = MicroService::instance().ConfigGetInt("storage.type.postgresql.maxsessions", 64);
auto IdleTime = MicroService::instance().ConfigGetInt("storage.type.postgresql.idletime", 60); auto IdleTime = MicroService::instance().ConfigGetInt("storage.type.postgresql.idletime", 60);
@@ -165,5 +133,3 @@ namespace OpenWifi {
#endif #endif
} }
#endif //OPENWIFI_STORAGE_H

View File

@@ -6,8 +6,7 @@
// Arilia Wireless Inc. // Arilia Wireless Inc.
// //
#ifndef __OPENWIFI_ORM_H__ #pragma once
#define __OPENWIFI_ORM_H__
#include <string> #include <string>
#include <memory> #include <memory>
@@ -33,7 +32,8 @@ namespace ORM {
FT_BIGINT, FT_BIGINT,
FT_TEXT, FT_TEXT,
FT_VARCHAR, FT_VARCHAR,
FT_BLOB FT_BLOB,
FT_BOOLEAN
}; };
enum Indextype { enum Indextype {
@@ -97,21 +97,22 @@ namespace ORM {
case FT_INT: return "INT"; case FT_INT: return "INT";
case FT_BIGINT: return "BIGINT"; case FT_BIGINT: return "BIGINT";
case FT_TEXT: return "TEXT"; case FT_TEXT: return "TEXT";
case FT_BOOLEAN: return "BOOLEAN";
case FT_VARCHAR: case FT_VARCHAR:
if(Size) if(Size)
return std::string("VARCHAR(") + std::to_string(Size) + std::string(")"); return std::string("VARCHAR(") + std::to_string(Size) + std::string(")");
else else
return "TEXT"; return "TEXT";
case FT_BLOB: case FT_BLOB:
if(Type==OpenWifi::DBType::mysql) if(Type==OpenWifi::DBType::mysql)
return "LONGBLOB"; return "LONGBLOB";
else if(Type==OpenWifi::DBType::pgsql) else if(Type==OpenWifi::DBType::pgsql)
return "BYTEA"; return "BYTEA";
else if(Type==OpenWifi::DBType::sqlite) else if(Type==OpenWifi::DBType::sqlite)
return "BLOB"; return "BLOB";
default: default:
assert(false); assert(false);
return ""; return "";
} }
assert(false); assert(false);
return ""; return "";
@@ -154,28 +155,46 @@ namespace ORM {
return S; return S;
} }
template <typename RecordType> class DBCache {
public:
DBCache(unsigned Size, unsigned Timeout)
{
}
virtual void Create(const RecordType &R)=0;
virtual bool GetFromCache(const std::string &FieldName, const std::string &Value, RecordType &R)=0;
virtual void UpdateCache(const RecordType &R)=0;
virtual void Delete(const std::string &FieldName, const std::string &Value)=0;
private:
};
template <typename RecordTuple, typename RecordType> class DB { template <typename RecordTuple, typename RecordType> class DB {
public: public:
typedef const char * field_name_t;
DB( OpenWifi::DBType dbtype, DB( OpenWifi::DBType dbtype,
const char *TableName, const char *TableName,
const FieldVec & Fields, const FieldVec & Fields,
const IndexVec & Indexes, const IndexVec & Indexes,
Poco::Data::SessionPool & Pool, Poco::Data::SessionPool & Pool,
Poco::Logger &L, Poco::Logger &L,
const char *Prefix): const char *Prefix,
Type(dbtype), DBCache<RecordType> * Cache=nullptr):
DBName(TableName), Type_(dbtype),
TableName_(TableName),
Pool_(Pool), Pool_(Pool),
Logger_(L), Logger_(L),
Prefix_(Prefix) Prefix_(Prefix),
Cache_(Cache)
{ {
assert(RecordTuple::length == Fields.size());
bool first = true; bool first = true;
int Place=0; int Place=0;
assert( RecordTuple::length == Fields.size());
for(const auto &i:Fields) { for(const auto &i:Fields) {
FieldNames_[i.Name] = Place; FieldNames_[i.Name] = Place;
if(!first) { if(!first) {
CreateFields_ += ", "; CreateFields_ += ", ";
@@ -186,7 +205,7 @@ namespace ORM {
SelectList_ += "("; SelectList_ += "(";
} }
CreateFields_ += i.Name + " " + FieldTypeToChar(Type, i.Type,i.Size) + (i.Index ? " unique primary key" : ""); CreateFields_ += i.Name + " " + FieldTypeToChar(Type_, i.Type,i.Size) + (i.Index ? " unique primary key" : "");
SelectFields_ += i.Name ; SelectFields_ += i.Name ;
UpdateFields_ += i.Name + "=?"; UpdateFields_ += i.Name + "=?";
SelectList_ += "?"; SelectList_ += "?";
@@ -196,11 +215,11 @@ namespace ORM {
SelectList_ += ")"; SelectList_ += ")";
if(!Indexes.empty()) { if(!Indexes.empty()) {
if(Type==OpenWifi::DBType::sqlite || Type==OpenWifi::DBType::pgsql) { if(Type_==OpenWifi::DBType::sqlite || Type_==OpenWifi::DBType::pgsql) {
for(const auto &j:Indexes) { for(const auto &j:Indexes) {
std::string IndexLine; std::string IndexLine;
IndexLine = std::string("CREATE INDEX IF NOT EXISTS ") + j.Name + std::string(" ON ") + DBName + " ("; IndexLine = std::string("CREATE INDEX IF NOT EXISTS ") + j.Name + std::string(" ON ") + TableName_+ " (";
bool first_entry=true; bool first_entry=true;
for(const auto &k:j.Entries) { for(const auto &k:j.Entries) {
assert(FieldNames_.find(k.FieldName) != FieldNames_.end()); assert(FieldNames_.find(k.FieldName) != FieldNames_.end());
@@ -210,10 +229,10 @@ namespace ORM {
first_entry = false; first_entry = false;
IndexLine += k.FieldName + std::string(" ") + std::string(k.Type == Indextype::ASC ? "ASC" : "DESC") ; IndexLine += k.FieldName + std::string(" ") + std::string(k.Type == Indextype::ASC ? "ASC" : "DESC") ;
} }
IndexLine += " );"; IndexLine += " )";
IndexCreation += IndexLine; IndexCreation_.template emplace_back(IndexLine);
} }
} else if(Type==OpenWifi::DBType::mysql) { } else if(Type_==OpenWifi::DBType::mysql) {
bool firstIndex = true; bool firstIndex = true;
std::string IndexLine; std::string IndexLine;
for(const auto &j:Indexes) { for(const auto &j:Indexes) {
@@ -232,7 +251,7 @@ namespace ORM {
} }
IndexLine += " ) "; IndexLine += " ) ";
} }
IndexCreation = IndexLine; IndexCreation_.template emplace_back(IndexLine);
} }
} }
} }
@@ -242,22 +261,27 @@ namespace ORM {
[[nodiscard]] const std::string & SelectList() const { return SelectList_; }; [[nodiscard]] const std::string & SelectList() const { return SelectList_; };
[[nodiscard]] const std::string & UpdateFields() const { return UpdateFields_; }; [[nodiscard]] const std::string & UpdateFields() const { return UpdateFields_; };
inline std::string OP(const char *F, SqlComparison O , int V) { inline std::string OP(field_name_t F, SqlComparison O , bool V) {
assert( FieldNames_.find(F) != FieldNames_.end() );
return std::string{"("} + F + SQLCOMPS[O] + (V ? "true" : "false") + ")" ;
}
inline std::string OP(field_name_t F, SqlComparison O , int V) {
assert( FieldNames_.find(F) != FieldNames_.end() ); assert( FieldNames_.find(F) != FieldNames_.end() );
return std::string{"("} + F + SQLCOMPS[O] + std::to_string(V) + ")" ; return std::string{"("} + F + SQLCOMPS[O] + std::to_string(V) + ")" ;
} }
inline std::string OP(const char *F, SqlComparison O , uint64_t V) { inline std::string OP(field_name_t F, SqlComparison O , uint64_t V) {
assert( FieldNames_.find(F) != FieldNames_.end() ); assert( FieldNames_.find(F) != FieldNames_.end() );
return std::string{"("} + F + SQLCOMPS[O] + std::to_string(V) + ")" ; return std::string{"("} + F + SQLCOMPS[O] + std::to_string(V) + ")" ;
} }
std::string OP(const char *F, SqlComparison O , const std::string & V) { std::string OP(field_name_t F, SqlComparison O , const std::string & V) {
assert( FieldNames_.find(F) != FieldNames_.end() ); assert( FieldNames_.find(F) != FieldNames_.end() );
return std::string{"("} + F + SQLCOMPS[O] + "'" + Escape(V) + "')" ; return std::string{"("} + F + SQLCOMPS[O] + "'" + Escape(V) + "')" ;
} }
std::string OP(const char *F, SqlComparison O , const char * V) { std::string OP(field_name_t F, SqlComparison O , const char * V) {
assert( FieldNames_.find(F) != FieldNames_.end() ); assert( FieldNames_.find(F) != FieldNames_.end() );
return std::string{"("} + F + SQLCOMPS[O] + "'" + Escape(V) + "')" ; return std::string{"("} + F + SQLCOMPS[O] + "'" + Escape(V) + "')" ;
} }
@@ -278,35 +302,61 @@ namespace ORM {
return std::string{"("} + P1 + BOPS[BOP] + OP(true, P2, More...); return std::string{"("} + P1 + BOPS[BOP] + OP(true, P2, More...);
} }
bool Upgrade() {
uint32_t To;
return Upgrade(0, To);
}
inline bool Create() { inline bool Create() {
std::string S; switch(Type_) {
case OpenWifi::DBType::mysql: {
try {
Poco::Data::Session Session = Pool_.get();
std::string Statement = IndexCreation_.empty() ? "create table if not exists " + TableName_ +" ( " + CreateFields_ + " )" :
"create table if not exists " + TableName_ +" ( " + CreateFields_ + " ), " + IndexCreation_[0] + " )";
Session << Statement , Poco::Data::Keywords::now;
} catch (const Poco::Exception &E) {
Logger_.error("Failure to create MySQL DB resources.");
Logger_.log(E);
}
}
break;
if(Type==OpenWifi::DBType::mysql) { case OpenWifi::DBType::sqlite: {
if(IndexCreation.empty()) try {
S = "create table if not exists " + DBName +" ( " + CreateFields_ + " )" ; Poco::Data::Session Session = Pool_.get();
else std::string Statement = "create table if not exists " + TableName_ + " ( " + CreateFields_ + " )";
S = "create table if not exists " + DBName +" ( " + CreateFields_ + " ), " + IndexCreation + " )"; Session << Statement , Poco::Data::Keywords::now;
} else if (Type==OpenWifi::DBType::pgsql || Type==OpenWifi::DBType::sqlite) { for(const auto &i:IndexCreation_) {
S = "create table if not exists " + DBName + " ( " + CreateFields_ + " ); " + IndexCreation ; Session << i , Poco::Data::Keywords::now;
}
} catch (const Poco::Exception &E) {
Logger_.error("Failure to create SQLITE DB resources.");
Logger_.log(E);
}
}
break;
case OpenWifi::DBType::pgsql: {
try {
Poco::Data::Session Session = Pool_.get();
std::string Statement = "create table if not exists " + TableName_ + " ( " + CreateFields_ + " )";
Session << Statement , Poco::Data::Keywords::now;
for(const auto &i:IndexCreation_) {
Session << i , Poco::Data::Keywords::now;
}
} catch (const Poco::Exception &E) {
Logger_.error("Failure to create POSTGRESQL DB resources.");
Logger_.log(E);
}
}
break;
} }
return Upgrade();
// std::cout << "CREATE-DB: " << S << std::endl;
try {
Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement CreateStatement(Session);
CreateStatement << S;
CreateStatement.execute();
return true;
} catch (const Poco::Exception &E) {
std::cout << "Exception while creating DB: " << E.name() << std::endl;
}
return false;
} }
[[nodiscard]] std::string ConvertParams(const std::string & S) const { [[nodiscard]] std::string ConvertParams(const std::string & S) const {
if(Type!=OpenWifi::DBType::pgsql) if(Type_!=OpenWifi::DBType::pgsql)
return S; return S;
std::string R; std::string R;
@@ -325,45 +375,59 @@ namespace ORM {
return R; return R;
} }
void Convert( RecordTuple &in , RecordType &out); void Convert( const RecordTuple &in , RecordType &out);
void Convert( RecordType &in , RecordTuple &out); void Convert( const RecordType &in , RecordTuple &out);
inline const std::string & Prefix() { return Prefix_; }; inline const std::string & Prefix() { return Prefix_; };
bool CreateRecord( RecordType & R) { bool CreateRecord( const RecordType & R) {
try { try {
Poco::Data::Session Session = Pool_.get(); Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Insert(Session); Poco::Data::Statement Insert(Session);
RecordTuple RT; RecordTuple RT;
Convert(R, RT); Convert(R, RT);
std::string St = "insert into " + DBName + " ( " + SelectFields_ + " ) values " + SelectList_; std::string St = "insert into " + TableName_ + " ( " + SelectFields_ + " ) values " + SelectList_;
Insert << ConvertParams(St) , Insert << ConvertParams(St) ,
Poco::Data::Keywords::use(RT); Poco::Data::Keywords::use(RT);
Insert.execute(); Insert.execute();
if(Cache_)
Cache_->Create(R);
return true; return true;
} catch (const Poco::Exception &E) { } catch (const Poco::Exception &E) {
Logger_.log(E); Logger_.log(E);
} }
return false; return false;
} }
template<typename T> bool GetRecord( const char * FieldName, T Value, RecordType & R) { template<typename T> bool GetRecord(field_name_t FieldName, const T & Value, RecordType & R) {
try { try {
assert( FieldNames_.find(FieldName) != FieldNames_.end() ); assert( FieldNames_.find(FieldName) != FieldNames_.end() );
if(Cache_) {
if(Cache_->GetFromCache(FieldName, Value, R))
return true;
}
Poco::Data::Session Session = Pool_.get(); Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Select(Session); Poco::Data::Statement Select(Session);
RecordTuple RT; RecordTuple RT;
std::string St = "select " + SelectFields_ + " from " + DBName + " where " + FieldName + "=?" ; std::string St = "select " + SelectFields_ + " from " + TableName_ + " where " + FieldName + "=?" ;
auto tValue{Value};
Select << ConvertParams(St) , Select << ConvertParams(St) ,
Poco::Data::Keywords::into(RT), Poco::Data::Keywords::into(RT),
Poco::Data::Keywords::use(Value); Poco::Data::Keywords::use(tValue);
if(Select.execute()==1) { Select.execute();
if(Select.rowsExtracted()==1) {
Convert(RT,R); Convert(RT,R);
if(Cache_)
Cache_->UpdateCache(R);
return true; return true;
} }
return false; return false;
@@ -376,7 +440,7 @@ namespace ORM {
typedef std::vector<std::string> StringVec; typedef std::vector<std::string> StringVec;
template < typename T, template < typename T,
typename T0, typename T1> bool GR(const char *FieldName, T & R,T0 &V0, T1 &V1) { typename T0, typename T1> bool GR(field_name_t FieldName, T & R,T0 &V0, T1 &V1) {
try { try {
assert( FieldNames_.find(FieldName) != FieldNames_.end() ); assert( FieldNames_.find(FieldName) != FieldNames_.end() );
@@ -385,7 +449,7 @@ namespace ORM {
Poco::Data::Statement Select(Session); Poco::Data::Statement Select(Session);
RecordTuple RT; RecordTuple RT;
std::string St = "select " + SelectFields_ + " from " + DBName std::string St = "select " + SelectFields_ + " from " + TableName_
+ " where " + FieldName[0] + "=? and " + FieldName[1] + "=?" ; + " where " + FieldName[0] + "=? and " + FieldName[1] + "=?" ;
Select << ConvertParams(St) , Select << ConvertParams(St) ,
Poco::Data::Keywords::into(RT), Poco::Data::Keywords::into(RT),
@@ -410,14 +474,15 @@ namespace ORM {
Poco::Data::Session Session = Pool_.get(); Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Select(Session); Poco::Data::Statement Select(Session);
RecordList RL; RecordList RL;
std::string St = "select " + SelectFields_ + " from " + DBName + std::string St = "select " + SelectFields_ + " from " + TableName_ +
(Where.empty() ? "" : " where " + Where) + OrderBy + (Where.empty() ? "" : " where " + Where) + OrderBy +
ComputeRange(Offset, HowMany) ; ComputeRange(Offset, HowMany) ;
Select << St , Select << St ,
Poco::Data::Keywords::into(RL); Poco::Data::Keywords::into(RL);
Select.execute();
if(Select.execute()>0) { if(Select.rowsExtracted()>0) {
for(auto &i:RL) { for(auto &i:RL) {
RecordType R; RecordType R;
Convert(i, R); Convert(i, R);
@@ -432,7 +497,7 @@ namespace ORM {
return false; return false;
} }
template <typename T> bool UpdateRecord( const char *FieldName, T & Value, RecordType & R) { template <typename T> bool UpdateRecord(field_name_t FieldName, const T & Value, const RecordType & R) {
try { try {
assert( FieldNames_.find(FieldName) != FieldNames_.end() ); assert( FieldNames_.find(FieldName) != FieldNames_.end() );
@@ -443,11 +508,15 @@ namespace ORM {
Convert(R, RT); Convert(R, RT);
std::string St = "update " + DBName + " set " + UpdateFields_ + " where " + FieldName + "=?" ; auto tValue(Value);
std::string St = "update " + TableName_ + " set " + UpdateFields_ + " where " + FieldName + "=?" ;
Update << ConvertParams(St) , Update << ConvertParams(St) ,
Poco::Data::Keywords::use(RT), Poco::Data::Keywords::use(RT),
Poco::Data::Keywords::use(Value); Poco::Data::Keywords::use(tValue);
Update.execute(); Update.execute();
if(Cache_)
Cache_->UpdateCache(R);
return true; return true;
} catch (const Poco::Exception &E) { } catch (const Poco::Exception &E) {
Logger_.log(E); Logger_.log(E);
@@ -455,18 +524,32 @@ namespace ORM {
return false; return false;
} }
template <typename T> bool GetNameAndDescription(const char *FieldName, T & Value, std::string & Name, std::string & Description ) { template <typename T> bool ReplaceRecord(field_name_t FieldName, const T & Value, RecordType & R) {
try {
if(Exists(FieldName, Value)) {
return UpdateRecord(FieldName,Value,R);
}
return CreateRecord(R);
} catch (const Poco::Exception &E) {
Logger_.log(E);
}
return false;
}
template <typename T> bool GetNameAndDescription(field_name_t FieldName, const T & Value, std::string & Name, std::string & Description ) {
try { try {
assert( FieldNames_.find(FieldName) != FieldNames_.end() ); assert( FieldNames_.find(FieldName) != FieldNames_.end() );
Poco::Data::Session Session = Pool_.get(); Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Select(Session); Poco::Data::Statement Select(Session);
RecordTuple RT; RecordTuple RT;
std::string St = "select " + SelectFields_ + " from " + DBName + " where " + FieldName + "=?" ; std::string St = "select " + SelectFields_ + " from " + TableName_ + " where " + FieldName + "=?" ;
RecordType R; RecordType R;
auto tValue{Value};
Select << ConvertParams(St) , Select << ConvertParams(St) ,
Poco::Data::Keywords::into(RT), Poco::Data::Keywords::into(RT),
Poco::Data::Keywords::use(Value); Poco::Data::Keywords::use(tValue);
if(Select.execute()==1) { if(Select.execute()==1) {
Convert(RT,R); Convert(RT,R);
Name = R.info.name; Name = R.info.name;
@@ -480,17 +563,21 @@ namespace ORM {
return false; return false;
} }
template <typename T> bool DeleteRecord( const char *FieldName, T Value) { template <typename T> bool DeleteRecord(field_name_t FieldName, const T & Value) {
try { try {
assert( FieldNames_.find(FieldName) != FieldNames_.end() ); assert( FieldNames_.find(FieldName) != FieldNames_.end() );
Poco::Data::Session Session = Pool_.get(); Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Delete(Session); Poco::Data::Statement Delete(Session);
std::string St = "delete from " + DBName + " where " + FieldName + "=?" ; std::string St = "delete from " + TableName_ + " where " + FieldName + "=?" ;
auto tValue{Value};
Delete << ConvertParams(St) , Delete << ConvertParams(St) ,
Poco::Data::Keywords::use(Value); Poco::Data::Keywords::use(tValue);
Delete.execute(); Delete.execute();
if(Cache_)
Cache_->Delete(FieldName, Value);
return true; return true;
} catch (const Poco::Exception &E) { } catch (const Poco::Exception &E) {
Logger_.log(E); Logger_.log(E);
@@ -504,7 +591,7 @@ namespace ORM {
Poco::Data::Session Session = Pool_.get(); Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Delete(Session); Poco::Data::Statement Delete(Session);
std::string St = "delete from " + DBName + " where " + WhereClause; std::string St = "delete from " + TableName_ + " where " + WhereClause;
Delete << St; Delete << St;
Delete.execute(); Delete.execute();
return true; return true;
@@ -514,7 +601,7 @@ namespace ORM {
return false; return false;
} }
bool Exists(const char *FieldName, std::string & Value) { bool Exists(field_name_t FieldName, const std::string & Value) {
try { try {
assert( FieldNames_.find(FieldName) != FieldNames_.end() ); assert( FieldNames_.find(FieldName) != FieldNames_.end() );
@@ -528,15 +615,15 @@ namespace ORM {
return false; return false;
} }
bool Iterate( std::function<bool(const RecordType &R)> F) { bool Iterate( std::function<bool(const RecordType &R)> F, const std::string & WhereClause = "" ) {
try { try {
uint64_t Offset=1; uint64_t Offset=0;
uint64_t Batch=50; uint64_t Batch=50;
bool Done=false; bool Done=false;
while(!Done) { while(!Done) {
std::vector<RecordType> Records; std::vector<RecordType> Records;
if(GetRecords(Offset,Batch,Records)) { if(GetRecords(Offset,Batch,Records, WhereClause)) {
for(const auto &i:Records) { for(const auto &i:Records) {
if(!F(i)) if(!F(i))
return true; return true;
@@ -592,7 +679,7 @@ namespace ORM {
Poco::Data::Session Session = Pool_.get(); Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Select(Session); Poco::Data::Statement Select(Session);
std::string st{"SELECT COUNT(*) FROM " + DBName + " " + (Where.empty() ? "" : (" where " + Where)) }; std::string st{"SELECT COUNT(*) FROM " + TableName_ + " " + (Where.empty() ? "" : (" where " + Where)) };
Select << st , Select << st ,
Poco::Data::Keywords::into(Cnt); Poco::Data::Keywords::into(Cnt);
@@ -606,7 +693,7 @@ namespace ORM {
return 0; return 0;
} }
template <typename X> bool ManipulateVectorMember( X T, const char *FieldName, std::string & ParentUUID, std::string & ChildUUID, bool Add) { template <typename X> bool ManipulateVectorMember( X T, field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID, bool Add) {
try { try {
assert( FieldNames_.find(FieldName) != FieldNames_.end() ); assert( FieldNames_.find(FieldName) != FieldNames_.end() );
@@ -633,89 +720,122 @@ namespace ORM {
return false; return false;
} }
inline bool AddChild( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) { bool RunScript(const std::vector<std::string> & Statements, bool IgnoreExceptions=true) {
try {
Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Command(Session);
for(const auto &i:Statements) {
try {
Command << i, Poco::Data::Keywords::now;
} catch (const Poco::Exception &E) {
Logger_.log(E);
Logger_.error(Poco::format("The following statement '%s' generated an exception during a table upgrade. This maya or may not be a problem.", i));
}
if(!IgnoreExceptions) {
return false;
}
Command.reset(Session);
}
return true;
} catch (const Poco::Exception &E) {
Logger_.log(E);
}
return false;
}
virtual uint32_t Version() {
return 0;
}
virtual bool Upgrade(uint32_t from, uint32_t &to) {
to = from;
return true;
}
inline bool AddChild(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::children, FieldName, ParentUUID, ChildUUID, true); return ManipulateVectorMember(&RecordType::children, FieldName, ParentUUID, ChildUUID, true);
} }
inline bool DeleteChild( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) { inline bool DeleteChild(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::children, FieldName, ParentUUID, ChildUUID, false); return ManipulateVectorMember(&RecordType::children, FieldName, ParentUUID, ChildUUID, false);
} }
inline bool AddLocation( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) { inline bool AddLocation(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::locations, FieldName, ParentUUID, ChildUUID, true); return ManipulateVectorMember(&RecordType::locations, FieldName, ParentUUID, ChildUUID, true);
} }
inline bool DeleteLocation( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) { inline bool DeleteLocation(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::locations, FieldName, ParentUUID, ChildUUID, false); return ManipulateVectorMember(&RecordType::locations, FieldName, ParentUUID, ChildUUID, false);
} }
inline bool AddContact( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) { inline bool AddContact(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::contacts, FieldName, ParentUUID, ChildUUID, true); return ManipulateVectorMember(&RecordType::contacts, FieldName, ParentUUID, ChildUUID, true);
} }
inline bool DeleteContact( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) { inline bool DeleteContact(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::contacts, FieldName, ParentUUID, ChildUUID, false); return ManipulateVectorMember(&RecordType::contacts, FieldName, ParentUUID, ChildUUID, false);
} }
inline bool AddVenue( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) { inline bool AddVenue(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::venues, FieldName, ParentUUID, ChildUUID, true); return ManipulateVectorMember(&RecordType::venues, FieldName, ParentUUID, ChildUUID, true);
} }
inline bool DeleteVenue( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) { inline bool DeleteVenue(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::venues, FieldName, ParentUUID, ChildUUID, false); return ManipulateVectorMember(&RecordType::venues, FieldName, ParentUUID, ChildUUID, false);
} }
inline bool AddDevice( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) { inline bool AddDevice(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::devices, FieldName, ParentUUID, ChildUUID, true); return ManipulateVectorMember(&RecordType::devices, FieldName, ParentUUID, ChildUUID, true);
} }
inline bool DeleteDevice( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) { inline bool DeleteDevice(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::devices, FieldName, ParentUUID, ChildUUID, false); return ManipulateVectorMember(&RecordType::devices, FieldName, ParentUUID, ChildUUID, false);
} }
inline bool AddEntity( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) { inline bool AddEntity(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::entities, FieldName, ParentUUID, ChildUUID, true); return ManipulateVectorMember(&RecordType::entities, FieldName, ParentUUID, ChildUUID, true);
} }
inline bool DeleteEntity( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) { inline bool DeleteEntity(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::entities, FieldName, ParentUUID, ChildUUID, false); return ManipulateVectorMember(&RecordType::entities, FieldName, ParentUUID, ChildUUID, false);
} }
inline bool AddUser( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) { inline bool AddUser(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::users, FieldName, ParentUUID, ChildUUID, true); return ManipulateVectorMember(&RecordType::users, FieldName, ParentUUID, ChildUUID, true);
} }
inline bool DelUser( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) { inline bool DelUser(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::users, FieldName, ParentUUID, ChildUUID, false); return ManipulateVectorMember(&RecordType::users, FieldName, ParentUUID, ChildUUID, false);
} }
inline bool AddInUse(const char *FieldName, std::string & ParentUUID, const std::string & Prefix, const std::string & ChildUUID) { inline bool AddInUse(field_name_t FieldName, std::string & ParentUUID, const std::string & Prefix, const std::string & ChildUUID) {
std::string FakeUUID{ Prefix + ":" + ChildUUID}; std::string FakeUUID{ Prefix + ":" + ChildUUID};
return ManipulateVectorMember(&RecordType::inUse,FieldName, ParentUUID, FakeUUID, true); return ManipulateVectorMember(&RecordType::inUse,FieldName, ParentUUID, FakeUUID, true);
} }
inline bool DeleteInUse(const char *FieldName, std::string & ParentUUID, const std::string & Prefix, const std::string & ChildUUID) { inline bool DeleteInUse(field_name_t FieldName, std::string & ParentUUID, const std::string & Prefix, const std::string & ChildUUID) {
std::string FakeUUID{ Prefix + ":" + ChildUUID}; std::string FakeUUID{ Prefix + ":" + ChildUUID};
return ManipulateVectorMember(&RecordType::inUse,FieldName, ParentUUID, FakeUUID, false); return ManipulateVectorMember(&RecordType::inUse,FieldName, ParentUUID, FakeUUID, false);
} }
inline bool DeleteContact(const char *FieldName, std::string & ParentUUID, const std::string & ChildUUID) { inline bool DeleteContact(field_name_t FieldName, std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::contacts,FieldName, ParentUUID, ChildUUID, false); return ManipulateVectorMember(&RecordType::contacts,FieldName, ParentUUID, ChildUUID, false);
} }
inline bool AddContact(const char *FieldName, std::string & ParentUUID, const std::string & ChildUUID) { inline bool AddContact(field_name_t FieldName, std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::contacts,FieldName, ParentUUID, ChildUUID, true); return ManipulateVectorMember(&RecordType::contacts,FieldName, ParentUUID, ChildUUID, true);
} }
inline bool DeleteLocation(const char *FieldName, std::string & ParentUUID, const std::string & ChildUUID) { inline bool DeleteLocation(field_name_t FieldName, std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::locations,FieldName, ParentUUID, ChildUUID, false); return ManipulateVectorMember(&RecordType::locations,FieldName, ParentUUID, ChildUUID, false);
} }
inline bool AddLocation(const char *FieldName, std::string & ParentUUID, const std::string & ChildUUID) { inline bool AddLocation(field_name_t FieldName, std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::locations,FieldName, ParentUUID, ChildUUID, true); return ManipulateVectorMember(&RecordType::locations,FieldName, ParentUUID, ChildUUID, true);
} }
inline bool GetInUse(const char *FieldName, std::string & UUID, std::vector<std::string> & UUIDs ) { inline bool GetInUse(field_name_t FieldName, const std::string & UUID, std::vector<std::string> & UUIDs ) {
RecordType R; RecordType R;
if(GetRecord(FieldName,UUID,R)) { if(GetRecord(FieldName,UUID,R)) {
UUIDs = R.inUse; UUIDs = R.inUse;
@@ -725,34 +845,41 @@ namespace ORM {
} }
[[nodiscard]] inline std::string ComputeRange(uint64_t From, uint64_t HowMany) { [[nodiscard]] inline std::string ComputeRange(uint64_t From, uint64_t HowMany) {
if(From<1) From=1; if(From<1) From=0;
switch(Type) { switch(Type_) {
case OpenWifi::DBType::sqlite: case OpenWifi::DBType::sqlite:
return " LIMIT " + std::to_string(From-1) + ", " + std::to_string(HowMany) + " "; return " LIMIT " + std::to_string(From) + ", " + std::to_string(HowMany) + " ";
case OpenWifi::DBType::pgsql: case OpenWifi::DBType::pgsql:
return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From-1) + " "; return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) + " ";
case OpenWifi::DBType::mysql: case OpenWifi::DBType::mysql:
return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From-1) + " "; return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) + " ";
default: default:
return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From-1) + " "; return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) + " ";
} }
} }
Poco::Logger & Logger() { return Logger_; } Poco::Logger & Logger() { return Logger_; }
bool DeleteRecordsFromCache(const char *FieldName, const std::string &Value ) {
if(Cache_)
Cache_->Delete(FieldName, Value);
return true;
}
protected:
Poco::Data::SessionPool &Pool_;
Poco::Logger &Logger_;
std::string TableName_;
DBCache<RecordType> *Cache_= nullptr;
private: private:
OpenWifi::DBType Type; OpenWifi::DBType Type_;
std::string DBName;
std::string CreateFields_; std::string CreateFields_;
std::string SelectFields_; std::string SelectFields_;
std::string SelectList_; std::string SelectList_;
std::string UpdateFields_; std::string UpdateFields_;
std::string IndexCreation; std::vector<std::string> IndexCreation_;
std::map<std::string,int> FieldNames_; std::map<std::string,int> FieldNames_;
Poco::Data::SessionPool &Pool_;
Poco::Logger &Logger_;
std::string Prefix_; std::string Prefix_;
}; };
} }
#endif

View File

@@ -5,9 +5,7 @@
// Created by Stephane Bourque on 2021-03-04. // Created by Stephane Bourque on 2021-03-04.
// Arilia Wireless Inc. // Arilia Wireless Inc.
// //
#pragma once
#ifndef UCENTRALGW_UCENTRALPROTOCOL_H
#define UCENTRALGW_UCENTRALPROTOCOL_H
#include "Poco/String.h" #include "Poco/String.h"
@@ -40,6 +38,7 @@ namespace OpenWifi::uCentralProtocol {
static const char * LOGLINES = "loglines"; static const char * LOGLINES = "loglines";
static const char * SEVERITY = "severity"; static const char * SEVERITY = "severity";
static const char * ACTIVE = "active"; static const char * ACTIVE = "active";
static const char * OVERRIDEDFS = "override_dfs";
static const char * REBOOT = "reboot"; static const char * REBOOT = "reboot";
static const char * WHEN = "when"; static const char * WHEN = "when";
static const char * CONFIG = "config"; static const char * CONFIG = "config";
@@ -130,5 +129,3 @@ namespace OpenWifi::uCentralProtocol {
return ET_UNKNOWN; return ET_UNKNOWN;
}; };
} }
#endif // UCENTRALGW_UCENTRALPROTOCOL_H

13
src/ow_version.h.in Normal file
View File

@@ -0,0 +1,13 @@
//
// Created by stephane bourque on 2021-12-06.
//
#pragma once
#include <string>
namespace OW_VERSION {
inline static const std::string VERSION{"@CMAKE_PROJECT_VERSION@"};
inline static const std::string BUILD{"@BUILD_NUM@"};
inline static const std::string HASH{"@GIT_HASH@"};
}

View File

@@ -0,0 +1,119 @@
//
// Created by stephane bourque on 2021-12-29.
//
#include "orm_deviceInfo.h"
#include "StorageService.h"
/*
"serialNumber varchar(36) UNIQUE PRIMARY KEY, "
"revision varchar, "
"deviceType varchar, "
"endPoint varchar, "
"lastUpdate bigint, "
"status varchar "
*/
namespace OpenWifi {
static ORM::FieldVec DevicesDB_Fields{
ORM::Field{"serialNumber", 36, true},
ORM::Field{"revision", ORM::FieldType::FT_TEXT},
ORM::Field{"deviceType", ORM::FieldType::FT_TEXT},
ORM::Field{"endPoint", ORM::FieldType::FT_TEXT},
ORM::Field{"lastUpdate", ORM::FieldType::FT_BIGINT},
ORM::Field{"status", ORM::FieldType::FT_TEXT}
};
DevicesDB::DevicesDB(OpenWifi::DBType T,
Poco::Data::SessionPool &P, Poco::Logger &L) :
DB(T, "devices", DevicesDB_Fields,{}, P, L, "fdi") {
}
bool DevicesDB::SetDeviceRevision(std::string &SerialNumber, std::string & Revision, std::string & DeviceType, std::string &EndPoint) {
FMSObjects::DeviceConnectionInformation D;
if(GetRecord("serialNumber", SerialNumber, D)) {
if(D.revision!=Revision) {
StorageService()->HistoryDB().AddHistory(SerialNumber, DeviceType, D.revision, Revision);
}
D.revision = Revision;
D.deviceType = DeviceType;
D.endPoint = EndPoint;
D.status = "connected";
return UpdateRecord("serialNumber", SerialNumber, D);
} else {
FMSObjects::DeviceConnectionInformation DI{
.serialNumber = SerialNumber,
.revision = Revision,
.deviceType = DeviceType,
.endPoint = EndPoint,
.lastUpdate = (uint64_t)std::time(nullptr),
.status = "connected"};
return CreateRecord(DI);
}
}
bool DevicesDB::DeleteDevice( std::string & SerialNumber) {
return DeleteRecord("serialNumber", SerialNumber);
}
bool DevicesDB::SetDeviceDisconnected(std::string &SerialNumber, std::string &EndPoint) {
FMSObjects::DeviceConnectionInformation D;
if(GetRecord("serialNumber", SerialNumber, D)) {
D.status = "not connected";
D.endPoint = EndPoint;
return UpdateRecord("serialNumber", SerialNumber, D);
}
return false;
}
bool DevicesDB::GetDevices(uint64_t From, uint64_t HowMany, std::vector<FMSObjects::DeviceConnectionInformation> & Devices) {
return GetRecords(From, HowMany, Devices, "", " ORDER BY SerialNumber ASC ");
}
bool DevicesDB::GetDevice(std::string &SerialNumber, FMSObjects::DeviceConnectionInformation & Device) {
return GetRecord("serialNumber", SerialNumber, Device);
}
bool DevicesDB::GenerateDeviceReport(FMSObjects::DeviceReport &Report) {
Iterate([&Report](const FMSObjects::DeviceConnectionInformation &D) {
Report.numberOfDevices++;
UpdateCountedMap(Report.DeviceTypes_, D.deviceType);
UpdateCountedMap(Report.Revisions_, D.revision);
UpdateCountedMap(Report.Status_, D.status);
UpdateCountedMap(Report.EndPoints_, D.endPoint);
UpdateCountedMap(Report.OUI_, D.serialNumber.substr(0, 6));
FMSObjects::FirmwareAgeDetails Age;
if (StorageService()->FirmwaresDB().ComputeFirmwareAge(D.deviceType, D.revision, Age)) {
if (Age.latest) {
UpdateCountedMap(Report.UsingLatest_, D.revision);
} else if (Age.age == 0) {
UpdateCountedMap(Report.UnknownFirmwares_, D.revision);
} else {
UpdateCountedMap(Report.totalSecondsOld_,"total_seconds", Age.age);
}
}
return true;
});
return true;
}
}
template<> void ORM::DB<OpenWifi::DevicesRecordTuple, OpenWifi::FMSObjects::DeviceConnectionInformation>::Convert(const OpenWifi::DevicesRecordTuple &T, OpenWifi::FMSObjects::DeviceConnectionInformation &F ) {
F.serialNumber = T.get<0>();
F.revision = T.get<1>();
F.deviceType = T.get<2>();
F.endPoint = T.get<3>();
F.lastUpdate = T.get<4>();
F.status = T.get<5>();
}
template<> void ORM::DB<OpenWifi::DevicesRecordTuple, OpenWifi::FMSObjects::DeviceConnectionInformation>::Convert(const OpenWifi::FMSObjects::DeviceConnectionInformation &F, OpenWifi::DevicesRecordTuple &T ) {
T.set<0>(F.serialNumber);
T.set<1>(F.revision);
T.set<2>(F.deviceType);
T.set<3>(F.endPoint);
T.set<4>(F.lastUpdate);
T.set<5>(F.status);
}

View File

@@ -0,0 +1,34 @@
//
// Created by stephane bourque on 2021-12-29.
//
#pragma once
#include "framework/orm.h"
#include "RESTObjects/RESTAPI_FMSObjects.h"
namespace OpenWifi {
typedef Poco::Tuple<
std::string,
std::string,
std::string,
std::string,
uint64_t,
std::string> DevicesRecordTuple;
typedef std::vector<DevicesRecordTuple> DevicesRecordTupleList;
class DevicesDB : public ORM::DB<DevicesRecordTuple, FMSObjects::DeviceConnectionInformation> {
public:
DevicesDB(OpenWifi::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L);
bool SetDeviceRevision(std::string &SerialNumber, std::string & Revision, std::string & DeviceType, std::string &EndPoint);
bool DeleteDevice( std::string & SerialNumber);
bool SetDeviceDisconnected(std::string &SerialNumber, std::string &EndPoint);
bool GetDevices(uint64_t From, uint64_t HowMany, std::vector<FMSObjects::DeviceConnectionInformation> & Devices);
bool GetDevice(std::string &SerialNumber, FMSObjects::DeviceConnectionInformation & Device);
bool GenerateDeviceReport(FMSObjects::DeviceReport &Report);
private:
};
}

View File

@@ -0,0 +1,216 @@
//
// Created by stephane bourque on 2021-12-28.
//
#include "orm_firmwares.h"
#include "LatestFirmwareCache.h"
#include "ManifestCreator.h"
/*
"Id varchar(36) UNIQUE PRIMARY KEY, "
"release varchar, "
"deviceType varchar, "
"description varchar, "
"revision varchar, "
"uri varchar, "
"image varchar, "
"imageDate bigint, "
"size bigint, "
"downloadCount bigint, "
"firmwareHash varchar, "
"owner varchar, "
"location varchar, "
"uploader varchar, "
"digest varchar, "
"latest boolean, "
"notes text, "
"created bigint"
*/
namespace OpenWifi {
static ORM::FieldVec FirmwaresDB_Fields{
ORM::Field{"id", 36, true},
ORM::Field{"release", ORM::FieldType::FT_TEXT},
ORM::Field{"deviceType", ORM::FieldType::FT_TEXT},
ORM::Field{"description", ORM::FieldType::FT_TEXT},
ORM::Field{"revision", ORM::FieldType::FT_TEXT},
ORM::Field{"uri", ORM::FieldType::FT_TEXT},
ORM::Field{"image", ORM::FieldType::FT_TEXT},
ORM::Field{"imageDate", ORM::FieldType::FT_BIGINT},
ORM::Field{"size", ORM::FieldType::FT_BIGINT},
ORM::Field{"downloadCount", ORM::FieldType::FT_BIGINT},
ORM::Field{"firmwareHash", ORM::FieldType::FT_TEXT},
ORM::Field{"owner", ORM::FieldType::FT_TEXT},
ORM::Field{"location", ORM::FieldType::FT_TEXT},
ORM::Field{"uploader", ORM::FieldType::FT_TEXT},
ORM::Field{"digest", ORM::FieldType::FT_TEXT},
ORM::Field{"latest", ORM::FieldType::FT_BOOLEAN},
ORM::Field{"notes", ORM::FieldType::FT_TEXT},
ORM::Field{"created", ORM::FieldType::FT_BIGINT}
};
FirmwaresDB::FirmwaresDB(OpenWifi::DBType T,
Poco::Data::SessionPool &P, Poco::Logger &L) :
DB(T, "firmwares", FirmwaresDB_Fields,{}, P, L, "fws") {
}
bool FirmwaresDB::AddFirmware(FMSObjects::Firmware & F) {
// find the older software and change to latest = 0
F.id = MicroService::CreateUUID();
if (LatestFirmwareCache()->AddToCache(F.deviceType, F.revision, F.id, F.imageDate)) {
F.latest = true;
std::vector<FMSObjects::Firmware> Fs;
std::string WhereClause{" deviceType='" + F.deviceType + "' AND Latest=true "};
if (GetRecords(0, 200, Fs, WhereClause)) {
for (auto &i: Fs) {
i.latest = false;
UpdateRecord("id", i.id, i);
}
}
} else {
F.latest = false;
}
return CreateRecord(F);
}
bool FirmwaresDB::UpdateFirmware(std::string & Id, FMSObjects::Firmware & F) {
return UpdateRecord("id",Id, F);
}
bool FirmwaresDB::DeleteFirmware(std::string & Id) {
return DeleteRecord("id", Id);
}
void FirmwaresDB::RemoveOldFirmware() {
uint64_t Limit = std::time(nullptr) - ManifestCreator()->MaxAge();
std::string WhereClause{"imageDate < " + std::to_string(Limit)};
DeleteRecords(WhereClause);
}
bool FirmwaresDB::GetFirmware(std::string & Id, FMSObjects::Firmware & F) {
return GetRecord("id", Id, F);
}
bool FirmwaresDB::GetFirmwareByName(const std::string & Release, const std::string &DeviceType, FMSObjects::Firmware & Firmware ) {
std::string WhereClause{" release='" + Release + "' and DeviceType='" + DeviceType + "' "};
std::vector<FMSObjects::Firmware> Fs;
if(GetRecords(0,2,Fs,WhereClause)) {
Firmware = Fs[0];
return true;
}
return false;
}
bool FirmwaresDB::GetFirmwareByRevision(const std::string & Revision, const std::string &DeviceType,FMSObjects::Firmware & Firmware ) {
std::string WhereClause{" Revision='" + Revision + "' and DeviceType='" + DeviceType + "' "};
std::vector<FMSObjects::Firmware> Fs;
if (GetRecords(0, 2, Fs, WhereClause)) {
Firmware = Fs[0];
return true;
}
return false;
}
bool FirmwaresDB::GetFirmwares(uint64_t From, uint64_t HowMany, const std::string & Compatible, FMSObjects::FirmwareVec & Firmwares) {
if(Compatible.empty()) {
GetRecords(From, HowMany, Firmwares);
return true;
} else {
std::string WhereClause{ " DeviceType='" + Compatible + "' "};
GetRecords(From, HowMany, Firmwares, WhereClause);
return true;
}
}
void FirmwaresDB::PopulateLatestFirmwareCache() {
Iterate([](const OpenWifi::FMSObjects::Firmware &F){
LatestFirmwareCache()->AddToCache(F.deviceType, F.revision, F.id, F.imageDate);
return true;
});
}
bool FirmwaresDB::ComputeFirmwareAge(const std::string & DeviceType, const std::string & Revision, FMSObjects::FirmwareAgeDetails &AgeDetails) {
try {
FMSObjects::Firmware CurrentFirmware;
FMSObjects::Firmware LatestFirmware;
bool CurrentFirmwareExists = false;
if(GetFirmwareByRevision(Revision,DeviceType,CurrentFirmware)) {
CurrentFirmwareExists = true;
}
LatestFirmwareCacheEntry LE;
if(LatestFirmwareCache()->FindLatestFirmware(DeviceType,LE)) {
// std::cout << "LE.id" << LE.Id << std::endl;
if(GetFirmware(LE.Id, LatestFirmware)) {
AgeDetails.imageDate = LatestFirmware.imageDate;
AgeDetails.uri = LatestFirmware.uri;
AgeDetails.image = LatestFirmware.image;
AgeDetails.revision = LatestFirmware.revision;
AgeDetails.latestId = LatestFirmware.id;
// std::cout << " Revision='" << Revision << "'" << std::endl;
// std::cout << "LF Revision='" << LatestFirmware.revision << "'" << std::endl;
AgeDetails.latest = (Revision == LatestFirmware.revision);
// std::cout << "Latest=" << AgeDetails.latest << std::endl;
AgeDetails.age = CurrentFirmwareExists ? (LatestFirmware.imageDate - CurrentFirmware.imageDate) : 0;
//std::cout << "Revision: '" << Revision << "' vs '" << LatestFirmware.revision << "'" << std::endl;
//if (AgeDetails.latest)
// std::cout << "Found latest firmware" << std::endl;
return true;
} else {
// std::cout << "Cannot find firmware: " << LE.Id << std::endl;
}
}
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
}
template<> void ORM::DB<OpenWifi::FirmwaresRecordTuple, OpenWifi::FMSObjects::Firmware>::Convert(const OpenWifi::FirmwaresRecordTuple &T, OpenWifi::FMSObjects::Firmware &F ) {
F.id = T.get<0>();
F.release = T.get<1>();
F.deviceType = T.get<2>();
F.description = T.get<3>();
F.revision = T.get<4>();
F.uri = T.get<5>();
F.image = T.get<6>();
F.imageDate = T.get<7>();
F.size = T.get<8>();
F.downloadCount = T.get<9>();
F.firmwareHash = T.get<10>();
F.owner = T.get<11>();
F.location = T.get<12>();
F.uploader = T.get<13>();
F.digest = T.get<14>();
F.latest = T.get<15>();
F.notes = OpenWifi::RESTAPI_utils::to_object_array<OpenWifi::SecurityObjects::NoteInfo>(T.get<16>());
F.created = T.get<17>();
}
template<> void ORM::DB<OpenWifi::FirmwaresRecordTuple, OpenWifi::FMSObjects::Firmware>::Convert(const OpenWifi::FMSObjects::Firmware &F, OpenWifi::FirmwaresRecordTuple &T ) {
T.set<0>(F.id);
T.set<1>(F.release);
T.set<2>(F.deviceType);
T.set<3>(F.description);
T.set<4>(F.revision);
T.set<5>(F.uri);
T.set<6>(F.image);
T.set<7>(F.imageDate);
T.set<8>(F.size);
T.set<9>(F.downloadCount);
T.set<10>(F.firmwareHash);
T.set<11>(F.owner);
T.set<12>(F.location);
T.set<13>(F.uploader);
T.set<14>(F.digest);
T.set<15>(F.latest);
T.set<16>(OpenWifi::RESTAPI_utils::to_string(F.notes));
T.set<17>(F.created);
}

View File

@@ -0,0 +1,50 @@
//
// Created by stephane bourque on 2021-12-28.
//
#pragma once
#include "framework/orm.h"
#include "RESTObjects/RESTAPI_FMSObjects.h"
namespace OpenWifi {
typedef Poco::Tuple<
std::string,
std::string,
std::string,
std::string,
std::string,
std::string,
std::string,
uint64_t,
uint64_t,
uint64_t,
std::string,
std::string,
std::string,
std::string,
std::string,
bool,
std::string,
uint64_t> FirmwaresRecordTuple;
typedef std::vector <FirmwaresRecordTuple> FirmwaresRecordTupleList;
class FirmwaresDB : public ORM::DB<FirmwaresRecordTuple, FMSObjects::Firmware> {
public:
FirmwaresDB(OpenWifi::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L);
bool AddFirmware(FMSObjects::Firmware & F);
bool UpdateFirmware(std::string & ID, FMSObjects::Firmware & F);
bool DeleteFirmware(std::string & ID);
void RemoveOldFirmware();
bool GetFirmware(std::string & ID, FMSObjects::Firmware & F);
bool GetFirmwareByName(const std::string & Release, const std::string &DeviceType, FMSObjects::Firmware & Firmware );
bool GetFirmwareByRevision(const std::string & Revision, const std::string &DeviceType,FMSObjects::Firmware & Firmware );
bool GetFirmwares(uint64_t From, uint64_t HowMany, const std::string & Compatible, FMSObjects::FirmwareVec & Firmwares);
void PopulateLatestFirmwareCache();
bool ComputeFirmwareAge(const std::string & DeviceType, const std::string & Revision, FMSObjects::FirmwareAgeDetails &AgeDetails);
private:
};
}

View File

@@ -0,0 +1,97 @@
//
// Created by stephane bourque on 2021-12-28.
//
#include "orm_history.h"
#include "StorageService.h"
/*
"id varchar(36) UNIQUE PRIMARY KEY, "
"serialNumber varchar, "
"fromRelease varchar, "
"toRelease varchar, "
"commandUUID varchar, "
"revisionId varchar, "
"upgraded bigint "
*/
namespace OpenWifi {
static ORM::FieldVec HistoryDB_Fields{
ORM::Field{"id", 36, true},
ORM::Field{"serialNumber", ORM::FieldType::FT_TEXT},
ORM::Field{"fromRelease", ORM::FieldType::FT_TEXT},
ORM::Field{"toRelease", ORM::FieldType::FT_TEXT},
ORM::Field{"commandUUID", ORM::FieldType::FT_TEXT},
ORM::Field{"revisionId", ORM::FieldType::FT_TEXT},
ORM::Field{"upgraded", ORM::FieldType::FT_BIGINT}
};
HistoryDB::HistoryDB(OpenWifi::DBType T,
Poco::Data::SessionPool &P, Poco::Logger &L) :
DB(T, "history", HistoryDB_Fields,{}, P, L, "his") {
}
bool HistoryDB::GetHistory(const std::string &SerialNumber, uint64_t From, uint64_t HowMany,
FMSObjects::RevisionHistoryEntryVec &History) {
std::string WhereClause{" serialNumber='" + SerialNumber + "' "};
std::string OrderBy{ " order by upgraded DESC "};
return GetRecords(From, HowMany, History, WhereClause, OrderBy);
}
bool HistoryDB::AddHistory(FMSObjects::RevisionHistoryEntry &History) {
return CreateRecord(History);
}
bool HistoryDB::AddHistory(std::string &SerialNumber, std::string &DeviceType, std::string &PreviousRevision,
std::string &NewVersion) {
FMSObjects::RevisionHistoryEntry History{
.id = MicroService::CreateUUID(),
.serialNumber = SerialNumber,
.fromRelease = PreviousRevision,
.toRelease = NewVersion,
.upgraded = (uint64_t) std::time(nullptr)};
FMSObjects::Firmware F;
if (StorageService()->FirmwaresDB().GetFirmwareByRevision(NewVersion, DeviceType, F)) {
History.revisionId = F.id;
} else {
History.revisionId = "unknown";
}
return AddHistory(History);
}
bool HistoryDB::DeleteHistory(std::string &SerialNumber, std::string &Id) {
return DeleteRecord("id", Id);
}
bool HistoryDB::DeleteHistory(std::string &SerialNumber) {
std::string WhereClause{" serialNumber='" + SerialNumber + "' "};
return DeleteRecords(WhereClause);
}
}
template<> void ORM::DB<OpenWifi::HistoryRecordTuple, OpenWifi::FMSObjects::RevisionHistoryEntry>::Convert(const OpenWifi::HistoryRecordTuple &T, OpenWifi::FMSObjects::RevisionHistoryEntry &F ) {
F.id = T.get<0>();
F.serialNumber = T.get<1>();
F.fromRelease = T.get<2>();
F.toRelease = T.get<3>();
F.commandUUID = T.get<4>();
F.revisionId = T.get<5>();
F.upgraded = T.get<6>();
}
template<> void ORM::DB<OpenWifi::HistoryRecordTuple, OpenWifi::FMSObjects::RevisionHistoryEntry>::Convert(const OpenWifi::FMSObjects::RevisionHistoryEntry &F, OpenWifi::HistoryRecordTuple &T ) {
T.set<0>(F.id);
T.set<1>(F.serialNumber);
T.set<2>(F.fromRelease);
T.set<3>(F.toRelease);
T.set<4>(F.commandUUID);
T.set<5>(F.revisionId);
T.set<6>(F.upgraded);
}

36
src/storage/orm_history.h Normal file
View File

@@ -0,0 +1,36 @@
//
// Created by stephane bourque on 2021-12-28.
//
#pragma once
#include "framework/orm.h"
#include "RESTObjects/RESTAPI_FMSObjects.h"
namespace OpenWifi {
typedef Poco::Tuple<
std::string,
std::string,
std::string,
std::string,
std::string,
std::string,
uint64_t> HistoryRecordTuple;
typedef std::vector<HistoryRecordTuple> HistoryRecordTupleList;
class HistoryDB : public ORM::DB<HistoryRecordTuple, FMSObjects::RevisionHistoryEntry> {
public:
HistoryDB(OpenWifi::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L);
bool GetHistory(const std::string &SerialNumber, uint64_t From, uint64_t HowMany,
FMSObjects::RevisionHistoryEntryVec &History);
bool AddHistory(FMSObjects::RevisionHistoryEntry &History);
bool AddHistory(std::string &SerialNumber, std::string &DeviceType, std::string &PreviousRevision,
std::string &NewVersion);
bool DeleteHistory(std::string &SerialNumber, std::string &Id);
bool DeleteHistory(std::string &SerialNumber);
private:
};
}

View File

@@ -1,236 +0,0 @@
//
// Created by stephane bourque on 2021-07-16.
//
#include "storage_deviceInfo.h"
#include "StorageService.h"
#include "Poco/Data/RecordSet.h"
#include "LatestFirmwareCache.h"
/*
"serialNumber=?, "
"revision=?, "
"deviceType=?, "
"endPoint=?, "
"lastUpdate=?, "
"status=?
*/
namespace OpenWifi {
bool Convert(const DevicesRecord &T, FMSObjects::DeviceConnectionInformation & F) {
F.serialNumber = T.get<0>();
F.revision = T.get<1>();
F.deviceType = T.get<2>();
F.endPoint = T.get<3>();
F.lastUpdate = T.get<4>();
F.status = T.get<5>();
return true;
}
bool Convert(const FMSObjects::DeviceConnectionInformation & F, DevicesRecord & T) {
T.set<0>(F.serialNumber);
T.set<1>(F.revision);
T.set<2>(F.deviceType);
T.set<3>(F.endPoint);
T.set<4>(F.lastUpdate);
T.set<5>(F.status);
return true;
}
bool Storage::SetDeviceRevision(std::string &SerialNumber, std::string & Revision, std::string & DeviceType, std::string &EndPoint) {
try {
Poco::Data::Session Sess = Pool_->get();
DevicesRecordList Records;
std::string PreviousVersion;
bool DeviceExists=false;
try {
Poco::Data::Statement Select(Sess);
std::string St{"select " + DBFIELDS_DEVICES_SELECT + " from " + DBNAME_DEVICES + " where serialNumber=?"};
Select << ConvertParams(St) ,
Poco::Data::Keywords::into(Records),
Poco::Data::Keywords::use(SerialNumber);
Select.execute();
if(!Records.empty()) {
PreviousVersion = Records[0].get<1>();
DeviceExists = true;
}
} catch (const Poco::Exception &E) {
}
std::string Status{"connected"};
if(!DeviceExists) {
std::string st{"INSERT INTO " + DBNAME_DEVICES + " (" +
DBFIELDS_DEVICES_SELECT +
") VALUES(?,?,?,?,?,?)"};
Logger_.information(Poco::format("New device '%s' connected", SerialNumber));
FMSObjects::DeviceConnectionInformation DI{
.serialNumber = SerialNumber,
.revision = Revision,
.deviceType = DeviceType,
.endPoint = EndPoint,
.lastUpdate = (uint64_t)std::time(nullptr),
.status = Status};
Poco::Data::Statement Insert(Sess);
DevicesRecordList InsertRecords;
DevicesRecord R;
Convert(DI, R);
InsertRecords.push_back(R);
Insert << ConvertParams(st),
Poco::Data::Keywords::use(InsertRecords);
Insert.execute();
} else {
Poco::Data::Statement Update(Sess);
auto Now = (uint64_t)std::time(nullptr);
// std::cout << "Updating device: " << SerialNumber << std::endl;
std::string st{"UPDATE " + DBNAME_DEVICES + " set revision=?, lastUpdate=?, endpoint=?, status=? " + " where serialNumber=?"};
Update << ConvertParams(st) ,
Poco::Data::Keywords::use(Revision),
Poco::Data::Keywords::use(Now),
Poco::Data::Keywords::use(EndPoint),
Poco::Data::Keywords::use(Status),
Poco::Data::Keywords::use(SerialNumber);
Update.execute();
if(PreviousVersion!=Revision) {
AddHistory(SerialNumber, DeviceType, PreviousVersion, Revision);
}
}
return true;
} catch (const Poco::Exception &E) {
Logger_.log(E);
}
return false;
}
bool Storage::SetDeviceDisconnected(std::string &SerialNumber, std::string &EndPoint) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Update(Sess);
uint64_t Now = (uint64_t)std::time(nullptr);
std::string Status{"not connected"};
// std::cout << "Updating device: " << SerialNumber << std::endl;
std::string st{"UPDATE " + DBNAME_DEVICES + " set lastUpdate=?, endpoint=?, status=? " + " where serialNumber=?"};
Update << ConvertParams(st) ,
Poco::Data::Keywords::use(Now),
Poco::Data::Keywords::use(EndPoint),
Poco::Data::Keywords::use(Status),
Poco::Data::Keywords::use(SerialNumber);
Update.execute();
} catch (const Poco::Exception &E) {
Logger_.log(E);
}
return false;
}
bool Storage::GetDevices(uint64_t From, uint64_t HowMany, std::vector<FMSObjects::DeviceConnectionInformation> & Devices) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess);
DevicesRecordList Records;
std::string St{"select " + DBFIELDS_DEVICES_SELECT + " from " + DBNAME_DEVICES + " ORDER BY SerialNumber ASC "};
Select << ConvertParams(St) + ComputeRange(From, HowMany),
Poco::Data::Keywords::into(Records);
Select.execute();
for(const auto &i:Records) {
FMSObjects::DeviceConnectionInformation DI;
Convert(i,DI);
Devices.push_back(DI);
}
return true;
} catch (const Poco::Exception &E) {
Logger_.log(E);
}
return false;
}
bool Storage::GetDevice(std::string &SerialNumber, FMSObjects::DeviceConnectionInformation & Device) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess);
DevicesRecordList Records;
std::string St{"select " + DBFIELDS_DEVICES_SELECT + " from " + DBNAME_DEVICES + " where serialNumber=?"};
Select << ConvertParams(St) ,
Poco::Data::Keywords::into(Records),
Poco::Data::Keywords::use(SerialNumber);
Select.execute();
if(!Records.empty()) {
Convert(Records[0],Device);
return true;
}
} catch (const Poco::Exception &E) {
Logger_.log(E);
}
return false;
}
/*
"serialNumber, "
"revision, "
"deviceType, "
"endPoint, "
"lastUpdate, "
"status "
*/
bool Storage::GenerateDeviceReport(FMSObjects::DeviceReport &Report) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess);
Report.reset();
Select << "SELECT " + DBFIELDS_DEVICES_SELECT + " from " + DBNAME_DEVICES;
Select.execute();
Poco::Data::RecordSet RSet(Select);
bool More = RSet.moveFirst();
while(More) {
Report.numberOfDevices++;
auto SerialNumber = RSet[0].convert<std::string>();
auto Revision = RSet[1].convert<std::string>();
auto DeviceType = RSet[2].convert<std::string>();
auto EndPoint = RSet[3].convert<std::string>();
auto Status = RSet[5].convert<std::string>();
// find the real revision for this device...
Types::UpdateCountedMap(Report.DeviceTypes_, DeviceType);
Types::UpdateCountedMap(Report.Revisions_, Revision);
Types::UpdateCountedMap(Report.Status_, Status);
Types::UpdateCountedMap(Report.EndPoints_, EndPoint);
Types::UpdateCountedMap(Report.OUI_, SerialNumber.substr(0, 6));
FMSObjects::FirmwareAgeDetails Age;
if (ComputeFirmwareAge(DeviceType, Revision, Age)) {
if (Age.latest) {
Types::UpdateCountedMap(Report.UsingLatest_, Revision);
} else if (Age.age == 0) {
Types::UpdateCountedMap(Report.UnknownFirmwares_, Revision);
} else {
Types::UpdateCountedMap(Report.totalSecondsOld_,"total_seconds", Age.age);
}
}
More = RSet.moveNext();
}
return true;
} catch( const Poco::Exception &E) {
Logger_.log(E);
}
return false;
}
}

View File

@@ -1,51 +0,0 @@
//
// Created by stephane bourque on 2021-07-16.
//
#ifndef UCENTRALFMS_STORAGE_DEVICEINFO_H
#define UCENTRALFMS_STORAGE_DEVICEINFO_H
#include "StorageService.h"
namespace OpenWifi {
static const std::string DBNAME_DEVICES{"devices"};
static const std::string DBFIELDS_DEVICES_CREATION {
"serialNumber varchar(36) UNIQUE PRIMARY KEY, "
"revision varchar, "
"deviceType varchar, "
"endPoint varchar, "
"lastUpdate bigint, "
"status varchar "
};
static const std::string DBFIELDS_DEVICES_SELECT{
"serialNumber, "
"revision, "
"deviceType, "
"endPoint, "
"lastUpdate, "
"status "
};
static const std::string DBFIELDS_DEVICES_UPDATE {
"serialNumber=?, "
"revision=?, "
"deviceType=?, "
"endPoint=?, "
"lastUpdate=?, "
"status=? "
};
typedef Poco::Tuple<
std::string,
std::string,
std::string,
std::string,
uint64_t,
std::string> DevicesRecord;
typedef std::vector<DevicesRecord> DevicesRecordList;
}
#endif //UCENTRALFMS_STORAGE_DEVICEINFO_H

View File

@@ -1,5 +0,0 @@
//
// Created by stephane bourque on 2021-07-12.
//
#include "storage_deviceTypes.h"

View File

@@ -1,47 +0,0 @@
//
// Created by stephane bourque on 2021-07-12.
//
#ifndef UCENTRALFMS_STORAGE_DEVICETYPES_H
#define UCENTRALFMS_STORAGE_DEVICETYPES_H
#include <string>
namespace OpenWifi {
static const std::string DBNAME_DEVICETYPES{"deviceTypes"};
static const std::string DBFIELDS_DEVICETYPES_CREATION {
" id varchar(36) UNIQUE PRIMARY KEY, "
"deviceType varchar, "
"manufacturer varchar, "
"model varchar, "
"policy varchar, "
"notes varchar, "
"lastUpdate bigint, "
"created bigint "
};
static const std::string DBFIELDS_DEVICETYPES_SELECT{
" id, "
"deviceType, "
"manufacturer, "
"model, "
"policy, "
"notes, "
"lastUpdate, "
"created "
};
static const std::string DBFIELDS_DEVICETYPES_UPDATE {
" id=?, "
"deviceType=?, "
"manufacturer=?, "
"model=?, "
"policy=?, "
"notes=?, "
"lastUpdate=?, "
"created=? "
};
}
#endif //UCENTRALFMS_STORAGE_DEVICETYPES_H

View File

@@ -1,356 +0,0 @@
//
// Created by stephane bourque on 2021-05-09.
//
#include <limits>
#include "StorageService.h"
#include "RESTObjects/RESTAPI_FMSObjects.h"
#include "LatestFirmwareCache.h"
#include "ManifestCreator.h"
namespace OpenWifi {
bool Convert(const FirmwaresRecord &T, FMSObjects::Firmware & F) {
F.id = T.get<0>();
F.release = T.get<1>();
F.deviceType = T.get<2>();
F.description = T.get<3>();
F.revision = T.get<4>();
F.uri = T.get<5>();
F.image = T.get<6>();
F.imageDate = T.get<7>();
F.size = T.get<8>();
F.downloadCount = T.get<9>();
F.firmwareHash = T.get<10>();
F.owner = T.get<11>();
F.location = T.get<12>();
F.uploader = T.get<13>();
F.digest = T.get<14>();
F.latest = T.get<15>();
F.notes = RESTAPI_utils::to_object_array<SecurityObjects::NoteInfo>(T.get<16>());
F.created = T.get<17>();
return true;
}
bool Convert(const FMSObjects::Firmware & F, FirmwaresRecord & T) {
T.set<0>(F.id);
T.set<1>(F.release);
T.set<2>(F.deviceType);
T.set<3>(F.description);
T.set<4>(F.revision);
T.set<5>(F.uri);
T.set<6>(F.image);
T.set<7>(F.imageDate);
T.set<8>(F.size);
T.set<9>(F.downloadCount);
T.set<10>(F.firmwareHash);
T.set<11>(F.owner);
T.set<12>(F.location);
T.set<13>(F.uploader);
T.set<14>(F.digest);
T.set<15>(F.latest);
T.set<16>(RESTAPI_utils::to_string(F.notes));
T.set<17>(F.created);
return true;
}
bool Storage::AddFirmware(FMSObjects::Firmware & F) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Insert(Sess);
// find the older software and change to latest = 0
F.id = MicroService::CreateUUID();
if(LatestFirmwareCache()->AddToCache(F.deviceType,F.revision,F.id,F.imageDate)) {
F.latest = true ;
Poco::Data::Statement Update(Sess);
std::string st{"UPDATE " + DBNAME_FIRMWARES + " SET latest=0 WHERE deviceType=? AND Latest=1"};
Update << ConvertParams(st),
Poco::Data::Keywords::use(F.deviceType);
Update.execute();
} else {
F.latest = false;
}
auto Notes = RESTAPI_utils::to_string(F.notes);
std::string st{"INSERT INTO " + DBNAME_FIRMWARES + " (" +
DBFIELDS_FIRMWARES_SELECT +
") VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"};
Insert << ConvertParams(st),
Poco::Data::Keywords::use(F.id),
Poco::Data::Keywords::use(F.release),
Poco::Data::Keywords::use(F.deviceType),
Poco::Data::Keywords::use(F.description),
Poco::Data::Keywords::use(F.revision),
Poco::Data::Keywords::use(F.uri),
Poco::Data::Keywords::use(F.image),
Poco::Data::Keywords::use(F.imageDate),
Poco::Data::Keywords::use(F.size),
Poco::Data::Keywords::use(F.downloadCount),
Poco::Data::Keywords::use(F.firmwareHash),
Poco::Data::Keywords::use(F.owner),
Poco::Data::Keywords::use(F.location),
Poco::Data::Keywords::use(F.uploader),
Poco::Data::Keywords::use(F.digest),
Poco::Data::Keywords::use(F.latest),
Poco::Data::Keywords::use(Notes),
Poco::Data::Keywords::use(F.created);
Insert.execute();
return true;
} catch (const Poco::Exception &E) {
Logger_.log(E);
}
return false;
}
bool Storage::UpdateFirmware(std::string & ID, FMSObjects::Firmware & F) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Update(Sess);
std::string st{"UPDATE " + DBNAME_FIRMWARES + " set " + DBFIELDS_FIRMWARES_UPDATE +
" WHERE id=?"};
auto Notes = RESTAPI_utils::to_string(F.notes);
Update << ConvertParams(st),
Poco::Data::Keywords::use(F.id),
Poco::Data::Keywords::use(F.release),
Poco::Data::Keywords::use(F.deviceType),
Poco::Data::Keywords::use(F.description),
Poco::Data::Keywords::use(F.revision),
Poco::Data::Keywords::use(F.uri),
Poco::Data::Keywords::use(F.image),
Poco::Data::Keywords::use(F.imageDate),
Poco::Data::Keywords::use(F.size),
Poco::Data::Keywords::use(F.downloadCount),
Poco::Data::Keywords::use(F.firmwareHash),
Poco::Data::Keywords::use(F.owner),
Poco::Data::Keywords::use(F.location),
Poco::Data::Keywords::use(F.uploader),
Poco::Data::Keywords::use(F.digest),
Poco::Data::Keywords::use(F.latest),
Poco::Data::Keywords::use(Notes),
Poco::Data::Keywords::use(F.created),
Poco::Data::Keywords::use(ID);
Update.execute();
return true;
} catch (const Poco::Exception &E) {
Logger_.log(E);
}
return false;
}
bool Storage::DeleteFirmware(std::string & ID) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Delete(Sess);
std::string st{"DELETE FROM " + DBNAME_FIRMWARES + " WHERE id=?"};
Delete << ConvertParams(st),
Poco::Data::Keywords::use(ID);
Delete.execute();
return true;
} catch (const Poco::Exception &E) {
Logger_.log(E);
}
return false;
}
void Storage::RemoveOldFirmware() {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Delete(Sess);
std::cout << "Removing old firmware..." << std::endl;
uint64_t Limit = std::time(nullptr) - ManifestCreator()->MaxAge();
std::string st{"DELETE FROM " + DBNAME_FIRMWARES + " WHERE imageDate<?"};
Delete << ConvertParams(st),
Poco::Data::Keywords::use(Limit);
Delete.execute();
} catch (const Poco::Exception &E) {
Logger_.log(E);
}
}
bool Storage::GetFirmware(std::string & ID, FMSObjects::Firmware & F) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess);
std::string st{"SELECT " + DBFIELDS_FIRMWARES_SELECT +
" FROM " + DBNAME_FIRMWARES + " WHERE id=?"};
FirmwaresRecordList Records;
Select << ConvertParams(st),
Poco::Data::Keywords::into(Records),
Poco::Data::Keywords::use(ID);
Select.execute();
if(Records.empty())
return false;
Convert(Records[0],F);
return true;
} catch (const Poco::Exception &E) {
Logger_.log(E);
}
return false;
}
bool Storage::GetFirmwareByName( std::string & Release, std::string &DeviceType, FMSObjects::Firmware & Firmware ) {
try {
FirmwaresRecordList Records;
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess);
std::string st{"SELECT " + DBFIELDS_FIRMWARES_SELECT +
" FROM " + DBNAME_FIRMWARES + " where release=? and DeviceType=?"};
Select << ConvertParams(st),
Poco::Data::Keywords::into(Records),
Poco::Data::Keywords::use(Release),
Poco::Data::Keywords::use(DeviceType);
Select.execute();
if(Records.empty())
return false;
Convert(Records[0],Firmware);
return true;
} catch (const Poco::Exception &E) {
Logger_.log(E);
}
return false;
}
bool Storage::GetFirmwareByRevision(std::string & Revision, std::string &DeviceType,FMSObjects::Firmware & Firmware ) {
try {
FirmwaresRecordList Records;
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess);
std::string st{"SELECT " + DBFIELDS_FIRMWARES_SELECT +
" FROM " + DBNAME_FIRMWARES + " where Revision=? and DeviceType=?"};
Select << ConvertParams(st),
Poco::Data::Keywords::into(Records),
Poco::Data::Keywords::use(Revision),
Poco::Data::Keywords::use(DeviceType);
Select.execute();
if (Records.empty())
return false;
Convert(Records[0], Firmware);
return true;
} catch (const Poco::Exception &E) {
Logger_.log(E);
}
return false;
}
bool Storage::GetFirmwares(uint64_t From, uint64_t HowMany, std::string & Compatible, FMSObjects::FirmwareVec & Firmwares) {
try {
FirmwaresRecordList Records;
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess);
std::string st;
if(Compatible.empty()) {
st = "SELECT " + DBFIELDS_FIRMWARES_SELECT + " FROM " + DBNAME_FIRMWARES + " ORDER BY Id ASC ";
Select << ConvertParams(st) + ComputeRange(From, HowMany),
Poco::Data::Keywords::into(Records);
} else {
st = "SELECT " + DBFIELDS_FIRMWARES_SELECT + " FROM " + DBNAME_FIRMWARES + " where DeviceType=? ORDER BY Id ASC ";
Select << ConvertParams(st) + ComputeRange(From, HowMany),
Poco::Data::Keywords::into(Records),
Poco::Data::Keywords::use(Compatible);
}
Select.execute();
for(const auto &R:Records) {
FMSObjects::Firmware F;
Convert(R,F);
Firmwares.push_back(F);
}
return true;
} catch (const Poco::Exception &E) {
Logger_.log(E);
}
return false;
}
void Storage::PopulateLatestFirmwareCache() {
try {
typedef Poco::Tuple<
std::string,
std::string,
uint64_t,
std::string> FCE;
typedef std::vector<FCE> FCEList;
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess);
std::string st{"SELECT Id, DeviceType, ImageDate, Revision FROM " + DBNAME_FIRMWARES};
FCEList Records;
Select << ConvertParams(st),
Poco::Data::Keywords::into(Records);
Select.execute();
for(const auto &R:Records) {
LatestFirmwareCache()->AddToCache(R.get<1>(), R.get<3>(), R.get<0>(), R.get<2>());
}
} catch (const Poco::Exception &E) {
Logger_.log(E);
}
}
bool Storage::ComputeFirmwareAge(std::string & DeviceType, std::string & Revision, FMSObjects::FirmwareAgeDetails &AgeDetails) {
try {
FMSObjects::Firmware CurrentFirmware;
FMSObjects::Firmware LatestFirmware;
bool CurrentFirmwareExists = false;
if(GetFirmwareByRevision(Revision,DeviceType,CurrentFirmware)) {
CurrentFirmwareExists = true;
}
LatestFirmwareCacheEntry LE;
if(LatestFirmwareCache()->FindLatestFirmware(DeviceType,LE)) {
// std::cout << "LE.id" << LE.Id << std::endl;
if(GetFirmware(LE.Id, LatestFirmware)) {
AgeDetails.imageDate = LatestFirmware.imageDate;
AgeDetails.uri = LatestFirmware.uri;
AgeDetails.image = LatestFirmware.image;
AgeDetails.revision = LatestFirmware.revision;
AgeDetails.latestId = LatestFirmware.id;
// std::cout << " Revision='" << Revision << "'" << std::endl;
// std::cout << "LF Revision='" << LatestFirmware.revision << "'" << std::endl;
AgeDetails.latest = (Revision == LatestFirmware.revision);
// std::cout << "Latest=" << AgeDetails.latest << std::endl;
AgeDetails.age = CurrentFirmwareExists ? (LatestFirmware.imageDate - CurrentFirmware.imageDate) : 0;
//std::cout << "Revision: '" << Revision << "' vs '" << LatestFirmware.revision << "'" << std::endl;
//if (AgeDetails.latest)
// std::cout << "Found latest firmware" << std::endl;
return true;
} else {
// std::cout << "Cannot find firmware: " << LE.Id << std::endl;
}
}
} catch (const Poco::Exception &E) {
Logger_.log(E);
}
return false;
}
}

View File

@@ -1,97 +0,0 @@
//
// Created by stephane bourque on 2021-07-12.
//
#ifndef UCENTRALFMS_STORAGE_FIRMWARES_H
#define UCENTRALFMS_STORAGE_FIRMWARES_H
#include "Poco/Tuple.h"
namespace OpenWifi {
static const std::string DBNAME_FIRMWARES{"firmwares"};
static const std::string DBFIELDS_FIRMWARES_CREATION {
"Id varchar(36) UNIQUE PRIMARY KEY, "
"release varchar, "
"deviceType varchar, "
"description varchar, "
"revision varchar, "
"uri varchar, "
"image varchar, "
"imageDate bigint, "
"size bigint, "
"downloadCount bigint, "
"firmwareHash varchar, "
"owner varchar, "
"location varchar, "
"uploader varchar, "
"digest varchar, "
"latest int, "
"notes text, "
"created bigint"
};
static const std::string DBFIELDS_FIRMWARES_SELECT{
" Id, "
"release, "
"deviceType, "
"description, "
"revision, "
"uri, "
"image, "
"imageDate, "
"size, "
"downloadCount, "
"firmwareHash, "
"owner, "
"location, "
"uploader, "
"digest, "
"latest, "
"notes, "
"created "
};
static const std::string DBFIELDS_FIRMWARES_UPDATE {
" Id=?, "
"release=?, "
"deviceType=?, "
"description=?, "
"revision=?, "
"uri=?, "
"image=?, "
"imageDate=?, "
"size=?, "
"downloadCount=?, "
"firmwareHash=?, "
"owner=?, "
"location=?, "
"uploader=?, "
"digest=?, "
"latest=?, "
"notes=?, "
"created=? "
};
typedef Poco::Tuple<
std::string,
std::string,
std::string,
std::string,
std::string,
std::string,
std::string,
uint64_t,
uint64_t,
uint64_t,
std::string,
std::string,
std::string,
std::string,
std::string,
uint64_t,
std::string,
uint64_t> FirmwaresRecord;
typedef std::vector<FirmwaresRecord> FirmwaresRecordList;
}
#endif //UCENTRALFMS_STORAGE_FIRMWARES_H

View File

@@ -1,130 +0,0 @@
//
// Created by stephane bourque on 2021-07-12.
//
#include "StorageService.h"
#include "storage_history.h"
#include "RESTObjects/RESTAPI_FMSObjects.h"
#include "Daemon.h"
namespace OpenWifi {
/*
* " id, "
"serialNumber, "
"fromRelease, "
"toRelease, "
"commandUUID, "
"revisionId, "
"upgraded "
*/
bool Convert(const HistoryRecord &T, FMSObjects::RevisionHistoryEntry & F) {
F.id = T.get<0>();
F.serialNumber = T.get<1>();
F.fromRelease = T.get<2>();
F.toRelease = T.get<3>();
F.commandUUID = T.get<4>();
F.revisionId = T.get<5>();
F.upgraded = T.get<6>();
return true;
}
bool Convert(const FMSObjects::RevisionHistoryEntry & F, HistoryRecord & T) {
T.set<0>(F.id);
T.set<1>(F.serialNumber);
T.set<2>(F.fromRelease);
T.set<3>(F.toRelease);
T.set<4>(F.commandUUID);
T.set<5>(F.revisionId);
T.set<6>(F.upgraded);
return true;
}
bool Storage::GetHistory(std::string &SerialNumber,uint64_t From, uint64_t HowMany,FMSObjects::RevisionHistoryEntryVec &History) {
try {
HistoryRecordList Records;
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess);
std::string st{"SELECT " + DBFIELDS_HISTORY_SELECT +
" FROM " + DBNAME_HISTORY + " where SerialNumber=? ORDER BY Upgraded DESC " };
Select << ConvertParams(st) + ComputeRange(From, HowMany),
Poco::Data::Keywords::into(Records),
Poco::Data::Keywords::use(SerialNumber);
Select.execute();
for(const auto &R:Records) {
FMSObjects::RevisionHistoryEntry F;
Convert(R,F);
History.push_back(F);
}
return true;
} catch(const Poco::Exception &E) {
Logger_.log(E);
}
return false;
}
bool Storage::AddHistory(FMSObjects::RevisionHistoryEntry &History) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Insert(Sess);
std::string st{"INSERT INTO " + DBNAME_HISTORY + " (" + DBFIELDS_HISTORY_SELECT +
" ) values(?,?,?,?,?,?,?)" };
std::cout << "Adding history for " << History.serialNumber << std::endl;
HistoryRecordList RL;
HistoryRecord R;
Convert(History, R);
RL.push_back(R);
Insert << ConvertParams(st),
Poco::Data::Keywords::use(RL);
Insert.execute();
return true;
} catch(const Poco::Exception &E) {
Logger_.log(E);
}
return false;
}
bool Storage::AddHistory( std::string & SerialNumber, std::string &DeviceType, std::string & PreviousRevision, std::string & NewVersion) {
FMSObjects::RevisionHistoryEntry History{
.id = MicroService::CreateUUID(),
.serialNumber = SerialNumber,
.fromRelease = PreviousRevision,
.toRelease = NewVersion,
.upgraded = (uint64_t)std::time(nullptr)};
FMSObjects::Firmware F;
if(GetFirmwareByRevision(NewVersion,DeviceType,F)) {
History.revisionId = F.id;
} else {
History.revisionId = "unknown";
}
return AddHistory(History);
}
bool Storage::DeleteHistory( std::string & SerialNumber, std::string &Id) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Delete(Sess);
std::string st{"DELETE FROM " + DBNAME_HISTORY + " where id=? and serialnumber=?"};
Delete << ConvertParams(st),
Poco::Data::Keywords::use(Id),
Poco::Data::Keywords::use(SerialNumber);
Delete.execute();
return true;
} catch(const Poco::Exception &E) {
Logger_.log(E);
}
return false;
}
}

View File

@@ -1,56 +0,0 @@
//
// Created by stephane bourque on 2021-07-12.
//
#ifndef UCENTRALFMS_STORAGE_HISTORY_H
#define UCENTRALFMS_STORAGE_HISTORY_H
#include <string>
#include "Poco/Tuple.h"
namespace OpenWifi {
static const std::string DBNAME_HISTORY{"history"};
static const std::string DBFIELDS_HISTORY_CREATION {
" id varchar(36) UNIQUE PRIMARY KEY, "
"serialNumber varchar, "
"fromRelease varchar, "
"toRelease varchar, "
"commandUUID varchar, "
"revisionId varchar, "
"upgraded bigint "
};
static const std::string DBFIELDS_HISTORY_SELECT{
" id, "
"serialNumber, "
"fromRelease, "
"toRelease, "
"commandUUID, "
"revisionId, "
"upgraded "
};
static const std::string DBFIELDS_HISTORY_UPDATE {
" id=?, "
"serialNumber=?, "
"fromRelease=?, "
"toRelease=?, "
"commandUUID=?, "
"revisionId=?, "
"upgraded=? "
};
typedef Poco::Tuple<
std::string,
std::string,
std::string,
std::string,
std::string,
std::string,
uint64_t> HistoryRecord;
typedef std::vector<HistoryRecord> HistoryRecordList;
}
#endif //UCENTRALFMS_STORAGE_HISTORY_H

View File

@@ -1,106 +0,0 @@
//
// License type: BSD 3-Clause License
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
//
// Created by Stephane Bourque on 2021-03-04.
// Arilia Wireless Inc.
//
#include "StorageService.h"
namespace OpenWifi {
int Storage::Create_Tables() {
Create_Firmwares();
Create_History();
Create_DeviceTypes();
Create_DeviceInfo();
return 0;
}
int Storage::Create_Firmwares() {
try {
Poco::Data::Session Sess = Pool_->get();
if(dbType_==mysql) {
Sess << "CREATE TABLE IF NOT EXISTS " + DBNAME_FIRMWARES + " (" +
DBFIELDS_FIRMWARES_CREATION +
")",
Poco::Data::Keywords::now;
} else {
Sess << "CREATE TABLE IF NOT EXISTS " + DBNAME_FIRMWARES + " (" +
DBFIELDS_FIRMWARES_CREATION +
")",
Poco::Data::Keywords::now;
}
return 0;
} catch(const Poco::Exception &E) {
Logger_.log(E);
}
return -1;
}
int Storage::Create_History() {
try {
Poco::Data::Session Sess = Pool_->get();
if(dbType_==mysql) {
Sess << "CREATE TABLE IF NOT EXISTS " + DBNAME_HISTORY + " (" +
DBFIELDS_HISTORY_CREATION +
",INDEX Serial (SerialNumber ASC, upgraded ASC))"
, Poco::Data::Keywords::now;
} else {
Sess << "CREATE TABLE IF NOT EXISTS " + DBNAME_HISTORY + " (" +
DBFIELDS_HISTORY_CREATION +
")",
Poco::Data::Keywords::now;
Sess << "CREATE INDEX IF NOT EXISTS Serial ON " + DBNAME_HISTORY + " (SerialNumber ASC, upgraded ASC)", Poco::Data::Keywords::now;
}
return 0;
} catch(const Poco::Exception &E) {
Logger_.log(E);
}
return -1;
}
int Storage::Create_DeviceTypes() {
try {
Poco::Data::Session Sess = Pool_->get();
if(dbType_==mysql) {
Sess << "CREATE TABLE IF NOT EXISTS " + DBNAME_DEVICETYPES + " (" +
DBFIELDS_DEVICETYPES_CREATION +
")",
Poco::Data::Keywords::now;
} else {
Sess << "CREATE TABLE IF NOT EXISTS " + DBNAME_DEVICETYPES + " (" +
DBFIELDS_DEVICETYPES_CREATION +
")",
Poco::Data::Keywords::now;
}
return 0;
} catch(const Poco::Exception &E) {
Logger_.log(E);
}
return -1;
}
int Storage::Create_DeviceInfo() {
try {
Poco::Data::Session Sess = Pool_->get();
Sess << "CREATE TABLE IF NOT EXISTS " + DBNAME_DEVICES + " (" +
DBFIELDS_DEVICES_CREATION +
")",
Poco::Data::Keywords::now;
return 0;
} catch(const Poco::Exception &E) {
Logger_.log(E);
}
return -1;
}
}

View File

@@ -34,11 +34,20 @@ fi
token="" token=""
result_file=result.json result_file=result.json
username="tip@ucentral.com"
password="openwifi"
browser_list=(firefox sensible-browser xdg-open w3m links links2 lynx youtube-dl) browser_list=(firefox sensible-browser xdg-open w3m links links2 lynx youtube-dl)
browser="" browser=""
if [ -z ${OWSEC_USERNAME+x} ]; then
username="script.runner@arilia.com"
else
username=${OWSEC_USERNAME}
fi
if [ -z ${OWSEC_PASSWORD+x} ]; then
password="Snoopy99!!!"
else
password=${OWSEC_PASSWORD}
fi
login() { login() {
payload="{ \"userId\" : \"$username\" , \"password\" : \"$password\" }" payload="{ \"userId\" : \"$username\" , \"password\" : \"$password\" }"
token=$(curl ${FLAGS} -X POST -H "Content-Type: application/json" -d "$payload" "https://${OWSEC}/api/v1/oauth2" | jq -r '.access_token') token=$(curl ${FLAGS} -X POST -H "Content-Type: application/json" -d "$payload" "https://${OWSEC}/api/v1/oauth2" | jq -r '.access_token')
@@ -73,40 +82,31 @@ findbrowser() {
} }
setfms() { setfms() {
if [ -z ${OWFMS_OVERRIDE+x} ]; then
curl ${FLAGS} -X GET "https://${OWSEC}/api/v1/systemEndpoints" \ curl ${FLAGS} -X GET "https://${OWSEC}/api/v1/systemEndpoints" \
-H "accept: application/json" \ -H "accept: application/json" \
-H "Authorization: Bearer ${token}" > ${result_file} -H "Authorization: Bearer ${token}" > ${result_file}
# jq < ${result_file} rawurl="$(cat ${result_file} | jq -r '.endpoints[] | select( .type == "owfms" ) | .uri')"
if [[ ! -z "${rawurl}" ]]; then
for index in {0..10} proto="$(echo $rawurl | grep :// | sed -e's,^\(.*://\).*,\1,g')"
do url="$(echo ${rawurl/$proto/})"
endpointlocation=".endpoints[${index}].uri" user="$(echo $url | grep @ | cut -d@ -f1)"
endpointlocationtype=".endpoints[${index}].type" hostport="$(echo ${url/$user@/} | cut -d/ -f1)"
rawurl="$(cat ${result_file} | jq -r ${endpointlocation})" host="$(echo $hostport | sed -e 's,:.*,,g')"
svctype="$(cat ${result_file} | jq -r ${endpointlocationtype})" port="$(echo $hostport | sed -e 's,^.*:,:,g' -e 's,.*:\([0-9]*\).*,\1,g' -e 's,[^0-9],,g')"
proto="$(echo $rawurl | grep :// | sed -e's,^\(.*://\).*,\1,g')" path="$(echo $url | grep / | cut -d/ -f2-)"
url="$(echo ${rawurl/$proto/})" export OWFMS=${url}
user="$(echo $url | grep @ | cut -d@ -f1)" echo "Using ${OWFMS}..."
hostport="$(echo ${url/$user@/} | cut -d/ -f1)" else
host="$(echo $hostport | sed -e 's,:.*,,g')" echo "OWFMS endpoint is not found:"
port="$(echo $hostport | sed -e 's,^.*:,:,g' -e 's,.*:\([0-9]*\).*,\1,g' -e 's,[^0-9],,g')" jq < ${result_file}
path="$(echo $url | grep / | cut -d/ -f2-)" exit 1
if [[ ${url} != "null" ]]
then
if [[ ${svctype} == "owfms" ]]
then
# echo "url: $url"
# echo " proto: $proto"
# echo " user: $user"
# echo " host: $host"
# echo " port: $port"
# echo " path: $path"
OWFMS="${url}"
break
fi
fi fi
done
echo "Using ${OWFMS}..." else
export OWFMS=${OWFMS_OVERRIDE}
fi
} }
logout() { logout() {

File diff suppressed because one or more lines are too long

26
wait-for-postgres.sh Executable file
View File

@@ -0,0 +1,26 @@
#!/bin/sh
# wait-for-postgres.sh
set -e
host="$1"
shift
export PGUSER=$(grep 'storage.type.postgresql.username' $OWFMS_CONFIG/owfms.properties | awk -F '= ' '{print $2}')
export PGPASSWORD=$(grep 'storage.type.postgresql.password' $OWFMS_CONFIG/owfms.properties | awk -F '= ' '{print $2}')
until psql -h "$host" -c '\q'; do
>&2 echo "Postgres is unavailable - sleeping"
sleep 1
done
>&2 echo "Postgres is up - executing command"
if [ "$1" = '/openwifi/owfms' -a "$(id -u)" = '0' ]; then
if [ "$RUN_CHOWN" = 'true' ]; then
chown -R "$OWFMS_USER": "$OWFMS_ROOT" "$OWFMS_CONFIG"
fi
exec su-exec "$OWFMS_USER" "$@"
fi
exec "$@"