mirror of
				https://github.com/Telecominfraproject/wlan-cloud-owprov.git
				synced 2025-10-31 18:48:09 +00:00 
			
		
		
		
	Compare commits
	
		
			21 Commits
		
	
	
		
			v2.7.0-RC2
			...
			v2.6.0
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 7fcf2ca41b | ||
|   | 3c2017859b | ||
|   | eecf9a49c2 | ||
|   | 944500dea9 | ||
|   | a5e0dcb210 | ||
|   | 656562c691 | ||
|   | 2ea7e3dcc5 | ||
|   | 205343619b | ||
|   | aa1136e55b | ||
|   | 439aa1d07a | ||
|   | a9293a7717 | ||
|   | 80d5ae340f | ||
|   | 265ae7483b | ||
|   | 43c4ad2211 | ||
|   | 5cccd0b797 | ||
|   | b8bcece4bf | ||
|   | 3132b964bd | ||
|   | 711dc59fa6 | ||
|   | 82fbfeebc6 | ||
|   | 77a4df5221 | ||
|   | c749275ef8 | 
| @@ -1,5 +1,5 @@ | |||||||
| cmake_minimum_required(VERSION 3.13) | cmake_minimum_required(VERSION 3.13) | ||||||
| project(owprov VERSION 2.7.0) | project(owprov VERSION 2.6.0) | ||||||
|  |  | ||||||
| set(CMAKE_CXX_STANDARD 17) | set(CMAKE_CXX_STANDARD 17) | ||||||
|  |  | ||||||
| @@ -58,8 +58,6 @@ include_directories(/usr/local/include  /usr/local/opt/openssl/include src inclu | |||||||
|  |  | ||||||
| configure_file(src/ow_version.h.in ${PROJECT_SOURCE_DIR}/src/ow_version.h @ONLY) | configure_file(src/ow_version.h.in ${PROJECT_SOURCE_DIR}/src/ow_version.h @ONLY) | ||||||
|  |  | ||||||
| add_definitions(-DPOCO_LOG_DEBUG="1") |  | ||||||
|  |  | ||||||
| add_compile_options(-Wall -Wextra) | add_compile_options(-Wall -Wextra) | ||||||
| if(ASAN) | if(ASAN) | ||||||
|     add_compile_options(-fsanitize=address) |     add_compile_options(-fsanitize=address) | ||||||
| @@ -136,14 +134,7 @@ add_executable(owprov | |||||||
|         src/storage/storage_variables.cpp src/storage/storage_variables.h |         src/storage/storage_variables.cpp src/storage/storage_variables.h | ||||||
|         src/RESTAPI/RESTAPI_variables_handler.cpp src/RESTAPI/RESTAPI_variables_handler.h |         src/RESTAPI/RESTAPI_variables_handler.cpp src/RESTAPI/RESTAPI_variables_handler.h | ||||||
|         src/RESTAPI/RESTAPI_variables_list_handler.cpp src/RESTAPI/RESTAPI_variables_list_handler.h |         src/RESTAPI/RESTAPI_variables_list_handler.cpp src/RESTAPI/RESTAPI_variables_list_handler.h | ||||||
|         src/FileDownloader.cpp src/FileDownloader.h |         src/FileDownloader.cpp src/FileDownloader.h src/Tasks/VenueConfigUpdater.h src/Kafka_ProvUpdater.cpp src/Kafka_ProvUpdater.h src/storage/storage_operataor.cpp src/storage/storage_operataor.h src/storage/storage_sub_devices.cpp src/storage/storage_sub_devices.h src/storage/storage_service_class.cpp src/storage/storage_service_class.h src/RESTAPI/RESTAPI_sub_devices_list_handler.cpp src/RESTAPI/RESTAPI_sub_devices_list_handler.h src/RESTAPI/RESTAPI_sub_devices_handler.cpp src/RESTAPI/RESTAPI_sub_devices_handler.h src/RESTAPI/RESTAPI_service_class_list_handler.cpp src/RESTAPI/RESTAPI_service_class_list_handler.h src/RESTAPI/RESTAPI_service_class_handler.cpp src/RESTAPI/RESTAPI_service_class_handler.h src/RESTAPI/RESTAPI_operators_list_handler.cpp src/RESTAPI/RESTAPI_operators_list_handler.h src/RESTAPI/RESTAPI_operators_handler.cpp src/RESTAPI/RESTAPI_operators_handler.h src/storage/storage_op_contacts.cpp src/storage/storage_op_contacts.h src/storage/storage_op_locations.cpp src/storage/storage_op_locations.h src/RESTAPI/RESTAPI_op_contact_list_handler.cpp src/RESTAPI/RESTAPI_op_contact_list_handler.h src/RESTAPI/RESTAPI_op_contact_handler.cpp src/RESTAPI/RESTAPI_op_contact_handler.h src/RESTAPI/RESTAPI_op_location_list_handler.cpp src/RESTAPI/RESTAPI_op_location_list_handler.h src/RESTAPI/RESTAPI_op_location_handler.cpp src/RESTAPI/RESTAPI_op_location_handler.h src/ProvWebSocketClient.cpp src/ProvWebSocketClient.h src/Tasks/VenueRebooter.h src/Tasks/VenueUpgrade.h src/sdks/SDK_fms.cpp src/sdks/SDK_fms.h) | ||||||
|         src/Tasks/VenueConfigUpdater.h |  | ||||||
|         src/libs/croncpp.h |  | ||||||
|         src/Kafka_ProvUpdater.cpp src/Kafka_ProvUpdater.h |  | ||||||
|         src/storage/storage_operataor.cpp src/storage/storage_operataor.h |  | ||||||
|         src/storage/storage_sub_devices.cpp src/storage/storage_sub_devices.h |  | ||||||
|         src/storage/storage_service_class.cpp src/storage/storage_service_class.h |  | ||||||
|         src/RESTAPI/RESTAPI_sub_devices_list_handler.cpp src/RESTAPI/RESTAPI_sub_devices_list_handler.h src/RESTAPI/RESTAPI_sub_devices_handler.cpp src/RESTAPI/RESTAPI_sub_devices_handler.h src/RESTAPI/RESTAPI_service_class_list_handler.cpp src/RESTAPI/RESTAPI_service_class_list_handler.h src/RESTAPI/RESTAPI_service_class_handler.cpp src/RESTAPI/RESTAPI_service_class_handler.h src/RESTAPI/RESTAPI_operators_list_handler.cpp src/RESTAPI/RESTAPI_operators_list_handler.h src/RESTAPI/RESTAPI_operators_handler.cpp src/RESTAPI/RESTAPI_operators_handler.h src/storage/storage_op_contacts.cpp src/storage/storage_op_contacts.h src/storage/storage_op_locations.cpp src/storage/storage_op_locations.h src/RESTAPI/RESTAPI_op_contact_list_handler.cpp src/RESTAPI/RESTAPI_op_contact_list_handler.h src/RESTAPI/RESTAPI_op_contact_handler.cpp src/RESTAPI/RESTAPI_op_contact_handler.h src/RESTAPI/RESTAPI_op_location_list_handler.cpp src/RESTAPI/RESTAPI_op_location_list_handler.h src/RESTAPI/RESTAPI_op_location_handler.cpp src/RESTAPI/RESTAPI_op_location_handler.h src/ProvWebSocketClient.cpp src/ProvWebSocketClient.h src/Tasks/VenueRebooter.h src/Tasks/VenueUpgrade.h src/sdks/SDK_fms.cpp src/sdks/SDK_fms.h) |  | ||||||
|  |  | ||||||
| target_link_libraries(owprov PUBLIC | target_link_libraries(owprov PUBLIC | ||||||
|         ${Poco_LIBRARIES} |         ${Poco_LIBRARIES} | ||||||
|   | |||||||
							
								
								
									
										54
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						
									
										54
									
								
								Dockerfile
									
									
									
									
									
								
							| @@ -1,10 +1,4 @@ | |||||||
| ARG ALPINE_VERSION=3.16.2 | FROM alpine:3.15 AS build-base | ||||||
| ARG POCO_VERSION=poco-tip-v1 |  | ||||||
| ARG FMTLIB_VERSION=9.0.0 |  | ||||||
| ARG CPPKAFKA_VERSION=tip-v1 |  | ||||||
| ARG JSON_VALIDATOR_VERSION=2.1.0 |  | ||||||
|  |  | ||||||
| FROM alpine:$ALPINE_VERSION AS build-base |  | ||||||
|  |  | ||||||
| RUN apk add --update --no-cache \ | RUN apk add --update --no-cache \ | ||||||
|     make cmake g++ git \ |     make cmake g++ git \ | ||||||
| @@ -15,10 +9,8 @@ RUN apk add --update --no-cache \ | |||||||
|  |  | ||||||
| FROM build-base AS poco-build | FROM build-base AS poco-build | ||||||
|  |  | ||||||
| ARG POCO_VERSION | ADD https://api.github.com/repos/stephb9959/poco/git/refs/heads/master version.json | ||||||
|  | RUN git clone https://github.com/stephb9959/poco /poco | ||||||
| ADD https://api.github.com/repos/AriliaWireless/poco/git/refs/tags/${POCO_VERSION} version.json |  | ||||||
| RUN git clone https://github.com/AriliaWireless/poco --branch ${POCO_VERSION} /poco |  | ||||||
|  |  | ||||||
| WORKDIR /poco | WORKDIR /poco | ||||||
| RUN mkdir cmake-build | RUN mkdir cmake-build | ||||||
| @@ -27,26 +19,10 @@ RUN cmake .. | |||||||
| RUN cmake --build . --config Release -j8 | RUN cmake --build . --config Release -j8 | ||||||
| RUN cmake --build . --target install | RUN cmake --build . --target install | ||||||
|  |  | ||||||
| FROM build-base AS fmtlib-build |  | ||||||
|  |  | ||||||
| ARG FMTLIB_VERSION |  | ||||||
|  |  | ||||||
| ADD https://api.github.com/repos/fmtlib/fmt/git/refs/tags/${FMTLIB_VERSION} version.json |  | ||||||
| RUN git clone https://github.com/fmtlib/fmt --branch ${FMTLIB_VERSION} /fmtlib |  | ||||||
|  |  | ||||||
| WORKDIR /fmtlib |  | ||||||
| RUN mkdir cmake-build |  | ||||||
| WORKDIR cmake-build |  | ||||||
| RUN cmake .. |  | ||||||
| RUN make |  | ||||||
| RUN make install |  | ||||||
|  |  | ||||||
| FROM build-base AS cppkafka-build | FROM build-base AS cppkafka-build | ||||||
|  |  | ||||||
| ARG CPPKAFKA_VERSION | ADD https://api.github.com/repos/stephb9959/cppkafka/git/refs/heads/master version.json | ||||||
|  | RUN git clone https://github.com/stephb9959/cppkafka /cppkafka | ||||||
| ADD https://api.github.com/repos/AriliaWireless/cppkafka/git/refs/tags/${CPPKAFKA_VERSION} version.json |  | ||||||
| RUN git clone https://github.com/AriliaWireless/cppkafka --branch ${CPPKAFKA_VERSION} /cppkafka |  | ||||||
|  |  | ||||||
| WORKDIR /cppkafka | WORKDIR /cppkafka | ||||||
| RUN mkdir cmake-build | RUN mkdir cmake-build | ||||||
| @@ -57,10 +33,8 @@ RUN cmake --build . --target install | |||||||
|  |  | ||||||
| FROM build-base AS json-schema-validator-build | FROM build-base AS json-schema-validator-build | ||||||
|  |  | ||||||
| ARG JSON_VALIDATOR_VERSION | 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 | ||||||
| ADD https://api.github.com/repos/pboettch/json-schema-validator/git/refs/tags/${JSON_VALIDATOR_VERSION} version.json |  | ||||||
| RUN git clone https://github.com/pboettch/json-schema-validator --branch ${JSON_VALIDATOR_VERSION} /json-schema-validator |  | ||||||
|  |  | ||||||
| WORKDIR /json-schema-validator | WORKDIR /json-schema-validator | ||||||
| RUN mkdir cmake-build | RUN mkdir cmake-build | ||||||
| @@ -69,6 +43,18 @@ RUN cmake .. | |||||||
| RUN make | RUN make | ||||||
| RUN make install | RUN make install | ||||||
|  |  | ||||||
|  | FROM build-base AS fmtlib-build | ||||||
|  |  | ||||||
|  | ADD https://api.github.com/repos/fmtlib/fmt/git/refs/heads/master version.json | ||||||
|  | RUN git clone https://github.com/fmtlib/fmt /fmtlib | ||||||
|  |  | ||||||
|  | WORKDIR /fmtlib | ||||||
|  | RUN mkdir cmake-build | ||||||
|  | WORKDIR cmake-build | ||||||
|  | RUN cmake .. | ||||||
|  | RUN make | ||||||
|  | RUN make install | ||||||
|  |  | ||||||
| FROM build-base AS owprov-build | FROM build-base AS owprov-build | ||||||
|  |  | ||||||
| ADD CMakeLists.txt build /owprov/ | ADD CMakeLists.txt build /owprov/ | ||||||
| @@ -91,7 +77,7 @@ WORKDIR /owprov/cmake-build | |||||||
| RUN cmake .. | RUN cmake .. | ||||||
| RUN cmake --build . --config Release -j8 | RUN cmake --build . --config Release -j8 | ||||||
|  |  | ||||||
| FROM alpine:$ALPINE_VERSION | FROM alpine:3.15 | ||||||
|  |  | ||||||
| ENV OWPROV_USER=owprov \ | ENV OWPROV_USER=owprov \ | ||||||
|     OWPROV_ROOT=/owprov-data \ |     OWPROV_ROOT=/owprov-data \ | ||||||
|   | |||||||
| @@ -24,7 +24,6 @@ if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then | |||||||
|   SYSTEM_URI_PRIVATE=${SYSTEM_URI_PRIVATE:-"https://localhost:17005"} \ |   SYSTEM_URI_PRIVATE=${SYSTEM_URI_PRIVATE:-"https://localhost:17005"} \ | ||||||
|   SYSTEM_URI_PUBLIC=${SYSTEM_URI_PUBLIC:-"https://localhost:16005"} \ |   SYSTEM_URI_PUBLIC=${SYSTEM_URI_PUBLIC:-"https://localhost:16005"} \ | ||||||
|   SYSTEM_URI_UI=${SYSTEM_URI_UI:-"http://localhost"} \ |   SYSTEM_URI_UI=${SYSTEM_URI_UI:-"http://localhost"} \ | ||||||
|   SECURITY_RESTAPI_DISABLE=${SECURITY_RESTAPI_DISABLE:-"false"} \ |  | ||||||
|   KAFKA_ENABLE=${KAFKA_ENABLE:-"true"} \ |   KAFKA_ENABLE=${KAFKA_ENABLE:-"true"} \ | ||||||
|   KAFKA_BROKERLIST=${KAFKA_BROKERLIST:-"localhost:9092"} \ |   KAFKA_BROKERLIST=${KAFKA_BROKERLIST:-"localhost:9092"} \ | ||||||
|   KAFKA_SSL_CA_LOCATION=${KAFKA_SSL_CA_LOCATION:-""} \ |   KAFKA_SSL_CA_LOCATION=${KAFKA_SSL_CA_LOCATION:-""} \ | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								helm/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								helm/.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,3 +1 @@ | |||||||
| *.swp | *.swp | ||||||
| Chart.lock |  | ||||||
| charts/ |  | ||||||
|   | |||||||
| @@ -70,8 +70,8 @@ The following table lists the configurable parameters of the chart and their def | |||||||
| | persistence.size | string | Defines PV size | `'10Gi'` | | | persistence.size | string | Defines PV size | `'10Gi'` | | ||||||
| | public_env_variables | hash | Defines list of environment variables to be passed to the Provisioning | | | | public_env_variables | hash | Defines list of environment variables to be passed to the Provisioning | | | ||||||
| | configProperties | hash | Configuration properties that should be passed to the application in `owprov.properties`. May be passed by key in set (i.e. `configProperties."rtty\.token"`) | | | | configProperties | hash | Configuration properties that should be passed to the application in `owprov.properties`. May be passed by key in set (i.e. `configProperties."rtty\.token"`) | | | ||||||
| | existingCertsSecret | string | Existing Kubernetes secret containing all required certificates and private keys for microservice operation. If set, certificates from `certs` key are ignored | `""` | | | certs | hash | Defines files (keys and certificates) that should be passed to the Provisioning (PEM format is adviced to be used) (see `volumes.owprov` on where it is mounted) |  | | ||||||
| | certs | hash | Defines files (keys and certificates) that should be passed to the Gateway (PEM format is adviced to be used) (see `volumes.owprov` on where it is mounted). If `existingCertsSecret` is set, certificates passed this way will not be used. |  | |  | ||||||
|  |  | ||||||
| Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, | Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,5 +1,4 @@ | |||||||
| {{- $root := . -}} | {{- $root := . -}} | ||||||
| {{- $storageType := index .Values.configProperties "storage.type" -}} |  | ||||||
| --- | --- | ||||||
| apiVersion: apps/v1 | apiVersion: apps/v1 | ||||||
| kind: Deployment | kind: Deployment | ||||||
| @@ -47,39 +46,6 @@ spec: | |||||||
|             - -timeout |             - -timeout | ||||||
|             - 600s |             - 600s | ||||||
|  |  | ||||||
| {{- if eq $storageType "postgresql" }} |  | ||||||
|         - name: wait-postgres |  | ||||||
|           image: "{{ .Values.images.owprov.repository }}:{{ .Values.images.owprov.tag }}" |  | ||||||
|           imagePullPolicy: {{ .Values.images.owprov.pullPolicy }} |  | ||||||
|           command: |  | ||||||
|             - /wait-for-postgres.sh |  | ||||||
|             - {{ index .Values.configProperties "storage.type.postgresql.host" }} |  | ||||||
|             - echo |  | ||||||
|             - "PostgreSQL is ready" |  | ||||||
|           env: |  | ||||||
|             - name: KUBERNETES_DEPLOYED |  | ||||||
|               value: "{{ now }}" |  | ||||||
|           {{- range $key, $value := .Values.public_env_variables }} |  | ||||||
|             - name: {{ $key }} |  | ||||||
|               value: {{ $value | quote }} |  | ||||||
|           {{- end }} |  | ||||||
|           {{- range $key, $value := .Values.secret_env_variables }} |  | ||||||
|             - name: {{ $key }} |  | ||||||
|               valueFrom: |  | ||||||
|                 secretKeyRef: |  | ||||||
|                   name: {{ include "owprov.fullname" $root }}-env |  | ||||||
|                   key: {{ $key }} |  | ||||||
|           {{- end }} |  | ||||||
|           volumeMounts: |  | ||||||
|           {{- range .Values.volumes.owprov }} |  | ||||||
|           - name: {{ .name }} |  | ||||||
|             mountPath: {{ .mountPath }} |  | ||||||
|             {{- if .subPath }} |  | ||||||
|             subPath: {{ .subPath }} |  | ||||||
|             {{- end }} |  | ||||||
|           {{- end }} |  | ||||||
| {{- end }} |  | ||||||
|  |  | ||||||
|       containers: |       containers: | ||||||
|  |  | ||||||
|         - name: owprov |         - name: owprov | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ fullnameOverride: "" | |||||||
| images: | images: | ||||||
|   owprov: |   owprov: | ||||||
|     repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owprov |     repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owprov | ||||||
|     tag: v2.7.0-RC2 |     tag: v2.6.0 | ||||||
|     pullPolicy: Always |     pullPolicy: Always | ||||||
| #    regcred: | #    regcred: | ||||||
| #      registry: tip-tip-wlan-cloud-ucentral.jfrog.io | #      registry: tip-tip-wlan-cloud-ucentral.jfrog.io | ||||||
| @@ -71,7 +71,7 @@ volumes: | |||||||
|       mountPath: /owprov-data/certs |       mountPath: /owprov-data/certs | ||||||
|       volumeDefinition: | |       volumeDefinition: | | ||||||
|         secret: |         secret: | ||||||
|           secretName: {{ if .Values.existingCertsSecret }}{{ .Values.existingCertsSecret }}{{ else }}{{ include "owprov.fullname" . }}-certs{{ end }} |           secretName: {{ include "owprov.fullname" . }}-certs | ||||||
|     # Change this if you want to use another volume type |     # Change this if you want to use another volume type | ||||||
|     - name: persist |     - name: persist | ||||||
|       mountPath: /owprov-data/persist |       mountPath: /owprov-data/persist | ||||||
| @@ -199,9 +199,6 @@ configProperties: | |||||||
|   storage.type.mysql.username: stephb |   storage.type.mysql.username: stephb | ||||||
|   storage.type.mysql.password: snoopy99 |   storage.type.mysql.password: snoopy99 | ||||||
|  |  | ||||||
| # NOTE: List of required certificates may be found in "certs" key. Alternative way to pass required certificates is to create external secret with all required certificates and set secret name in "existingCertsSecret" key. Details may be found in https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/tree/main/chart#tldr |  | ||||||
| existingCertsSecret: "" |  | ||||||
|  |  | ||||||
| certs: | certs: | ||||||
|   # restapi-ca.pem: "" |   # restapi-ca.pem: "" | ||||||
|   # restapi-cert.pem: "" |   # restapi-cert.pem: "" | ||||||
|   | |||||||
| @@ -1958,6 +1958,11 @@ paths: | |||||||
|           schema: |           schema: | ||||||
|             type: boolean |             type: boolean | ||||||
|           required: false |           required: false | ||||||
|  |         - in: query | ||||||
|  |           name: deviceType | ||||||
|  |           schema: | ||||||
|  |             type: string | ||||||
|  |           required: false | ||||||
|         - in: query |         - in: query | ||||||
|           description: Pagination start (starts at 1. If not specified, 1 is assumed) |           description: Pagination start (starts at 1. If not specified, 1 is assumed) | ||||||
|           name: offset |           name: offset | ||||||
| @@ -2029,21 +2034,6 @@ paths: | |||||||
|             type: string |             type: string | ||||||
|             format: uuid |             format: uuid | ||||||
|           required: false |           required: false | ||||||
|         - in: query |  | ||||||
|           description: return RRM settings for a specific device |  | ||||||
|           name: rrmSettings |  | ||||||
|           schema: |  | ||||||
|             type: boolean |  | ||||||
|             default: false |  | ||||||
|           required: false |  | ||||||
|         - in: query |  | ||||||
|           description: return the resolved configuration for a specific device |  | ||||||
|           name:   resolveConfig |  | ||||||
|           schema: |  | ||||||
|             type: boolean |  | ||||||
|             default: false |  | ||||||
|           required: false |  | ||||||
|  |  | ||||||
|       responses: |       responses: | ||||||
|         200: |         200: | ||||||
|           description: Return a list of elements |           description: Return a list of elements | ||||||
| @@ -2265,6 +2255,12 @@ paths: | |||||||
|             type: string |             type: string | ||||||
|             example: serial1,serial2,serial3 |             example: serial1,serial2,serial3 | ||||||
|           required: false |           required: false | ||||||
|  |         - in: query | ||||||
|  |           description: only serial numbers of full device details | ||||||
|  |           name: serialOnly | ||||||
|  |           schema: | ||||||
|  |             type: boolean | ||||||
|  |           required: false | ||||||
|         - in: query |         - in: query | ||||||
|           description: return the number of devices |           description: return the number of devices | ||||||
|           name: countOnly |           name: countOnly | ||||||
|   | |||||||
| @@ -1,174 +0,0 @@ | |||||||
| openapi: 3.0.1 |  | ||||||
| info: |  | ||||||
|   title: OpenWiFi RRM Provider Model |  | ||||||
|   description: Definitions and APIs to manages an OpenWiFi RRM Providers. |  | ||||||
|   version: 1.0.0 |  | ||||||
|   license: |  | ||||||
|     name: BSD3 |  | ||||||
|     url: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE |  | ||||||
|  |  | ||||||
| servers: |  | ||||||
|   - url: 'https://localhost:16022/api/v1' |  | ||||||
|  |  | ||||||
| security: |  | ||||||
|   - bearerAuth: [] |  | ||||||
|   - ApiKeyAuth: [] |  | ||||||
|  |  | ||||||
| components: |  | ||||||
|   securitySchemes: |  | ||||||
|     ApiKeyAuth: |  | ||||||
|       type: apiKey |  | ||||||
|       in: header |  | ||||||
|       name: X-API-KEY |  | ||||||
|     bearerAuth: |  | ||||||
|       type: http |  | ||||||
|       scheme: bearer |  | ||||||
|       bearerFormat: JWT |  | ||||||
|  |  | ||||||
|   responses: |  | ||||||
|     NotFound: |  | ||||||
|       $ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/NotFound' |  | ||||||
|     Unauthorized: |  | ||||||
|       $ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Unauthorized' |  | ||||||
|     Success: |  | ||||||
|       $ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Success' |  | ||||||
|     BadRequest: |  | ||||||
|       $ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/BadRequest' |  | ||||||
|  |  | ||||||
|   schemas: |  | ||||||
|  |  | ||||||
|     Provider: |  | ||||||
|       type: object |  | ||||||
|       properties: |  | ||||||
|         vendor: |  | ||||||
|           description: The name of the vendor for display. |  | ||||||
|           type: string |  | ||||||
|           minLength: 1 |  | ||||||
|           maxLength: 128 |  | ||||||
|         vendorShortname: |  | ||||||
|           description: A shortname for the vendor. Only letters and numbers are allowed. This is the name used internally. |  | ||||||
|           type: string |  | ||||||
|           minLength: 4 |  | ||||||
|           maxLength: 16 |  | ||||||
|         version: |  | ||||||
|           description: An identifier that will help users identify the version of the RRM module they are using. |  | ||||||
|           type: string |  | ||||||
|         about: |  | ||||||
|           description: A link to the Vendor page for this RRM Module |  | ||||||
|           type: string |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     Algorithm: |  | ||||||
|       type: object |  | ||||||
|       properties: |  | ||||||
|         name: |  | ||||||
|           description: A display for this algorithm. |  | ||||||
|           type: string |  | ||||||
|           minLength: 1 |  | ||||||
|           maxLength: 128 |  | ||||||
|         description: |  | ||||||
|           description: A description of the algorithm. |  | ||||||
|           type: string |  | ||||||
|         shortName: |  | ||||||
|           description: This is the name used internally. |  | ||||||
|           type: string |  | ||||||
|           minLength: 4 |  | ||||||
|           maxLength: 16 |  | ||||||
|         parameterFormat: |  | ||||||
|           description: this is a Regex used to validate the input. If this is empty, no validation will be performed. |  | ||||||
|           type: string |  | ||||||
|         parameterSamples: |  | ||||||
|           description: These samples will be displayed in the UI to the user trying to configure the options |  | ||||||
|           type: array |  | ||||||
|           items: |  | ||||||
|             type: string |  | ||||||
|         helper: |  | ||||||
|           description: A link to a web page or PDF document explaining the algorithm and its parameters |  | ||||||
|           type: string |  | ||||||
|  |  | ||||||
|     Algorithms: |  | ||||||
|       description: The list of all algorithms supported by the vendor |  | ||||||
|       type: array |  | ||||||
|       items: |  | ||||||
|         $ref: '#/components/schemas/Algorithm' |  | ||||||
|  |  | ||||||
| paths: |  | ||||||
|   /provider: |  | ||||||
|     get: |  | ||||||
|       tags: |  | ||||||
|         - RRM |  | ||||||
|       operationId: getProvider |  | ||||||
|       summary: Retrieve information about the provider for this RRM Module |  | ||||||
|       responses: |  | ||||||
|         200: |  | ||||||
|           $ref: '#/components/schemas/Provider' |  | ||||||
|         400: |  | ||||||
|           $ref: '#/components/responses/BadRequest' |  | ||||||
|         403: |  | ||||||
|           $ref: '#/components/responses/Unauthorized' |  | ||||||
|         404: |  | ||||||
|           $ref: '#/components/responses/NotFound' |  | ||||||
|  |  | ||||||
|   /algorithms: |  | ||||||
|     get: |  | ||||||
|       tags: |  | ||||||
|         - RRM |  | ||||||
|       operationId: getAlgorithms |  | ||||||
|       summary: Retrieve a lists of algorithms supported in the module. |  | ||||||
|       responses: |  | ||||||
|         200: |  | ||||||
|           $ref: '#/components/schemas/Algorithms' |  | ||||||
|         400: |  | ||||||
|           $ref: '#/components/responses/BadRequest' |  | ||||||
|         403: |  | ||||||
|           $ref: '#/components/responses/Unauthorized' |  | ||||||
|         404: |  | ||||||
|           $ref: '#/components/responses/NotFound' |  | ||||||
|  |  | ||||||
|   /runRRM: |  | ||||||
|     put: |  | ||||||
|       tags: |  | ||||||
|         - RRM |  | ||||||
|       operationId: runRRMNow |  | ||||||
|       summary: Run a specific or default RRM algorithm. The UI user or CLI user will have the ability to run an algorithm on demand. |  | ||||||
|       parameters: |  | ||||||
|         - in: query |  | ||||||
|           description: |  | ||||||
|           name: venue |  | ||||||
|           schema: |  | ||||||
|             type: string |  | ||||||
|             format: uuid |  | ||||||
|           required: true |  | ||||||
|         - in: query |  | ||||||
|           description: Perform RRM without updating anything. This may be used by an admin to see what RRM would do. |  | ||||||
|           name: mock |  | ||||||
|           schema: |  | ||||||
|             type: boolean |  | ||||||
|             default: false |  | ||||||
|           required: false |  | ||||||
|         - in: query |  | ||||||
|           description: Specify the RRM algorithm to use. If omitted, select the default algorithm. |  | ||||||
|           schema: |  | ||||||
|             type: string |  | ||||||
|           required: false |  | ||||||
|         - in: query |  | ||||||
|           description: Specify the parameters to use with the RRM algorithm to use. If omitted, select the default parameters. |  | ||||||
|           schema: |  | ||||||
|             type: string |  | ||||||
|           required: false |  | ||||||
|       responses: |  | ||||||
|         200: |  | ||||||
|           description: Return the list of actions that were or would be performed. |  | ||||||
|           content: |  | ||||||
|             application/json: |  | ||||||
|               schema: |  | ||||||
|                 type: array |  | ||||||
|                 items: |  | ||||||
|                   type: string |  | ||||||
|         400: |  | ||||||
|           $ref: '#/components/responses/BadRequest' |  | ||||||
|         403: |  | ||||||
|           $ref: '#/components/responses/Unauthorized' |  | ||||||
|         404: |  | ||||||
|           $ref: '#/components/responses/NotFound' |  | ||||||
|  |  | ||||||
| @@ -34,7 +34,6 @@ openwifi.system.uri.private = https://localhost:17005 | |||||||
| openwifi.system.uri.public = https://ucentral.dpaas.arilia.com:16005 | openwifi.system.uri.public = https://ucentral.dpaas.arilia.com:16005 | ||||||
| openwifi.system.commandchannel = /tmp/app.owprov | openwifi.system.commandchannel = /tmp/app.owprov | ||||||
| openwifi.system.uri.ui = owprov-ui.arilia.com | openwifi.system.uri.ui = owprov-ui.arilia.com | ||||||
| openwifi.security.restapi.disable = false |  | ||||||
|  |  | ||||||
| firmware.updater.upgrade = false | firmware.updater.upgrade = false | ||||||
| firmware.updater.releaseonly = false | firmware.updater.releaseonly = false | ||||||
|   | |||||||
| @@ -39,7 +39,6 @@ openwifi.system.uri.private = ${SYSTEM_URI_PRIVATE} | |||||||
| openwifi.system.uri.public = ${SYSTEM_URI_PUBLIC} | openwifi.system.uri.public = ${SYSTEM_URI_PUBLIC} | ||||||
| openwifi.system.commandchannel = /tmp/app.ucentralfms | openwifi.system.commandchannel = /tmp/app.ucentralfms | ||||||
| openwifi.system.uri.ui = ${SYSTEM_URI_UI} | openwifi.system.uri.ui = ${SYSTEM_URI_UI} | ||||||
| openwifi.security.restapi.disable = ${SECURITY_RESTAPI_DISABLE} |  | ||||||
|  |  | ||||||
| ############################# | ############################# | ||||||
| # Generic information for all micro services | # Generic information for all micro services | ||||||
|   | |||||||
| @@ -23,7 +23,6 @@ namespace OpenWifi { | |||||||
|                                                               bool &Done, std::string &Answer) { |                                                               bool &Done, std::string &Answer) { | ||||||
|         Done = false; |         Done = false; | ||||||
|         auto Prefix = O->get("serial_prefix").toString(); |         auto Prefix = O->get("serial_prefix").toString(); | ||||||
|         Poco::toLowerInPlace(Prefix); |  | ||||||
|         Logger().information(Poco::format("serial_number_search: %s", Prefix)); |         Logger().information(Poco::format("serial_number_search: %s", Prefix)); | ||||||
|         if (!Prefix.empty() && Prefix.length() < 13) { |         if (!Prefix.empty() && Prefix.length() < 13) { | ||||||
|             std::vector<uint64_t> Numbers; |             std::vector<uint64_t> Numbers; | ||||||
| @@ -84,7 +83,6 @@ namespace OpenWifi { | |||||||
|         Done = false; |         Done = false; | ||||||
|         auto operatorId = O->get("operatorId").toString(); |         auto operatorId = O->get("operatorId").toString(); | ||||||
|         auto Prefix = O->get("serial_prefix").toString(); |         auto Prefix = O->get("serial_prefix").toString(); | ||||||
|         Poco::toLowerInPlace(Prefix); |  | ||||||
|         std::string Query; |         std::string Query; | ||||||
|  |  | ||||||
|         if(Prefix[0]=='*') { |         if(Prefix[0]=='*') { | ||||||
|   | |||||||
| @@ -9,9 +9,6 @@ | |||||||
| #include "framework/MicroService.h" | #include "framework/MicroService.h" | ||||||
| #include "framework/ConfigurationValidator.h" | #include "framework/ConfigurationValidator.h" | ||||||
| #include "sdks/SDK_sec.h" | #include "sdks/SDK_sec.h" | ||||||
| #include "Poco/StringTokenizer.h" |  | ||||||
|  |  | ||||||
| #include "libs/croncpp.h" |  | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
| @@ -408,9 +405,7 @@ namespace OpenWifi { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     inline bool ValidateConfigBlock(const ProvObjects::DeviceConfiguration &Config, RESTAPI::Errors::msg & Error) { |     inline bool ValidateConfigBlock(const ProvObjects::DeviceConfiguration &Config, RESTAPI::Errors::msg & Error) { | ||||||
|         static const std::vector<std::string> SectionNames{ "globals", "interfaces", "metrics", "radios", "services", |         static const std::vector<std::string> SectionNames{ "globals", "interfaces", "metrics", "radios", "services", "unit" }; | ||||||
|                                                             "unit", "definitions", "ethernet", "switch", "config-raw", |  | ||||||
|                                                             "third-party" }; |  | ||||||
|  |  | ||||||
|         for(const auto &i:Config.configuration) { |         for(const auto &i:Config.configuration) { | ||||||
|             Poco::JSON::Parser  P; |             Poco::JSON::Parser  P; | ||||||
| @@ -526,39 +521,12 @@ namespace OpenWifi { | |||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return Result; |         return Result; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     inline bool ValidSchedule(const std::string &v) { |  | ||||||
|         try |  | ||||||
|         { |  | ||||||
|             auto cron = cron::make_cron(v); |  | ||||||
|             return true; |  | ||||||
|         } |  | ||||||
|         catch (cron::bad_cronexpr const & ex) |  | ||||||
|         { |  | ||||||
|         } |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     inline bool ValidRRM(const std::string &v) { |  | ||||||
|         if((v=="no") || (v=="inherit")) return true; |  | ||||||
|         try { |  | ||||||
|             Poco::JSON::Parser  P; |  | ||||||
|             auto O = P.parse(v).extract<Poco::JSON::Object::Ptr>(); |  | ||||||
|  |  | ||||||
|             ProvObjects::RRMDetails D; |  | ||||||
|             if(D.from_json(O)) { |  | ||||||
|                 return ValidSchedule(D.schedule); |  | ||||||
|             } |  | ||||||
|         } catch (...) { |  | ||||||
|  |  | ||||||
|         } |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     inline bool ValidDeviceRules(const ProvObjects::DeviceRules & DR) { |     inline bool ValidDeviceRules(const ProvObjects::DeviceRules & DR) { | ||||||
|         return  (ValidRRM(DR.rrm)) && |         return  (DR.rrm=="yes" || DR.rrm=="no" || DR.rrm=="inherit") && | ||||||
|                 (DR.firmwareUpgrade=="yes" || DR.firmwareUpgrade=="no" || DR.firmwareUpgrade=="inherit") && |                 (DR.firmwareUpgrade=="yes" || DR.firmwareUpgrade=="no" || DR.firmwareUpgrade=="inherit") && | ||||||
|                 (DR.rcOnly=="yes" || DR.rcOnly=="no" || DR.rcOnly=="inherit"); |                 (DR.rcOnly=="yes" || DR.rcOnly=="no" || DR.rcOnly=="inherit"); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -41,8 +41,7 @@ namespace OpenWifi{ | |||||||
|         if(SerialNumber.empty() || !DB_.GetRecord(RESTAPI::Protocol::SERIALNUMBER,SerialNumber,Existing)) { |         if(SerialNumber.empty() || !DB_.GetRecord(RESTAPI::Protocol::SERIALNUMBER,SerialNumber,Existing)) { | ||||||
|             return NotFound(); |             return NotFound(); | ||||||
|         } |         } | ||||||
|         Logger().debug( |         Logger().debug(Poco::format("%s,%s: Retrieving inventory information.", Existing.serialNumber, Existing.info.id )); | ||||||
|                 Poco::format("%s,%s: Retrieving inventory information.", Existing.serialNumber, Existing.info.id)); |  | ||||||
|  |  | ||||||
|         Poco::JSON::Object  Answer; |         Poco::JSON::Object  Answer; | ||||||
|         std::string Arg; |         std::string Arg; | ||||||
| @@ -59,29 +58,13 @@ namespace OpenWifi{ | |||||||
|                 Answer.set("config","none"); |                 Answer.set("config","none"); | ||||||
|             } |             } | ||||||
|             return ReturnObject(Answer); |             return ReturnObject(Answer); | ||||||
|         } else if (GetBoolParameter("firmwareOptions", false)) { |         } else if(HasParameter("firmwareOptions", Arg) && Arg=="true") { | ||||||
|             ProvObjects::DeviceRules Rules; |             ProvObjects::DeviceRules Rules; | ||||||
|             StorageService()->InventoryDB().EvaluateDeviceSerialNumberRules(SerialNumber,Rules); |             StorageService()->InventoryDB().EvaluateDeviceSerialNumberRules(SerialNumber,Rules); | ||||||
|             Answer.set("firmwareUpgrade",Rules.firmwareUpgrade); |             Answer.set("firmwareUpgrade",Rules.firmwareUpgrade); | ||||||
|             Answer.set("firmwareRCOnly", Rules.rcOnly == "yes" ); |             Answer.set("firmwareRCOnly", Rules.rcOnly == "yes" ); | ||||||
|             return ReturnObject(Answer); |             return ReturnObject(Answer); | ||||||
|         } else if(GetBoolParameter("rrmSettings",false)) { |         } else if(HasParameter("applyConfiguration",Arg) && Arg=="true") { | ||||||
|             ProvObjects::DeviceRules Rules; |  | ||||||
|             StorageService()->InventoryDB().EvaluateDeviceSerialNumberRules(SerialNumber, Rules); |  | ||||||
|             if(Rules.rrm=="no" || Rules.rrm=="inherit") { |  | ||||||
|                 Answer.set("rrm", Rules.rrm); |  | ||||||
|             } else { |  | ||||||
|                 ProvObjects::RRMDetails D; |  | ||||||
|                 Poco::JSON::Parser  P; |  | ||||||
|                 try { |  | ||||||
|                     auto Obj = P.parse(Rules.rrm).extract<Poco::JSON::Object::Ptr>(); |  | ||||||
|                     Answer.set("rrm", Obj); |  | ||||||
|                 } catch (...) { |  | ||||||
|                     Answer.set("rrm", "invalid"); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             return ReturnObject(Answer); |  | ||||||
|         } else if(GetBoolParameter("applyConfiguration", false)) { |  | ||||||
|             Logger().debug(Poco::format("%s: Retrieving configuration.",Existing.serialNumber)); |             Logger().debug(Poco::format("%s: Retrieving configuration.",Existing.serialNumber)); | ||||||
|             auto Device = std::make_shared<APConfig>(SerialNumber, Existing.deviceType, Logger(), false); |             auto Device = std::make_shared<APConfig>(SerialNumber, Existing.deviceType, Logger(), false); | ||||||
|             auto Configuration = Poco::makeShared<Poco::JSON::Object>(); |             auto Configuration = Poco::makeShared<Poco::JSON::Object>(); | ||||||
| @@ -108,19 +91,6 @@ namespace OpenWifi{ | |||||||
|             } |             } | ||||||
|             Results.to_json(Answer); |             Results.to_json(Answer); | ||||||
|             return ReturnObject(Answer); |             return ReturnObject(Answer); | ||||||
|         } else if(GetBoolParameter("resolveConfig", false)) { |  | ||||||
|             Logger().debug(Poco::format("%s: Retrieving configuration.",Existing.serialNumber)); |  | ||||||
|             auto Device = std::make_shared<APConfig>(SerialNumber, Existing.deviceType, Logger(), false); |  | ||||||
|             auto Configuration = Poco::makeShared<Poco::JSON::Object>(); |  | ||||||
|             Poco::JSON::Object ErrorsObj, WarningsObj; |  | ||||||
|             ProvObjects::InventoryConfigApplyResult Results; |  | ||||||
|             Logger().debug(Poco::format("%s: Computing configuration.",Existing.serialNumber)); |  | ||||||
|             if (Device->Get(Configuration)) { |  | ||||||
|                 Answer.set("configuration", Configuration); |  | ||||||
|             } else { |  | ||||||
|                 Answer.set("error", 1); |  | ||||||
|             } |  | ||||||
|             return ReturnObject(Answer); |  | ||||||
|         }   else if(QB_.AdditionalInfo) { |         }   else if(QB_.AdditionalInfo) { | ||||||
|             AddExtendedInfo(Existing,Answer); |             AddExtendedInfo(Existing,Answer); | ||||||
|         } |         } | ||||||
| @@ -166,7 +136,6 @@ namespace OpenWifi{ | |||||||
|  |  | ||||||
|     void RESTAPI_inventory_handler::DoPost() { |     void RESTAPI_inventory_handler::DoPost() { | ||||||
|         std::string SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER,""); |         std::string SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER,""); | ||||||
|         Poco::toLowerInPlace(SerialNumber); |  | ||||||
|         if(SerialNumber.empty()) { |         if(SerialNumber.empty()) { | ||||||
|             return BadRequest(RESTAPI::Errors::MissingSerialNumber); |             return BadRequest(RESTAPI::Errors::MissingSerialNumber); | ||||||
|         } |         } | ||||||
| @@ -185,11 +154,6 @@ namespace OpenWifi{ | |||||||
|             return BadRequest(RESTAPI::Errors::InvalidJSONDocument); |             return BadRequest(RESTAPI::Errors::InvalidJSONDocument); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         NormalizeMac(NewObject.serialNumber); |  | ||||||
|         if(SerialNumber!=NewObject.serialNumber) { |  | ||||||
|             return BadRequest(RESTAPI::Errors::SerialNumberMismatch); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if((RawObject->has("deviceRules") && !ValidDeviceRules(NewObject.deviceRules,*this))) { |         if((RawObject->has("deviceRules") && !ValidDeviceRules(NewObject.deviceRules,*this))) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -101,7 +101,7 @@ namespace OpenWifi { | |||||||
|                 { "email", UserName }, |                 { "email", UserName }, | ||||||
|                 { "signupUUID" , SignupUUID }, |                 { "signupUUID" , SignupUUID }, | ||||||
|                 { "owner" , SignupOperator.info.id }, |                 { "owner" , SignupOperator.info.id }, | ||||||
|                 { "operatorName", SignupOperator.registrationId } |  | ||||||
|         }, Body, 30000); |         }, Body, 30000); | ||||||
|  |  | ||||||
|         Poco::JSON::Object::Ptr Answer; |         Poco::JSON::Object::Ptr Answer; | ||||||
|   | |||||||
| @@ -203,10 +203,6 @@ namespace OpenWifi::GWObjects { | |||||||
| 		field_to_json(Obj,"kafkaClients", kafkaClients); | 		field_to_json(Obj,"kafkaClients", kafkaClients); | ||||||
| 		field_to_json(Obj,"kafkaPackets", kafkaPackets); | 		field_to_json(Obj,"kafkaPackets", kafkaPackets); | ||||||
| 		field_to_json(Obj,"locale", locale); | 		field_to_json(Obj,"locale", locale); | ||||||
| 		field_to_json(Obj,"started", started); |  | ||||||
| 		field_to_json(Obj,"sessionId", sessionId); |  | ||||||
| 		field_to_json(Obj,"connectionCompletionTime", connectionCompletionTime); |  | ||||||
| 		field_to_json(Obj,"totalConnectionTime", OpenWifi::Now() - started); |  | ||||||
|  |  | ||||||
| 		switch(VerifiedCertificate) { | 		switch(VerifiedCertificate) { | ||||||
| 			case NO_CERTIFICATE: | 			case NO_CERTIFICATE: | ||||||
| @@ -222,21 +218,6 @@ namespace OpenWifi::GWObjects { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	void DeviceConnectionStatistics::to_json(Poco::JSON::Object &Obj) const { |  | ||||||
| 		field_to_json(Obj,"averageConnectionTime", averageConnectionTime); |  | ||||||
| 		field_to_json(Obj,"connectedDevices", connectedDevices ); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	bool DeviceConnectionStatistics::from_json(const Poco::JSON::Object::Ptr &Obj) { |  | ||||||
| 		try { |  | ||||||
| 			field_from_json(Obj,"averageConnectionTime", averageConnectionTime); |  | ||||||
| 			field_from_json(Obj,"connectedDevices", connectedDevices ); |  | ||||||
| 			return true; |  | ||||||
| 		} catch (const Poco::Exception &E) { |  | ||||||
| 		} |  | ||||||
| 		return false; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	void RttySessionDetails::to_json(Poco::JSON::Object &Obj) const { | 	void RttySessionDetails::to_json(Poco::JSON::Object &Obj) const { | ||||||
| 		field_to_json(Obj,"serialNumber", SerialNumber); | 		field_to_json(Obj,"serialNumber", SerialNumber); | ||||||
| 		field_to_json(Obj,"server", Server); | 		field_to_json(Obj,"server", Server); | ||||||
| @@ -312,6 +293,7 @@ namespace OpenWifi::GWObjects { | |||||||
| 		} catch (const Poco::Exception &E) { | 		} catch (const Poco::Exception &E) { | ||||||
| 		} | 		} | ||||||
| 		return false; | 		return false; | ||||||
|  |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	void RadiusProxyPoolList::to_json(Poco::JSON::Object &Obj) const { | 	void RadiusProxyPoolList::to_json(Poco::JSON::Object &Obj) const { | ||||||
| @@ -332,8 +314,6 @@ namespace OpenWifi::GWObjects { | |||||||
| 		field_to_json(Obj,"description",description); | 		field_to_json(Obj,"description",description); | ||||||
| 		field_to_json(Obj,"authConfig",authConfig); | 		field_to_json(Obj,"authConfig",authConfig); | ||||||
| 		field_to_json(Obj,"acctConfig",acctConfig); | 		field_to_json(Obj,"acctConfig",acctConfig); | ||||||
| 		field_to_json(Obj,"coaConfig",coaConfig); |  | ||||||
| 		field_to_json(Obj,"useByDefault",useByDefault); |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	bool RadiusProxyPool::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	bool RadiusProxyPool::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
| @@ -342,8 +322,6 @@ namespace OpenWifi::GWObjects { | |||||||
| 			field_from_json(Obj,"description",description); | 			field_from_json(Obj,"description",description); | ||||||
| 			field_from_json(Obj,"authConfig",authConfig); | 			field_from_json(Obj,"authConfig",authConfig); | ||||||
| 			field_from_json(Obj,"acctConfig",acctConfig); | 			field_from_json(Obj,"acctConfig",acctConfig); | ||||||
| 			field_from_json(Obj,"coaConfig",coaConfig); |  | ||||||
| 			field_from_json(Obj,"useByDefault",useByDefault); |  | ||||||
| 			return true; | 			return true; | ||||||
| 		} catch (const Poco::Exception &E) { | 		} catch (const Poco::Exception &E) { | ||||||
| 		} | 		} | ||||||
| @@ -351,7 +329,7 @@ namespace OpenWifi::GWObjects { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	void RadiusProxyServerConfig::to_json(Poco::JSON::Object &Obj) const { | 	void RadiusProxyServerConfig::to_json(Poco::JSON::Object &Obj) const { | ||||||
| 		field_to_json(Obj,"strategy",strategy); | 		field_to_json(Obj,"policy",strategy); | ||||||
| 		field_to_json(Obj,"monitor",monitor); | 		field_to_json(Obj,"monitor",monitor); | ||||||
| 		field_to_json(Obj,"monitorMethod",monitorMethod); | 		field_to_json(Obj,"monitorMethod",monitorMethod); | ||||||
| 		field_to_json(Obj,"methodParameters",methodParameters); | 		field_to_json(Obj,"methodParameters",methodParameters); | ||||||
| @@ -360,7 +338,7 @@ namespace OpenWifi::GWObjects { | |||||||
|  |  | ||||||
| 	bool RadiusProxyServerConfig::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	bool RadiusProxyServerConfig::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
| 		try { | 		try { | ||||||
| 			field_from_json(Obj,"strategy",strategy); | 			field_from_json(Obj,"policy",strategy); | ||||||
| 			field_from_json(Obj,"monitor",monitor); | 			field_from_json(Obj,"monitor",monitor); | ||||||
| 			field_from_json(Obj,"monitorMethod",monitorMethod); | 			field_from_json(Obj,"monitorMethod",monitorMethod); | ||||||
| 			field_from_json(Obj,"methodParameters",methodParameters); | 			field_from_json(Obj,"methodParameters",methodParameters); | ||||||
| @@ -376,16 +354,6 @@ namespace OpenWifi::GWObjects { | |||||||
| 		field_to_json(Obj,"ip",ip); | 		field_to_json(Obj,"ip",ip); | ||||||
| 		field_to_json(Obj,"port",port); | 		field_to_json(Obj,"port",port); | ||||||
| 		field_to_json(Obj,"weight",weight); | 		field_to_json(Obj,"weight",weight); | ||||||
| 		field_to_json(Obj,"secret",secret); |  | ||||||
| 		field_to_json(Obj,"certificate",certificate); |  | ||||||
| 		field_to_json(Obj,"radsec",radsec); |  | ||||||
| 		field_to_json(Obj,"radsecPort",radsecPort); |  | ||||||
| 		field_to_json(Obj,"radsecSecret",radsecSecret); |  | ||||||
| 		field_to_json(Obj,"radsecCacerts",radsecCacerts); |  | ||||||
| 		field_to_json(Obj,"radsecCert",radsecCert); |  | ||||||
| 		field_to_json(Obj,"radsecKey",radsecKey); |  | ||||||
| 		field_to_json(Obj,"radsecRealms",radsecRealms); |  | ||||||
| 		field_to_json(Obj,"ignore",ignore); |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	bool RadiusProxyServerEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	bool RadiusProxyServerEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
| @@ -394,16 +362,6 @@ namespace OpenWifi::GWObjects { | |||||||
| 			field_from_json(Obj,"ip",ip); | 			field_from_json(Obj,"ip",ip); | ||||||
| 			field_from_json(Obj,"port",port); | 			field_from_json(Obj,"port",port); | ||||||
| 			field_from_json(Obj,"weight",weight); | 			field_from_json(Obj,"weight",weight); | ||||||
| 			field_from_json(Obj,"secret",secret); |  | ||||||
| 			field_from_json(Obj,"certificate",certificate); |  | ||||||
| 			field_from_json(Obj,"radsec",radsec); |  | ||||||
| 			field_from_json(Obj,"radsecSecret",radsecSecret); |  | ||||||
| 			field_from_json(Obj,"radsecPort",radsecPort); |  | ||||||
| 			field_from_json(Obj,"radsecCacerts",radsecCacerts); |  | ||||||
| 			field_from_json(Obj,"radsecCert",radsecCert); |  | ||||||
| 			field_from_json(Obj,"radsecKey",radsecKey); |  | ||||||
| 			field_from_json(Obj,"radsecRealms",radsecRealms); |  | ||||||
| 			field_from_json(Obj,"ignore",ignore); |  | ||||||
| 			return true; | 			return true; | ||||||
| 		} catch (const Poco::Exception &E) { | 		} catch (const Poco::Exception &E) { | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -38,10 +38,6 @@ namespace OpenWifi::GWObjects { | |||||||
| 		uint64_t 	kafkaPackets=0; | 		uint64_t 	kafkaPackets=0; | ||||||
| 		uint64_t 	websocketPackets=0; | 		uint64_t 	websocketPackets=0; | ||||||
| 		std::string locale; | 		std::string locale; | ||||||
| 		uint64_t 	started=0; |  | ||||||
| 		uint64_t 	sessionId=0; |  | ||||||
| 		double      connectionCompletionTime=0.0; |  | ||||||
|  |  | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| @@ -75,13 +71,6 @@ namespace OpenWifi::GWObjects { | |||||||
| 		void Print() const; | 		void Print() const; | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	struct DeviceConnectionStatistics { |  | ||||||
| 		std::uint64_t connectedDevices = 0; |  | ||||||
| 		std::uint64_t averageConnectionTime = 0; |  | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; |  | ||||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); |  | ||||||
| 	}; |  | ||||||
|  |  | ||||||
| 	struct Statistics { | 	struct Statistics { | ||||||
| 		std::string SerialNumber; | 		std::string SerialNumber; | ||||||
| 		uint64_t 	UUID = 0 ; | 		uint64_t 	UUID = 0 ; | ||||||
| @@ -227,16 +216,6 @@ namespace OpenWifi::GWObjects { | |||||||
| 		std::string ip; | 		std::string ip; | ||||||
| 		uint16_t 	port=0; | 		uint16_t 	port=0; | ||||||
| 		uint64_t 	weight=0; | 		uint64_t 	weight=0; | ||||||
| 		std::string secret; |  | ||||||
| 		std::string certificate; |  | ||||||
| 		bool 		radsec=false; |  | ||||||
| 		uint16_t 	radsecPort=2083; |  | ||||||
| 		std::string radsecSecret; |  | ||||||
| 		std::string radsecKey; |  | ||||||
| 		std::string radsecCert; |  | ||||||
| 		std::vector<std::string> 	radsecCacerts; |  | ||||||
| 		std::vector<std::string>	radsecRealms; |  | ||||||
| 		bool 		ignore=false; |  | ||||||
|  |  | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
| @@ -258,8 +237,6 @@ namespace OpenWifi::GWObjects { | |||||||
| 		std::string description; | 		std::string description; | ||||||
| 		RadiusProxyServerConfig	authConfig; | 		RadiusProxyServerConfig	authConfig; | ||||||
| 		RadiusProxyServerConfig	acctConfig; | 		RadiusProxyServerConfig	acctConfig; | ||||||
| 		RadiusProxyServerConfig	coaConfig; |  | ||||||
| 		bool 		useByDefault=false; |  | ||||||
|  |  | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|   | |||||||
| @@ -1159,40 +1159,5 @@ namespace OpenWifi::ProvObjects { | |||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void RRMAlgorithmDetails::to_json(Poco::JSON::Object &Obj) const { |  | ||||||
|         field_to_json(Obj,"name",name); |  | ||||||
|         field_to_json(Obj,"parameters",parameters); |  | ||||||
| } | } | ||||||
|  |  | ||||||
|     bool RRMAlgorithmDetails::from_json(const Poco::JSON::Object::Ptr &Obj) { |  | ||||||
|         try { |  | ||||||
|             field_from_json(Obj,"name",name); |  | ||||||
|             field_from_json(Obj,"parameters",parameters); |  | ||||||
|             return true; |  | ||||||
|         } catch(...) { |  | ||||||
|  |  | ||||||
|         } |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void RRMDetails::to_json(Poco::JSON::Object &Obj) const { |  | ||||||
|         field_to_json(Obj,"vendor",vendor); |  | ||||||
|         field_to_json(Obj,"schedule",schedule); |  | ||||||
|         field_to_json(Obj,"algorithms",algorithms); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     bool RRMDetails::from_json(const Poco::JSON::Object::Ptr &Obj) { |  | ||||||
|         try { |  | ||||||
|             field_from_json(Obj,"vendor",vendor); |  | ||||||
|             field_from_json(Obj,"schedule",schedule); |  | ||||||
|             field_from_json(Obj,"algorithms",algorithms); |  | ||||||
|             return true; |  | ||||||
|         } catch(...) { |  | ||||||
|  |  | ||||||
|         } |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -62,21 +62,6 @@ namespace OpenWifi::ProvObjects { | |||||||
|     }; |     }; | ||||||
|     typedef std::vector<ManagementPolicy>      ManagementPolicyVec; |     typedef std::vector<ManagementPolicy>      ManagementPolicyVec; | ||||||
|  |  | ||||||
|     struct RRMAlgorithmDetails { |  | ||||||
|         std::string     name; |  | ||||||
|         std::string     parameters; |  | ||||||
|         void to_json(Poco::JSON::Object &Obj) const; |  | ||||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     struct RRMDetails { |  | ||||||
|         std::string     vendor; |  | ||||||
|         std::string     schedule; |  | ||||||
|         std::vector<RRMAlgorithmDetails>    algorithms; |  | ||||||
|         void to_json(Poco::JSON::Object &Obj) const; |  | ||||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     struct DeviceRules { |     struct DeviceRules { | ||||||
|         std::string     rcOnly{"inherit"}; |         std::string     rcOnly{"inherit"}; | ||||||
|         std::string     rrm{"inherit"}; |         std::string     rrm{"inherit"}; | ||||||
|   | |||||||
| @@ -195,24 +195,18 @@ namespace OpenWifi { | |||||||
|         // check that all inventory in venues and entities actually exists, if not, fix it. |         // check that all inventory in venues and entities actually exists, if not, fix it. | ||||||
|         auto FixVenueDevices = [&](const ProvObjects::Venue &V) -> bool { |         auto FixVenueDevices = [&](const ProvObjects::Venue &V) -> bool { | ||||||
|             Types::UUIDvec_t NewDevices; |             Types::UUIDvec_t NewDevices; | ||||||
|             bool modified=false; |  | ||||||
|             for(const auto &device:V.devices) { |             for(const auto &device:V.devices) { | ||||||
|                 ProvObjects::InventoryTag T; |                 ProvObjects::InventoryTag T; | ||||||
|                 if(InventoryDB().GetRecord("id", device, T)) { |                 if(InventoryDB().GetRecord("id", device, T)) { | ||||||
|                     NewDevices.emplace_back(device); |                     NewDevices.emplace_back(device); | ||||||
|                 } else { |                 } else { | ||||||
|                     modified=true; |  | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             ProvObjects::Venue NewVenue = V; |             if(NewDevices!=V.devices) { | ||||||
|             if(V.deviceRules.rrm=="yes") { |  | ||||||
|                 NewVenue.deviceRules.rrm="inherit"; |  | ||||||
|                 modified=true; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             if(modified) { |  | ||||||
|                 Logger().warning(fmt::format("  fixing venue: {}", V.info.name)); |                 Logger().warning(fmt::format("  fixing venue: {}", V.info.name)); | ||||||
|  |                 ProvObjects::Venue NewVenue = V; | ||||||
|                 NewVenue.devices = NewDevices; |                 NewVenue.devices = NewDevices; | ||||||
|                 VenueDB().UpdateRecord("id", V.info.id, NewVenue); |                 VenueDB().UpdateRecord("id", V.info.id, NewVenue); | ||||||
|             } |             } | ||||||
| @@ -272,16 +266,10 @@ namespace OpenWifi { | |||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             ProvObjects::Entity NewEntity = E; |  | ||||||
|  |  | ||||||
|             if(E.deviceRules.rrm=="yes") { |  | ||||||
|                 NewEntity.deviceRules.rrm="inherit"; |  | ||||||
|                 Modified=true; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             if(Modified) |             if(Modified) | ||||||
|             { |             { | ||||||
|                 Logger().warning(fmt::format("  fixing entity: {}",E.info.name)); |                 Logger().warning(fmt::format("  fixing entity: {}",E.info.name)); | ||||||
|  |                 ProvObjects::Entity NewEntity = E; | ||||||
|                 NewEntity.devices = NewDevices; |                 NewEntity.devices = NewDevices; | ||||||
|                 NewEntity.contacts = NewContacts; |                 NewEntity.contacts = NewContacts; | ||||||
|                 NewEntity.locations = NewLocations; |                 NewEntity.locations = NewLocations; | ||||||
| @@ -316,11 +304,6 @@ namespace OpenWifi { | |||||||
|                 modified=true; |                 modified=true; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             if(T.deviceRules.rrm=="yes") { |  | ||||||
|                 NewTag.deviceRules.rrm = "inherit"; |  | ||||||
|                 modified=true; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             if(modified) { |             if(modified) { | ||||||
|                 Logger().warning(fmt::format("  fixing entity: {}",T.info.name)); |                 Logger().warning(fmt::format("  fixing entity: {}",T.info.name)); | ||||||
|                 InventoryDB().UpdateRecord("id", T.info.id, NewTag); |                 InventoryDB().UpdateRecord("id", T.info.id, NewTag); | ||||||
| @@ -328,67 +311,12 @@ namespace OpenWifi { | |||||||
|             return true; |             return true; | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
|         auto FixConfiguration = [&](const ProvObjects::DeviceConfiguration &C) -> bool { |  | ||||||
|             ProvObjects::DeviceConfiguration NewConfig{C}; |  | ||||||
|  |  | ||||||
|             bool modified = false; |  | ||||||
|  |  | ||||||
|             if (C.deviceRules.rrm == "yes") { |  | ||||||
|                 NewConfig.deviceRules.rrm = "inherit"; |  | ||||||
|                 modified = true; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             if (modified) { |  | ||||||
|                 Logger().warning(fmt::format("  fixing configuration: {}", C.info.name)); |  | ||||||
|                 ConfigurationDB().UpdateRecord("id", C.info.id, NewConfig); |  | ||||||
|             } |  | ||||||
|             return true; |  | ||||||
|         }; |  | ||||||
|  |  | ||||||
|         auto FixOperator = [&](const ProvObjects::Operator &O) -> bool { |  | ||||||
|             ProvObjects::Operator NewOp{O}; |  | ||||||
|             bool modified = false; |  | ||||||
|  |  | ||||||
|             if (O.deviceRules.rrm == "yes") { |  | ||||||
|                 NewOp.deviceRules.rrm = "inherit"; |  | ||||||
|                 modified = true; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             if (modified) { |  | ||||||
|                 Logger().warning(fmt::format("  fixing operator: {}", O.info.name)); |  | ||||||
|                 OperatorDB().UpdateRecord("id", O.info.id, NewOp); |  | ||||||
|             } |  | ||||||
|             return true; |  | ||||||
|         }; |  | ||||||
|  |  | ||||||
|         auto FixSubscriber = [&](const ProvObjects::SubscriberDevice &O) -> bool { |  | ||||||
|             ProvObjects::SubscriberDevice NewSub{O}; |  | ||||||
|             bool modified = false; |  | ||||||
|  |  | ||||||
|             if (O.deviceRules.rrm == "yes") { |  | ||||||
|                 NewSub.deviceRules.rrm = "inherit"; |  | ||||||
|                 modified = true; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             if (modified) { |  | ||||||
|                 Logger().warning(fmt::format("  fixing subscriber: {}", O.info.name)); |  | ||||||
|                 SubscriberDeviceDB().UpdateRecord("id", O.info.id, NewSub); |  | ||||||
|             } |  | ||||||
|             return true; |  | ||||||
|         }; |  | ||||||
|  |  | ||||||
|         Logger().information("Checking DB consistency: venues"); |         Logger().information("Checking DB consistency: venues"); | ||||||
|         VenueDB().Iterate(FixVenueDevices); |         VenueDB().Iterate(FixVenueDevices); | ||||||
|         Logger().information("Checking DB consistency: entities"); |         Logger().information("Checking DB consistency: entities"); | ||||||
|         EntityDB().Iterate(FixEntity); |         EntityDB().Iterate(FixEntity); | ||||||
|         Logger().information("Checking DB consistency: inventory"); |         Logger().information("Checking DB consistency: inventory"); | ||||||
|         InventoryDB().Iterate(FixInventory); |         InventoryDB().Iterate(FixInventory); | ||||||
|         Logger().information("Checking DB consistency: configurations"); |  | ||||||
|         ConfigurationDB().Iterate(FixConfiguration); |  | ||||||
|         Logger().information("Checking DB consistency: operators"); |  | ||||||
|         OperatorDB().Iterate(FixOperator); |  | ||||||
|         Logger().information("Checking DB consistency: subscribers"); |  | ||||||
|         SubscriberDeviceDB().Iterate(FixSubscriber); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void Storage::InitializeSystemDBs() { |     void Storage::InitializeSystemDBs() { | ||||||
|   | |||||||
| @@ -44,21 +44,18 @@ namespace OpenWifi { | |||||||
|                         upgraded_++; |                         upgraded_++; | ||||||
|                     } else { |                     } else { | ||||||
|                         Logger().information(fmt::format("{}: Not Upgraded.", Device.serialNumber)); |                         Logger().information(fmt::format("{}: Not Upgraded.", Device.serialNumber)); | ||||||
|                         not_connected_++; |                         failed_++; | ||||||
|                     } |                     } | ||||||
|                 } else { |                 } else { | ||||||
|                     Logger().information(fmt::format("{}: Not Upgraded. No firmware available.", Device.serialNumber)); |                     Logger().information(fmt::format("{}: Not Upgraded. No firmware available.", Device.serialNumber)); | ||||||
|                     no_firmware_++; |                     failed_++; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             done_ = true; |             done_ = true; | ||||||
|             // std::cout << "Done push for " << Device.serialNumber << std::endl; |             // std::cout << "Done push for " << Device.serialNumber << std::endl; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         std::uint64_t   upgraded_ = 0, |         uint64_t        upgraded_=0, failed_=0, skipped_=0; | ||||||
|                         not_connected_ = 0, |  | ||||||
|                         skipped_ = 0, |  | ||||||
|                         no_firmware_ = 0; |  | ||||||
|         bool            started_ = false, |         bool            started_ = false, | ||||||
|                         done_ = false; |                         done_ = false; | ||||||
|         std::string     SerialNumber; |         std::string     SerialNumber; | ||||||
| @@ -83,13 +80,10 @@ namespace OpenWifi { | |||||||
|             Utils::SetThreadName("venue-upgr"); |             Utils::SetThreadName("venue-upgr"); | ||||||
|             auto VenueUUID_ = Parameter(0); |             auto VenueUUID_ = Parameter(0); | ||||||
|  |  | ||||||
|             WebSocketClientNotificationVenueUpgradeList_t        N; |             WebSocketClientNotificationVenueRebootList_t        N; | ||||||
|  |  | ||||||
|             ProvObjects::Venue  Venue; |             ProvObjects::Venue  Venue; | ||||||
|             uint64_t    upgraded_ = 0, |             uint64_t upgraded_ = 0, failed_ = 0; | ||||||
|                         not_connected_ = 0, |  | ||||||
|                         skipped_ = 0, |  | ||||||
|                         no_firmware_ = 0; |  | ||||||
|             if(StorageService()->VenueDB().GetRecord("id",VenueUUID_,Venue)) { |             if(StorageService()->VenueDB().GetRecord("id",VenueUUID_,Venue)) { | ||||||
|  |  | ||||||
|                 N.content.title = fmt::format("Upgrading {} devices.", Venue.info.name); |                 N.content.title = fmt::format("Upgrading {} devices.", Venue.info.name); | ||||||
| @@ -118,16 +112,10 @@ namespace OpenWifi { | |||||||
|                         if (current_job != nullptr && current_job->done_) { |                         if (current_job != nullptr && current_job->done_) { | ||||||
|                             if (current_job->upgraded_) |                             if (current_job->upgraded_) | ||||||
|                                 N.content.success.push_back(current_job->SerialNumber); |                                 N.content.success.push_back(current_job->SerialNumber); | ||||||
|                             else  if (current_job->skipped_) |                             else | ||||||
|                                 N.content.skipped.push_back(current_job->SerialNumber); |                                 N.content.warning.push_back(current_job->SerialNumber); | ||||||
|                             else  if (current_job->not_connected_) |  | ||||||
|                                 N.content.not_connected.push_back(current_job->SerialNumber); |  | ||||||
|                             else  if (current_job->no_firmware_) |  | ||||||
|                                 N.content.no_firmware.push_back(current_job->SerialNumber); |  | ||||||
|                             upgraded_ += current_job->upgraded_; |                             upgraded_ += current_job->upgraded_; | ||||||
|                             skipped_ += current_job->skipped_; |                             failed_ += current_job->failed_; | ||||||
|                             no_firmware_ += current_job->no_firmware_; |  | ||||||
|                             not_connected_ += current_job->not_connected_; |  | ||||||
|                             job_it = JobList.erase(job_it); |                             job_it = JobList.erase(job_it); | ||||||
|                             delete current_job; |                             delete current_job; | ||||||
|                         } else { |                         } else { | ||||||
| @@ -143,16 +131,10 @@ namespace OpenWifi { | |||||||
|                     if(current_job!= nullptr && current_job->done_) { |                     if(current_job!= nullptr && current_job->done_) { | ||||||
|                         if(current_job->upgraded_) |                         if(current_job->upgraded_) | ||||||
|                             N.content.success.push_back(current_job->SerialNumber); |                             N.content.success.push_back(current_job->SerialNumber); | ||||||
|                         else  if (current_job->skipped_) |                         else | ||||||
|                             N.content.skipped.push_back(current_job->SerialNumber); |                             N.content.warning.push_back(current_job->SerialNumber); | ||||||
|                         else  if (current_job->not_connected_) |  | ||||||
|                             N.content.not_connected.push_back(current_job->SerialNumber); |  | ||||||
|                         else  if (current_job->no_firmware_) |  | ||||||
|                             N.content.no_firmware.push_back(current_job->SerialNumber); |  | ||||||
|                         upgraded_ += current_job->upgraded_; |                         upgraded_ += current_job->upgraded_; | ||||||
|                         skipped_ += current_job->skipped_; |                         failed_ += current_job->failed_; | ||||||
|                         no_firmware_ += current_job->no_firmware_; |  | ||||||
|                         not_connected_ += current_job->not_connected_; |  | ||||||
|                         job_it = JobList.erase(job_it); |                         job_it = JobList.erase(job_it); | ||||||
|                         delete current_job; |                         delete current_job; | ||||||
|                     } else { |                     } else { | ||||||
| @@ -160,21 +142,19 @@ namespace OpenWifi { | |||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 N.content.details = fmt::format("Job {} Completed: {} upgraded, {} not connected, {} skipped, {} no firmware.", |                 N.content.details = fmt::format("Job {} Completed: {} upgraded, {} failed to upgrade.", | ||||||
|                                                 JobId(), |                                                 JobId(), upgraded_ ,failed_); | ||||||
|                                                 upgraded_ , |  | ||||||
|                                                 not_connected_, |  | ||||||
|                                                 skipped_, |  | ||||||
|                                                 no_firmware_); |  | ||||||
|             } else { |             } else { | ||||||
|                 N.content.details = fmt::format("Venue {} no longer exists.",VenueUUID_); |                 N.content.details = fmt::format("Venue {} no longer exists.",VenueUUID_); | ||||||
|                 Logger().warning(N.content.details); |                 Logger().warning(N.content.details); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             // std::cout << N.content.details << std::endl; |             // std::cout << N.content.details << std::endl; | ||||||
|             WebSocketClientNotificationVenueUpgradeCompletionToUser(UserInfo().email,N); |             WebSocketClientNotificationVenueRebootCompletionToUser(UserInfo().email,N); | ||||||
|             Logger().information(N.content.details); |             Logger().information(fmt::format("Job {} Completed: {} upgraded, {} failed to upgrade.", | ||||||
|  |                                              JobId(), upgraded_ ,failed_)); | ||||||
|             Utils::SetThreadName("free"); |             Utils::SetThreadName("free"); | ||||||
|  |  | ||||||
|             Complete(); |             Complete(); | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
|   | |||||||
| @@ -44,7 +44,7 @@ static json DefaultUCentralSchema = R"( | |||||||
| 		"switch": { | 		"switch": { | ||||||
| 			"$ref": "#/$defs/switch" | 			"$ref": "#/$defs/switch" | ||||||
| 		}, | 		}, | ||||||
| 		"radiosgrep": { | 		"radios": { | ||||||
| 			"type": "array", | 			"type": "array", | ||||||
| 			"items": { | 			"items": { | ||||||
| 				"$ref": "#/$defs/radio" | 				"$ref": "#/$defs/radio" | ||||||
|   | |||||||
| @@ -23,22 +23,10 @@ | |||||||
| #include <queue> | #include <queue> | ||||||
| #include <variant> | #include <variant> | ||||||
|  |  | ||||||
|  |  | ||||||
| // This must be defined for poco_debug and poco_trace macros to function. |  | ||||||
|  |  | ||||||
| #ifndef POCO_LOG_DEBUG |  | ||||||
| #define POCO_LOG_DEBUG true |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|     inline uint64_t Now() { return std::time(nullptr); }; |     inline uint64_t Now() { return std::time(nullptr); }; | ||||||
| } | } | ||||||
|  |  | ||||||
| namespace OpenWifi::Utils { |  | ||||||
|     std::vector<unsigned char> base64decode(const std::string& input); |  | ||||||
|     std::string base64encode(const unsigned char *input, uint32_t size); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| using namespace std::chrono_literals; | using namespace std::chrono_literals; | ||||||
|  |  | ||||||
| #include "Poco/Util/Application.h" | #include "Poco/Util/Application.h" | ||||||
| @@ -250,11 +238,6 @@ namespace OpenWifi::RESTAPI_utils { | |||||||
|         Obj.set(Field,Value); |         Obj.set(Field,Value); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Poco::Data::BLOB &Value) { |  | ||||||
|         auto Result = Utils::base64encode((const unsigned char *)Value.rawContent(),Value.size()); |  | ||||||
|         Obj.set(Field,Result); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::StringPairVec & S) { |     inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::StringPairVec & S) { | ||||||
|         Poco::JSON::Array   Array; |         Poco::JSON::Array   Array; | ||||||
|         for(const auto &i:S) { |         for(const auto &i:S) { | ||||||
| @@ -394,13 +377,6 @@ namespace OpenWifi::RESTAPI_utils { | |||||||
|             Value = (uint64_t ) Obj->get(Field); |             Value = (uint64_t ) Obj->get(Field); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, Poco::Data::BLOB &Value) { |  | ||||||
|         if(Obj->has(Field) && !Obj->isNull(Field)) { |  | ||||||
|             auto Result = Utils::base64decode(Obj->get(Field).toString()); |  | ||||||
|             Value.assignRaw((const unsigned char *)&Result[0],Result.size()); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, Types::StringPairVec &Vec) { |     inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, Types::StringPairVec &Vec) { | ||||||
|         if(Obj->isArray(Field) && !Obj->isNull(Field)) { |         if(Obj->isArray(Field) && !Obj->isNull(Field)) { | ||||||
|             auto O = Obj->getArray(Field); |             auto O = Obj->getArray(Field); | ||||||
| @@ -710,19 +686,6 @@ namespace OpenWifi::Utils { | |||||||
|         return (std::all_of(UUID.begin(),UUID.end(),[&](auto i){ if(i=='-') dashes++; return i=='-' || std::isxdigit(i);})) && (dashes>0); |         return (std::all_of(UUID.begin(),UUID.end(),[&](auto i){ if(i=='-') dashes++; return i=='-' || std::isxdigit(i);})) && (dashes>0); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| 	template <typename ...Args> std::string ComputeHash(Args&&... args) { |  | ||||||
| 		Poco::SHA2Engine    E; |  | ||||||
| 		auto as_string = [](auto p) { |  | ||||||
| 			if constexpr(std::is_arithmetic_v<decltype(p)>) { |  | ||||||
| 				return std::to_string(p); |  | ||||||
| 			} else { |  | ||||||
| 				return p; |  | ||||||
| 			} |  | ||||||
| 		}; |  | ||||||
| 		(E.update(as_string(args)),...); |  | ||||||
| 		return Poco::SHA2Engine::digestToHex(E.digest()); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
|     [[nodiscard]] inline std::vector<std::string> Split(const std::string &List, char Delimiter=',' ) { |     [[nodiscard]] inline std::vector<std::string> Split(const std::string &List, char Delimiter=',' ) { | ||||||
|         std::vector<std::string> ReturnList; |         std::vector<std::string> ReturnList; | ||||||
|  |  | ||||||
| @@ -1352,17 +1315,17 @@ namespace OpenWifi { | |||||||
| 		inline void exception(const Poco::Exception & E) { | 		inline void exception(const Poco::Exception & E) { | ||||||
| 		    Poco::Thread * CurrentThread = Poco::Thread::current(); | 		    Poco::Thread * CurrentThread = Poco::Thread::current(); | ||||||
| 		    App_.logger().log(E); | 		    App_.logger().log(E); | ||||||
| 		    poco_error(App_.logger(), fmt::format("Exception occurred in {}",CurrentThread->getName())); | 		    App_.logger().error(fmt::format("Exception occurred in {}",CurrentThread->getName())); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		inline void exception(const std::exception & E) { | 		inline void exception(const std::exception & E) { | ||||||
| 		    Poco::Thread * CurrentThread = Poco::Thread::current(); | 		    Poco::Thread * CurrentThread = Poco::Thread::current(); | ||||||
| 			poco_warning(App_.logger(), fmt::format("std::exception in {}: {}",CurrentThread->getName(),E.what())); | 		    App_.logger().warning(fmt::format("std::exception in {}: {}",CurrentThread->getName(),E.what())); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		inline void exception() { | 		inline void exception() { | ||||||
| 		    Poco::Thread * CurrentThread = Poco::Thread::current(); | 		    Poco::Thread * CurrentThread = Poco::Thread::current(); | ||||||
| 			poco_warning(App_.logger(), fmt::format("exception in {}",CurrentThread->getName())); | 		    App_.logger().warning(fmt::format("exception in {}",CurrentThread->getName())); | ||||||
| 		} | 		} | ||||||
| 	  private: | 	  private: | ||||||
| 		Poco::Util::Application	&App_; | 		Poco::Util::Application	&App_; | ||||||
| @@ -1370,17 +1333,12 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
| 	class BusEventManager : public Poco::Runnable { | 	class BusEventManager : public Poco::Runnable { | ||||||
| 	  public: | 	  public: | ||||||
| 		explicit BusEventManager(Poco::Logger &L) : Logger_(L) { |  | ||||||
|  |  | ||||||
| 		} |  | ||||||
| 		inline void run() final; | 		inline void run() final; | ||||||
| 		inline void Start(); | 		inline void Start(); | ||||||
| 		inline void Stop(); | 		inline void Stop(); | ||||||
| 		inline Poco::Logger & Logger() { return Logger_; } |  | ||||||
| 	  private: | 	  private: | ||||||
| 		mutable std::atomic_bool 	Running_ = false; | 		mutable std::atomic_bool 	Running_ = false; | ||||||
| 		Poco::Thread		Thread_; | 		Poco::Thread		Thread_; | ||||||
| 		Poco::Logger		&Logger_; |  | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	class MyPrivateKeyPassphraseHandler : public Poco::Net::PrivateKeyPassphraseHandler { | 	class MyPrivateKeyPassphraseHandler : public Poco::Net::PrivateKeyPassphraseHandler { | ||||||
| @@ -1394,7 +1352,6 @@ namespace OpenWifi { | |||||||
| 	        Logger_.information("Returning key passphrase."); | 	        Logger_.information("Returning key passphrase."); | ||||||
| 	        privateKey = Password_; | 	        privateKey = Password_; | ||||||
| 	    }; | 	    }; | ||||||
| 		inline Poco::Logger & Logger() { return Logger_; } |  | ||||||
| 	private: | 	private: | ||||||
| 	    std::string Password_; | 	    std::string Password_; | ||||||
| 	    Poco::Logger & Logger_; | 	    Poco::Logger & Logger_; | ||||||
| @@ -1425,14 +1382,13 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
| 	    [[nodiscard]] inline const std::string &Address() const { return address_; }; | 	    [[nodiscard]] inline const std::string &Address() const { return address_; }; | ||||||
| 	    [[nodiscard]] inline uint32_t Port() const { return port_; }; | 	    [[nodiscard]] inline uint32_t Port() const { return port_; }; | ||||||
| 	    [[nodiscard]] inline auto KeyFile() const { return key_file_; }; | 	    [[nodiscard]] inline const std::string &KeyFile() const { return key_file_; }; | ||||||
| 	    [[nodiscard]] inline auto CertFile() const { return cert_file_; }; | 	    [[nodiscard]] inline const std::string &CertFile() const { return cert_file_; }; | ||||||
| 	    [[nodiscard]] inline auto RootCA() const { return root_ca_; }; | 	    [[nodiscard]] inline const std::string &RootCA() const { return root_ca_; }; | ||||||
| 	    [[nodiscard]] inline auto KeyFilePassword() const { return key_file_password_; }; | 	    [[nodiscard]] inline const std::string &KeyFilePassword() const { return key_file_password_; }; | ||||||
| 	    [[nodiscard]] inline auto IssuerCertFile() const { return issuer_cert_file_; }; | 	    [[nodiscard]] inline const std::string &IssuerCertFile() const { return issuer_cert_file_; }; | ||||||
| 	    [[nodiscard]] inline auto Name() const { return name_; }; | 	    [[nodiscard]] inline const std::string &Name() const { return name_; }; | ||||||
| 	    [[nodiscard]] inline int Backlog() const { return backlog_; } | 	    [[nodiscard]] inline int Backlog() const { return backlog_; } | ||||||
| 		[[nodiscard]] inline auto Cas() const { return cas_; } |  | ||||||
|  |  | ||||||
| 	    [[nodiscard]] inline Poco::Net::SecureServerSocket CreateSecureSocket(Poco::Logger &L) const { | 	    [[nodiscard]] inline Poco::Net::SecureServerSocket CreateSecureSocket(Poco::Logger &L) const { | ||||||
| 	        Poco::Net::Context::Params P; | 	        Poco::Net::Context::Params P; | ||||||
| @@ -1663,14 +1619,14 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
| 	class SubSystemServer : public Poco::Util::Application::Subsystem { | 	class SubSystemServer : public Poco::Util::Application::Subsystem { | ||||||
| 	public: | 	public: | ||||||
| 	    SubSystemServer(const std::string & Name, const std::string &LoggingPrefix, | 	    SubSystemServer(std::string Name, const std::string &LoggingPrefix, | ||||||
|                         const std::string & SubSystemConfigPrefix); |                         std::string SubSystemConfigPrefix); | ||||||
|  |  | ||||||
| 	    inline void initialize(Poco::Util::Application &self) override; | 	    inline void initialize(Poco::Util::Application &self) override; | ||||||
| 	    inline void uninitialize() override { | 	    inline void uninitialize() override { | ||||||
| 	    } | 	    } | ||||||
| 	    inline void reinitialize([[maybe_unused]] Poco::Util::Application &self) override { | 	    inline void reinitialize([[maybe_unused]] Poco::Util::Application &self) override { | ||||||
| 	        Logger_->L_.information("Reloading of this subsystem is not supported."); | 	        Logger().information("Reloading of this subsystem is not supported."); | ||||||
| 	    } | 	    } | ||||||
| 	    inline void defineOptions([[maybe_unused]] Poco::Util::OptionSet &options) override { | 	    inline void defineOptions([[maybe_unused]] Poco::Util::OptionSet &options) override { | ||||||
| 	    } | 	    } | ||||||
| @@ -1679,27 +1635,27 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
| 	    inline const PropertiesFileServerEntry & Host(uint64_t index) { return ConfigServersList_[index]; }; | 	    inline const PropertiesFileServerEntry & Host(uint64_t index) { return ConfigServersList_[index]; }; | ||||||
| 	    inline uint64_t HostSize() const { return ConfigServersList_.size(); } | 	    inline uint64_t HostSize() const { return ConfigServersList_.size(); } | ||||||
| 		inline Poco::Logger & Logger() const { return Logger_->L_; } | 	    inline Poco::Logger &Logger() { if(Log_) | ||||||
| 	    inline void SetLoggingLevel(const std::string & levelName) { |                                             return Log_->L; | ||||||
| 			Logger_->L_.setLevel(Poco::Logger::parseLevel(levelName)); |                                         return Poco::Logger::get("tmp"); | ||||||
| 		} |                                         }; | ||||||
| 	    inline int GetLoggingLevel() { return Logger_->L_.getLevel(); } | 	    inline void SetLoggingLevel(Poco::Message::Priority NewPriority) { Logger().setLevel(NewPriority); } | ||||||
|  | 	    inline int GetLoggingLevel() { return Logger().getLevel(); } | ||||||
|  |  | ||||||
| 	    virtual int Start() = 0; | 	    virtual int Start() = 0; | ||||||
| 	    virtual void Stop() = 0; | 	    virtual void Stop() = 0; | ||||||
|  |  | ||||||
|         struct LoggerWrapper { |         struct LoggerWrapper { | ||||||
| 			Poco::Logger & L_; |             Poco::Logger &L; | ||||||
| 			LoggerWrapper(Poco::Logger &L) : |             explicit inline LoggerWrapper(Poco::Logger &Logger) : L(Logger) {} | ||||||
| 				L_(L) {} |  | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
| 	protected: | 	protected: | ||||||
| 	    std::recursive_mutex Mutex_; | 	    std::recursive_mutex Mutex_; | ||||||
|         std::vector<PropertiesFileServerEntry> ConfigServersList_; |         std::vector<PropertiesFileServerEntry> ConfigServersList_; | ||||||
|  |  | ||||||
|     private: |     private: | ||||||
|         std::unique_ptr<LoggerWrapper>  Logger_; |         std::unique_ptr<LoggerWrapper>  Log_; | ||||||
|  | 	    // Poco::Logger 		&Logger_; | ||||||
| 	    std::string 		Name_; | 	    std::string 		Name_; | ||||||
|         std::string         LoggerPrefix_; |         std::string         LoggerPrefix_; | ||||||
| 	    std::string 		SubSystemConfigPrefix_; | 	    std::string 		SubSystemConfigPrefix_; | ||||||
| @@ -1836,7 +1792,7 @@ namespace OpenWifi { | |||||||
| 	            E->Count++; | 	            E->Count++; | ||||||
| 	            Cache_.update(H,E); | 	            Cache_.update(H,E); | ||||||
| 	            if(E->Count > MaxCalls) { | 	            if(E->Count > MaxCalls) { | ||||||
| 	                poco_warning(Logger(),fmt::format("RATE-LIMIT-EXCEEDED: from '{}'", R.clientAddress().toString())); | 	                Logger().warning(fmt::format("RATE-LIMIT-EXCEEDED: from '{}'", R.clientAddress().toString())); | ||||||
| 	                return true; | 	                return true; | ||||||
| 	            } | 	            } | ||||||
| 	            return false; | 	            return false; | ||||||
| @@ -1912,8 +1868,8 @@ namespace OpenWifi { | |||||||
| 	            Request = &RequestIn; | 	            Request = &RequestIn; | ||||||
| 	            Response = &ResponseIn; | 	            Response = &ResponseIn; | ||||||
|  |  | ||||||
| //				std::string th_name = "restsvr_" + std::to_string(TransactionId_); | 				std::string th_name = "restsvr_" + std::to_string(TransactionId_); | ||||||
| //				Utils::SetThreadName(th_name.c_str()); | 				Utils::SetThreadName(th_name.c_str()); | ||||||
|  |  | ||||||
|                 if(Request->getContentLength()>0) { |                 if(Request->getContentLength()>0) { | ||||||
|                     if(Request->getContentType().find("application/json")!=std::string::npos) { |                     if(Request->getContentType().find("application/json")!=std::string::npos) { | ||||||
| @@ -2108,17 +2064,6 @@ namespace OpenWifi { | |||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, Poco::Data::BLOB &Value) { |  | ||||||
|             if(O->has(Field)) { |  | ||||||
|                 std::string Content = O->get(Field).toString(); |  | ||||||
|                 auto DecodedBlob = Utils::base64decode(Content); |  | ||||||
|                 Value.assignRaw((const unsigned char *)&DecodedBlob[0],DecodedBlob.size()); |  | ||||||
|                 return true; |  | ||||||
|             } |  | ||||||
|             return false; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|         template <typename T> bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, const T &value, T & assignee) { |         template <typename T> bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, const T &value, T & assignee) { | ||||||
|             if(O->has(Field)) { |             if(O->has(Field)) { | ||||||
|                 assignee = value; |                 assignee = value; | ||||||
| @@ -2178,16 +2123,12 @@ namespace OpenWifi { | |||||||
| 	        SetCommonHeaders(CloseConnection); | 	        SetCommonHeaders(CloseConnection); | ||||||
| 	    } | 	    } | ||||||
|  |  | ||||||
| 	    inline void BadRequest(const OpenWifi::RESTAPI::Errors::msg &E, const std::string & Extra="") { | 	    inline void BadRequest(const OpenWifi::RESTAPI::Errors::msg &E) { | ||||||
| 	        PrepareResponse(Poco::Net::HTTPResponse::HTTP_BAD_REQUEST); | 	        PrepareResponse(Poco::Net::HTTPResponse::HTTP_BAD_REQUEST); | ||||||
| 	        Poco::JSON::Object	ErrorObject; | 	        Poco::JSON::Object	ErrorObject; | ||||||
| 	        ErrorObject.set("ErrorCode",400); | 	        ErrorObject.set("ErrorCode",400); | ||||||
| 	        ErrorObject.set("ErrorDetails",Request->getMethod()); | 	        ErrorObject.set("ErrorDetails",Request->getMethod()); | ||||||
| 			if(Extra.empty()) |  | ||||||
| 	        ErrorObject.set("ErrorDescription",fmt::format("{}: {}",E.err_num,E.err_txt)) ; | 	        ErrorObject.set("ErrorDescription",fmt::format("{}: {}",E.err_num,E.err_txt)) ; | ||||||
| 			else |  | ||||||
| 				ErrorObject.set("ErrorDescription",fmt::format("{}: {} ({})",E.err_num,E.err_txt, Extra)) ; |  | ||||||
|  |  | ||||||
| 	        std::ostream &Answer = Response->send(); | 	        std::ostream &Answer = Response->send(); | ||||||
| 	        Poco::JSON::Stringifier::stringify(ErrorObject, Answer); | 	        Poco::JSON::Stringifier::stringify(ErrorObject, Answer); | ||||||
| 	    } | 	    } | ||||||
| @@ -2231,7 +2172,7 @@ namespace OpenWifi { | |||||||
|             ErrorObject.set("ErrorDescription",fmt::format("{}: {}",E.err_num,E.err_txt)) ; |             ErrorObject.set("ErrorDescription",fmt::format("{}: {}",E.err_num,E.err_txt)) ; | ||||||
| 	        std::ostream &Answer = Response->send(); | 	        std::ostream &Answer = Response->send(); | ||||||
| 	        Poco::JSON::Stringifier::stringify(ErrorObject, Answer); | 	        Poco::JSON::Stringifier::stringify(ErrorObject, Answer); | ||||||
| 			poco_debug(Logger_,fmt::format("RES-NOTFOUND: User='{}@{}' Method='{}' Path='{}", | 	        Logger_.debug(fmt::format("RES-NOTFOUND: User='{}@{}' Method='{}' Path='{}", | ||||||
|                                        UserInfo_.userinfo.email, |                                        UserInfo_.userinfo.email, | ||||||
|                                        Utils::FormatIPv6(Request->clientAddress().toString()), |                                        Utils::FormatIPv6(Request->clientAddress().toString()), | ||||||
|                                        Request->getMethod(), |                                        Request->getMethod(), | ||||||
| @@ -2463,7 +2404,6 @@ namespace OpenWifi { | |||||||
|             Poco::Net::HTTPServerResponse       *Response= nullptr; |             Poco::Net::HTTPServerResponse       *Response= nullptr; | ||||||
|             SecurityObjects::UserInfoAndPolicy 	UserInfo_; |             SecurityObjects::UserInfoAndPolicy 	UserInfo_; | ||||||
|             QueryBlock					QB_; |             QueryBlock					QB_; | ||||||
| 			const std::string & Requester() const { return REST_Requester_; } |  | ||||||
| 	    protected: | 	    protected: | ||||||
| 	        BindingMap 					Bindings_; | 	        BindingMap 					Bindings_; | ||||||
| 	        Poco::URI::QueryParameters 	Parameters_; | 	        Poco::URI::QueryParameters 	Parameters_; | ||||||
| @@ -2480,7 +2420,6 @@ namespace OpenWifi { | |||||||
| 	        RateLimit                   MyRates_; | 	        RateLimit                   MyRates_; | ||||||
|             uint64_t                    TransactionId_; |             uint64_t                    TransactionId_; | ||||||
|             Poco::JSON::Object::Ptr     ParsedBody_; |             Poco::JSON::Object::Ptr     ParsedBody_; | ||||||
| 			std::string					REST_Requester_; |  | ||||||
| 	    }; | 	    }; | ||||||
|  |  | ||||||
| 	    class RESTAPI_UnknownRequestHandler : public RESTAPIHandler { | 	    class RESTAPI_UnknownRequestHandler : public RESTAPIHandler { | ||||||
| @@ -2745,7 +2684,7 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
| 		inline void run() override { | 		inline void run() override { | ||||||
| 			Poco::AutoPtr<Poco::Notification>	Note(Queue_.waitDequeueNotification()); | 			Poco::AutoPtr<Poco::Notification>	Note(Queue_.waitDequeueNotification()); | ||||||
| 			Utils::SetThreadName("kafka:dispatch"); | 			Utils::SetThreadName("kafka-dispatch"); | ||||||
| 			while(Note && Running_) { | 			while(Note && Running_) { | ||||||
| 				auto Msg = dynamic_cast<KafkaMessage*>(Note.get()); | 				auto Msg = dynamic_cast<KafkaMessage*>(Note.get()); | ||||||
| 				if(Msg!= nullptr) { | 				if(Msg!= nullptr) { | ||||||
| @@ -2800,11 +2739,9 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
| 	    inline void Stop() override { | 	    inline void Stop() override { | ||||||
| 	        if(KafkaEnabled_) { | 	        if(KafkaEnabled_) { | ||||||
| 				poco_information(Logger(),"Stopping..."); |  | ||||||
| 				Dispatcher_.Stop(); | 				Dispatcher_.Stop(); | ||||||
| 	            ProducerThr_.Stop(); | 	            ProducerThr_.Stop(); | ||||||
| 	            ConsumerThr_.Stop(); | 	            ConsumerThr_.Stop(); | ||||||
| 				poco_information(Logger(),"Stopped..."); |  | ||||||
| 	            return; | 	            return; | ||||||
| 	        } | 	        } | ||||||
| 	    } | 	    } | ||||||
| @@ -2882,13 +2819,12 @@ namespace OpenWifi { | |||||||
| 	    } | 	    } | ||||||
|  |  | ||||||
| 	    inline void Stop() override { | 	    inline void Stop() override { | ||||||
| 			poco_information(Logger(),"Stopping..."); |  | ||||||
|             std::lock_guard	G(Mutex_); |             std::lock_guard	G(Mutex_); | ||||||
| 	        Cache_.clear(); | 	        Cache_.clear(); | ||||||
| 			poco_information(Logger(),"Stopped..."); |  | ||||||
| 	    } | 	    } | ||||||
|  |  | ||||||
| 	    inline void RemovedCachedToken(const std::string &Token) { | 	    inline void RemovedCachedToken(const std::string &Token) { | ||||||
|  | 	        std::lock_guard	G(Mutex_); | ||||||
| 	        Cache_.remove(Token); | 	        Cache_.remove(Token); | ||||||
| 	    } | 	    } | ||||||
|  |  | ||||||
| @@ -2898,7 +2834,6 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
| 	    inline bool RetrieveTokenInformation(const std::string & SessionToken, | 	    inline bool RetrieveTokenInformation(const std::string & SessionToken, | ||||||
| 											 SecurityObjects::UserInfoAndPolicy & UInfo, | 											 SecurityObjects::UserInfoAndPolicy & UInfo, | ||||||
| 											 std::uint64_t TID, |  | ||||||
| 											 bool & Expired, bool & Contacted, bool Sub=false) { | 											 bool & Expired, bool & Contacted, bool Sub=false) { | ||||||
| 	        try { | 	        try { | ||||||
| 	            Types::StringPairVec QueryData; | 	            Types::StringPairVec QueryData; | ||||||
| @@ -2924,6 +2859,7 @@ namespace OpenWifi { | |||||||
| 	                        return false; | 	                        return false; | ||||||
| 	                    } | 	                    } | ||||||
| 	                    Expired = false; | 	                    Expired = false; | ||||||
|  |                         std::lock_guard	G(Mutex_); | ||||||
| 	                    Cache_.update(SessionToken, UInfo); | 	                    Cache_.update(SessionToken, UInfo); | ||||||
| 	                    return true; | 	                    return true; | ||||||
| 	                } else { | 	                } else { | ||||||
| @@ -2931,15 +2867,14 @@ namespace OpenWifi { | |||||||
|                     } |                     } | ||||||
| 	            } | 	            } | ||||||
| 	        } catch (...) { | 	        } catch (...) { | ||||||
| 				poco_error(Logger(),fmt::format("Failed to retrieve token={} for TID={}", SessionToken, TID)); |  | ||||||
| 	        } | 	        } | ||||||
| 	        Expired = false; | 	        Expired = false; | ||||||
| 	        return false; | 	        return false; | ||||||
| 	    } | 	    } | ||||||
|  |  | ||||||
|         inline bool IsAuthorized(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, |         inline bool IsAuthorized(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, | ||||||
| 								 std::uint64_t TID, |  | ||||||
| 								 bool & Expired, bool & Contacted, bool Sub = false) { | 								 bool & Expired, bool & Contacted, bool Sub = false) { | ||||||
|  |             std::lock_guard	G(Mutex_); | ||||||
| 	        auto User = Cache_.get(SessionToken); | 	        auto User = Cache_.get(SessionToken); | ||||||
| 	        if(!User.isNull()) { | 	        if(!User.isNull()) { | ||||||
| 	            if(IsTokenExpired(User->webtoken)) { | 	            if(IsTokenExpired(User->webtoken)) { | ||||||
| @@ -2950,7 +2885,7 @@ namespace OpenWifi { | |||||||
|                 UInfo = *User; |                 UInfo = *User; | ||||||
|                 return true; |                 return true; | ||||||
| 	        } | 	        } | ||||||
| 	        return RetrieveTokenInformation(SessionToken, UInfo, TID, Expired, Contacted, Sub); | 	        return RetrieveTokenInformation(SessionToken, UInfo, Expired, Contacted, Sub); | ||||||
| 	    } | 	    } | ||||||
|  |  | ||||||
| 	private: | 	private: | ||||||
| @@ -2968,12 +2903,12 @@ namespace OpenWifi { | |||||||
| 	            { | 	            { | ||||||
| 	            } | 	            } | ||||||
|  |  | ||||||
| 	            void handleRequest([[maybe_unused]] Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response) override | 	            void handleRequest(Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response) override | ||||||
| 	            { | 	            { | ||||||
| 					Utils::SetThreadName("alb-request"); | 					Utils::SetThreadName("alb-request"); | ||||||
| 					try { | 					try { | ||||||
| 						if((id_ % 100) == 0) { | 						if((id_ % 100) == 0) { | ||||||
| 							poco_debug(Logger_,fmt::format("ALB-REQUEST({}): ALB Request {}.", | 							Logger_.debug(fmt::format("ALB-REQUEST({}): ALB Request {}.", | ||||||
| 															Request.clientAddress().toString(), id_)); | 															Request.clientAddress().toString(), id_)); | ||||||
| 						} | 						} | ||||||
| 						Response.setChunkedTransferEncoding(true); | 						Response.setChunkedTransferEncoding(true); | ||||||
| @@ -3031,10 +2966,8 @@ namespace OpenWifi { | |||||||
| 	    inline int Start() override; | 	    inline int Start() override; | ||||||
|  |  | ||||||
| 	    inline void Stop() override { | 	    inline void Stop() override { | ||||||
| 			poco_information(Logger(),"Stopping..."); |  | ||||||
| 	        if(Running_) | 	        if(Running_) | ||||||
| 	            Server_->stopAll(true); | 	            Server_->stop(); | ||||||
| 			poco_information(Logger(),"Stopped..."); |  | ||||||
| 	    } | 	    } | ||||||
|  |  | ||||||
| 	private: | 	private: | ||||||
| @@ -3061,32 +2994,30 @@ namespace OpenWifi { | |||||||
| 	    } | 	    } | ||||||
| 	    int Start() override; | 	    int Start() override; | ||||||
| 	    inline void Stop() override { | 	    inline void Stop() override { | ||||||
| 	        Logger().information("Stopping..."); | 	        Logger().information("Stopping "); | ||||||
| 	        for( const auto & svr : RESTServers_ ) | 	        for( const auto & svr : RESTServers_ ) | ||||||
| 	            svr->stopAll(true); | 	            svr->stop(); | ||||||
| 			Pool_.stopAll(); | 			Pool_.stopAll(); | ||||||
| 	        Pool_.joinAll(); | 	        Pool_.joinAll(); | ||||||
| 	        RESTServers_.clear(); | 	        RESTServers_.clear(); | ||||||
| 			Logger().information("Stopped..."); |  | ||||||
| 	    } | 	    } | ||||||
|  |  | ||||||
|  |  | ||||||
| 	    inline void reinitialize(Poco::Util::Application &self) override; | 	    inline void reinitialize(Poco::Util::Application &self) override; | ||||||
|  |  | ||||||
| 	    inline Poco::Net::HTTPRequestHandler *CallServer(const std::string &Path, uint64_t Id) { | 	    inline Poco::Net::HTTPRequestHandler *CallServer(const std::string &Path, uint64_t Id) { | ||||||
| 	        RESTAPIHandler::BindingMap Bindings; | 	        RESTAPIHandler::BindingMap Bindings; | ||||||
| 			Utils::SetThreadName(fmt::format("x-rest:{}",Id).c_str()); | 			Utils::SetThreadName(fmt::format("rest_ext_{}",Id).c_str()); | ||||||
| 	        return RESTAPI_ExtRouter(Path, Bindings, Logger(), Server_, Id); | 	        return RESTAPI_ExtRouter(Path, Bindings, Logger(), Server_, Id); | ||||||
| 	    } | 	    } | ||||||
|         const Poco::ThreadPool & Pool() { return Pool_; } |  | ||||||
|  |  | ||||||
| 	private: | 	private: | ||||||
| 	    std::vector<std::unique_ptr<Poco::Net::HTTPServer>>   RESTServers_; | 	    std::vector<std::unique_ptr<Poco::Net::HTTPServer>>   RESTServers_; | ||||||
| 	    Poco::ThreadPool	    Pool_{"x-rest",4,128}; | 	    Poco::ThreadPool	    Pool_; | ||||||
| 	    RESTAPI_GenericServer   Server_; | 	    RESTAPI_GenericServer   Server_; | ||||||
|  |  | ||||||
|         RESTAPI_ExtServer() noexcept: |         RESTAPI_ExtServer() noexcept: | ||||||
| 	    SubSystemServer("RESTAPI_ExtServer", "REST-XSRV", "openwifi.restapi") | 	    SubSystemServer("RESTAPI_ExtServer", "RESTAPIServer", "openwifi.restapi"), | ||||||
|  |         Pool_("RESTAPI_ExtServer",4,50,120) | ||||||
|             { |             { | ||||||
|             } |             } | ||||||
| 	}; | 	}; | ||||||
| @@ -3099,7 +3030,7 @@ namespace OpenWifi { | |||||||
| 	    inline Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override { | 	    inline Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override { | ||||||
| 			try { | 			try { | ||||||
| 				Poco::URI uri(Request.getURI()); | 				Poco::URI uri(Request.getURI()); | ||||||
| 				Utils::SetThreadName(fmt::format("x-rest:{}",TransactionId_).c_str()); | 				Utils::SetThreadName(fmt::format("rest_ext_{}",TransactionId_).c_str()); | ||||||
| 				return RESTAPI_ExtServer()->CallServer(uri.getPath(), TransactionId_++); | 				return RESTAPI_ExtServer()->CallServer(uri.getPath(), TransactionId_++); | ||||||
| 			} catch (...) { | 			} catch (...) { | ||||||
|  |  | ||||||
| @@ -3197,29 +3128,28 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
| 	    inline int Start() override; | 	    inline int Start() override; | ||||||
| 	    inline void Stop() override { | 	    inline void Stop() override { | ||||||
| 	        Logger().information("Stopping..."); | 	        Logger().information("Stopping "); | ||||||
| 	        for( const auto & svr : RESTServers_ ) | 	        for( const auto & svr : RESTServers_ ) | ||||||
| 	            svr->stopAll(true); | 	            svr->stop(); | ||||||
| 			Pool_.stopAll(); | 			Pool_.stopAll(); | ||||||
| 			Pool_.joinAll(); | 			Pool_.joinAll(); | ||||||
| 			Logger().information("Stopped..."); |  | ||||||
| 	    } | 	    } | ||||||
|  |  | ||||||
| 	    inline void reinitialize(Poco::Util::Application &self) override; | 	    inline void reinitialize(Poco::Util::Application &self) override; | ||||||
|  |  | ||||||
| 	    inline Poco::Net::HTTPRequestHandler *CallServer(const std::string &Path, uint64_t Id) { | 	    inline Poco::Net::HTTPRequestHandler *CallServer(const std::string &Path, uint64_t Id) { | ||||||
| 	        RESTAPIHandler::BindingMap Bindings; | 	        RESTAPIHandler::BindingMap Bindings; | ||||||
| 			Utils::SetThreadName(fmt::format("i-rest:{}",Id).c_str()); | 			Utils::SetThreadName(fmt::format("rest_int_{}",Id).c_str()); | ||||||
| 	        return RESTAPI_IntRouter(Path, Bindings, Logger(), Server_, Id); | 	        return RESTAPI_IntRouter(Path, Bindings, Logger(), Server_, Id); | ||||||
| 	    } | 	    } | ||||||
|         const Poco::ThreadPool & Pool() { return Pool_; } |  | ||||||
| 	private: | 	private: | ||||||
| 	    std::vector<std::unique_ptr<Poco::Net::HTTPServer>>   RESTServers_; | 	    std::vector<std::unique_ptr<Poco::Net::HTTPServer>>   RESTServers_; | ||||||
| 	    Poco::ThreadPool	    Pool_{"i-rest",4,96}; | 	    Poco::ThreadPool	    Pool_; | ||||||
| 	    RESTAPI_GenericServer   Server_; | 	    RESTAPI_GenericServer   Server_; | ||||||
|  |  | ||||||
|         RESTAPI_IntServer() noexcept: |         RESTAPI_IntServer() noexcept: | ||||||
| 		   SubSystemServer("RESTAPI_IntServer", "REST-ISRV", "openwifi.internal.restapi") | 		   SubSystemServer("RESTAPI_IntServer", "REST-ISRV", "openwifi.internal.restapi"), | ||||||
|  |             Pool_("RESTAPI_IntServer",4,50,120) | ||||||
|         { |         { | ||||||
|         } |         } | ||||||
| 	}; | 	}; | ||||||
| @@ -3230,7 +3160,6 @@ namespace OpenWifi { | |||||||
| 	public: | 	public: | ||||||
|         inline IntRequestHandlerFactory() = default; |         inline IntRequestHandlerFactory() = default; | ||||||
| 	    inline Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override { | 	    inline Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override { | ||||||
| 			Utils::SetThreadName(fmt::format("i-rest:{}",TransactionId_).c_str()); |  | ||||||
| 	        Poco::URI uri(Request.getURI()); | 	        Poco::URI uri(Request.getURI()); | ||||||
| 	        return RESTAPI_IntServer()->CallServer(uri.getPath(), TransactionId_); | 	        return RESTAPI_IntServer()->CallServer(uri.getPath(), TransactionId_); | ||||||
| 	    } | 	    } | ||||||
| @@ -3274,6 +3203,7 @@ namespace OpenWifi { | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		[[nodiscard]] std::string Version() { return Version_; } | 		[[nodiscard]] std::string Version() { return Version_; } | ||||||
|  | 		// [[nodiscard]] const Poco::SharedPtr<Poco::Crypto::RSAKey> & Key() { return AppKey_; } | ||||||
| 		[[nodiscard]] inline const std::string & DataDir() { return DataDir_; } | 		[[nodiscard]] inline const std::string & DataDir() { return DataDir_; } | ||||||
| 		[[nodiscard]] inline const std::string & WWWAssetsDir() { return WWWAssetsDir_; } | 		[[nodiscard]] inline const std::string & WWWAssetsDir() { return WWWAssetsDir_; } | ||||||
| 		[[nodiscard]] bool Debug() const { return DebugMode_; } | 		[[nodiscard]] bool Debug() const { return DebugMode_; } | ||||||
| @@ -3296,7 +3226,7 @@ namespace OpenWifi { | |||||||
| 		    return ((RandomEngine_() % (max-min)) + min); | 		    return ((RandomEngine_() % (max-min)) + min); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| /*        inline Poco::Logger & GetLogger(const std::string &Name) { |         inline Poco::Logger & GetLogger(const std::string &Name) { | ||||||
|             static auto initialized = false; |             static auto initialized = false; | ||||||
|  |  | ||||||
|             if(!initialized) { |             if(!initialized) { | ||||||
| @@ -3305,11 +3235,6 @@ namespace OpenWifi { | |||||||
|             } |             } | ||||||
|             return Poco::Logger::get(Name); |             return Poco::Logger::get(Name); | ||||||
|         } |         } | ||||||
| */ |  | ||||||
|         virtual void GetExtraConfiguration(Poco::JSON::Object & Cfg) { |  | ||||||
|             Cfg.set("additionalConfiguration",false); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 		static inline void Exit(int Reason); | 		static inline void Exit(int Reason); | ||||||
| 		inline void BusMessageReceived(const std::string &Key, const std::string & Payload); | 		inline void BusMessageReceived(const std::string &Key, const std::string & Payload); | ||||||
| @@ -3347,6 +3272,7 @@ namespace OpenWifi { | |||||||
| 		inline std::string ConfigPath(const std::string &Key); | 		inline std::string ConfigPath(const std::string &Key); | ||||||
| 		inline std::string Encrypt(const std::string &S); | 		inline std::string Encrypt(const std::string &S); | ||||||
| 		inline std::string Decrypt(const std::string &S); | 		inline std::string Decrypt(const std::string &S); | ||||||
|  | 		inline std::string CreateHash(const std::string &S); | ||||||
| 		inline std::string MakeSystemEventMessage( const std::string & Type ) const; | 		inline std::string MakeSystemEventMessage( const std::string & Type ) const; | ||||||
| 		[[nodiscard]] inline bool IsValidAPIKEY(const Poco::Net::HTTPServerRequest &Request); | 		[[nodiscard]] inline bool IsValidAPIKEY(const Poco::Net::HTTPServerRequest &Request); | ||||||
| 		inline static void SavePID(); | 		inline static void SavePID(); | ||||||
| @@ -3376,9 +3302,6 @@ namespace OpenWifi { | |||||||
|                 return Signer_.sign(T,Algo); |                 return Signer_.sign(T,Algo); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
| 		inline Poco::ThreadPool & TimerPool() { return TimerPool_; } |  | ||||||
|  |  | ||||||
| 	  private: | 	  private: | ||||||
| 	    static MicroService         * instance_; | 	    static MicroService         * instance_; | ||||||
| 		bool                        HelpRequested_ = false; | 		bool                        HelpRequested_ = false; | ||||||
| @@ -3392,12 +3315,14 @@ namespace OpenWifi { | |||||||
| 		std::string                 WWWAssetsDir_; | 		std::string                 WWWAssetsDir_; | ||||||
| 		Poco::Crypto::CipherFactory & CipherFactory_ = Poco::Crypto::CipherFactory::defaultFactory(); | 		Poco::Crypto::CipherFactory & CipherFactory_ = Poco::Crypto::CipherFactory::defaultFactory(); | ||||||
| 		Poco::Crypto::Cipher        * Cipher_ = nullptr; | 		Poco::Crypto::Cipher        * Cipher_ = nullptr; | ||||||
|  | 		Poco::SHA2Engine			SHA2_; | ||||||
| 		MicroServiceMetaMap			Services_; | 		MicroServiceMetaMap			Services_; | ||||||
| 		std::string 				MyHash_; | 		std::string 				MyHash_; | ||||||
| 		std::string 				MyPrivateEndPoint_; | 		std::string 				MyPrivateEndPoint_; | ||||||
| 		std::string 				MyPublicEndPoint_; | 		std::string 				MyPublicEndPoint_; | ||||||
| 		std::string                 UIURI_; | 		std::string                 UIURI_; | ||||||
| 		std::string 				Version_{ OW_VERSION::VERSION + "("+ OW_VERSION::BUILD + ")" + " - " + OW_VERSION::HASH }; | 		std::string 				Version_{ OW_VERSION::VERSION + "("+ OW_VERSION::BUILD + ")" + " - " + OW_VERSION::HASH }; | ||||||
|  | 		BusEventManager				BusEventManager_; | ||||||
| 		std::recursive_mutex		InfraMutex_; | 		std::recursive_mutex		InfraMutex_; | ||||||
| 		std::default_random_engine  RandomEngine_; | 		std::default_random_engine  RandomEngine_; | ||||||
|         Poco::Util::PropertyFileConfiguration   * PropConfigurationFile_ = nullptr; |         Poco::Util::PropertyFileConfiguration   * PropConfigurationFile_ = nullptr; | ||||||
| @@ -3411,8 +3336,6 @@ namespace OpenWifi { | |||||||
|         bool                        NoBuiltInCrypto_=false; |         bool                        NoBuiltInCrypto_=false; | ||||||
|         Poco::JWT::Signer	        Signer_; |         Poco::JWT::Signer	        Signer_; | ||||||
| 		Poco::Logger				&Logger_; | 		Poco::Logger				&Logger_; | ||||||
| 		Poco::ThreadPool				TimerPool_{"timer:pool",2,16}; |  | ||||||
| 		std::unique_ptr<BusEventManager>	BusEventManager_; |  | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
| 	inline void MicroService::Exit(int Reason) { | 	inline void MicroService::Exit(int Reason) { | ||||||
| @@ -3493,7 +3416,7 @@ namespace OpenWifi { | |||||||
| 	        } | 	        } | ||||||
|  |  | ||||||
| 	    } catch (const Poco::Exception &E) { | 	    } catch (const Poco::Exception &E) { | ||||||
| 	        logger().log(E); | 	        Logger_.log(E); | ||||||
| 	    } | 	    } | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -3562,7 +3485,7 @@ namespace OpenWifi { | |||||||
| 	    MyPrivateEndPoint_ = ConfigGetString("openwifi.system.uri.private"); | 	    MyPrivateEndPoint_ = ConfigGetString("openwifi.system.uri.private"); | ||||||
| 	    MyPublicEndPoint_ = ConfigGetString("openwifi.system.uri.public"); | 	    MyPublicEndPoint_ = ConfigGetString("openwifi.system.uri.public"); | ||||||
| 	    UIURI_ = ConfigGetString("openwifi.system.uri.ui"); | 	    UIURI_ = ConfigGetString("openwifi.system.uri.ui"); | ||||||
| 	    MyHash_ = Utils::ComputeHash(MyPublicEndPoint_); | 	    MyHash_ = CreateHash(MyPublicEndPoint_); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	void MicroServicePostInitialization(); | 	void MicroServicePostInitialization(); | ||||||
| @@ -3625,6 +3548,8 @@ namespace OpenWifi { | |||||||
|     void DaemonPostInitialization(Poco::Util::Application &self); |     void DaemonPostInitialization(Poco::Util::Application &self); | ||||||
|  |  | ||||||
| 	inline void MicroService::initialize(Poco::Util::Application &self) { | 	inline void MicroService::initialize(Poco::Util::Application &self) { | ||||||
|  | 		// Utils::SetThreadName("microservice"); | ||||||
|  |  | ||||||
| 		// add the default services | 		// add the default services | ||||||
|         LoadConfigurationFile(); |         LoadConfigurationFile(); | ||||||
|         InitializeLoggingSystem(); |         InitializeLoggingSystem(); | ||||||
| @@ -3633,9 +3558,7 @@ namespace OpenWifi { | |||||||
| 	    SubSystems_.push_back(ALBHealthCheckServer()); | 	    SubSystems_.push_back(ALBHealthCheckServer()); | ||||||
| 	    SubSystems_.push_back(RESTAPI_ExtServer()); | 	    SubSystems_.push_back(RESTAPI_ExtServer()); | ||||||
| 	    SubSystems_.push_back(RESTAPI_IntServer()); | 	    SubSystems_.push_back(RESTAPI_IntServer()); | ||||||
| #ifndef TIP_SECURITY_SERVICE |  | ||||||
| 		SubSystems_.push_back(AuthClient()); |  | ||||||
| #endif |  | ||||||
| 	    Poco::Net::initializeSSL(); | 	    Poco::Net::initializeSSL(); | ||||||
| 	    Poco::Net::HTTPStreamFactory::registerFactory(); | 	    Poco::Net::HTTPStreamFactory::registerFactory(); | ||||||
| 	    Poco::Net::HTTPSStreamFactory::registerFactory(); | 	    Poco::Net::HTTPSStreamFactory::registerFactory(); | ||||||
| @@ -3746,23 +3669,21 @@ namespace OpenWifi { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	inline void MicroService::InitializeSubSystemServers() { | 	inline void MicroService::InitializeSubSystemServers() { | ||||||
| 	    for(auto i:SubSystems_) { | 	    for(auto i:SubSystems_) | ||||||
| 	        addSubsystem(i); | 	        addSubsystem(i); | ||||||
| 	} | 	} | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	inline void MicroService::StartSubSystemServers() { | 	inline void MicroService::StartSubSystemServers() { | ||||||
|         AddActivity("Starting"); |         AddActivity("Starting"); | ||||||
| 	    for(auto i:SubSystems_) { | 	    for(auto i:SubSystems_) { | ||||||
| 	        i->Start(); | 	        i->Start(); | ||||||
| 	    } | 	    } | ||||||
| 		BusEventManager_ = std::make_unique<BusEventManager>(Poco::Logger::create("BusEventManager",Poco::Logger::root().getChannel(),Poco::Logger::root().getLevel())); | 	    BusEventManager_.Start(); | ||||||
| 	    BusEventManager_->Start(); |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	inline void MicroService::StopSubSystemServers() { | 	inline void MicroService::StopSubSystemServers() { | ||||||
|         AddActivity("Stopping"); |         AddActivity("Stopping"); | ||||||
| 	    BusEventManager_->Stop(); | 	    BusEventManager_.Stop(); | ||||||
| 	    for(auto i=SubSystems_.rbegin(); i!=SubSystems_.rend(); ++i) { | 	    for(auto i=SubSystems_.rbegin(); i!=SubSystems_.rend(); ++i) { | ||||||
| 			(*i)->Stop(); | 			(*i)->Stop(); | ||||||
| 		} | 		} | ||||||
| @@ -3903,6 +3824,11 @@ namespace OpenWifi { | |||||||
| 	    return Cipher_->decryptString(S, Poco::Crypto::Cipher::Cipher::ENC_BASE64);; | 	    return Cipher_->decryptString(S, Poco::Crypto::Cipher::Cipher::ENC_BASE64);; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	inline std::string MicroService::CreateHash(const std::string &S) { | ||||||
|  | 	    SHA2_.update(S); | ||||||
|  | 	    return Utils::ToHex(SHA2_.digest()); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	inline std::string MicroService::MakeSystemEventMessage( const std::string & Type ) const { | 	inline std::string MicroService::MakeSystemEventMessage( const std::string & Type ) const { | ||||||
| 	    Poco::JSON::Object	Obj; | 	    Poco::JSON::Object	Obj; | ||||||
| 	    Obj.set(KafkaTopics::ServiceEvents::Fields::EVENT,Type); | 	    Obj.set(KafkaTopics::ServiceEvents::Fields::EVENT,Type); | ||||||
| @@ -3939,15 +3865,14 @@ namespace OpenWifi { | |||||||
| 	    } | 	    } | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|     inline SubSystemServer::SubSystemServer(const std::string &Name, const std::string &LoggingPrefix, |     inline SubSystemServer::SubSystemServer(std::string Name, const std::string &LoggingPrefix, | ||||||
|             const std::string &SubSystemConfigPrefix): |             std::string SubSystemConfigPrefix): | ||||||
| 		Name_(Name), |         Name_(std::move(Name)), | ||||||
|         LoggerPrefix_(LoggingPrefix), |         LoggerPrefix_(LoggingPrefix), | ||||||
| 		SubSystemConfigPrefix_(SubSystemConfigPrefix) { |         SubSystemConfigPrefix_(std::move(SubSystemConfigPrefix)) { | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     inline int RESTAPI_ExtServer::Start() { |     inline int RESTAPI_ExtServer::Start() { | ||||||
| 		Logger().information("Starting."); |  | ||||||
|         Server_.InitLogging(); |         Server_.InitLogging(); | ||||||
|  |  | ||||||
|         for(const auto & Svr: ConfigServersList_) { |         for(const auto & Svr: ConfigServersList_) { | ||||||
| @@ -3966,7 +3891,6 @@ namespace OpenWifi { | |||||||
|             Params->setMaxThreads(50); |             Params->setMaxThreads(50); | ||||||
|             Params->setMaxQueued(200); |             Params->setMaxQueued(200); | ||||||
|             Params->setKeepAlive(true); |             Params->setKeepAlive(true); | ||||||
| 			Params->setName("ws:xrest"); |  | ||||||
|  |  | ||||||
|             std::unique_ptr<Poco::Net::HTTPServer>  NewServer; |             std::unique_ptr<Poco::Net::HTTPServer>  NewServer; | ||||||
|             if(MicroService::instance().NoAPISecurity()) { |             if(MicroService::instance().NoAPISecurity()) { | ||||||
| @@ -3979,6 +3903,7 @@ namespace OpenWifi { | |||||||
|             NewServer->start(); |             NewServer->start(); | ||||||
|             RESTServers_.push_back(std::move(NewServer)); |             RESTServers_.push_back(std::move(NewServer)); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         return 0; |         return 0; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -4002,7 +3927,6 @@ namespace OpenWifi { | |||||||
|             Params->setMaxThreads(50); |             Params->setMaxThreads(50); | ||||||
|             Params->setMaxQueued(200); |             Params->setMaxQueued(200); | ||||||
|             Params->setKeepAlive(true); |             Params->setKeepAlive(true); | ||||||
| 			Params->setName("ws:irest"); |  | ||||||
|  |  | ||||||
|             std::unique_ptr<Poco::Net::HTTPServer>  NewServer; |             std::unique_ptr<Poco::Net::HTTPServer>  NewServer; | ||||||
|             if(MicroService::instance().NoAPISecurity()) { |             if(MicroService::instance().NoAPISecurity()) { | ||||||
| @@ -4020,6 +3944,8 @@ namespace OpenWifi { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     inline int MicroService::main([[maybe_unused]] const ArgVec &args) { |     inline int MicroService::main([[maybe_unused]] const ArgVec &args) { | ||||||
|  |  | ||||||
|  | 		// Utils::SetThreadName("main"); | ||||||
| 	    MyErrorHandler	ErrorHandler(*this); | 	    MyErrorHandler	ErrorHandler(*this); | ||||||
| 	    Poco::ErrorHandler::set(&ErrorHandler); | 	    Poco::ErrorHandler::set(&ErrorHandler); | ||||||
|  |  | ||||||
| @@ -4068,11 +3994,7 @@ namespace OpenWifi { | |||||||
| 	    auto i = 0; | 	    auto i = 0; | ||||||
| 	    bool good = true; | 	    bool good = true; | ||||||
|  |  | ||||||
| 		auto NewLevel = MicroService::instance().ConfigGetString("logging.level." + Name_, ""); |         Log_ = std::make_unique<LoggerWrapper>(Poco::Logger::get(LoggerPrefix_)); | ||||||
| 		if(NewLevel.empty()) |  | ||||||
|         	Logger_ = std::make_unique<LoggerWrapper>(Poco::Logger::create(LoggerPrefix_, Poco::Logger::root().getChannel(), Poco::Logger::root().getLevel())); |  | ||||||
| 		else |  | ||||||
| 			Logger_ = std::make_unique<LoggerWrapper>(Poco::Logger::create(LoggerPrefix_, Poco::Logger::root().getChannel(), Poco::Logger::parseLevel(NewLevel))); |  | ||||||
|  |  | ||||||
| 	    ConfigServersList_.clear(); | 	    ConfigServersList_.clear(); | ||||||
| 	    while (good) { | 	    while (good) { | ||||||
| @@ -4130,7 +4052,6 @@ namespace OpenWifi { | |||||||
| 	        Port_ = (int)MicroService::instance().ConfigGetInt("alb.port",15015); | 	        Port_ = (int)MicroService::instance().ConfigGetInt("alb.port",15015); | ||||||
| 	        Socket_ = std::make_unique<Poco::Net::ServerSocket>(Port_); | 	        Socket_ = std::make_unique<Poco::Net::ServerSocket>(Port_); | ||||||
| 	        auto Params = new Poco::Net::HTTPServerParams; | 	        auto Params = new Poco::Net::HTTPServerParams; | ||||||
| 			Params->setName("ws:alb"); |  | ||||||
| 	        Server_ = std::make_unique<Poco::Net::HTTPServer>(new ALBRequestHandlerFactory(Logger()), *Socket_, Params); | 	        Server_ = std::make_unique<Poco::Net::HTTPServer>(new ALBRequestHandlerFactory(Logger()), *Socket_, Params); | ||||||
| 	        Server_->start(); | 	        Server_->start(); | ||||||
| 	    } | 	    } | ||||||
| @@ -4140,7 +4061,7 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|     inline void BusEventManager::run() { |     inline void BusEventManager::run() { | ||||||
|         Running_ = true; |         Running_ = true; | ||||||
| 		Utils::SetThreadName("fmwk:EventMgr"); | 		Utils::SetThreadName("BusEventManager"); | ||||||
|         auto Msg = MicroService::instance().MakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_JOIN); |         auto Msg = MicroService::instance().MakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_JOIN); | ||||||
|         KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,MicroService::instance().PrivateEndPoint(),Msg, false); |         KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,MicroService::instance().PrivateEndPoint(),Msg, false); | ||||||
|         while(Running_) { |         while(Running_) { | ||||||
| @@ -4162,11 +4083,9 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|     inline void BusEventManager::Stop() { |     inline void BusEventManager::Stop() { | ||||||
|         if(KafkaManager()->Enabled()) { |         if(KafkaManager()->Enabled()) { | ||||||
| 			poco_information(Logger(),"Stopping..."); |  | ||||||
|             Running_ = false; |             Running_ = false; | ||||||
|             Thread_.wakeUp(); |             Thread_.wakeUp(); | ||||||
|             Thread_.join(); |             Thread_.join(); | ||||||
| 			poco_information(Logger(),"Stopped..."); |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -4178,37 +4097,37 @@ namespace OpenWifi { | |||||||
| 	inline void KafkaLoggerFun([[maybe_unused]] cppkafka::KafkaHandleBase & handle, int level, const std::string & facility, const std::string &message) { | 	inline void KafkaLoggerFun([[maybe_unused]] cppkafka::KafkaHandleBase & handle, int level, const std::string & facility, const std::string &message) { | ||||||
| 		switch ((cppkafka::LogLevel) level) { | 		switch ((cppkafka::LogLevel) level) { | ||||||
| 			case cppkafka::LogLevel::LogNotice: { | 			case cppkafka::LogLevel::LogNotice: { | ||||||
| 					poco_notice(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message)); | 					KafkaManager()->Logger().notice(fmt::format("kafka-log: facility: {} message: {}",facility, message)); | ||||||
| 				} | 				} | ||||||
| 				break; | 				break; | ||||||
| 			case cppkafka::LogLevel::LogDebug: { | 			case cppkafka::LogLevel::LogDebug: { | ||||||
| 					poco_debug(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message)); | 					KafkaManager()->Logger().debug(fmt::format("kafka-log: facility: {} message: {}",facility, message)); | ||||||
| 				} | 				} | ||||||
| 				break; | 				break; | ||||||
| 			case cppkafka::LogLevel::LogInfo: { | 			case cppkafka::LogLevel::LogInfo: { | ||||||
| 					poco_information(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message)); | 					KafkaManager()->Logger().information(fmt::format("kafka-log: facility: {} message: {}",facility, message)); | ||||||
| 				} | 				} | ||||||
| 				break; | 				break; | ||||||
| 				case cppkafka::LogLevel::LogWarning: { | 				case cppkafka::LogLevel::LogWarning: { | ||||||
| 					poco_warning(KafkaManager()->Logger(), fmt::format("kafka-log: facility: {} message: {}",facility, message)); | 					KafkaManager()->Logger().warning(fmt::format("kafka-log: facility: {} message: {}",facility, message)); | ||||||
| 				} | 				} | ||||||
| 				break; | 				break; | ||||||
| 			case cppkafka::LogLevel::LogAlert: | 			case cppkafka::LogLevel::LogAlert: | ||||||
| 			case cppkafka::LogLevel::LogCrit: { | 			case cppkafka::LogLevel::LogCrit: { | ||||||
| 					poco_critical(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message)); | 					KafkaManager()->Logger().critical(fmt::format("kafka-log: facility: {} message: {}",facility, message)); | ||||||
| 				} | 				} | ||||||
| 				break; | 				break; | ||||||
| 			case cppkafka::LogLevel::LogErr: | 			case cppkafka::LogLevel::LogErr: | ||||||
| 			case cppkafka::LogLevel::LogEmerg: | 			case cppkafka::LogLevel::LogEmerg: | ||||||
| 			default: { | 			default: { | ||||||
| 					poco_error(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message)); | 				KafkaManager()->Logger().error(fmt::format("kafka-log: facility: {} message: {}",facility, message)); | ||||||
| 				} | 				} | ||||||
| 				break; | 				break; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	inline void KafkaErrorFun([[maybe_unused]] cppkafka::KafkaHandleBase & handle, int error, const std::string &reason) { | 	inline void KafkaErrorFun([[maybe_unused]] cppkafka::KafkaHandleBase & handle, int error, const std::string &reason) { | ||||||
| 		poco_error(KafkaManager()->Logger(),fmt::format("kafka-error: {}, reason: {}", error, reason)); | 		KafkaManager()->Logger().error(fmt::format("kafka-error: {}, reason: {}", error, reason)); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	inline void AddKafkaSecurity(cppkafka::Configuration & Config) { | 	inline void AddKafkaSecurity(cppkafka::Configuration & Config) { | ||||||
| @@ -4229,7 +4148,7 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
| 	inline void KafkaProducer::run() { | 	inline void KafkaProducer::run() { | ||||||
|  |  | ||||||
| 		Utils::SetThreadName("Kafka:Prod"); | 		Utils::SetThreadName("KafkaProducer"); | ||||||
| 	    cppkafka::Configuration Config({ | 	    cppkafka::Configuration Config({ | ||||||
|             { "client.id", MicroService::instance().ConfigGetString("openwifi.kafka.client.id") }, |             { "client.id", MicroService::instance().ConfigGetString("openwifi.kafka.client.id") }, | ||||||
|             { "metadata.broker.list", MicroService::instance().ConfigGetString("openwifi.kafka.brokerlist") } |             { "metadata.broker.list", MicroService::instance().ConfigGetString("openwifi.kafka.brokerlist") } | ||||||
| @@ -4257,18 +4176,18 @@ namespace OpenWifi { | |||||||
|                             cppkafka::MessageBuilder(Msg->Topic()).key(Msg->Key()).payload(Msg->Payload())); |                             cppkafka::MessageBuilder(Msg->Topic()).key(Msg->Key()).payload(Msg->Payload())); | ||||||
|                 } |                 } | ||||||
|             } catch (const cppkafka::HandleException &E) { |             } catch (const cppkafka::HandleException &E) { | ||||||
| 				poco_warning(KafkaManager()->Logger(),fmt::format("Caught a Kafka exception (producer): {}", E.what())); |                 KafkaManager()->Logger().warning(fmt::format("Caught a Kafka exception (producer): {}", E.what())); | ||||||
|             } catch( const Poco::Exception &E) { |             } catch( const Poco::Exception &E) { | ||||||
|                 KafkaManager()->Logger().log(E); |                 KafkaManager()->Logger().log(E); | ||||||
|             } catch (...) { |             } catch (...) { | ||||||
| 				poco_error(KafkaManager()->Logger(),"std::exception"); |                 KafkaManager()->Logger().error("std::exception"); | ||||||
|             } |             } | ||||||
| 			Note = Queue_.waitDequeueNotification(); | 			Note = Queue_.waitDequeueNotification(); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	inline void KafkaConsumer::run() { | 	inline void KafkaConsumer::run() { | ||||||
| 		Utils::SetThreadName("Kafka:Cons"); | 		Utils::SetThreadName("KafkaConsumer"); | ||||||
|  |  | ||||||
| 	    cppkafka::Configuration Config({ | 	    cppkafka::Configuration Config({ | ||||||
| 	        { "client.id", MicroService::instance().ConfigGetString("openwifi.kafka.client.id") }, | 	        { "client.id", MicroService::instance().ConfigGetString("openwifi.kafka.client.id") }, | ||||||
| @@ -4321,7 +4240,7 @@ namespace OpenWifi { | |||||||
| 	                    continue; | 	                    continue; | ||||||
| 	                if (Msg.get_error()) { | 	                if (Msg.get_error()) { | ||||||
| 	                    if (!Msg.is_eof()) { | 	                    if (!Msg.is_eof()) { | ||||||
| 							poco_error(KafkaManager()->Logger(),fmt::format("Error: {}", Msg.get_error().to_string())); | 	                        KafkaManager()->Logger().error(fmt::format("Error: {}", Msg.get_error().to_string())); | ||||||
| 	                    } | 	                    } | ||||||
|                         if(!AutoCommit) |                         if(!AutoCommit) | ||||||
| 	                        Consumer.async_commit(Msg); | 	                        Consumer.async_commit(Msg); | ||||||
| @@ -4332,11 +4251,11 @@ namespace OpenWifi { | |||||||
| 	                    Consumer.async_commit(Msg); | 	                    Consumer.async_commit(Msg); | ||||||
| 	            } | 	            } | ||||||
| 	        } catch (const cppkafka::HandleException &E) { | 	        } catch (const cppkafka::HandleException &E) { | ||||||
| 				poco_warning(KafkaManager()->Logger(),fmt::format("Caught a Kafka exception (consumer): {}", E.what())); | 	            KafkaManager()->Logger().warning(fmt::format("Caught a Kafka exception (consumer): {}", E.what())); | ||||||
| 	        } catch (const Poco::Exception &E) { | 	        } catch (const Poco::Exception &E) { | ||||||
| 	            KafkaManager()->Logger().log(E); | 	            KafkaManager()->Logger().log(E); | ||||||
|             } catch (...) { |             } catch (...) { | ||||||
| 				poco_error(KafkaManager()->Logger(),"std::exception"); |                 KafkaManager()->Logger().error("std::exception"); | ||||||
|             } |             } | ||||||
| 	    } | 	    } | ||||||
| 	    Consumer.unsubscribe(); | 	    Consumer.unsubscribe(); | ||||||
| @@ -4408,11 +4327,6 @@ namespace OpenWifi { | |||||||
| 	            Answer.set("certificates", Certificates); | 	            Answer.set("certificates", Certificates); | ||||||
| 	            return ReturnObject(Answer); | 	            return ReturnObject(Answer); | ||||||
| 	        } | 	        } | ||||||
|             if(GetBoolParameter("extraConfiguration")) { |  | ||||||
|                 Poco::JSON::Object  Answer; |  | ||||||
|                 MicroService::instance().GetExtraConfiguration(Answer); |  | ||||||
|                 return ReturnObject(Answer); |  | ||||||
|             } |  | ||||||
| 	        BadRequest(RESTAPI::Errors::InvalidCommand); | 	        BadRequest(RESTAPI::Errors::InvalidCommand); | ||||||
| 	    } | 	    } | ||||||
|  |  | ||||||
| @@ -4780,27 +4694,22 @@ namespace OpenWifi { | |||||||
|     } |     } | ||||||
|  |  | ||||||
| #ifdef    TIP_SECURITY_SERVICE | #ifdef    TIP_SECURITY_SERVICE | ||||||
|     [[nodiscard]] bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, std::uint64_t TID, bool & Expired , bool Sub ); |     [[nodiscard]] bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired , bool Sub ); | ||||||
| #endif | #endif | ||||||
|     inline bool RESTAPIHandler::IsAuthorized( bool & Expired , [[maybe_unused]] bool & Contacted , bool Sub ) { |     inline bool RESTAPIHandler::IsAuthorized( bool & Expired , [[maybe_unused]] bool & Contacted , bool Sub ) { | ||||||
|         if(Internal_ && Request->has("X-INTERNAL-NAME")) { |         if(Internal_ && Request->has("X-INTERNAL-NAME")) { | ||||||
|             auto Allowed = MicroService::instance().IsValidAPIKEY(*Request); |             auto Allowed = MicroService::instance().IsValidAPIKEY(*Request); | ||||||
| 			Contacted = true; |  | ||||||
|             if(!Allowed) { |             if(!Allowed) { | ||||||
|                 if(Server_.LogBadTokens(false)) { |                 if(Server_.LogBadTokens(false)) { | ||||||
|                     poco_debug(Logger_,fmt::format("I-REQ-DENIED({}): TID={} Method={} Path={}", |                     Logger_.debug(fmt::format("I-REQ-DENIED({}): Method={} Path={}", | ||||||
|                                                Utils::FormatIPv6(Request->clientAddress().toString()), |                                                Utils::FormatIPv6(Request->clientAddress().toString()), | ||||||
| 						TransactionId_, |  | ||||||
|                                                Request->getMethod(), Request->getURI())); |                                                Request->getMethod(), Request->getURI())); | ||||||
|                 } |                 } | ||||||
|             } else { |             } else { | ||||||
|                 auto Id = Request->get("X-INTERNAL-NAME", "unknown"); |                 auto Id = Request->get("X-INTERNAL-NAME", "unknown"); | ||||||
| 				REST_Requester_ = Id; |  | ||||||
|                 if(Server_.LogIt(Request->getMethod(),true)) { |                 if(Server_.LogIt(Request->getMethod(),true)) { | ||||||
| 					poco_debug(Logger_,fmt::format("I-REQ-ALLOWED({}): TID={} User='{}' Method={} Path={}", |                     Logger_.debug(fmt::format("I-REQ-ALLOWED({}): User='{}' Method={} Path={}", | ||||||
| 						Utils::FormatIPv6(Request->clientAddress().toString()), |                                                Utils::FormatIPv6(Request->clientAddress().toString()), Id, | ||||||
| 						TransactionId_, |  | ||||||
| 						Id, |  | ||||||
|                                                Request->getMethod(), Request->getURI())); |                                                Request->getMethod(), Request->getURI())); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| @@ -4817,15 +4726,13 @@ namespace OpenWifi { | |||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| #ifdef    TIP_SECURITY_SERVICE | #ifdef    TIP_SECURITY_SERVICE | ||||||
|             if (AuthServiceIsAuthorized(*Request, SessionToken_, UserInfo_, TransactionId_, Expired, Sub)) { |             if (AuthServiceIsAuthorized(*Request, SessionToken_, UserInfo_, Expired, Sub)) { | ||||||
| #else | #else | ||||||
|             if (AuthClient()->IsAuthorized( SessionToken_, UserInfo_, TransactionId_, Expired, Contacted, Sub)) { |             if (AuthClient()->IsAuthorized( SessionToken_, UserInfo_, Expired, Contacted, Sub)) { | ||||||
| #endif | #endif | ||||||
| 				REST_Requester_ = UserInfo_.userinfo.email; |  | ||||||
|                 if(Server_.LogIt(Request->getMethod(),true)) { |                 if(Server_.LogIt(Request->getMethod(),true)) { | ||||||
| 					poco_debug(Logger_,fmt::format("X-REQ-ALLOWED({}): TID={} User='{}@{}' Method={} Path={}", |                     Logger_.debug(fmt::format("X-REQ-ALLOWED({}): User='{}@{}' Method={} Path={}", | ||||||
|                                                UserInfo_.userinfo.email, |                                                UserInfo_.userinfo.email, | ||||||
| 						TransactionId_, |  | ||||||
|                                                Utils::FormatIPv6(Request->clientAddress().toString()), |                                                Utils::FormatIPv6(Request->clientAddress().toString()), | ||||||
|                                                Request->clientAddress().toString(), |                                                Request->clientAddress().toString(), | ||||||
|                                                Request->getMethod(), |                                                Request->getMethod(), | ||||||
| @@ -4834,11 +4741,9 @@ namespace OpenWifi { | |||||||
|                 return true; |                 return true; | ||||||
|             } else { |             } else { | ||||||
|                 if(Server_.LogBadTokens(true)) { |                 if(Server_.LogBadTokens(true)) { | ||||||
| 					poco_debug(Logger_,fmt::format("X-REQ-DENIED({}): TID={} Method={} Path={}", |                     Logger_.debug(fmt::format("X-REQ-DENIED({}): Method={} Path={}", | ||||||
|                                                Utils::FormatIPv6(Request->clientAddress().toString()), |                                                Utils::FormatIPv6(Request->clientAddress().toString()), | ||||||
| 						TransactionId_, |                                                Request->getMethod(), Request->getURI())); | ||||||
| 						Request->getMethod(), |  | ||||||
| 						Request->getURI())); |  | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             return false; |             return false; | ||||||
| @@ -4907,7 +4812,7 @@ namespace OpenWifi { | |||||||
|         void run() override; |         void run() override; | ||||||
|         // MyParallelSocketReactor &ReactorPool(); |         // MyParallelSocketReactor &ReactorPool(); | ||||||
| 		Poco::Net::SocketReactor & Reactor() { return Reactor_; } | 		Poco::Net::SocketReactor & Reactor() { return Reactor_; } | ||||||
|         void NewClient(Poco::Net::WebSocket &WS, const std::string &Id, const std::string &UserName); |         void NewClient(Poco::Net::WebSocket &WS, const std::string &Id); | ||||||
|         bool Register(WebSocketClient *Client, const std::string &Id); |         bool Register(WebSocketClient *Client, const std::string &Id); | ||||||
|         void SetProcessor(WebSocketClientProcessor *F); |         void SetProcessor(WebSocketClientProcessor *F); | ||||||
|         void UnRegister(const std::string &Id); |         void UnRegister(const std::string &Id); | ||||||
| @@ -4958,10 +4863,7 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|     class WebSocketClient { |     class WebSocketClient { | ||||||
|     public: |     public: | ||||||
|         explicit WebSocketClient(Poco::Net::WebSocket &WS, |         explicit WebSocketClient(Poco::Net::WebSocket &WS, const std::string &Id, Poco::Logger &L, | ||||||
| 							   		const std::string &Id, |  | ||||||
| 							   		const std::string &UserName, |  | ||||||
| 							   		Poco::Logger &L, |  | ||||||
|                                  WebSocketClientProcessor *Processor); |                                  WebSocketClientProcessor *Processor); | ||||||
|         virtual ~WebSocketClient(); |         virtual ~WebSocketClient(); | ||||||
|         [[nodiscard]] inline const std::string &Id(); |         [[nodiscard]] inline const std::string &Id(); | ||||||
| @@ -4971,9 +4873,8 @@ namespace OpenWifi { | |||||||
|         std::unique_ptr<Poco::Net::WebSocket> WS_; |         std::unique_ptr<Poco::Net::WebSocket> WS_; | ||||||
|         Poco::Net::SocketReactor &Reactor_; |         Poco::Net::SocketReactor &Reactor_; | ||||||
|         std::string Id_; |         std::string Id_; | ||||||
| 		std::string					UserName_; |  | ||||||
|         Poco::Logger &Logger_; |         Poco::Logger &Logger_; | ||||||
|         std::atomic_bool 			Authenticated_ = false; |         bool Authenticated_ = false; | ||||||
|         SecurityObjects::UserInfoAndPolicy UserInfo_; |         SecurityObjects::UserInfoAndPolicy UserInfo_; | ||||||
|         WebSocketClientProcessor *Processor_ = nullptr; |         WebSocketClientProcessor *Processor_ = nullptr; | ||||||
|         void OnSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf); |         void OnSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf); | ||||||
| @@ -4981,9 +4882,33 @@ namespace OpenWifi { | |||||||
|         void OnSocketError(const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf); |         void OnSocketError(const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf); | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     inline void WebSocketClientServer::NewClient(Poco::Net::WebSocket & WS, const std::string &Id, const std::string &UserName ) { | /*    inline MyParallelSocketReactor::MyParallelSocketReactor(uint32_t NumReactors) : | ||||||
|  |             NumReactors_(NumReactors) | ||||||
|  |     { | ||||||
|  |         Reactors_ = new Poco::Net::SocketReactor[NumReactors_]; | ||||||
|  |         for(uint32_t i=0;i<NumReactors_;i++) { | ||||||
|  |             ReactorPool_.start(Reactors_[i]); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     inline MyParallelSocketReactor::~MyParallelSocketReactor() { | ||||||
|  |         for(uint32_t i=0;i<NumReactors_;i++) { | ||||||
|  |             Reactors_[i].stop(); | ||||||
|  |         } | ||||||
|  |         ReactorPool_.stopAll(); | ||||||
|  |         ReactorPool_.joinAll(); | ||||||
|  |         delete [] Reactors_; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     inline Poco::Net::SocketReactor & MyParallelSocketReactor::Reactor() { | ||||||
|  |         return Reactors_[ rand() % NumReactors_ ]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // inline MyParallelSocketReactor & WebSocketClientServer::ReactorPool() { return *ReactorPool_; } | ||||||
|  | */ | ||||||
|  |     inline void WebSocketClientServer::NewClient(Poco::Net::WebSocket & WS, const std::string &Id) { | ||||||
|         std::lock_guard G(Mutex_); |         std::lock_guard G(Mutex_); | ||||||
|         auto Client = new WebSocketClient(WS,Id,UserName,Logger(), Processor_); |         auto Client = new WebSocketClient(WS,Id,Logger(), Processor_); | ||||||
|         Clients_[Id] = std::make_pair(Client,""); |         Clients_[Id] = std::make_pair(Client,""); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -5013,13 +4938,13 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|     [[nodiscard]] inline bool SendToUser(const std::string &userName, const std::string &Payload); |     [[nodiscard]] inline bool SendToUser(const std::string &userName, const std::string &Payload); | ||||||
|     inline WebSocketClientServer::WebSocketClientServer() noexcept: |     inline WebSocketClientServer::WebSocketClientServer() noexcept: | ||||||
|             SubSystemServer("WebSocketClientServer", "UI-WSCLNT-SVR", "websocketclients") |             SubSystemServer("WebSocketClientServer", "WSCLNT-SVR", "websocketclients") | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     inline void WebSocketClientServer::run() { |     inline void WebSocketClientServer::run() { | ||||||
|         Running_ = true ; |         Running_ = true ; | ||||||
| 		Utils::SetThreadName("ws:uiclnt-svr"); | 		Utils::SetThreadName("ws:clnt-svr"); | ||||||
|         while(Running_) { |         while(Running_) { | ||||||
|             Poco::Thread::trySleep(2000); |             Poco::Thread::trySleep(2000); | ||||||
|  |  | ||||||
| @@ -5100,7 +5025,6 @@ namespace OpenWifi { | |||||||
| 			auto Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK; | 			auto Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK; | ||||||
|  |  | ||||||
| 			if (n == 0) { | 			if (n == 0) { | ||||||
| 				poco_warning(Logger(),Poco::format("CLOSE(%s): %s UI Client is closing WS connection.", Id_, UserName_)); |  | ||||||
| 				return delete this; | 				return delete this; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| @@ -5113,7 +5037,7 @@ namespace OpenWifi { | |||||||
| 			case Poco::Net::WebSocket::FRAME_OP_PONG: { | 			case Poco::Net::WebSocket::FRAME_OP_PONG: { | ||||||
| 			} break; | 			} break; | ||||||
| 			case Poco::Net::WebSocket::FRAME_OP_CLOSE: { | 			case Poco::Net::WebSocket::FRAME_OP_CLOSE: { | ||||||
| 				poco_warning(Logger(),Poco::format("CLOSE(%s): %s UI Client is closing WS connection.", Id_, UserName_)); | 				Logger().warning(Poco::format("CLOSE(%s): Client is closing its connection.", Id_)); | ||||||
| 				Done = true; | 				Done = true; | ||||||
| 			} break; | 			} break; | ||||||
| 			case Poco::Net::WebSocket::FRAME_OP_TEXT: { | 			case Poco::Net::WebSocket::FRAME_OP_TEXT: { | ||||||
| @@ -5123,10 +5047,8 @@ namespace OpenWifi { | |||||||
| 					auto Tokens = Utils::Split(Frame, ':'); | 					auto Tokens = Utils::Split(Frame, ':'); | ||||||
| 					bool Expired = false, Contacted = false; | 					bool Expired = false, Contacted = false; | ||||||
| 					if (Tokens.size() == 2 && | 					if (Tokens.size() == 2 && | ||||||
| 						AuthClient()->IsAuthorized(Tokens[1], UserInfo_, 0, Expired, Contacted)) { | 						AuthClient()->IsAuthorized(Tokens[1], UserInfo_, Expired, Contacted)) { | ||||||
| 						Authenticated_ = true; | 						Authenticated_ = true; | ||||||
| 						UserName_ = UserInfo_.userinfo.email; |  | ||||||
| 						poco_warning(Logger(),Poco::format("START(%s): %s UI Client is starting WS connection.", Id_, UserName_)); |  | ||||||
| 						std::string S{"Welcome! Bienvenue! Bienvenidos!"}; | 						std::string S{"Welcome! Bienvenue! Bienvenidos!"}; | ||||||
| 						WS_->sendFrame(S.c_str(), S.size()); | 						WS_->sendFrame(S.c_str(), S.size()); | ||||||
| 						WebSocketClientServer()->SetUser(Id_, UserInfo_.userinfo.email); | 						WebSocketClientServer()->SetUser(Id_, UserInfo_.userinfo.email); | ||||||
| @@ -5172,10 +5094,9 @@ namespace OpenWifi { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|     inline WebSocketClient::WebSocketClient( Poco::Net::WebSocket & WS , const std::string &Id, const std::string &UserName, Poco::Logger & L, WebSocketClientProcessor * Processor) : |     inline WebSocketClient::WebSocketClient( Poco::Net::WebSocket & WS , const std::string &Id, Poco::Logger & L, WebSocketClientProcessor * Processor) : | ||||||
|             Reactor_(WebSocketClientServer()->Reactor()), |             Reactor_(WebSocketClientServer()->Reactor()), | ||||||
|             Id_(Id), |             Id_(Id), | ||||||
| 			UserName_(UserName), |  | ||||||
|             Logger_(L), |             Logger_(L), | ||||||
|             Processor_(Processor) { |             Processor_(Processor) { | ||||||
|         try { |         try { | ||||||
| @@ -5189,10 +5110,7 @@ namespace OpenWifi { | |||||||
|             Reactor_.addEventHandler(*WS_, |             Reactor_.addEventHandler(*WS_, | ||||||
|                                      Poco::NObserver<WebSocketClient, Poco::Net::ErrorNotification>( |                                      Poco::NObserver<WebSocketClient, Poco::Net::ErrorNotification>( | ||||||
|                                              *this, &WebSocketClient::OnSocketError)); |                                              *this, &WebSocketClient::OnSocketError)); | ||||||
| 			WS_->setNoDelay(true); |             // WebSocketClientServer()->Register(this, Id_); | ||||||
| 			WS_->setKeepAlive(true); |  | ||||||
| 			WS_->setBlocking(false); |  | ||||||
|  |  | ||||||
|         } catch (...) { |         } catch (...) { | ||||||
|             delete this; |             delete this; | ||||||
|         } |         } | ||||||
| @@ -5258,8 +5176,9 @@ namespace OpenWifi { | |||||||
|                 try |                 try | ||||||
|                 { |                 { | ||||||
|                     Poco::Net::WebSocket WS(*Request, *Response); |                     Poco::Net::WebSocket WS(*Request, *Response); | ||||||
|  |                     Logger().information("WebSocket connection established."); | ||||||
|                     auto Id = MicroService::CreateUUID(); |                     auto Id = MicroService::CreateUUID(); | ||||||
|                     WebSocketClientServer()->NewClient(WS,Id,UserInfo_.userinfo.email); |                     WebSocketClientServer()->NewClient(WS,Id); | ||||||
|                 } |                 } | ||||||
|                 catch (...) { |                 catch (...) { | ||||||
|                     std::cout << "Cannot create websocket client..." << std::endl; |                     std::cout << "Cannot create websocket client..." << std::endl; | ||||||
|   | |||||||
| @@ -33,6 +33,7 @@ namespace OpenWifi { | |||||||
|         int Start() override { |         int Start() override { | ||||||
|             std::lock_guard		Guard(Mutex_); |             std::lock_guard		Guard(Mutex_); | ||||||
|  |  | ||||||
|  |             Logger().setLevel(Poco::Message::PRIO_INFORMATION); | ||||||
|             Logger().notice("Starting."); |             Logger().notice("Starting."); | ||||||
|             std::string DBType = MicroService::instance().ConfigGetString("storage.type"); |             std::string DBType = MicroService::instance().ConfigGetString("storage.type"); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -146,10 +146,6 @@ namespace OpenWifi { | |||||||
|         WebSocketClientServer()->SendUserNotification(User,N); |         WebSocketClientServer()->SendUserNotification(User,N); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     ///// |  | ||||||
|     ///// |  | ||||||
|     ///// |  | ||||||
|  |  | ||||||
|     struct WebSocketNotificationRebootList { |     struct WebSocketNotificationRebootList { | ||||||
|         std::string                 title, |         std::string                 title, | ||||||
|                 details, |                 details, | ||||||
| @@ -193,58 +189,5 @@ namespace OpenWifi { | |||||||
|         WebSocketClientServer()->SendUserNotification(User,N); |         WebSocketClientServer()->SendUserNotification(User,N); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     ///// |  | ||||||
|     ///// |  | ||||||
|     ///// |  | ||||||
|  |  | ||||||
|     struct WebSocketNotificationUpgradeList { |  | ||||||
|         std::string                 title, |  | ||||||
|                 details, |  | ||||||
|                 jobId; |  | ||||||
|         std::vector<std::string>    success, |  | ||||||
|                                     skipped, |  | ||||||
|                                     no_firmware, |  | ||||||
|                                     not_connected; |  | ||||||
|         uint64_t                    timeStamp=OpenWifi::Now(); |  | ||||||
|  |  | ||||||
|         void to_json(Poco::JSON::Object &Obj) const; |  | ||||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     typedef WebSocketNotification<WebSocketNotificationUpgradeList> WebSocketClientNotificationVenueUpgradeList_t; |  | ||||||
|  |  | ||||||
|     inline void WebSocketNotificationUpgradeList::to_json(Poco::JSON::Object &Obj) const { |  | ||||||
|         RESTAPI_utils::field_to_json(Obj,"title",title); |  | ||||||
|         RESTAPI_utils::field_to_json(Obj,"jobId",jobId); |  | ||||||
|         RESTAPI_utils::field_to_json(Obj,"success",success); |  | ||||||
|         RESTAPI_utils::field_to_json(Obj,"notConnected",not_connected); |  | ||||||
|         RESTAPI_utils::field_to_json(Obj,"noFirmware",no_firmware); |  | ||||||
|         RESTAPI_utils::field_to_json(Obj,"skipped",skipped); |  | ||||||
|         RESTAPI_utils::field_to_json(Obj,"timeStamp",timeStamp); |  | ||||||
|         RESTAPI_utils::field_to_json(Obj,"details",details); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     inline bool WebSocketNotificationUpgradeList::from_json(const Poco::JSON::Object::Ptr &Obj) { |  | ||||||
|         try { |  | ||||||
|             RESTAPI_utils::field_from_json(Obj,"title",title); |  | ||||||
|             RESTAPI_utils::field_from_json(Obj,"jobId",jobId); |  | ||||||
|             RESTAPI_utils::field_from_json(Obj,"success",success); |  | ||||||
|             RESTAPI_utils::field_from_json(Obj,"notConnected",not_connected); |  | ||||||
|             RESTAPI_utils::field_from_json(Obj,"noFirmware",no_firmware); |  | ||||||
|             RESTAPI_utils::field_from_json(Obj,"skipped",skipped); |  | ||||||
|             RESTAPI_utils::field_from_json(Obj,"timeStamp",timeStamp); |  | ||||||
|             RESTAPI_utils::field_from_json(Obj,"details",details); |  | ||||||
|             return true; |  | ||||||
|         } catch(...) { |  | ||||||
|  |  | ||||||
|         } |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     inline void WebSocketClientNotificationVenueUpgradeCompletionToUser( const std::string & User, WebSocketClientNotificationVenueUpgradeList_t &N) { |  | ||||||
|         N.type = "venue_upgrader"; |  | ||||||
|         WebSocketClientServer()->SendUserNotification(User,N); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| } // namespace OpenWifi | } // namespace OpenWifi | ||||||
|  |  | ||||||
|   | |||||||
| @@ -196,8 +196,6 @@ namespace OpenWifi::RESTAPI::Errors { | |||||||
| 	static const struct msg InvalidRadiusServerEntry{1142,"RADIUS Server IP address invalid or port missing."}; | 	static const struct msg InvalidRadiusServerEntry{1142,"RADIUS Server IP address invalid or port missing."}; | ||||||
| 	static const struct msg InvalidRadiusServerWeigth{1143,"RADIUS Server IP weight cannot be 0."}; | 	static const struct msg InvalidRadiusServerWeigth{1143,"RADIUS Server IP weight cannot be 0."}; | ||||||
|  |  | ||||||
| 	static const struct msg MaximumRTTYSessionsReached{1144,"Too many RTTY sessions currently active"}; |  | ||||||
| 	static const struct msg DeviceIsAlreadyBusy{1145,"Device is already executing a command. Please try later."}; |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -430,7 +428,6 @@ namespace OpenWifi::uCentralProtocol { | |||||||
| 	static const char *RADIUSDATA = "data"; | 	static const char *RADIUSDATA = "data"; | ||||||
| 	static const char *RADIUSACCT = "acct"; | 	static const char *RADIUSACCT = "acct"; | ||||||
| 	static const char *RADIUSAUTH = "auth"; | 	static const char *RADIUSAUTH = "auth"; | ||||||
| 	static const char *RADIUSCOA = "coa"; |  | ||||||
| 	static const char *RADIUSDST = "dst"; | 	static const char *RADIUSDST = "dst"; | ||||||
| 	static const char *IES = "ies"; | 	static const char *IES = "ies"; | ||||||
| 	} | 	} | ||||||
| @@ -447,7 +444,6 @@ namespace OpenWifi::uCentralProtocol::Events { | |||||||
|     static const char *RECOVERY = "recovery"; |     static const char *RECOVERY = "recovery"; | ||||||
|     static const char *TELEMETRY = "telemetry"; |     static const char *TELEMETRY = "telemetry"; | ||||||
|     static const char *DEVICEUPDATE = "deviceupdate"; |     static const char *DEVICEUPDATE = "deviceupdate"; | ||||||
| 	static const char *VENUE_BROADCAST = "venue_broadcast"; |  | ||||||
|  |  | ||||||
|     enum EVENT_MSG { |     enum EVENT_MSG { | ||||||
| 		ET_UNKNOWN, | 		ET_UNKNOWN, | ||||||
| @@ -460,8 +456,7 @@ namespace OpenWifi::uCentralProtocol::Events { | |||||||
| 		ET_CFGPENDING, | 		ET_CFGPENDING, | ||||||
| 		ET_RECOVERY, | 		ET_RECOVERY, | ||||||
| 		ET_DEVICEUPDATE, | 		ET_DEVICEUPDATE, | ||||||
| 		ET_TELEMETRY, | 		ET_TELEMETRY | ||||||
| 		ET_VENUEBROADCAST |  | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	inline EVENT_MSG EventFromString(const std::string & Method) { | 	inline EVENT_MSG EventFromString(const std::string & Method) { | ||||||
| @@ -485,8 +480,6 @@ namespace OpenWifi::uCentralProtocol::Events { | |||||||
| 			return ET_RECOVERY; | 			return ET_RECOVERY; | ||||||
| 		else if(strcmp(TELEMETRY,Method.c_str())==0) | 		else if(strcmp(TELEMETRY,Method.c_str())==0) | ||||||
| 			return ET_TELEMETRY; | 			return ET_TELEMETRY; | ||||||
| 		else if(strcmp(VENUE_BROADCAST,Method.c_str())==0) |  | ||||||
| 			return ET_VENUEBROADCAST; |  | ||||||
| 		return ET_UNKNOWN; | 		return ET_UNKNOWN; | ||||||
| 	}; | 	}; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,937 +0,0 @@ | |||||||
| /* |  | ||||||
|     MIT License |  | ||||||
|  |  | ||||||
|     Copyright (c) 2018 Marius Bancila |  | ||||||
|  |  | ||||||
|     Permission is hereby granted, free of charge, to any person obtaining a copy |  | ||||||
|     of this software and associated documentation files (the "Software"), to deal |  | ||||||
|     in the Software without restriction, including without limitation the rights |  | ||||||
|     to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |  | ||||||
|     copies of the Software, and to permit persons to whom the Software is |  | ||||||
|     furnished to do so, subject to the following conditions: |  | ||||||
|  |  | ||||||
|     The above copyright notice and this permission notice shall be included in all |  | ||||||
|     copies or substantial portions of the Software. |  | ||||||
|  |  | ||||||
|     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |  | ||||||
|     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |  | ||||||
|     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |  | ||||||
|     AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |  | ||||||
|     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |  | ||||||
|     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |  | ||||||
|     SOFTWARE. |  | ||||||
|  |  | ||||||
|     This file is from https://github.com/mariusbancila/croncpp.git. |  | ||||||
| */ |  | ||||||
|  |  | ||||||
| #pragma once |  | ||||||
|  |  | ||||||
| #include <vector> |  | ||||||
| #include <string> |  | ||||||
| #include <sstream> |  | ||||||
| #include <bitset> |  | ||||||
| #include <cctype> |  | ||||||
| #include <ctime> |  | ||||||
| #include <iomanip> |  | ||||||
| #include <algorithm> |  | ||||||
| #include <chrono> |  | ||||||
|  |  | ||||||
| #if __cplusplus > 201402L |  | ||||||
| #include <string_view> |  | ||||||
| #define CRONCPP_IS_CPP17 |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| namespace cron |  | ||||||
| { |  | ||||||
| #ifdef CRONCPP_IS_CPP17 |  | ||||||
|    #define  CRONCPP_STRING_VIEW       std::string_view |  | ||||||
|    #define  CRONCPP_STRING_VIEW_NPOS  std::string_view::npos |  | ||||||
|    #define  CRONCPP_CONSTEXPTR        constexpr |  | ||||||
| #else |  | ||||||
|    #define  CRONCPP_STRING_VIEW       std::string const & |  | ||||||
|    #define  CRONCPP_STRING_VIEW_NPOS  std::string::npos |  | ||||||
|    #define  CRONCPP_CONSTEXPTR |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|    using cron_int  = uint8_t; |  | ||||||
|  |  | ||||||
|    constexpr std::time_t INVALID_TIME = static_cast<std::time_t>(-1); |  | ||||||
|  |  | ||||||
|    constexpr size_t INVALID_INDEX = static_cast<size_t>(-1); |  | ||||||
|  |  | ||||||
|    class cronexpr; |  | ||||||
|  |  | ||||||
|    namespace detail |  | ||||||
|    { |  | ||||||
|       enum class cron_field |  | ||||||
|       { |  | ||||||
|          second, |  | ||||||
|          minute, |  | ||||||
|          hour_of_day, |  | ||||||
|          day_of_week, |  | ||||||
|          day_of_month, |  | ||||||
|          month, |  | ||||||
|          year |  | ||||||
|       }; |  | ||||||
|  |  | ||||||
|       template <typename Traits> |  | ||||||
|       static bool find_next(cronexpr const & cex, |  | ||||||
|                             std::tm& date, |  | ||||||
|                             size_t const dot); |  | ||||||
|    } |  | ||||||
|  |  | ||||||
|    struct bad_cronexpr : public std::runtime_error |  | ||||||
|    { |  | ||||||
|    public: |  | ||||||
|       explicit bad_cronexpr(CRONCPP_STRING_VIEW message) : |  | ||||||
|          std::runtime_error(message.data()) |  | ||||||
|       {} |  | ||||||
|    }; |  | ||||||
|  |  | ||||||
|  |  | ||||||
|    struct cron_standard_traits |  | ||||||
|    { |  | ||||||
|       static const cron_int CRON_MIN_SECONDS = 0; |  | ||||||
|       static const cron_int CRON_MAX_SECONDS = 59; |  | ||||||
|  |  | ||||||
|       static const cron_int CRON_MIN_MINUTES = 0; |  | ||||||
|       static const cron_int CRON_MAX_MINUTES = 59; |  | ||||||
|  |  | ||||||
|       static const cron_int CRON_MIN_HOURS = 0; |  | ||||||
|       static const cron_int CRON_MAX_HOURS = 23; |  | ||||||
|  |  | ||||||
|       static const cron_int CRON_MIN_DAYS_OF_WEEK = 0; |  | ||||||
|       static const cron_int CRON_MAX_DAYS_OF_WEEK = 6; |  | ||||||
|  |  | ||||||
|       static const cron_int CRON_MIN_DAYS_OF_MONTH = 1; |  | ||||||
|       static const cron_int CRON_MAX_DAYS_OF_MONTH = 31; |  | ||||||
|  |  | ||||||
|       static const cron_int CRON_MIN_MONTHS = 1; |  | ||||||
|       static const cron_int CRON_MAX_MONTHS = 12; |  | ||||||
|  |  | ||||||
|       static const cron_int CRON_MAX_YEARS_DIFF = 4; |  | ||||||
|  |  | ||||||
| #ifdef CRONCPP_IS_CPP17 |  | ||||||
|       static const inline std::vector<std::string> DAYS = { "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" }; |  | ||||||
|       static const inline std::vector<std::string> MONTHS = { "NIL", "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" }; |  | ||||||
| #else |  | ||||||
|       static std::vector<std::string>& DAYS() |  | ||||||
|       { |  | ||||||
|          static std::vector<std::string> days = { "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" }; |  | ||||||
|          return days; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       static std::vector<std::string>& MONTHS() |  | ||||||
|       { |  | ||||||
|          static std::vector<std::string> months = { "NIL", "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" }; |  | ||||||
|          return months; |  | ||||||
|       } |  | ||||||
| #endif |  | ||||||
|    }; |  | ||||||
|  |  | ||||||
|    struct cron_oracle_traits |  | ||||||
|    { |  | ||||||
|       static const cron_int CRON_MIN_SECONDS = 0; |  | ||||||
|       static const cron_int CRON_MAX_SECONDS = 59; |  | ||||||
|  |  | ||||||
|       static const cron_int CRON_MIN_MINUTES = 0; |  | ||||||
|       static const cron_int CRON_MAX_MINUTES = 59; |  | ||||||
|  |  | ||||||
|       static const cron_int CRON_MIN_HOURS = 0; |  | ||||||
|       static const cron_int CRON_MAX_HOURS = 23; |  | ||||||
|  |  | ||||||
|       static const cron_int CRON_MIN_DAYS_OF_WEEK = 1; |  | ||||||
|       static const cron_int CRON_MAX_DAYS_OF_WEEK = 7; |  | ||||||
|  |  | ||||||
|       static const cron_int CRON_MIN_DAYS_OF_MONTH = 1; |  | ||||||
|       static const cron_int CRON_MAX_DAYS_OF_MONTH = 31; |  | ||||||
|  |  | ||||||
|       static const cron_int CRON_MIN_MONTHS = 0; |  | ||||||
|       static const cron_int CRON_MAX_MONTHS = 11; |  | ||||||
|  |  | ||||||
|       static const cron_int CRON_MAX_YEARS_DIFF = 4; |  | ||||||
|  |  | ||||||
| #ifdef CRONCPP_IS_CPP17 |  | ||||||
|       static const inline std::vector<std::string> DAYS = { "NIL", "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" }; |  | ||||||
|       static const inline std::vector<std::string> MONTHS = { "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" }; |  | ||||||
| #else |  | ||||||
|  |  | ||||||
|       static std::vector<std::string>& DAYS() |  | ||||||
|       { |  | ||||||
|          static std::vector<std::string> days = { "NIL", "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" }; |  | ||||||
|          return days; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       static std::vector<std::string>& MONTHS() |  | ||||||
|       { |  | ||||||
|          static std::vector<std::string> months = { "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" }; |  | ||||||
|          return months; |  | ||||||
|       } |  | ||||||
| #endif |  | ||||||
|    }; |  | ||||||
|  |  | ||||||
|    struct cron_quartz_traits |  | ||||||
|    { |  | ||||||
|       static const cron_int CRON_MIN_SECONDS = 0; |  | ||||||
|       static const cron_int CRON_MAX_SECONDS = 59; |  | ||||||
|  |  | ||||||
|       static const cron_int CRON_MIN_MINUTES = 0; |  | ||||||
|       static const cron_int CRON_MAX_MINUTES = 59; |  | ||||||
|  |  | ||||||
|       static const cron_int CRON_MIN_HOURS = 0; |  | ||||||
|       static const cron_int CRON_MAX_HOURS = 23; |  | ||||||
|  |  | ||||||
|       static const cron_int CRON_MIN_DAYS_OF_WEEK = 1; |  | ||||||
|       static const cron_int CRON_MAX_DAYS_OF_WEEK = 7; |  | ||||||
|  |  | ||||||
|       static const cron_int CRON_MIN_DAYS_OF_MONTH = 1; |  | ||||||
|       static const cron_int CRON_MAX_DAYS_OF_MONTH = 31; |  | ||||||
|  |  | ||||||
|       static const cron_int CRON_MIN_MONTHS = 1; |  | ||||||
|       static const cron_int CRON_MAX_MONTHS = 12; |  | ||||||
|  |  | ||||||
|       static const cron_int CRON_MAX_YEARS_DIFF = 4; |  | ||||||
|  |  | ||||||
| #ifdef CRONCPP_IS_CPP17 |  | ||||||
|       static const inline std::vector<std::string> DAYS = { "NIL", "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" }; |  | ||||||
|       static const inline std::vector<std::string> MONTHS = { "NIL", "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" }; |  | ||||||
| #else |  | ||||||
|       static std::vector<std::string>& DAYS() |  | ||||||
|       { |  | ||||||
|          static std::vector<std::string> days = { "NIL", "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" }; |  | ||||||
|          return days; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       static std::vector<std::string>& MONTHS() |  | ||||||
|       { |  | ||||||
|          static std::vector<std::string> months = { "NIL", "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" }; |  | ||||||
|          return months; |  | ||||||
|       } |  | ||||||
| #endif |  | ||||||
|    }; |  | ||||||
|  |  | ||||||
|    class cronexpr; |  | ||||||
|  |  | ||||||
|    template <typename Traits = cron_standard_traits> |  | ||||||
|    static cronexpr make_cron(CRONCPP_STRING_VIEW expr); |  | ||||||
|  |  | ||||||
|    class cronexpr |  | ||||||
|    { |  | ||||||
|       std::bitset<60> seconds; |  | ||||||
|       std::bitset<60> minutes; |  | ||||||
|       std::bitset<24> hours; |  | ||||||
|       std::bitset<7>  days_of_week; |  | ||||||
|       std::bitset<31> days_of_month; |  | ||||||
|       std::bitset<12> months; |  | ||||||
|       std::string     expr; |  | ||||||
|  |  | ||||||
|       friend bool operator==(cronexpr const & e1, cronexpr const & e2); |  | ||||||
|       friend bool operator!=(cronexpr const & e1, cronexpr const & e2); |  | ||||||
|  |  | ||||||
|       template <typename Traits> |  | ||||||
|       friend bool detail::find_next(cronexpr const & cex, |  | ||||||
|                                     std::tm& date, |  | ||||||
|                                     size_t const dot); |  | ||||||
|  |  | ||||||
|       friend std::string to_cronstr(cronexpr const& cex); |  | ||||||
|       friend std::string to_string(cronexpr const & cex); |  | ||||||
|  |  | ||||||
|       template <typename Traits> |  | ||||||
|       friend cronexpr make_cron(CRONCPP_STRING_VIEW expr); |  | ||||||
|    }; |  | ||||||
|  |  | ||||||
|    inline bool operator==(cronexpr const & e1, cronexpr const & e2) |  | ||||||
|    { |  | ||||||
|       return |  | ||||||
|          e1.seconds == e2.seconds && |  | ||||||
|          e1.minutes == e2.minutes && |  | ||||||
|          e1.hours == e2.hours && |  | ||||||
|          e1.days_of_week == e2.days_of_week && |  | ||||||
|          e1.days_of_month == e2.days_of_month && |  | ||||||
|          e1.months == e2.months; |  | ||||||
|    } |  | ||||||
|  |  | ||||||
|    inline bool operator!=(cronexpr const & e1, cronexpr const & e2) |  | ||||||
|    { |  | ||||||
|       return !(e1 == e2); |  | ||||||
|    } |  | ||||||
|  |  | ||||||
|    inline std::string to_string(cronexpr const & cex) |  | ||||||
|    { |  | ||||||
|       return |  | ||||||
|          cex.seconds.to_string() + " " + |  | ||||||
|          cex.minutes.to_string() + " " + |  | ||||||
|          cex.hours.to_string() + " " + |  | ||||||
|          cex.days_of_month.to_string() + " " + |  | ||||||
|          cex.months.to_string() + " " + |  | ||||||
|          cex.days_of_week.to_string(); |  | ||||||
|    } |  | ||||||
|  |  | ||||||
|    inline std::string to_cronstr(cronexpr const& cex) |  | ||||||
|    { |  | ||||||
|       return cex.expr; |  | ||||||
|    } |  | ||||||
|  |  | ||||||
|    namespace utils |  | ||||||
|    { |  | ||||||
|       inline std::time_t tm_to_time(std::tm& date) |  | ||||||
|       { |  | ||||||
|          return std::mktime(&date); |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       inline std::tm* time_to_tm(std::time_t const * date, std::tm* const out) |  | ||||||
|       { |  | ||||||
| #ifdef _WIN32 |  | ||||||
|          errno_t err = localtime_s(out, date); |  | ||||||
|          return 0 == err ? out : nullptr; |  | ||||||
| #else |  | ||||||
|          return localtime_r(date, out); |  | ||||||
| #endif |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       inline std::tm to_tm(CRONCPP_STRING_VIEW time) |  | ||||||
|       { |  | ||||||
|          std::tm result; |  | ||||||
| #if __cplusplus > 201103L |  | ||||||
|          std::istringstream str(time.data()); |  | ||||||
|          str.imbue(std::locale(setlocale(LC_ALL, nullptr))); |  | ||||||
|  |  | ||||||
|          str >> std::get_time(&result, "%Y-%m-%d %H:%M:%S"); |  | ||||||
|          if (str.fail()) throw std::runtime_error("Parsing date failed!"); |  | ||||||
| #else |  | ||||||
|          int year = 1900; |  | ||||||
|          int month = 1; |  | ||||||
|          int day = 1; |  | ||||||
|          int hour = 0; |  | ||||||
|          int minute = 0; |  | ||||||
|          int second = 0; |  | ||||||
|          sscanf(time.data(), "%d-%d-%d %d:%d:%d", &year, &month, &day, &hour, &minute, &second); |  | ||||||
|          result.tm_year = year - 1900; |  | ||||||
|          result.tm_mon = month - 1; |  | ||||||
|          result.tm_mday = day; |  | ||||||
|          result.tm_hour = hour; |  | ||||||
|          result.tm_min = minute; |  | ||||||
|          result.tm_sec = second; |  | ||||||
| #endif |  | ||||||
|          result.tm_isdst = -1; // DST info not available |  | ||||||
|  |  | ||||||
|          return result; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       inline std::string to_string(std::tm const & tm) |  | ||||||
|       { |  | ||||||
| #if __cplusplus > 201103L |  | ||||||
|          std::ostringstream str; |  | ||||||
|          str.imbue(std::locale(setlocale(LC_ALL, nullptr))); |  | ||||||
|          str << std::put_time(&tm, "%Y-%m-%d %H:%M:%S"); |  | ||||||
|          if (str.fail()) throw std::runtime_error("Writing date failed!"); |  | ||||||
|  |  | ||||||
|          return str.str(); |  | ||||||
| #else |  | ||||||
|          char buff[70] = {0}; |  | ||||||
|          strftime(buff, sizeof(buff), "%Y-%m-%d %H:%M:%S", &tm); |  | ||||||
|          return std::string(buff); |  | ||||||
| #endif |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       inline std::string to_upper(std::string text) |  | ||||||
|       { |  | ||||||
|          std::transform(std::begin(text), std::end(text), |  | ||||||
|             std::begin(text), [](char const c) { return static_cast<char>(std::toupper(c)); }); |  | ||||||
|  |  | ||||||
|          return text; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       static std::vector<std::string> split(CRONCPP_STRING_VIEW text, char const delimiter) |  | ||||||
|       { |  | ||||||
|          std::vector<std::string> tokens; |  | ||||||
|          std::string token; |  | ||||||
|          std::istringstream tokenStream(text.data()); |  | ||||||
|          while (std::getline(tokenStream, token, delimiter)) |  | ||||||
|          { |  | ||||||
|             tokens.push_back(token); |  | ||||||
|          } |  | ||||||
|          return tokens; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       CRONCPP_CONSTEXPTR inline bool contains(CRONCPP_STRING_VIEW text, char const ch) noexcept |  | ||||||
|       { |  | ||||||
|          return CRONCPP_STRING_VIEW_NPOS != text.find_first_of(ch); |  | ||||||
|       } |  | ||||||
|    } |  | ||||||
|  |  | ||||||
|    namespace detail |  | ||||||
|    { |  | ||||||
|  |  | ||||||
|       inline cron_int to_cron_int(CRONCPP_STRING_VIEW text) |  | ||||||
|       { |  | ||||||
|          try |  | ||||||
|          { |  | ||||||
|             return static_cast<cron_int>(std::stoul(text.data())); |  | ||||||
|          } |  | ||||||
|          catch (std::exception const & ex) |  | ||||||
|          { |  | ||||||
|             throw bad_cronexpr(ex.what()); |  | ||||||
|          } |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       static std::string replace_ordinals( |  | ||||||
|          std::string text, |  | ||||||
|          std::vector<std::string> const & replacement) |  | ||||||
|       { |  | ||||||
|          for (size_t i = 0; i < replacement.size(); ++i) |  | ||||||
|          { |  | ||||||
|             auto pos = text.find(replacement[i]); |  | ||||||
|             if (std::string::npos != pos) |  | ||||||
|                text.replace(pos, 3 ,std::to_string(i)); |  | ||||||
|          } |  | ||||||
|  |  | ||||||
|          return text; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       static std::pair<cron_int, cron_int> make_range( |  | ||||||
|          CRONCPP_STRING_VIEW field, |  | ||||||
|          cron_int const minval, |  | ||||||
|          cron_int const maxval) |  | ||||||
|       { |  | ||||||
|          cron_int first = 0; |  | ||||||
|          cron_int last = 0; |  | ||||||
|          if (field.size() == 1 && field[0] == '*') |  | ||||||
|          { |  | ||||||
|             first = minval; |  | ||||||
|             last = maxval; |  | ||||||
|          } |  | ||||||
|          else if (!utils::contains(field, '-')) |  | ||||||
|          { |  | ||||||
|             first = to_cron_int(field); |  | ||||||
|             last = first; |  | ||||||
|          } |  | ||||||
|          else |  | ||||||
|          { |  | ||||||
|             auto parts = utils::split(field, '-'); |  | ||||||
|             if (parts.size() != 2) |  | ||||||
|                throw bad_cronexpr("Specified range requires two fields"); |  | ||||||
|  |  | ||||||
|             first = to_cron_int(parts[0]); |  | ||||||
|             last = to_cron_int(parts[1]); |  | ||||||
|          } |  | ||||||
|  |  | ||||||
|          if (first > maxval || last > maxval) |  | ||||||
|          { |  | ||||||
|             throw bad_cronexpr("Specified range exceeds maximum"); |  | ||||||
|          } |  | ||||||
|          if (first < minval || last < minval) |  | ||||||
|          { |  | ||||||
|             throw bad_cronexpr("Specified range is less than minimum"); |  | ||||||
|          } |  | ||||||
|          if (first > last) |  | ||||||
|          { |  | ||||||
|             throw bad_cronexpr("Specified range start exceeds range end"); |  | ||||||
|          } |  | ||||||
|  |  | ||||||
|          return { first, last }; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       template <size_t N> |  | ||||||
|       static void set_cron_field( |  | ||||||
|          CRONCPP_STRING_VIEW value, |  | ||||||
|          std::bitset<N>& target, |  | ||||||
|          cron_int const minval, |  | ||||||
|          cron_int const maxval) |  | ||||||
|       { |  | ||||||
|          if(value.length() > 0 && value[value.length()-1] == ',') |  | ||||||
|             throw bad_cronexpr("Value cannot end with comma"); |  | ||||||
|  |  | ||||||
|          auto fields = utils::split(value, ','); |  | ||||||
|          if (fields.empty()) |  | ||||||
|             throw bad_cronexpr("Expression parsing error"); |  | ||||||
|  |  | ||||||
|          for (auto const & field : fields) |  | ||||||
|          { |  | ||||||
|             if (!utils::contains(field, '/')) |  | ||||||
|             { |  | ||||||
| #ifdef CRONCPP_IS_CPP17 |  | ||||||
|                auto[first, last] = detail::make_range(field, minval, maxval); |  | ||||||
| #else |  | ||||||
|                auto range = detail::make_range(field, minval, maxval); |  | ||||||
|                auto first = range.first; |  | ||||||
|                auto last = range.second; |  | ||||||
| #endif |  | ||||||
|                for (cron_int i = first - minval; i <= last - minval; ++i) |  | ||||||
|                { |  | ||||||
|                   target.set(i); |  | ||||||
|                } |  | ||||||
|             } |  | ||||||
|             else |  | ||||||
|             { |  | ||||||
|                auto parts = utils::split(field, '/'); |  | ||||||
|                if (parts.size() != 2) |  | ||||||
|                   throw bad_cronexpr("Incrementer must have two fields"); |  | ||||||
|  |  | ||||||
| #ifdef CRONCPP_IS_CPP17 |  | ||||||
|                auto[first, last] = detail::make_range(parts[0], minval, maxval); |  | ||||||
| #else |  | ||||||
|                auto range = detail::make_range(parts[0], minval, maxval); |  | ||||||
|                auto first = range.first; |  | ||||||
|                auto last = range.second; |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|                if (!utils::contains(parts[0], '-')) |  | ||||||
|                { |  | ||||||
|                   last = maxval; |  | ||||||
|                } |  | ||||||
|  |  | ||||||
|                auto delta = detail::to_cron_int(parts[1]); |  | ||||||
|                if(delta <= 0) |  | ||||||
|                   throw bad_cronexpr("Incrementer must be a positive value"); |  | ||||||
|  |  | ||||||
|                for (cron_int i = first - minval; i <= last - minval; i += delta) |  | ||||||
|                { |  | ||||||
|                   target.set(i); |  | ||||||
|                } |  | ||||||
|             } |  | ||||||
|          } |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       template <typename Traits> |  | ||||||
|       static void set_cron_days_of_week( |  | ||||||
|          std::string value, |  | ||||||
|          std::bitset<7>& target) |  | ||||||
|       { |  | ||||||
|          auto days = utils::to_upper(value); |  | ||||||
|          auto days_replaced = detail::replace_ordinals( |  | ||||||
|             days, |  | ||||||
| #ifdef CRONCPP_IS_CPP17 |  | ||||||
|             Traits::DAYS |  | ||||||
| #else |  | ||||||
|             Traits::DAYS() |  | ||||||
| #endif |  | ||||||
|          ); |  | ||||||
|  |  | ||||||
|          if (days_replaced.size() == 1 && days_replaced[0] == '?') |  | ||||||
|             days_replaced[0] = '*'; |  | ||||||
|  |  | ||||||
|          set_cron_field( |  | ||||||
|             days_replaced, |  | ||||||
|             target, |  | ||||||
|             Traits::CRON_MIN_DAYS_OF_WEEK, |  | ||||||
|             Traits::CRON_MAX_DAYS_OF_WEEK); |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       template <typename Traits> |  | ||||||
|       static void set_cron_days_of_month( |  | ||||||
|          std::string value, |  | ||||||
|          std::bitset<31>& target) |  | ||||||
|       { |  | ||||||
|          if (value.size() == 1 && value[0] == '?') |  | ||||||
|             value[0] = '*'; |  | ||||||
|  |  | ||||||
|          set_cron_field( |  | ||||||
|             value, |  | ||||||
|             target, |  | ||||||
|             Traits::CRON_MIN_DAYS_OF_MONTH, |  | ||||||
|             Traits::CRON_MAX_DAYS_OF_MONTH); |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       template <typename Traits> |  | ||||||
|       static void set_cron_month( |  | ||||||
|          std::string value, |  | ||||||
|          std::bitset<12>& target) |  | ||||||
|       { |  | ||||||
|          auto month = utils::to_upper(value); |  | ||||||
|          auto month_replaced = replace_ordinals( |  | ||||||
|             month, |  | ||||||
| #ifdef CRONCPP_IS_CPP17 |  | ||||||
|             Traits::MONTHS |  | ||||||
| #else |  | ||||||
|             Traits::MONTHS() |  | ||||||
| #endif |  | ||||||
|          ); |  | ||||||
|  |  | ||||||
|          set_cron_field( |  | ||||||
|             month_replaced, |  | ||||||
|             target, |  | ||||||
|             Traits::CRON_MIN_MONTHS, |  | ||||||
|             Traits::CRON_MAX_MONTHS); |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       template <size_t N> |  | ||||||
|       inline size_t next_set_bit( |  | ||||||
|          std::bitset<N> const & target, |  | ||||||
|          size_t /*minimum*/, |  | ||||||
|          size_t /*maximum*/, |  | ||||||
|          size_t offset) |  | ||||||
|       { |  | ||||||
|          for (auto i = offset; i < N; ++i) |  | ||||||
|          { |  | ||||||
|             if (target.test(i)) return i; |  | ||||||
|          } |  | ||||||
|  |  | ||||||
|          return INVALID_INDEX; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       inline void add_to_field( |  | ||||||
|          std::tm& date, |  | ||||||
|          cron_field const field, |  | ||||||
|          int const val) |  | ||||||
|       { |  | ||||||
|          switch (field) |  | ||||||
|          { |  | ||||||
|          case cron_field::second: |  | ||||||
|             date.tm_sec += val; |  | ||||||
|             break; |  | ||||||
|          case cron_field::minute: |  | ||||||
|             date.tm_min += val; |  | ||||||
|             break; |  | ||||||
|          case cron_field::hour_of_day: |  | ||||||
|             date.tm_hour += val; |  | ||||||
|             break; |  | ||||||
|          case cron_field::day_of_week: |  | ||||||
|          case cron_field::day_of_month: |  | ||||||
|             date.tm_mday += val; |  | ||||||
|             break; |  | ||||||
|          case cron_field::month: |  | ||||||
|             date.tm_mon += val; |  | ||||||
|             break; |  | ||||||
|          case cron_field::year: |  | ||||||
|             date.tm_year += val; |  | ||||||
|             break; |  | ||||||
|          } |  | ||||||
|  |  | ||||||
|          if (INVALID_TIME == utils::tm_to_time(date)) |  | ||||||
|             throw bad_cronexpr("Invalid time expression"); |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       inline void set_field( |  | ||||||
|          std::tm& date, |  | ||||||
|          cron_field const field, |  | ||||||
|          int const val) |  | ||||||
|       { |  | ||||||
|          switch (field) |  | ||||||
|          { |  | ||||||
|          case cron_field::second: |  | ||||||
|             date.tm_sec = val; |  | ||||||
|             break; |  | ||||||
|          case cron_field::minute: |  | ||||||
|             date.tm_min = val; |  | ||||||
|             break; |  | ||||||
|          case cron_field::hour_of_day: |  | ||||||
|             date.tm_hour = val; |  | ||||||
|             break; |  | ||||||
|          case cron_field::day_of_week: |  | ||||||
|             date.tm_wday = val; |  | ||||||
|             break; |  | ||||||
|          case cron_field::day_of_month: |  | ||||||
|             date.tm_mday = val; |  | ||||||
|             break; |  | ||||||
|          case cron_field::month: |  | ||||||
|             date.tm_mon = val; |  | ||||||
|             break; |  | ||||||
|          case cron_field::year: |  | ||||||
|             date.tm_year = val; |  | ||||||
|             break; |  | ||||||
|          } |  | ||||||
|  |  | ||||||
|          if (INVALID_TIME == utils::tm_to_time(date)) |  | ||||||
|             throw bad_cronexpr("Invalid time expression"); |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       inline void reset_field( |  | ||||||
|          std::tm& date, |  | ||||||
|          cron_field const field) |  | ||||||
|       { |  | ||||||
|          switch (field) |  | ||||||
|          { |  | ||||||
|          case cron_field::second: |  | ||||||
|             date.tm_sec = 0; |  | ||||||
|             break; |  | ||||||
|          case cron_field::minute: |  | ||||||
|             date.tm_min = 0; |  | ||||||
|             break; |  | ||||||
|          case cron_field::hour_of_day: |  | ||||||
|             date.tm_hour = 0; |  | ||||||
|             break; |  | ||||||
|          case cron_field::day_of_week: |  | ||||||
|             date.tm_wday = 0; |  | ||||||
|             break; |  | ||||||
|          case cron_field::day_of_month: |  | ||||||
|             date.tm_mday = 1; |  | ||||||
|             break; |  | ||||||
|          case cron_field::month: |  | ||||||
|             date.tm_mon = 0; |  | ||||||
|             break; |  | ||||||
|          case cron_field::year: |  | ||||||
|             date.tm_year = 0; |  | ||||||
|             break; |  | ||||||
|          } |  | ||||||
|  |  | ||||||
|          if (INVALID_TIME == utils::tm_to_time(date)) |  | ||||||
|             throw bad_cronexpr("Invalid time expression"); |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       inline void reset_all_fields( |  | ||||||
|          std::tm& date, |  | ||||||
|          std::bitset<7> const & marked_fields) |  | ||||||
|       { |  | ||||||
|          for (size_t i = 0; i < marked_fields.size(); ++i) |  | ||||||
|          { |  | ||||||
|             if (marked_fields.test(i)) |  | ||||||
|                reset_field(date, static_cast<cron_field>(i)); |  | ||||||
|          } |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       inline void mark_field( |  | ||||||
|          std::bitset<7> & orders, |  | ||||||
|          cron_field const field) |  | ||||||
|       { |  | ||||||
|          if (!orders.test(static_cast<size_t>(field))) |  | ||||||
|             orders.set(static_cast<size_t>(field)); |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       template <size_t N> |  | ||||||
|       static size_t find_next( |  | ||||||
|          std::bitset<N> const & target, |  | ||||||
|          std::tm& date, |  | ||||||
|          unsigned int const minimum, |  | ||||||
|          unsigned int const maximum, |  | ||||||
|          unsigned int const value, |  | ||||||
|          cron_field const field, |  | ||||||
|          cron_field const next_field, |  | ||||||
|          std::bitset<7> const & marked_fields) |  | ||||||
|       { |  | ||||||
|          auto next_value = next_set_bit(target, minimum, maximum, value); |  | ||||||
|          if (INVALID_INDEX == next_value) |  | ||||||
|          { |  | ||||||
|             add_to_field(date, next_field, 1); |  | ||||||
|             reset_field(date, field); |  | ||||||
|             next_value = next_set_bit(target, minimum, maximum, 0); |  | ||||||
|          } |  | ||||||
|  |  | ||||||
|          if (INVALID_INDEX == next_value || next_value != value) |  | ||||||
|          { |  | ||||||
|             set_field(date, field, static_cast<int>(next_value)); |  | ||||||
|             reset_all_fields(date, marked_fields); |  | ||||||
|          } |  | ||||||
|  |  | ||||||
|          return next_value; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       template <typename Traits> |  | ||||||
|       static size_t find_next_day( |  | ||||||
|          std::tm& date, |  | ||||||
|          std::bitset<31> const & days_of_month, |  | ||||||
|          size_t day_of_month, |  | ||||||
|          std::bitset<7> const & days_of_week, |  | ||||||
|          size_t day_of_week, |  | ||||||
|          std::bitset<7> const & marked_fields) |  | ||||||
|       { |  | ||||||
|          unsigned int count = 0; |  | ||||||
|          unsigned int maximum = 366; |  | ||||||
|          while ( |  | ||||||
|             (!days_of_month.test(day_of_month - Traits::CRON_MIN_DAYS_OF_MONTH) || |  | ||||||
|             !days_of_week.test(day_of_week - Traits::CRON_MIN_DAYS_OF_WEEK)) |  | ||||||
|             && count++ < maximum) |  | ||||||
|          { |  | ||||||
|             add_to_field(date, cron_field::day_of_month, 1); |  | ||||||
|  |  | ||||||
|             day_of_month = date.tm_mday; |  | ||||||
|             day_of_week = date.tm_wday; |  | ||||||
|  |  | ||||||
|             reset_all_fields(date, marked_fields); |  | ||||||
|          } |  | ||||||
|  |  | ||||||
|          return day_of_month; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       template <typename Traits> |  | ||||||
|       static bool find_next(cronexpr const & cex, |  | ||||||
|                             std::tm& date, |  | ||||||
|                             size_t const dot) |  | ||||||
|       { |  | ||||||
|          bool res = true; |  | ||||||
|  |  | ||||||
|          std::bitset<7> marked_fields{ 0 }; |  | ||||||
|          std::bitset<7> empty_list{ 0 }; |  | ||||||
|  |  | ||||||
|          unsigned int second = date.tm_sec; |  | ||||||
|          auto updated_second = find_next( |  | ||||||
|             cex.seconds, |  | ||||||
|             date, |  | ||||||
|             Traits::CRON_MIN_SECONDS, |  | ||||||
|             Traits::CRON_MAX_SECONDS, |  | ||||||
|             second, |  | ||||||
|             cron_field::second, |  | ||||||
|             cron_field::minute, |  | ||||||
|             empty_list); |  | ||||||
|  |  | ||||||
|          if (second == updated_second) |  | ||||||
|          { |  | ||||||
|             mark_field(marked_fields, cron_field::second); |  | ||||||
|          } |  | ||||||
|  |  | ||||||
|          unsigned int minute = date.tm_min; |  | ||||||
|          auto update_minute = find_next( |  | ||||||
|             cex.minutes, |  | ||||||
|             date, |  | ||||||
|             Traits::CRON_MIN_MINUTES, |  | ||||||
|             Traits::CRON_MAX_MINUTES, |  | ||||||
|             minute, |  | ||||||
|             cron_field::minute, |  | ||||||
|             cron_field::hour_of_day, |  | ||||||
|             marked_fields); |  | ||||||
|          if (minute == update_minute) |  | ||||||
|          { |  | ||||||
|             mark_field(marked_fields, cron_field::minute); |  | ||||||
|          } |  | ||||||
|          else |  | ||||||
|          { |  | ||||||
|             res = find_next<Traits>(cex, date, dot); |  | ||||||
|             if (!res) return res; |  | ||||||
|          } |  | ||||||
|  |  | ||||||
|          unsigned int hour = date.tm_hour; |  | ||||||
|          auto updated_hour = find_next( |  | ||||||
|             cex.hours, |  | ||||||
|             date, |  | ||||||
|             Traits::CRON_MIN_HOURS, |  | ||||||
|             Traits::CRON_MAX_HOURS, |  | ||||||
|             hour, |  | ||||||
|             cron_field::hour_of_day, |  | ||||||
|             cron_field::day_of_week, |  | ||||||
|             marked_fields); |  | ||||||
|          if (hour == updated_hour) |  | ||||||
|          { |  | ||||||
|             mark_field(marked_fields, cron_field::hour_of_day); |  | ||||||
|          } |  | ||||||
|          else |  | ||||||
|          { |  | ||||||
|             res = find_next<Traits>(cex, date, dot); |  | ||||||
|             if (!res) return res; |  | ||||||
|          } |  | ||||||
|  |  | ||||||
|          unsigned int day_of_week = date.tm_wday; |  | ||||||
|          unsigned int day_of_month = date.tm_mday; |  | ||||||
|          auto updated_day_of_month = find_next_day<Traits>( |  | ||||||
|             date, |  | ||||||
|             cex.days_of_month, |  | ||||||
|             day_of_month, |  | ||||||
|             cex.days_of_week, |  | ||||||
|             day_of_week, |  | ||||||
|             marked_fields); |  | ||||||
|          if (day_of_month == updated_day_of_month) |  | ||||||
|          { |  | ||||||
|             mark_field(marked_fields, cron_field::day_of_month); |  | ||||||
|          } |  | ||||||
|          else |  | ||||||
|          { |  | ||||||
|             res = find_next<Traits>(cex, date, dot); |  | ||||||
|             if (!res) return res; |  | ||||||
|          } |  | ||||||
|  |  | ||||||
|          unsigned int month = date.tm_mon; |  | ||||||
|          auto updated_month = find_next( |  | ||||||
|             cex.months, |  | ||||||
|             date, |  | ||||||
|             Traits::CRON_MIN_MONTHS, |  | ||||||
|             Traits::CRON_MAX_MONTHS, |  | ||||||
|             month, |  | ||||||
|             cron_field::month, |  | ||||||
|             cron_field::year, |  | ||||||
|             marked_fields); |  | ||||||
|          if (month != updated_month) |  | ||||||
|          { |  | ||||||
|             if (date.tm_year - dot > Traits::CRON_MAX_YEARS_DIFF) |  | ||||||
|                return false; |  | ||||||
|  |  | ||||||
|             res = find_next<Traits>(cex, date, dot); |  | ||||||
|             if (!res) return res; |  | ||||||
|          } |  | ||||||
|  |  | ||||||
|          return res; |  | ||||||
|       } |  | ||||||
|    } |  | ||||||
|  |  | ||||||
|    template <typename Traits> |  | ||||||
|    static cronexpr make_cron(CRONCPP_STRING_VIEW expr) |  | ||||||
|    { |  | ||||||
|       cronexpr cex; |  | ||||||
|  |  | ||||||
|       if (expr.empty()) |  | ||||||
|          throw bad_cronexpr("Invalid empty cron expression"); |  | ||||||
|  |  | ||||||
|       auto fields = utils::split(expr, ' '); |  | ||||||
|       fields.erase( |  | ||||||
|          std::remove_if(std::begin(fields), std::end(fields), |  | ||||||
|             [](CRONCPP_STRING_VIEW s) {return s.empty(); }), |  | ||||||
|          std::end(fields)); |  | ||||||
|       if (fields.size() != 6) |  | ||||||
|          throw bad_cronexpr("cron expression must have six fields"); |  | ||||||
|  |  | ||||||
|       detail::set_cron_field(fields[0], cex.seconds, Traits::CRON_MIN_SECONDS, Traits::CRON_MAX_SECONDS); |  | ||||||
|       detail::set_cron_field(fields[1], cex.minutes, Traits::CRON_MIN_MINUTES, Traits::CRON_MAX_MINUTES); |  | ||||||
|       detail::set_cron_field(fields[2], cex.hours, Traits::CRON_MIN_HOURS, Traits::CRON_MAX_HOURS); |  | ||||||
|  |  | ||||||
|       detail::set_cron_days_of_week<Traits>(fields[5], cex.days_of_week); |  | ||||||
|  |  | ||||||
|       detail::set_cron_days_of_month<Traits>(fields[3], cex.days_of_month); |  | ||||||
|  |  | ||||||
|       detail::set_cron_month<Traits>(fields[4], cex.months); |  | ||||||
|  |  | ||||||
|       cex.expr = expr; |  | ||||||
|  |  | ||||||
|       return cex; |  | ||||||
|    } |  | ||||||
|  |  | ||||||
|    template <typename Traits = cron_standard_traits> |  | ||||||
|    static std::tm cron_next(cronexpr const & cex, std::tm date) |  | ||||||
|    { |  | ||||||
|       time_t original = utils::tm_to_time(date); |  | ||||||
|       if (INVALID_TIME == original) return {}; |  | ||||||
|  |  | ||||||
|       if (!detail::find_next<Traits>(cex, date, date.tm_year)) |  | ||||||
|          return {}; |  | ||||||
|  |  | ||||||
|       time_t calculated = utils::tm_to_time(date); |  | ||||||
|       if (INVALID_TIME == calculated) return {}; |  | ||||||
|  |  | ||||||
|       if (calculated == original) |  | ||||||
|       { |  | ||||||
|          add_to_field(date, detail::cron_field::second, 1); |  | ||||||
|          if (!detail::find_next<Traits>(cex, date, date.tm_year)) |  | ||||||
|             return {}; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       return date; |  | ||||||
|    } |  | ||||||
|  |  | ||||||
|    template <typename Traits = cron_standard_traits> |  | ||||||
|    static std::time_t cron_next(cronexpr const & cex, std::time_t const & date) |  | ||||||
|    { |  | ||||||
|       std::tm val; |  | ||||||
|       std::tm* dt = utils::time_to_tm(&date, &val); |  | ||||||
|       if (dt == nullptr) return INVALID_TIME; |  | ||||||
|  |  | ||||||
|       time_t original = utils::tm_to_time(*dt); |  | ||||||
|       if (INVALID_TIME == original) return INVALID_TIME; |  | ||||||
|  |  | ||||||
|       if(!detail::find_next<Traits>(cex, *dt, dt->tm_year)) |  | ||||||
|          return INVALID_TIME; |  | ||||||
|  |  | ||||||
|       time_t calculated = utils::tm_to_time(*dt); |  | ||||||
|       if (INVALID_TIME == calculated) return calculated; |  | ||||||
|  |  | ||||||
|       if (calculated == original) |  | ||||||
|       { |  | ||||||
|          add_to_field(*dt, detail::cron_field::second, 1); |  | ||||||
|          if(!detail::find_next<Traits>(cex, *dt, dt->tm_year)) |  | ||||||
|             return INVALID_TIME; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       return utils::tm_to_time(*dt); |  | ||||||
|    } |  | ||||||
|  |  | ||||||
|   template <typename Traits = cron_standard_traits> |  | ||||||
|   static std::chrono::system_clock::time_point cron_next(cronexpr const & cex, std::chrono::system_clock::time_point const & time_point) { |  | ||||||
|      return std::chrono::system_clock::from_time_t(cron_next<Traits>(cex, std::chrono::system_clock::to_time_t(time_point))); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @@ -83,13 +83,12 @@ namespace OpenWifi { | |||||||
|     InventoryDB::InventoryDB( OpenWifi::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L) : |     InventoryDB::InventoryDB( OpenWifi::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L) : | ||||||
|         DB(T, "inventory", InventoryDB_Fields, InventoryDB_Indexes, P, L, "inv") {} |         DB(T, "inventory", InventoryDB_Fields, InventoryDB_Indexes, P, L, "inv") {} | ||||||
|  |  | ||||||
|     bool InventoryDB::CreateFromConnection( const std::string &SerialNumberRaw, |     bool InventoryDB::CreateFromConnection( const std::string &SerialNumber, | ||||||
|                                             const std::string &ConnectionInfo, |                                             const std::string &ConnectionInfo, | ||||||
|                                             const std::string &DeviceType, |                                             const std::string &DeviceType, | ||||||
|                                             const std::string &Locale) { |                                             const std::string &Locale) { | ||||||
|  |  | ||||||
|         ProvObjects::InventoryTag   ExistingDevice; |         ProvObjects::InventoryTag   ExistingDevice; | ||||||
|         auto SerialNumber = Poco::toLower(SerialNumberRaw); |  | ||||||
|         if(!GetRecord("serialNumber",SerialNumber,ExistingDevice)) { |         if(!GetRecord("serialNumber",SerialNumber,ExistingDevice)) { | ||||||
|             ProvObjects::InventoryTag   NewDevice; |             ProvObjects::InventoryTag   NewDevice; | ||||||
|             uint64_t Now = OpenWifi::Now(); |             uint64_t Now = OpenWifi::Now(); | ||||||
| @@ -224,7 +223,7 @@ namespace OpenWifi { | |||||||
|             ProvObjects::DeviceRules    Rules; |             ProvObjects::DeviceRules    Rules; | ||||||
|             std::string     SerialNumber = Utils::IntToSerialNumber(i); |             std::string     SerialNumber = Utils::IntToSerialNumber(i); | ||||||
|             if(EvaluateDeviceSerialNumberRules(SerialNumber,Rules)) { |             if(EvaluateDeviceSerialNumberRules(SerialNumber,Rules)) { | ||||||
|                 if(Rules.rrm!="no" && Rules.rrm!="inherit") |                 if(Rules.rrm=="yes") | ||||||
|                     DeviceList.push_back(SerialNumber); |                     DeviceList.push_back(SerialNumber); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -97,7 +97,7 @@ if [ -z ${OWPROV_OVERRIDE+x} ]; then | |||||||
| 		port="$(echo $hostport | sed -e 's,^.*:,:,g' -e 's,.*:\([0-9]*\).*,\1,g' -e 's,[^0-9],,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-)" | 		path="$(echo $url | grep / | cut -d/ -f2-)" | ||||||
| 		export OWPROV=${url} | 		export OWPROV=${url} | ||||||
| 		echo "Using PROV=${OWPROV}..." | 		echo "Using ${OWPROV}..." | ||||||
| 	else | 	else | ||||||
| 		echo "OWPROV endpoint is not found:" | 		echo "OWPROV endpoint is not found:" | ||||||
| 		jq < ${result_file} | 		jq < ${result_file} | ||||||
| @@ -108,33 +108,6 @@ else | |||||||
| fi | fi | ||||||
| } | } | ||||||
|  |  | ||||||
| setrrm() { |  | ||||||
|     if [ -z ${OWRRM_OVERRIDE+x} ]; then |  | ||||||
|     curl  ${FLAGS} -X GET "https://${OWSEC}/api/v1/systemEndpoints" \ |  | ||||||
|         -H "Accept: application/json" \ |  | ||||||
|         -H "Content-Type: application/json" \ |  | ||||||
|         -H "Authorization: Bearer ${token}"  > ${result_file} |  | ||||||
|     rawurl="$(cat ${result_file} | jq -r '.endpoints[] | select( .type == "owrrm" ) | .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 OWRRM=${url} |  | ||||||
|     echo "Using RRM=${OWRRM}..." |  | ||||||
|     else |  | ||||||
|     echo "OWRRM endpoint is not found:" |  | ||||||
|     jq < ${result_file} |  | ||||||
|     exit 1 |  | ||||||
|     fi |  | ||||||
|     else |  | ||||||
|     export OWRRM=${OWRRM_OVERRIDE} |  | ||||||
|     fi |  | ||||||
| } |  | ||||||
|  |  | ||||||
| logout() { | logout() { | ||||||
|   curl  ${FLAGS} -X DELETE "https://${OWSEC}/api/v1/oauth2/${token}" \ |   curl  ${FLAGS} -X DELETE "https://${OWSEC}/api/v1/oauth2/${token}" \ | ||||||
|         -H "Content-Type: application/json" \ |         -H "Content-Type: application/json" \ | ||||||
| @@ -534,24 +507,6 @@ getvenuedevices() { | |||||||
|     jq < ${result_file} |     jq < ${result_file} | ||||||
| } | } | ||||||
|  |  | ||||||
| listrrmalgos() { |  | ||||||
|     setrrm |  | ||||||
|     curl    ${FLAGS} -X GET "http://${OWRRM}/api/v1/algorithms" \ |  | ||||||
|         -H "Content-Type: application/json" \ |  | ||||||
|         -H "Authorization: Bearer ${token}" \ |  | ||||||
|         -H "Accept: application/json" > ${result_file} |  | ||||||
|     jq < ${result_file} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| rrmprovider() { |  | ||||||
|     setrrm |  | ||||||
|     curl    ${FLAGS} -X GET "http://${OWRRM}/api/v1/provider" \ |  | ||||||
|         -H "Content-Type: application/json" \ |  | ||||||
|         -H "Authorization: Bearer ${token}" \ |  | ||||||
|         -H "Accept: application/json" > ${result_file} |  | ||||||
|     jq < ${result_file} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| shopt -s nocasematch | shopt -s nocasematch | ||||||
| case "$1" in | case "$1" in | ||||||
|     "login") login; echo "You are logged in..."  ; logout ;; |     "login") login; echo "You are logged in..."  ; logout ;; | ||||||
| @@ -600,8 +555,6 @@ case "$1" in | |||||||
|     "getsubdevs") login; getsubdevs $2; logout;; |     "getsubdevs") login; getsubdevs $2; logout;; | ||||||
|     "listvenues") login; listvenues $2; logout;; |     "listvenues") login; listvenues $2; logout;; | ||||||
|     "getvenuedevices") login; getvenuedevices $2; logout;; |     "getvenuedevices") login; getvenuedevices $2; logout;; | ||||||
|     "listrrmalgos") login; listrrmalgos; logout;; |  | ||||||
|     "rrmprovider") login; rrmprovider; logout;; |  | ||||||
|     *) help ;; |     *) help ;; | ||||||
| esac | esac | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user