mirror of
https://github.com/Telecominfraproject/wlan-cloud-ucentralfms.git
synced 2025-10-29 09:52:20 +00:00
Compare commits
77 Commits
v2.4.0-RC4
...
release/v2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
889d98a162 | ||
|
|
a46401bf87 | ||
|
|
f0be8ffdc5 | ||
|
|
941680c0fd | ||
|
|
f2b64939a3 | ||
|
|
bf7375c8f1 | ||
|
|
e516e60179 | ||
|
|
7036d960e5 | ||
|
|
eb8a858e05 | ||
|
|
4527248545 | ||
|
|
783b7bd32e | ||
|
|
76c34c5b7e | ||
|
|
316e51a0e2 | ||
|
|
f2f8edd905 | ||
|
|
68389ec1e8 | ||
|
|
615408acff | ||
|
|
0a4bd59c56 | ||
|
|
479e3cc96c | ||
|
|
0e6ce5d6d9 | ||
|
|
507e8dadb5 | ||
|
|
3e72a41686 | ||
|
|
50050fe16d | ||
|
|
3344f5bb13 | ||
|
|
b4ab5192d3 | ||
|
|
707014d698 | ||
|
|
e34874f68b | ||
|
|
2244e9fcab | ||
|
|
4f4fe39edc | ||
|
|
7f143c6eaf | ||
|
|
f2b6339470 | ||
|
|
79622fd5ca | ||
|
|
090c019175 | ||
|
|
c32a7bd91f | ||
|
|
00fb2bab4f | ||
|
|
b4862aa11c | ||
|
|
f476d4711b | ||
|
|
ad436b0a7c | ||
|
|
5f0bf8b37f | ||
|
|
69d42a1074 | ||
|
|
69f4ac6035 | ||
|
|
27aa44ac30 | ||
|
|
edc855063a | ||
|
|
be520211bf | ||
|
|
506150cbee | ||
|
|
64f941e9ac | ||
|
|
d30e1715fe | ||
|
|
be01b70d4c | ||
|
|
6f6d539a14 | ||
|
|
6d1285cb77 | ||
|
|
e170f23300 | ||
|
|
d02a19d649 | ||
|
|
6546c14b3e | ||
|
|
4a80848fd9 | ||
|
|
935139067f | ||
|
|
e3cceeab32 | ||
|
|
d061e126bc | ||
|
|
7612196acc | ||
|
|
7c098c7925 | ||
|
|
814e9bf781 | ||
|
|
44bb657c48 | ||
|
|
fab5e85f03 | ||
|
|
3a7dae3855 | ||
|
|
f9b14c7723 | ||
|
|
53e2caa3cb | ||
|
|
fcb67912b0 | ||
|
|
76376ec7c0 | ||
|
|
31e3b5e606 | ||
|
|
266570f7d0 | ||
|
|
8414e0386a | ||
|
|
993405851a | ||
|
|
7e0da73c54 | ||
|
|
cd93e29a99 | ||
|
|
049cb888c1 | ||
|
|
0495bf88e8 | ||
|
|
95d8ef42ae | ||
|
|
d057bacd9c | ||
|
|
b87ee360e5 |
75
.github/workflows/ci.yml
vendored
75
.github/workflows/ci.yml
vendored
@@ -25,41 +25,46 @@ jobs:
|
||||
DOCKER_REGISTRY_URL: tip-tip-wlan-cloud-ucentral.jfrog.io
|
||||
DOCKER_REGISTRY_USERNAME: ucentral
|
||||
steps:
|
||||
- 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
|
||||
- name: Checkout actions repo
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
registry: ${{ env.DOCKER_REGISTRY_URL }}
|
||||
username: ${{ env.DOCKER_REGISTRY_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_REGISTRY_PASSWORD }}
|
||||
repository: Telecominfraproject/.github
|
||||
path: github
|
||||
|
||||
- name: Push Docker images
|
||||
if: startsWith(github.ref, 'refs/tags/') || startsWith(github.ref, 'refs/pull/') || github.ref == 'refs/heads/main'
|
||||
- name: Build and push Docker image
|
||||
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: |
|
||||
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"}'
|
||||
|
||||
24
.github/workflows/enforce-jira-issue-key.yml
vendored
Normal file
24
.github/workflows/enforce-jira-issue-key.yml
vendored
Normal 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
3
.gitignore
vendored
@@ -20,5 +20,4 @@ _deps
|
||||
*.zip
|
||||
result.json
|
||||
pidfile
|
||||
|
||||
|
||||
test_scripts/curl/result.json
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
project(owfms VERSION 2.4.0)
|
||||
project(owfms VERSION 2.5.0)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
@@ -15,18 +15,32 @@ if(UNIX AND NOT APPLE)
|
||||
endif()
|
||||
|
||||
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/build)
|
||||
file(READ build BUILD_NUM)
|
||||
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/build BUILD_NUM)
|
||||
if(BUILD_INCREMENT)
|
||||
MATH(EXPR BUILD_NUM "${BUILD_NUM}+1")
|
||||
file(WRITE build ${BUILD_NUM})
|
||||
file(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/build ${BUILD_NUM})
|
||||
endif()
|
||||
else()
|
||||
set(BUILD_NUM 1)
|
||||
file(WRITE build ${BUILD_NUM})
|
||||
file(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/build ${BUILD_NUM})
|
||||
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)
|
||||
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_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)
|
||||
|
||||
configure_file(src/ow_version.h.in ${PROJECT_SOURCE_DIR}/src/ow_version.h @ONLY)
|
||||
|
||||
add_executable( owfms
|
||||
build
|
||||
src/ow_version.h.in
|
||||
src/framework/CountryCodes.h
|
||||
src/framework/KafkaTopics.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_deviceReportHandler.cpp src/RESTAPI/RESTAPI_deviceReportHandler.h
|
||||
src/RESTAPI/RESTAPI_connectedDeviceHandler.cpp src/RESTAPI/RESTAPI_connectedDeviceHandler.h
|
||||
src/storage/storage_tables.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/RESTAPI/RESTAPI_Routers.cpp
|
||||
src/Dashboard.cpp src/Dashboard.h
|
||||
src/Daemon.cpp src/Daemon.h
|
||||
src/StorageService.cpp src/StorageService.h
|
||||
@@ -87,7 +99,10 @@ add_executable( owfms
|
||||
src/FirmwareCache.cpp src/FirmwareCache.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/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
|
||||
${Poco_LIBRARIES} ${MySQL_LIBRARIES}
|
||||
|
||||
104
Dockerfile
104
Dockerfile
@@ -1,36 +1,16 @@
|
||||
FROM alpine AS builder
|
||||
FROM alpine:3.15 AS build-base
|
||||
|
||||
RUN apk add --update --no-cache \
|
||||
openssl openssh \
|
||||
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 \
|
||||
make cmake g++ git \
|
||||
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/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
|
||||
RUN mkdir cmake-build
|
||||
@@ -39,12 +19,22 @@ RUN cmake ..
|
||||
RUN cmake --build . --config Release -j8
|
||||
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
|
||||
WORKDIR cmake-build
|
||||
RUN cmake ..
|
||||
RUN make
|
||||
RUN make install
|
||||
RUN cmake --build . --config Release -j8
|
||||
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
|
||||
RUN mkdir cmake-build
|
||||
@@ -53,17 +43,46 @@ RUN cmake ..
|
||||
RUN make
|
||||
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 cmake /owfms/cmake
|
||||
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
|
||||
RUN mkdir 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
|
||||
|
||||
FROM alpine
|
||||
FROM alpine:3.15
|
||||
|
||||
ENV OWFMS_USER=owfms \
|
||||
OWFMS_ROOT=/owfms-data \
|
||||
@@ -75,20 +94,25 @@ RUN addgroup -S "$OWFMS_USER" && \
|
||||
RUN mkdir /openwifi
|
||||
RUN mkdir -p "$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
|
||||
COPY --from=builder /cppkafka/cmake-build/src/lib/* /lib/
|
||||
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 --from=builder /aws-sdk-cpp/cmake-build/aws-cpp-sdk-s3/libaws-cpp-sdk-s3.so /lib/
|
||||
RUN apk add --update --no-cache librdkafka su-exec gettext ca-certificates bash jq curl \
|
||||
mariadb-connector-c libpq unixodbc postgresql-client
|
||||
|
||||
COPY readiness_check /readiness_check
|
||||
COPY test_scripts/curl/cli /cli
|
||||
|
||||
COPY owfms.properties.tmpl /
|
||||
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 \
|
||||
-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
|
||||
|
||||
|
||||
@@ -5,14 +5,14 @@ name: owfms
|
||||
version: 0.1.0
|
||||
dependencies:
|
||||
- name: postgresql
|
||||
repository: https://charts.bitnami.com/bitnami
|
||||
repository: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
|
||||
version: 10.9.2
|
||||
condition: postgresql.enabled
|
||||
- name: mysql
|
||||
repository: https://charts.bitnami.com/bitnami
|
||||
repository: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
|
||||
version: 8.8.3
|
||||
condition: mysql.enabled
|
||||
- name: mariadb
|
||||
repository: https://charts.bitnami.com/bitnami
|
||||
repository: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
|
||||
version: 9.4.2
|
||||
condition: mariadb.enabled
|
||||
|
||||
@@ -30,3 +30,13 @@ Create chart name and version as used by the chart label.
|
||||
{{- define "owfms.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
|
||||
{{- 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 -}}
|
||||
|
||||
@@ -13,6 +13,7 @@ spec:
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
strategy:
|
||||
type: {{ .Values.strategyType }}
|
||||
revisionHistoryLimit: {{ .Values.revisionHistoryLimit }}
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: {{ include "owfms.name" . }}
|
||||
@@ -35,6 +36,16 @@ spec:
|
||||
{{- end }}
|
||||
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:
|
||||
|
||||
- name: owfms
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{{- range $ingress, $ingressValue := .Values.ingresses }}
|
||||
{{- if $ingressValue.enabled }}
|
||||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
apiVersion: {{ include "owfms.ingress.apiVersion" $root }}
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ include "owfms.fullname" $root }}-{{ $ingress }}
|
||||
@@ -36,9 +36,23 @@ spec:
|
||||
paths:
|
||||
{{- range $ingressValue.paths }}
|
||||
- path: {{ .path }}
|
||||
{{- if $root.Capabilities.APIVersions.Has "networking.k8s.io/v1" }}
|
||||
pathType: {{ .pathType | default "ImplementationSpecific" }}
|
||||
{{- end }}
|
||||
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 }}
|
||||
servicePort: {{ .servicePort }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# System
|
||||
replicaCount: 1
|
||||
strategyType: Recreate
|
||||
revisionHistoryLimit: 2
|
||||
|
||||
nameOverride: ""
|
||||
fullnameOverride: ""
|
||||
@@ -8,16 +9,20 @@ fullnameOverride: ""
|
||||
images:
|
||||
owfms:
|
||||
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owfms
|
||||
tag: main
|
||||
tag: v2.5.2
|
||||
pullPolicy: Always
|
||||
# regcred:
|
||||
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io
|
||||
# username: username
|
||||
# password: password
|
||||
dockerize:
|
||||
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/dockerize
|
||||
tag: 0.16.0
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
services:
|
||||
owfms:
|
||||
type: LoadBalancer
|
||||
type: ClusterIP
|
||||
ports:
|
||||
restapi:
|
||||
servicePort: 16004
|
||||
@@ -38,8 +43,6 @@ checks:
|
||||
exec:
|
||||
command:
|
||||
- /readiness_check
|
||||
failureThreshold: 1
|
||||
|
||||
|
||||
ingresses:
|
||||
restapi:
|
||||
@@ -51,6 +54,7 @@ ingresses:
|
||||
- restapi.chart-example.local
|
||||
paths:
|
||||
- path: /
|
||||
pathType: ImplementationSpecific
|
||||
serviceName: owfms
|
||||
servicePort: restapi
|
||||
|
||||
@@ -180,22 +184,9 @@ configProperties:
|
||||
openwifi.system.uri.ui: https://localhost
|
||||
openwifi.system.commandchannel: /tmp/app_owfms
|
||||
# Logging
|
||||
logging.formatters.f1.class: PatternFormatter
|
||||
logging.formatters.f1.pattern: "%Y-%m-%d %H:%M:%S %s: [%p] %t"
|
||||
logging.formatters.f1.times: UTC
|
||||
logging.channels.c1.class: ConsoleChannel
|
||||
logging.channels.c1.formatter: f1
|
||||
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
|
||||
logging.type: console
|
||||
logging.path: $OWFMS_ROOT/logs
|
||||
logging.level: debug
|
||||
|
||||
# -> Secret part
|
||||
# REST API
|
||||
|
||||
@@ -2,7 +2,7 @@ openapi: 3.0.1
|
||||
info:
|
||||
title: uCentral Firmware Service API
|
||||
description: A process to manage new uCentral firmware distribution.
|
||||
version: 2.0.0
|
||||
version: 2.5.0
|
||||
license:
|
||||
name: BSD3
|
||||
url: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
|
||||
@@ -60,6 +60,11 @@ components:
|
||||
- 6 # INTERNAL_ERROR,
|
||||
- 7 # ACCESS_DENIED,
|
||||
- 8 # INVALID_TOKEN
|
||||
- 9 # EXPIRED_TOKEN
|
||||
- 10 # RATE_LIMIT_EXCEEDED
|
||||
- 11 # BAD_MFA_TRANSACTION
|
||||
- 12 # MFA_FAILURE
|
||||
- 13 # SECURITY_SERVICE_UNREACHABLE
|
||||
ErrorDetails:
|
||||
type: string
|
||||
ErrorDescription:
|
||||
|
||||
@@ -35,6 +35,7 @@ openwifi.system.uri.private = https://localhost:17004
|
||||
openwifi.system.uri.public = https://ucentral.dpaas.arilia.com:16004
|
||||
openwifi.system.commandchannel = /tmp/app.owfms
|
||||
openwifi.system.uri.ui = ucentral-ui.arilia.com
|
||||
|
||||
firmwaredb.refresh = 1800
|
||||
firmwaredb.maxage = 90
|
||||
|
||||
@@ -108,37 +109,9 @@ storage.type.mysql.connectiontimeout = 60
|
||||
# Logging: please leave as is for now.
|
||||
#
|
||||
########################################################################
|
||||
logging.formatters.f1.class = PatternFormatter
|
||||
logging.formatters.f1.pattern = %s: [%p] %t
|
||||
logging.formatters.f1.times = UTC
|
||||
logging.channels.c1.class = ConsoleChannel
|
||||
logging.channels.c1.formatter = f1
|
||||
|
||||
# This is where the logs will be written. This path MUST exist
|
||||
logging.channels.c2.class = FileChannel
|
||||
logging.channels.c2.path = $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
|
||||
logging.type = file
|
||||
logging.path = $OWFMS_ROOT/logs
|
||||
logging.level = debug
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -104,37 +104,6 @@ storage.type.mysql.connectiontimeout = 60
|
||||
# Logging: please leave as is for now.
|
||||
#
|
||||
########################################################################
|
||||
logging.formatters.f1.class = PatternFormatter
|
||||
logging.formatters.f1.pattern = %Y-%m-%d %H:%M:%S %s: [%p] %t
|
||||
logging.formatters.f1.times = UTC
|
||||
logging.channels.c1.class = ConsoleChannel
|
||||
logging.channels.c1.formatter = f1
|
||||
|
||||
# This is where the logs will be written. This path MUST exist
|
||||
logging.channels.c2.class = FileChannel
|
||||
logging.channels.c2.path = $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
|
||||
|
||||
|
||||
|
||||
logging.type = console
|
||||
logging.path = $OWFMS_ROOT/logs
|
||||
logging.level = debug
|
||||
|
||||
@@ -13,29 +13,29 @@ then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "${OWSEC}" == "" ]]
|
||||
then
|
||||
echo "You must set the variable OWSEC in order to use this script. Something like"
|
||||
echo "OWSEC=security.isp.com:16001"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "${OWSEC_USERNAME}" == "" ]]
|
||||
then
|
||||
echo "You must set the variable OWSEC_USERNAME in order to use this script. Something like"
|
||||
echo "OWSEC_USERNAME=tip@ucentral.com"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "${OWSEC_PASSWORD}" == "" ]]
|
||||
then
|
||||
echo "You must set the variable OWSEC_PASSWORD in order to use this script. Something like"
|
||||
echo "OWSEC_PASSWORD=openwifi"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "${READINESS_METHOD}" == "systeminfo" ]]
|
||||
then
|
||||
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
|
||||
payload="{ \"userId\" : \"$OWSEC_USERNAME\" , \"password\" : \"$OWSEC_PASSWORD\" }"
|
||||
if [[ -f "/tmp/token" ]]
|
||||
|
||||
@@ -11,19 +11,22 @@
|
||||
namespace OpenWifi {
|
||||
|
||||
int AutoUpdater::Start() {
|
||||
Running_ = true;
|
||||
AutoUpdaterFrequency_ = MicroService::instance().ConfigGetInt("autoupdater.frequency",600);
|
||||
AutoUpdaterEnabled_ = MicroService::instance().ConfigGetBool("autoupdater.enabled", false);
|
||||
if(AutoUpdaterEnabled_)
|
||||
Thr_.start(*this);
|
||||
if(AutoUpdaterEnabled_) {
|
||||
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;
|
||||
}
|
||||
|
||||
void AutoUpdater::Stop() {
|
||||
Running_ = false;
|
||||
if(AutoUpdaterEnabled_) {
|
||||
Thr_.wakeUp();
|
||||
Thr_.join();
|
||||
Timer_.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,71 +37,67 @@ namespace OpenWifi {
|
||||
Queue_.emplace_back(std::make_pair(std::move(serialNumber),std::move(DeviceType)));
|
||||
}
|
||||
|
||||
void AutoUpdater::run() {
|
||||
while(Running_) {
|
||||
Poco::Thread::trySleep(2000);
|
||||
if(!Running_)
|
||||
break;
|
||||
std::unique_lock L(Mutex_);
|
||||
while(!Queue_.empty() && Running_) {
|
||||
auto Entry = Queue_.front();
|
||||
Queue_.pop_front();
|
||||
try {
|
||||
Logger_.debug(Poco::format("Preparing to upgrade %s",Entry.first));
|
||||
auto CacheEntry = Cache_.find(Entry.first);
|
||||
uint64_t Now = std::time(nullptr);
|
||||
std::string firmwareUpgrade;
|
||||
void AutoUpdater::onTimer(Poco::Timer & timer) {
|
||||
Running_ = true;
|
||||
std::unique_lock L(Mutex_);
|
||||
while(!Queue_.empty() && Running_) {
|
||||
auto Entry = Queue_.front();
|
||||
Queue_.pop_front();
|
||||
try {
|
||||
Logger().debug(Poco::format("Preparing to upgrade %s",Entry.first));
|
||||
auto CacheEntry = Cache_.find(Entry.first);
|
||||
uint64_t Now = std::time(nullptr);
|
||||
std::string firmwareUpgrade;
|
||||
if(CacheEntry == Cache_.end() || (CacheEntry->second.LastCheck-Now)>300) {
|
||||
// get the firmware settings for that device.
|
||||
SerialCache C;
|
||||
C.LastCheck = Now;
|
||||
bool firmwareRCOnly;
|
||||
if(CacheEntry == Cache_.end() || (CacheEntry->second.LastCheck-Now)>300) {
|
||||
// get the firmware settings for that device.
|
||||
SerialCache C;
|
||||
C.LastCheck = Now;
|
||||
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;
|
||||
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 {
|
||||
|
||||
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) {
|
||||
Logger_.information("Reinitializing.");
|
||||
Logger().information("Reinitializing.");
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
@@ -8,9 +8,11 @@
|
||||
#include "framework/MicroService.h"
|
||||
#include <deque>
|
||||
#include "Poco/Util/Application.h"
|
||||
#include "Poco/Timer.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class AutoUpdater : public SubSystemServer, Poco::Runnable {
|
||||
|
||||
class AutoUpdater : public SubSystemServer { // };, Poco::Runnable {
|
||||
public:
|
||||
|
||||
struct SerialCache {
|
||||
@@ -19,14 +21,13 @@ class AutoUpdater : public SubSystemServer, Poco::Runnable {
|
||||
bool firmwareRCOnly=false;
|
||||
};
|
||||
|
||||
static AutoUpdater *instance() {
|
||||
static AutoUpdater *instance_ = new AutoUpdater;
|
||||
static auto instance() {
|
||||
static auto instance_ = new AutoUpdater;
|
||||
return instance_;
|
||||
}
|
||||
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
void run() final;
|
||||
void ToBeUpgraded(std::string serialNumber, std::string DeviceType);
|
||||
inline void Reset() {
|
||||
std::lock_guard G(Mutex_);
|
||||
@@ -34,21 +35,24 @@ class AutoUpdater : public SubSystemServer, Poco::Runnable {
|
||||
Queue_.clear();
|
||||
}
|
||||
void reinitialize(Poco::Util::Application &self) final;
|
||||
void onTimer(Poco::Timer & timer);
|
||||
|
||||
private:
|
||||
std::atomic_bool Running_=false;
|
||||
Poco::Thread Thr_;
|
||||
std::map<std::string,SerialCache> Cache_;
|
||||
std::deque<std::pair<std::string,std::string>> Queue_;
|
||||
uint64_t AutoUpdaterFrequency_=600;
|
||||
bool AutoUpdaterEnabled_=true;
|
||||
std::atomic_bool Running_=false;
|
||||
std::map<std::string,SerialCache> Cache_;
|
||||
std::deque<std::pair<std::string,std::string>> Queue_;
|
||||
uint64_t AutoUpdaterFrequency_=600;
|
||||
bool AutoUpdaterEnabled_=true;
|
||||
Poco::Timer Timer_;
|
||||
std::unique_ptr<Poco::TimerCallback<AutoUpdater>> AutoUpdaterCallBack_;
|
||||
|
||||
explicit AutoUpdater() noexcept:
|
||||
SubSystemServer("AutoUpdater", "AUTO-UPDATER", "autoupdater")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
inline AutoUpdater * AutoUpdater() { return AutoUpdater::instance(); }
|
||||
inline auto AutoUpdater() { return AutoUpdater::instance(); }
|
||||
}
|
||||
|
||||
#endif //OWFMS_AUTOUPDATER_H
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "DeviceCache.h"
|
||||
#include "FirmwareCache.h"
|
||||
#include "AutoUpdater.h"
|
||||
#include "NewCommandHandler.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class Daemon *Daemon::instance_ = nullptr;
|
||||
@@ -35,7 +36,8 @@ namespace OpenWifi {
|
||||
DeviceCache(),
|
||||
NewConnectionHandler(),
|
||||
ManifestCreator(),
|
||||
AutoUpdater()
|
||||
AutoUpdater(),
|
||||
NewCommandHandler()
|
||||
});
|
||||
}
|
||||
return instance_;
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace OpenWifi {
|
||||
|
||||
if(LastRun_==0 || (Now-LastRun_)>120) {
|
||||
DB_.reset();
|
||||
StorageService()->GenerateDeviceReport(DB_);
|
||||
StorageService()->DevicesDB().GenerateDeviceReport(DB_);
|
||||
LastRun_ = Now;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@ namespace OpenWifi {
|
||||
|
||||
class DeviceCache : public SubSystemServer {
|
||||
public:
|
||||
static DeviceCache *instance() {
|
||||
static DeviceCache *instance_ = new DeviceCache;
|
||||
static auto instance() {
|
||||
static auto instance_ = new DeviceCache;
|
||||
return instance_;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace OpenWifi {
|
||||
}
|
||||
};
|
||||
|
||||
inline DeviceCache * DeviceCache() { return DeviceCache::instance(); }
|
||||
inline auto DeviceCache() { return DeviceCache::instance(); }
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -17,8 +17,8 @@ namespace OpenWifi {
|
||||
|
||||
class FirmwareCache: public SubSystemServer {
|
||||
public:
|
||||
static FirmwareCache *instance() {
|
||||
static FirmwareCache *instance_= new FirmwareCache;
|
||||
static auto instance() {
|
||||
static auto instance_= new FirmwareCache;
|
||||
return instance_;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace OpenWifi {
|
||||
}
|
||||
};
|
||||
|
||||
inline FirmwareCache * FirmwareCache() { return FirmwareCache::instance(); }
|
||||
inline auto FirmwareCache() { return FirmwareCache::instance(); }
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
namespace OpenWifi {
|
||||
|
||||
int LatestFirmwareCache::Start() {
|
||||
StorageService()->PopulateLatestFirmwareCache();
|
||||
StorageService()->FirmwaresDB().PopulateLatestFirmwareCache();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,8 +24,8 @@ namespace OpenWifi {
|
||||
|
||||
class LatestFirmwareCache : public SubSystemServer {
|
||||
public:
|
||||
static LatestFirmwareCache *instance() {
|
||||
static LatestFirmwareCache *instance_ = new LatestFirmwareCache;
|
||||
static auto instance() {
|
||||
static auto instance_ = new LatestFirmwareCache;
|
||||
return instance_;
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace OpenWifi {
|
||||
}
|
||||
};
|
||||
|
||||
inline LatestFirmwareCache * LatestFirmwareCache() { return LatestFirmwareCache::instance(); }
|
||||
inline auto LatestFirmwareCache() { return LatestFirmwareCache::instance(); }
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -16,25 +16,14 @@
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
void ManifestCreator::run() {
|
||||
Running_ = true;
|
||||
bool FirstRun = true;
|
||||
|
||||
while(Running_) {
|
||||
Poco::Thread::trySleep(FirstRun ? 10000 : DBRefresh_*1000);
|
||||
if(!Running_)
|
||||
break;
|
||||
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);
|
||||
}
|
||||
void ManifestCreator::onTimer(Poco::Timer &timer) {
|
||||
Logger().information("Performing DB refresh");
|
||||
S3BucketContent BucketList;
|
||||
StorageService()->FirmwaresDB().RemoveOldFirmware();
|
||||
ReadBucket(BucketList);
|
||||
Logger().information(Poco::format("Found %Lu firmware entries in S3 repository.",(uint64_t)BucketList.size()));
|
||||
ComputeManifest(BucketList);
|
||||
AddManifestToDB(BucketList);
|
||||
}
|
||||
|
||||
bool ManifestCreator::ComputeManifest(S3BucketContent &BucketContent) {
|
||||
@@ -59,7 +48,7 @@ namespace OpenWifi {
|
||||
Entry.Image = ParsedContent->get("image").toString();
|
||||
auto FullNme = Name + "-upgrade.bin";
|
||||
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;
|
||||
BadFormat++;
|
||||
continue;
|
||||
@@ -71,19 +60,19 @@ namespace OpenWifi {
|
||||
Entry.Valid = false;
|
||||
}
|
||||
} 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++;
|
||||
Entry.Valid = false;
|
||||
}
|
||||
} catch (const Poco::Exception &E ) {
|
||||
Logger_.log(E);
|
||||
Logger().log(E);
|
||||
}
|
||||
}
|
||||
|
||||
Logger_.information(Poco::format("Accepted %Lu firmwares.", Accepted));
|
||||
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 missing JSON.", MissingJson));
|
||||
Logger().information(Poco::format("Accepted %Lu firmwares.", Accepted));
|
||||
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 missing JSON.", MissingJson));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -98,7 +87,7 @@ namespace OpenWifi {
|
||||
if(BucketEntry.URI.find("-staging-")!=std::string::npos)
|
||||
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.release = Release;
|
||||
F.size = BucketEntry.S3Size;
|
||||
@@ -108,8 +97,8 @@ namespace OpenWifi {
|
||||
F.uri = BucketEntry.URI;
|
||||
F.revision = BucketEntry.Revision;
|
||||
F.deviceType = BucketEntry.Compatible;
|
||||
if(StorageService()->AddFirmware(F)) {
|
||||
Logger_.information(Poco::format("Adding firmware '%s'",Release));
|
||||
if(StorageService()->FirmwaresDB().AddFirmware(F)) {
|
||||
Logger().information(Poco::format("Adding firmware '%s'",Release));
|
||||
} else {
|
||||
}
|
||||
}
|
||||
@@ -118,6 +107,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
int ManifestCreator::Start() {
|
||||
Running_ = true;
|
||||
S3BucketName_ = MicroService::instance().ConfigGetString("s3.bucketname");
|
||||
S3Region_ = MicroService::instance().ConfigGetString("s3.region");
|
||||
S3Secret_ = MicroService::instance().ConfigGetString("s3.secret");
|
||||
@@ -135,23 +125,21 @@ namespace OpenWifi {
|
||||
AwsCreds_.SetAWSAccessKeyId(S3Key_);
|
||||
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;
|
||||
}
|
||||
|
||||
void ManifestCreator::Stop() {
|
||||
if(Running_) {
|
||||
Running_ = false;
|
||||
Worker_.wakeUp();
|
||||
Worker_.join();
|
||||
Timer_.stop();
|
||||
}
|
||||
}
|
||||
|
||||
bool ManifestCreator::Update() {
|
||||
Worker_.wakeUp();
|
||||
return true;
|
||||
}
|
||||
|
||||
void ManifestCreator::CloseBucket() {
|
||||
}
|
||||
|
||||
@@ -196,7 +184,7 @@ namespace OpenWifi {
|
||||
while(!isDone) {
|
||||
Outcome = S3Client.ListObjectsV2(Request);
|
||||
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().GetMessage()}));
|
||||
return false;
|
||||
@@ -280,7 +268,7 @@ namespace OpenWifi {
|
||||
|
||||
// std::cout << "Count:" << Count << " Runs:" << Runs << std::endl;
|
||||
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().GetMessage()}));
|
||||
return false;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <aws/core/auth/AWSCredentials.h>
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
#include "Poco/Timer.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
@@ -28,17 +29,15 @@ namespace OpenWifi {
|
||||
};
|
||||
typedef std::map<const std::string, S3BucketEntry> S3BucketContent;
|
||||
|
||||
class ManifestCreator : public SubSystemServer, Poco::Runnable {
|
||||
class ManifestCreator : public SubSystemServer {
|
||||
public:
|
||||
static ManifestCreator *instance() {
|
||||
static ManifestCreator *instance_ = new ManifestCreator;
|
||||
static auto instance() {
|
||||
static auto instance_ = new ManifestCreator;
|
||||
return instance_;
|
||||
}
|
||||
|
||||
void run() override;
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
bool Update();
|
||||
|
||||
bool ComputeManifest(S3BucketContent & BucketContent);
|
||||
bool AddManifestToDB(S3BucketContent & BucketContent);
|
||||
@@ -48,10 +47,9 @@ namespace OpenWifi {
|
||||
void CloseBucket();
|
||||
void Print(const S3BucketContent &B);
|
||||
uint64_t MaxAge() const { return MaxAge_; }
|
||||
void onTimer(Poco::Timer & timer);
|
||||
|
||||
private:
|
||||
static ManifestCreator *instance_;
|
||||
Poco::Thread Worker_;
|
||||
std::atomic_bool Running_ = false;
|
||||
Aws::String S3BucketName_;
|
||||
Aws::String S3Region_;
|
||||
@@ -62,13 +60,15 @@ namespace OpenWifi {
|
||||
Aws::Auth::AWSCredentials AwsCreds_;
|
||||
uint64_t DBRefresh_ = 30 * 60;
|
||||
uint64_t MaxAge_ = 0 ;
|
||||
Poco::Timer Timer_;
|
||||
std::unique_ptr<Poco::TimerCallback<ManifestCreator>> ManifestCreatorCallBack_;
|
||||
|
||||
ManifestCreator() noexcept:
|
||||
SubSystemServer("ManifestCreator", "MANIFEST-MGR", "manifestcreator") {
|
||||
}
|
||||
};
|
||||
|
||||
inline ManifestCreator * ManifestCreator() { return ManifestCreator::instance(); };
|
||||
inline auto ManifestCreator() { return ManifestCreator::instance(); };
|
||||
|
||||
}
|
||||
|
||||
|
||||
86
src/NewCommandHandler.cpp
Normal file
86
src/NewCommandHandler.cpp
Normal 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
41
src/NewCommandHandler.h
Normal 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
|
||||
@@ -64,15 +64,15 @@ namespace OpenWifi {
|
||||
auto Revision = Storage::TrimRevision(PayloadObj->get(uCentralProtocol::FIRMWARE).toString());
|
||||
// std::cout << "ConnectionEvent: SerialNumber: " << SerialNumber << " DeviceType: " << DeviceType << " Revision:" << Revision << std::endl;
|
||||
FMSObjects::FirmwareAgeDetails FA;
|
||||
if(StorageService()->ComputeFirmwareAge(DeviceType, Revision, FA)) {
|
||||
StorageService()->SetDeviceRevision(SerialNumber, Revision, DeviceType, EndPoint);
|
||||
if(StorageService()->FirmwaresDB().ComputeFirmwareAge(DeviceType, Revision, FA)) {
|
||||
StorageService()->DevicesDB().SetDeviceRevision(SerialNumber, Revision, DeviceType, EndPoint);
|
||||
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
|
||||
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 {
|
||||
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)) {
|
||||
@@ -86,7 +86,7 @@ namespace OpenWifi {
|
||||
if(DisconnectMessage->has(uCentralProtocol::SERIALNUMBER) && DisconnectMessage->has(uCentralProtocol::TIMESTAMP)) {
|
||||
auto SNum = DisconnectMessage->get(uCentralProtocol::SERIALNUMBER).toString();
|
||||
auto Timestamp = DisconnectMessage->get(uCentralProtocol::TIMESTAMP);
|
||||
StorageService()->SetDeviceDisconnected(SNum,EndPoint);
|
||||
StorageService()->DevicesDB().SetDeviceDisconnected(SNum,EndPoint);
|
||||
// std::cout << "DISCONNECTION:" << SerialNumber << std::endl;
|
||||
}
|
||||
} else if(PayloadObj->has(uCentralProtocol::PING)) {
|
||||
@@ -98,7 +98,7 @@ namespace OpenWifi {
|
||||
auto Revision = Storage::TrimRevision(PingMessage->get(uCentralProtocol::FIRMWARE).toString());
|
||||
auto Serial = PingMessage->get( uCentralProtocol::SERIALNUMBER).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);
|
||||
if(!LatestFirmwareCache()->IsLatest(DeviceType, Revision)) {
|
||||
// std::cout << "Device(ping): " << SerialNumber << " to be upgraded ... " << std::endl;
|
||||
@@ -108,7 +108,7 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
Logger().log(E);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,8 +14,8 @@ namespace OpenWifi {
|
||||
class NewConnectionHandler : public SubSystemServer, Poco::Runnable {
|
||||
public:
|
||||
|
||||
static NewConnectionHandler *instance() {
|
||||
static NewConnectionHandler *instance_ = new NewConnectionHandler;
|
||||
static auto instance() {
|
||||
static auto instance_ = new NewConnectionHandler;
|
||||
return instance_;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
};
|
||||
inline NewConnectionHandler * NewConnectionHandler() { return NewConnectionHandler::instance(); };
|
||||
inline auto NewConnectionHandler() { return NewConnectionHandler::instance(); };
|
||||
}
|
||||
|
||||
#endif //UCENTRALFMS_NEWCONNECTIONHANDLER_H
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
Poco::Net::HTTPRequestHandler * RESTAPI_external_server(const char *Path, RESTAPIHandler::BindingMap &Bindings,
|
||||
Poco::Logger & L, RESTAPI_GenericServer & S) {
|
||||
Poco::Net::HTTPRequestHandler * RESTAPI_ExtRouter(const char *Path, RESTAPIHandler::BindingMap &Bindings,
|
||||
Poco::Logger & L, RESTAPI_GenericServer & S, uint64_t TransactionId) {
|
||||
return RESTAPI_Router<
|
||||
RESTAPI_firmwaresHandler,
|
||||
RESTAPI_firmwareHandler,
|
||||
@@ -25,17 +25,17 @@ namespace OpenWifi {
|
||||
RESTAPI_connectedDeviceHandler,
|
||||
RESTAPI_historyHandler,
|
||||
RESTAPI_deviceReportHandler
|
||||
>(Path,Bindings,L, S);
|
||||
>(Path,Bindings,L, S, TransactionId);
|
||||
}
|
||||
|
||||
Poco::Net::HTTPRequestHandler * RESTAPI_internal_server(const char *Path, RESTAPIHandler::BindingMap &Bindings,
|
||||
Poco::Logger & L, RESTAPI_GenericServer & S) {
|
||||
Poco::Net::HTTPRequestHandler * RESTAPI_IntRouter(const char *Path, RESTAPIHandler::BindingMap &Bindings,
|
||||
Poco::Logger & L, RESTAPI_GenericServer & S, uint64_t TransactionId) {
|
||||
return RESTAPI_Router_I<
|
||||
RESTAPI_firmwaresHandler,
|
||||
RESTAPI_firmwareHandler,
|
||||
RESTAPI_system_command,
|
||||
RESTAPI_connectedDevicesHandler,
|
||||
RESTAPI_connectedDeviceHandler
|
||||
>(Path, Bindings, L, S);
|
||||
>(Path, Bindings, L, S, TransactionId);
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
FMSObjects::DeviceConnectionInformation DevInfo;
|
||||
if(StorageService()->GetDevice(SerialNumber, DevInfo)) {
|
||||
if(StorageService()->DevicesDB().GetDevice(SerialNumber, DevInfo)) {
|
||||
Poco::JSON::Object Answer;
|
||||
DevInfo.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
|
||||
@@ -10,12 +10,13 @@
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_connectedDeviceHandler : public RESTAPIHandler {
|
||||
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,
|
||||
std::vector<std::string>
|
||||
{Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server,
|
||||
TransactionId,
|
||||
Internal) {}
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/connectedDevice/{serialNumber}"};}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace OpenWifi {
|
||||
std::vector<FMSObjects::DeviceConnectionInformation> Devices;
|
||||
Poco::JSON::Object AnswerObj;
|
||||
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) {
|
||||
Poco::JSON::Object Obj;
|
||||
i.to_json(Obj);
|
||||
|
||||
@@ -11,12 +11,13 @@
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_connectedDevicesHandler : public RESTAPIHandler {
|
||||
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,
|
||||
std::vector<std::string>
|
||||
{Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server,
|
||||
TransactionId,
|
||||
Internal) {}
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/connectedDevices"};}
|
||||
void DoGet() final;
|
||||
|
||||
@@ -10,12 +10,13 @@
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_deviceReportHandler : public RESTAPIHandler {
|
||||
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,
|
||||
std::vector<std::string>
|
||||
{Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server,
|
||||
TransactionId,
|
||||
Internal) {}
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/deviceReport"};}
|
||||
void DoGet() final;
|
||||
|
||||
@@ -11,16 +11,16 @@
|
||||
#include "framework/RESTAPI_protocol.h"
|
||||
#include "framework/RESTAPI_errors.h"
|
||||
|
||||
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_firmwareAgeHandler::DoGet() {
|
||||
if (!QB_.Select.empty()) {
|
||||
Poco::JSON::Array Objects;
|
||||
std::vector<std::string> Numbers = Utils::Split(QB_.Select);
|
||||
for (auto &i : Numbers) {
|
||||
for (auto &i : SelectedRecords()) {
|
||||
DeviceCacheEntry E;
|
||||
if (DeviceCache()->GetDevice(i, E)) {
|
||||
FMSObjects::FirmwareAgeDetails FA;
|
||||
if(StorageService()->ComputeFirmwareAge(E.deviceType,E.revision,FA)) {
|
||||
if(StorageService()->FirmwaresDB().ComputeFirmwareAge(E.deviceType,E.revision,FA)) {
|
||||
Poco::JSON::Object O;
|
||||
FA.to_json(O);
|
||||
O.set(uCentralProtocol::SERIALNUMBER,i);
|
||||
@@ -50,7 +50,7 @@ namespace OpenWifi {
|
||||
Revision = Storage::TrimRevision(Revision);
|
||||
|
||||
FMSObjects::FirmwareAgeDetails FA;
|
||||
if (StorageService()->ComputeFirmwareAge(DeviceType, Revision, FA)) {
|
||||
if (StorageService()->FirmwaresDB().ComputeFirmwareAge(DeviceType, Revision, FA)) {
|
||||
Poco::JSON::Object Answer;
|
||||
|
||||
FA.to_json(Answer);
|
||||
|
||||
@@ -10,12 +10,13 @@
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_firmwareAgeHandler : public RESTAPIHandler {
|
||||
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,
|
||||
std::vector<std::string>
|
||||
{Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server,
|
||||
TransactionId,
|
||||
Internal) {}
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/firmwareAge"};}
|
||||
void DoGet() final;
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace OpenWifi {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
F.id = MicroService::instance().CreateUUID();
|
||||
if(StorageService()->AddFirmware(F)) {
|
||||
if(StorageService()->FirmwaresDB().AddFirmware(F)) {
|
||||
Poco::JSON::Object Answer;
|
||||
F.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
@@ -36,7 +36,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
FMSObjects::Firmware F;
|
||||
if (StorageService()->GetFirmware(UUID, F)) {
|
||||
if (StorageService()->FirmwaresDB().GetFirmware(UUID, F)) {
|
||||
Poco::JSON::Object Object;
|
||||
F.to_json(Object);
|
||||
return ReturnObject(Object);
|
||||
@@ -51,7 +51,7 @@ namespace OpenWifi {
|
||||
return BadRequest(RESTAPI::Errors::MissingUUID);
|
||||
}
|
||||
|
||||
if (StorageService()->DeleteFirmware(UUID)) {
|
||||
if (StorageService()->FirmwaresDB().DeleteFirmware(UUID)) {
|
||||
return OK();
|
||||
}
|
||||
BadRequest(RESTAPI::Errors::CouldNotBeDeleted);
|
||||
@@ -64,7 +64,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
FMSObjects::Firmware F;
|
||||
if(!StorageService()->GetFirmware(UUID, F)) {
|
||||
if(!StorageService()->FirmwaresDB().GetFirmware(UUID, F)) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
|
||||
if(StorageService()->UpdateFirmware(UUID, F)) {
|
||||
if(StorageService()->FirmwaresDB().UpdateFirmware(UUID, F)) {
|
||||
Poco::JSON::Object Answer;
|
||||
F.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_firmwareHandler : public RESTAPIHandler {
|
||||
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,
|
||||
std::vector<std::string>
|
||||
{Poco::Net::HTTPRequest::HTTP_GET,
|
||||
@@ -19,6 +19,7 @@ namespace OpenWifi {
|
||||
Poco::Net::HTTPRequest::HTTP_DELETE,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server,
|
||||
TransactionId,
|
||||
Internal) {}
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/firmware/{id}"};}
|
||||
void DoGet() final;
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
FMSObjects::Firmware F;
|
||||
if(StorageService()->GetFirmware(Entry.Id,F)) {
|
||||
if(StorageService()->FirmwaresDB().GetFirmware(Entry.Id,F)) {
|
||||
Poco::JSON::Object Answer;
|
||||
F.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
@@ -55,7 +55,7 @@ namespace OpenWifi {
|
||||
return NotFound();
|
||||
} else {
|
||||
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;
|
||||
for (const auto &i:List) {
|
||||
if(IdOnly) {
|
||||
@@ -78,7 +78,7 @@ namespace OpenWifi {
|
||||
std::vector<FMSObjects::Firmware> List;
|
||||
Poco::JSON::Array ObjectArray;
|
||||
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) {
|
||||
if(IdOnly) {
|
||||
ObjectArray.add(i.id);
|
||||
|
||||
@@ -10,12 +10,13 @@
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_firmwaresHandler : public RESTAPIHandler {
|
||||
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,
|
||||
std::vector<std::string>
|
||||
{Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server,
|
||||
TransactionId,
|
||||
Internal) {}
|
||||
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/firmwares"};}
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
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;
|
||||
for (auto const &i:H) {
|
||||
Poco::JSON::Object O;
|
||||
@@ -38,7 +38,7 @@ namespace OpenWifi {
|
||||
return BadRequest(RESTAPI::Errors::IdOrSerialEmpty);
|
||||
}
|
||||
|
||||
if (!StorageService()->DeleteHistory(SerialNumber, Id)) {
|
||||
if (!StorageService()->HistoryDB().DeleteHistory(SerialNumber, Id)) {
|
||||
return OK();
|
||||
}
|
||||
NotFound();
|
||||
|
||||
@@ -11,13 +11,14 @@
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_historyHandler : public RESTAPIHandler {
|
||||
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,
|
||||
std::vector<std::string>
|
||||
{Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_DELETE,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server,
|
||||
TransactionId,
|
||||
Internal) {}
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/revisionHistory/{serialNumber}"};}
|
||||
void DoGet() final;
|
||||
|
||||
178
src/RESTObjects/RESTAPI_CertObjects.cpp
Normal file
178
src/RESTObjects/RESTAPI_CertObjects.cpp
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
101
src/RESTObjects/RESTAPI_CertObjects.h
Normal file
101
src/RESTObjects/RESTAPI_CertObjects.h
Normal 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);
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,7 @@ namespace OpenWifi::FMSObjects {
|
||||
std::string location;
|
||||
std::string uploader;
|
||||
std::string digest;
|
||||
bool latest=false;
|
||||
bool latest=0;
|
||||
SecurityObjects::NoteInfoVec notes;
|
||||
uint64_t created=0;
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "Daemon.h"
|
||||
#ifdef TIP_GATEWAY_SERVICE
|
||||
#include "DeviceRegistry.h"
|
||||
#include "CapabilitiesCache.h"
|
||||
#endif
|
||||
|
||||
#include "RESTAPI_GWobjects.h"
|
||||
@@ -26,7 +27,7 @@ namespace OpenWifi::GWObjects {
|
||||
void Device::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"serialNumber", SerialNumber);
|
||||
#ifdef TIP_GATEWAY_SERVICE
|
||||
field_to_json(Obj,"deviceType", Daemon::instance()->IdentifyDevice(Compatible));
|
||||
field_to_json(Obj,"deviceType", CapabilitiesCache::instance()->Get(Compatible));
|
||||
#endif
|
||||
field_to_json(Obj,"macAddress", MACAddress);
|
||||
field_to_json(Obj,"manufacturer", Manufacturer);
|
||||
@@ -145,6 +146,7 @@ namespace OpenWifi::GWObjects {
|
||||
field_to_json(Obj,"custom", Custom);
|
||||
field_to_json(Obj,"waitingForFile", WaitingForFile);
|
||||
field_to_json(Obj,"attachFile", AttachDate);
|
||||
field_to_json(Obj,"executionTime", executionTime);
|
||||
}
|
||||
|
||||
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 {
|
||||
field_to_json(Obj,"serialNumber", SerialNumber);
|
||||
field_to_json(Obj,"ipAddress", Address);
|
||||
field_to_json(Obj,"txBytes", TX);
|
||||
field_to_json(Obj,"rxBytes", RX);
|
||||
@@ -190,6 +191,10 @@ namespace OpenWifi::GWObjects {
|
||||
field_to_json(Obj,"lastContact", LastContact);
|
||||
field_to_json(Obj,"associations_2G", Associations_2G);
|
||||
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) {
|
||||
case NO_CERTIFICATE:
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
#ifndef UCENTRAL_RESTAPI_OBJECTS_H
|
||||
#define UCENTRAL_RESTAPI_OBJECTS_H
|
||||
#pragma once
|
||||
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include "RESTAPI_SecurityObjects.h"
|
||||
@@ -23,7 +22,6 @@ namespace OpenWifi::GWObjects {
|
||||
|
||||
struct ConnectionState {
|
||||
uint64_t MessageCount = 0 ;
|
||||
std::string SerialNumber;
|
||||
std::string Address;
|
||||
uint64_t UUID = 0 ;
|
||||
uint64_t PendingUUID = 0 ;
|
||||
@@ -35,6 +33,10 @@ namespace OpenWifi::GWObjects {
|
||||
std::string Firmware;
|
||||
CertificateValidation VerifiedCertificate = NO_CERTIFICATE;
|
||||
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;
|
||||
};
|
||||
|
||||
@@ -50,11 +52,11 @@ namespace OpenWifi::GWObjects {
|
||||
std::string Firmware;
|
||||
std::string Compatible;
|
||||
std::string FWUpdatePolicy;
|
||||
uint64_t UUID;
|
||||
uint64_t CreationTimestamp;
|
||||
uint64_t LastConfigurationChange;
|
||||
uint64_t LastConfigurationDownload;
|
||||
uint64_t LastFWUpdate;
|
||||
uint64_t UUID = 0 ;
|
||||
uint64_t CreationTimestamp = 0 ;
|
||||
uint64_t LastConfigurationChange = 0 ;
|
||||
uint64_t LastConfigurationDownload = 0 ;
|
||||
uint64_t LastFWUpdate = 0 ;
|
||||
std::string Venue;
|
||||
std::string DevicePassword;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
@@ -65,25 +67,25 @@ namespace OpenWifi::GWObjects {
|
||||
|
||||
struct Statistics {
|
||||
std::string SerialNumber;
|
||||
uint64_t UUID;
|
||||
uint64_t UUID = 0 ;
|
||||
std::string Data;
|
||||
uint64_t Recorded;
|
||||
uint64_t Recorded = 0;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
};
|
||||
|
||||
struct HealthCheck {
|
||||
std::string SerialNumber;
|
||||
uint64_t UUID;
|
||||
uint64_t UUID = 0 ;
|
||||
std::string Data;
|
||||
uint64_t Recorded;
|
||||
uint64_t Sanity;
|
||||
uint64_t Recorded = 0 ;
|
||||
uint64_t Sanity = 0 ;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
};
|
||||
|
||||
struct Capabilities {
|
||||
std::string Capabilities;
|
||||
uint64_t FirstUpdate;
|
||||
uint64_t LastUpdate;
|
||||
uint64_t FirstUpdate = 0 ;
|
||||
uint64_t LastUpdate = 0 ;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
};
|
||||
|
||||
@@ -101,17 +103,17 @@ namespace OpenWifi::GWObjects {
|
||||
std::string SerialNumber;
|
||||
std::string Log;
|
||||
std::string Data;
|
||||
uint64_t Severity;
|
||||
uint64_t Recorded;
|
||||
uint64_t LogType;
|
||||
uint64_t UUID;
|
||||
uint64_t Severity = 0 ;
|
||||
uint64_t Recorded = 0 ;
|
||||
uint64_t LogType = 0 ;
|
||||
uint64_t UUID = 0 ;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
};
|
||||
|
||||
struct DefaultConfiguration {
|
||||
std::string Name;
|
||||
std::string Configuration;
|
||||
std::string Models;
|
||||
Types::StringVec Models;
|
||||
std::string Description;
|
||||
uint64_t Created;
|
||||
uint64_t LastModified;
|
||||
@@ -138,6 +140,7 @@ namespace OpenWifi::GWObjects {
|
||||
uint64_t AttachDate = 0 ;
|
||||
uint64_t AttachSize = 0 ;
|
||||
std::string AttachType;
|
||||
double executionTime = 0.0;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
};
|
||||
|
||||
@@ -153,20 +156,20 @@ namespace OpenWifi::GWObjects {
|
||||
struct RttySessionDetails {
|
||||
std::string SerialNumber;
|
||||
std::string Server;
|
||||
uint64_t Port;
|
||||
uint64_t Port = 0 ;
|
||||
std::string Token;
|
||||
uint64_t TimeOut;
|
||||
uint64_t TimeOut = 0 ;
|
||||
std::string ConnectionId;
|
||||
uint64_t Started;
|
||||
uint64_t Started = 0 ;
|
||||
std::string CommandUUID;
|
||||
uint64_t ViewPort;
|
||||
uint64_t ViewPort = 0 ;
|
||||
std::string DevicePassword;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
};
|
||||
|
||||
struct Dashboard {
|
||||
uint64_t snapshot;
|
||||
uint64_t numberOfDevices;
|
||||
uint64_t snapshot = 0 ;
|
||||
uint64_t numberOfDevices = 0 ;
|
||||
Types::CountedMap commands;
|
||||
Types::CountedMap upTimes;
|
||||
Types::CountedMap memoryUsed;
|
||||
@@ -191,5 +194,3 @@ namespace OpenWifi::GWObjects {
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //UCENTRAL_RESTAPI_OBJECTS_H
|
||||
|
||||
@@ -309,6 +309,7 @@ namespace OpenWifi::ProvObjects {
|
||||
field_to_json( Obj,"deviceConfiguration",deviceConfiguration);
|
||||
field_to_json( Obj,"rrm",rrm);
|
||||
field_to_json( Obj,"managementPolicy",managementPolicy);
|
||||
field_to_json( Obj,"state",state);
|
||||
}
|
||||
|
||||
bool InventoryTag::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
@@ -326,6 +327,7 @@ namespace OpenWifi::ProvObjects {
|
||||
field_from_json( Obj,"deviceConfiguration",deviceConfiguration);
|
||||
field_from_json( Obj,"rrm",rrm);
|
||||
field_from_json( Obj,"managementPolicy",managementPolicy);
|
||||
field_from_json( Obj,"state",state);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
@@ -333,6 +335,20 @@ namespace OpenWifi::ProvObjects {
|
||||
return false;
|
||||
}
|
||||
|
||||
void InventoryTagList::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json( Obj,"taglist",taglist);
|
||||
}
|
||||
|
||||
bool InventoryTagList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json( Obj,"taglist",taglist);
|
||||
return false;
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
void DeviceConfigurationElement::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json( Obj,"name", name);
|
||||
field_to_json( Obj,"description", description);
|
||||
@@ -440,11 +456,11 @@ namespace OpenWifi::ProvObjects {
|
||||
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);
|
||||
}
|
||||
|
||||
bool UserList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
bool UuidList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "list", list);
|
||||
return true;
|
||||
@@ -454,14 +470,46 @@ namespace OpenWifi::ProvObjects {
|
||||
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 {
|
||||
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);
|
||||
}
|
||||
|
||||
bool ObjectACL::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
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);
|
||||
return true;
|
||||
} catch(...) {
|
||||
@@ -471,12 +519,12 @@ namespace OpenWifi::ProvObjects {
|
||||
}
|
||||
|
||||
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) {
|
||||
try {
|
||||
field_from_json(Obj, "list", list);
|
||||
RESTAPI_utils::field_from_json(Obj, "list", list);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
@@ -484,23 +532,54 @@ namespace OpenWifi::ProvObjects {
|
||||
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 {
|
||||
info.to_json(Obj);
|
||||
field_to_json( Obj,"data",data);
|
||||
field_to_json( Obj,"entity",entity);
|
||||
field_to_json( Obj,"creator",creator);
|
||||
RESTAPI_utils::field_to_json( Obj,"data",data);
|
||||
RESTAPI_utils::field_to_json( Obj,"entity",entity);
|
||||
RESTAPI_utils::field_to_json( Obj,"creator",creator);
|
||||
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) {
|
||||
try {
|
||||
info.from_json(Obj);
|
||||
field_from_json( Obj,"data",data);
|
||||
field_from_json( Obj,"entity",entity);
|
||||
field_from_json( Obj,"creator",creator);
|
||||
RESTAPI_utils::field_from_json( Obj,"data",data);
|
||||
RESTAPI_utils::field_from_json( Obj,"entity",entity);
|
||||
RESTAPI_utils::field_from_json( Obj,"creator",creator);
|
||||
field_from_json( Obj,"visibility",visibility);
|
||||
field_from_json( Obj,"access",access);
|
||||
RESTAPI_utils::field_from_json( Obj,"access",access);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
@@ -509,12 +588,12 @@ namespace OpenWifi::ProvObjects {
|
||||
}
|
||||
|
||||
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) {
|
||||
try {
|
||||
field_from_json( Obj,"list",list);
|
||||
RESTAPI_utils::field_from_json( Obj,"list",list);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
@@ -530,7 +609,7 @@ namespace OpenWifi::ProvObjects {
|
||||
if(I.name.empty())
|
||||
return false;
|
||||
|
||||
if(O->has("description"))
|
||||
if(O->has("description"))
|
||||
I.description = O->get("description").toString();
|
||||
SecurityObjects::MergeNotes(O,U,I.notes);
|
||||
SecurityObjects::NoteInfoVec N;
|
||||
@@ -562,8 +641,9 @@ namespace OpenWifi::ProvObjects {
|
||||
}
|
||||
I.notes = N;
|
||||
I.modified = I.created = Now;
|
||||
I.id = MicroService::instance().CreateUUID();
|
||||
I.id = MicroService::CreateUUID();
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -6,9 +6,7 @@
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
|
||||
#ifndef OWPROV_RESTAPI_PROVOBJECTS_H
|
||||
#define OWPROV_RESTAPI_PROVOBJECTS_H
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "RESTAPI_SecurityObjects.h"
|
||||
@@ -286,12 +284,22 @@ namespace OpenWifi::ProvObjects {
|
||||
std::string deviceConfiguration;
|
||||
std::string rrm;
|
||||
Types::UUID_t managementPolicy;
|
||||
std::string state;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
typedef std::vector<InventoryTag> InventoryTagVec;
|
||||
|
||||
struct InventoryTagList {
|
||||
InventoryTagVec taglist;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
|
||||
struct Report {
|
||||
uint64_t snapShot=0;
|
||||
Types::CountedMap tenants;
|
||||
@@ -324,16 +332,21 @@ namespace OpenWifi::ProvObjects {
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct UserList {
|
||||
struct UuidList {
|
||||
std::vector<std::string> list;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
enum ACLACCESS {
|
||||
NONE, READ, MODIFY, CREATE, DELETE
|
||||
};
|
||||
|
||||
struct ObjectACL {
|
||||
UserList users;
|
||||
std::string access;
|
||||
UuidList users;
|
||||
UuidList roles;
|
||||
ACLACCESS access = NONE;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
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);
|
||||
};
|
||||
|
||||
enum VISIBILITY {
|
||||
PUBLIC, PRIVATE, SELECT
|
||||
};
|
||||
|
||||
std::string to_string(VISIBILITY A);
|
||||
VISIBILITY visibility_from_string(const std::string &V);
|
||||
|
||||
struct Map {
|
||||
ObjectInfo info;
|
||||
std::string data;
|
||||
std::string entity;
|
||||
std::string creator;
|
||||
std::string visibility;
|
||||
VISIBILITY visibility = PRIVATE;
|
||||
ObjectACLList access;
|
||||
|
||||
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 CreateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I);
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //OWPROV_RESTAPI_PROVOBJECTS_H
|
||||
|
||||
@@ -54,6 +54,8 @@ namespace OpenWifi::SecurityObjects {
|
||||
return ADMIN;
|
||||
else if (!Poco::icompare(U,"subscriber"))
|
||||
return SUBSCRIBER;
|
||||
else if (!Poco::icompare(U,"partner"))
|
||||
return PARTNER;
|
||||
else if (!Poco::icompare(U,"csr"))
|
||||
return CSR;
|
||||
else if (!Poco::icompare(U, "system"))
|
||||
@@ -72,6 +74,7 @@ namespace OpenWifi::SecurityObjects {
|
||||
case ROOT: return "root";
|
||||
case ADMIN: return "admin";
|
||||
case SUBSCRIBER: return "subscriber";
|
||||
case PARTNER: return "partner";
|
||||
case CSR: return "csr";
|
||||
case SYSTEM: return "system";
|
||||
case INSTALLER: return "installer";
|
||||
@@ -169,12 +172,14 @@ namespace OpenWifi::SecurityObjects {
|
||||
void UserLoginLoginExtensions::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj, "mobiles", mobiles);
|
||||
field_to_json(Obj, "mfa", mfa);
|
||||
field_to_json(Obj, "authenticatorSecret", authenticatorSecret);
|
||||
}
|
||||
|
||||
bool UserLoginLoginExtensions::from_json(Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"mobiles",mobiles);
|
||||
field_from_json(Obj,"mfa",mfa);
|
||||
field_from_json(Obj, "authenticatorSecret", authenticatorSecret);
|
||||
return true;
|
||||
} catch (...) {
|
||||
|
||||
@@ -221,7 +226,7 @@ namespace OpenWifi::SecurityObjects {
|
||||
}
|
||||
|
||||
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,"description", description);
|
||||
field_to_json(Obj,"avatar", avatar);
|
||||
@@ -251,11 +256,12 @@ namespace OpenWifi::SecurityObjects {
|
||||
field_to_json(Obj,"lastPasswords",lastPasswords);
|
||||
field_to_json(Obj,"oauthType",oauthType);
|
||||
field_to_json(Obj,"oauthUserInfo",oauthUserInfo);
|
||||
field_to_json(Obj,"modified",modified);
|
||||
};
|
||||
|
||||
bool UserInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"Id",Id);
|
||||
field_from_json(Obj,"id",id);
|
||||
field_from_json(Obj,"name",name);
|
||||
field_from_json(Obj,"description",description);
|
||||
field_from_json(Obj,"avatar",avatar);
|
||||
@@ -265,6 +271,8 @@ namespace OpenWifi::SecurityObjects {
|
||||
field_from_json(Obj,"currentLoginURI",currentLoginURI);
|
||||
field_from_json(Obj,"locale",locale);
|
||||
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(Obj,"securityPolicy",securityPolicy);
|
||||
field_from_json(Obj,"userTypeProprietaryInfo",userTypeProprietaryInfo);
|
||||
@@ -283,6 +291,7 @@ namespace OpenWifi::SecurityObjects {
|
||||
field_from_json(Obj,"lastPasswords",lastPasswords);
|
||||
field_from_json(Obj,"oauthType",oauthType);
|
||||
field_from_json(Obj,"oauthUserInfo",oauthUserInfo);
|
||||
field_from_json(Obj,"modified",modified);
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
|
||||
@@ -491,7 +500,7 @@ namespace OpenWifi::SecurityObjects {
|
||||
field_to_json(Obj,"expires",expires);
|
||||
field_to_json(Obj,"completed",completed);
|
||||
field_to_json(Obj,"canceled",canceled);
|
||||
|
||||
field_to_json(Obj,"userAction",userAction);
|
||||
}
|
||||
|
||||
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,"completed",completed);
|
||||
field_from_json(Obj,"canceled",canceled);
|
||||
field_from_json(Obj,"userAction",userAction);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,244 +6,303 @@
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
#ifndef UCENTRAL_RESTAPI_SECURITYOBJECTS_H
|
||||
#define UCENTRAL_RESTAPI_SECURITYOBJECTS_H
|
||||
#pragma once
|
||||
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include <string>
|
||||
#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 {
|
||||
bool Read_ = true;
|
||||
bool ReadWrite_ = true;
|
||||
bool ReadWriteCreate_ = true;
|
||||
bool Delete_ = true;
|
||||
bool PortalLogin_ = true;
|
||||
typedef std::string USER_ID_TYPE;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj); };
|
||||
struct AclTemplate {
|
||||
bool Read_ = true;
|
||||
bool ReadWrite_ = true;
|
||||
bool ReadWriteCreate_ = true;
|
||||
bool Delete_ = true;
|
||||
bool PortalLogin_ = true;
|
||||
|
||||
struct WebToken {
|
||||
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;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
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);
|
||||
};
|
||||
struct WebToken {
|
||||
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 {
|
||||
UNKNOWN, ROOT, ADMIN, SUBSCRIBER, CSR, SYSTEM, INSTALLER, NOC, ACCOUNTING
|
||||
};
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
USER_ROLE UserTypeFromString(const std::string &U);
|
||||
std::string UserTypeToString(USER_ROLE U);
|
||||
enum USER_ROLE {
|
||||
UNKNOWN, ROOT, ADMIN, SUBSCRIBER, CSR, SYSTEM, INSTALLER, NOC, ACCOUNTING, PARTNER
|
||||
};
|
||||
|
||||
struct NoteInfo {
|
||||
uint64_t created = std::time(nullptr);
|
||||
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;
|
||||
USER_ROLE UserTypeFromString(const std::string &U);
|
||||
std::string UserTypeToString(USER_ROLE U);
|
||||
|
||||
struct MobilePhoneNumber {
|
||||
std::string number;
|
||||
bool verified = false;
|
||||
bool primary = false;
|
||||
struct NoteInfo {
|
||||
uint64_t created = std::time(nullptr);
|
||||
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;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
struct MobilePhoneNumber {
|
||||
std::string number;
|
||||
bool verified = false;
|
||||
bool primary = false;
|
||||
|
||||
struct MfaAuthInfo {
|
||||
bool enabled = false;
|
||||
std::string method;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
struct MfaAuthInfo {
|
||||
bool enabled = false;
|
||||
std::string method;
|
||||
|
||||
struct UserLoginLoginExtensions {
|
||||
std::vector<MobilePhoneNumber> mobiles;
|
||||
struct MfaAuthInfo mfa;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
struct UserLoginLoginExtensions {
|
||||
std::vector<MobilePhoneNumber> mobiles;
|
||||
struct MfaAuthInfo mfa;
|
||||
std::string authenticatorSecret;
|
||||
|
||||
struct MFAChallengeRequest {
|
||||
std::string uuid;
|
||||
std::string question;
|
||||
std::string method;
|
||||
uint64_t created = std::time(nullptr);
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
struct MFAChallengeRequest {
|
||||
std::string uuid;
|
||||
std::string question;
|
||||
std::string method;
|
||||
uint64_t created = std::time(nullptr);
|
||||
|
||||
struct MFAChallengeResponse {
|
||||
std::string uuid;
|
||||
std::string answer;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
struct MFAChallengeResponse {
|
||||
std::string uuid;
|
||||
std::string answer;
|
||||
|
||||
struct UserInfo {
|
||||
std::string Id;
|
||||
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;
|
||||
bool from_json(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<UserInfo> UserInfoVec;
|
||||
struct UserInfo {
|
||||
std::string id;
|
||||
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;
|
||||
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);
|
||||
bool MergeNotes(Poco::JSON::Object::Ptr Obj, const UserInfo &UInfo, NoteInfoVec & Notes);
|
||||
bool MergeNotes(const NoteInfoVec & NewNotes, const UserInfo &UInfo, NoteInfoVec & ExistingNotes);
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
typedef std::vector<UserInfo> UserInfoVec;
|
||||
|
||||
struct InternalServiceInfo {
|
||||
std::string privateURI;
|
||||
std::string publicURI;
|
||||
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;
|
||||
// bool append_from_json(Poco::JSON::Object::Ptr Obj, const UserInfo &UInfo, NoteInfoVec & Notes);
|
||||
bool MergeNotes(Poco::JSON::Object::Ptr Obj, const UserInfo &UInfo, NoteInfoVec & Notes);
|
||||
bool MergeNotes(const NoteInfoVec & NewNotes, const UserInfo &UInfo, NoteInfoVec & ExistingNotes);
|
||||
|
||||
struct InternalSystemServices {
|
||||
std::string key;
|
||||
std::string version;
|
||||
InternalServiceInfoVec services;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
struct InternalServiceInfo {
|
||||
std::string privateURI;
|
||||
std::string publicURI;
|
||||
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 SystemEndpoint {
|
||||
std::string type;
|
||||
uint64_t id = 0;
|
||||
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 InternalSystemServices {
|
||||
std::string key;
|
||||
std::string version;
|
||||
InternalServiceInfoVec services;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct SystemEndpointList {
|
||||
SystemEndpointVec endpoints;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
struct SystemEndpoint {
|
||||
std::string type;
|
||||
uint64_t id = 0;
|
||||
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 {
|
||||
WebToken webtoken;
|
||||
UserInfo userinfo;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
typedef std::map<std::string,SecurityObjects::UserInfoAndPolicy> UserInfoCache;
|
||||
struct SystemEndpointList {
|
||||
SystemEndpointVec endpoints;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
enum ResourceAccessType {
|
||||
NONE,
|
||||
READ,
|
||||
MODIFY,
|
||||
DELETE,
|
||||
CREATE,
|
||||
TEST,
|
||||
MOVE
|
||||
};
|
||||
struct UserInfoAndPolicy {
|
||||
WebToken webtoken;
|
||||
UserInfo userinfo;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
typedef std::map<std::string,SecurityObjects::UserInfoAndPolicy> UserInfoCache;
|
||||
|
||||
ResourceAccessType ResourceAccessTypeFromString(const std::string &s);
|
||||
std::string ResourceAccessTypeToString(const ResourceAccessType & T);
|
||||
enum ResourceAccessType {
|
||||
NONE,
|
||||
READ,
|
||||
MODIFY,
|
||||
DELETE,
|
||||
CREATE,
|
||||
TEST,
|
||||
MOVE
|
||||
};
|
||||
|
||||
struct ProfileAction {
|
||||
std::string resource;
|
||||
ResourceAccessType access;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
typedef std::vector<ProfileAction> ProfileActionVec;
|
||||
ResourceAccessType ResourceAccessTypeFromString(const std::string &s);
|
||||
std::string ResourceAccessTypeToString(const ResourceAccessType & T);
|
||||
|
||||
struct SecurityProfile {
|
||||
uint64_t id=0;
|
||||
std::string name;
|
||||
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;
|
||||
struct ProfileAction {
|
||||
std::string resource;
|
||||
ResourceAccessType access;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
typedef std::vector<ProfileAction> ProfileActionVec;
|
||||
|
||||
struct SecurityProfileList {
|
||||
SecurityProfileVec profiles;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
struct SecurityProfile {
|
||||
uint64_t id=0;
|
||||
std::string name;
|
||||
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 {
|
||||
FORGOT_PASSWORD=1,
|
||||
VERIFY_EMAIL
|
||||
};
|
||||
struct SecurityProfileList {
|
||||
SecurityProfileVec profiles;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct ActionLink {
|
||||
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;
|
||||
enum LinkActions {
|
||||
FORGOT_PASSWORD=1,
|
||||
VERIFY_EMAIL,
|
||||
SUB_FORGOT_PASSWORD,
|
||||
SUB_VERIFY_EMAIL
|
||||
};
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
struct ActionLink {
|
||||
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
|
||||
547
src/RESTObjects/RESTAPI_SubObjects.cpp
Normal file
547
src/RESTObjects/RESTAPI_SubObjects.cpp
Normal 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;
|
||||
}
|
||||
}
|
||||
293
src/RESTObjects/RESTAPI_SubObjects.h
Normal file
293
src/RESTObjects/RESTAPI_SubObjects.h
Normal 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
|
||||
@@ -13,18 +13,22 @@ namespace OpenWifi {
|
||||
int Storage::Start() {
|
||||
std::lock_guard Guard(Mutex_);
|
||||
|
||||
Logger_.setLevel(Poco::Message::PRIO_NOTICE);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void Storage::Stop() {
|
||||
std::lock_guard Guard(Mutex_);
|
||||
Logger_.notice("Stopping.");
|
||||
Logger().notice("Stopping.");
|
||||
StorageClass::Stop();
|
||||
}
|
||||
|
||||
|
||||
@@ -13,61 +13,43 @@
|
||||
#include "framework/StorageClass.h"
|
||||
|
||||
#include "RESTObjects/RESTAPI_FMSObjects.h"
|
||||
#include "storage/storage_firmwares.h"
|
||||
#include "storage/storage_history.h"
|
||||
#include "storage/storage_deviceTypes.h"
|
||||
#include "storage/storage_deviceInfo.h"
|
||||
|
||||
#include "storage/orm_history.h"
|
||||
#include "storage/orm_firmwares.h"
|
||||
#include "storage/orm_deviceInfo.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class Storage : public StorageClass {
|
||||
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;
|
||||
void Stop() override;
|
||||
|
||||
bool SetDeviceRevision(std::string &SerialNumber, std::string & Revision, std::string & DeviceType, std::string &EndPoint);
|
||||
bool AddHistory( std::string & SerialNumber, std::string &DeviceType, std::string & PreviousRevision, std::string & NewVersion);
|
||||
bool DeleteHistory( std::string & SerialNumber, std::string &Id);
|
||||
int Create_Tables();
|
||||
int Create_DeviceTypes();
|
||||
int Create_DeviceInfo();
|
||||
|
||||
bool GetDevices(uint64_t From, uint64_t HowMany, std::vector<FMSObjects::DeviceConnectionInformation> & Devices);
|
||||
bool GetDevice(std::string &SerialNumber, FMSObjects::DeviceConnectionInformation & Device);
|
||||
bool SetDeviceDisconnected(std::string &SerialNumber, std::string &EndPoint);
|
||||
bool BuildFirmwareManifest(Poco::JSON::Object & Manifest, uint64_t & Version);
|
||||
|
||||
bool GenerateDeviceReport(FMSObjects::DeviceReport &Report);
|
||||
static std::string TrimRevision(const std::string &R);
|
||||
static Storage *instance() {
|
||||
static Storage *instance_ = new Storage;
|
||||
static auto instance() {
|
||||
static auto instance_ = new Storage;
|
||||
return instance_;
|
||||
}
|
||||
|
||||
OpenWifi::HistoryDB & HistoryDB() { return * HistoryDB_; }
|
||||
OpenWifi::FirmwaresDB & FirmwaresDB() { return * FirmwaresDB_; }
|
||||
OpenWifi::DevicesDB & DevicesDB() { return * DevicesDB_; }
|
||||
|
||||
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
|
||||
|
||||
|
||||
93
src/framework/API_Proxy.h
Normal file
93
src/framework/API_Proxy.h
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2327,7 +2327,7 @@ namespace OpenWifi {
|
||||
if(Utils::wgets(GitUCentralJSONSchemaFile, GitSchema)) {
|
||||
auto schema = json::parse(GitSchema);
|
||||
Validator_->set_root_schema(schema);
|
||||
Logger_.information("Using uCentral validation schema from GIT.");
|
||||
Logger().information("Using uCentral validation schema from GIT.");
|
||||
} else {
|
||||
std::string FileName{ MicroService::instance().DataDir() + "/ucentral.schema.json" };
|
||||
std::ifstream input(FileName);
|
||||
@@ -2336,11 +2336,11 @@ namespace OpenWifi {
|
||||
input.close();
|
||||
auto schema = json::parse(schema_file.str());
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
@@ -2471,7 +2471,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
void ConfigurationValidator::reinitialize(Poco::Util::Application &self) {
|
||||
Logger_.information("Reinitializing.");
|
||||
Logger().information("Reinitializing.");
|
||||
Working_ = Initialized_ = false;
|
||||
Init();
|
||||
}
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
// Created by stephane bourque on 2021-09-14.
|
||||
//
|
||||
|
||||
#ifndef OWPROV_CONFIGURATIONVALIDATOR_H
|
||||
#define OWPROV_CONFIGURATIONVALIDATOR_H
|
||||
#pragma once
|
||||
|
||||
#include <nlohmann/json-schema.hpp>
|
||||
#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); }
|
||||
}
|
||||
|
||||
#endif //OWPROV_CONFIGURATIONVALIDATOR_H
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
// Created by stephane bourque on 2021-10-08.
|
||||
//
|
||||
|
||||
#ifndef OWPROV_COUNTRYCODES_H
|
||||
#define OWPROV_COUNTRYCODES_H
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
@@ -270,4 +269,3 @@ namespace OpenWifi {
|
||||
|
||||
}
|
||||
|
||||
#endif //OWPROV_COUNTRYCODES_H
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// Created by Stephane Bourque on 2021-03-04.
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
#ifndef UCENTRALGW_KAFKA_TOPICS_H
|
||||
#define UCENTRALGW_KAFKA_TOPICS_H
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace OpenWifi::KafkaTopics {
|
||||
static const std::string HEALTHCHECK{"healthcheck"};
|
||||
@@ -17,6 +17,7 @@ namespace OpenWifi::KafkaTopics {
|
||||
static const std::string COMMAND{"command"};
|
||||
static const std::string SERVICE_EVENTS{"service_events"};
|
||||
static const std::string DEVICE_EVENT_QUEUE{"device_event_queue"};
|
||||
static const std::string DEVICE_TELEMETRY{"device_telemetry"};
|
||||
|
||||
namespace ServiceEvents {
|
||||
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
@@ -1,42 +1,38 @@
|
||||
//
|
||||
// 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.
|
||||
// Created by stephane bourque on 2021-11-16.
|
||||
//
|
||||
|
||||
#ifndef UCENTRALGW_UCENTRALTYPES_H
|
||||
#define UCENTRALGW_UCENTRALTYPES_H
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <queue>
|
||||
|
||||
#include "Poco/StringTokenizer.h"
|
||||
#include "Poco/JSON/Parser.h"
|
||||
#include "Poco/JSON/Stringifier.h"
|
||||
#include <list>
|
||||
#include <set>
|
||||
|
||||
namespace OpenWifi::Types {
|
||||
typedef std::pair<std::string,std::string> StringPair;
|
||||
typedef std::vector<StringPair> StringPairVec;
|
||||
typedef std::queue<StringPair> StringPairQueue;
|
||||
typedef std::vector<std::string> StringVec;
|
||||
typedef std::set<std::string> StringSet;
|
||||
typedef std::map<std::string,std::set<std::string>> StringMapStringSet;
|
||||
typedef std::function<void(std::string, std::string)> TopicNotifyFunction;
|
||||
typedef std::list<std::pair<TopicNotifyFunction,int>> TopicNotifyFunctionList;
|
||||
typedef std::map<std::string, TopicNotifyFunctionList> NotifyTable;
|
||||
typedef std::map<std::string,uint64_t> CountedMap;
|
||||
typedef std::vector<uint64_t> TagList;
|
||||
typedef std::string UUID_t;
|
||||
typedef std::vector<UUID_t> UUIDvec_t;
|
||||
typedef std::pair<std::string,std::string> StringPair;
|
||||
typedef std::vector<StringPair> StringPairVec;
|
||||
typedef std::queue<StringPair> StringPairQueue;
|
||||
typedef std::vector<std::string> StringVec;
|
||||
typedef std::set<std::string> StringSet;
|
||||
typedef std::map<std::string,std::set<std::string>> StringMapStringSet;
|
||||
typedef std::function<void(const std::string &, const std::string &)> TopicNotifyFunction;
|
||||
typedef std::list<std::pair<TopicNotifyFunction,int>> TopicNotifyFunctionList;
|
||||
typedef std::map<std::string, TopicNotifyFunctionList> NotifyTable;
|
||||
typedef std::map<std::string,uint64_t> CountedMap;
|
||||
typedef std::vector<uint64_t> TagList;
|
||||
typedef std::string UUID_t;
|
||||
typedef std::vector<UUID_t> UUIDvec_t;
|
||||
typedef std::map<std::string,std::map<uint32_t,uint64_t>> Counted3DMapSII;
|
||||
}
|
||||
|
||||
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);
|
||||
if(it==M.end())
|
||||
M[S] = Increment;
|
||||
@@ -44,60 +40,21 @@ namespace OpenWifi::Types {
|
||||
it->second += Increment;
|
||||
}
|
||||
|
||||
inline std::string to_string( const StringVec &V) {
|
||||
Poco::JSON::Array O;
|
||||
for(const auto &i:V) {
|
||||
O.add(i);
|
||||
inline void UpdateCountedMap(OpenWifi::Types::Counted3DMapSII &M, const std::string &S, uint32_t Index, uint64_t Increment=1) {
|
||||
auto it = M.find(S);
|
||||
if(it==M.end()) {
|
||||
std::map<uint32_t,uint64_t> E;
|
||||
E[Index] = Increment;
|
||||
M[S] = E;
|
||||
}
|
||||
std::stringstream SS;
|
||||
Poco::JSON::Stringifier::stringify(O,SS);
|
||||
return SS.str();
|
||||
}
|
||||
|
||||
inline std::string to_string( const StringPairVec &V) {
|
||||
Poco::JSON::Array O;
|
||||
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));
|
||||
}
|
||||
else {
|
||||
std::map<uint32_t,uint64_t> & IndexMap = it->second;
|
||||
auto it_index = IndexMap.find(Index);
|
||||
if(it_index == IndexMap.end()) {
|
||||
IndexMap[Index] = Increment;
|
||||
} else {
|
||||
it_index->second += Increment;
|
||||
}
|
||||
} 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
|
||||
}
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
// Created by stephane bourque on 2021-09-12.
|
||||
//
|
||||
|
||||
#ifndef OWPROV_RESTAPI_ERRORS_H
|
||||
#define OWPROV_RESTAPI_ERRORS_H
|
||||
#pragma once
|
||||
|
||||
namespace OpenWifi::RESTAPI::Errors {
|
||||
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 NameMustBeSet{"The name property must be set."};
|
||||
static const std::string ConfigBlockInvalid{"Configuration block type invalid."};
|
||||
static const std::string UnknownId{"Unknown management policy."};
|
||||
static const std::string UnknownId{"Unknown UUID."};
|
||||
static const std::string InvalidDeviceTypes{"Unknown or invalid device type(s)."};
|
||||
static const std::string RecordNotCreated{"Record could not be created."};
|
||||
static const std::string RecordNotUpdated{"Record could not be updated."};
|
||||
@@ -60,6 +59,10 @@ namespace OpenWifi::RESTAPI::Errors {
|
||||
static const std::string MissingAuthenticationInformation{"Missing authentication information."};
|
||||
static const std::string InsufficientAccessRights{"Insufficient access rights to complete the operation."};
|
||||
static const std::string ExpiredToken{"Token has expired, user must login."};
|
||||
static const std::string SubscriberMustExist{"Subscriber must exist."};
|
||||
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
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
#ifndef UCENTRALGW_RESTAPI_PROTOCOL_H
|
||||
#define UCENTRALGW_RESTAPI_PROTOCOL_H
|
||||
#pragma once
|
||||
|
||||
namespace OpenWifi::RESTAPI::Protocol {
|
||||
static const char * CAPABILITIES = "capabilities";
|
||||
@@ -85,11 +84,13 @@ namespace OpenWifi::RESTAPI::Protocol {
|
||||
static const char * GETSUBSYSTEMNAMES = "getsubsystemnames";
|
||||
static const char * GETLOGLEVELNAMES = "getloglevelnames";
|
||||
static const char * STATS = "stats";
|
||||
static const char * PING = "ping";
|
||||
static const char * PARAMETERS = "parameters";
|
||||
static const char * VALUE = "value";
|
||||
static const char * LASTONLY = "lastOnly";
|
||||
static const char * NEWEST = "newest";
|
||||
static const char * ACTIVESCAN = "activeScan";
|
||||
static const char * OVERRIDEDFS = "override_dfs";
|
||||
static const char * LIST = "list";
|
||||
static const char * TAG = "tag";
|
||||
static const char * TAGLIST = "tagList";
|
||||
@@ -136,5 +137,3 @@ namespace OpenWifi::RESTAPI::Protocol {
|
||||
static const char * UI = "UI";
|
||||
|
||||
}
|
||||
|
||||
#endif // UCENTRALGW_RESTAPI_PROTOCOL_H
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
// Created by stephane bourque on 2021-10-06.
|
||||
//
|
||||
|
||||
#ifndef OPENWIFI_STORAGE_H
|
||||
#define OPENWIFI_STORAGE_H
|
||||
#pragma once
|
||||
|
||||
#include "Poco/Data/Session.h"
|
||||
#include "Poco/Data/SessionPool.h"
|
||||
@@ -34,8 +33,8 @@ namespace OpenWifi {
|
||||
int Start() override {
|
||||
std::lock_guard Guard(Mutex_);
|
||||
|
||||
Logger_.setLevel(Poco::Message::PRIO_NOTICE);
|
||||
Logger_.notice("Starting.");
|
||||
Logger().setLevel(Poco::Message::PRIO_INFORMATION);
|
||||
Logger().notice("Starting.");
|
||||
std::string DBType = MicroService::instance().ConfigGetString("storage.type");
|
||||
|
||||
if (DBType == "sqlite") {
|
||||
@@ -52,37 +51,6 @@ namespace OpenWifi {
|
||||
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:
|
||||
inline int Setup_SQLite();
|
||||
inline int Setup_MySQL();
|
||||
@@ -102,7 +70,7 @@ namespace OpenWifi {
|
||||
#else
|
||||
|
||||
inline int StorageClass::Setup_SQLite() {
|
||||
Logger_.notice("SQLite StorageClass enabled.");
|
||||
Logger().notice("SQLite StorageClass enabled.");
|
||||
dbType_ = sqlite;
|
||||
auto DBName = MicroService::instance().DataDir() + "/" + MicroService::instance().ConfigGetString("storage.type.sqlite.db");
|
||||
auto NumSessions = MicroService::instance().ConfigGetInt("storage.type.sqlite.maxsessions", 64);
|
||||
@@ -113,7 +81,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
inline int StorageClass::Setup_MySQL() {
|
||||
Logger_.notice("MySQL StorageClass enabled.");
|
||||
Logger().notice("MySQL StorageClass enabled.");
|
||||
dbType_ = mysql;
|
||||
auto NumSessions = MicroService::instance().ConfigGetInt("storage.type.mysql.maxsessions", 64);
|
||||
auto IdleTime = MicroService::instance().ConfigGetInt("storage.type.mysql.idletime", 60);
|
||||
@@ -138,7 +106,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
inline int StorageClass::Setup_PostgreSQL() {
|
||||
Logger_.notice("PostgreSQL StorageClass enabled.");
|
||||
Logger().notice("PostgreSQL StorageClass enabled.");
|
||||
dbType_ = pgsql;
|
||||
auto NumSessions = MicroService::instance().ConfigGetInt("storage.type.postgresql.maxsessions", 64);
|
||||
auto IdleTime = MicroService::instance().ConfigGetInt("storage.type.postgresql.idletime", 60);
|
||||
@@ -165,5 +133,3 @@ namespace OpenWifi {
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endif //OPENWIFI_STORAGE_H
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
#ifndef __OPENWIFI_ORM_H__
|
||||
#define __OPENWIFI_ORM_H__
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
@@ -33,7 +32,8 @@ namespace ORM {
|
||||
FT_BIGINT,
|
||||
FT_TEXT,
|
||||
FT_VARCHAR,
|
||||
FT_BLOB
|
||||
FT_BLOB,
|
||||
FT_BOOLEAN
|
||||
};
|
||||
|
||||
enum Indextype {
|
||||
@@ -97,21 +97,22 @@ namespace ORM {
|
||||
case FT_INT: return "INT";
|
||||
case FT_BIGINT: return "BIGINT";
|
||||
case FT_TEXT: return "TEXT";
|
||||
case FT_BOOLEAN: return "BOOLEAN";
|
||||
case FT_VARCHAR:
|
||||
if(Size)
|
||||
return std::string("VARCHAR(") + std::to_string(Size) + std::string(")");
|
||||
else
|
||||
return "TEXT";
|
||||
case FT_BLOB:
|
||||
if(Type==OpenWifi::DBType::mysql)
|
||||
return "LONGBLOB";
|
||||
else if(Type==OpenWifi::DBType::pgsql)
|
||||
return "BYTEA";
|
||||
else if(Type==OpenWifi::DBType::sqlite)
|
||||
return "BLOB";
|
||||
default:
|
||||
assert(false);
|
||||
return "";
|
||||
case FT_BLOB:
|
||||
if(Type==OpenWifi::DBType::mysql)
|
||||
return "LONGBLOB";
|
||||
else if(Type==OpenWifi::DBType::pgsql)
|
||||
return "BYTEA";
|
||||
else if(Type==OpenWifi::DBType::sqlite)
|
||||
return "BLOB";
|
||||
default:
|
||||
assert(false);
|
||||
return "";
|
||||
}
|
||||
assert(false);
|
||||
return "";
|
||||
@@ -154,28 +155,46 @@ namespace ORM {
|
||||
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 {
|
||||
public:
|
||||
|
||||
typedef const char * field_name_t;
|
||||
|
||||
DB( OpenWifi::DBType dbtype,
|
||||
const char *TableName,
|
||||
const FieldVec & Fields,
|
||||
const IndexVec & Indexes,
|
||||
Poco::Data::SessionPool & Pool,
|
||||
Poco::Logger &L,
|
||||
const char *Prefix):
|
||||
Type(dbtype),
|
||||
DBName(TableName),
|
||||
Poco::Logger &L,
|
||||
const char *Prefix,
|
||||
DBCache<RecordType> * Cache=nullptr):
|
||||
Type_(dbtype),
|
||||
TableName_(TableName),
|
||||
Pool_(Pool),
|
||||
Logger_(L),
|
||||
Prefix_(Prefix)
|
||||
Prefix_(Prefix),
|
||||
Cache_(Cache)
|
||||
{
|
||||
assert(RecordTuple::length == Fields.size());
|
||||
|
||||
bool first = true;
|
||||
int Place=0;
|
||||
|
||||
assert( RecordTuple::length == Fields.size());
|
||||
|
||||
for(const auto &i:Fields) {
|
||||
|
||||
FieldNames_[i.Name] = Place;
|
||||
if(!first) {
|
||||
CreateFields_ += ", ";
|
||||
@@ -186,7 +205,7 @@ namespace ORM {
|
||||
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 ;
|
||||
UpdateFields_ += i.Name + "=?";
|
||||
SelectList_ += "?";
|
||||
@@ -196,11 +215,11 @@ namespace ORM {
|
||||
SelectList_ += ")";
|
||||
|
||||
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) {
|
||||
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;
|
||||
for(const auto &k:j.Entries) {
|
||||
assert(FieldNames_.find(k.FieldName) != FieldNames_.end());
|
||||
@@ -210,10 +229,10 @@ namespace ORM {
|
||||
first_entry = false;
|
||||
IndexLine += k.FieldName + std::string(" ") + std::string(k.Type == Indextype::ASC ? "ASC" : "DESC") ;
|
||||
}
|
||||
IndexLine += " );";
|
||||
IndexCreation += IndexLine;
|
||||
IndexLine += " )";
|
||||
IndexCreation_.template emplace_back(IndexLine);
|
||||
}
|
||||
} else if(Type==OpenWifi::DBType::mysql) {
|
||||
} else if(Type_==OpenWifi::DBType::mysql) {
|
||||
bool firstIndex = true;
|
||||
std::string IndexLine;
|
||||
for(const auto &j:Indexes) {
|
||||
@@ -232,7 +251,7 @@ namespace ORM {
|
||||
}
|
||||
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 & 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() );
|
||||
return std::string{"("} + F + SQLCOMPS[O] + std::to_string(V) + ")" ;
|
||||
}
|
||||
|
||||
inline std::string OP(const char *F, SqlComparison O , uint64_t V) {
|
||||
inline std::string OP(field_name_t F, SqlComparison O , uint64_t V) {
|
||||
assert( FieldNames_.find(F) != FieldNames_.end() );
|
||||
return std::string{"("} + F + SQLCOMPS[O] + std::to_string(V) + ")" ;
|
||||
}
|
||||
|
||||
std::string OP(const char *F, SqlComparison O , const std::string & V) {
|
||||
std::string OP(field_name_t F, SqlComparison O , const std::string & V) {
|
||||
assert( FieldNames_.find(F) != FieldNames_.end() );
|
||||
return std::string{"("} + F + SQLCOMPS[O] + "'" + Escape(V) + "')" ;
|
||||
}
|
||||
|
||||
std::string OP(const char *F, SqlComparison O , const char * V) {
|
||||
std::string OP(field_name_t F, SqlComparison O , const char * V) {
|
||||
assert( FieldNames_.find(F) != FieldNames_.end() );
|
||||
return std::string{"("} + F + SQLCOMPS[O] + "'" + Escape(V) + "')" ;
|
||||
}
|
||||
@@ -278,35 +302,61 @@ namespace ORM {
|
||||
return std::string{"("} + P1 + BOPS[BOP] + OP(true, P2, More...);
|
||||
}
|
||||
|
||||
bool Upgrade() {
|
||||
uint32_t To;
|
||||
return Upgrade(0, To);
|
||||
}
|
||||
|
||||
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) {
|
||||
if(IndexCreation.empty())
|
||||
S = "create table if not exists " + DBName +" ( " + CreateFields_ + " )" ;
|
||||
else
|
||||
S = "create table if not exists " + DBName +" ( " + CreateFields_ + " ), " + IndexCreation + " )";
|
||||
} else if (Type==OpenWifi::DBType::pgsql || Type==OpenWifi::DBType::sqlite) {
|
||||
S = "create table if not exists " + DBName + " ( " + CreateFields_ + " ); " + IndexCreation ;
|
||||
case OpenWifi::DBType::sqlite: {
|
||||
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 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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
return Upgrade();
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string ConvertParams(const std::string & S) const {
|
||||
if(Type!=OpenWifi::DBType::pgsql)
|
||||
if(Type_!=OpenWifi::DBType::pgsql)
|
||||
return S;
|
||||
|
||||
std::string R;
|
||||
@@ -325,45 +375,59 @@ namespace ORM {
|
||||
return R;
|
||||
}
|
||||
|
||||
void Convert( RecordTuple &in , RecordType &out);
|
||||
void Convert( RecordType &in , RecordTuple &out);
|
||||
void Convert( const RecordTuple &in , RecordType &out);
|
||||
void Convert( const RecordType &in , RecordTuple &out);
|
||||
|
||||
inline const std::string & Prefix() { return Prefix_; };
|
||||
|
||||
bool CreateRecord( RecordType & R) {
|
||||
bool CreateRecord( const RecordType & R) {
|
||||
try {
|
||||
Poco::Data::Session Session = Pool_.get();
|
||||
Poco::Data::Statement Insert(Session);
|
||||
|
||||
RecordTuple 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) ,
|
||||
Poco::Data::Keywords::use(RT);
|
||||
Insert.execute();
|
||||
|
||||
if(Cache_)
|
||||
Cache_->Create(R);
|
||||
return true;
|
||||
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
}
|
||||
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 {
|
||||
|
||||
assert( FieldNames_.find(FieldName) != FieldNames_.end() );
|
||||
|
||||
if(Cache_) {
|
||||
if(Cache_->GetFromCache(FieldName, Value, R))
|
||||
return true;
|
||||
}
|
||||
|
||||
Poco::Data::Session Session = Pool_.get();
|
||||
Poco::Data::Statement Select(Session);
|
||||
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) ,
|
||||
Poco::Data::Keywords::into(RT),
|
||||
Poco::Data::Keywords::use(Value);
|
||||
if(Select.execute()==1) {
|
||||
Poco::Data::Keywords::use(tValue);
|
||||
Select.execute();
|
||||
|
||||
if(Select.rowsExtracted()==1) {
|
||||
Convert(RT,R);
|
||||
if(Cache_)
|
||||
Cache_->UpdateCache(R);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -376,7 +440,7 @@ namespace ORM {
|
||||
typedef std::vector<std::string> StringVec;
|
||||
|
||||
template < typename T,
|
||||
typename T0, typename T1> bool GR(const char *FieldName, T & R,T0 &V0, T1 &V1) {
|
||||
typename T0, typename T1> bool GR(field_name_t FieldName, T & R,T0 &V0, T1 &V1) {
|
||||
try {
|
||||
|
||||
assert( FieldNames_.find(FieldName) != FieldNames_.end() );
|
||||
@@ -385,7 +449,7 @@ namespace ORM {
|
||||
Poco::Data::Statement Select(Session);
|
||||
RecordTuple RT;
|
||||
|
||||
std::string St = "select " + SelectFields_ + " from " + DBName
|
||||
std::string St = "select " + SelectFields_ + " from " + TableName_
|
||||
+ " where " + FieldName[0] + "=? and " + FieldName[1] + "=?" ;
|
||||
Select << ConvertParams(St) ,
|
||||
Poco::Data::Keywords::into(RT),
|
||||
@@ -410,14 +474,15 @@ namespace ORM {
|
||||
Poco::Data::Session Session = Pool_.get();
|
||||
Poco::Data::Statement Select(Session);
|
||||
RecordList RL;
|
||||
std::string St = "select " + SelectFields_ + " from " + DBName +
|
||||
std::string St = "select " + SelectFields_ + " from " + TableName_ +
|
||||
(Where.empty() ? "" : " where " + Where) + OrderBy +
|
||||
ComputeRange(Offset, HowMany) ;
|
||||
|
||||
Select << St ,
|
||||
Poco::Data::Keywords::into(RL);
|
||||
Select.execute();
|
||||
|
||||
if(Select.execute()>0) {
|
||||
if(Select.rowsExtracted()>0) {
|
||||
for(auto &i:RL) {
|
||||
RecordType R;
|
||||
Convert(i, R);
|
||||
@@ -432,7 +497,7 @@ namespace ORM {
|
||||
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 {
|
||||
assert( FieldNames_.find(FieldName) != FieldNames_.end() );
|
||||
|
||||
@@ -443,11 +508,15 @@ namespace ORM {
|
||||
|
||||
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) ,
|
||||
Poco::Data::Keywords::use(RT),
|
||||
Poco::Data::Keywords::use(Value);
|
||||
Poco::Data::Keywords::use(tValue);
|
||||
Update.execute();
|
||||
if(Cache_)
|
||||
Cache_->UpdateCache(R);
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
@@ -455,18 +524,32 @@ namespace ORM {
|
||||
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 {
|
||||
assert( FieldNames_.find(FieldName) != FieldNames_.end() );
|
||||
Poco::Data::Session Session = Pool_.get();
|
||||
Poco::Data::Statement Select(Session);
|
||||
RecordTuple RT;
|
||||
|
||||
std::string St = "select " + SelectFields_ + " from " + DBName + " where " + FieldName + "=?" ;
|
||||
std::string St = "select " + SelectFields_ + " from " + TableName_ + " where " + FieldName + "=?" ;
|
||||
RecordType R;
|
||||
auto tValue{Value};
|
||||
Select << ConvertParams(St) ,
|
||||
Poco::Data::Keywords::into(RT),
|
||||
Poco::Data::Keywords::use(Value);
|
||||
Poco::Data::Keywords::into(RT),
|
||||
Poco::Data::Keywords::use(tValue);
|
||||
|
||||
if(Select.execute()==1) {
|
||||
Convert(RT,R);
|
||||
Name = R.info.name;
|
||||
@@ -480,17 +563,21 @@ namespace ORM {
|
||||
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 {
|
||||
assert( FieldNames_.find(FieldName) != FieldNames_.end() );
|
||||
|
||||
Poco::Data::Session Session = Pool_.get();
|
||||
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) ,
|
||||
Poco::Data::Keywords::use(Value);
|
||||
Poco::Data::Keywords::use(tValue);
|
||||
Delete.execute();
|
||||
if(Cache_)
|
||||
Cache_->Delete(FieldName, Value);
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
@@ -504,7 +591,7 @@ namespace ORM {
|
||||
Poco::Data::Session Session = Pool_.get();
|
||||
Poco::Data::Statement Delete(Session);
|
||||
|
||||
std::string St = "delete from " + DBName + " where " + WhereClause;
|
||||
std::string St = "delete from " + TableName_ + " where " + WhereClause;
|
||||
Delete << St;
|
||||
Delete.execute();
|
||||
return true;
|
||||
@@ -514,7 +601,7 @@ namespace ORM {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Exists(const char *FieldName, std::string & Value) {
|
||||
bool Exists(field_name_t FieldName, const std::string & Value) {
|
||||
try {
|
||||
assert( FieldNames_.find(FieldName) != FieldNames_.end() );
|
||||
|
||||
@@ -528,15 +615,15 @@ namespace ORM {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Iterate( std::function<bool(const RecordType &R)> F) {
|
||||
bool Iterate( std::function<bool(const RecordType &R)> F, const std::string & WhereClause = "" ) {
|
||||
try {
|
||||
|
||||
uint64_t Offset=1;
|
||||
uint64_t Offset=0;
|
||||
uint64_t Batch=50;
|
||||
bool Done=false;
|
||||
while(!Done) {
|
||||
std::vector<RecordType> Records;
|
||||
if(GetRecords(Offset,Batch,Records)) {
|
||||
if(GetRecords(Offset,Batch,Records, WhereClause)) {
|
||||
for(const auto &i:Records) {
|
||||
if(!F(i))
|
||||
return true;
|
||||
@@ -592,7 +679,7 @@ namespace ORM {
|
||||
Poco::Data::Session Session = Pool_.get();
|
||||
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 ,
|
||||
Poco::Data::Keywords::into(Cnt);
|
||||
@@ -606,7 +693,7 @@ namespace ORM {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename X> bool ManipulateVectorMember( X T, const char *FieldName, std::string & ParentUUID, std::string & ChildUUID, bool Add) {
|
||||
template <typename X> bool ManipulateVectorMember( X T, field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID, bool Add) {
|
||||
try {
|
||||
assert( FieldNames_.find(FieldName) != FieldNames_.end() );
|
||||
|
||||
@@ -633,89 +720,122 @@ namespace ORM {
|
||||
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);
|
||||
}
|
||||
|
||||
inline bool DeleteChild( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) {
|
||||
inline bool DeleteChild(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::children, FieldName, ParentUUID, ChildUUID, false);
|
||||
}
|
||||
|
||||
inline bool AddLocation( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) {
|
||||
inline bool AddLocation(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::locations, FieldName, ParentUUID, ChildUUID, true);
|
||||
}
|
||||
|
||||
inline bool DeleteLocation( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) {
|
||||
inline bool DeleteLocation(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::locations, FieldName, ParentUUID, ChildUUID, false);
|
||||
}
|
||||
|
||||
inline bool AddContact( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) {
|
||||
inline bool AddContact(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::contacts, FieldName, ParentUUID, ChildUUID, true);
|
||||
}
|
||||
|
||||
inline bool DeleteContact( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) {
|
||||
inline bool DeleteContact(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::contacts, FieldName, ParentUUID, ChildUUID, false);
|
||||
}
|
||||
|
||||
inline bool AddVenue( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) {
|
||||
inline bool AddVenue(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::venues, FieldName, ParentUUID, ChildUUID, true);
|
||||
}
|
||||
|
||||
inline bool DeleteVenue( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) {
|
||||
inline bool DeleteVenue(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::venues, FieldName, ParentUUID, ChildUUID, false);
|
||||
}
|
||||
|
||||
inline bool AddDevice( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) {
|
||||
inline bool AddDevice(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::devices, FieldName, ParentUUID, ChildUUID, true);
|
||||
}
|
||||
|
||||
inline bool DeleteDevice( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) {
|
||||
inline bool DeleteDevice(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::devices, FieldName, ParentUUID, ChildUUID, false);
|
||||
}
|
||||
|
||||
inline bool AddEntity( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) {
|
||||
inline bool AddEntity(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::entities, FieldName, ParentUUID, ChildUUID, true);
|
||||
}
|
||||
|
||||
inline bool DeleteEntity( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) {
|
||||
inline bool DeleteEntity(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::entities, FieldName, ParentUUID, ChildUUID, false);
|
||||
}
|
||||
|
||||
inline bool AddUser( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) {
|
||||
inline bool AddUser(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::users, FieldName, ParentUUID, ChildUUID, true);
|
||||
}
|
||||
|
||||
inline bool DelUser( const char *FieldName, std::string & ParentUUID, std::string & ChildUUID) {
|
||||
inline bool DelUser(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::users, FieldName, ParentUUID, ChildUUID, false);
|
||||
}
|
||||
|
||||
inline bool AddInUse(const char *FieldName, std::string & ParentUUID, const std::string & Prefix, const std::string & ChildUUID) {
|
||||
inline bool AddInUse(field_name_t FieldName, std::string & ParentUUID, const std::string & Prefix, const std::string & ChildUUID) {
|
||||
std::string FakeUUID{ Prefix + ":" + ChildUUID};
|
||||
return ManipulateVectorMember(&RecordType::inUse,FieldName, ParentUUID, FakeUUID, true);
|
||||
}
|
||||
|
||||
inline bool DeleteInUse(const char *FieldName, std::string & ParentUUID, const std::string & Prefix, const std::string & ChildUUID) {
|
||||
inline bool DeleteInUse(field_name_t FieldName, std::string & ParentUUID, const std::string & Prefix, const std::string & ChildUUID) {
|
||||
std::string FakeUUID{ Prefix + ":" + ChildUUID};
|
||||
return ManipulateVectorMember(&RecordType::inUse,FieldName, ParentUUID, FakeUUID, false);
|
||||
}
|
||||
|
||||
inline bool DeleteContact(const char *FieldName, std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
inline bool DeleteContact(field_name_t FieldName, std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::contacts,FieldName, ParentUUID, ChildUUID, false);
|
||||
}
|
||||
|
||||
inline bool AddContact(const char *FieldName, std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
inline bool AddContact(field_name_t FieldName, std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::contacts,FieldName, ParentUUID, ChildUUID, true);
|
||||
}
|
||||
|
||||
inline bool DeleteLocation(const char *FieldName, std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
inline bool DeleteLocation(field_name_t FieldName, std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::locations,FieldName, ParentUUID, ChildUUID, false);
|
||||
}
|
||||
|
||||
inline bool AddLocation(const char *FieldName, std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
inline bool AddLocation(field_name_t FieldName, std::string & ParentUUID, const std::string & ChildUUID) {
|
||||
return ManipulateVectorMember(&RecordType::locations,FieldName, ParentUUID, ChildUUID, true);
|
||||
}
|
||||
|
||||
inline bool GetInUse(const char *FieldName, std::string & UUID, std::vector<std::string> & UUIDs ) {
|
||||
inline bool GetInUse(field_name_t FieldName, const std::string & UUID, std::vector<std::string> & UUIDs ) {
|
||||
RecordType R;
|
||||
if(GetRecord(FieldName,UUID,R)) {
|
||||
UUIDs = R.inUse;
|
||||
@@ -725,34 +845,41 @@ namespace ORM {
|
||||
}
|
||||
|
||||
[[nodiscard]] inline std::string ComputeRange(uint64_t From, uint64_t HowMany) {
|
||||
if(From<1) From=1;
|
||||
switch(Type) {
|
||||
if(From<1) From=0;
|
||||
switch(Type_) {
|
||||
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:
|
||||
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:
|
||||
return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From-1) + " ";
|
||||
return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) + " ";
|
||||
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_; }
|
||||
|
||||
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:
|
||||
OpenWifi::DBType Type;
|
||||
std::string DBName;
|
||||
OpenWifi::DBType Type_;
|
||||
std::string CreateFields_;
|
||||
std::string SelectFields_;
|
||||
std::string SelectList_;
|
||||
std::string UpdateFields_;
|
||||
std::string IndexCreation;
|
||||
std::vector<std::string> IndexCreation_;
|
||||
std::map<std::string,int> FieldNames_;
|
||||
Poco::Data::SessionPool &Pool_;
|
||||
Poco::Logger &Logger_;
|
||||
std::string Prefix_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -5,9 +5,7 @@
|
||||
// Created by Stephane Bourque on 2021-03-04.
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
#ifndef UCENTRALGW_UCENTRALPROTOCOL_H
|
||||
#define UCENTRALGW_UCENTRALPROTOCOL_H
|
||||
#pragma once
|
||||
|
||||
#include "Poco/String.h"
|
||||
|
||||
@@ -40,6 +38,7 @@ namespace OpenWifi::uCentralProtocol {
|
||||
static const char * LOGLINES = "loglines";
|
||||
static const char * SEVERITY = "severity";
|
||||
static const char * ACTIVE = "active";
|
||||
static const char * OVERRIDEDFS = "override_dfs";
|
||||
static const char * REBOOT = "reboot";
|
||||
static const char * WHEN = "when";
|
||||
static const char * CONFIG = "config";
|
||||
@@ -130,5 +129,3 @@ namespace OpenWifi::uCentralProtocol {
|
||||
return ET_UNKNOWN;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // UCENTRALGW_UCENTRALPROTOCOL_H
|
||||
|
||||
13
src/ow_version.h.in
Normal file
13
src/ow_version.h.in
Normal 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@"};
|
||||
}
|
||||
119
src/storage/orm_deviceInfo.cpp
Normal file
119
src/storage/orm_deviceInfo.cpp
Normal 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);
|
||||
}
|
||||
|
||||
34
src/storage/orm_deviceInfo.h
Normal file
34
src/storage/orm_deviceInfo.h
Normal 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:
|
||||
};
|
||||
|
||||
}
|
||||
216
src/storage/orm_firmwares.cpp
Normal file
216
src/storage/orm_firmwares.cpp
Normal 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);
|
||||
}
|
||||
50
src/storage/orm_firmwares.h
Normal file
50
src/storage/orm_firmwares.h
Normal 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:
|
||||
};
|
||||
|
||||
}
|
||||
97
src/storage/orm_history.cpp
Normal file
97
src/storage/orm_history.cpp
Normal 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
36
src/storage/orm_history.h
Normal 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:
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
@@ -1,5 +0,0 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-07-12.
|
||||
//
|
||||
|
||||
#include "storage_deviceTypes.h"
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -34,11 +34,20 @@ fi
|
||||
|
||||
token=""
|
||||
result_file=result.json
|
||||
username="tip@ucentral.com"
|
||||
password="openwifi"
|
||||
browser_list=(firefox sensible-browser xdg-open w3m links links2 lynx youtube-dl)
|
||||
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() {
|
||||
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')
|
||||
@@ -73,40 +82,31 @@ findbrowser() {
|
||||
}
|
||||
|
||||
setfms() {
|
||||
if [ -z ${OWFMS_OVERRIDE+x} ]; then
|
||||
curl ${FLAGS} -X GET "https://${OWSEC}/api/v1/systemEndpoints" \
|
||||
-H "accept: application/json" \
|
||||
-H "Authorization: Bearer ${token}" > ${result_file}
|
||||
# jq < ${result_file}
|
||||
|
||||
for index in {0..10}
|
||||
do
|
||||
endpointlocation=".endpoints[${index}].uri"
|
||||
endpointlocationtype=".endpoints[${index}].type"
|
||||
rawurl="$(cat ${result_file} | jq -r ${endpointlocation})"
|
||||
svctype="$(cat ${result_file} | jq -r ${endpointlocationtype})"
|
||||
proto="$(echo $rawurl | grep :// | sed -e's,^\(.*://\).*,\1,g')"
|
||||
url="$(echo ${rawurl/$proto/})"
|
||||
user="$(echo $url | grep @ | cut -d@ -f1)"
|
||||
hostport="$(echo ${url/$user@/} | cut -d/ -f1)"
|
||||
host="$(echo $hostport | sed -e 's,:.*,,g')"
|
||||
port="$(echo $hostport | sed -e 's,^.*:,:,g' -e 's,.*:\([0-9]*\).*,\1,g' -e 's,[^0-9],,g')"
|
||||
path="$(echo $url | grep / | cut -d/ -f2-)"
|
||||
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
|
||||
rawurl="$(cat ${result_file} | jq -r '.endpoints[] | select( .type == "owfms" ) | .uri')"
|
||||
if [[ ! -z "${rawurl}" ]]; then
|
||||
proto="$(echo $rawurl | grep :// | sed -e's,^\(.*://\).*,\1,g')"
|
||||
url="$(echo ${rawurl/$proto/})"
|
||||
user="$(echo $url | grep @ | cut -d@ -f1)"
|
||||
hostport="$(echo ${url/$user@/} | cut -d/ -f1)"
|
||||
host="$(echo $hostport | sed -e 's,:.*,,g')"
|
||||
port="$(echo $hostport | sed -e 's,^.*:,:,g' -e 's,.*:\([0-9]*\).*,\1,g' -e 's,[^0-9],,g')"
|
||||
path="$(echo $url | grep / | cut -d/ -f2-)"
|
||||
export OWFMS=${url}
|
||||
echo "Using ${OWFMS}..."
|
||||
else
|
||||
echo "OWFMS endpoint is not found:"
|
||||
jq < ${result_file}
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
echo "Using ${OWFMS}..."
|
||||
|
||||
else
|
||||
export OWFMS=${OWFMS_OVERRIDE}
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
logout() {
|
||||
|
||||
File diff suppressed because one or more lines are too long
26
wait-for-postgres.sh
Executable file
26
wait-for-postgres.sh
Executable 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 "$@"
|
||||
Reference in New Issue
Block a user