mirror of
				https://github.com/Telecominfraproject/wlan-cloud-ucentralfms.git
				synced 2025-10-30 02:12:22 +00:00 
			
		
		
		
	Compare commits
	
		
			282 Commits
		
	
	
		
			v2.5.2
			...
			v2.8.0-RC2
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 7760230f02 | ||
|   | 6223ade0f6 | ||
|   | 64e6a6f70a | ||
|   | c67367ec4d | ||
|   | fe3c5d7c4a | ||
|   | da52cf5823 | ||
|   | 3c8d8697e0 | ||
|   | 7b0c61ff5e | ||
|   | e9a9416332 | ||
|   | 2255988b4c | ||
|   | 106c9353fc | ||
|   | 6c7fc8e310 | ||
|   | e151b45d51 | ||
|   | 1584ff1ebe | ||
|   | 82ccb08d6b | ||
|   | 82b184a79f | ||
|   | 71c37edde7 | ||
|   | 0c8fa44935 | ||
|   | 32714f95b6 | ||
|   | 13cbf8c603 | ||
|   | 48c95c3101 | ||
|   | 857055750f | ||
|   | 96b22ef09b | ||
|   | acff9afff2 | ||
|   | 1e250be2cd | ||
|   | 93a8624645 | ||
|   | b9bf57e1f2 | ||
|   | f203622299 | ||
|   | 698282658c | ||
|   | 5baacac9bf | ||
|   | 8ca4531c99 | ||
|   | a6e0cd453b | ||
|   | 5e39f63fd2 | ||
|   | 9b081c6924 | ||
|   | be2150d845 | ||
|   | 2d6f1879f5 | ||
|   | e870a381a8 | ||
|   | 0cc0d0204e | ||
|   | 498e55f933 | ||
|   | a9b3cb9821 | ||
|   | 29736da681 | ||
|   | 28f890002b | ||
|   | 0ec0a4fd95 | ||
|   | 6dce398ddc | ||
|   | eca0e8883a | ||
|   | 43cc667a59 | ||
|   | a084230cbd | ||
|   | 59c5ed51c0 | ||
|   | 1128fd3c23 | ||
|   | ee4f1fac93 | ||
|   | a1a600de77 | ||
|   | 9d64c2dabd | ||
|   | 4f6c9728ef | ||
|   | 167933e422 | ||
|   | f661bb579a | ||
|   | 1e14eb1611 | ||
|   | dae57a7492 | ||
|   | d30014372b | ||
|   | a9f37ae30d | ||
|   | 23bc11f26e | ||
|   | caa25f0a1e | ||
|   | b86e80be6d | ||
|   | 880a14b651 | ||
|   | fa5d1b982a | ||
|   | e803885d24 | ||
|   | 17b7e1de59 | ||
|   | 15d7ae635c | ||
|   | 244423132e | ||
|   | ad149a8e40 | ||
|   | 59020f8809 | ||
|   | 4c5dbea4fb | ||
|   | 8fa42ab75d | ||
|   | ad1d7301a1 | ||
|   | 6ad2f0ba1b | ||
|   | aad7cf752a | ||
|   | ff8fa5e625 | ||
|   | 6e38083912 | ||
|   | 98509fdab7 | ||
|   | 2bbaf44e88 | ||
|   | c187710ddf | ||
|   | c04a0c47ba | ||
|   | 7492e68a73 | ||
|   | 912903cc49 | ||
|   | 2a1cc8dc2a | ||
|   | 4e344eac03 | ||
|   | 9be24a146d | ||
|   | 2b9e934ac1 | ||
|   | db5dffe2b8 | ||
|   | e527983fa6 | ||
|   | e0ef8d1dbf | ||
|   | bc1a2b2ab8 | ||
|   | 06da583a6d | ||
|   | 39e8fbc863 | ||
|   | 88adcf6e78 | ||
|   | dc6455813a | ||
|   | fed5739afc | ||
|   | f2fd761558 | ||
|   | 139c3ba217 | ||
|   | ec8d304ae7 | ||
|   | 578580ad95 | ||
|   | 5e719c9b90 | ||
|   | 96b59c700a | ||
|   | bbaa5da556 | ||
|   | 5df2701c21 | ||
|   | ebd890dc79 | ||
|   | 23729bdde0 | ||
|   | f02d932059 | ||
|   | c450328e05 | ||
|   | cf461eadb0 | ||
|   | 73ee40acde | ||
|   | acd5800206 | ||
|   | c5b613ecff | ||
|   | 892a756aae | ||
|   | ccf1834c0b | ||
|   | f5c4b3b37b | ||
|   | 33f8d5afb2 | ||
|   | 8b37fe2c8c | ||
|   | 66433efb61 | ||
|   | 085aa109c3 | ||
|   | 63043acce8 | ||
|   | 2612a74567 | ||
|   | 38e86e4de6 | ||
|   | d0ba0eac22 | ||
|   | 0a59afa1fa | ||
|   | 7df6151da8 | ||
|   | 6351082acf | ||
|   | de6abed9ae | ||
|   | ba97fd59df | ||
|   | 8ef97f6300 | ||
|   | f24fb790eb | ||
|   | 1c786ec360 | ||
|   | c001eb77d8 | ||
|   | 7e7ddd953f | ||
|   | 477f59ca9b | ||
|   | e0548a2696 | ||
|   | a900b7e28e | ||
|   | ef63dcd5b9 | ||
|   | 946c4bc1df | ||
|   | 7fb5be32be | ||
|   | 7cc719fcd6 | ||
|   | 9ea29b6088 | ||
|   | 24e25daa11 | ||
|   | 9a5063b6cf | ||
|   | f0188afdc1 | ||
|   | f5c1f808d8 | ||
|   | eb2e039d48 | ||
|   | adafc84cb8 | ||
|   | 2eff4174c3 | ||
|   | dcc39392cf | ||
|   | f19276e63e | ||
|   | 9ba9b82c31 | ||
|   | 602ca394ed | ||
|   | 29d961323b | ||
|   | 0530f255b4 | ||
|   | 6ff02c5f06 | ||
|   | cfb0e6e219 | ||
|   | bb19c0e70b | ||
|   | d197323dba | ||
|   | a374baceb8 | ||
|   | 63fb788653 | ||
|   | 8ccb95bf45 | ||
|   | 4433e1b189 | ||
|   | c592af964a | ||
|   | 4fef783d30 | ||
|   | 2267fe7fc0 | ||
|   | 354c17ed3a | ||
|   | bfb9018642 | ||
|   | e075b8d7ab | ||
|   | 7328728006 | ||
|   | c61236d613 | ||
|   | fc09604442 | ||
|   | 72aeafde48 | ||
|   | f55705ff64 | ||
|   | adfd583f9f | ||
|   | e0b160cdc4 | ||
|   | b18f178601 | ||
|   | 1bf2d5c413 | ||
|   | 1908217e38 | ||
|   | 8dc2c4645d | ||
|   | 63d5d8ac92 | ||
|   | 5dd1a87376 | ||
|   | 7a3827a425 | ||
|   | 672d92ad96 | ||
|   | aef714855b | ||
|   | 98ef247fab | ||
|   | 1831bb59c7 | ||
|   | 714742cf58 | ||
|   | dec87434d2 | ||
|   | 83e957fd2e | ||
|   | 3cc000c4c3 | ||
|   | 60e5d45e74 | ||
|   | 15215a4c7d | ||
|   | 2d3717bb98 | ||
|   | ea0caa0815 | ||
|   | e46170f138 | ||
|   | 9387c82b0d | ||
|   | b1a480fa6e | ||
|   | 25b841915f | ||
|   | 48d20ad443 | ||
|   | b908255a8d | ||
|   | c6baee3c7e | ||
|   | 1116245f78 | ||
|   | 833ef911b7 | ||
|   | fcc93770bd | ||
|   | 496eabf20c | ||
|   | 3819ce4fbe | ||
|   | 36f6f8088b | ||
|   | ec8b32ed0c | ||
|   | f27f5078b4 | ||
|   | 400ee5d767 | ||
|   | bea6a172ac | ||
|   | 51abcf9f0d | ||
|   | 7c39080ba2 | ||
|   | 932dd65df4 | ||
|   | 7e1dbea118 | ||
|   | 762b3ac60d | ||
|   | d3eebf5b89 | ||
|   | 6e35848cd5 | ||
|   | 8afbec7c64 | ||
|   | 70b63704c0 | ||
|   | 773c72a0cc | ||
|   | 2904d7c258 | ||
|   | d05aec1276 | ||
|   | d03f767a1f | ||
|   | 9b5f30ce91 | ||
|   | 3067d5c90b | ||
|   | 7a13576746 | ||
|   | 85d8667da5 | ||
|   | a2a0aa2e49 | ||
|   | 902c5e2837 | ||
|   | caf86af949 | ||
|   | 2a90955d3c | ||
|   | d0e7bbfb09 | ||
|   | cb1b843c87 | ||
|   | 0af7ee372f | ||
|   | 35ef1d5182 | ||
|   | ea66f54339 | ||
|   | 17052b1841 | ||
|   | c5649f4b42 | ||
|   | 1836265c08 | ||
|   | 9bebaea65f | ||
|   | 45b5e77060 | ||
|   | b018d6c941 | ||
|   | c5135d4d72 | ||
|   | 66edc4026e | ||
|   | e6d8d4b7e5 | ||
|   | 7eb724ffe0 | ||
|   | 6e6d39a309 | ||
|   | f4944c1ab9 | ||
|   | d9bf707579 | ||
|   | 6b09a373d2 | ||
|   | 084c9c2a38 | ||
|   | 5f5f8f6af5 | ||
|   | 5f922377d3 | ||
|   | 208fd05389 | ||
|   | 0055320331 | ||
|   | fc4e66418a | ||
|   | 3b394627ba | ||
|   | 21815a6f85 | ||
|   | 24f93004d5 | ||
|   | 2023ca4cf9 | ||
|   | 694191f1d9 | ||
|   | 27bad516d2 | ||
|   | 9b1cae679d | ||
|   | a53fc99753 | ||
|   | 1b0c11cbe0 | ||
|   | 68028c1137 | ||
|   | 8d63fa2bda | ||
|   | 0c015595d9 | ||
|   | b17fd923ed | ||
|   | b6f035b54e | ||
|   | c22765896e | ||
|   | 4b0d2e6a18 | ||
|   | 75d3ee7722 | ||
|   | 2a5d864b2a | ||
|   | 419dd9d12f | ||
|   | 7474727d91 | ||
|   | 2e842918bc | ||
|   | 0f36f15b64 | ||
|   | 0262d00b0d | ||
|   | da2f8341db | ||
|   | 47b014d502 | 
							
								
								
									
										43
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										43
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							| @@ -13,6 +13,7 @@ on: | ||||
|   pull_request: | ||||
|     branches: | ||||
|       - main | ||||
|       - 'release/*' | ||||
|  | ||||
| defaults: | ||||
|   run: | ||||
| @@ -26,7 +27,7 @@ jobs: | ||||
|       DOCKER_REGISTRY_USERNAME: ucentral | ||||
|     steps: | ||||
|     - name: Checkout actions repo | ||||
|       uses: actions/checkout@v2 | ||||
|       uses: actions/checkout@v3 | ||||
|       with: | ||||
|         repository: Telecominfraproject/.github | ||||
|         path: github | ||||
| @@ -39,6 +40,16 @@ jobs: | ||||
|         registry_user: ucentral | ||||
|         registry_password: ${{ secrets.DOCKER_REGISTRY_PASSWORD }} | ||||
|  | ||||
|     - name: Notify on failure via Slack | ||||
|       if: failure() && github.ref == 'refs/heads/main' | ||||
|       uses: rtCamp/action-slack-notify@v2 | ||||
|       env: | ||||
|         SLACK_USERNAME: GitHub Actions failure notifier | ||||
|         SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} | ||||
|         SLACK_COLOR: "${{ job.status }}" | ||||
|         SLACK_ICON: https://raw.githubusercontent.com/quintessence/slack-icons/master/images/github-logo-slack-icon.png | ||||
|         SLACK_TITLE: Docker build failed for OWFMS service | ||||
|  | ||||
|   trigger-testing: | ||||
|     if: startsWith(github.ref, 'refs/pull/') | ||||
|     runs-on: ubuntu-latest | ||||
| @@ -47,11 +58,11 @@ jobs: | ||||
|     - name: Get base branch name and set as output | ||||
|       id: get_base_branch | ||||
|       run: | | ||||
|         echo ::set-output name=branch::$(echo ${GITHUB_BASE_REF##*/}) | ||||
|         echo ::set-output name=owgw_branch::$(echo ${GITHUB_BASE_REF##*/} | sed 's/main/master/g') | ||||
|         echo "branch=$(echo ${GITHUB_BASE_REF##*/})" >> $GITHUB_OUTPUT | ||||
|         echo "owgw_branch=$(echo ${GITHUB_BASE_REF##*/} | sed 's/main/master/g')" >> $GITHUB_OUTPUT | ||||
|  | ||||
|     - name: Checkout actions repo | ||||
|       uses: actions/checkout@v2 | ||||
|       uses: actions/checkout@v3 | ||||
|       with: | ||||
|         repository: Telecominfraproject/.github | ||||
|         path: github | ||||
| @@ -67,4 +78,26 @@ jobs: | ||||
|         workflow: ow_docker-compose.yml | ||||
|         token: ${{ secrets.WLAN_TESTING_PAT }} | ||||
|         ref: master | ||||
|         inputs: '{"owgw_version": "${{ env.OWGW_BASE_BRANCH }}", "owgwui_version": "${{ env.BASE_BRANCH }}", "owsec_version": "${{ env.BASE_BRANCH }}", "owfms_version": "${{ github.sha }}", "owprov_version": "main", "owprovui_version": "main"}' | ||||
|         inputs: '{"deployment_version": "${{ env.BASE_BRANCH }}", "owgw_version": "${{ env.OWGW_BASE_BRANCH }}", "owsec_version": "${{ env.BASE_BRANCH }}", "owfms_version": "${{ github.sha }}", "owprov_version": "${{ env.BASE_BRANCH }}", "owanalytics_version": "${{ env.BASE_BRANCH }}", "owsub_version": "${{ env.BASE_BRANCH }}", "microservice": "owfms"}' | ||||
|  | ||||
|   trigger-deploy-to-dev: | ||||
|     runs-on: ubuntu-latest | ||||
|     if: github.ref == 'refs/heads/main' | ||||
|     needs: | ||||
|       - docker | ||||
|     steps: | ||||
|     - name: Checkout actions repo | ||||
|       uses: actions/checkout@v3 | ||||
|       with: | ||||
|         repository: Telecominfraproject/.github | ||||
|         path: github | ||||
|  | ||||
|     - name: Trigger deployment of the latest version to dev instance and wait for result | ||||
|       uses: ./github/composite-actions/trigger-workflow-and-wait | ||||
|       with: | ||||
|         owner: Telecominfraproject | ||||
|         repo: wlan-testing | ||||
|         workflow: ucentralgw-dev-deployment.yaml | ||||
|         token: ${{ secrets.WLAN_TESTING_PAT }} | ||||
|         ref: master | ||||
|         inputs: '{"force_latest": "true"}' | ||||
|   | ||||
							
								
								
									
										9
									
								
								.github/workflows/cleanup.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								.github/workflows/cleanup.yml
									
									
									
									
										vendored
									
									
								
							| @@ -4,6 +4,7 @@ on: | ||||
|   pull_request: | ||||
|     branches: | ||||
|       - main | ||||
|       - 'release/*' | ||||
|     types: [ closed ] | ||||
|  | ||||
| defaults: | ||||
| @@ -16,4 +17,10 @@ jobs: | ||||
|     steps: | ||||
|       - run: | | ||||
|           export PR_BRANCH_TAG=$(echo ${GITHUB_HEAD_REF#refs/heads/} | tr '/' '-') | ||||
|           curl -uucentral:${{ secrets.DOCKER_REGISTRY_PASSWORD }} -X DELETE "https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral/owfms/$PR_BRANCH_TAG" | ||||
|  | ||||
|           if [[ ! $PR_BRANCH_TAG =~ (main|master|release-*) ]]; then | ||||
|             echo "PR branch is $PR_BRANCH_TAG, deleting Docker image" | ||||
|             curl -s -uucentral:${{ secrets.DOCKER_REGISTRY_PASSWORD }} -X DELETE "https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral/owfms/$PR_BRANCH_TAG" | ||||
|           else | ||||
|             echo "PR branch is $PR_BRANCH_TAG, not deleting Docker image" | ||||
|           fi | ||||
|   | ||||
							
								
								
									
										41
									
								
								.github/workflows/openapi-pages.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								.github/workflows/openapi-pages.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | ||||
| name: Update OpenAPI docs on GitHub Pages | ||||
|  | ||||
| on: | ||||
|   push: | ||||
|     paths: | ||||
|       - 'openapi/**' | ||||
|     branches: | ||||
|       - main | ||||
|   workflow_dispatch: | ||||
|  | ||||
| defaults: | ||||
|   run: | ||||
|     shell: bash | ||||
|  | ||||
| jobs: | ||||
|   docsgen: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - uses: actions/checkout@v3 | ||||
|  | ||||
|       - name: Generate static HTML page with docs from OpenAPI definition | ||||
|         run: | | ||||
|           docker run --rm -v "${PWD}:/local" openapitools/openapi-generator-cli:v6.2.1 generate -i https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentralfms/main/openapi/owfms.yaml -g html2 --skip-validate-spec -o /local/ | ||||
|  | ||||
|       - name: Update OpenAPI docs | ||||
|         run: | | ||||
|           mkdir tmp-docs | ||||
|           mv index.html tmp-docs/index.html | ||||
|           mkdir -p ~/.ssh | ||||
|           ssh-keyscan -H github.com >> ~/.ssh/known_hosts | ||||
|           echo https://tip-automation:${{ secrets.GIT_PUSH_PAT }}@github.com > ~/.git-credentials | ||||
|           git config --global credential.helper store | ||||
|           git config --global user.email "tip-automation@telecominfraproject.com" | ||||
|           git config --global user.name "TIP Automation User" | ||||
|           git pull | ||||
|           git checkout gh-pages || git checkout -b gh-pages | ||||
|           rm -rf docs | ||||
|           mv tmp-docs docs | ||||
|           git add docs | ||||
|           git commit -m'Update OpenAPI docs for GitHub pages' | ||||
|           git push --set-upstream origin gh-pages | ||||
							
								
								
									
										46
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| name: Release chart package | ||||
|  | ||||
| on: | ||||
|   push: | ||||
|     tags: | ||||
|       - 'v*' | ||||
|  | ||||
| defaults: | ||||
|   run: | ||||
|     shell: bash | ||||
|  | ||||
| jobs: | ||||
|   helm-package: | ||||
|     runs-on: ubuntu-20.04 | ||||
|     env: | ||||
|       HELM_REPO_URL: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/ | ||||
|       HELM_REPO_USERNAME: ucentral | ||||
|     steps: | ||||
|       - name: Checkout uCentral assembly chart repo | ||||
|         uses: actions/checkout@v2 | ||||
|         with: | ||||
|           path: wlan-cloud-ucentralfms | ||||
|  | ||||
|       - name: Build package | ||||
|         working-directory: wlan-cloud-ucentralfms/helm | ||||
|         run: | | ||||
|           helm plugin install https://github.com/aslafy-z/helm-git --version 0.10.0 | ||||
|           helm repo add bitnami https://charts.bitnami.com/bitnami | ||||
|           helm repo update | ||||
|           helm dependency update | ||||
|           mkdir dist | ||||
|           helm package . -d dist | ||||
|  | ||||
|       - name: Generate GitHub release body | ||||
|         working-directory: wlan-cloud-ucentralfms/helm | ||||
|         run: | | ||||
|           pip3 install yq -q | ||||
|           echo "Docker image - tip-tip-wlan-cloud-ucentral.jfrog.io/owfms:$GITHUB_REF_NAME" > release.txt | ||||
|           echo "Helm charted may be attached to this release" >> release.txt | ||||
|           echo "Deployment artifacts may be found in https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/tree/$GITHUB_REF_NAME" >> release.txt | ||||
|  | ||||
|       - name: Create GitHub release | ||||
|         uses: softprops/action-gh-release@v1 | ||||
|         with: | ||||
|           body_path: wlan-cloud-ucentralfms/helm/release.txt | ||||
|           files: wlan-cloud-ucentralfms/helm/dist/* | ||||
| @@ -1,5 +1,5 @@ | ||||
| cmake_minimum_required(VERSION 3.13) | ||||
| project(owfms VERSION 2.5.0) | ||||
| project(owfms VERSION 2.8.0) | ||||
|  | ||||
| set(CMAKE_CXX_STANDARD 17) | ||||
|  | ||||
| @@ -27,29 +27,25 @@ endif() | ||||
|  | ||||
| find_package(Git QUIET) | ||||
| if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") | ||||
|     execute_process(COMMAND ${GIT_EXECUTABLE} describe --always --tags | ||||
|     execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD | ||||
|             WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} | ||||
|             RESULT_VARIABLE GIT_RESULT | ||||
|             OUTPUT_VARIABLE GIT_HASH) | ||||
|     if(NOT GIT_RESULT EQUAL "0") | ||||
|         message(FATAL_ERROR "git describe --always --tags failed with ${GIT_RESULT}") | ||||
|         message(FATAL_ERROR "git rev-parse --short HEAD failed with ${GIT_RESULT}") | ||||
|     endif() | ||||
|     string(REGEX REPLACE "\n$" "" GIT_HASH "${GIT_HASH}") | ||||
| endif() | ||||
|  | ||||
| add_definitions(-DAWS_CUSTOM_MEMORY_MANAGEMENT) | ||||
| # set(BUILD_SHARED_LIBS 1) | ||||
| # add_definitions(-DAWS_CUSTOM_MEMORY_MANAGEMENT) | ||||
|  | ||||
| set(BUILD_SHARED_LIBS 1) | ||||
| add_definitions(-DAWS_CUSTOM_MEMORY_MANAGEMENT) | ||||
|  | ||||
| set(Boost_USE_STATIC_LIBS OFF) | ||||
| set(Boost_USE_MULTITHREADED ON) | ||||
| set(Boost_USE_STATIC_RUNTIME OFF) | ||||
|  | ||||
| find_package(Boost      REQUIRED system) | ||||
| find_package(OpenSSL    REQUIRED) | ||||
| find_package(AWSSDK     REQUIRED COMPONENTS s3) | ||||
| find_package(fmt        REQUIRED) | ||||
| find_package(ZLIB       REQUIRED) | ||||
| find_package(Poco       REQUIRED COMPONENTS Crypto JWT Net Util NetSSL Data DataSQLite) | ||||
| find_package(AWSSDK     REQUIRED COMPONENTS s3) | ||||
| find_package(ZLIB       REQUIRED) | ||||
|  | ||||
| if(SMALL_BUILD) | ||||
|     find_package(Poco REQUIRED COMPONENTS Crypto JWT Net Util NetSSL Data DataSQLite) | ||||
| @@ -64,6 +60,14 @@ 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) | ||||
|  | ||||
| add_compile_options(-Wall -Wextra) | ||||
| add_definitions(-DPOCO_LOG_DEBUG="1") | ||||
|  | ||||
| if(ASAN) | ||||
|     add_compile_options(-fsanitize=address) | ||||
|     add_link_options(-fsanitize=address) | ||||
| endif() | ||||
|  | ||||
| add_executable( owfms | ||||
|         build | ||||
|         src/ow_version.h.in | ||||
| @@ -72,14 +76,55 @@ add_executable( owfms | ||||
|         src/framework/MicroService.h | ||||
|         src/framework/OpenWifiTypes.h | ||||
|         src/framework/orm.h | ||||
|         src/framework/RESTAPI_errors.h | ||||
|         src/framework/RESTAPI_protocol.h | ||||
|         src/framework/StorageClass.h | ||||
|         src/framework/uCentral_Protocol.h | ||||
|         src/framework/MicroServiceErrorHandler.h | ||||
|         src/framework/UI_WebSocketClientServer.cpp | ||||
|         src/framework/UI_WebSocketClientServer.h | ||||
|         src/framework/UI_WebSocketClientNotifications.cpp | ||||
|         src/framework/UI_WebSocketClientNotifications.h | ||||
|         src/framework/utils.h | ||||
|         src/framework/utils.cpp | ||||
|         src/framework/AppServiceRegistry.h | ||||
|         src/framework/SubSystemServer.cpp | ||||
|         src/framework/SubSystemServer.h | ||||
|         src/framework/RESTAPI_utils.h | ||||
|         src/framework/AuthClient.cpp | ||||
|         src/framework/AuthClient.h | ||||
|         src/framework/MicroServiceNames.h | ||||
|         src/framework/MicroServiceFuncs.h | ||||
|         src/framework/OpenAPIRequests.cpp | ||||
|         src/framework/OpenAPIRequests.h | ||||
|         src/framework/MicroServiceFuncs.cpp | ||||
|         src/framework/ALBserver.cpp | ||||
|         src/framework/ALBserver.h | ||||
|         src/framework/KafkaManager.cpp | ||||
|         src/framework/KafkaManager.h | ||||
|         src/framework/RESTAPI_RateLimiter.h | ||||
|         src/framework/WebSocketLogger.h | ||||
|         src/framework/RESTAPI_GenericServerAccounting.h | ||||
|         src/framework/RESTAPI_SystemConfiguration.h | ||||
|         src/framework/CIDR.h | ||||
|         src/framework/RESTAPI_Handler.cpp | ||||
|         src/framework/RESTAPI_Handler.h | ||||
|         src/framework/RESTAPI_ExtServer.h | ||||
|         src/framework/RESTAPI_ExtServer.cpp | ||||
|         src/framework/RESTAPI_IntServer.cpp | ||||
|         src/framework/RESTAPI_IntServer.h | ||||
|         src/framework/RESTAPI_SystemCommand.h | ||||
|         src/framework/RESTAPI_WebSocketServer.h | ||||
|         src/framework/EventBusManager.cpp | ||||
|         src/framework/EventBusManager.h | ||||
|         src/framework/RESTAPI_PartHandler.h | ||||
|         src/framework/MicroService.cpp | ||||
|         src/framework/MicroServiceExtra.h | ||||
|         src/RESTObjects/RESTAPI_SecurityObjects.h src/RESTObjects/RESTAPI_SecurityObjects.cpp | ||||
|         src/RESTObjects/RESTAPI_ProvObjects.cpp src/RESTObjects/RESTAPI_ProvObjects.h | ||||
|         src/RESTObjects/RESTAPI_GWobjects.h src/RESTObjects/RESTAPI_GWobjects.cpp | ||||
|         src/RESTObjects/RESTAPI_FMSObjects.h src/RESTObjects/RESTAPI_FMSObjects.cpp | ||||
|         src/RESTObjects/RESTAPI_CertObjects.cpp src/RESTObjects/RESTAPI_CertObjects.h | ||||
|         src/RESTObjects/RESTAPI_OWLSobjects.cpp src/RESTObjects/RESTAPI_OWLSobjects.h | ||||
|         src/RESTObjects/RESTAPI_ProvObjects.cpp src/RESTObjects/RESTAPI_ProvObjects.h | ||||
|         src/RESTObjects/RESTAPI_AnalyticsObjects.cpp src/RESTObjects/RESTAPI_AnalyticsObjects.h | ||||
|         src/RESTObjects/RESTAPI_SubObjects.cpp src/RESTObjects/RESTAPI_SubObjects.h | ||||
|         src/RESTAPI/RESTAPI_firmwaresHandler.cpp src/RESTAPI/RESTAPI_firmwaresHandler.h | ||||
|         src/RESTAPI/RESTAPI_firmwareHandler.cpp src/RESTAPI/RESTAPI_firmwareHandler.h | ||||
|         src/RESTAPI/RESTAPI_historyHandler.cpp src/RESTAPI/RESTAPI_historyHandler.h | ||||
| @@ -92,7 +137,6 @@ add_executable( owfms | ||||
|         src/Daemon.cpp src/Daemon.h | ||||
|         src/StorageService.cpp src/StorageService.h | ||||
|         src/ManifestCreator.cpp src/ManifestCreator.h | ||||
|         src/framework/MicroService.h | ||||
|         src/NewConnectionHandler.cpp src/NewConnectionHandler.h | ||||
|         src/LatestFirmwareCache.cpp src/LatestFirmwareCache.h | ||||
|         src/DeviceCache.cpp src/DeviceCache.h | ||||
| @@ -102,11 +146,16 @@ add_executable( owfms | ||||
|         src/NewCommandHandler.cpp src/NewCommandHandler.h | ||||
|         src/storage/orm_history.cpp src/storage/orm_history.h | ||||
|         src/storage/orm_firmwares.cpp src/storage/orm_firmwares.h | ||||
|         src/storage/orm_deviceInfo.cpp src/storage/orm_deviceInfo.h) | ||||
|         src/storage/orm_deviceInfo.cpp src/storage/orm_deviceInfo.h | ||||
|         src/RESTAPI/RESTAPI_deviceInformation_handler.cpp | ||||
|         src/RESTAPI/RESTAPI_deviceInformation_handler.h) | ||||
|  | ||||
| target_link_libraries(owfms PUBLIC | ||||
|         ${Poco_LIBRARIES} ${MySQL_LIBRARIES} | ||||
|         ${Boost_LIBRARIES} | ||||
|         ${ZLIB_LIBRARIES} ${AWSSDK_LINK_LIBRARIES} | ||||
|         CppKafka::cppkafka ) | ||||
| target_link_libraries( owfms PUBLIC | ||||
|         ${Poco_LIBRARIES} | ||||
|         ${MySQL_LIBRARIES} | ||||
|         ${ZLIB_LIBRARIES} | ||||
|         ${AWSSDK_LINK_LIBRARIES} | ||||
|         fmt::fmt | ||||
|         CppKafka::cppkafka | ||||
|     ) | ||||
|  | ||||
|   | ||||
							
								
								
									
										94
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						
									
										94
									
								
								Dockerfile
									
									
									
									
									
								
							| @@ -1,16 +1,21 @@ | ||||
| FROM alpine:3.15 AS build-base | ||||
| ARG DEBIAN_VERSION=11.5-slim | ||||
| ARG POCO_VERSION=poco-tip-v2 | ||||
| ARG CPPKAFKA_VERSION=tip-v1 | ||||
|  | ||||
| RUN apk add --update --no-cache \ | ||||
|     make cmake g++ git \ | ||||
|     unixodbc-dev postgresql-dev mariadb-dev \ | ||||
|     librdkafka-dev boost-dev openssl-dev \ | ||||
|     zlib-dev nlohmann-json \ | ||||
|     curl-dev | ||||
| FROM debian:$DEBIAN_VERSION AS build-base | ||||
|  | ||||
| RUN apt-get update && apt-get install --no-install-recommends -y \ | ||||
|     make cmake g++ git curl zip unzip pkg-config \ | ||||
|     libpq-dev libmariadb-dev libmariadbclient-dev-compat \ | ||||
|     librdkafka-dev libboost-all-dev libssl-dev \ | ||||
|     zlib1g-dev ca-certificates libcurl4-openssl-dev libfmt-dev | ||||
|  | ||||
| FROM build-base AS poco-build | ||||
|  | ||||
| ADD https://api.github.com/repos/stephb9959/poco/git/refs/heads/master version.json | ||||
| RUN git clone https://github.com/stephb9959/poco /poco | ||||
| ARG POCO_VERSION | ||||
|  | ||||
| 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 | ||||
| RUN mkdir cmake-build | ||||
| @@ -21,8 +26,10 @@ RUN cmake --build . --target install | ||||
|  | ||||
| FROM build-base AS cppkafka-build | ||||
|  | ||||
| ADD https://api.github.com/repos/stephb9959/cppkafka/git/refs/heads/master version.json | ||||
| RUN git clone https://github.com/stephb9959/cppkafka /cppkafka | ||||
| ARG CPPKAFKA_VERSION | ||||
|  | ||||
| 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 | ||||
| RUN mkdir cmake-build | ||||
| @@ -31,72 +38,47 @@ RUN cmake .. | ||||
| RUN cmake --build . --config Release -j8 | ||||
| RUN cmake --build . --target install | ||||
|  | ||||
| FROM build-base AS json-schema-validator-build | ||||
|  | ||||
| ADD https://api.github.com/repos/pboettch/json-schema-validator/git/refs/heads/master version.json | ||||
| RUN git clone https://github.com/pboettch/json-schema-validator /json-schema-validator | ||||
|  | ||||
| WORKDIR /json-schema-validator | ||||
| RUN mkdir cmake-build | ||||
| WORKDIR cmake-build | ||||
| RUN cmake .. | ||||
| RUN make | ||||
| RUN make install | ||||
|  | ||||
| FROM build-base AS aws-sdk-cpp-build | ||||
|  | ||||
| ADD https://api.github.com/repos/aws/aws-sdk-cpp/git/refs/heads/main version.json | ||||
| RUN git clone --recurse-submodules https://github.com/aws/aws-sdk-cpp /aws-sdk-cpp | ||||
|  | ||||
| WORKDIR /aws-sdk-cpp | ||||
| RUN mkdir cmake-build | ||||
| WORKDIR cmake-build | ||||
| RUN cmake .. -DBUILD_ONLY="sns;s3" \ | ||||
|              -DCMAKE_BUILD_TYPE=Release \ | ||||
|              -DCMAKE_CXX_FLAGS="-Wno-error=stringop-overflow -Wno-error=uninitialized" \ | ||||
|              -DAUTORUN_UNIT_TESTS=OFF | ||||
| RUN cmake --build . --config Release -j8 | ||||
| RUN cmake --build . --target install | ||||
|  | ||||
| FROM build-base AS owfms-build | ||||
|  | ||||
| ADD CMakeLists.txt build /owfms/ | ||||
| ADD overlays /owfms/overlays | ||||
| ADD cmake /owfms/cmake | ||||
| ADD src /owfms/src | ||||
| ADD .git /owfms/.git | ||||
| ARG VCPKG_VERSION=2022.11.14 | ||||
| RUN git clone --depth 1 --branch ${VCPKG_VERSION} https://github.com/microsoft/vcpkg && \ | ||||
|     ./vcpkg/bootstrap-vcpkg.sh && \ | ||||
|     mkdir /vcpkg/custom-triplets && \ | ||||
|     cp /vcpkg/triplets/x64-linux.cmake /vcpkg/custom-triplets/x64-linux.cmake && \ | ||||
|     sed -i 's/set(VCPKG_LIBRARY.*/set(VCPKG_LIBRARY_LINKAGE dynamic)/g' /vcpkg/custom-triplets/x64-linux.cmake && \ | ||||
|     ./vcpkg/vcpkg install aws-sdk-cpp[s3]:x64-linux json-schema-validator:x64-linux --overlay-triplets=/vcpkg/custom-triplets --overlay-ports=/owfms/overlays | ||||
|  | ||||
| COPY --from=poco-build /usr/local/include /usr/local/include | ||||
| COPY --from=poco-build /usr/local/lib /usr/local/lib | ||||
| COPY --from=cppkafka-build /usr/local/include /usr/local/include | ||||
| COPY --from=cppkafka-build /usr/local/lib /usr/local/lib | ||||
| COPY --from=json-schema-validator-build /usr/local/include /usr/local/include | ||||
| COPY --from=json-schema-validator-build /usr/local/lib /usr/local/lib | ||||
| COPY --from=aws-sdk-cpp-build /usr/local/include /usr/local/include | ||||
| COPY --from=aws-sdk-cpp-build /usr/local/lib /usr/local/lib | ||||
|  | ||||
| WORKDIR /owfms | ||||
| RUN mkdir cmake-build | ||||
| WORKDIR /owfms/cmake-build | ||||
| RUN cmake .. \ | ||||
|           -Dcrypto_LIBRARY=/usr/lib/libcrypto.so \ | ||||
|           -DBUILD_SHARED_LIBS=ON | ||||
| RUN cmake -DCMAKE_TOOLCHAIN_FILE=/vcpkg/scripts/buildsystems/vcpkg.cmake .. | ||||
| RUN cmake --build . --config Release -j8 | ||||
|  | ||||
| FROM alpine:3.15 | ||||
| FROM debian:$DEBIAN_VERSION | ||||
|  | ||||
| ENV OWFMS_USER=owfms \ | ||||
|     OWFMS_ROOT=/owfms-data \ | ||||
|     OWFMS_CONFIG=/owfms-data | ||||
|  | ||||
| RUN addgroup -S "$OWFMS_USER" && \ | ||||
|     adduser -S -G "$OWFMS_USER" "$OWFMS_USER" | ||||
| RUN useradd "$OWFMS_USER" | ||||
|  | ||||
| RUN mkdir /openwifi | ||||
| RUN mkdir -p "$OWFMS_ROOT" "$OWFMS_CONFIG" && \ | ||||
|     chown "$OWFMS_USER": "$OWFMS_ROOT" "$OWFMS_CONFIG" | ||||
|  | ||||
| RUN apk add --update --no-cache librdkafka su-exec gettext ca-certificates bash jq curl \ | ||||
|     mariadb-connector-c libpq unixodbc postgresql-client | ||||
| RUN apt-get update && apt-get install --no-install-recommends -y \ | ||||
|     librdkafka++1 gosu gettext ca-certificates bash jq curl wget \ | ||||
|     libmariadb-dev-compat libpq5 postgresql-client libfmt7 sqlite3 | ||||
|  | ||||
| COPY readiness_check /readiness_check | ||||
| COPY test_scripts/curl/cli /cli | ||||
| @@ -105,14 +87,14 @@ COPY owfms.properties.tmpl / | ||||
| COPY docker-entrypoint.sh / | ||||
| COPY wait-for-postgres.sh / | ||||
| RUN wget https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentral-deploy/main/docker-compose/certs/restapi-ca.pem \ | ||||
|     -O /usr/local/share/ca-certificates/restapi-ca-selfsigned.pem | ||||
|     -O /usr/local/share/ca-certificates/restapi-ca-selfsigned.crt | ||||
|  | ||||
| COPY --from=owfms-build /owfms/cmake-build/owfms /openwifi/owfms | ||||
| COPY --from=cppkafka-build /cppkafka/cmake-build/src/lib/* /usr/local/lib | ||||
| COPY --from=poco-build /poco/cmake-build/lib/* /usr/local/lib | ||||
| COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-core/libaws-cpp-sdk-core.so /usr/local/lib | ||||
| COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-s3/libaws-cpp-sdk-s3.so /usr/local/lib | ||||
| COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-sns/libaws-cpp-sdk-sns.so /usr/local/lib | ||||
| COPY --from=owfms-build /vcpkg/installed/x64-linux/lib/ /usr/local/lib/ | ||||
| COPY --from=cppkafka-build /cppkafka/cmake-build/src/lib/ /usr/local/lib/ | ||||
| COPY --from=poco-build /poco/cmake-build/lib/ /usr/local/lib/ | ||||
|  | ||||
| RUN ldconfig | ||||
|  | ||||
| EXPOSE 16004 17004 16104 | ||||
|  | ||||
|   | ||||
| @@ -5,6 +5,11 @@ The uCentralFMS is a micro-service part of the OpenWiFi ecosystem. uCentralFMS i | ||||
| to facilitate the task of upgrade and maintaining the proper firmware for all the devices  | ||||
| used in your OpenWiFi solution. You may either [build it](#building) or use the [Docker version](#docker). | ||||
|  | ||||
| ## OpenAPI | ||||
| You may get static page with OpenAPI docs generated from the definition on [GitHub Page](https://telecominfraproject.github.io/wlan-cloud-ucentralfms/). | ||||
|  | ||||
| Also you may use [Swagger UI](https://petstore.swagger.io/#/) with OpenAPI definition file raw link (i.e. [latest version file](https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentralfms/main/openapi/owfms.yaml)) to get interactive docs page. | ||||
|  | ||||
| ## Building | ||||
| In order to build the uCentralFMS, you will need to install its dependencies, which includes the following: | ||||
| - cmake | ||||
| @@ -216,4 +221,4 @@ s3.key =  ******************************************* | ||||
| s3.retry = 60 | ||||
| s3.bucket.uri = ucentral-ap-firmware.s3.amazonaws.com | ||||
|  | ||||
| ``` | ||||
| ``` | ||||
|   | ||||
| @@ -1,11 +1,11 @@ | ||||
| #!/bin/sh | ||||
| #!/bin/bash | ||||
| set -e | ||||
|  | ||||
| if [ "$SELFSIGNED_CERTS" = 'true' ]; then | ||||
|     update-ca-certificates | ||||
| fi | ||||
|  | ||||
| if [[ "$TEMPLATE_CONFIG" = 'true' && ! -f "$OWFMS_CONFIG"/owfms.properties ]]; then | ||||
| if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then | ||||
|   RESTAPI_HOST_ROOTCA=${RESTAPI_HOST_ROOTCA:-"\$OWFMS_ROOT/certs/restapi-ca.pem"} \ | ||||
|   RESTAPI_HOST_PORT=${RESTAPI_HOST_PORT:-"16004"} \ | ||||
|   RESTAPI_HOST_CERT=${RESTAPI_HOST_CERT:-"\$OWFMS_ROOT/certs/restapi-cert.pem"} \ | ||||
| @@ -22,6 +22,9 @@ if [[ "$TEMPLATE_CONFIG" = 'true' && ! -f "$OWFMS_CONFIG"/owfms.properties ]]; t | ||||
|   SYSTEM_URI_PRIVATE=${SYSTEM_URI_PRIVATE:-"https://localhost:17004"} \ | ||||
|   SYSTEM_URI_PUBLIC=${SYSTEM_URI_PUBLIC:-"https://localhost:16004"} \ | ||||
|   SYSTEM_URI_UI=${SYSTEM_URI_UI:-"http://localhost"} \ | ||||
|   SECURITY_RESTAPI_DISABLE=${SECURITY_RESTAPI_DISABLE:-"false"} \ | ||||
|   FIRMWAREDB_REFRESH=${FIRMWAREDB_REFRESH:-"86400"} \ | ||||
|   FIRMWAREDB_MAXAGE=${FIRMWAREDB_MAXAGE:-"90"} \ | ||||
|   S3_BUCKETNAME=${S3_BUCKETNAME:-"ucentral-ap-firmware"} \ | ||||
|   S3_REGION=${S3_REGION:-"us-east-1"} \ | ||||
|   S3_SECRET=${S3_SECRET:-"*******************************************"} \ | ||||
| @@ -29,6 +32,10 @@ if [[ "$TEMPLATE_CONFIG" = 'true' && ! -f "$OWFMS_CONFIG"/owfms.properties ]]; t | ||||
|   S3_BUCKET_URI=${S3_BUCKET_URI:-"ucentral-ap-firmware.s3.amazonaws.com"} \ | ||||
|   KAFKA_ENABLE=${KAFKA_ENABLE:-"true"} \ | ||||
|   KAFKA_BROKERLIST=${KAFKA_BROKERLIST:-"localhost:9092"} \ | ||||
|   KAFKA_SSL_CA_LOCATION=${KAFKA_SSL_CA_LOCATION:-""} \ | ||||
|   KAFKA_SSL_CERTIFICATE_LOCATION=${KAFKA_SSL_CERTIFICATE_LOCATION:-""} \ | ||||
|   KAFKA_SSL_KEY_LOCATION=${KAFKA_SSL_KEY_LOCATION:-""} \ | ||||
|   KAFKA_SSL_KEY_PASSWORD=${KAFKA_SSL_KEY_PASSWORD:-""} \ | ||||
|   STORAGE_TYPE=${STORAGE_TYPE:-"sqlite"} \ | ||||
|   STORAGE_TYPE_POSTGRESQL_HOST=${STORAGE_TYPE_POSTGRESQL_HOST:-"localhost"} \ | ||||
|   STORAGE_TYPE_POSTGRESQL_USERNAME=${STORAGE_TYPE_POSTGRESQL_USERNAME:-"owfms"} \ | ||||
| @@ -47,7 +54,7 @@ if [ "$1" = '/openwifi/owfms' -a "$(id -u)" = '0' ]; then | ||||
|     if [ "$RUN_CHOWN" = 'true' ]; then | ||||
|       chown -R "$OWFMS_USER": "$OWFMS_ROOT" "$OWFMS_CONFIG" | ||||
|     fi | ||||
|     exec su-exec "$OWFMS_USER" "$@" | ||||
|     exec gosu "$OWFMS_USER" "$@" | ||||
| fi | ||||
|  | ||||
| exec "$@" | ||||
|   | ||||
							
								
								
									
										2
									
								
								helm/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								helm/.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1 +1,3 @@ | ||||
| *.swp | ||||
| Chart.lock | ||||
| charts/ | ||||
|   | ||||
| @@ -70,7 +70,8 @@ The following table lists the configurable parameters of the chart and their def | ||||
| | persistence.size | string | Defines PV size | `'10Gi'` | | ||||
| | public_env_variables | hash | Defines list of environment variables to be passed to the Firmware | | | ||||
| | configProperties | hash | Configuration properties that should be passed to the application in `owfms.properties`. May be passed by key in set (i.e. `configProperties."rtty\.token"`) | | | ||||
| | certs | hash | Defines files (keys and certificates) that should be passed to the Firmware (PEM format is adviced to be used) (see `volumes.owfms` on where it is mounted) |  | | ||||
| | 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 Gateway (PEM format is adviced to be used) (see `volumes.owfms` 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, | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| {{- $root := . -}} | ||||
| {{- $storageType := index .Values.configProperties "storage.type" -}} | ||||
| --- | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| @@ -46,6 +47,39 @@ spec: | ||||
|             - -timeout | ||||
|             - 600s | ||||
|  | ||||
| {{- if eq $storageType "postgresql" }} | ||||
|         - name: wait-postgres | ||||
|           image: "{{ .Values.images.owfms.repository }}:{{ .Values.images.owfms.tag }}" | ||||
|           imagePullPolicy: {{ .Values.images.owfms.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 "owfms.fullname" $root }}-env | ||||
|                   key: {{ $key }} | ||||
|           {{- end }} | ||||
|           volumeMounts: | ||||
|           {{- range .Values.volumes.owfms }} | ||||
|           - name: {{ .name }} | ||||
|             mountPath: {{ .mountPath }} | ||||
|             {{- if .subPath }} | ||||
|             subPath: {{ .subPath }} | ||||
|             {{- end }} | ||||
|           {{- end }} | ||||
| {{- end }} | ||||
|  | ||||
|       containers: | ||||
|  | ||||
|         - name: owfms | ||||
| @@ -97,8 +131,10 @@ spec: | ||||
|             {{- toYaml . | nindent 12 }} | ||||
|           {{- end }} | ||||
|  | ||||
|       {{- with .Values.securityContext }} | ||||
|       securityContext: | ||||
|         fsGroup: 101 | ||||
|         {{- toYaml . | nindent 8 }} | ||||
|       {{- end }} | ||||
|  | ||||
|       imagePullSecrets: | ||||
|       {{- range $image, $imageValue := .Values.images }} | ||||
|   | ||||
| @@ -9,7 +9,7 @@ fullnameOverride: "" | ||||
| images: | ||||
|   owfms: | ||||
|     repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owfms | ||||
|     tag: v2.5.2 | ||||
|     tag: v2.8.0-RC2 | ||||
|     pullPolicy: Always | ||||
| #    regcred: | ||||
| #      registry: tip-tip-wlan-cloud-ucentral.jfrog.io | ||||
| @@ -71,7 +71,7 @@ volumes: | ||||
|       mountPath: /owfms-data/certs | ||||
|       volumeDefinition: | | ||||
|         secret: | ||||
|           secretName: {{ include "owfms.fullname" . }}-certs | ||||
|           secretName: {{ if .Values.existingCertsSecret }}{{ .Values.existingCertsSecret }}{{ else }}{{ include "owfms.fullname" . }}-certs{{ end }} | ||||
|     # Change this if you want to use another volume type | ||||
|     - name: persist | ||||
|       mountPath: /owfms-data/persist | ||||
| @@ -91,6 +91,9 @@ resources: {} | ||||
|   #  cpu: 100m | ||||
|   #  memory: 128Mi | ||||
|  | ||||
| securityContext: | ||||
|   fsGroup: 1000 | ||||
|  | ||||
| nodeSelector: {} | ||||
|  | ||||
| tolerations: [] | ||||
| @@ -144,7 +147,7 @@ configProperties: | ||||
|   s3.region: us-east-1 | ||||
|   s3.retry: 60 | ||||
|   s3.bucket.uri: ucentral-ap-firmware.s3.amazonaws.com | ||||
|   firmwaredb.refresh: 1800 | ||||
|   firmwaredb.refresh: 86400 | ||||
|   # ALB | ||||
|   alb.enable: "true" | ||||
|   alb.port: 16104 | ||||
| @@ -155,6 +158,10 @@ configProperties: | ||||
|   openwifi.kafka.brokerlist: localhost:9092 | ||||
|   openwifi.kafka.auto.commit: false | ||||
|   openwifi.kafka.queue.buffering.max.ms: 50 | ||||
|   openwifi.kafka.ssl.ca.location: "" | ||||
|   openwifi.kafka.ssl.certificate.location: "" | ||||
|   openwifi.kafka.ssl.key.location: "" | ||||
|   openwifi.kafka.ssl.key.password: "" | ||||
|   # Storage | ||||
|   storage.type: sqlite # (sqlite|postgresql|mysql|odbc) | ||||
|   ## SQLite | ||||
| @@ -203,6 +210,9 @@ configProperties: | ||||
|   storage.type.mysql.username: stephb | ||||
|   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: | ||||
|   # restapi-ca.pem: "" | ||||
|   # restapi-cert.pem: "" | ||||
|   | ||||
| @@ -30,58 +30,13 @@ components: | ||||
|  | ||||
|   responses: | ||||
|     NotFound: | ||||
|       description: The specified resource was not found. | ||||
|       content: | ||||
|         application/json: | ||||
|           schema: | ||||
|             properties: | ||||
|               ErrorCode: | ||||
|                 type: integer | ||||
|               ErrorDetails: | ||||
|                 type: string | ||||
|               ErrorDescription: | ||||
|                 type: string | ||||
|  | ||||
|       $ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/NotFound' | ||||
|     Unauthorized: | ||||
|       description: The requested does not have sufficient rights to perform the operation. | ||||
|       content: | ||||
|         application/json: | ||||
|           schema: | ||||
|             properties: | ||||
|               ErrorCode: | ||||
|                 type: integer | ||||
|                 enum: | ||||
|                   - 0     # Success | ||||
|                   - 1     # PASSWORD_CHANGE_REQUIRED, | ||||
|                   - 2     # INVALID_CREDENTIALS, | ||||
|                   - 3     # PASSWORD_ALREADY_USED, | ||||
|                   - 4     # USERNAME_PENDING_VERIFICATION, | ||||
|                   - 5     # PASSWORD_INVALID, | ||||
|                   - 6     # INTERNAL_ERROR, | ||||
|                   - 7     # ACCESS_DENIED, | ||||
|                   - 8     # INVALID_TOKEN | ||||
|                   - 9     # EXPIRED_TOKEN | ||||
|                   - 10    # RATE_LIMIT_EXCEEDED | ||||
|                   - 11    # BAD_MFA_TRANSACTION | ||||
|                   - 12    # MFA_FAILURE | ||||
|                   - 13    # SECURITY_SERVICE_UNREACHABLE | ||||
|               ErrorDetails: | ||||
|                 type: string | ||||
|               ErrorDescription: | ||||
|                 type: string | ||||
|  | ||||
|       $ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Unauthorized' | ||||
|     Success: | ||||
|       description: The requested operation was performed. | ||||
|       content: | ||||
|         application/json: | ||||
|           schema: | ||||
|             properties: | ||||
|               Operation: | ||||
|                 type: string | ||||
|               Details: | ||||
|                 type: string | ||||
|               Code: | ||||
|                 type: integer | ||||
|       $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: | ||||
|     FirmwareDetails: | ||||
| @@ -140,6 +95,25 @@ components: | ||||
|           items: | ||||
|             $ref: '#/components/schemas/FirmwareDetails' | ||||
|  | ||||
|     DeviceCurrentInfo: | ||||
|       type: object | ||||
|       properties: | ||||
|         serialNumber: | ||||
|           type: string | ||||
|         revision: | ||||
|           type: string | ||||
|         upgraded: | ||||
|           type: integer | ||||
|           format: int64 | ||||
|  | ||||
|     DeviceCurrentInfoList: | ||||
|       type: object | ||||
|       properties: | ||||
|         devices: | ||||
|           type: array | ||||
|           items: | ||||
|             $ref: '#/components/schemas/DeviceCurrentInfo' | ||||
|  | ||||
|     RevisionHistoryEntry: | ||||
|       type: object | ||||
|       properties: | ||||
| @@ -257,6 +231,26 @@ components: | ||||
|         totalSecondsOld: | ||||
|           $ref: '#/components/schemas/TagIntPairList' | ||||
|  | ||||
|     DeviceInformation: | ||||
|       type: object | ||||
|       properties: | ||||
|         serialNumber: | ||||
|           type: string | ||||
|         history: | ||||
|           $ref: '#/components/schemas/RevisionHistoryEntryList' | ||||
|         currentFirmware: | ||||
|           type: string | ||||
|         currentFirmwareDate: | ||||
|           type: integer | ||||
|           format: int64 | ||||
|         latestFirmware: | ||||
|           type: string | ||||
|         latestFirmwareDate: | ||||
|           type: integer | ||||
|           format: int64 | ||||
|         latestFirmwareAvailable: | ||||
|           type: boolean | ||||
|  | ||||
|     ######################################################################################### | ||||
|     ## | ||||
|     ## These are endpoints that all services in the uCentral stack must provide | ||||
| @@ -455,9 +449,10 @@ paths: | ||||
|           required: false | ||||
|         - in: query | ||||
|           name: latestOnly | ||||
|           description: Return only the latest firwares | ||||
|           description: Return only the latest firmware | ||||
|           schema: | ||||
|             type: boolean | ||||
|             default: false | ||||
|           required: false | ||||
|         - in: query | ||||
|           name: deviceType | ||||
| @@ -468,19 +463,28 @@ paths: | ||||
|           name: revisionSet | ||||
|           schema: | ||||
|             type: boolean | ||||
|             default: false | ||||
|           required: false | ||||
|         - in: query | ||||
|           name: deviceSet | ||||
|           schema: | ||||
|             type: boolean | ||||
|           required: false | ||||
|         - in: query | ||||
|           name: rcOnly | ||||
|           schema: | ||||
|             type: boolean | ||||
|             default: false | ||||
|           required: false | ||||
|       responses: | ||||
|         200: | ||||
|           description: List firmwares | ||||
|           content: | ||||
|             application/json: | ||||
|               schema: | ||||
|                 $ref: '#/components/schemas/FirmwareDetailsList' | ||||
|                 oneOf: | ||||
|                   - $ref: '#/components/schemas/FirmwareDetailsList' | ||||
|                   - $ref: '#/components/schemas/FirmwareDetails' | ||||
|         403: | ||||
|           $ref: '#/components/responses/Unauthorized' | ||||
|         404: | ||||
| @@ -627,13 +631,31 @@ paths: | ||||
|           schema: | ||||
|             type: string | ||||
|           required: false | ||||
|         - in: query | ||||
|           description: Return current device list and current firmware | ||||
|           name: currentList | ||||
|           schema: | ||||
|             type: boolean | ||||
|             default: false | ||||
|           required: false | ||||
|           example: You must set {serialNumber} to 000000000000 | ||||
|         - in: query | ||||
|           description: Return current device list and current firmware | ||||
|           name: unknownList | ||||
|           schema: | ||||
|             type: boolean | ||||
|             default: false | ||||
|           required: false | ||||
|           example: You must set {serialNumber} to 000000000000 | ||||
|       responses: | ||||
|         200: | ||||
|           description: List of device history upgrade. | ||||
|           content: | ||||
|             application/json: | ||||
|               schema: | ||||
|                 $ref: '#/components/schemas/RevisionHistoryEntryList' | ||||
|                 oneOf: | ||||
|                   - $ref: '#/components/schemas/RevisionHistoryEntryList' | ||||
|                   - $ref: '#/components/schemas/DeviceCurrentInfoList' | ||||
|         403: | ||||
|           $ref: '#/components/responses/Unauthorized' | ||||
|         404: | ||||
| @@ -788,6 +810,28 @@ paths: | ||||
|         404: | ||||
|           $ref: '#/components/responses/NotFound' | ||||
|  | ||||
|   /deviceInformation/{serialNumber}: | ||||
|     get: | ||||
|       tags: | ||||
|         - Device Information | ||||
|       summary: receive a repor on a single decide | ||||
|       parameters: | ||||
|         - in: path | ||||
|           name: serialNumber | ||||
|           schema: | ||||
|             type: string | ||||
|             example: | ||||
|               aabbccdd1234 | ||||
|           required: true | ||||
|       responses: | ||||
|         200: | ||||
|           $ref: '#/components/schemas/DeviceInformation' | ||||
|         403: | ||||
|           $ref: '#/components/responses/Unauthorized' | ||||
|         404: | ||||
|           $ref: '#/components/responses/NotFound' | ||||
|  | ||||
|  | ||||
|   ######################################################################################### | ||||
|   ## | ||||
|   ## These are endpoints that all services in the uCentral stack must provide | ||||
|   | ||||
							
								
								
									
										1
									
								
								overlays/curl/portfile.cmake
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								overlays/curl/portfile.cmake
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| set(VCPKG_POLICY_EMPTY_PACKAGE enabled) | ||||
							
								
								
									
										4
									
								
								overlays/curl/vcpkg.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								overlays/curl/vcpkg.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| { | ||||
|     "name": "curl", | ||||
|     "version-string": "7.74.0-1.3+deb11u3" | ||||
| } | ||||
							
								
								
									
										1
									
								
								overlays/openssl/portfile.cmake
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								overlays/openssl/portfile.cmake
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| set(VCPKG_POLICY_EMPTY_PACKAGE enabled) | ||||
							
								
								
									
										4
									
								
								overlays/openssl/vcpkg.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								overlays/openssl/vcpkg.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| { | ||||
|     "name": "openssl", | ||||
|     "version-string": "1.1.1n-0+deb11u3" | ||||
| } | ||||
							
								
								
									
										1
									
								
								overlays/zlib/portfile.cmake
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								overlays/zlib/portfile.cmake
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| set(VCPKG_POLICY_EMPTY_PACKAGE enabled) | ||||
							
								
								
									
										4
									
								
								overlays/zlib/vcpkg.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								overlays/zlib/vcpkg.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| { | ||||
|     "name": "zlib", | ||||
|     "version-string": "1:1.2.11.dfsg-2+deb11u2" | ||||
| } | ||||
| @@ -35,6 +35,7 @@ openwifi.system.uri.private = https://localhost:17004 | ||||
| openwifi.system.uri.public = https://ucentral.dpaas.arilia.com:16004 | ||||
| openwifi.system.commandchannel = /tmp/app.owfms | ||||
| openwifi.system.uri.ui = ucentral-ui.arilia.com | ||||
| openwifi.security.restapi.disable = false | ||||
|  | ||||
| firmwaredb.refresh = 1800 | ||||
| firmwaredb.maxage = 90 | ||||
| @@ -69,6 +70,10 @@ openwifi.kafka.enable = true | ||||
| openwifi.kafka.brokerlist = a1.arilia.com:9092 | ||||
| openwifi.kafka.auto.commit = false | ||||
| openwifi.kafka.queue.buffering.max.ms = 50 | ||||
| openwifi.kafka.ssl.ca.location = | ||||
| openwifi.kafka.ssl.certificate.location = | ||||
| openwifi.kafka.ssl.key.location = | ||||
| openwifi.kafka.ssl.key.password = | ||||
|  | ||||
| # | ||||
| # This section select which form of persistence you need | ||||
|   | ||||
| @@ -36,8 +36,10 @@ openwifi.system.uri.private = ${SYSTEM_URI_PRIVATE} | ||||
| openwifi.system.uri.public = ${SYSTEM_URI_PUBLIC} | ||||
| openwifi.system.commandchannel = /tmp/app.ucentralfms | ||||
| openwifi.system.uri.ui = ${SYSTEM_URI_UI} | ||||
| firmwaredb.refresh = 1800 | ||||
| firmwaredb.maxage = 90 | ||||
| openwifi.security.restapi.disable = ${SECURITY_RESTAPI_DISABLE} | ||||
|  | ||||
| firmwaredb.refresh = ${FIRMWAREDB_REFRESH} | ||||
| firmwaredb.maxage = ${FIRMWAREDB_MAXAGE} | ||||
|  | ||||
| # | ||||
| # Firmware Microservice Specific Section | ||||
| @@ -67,6 +69,10 @@ openwifi.kafka.enable = ${KAFKA_ENABLE} | ||||
| openwifi.kafka.brokerlist = ${KAFKA_BROKERLIST} | ||||
| openwifi.kafka.auto.commit = false | ||||
| openwifi.kafka.queue.buffering.max.ms = 50 | ||||
| openwifi.kafka.ssl.ca.location = ${KAFKA_SSL_CA_LOCATION} | ||||
| openwifi.kafka.ssl.certificate.location = ${KAFKA_SSL_CERTIFICATE_LOCATION} | ||||
| openwifi.kafka.ssl.key.location = ${KAFKA_SSL_KEY_LOCATION} | ||||
| openwifi.kafka.ssl.key.password = ${KAFKA_SSL_KEY_PASSWORD} | ||||
|  | ||||
| # | ||||
| # This section select which form of persistence you need | ||||
|   | ||||
| @@ -8,13 +8,19 @@ | ||||
| #include "LatestFirmwareCache.h" | ||||
| #include "StorageService.h" | ||||
|  | ||||
| #include "framework/MicroServiceFuncs.h" | ||||
| #include "framework/utils.h" | ||||
|  | ||||
| #include "fmt/format.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
|     int AutoUpdater::Start() { | ||||
|         AutoUpdaterEnabled_ = MicroService::instance().ConfigGetBool("autoupdater.enabled", false); | ||||
|         poco_information(Logger(),"Starting..."); | ||||
|         AutoUpdaterEnabled_ = MicroServiceConfigGetBool("autoupdater.enabled", false); | ||||
|         if(AutoUpdaterEnabled_) { | ||||
|             Running_ = false; | ||||
|             AutoUpdaterFrequency_ = MicroService::instance().ConfigGetInt("autoupdater.frequency",600); | ||||
|             AutoUpdaterFrequency_ = MicroServiceConfigGetInt("autoupdater.frequency",600); | ||||
|             AutoUpdaterCallBack_ = std::make_unique<Poco::TimerCallback<AutoUpdater>>(*this, &AutoUpdater::onTimer); | ||||
|             Timer_.setStartInterval(5 * 60 * 1000);  // first run in 5 minutes | ||||
|             Timer_.setPeriodicInterval(AutoUpdaterFrequency_ * 1000); | ||||
| @@ -24,10 +30,12 @@ namespace OpenWifi { | ||||
|     } | ||||
|  | ||||
|     void AutoUpdater::Stop() { | ||||
|         poco_information(Logger(),"Stopping..."); | ||||
|         Running_ = false; | ||||
|         if(AutoUpdaterEnabled_) { | ||||
|             Timer_.stop(); | ||||
|         } | ||||
|         poco_information(Logger(),"Stopped..."); | ||||
|     } | ||||
|  | ||||
|     void AutoUpdater::ToBeUpgraded(std::string serialNumber, std::string DeviceType) { | ||||
| @@ -37,28 +45,29 @@ namespace OpenWifi { | ||||
|         Queue_.emplace_back(std::make_pair(std::move(serialNumber),std::move(DeviceType))); | ||||
|     } | ||||
|  | ||||
|     void AutoUpdater::onTimer(Poco::Timer & timer) { | ||||
|     void AutoUpdater::onTimer([[maybe_unused]] Poco::Timer & timer) { | ||||
|         Utils::SetThreadName("auto-updater"); | ||||
|         Running_ = true; | ||||
|         std::unique_lock    L(Mutex_); | ||||
|         while(!Queue_.empty() && Running_) { | ||||
|             auto Entry = Queue_.front(); | ||||
|             Queue_.pop_front(); | ||||
|             try { | ||||
|                 Logger().debug(Poco::format("Preparing to upgrade %s",Entry.first)); | ||||
|                 poco_debug(Logger(),fmt::format("Preparing to upgrade {}",Entry.first)); | ||||
|                 auto CacheEntry = Cache_.find(Entry.first); | ||||
|                 uint64_t Now = std::time(nullptr); | ||||
|                 uint64_t now = Utils::Now(); | ||||
|                 std::string firmwareUpgrade; | ||||
|                 if(CacheEntry == Cache_.end() || (CacheEntry->second.LastCheck-Now)>300) { | ||||
|                 if(CacheEntry == Cache_.end() || (CacheEntry->second.LastCheck-now)>300) { | ||||
|                     //  get the firmware settings for that device. | ||||
|                     SerialCache     C; | ||||
|                     C.LastCheck = Now; | ||||
|                     C.LastCheck = now; | ||||
|                     bool        firmwareRCOnly; | ||||
|                     if(OpenWifi::SDK::Prov::GetFirmwareOptions(Entry.first, firmwareUpgrade, firmwareRCOnly)) { | ||||
|                         Logger().debug(Poco::format("Found firmware options for %s",Entry.first)); | ||||
|                         poco_debug(Logger(),fmt::format("Found firmware options for {}",Entry.first)); | ||||
|                         C.firmwareRCOnly = firmwareRCOnly; | ||||
|                         C.firmwareUpgrade = firmwareUpgrade; | ||||
|                     } else { | ||||
|                         Logger().debug(Poco::format("Found no firmware options for %s",Entry.first)); | ||||
|                         poco_debug(Logger(),fmt::format("Found no firmware options for {}",Entry.first)); | ||||
|                         C.firmwareRCOnly = firmwareRCOnly; | ||||
|                         C.firmwareUpgrade = firmwareUpgrade; | ||||
|                     } | ||||
| @@ -68,7 +77,7 @@ namespace OpenWifi { | ||||
|                 } | ||||
|  | ||||
|                 if(firmwareUpgrade=="no") { | ||||
|                     Logger().information(Poco::format("Device %s not upgradable. Provisioning service settings.",Entry.first)); | ||||
|                     poco_information(Logger(),fmt::format("Device {} not upgradable. Provisioning service settings.",Entry.first)); | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
| @@ -78,26 +87,26 @@ namespace OpenWifi { | ||||
|                 if(LF) { | ||||
|                     if(StorageService()->FirmwaresDB().GetFirmware(fwEntry.Id,fwDetails)) { | ||||
|                         //  send the command to upgrade this device... | ||||
|                         Logger().information(Poco::format("Upgrading %s to version %s", Entry.first, fwEntry.Revision)); | ||||
|                         poco_information(Logger(),fmt::format("Upgrading {} to version {}", Entry.first, fwEntry.Revision)); | ||||
|                         if(OpenWifi::SDK::GW::SendFirmwareUpgradeCommand(Entry.first,fwDetails.uri)) { | ||||
|                             Logger().information(Poco::format("Upgrade command sent for %s",Entry.first)); | ||||
|                             poco_information(Logger(),fmt::format("Upgrade command sent for {}",Entry.first)); | ||||
|                         } else { | ||||
|                             Logger().information(Poco::format("Upgrade command not sent for %s",Entry.first)); | ||||
|                             poco_information(Logger(),fmt::format("Upgrade command not sent for {}",Entry.first)); | ||||
|                         } | ||||
|                     } else { | ||||
|                         Logger().information(Poco::format("Firmware for device %s (%s) cannot be found.", Entry.first, Entry.second )); | ||||
|                         poco_information(Logger(),fmt::format("Firmware for device {} ({}) cannot be found.", Entry.first, Entry.second )); | ||||
|                     } | ||||
|                 } else { | ||||
|                     Logger().information(Poco::format("Firmware for device %s (%s) cannot be found.", Entry.first, Entry.second )); | ||||
|                     poco_information(Logger(),fmt::format("Firmware for device {} ({}) cannot be found.", Entry.first, Entry.second )); | ||||
|                 } | ||||
|             } catch (...) { | ||||
|                 Logger().information(Poco::format("Exception during auto update for device %s.", Entry.first )); | ||||
|                 poco_information(Logger(),fmt::format("Exception during auto update for device {}.", Entry.first )); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void AutoUpdater::reinitialize(Poco::Util::Application &self) { | ||||
|         Logger().information("Reinitializing."); | ||||
|     void AutoUpdater::reinitialize([[maybe_unused]] Poco::Util::Application &self) { | ||||
|         poco_information(Logger(),"Reinitializing."); | ||||
|         Reset(); | ||||
|     } | ||||
| } | ||||
| @@ -2,11 +2,11 @@ | ||||
| // Created by stephane bourque on 2021-10-04. | ||||
| // | ||||
|  | ||||
| #ifndef OWFMS_AUTOUPDATER_H | ||||
| #define OWFMS_AUTOUPDATER_H | ||||
| #pragma once | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include <deque> | ||||
|  | ||||
| #include "framework/SubSystemServer.h" | ||||
| #include "Poco/Util/Application.h" | ||||
| #include "Poco/Timer.h" | ||||
|  | ||||
| @@ -55,4 +55,3 @@ namespace OpenWifi { | ||||
|     inline auto AutoUpdater() { return AutoUpdater::instance(); } | ||||
| } | ||||
|  | ||||
| #endif //OWFMS_AUTOUPDATER_H | ||||
|   | ||||
| @@ -19,6 +19,8 @@ | ||||
| #include "AutoUpdater.h" | ||||
| #include "NewCommandHandler.h" | ||||
|  | ||||
| #include "framework/UI_WebSocketClientServer.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     class Daemon *Daemon::instance_ = nullptr; | ||||
|  | ||||
| @@ -37,19 +39,20 @@ namespace OpenWifi { | ||||
|                                             NewConnectionHandler(), | ||||
|                                             ManifestCreator(), | ||||
|                                             AutoUpdater(), | ||||
|                                             NewCommandHandler() | ||||
|                                             NewCommandHandler(), | ||||
|                                             UI_WebSocketClientServer() | ||||
|                                    }); | ||||
|         } | ||||
|         return instance_; | ||||
|     } | ||||
|  | ||||
|     void Daemon::initialize(Poco::Util::Application &self) { | ||||
|         MicroService::initialize(*this); | ||||
|     void Daemon::PostInitialization([[maybe_unused]] Poco::Util::Application &self) { | ||||
|     } | ||||
|  | ||||
|     void MicroServicePostInitialization() { | ||||
|  | ||||
|     void DaemonPostInitialization(Poco::Util::Application &self) { | ||||
|         Daemon()->PostInitialization(self); | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| int main(int argc, char **argv) { | ||||
|   | ||||
							
								
								
									
										18
									
								
								src/Daemon.h
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								src/Daemon.h
									
									
									
									
									
								
							| @@ -7,16 +7,18 @@ | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/OpenWifiTypes.h" | ||||
| #include "framework/MicroServiceNames.h" | ||||
|  | ||||
| #include "RESTObjects/RESTAPI_FMSObjects.h" | ||||
| #include "Dashboard.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
|     static const char * vDAEMON_PROPERTIES_FILENAME = "owfms.properties"; | ||||
|     static const char * vDAEMON_ROOT_ENV_VAR = "OWFMS_ROOT"; | ||||
|     static const char * vDAEMON_CONFIG_ENV_VAR = "OWFMS_CONFIG"; | ||||
|     static const char * vDAEMON_APP_NAME = uSERVICE_FIRMWARE.c_str(); | ||||
|     static const uint64_t vDAEMON_BUS_TIMER = 10000; | ||||
|     [[maybe_unused]] static const char * vDAEMON_PROPERTIES_FILENAME = "owfms.properties"; | ||||
|     [[maybe_unused]] static const char * vDAEMON_ROOT_ENV_VAR = "OWFMS_ROOT"; | ||||
|     [[maybe_unused]] static const char * vDAEMON_CONFIG_ENV_VAR = "OWFMS_CONFIG"; | ||||
|     [[maybe_unused]] static const char * vDAEMON_APP_NAME = uSERVICE_FIRMWARE.c_str(); | ||||
|     [[maybe_unused]] static const uint64_t vDAEMON_BUS_TIMER = 10000; | ||||
|  | ||||
|     class Daemon : public MicroService { | ||||
|     public: | ||||
| @@ -28,11 +30,9 @@ namespace OpenWifi { | ||||
|                         const SubSystemVec & SubSystems) : | ||||
|                 MicroService( PropFile, RootEnv, ConfigEnv, AppName, BusTimer, SubSystems) {}; | ||||
|  | ||||
|         void initialize(Poco::Util::Application &self); | ||||
|         void PostInitialization(Poco::Util::Application &self); | ||||
|         static Daemon *instance(); | ||||
|         inline void ResetDashboard() { DB_.Reset(); } | ||||
|         inline void CreateDashboard() { DB_.Create(); } | ||||
|         inline const FMSObjects::DeviceReport & GetDashboard() { return DB_.Report(); } | ||||
|         inline DeviceDashboard & GetDashboard() { return DB_; } | ||||
|  | ||||
|     private: | ||||
|         static Daemon 				*instance_; | ||||
|   | ||||
| @@ -4,15 +4,48 @@ | ||||
|  | ||||
| #include "Dashboard.h" | ||||
| #include "StorageService.h" | ||||
| #include "framework/utils.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
| 	void DeviceDashboard::Create() { | ||||
| 		uint64_t Now = std::time(nullptr); | ||||
|  | ||||
| 		if(LastRun_==0 || (Now-LastRun_)>120) { | ||||
| 			DB_.reset(); | ||||
| 			StorageService()->DevicesDB().GenerateDeviceReport(DB_); | ||||
| 			LastRun_ = Now; | ||||
| 		} | ||||
| 	} | ||||
|     bool DeviceDashboard::Get(FMSObjects::DeviceReport &D, Poco::Logger & Logger) { | ||||
|         uint64_t Now = Utils::Now(); | ||||
|         if(!ValidDashboard_ || LastRun_==0 || (Now-LastRun_)>120) { | ||||
|             Generate(D, Logger); | ||||
|         } else { | ||||
|             std::lock_guard	G(DataMutex_); | ||||
|             D = DB_; | ||||
|         } | ||||
|         return ValidDashboard_; | ||||
|     }; | ||||
|  | ||||
|     void DeviceDashboard::Generate(FMSObjects::DeviceReport &D, Poco::Logger & Logger ) { | ||||
|         if (GeneratingDashboard_.load()) { | ||||
|             // std::cout << "Trying to generate dashboard but already being generated" << std::endl; | ||||
|             while(GeneratingDashboard_.load()) { | ||||
|                 Poco::Thread::trySleep(100); | ||||
|             } | ||||
|             std::lock_guard	G(DataMutex_); | ||||
|             D = DB_; | ||||
|         } else { | ||||
|             GeneratingDashboard_ = true; | ||||
|             ValidDashboard_ = false; | ||||
|             try { | ||||
|                 // std::cout << "Generating dashboard." << std::endl; | ||||
|                 poco_information(Logger, "DASHBOARD: Generating a new dashboard."); | ||||
|                 FMSObjects::DeviceReport	NewData; | ||||
|                 StorageService()->DevicesDB().GenerateDeviceReport(NewData); | ||||
|                 LastRun_ = Utils::Now(); | ||||
|                 NewData.snapshot = LastRun_; | ||||
|                 D = NewData; | ||||
|                 std::lock_guard	G(DataMutex_); | ||||
|                 DB_ = NewData; | ||||
|                 ValidDashboard_=true; | ||||
|             } catch(...) { | ||||
|  | ||||
|             } | ||||
|             GeneratingDashboard_ = false; | ||||
|         } | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -2,22 +2,26 @@ | ||||
| // Created by stephane bourque on 2021-07-21. | ||||
| // | ||||
|  | ||||
| #ifndef UCENTRALGW_DASHBOARD_H | ||||
| #define UCENTRALGW_DASHBOARD_H | ||||
| #pragma once | ||||
|  | ||||
| #include <mutex> | ||||
|  | ||||
| #include "framework/OpenWifiTypes.h" | ||||
| #include "RESTObjects/RESTAPI_FMSObjects.h" | ||||
| #include "Poco/Logger.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
| 	class DeviceDashboard { | ||||
| 	  public: | ||||
| 			void Create(); | ||||
| 			const FMSObjects::DeviceReport & Report() const { return DB_;} | ||||
| 			inline void Reset() { LastRun_=0; DB_.reset(); } | ||||
| 	  private: | ||||
|             FMSObjects::DeviceReport  	DB_; | ||||
| 			uint64_t 				LastRun_=0; | ||||
| 	}; | ||||
| } | ||||
|     class DeviceDashboard { | ||||
|     public: | ||||
|         bool Get(FMSObjects::DeviceReport &D, Poco::Logger &Logger); | ||||
|  | ||||
| #endif // UCENTRALGW_DASHBOARD_H | ||||
|     private: | ||||
|         std::mutex DataMutex_; | ||||
|         volatile std::atomic_bool GeneratingDashboard_ = false; | ||||
|         volatile bool ValidDashboard_ = false; | ||||
|         FMSObjects::DeviceReport DB_; | ||||
|         uint64_t LastRun_ = 0; | ||||
|  | ||||
|         void Generate(FMSObjects::DeviceReport &D, Poco::Logger &Logger); | ||||
|     }; | ||||
| } | ||||
|   | ||||
| @@ -7,10 +7,13 @@ | ||||
| namespace OpenWifi { | ||||
|  | ||||
|     int DeviceCache::Start() { | ||||
|         poco_information(Logger(),"Starting..."); | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     void DeviceCache::Stop() { | ||||
|         poco_information(Logger(),"Stopping..."); | ||||
|         poco_information(Logger(),"Stopped..."); | ||||
|     } | ||||
|  | ||||
|     void DeviceCache::AddToCache( | ||||
|   | ||||
| @@ -2,11 +2,10 @@ | ||||
| // Created by stephane bourque on 2021-07-13. | ||||
| // | ||||
|  | ||||
| #ifndef UCENTRALFMS_DEVICECACHE_H | ||||
| #define UCENTRALFMS_DEVICECACHE_H | ||||
| #pragma once | ||||
|  | ||||
| #include <string> | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/SubSystemServer.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
| @@ -43,6 +42,3 @@ namespace OpenWifi { | ||||
|     inline auto DeviceCache() { return DeviceCache::instance(); } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| #endif //UCENTRALFMS_DEVICECACHE_H | ||||
|   | ||||
| @@ -7,18 +7,20 @@ | ||||
| namespace OpenWifi { | ||||
|  | ||||
|     int FirmwareCache::Start() { | ||||
|         poco_information(Logger(),"Starting..."); | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     void FirmwareCache::Stop() { | ||||
|  | ||||
|         poco_information(Logger(),"Stopping..."); | ||||
|         poco_information(Logger(),"Stopped..."); | ||||
|     } | ||||
|  | ||||
|     std::shared_ptr<FMSObjects::Firmware> GetFirmware(const std::string & DeviceType, const std::string & Revision) { | ||||
|     std::shared_ptr<FMSObjects::Firmware> GetFirmware([[maybe_unused]] const std::string & DeviceType, [[maybe_unused]] const std::string & Revision) { | ||||
|         return nullptr; | ||||
|     } | ||||
|  | ||||
|     std::shared_ptr<FMSObjects::Firmware> AddFirmware(const FMSObjects::Firmware &F) { | ||||
|     std::shared_ptr<FMSObjects::Firmware> AddFirmware([[maybe_unused]] const FMSObjects::Firmware &F) { | ||||
|         return nullptr; | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -2,14 +2,13 @@ | ||||
| // Created by stephane bourque on 2021-07-26. | ||||
| // | ||||
|  | ||||
| #ifndef UCENTRALFMS_FIRMWARECACHE_H | ||||
| #define UCENTRALFMS_FIRMWARECACHE_H | ||||
| #pragma once | ||||
|  | ||||
| #include <map> | ||||
| #include <memory> | ||||
|  | ||||
| #include "RESTObjects/RESTAPI_FMSObjects.h" | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/SubSystemServer.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
| @@ -28,7 +27,6 @@ namespace OpenWifi { | ||||
|         std::shared_ptr<FMSObjects::Firmware> GetFirmware(const std::string & DeviceType, const std::string & Revision); | ||||
|         std::shared_ptr<FMSObjects::Firmware> AddFirmware(const FMSObjects::Firmware &F); | ||||
|  | ||||
|  | ||||
|     private: | ||||
|         std::atomic_bool        Running_=false; | ||||
|         FirmwareCacheMap        Cache_; | ||||
| @@ -41,6 +39,3 @@ namespace OpenWifi { | ||||
|     inline auto FirmwareCache() { return FirmwareCache::instance(); } | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| #endif //UCENTRALFMS_FIRMWARECACHE_H | ||||
|   | ||||
| @@ -8,11 +8,14 @@ | ||||
| namespace OpenWifi { | ||||
|  | ||||
|     int LatestFirmwareCache::Start() { | ||||
|         poco_information(Logger(),"Starting..."); | ||||
|         StorageService()->FirmwaresDB().PopulateLatestFirmwareCache(); | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     void LatestFirmwareCache::Stop() { | ||||
|         poco_information(Logger(),"Stopping..."); | ||||
|         poco_information(Logger(),"Stopped..."); | ||||
|     } | ||||
|  | ||||
|     bool LatestFirmwareCache::AddToCache(const std::string & DeviceType, const std::string &Revision, const std::string &Id, uint64_t TimeStamp) { | ||||
| @@ -20,14 +23,26 @@ namespace OpenWifi { | ||||
|  | ||||
|         RevisionSet_.insert(Revision); | ||||
|         DeviceSet_.insert(DeviceType); | ||||
|  | ||||
|         auto E = Cache_.find(DeviceType); | ||||
|         if((E==Cache_.end()) || (TimeStamp >= E->second.TimeStamp)) { | ||||
|             Cache_[DeviceType] = LatestFirmwareCacheEntry{  .Id=Id, | ||||
|                                                             .TimeStamp=TimeStamp, | ||||
|                                                             .Revision=Revision}; | ||||
|             return true; | ||||
|             Cache_[DeviceType] = LatestFirmwareCacheEntry{ | ||||
|                 .Id=Id, | ||||
|                 .TimeStamp=TimeStamp, | ||||
|                 .Revision=Revision}; | ||||
|         } | ||||
|         return false; | ||||
|  | ||||
|         if(!IsRC(Revision)) | ||||
|             return true; | ||||
|  | ||||
|         auto rcE = rcCache_.find(DeviceType); | ||||
|         if((rcE==rcCache_.end()) || (TimeStamp >= rcE->second.TimeStamp)) { | ||||
|             rcCache_[DeviceType] = LatestFirmwareCacheEntry{ | ||||
|                 .Id=Id, | ||||
|                 .TimeStamp=TimeStamp, | ||||
|                 .Revision=Revision}; | ||||
|         } | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     bool LatestFirmwareCache::FindLatestFirmware(const std::string &DeviceType, LatestFirmwareCacheEntry &Entry )  { | ||||
| @@ -38,10 +53,21 @@ namespace OpenWifi { | ||||
|             Entry = E->second; | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     bool LatestFirmwareCache::FindLatestRCOnlyFirmware(const std::string &DeviceType, LatestFirmwareCacheEntry &Entry ) { | ||||
|         std::lock_guard G(Mutex_); | ||||
|  | ||||
|         auto E=rcCache_.find(DeviceType); | ||||
|         if(E!=rcCache_.end()) { | ||||
|             Entry = E->second; | ||||
|             return true; | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     bool LatestFirmwareCache::IsLatest(const std::string &DeviceType, const std::string &Revision) { | ||||
|         std::lock_guard G(Mutex_); | ||||
|  | ||||
| @@ -52,6 +78,16 @@ namespace OpenWifi { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     bool LatestFirmwareCache::IsLatestRCOnly(const std::string &DeviceType, const std::string &Revision) { | ||||
|         std::lock_guard G(Mutex_); | ||||
|  | ||||
|         auto E=rcCache_.find(DeviceType); | ||||
|         if(E!=rcCache_.end()) { | ||||
|             return E->second.Revision==Revision; | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     void LatestFirmwareCache::DumpCache() { | ||||
|         std::lock_guard G(Mutex_); | ||||
|   | ||||
| @@ -2,16 +2,17 @@ | ||||
| // Created by stephane bourque on 2021-07-13. | ||||
| // | ||||
|  | ||||
| #ifndef UCENTRALFMS_LATESTFIRMWARECACHE_H | ||||
| #define UCENTRALFMS_LATESTFIRMWARECACHE_H | ||||
| #pragma once | ||||
|  | ||||
| #include "Poco/JSON/Object.h" | ||||
| #include "Poco/Net/HTTPServerRequest.h" | ||||
| #include "Poco/Net/HTTPServerResponse.h" | ||||
| #include "Poco/JWT/Signer.h" | ||||
| #include "Poco/SHA2Engine.h" | ||||
| #include "Poco/StringTokenizer.h" | ||||
|  | ||||
| #include "RESTObjects/RESTAPI_SecurityObjects.h" | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/SubSystemServer.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
| @@ -21,6 +22,7 @@ namespace OpenWifi { | ||||
|         std::string     Revision; | ||||
|     }; | ||||
|     typedef std::map<std::string, LatestFirmwareCacheEntry> LatestFirmwareCacheMap; | ||||
|     typedef std::map<std::string, LatestFirmwareCacheEntry> rcOnlyLatestFirmwareCacheMap; | ||||
|  | ||||
|     class LatestFirmwareCache : public SubSystemServer { | ||||
|     public: | ||||
| @@ -34,23 +36,32 @@ namespace OpenWifi { | ||||
|         bool AddToCache(const std::string & DeviceType, const std::string & Revision, const std::string &Id, uint64_t TimeStamp); | ||||
|         // void AddRevision(const std::string &Revision); | ||||
|         bool FindLatestFirmware(const std::string &DeviceType, LatestFirmwareCacheEntry &Entry ); | ||||
|         bool FindLatestRCOnlyFirmware(const std::string &DeviceType, LatestFirmwareCacheEntry &Entry ); | ||||
|  | ||||
|         inline static bool IsRC(const std::string & Revision) { | ||||
|             // OpenWrt 21.02-SNAPSHOT r16399+120-c67509efd7 / TIP-v2.5.0-36b5478 | ||||
|             auto Tokens = Poco::StringTokenizer(Revision,"/", Poco::StringTokenizer::TOK_TRIM); | ||||
|             if(Tokens.count()!=2) | ||||
|                 return false; | ||||
|             return (Tokens[1].substr(0,5) == "TIP-v"); | ||||
|         } | ||||
|  | ||||
|         void DumpCache(); | ||||
|         inline Types::StringSet GetRevisions() { std::lock_guard G(Mutex_); return RevisionSet_; }; | ||||
|         inline Types::StringSet GetDevices() { std::lock_guard G(Mutex_); return DeviceSet_; }; | ||||
|         bool IsLatest(const std::string &DeviceType, const std::string &Revision); | ||||
|         bool IsLatestRCOnly(const std::string &DeviceType, const std::string &Revision); | ||||
|  | ||||
|     private: | ||||
|         LatestFirmwareCacheMap      Cache_; | ||||
|         LatestFirmwareCacheMap          Cache_; | ||||
|         rcOnlyLatestFirmwareCacheMap    rcCache_; | ||||
|         Types::StringSet            RevisionSet_; | ||||
|         Types::StringSet            DeviceSet_; | ||||
|         explicit LatestFirmwareCache() noexcept: | ||||
|                 SubSystemServer("FirmwareCache", "FIRMWARE-CACHE", "FirmwareCache") | ||||
|                 SubSystemServer("LatestFirmwareCache", "LATEST-FIRMWARE-CACHE", "LatestFirmwareCache") | ||||
|         { | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     inline auto LatestFirmwareCache() { return LatestFirmwareCache::instance(); } | ||||
| } | ||||
|  | ||||
|  | ||||
| #endif //UCENTRALFMS_LATESTFIRMWARECACHE_H | ||||
|   | ||||
| @@ -14,21 +14,25 @@ | ||||
| #include "StorageService.h" | ||||
| #include "LatestFirmwareCache.h" | ||||
|  | ||||
| #include "framework/utils.h" | ||||
| #include "fmt/format.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
|     void ManifestCreator::onTimer(Poco::Timer &timer) { | ||||
|         Logger().information("Performing DB refresh"); | ||||
|     void ManifestCreator::onTimer([[maybe_unused]] Poco::Timer &timer) { | ||||
|         Utils::SetThreadName("manifest"); | ||||
|         poco_information(Logger(),"Performing DB refresh"); | ||||
|         S3BucketContent BucketList; | ||||
|         StorageService()->FirmwaresDB().RemoveOldFirmware(); | ||||
|         ReadBucket(BucketList); | ||||
|         Logger().information(Poco::format("Found %Lu firmware entries in S3 repository.",(uint64_t)BucketList.size())); | ||||
|         poco_information(Logger(),fmt::format("Found {} firmware entries in S3 repository.", BucketList.size())); | ||||
|         ComputeManifest(BucketList); | ||||
|         AddManifestToDB(BucketList); | ||||
|     } | ||||
|  | ||||
|     bool ManifestCreator::ComputeManifest(S3BucketContent &BucketContent) { | ||||
|  | ||||
|         uint64_t Limit = std::time(nullptr) - MaxAge_, Rejected=0, Accepted=0, BadFormat=0, MissingJson=0; | ||||
|         uint64_t Limit = Utils::Now() - MaxAge_, Rejected=0, Accepted=0, BadFormat=0, MissingJson=0; | ||||
|         for(auto &[Name,Entry]:BucketContent) { | ||||
|             std::string C = Entry.S3ContentManifest; | ||||
|  | ||||
| @@ -48,7 +52,7 @@ namespace OpenWifi { | ||||
|                         Entry.Image = ParsedContent->get("image").toString(); | ||||
|                         auto FullNme = Name + "-upgrade.bin"; | ||||
|                         if(FullNme!=Entry.Image) { | ||||
|                             Logger().error(Poco::format("MANIFEST(%s): Image name does not match manifest name (%s).",Name,Entry.Image)); | ||||
|                             poco_error(Logger(),fmt::format("MANIFEST({}): Image name does not match manifest name ({}).",Name,Entry.Image)); | ||||
|                             Entry.Valid = false; | ||||
|                             BadFormat++; | ||||
|                             continue; | ||||
| @@ -60,7 +64,7 @@ namespace OpenWifi { | ||||
|                         Entry.Valid = false; | ||||
|                     } | ||||
|                 } else { | ||||
|                     Logger().error(Poco::format("MANIFEST(%s): Entry does not have a valid JSON manifest.",Name)); | ||||
|                     poco_error(Logger(),fmt::format("MANIFEST({}): Entry does not have a valid JSON manifest.",Name)); | ||||
|                     MissingJson++; | ||||
|                     Entry.Valid = false; | ||||
|                 } | ||||
| @@ -69,10 +73,10 @@ namespace OpenWifi { | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         Logger().information(Poco::format("Accepted %Lu firmwares.", Accepted)); | ||||
|         Logger().information(Poco::format("Rejected %Lu too old firmwares.", Rejected)); | ||||
|         Logger().information(Poco::format("Rejected %Lu bad JSON.", BadFormat)); | ||||
|         Logger().information(Poco::format("Rejected %Lu missing JSON.", MissingJson)); | ||||
|         poco_information(Logger(),fmt::format("Accepted {} firmwares.", Accepted)); | ||||
|         poco_information(Logger(),fmt::format("Rejected {} too old firmwares.", Rejected)); | ||||
|         poco_information(Logger(),fmt::format("Rejected {} bad JSON.", BadFormat)); | ||||
|         poco_information(Logger(),fmt::format("Rejected {} missing JSON.", MissingJson)); | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
| @@ -88,17 +92,17 @@ namespace OpenWifi { | ||||
|                 continue; | ||||
|  | ||||
|             if(BucketEntry.Valid && !StorageService()->FirmwaresDB().GetFirmwareByName(R,BucketEntry.Compatible,F)) { | ||||
|                 F.id = MicroService::instance().CreateUUID(); | ||||
|                 F.id = MicroServiceCreateUUID(); | ||||
|                 F.release = Release; | ||||
|                 F.size = BucketEntry.S3Size; | ||||
|                 F.created = std::time(nullptr); | ||||
|                 F.created = Utils::Now(); | ||||
|                 F.imageDate = BucketEntry.S3TimeStamp; | ||||
|                 F.image = BucketEntry.S3Name; | ||||
|                 F.image = BucketEntry.Image; | ||||
|                 F.uri = BucketEntry.URI; | ||||
|                 F.revision = BucketEntry.Revision; | ||||
|                 F.deviceType = BucketEntry.Compatible; | ||||
|                 if(StorageService()->FirmwaresDB().AddFirmware(F)) { | ||||
|                     Logger().information(Poco::format("Adding firmware '%s'",Release)); | ||||
|                     poco_information(Logger(),fmt::format("Adding firmware '{}', size={}",Release,F.size)); | ||||
|                 } else { | ||||
|                 } | ||||
|             } | ||||
| @@ -108,14 +112,14 @@ namespace OpenWifi { | ||||
|  | ||||
|     int ManifestCreator::Start() { | ||||
|         Running_ = true; | ||||
|         S3BucketName_ = MicroService::instance().ConfigGetString("s3.bucketname"); | ||||
|         S3Region_ = MicroService::instance().ConfigGetString("s3.region"); | ||||
|         S3Secret_ = MicroService::instance().ConfigGetString("s3.secret"); | ||||
|         S3Key_ = MicroService::instance().ConfigGetString("s3.key"); | ||||
|         S3Retry_ = MicroService::instance().ConfigGetInt("s3.retry",60); | ||||
|         S3BucketName_ = MicroServiceConfigGetString("s3.bucketname",""); | ||||
|         S3Region_ = MicroServiceConfigGetString("s3.region",""); | ||||
|         S3Secret_ = MicroServiceConfigGetString("s3.secret",""); | ||||
|         S3Key_ = MicroServiceConfigGetString("s3.key",""); | ||||
|         S3Retry_ = MicroServiceConfigGetInt("s3.retry",60); | ||||
|  | ||||
|         DBRefresh_ = MicroService::instance().ConfigGetInt("firmwaredb.refresh",30*60); | ||||
|         MaxAge_ = MicroService::instance().ConfigGetInt("firmwaredb.maxage",90) * 24 * 60 * 60; | ||||
|         DBRefresh_ = MicroServiceConfigGetInt("firmwaredb.refresh",30*60); | ||||
|         MaxAge_ = MicroServiceConfigGetInt("firmwaredb.maxage",90) * 24 * 60 * 60; | ||||
|  | ||||
|         AwsConfig_.enableTcpKeepAlive = true; | ||||
|         AwsConfig_.enableEndpointDiscovery = true; | ||||
| @@ -126,8 +130,8 @@ namespace OpenWifi { | ||||
|         AwsCreds_.SetAWSSecretKey(S3Secret_); | ||||
|  | ||||
|         ManifestCreatorCallBack_ = std::make_unique<Poco::TimerCallback<ManifestCreator>>(*this, &ManifestCreator::onTimer); | ||||
|         Timer_.setStartInterval(5 * 60 * 1000);  // first run in 5 minutes | ||||
|         Timer_.setPeriodicInterval(DBRefresh_ * 1000); | ||||
|         Timer_.setStartInterval(1 * 60 * 1000);  // first run in 1 minutes | ||||
|         Timer_.setPeriodicInterval((long)(DBRefresh_ * 1000)); | ||||
|         Timer_.start(*ManifestCreatorCallBack_); | ||||
|  | ||||
|         return 0; | ||||
| @@ -168,7 +172,7 @@ namespace OpenWifi { | ||||
|         static const std::string UPGRADE("-upgrade.bin"); | ||||
|  | ||||
|         std::string     URIBase = "https://"; | ||||
|         URIBase += MicroService::instance().ConfigGetString("s3.bucket.uri"); | ||||
|         URIBase += MicroServiceConfigGetString("s3.bucket.uri",""); | ||||
|  | ||||
|         Bucket.clear(); | ||||
|  | ||||
| @@ -184,7 +188,7 @@ namespace OpenWifi { | ||||
|         while(!isDone) { | ||||
|             Outcome = S3Client.ListObjectsV2(Request); | ||||
|             if(!Outcome.IsSuccess()) { | ||||
|                 Logger().error(Poco::format("Error while doing ListObjectsV2: %s, %s", | ||||
|                 poco_error(Logger(),fmt::format("Error while doing ListObjectsV2: {}, {}", | ||||
|                                            std::string{Outcome.GetError().GetExceptionName()}, | ||||
|                                            std::string{Outcome.GetError().GetMessage()})); | ||||
|                 return false; | ||||
| @@ -223,12 +227,17 @@ namespace OpenWifi { | ||||
|                                 It->second.Image = Image; | ||||
|                                 It->second.S3ContentManifest = Content; | ||||
|                             } else { | ||||
|                                 Bucket.emplace(Release, S3BucketEntry{ | ||||
|                                       Bucket.emplace(Release, S3BucketEntry{ | ||||
|                                         .Valid = false, | ||||
|                                         .S3Name = "", | ||||
|                                         .S3ContentManifest = Content, | ||||
|                                         .S3TimeStamp = 0 , | ||||
|                                         .S3Size = 0 , | ||||
|                                         .Revision = Revision, | ||||
|                                         .Image = Image, | ||||
|                                         .Compatible = Compatible, | ||||
|                                         .Timestamp = TimeStamp}); | ||||
|                                         .Timestamp = TimeStamp, | ||||
|                                         .URI = ""}); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
| @@ -245,10 +254,17 @@ namespace OpenWifi { | ||||
|                         It->second.S3Name = ReleaseName; | ||||
|                         It->second.URI = URI; | ||||
|                     } else { | ||||
|  | ||||
|                         Bucket.emplace(ReleaseName, S3BucketEntry{ | ||||
|                                 .S3Name = ReleaseName, | ||||
|                                 .Valid = false, | ||||
|                                 .S3Name = "", | ||||
|                                 .S3ContentManifest = "", | ||||
|                                 .S3TimeStamp = S3TimeStamp, | ||||
|                                 .S3Size = S3Size, | ||||
|                                 .S3Size = S3Size , | ||||
|                                 .Revision = "", | ||||
|                                 .Image = "", | ||||
|                                 .Compatible = "", | ||||
|                                 .Timestamp = 0 , | ||||
|                                 .URI = URI}); | ||||
|                     } | ||||
|                 } else { | ||||
| @@ -268,7 +284,7 @@ namespace OpenWifi { | ||||
|  | ||||
|         // std::cout << "Count:" << Count << "  Runs:" << Runs << std::endl; | ||||
|         if(!Outcome.IsSuccess()) { | ||||
|             Logger().error(Poco::format("Error while doing ListObjectsV2: %s, %s", | ||||
|             poco_error(Logger(),fmt::format("Error while doing ListObjectsV2: {}, {}", | ||||
|                                        std::string{Outcome.GetError().GetExceptionName()}, | ||||
|                                        std::string{Outcome.GetError().GetMessage()})); | ||||
|             return false; | ||||
|   | ||||
| @@ -2,14 +2,13 @@ | ||||
| // Created by stephane bourque on 2021-06-02. | ||||
| // | ||||
|  | ||||
| #ifndef UCENTRALFWS_MANIFESTCREATOR_H | ||||
| #define UCENTRALFWS_MANIFESTCREATOR_H | ||||
| #pragma once | ||||
|  | ||||
| #include <aws/core/Aws.h> | ||||
| #include <aws/s3/S3Client.h> | ||||
| #include <aws/core/auth/AWSCredentials.h> | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/SubSystemServer.h" | ||||
| #include "Poco/Timer.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
| @@ -71,5 +70,3 @@ namespace OpenWifi { | ||||
|     inline auto ManifestCreator() { return ManifestCreator::instance(); }; | ||||
|  | ||||
| } | ||||
|  | ||||
| #endif //UCENTRALFWS_MANIFESTCREATOR_H | ||||
|   | ||||
| @@ -5,10 +5,15 @@ | ||||
| #include "NewCommandHandler.h" | ||||
| #include "StorageService.h" | ||||
|  | ||||
| #include "framework/KafkaManager.h" | ||||
| #include "fmt/format.h" | ||||
| #include "nlohmann/json.hpp" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
|     void NewCommandHandler::run() { | ||||
|         Running_ = true ; | ||||
|         Utils::SetThreadName("cmd-handler"); | ||||
|         while(Running_) { | ||||
|             Poco::Thread::trySleep(2000); | ||||
|  | ||||
| @@ -45,9 +50,9 @@ namespace OpenWifi { | ||||
|                             if(Command=="delete_device") { | ||||
|                                 auto pSerialNumber = PayloadSection["payload"]["serialNumber"]; | ||||
|                                 if(pSerialNumber==SerialNumber) { | ||||
|                                     Logger().debug(Poco::format("Removing device '%s' from upgrade history.",SerialNumber)); | ||||
|                                     poco_debug(Logger(),fmt::format("Removing device '{}' from upgrade history.",SerialNumber)); | ||||
|                                     StorageService()->HistoryDB().DeleteHistory(SerialNumber); | ||||
|                                     Logger().debug(Poco::format("Removing device '%s' from device table.",SerialNumber)); | ||||
|                                     poco_debug(Logger(),fmt::format("Removing device '{}' from device table.",SerialNumber)); | ||||
|                                     StorageService()->DevicesDB().DeleteDevice(SerialNumber); | ||||
|                                 } | ||||
|                             } | ||||
|   | ||||
| @@ -2,10 +2,9 @@ | ||||
| // Created by stephane bourque on 2021-11-21. | ||||
| // | ||||
|  | ||||
| #ifndef OWFMS_NEWCOMMANDHANDLER_H | ||||
| #define OWFMS_NEWCOMMANDHANDLER_H | ||||
| #pragma once | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/SubSystemServer.h" | ||||
| #include "framework/OpenWifiTypes.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
| @@ -37,5 +36,3 @@ namespace OpenWifi { | ||||
|     inline auto NewCommandHandler() { return NewCommandHandler::instance(); }; | ||||
|  | ||||
| } | ||||
|  | ||||
| #endif //OWFMS_NEWCOMMANDHANDLER_H | ||||
|   | ||||
| @@ -5,14 +5,17 @@ | ||||
| #include "NewConnectionHandler.h" | ||||
| #include "framework/KafkaTopics.h" | ||||
| #include "framework/OpenWifiTypes.h" | ||||
| #include "framework/ow_constants.h" | ||||
| #include "Poco/JSON/Object.h" | ||||
| #include "Poco/JSON/Parser.h" | ||||
| #include "StorageService.h" | ||||
| #include "LatestFirmwareCache.h" | ||||
| #include "framework/uCentral_Protocol.h" | ||||
| #include "DeviceCache.h" | ||||
| #include "AutoUpdater.h" | ||||
|  | ||||
| #include "framework/KafkaManager.h" | ||||
| #include "fmt/format.h" | ||||
|  | ||||
| /* | ||||
| { "system" : { "id" : 6715803232063 , "host" : "https://localhost:17002" } , | ||||
|  "payload" : "{"capabilities":{"compatible":"linksys_ea8300","model":"Linksys EA8300 (Dallas)","network":{"lan":["eth0"],"wan":["eth1"]},"platform":"ap","switch":{"switch0":{"enable":true,"ports":[{"device":"eth0","need_tag":false,"num":0,"want_untag":true},{"num":1,"role":"lan"},{"num":2,"role":"lan"},{"num":3,"role":"lan"},{"num":4,"role":"lan"}],"reset":true,"roles":[{"device":"eth0","ports":"1 2 3 4 0","role":"lan"}]}},"wifi":{"platform/soc/a000000.wifi":{"band":["2G"],"channels":[1,2,3,4,5,6,7,8,9,10,11],"frequencies":[2412,2417,2422,2427,2432,2437,2442,2447,2452,2457,2462],"ht_capa":6639,"htmode":["HT20","HT40","VHT20","VHT40","VHT80"],"rx_ant":3,"tx_ant":3,"vht_capa":865687986},"platform/soc/a800000.wifi":{"band":["5G"],"channels":[36,40,44,48,52,56,60,64],"frequencies":[5180,5200,5220,5240,5260,5280,5300,5320],"ht_capa":6639,"htmode":["HT20","HT40","VHT20","VHT40","VHT80"],"rx_ant":3,"tx_ant":3,"vht_capa":865687986},"soc/40000000.pci/pci0000:00/0000:00:00.0/0000:01:00.0":{"band":["5G"],"channels":[100,104,108,112,116,120,124,128,132,136,140,144,149,153,157,161,165],"frequencies":[5500,5520,5540,5560,5580,5600,5620,5640,5660,5680,5700,5720,5745,5765,5785,5805,5825],"ht_capa":6639,"htmode":["HT20","HT40","VHT20","VHT40","VHT80"],"rx_ant":3,"tx_ant":3,"vht_capa":865696178}}},"firmware":"OpenWrt 21.02-SNAPSHOT r16011+53-6fd65c6573 / TIP-devel-0825cb93","serial":"24f5a207a130","uuid":1623866223}} | ||||
| @@ -22,6 +25,7 @@ | ||||
| namespace OpenWifi { | ||||
|  | ||||
|     void NewConnectionHandler::run() { | ||||
|         Utils::SetThreadName("conn-handler"); | ||||
|         Running_ = true ; | ||||
|         while(Running_) { | ||||
|             Poco::Thread::trySleep(2000); | ||||
| @@ -67,12 +71,12 @@ namespace OpenWifi { | ||||
|                                 if(StorageService()->FirmwaresDB().ComputeFirmwareAge(DeviceType, Revision, FA)) { | ||||
|                                     StorageService()->DevicesDB().SetDeviceRevision(SerialNumber, Revision, DeviceType, EndPoint); | ||||
|                                     if(FA.age) | ||||
|                                         Logger().information(Poco::format("Device %s connection. Firmware is %s older than latest.",SerialNumber, Utils::SecondsToNiceText(FA.age))); | ||||
|                                         poco_information(Logger(),fmt::format("Device {} connection. Firmware is {} older than latest.",SerialNumber, Utils::SecondsToNiceText(FA.age))); | ||||
|                                     else | ||||
|                                         Logger().information(Poco::format("Device %s connection. Device firmware is up to date.",SerialNumber)); | ||||
|                                     poco_information(Logger(),fmt::format("Device {} connection. Device firmware is up to date.",SerialNumber)); | ||||
|                                 } | ||||
|                                 else { | ||||
|                                     Logger().information(Poco::format("Device %s connection. Firmware age cannot be determined",SerialNumber)); | ||||
|                                     poco_information(Logger(),fmt::format("Device {} connection. Firmware age cannot be determined.",SerialNumber)); | ||||
|                                 } | ||||
|  | ||||
|                                 if(!LatestFirmwareCache()->IsLatest(DeviceType, Revision)) { | ||||
| @@ -115,6 +119,7 @@ namespace OpenWifi { | ||||
|     }; | ||||
|  | ||||
|     int NewConnectionHandler::Start() { | ||||
|         poco_information(Logger(),"Starting..."); | ||||
|         Types::TopicNotifyFunction F = [this](std::string s1,std::string s2) { this->ConnectionReceived(s1,s2); }; | ||||
|         ConnectionWatcherId_ = KafkaManager()->RegisterTopicWatcher(KafkaTopics::CONNECTION, F); | ||||
|         Worker_.start(*this); | ||||
| @@ -122,10 +127,12 @@ namespace OpenWifi { | ||||
|     }; | ||||
|  | ||||
|     void NewConnectionHandler::Stop() { | ||||
|         poco_information(Logger(),"Stopping..."); | ||||
|         KafkaManager()->UnregisterTopicWatcher(KafkaTopics::CONNECTION, ConnectionWatcherId_); | ||||
|         Running_ = false; | ||||
|         Worker_.wakeUp(); | ||||
|         Worker_.join(); | ||||
|         poco_information(Logger(),"Stopped..."); | ||||
|     }; | ||||
|  | ||||
|     bool NewConnectionHandler::Update() { | ||||
|   | ||||
| @@ -2,11 +2,9 @@ | ||||
| // Created by stephane bourque on 2021-07-13. | ||||
| // | ||||
|  | ||||
| #ifndef UCENTRALFMS_NEWCONNECTIONHANDLER_H | ||||
| #define UCENTRALFMS_NEWCONNECTIONHANDLER_H | ||||
| #pragma once | ||||
|  | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/SubSystemServer.h" | ||||
| #include "framework/OpenWifiTypes.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
| @@ -29,8 +27,7 @@ namespace OpenWifi { | ||||
|     private: | ||||
|         Poco::Thread                Worker_; | ||||
|         std::atomic_bool            Running_ = false; | ||||
|         int                         ConnectionWatcherId_=0; | ||||
|         int                         HealthcheckWatcherId_=0; | ||||
|         uint64_t                    ConnectionWatcherId_=0; | ||||
|         Types::StringPairQueue      NewConnections_; | ||||
|  | ||||
|         NewConnectionHandler() noexcept: | ||||
| @@ -41,4 +38,3 @@ namespace OpenWifi { | ||||
|     inline auto NewConnectionHandler() { return NewConnectionHandler::instance(); }; | ||||
| } | ||||
|  | ||||
| #endif //UCENTRALFMS_NEWCONNECTIONHANDLER_H | ||||
|   | ||||
| @@ -2,8 +2,7 @@ | ||||
| // Created by stephane bourque on 2021-10-23. | ||||
| // | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
|  | ||||
| #include "framework/RESTAPI_Handler.h" | ||||
| #include "RESTAPI/RESTAPI_firmwareHandler.h" | ||||
| #include "RESTAPI/RESTAPI_firmwaresHandler.h" | ||||
| #include "RESTAPI/RESTAPI_firmwareAgeHandler.h" | ||||
| @@ -11,31 +10,40 @@ | ||||
| #include "RESTAPI/RESTAPI_connectedDevicesHandler.h" | ||||
| #include "RESTAPI/RESTAPI_historyHandler.h" | ||||
| #include "RESTAPI/RESTAPI_deviceReportHandler.h" | ||||
| #include "RESTAPI/RESTAPI_deviceInformation_handler.h" | ||||
| #include "framework/RESTAPI_SystemCommand.h" | ||||
| #include "framework/RESTAPI_WebSocketServer.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
|     Poco::Net::HTTPRequestHandler * RESTAPI_ExtRouter(const char *Path, RESTAPIHandler::BindingMap &Bindings, | ||||
|                                                             Poco::Logger & L, RESTAPI_GenericServer & S, uint64_t TransactionId) { | ||||
|     Poco::Net::HTTPRequestHandler * RESTAPI_ExtRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings, | ||||
|                                                             Poco::Logger & L, RESTAPI_GenericServerAccounting & S, uint64_t TransactionId) { | ||||
|         return  RESTAPI_Router< | ||||
|             RESTAPI_firmwaresHandler, | ||||
|             RESTAPI_firmwareHandler, | ||||
|             RESTAPI_system_command, | ||||
|             RESTAPI_firmwareAgeHandler, | ||||
|             RESTAPI_connectedDevicesHandler, | ||||
|             RESTAPI_connectedDeviceHandler, | ||||
|             RESTAPI_historyHandler, | ||||
|             RESTAPI_deviceReportHandler | ||||
|                 RESTAPI_firmwaresHandler, | ||||
|                 RESTAPI_firmwareHandler, | ||||
|                 RESTAPI_system_command, | ||||
|                 RESTAPI_firmwareAgeHandler, | ||||
|                 RESTAPI_connectedDevicesHandler, | ||||
|                 RESTAPI_connectedDeviceHandler, | ||||
|                 RESTAPI_historyHandler, | ||||
|                 RESTAPI_deviceReportHandler, | ||||
|                 RESTAPI_deviceInformation_handler, | ||||
|                 RESTAPI_webSocketServer | ||||
|             >(Path,Bindings,L, S, TransactionId); | ||||
|     } | ||||
|  | ||||
|     Poco::Net::HTTPRequestHandler * RESTAPI_IntRouter(const char *Path, RESTAPIHandler::BindingMap &Bindings, | ||||
|                                                             Poco::Logger & L, RESTAPI_GenericServer & S, uint64_t TransactionId) { | ||||
|     Poco::Net::HTTPRequestHandler * RESTAPI_IntRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings, | ||||
|                                                             Poco::Logger & L, RESTAPI_GenericServerAccounting & S, uint64_t TransactionId) { | ||||
|         return RESTAPI_Router_I< | ||||
|             RESTAPI_firmwaresHandler, | ||||
|             RESTAPI_firmwareHandler, | ||||
|             RESTAPI_system_command, | ||||
|             RESTAPI_connectedDevicesHandler, | ||||
|             RESTAPI_connectedDeviceHandler | ||||
|                 RESTAPI_firmwaresHandler, | ||||
|                 RESTAPI_firmwareHandler, | ||||
|                 RESTAPI_system_command, | ||||
|                 RESTAPI_firmwareAgeHandler, | ||||
|                 RESTAPI_connectedDevicesHandler, | ||||
|                 RESTAPI_connectedDeviceHandler, | ||||
|                 RESTAPI_historyHandler, | ||||
|                 RESTAPI_deviceReportHandler, | ||||
|                 RESTAPI_deviceInformation_handler | ||||
|             >(Path, Bindings, L, S, TransactionId); | ||||
|     } | ||||
| } | ||||
| @@ -5,8 +5,7 @@ | ||||
| #include "RESTAPI_connectedDeviceHandler.h" | ||||
| #include "RESTObjects/RESTAPI_FMSObjects.h" | ||||
| #include "StorageService.h" | ||||
| #include "framework/RESTAPI_protocol.h" | ||||
| #include "framework/RESTAPI_errors.h" | ||||
| #include "framework/ow_constants.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
|   | ||||
| @@ -5,12 +5,12 @@ | ||||
| #ifndef UCENTRALFMS_RESTAPI_CONNECTEDDEVICEHANDLER_H | ||||
| #define UCENTRALFMS_RESTAPI_CONNECTEDDEVICEHANDLER_H | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_Handler.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     class RESTAPI_connectedDeviceHandler : public RESTAPIHandler { | ||||
|     public: | ||||
|         RESTAPI_connectedDeviceHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal) | ||||
|         RESTAPI_connectedDeviceHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal) | ||||
|                 : RESTAPIHandler(bindings, L, | ||||
|                                  std::vector<std::string> | ||||
|                                          {Poco::Net::HTTPRequest::HTTP_GET, | ||||
| @@ -18,7 +18,7 @@ namespace OpenWifi { | ||||
|                                           Server, | ||||
|                                           TransactionId, | ||||
|                                           Internal) {} | ||||
|         static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/connectedDevice/{serialNumber}"};} | ||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/connectedDevice/{serialNumber}"};} | ||||
|  | ||||
|         void DoGet() final; | ||||
|         void DoDelete() final {}; | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
| #include "RESTAPI_connectedDevicesHandler.h" | ||||
| #include "RESTObjects/RESTAPI_FMSObjects.h" | ||||
| #include "StorageService.h" | ||||
| #include "framework/RESTAPI_protocol.h" | ||||
| #include "framework/ow_constants.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     void RESTAPI_connectedDevicesHandler::DoGet() { | ||||
|   | ||||
| @@ -6,12 +6,12 @@ | ||||
| #define UCENTRALFMS_RESTAPI_CONNECTEDDEVICESHANDLER_H | ||||
|  | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_Handler.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     class RESTAPI_connectedDevicesHandler : public RESTAPIHandler { | ||||
|     public: | ||||
|         RESTAPI_connectedDevicesHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal) | ||||
|         RESTAPI_connectedDevicesHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal) | ||||
|                 : RESTAPIHandler(bindings, L, | ||||
|                                  std::vector<std::string> | ||||
|                                          {Poco::Net::HTTPRequest::HTTP_GET, | ||||
| @@ -19,7 +19,7 @@ namespace OpenWifi { | ||||
|                                           Server, | ||||
|                                           TransactionId, | ||||
|                                           Internal) {} | ||||
|         static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/connectedDevices"};} | ||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/connectedDevices"};} | ||||
|         void DoGet()  final; | ||||
|         void DoDelete() final {}; | ||||
|         void DoPost() final {}; | ||||
|   | ||||
							
								
								
									
										47
									
								
								src/RESTAPI/RESTAPI_deviceInformation_handler.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/RESTAPI/RESTAPI_deviceInformation_handler.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | ||||
| // | ||||
| // Created by stephane bourque on 2022-03-04. | ||||
| // | ||||
|  | ||||
| #include "RESTAPI_deviceInformation_handler.h" | ||||
| #include "StorageService.h" | ||||
| #include "LatestFirmwareCache.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     void RESTAPI_deviceInformation_handler::DoGet() { | ||||
|         auto SerialNumber = GetBinding("serialNumber",""); | ||||
|  | ||||
|         if(SerialNumber.empty() || !Utils::ValidSerialNumber(SerialNumber)) { | ||||
|             return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); | ||||
|         } | ||||
|  | ||||
|         FMSObjects::DeviceInformation   DI; | ||||
|  | ||||
|         //  Let's get the history | ||||
|         StorageService()->HistoryDB().GetHistory(SerialNumber,0,100,DI.history.history); | ||||
|  | ||||
|         // Let's get the DeviceConnectionInformation | ||||
|         FMSObjects::DeviceConnectionInformation DCI; | ||||
|         StorageService()->DevicesDB().GetDevice(SerialNumber,DCI); | ||||
|  | ||||
|         LatestFirmwareCacheEntry    LFE; | ||||
|         LatestFirmwareCache()->FindLatestFirmware(DCI.deviceType,LFE); | ||||
|  | ||||
|         FMSObjects::Firmware        Latest; | ||||
|         StorageService()->FirmwaresDB().GetFirmware(LFE.Id,Latest); | ||||
|  | ||||
|         DI.serialNumber = SerialNumber; | ||||
|         DI.currentFirmware = DCI.revision; | ||||
|         DI.latestFirmware = LFE.Revision; | ||||
|         DI.latestFirmwareDate = LFE.TimeStamp; | ||||
|         DI.latestFirmwareURI = Latest.uri; | ||||
|         FirmwaresDB::RecordName FI; | ||||
|         StorageService()->FirmwaresDB().GetFirmwareByRevision(DCI.revision,DCI.deviceType,FI); | ||||
|         DI.currentFirmwareDate = FI.imageDate; | ||||
|  | ||||
|         DI.latestFirmwareAvailable = (LFE.Revision != DCI.revision); | ||||
|  | ||||
|         Poco::JSON::Object  Answer; | ||||
|         DI.to_json(Answer); | ||||
|         return ReturnObject(Answer); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										26
									
								
								src/RESTAPI/RESTAPI_deviceInformation_handler.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/RESTAPI/RESTAPI_deviceInformation_handler.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| // | ||||
| // Created by stephane bourque on 2022-03-04. | ||||
| // | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "framework/RESTAPI_Handler.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     class RESTAPI_deviceInformation_handler : public RESTAPIHandler { | ||||
|     public: | ||||
|         RESTAPI_deviceInformation_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal) | ||||
|                 : RESTAPIHandler(bindings, L, | ||||
|                                  std::vector<std::string> | ||||
|                                          {Poco::Net::HTTPRequest::HTTP_GET, | ||||
|                                           Poco::Net::HTTPRequest::HTTP_OPTIONS}, | ||||
|                                  Server, | ||||
|                                  TransactionId, | ||||
|                                  Internal) {} | ||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/deviceInformation/{serialNumber}"};} | ||||
|         void DoGet()  final; | ||||
|         void DoDelete() final {}; | ||||
|         void DoPost() final {}; | ||||
|         void DoPut() final {}; | ||||
|     }; | ||||
| } | ||||
| @@ -3,16 +3,19 @@ | ||||
| // | ||||
|  | ||||
| #include "RESTAPI_deviceReportHandler.h" | ||||
| #include "StorageService.h" | ||||
| #include "RESTObjects/RESTAPI_FMSObjects.h" | ||||
| #include "Poco/JSON/Object.h" | ||||
| #include "Daemon.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     void RESTAPI_deviceReportHandler::DoGet() { | ||||
|         Daemon()->CreateDashboard(); | ||||
|         Poco::JSON::Object  O; | ||||
|         Daemon()->GetDashboard().to_json(O); | ||||
|         ReturnObject(O); | ||||
|         poco_information(Logger(),fmt::format("GET-DASHBOARD: {}", Requester())); | ||||
|         FMSObjects::DeviceReport	Data; | ||||
|         if(Daemon()->GetDashboard().Get(Data, Logger())) { | ||||
|             Poco::JSON::Object Answer; | ||||
|             Data.to_json(Answer); | ||||
|             return ReturnObject(Answer); | ||||
|         } | ||||
|         return BadRequest(RESTAPI::Errors::InternalError); | ||||
|     } | ||||
| } | ||||
| @@ -2,15 +2,14 @@ | ||||
| // Created by stephane bourque on 2021-07-19. | ||||
| // | ||||
|  | ||||
| #ifndef UCENTRALFMS_RESTAPI_DEVICEREPORTHANDLER_H | ||||
| #define UCENTRALFMS_RESTAPI_DEVICEREPORTHANDLER_H | ||||
| #pragma once | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_Handler.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     class RESTAPI_deviceReportHandler : public RESTAPIHandler { | ||||
|     public: | ||||
|         RESTAPI_deviceReportHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal) | ||||
|         RESTAPI_deviceReportHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal) | ||||
|                 : RESTAPIHandler(bindings, L, | ||||
|                                  std::vector<std::string> | ||||
|                                          {Poco::Net::HTTPRequest::HTTP_GET, | ||||
| @@ -18,13 +17,10 @@ namespace OpenWifi { | ||||
|                                           Server, | ||||
|                                           TransactionId, | ||||
|                                  Internal) {} | ||||
|         static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/deviceReport"};} | ||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/deviceReport"};} | ||||
|         void DoGet()  final; | ||||
|         void DoDelete() final {}; | ||||
|         void DoPost() final {}; | ||||
|         void DoPut() final {}; | ||||
|     }; | ||||
| } | ||||
|  | ||||
|  | ||||
| #endif //UCENTRALFMS_RESTAPI_DEVICEREPORTHANDLER_H | ||||
|   | ||||
| @@ -7,10 +7,7 @@ | ||||
| #include "StorageService.h" | ||||
| #include "Poco/JSON/Parser.h" | ||||
| #include "DeviceCache.h" | ||||
| #include "framework/uCentral_Protocol.h" | ||||
| #include "framework/RESTAPI_protocol.h" | ||||
| #include "framework/RESTAPI_errors.h" | ||||
|  | ||||
| #include "framework/ow_constants.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     void RESTAPI_firmwareAgeHandler::DoGet() { | ||||
|   | ||||
| @@ -5,12 +5,12 @@ | ||||
| #ifndef UCENTRALFMS_RESTAPI_FIRMWAREAGEHANDLER_H | ||||
| #define UCENTRALFMS_RESTAPI_FIRMWAREAGEHANDLER_H | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_Handler.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     class RESTAPI_firmwareAgeHandler : public RESTAPIHandler { | ||||
|     public: | ||||
|         RESTAPI_firmwareAgeHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal) | ||||
|         RESTAPI_firmwareAgeHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal) | ||||
|                 : RESTAPIHandler(bindings, L, | ||||
|                                  std::vector<std::string> | ||||
|                                          {Poco::Net::HTTPRequest::HTTP_GET, | ||||
| @@ -18,7 +18,7 @@ namespace OpenWifi { | ||||
|                                           Server, | ||||
|                                           TransactionId, | ||||
|                                           Internal) {} | ||||
|         static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/firmwareAge"};} | ||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/firmwareAge"};} | ||||
|         void DoGet()  final; | ||||
|         void DoDelete() final {}; | ||||
|         void DoPost() final {}; | ||||
|   | ||||
| @@ -4,21 +4,21 @@ | ||||
|  | ||||
| #include "Poco/JSON/Parser.h" | ||||
|  | ||||
| #include "RESTAPI_firmwareHandler.h" | ||||
| #include "RESTAPI/RESTAPI_firmwareHandler.h" | ||||
| #include "StorageService.h" | ||||
| #include "framework/uCentral_Protocol.h" | ||||
| #include "framework/RESTAPI_protocol.h" | ||||
| #include "framework/RESTAPI_errors.h" | ||||
| #include "framework/ow_constants.h" | ||||
| #include "framework/MicroServiceFuncs.h" | ||||
| #include "framework/utils.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     void | ||||
|     RESTAPI_firmwareHandler::DoPost() { | ||||
|         auto Obj = ParseStream(); | ||||
|         const auto &Obj = ParsedBody_; | ||||
|         FMSObjects::Firmware F; | ||||
|         if (!F.from_json(Obj)) { | ||||
|             return BadRequest(RESTAPI::Errors::InvalidJSONDocument); | ||||
|         } | ||||
|         F.id = MicroService::instance().CreateUUID(); | ||||
|         F.id = MicroServiceCreateUUID(); | ||||
|         if(StorageService()->FirmwaresDB().AddFirmware(F)) { | ||||
|             Poco::JSON::Object  Answer; | ||||
|             F.to_json(Answer); | ||||
| @@ -68,7 +68,7 @@ namespace OpenWifi { | ||||
|             return NotFound(); | ||||
|         } | ||||
|  | ||||
|         auto Obj = ParseStream(); | ||||
|         const auto & Obj = ParsedBody_; | ||||
|         FMSObjects::Firmware    NewFirmware; | ||||
|         if(!NewFirmware.from_json(Obj)) { | ||||
|             return BadRequest(RESTAPI::Errors::InvalidJSONDocument); | ||||
| @@ -80,7 +80,7 @@ namespace OpenWifi { | ||||
|             SecurityObjects::NoteInfoVec NIV; | ||||
|             NIV = RESTAPI_utils::to_object_array<SecurityObjects::NoteInfo>(Obj->get(RESTAPI::Protocol::NOTES).toString()); | ||||
|             for(auto const &i:NIV) { | ||||
|                 SecurityObjects::NoteInfo   ii{.created=(uint64_t)std::time(nullptr), .createdBy=UserInfo_.userinfo.email, .note=i.note}; | ||||
|                 SecurityObjects::NoteInfo   ii{.created=(uint64_t)Utils::Now(), .createdBy=UserInfo_.userinfo.email, .note=i.note}; | ||||
|                 F.notes.push_back(ii); | ||||
|             } | ||||
|         } | ||||
|   | ||||
| @@ -5,12 +5,12 @@ | ||||
| #ifndef UCENTRALFWS_RESTAPI_FIRMWAREHANDLER_H | ||||
| #define UCENTRALFWS_RESTAPI_FIRMWAREHANDLER_H | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_Handler.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     class RESTAPI_firmwareHandler : public RESTAPIHandler { | ||||
|     public: | ||||
|         RESTAPI_firmwareHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal) | ||||
|         RESTAPI_firmwareHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal) | ||||
|                 : RESTAPIHandler(bindings, L, | ||||
|                                  std::vector<std::string> | ||||
|                                          {Poco::Net::HTTPRequest::HTTP_GET, | ||||
| @@ -21,7 +21,7 @@ namespace OpenWifi { | ||||
|                                           Server, | ||||
|                                           TransactionId, | ||||
|                                           Internal) {} | ||||
|         static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/firmware/{id}"};} | ||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/firmware/{id}"};} | ||||
|         void DoGet()  final; | ||||
|         void DoDelete() final; | ||||
|         void DoPost() final; | ||||
|   | ||||
| @@ -5,18 +5,17 @@ | ||||
| #include "RESTAPI_firmwaresHandler.h" | ||||
| #include "StorageService.h" | ||||
| #include "LatestFirmwareCache.h" | ||||
| #include "framework/RESTAPI_protocol.h" | ||||
| #include "framework/ow_constants.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     void | ||||
|     RESTAPI_firmwaresHandler::DoGet() { | ||||
|         std::string DeviceType = GetParameter(RESTAPI::Protocol::DEVICETYPE, ""); | ||||
|         bool IdOnly = GetBoolParameter(RESTAPI::Protocol::IDONLY, false); | ||||
|         bool RevisionSet = GetBoolParameter(RESTAPI::Protocol::REVISIONSET, false); | ||||
|         bool LatestOnly = GetBoolParameter(RESTAPI::Protocol::LATESTONLY, false); | ||||
|         bool DeviceSet = GetBoolParameter(RESTAPI::Protocol::DEVICESET, false); | ||||
|         bool IdOnly = GetBoolParameter(RESTAPI::Protocol::IDONLY); | ||||
|         bool LatestOnly = GetBoolParameter(RESTAPI::Protocol::LATESTONLY); | ||||
|         bool rcOnly = GetBoolParameter("rcOnly"); | ||||
|  | ||||
|         if(DeviceSet) { | ||||
|         if(GetBoolParameter(RESTAPI::Protocol::DEVICESET)) { | ||||
|             auto Revisions = LatestFirmwareCache()->GetDevices(); | ||||
|             Poco::JSON::Array ObjectArray; | ||||
|             for (const auto &i:Revisions) { | ||||
| @@ -27,7 +26,7 @@ namespace OpenWifi { | ||||
|             return ReturnObject(RetObj); | ||||
|         } | ||||
|  | ||||
|         if(RevisionSet) { | ||||
|         if(GetBoolParameter(RESTAPI::Protocol::REVISIONSET)) { | ||||
|             auto Revisions = LatestFirmwareCache()->GetRevisions(); | ||||
|             Poco::JSON::Array ObjectArray; | ||||
|             for (const auto &i:Revisions) { | ||||
| @@ -42,8 +41,14 @@ namespace OpenWifi { | ||||
|         if(!DeviceType.empty()) { | ||||
|             if(LatestOnly) { | ||||
|                 LatestFirmwareCacheEntry    Entry; | ||||
|                 if(!LatestFirmwareCache()->FindLatestFirmware(DeviceType,Entry)) { | ||||
|                     return NotFound(); | ||||
|                 if(rcOnly) { | ||||
|                     if (!LatestFirmwareCache()->FindLatestRCOnlyFirmware(DeviceType, Entry)) { | ||||
|                         return NotFound(); | ||||
|                     } | ||||
|                 } else { | ||||
|                     if (!LatestFirmwareCache()->FindLatestFirmware(DeviceType, Entry)) { | ||||
|                         return NotFound(); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 FMSObjects::Firmware    F; | ||||
| @@ -58,6 +63,8 @@ namespace OpenWifi { | ||||
|                 if (StorageService()->FirmwaresDB().GetFirmwares(QB_.Offset, QB_.Limit, DeviceType, List)) { | ||||
|                     Poco::JSON::Array ObjectArray; | ||||
|                     for (const auto &i:List) { | ||||
|                         if(rcOnly && !LatestFirmwareCache::IsRC(i.revision)) | ||||
|                             continue; | ||||
|                         if(IdOnly) { | ||||
|                             ObjectArray.add(i.id); | ||||
|                         } else { | ||||
| @@ -80,6 +87,8 @@ namespace OpenWifi { | ||||
|         Poco::JSON::Object Answer; | ||||
|         if (StorageService()->FirmwaresDB().GetFirmwares(QB_.Offset, QB_.Limit, DeviceType, List)) { | ||||
|             for (const auto &i:List) { | ||||
|                 if(rcOnly && !LatestFirmwareCache::IsRC(i.revision)) | ||||
|                     continue; | ||||
|                 if(IdOnly) { | ||||
|                     ObjectArray.add(i.id); | ||||
|                 } else { | ||||
|   | ||||
| @@ -5,12 +5,12 @@ | ||||
| #ifndef UCENTRALFWS_RESTAPI_FIRMWARESHANDLER_H | ||||
| #define UCENTRALFWS_RESTAPI_FIRMWARESHANDLER_H | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_Handler.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     class RESTAPI_firmwaresHandler : public RESTAPIHandler { | ||||
|     public: | ||||
|         RESTAPI_firmwaresHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal) | ||||
|         RESTAPI_firmwaresHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal) | ||||
|                 : RESTAPIHandler(bindings, L, | ||||
|                                  std::vector<std::string> | ||||
|                                          {Poco::Net::HTTPRequest::HTTP_GET, | ||||
| @@ -19,7 +19,7 @@ namespace OpenWifi { | ||||
|                                           TransactionId, | ||||
|                                           Internal) {} | ||||
|  | ||||
|         static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/firmwares"};} | ||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/firmwares"};} | ||||
|         void DoGet()  final; | ||||
|         void DoDelete() final {}; | ||||
|         void DoPost() final {}; | ||||
|   | ||||
| @@ -4,8 +4,7 @@ | ||||
|  | ||||
| #include "RESTAPI_historyHandler.h" | ||||
| #include "StorageService.h" | ||||
| #include "framework/RESTAPI_protocol.h" | ||||
| #include "framework/RESTAPI_errors.h" | ||||
| #include "framework/ow_constants.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     void | ||||
| @@ -16,6 +15,26 @@ namespace OpenWifi { | ||||
|             return BadRequest(RESTAPI::Errors::MissingSerialNumber); | ||||
|         } | ||||
|  | ||||
|         auto unknownList = GetBoolParameter("unknownList"); | ||||
|         if(SerialNumber=="000000000000" && unknownList) { | ||||
|             // so let's get all the devices, filter the latest record | ||||
|             FMSObjects::DeviceCurrentInfoList   L; | ||||
|             StorageService()->HistoryDB().GetUnknownDeviceFirmwares(QB_.Offset,QB_.Limit,L.devices); | ||||
|             Poco::JSON::Object  Answer; | ||||
|             L.to_json(Answer); | ||||
|             return ReturnObject(Answer); | ||||
|         } | ||||
|  | ||||
|         auto currentList = GetBoolParameter("currentList"); | ||||
|         if(SerialNumber=="000000000000" && currentList) { | ||||
|             // so let's get all the devices, filter the latest record | ||||
|             FMSObjects::DeviceCurrentInfoList   L; | ||||
|             StorageService()->HistoryDB().GetDeviceFirmwares(QB_.Offset,QB_.Limit,L.devices); | ||||
|             Poco::JSON::Object  Answer; | ||||
|             L.to_json(Answer); | ||||
|             return ReturnObject(Answer); | ||||
|         } | ||||
|  | ||||
|         FMSObjects::RevisionHistoryEntryVec H; | ||||
|         if (StorageService()->HistoryDB().GetHistory(SerialNumber, QB_.Offset, QB_.Limit, H)) { | ||||
|             Poco::JSON::Array A; | ||||
|   | ||||
| @@ -2,16 +2,14 @@ | ||||
| // Created by stephane bourque on 2021-07-13. | ||||
| // | ||||
|  | ||||
| #ifndef UCENTRALFMS_RESTAPI_HISTORYHANDLER_H | ||||
| #define UCENTRALFMS_RESTAPI_HISTORYHANDLER_H | ||||
| #pragma once | ||||
|  | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_Handler.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     class RESTAPI_historyHandler : public RESTAPIHandler { | ||||
|     public: | ||||
|         RESTAPI_historyHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal) | ||||
|         RESTAPI_historyHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal) | ||||
|                 : RESTAPIHandler(bindings, L, | ||||
|                                  std::vector<std::string> | ||||
|                                          {Poco::Net::HTTPRequest::HTTP_GET, | ||||
| @@ -20,13 +18,10 @@ namespace OpenWifi { | ||||
|                                           Server, | ||||
|                                           TransactionId, | ||||
|                                           Internal) {} | ||||
|         static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/revisionHistory/{serialNumber}"};} | ||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/revisionHistory/{serialNumber}"};} | ||||
|         void DoGet()  final; | ||||
|         void DoDelete() final; | ||||
|         void DoPost() final {}; | ||||
|         void DoPut() final {}; | ||||
|     }; | ||||
| } | ||||
|  | ||||
|  | ||||
| #endif //UCENTRALFMS_RESTAPI_HISTORYHANDLER_H | ||||
|   | ||||
							
								
								
									
										624
									
								
								src/RESTObjects/RESTAPI_AnalyticsObjects.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										624
									
								
								src/RESTObjects/RESTAPI_AnalyticsObjects.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,624 @@ | ||||
| // | ||||
| // Created by stephane bourque on 2022-01-10. | ||||
| // | ||||
|  | ||||
| #include "RESTAPI_AnalyticsObjects.h" | ||||
| #include "RESTAPI_ProvObjects.h" | ||||
| #include "framework/RESTAPI_utils.h" | ||||
|  | ||||
| using OpenWifi::RESTAPI_utils::field_to_json; | ||||
| using OpenWifi::RESTAPI_utils::field_from_json; | ||||
|  | ||||
| namespace OpenWifi::AnalyticsObjects { | ||||
|  | ||||
|     void Report::reset() { | ||||
|     } | ||||
|  | ||||
|     void Report::to_json([[maybe_unused]] Poco::JSON::Object &Obj) const { | ||||
|     } | ||||
|  | ||||
|     void VenueInfo::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj,"id",id); | ||||
|         field_to_json(Obj,"name",name); | ||||
|         field_to_json(Obj,"description",description); | ||||
|         field_to_json(Obj,"retention",retention); | ||||
|         field_to_json(Obj,"interval",interval); | ||||
|         field_to_json(Obj,"monitorSubVenues",monitorSubVenues); | ||||
|     } | ||||
|  | ||||
|     bool VenueInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj,"id",id); | ||||
|             field_from_json(Obj,"name",name); | ||||
|             field_from_json(Obj,"description",description); | ||||
|             field_from_json(Obj,"retention",retention); | ||||
|             field_from_json(Obj,"interval",interval); | ||||
|             field_from_json(Obj,"monitorSubVenues",monitorSubVenues); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void BoardInfo::to_json(Poco::JSON::Object &Obj) const { | ||||
|         info.to_json(Obj); | ||||
|         field_to_json(Obj,"venueList",venueList); | ||||
|     } | ||||
|  | ||||
|     bool BoardInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             info.from_json(Obj); | ||||
|             field_from_json(Obj,"venueList",venueList); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void DeviceInfo::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj,"boardId",boardId); | ||||
|         field_to_json(Obj,"type",type); | ||||
|         field_to_json(Obj,"serialNumber",serialNumber); | ||||
|         field_to_json(Obj,"deviceType",deviceType); | ||||
|         field_to_json(Obj,"lastContact",lastContact); | ||||
|         field_to_json(Obj,"lastPing",lastPing); | ||||
|         field_to_json(Obj,"lastState",lastState); | ||||
|         field_to_json(Obj,"lastFirmware",lastFirmware); | ||||
|         field_to_json(Obj,"lastFirmwareUpdate",lastFirmwareUpdate); | ||||
|         field_to_json(Obj,"lastConnection",lastConnection); | ||||
|         field_to_json(Obj,"lastDisconnection",lastDisconnection); | ||||
|         field_to_json(Obj,"pings",pings); | ||||
|         field_to_json(Obj,"states",states); | ||||
|         field_to_json(Obj,"connected",connected); | ||||
|         field_to_json(Obj,"connectionIp",connectionIp); | ||||
|         field_to_json(Obj,"associations_2g",associations_2g); | ||||
|         field_to_json(Obj,"associations_5g",associations_5g); | ||||
|         field_to_json(Obj,"associations_6g",associations_6g); | ||||
|         field_to_json(Obj,"health",health); | ||||
|         field_to_json(Obj,"lastHealth",lastHealth); | ||||
|         field_to_json(Obj,"locale",locale); | ||||
|         field_to_json(Obj,"uptime",uptime); | ||||
|         field_to_json(Obj,"memory",memory); | ||||
|     } | ||||
|  | ||||
|     bool DeviceInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj,"boardId",boardId); | ||||
|             field_from_json(Obj,"type",type); | ||||
|             field_from_json(Obj,"serialNumber",serialNumber); | ||||
|             field_from_json(Obj,"deviceType",deviceType); | ||||
|             field_from_json(Obj,"lastContact",lastContact); | ||||
|             field_from_json(Obj,"lastPing",lastPing); | ||||
|             field_from_json(Obj,"lastState",lastState); | ||||
|             field_from_json(Obj,"lastFirmware",lastFirmware); | ||||
|             field_from_json(Obj,"lastFirmwareUpdate",lastFirmwareUpdate); | ||||
|             field_from_json(Obj,"lastConnection",lastConnection); | ||||
|             field_from_json(Obj,"lastDisconnection",lastDisconnection); | ||||
|             field_from_json(Obj,"pings",pings); | ||||
|             field_from_json(Obj,"states",states); | ||||
|             field_from_json(Obj,"connected",connected); | ||||
|             field_from_json(Obj,"connectionIp",connectionIp); | ||||
|             field_from_json(Obj,"associations_2g",associations_2g); | ||||
|             field_from_json(Obj,"associations_5g",associations_5g); | ||||
|             field_from_json(Obj,"associations_6g",associations_6g); | ||||
|             field_from_json(Obj,"health",health); | ||||
|             field_from_json(Obj,"lastHealth",lastHealth); | ||||
|             field_from_json(Obj,"locale",locale); | ||||
|             field_from_json(Obj,"uptime",uptime); | ||||
|             field_from_json(Obj,"memory",memory); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void DeviceInfoList::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj,"devices",devices); | ||||
|     } | ||||
|  | ||||
|     bool DeviceInfoList::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj,"devices",devices); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void UE_rate::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj,"bitrate",bitrate); | ||||
|         field_to_json(Obj,"mcs",mcs); | ||||
|         field_to_json(Obj,"nss",nss); | ||||
|         field_to_json(Obj,"ht",ht); | ||||
|         field_to_json(Obj,"sgi",sgi); | ||||
|         field_to_json(Obj,"chwidth",chwidth); | ||||
|     } | ||||
|  | ||||
|     bool UE_rate::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj,"bitrate",bitrate); | ||||
|             field_from_json(Obj,"mcs",mcs); | ||||
|             field_from_json(Obj,"nss",nss); | ||||
|             field_from_json(Obj,"ht",ht); | ||||
|             field_from_json(Obj,"sgi",sgi); | ||||
|             field_from_json(Obj,"chwidth",chwidth); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void UETimePoint::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj,"station",station); | ||||
|         field_to_json(Obj,"rssi",rssi); | ||||
|         field_to_json(Obj,"tx_bytes",tx_bytes); | ||||
|         field_to_json(Obj,"rx_bytes",rx_bytes); | ||||
|         field_to_json(Obj,"tx_duration",tx_duration); | ||||
|         field_to_json(Obj,"rx_packets",rx_packets); | ||||
|         field_to_json(Obj,"tx_packets",tx_packets); | ||||
|         field_to_json(Obj,"tx_retries",tx_retries); | ||||
|         field_to_json(Obj,"tx_failed",tx_failed); | ||||
|         field_to_json(Obj,"connected",connected); | ||||
|         field_to_json(Obj,"inactive",inactive); | ||||
|         field_to_json(Obj,"tx_rate",tx_rate); | ||||
|         field_to_json(Obj,"rx_rate",rx_rate); | ||||
| //      field_to_json(Obj, "tidstats", tidstats); | ||||
|  | ||||
|         field_to_json(Obj,"tx_bytes_bw",tx_bytes_bw); | ||||
|         field_to_json(Obj,"rx_bytes_bw",rx_bytes_bw); | ||||
|         field_to_json(Obj,"tx_packets_bw",tx_packets_bw); | ||||
|         field_to_json(Obj,"rx_packets_bw",rx_packets_bw); | ||||
|         field_to_json(Obj,"tx_failed_pct",tx_failed_pct); | ||||
|         field_to_json(Obj,"tx_retries_pct",tx_retries_pct); | ||||
|         field_to_json(Obj,"tx_duration_pct",tx_duration_pct); | ||||
|  | ||||
|         field_to_json(Obj,"tx_bytes_delta",tx_bytes_delta); | ||||
|         field_to_json(Obj,"rx_bytes_delta",rx_bytes_delta); | ||||
|         field_to_json(Obj,"tx_packets_delta",tx_packets_delta); | ||||
|         field_to_json(Obj,"rx_packets_delta",rx_packets_delta); | ||||
|         field_to_json(Obj,"tx_failed_delta",tx_failed_delta); | ||||
|         field_to_json(Obj,"tx_retries_delta",tx_retries_delta); | ||||
|         field_to_json(Obj,"tx_duration_delta",tx_duration_delta); | ||||
|     } | ||||
|  | ||||
|     bool UETimePoint::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj,"station",station); | ||||
|             field_from_json(Obj,"rssi",rssi); | ||||
|             field_from_json(Obj,"tx_bytes",tx_bytes); | ||||
|             field_from_json(Obj,"rx_bytes",rx_bytes); | ||||
|             field_from_json(Obj,"tx_duration",tx_duration); | ||||
|             field_from_json(Obj,"rx_packets",rx_packets); | ||||
|             field_from_json(Obj,"tx_packets",tx_packets); | ||||
|             field_from_json(Obj,"tx_retries",tx_retries); | ||||
|             field_from_json(Obj,"tx_failed",tx_failed); | ||||
|             field_from_json(Obj,"connected",connected); | ||||
|             field_from_json(Obj,"inactive",inactive); | ||||
|             field_from_json(Obj,"tx_rate",tx_rate); | ||||
|             field_from_json(Obj,"rx_rate",rx_rate); | ||||
| //          field_from_json(Obj,"tidstats",tidstats); | ||||
|             field_from_json(Obj,"tx_bytes_bw",tx_bytes_bw); | ||||
|             field_from_json(Obj,"rx_bytes_bw",rx_bytes_bw); | ||||
|             field_from_json(Obj,"tx_packets_bw",tx_packets_bw); | ||||
|             field_from_json(Obj,"rx_packets_bw",rx_packets_bw); | ||||
|             field_from_json(Obj,"tx_failed_pct",tx_failed_pct); | ||||
|             field_from_json(Obj,"tx_retries_pct",tx_retries_pct); | ||||
|             field_from_json(Obj,"tx_duration_pct",tx_duration_pct); | ||||
|             field_from_json(Obj,"tx_bytes_delta",tx_bytes_delta); | ||||
|             field_from_json(Obj,"rx_bytes_delta",rx_bytes_delta); | ||||
|             field_from_json(Obj,"tx_packets_delta",tx_packets_delta); | ||||
|             field_from_json(Obj,"rx_packets_delta",rx_packets_delta); | ||||
|             field_from_json(Obj,"tx_failed_delta",tx_failed_delta); | ||||
|             field_from_json(Obj,"tx_retries_delta",tx_retries_delta); | ||||
|             field_from_json(Obj,"tx_duration_delta",tx_duration_delta); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void APTimePoint::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj,"collisions",collisions); | ||||
|         field_to_json(Obj,"multicast",multicast); | ||||
|         field_to_json(Obj,"rx_bytes",rx_bytes); | ||||
|         field_to_json(Obj,"rx_dropped",rx_dropped); | ||||
|         field_to_json(Obj,"rx_errors",rx_errors); | ||||
|         field_to_json(Obj,"rx_packets",rx_packets); | ||||
|         field_to_json(Obj,"tx_bytes",tx_bytes); | ||||
|         field_to_json(Obj,"tx_packets",tx_packets); | ||||
|         field_to_json(Obj,"tx_dropped",tx_dropped); | ||||
|         field_to_json(Obj,"tx_errors",tx_errors); | ||||
|         field_to_json(Obj,"tx_packets",tx_packets); | ||||
|  | ||||
|         field_to_json(Obj,"tx_bytes_bw",tx_bytes_bw); | ||||
|         field_to_json(Obj,"rx_bytes_bw",rx_bytes_bw); | ||||
|         field_to_json(Obj,"rx_dropped_pct",rx_dropped_pct); | ||||
|         field_to_json(Obj,"tx_dropped_pct",tx_dropped_pct); | ||||
|         field_to_json(Obj,"rx_packets_bw",rx_packets_bw); | ||||
|         field_to_json(Obj,"tx_packets_bw",tx_packets_bw); | ||||
|         field_to_json(Obj,"rx_errors_pct",rx_errors_pct); | ||||
|         field_to_json(Obj,"tx_errors_pct",tx_errors_pct); | ||||
|  | ||||
|         field_to_json(Obj,"tx_bytes_delta",tx_bytes_delta); | ||||
|         field_to_json(Obj,"rx_bytes_delta",rx_bytes_delta); | ||||
|         field_to_json(Obj,"rx_dropped_delta",rx_dropped_delta); | ||||
|         field_to_json(Obj,"tx_dropped_delta",tx_dropped_delta); | ||||
|         field_to_json(Obj,"rx_packets_delta",rx_packets_delta); | ||||
|         field_to_json(Obj,"tx_packets_delta",tx_packets_delta); | ||||
|         field_to_json(Obj,"rx_errors_delta",rx_errors_delta); | ||||
|         field_to_json(Obj,"tx_errors_delta",tx_errors_delta); | ||||
|     } | ||||
|  | ||||
|     bool APTimePoint::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj,"collisions",collisions); | ||||
|             field_from_json(Obj,"multicast",multicast); | ||||
|             field_from_json(Obj,"rx_bytes",rx_bytes); | ||||
|             field_from_json(Obj,"rx_dropped",rx_dropped); | ||||
|             field_from_json(Obj,"rx_errors",rx_errors); | ||||
|             field_from_json(Obj,"rx_packets",rx_packets); | ||||
|             field_from_json(Obj,"tx_bytes",tx_bytes); | ||||
|             field_from_json(Obj,"tx_packets",tx_packets); | ||||
|             field_from_json(Obj,"tx_dropped",tx_dropped); | ||||
|             field_from_json(Obj,"tx_errors",tx_errors); | ||||
|             field_from_json(Obj,"tx_packets",tx_packets); | ||||
|  | ||||
|             field_from_json(Obj,"tx_bytes_bw",tx_bytes_bw); | ||||
|             field_from_json(Obj,"rx_bytes_bw",rx_bytes_bw); | ||||
|             field_from_json(Obj,"rx_dropped_pct",rx_dropped_pct); | ||||
|             field_from_json(Obj,"tx_dropped_pct",tx_dropped_pct); | ||||
|             field_from_json(Obj,"rx_packets_bw",rx_packets_bw); | ||||
|             field_from_json(Obj,"tx_packets_bw",tx_packets_bw); | ||||
|             field_from_json(Obj,"rx_errors_pct",rx_errors_pct); | ||||
|             field_from_json(Obj,"tx_errors_pct",tx_errors_pct); | ||||
|  | ||||
|             field_from_json(Obj,"tx_bytes_delta",tx_bytes_delta); | ||||
|             field_from_json(Obj,"rx_bytes_delta",rx_bytes_delta); | ||||
|             field_from_json(Obj,"rx_dropped_delta",rx_dropped_delta); | ||||
|             field_from_json(Obj,"tx_dropped_delta",tx_dropped_delta); | ||||
|             field_from_json(Obj,"rx_packets_delta",rx_packets_delta); | ||||
|             field_from_json(Obj,"tx_packets_delta",tx_packets_delta); | ||||
|             field_from_json(Obj,"rx_errors_delta",rx_errors_delta); | ||||
|             field_from_json(Obj,"tx_errors_delta",tx_errors_delta); | ||||
|  | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void TIDstat_entry::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj,"rx_msdu",rx_msdu); | ||||
|         field_to_json(Obj,"tx_msdu",tx_msdu); | ||||
|         field_to_json(Obj,"tx_msdu_failed",tx_msdu_failed); | ||||
|         field_to_json(Obj,"tx_msdu_retries",tx_msdu_retries); | ||||
|     } | ||||
|  | ||||
|     bool TIDstat_entry::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj,"rx_msdu",rx_msdu); | ||||
|             field_from_json(Obj,"tx_msdu",tx_msdu); | ||||
|             field_from_json(Obj,"tx_msdu_failed",tx_msdu_failed); | ||||
|             field_from_json(Obj,"tx_msdu_retries",tx_msdu_retries); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void RadioTimePoint::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj,"band",band); | ||||
|         field_to_json(Obj,"channel_width",channel_width); | ||||
|         field_to_json(Obj,"active_ms",active_ms); | ||||
|         field_to_json(Obj,"busy_ms",busy_ms); | ||||
|         field_to_json(Obj,"receive_ms",receive_ms); | ||||
|         field_to_json(Obj,"transmit_ms",transmit_ms); | ||||
|         field_to_json(Obj,"tx_power",tx_power); | ||||
|         field_to_json(Obj,"channel",channel); | ||||
|         field_to_json(Obj,"temperature",temperature); | ||||
|         field_to_json(Obj,"noise",noise); | ||||
|         field_to_json(Obj,"active_pct",active_pct); | ||||
|         field_to_json(Obj,"busy_pct",busy_pct); | ||||
|         field_to_json(Obj,"receive_pct",receive_pct); | ||||
|         field_to_json(Obj,"transmit_pct",transmit_pct); | ||||
|     } | ||||
|  | ||||
|     bool RadioTimePoint::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj,"band",band); | ||||
|             field_from_json(Obj,"channel_width",channel_width); | ||||
|             field_from_json(Obj,"active_ms",active_ms); | ||||
|             field_from_json(Obj,"busy_ms",busy_ms); | ||||
|             field_from_json(Obj,"receive_ms",receive_ms); | ||||
|             field_from_json(Obj,"transmit_ms",transmit_ms); | ||||
|             field_from_json(Obj,"tx_power",tx_power); | ||||
|             field_from_json(Obj,"channel",channel); | ||||
|             field_from_json(Obj,"temperature",temperature); | ||||
|             field_from_json(Obj,"noise",noise); | ||||
|             field_from_json(Obj,"active_pct",active_pct); | ||||
|             field_from_json(Obj,"busy_pct",busy_pct); | ||||
|             field_from_json(Obj,"receive_pct",receive_pct); | ||||
|             field_from_json(Obj,"transmit_pct",transmit_pct); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void AveragePoint::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj,"min",min); | ||||
|         field_to_json(Obj,"max",max); | ||||
|         field_to_json(Obj,"avg",avg); | ||||
|     } | ||||
|  | ||||
|     bool AveragePoint::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj,"min",min); | ||||
|             field_from_json(Obj,"max",max); | ||||
|             field_from_json(Obj,"avg",avg); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void SSIDTimePoint::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj,"bssid",bssid); | ||||
|         field_to_json(Obj,"mode",mode); | ||||
|         field_to_json(Obj,"ssid",ssid); | ||||
|         field_to_json(Obj,"band",band); | ||||
|         field_to_json(Obj,"channel",channel); | ||||
|         field_to_json(Obj,"associations",associations); | ||||
|         field_to_json(Obj,"tx_bytes_bw",tx_bytes_bw); | ||||
|         field_to_json(Obj,"rx_bytes_bw",rx_bytes_bw); | ||||
|         field_to_json(Obj,"tx_packets_bw",tx_packets_bw); | ||||
|         field_to_json(Obj,"rx_packets_bw",rx_packets_bw); | ||||
|         field_to_json(Obj,"tx_failed_pct",tx_failed_pct); | ||||
|         field_to_json(Obj,"tx_retries_pct",tx_retries_pct); | ||||
|         field_to_json(Obj,"tx_duration_pct",tx_duration_pct); | ||||
|     } | ||||
|  | ||||
|     bool SSIDTimePoint::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj,"bssid",bssid); | ||||
|             field_from_json(Obj,"mode",mode); | ||||
|             field_from_json(Obj,"ssid",ssid); | ||||
|             field_from_json(Obj,"band",band); | ||||
|             field_from_json(Obj,"channel",channel); | ||||
|             field_from_json(Obj,"associations",associations); | ||||
|             field_from_json(Obj,"tx_bytes_bw",tx_bytes_bw); | ||||
|             field_from_json(Obj,"rx_bytes_bw",rx_bytes_bw); | ||||
|             field_from_json(Obj,"tx_packets_bw",tx_packets_bw); | ||||
|             field_from_json(Obj,"rx_packets_bw",rx_packets_bw); | ||||
|             field_from_json(Obj,"tx_failed_pct",tx_failed_pct); | ||||
|             field_from_json(Obj,"tx_retries_pct",tx_retries_pct); | ||||
|             field_from_json(Obj,"tx_duration_pct",tx_duration_pct); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void DeviceTimePoint::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj,"id",id); | ||||
|         field_to_json(Obj,"boardId",boardId); | ||||
|         field_to_json(Obj,"timestamp",timestamp); | ||||
|         field_to_json(Obj,"ap_data",ap_data); | ||||
|         field_to_json(Obj,"ssid_data",ssid_data); | ||||
|         field_to_json(Obj,"radio_data",radio_data); | ||||
|         field_to_json(Obj,"device_info",device_info); | ||||
|         field_to_json(Obj,"serialNumber",serialNumber); | ||||
|     } | ||||
|  | ||||
|     bool DeviceTimePoint::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj,"id",id); | ||||
|             field_from_json(Obj,"boardId",boardId); | ||||
|             field_from_json(Obj,"timestamp",timestamp); | ||||
|             field_from_json(Obj,"ap_data",ap_data); | ||||
|             field_from_json(Obj,"ssid_data",ssid_data); | ||||
|             field_from_json(Obj,"radio_data",radio_data); | ||||
|             field_from_json(Obj,"device_info",device_info); | ||||
|             field_from_json(Obj,"serialNumber",serialNumber); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void DeviceTimePointAnalysis::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj,"noise",noise); | ||||
|         field_to_json(Obj,"temperature",temperature); | ||||
|         field_to_json(Obj,"active_pct",active_pct); | ||||
|         field_to_json(Obj,"busy_pct",busy_pct); | ||||
|         field_to_json(Obj,"receive_pct",receive_pct); | ||||
|         field_to_json(Obj,"transmit_pct",transmit_pct); | ||||
|         field_to_json(Obj,"tx_power",tx_power); | ||||
|         field_to_json(Obj,"tx_bytes_bw",tx_bytes_bw); | ||||
|         field_to_json(Obj,"rx_bytes_bw",rx_bytes_bw); | ||||
|         field_to_json(Obj,"rx_dropped_pct",rx_dropped_pct); | ||||
|         field_to_json(Obj,"tx_dropped_pct",tx_dropped_pct); | ||||
|         field_to_json(Obj,"rx_packets_bw",rx_packets_bw); | ||||
|         field_to_json(Obj,"tx_packets_bw",tx_packets_bw); | ||||
|         field_to_json(Obj,"rx_errors_pct",rx_errors_pct); | ||||
|         field_to_json(Obj,"tx_errors_pct",tx_errors_pct); | ||||
|     } | ||||
|  | ||||
|     bool DeviceTimePointAnalysis::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj,"noise",noise); | ||||
|             field_from_json(Obj,"temperature",temperature); | ||||
|             field_from_json(Obj,"active_pct",active_pct); | ||||
|             field_from_json(Obj,"busy_pct",busy_pct); | ||||
|             field_from_json(Obj,"receive_pct",receive_pct); | ||||
|             field_from_json(Obj,"transmit_pct",transmit_pct); | ||||
|             field_from_json(Obj,"tx_power",tx_power); | ||||
|             field_from_json(Obj,"tx_bytes_bw",tx_bytes_bw); | ||||
|             field_from_json(Obj,"rx_bytes_bw",rx_bytes_bw); | ||||
|             field_from_json(Obj,"rx_dropped_pct",rx_dropped_pct); | ||||
|             field_from_json(Obj,"tx_dropped_pct",tx_dropped_pct); | ||||
|             field_from_json(Obj,"rx_packets_bw",rx_packets_bw); | ||||
|             field_from_json(Obj,"tx_packets_bw",tx_packets_bw); | ||||
|             field_from_json(Obj,"rx_errors_pct",rx_errors_pct); | ||||
|             field_from_json(Obj,"tx_errors_pct",tx_errors_pct); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void DeviceTimePointList::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj,"points",points); | ||||
|         field_to_json(Obj,"stats",stats); | ||||
|     } | ||||
|  | ||||
|     bool DeviceTimePointList::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj,"points",points); | ||||
|             field_from_json(Obj,"stats",stats); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void DeviceTimePointStats::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj,"firstPoint",firstPoint); | ||||
|         field_to_json(Obj,"lastPoint",lastPoint); | ||||
|         field_to_json(Obj,"count",count); | ||||
|     } | ||||
|  | ||||
|     bool DeviceTimePointStats::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj,"firstPoint",firstPoint); | ||||
|             field_from_json(Obj,"lastPoint",lastPoint); | ||||
|             field_from_json(Obj,"count",count); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void WifiClientRate::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj,"bitrate",bitrate); | ||||
|         field_to_json(Obj,"chwidth",chwidth); | ||||
|         field_to_json(Obj,"mcs",mcs); | ||||
|         field_to_json(Obj,"nss",nss); | ||||
|         field_to_json(Obj,"vht",vht); | ||||
|     } | ||||
|  | ||||
|     bool WifiClientRate::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj,"bitrate",bitrate); | ||||
|             field_from_json(Obj,"chwidth",chwidth); | ||||
|             field_from_json(Obj,"mcs",mcs); | ||||
|             field_from_json(Obj,"nss",nss); | ||||
|             field_from_json(Obj,"vht",vht); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void WifiClientHistory::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj,"timestamp",timestamp); | ||||
|         field_to_json(Obj,"station_id",station_id); | ||||
|         field_to_json(Obj,"bssid",bssid); | ||||
|         field_to_json(Obj,"ssid",ssid); | ||||
|         field_to_json(Obj,"rssi",rssi); | ||||
|         field_to_json(Obj,"rx_bitrate",rx_bitrate); | ||||
|         field_to_json(Obj,"rx_chwidth",rx_chwidth); | ||||
|         field_to_json(Obj,"rx_mcs",rx_mcs); | ||||
|         field_to_json(Obj,"rx_nss",rx_nss); | ||||
|         field_to_json(Obj,"rx_vht",rx_vht); | ||||
|         field_to_json(Obj,"tx_bitrate",tx_bitrate); | ||||
|         field_to_json(Obj,"tx_chwidth",tx_chwidth); | ||||
|         field_to_json(Obj,"tx_mcs",tx_mcs); | ||||
|         field_to_json(Obj,"tx_nss",tx_nss); | ||||
|         field_to_json(Obj,"tx_vht",tx_vht); | ||||
|         field_to_json(Obj,"rx_bytes",rx_bytes); | ||||
|         field_to_json(Obj,"tx_bytes",tx_bytes); | ||||
|         field_to_json(Obj,"rx_duration",rx_duration); | ||||
|         field_to_json(Obj,"tx_duration",tx_duration); | ||||
|         field_to_json(Obj,"rx_packets",rx_packets); | ||||
|         field_to_json(Obj,"tx_packets",tx_packets); | ||||
|         field_to_json(Obj,"ipv4",ipv4); | ||||
|         field_to_json(Obj,"ipv6",ipv6); | ||||
|         field_to_json(Obj,"channel_width",channel_width); | ||||
|         field_to_json(Obj,"noise",noise); | ||||
|         field_to_json(Obj,"tx_power",tx_power); | ||||
|         field_to_json(Obj,"channel",channel); | ||||
|         field_to_json(Obj,"active_ms",active_ms); | ||||
|         field_to_json(Obj,"busy_ms",busy_ms); | ||||
|         field_to_json(Obj,"receive_ms",receive_ms); | ||||
|         field_to_json(Obj,"mode",mode); | ||||
|         field_to_json(Obj,"ack_signal",ack_signal); | ||||
|         field_to_json(Obj,"ack_signal_avg",ack_signal_avg); | ||||
|         field_to_json(Obj,"connected",connected); | ||||
|         field_to_json(Obj,"inactive",inactive); | ||||
|         field_to_json(Obj,"tx_retries",tx_retries); | ||||
|         field_to_json(Obj,"venue_id",venue_id); | ||||
|     } | ||||
|  | ||||
|     bool WifiClientHistory::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj,"timestamp",timestamp); | ||||
|             field_from_json(Obj,"station_id",station_id); | ||||
|             field_from_json(Obj,"bssid",bssid); | ||||
|             field_from_json(Obj,"ssid",ssid); | ||||
|             field_from_json(Obj,"rssi",rssi); | ||||
|             field_from_json(Obj,"rx_bitrate",rx_bitrate); | ||||
|             field_from_json(Obj,"rx_chwidth",rx_chwidth); | ||||
|             field_from_json(Obj,"rx_mcs",rx_mcs); | ||||
|             field_from_json(Obj,"rx_nss",rx_nss); | ||||
|             field_from_json(Obj,"rx_vht",rx_vht); | ||||
|             field_from_json(Obj,"tx_bitrate",tx_bitrate); | ||||
|             field_from_json(Obj,"tx_chwidth",tx_chwidth); | ||||
|             field_from_json(Obj,"tx_mcs",tx_mcs); | ||||
|             field_from_json(Obj,"tx_nss",tx_nss); | ||||
|             field_from_json(Obj,"tx_vht",tx_vht); | ||||
|             field_from_json(Obj,"rx_bytes",rx_bytes); | ||||
|             field_from_json(Obj,"tx_bytes",tx_bytes); | ||||
|             field_from_json(Obj,"rx_duration",rx_duration); | ||||
|             field_from_json(Obj,"tx_duration",tx_duration); | ||||
|             field_from_json(Obj,"rx_packets",rx_packets); | ||||
|             field_from_json(Obj,"tx_packets",tx_packets); | ||||
|             field_from_json(Obj,"ipv4",ipv4); | ||||
|             field_from_json(Obj,"ipv6",ipv6); | ||||
|             field_from_json(Obj,"channel_width",channel_width); | ||||
|             field_from_json(Obj,"noise",noise); | ||||
|             field_from_json(Obj,"tx_power",tx_power); | ||||
|             field_from_json(Obj,"channel",channel); | ||||
|             field_from_json(Obj,"active_ms",active_ms); | ||||
|             field_from_json(Obj,"busy_ms",busy_ms); | ||||
|             field_from_json(Obj,"receive_ms",receive_ms); | ||||
|             field_from_json(Obj,"mode",mode); | ||||
|             field_from_json(Obj,"ack_signal",ack_signal); | ||||
|             field_from_json(Obj,"ack_signal_avg",ack_signal_avg); | ||||
|             field_from_json(Obj,"connected",connected); | ||||
|             field_from_json(Obj,"inactive",inactive); | ||||
|             field_from_json(Obj,"tx_retries",tx_retries); | ||||
|             field_from_json(Obj,"venue_id",venue_id); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										423
									
								
								src/RESTObjects/RESTAPI_AnalyticsObjects.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										423
									
								
								src/RESTObjects/RESTAPI_AnalyticsObjects.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,423 @@ | ||||
| // | ||||
| // Created by stephane bourque on 2022-01-10. | ||||
| // | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "RESTAPI_ProvObjects.h" | ||||
| #include "framework/utils.h" | ||||
| #include <vector> | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
|     namespace AnalyticsObjects { | ||||
|  | ||||
|         struct Report { | ||||
|             uint64_t snapShot = 0; | ||||
|  | ||||
|             void reset(); | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|         }; | ||||
|  | ||||
|         struct VenueInfo { | ||||
|             OpenWifi::Types::UUID_t id; | ||||
|             std::string name; | ||||
|             std::string description; | ||||
|             uint64_t retention = 0; | ||||
|             uint64_t interval = 0; | ||||
|             bool monitorSubVenues = false; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|  | ||||
|         struct BoardInfo { | ||||
|             ProvObjects::ObjectInfo info; | ||||
|             std::vector<VenueInfo> venueList; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|  | ||||
|             inline bool operator<(const BoardInfo &bb) const { | ||||
|                 return info.id < bb.info.id; | ||||
|             } | ||||
|  | ||||
|             inline bool operator==(const BoardInfo &bb) const { | ||||
|                 return info.id == bb.info.id; | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         struct DeviceInfo { | ||||
|             std::string boardId; | ||||
|             std::string type; | ||||
|             std::string serialNumber; | ||||
|             std::string deviceType; | ||||
|             uint64_t lastContact = 0 ; | ||||
|             uint64_t lastPing = 0; | ||||
|             uint64_t lastState = 0; | ||||
|             std::string lastFirmware; | ||||
|             uint64_t lastFirmwareUpdate = 0; | ||||
|             uint64_t lastConnection = 0; | ||||
|             uint64_t lastDisconnection = 0; | ||||
|             uint64_t pings = 0; | ||||
|             uint64_t states = 0; | ||||
|             bool connected = false; | ||||
|             std::string connectionIp; | ||||
|             uint64_t associations_2g = 0; | ||||
|             uint64_t associations_5g = 0; | ||||
|             uint64_t associations_6g = 0; | ||||
|             uint64_t health = 0; | ||||
|             uint64_t lastHealth = 0; | ||||
|             std::string locale; | ||||
|             uint64_t uptime = 0; | ||||
|             double memory = 0.0; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|  | ||||
|         struct DeviceInfoList { | ||||
|             std::vector<DeviceInfo> devices; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|  | ||||
|         enum wifi_band { | ||||
|             band_2g = 0, band_5g = 1, band_6g = 2 | ||||
|         }; | ||||
|  | ||||
|         struct TIDstat_entry { | ||||
|             uint64_t rx_msdu = 0, | ||||
|                     tx_msdu = 0, | ||||
|                     tx_msdu_failed = 0, | ||||
|                     tx_msdu_retries = 0; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|  | ||||
|         struct UE_rate { | ||||
|             uint64_t    bitrate=0; | ||||
|             uint64_t    mcs=0; | ||||
|             uint64_t    nss=0; | ||||
|             bool        ht=false; | ||||
|             bool        sgi=false; | ||||
|             uint64_t    chwidth=0; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|  | ||||
|         struct AveragePoint { | ||||
|             double      min = 0.0, | ||||
|                         max = 0.0, | ||||
|                         avg = 0.0; | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|  | ||||
|         struct UETimePoint { | ||||
|             std::string station; | ||||
|             int64_t rssi = 0; | ||||
|             uint64_t tx_bytes = 0, | ||||
|                     rx_bytes = 0, | ||||
|                     tx_duration = 0, | ||||
|                     rx_packets = 0, | ||||
|                     tx_packets = 0, | ||||
|                     tx_retries = 0, | ||||
|                     tx_failed = 0, | ||||
|                     connected = 0, | ||||
|                     inactive = 0; | ||||
|  | ||||
|             double  tx_bytes_bw = 0.0 , | ||||
|                     rx_bytes_bw = 0.0 , | ||||
|                     tx_packets_bw = 0.0 , | ||||
|                     rx_packets_bw = 0.0 , | ||||
|                     tx_failed_pct = 0.0 , | ||||
|                     tx_retries_pct = 0.0 , | ||||
|                     tx_duration_pct = 0.0; | ||||
|  | ||||
|             uint64_t    tx_bytes_delta = 0, | ||||
|                         rx_bytes_delta = 0, | ||||
|                         tx_duration_delta = 0, | ||||
|                         rx_packets_delta = 0, | ||||
|                         tx_packets_delta = 0, | ||||
|                         tx_retries_delta = 0, | ||||
|                         tx_failed_delta = 0; | ||||
|  | ||||
|             UE_rate tx_rate, | ||||
|                     rx_rate; | ||||
|             std::vector<TIDstat_entry> tidstats; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|  | ||||
|         enum SSID_MODES { | ||||
|             unknown = 0, | ||||
|             ap, | ||||
|             mesh, | ||||
|             sta, | ||||
|             wds_ap, | ||||
|             wds_sta, | ||||
|             wds_repeater | ||||
|         }; | ||||
|  | ||||
|         inline SSID_MODES SSID_Mode(const std::string &m) { | ||||
|             if (m == "ap") | ||||
|                 return ap; | ||||
|             if (m == "sta") | ||||
|                 return sta; | ||||
|             if (m == "mesh") | ||||
|                 return mesh; | ||||
|             if (m == "wds-ap") | ||||
|                 return wds_ap; | ||||
|             if (m == "wds-sta") | ||||
|                 return wds_sta; | ||||
|             if (m == "wds-repeater") | ||||
|                 return wds_repeater; | ||||
|             return unknown; | ||||
|         } | ||||
|  | ||||
|         struct SSIDTimePoint { | ||||
|             std::string bssid, | ||||
|                         mode, | ||||
|                         ssid; | ||||
|             uint64_t    band=0, | ||||
|                         channel=0; | ||||
|             std::vector<UETimePoint> associations; | ||||
|  | ||||
|             AveragePoint    tx_bytes_bw, | ||||
|                             rx_bytes_bw, | ||||
|                             tx_packets_bw, | ||||
|                             rx_packets_bw, | ||||
|                             tx_failed_pct, | ||||
|                             tx_retries_pct, | ||||
|                             tx_duration_pct; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|  | ||||
|  | ||||
|         struct APTimePoint { | ||||
|             uint64_t    collisions = 0, | ||||
|                         multicast = 0, | ||||
|                         rx_bytes = 0, | ||||
|                         rx_dropped = 0, | ||||
|                         rx_errors = 0, | ||||
|                         rx_packets = 0, | ||||
|                         tx_bytes = 0, | ||||
|                         tx_dropped = 0, | ||||
|                         tx_errors = 0, | ||||
|                         tx_packets = 0; | ||||
|  | ||||
|             double      tx_bytes_bw = 0.0 , | ||||
|                         rx_bytes_bw = 0.0 , | ||||
|                         rx_dropped_pct = 0.0, | ||||
|                         tx_dropped_pct = 0.0, | ||||
|                         rx_packets_bw = 0.0, | ||||
|                         tx_packets_bw = 0.0, | ||||
|                         rx_errors_pct = 0.0 , | ||||
|                         tx_errors_pct = 0.0; | ||||
|  | ||||
|             uint64_t    tx_bytes_delta = 0, | ||||
|                         rx_bytes_delta = 0 , | ||||
|                         rx_dropped_delta = 0, | ||||
|                         tx_dropped_delta = 0, | ||||
|                         rx_packets_delta = 0, | ||||
|                         tx_packets_delta = 0, | ||||
|                         rx_errors_delta = 0, | ||||
|                         tx_errors_delta = 0; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|  | ||||
|         struct RadioTimePoint { | ||||
|             uint64_t    band = 0, | ||||
|                         channel_width = 0; | ||||
|             uint64_t    active_ms = 0, | ||||
|                         busy_ms = 0, | ||||
|                         receive_ms = 0, | ||||
|                         transmit_ms = 0, | ||||
|                         tx_power = 0, | ||||
|                         channel = 0; | ||||
|             int64_t     temperature = 0, | ||||
|                         noise = 0; | ||||
|  | ||||
|             double      active_pct = 0.0 , | ||||
|                         busy_pct = 0.0, | ||||
|                         receive_pct = 0.0, | ||||
|                         transmit_pct = 0.0; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|  | ||||
|  | ||||
|         struct DeviceTimePoint { | ||||
|             std::string                     id; | ||||
|             std::string                     boardId; | ||||
|             uint64_t                        timestamp = 0; | ||||
|             APTimePoint                     ap_data; | ||||
|             std::vector<SSIDTimePoint>      ssid_data; | ||||
|             std::vector<RadioTimePoint>     radio_data; | ||||
|             AnalyticsObjects::DeviceInfo    device_info; | ||||
|             std::string                     serialNumber; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|  | ||||
|             inline bool operator<(const DeviceTimePoint &rhs) const { | ||||
|                 if(timestamp < rhs.timestamp) | ||||
|                     return true; | ||||
|                 if(timestamp > rhs.timestamp) | ||||
|                     return false; | ||||
|                 if(device_info.serialNumber < rhs.device_info.serialNumber) | ||||
|                     return true; | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             inline bool operator==(const DeviceTimePoint &rhs) const { | ||||
|                 return timestamp==rhs.timestamp && device_info.serialNumber==rhs.device_info.serialNumber; | ||||
|             } | ||||
|  | ||||
|             inline bool operator>(const DeviceTimePoint &rhs) const { | ||||
|                 if(timestamp > rhs.timestamp) | ||||
|                     return true; | ||||
|                 if(timestamp < rhs.timestamp) | ||||
|                     return false; | ||||
|                 if(device_info.serialNumber > rhs.device_info.serialNumber) | ||||
|                     return true; | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|         }; | ||||
|  | ||||
|         struct DeviceTimePointAnalysis { | ||||
|             uint64_t        timestamp; | ||||
|  | ||||
|             AveragePoint    noise; | ||||
|             AveragePoint    temperature; | ||||
|             AveragePoint    active_pct; | ||||
|             AveragePoint    busy_pct; | ||||
|             AveragePoint    receive_pct; | ||||
|             AveragePoint    transmit_pct; | ||||
|             AveragePoint    tx_power; | ||||
|  | ||||
|             AveragePoint    tx_bytes_bw; | ||||
|             AveragePoint    rx_bytes_bw; | ||||
|             AveragePoint    rx_dropped_pct; | ||||
|             AveragePoint    tx_dropped_pct; | ||||
|             AveragePoint    rx_packets_bw; | ||||
|             AveragePoint    tx_packets_bw; | ||||
|             AveragePoint    rx_errors_pct; | ||||
|             AveragePoint    tx_errors_pct; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|  | ||||
|         }; | ||||
|  | ||||
|         struct DeviceTimePointList { | ||||
|             std::vector<DeviceTimePoint>            points; | ||||
|             std::vector<DeviceTimePointAnalysis>    stats; | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|  | ||||
|         struct BandwidthAnalysisEntry { | ||||
|             uint64_t    timestamp = 0; | ||||
|  | ||||
|         }; | ||||
|  | ||||
|         struct BandwidthAnalysis { | ||||
|  | ||||
|         }; | ||||
|  | ||||
|         struct AverageValueSigned { | ||||
|             int64_t     peak=0, avg=0, low=0; | ||||
|         }; | ||||
|  | ||||
|         struct AverageValueUnsigned { | ||||
|             uint64_t     peak=0, avg=0, low=0; | ||||
|         }; | ||||
|  | ||||
|         struct RadioAnalysis { | ||||
|             uint64_t                timestamp=0; | ||||
|             AverageValueSigned      noise, temperature; | ||||
|             AverageValueUnsigned    active_ms, | ||||
|                                     busy_ms, | ||||
|                                     transmit_ms, | ||||
|                                     receive_ms; | ||||
|         }; | ||||
|  | ||||
|         struct DeviceTimePointStats { | ||||
|             uint64_t                firstPoint=0; | ||||
|             uint64_t                lastPoint=0; | ||||
|             uint64_t                count=0; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|  | ||||
|         struct WifiClientRate { | ||||
|             uint32_t    bitrate=0; | ||||
|             uint32_t    chwidth=0; | ||||
|             uint16_t    mcs=0; | ||||
|             uint16_t    nss=0; | ||||
|             bool        vht=false; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|  | ||||
|         struct WifiClientHistory { | ||||
|             uint64_t        timestamp=Utils::Now(); | ||||
|             std::string     station_id; | ||||
|             std::string     bssid; | ||||
|             std::string     ssid; | ||||
|             int64_t         rssi=0; | ||||
|             uint32_t        rx_bitrate=0; | ||||
|             uint32_t        rx_chwidth=0; | ||||
|             uint16_t        rx_mcs=0; | ||||
|             uint16_t        rx_nss=0; | ||||
|             bool            rx_vht=false; | ||||
|             uint32_t        tx_bitrate=0; | ||||
|             uint32_t        tx_chwidth=0; | ||||
|             uint16_t        tx_mcs=0; | ||||
|             uint16_t        tx_nss=0; | ||||
|             bool            tx_vht=false; | ||||
|             uint64_t        rx_bytes=0; | ||||
|             uint64_t        tx_bytes=0; | ||||
|             uint64_t        rx_duration=0; | ||||
|             uint64_t        tx_duration=0; | ||||
|             uint64_t        rx_packets=0; | ||||
|             uint64_t        tx_packets=0; | ||||
|             std::string     ipv4; | ||||
|             std::string     ipv6; | ||||
|             uint64_t        channel_width=0; | ||||
|             int64_t         noise=0; | ||||
|             uint64_t        tx_power=0; | ||||
|             uint64_t        channel=0; | ||||
|             uint64_t        active_ms=0; | ||||
|             uint64_t        busy_ms=0; | ||||
|             uint64_t        receive_ms=0; | ||||
|             std::string     mode; | ||||
|             int64_t         ack_signal=0; | ||||
|             int64_t         ack_signal_avg=0; | ||||
|             uint64_t        connected=0; | ||||
|             uint64_t        inactive=0; | ||||
|             uint64_t        tx_retries=0; | ||||
|             std::string     venue_id; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -3,176 +3,208 @@ | ||||
| // | ||||
|  | ||||
| #include "RESTAPI_CertObjects.h" | ||||
| #include "framework/RESTAPI_utils.h" | ||||
|  | ||||
| using OpenWifi::RESTAPI_utils::field_to_json; | ||||
| using OpenWifi::RESTAPI_utils::field_from_json; | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     namespace  CertObjects { | ||||
|         void CertificateEntry::to_json(Poco::JSON::Object &Obj) const { | ||||
|             field_to_json(Obj,"id", id); | ||||
|             field_to_json(Obj,"entity", entity); | ||||
|             field_to_json(Obj,"creator", creator); | ||||
|             field_to_json(Obj,"type", type); | ||||
|             field_to_json(Obj,"status", status); | ||||
|             field_to_json(Obj,"certificate", certificate); | ||||
|             field_to_json(Obj,"key", key); | ||||
|             field_to_json(Obj,"devid", devid); | ||||
|             field_to_json(Obj,"cas", cas); | ||||
|             field_to_json(Obj,"manufacturer", manufacturer); | ||||
|             field_to_json(Obj,"model", model); | ||||
|             field_to_json(Obj,"redirector", redirector); | ||||
|             field_to_json(Obj,"commonName", commonName); | ||||
|             field_to_json(Obj,"certificateId", certificateId); | ||||
|             field_to_json(Obj,"batch", batch); | ||||
|             field_to_json(Obj,"created", created); | ||||
|             field_to_json(Obj,"modified", modified); | ||||
|             field_to_json(Obj,"revoked", revoked); | ||||
|             field_to_json(Obj,"revokeCount", revokeCount); | ||||
|         } | ||||
| namespace OpenWifi::CertObjects { | ||||
|     void CertificateEntry::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj,"id", id); | ||||
|         field_to_json(Obj,"entity", entity); | ||||
|         field_to_json(Obj,"creator", creator); | ||||
|         field_to_json(Obj,"type", type); | ||||
|         field_to_json(Obj,"status", status); | ||||
|         field_to_json(Obj,"certificate", certificate); | ||||
|         field_to_json(Obj,"key", key); | ||||
|         field_to_json(Obj,"devid", devid); | ||||
|         field_to_json(Obj,"cas", cas); | ||||
|         field_to_json(Obj,"manufacturer", manufacturer); | ||||
|         field_to_json(Obj,"model", model); | ||||
|         field_to_json(Obj,"redirector", redirector); | ||||
|         field_to_json(Obj,"commonName", commonName); | ||||
|         field_to_json(Obj,"certificateId", certificateId); | ||||
|         field_to_json(Obj,"batch", batch); | ||||
|         field_to_json(Obj,"created", created); | ||||
|         field_to_json(Obj,"modified", modified); | ||||
|         field_to_json(Obj,"revoked", revoked); | ||||
|         field_to_json(Obj,"revokeCount", revokeCount); | ||||
|         field_to_json(Obj,"synched", synched); | ||||
|     } | ||||
|  | ||||
|         bool CertificateEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|             try { | ||||
|                 field_from_json(Obj,"id", id); | ||||
|                 field_from_json(Obj,"entity", entity); | ||||
|                 field_from_json(Obj,"creator", creator); | ||||
|                 field_from_json(Obj,"type", type); | ||||
|                 field_from_json(Obj,"status", status); | ||||
|                 field_from_json(Obj,"certificate", certificate); | ||||
|                 field_from_json(Obj,"key", key); | ||||
|                 field_from_json(Obj,"devid", devid); | ||||
|                 field_from_json(Obj,"cas", cas); | ||||
|                 field_from_json(Obj,"manufacturer", manufacturer); | ||||
|                 field_from_json(Obj,"model", model); | ||||
|                 field_from_json(Obj,"redirector", redirector); | ||||
|                 field_from_json(Obj,"commonName", commonName); | ||||
|                 field_from_json(Obj,"certificateId", certificateId); | ||||
|                 field_from_json(Obj,"batch", batch); | ||||
|                 field_from_json(Obj,"created", created); | ||||
|                 field_from_json(Obj,"modified", modified); | ||||
|                 field_from_json(Obj,"revoked", revoked); | ||||
|                 field_from_json(Obj,"revokeCount", revokeCount); | ||||
|                 return true; | ||||
|             } catch (...) { | ||||
|             } | ||||
|             return false; | ||||
|     bool CertificateEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj,"id", id); | ||||
|             field_from_json(Obj,"entity", entity); | ||||
|             field_from_json(Obj,"creator", creator); | ||||
|             field_from_json(Obj,"type", type); | ||||
|             field_from_json(Obj,"status", status); | ||||
|             field_from_json(Obj,"certificate", certificate); | ||||
|             field_from_json(Obj,"key", key); | ||||
|             field_from_json(Obj,"devid", devid); | ||||
|             field_from_json(Obj,"cas", cas); | ||||
|             field_from_json(Obj,"manufacturer", manufacturer); | ||||
|             field_from_json(Obj,"model", model); | ||||
|             field_from_json(Obj,"redirector", redirector); | ||||
|             field_from_json(Obj,"commonName", commonName); | ||||
|             field_from_json(Obj,"certificateId", certificateId); | ||||
|             field_from_json(Obj,"batch", batch); | ||||
|             field_from_json(Obj,"created", created); | ||||
|             field_from_json(Obj,"modified", modified); | ||||
|             field_from_json(Obj,"revoked", revoked); | ||||
|             field_from_json(Obj,"revokeCount", revokeCount); | ||||
|             field_from_json(Obj,"synched", synched); | ||||
|             return true; | ||||
|         } catch (...) { | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|         void EntityEntry::to_json(Poco::JSON::Object &Obj) const { | ||||
|             field_to_json(Obj,"id", id); | ||||
|             field_to_json(Obj,"creator", creator); | ||||
|             field_to_json(Obj,"name", name); | ||||
|             field_to_json(Obj,"description", description); | ||||
|             field_to_json(Obj,"defaultRedirector", defaultRedirector); | ||||
|             field_to_json(Obj,"apiKey", apiKey); | ||||
|             field_to_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile); | ||||
|             field_to_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile); | ||||
|             field_to_json(Obj,"organization", organization); | ||||
|             field_to_json(Obj,"created", created); | ||||
|             field_to_json(Obj,"modified", modified); | ||||
|             field_to_json(Obj,"suspended", suspended); | ||||
|             field_to_json(Obj,"deleted", deleted); | ||||
|             field_to_json(Obj,"notes", notes); | ||||
|         } | ||||
|     void EntityEntry::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj,"id", id); | ||||
|         field_to_json(Obj,"creator", creator); | ||||
|         field_to_json(Obj,"name", name); | ||||
|         field_to_json(Obj,"description", description); | ||||
|         field_to_json(Obj,"defaultRedirector", defaultRedirector); | ||||
|         field_to_json(Obj,"apiKey", apiKey); | ||||
|         field_to_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile); | ||||
|         field_to_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile); | ||||
|         field_to_json(Obj,"organization", organization); | ||||
|         field_to_json(Obj,"created", created); | ||||
|         field_to_json(Obj,"modified", modified); | ||||
|         field_to_json(Obj,"suspended", suspended); | ||||
|         field_to_json(Obj,"deleted", deleted); | ||||
|         field_to_json(Obj,"notes", notes); | ||||
|     } | ||||
|  | ||||
|         bool EntityEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|             try { | ||||
|                 field_from_json(Obj,"id", id); | ||||
|                 field_from_json(Obj,"creator", creator); | ||||
|                 field_from_json(Obj,"name", name); | ||||
|                 field_from_json(Obj,"description", description); | ||||
|                 field_from_json(Obj,"defaultRedirector", defaultRedirector); | ||||
|                 field_from_json(Obj,"apiKey", apiKey); | ||||
|                 field_from_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile); | ||||
|                 field_from_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile); | ||||
|                 field_from_json(Obj,"organization", organization); | ||||
|                 field_from_json(Obj,"created", created); | ||||
|                 field_from_json(Obj,"modified", modified); | ||||
|                 field_from_json(Obj,"suspended", suspended); | ||||
|                 field_from_json(Obj,"deleted", deleted); | ||||
|                 field_from_json(Obj,"notes", notes); | ||||
|                 return true; | ||||
|             } catch (...) { | ||||
|             } | ||||
|             return false; | ||||
|     bool EntityEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj,"id", id); | ||||
|             field_from_json(Obj,"creator", creator); | ||||
|             field_from_json(Obj,"name", name); | ||||
|             field_from_json(Obj,"description", description); | ||||
|             field_from_json(Obj,"defaultRedirector", defaultRedirector); | ||||
|             field_from_json(Obj,"apiKey", apiKey); | ||||
|             field_from_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile); | ||||
|             field_from_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile); | ||||
|             field_from_json(Obj,"organization", organization); | ||||
|             field_from_json(Obj,"created", created); | ||||
|             field_from_json(Obj,"modified", modified); | ||||
|             field_from_json(Obj,"suspended", suspended); | ||||
|             field_from_json(Obj,"deleted", deleted); | ||||
|             field_from_json(Obj,"notes", notes); | ||||
|             return true; | ||||
|         } catch (...) { | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|         void BatchEntry::to_json(Poco::JSON::Object &Obj) const { | ||||
|             field_to_json(Obj,"id", id); | ||||
|             field_to_json(Obj,"entity", entity); | ||||
|             field_to_json(Obj,"creator", creator); | ||||
|             field_to_json(Obj,"name", name); | ||||
|             field_to_json(Obj,"description", description); | ||||
|             field_to_json(Obj,"manufacturer", manufacturer); | ||||
|             field_to_json(Obj,"model", model); | ||||
|             field_to_json(Obj,"redirector", redirector); | ||||
|             field_to_json(Obj,"commonNames", commonNames); | ||||
|             field_to_json(Obj,"jobHistory", jobHistory); | ||||
|             field_to_json(Obj,"notes", notes); | ||||
|             field_to_json(Obj,"submitted", submitted); | ||||
|             field_to_json(Obj,"started", started); | ||||
|             field_to_json(Obj,"completed", completed); | ||||
|             field_to_json(Obj,"modified", modified); | ||||
|         } | ||||
|     void BatchEntry::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj,"id", id); | ||||
|         field_to_json(Obj,"entity", entity); | ||||
|         field_to_json(Obj,"creator", creator); | ||||
|         field_to_json(Obj,"name", name); | ||||
|         field_to_json(Obj,"description", description); | ||||
|         field_to_json(Obj,"manufacturer", manufacturer); | ||||
|         field_to_json(Obj,"model", model); | ||||
|         field_to_json(Obj,"redirector", redirector); | ||||
|         field_to_json(Obj,"commonNames", commonNames); | ||||
|         field_to_json(Obj,"jobHistory", jobHistory); | ||||
|         field_to_json(Obj,"notes", notes); | ||||
|         field_to_json(Obj,"submitted", submitted); | ||||
|         field_to_json(Obj,"started", started); | ||||
|         field_to_json(Obj,"completed", completed); | ||||
|         field_to_json(Obj,"modified", modified); | ||||
|     } | ||||
|  | ||||
|         bool BatchEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|             try { | ||||
|                 field_from_json(Obj,"id", id); | ||||
|                 field_from_json(Obj,"entity", entity); | ||||
|                 field_from_json(Obj,"creator", creator); | ||||
|                 field_from_json(Obj,"name", name); | ||||
|                 field_from_json(Obj,"description", description); | ||||
|                 field_from_json(Obj,"manufacturer", manufacturer); | ||||
|                 field_from_json(Obj,"model", model); | ||||
|                 field_from_json(Obj,"redirector", redirector); | ||||
|                 field_from_json(Obj,"commonNames", commonNames); | ||||
|                 field_from_json(Obj,"jobHistory", jobHistory); | ||||
|                 field_from_json(Obj,"notes", notes); | ||||
|                 field_from_json(Obj,"submitted", submitted); | ||||
|                 field_from_json(Obj,"started", started); | ||||
|                 field_from_json(Obj,"completed", completed); | ||||
|                 field_from_json(Obj,"modified", modified); | ||||
|                 return true; | ||||
|             } catch (...) { | ||||
|             } | ||||
|             return false; | ||||
|     bool BatchEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj,"id", id); | ||||
|             field_from_json(Obj,"entity", entity); | ||||
|             field_from_json(Obj,"creator", creator); | ||||
|             field_from_json(Obj,"name", name); | ||||
|             field_from_json(Obj,"description", description); | ||||
|             field_from_json(Obj,"manufacturer", manufacturer); | ||||
|             field_from_json(Obj,"model", model); | ||||
|             field_from_json(Obj,"redirector", redirector); | ||||
|             field_from_json(Obj,"commonNames", commonNames); | ||||
|             field_from_json(Obj,"jobHistory", jobHistory); | ||||
|             field_from_json(Obj,"notes", notes); | ||||
|             field_from_json(Obj,"submitted", submitted); | ||||
|             field_from_json(Obj,"started", started); | ||||
|             field_from_json(Obj,"completed", completed); | ||||
|             field_from_json(Obj,"modified", modified); | ||||
|             return true; | ||||
|         } catch (...) { | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|         void JobEntry::to_json(Poco::JSON::Object &Obj) const { | ||||
|             field_to_json(Obj,"id", id); | ||||
|             field_to_json(Obj,"entity", entity); | ||||
|             field_to_json(Obj,"creator", creator); | ||||
|             field_to_json(Obj,"batch", batch); | ||||
|             field_to_json(Obj,"commonNames", commonNames); | ||||
|             field_to_json(Obj,"completedNames", completedNames); | ||||
|             field_to_json(Obj,"errorNames", errorNames); | ||||
|             field_to_json(Obj,"status", status); | ||||
|             field_to_json(Obj,"command", command); | ||||
|             field_to_json(Obj,"parameters", parameters); | ||||
|             field_to_json(Obj,"submitted", submitted); | ||||
|             field_to_json(Obj,"started", started); | ||||
|             field_to_json(Obj,"completed", completed); | ||||
|         } | ||||
|     void JobEntry::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj,"id", id); | ||||
|         field_to_json(Obj,"entity", entity); | ||||
|         field_to_json(Obj,"creator", creator); | ||||
|         field_to_json(Obj,"batch", batch); | ||||
|         field_to_json(Obj,"commonNames", commonNames); | ||||
|         field_to_json(Obj,"completedNames", completedNames); | ||||
|         field_to_json(Obj,"errorNames", errorNames); | ||||
|         field_to_json(Obj,"status", status); | ||||
|         field_to_json(Obj,"command", command); | ||||
|         field_to_json(Obj,"parameters", parameters); | ||||
|         field_to_json(Obj,"submitted", submitted); | ||||
|         field_to_json(Obj,"started", started); | ||||
|         field_to_json(Obj,"completed", completed); | ||||
|         field_to_json(Obj,"requesterUsername", requesterUsername); | ||||
|     } | ||||
|  | ||||
|         bool JobEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|             try { | ||||
|                 field_from_json(Obj,"id", id); | ||||
|                 field_from_json(Obj,"entity", entity); | ||||
|                 field_from_json(Obj,"creator", creator); | ||||
|                 field_from_json(Obj,"batch", batch); | ||||
|                 field_from_json(Obj,"commonNames", commonNames); | ||||
|                 field_from_json(Obj,"completedNames", completedNames); | ||||
|                 field_from_json(Obj,"errorNames", errorNames); | ||||
|                 field_from_json(Obj,"status", status); | ||||
|                 field_from_json(Obj,"command", command); | ||||
|                 field_from_json(Obj,"parameters", parameters); | ||||
|                 field_from_json(Obj,"submitted", submitted); | ||||
|                 field_from_json(Obj,"started", started); | ||||
|                 field_from_json(Obj,"completed", completed); | ||||
|                 return true; | ||||
|             } catch (...) { | ||||
|             } | ||||
|             return false; | ||||
|     bool JobEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj,"id", id); | ||||
|             field_from_json(Obj,"entity", entity); | ||||
|             field_from_json(Obj,"creator", creator); | ||||
|             field_from_json(Obj,"batch", batch); | ||||
|             field_from_json(Obj,"commonNames", commonNames); | ||||
|             field_from_json(Obj,"completedNames", completedNames); | ||||
|             field_from_json(Obj,"errorNames", errorNames); | ||||
|             field_from_json(Obj,"status", status); | ||||
|             field_from_json(Obj,"command", command); | ||||
|             field_from_json(Obj,"parameters", parameters); | ||||
|             field_from_json(Obj,"submitted", submitted); | ||||
|             field_from_json(Obj,"started", started); | ||||
|             field_from_json(Obj,"completed", completed); | ||||
|             field_from_json(Obj,"requesterUsername", requesterUsername); | ||||
|             return true; | ||||
|         } catch (...) { | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void DashBoardYearlyStats::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj, "year", year); | ||||
|         field_to_json(Obj, "activeCerts", activeCerts); | ||||
|         field_to_json(Obj, "revokedCerts", revokedCerts); | ||||
|     } | ||||
|  | ||||
|     void Dashboard::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj,"snapshot", snapshot); | ||||
|         field_to_json(Obj,"numberOfIssuedCerts", numberOfIssuedCerts); | ||||
|         field_to_json(Obj,"numberOfRevokedCerts", numberOfRevokedCerts); | ||||
|         field_to_json(Obj,"activeCertsPerOrganization", activeCertsPerOrganization); | ||||
|         field_to_json(Obj,"revokedCertsPerOrganization", revokedCertsPerOrganization); | ||||
|         field_to_json(Obj,"numberOfRedirectors", numberOfRedirectors); | ||||
|         field_to_json(Obj,"deviceTypes", deviceTypes); | ||||
|         field_to_json(Obj,"monthlyNumberOfCerts", monthlyNumberOfCerts); | ||||
|         field_to_json(Obj,"monthlyNumberOfCertsPerOrgPerYear", monthlyNumberOfCertsPerOrgPerYear); | ||||
|     } | ||||
|  | ||||
|     void Dashboard::reset() { | ||||
|         snapshot=0; | ||||
|         numberOfRevokedCerts = numberOfIssuedCerts = 0; | ||||
|         activeCertsPerOrganization.clear(); | ||||
|         revokedCertsPerOrganization.clear(); | ||||
|         numberOfRedirectors.clear(); | ||||
|         deviceTypes.clear(); | ||||
|         monthlyNumberOfCerts.clear(); | ||||
|         monthlyNumberOfCertsPerOrgPerYear.clear(); | ||||
|     } | ||||
| } | ||||
| @@ -5,97 +5,119 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <string> | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/OpenWifiTypes.h" | ||||
| #include "RESTObjects/RESTAPI_SecurityObjects.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
| namespace OpenWifi::CertObjects { | ||||
|  | ||||
|     namespace CertObjects { | ||||
|     struct CertificateEntry { | ||||
|         OpenWifi::Types::UUID_t         id; | ||||
|         OpenWifi::Types::UUID_t         entity; | ||||
|         OpenWifi::Types::UUID_t         creator; | ||||
|         std::string                     type; | ||||
|         std::string                     status; | ||||
|         std::string                     certificate; | ||||
|         std::string                     key; | ||||
|         std::string                     devid; | ||||
|         std::string                     cas; | ||||
|         std::string                     manufacturer; | ||||
|         std::string                     model; | ||||
|         std::string                     redirector; | ||||
|         std::string                     commonName; | ||||
|         std::string                     certificateId; | ||||
|         OpenWifi::Types::UUID_t         batch; | ||||
|         uint64_t                        created = 0; | ||||
|         uint64_t                        modified = 0; | ||||
|         uint64_t                        revoked = 0; | ||||
|         uint64_t                        revokeCount = 0; | ||||
|         uint64_t                        synched = 0; | ||||
|  | ||||
|         struct CertificateEntry { | ||||
|             OpenWifi::Types::UUID_t         id; | ||||
|             OpenWifi::Types::UUID_t         entity; | ||||
|             OpenWifi::Types::UUID_t         creator; | ||||
|             std::string                     type; | ||||
|             std::string                     status; | ||||
|             std::string                     certificate; | ||||
|             std::string                     key; | ||||
|             std::string                     devid; | ||||
|             std::string                     cas; | ||||
|             std::string                     manufacturer; | ||||
|             std::string                     model; | ||||
|             std::string                     redirector; | ||||
|             std::string                     commonName; | ||||
|             std::string                     certificateId; | ||||
|             OpenWifi::Types::UUID_t         batch; | ||||
|             uint64_t                        created = 0; | ||||
|             uint64_t                        modified = 0; | ||||
|             uint64_t                        revoked = 0; | ||||
|             uint64_t                        revokeCount = 0; | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|     struct EntityEntry { | ||||
|         OpenWifi::Types::UUID_t         id; | ||||
|         OpenWifi::Types::UUID_t         creator; | ||||
|         std::string                     name; | ||||
|         std::string                     description; | ||||
|         std::string                     defaultRedirector; | ||||
|         std::string                     apiKey; | ||||
|         std::string                     serverEnrollmentProfile; | ||||
|         std::string                     clientEnrollmentProfile; | ||||
|         std::string                     organization; | ||||
|         SecurityObjects::NoteInfoVec    notes; | ||||
|         bool                            suspended=false; | ||||
|         bool                            deleted=false; | ||||
|         uint64_t                        created = 0 ; | ||||
|         uint64_t                        modified = 0 ; | ||||
|  | ||||
|         struct EntityEntry { | ||||
|             OpenWifi::Types::UUID_t         id; | ||||
|             OpenWifi::Types::UUID_t         creator; | ||||
|             std::string                     name; | ||||
|             std::string                     description; | ||||
|             std::string                     defaultRedirector; | ||||
|             std::string                     apiKey; | ||||
|             std::string                     serverEnrollmentProfile; | ||||
|             std::string                     clientEnrollmentProfile; | ||||
|             std::string                     organization; | ||||
|             SecurityObjects::NoteInfoVec    notes; | ||||
|             bool                            suspended=false; | ||||
|             bool                            deleted=false; | ||||
|             uint64_t                        created = 0 ; | ||||
|             uint64_t                        modified = 0 ; | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|     struct BatchEntry { | ||||
|         OpenWifi::Types::UUID_t         id; | ||||
|         OpenWifi::Types::UUID_t         entity; | ||||
|         OpenWifi::Types::UUID_t         creator; | ||||
|         std::string                     name; | ||||
|         std::string                     description; | ||||
|         std::string                     manufacturer; | ||||
|         std::string                     model; | ||||
|         std::string                     redirector; | ||||
|         std::vector<std::string>        commonNames; | ||||
|         std::vector<std::string>        jobHistory; | ||||
|         SecurityObjects::NoteInfoVec    notes; | ||||
|         uint64_t                        submitted = 0 ; | ||||
|         uint64_t                        started = 0 ; | ||||
|         uint64_t                        completed = 0 ; | ||||
|         uint64_t                        modified = 0 ; | ||||
|  | ||||
|         struct BatchEntry { | ||||
|             OpenWifi::Types::UUID_t         id; | ||||
|             OpenWifi::Types::UUID_t         entity; | ||||
|             OpenWifi::Types::UUID_t         creator; | ||||
|             std::string                     name; | ||||
|             std::string                     description; | ||||
|             std::string                     manufacturer; | ||||
|             std::string                     model; | ||||
|             std::string                     redirector; | ||||
|             std::vector<std::string>        commonNames; | ||||
|             std::vector<std::string>        jobHistory; | ||||
|             SecurityObjects::NoteInfoVec    notes; | ||||
|             uint64_t                        submitted = 0 ; | ||||
|             uint64_t                        started = 0 ; | ||||
|             uint64_t                        completed = 0 ; | ||||
|             uint64_t                        modified = 0 ; | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|     struct JobEntry { | ||||
|         OpenWifi::Types::UUID_t         id; | ||||
|         OpenWifi::Types::UUID_t         entity; | ||||
|         OpenWifi::Types::UUID_t         creator; | ||||
|         OpenWifi::Types::UUID_t         batch; | ||||
|         std::string                     command; | ||||
|         OpenWifi::Types::StringVec      commonNames; | ||||
|         OpenWifi::Types::StringVec      completedNames; | ||||
|         OpenWifi::Types::StringVec      errorNames; | ||||
|         Types::StringPairVec            parameters; | ||||
|         std::string                     status; | ||||
|         uint64_t                        submitted=0; | ||||
|         uint64_t                        started=0; | ||||
|         uint64_t                        completed=0; | ||||
|         std::string                     requesterUsername; | ||||
|  | ||||
|         struct JobEntry { | ||||
|             OpenWifi::Types::UUID_t         id; | ||||
|             OpenWifi::Types::UUID_t         entity; | ||||
|             OpenWifi::Types::UUID_t         creator; | ||||
|             OpenWifi::Types::UUID_t         batch; | ||||
|             std::string                     command; | ||||
|             OpenWifi::Types::StringVec      commonNames; | ||||
|             OpenWifi::Types::StringVec      completedNames; | ||||
|             OpenWifi::Types::StringVec      errorNames; | ||||
|             Types::StringPairVec            parameters; | ||||
|             std::string                     status; | ||||
|             uint64_t                        submitted=0; | ||||
|             uint64_t                        started=0; | ||||
|             uint64_t                        completed=0; | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     struct DashBoardYearlyStats { | ||||
|         uint64_t                            year=0; | ||||
|         OpenWifi::Types::Counted3DMapSII    activeCerts; | ||||
|         OpenWifi::Types::Counted3DMapSII    revokedCerts; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|     }; | ||||
|  | ||||
|     struct Dashboard { | ||||
|         uint64_t                            snapshot=0; | ||||
|         uint64_t                            numberOfIssuedCerts=0; | ||||
|         uint64_t                            numberOfRevokedCerts=0; | ||||
|         OpenWifi::Types::CountedMap         activeCertsPerOrganization; | ||||
|         OpenWifi::Types::CountedMap         revokedCertsPerOrganization; | ||||
|         OpenWifi::Types::CountedMap         numberOfRedirectors; | ||||
|         OpenWifi::Types::CountedMap         deviceTypes; | ||||
|         OpenWifi::Types::CountedMap         monthlyNumberOfCerts; | ||||
|         std::vector<DashBoardYearlyStats>   monthlyNumberOfCertsPerOrgPerYear; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         void reset(); | ||||
|     }; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| @@ -3,7 +3,8 @@ | ||||
| // | ||||
|  | ||||
| #include "RESTAPI_FMSObjects.h" | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_utils.h" | ||||
| #include "framework/utils.h" | ||||
|  | ||||
| using OpenWifi::RESTAPI_utils::field_to_json; | ||||
| using OpenWifi::RESTAPI_utils::field_from_json; | ||||
| @@ -233,10 +234,10 @@ namespace OpenWifi::FMSObjects { | ||||
|         UnknownFirmwares_.clear(); | ||||
|         totalSecondsOld_.clear(); | ||||
|         numberOfDevices = 0 ; | ||||
|         snapshot = std::time(nullptr); | ||||
|         snapshot = Utils::Now(); | ||||
|     } | ||||
|  | ||||
|     bool DeviceReport::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|     bool DeviceReport::from_json([[maybe_unused]] const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|  | ||||
|             return true; | ||||
| @@ -245,4 +246,65 @@ namespace OpenWifi::FMSObjects { | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void DeviceInformation::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj, "serialNumber",serialNumber); | ||||
|         field_to_json(Obj, "history", history); | ||||
|         field_to_json(Obj, "currentFirmware", currentFirmware); | ||||
|         field_to_json(Obj, "currentFirmwareDate", currentFirmwareDate); | ||||
|         field_to_json(Obj, "latestFirmware", latestFirmware); | ||||
|         field_to_json(Obj, "latestFirmwareDate", latestFirmwareDate); | ||||
|         field_to_json(Obj, "latestFirmwareAvailable",latestFirmwareAvailable); | ||||
|         field_to_json(Obj, "latestFirmwareURI",latestFirmwareURI); | ||||
|     } | ||||
|  | ||||
|     bool DeviceInformation::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj, "serialNumber",serialNumber); | ||||
|             field_from_json(Obj, "history", history); | ||||
|             field_from_json(Obj, "currentFirmware", currentFirmware); | ||||
|             field_from_json(Obj, "currentFirmwareDate", currentFirmwareDate); | ||||
|             field_from_json(Obj, "latestFirmware", latestFirmware); | ||||
|             field_from_json(Obj, "latestFirmwareDate", latestFirmwareDate); | ||||
|             field_from_json(Obj, "latestFirmwareAvailable",latestFirmwareAvailable); | ||||
|             field_from_json(Obj, "latestFirmwareURI",latestFirmwareURI); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void DeviceCurrentInfo::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj, "serialNumber",serialNumber); | ||||
|         field_to_json(Obj, "revision", revision); | ||||
|         field_to_json(Obj, "upgraded", upgraded); | ||||
|     } | ||||
|  | ||||
|     bool DeviceCurrentInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj, "serialNumber",serialNumber); | ||||
|             field_from_json(Obj, "revision", revision); | ||||
|             field_from_json(Obj, "upgraded", upgraded); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void DeviceCurrentInfoList::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj, "devices",devices); | ||||
|     } | ||||
|  | ||||
|     bool DeviceCurrentInfoList::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj, "devices",devices); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -4,9 +4,7 @@ | ||||
|  | ||||
| #include <string> | ||||
|  | ||||
| #ifndef UCENTRALFMS_RESTAPI_FMSOBJECTS_H | ||||
| #define UCENTRALFMS_RESTAPI_FMSOBJECTS_H | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "RESTAPI_SecurityObjects.h" | ||||
| #include "framework/OpenWifiTypes.h" | ||||
| @@ -29,7 +27,7 @@ namespace OpenWifi::FMSObjects { | ||||
|         std::string     location; | ||||
|         std::string     uploader; | ||||
|         std::string     digest; | ||||
|         bool            latest=0; | ||||
|         bool            latest=false; | ||||
|         SecurityObjects::NoteInfoVec    notes; | ||||
|         uint64_t        created=0; | ||||
|  | ||||
| @@ -127,7 +125,35 @@ namespace OpenWifi::FMSObjects { | ||||
|         void reset(); | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     struct DeviceInformation { | ||||
|         std::string                 serialNumber; | ||||
|         RevisionHistoryEntryList    history; | ||||
|         std::string                 currentFirmware; | ||||
|         uint64_t                    currentFirmwareDate=0; | ||||
|         std::string                 latestFirmware; | ||||
|         uint64_t                    latestFirmwareDate=0; | ||||
|         bool                        latestFirmwareAvailable; | ||||
|         std::string                 latestFirmwareURI; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     struct DeviceCurrentInfo { | ||||
|         std::string                 serialNumber; | ||||
|         std::string                 revision; | ||||
|         uint64_t                    upgraded=0; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     struct DeviceCurrentInfoList { | ||||
|         std::vector<DeviceCurrentInfo>  devices; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| #endif //UCENTRALFMS_RESTAPI_FMSOBJECTS_H | ||||
|   | ||||
| @@ -11,12 +11,13 @@ | ||||
|  | ||||
| #include "Daemon.h" | ||||
| #ifdef	TIP_GATEWAY_SERVICE | ||||
| #include "DeviceRegistry.h" | ||||
| #include "AP_WS_Server.h" | ||||
| #include "CapabilitiesCache.h" | ||||
| #endif | ||||
|  | ||||
| #include "RESTAPI_GWobjects.h" | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_utils.h" | ||||
| #include "framework/utils.h" | ||||
|  | ||||
| using OpenWifi::RESTAPI_utils::field_to_json; | ||||
| using OpenWifi::RESTAPI_utils::field_from_json; | ||||
| @@ -27,7 +28,7 @@ namespace OpenWifi::GWObjects { | ||||
| 	void Device::to_json(Poco::JSON::Object &Obj) const { | ||||
| 		field_to_json(Obj,"serialNumber", SerialNumber); | ||||
| #ifdef TIP_GATEWAY_SERVICE | ||||
| 		field_to_json(Obj,"deviceType", CapabilitiesCache::instance()->Get(Compatible)); | ||||
| 		field_to_json(Obj,"deviceType", CapabilitiesCache::instance()->GetPlatform(Compatible)); | ||||
| #endif | ||||
| 		field_to_json(Obj,"macAddress", MACAddress); | ||||
| 		field_to_json(Obj,"manufacturer", Manufacturer); | ||||
| @@ -45,6 +46,14 @@ namespace OpenWifi::GWObjects { | ||||
| 		field_to_json(Obj,"compatible", Compatible); | ||||
| 		field_to_json(Obj,"fwUpdatePolicy", FWUpdatePolicy); | ||||
| 		field_to_json(Obj,"devicePassword", DevicePassword); | ||||
| 		field_to_json(Obj,"subscriber", subscriber); | ||||
| 		field_to_json(Obj,"entity", entity); | ||||
| 		field_to_json(Obj,"modified", modified); | ||||
| 		field_to_json(Obj,"locale", locale); | ||||
| 		field_to_json(Obj,"restrictedDevice", restrictedDevice); | ||||
| 		field_to_json(Obj,"pendingConfiguration", pendingConfiguration); | ||||
| 		field_to_json(Obj,"pendingConfigurationCmd", pendingConfigurationCmd); | ||||
| 		field_to_json(Obj,"restrictionDetails", restrictionDetails); | ||||
| 	} | ||||
|  | ||||
| 	void Device::to_json_with_status(Poco::JSON::Object &Obj) const { | ||||
| @@ -53,7 +62,7 @@ namespace OpenWifi::GWObjects { | ||||
| #ifdef TIP_GATEWAY_SERVICE | ||||
| 		ConnectionState ConState; | ||||
|  | ||||
| 		if (DeviceRegistry()->GetState(SerialNumber, ConState)) { | ||||
| 		if (AP_WS_Server()->GetState(SerialNumber, ConState)) { | ||||
| 			ConState.to_json(Obj); | ||||
| 		} else { | ||||
| 			field_to_json(Obj,"ipAddress", ""); | ||||
| @@ -65,11 +74,12 @@ namespace OpenWifi::GWObjects { | ||||
| 			field_to_json(Obj,"verifiedCertificate", "NO_CERTIFICATE"); | ||||
| 			field_to_json(Obj,"associations_2G", (uint64_t) 0); | ||||
| 			field_to_json(Obj,"associations_5G", (uint64_t) 0); | ||||
| 			field_to_json(Obj,"associations_6G", (uint64_t) 0); | ||||
| 		} | ||||
| #endif | ||||
| 	} | ||||
|  | ||||
| 	bool Device::from_json(Poco::JSON::Object::Ptr &Obj) { | ||||
| 	bool Device::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| 		try { | ||||
| 			field_from_json(Obj,"serialNumber",SerialNumber); | ||||
| 			field_from_json(Obj,"deviceType",DeviceType); | ||||
| @@ -81,6 +91,13 @@ namespace OpenWifi::GWObjects { | ||||
| 			field_from_json(Obj,"location",Location); | ||||
| 			field_from_json(Obj,"venue",Venue); | ||||
| 			field_from_json(Obj,"compatible",Compatible); | ||||
| 			field_from_json(Obj,"subscriber", subscriber); | ||||
| 			field_from_json(Obj,"entity", entity); | ||||
| 			field_from_json(Obj,"locale", locale); | ||||
| 			field_from_json(Obj,"restrictedDevice", restrictedDevice); | ||||
| 			field_from_json(Obj,"pendingConfiguration", pendingConfiguration); | ||||
| 			field_from_json(Obj,"pendingConfigurationCmd", pendingConfigurationCmd); | ||||
| 			field_from_json(Obj,"restrictionDetails", restrictionDetails); | ||||
| 			return true; | ||||
| 		} catch (const Poco::Exception &E) { | ||||
| 		} | ||||
| @@ -149,7 +166,7 @@ namespace OpenWifi::GWObjects { | ||||
| 		field_to_json(Obj,"executionTime", executionTime); | ||||
| 	} | ||||
|  | ||||
| 	bool DefaultConfiguration::from_json(Poco::JSON::Object::Ptr &Obj) { | ||||
| 	bool DefaultConfiguration::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| 		try { | ||||
| 			field_from_json(Obj,"name",Name); | ||||
| 			field_from_json(Obj,"configuration",Configuration); | ||||
| @@ -168,7 +185,7 @@ namespace OpenWifi::GWObjects { | ||||
| 		field_to_json(Obj,"created", created); | ||||
| 	} | ||||
|  | ||||
| 	bool BlackListedDevice::from_json(Poco::JSON::Object::Ptr &Obj) { | ||||
| 	bool BlackListedDevice::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| 		try { | ||||
| 			field_from_json(Obj,"serialNumber",serialNumber); | ||||
| 			field_from_json(Obj,"author",author); | ||||
| @@ -191,10 +208,17 @@ namespace OpenWifi::GWObjects { | ||||
| 		field_to_json(Obj,"lastContact", LastContact); | ||||
| 		field_to_json(Obj,"associations_2G", Associations_2G); | ||||
| 		field_to_json(Obj,"associations_5G", Associations_5G); | ||||
| 		field_to_json(Obj,"associations_6G", Associations_6G); | ||||
| 		field_to_json(Obj,"webSocketClients", webSocketClients); | ||||
| 		field_to_json(Obj,"websocketPackets", websocketPackets); | ||||
| 		field_to_json(Obj,"kafkaClients", kafkaClients); | ||||
| 		field_to_json(Obj,"kafkaPackets", kafkaPackets); | ||||
| 		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", Utils::Now() - started); | ||||
| 		field_to_json(Obj,"certificateExpiryDate", certificateExpiryDate); | ||||
|  | ||||
| 		switch(VerifiedCertificate) { | ||||
| 			case NO_CERTIFICATE: | ||||
| @@ -210,6 +234,23 @@ namespace OpenWifi::GWObjects { | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	void DeviceConnectionStatistics::to_json(Poco::JSON::Object &Obj) const { | ||||
| 		field_to_json(Obj,"averageConnectionTime", averageConnectionTime); | ||||
| 		field_to_json(Obj,"connectedDevices", connectedDevices ); | ||||
| 		field_to_json(Obj,"connectingDevices", connectingDevices ); | ||||
| 	} | ||||
|  | ||||
| 	bool DeviceConnectionStatistics::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| 		try { | ||||
| 			field_from_json(Obj,"averageConnectionTime", averageConnectionTime); | ||||
| 			field_from_json(Obj,"connectedDevices", connectedDevices ); | ||||
| 			field_from_json(Obj,"connectingDevices", connectingDevices ); | ||||
| 			return true; | ||||
| 		} catch (const Poco::Exception &E) { | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	void RttySessionDetails::to_json(Poco::JSON::Object &Obj) const { | ||||
| 		field_to_json(Obj,"serialNumber", SerialNumber); | ||||
| 		field_to_json(Obj,"server", Server); | ||||
| @@ -256,7 +297,7 @@ namespace OpenWifi::GWObjects { | ||||
| 		lastContact.clear(); | ||||
| 		associations.clear(); | ||||
| 		numberOfDevices = 0 ; | ||||
| 		snapshot = std::time(nullptr); | ||||
| 		snapshot = Utils::Now(); | ||||
| 	} | ||||
|  | ||||
| 	void CapabilitiesModel::to_json(Poco::JSON::Object &Obj) const{ | ||||
| @@ -264,5 +305,243 @@ namespace OpenWifi::GWObjects { | ||||
| 		field_to_json(Obj,"capabilities", capabilities); | ||||
| 	}; | ||||
|  | ||||
| 	void ScriptRequest::to_json(Poco::JSON::Object &Obj) const { | ||||
| 		field_to_json(Obj,"serialNumber",serialNumber); | ||||
| 		field_to_json(Obj,"timeout",timeout); | ||||
| 		field_to_json(Obj,"type",type); | ||||
| 		field_to_json(Obj,"scriptId",scriptId); | ||||
| 		field_to_json(Obj,"script",script); | ||||
| 		field_to_json(Obj,"when",when); | ||||
| 		field_to_json(Obj,"signature", signature); | ||||
| 		field_to_json(Obj,"deferred", deferred); | ||||
| 		field_to_json(Obj,"uri", uri); | ||||
| 	} | ||||
|  | ||||
| 	bool ScriptRequest::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| 		try { | ||||
| 			field_from_json(Obj,"serialNumber",serialNumber); | ||||
| 			field_from_json(Obj,"timeout",timeout); | ||||
| 			field_from_json(Obj,"type",type); | ||||
| 			field_from_json(Obj,"script",script); | ||||
| 			field_from_json(Obj,"scriptId",scriptId); | ||||
| 			field_from_json(Obj,"when",when); | ||||
| 			field_from_json(Obj,"signature", signature); | ||||
| 			field_from_json(Obj,"deferred", deferred); | ||||
| 			field_from_json(Obj,"uri", uri); | ||||
| 			return true; | ||||
| 		} catch (const Poco::Exception &E) { | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	void RadiusProxyPoolList::to_json(Poco::JSON::Object &Obj) const { | ||||
| 		field_to_json(Obj,"pools",pools); | ||||
| 	} | ||||
|  | ||||
| 	bool RadiusProxyPoolList::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| 		try { | ||||
| 			field_from_json(Obj,"pools",pools); | ||||
| 			return true; | ||||
| 		} catch (const Poco::Exception &E) { | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	void RadiusProxyPool::to_json(Poco::JSON::Object &Obj) const { | ||||
| 		field_to_json(Obj,"name",name); | ||||
| 		field_to_json(Obj,"description",description); | ||||
| 		field_to_json(Obj,"authConfig",authConfig); | ||||
| 		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) { | ||||
| 		try { | ||||
| 			field_from_json(Obj,"name",name); | ||||
| 			field_from_json(Obj,"description",description); | ||||
| 			field_from_json(Obj,"authConfig",authConfig); | ||||
| 			field_from_json(Obj,"acctConfig",acctConfig); | ||||
| 			field_from_json(Obj,"coaConfig",coaConfig); | ||||
| 			field_from_json(Obj,"useByDefault",useByDefault); | ||||
| 			return true; | ||||
| 		} catch (const Poco::Exception &E) { | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	void RadiusProxyServerConfig::to_json(Poco::JSON::Object &Obj) const { | ||||
| 		field_to_json(Obj,"strategy",strategy); | ||||
| 		field_to_json(Obj,"monitor",monitor); | ||||
| 		field_to_json(Obj,"monitorMethod",monitorMethod); | ||||
| 		field_to_json(Obj,"methodParameters",methodParameters); | ||||
| 		field_to_json(Obj,"servers",servers); | ||||
| 	} | ||||
|  | ||||
| 	bool RadiusProxyServerConfig::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| 		try { | ||||
| 			field_from_json(Obj,"strategy",strategy); | ||||
| 			field_from_json(Obj,"monitor",monitor); | ||||
| 			field_from_json(Obj,"monitorMethod",monitorMethod); | ||||
| 			field_from_json(Obj,"methodParameters",methodParameters); | ||||
| 			field_from_json(Obj,"servers",servers); | ||||
| 			return true; | ||||
| 		} catch (const Poco::Exception &E) { | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	void RadiusProxyServerEntry::to_json(Poco::JSON::Object &Obj) const { | ||||
| 		field_to_json(Obj,"name",name); | ||||
| 		field_to_json(Obj,"ip",ip); | ||||
| 		field_to_json(Obj,"port",port); | ||||
| 		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,"allowSelfSigned",allowSelfSigned); | ||||
| 		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) { | ||||
| 		try { | ||||
| 			field_from_json(Obj,"name",name); | ||||
| 			field_from_json(Obj,"ip",ip); | ||||
| 			field_from_json(Obj,"port",port); | ||||
| 			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,"allowSelfSigned",allowSelfSigned); | ||||
| 			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; | ||||
| 		} catch (const Poco::Exception &E) { | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	void ScriptEntry::to_json(Poco::JSON::Object &Obj) const { | ||||
| 		field_to_json(Obj,"id", id); | ||||
| 		field_to_json(Obj,"name", name); | ||||
| 		field_to_json(Obj,"description", description); | ||||
| 		field_to_json(Obj,"uri", uri); | ||||
| 		field_to_json(Obj,"content", content); | ||||
| 		field_to_json(Obj,"version", version); | ||||
| 		field_to_json(Obj,"type", type); | ||||
| 		field_to_json(Obj,"created", created); | ||||
| 		field_to_json(Obj,"modified", modified); | ||||
| 		field_to_json(Obj,"author", author); | ||||
| 		field_to_json(Obj,"restricted", restricted); | ||||
| 		field_to_json(Obj,"deferred", deferred); | ||||
| 		field_to_json(Obj,"timeout", timeout); | ||||
| 		field_to_json(Obj,"defaultUploadURI", defaultUploadURI); | ||||
| 	} | ||||
|  | ||||
| 	bool ScriptEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| 		try { | ||||
| 			field_from_json(Obj,"id", id); | ||||
| 			field_from_json(Obj,"name", name); | ||||
| 			field_from_json(Obj,"description", description); | ||||
| 			field_from_json(Obj,"uri", uri); | ||||
| 			field_from_json(Obj,"content", content); | ||||
| 			field_from_json(Obj,"version", version); | ||||
| 			field_from_json(Obj,"type", type); | ||||
| 			field_from_json(Obj,"created", created); | ||||
| 			field_from_json(Obj,"modified", modified); | ||||
| 			field_from_json(Obj,"author", author); | ||||
| 			field_from_json(Obj,"restricted", restricted); | ||||
| 			field_from_json(Obj,"deferred", deferred); | ||||
| 			field_from_json(Obj,"timeout", timeout); | ||||
| 			field_from_json(Obj,"defaultUploadURI", defaultUploadURI); | ||||
| 			return true; | ||||
| 		} catch (const Poco::Exception &E) { | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	void ScriptEntryList::to_json(Poco::JSON::Object &Obj) const { | ||||
| 		field_to_json(Obj,"scripts",scripts); | ||||
| 	} | ||||
|  | ||||
| 	bool ScriptEntryList::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| 		try { | ||||
| 			field_from_json(Obj,"scripts",scripts); | ||||
| 			return true; | ||||
| 		} catch (const Poco::Exception &E) { | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	void DeviceRestrictionsKeyInfo::to_json(Poco::JSON::Object &Obj) const { | ||||
| 		field_to_json(Obj,"vendor", vendor); | ||||
| 		field_to_json(Obj,"algo", algo); | ||||
| 	} | ||||
|  | ||||
| 	bool DeviceRestrictionsKeyInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| 		try { | ||||
| 			field_from_json(Obj,"vendor", vendor); | ||||
| 			field_from_json(Obj,"algo", algo); | ||||
| 			return true; | ||||
| 		} catch (const Poco::Exception &E) { | ||||
| 		} | ||||
| 		return false; | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	void DeviceRestrictions::to_json(Poco::JSON::Object &Obj) const { | ||||
| 		field_to_json(Obj,"dfs", dfs); | ||||
| 		field_to_json(Obj,"ssh", ssh); | ||||
| 		field_to_json(Obj,"rtty", rtty); | ||||
| 		field_to_json(Obj,"tty", tty); | ||||
| 		field_to_json(Obj,"developer", developer); | ||||
| 		field_to_json(Obj,"upgrade", upgrade); | ||||
| 		field_to_json(Obj,"commands", commands); | ||||
| 		field_to_json(Obj,"country", country); | ||||
| 		field_to_json(Obj,"key_info", key_info); | ||||
| 	} | ||||
|  | ||||
| 	bool DeviceRestrictions::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| 		try { | ||||
| 			field_from_json(Obj,"dfs", dfs); | ||||
| 			field_from_json(Obj,"ssh", ssh); | ||||
| 			field_from_json(Obj,"rtty", rtty); | ||||
| 			field_from_json(Obj,"tty", tty); | ||||
| 			field_from_json(Obj,"developer", developer); | ||||
| 			field_from_json(Obj,"upgrade", upgrade); | ||||
| 			field_from_json(Obj,"commands", commands); | ||||
| 			field_from_json(Obj,"country", country); | ||||
| 			field_from_json(Obj,"key_info", key_info); | ||||
| 			return true; | ||||
| 		} catch (const Poco::Exception &E) { | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	bool DeviceRestrictionsKeyInfo::operator!=(const OpenWifi::GWObjects::DeviceRestrictionsKeyInfo &T) const { | ||||
| 		return (T.algo!=algo) || (T.vendor!=vendor); | ||||
| 	} | ||||
|  | ||||
| 	bool DeviceRestrictions::operator!=(const OpenWifi::GWObjects::DeviceRestrictions &T) const { | ||||
| 		return (	(T.dfs!=dfs)					|| | ||||
| 					(T.rtty!=rtty)					|| | ||||
| 					(T.upgrade!=upgrade)		|| | ||||
| 					(T.commands != commands)		|| | ||||
| 					(T.developer != developer)		|| | ||||
| 					(T.ssh !=ssh) 					|| | ||||
| 					(T.key_info != key_info)		|| | ||||
| 					(T.country != country) ); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -28,18 +28,52 @@ namespace OpenWifi::GWObjects { | ||||
| 		uint64_t TX = 0, RX = 0; | ||||
| 		uint64_t Associations_2G=0; | ||||
| 		uint64_t Associations_5G=0; | ||||
| 		uint64_t Associations_6G=0; | ||||
| 		bool Connected = false; | ||||
| 		uint64_t LastContact=0; | ||||
| 		std::string Firmware; | ||||
| 		CertificateValidation VerifiedCertificate = NO_CERTIFICATE; | ||||
| 		std::string Compatible; | ||||
| 		uint64_t 	kafkaClients=0; | ||||
| 		uint64_t 	webSocketClients=0; | ||||
| 		uint64_t 	kafkaPackets=0; | ||||
| 		uint64_t 	websocketPackets=0; | ||||
| 		std::string 	Compatible; | ||||
| 		uint64_t 		kafkaClients=0; | ||||
| 		uint64_t 		webSocketClients=0; | ||||
| 		uint64_t 		kafkaPackets=0; | ||||
| 		uint64_t 		websocketPackets=0; | ||||
| 		std::string 	locale; | ||||
| 		uint64_t 		started=0; | ||||
| 		uint64_t 		sessionId=0; | ||||
| 		double      	connectionCompletionTime=0.0; | ||||
| 		std::uint64_t	certificateExpiryDate=0; | ||||
|  | ||||
| 		void to_json(Poco::JSON::Object &Obj) const; | ||||
| 	}; | ||||
|  | ||||
| 	struct DeviceRestrictionsKeyInfo { | ||||
| 		std::string 	vendor; | ||||
| 		std::string 	algo; | ||||
|  | ||||
| 		bool operator !=(const DeviceRestrictionsKeyInfo &b) const; | ||||
|  | ||||
| 		void to_json(Poco::JSON::Object &Obj) const; | ||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| 	}; | ||||
|  | ||||
| 	struct DeviceRestrictions { | ||||
| 		bool    					dfs = false; | ||||
| 		bool    					ssh = false; | ||||
| 		bool    					rtty = false; | ||||
| 		bool    					tty = false; | ||||
| 		bool    					developer = false; | ||||
| 		bool    					upgrade = false; | ||||
| 		bool    					commands = false; | ||||
| 		std::vector<std::string>   	country; | ||||
| 		DeviceRestrictionsKeyInfo	key_info; | ||||
|  | ||||
| 		bool operator !=(const DeviceRestrictions &D) const; | ||||
|  | ||||
| 		void to_json(Poco::JSON::Object &Obj) const; | ||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| 	}; | ||||
|  | ||||
| 	struct Device { | ||||
| 		std::string SerialNumber; | ||||
| 		std::string DeviceType; | ||||
| @@ -59,12 +93,30 @@ namespace OpenWifi::GWObjects { | ||||
| 		uint64_t LastFWUpdate = 0 ; | ||||
| 		std::string Venue; | ||||
| 		std::string DevicePassword; | ||||
| 		std::string subscriber; | ||||
| 		std::string entity; | ||||
| 		uint64_t 	modified=0; | ||||
| 		std::string locale; | ||||
| 		bool 		restrictedDevice=false; | ||||
| 		std::string pendingConfiguration; | ||||
| 		std::string pendingConfigurationCmd; | ||||
| 		DeviceRestrictions	restrictionDetails; | ||||
|  | ||||
| 		void to_json(Poco::JSON::Object &Obj) const; | ||||
| 		void to_json_with_status(Poco::JSON::Object &Obj) const; | ||||
| 		bool from_json(Poco::JSON::Object::Ptr &Obj); | ||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| 		void Print() const; | ||||
| 	}; | ||||
|  | ||||
| 	struct DeviceConnectionStatistics { | ||||
| 		std::uint64_t connectedDevices = 0; | ||||
| 		std::uint64_t averageConnectionTime = 0; | ||||
| 		std::uint64_t connectingDevices = 0; | ||||
|  | ||||
| 		void to_json(Poco::JSON::Object &Obj) const; | ||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| 	}; | ||||
|  | ||||
| 	struct Statistics { | ||||
| 		std::string SerialNumber; | ||||
| 		uint64_t 	UUID = 0 ; | ||||
| @@ -118,7 +170,7 @@ namespace OpenWifi::GWObjects { | ||||
| 		uint64_t 	Created; | ||||
| 		uint64_t 	LastModified; | ||||
| 		void 		to_json(Poco::JSON::Object &Obj) const; | ||||
| 		bool 		from_json(Poco::JSON::Object::Ptr &Obj); | ||||
| 		bool 		from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| 	}; | ||||
|  | ||||
| 	struct CommandDetails { | ||||
| @@ -150,7 +202,7 @@ namespace OpenWifi::GWObjects { | ||||
| 		std::string author; | ||||
| 		uint64_t created; | ||||
| 		void to_json(Poco::JSON::Object &Obj) const; | ||||
| 		bool from_json(Poco::JSON::Object::Ptr &Obj); | ||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| 	}; | ||||
|  | ||||
| 	struct RttySessionDetails { | ||||
| @@ -193,4 +245,98 @@ namespace OpenWifi::GWObjects { | ||||
|  | ||||
| 		void to_json(Poco::JSON::Object &Obj) const; | ||||
| 	}; | ||||
|  | ||||
| 	struct ScriptEntry { | ||||
| 		std::string 		id; | ||||
| 		std::string 		name; | ||||
| 		std::string 		description; | ||||
| 		std::string 		uri; | ||||
| 		std::string 		content; | ||||
| 		std::string 		version; | ||||
| 		std::string 		type; | ||||
| 		std::uint64_t 		created; | ||||
| 		std::uint64_t 		modified; | ||||
| 		std::string 		author; | ||||
| 		Types::StringVec 	restricted; | ||||
| 		bool				deferred=false; | ||||
| 		std::uint64_t 		timeout=30; | ||||
| 		std::string 		defaultUploadURI; | ||||
|  | ||||
| 		void to_json(Poco::JSON::Object &Obj) const; | ||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| 	}; | ||||
|  | ||||
| 	struct ScriptEntryList { | ||||
| 		std::vector<ScriptEntry>	scripts; | ||||
|  | ||||
| 		void to_json(Poco::JSON::Object &Obj) const; | ||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| 	}; | ||||
|  | ||||
| 	struct ScriptRequest { | ||||
| 		std::string serialNumber; | ||||
| 		uint64_t 	timeout=30; | ||||
| 		std::string type; | ||||
| 		std::string script; | ||||
| 		std::string scriptId; | ||||
| 		std::uint64_t when; | ||||
| 		std::string signature; | ||||
| 		bool deferred; | ||||
| 		std::string uri; | ||||
|  | ||||
| 		void to_json(Poco::JSON::Object &Obj) const; | ||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| 	}; | ||||
|  | ||||
| 	struct RadiusProxyServerEntry { | ||||
| 		std::string name; | ||||
| 		std::string ip; | ||||
| 		uint16_t 	port=0; | ||||
| 		uint64_t 	weight=0; | ||||
| 		std::string secret; | ||||
| 		std::string certificate; | ||||
| 		bool 		radsec=false; | ||||
| 		bool 		allowSelfSigned=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; | ||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| 	}; | ||||
|  | ||||
| 	struct RadiusProxyServerConfig { | ||||
| 		std::string 	strategy; | ||||
| 		bool 			monitor=false; | ||||
| 		std::string 	monitorMethod; | ||||
| 		std::vector<std::string>	methodParameters; | ||||
| 		std::vector<RadiusProxyServerEntry>	servers; | ||||
|  | ||||
| 		void to_json(Poco::JSON::Object &Obj) const; | ||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| 	}; | ||||
|  | ||||
| 	struct 	RadiusProxyPool { | ||||
| 		std::string name; | ||||
| 		std::string description; | ||||
| 		RadiusProxyServerConfig	authConfig; | ||||
| 		RadiusProxyServerConfig	acctConfig; | ||||
| 		RadiusProxyServerConfig	coaConfig; | ||||
| 		bool 		useByDefault=false; | ||||
|  | ||||
| 		void to_json(Poco::JSON::Object &Obj) const; | ||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| 	}; | ||||
|  | ||||
| 	struct RadiusProxyPoolList { | ||||
| 		std::vector<RadiusProxyPool>	pools; | ||||
|  | ||||
| 		void to_json(Poco::JSON::Object &Obj) const; | ||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| 	}; | ||||
|  | ||||
| } | ||||
|   | ||||
							
								
								
									
										110
									
								
								src/RESTObjects/RESTAPI_OWLSobjects.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								src/RESTObjects/RESTAPI_OWLSobjects.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,110 @@ | ||||
| // | ||||
| // Created by stephane bourque on 2021-08-31. | ||||
| // | ||||
|  | ||||
| #include "framework/RESTAPI_utils.h" | ||||
|  | ||||
| using OpenWifi::RESTAPI_utils::field_to_json; | ||||
| using OpenWifi::RESTAPI_utils::field_from_json; | ||||
| using OpenWifi::RESTAPI_utils::EmbedDocument; | ||||
|  | ||||
| #include "RESTAPI_OWLSobjects.h" | ||||
|  | ||||
| // SIM -> 0x53/0x073, 0x49/0x69, 0x4d/0x6d | ||||
|  | ||||
| namespace OpenWifi::OWLSObjects { | ||||
|  | ||||
|     void SimulationDetails::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj,"id", id); | ||||
|         field_to_json(Obj,"name", name); | ||||
|         field_to_json(Obj,"gateway", gateway); | ||||
|         field_to_json(Obj,"certificate", certificate); | ||||
|         field_to_json(Obj,"key", key); | ||||
|         field_to_json(Obj,"macPrefix", macPrefix); | ||||
|         field_to_json(Obj,"deviceType", deviceType); | ||||
|         field_to_json(Obj,"devices", devices); | ||||
|         field_to_json(Obj,"healthCheckInterval", healthCheckInterval); | ||||
|         field_to_json(Obj,"stateInterval", stateInterval); | ||||
|         field_to_json(Obj,"minAssociations", minAssociations); | ||||
|         field_to_json(Obj,"maxAssociations", maxAssociations); | ||||
|         field_to_json(Obj,"minClients", minClients); | ||||
|         field_to_json(Obj,"maxClients", maxClients); | ||||
|         field_to_json(Obj,"simulationLength", simulationLength); | ||||
|         field_to_json(Obj,"threads", threads); | ||||
|         field_to_json(Obj,"clientInterval", clientInterval); | ||||
|         field_to_json(Obj,"keepAlive", keepAlive); | ||||
|         field_to_json(Obj,"reconnectInterval", reconnectInterval); | ||||
|         field_to_json(Obj,"concurrentDevices", concurrentDevices); | ||||
|     } | ||||
|  | ||||
|     bool SimulationDetails::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj,"id", id); | ||||
|             field_from_json(Obj,"name", name); | ||||
|             field_from_json(Obj,"gateway", gateway); | ||||
|             field_from_json(Obj,"certificate", certificate); | ||||
|             field_from_json(Obj,"key", key); | ||||
|             field_from_json(Obj,"macPrefix", macPrefix); | ||||
|             field_from_json(Obj,"deviceType", deviceType); | ||||
|             field_from_json(Obj,"devices", devices); | ||||
|             field_from_json(Obj,"healthCheckInterval", healthCheckInterval); | ||||
|             field_from_json(Obj,"stateInterval", stateInterval); | ||||
|             field_from_json(Obj,"minAssociations", minAssociations); | ||||
|             field_from_json(Obj,"maxAssociations", maxAssociations); | ||||
|             field_from_json(Obj,"minClients", minClients); | ||||
|             field_from_json(Obj,"maxClients", maxClients); | ||||
|             field_from_json(Obj,"simulationLength", simulationLength); | ||||
|             field_from_json(Obj,"threads", threads); | ||||
|             field_from_json(Obj,"clientInterval", clientInterval); | ||||
|             field_from_json(Obj,"keepAlive", keepAlive); | ||||
|             field_from_json(Obj,"reconnectInterval", reconnectInterval); | ||||
|             field_from_json(Obj,"concurrentDevices", concurrentDevices); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void SimulationDetailsList::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj,"list", list); | ||||
|     } | ||||
|  | ||||
|     bool SimulationDetailsList::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj,"list", list); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void SimulationStatus::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj,"id", id); | ||||
|         field_to_json(Obj,"simulationId", simulationId); | ||||
|         field_to_json(Obj,"state", state); | ||||
|         field_to_json(Obj,"tx", tx); | ||||
|         field_to_json(Obj,"rx", rx); | ||||
|         field_to_json(Obj,"msgsTx", msgsTx); | ||||
|         field_to_json(Obj,"msgsRx", msgsRx); | ||||
|         field_to_json(Obj,"liveDevices", liveDevices); | ||||
|         field_to_json(Obj,"timeToFullDevices", timeToFullDevices); | ||||
|         field_to_json(Obj,"startTime", startTime); | ||||
|         field_to_json(Obj,"endTime", endTime); | ||||
|         field_to_json(Obj,"errorDevices", errorDevices); | ||||
|         field_to_json(Obj,"owner", owner); | ||||
|     } | ||||
|  | ||||
|     void Dashboard::to_json([[maybe_unused]] Poco::JSON::Object &Obj) const { | ||||
|  | ||||
|     } | ||||
|  | ||||
|     bool Dashboard::from_json([[maybe_unused]] const Poco::JSON::Object::Ptr &Obj) { | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     void Dashboard::reset() { | ||||
|  | ||||
|     } | ||||
| } | ||||
							
								
								
									
										77
									
								
								src/RESTObjects/RESTAPI_OWLSobjects.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								src/RESTObjects/RESTAPI_OWLSobjects.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,77 @@ | ||||
| // | ||||
| // Created by stephane bourque on 2021-08-31. | ||||
| // | ||||
|  | ||||
| #ifndef UCENTRALSIM_RESTAPI_OWLSOBJECTS_H | ||||
| #define UCENTRALSIM_RESTAPI_OWLSOBJECTS_H | ||||
|  | ||||
| #include <vector> | ||||
| #include "Poco/JSON/Object.h" | ||||
|  | ||||
| namespace OpenWifi::OWLSObjects { | ||||
|  | ||||
|     struct SimulationDetails { | ||||
|         std::string     id; | ||||
|         std::string     name; | ||||
|         std::string     gateway; | ||||
|         std::string     certificate; | ||||
|         std::string     key; | ||||
|         std::string     macPrefix; | ||||
|         std::string     deviceType; | ||||
|         uint64_t        devices = 5; | ||||
|         uint64_t        healthCheckInterval = 60; | ||||
|         uint64_t        stateInterval = 60 ; | ||||
|         uint64_t        minAssociations = 1; | ||||
|         uint64_t        maxAssociations = 3; | ||||
|         uint64_t        minClients = 1 ; | ||||
|         uint64_t        maxClients = 3; | ||||
|         uint64_t        simulationLength = 60 * 60; | ||||
|         uint64_t        threads = 16; | ||||
|         uint64_t        clientInterval = 1; | ||||
|         uint64_t        keepAlive = 300; | ||||
|         uint64_t        reconnectInterval = 30 ; | ||||
|         uint64_t        concurrentDevices = 5; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     struct SimulationDetailsList { | ||||
|         std::vector<SimulationDetails>  list; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     struct SimulationStatus { | ||||
|         std::string     id; | ||||
|         std::string     simulationId; | ||||
|         std::string     state; | ||||
|         uint64_t        tx; | ||||
|         uint64_t        rx; | ||||
|         uint64_t        msgsTx; | ||||
|         uint64_t        msgsRx; | ||||
|         uint64_t        liveDevices; | ||||
|         uint64_t        timeToFullDevices; | ||||
|         uint64_t        startTime; | ||||
|         uint64_t        endTime; | ||||
|         uint64_t        errorDevices; | ||||
|         std::string     owner; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|     }; | ||||
|  | ||||
|  | ||||
|     struct Dashboard { | ||||
|         int O; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         void reset(); | ||||
|  | ||||
|     }; | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| #endif //UCENTRALSIM_RESTAPI_OWLSOBJECTS_H | ||||
| @@ -8,7 +8,9 @@ | ||||
|  | ||||
|  | ||||
| #include "RESTAPI_ProvObjects.h" | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_utils.h" | ||||
| #include "framework/MicroServiceFuncs.h" | ||||
| #include "framework/utils.h" | ||||
|  | ||||
| using OpenWifi::RESTAPI_utils::field_to_json; | ||||
| using OpenWifi::RESTAPI_utils::field_from_json; | ||||
| @@ -91,8 +93,13 @@ namespace OpenWifi::ProvObjects { | ||||
|         field_to_json( Obj,"managementPolicy",managementPolicy); | ||||
|         field_to_json( Obj,"deviceConfiguration",deviceConfiguration); | ||||
|         field_to_json( Obj,"devices",devices); | ||||
|         field_to_json( Obj,"rrm",rrm); | ||||
|         field_to_json( Obj,"deviceRules",deviceRules); | ||||
|         field_to_json( Obj,"sourceIP",sourceIP); | ||||
|         field_to_json( Obj,"variables", variables); | ||||
|         field_to_json( Obj,"managementPolicies", managementPolicies); | ||||
|         field_to_json( Obj,"managementRoles", managementRoles); | ||||
|         field_to_json( Obj,"maps", maps); | ||||
|         field_to_json( Obj,"configurations", configurations); | ||||
|     } | ||||
|  | ||||
|     bool Entity::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| @@ -106,8 +113,13 @@ namespace OpenWifi::ProvObjects { | ||||
|             field_from_json( Obj,"managementPolicy",managementPolicy); | ||||
|             field_from_json( Obj,"deviceConfiguration",deviceConfiguration); | ||||
|             field_from_json( Obj,"devices",devices); | ||||
|             field_from_json( Obj,"rrm",rrm); | ||||
|             field_from_json( Obj,"deviceRules",deviceRules); | ||||
|             field_from_json( Obj,"sourceIP",sourceIP); | ||||
|             field_from_json( Obj,"variables", variables); | ||||
|             field_from_json( Obj,"managementPolicies", managementPolicies); | ||||
|             field_from_json( Obj,"managementRoles", managementRoles); | ||||
|             field_from_json( Obj,"maps", maps); | ||||
|             field_from_json( Obj,"configurations", configurations); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
| @@ -142,10 +154,16 @@ namespace OpenWifi::ProvObjects { | ||||
|         field_to_json( Obj,"design",design); | ||||
|         field_to_json( Obj,"managementPolicy",managementPolicy); | ||||
|         field_to_json( Obj,"deviceConfiguration",deviceConfiguration); | ||||
|         field_to_json( Obj,"contact",contact); | ||||
|         field_to_json( Obj,"contacts",contacts); | ||||
|         field_to_json( Obj,"location",location); | ||||
|         field_to_json( Obj,"rrm",rrm); | ||||
|         field_to_json( Obj,"deviceRules",deviceRules); | ||||
|         field_to_json( Obj,"sourceIP",sourceIP); | ||||
|         field_to_json( Obj,"variables", variables); | ||||
|         field_to_json( Obj,"managementPolicies", managementPolicies); | ||||
|         field_to_json( Obj,"managementRoles", managementRoles); | ||||
|         field_to_json( Obj,"maps", maps); | ||||
|         field_to_json( Obj,"configurations", configurations); | ||||
|         field_to_json( Obj,"boards", boards); | ||||
|     } | ||||
|  | ||||
|     bool Venue::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| @@ -160,10 +178,16 @@ namespace OpenWifi::ProvObjects { | ||||
|             field_from_json( Obj,"design",design); | ||||
|             field_from_json( Obj,"managementPolicy",managementPolicy); | ||||
|             field_from_json( Obj,"deviceConfiguration",deviceConfiguration); | ||||
|             field_from_json( Obj,"contact",contact); | ||||
|             field_from_json( Obj,"contacts",contacts); | ||||
|             field_from_json( Obj,"location",location); | ||||
|             field_from_json( Obj,"rrm",rrm); | ||||
|             field_from_json( Obj,"deviceRules",deviceRules); | ||||
|             field_from_json( Obj,"sourceIP",sourceIP); | ||||
|             field_from_json( Obj,"variables", variables); | ||||
|             field_from_json( Obj,"managementPolicies", managementPolicies); | ||||
|             field_from_json( Obj,"managementRoles", managementRoles); | ||||
|             field_from_json( Obj,"maps", maps); | ||||
|             field_from_json( Obj,"configurations", configurations); | ||||
|             field_from_json( Obj,"boards", boards); | ||||
|             return true; | ||||
|         } catch (...) { | ||||
|  | ||||
| @@ -171,6 +195,89 @@ namespace OpenWifi::ProvObjects { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void Operator::to_json(Poco::JSON::Object &Obj) const { | ||||
|         info.to_json(Obj); | ||||
|         field_to_json( Obj,"managementPolicy",managementPolicy); | ||||
|         field_to_json( Obj,"managementRoles",managementRoles); | ||||
|         field_to_json( Obj,"deviceRules",deviceRules); | ||||
|         field_to_json( Obj,"variables",variables); | ||||
|         field_to_json( Obj,"defaultOperator",defaultOperator); | ||||
|         field_to_json( Obj,"sourceIP",sourceIP); | ||||
|         field_to_json( Obj,"registrationId",registrationId); | ||||
|     } | ||||
|  | ||||
|     bool Operator::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             info.from_json(Obj); | ||||
|             field_from_json( Obj,"managementPolicy",managementPolicy); | ||||
|             field_from_json( Obj,"managementRoles",managementRoles); | ||||
|             field_from_json( Obj,"deviceRules",deviceRules); | ||||
|             field_from_json( Obj,"variables",variables); | ||||
|             field_from_json( Obj,"defaultOperator",defaultOperator); | ||||
|             field_from_json( Obj,"sourceIP",sourceIP); | ||||
|             field_from_json( Obj,"registrationId",registrationId); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void OperatorList::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json( Obj,"operators",operators); | ||||
|     } | ||||
|  | ||||
|     bool OperatorList::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json( Obj,"operators",operators); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void ServiceClass::to_json(Poco::JSON::Object &Obj) const { | ||||
|         info.to_json(Obj); | ||||
|         field_to_json( Obj,"operatorId",operatorId); | ||||
|         field_to_json( Obj,"managementPolicy",managementPolicy); | ||||
|         field_to_json( Obj,"cost",cost); | ||||
|         field_to_json( Obj,"currency",currency); | ||||
|         field_to_json( Obj,"period",period); | ||||
|         field_to_json( Obj,"billingCode",billingCode); | ||||
|         field_to_json( Obj,"variables",variables); | ||||
|         field_to_json( Obj,"defaultService",defaultService); | ||||
|     } | ||||
|  | ||||
|     bool ServiceClass::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             info.from_json(Obj); | ||||
|             field_from_json( Obj,"operatorId",operatorId); | ||||
|             field_from_json( Obj,"managementPolicy",managementPolicy); | ||||
|             field_from_json( Obj,"cost",cost); | ||||
|             field_from_json( Obj,"currency",currency); | ||||
|             field_from_json( Obj,"period",period); | ||||
|             field_from_json( Obj,"billingCode",billingCode); | ||||
|             field_from_json( Obj,"variables",variables); | ||||
|             field_from_json( Obj,"defaultService",defaultService); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|         } | ||||
|         return false; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     void ServiceClassList::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json( Obj,"serviceClasses",serviceClasses); | ||||
|     } | ||||
|  | ||||
|     bool ServiceClassList::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json( Obj,"serviceClasses",serviceClasses); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void UserInfoDigest::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json( Obj,"id",id); | ||||
|         field_to_json( Obj,"entity",loginId); | ||||
| @@ -193,6 +300,7 @@ namespace OpenWifi::ProvObjects { | ||||
|         field_to_json( Obj,"managementPolicy",managementPolicy); | ||||
|         field_to_json( Obj,"users",users); | ||||
|         field_to_json( Obj,"entity",entity); | ||||
|         field_to_json( Obj,"venue",venue); | ||||
|     } | ||||
|  | ||||
|     bool ManagementRole::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| @@ -201,6 +309,7 @@ namespace OpenWifi::ProvObjects { | ||||
|             field_from_json( Obj,"managementPolicy",managementPolicy); | ||||
|             field_from_json( Obj,"users",users); | ||||
|             field_from_json( Obj,"entity",entity); | ||||
|             field_from_json( Obj,"venue",venue); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|         } | ||||
| @@ -249,6 +358,92 @@ namespace OpenWifi::ProvObjects { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void OperatorLocation::to_json(Poco::JSON::Object &Obj) const { | ||||
|         info.to_json(Obj); | ||||
|         field_to_json( Obj,"type",type); | ||||
|         field_to_json( Obj,"buildingName",buildingName); | ||||
|         field_to_json( Obj,"addressLines",addressLines); | ||||
|         field_to_json( Obj,"city",city); | ||||
|         field_to_json( Obj,"state",state); | ||||
|         field_to_json( Obj,"postal",postal); | ||||
|         field_to_json( Obj,"country",country); | ||||
|         field_to_json( Obj,"phones",phones); | ||||
|         field_to_json( Obj,"mobiles",mobiles); | ||||
|         field_to_json( Obj,"geoCode",geoCode); | ||||
|         field_to_json( Obj,"operatorId",operatorId); | ||||
|         field_to_json( Obj,"subscriberDeviceId",subscriberDeviceId); | ||||
|         field_to_json( Obj,"managementPolicy",managementPolicy); | ||||
|     } | ||||
|  | ||||
|     bool OperatorLocation::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             info.from_json(Obj); | ||||
|             field_from_json( Obj,"type", type); | ||||
|             field_from_json( Obj,"buildingName",buildingName); | ||||
|             field_from_json( Obj,"addressLines",addressLines); | ||||
|             field_from_json( Obj,"city",city); | ||||
|             field_from_json( Obj,"state",state); | ||||
|             field_from_json( Obj,"postal",postal); | ||||
|             field_from_json( Obj,"country",country); | ||||
|             field_from_json( Obj,"phones",phones); | ||||
|             field_from_json( Obj,"mobiles",mobiles); | ||||
|             field_from_json( Obj,"geoCode",geoCode); | ||||
|             field_from_json( Obj,"operatorId",operatorId); | ||||
|             field_from_json( Obj,"subscriberDeviceId",subscriberDeviceId); | ||||
|             field_from_json( Obj,"managementPolicy",managementPolicy); | ||||
|             return true; | ||||
|         } catch (...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void SubLocation::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json( Obj,"type",type); | ||||
|         field_to_json( Obj,"buildingName",buildingName); | ||||
|         field_to_json( Obj,"addressLines",addressLines); | ||||
|         field_to_json( Obj,"city",city); | ||||
|         field_to_json( Obj,"state",state); | ||||
|         field_to_json( Obj,"postal",postal); | ||||
|         field_to_json( Obj,"country",country); | ||||
|         field_to_json( Obj,"phones",phones); | ||||
|         field_to_json( Obj,"mobiles",mobiles); | ||||
|         field_to_json( Obj,"geoCode",geoCode); | ||||
|     } | ||||
|  | ||||
|     bool SubLocation::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json( Obj,"type", type); | ||||
|             field_from_json( Obj,"buildingName",buildingName); | ||||
|             field_from_json( Obj,"addressLines",addressLines); | ||||
|             field_from_json( Obj,"city",city); | ||||
|             field_from_json( Obj,"state",state); | ||||
|             field_from_json( Obj,"postal",postal); | ||||
|             field_from_json( Obj,"country",country); | ||||
|             field_from_json( Obj,"phones",phones); | ||||
|             field_from_json( Obj,"mobiles",mobiles); | ||||
|             field_from_json( Obj,"geoCode",geoCode); | ||||
|             return true; | ||||
|         } catch (...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void OperatorLocationList::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json( Obj, "locations", locations); | ||||
|     } | ||||
|  | ||||
|     bool OperatorLocationList::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json( Obj, "locations", locations); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void Contact::to_json(Poco::JSON::Object &Obj) const { | ||||
|         info.to_json(Obj); | ||||
|         field_to_json( Obj,"type", to_string(type)); | ||||
| @@ -295,21 +490,119 @@ namespace OpenWifi::ProvObjects { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void OperatorContact::to_json(Poco::JSON::Object &Obj) const { | ||||
|         info.to_json(Obj); | ||||
|         field_to_json( Obj,"type", type); | ||||
|         field_to_json( Obj,"title",title); | ||||
|         field_to_json( Obj,"salutation",salutation); | ||||
|         field_to_json( Obj,"firstname",firstname); | ||||
|         field_to_json( Obj,"lastname",lastname); | ||||
|         field_to_json( Obj,"initials",initials); | ||||
|         field_to_json( Obj,"visual",visual); | ||||
|         field_to_json( Obj,"mobiles",mobiles); | ||||
|         field_to_json( Obj,"phones",phones); | ||||
|         field_to_json( Obj,"primaryEmail",primaryEmail); | ||||
|         field_to_json( Obj,"secondaryEmail",secondaryEmail); | ||||
|         field_to_json( Obj,"accessPIN",accessPIN); | ||||
|         field_to_json( Obj,"operatorId",operatorId); | ||||
|         field_to_json( Obj,"subscriberDeviceId",subscriberDeviceId); | ||||
|         field_to_json( Obj,"managementPolicy",managementPolicy); | ||||
|     } | ||||
|  | ||||
|     bool OperatorContact::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             info.from_json(Obj); | ||||
|             field_from_json( Obj,"type", type); | ||||
|             field_from_json( Obj,"title",title); | ||||
|             field_from_json( Obj,"salutation",salutation); | ||||
|             field_from_json( Obj,"firstname",firstname); | ||||
|             field_from_json( Obj,"lastname",lastname); | ||||
|             field_from_json( Obj,"initials",initials); | ||||
|             field_from_json( Obj,"visual",visual); | ||||
|             field_from_json( Obj,"mobiles",mobiles); | ||||
|             field_from_json( Obj,"phones",phones); | ||||
|             field_from_json( Obj,"primaryEmail",primaryEmail); | ||||
|             field_from_json( Obj,"secondaryEmail",secondaryEmail); | ||||
|             field_from_json( Obj,"accessPIN",accessPIN); | ||||
|             field_from_json( Obj,"operatorId",operatorId); | ||||
|             field_from_json( Obj,"subscriberDeviceId",subscriberDeviceId); | ||||
|             field_from_json( Obj,"managementPolicy",managementPolicy); | ||||
|             return true; | ||||
|         } catch (...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void SubContact::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json( Obj,"type", type); | ||||
|         field_to_json( Obj,"title",title); | ||||
|         field_to_json( Obj,"salutation",salutation); | ||||
|         field_to_json( Obj,"firstname",firstname); | ||||
|         field_to_json( Obj,"lastname",lastname); | ||||
|         field_to_json( Obj,"initials",initials); | ||||
|         field_to_json( Obj,"visual",visual); | ||||
|         field_to_json( Obj,"mobiles",mobiles); | ||||
|         field_to_json( Obj,"phones",phones); | ||||
|         field_to_json( Obj,"primaryEmail",primaryEmail); | ||||
|         field_to_json( Obj,"secondaryEmail",secondaryEmail); | ||||
|         field_to_json( Obj,"accessPIN",accessPIN); | ||||
|     } | ||||
|  | ||||
|     bool SubContact::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json( Obj,"type", type); | ||||
|             field_from_json( Obj,"title",title); | ||||
|             field_from_json( Obj,"salutation",salutation); | ||||
|             field_from_json( Obj,"firstname",firstname); | ||||
|             field_from_json( Obj,"lastname",lastname); | ||||
|             field_from_json( Obj,"initials",initials); | ||||
|             field_from_json( Obj,"visual",visual); | ||||
|             field_from_json( Obj,"mobiles",mobiles); | ||||
|             field_from_json( Obj,"phones",phones); | ||||
|             field_from_json( Obj,"primaryEmail",primaryEmail); | ||||
|             field_from_json( Obj,"secondaryEmail",secondaryEmail); | ||||
|             field_from_json( Obj,"accessPIN",accessPIN); | ||||
|             return true; | ||||
|         } catch (...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void OperatorContactList::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json( Obj, "contacts", contacts); | ||||
|     } | ||||
|  | ||||
|     bool OperatorContactList::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json( Obj, "contacts", contacts); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void InventoryTag::to_json(Poco::JSON::Object &Obj) const { | ||||
|         info.to_json(Obj); | ||||
|         field_to_json(Obj, "serialNumber", serialNumber); | ||||
|         field_to_json(Obj, "venue", venue); | ||||
|         field_to_json(Obj, "entity", entity); | ||||
|         field_to_json(Obj, "subscriber", subscriber); | ||||
|         field_to_json(Obj, "deviceType", deviceType); | ||||
|         field_to_json(Obj, "qrCode", qrCode); | ||||
|         field_to_json(Obj, "geoCode", geoCode); | ||||
|         field_to_json(Obj, "location", location); | ||||
|         field_to_json(Obj, "contact", contact); | ||||
|         field_to_json( Obj,"deviceConfiguration",deviceConfiguration); | ||||
|         field_to_json( Obj,"rrm",rrm); | ||||
|         field_to_json( Obj,"managementPolicy",managementPolicy); | ||||
|         field_to_json( Obj,"state",state); | ||||
|         field_to_json( Obj, "serialNumber", serialNumber); | ||||
|         field_to_json( Obj, "venue", venue); | ||||
|         field_to_json( Obj, "entity", entity); | ||||
|         field_to_json( Obj, "subscriber", subscriber); | ||||
|         field_to_json( Obj, "deviceType", deviceType); | ||||
|         field_to_json( Obj, "qrCode", qrCode); | ||||
|         field_to_json( Obj, "geoCode", geoCode); | ||||
|         field_to_json( Obj, "location", location); | ||||
|         field_to_json( Obj, "contact", contact); | ||||
|         field_to_json( Obj, "deviceConfiguration",deviceConfiguration); | ||||
|         field_to_json( Obj,"deviceRules",deviceRules); | ||||
|         field_to_json( Obj, "managementPolicy",managementPolicy); | ||||
|         field_to_json( Obj, "state",state); | ||||
|         field_to_json( Obj, "devClass",devClass); | ||||
|         field_to_json( Obj, "locale",locale); | ||||
|         field_to_json( Obj, "realMacAddress",realMacAddress); | ||||
|         field_to_json( Obj, "doNotAllowOverrides",doNotAllowOverrides); | ||||
|     } | ||||
|  | ||||
|     bool InventoryTag::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| @@ -320,14 +613,18 @@ namespace OpenWifi::ProvObjects { | ||||
|             field_from_json( Obj,"entity",entity); | ||||
|             field_from_json( Obj,"subscriber",subscriber); | ||||
|             field_from_json( Obj,"deviceType",deviceType); | ||||
|             field_from_json(Obj, "qrCode", qrCode); | ||||
|             field_from_json( Obj,"qrCode", qrCode); | ||||
|             field_from_json( Obj,"geoCode",geoCode); | ||||
|             field_from_json( Obj,"location",location); | ||||
|             field_from_json( Obj,"contact",contact); | ||||
|             field_from_json( Obj,"deviceConfiguration",deviceConfiguration); | ||||
|             field_from_json( Obj,"rrm",rrm); | ||||
|             field_from_json( Obj,"deviceRules",deviceRules); | ||||
|             field_from_json( Obj,"managementPolicy",managementPolicy); | ||||
|             field_from_json( Obj,"state",state); | ||||
|             field_from_json( Obj,"devClass",devClass); | ||||
|             field_from_json( Obj,"locale",locale); | ||||
|             field_from_json( Obj,"realMacAddress",realMacAddress); | ||||
|             field_from_json( Obj, "doNotAllowOverrides",doNotAllowOverrides); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
| @@ -335,6 +632,26 @@ namespace OpenWifi::ProvObjects { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void InventoryConfigApplyResult::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json( Obj, "appliedConfiguration", appliedConfiguration); | ||||
|         field_to_json( Obj, "warnings", warnings); | ||||
|         field_to_json( Obj, "errors", errors); | ||||
|         field_to_json( Obj, "errorCode", errorCode); | ||||
|     } | ||||
|  | ||||
|     bool InventoryConfigApplyResult::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json( Obj, "appliedConfiguration", appliedConfiguration); | ||||
|             field_from_json( Obj, "warnings", warnings); | ||||
|             field_from_json( Obj, "errors", errors); | ||||
|             field_from_json( Obj, "errorCode", errorCode); | ||||
|             return true; | ||||
|         } catch (...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void InventoryTagList::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json( Obj,"taglist",taglist); | ||||
|     } | ||||
| @@ -342,7 +659,7 @@ namespace OpenWifi::ProvObjects { | ||||
|     bool InventoryTagList::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json( Obj,"taglist",taglist); | ||||
|             return false; | ||||
|             return true; | ||||
|         } catch (...) { | ||||
|  | ||||
|         } | ||||
| @@ -373,12 +690,14 @@ namespace OpenWifi::ProvObjects { | ||||
|         info.to_json(Obj); | ||||
|         field_to_json( Obj,"managementPolicy",managementPolicy); | ||||
|         field_to_json( Obj,"deviceTypes",deviceTypes); | ||||
|         field_to_json( Obj,"subscriberOnly",subscriberOnly); | ||||
|         field_to_json( Obj,"entity", entity); | ||||
|         field_to_json( Obj,"venue", venue); | ||||
|         field_to_json( Obj,"subscriber", subscriber); | ||||
|         field_to_json( Obj,"configuration",configuration); | ||||
|         field_to_json( Obj,"inUse",inUse); | ||||
|         field_to_json( Obj,"variables",variables); | ||||
|         field_to_json( Obj,"rrm",rrm); | ||||
|         field_to_json( Obj,"firmwareUpgrade",firmwareUpgrade); | ||||
|         field_to_json( Obj,"firmwareRCOnly",firmwareRCOnly); | ||||
|         field_to_json( Obj,"deviceRules",deviceRules); | ||||
|     } | ||||
|  | ||||
|     bool DeviceConfiguration::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| @@ -386,12 +705,14 @@ namespace OpenWifi::ProvObjects { | ||||
|             info.from_json(Obj); | ||||
|             field_from_json( Obj,"managementPolicy",managementPolicy); | ||||
|             field_from_json( Obj,"deviceTypes",deviceTypes); | ||||
|             field_from_json( Obj,"configuration",configuration); | ||||
|             field_from_json( Obj,"inUse",inUse); | ||||
|             field_from_json( Obj,"variables",variables); | ||||
|             field_from_json( Obj,"rrm",rrm); | ||||
|             field_from_json( Obj,"firmwareUpgrade",firmwareUpgrade); | ||||
|             field_from_json( Obj,"firmwareRCOnly",firmwareRCOnly); | ||||
|             field_from_json( Obj,"subscriberOnly",subscriberOnly); | ||||
|             field_from_json( Obj,"entity", entity); | ||||
|             field_from_json( Obj,"venue", venue); | ||||
|             field_from_json( Obj,"subscriber", subscriber); | ||||
|             field_from_json( Obj,"configuration",configuration); | ||||
|             field_from_json( Obj,"deviceRules",deviceRules); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
| @@ -470,46 +791,16 @@ namespace OpenWifi::ProvObjects { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void field_to_json(Poco::JSON::Object &Obj, const char * FieldName, ACLACCESS A) { | ||||
|         switch(A) { | ||||
|             case READ: Obj.set(FieldName,"read"); break; | ||||
|             case MODIFY: Obj.set(FieldName,"modify"); break; | ||||
|             case CREATE: Obj.set(FieldName,"create"); break; | ||||
|             case DELETE: Obj.set(FieldName,"delete"); break; | ||||
|             case NONE: | ||||
|                 default: | ||||
|                     Obj.set(FieldName,"none"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char * FieldName, ACLACCESS &A) { | ||||
|         if(Obj->has(FieldName)) { | ||||
|             auto V = Obj->getValue<std::string>(FieldName); | ||||
|             if(V=="read") | ||||
|                 A = READ; | ||||
|             else if(V=="modify") | ||||
|                 A = MODIFY; | ||||
|             else if(V=="create") | ||||
|                 A = CREATE; | ||||
|             else if(V=="delete") | ||||
|                 A = DELETE; | ||||
|             else if(V=="none") | ||||
|                 A = NONE; | ||||
|             else | ||||
|                 throw Poco::Exception("invalid JSON"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void ObjectACL::to_json(Poco::JSON::Object &Obj) const { | ||||
|         RESTAPI_utils::field_to_json(Obj, "users", users); | ||||
|         RESTAPI_utils::field_to_json(Obj, "roles", roles); | ||||
|         field_to_json(Obj, "users", users); | ||||
|         field_to_json(Obj, "roles", roles); | ||||
|         field_to_json(Obj, "access", access); | ||||
|     } | ||||
|  | ||||
|     bool ObjectACL::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             RESTAPI_utils::field_from_json(Obj, "users", users); | ||||
|             RESTAPI_utils::field_from_json(Obj, "roles", roles); | ||||
|             field_from_json(Obj, "users", users); | ||||
|             field_from_json(Obj, "roles", roles); | ||||
|             field_from_json(Obj, "access", access); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
| @@ -519,12 +810,12 @@ namespace OpenWifi::ProvObjects { | ||||
|     } | ||||
|      | ||||
|     void ObjectACLList::to_json(Poco::JSON::Object &Obj) const { | ||||
|         RESTAPI_utils::field_to_json(Obj, "list", list); | ||||
|         field_to_json(Obj, "list", list); | ||||
|     } | ||||
|  | ||||
|     bool ObjectACLList::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             RESTAPI_utils::field_from_json(Obj, "list", list); | ||||
|             field_from_json(Obj, "list", list); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
| @@ -532,44 +823,15 @@ namespace OpenWifi::ProvObjects { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     std::string to_string(VISIBILITY A) { | ||||
|         switch(A) { | ||||
|             case PUBLIC: return "public"; | ||||
|             case SELECT: return "select"; | ||||
|             case PRIVATE: | ||||
|             default: | ||||
|                 return "private"; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void field_to_json(Poco::JSON::Object &Obj, const char * FieldName, VISIBILITY A) { | ||||
|         Obj.set(FieldName,to_string(A)); | ||||
|     } | ||||
|  | ||||
|     VISIBILITY visibility_from_string(const std::string &V) { | ||||
|         if(V=="public") | ||||
|             return PUBLIC; | ||||
|         else if(V=="select") | ||||
|             return SELECT; | ||||
|         else if(V=="private") | ||||
|             return PRIVATE; | ||||
|         throw Poco::Exception("invalid json"); | ||||
|     } | ||||
|  | ||||
|     void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char * FieldName, VISIBILITY &A) { | ||||
|         if(Obj->has(FieldName)) { | ||||
|             auto V = Obj->getValue<std::string>(FieldName); | ||||
|             A = visibility_from_string(V); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void Map::to_json(Poco::JSON::Object &Obj) const { | ||||
|         info.to_json(Obj); | ||||
|         RESTAPI_utils::field_to_json( Obj,"data",data); | ||||
|         RESTAPI_utils::field_to_json( Obj,"entity",entity); | ||||
|         RESTAPI_utils::field_to_json( Obj,"creator",creator); | ||||
|         field_to_json( Obj,"data",data); | ||||
|         field_to_json( Obj,"entity",entity); | ||||
|         field_to_json( Obj,"creator",creator); | ||||
|         field_to_json( Obj,"visibility",visibility); | ||||
|         RESTAPI_utils::field_to_json( Obj,"access",access); | ||||
|         field_to_json( Obj,"access",access); | ||||
|         field_to_json( Obj,"managementPolicy", managementPolicy); | ||||
|         field_to_json( Obj,"venue", venue); | ||||
|     } | ||||
|  | ||||
|     bool Map::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| @@ -578,8 +840,24 @@ namespace OpenWifi::ProvObjects { | ||||
|             RESTAPI_utils::field_from_json( Obj,"data",data); | ||||
|             RESTAPI_utils::field_from_json( Obj,"entity",entity); | ||||
|             RESTAPI_utils::field_from_json( Obj,"creator",creator); | ||||
|             field_from_json( Obj,"visibility",visibility); | ||||
|             RESTAPI_utils::field_from_json( Obj,"visibility",visibility); | ||||
|             RESTAPI_utils::field_from_json( Obj,"access",access); | ||||
|             RESTAPI_utils::field_from_json( Obj,"managementPolicy", managementPolicy); | ||||
|             RESTAPI_utils::field_from_json( Obj,"venue", venue); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void SerialNumberList::to_json(Poco::JSON::Object &Obj) const { | ||||
|         RESTAPI_utils::field_to_json( Obj,"serialNumbers",serialNumbers); | ||||
|     } | ||||
|  | ||||
|     bool SerialNumberList::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             RESTAPI_utils::field_from_json( Obj,"serialNumbers",serialNumbers); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
| @@ -601,8 +879,223 @@ namespace OpenWifi::ProvObjects { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void SignupEntry::to_json(Poco::JSON::Object &Obj) const { | ||||
|         info.to_json(Obj); | ||||
|         field_to_json( Obj,"email", email); | ||||
|         field_to_json( Obj,"userId", userId); | ||||
|         field_to_json( Obj,"macAddress", macAddress); | ||||
|         field_to_json( Obj,"serialNumber", serialNumber); | ||||
|         field_to_json( Obj,"submitted", submitted); | ||||
|         field_to_json( Obj,"completed", completed); | ||||
|         field_to_json( Obj,"status", status); | ||||
|         field_to_json( Obj,"error", error); | ||||
|         field_to_json( Obj,"statusCode", statusCode); | ||||
|         field_to_json( Obj,"deviceID", deviceID); | ||||
|         field_to_json( Obj,"registrationId",registrationId); | ||||
|         field_to_json( Obj,"operatorId",operatorId); | ||||
|     } | ||||
|  | ||||
|     bool SignupEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             info.from_json(Obj); | ||||
|             field_from_json( Obj,"email", email); | ||||
|             field_from_json( Obj,"userId", userId); | ||||
|             field_from_json( Obj,"macAddress", macAddress); | ||||
|             field_from_json( Obj,"serialNumber", serialNumber); | ||||
|             field_from_json( Obj,"submitted", submitted); | ||||
|             field_from_json( Obj,"completed", completed); | ||||
|             field_from_json( Obj,"status", status); | ||||
|             field_from_json( Obj,"error", error); | ||||
|             field_from_json( Obj,"statusCode", statusCode); | ||||
|             field_from_json( Obj,"deviceID", deviceID); | ||||
|             field_from_json( Obj,"registrationId",registrationId); | ||||
|             field_from_json( Obj,"operatorId",operatorId); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void Variable::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json( Obj,"type", type); | ||||
|         field_to_json( Obj,"weight", weight); | ||||
|         field_to_json( Obj,"prefix", prefix); | ||||
|         field_to_json( Obj,"value", value); | ||||
|     } | ||||
|  | ||||
|     bool Variable::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json( Obj,"type", type); | ||||
|             field_from_json( Obj,"weight", weight); | ||||
|             field_from_json( Obj,"prefix", prefix); | ||||
|             field_from_json( Obj,"value", value); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void VariableList::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json( Obj,"variables", variables); | ||||
|     } | ||||
|  | ||||
|     bool VariableList::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json( Obj,"variables", variables); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void VariableBlock::to_json(Poco::JSON::Object &Obj) const { | ||||
|         info.to_json(Obj); | ||||
|         field_to_json( Obj,"variables", variables); | ||||
|         field_to_json( Obj,"entity", entity); | ||||
|         field_to_json( Obj,"venue", venue); | ||||
|         field_to_json( Obj,"subscriber", subscriber); | ||||
|         field_to_json( Obj,"inventory", inventory); | ||||
|         field_to_json( Obj,"configurations", configurations); | ||||
|         field_to_json( Obj,"managementPolicy", managementPolicy); | ||||
|     } | ||||
|  | ||||
|     bool VariableBlock::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             info.from_json(Obj); | ||||
|             field_from_json( Obj,"variables", variables); | ||||
|             field_from_json( Obj,"entity", entity); | ||||
|             field_from_json( Obj,"venue", venue); | ||||
|             field_from_json( Obj,"subscriber", subscriber); | ||||
|             field_from_json( Obj,"inventory", inventory); | ||||
|             field_from_json( Obj,"configurations", configurations); | ||||
|             field_from_json( Obj,"managementPolicy", managementPolicy); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void VariableBlockList::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json( Obj,"variableBlocks", variableBlocks); | ||||
|     } | ||||
|  | ||||
|     bool VariableBlockList::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json( Obj,"variableBlocks", variableBlocks); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void ConfigurationDetails::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json( Obj,"configuration", configuration); | ||||
|         field_to_json( Obj,"rrm", rrm); | ||||
|         field_to_json( Obj,"firmwareRCOnly", firmwareRCOnly); | ||||
|         field_to_json( Obj,"firmwareUpgrade", firmwareUpgrade); | ||||
|     } | ||||
|  | ||||
|     bool ConfigurationDetails::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json( Obj,"configuration", configuration); | ||||
|             field_from_json( Obj,"rrm", rrm); | ||||
|             field_from_json( Obj,"firmwareRCOnly", firmwareRCOnly); | ||||
|             field_from_json( Obj,"firmwareUpgrade", firmwareUpgrade); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void SubscriberDevice::to_json(Poco::JSON::Object &Obj) const { | ||||
|         info.to_json(Obj); | ||||
|         field_to_json( Obj,"serialNumber", serialNumber); | ||||
|         field_to_json( Obj,"deviceType", deviceType); | ||||
|         field_to_json( Obj,"operatorId", operatorId); | ||||
|         field_to_json( Obj,"subscriberId", subscriberId); | ||||
|         field_to_json( Obj,"location", location); | ||||
|         field_to_json( Obj,"contact", contact); | ||||
|         field_to_json( Obj,"managementPolicy", managementPolicy); | ||||
|         field_to_json( Obj,"serviceClass", serviceClass); | ||||
|         field_to_json( Obj,"qrCode", qrCode); | ||||
|         field_to_json( Obj,"geoCode", geoCode); | ||||
|         field_to_json( Obj,"deviceRules",deviceRules); | ||||
|         field_to_json( Obj,"state", state); | ||||
|         field_to_json( Obj,"locale", locale); | ||||
|         field_to_json( Obj,"billingCode", billingCode); | ||||
|         field_to_json( Obj,"configuration", configuration); | ||||
|         field_to_json( Obj,"suspended", suspended); | ||||
|         field_to_json( Obj,"realMacAddress", realMacAddress); | ||||
|     } | ||||
|  | ||||
|     bool SubscriberDevice::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             info.from_json(Obj); | ||||
|             field_from_json( Obj,"serialNumber", serialNumber); | ||||
|             field_from_json( Obj,"deviceType", deviceType); | ||||
|             field_from_json( Obj,"operatorId", operatorId); | ||||
|             field_from_json( Obj,"subscriberId", subscriberId); | ||||
|             field_from_json( Obj,"location", location); | ||||
|             field_from_json( Obj,"contact", contact); | ||||
|             field_from_json( Obj,"managementPolicy", managementPolicy); | ||||
|             field_from_json( Obj,"serviceClass", serviceClass); | ||||
|             field_from_json( Obj,"qrCode", qrCode); | ||||
|             field_from_json( Obj,"geoCode", geoCode); | ||||
|             field_from_json( Obj,"deviceRules",deviceRules); | ||||
|             field_from_json( Obj,"state", state); | ||||
|             field_from_json( Obj,"locale", locale); | ||||
|             field_from_json( Obj,"billingCode", billingCode); | ||||
|             field_from_json( Obj,"configuration", configuration); | ||||
|             field_from_json( Obj,"suspended", suspended); | ||||
|             field_from_json( Obj,"realMacAddress", realMacAddress); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void SubscriberDeviceList::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json( Obj,"subscriberDevices", subscriberDevices); | ||||
|     } | ||||
|  | ||||
|     bool SubscriberDeviceList::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json( Obj,"subscriberDevices", subscriberDevices); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void VenueDeviceList::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj,"id",id); | ||||
|         field_to_json(Obj,"name",name); | ||||
|         field_to_json(Obj,"description",description); | ||||
|         field_to_json(Obj,"devices",devices); | ||||
|     } | ||||
|  | ||||
|     bool VenueDeviceList::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj,"id",id); | ||||
|             field_from_json(Obj,"name",name); | ||||
|             field_from_json(Obj,"description",description); | ||||
|             field_from_json(Obj,"devices",devices); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     bool UpdateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I) { | ||||
|         uint64_t Now = std::time(nullptr); | ||||
|         uint64_t Now = Utils::Now(); | ||||
|         if(O->has("name")) | ||||
|             I.name = O->get("name").toString(); | ||||
|  | ||||
| @@ -623,7 +1116,7 @@ namespace OpenWifi::ProvObjects { | ||||
|     } | ||||
|  | ||||
|     bool CreateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I) { | ||||
|         uint64_t Now = std::time(nullptr); | ||||
|         uint64_t Now = Utils::Now(); | ||||
|         if(O->has("name")) | ||||
|             I.name = O->get("name").toString(); | ||||
|  | ||||
| @@ -641,9 +1134,111 @@ namespace OpenWifi::ProvObjects { | ||||
|         } | ||||
|         I.notes = N; | ||||
|         I.modified = I.created = Now; | ||||
|         I.id = MicroService::CreateUUID(); | ||||
|         I.id = MicroServiceCreateUUID(); | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     bool CreateObjectInfo([[maybe_unused]] const SecurityObjects::UserInfo &U, ObjectInfo &I) { | ||||
|         I.modified = I.created = Utils::Now(); | ||||
|         I.id = MicroServiceCreateUUID(); | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     void DeviceRules::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj,"rcOnly",rcOnly); | ||||
|         field_to_json(Obj,"rrm",rrm); | ||||
|         field_to_json(Obj,"firmwareUpgrade",firmwareUpgrade); | ||||
|     } | ||||
|  | ||||
|     bool DeviceRules::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj,"rcOnly",rcOnly); | ||||
|             field_from_json(Obj,"rrm",rrm); | ||||
|             field_from_json(Obj,"firmwareUpgrade",firmwareUpgrade); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         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; | ||||
|     } | ||||
|  | ||||
|     void ConfigurationOverride::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj,"source",source); | ||||
|         field_to_json(Obj,"reason",reason); | ||||
|         field_to_json(Obj,"parameterName",parameterName); | ||||
|         field_to_json(Obj,"parameterType",parameterType); | ||||
|         field_to_json(Obj,"parameterValue",parameterValue); | ||||
|         field_to_json(Obj,"modified",modified); | ||||
|     } | ||||
|  | ||||
|     bool ConfigurationOverride::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj,"source",source); | ||||
|             field_from_json(Obj,"reason",reason); | ||||
|             field_from_json(Obj,"parameterName",parameterName); | ||||
|             field_from_json(Obj,"parameterType",parameterType); | ||||
|             field_from_json(Obj,"parameterValue",parameterValue); | ||||
|             field_from_json(Obj,"modified",modified); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void ConfigurationOverrideList::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj,"serialNumber",serialNumber); | ||||
|         field_to_json(Obj,"managementPolicy",managementPolicy); | ||||
|         field_to_json(Obj,"overrides",overrides); | ||||
|     } | ||||
|  | ||||
|     bool ConfigurationOverrideList::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj,"serialNumber",serialNumber); | ||||
|             field_from_json(Obj,"managementPolicy",managementPolicy); | ||||
|             field_from_json(Obj,"overrides",overrides); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -8,8 +8,7 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <string> | ||||
| #include "RESTAPI_SecurityObjects.h" | ||||
| #include "RESTObjects/RESTAPI_SecurityObjects.h" | ||||
|  | ||||
| namespace OpenWifi::ProvObjects { | ||||
|  | ||||
| @@ -33,6 +32,13 @@ namespace OpenWifi::ProvObjects { | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     struct SerialNumberList { | ||||
|         Types::UUIDvec_t    serialNumbers; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     struct ManagementPolicyEntry { | ||||
|         Types::UUIDvec_t users; | ||||
|         Types::UUIDvec_t resources; | ||||
| @@ -48,12 +54,37 @@ namespace OpenWifi::ProvObjects { | ||||
|         std::vector<ManagementPolicyEntry>  entries; | ||||
|         Types::StringVec    inUse; | ||||
|         Types::UUID_t       entity; | ||||
|         Types::UUID_t       venue; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|     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 { | ||||
|         std::string     rcOnly{"inherit"}; | ||||
|         std::string     rrm{"inherit"}; | ||||
|         std::string     firmwareUpgrade{"inherit"}; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     struct Entity { | ||||
|         ObjectInfo              info; | ||||
|         Types::UUID_t           parent; | ||||
| @@ -64,8 +95,13 @@ namespace OpenWifi::ProvObjects { | ||||
|         Types::UUID_t           managementPolicy; | ||||
|         Types::UUIDvec_t        deviceConfiguration; | ||||
|         Types::UUIDvec_t        devices; | ||||
|         std::string             rrm; | ||||
|         DeviceRules             deviceRules; | ||||
|         Types::StringVec        sourceIP; | ||||
|         Types::UUIDvec_t        variables; | ||||
|         Types::UUIDvec_t        managementPolicies; | ||||
|         Types::UUIDvec_t        managementRoles; | ||||
|         Types::UUIDvec_t        maps; | ||||
|         Types::UUIDvec_t        configurations; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| @@ -92,10 +128,16 @@ namespace OpenWifi::ProvObjects { | ||||
|         DiGraph             topology; | ||||
|         std::string         design; | ||||
|         Types::UUIDvec_t    deviceConfiguration; | ||||
|         std::string         contact; | ||||
|         Types::UUIDvec_t    contacts; | ||||
|         std::string         location; | ||||
|         std::string         rrm; | ||||
|         DeviceRules         deviceRules; | ||||
|         Types::StringVec    sourceIP; | ||||
|         Types::UUIDvec_t    variables; | ||||
|         Types::UUIDvec_t    configurations; | ||||
|         Types::UUIDvec_t    maps; | ||||
|         Types::UUIDvec_t    managementPolicies; | ||||
|         Types::UUIDvec_t    managementRoles; | ||||
|         Types::UUIDvec_t    boards; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| @@ -117,6 +159,7 @@ namespace OpenWifi::ProvObjects { | ||||
|         Types::UUIDvec_t    users; | ||||
|         Types::StringVec    inUse; | ||||
|         Types::UUID_t       entity; | ||||
|         Types::UUID_t       venue; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| @@ -180,6 +223,51 @@ namespace OpenWifi::ProvObjects { | ||||
|     }; | ||||
|     typedef std::vector<Location>      LocationVec; | ||||
|  | ||||
|     struct OperatorLocation { | ||||
|         ObjectInfo          info; | ||||
|         std::string         type; | ||||
|         std::string         buildingName; | ||||
|         Types::StringVec    addressLines; | ||||
|         std::string         city; | ||||
|         std::string         state; | ||||
|         std::string         postal; | ||||
|         std::string         country; | ||||
|         Types::StringVec    phones; | ||||
|         Types::StringVec    mobiles; | ||||
|         std::string         geoCode; | ||||
|         Types::UUID_t       operatorId; | ||||
|         Types::UUID_t       subscriberDeviceId; | ||||
|         Types::UUID_t       managementPolicy; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|     typedef std::vector<Location>      LocationVec; | ||||
|  | ||||
|     struct SubLocation { | ||||
|         std::string         type; | ||||
|         std::string         buildingName; | ||||
|         Types::StringVec    addressLines; | ||||
|         std::string         city; | ||||
|         std::string         state; | ||||
|         std::string         postal; | ||||
|         std::string         country; | ||||
|         Types::StringVec    phones; | ||||
|         Types::StringVec    mobiles; | ||||
|         std::string         geoCode; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     struct OperatorLocationList { | ||||
|         std::vector<OperatorLocation>    locations; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|  | ||||
|     enum ContactType { | ||||
|         CT_SUBSCRIBER, CT_USER, CT_INSTALLER, CT_CSR, CT_MANAGER, | ||||
|         CT_BUSINESSOWNER, CT_TECHNICIAN, CT_CORPORATE, CT_UNKNOWN | ||||
| @@ -243,6 +331,55 @@ namespace OpenWifi::ProvObjects { | ||||
|     }; | ||||
|     typedef std::vector<Contact>      ContactVec; | ||||
|  | ||||
|     struct OperatorContact { | ||||
|         ObjectInfo      info; | ||||
|         std::string     type; | ||||
|         std::string     title; | ||||
|         std::string     salutation; | ||||
|         std::string     firstname; | ||||
|         std::string     lastname; | ||||
|         std::string     initials; | ||||
|         std::string     visual; | ||||
|         Types::StringVec mobiles; | ||||
|         Types::StringVec phones; | ||||
|         std::string     primaryEmail; | ||||
|         std::string     secondaryEmail; | ||||
|         std::string     accessPIN; | ||||
|         Types::UUID_t   operatorId; | ||||
|         Types::UUID_t   subscriberDeviceId; | ||||
|         Types::UUID_t   managementPolicy; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     struct SubContact { | ||||
|         std::string     type; | ||||
|         std::string     title; | ||||
|         std::string     salutation; | ||||
|         std::string     firstname; | ||||
|         std::string     lastname; | ||||
|         std::string     initials; | ||||
|         std::string     visual; | ||||
|         Types::StringVec mobiles; | ||||
|         Types::StringVec phones; | ||||
|         std::string     primaryEmail; | ||||
|         std::string     secondaryEmail; | ||||
|         std::string     accessPIN; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     struct OperatorContactList { | ||||
|         std::vector<OperatorContact>    contacts; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     typedef std::vector<OperatorContact>      OperatorContactVec; | ||||
|  | ||||
|     struct DeviceConfigurationElement { | ||||
|         std::string name; | ||||
|         std::string description; | ||||
| @@ -255,21 +392,24 @@ namespace OpenWifi::ProvObjects { | ||||
|     typedef std::vector<DeviceConfigurationElement> DeviceConfigurationElementVec; | ||||
|  | ||||
|     struct DeviceConfiguration { | ||||
|     ObjectInfo                          info; | ||||
|         ObjectInfo                      info; | ||||
|         Types::UUID_t                   managementPolicy; | ||||
|         Types::StringVec                deviceTypes; | ||||
|         DeviceConfigurationElementVec   configuration; | ||||
|         Types::StringVec                inUse; | ||||
|         Types::StringPairVec            variables; | ||||
|         std::string                     rrm; | ||||
|         std::string                     firmwareUpgrade; | ||||
|         bool                            firmwareRCOnly=false; | ||||
|         Types::UUIDvec_t                variables; | ||||
|         DeviceRules                     deviceRules; | ||||
|         bool                            subscriberOnly=false; | ||||
|         std::string                     venue; | ||||
|         std::string                     entity; | ||||
|         std::string                     subscriber; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|     typedef std::vector<DeviceConfiguration>      DeviceConfigurationVec; | ||||
|  | ||||
|  | ||||
|     struct InventoryTag { | ||||
|         ObjectInfo      info; | ||||
|         std::string     serialNumber; | ||||
| @@ -282,9 +422,13 @@ namespace OpenWifi::ProvObjects { | ||||
|         std::string     location; | ||||
|         std::string     contact; | ||||
|         std::string     deviceConfiguration; | ||||
|         std::string     rrm; | ||||
|         DeviceRules     deviceRules; | ||||
|         Types::UUID_t   managementPolicy; | ||||
|         std::string     state; | ||||
|         std::string     devClass; | ||||
|         std::string     locale; | ||||
|         std::string     realMacAddress; | ||||
|         bool            doNotAllowOverrides=false; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| @@ -299,6 +443,15 @@ namespace OpenWifi::ProvObjects { | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     struct InventoryConfigApplyResult { | ||||
|         std::string         appliedConfiguration; | ||||
|         Types::StringVec    errors; | ||||
|         Types::StringVec    warnings; | ||||
|         uint64_t            errorCode; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     struct Report { | ||||
|         uint64_t            snapShot=0; | ||||
| @@ -333,20 +486,20 @@ namespace OpenWifi::ProvObjects { | ||||
|     }; | ||||
|  | ||||
|     struct UuidList { | ||||
|         std::vector<std::string>    list; | ||||
|         Types::UUIDvec_t    list; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     enum ACLACCESS { | ||||
|         NONE, READ, MODIFY, CREATE, DELETE | ||||
|         NONE = 0, READ=1, MODIFY=2, CREATE=3, DELETE=4 | ||||
|     }; | ||||
|  | ||||
|     struct ObjectACL { | ||||
|         UuidList        users; | ||||
|         UuidList        roles; | ||||
|         ACLACCESS       access = NONE; | ||||
|         uint64_t        access = (uint64_t) NONE; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| @@ -359,20 +512,15 @@ namespace OpenWifi::ProvObjects { | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     enum VISIBILITY { | ||||
|         PUBLIC, PRIVATE, SELECT | ||||
|     }; | ||||
|  | ||||
|     std::string to_string(VISIBILITY A); | ||||
|     VISIBILITY visibility_from_string(const std::string &V); | ||||
|  | ||||
|     struct Map { | ||||
|         ObjectInfo          info; | ||||
|         std::string         data; | ||||
|         std::string         entity; | ||||
|         std::string         creator; | ||||
|         VISIBILITY          visibility = PRIVATE; | ||||
|         std::string         visibility{"private"}; | ||||
|         ObjectACLList       access; | ||||
|         Types::UUID_t       managementPolicy; | ||||
|         std::string         venue; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| @@ -385,6 +533,189 @@ namespace OpenWifi::ProvObjects { | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     enum SignupStatusCodes { | ||||
|         SignupCreated = 0 , | ||||
|         SignupWaitingForEmail, | ||||
|         SignupWaitingForDevice, | ||||
|         SignupSuccess, | ||||
|         SignupFailure, | ||||
|         SignupCanceled, | ||||
|         SignupTimedOut | ||||
|     }; | ||||
|  | ||||
|     struct SignupEntry { | ||||
|         ObjectInfo          info; | ||||
|         std::string         email; | ||||
|         std::string         userId; | ||||
|         std::string         macAddress; | ||||
|         std::string         serialNumber; | ||||
|         uint64_t            submitted = 0 ; | ||||
|         uint64_t            completed = 0 ; | ||||
|         std::string         status; | ||||
|         uint64_t            error=0; | ||||
|         uint64_t            statusCode=0; | ||||
|         std::string         deviceID; | ||||
|         std::string         registrationId; | ||||
|         std::string         operatorId; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     struct Variable { | ||||
|         std::string         type; | ||||
|         uint64_t            weight=0; | ||||
|         std::string         prefix; | ||||
|         std::string         value; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     struct VariableList { | ||||
|         std::vector<Variable>   variables; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     struct VariableBlock { | ||||
|         ObjectInfo                  info; | ||||
|         std::vector<Variable>       variables; | ||||
|         std::string                 entity; | ||||
|         std::string                 venue; | ||||
|         std::string                 subscriber; | ||||
|         std::string                 inventory; | ||||
|         Types::UUIDvec_t            configurations; | ||||
|         Types::UUID_t               managementPolicy; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     struct VariableBlockList { | ||||
|         std::vector<VariableBlock>      variableBlocks; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     struct Operator { | ||||
|         ObjectInfo                      info; | ||||
|         Types::UUID_t                   managementPolicy; | ||||
|         Types::UUIDvec_t                managementRoles; | ||||
|         DeviceRules                     deviceRules; | ||||
|         std::vector<Variable>           variables; | ||||
|         bool                            defaultOperator=false; | ||||
|         Types::StringVec                sourceIP; | ||||
|         std::string                     registrationId; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     struct OperatorList { | ||||
|         std::vector<Operator>            operators; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     struct VenueDeviceList { | ||||
|         std::string         id; | ||||
|         std::string         name; | ||||
|         std::string         description; | ||||
|         Types::UUIDvec_t    devices; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     struct ServiceClass { | ||||
|         ObjectInfo                      info; | ||||
|         Types::UUID_t                   operatorId; | ||||
|         Types::UUID_t                   managementPolicy; | ||||
|         double                          cost=0.0; | ||||
|         std::string                     currency; | ||||
|         std::string                     period; | ||||
|         std::string                     billingCode; | ||||
|         std::vector<Variable>           variables; | ||||
|         bool                            defaultService=false; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     struct ServiceClassList { | ||||
|         std::vector<ServiceClass>            serviceClasses; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     struct ConfigurationDetails { | ||||
|         DeviceConfigurationElementVec   configuration; | ||||
|         std::string                     rrm{"inherit"}; | ||||
|         std::string                     firmwareUpgrade{"inherit"}; | ||||
|         std::string                     firmwareRCOnly{"inherit"}; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     struct SubscriberDevice { | ||||
|         ObjectInfo                      info; | ||||
|         std::string                     serialNumber; | ||||
|         std::string                     deviceType; | ||||
|         Types::UUID_t                   operatorId; | ||||
|         Types::UUID_t                   subscriberId; | ||||
|         SubLocation                     location; | ||||
|         SubContact                      contact; | ||||
|         Types::UUID_t                   managementPolicy; | ||||
|         Types::UUID_t                   serviceClass; | ||||
|         std::string                     qrCode; | ||||
|         std::string                     geoCode; | ||||
|         DeviceRules                     deviceRules; | ||||
|         std::string                     state; | ||||
|         std::string                     locale; | ||||
|         std::string                     billingCode; | ||||
|         DeviceConfigurationElementVec   configuration; | ||||
|         bool                            suspended=false; | ||||
|         std::string                     realMacAddress; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     struct SubscriberDeviceList { | ||||
|         std::vector<SubscriberDevice>       subscriberDevices; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     struct ConfigurationOverride { | ||||
|         std::string     source; | ||||
|         std::string     reason; | ||||
|         std::string     parameterName; | ||||
|         std::string     parameterType; | ||||
|         std::string     parameterValue; | ||||
|         std::uint64_t   modified; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     struct ConfigurationOverrideList { | ||||
|         std::string     serialNumber; | ||||
|         Types::UUID_t   managementPolicy; | ||||
|         std::vector<ConfigurationOverride>  overrides; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     bool UpdateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I); | ||||
|     bool CreateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I); | ||||
|     bool CreateObjectInfo(const SecurityObjects::UserInfo &U, ObjectInfo &I); | ||||
| }; | ||||
|   | ||||
| @@ -9,7 +9,7 @@ | ||||
| #include "Poco/JSON/Parser.h" | ||||
| #include "Poco/JSON/Stringifier.h" | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_utils.h" | ||||
| #include "RESTAPI_SecurityObjects.h" | ||||
|  | ||||
| using OpenWifi::RESTAPI_utils::field_to_json; | ||||
| @@ -95,6 +95,7 @@ namespace OpenWifi::SecurityObjects { | ||||
| 			field_from_json(Obj, "PortalLogin", PortalLogin_); | ||||
| 			return true; | ||||
| 		} catch(...) { | ||||
|             std::cout << "Cannot parse: AclTemplate" << std::endl; | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
| @@ -112,6 +113,8 @@ namespace OpenWifi::SecurityObjects { | ||||
|         field_to_json(Obj,"userMustChangePassword",userMustChangePassword); | ||||
|         field_to_json(Obj,"errorCode", errorCode); | ||||
| 		Obj.set("aclTemplate",AclTemplateObj); | ||||
|         field_to_json(Obj,"errorCode", errorCode); | ||||
|         field_to_json(Obj,"lastRefresh", lastRefresh_); | ||||
| 	} | ||||
|  | ||||
| 	bool WebToken::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| @@ -128,9 +131,10 @@ namespace OpenWifi::SecurityObjects { | ||||
| 			field_from_json(Obj, "created", created_); | ||||
| 			field_from_json(Obj, "username", username_); | ||||
|             field_from_json(Obj, "userMustChangePassword",userMustChangePassword); | ||||
|             field_from_json(Obj,"lastRefresh", lastRefresh_); | ||||
| 			return true; | ||||
| 		} catch (...) { | ||||
|  | ||||
|             std::cout << "Cannot parse: WebToken" << std::endl; | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
| @@ -141,14 +145,14 @@ namespace OpenWifi::SecurityObjects { | ||||
| 	    field_to_json(Obj,"primary", primary); | ||||
| 	} | ||||
|  | ||||
| 	bool MobilePhoneNumber::from_json(Poco::JSON::Object::Ptr &Obj) { | ||||
| 	bool MobilePhoneNumber::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| 	    try { | ||||
| 	        field_from_json(Obj,"number",number); | ||||
| 	        field_from_json(Obj,"verified",verified); | ||||
| 	        field_from_json(Obj,"primary",primary); | ||||
| 	        return true; | ||||
| 	    } catch (...) { | ||||
|  | ||||
|             std::cout << "Cannot parse: MobilePhoneNumber" << std::endl; | ||||
| 	    } | ||||
| 	    return false; | ||||
| 	}; | ||||
| @@ -158,13 +162,13 @@ namespace OpenWifi::SecurityObjects { | ||||
| 	    field_to_json(Obj,"method", method); | ||||
| 	} | ||||
|  | ||||
| 	bool MfaAuthInfo::from_json(Poco::JSON::Object::Ptr &Obj) { | ||||
| 	bool MfaAuthInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| 	    try { | ||||
| 	        field_from_json(Obj,"enabled",enabled); | ||||
| 	        field_from_json(Obj,"method",method); | ||||
| 	        return true; | ||||
| 	    } catch (...) { | ||||
|  | ||||
|             std::cout << "Cannot parse: MfaAuthInfo" << std::endl; | ||||
| 	    } | ||||
| 	    return false; | ||||
| 	} | ||||
| @@ -175,14 +179,14 @@ namespace OpenWifi::SecurityObjects { | ||||
|         field_to_json(Obj, "authenticatorSecret", authenticatorSecret); | ||||
| 	} | ||||
|  | ||||
| 	bool UserLoginLoginExtensions::from_json(Poco::JSON::Object::Ptr &Obj) { | ||||
| 	bool UserLoginLoginExtensions::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| 	    try { | ||||
| 	        field_from_json(Obj,"mobiles",mobiles); | ||||
| 	        field_from_json(Obj,"mfa",mfa); | ||||
| 	        field_from_json(Obj, "mobiles",mobiles); | ||||
| 	        field_from_json(Obj, "mfa",mfa); | ||||
|             field_from_json(Obj, "authenticatorSecret", authenticatorSecret); | ||||
| 	        return true; | ||||
| 	    } catch (...) { | ||||
|  | ||||
|             std::cout << "Cannot parse: UserLoginLoginExtensions" << std::endl; | ||||
| 	    } | ||||
| 	    return false; | ||||
| 	} | ||||
| @@ -194,7 +198,7 @@ namespace OpenWifi::SecurityObjects { | ||||
|         field_to_json(Obj, "method", method); | ||||
|     } | ||||
|  | ||||
|     bool MFAChallengeRequest::from_json(Poco::JSON::Object::Ptr &Obj) { | ||||
|     bool MFAChallengeRequest::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| 	    try { | ||||
| 	        field_from_json(Obj,"uuid",uuid); | ||||
| 	        field_from_json(Obj,"question",question); | ||||
| @@ -202,7 +206,7 @@ namespace OpenWifi::SecurityObjects { | ||||
| 	        field_from_json(Obj,"method",method); | ||||
| 	        return true; | ||||
| 	    } catch (...) { | ||||
|  | ||||
|             std::cout << "Cannot parse: MFAChallengeRequest" << std::endl; | ||||
| 	    } | ||||
| 	    return false; | ||||
| 	}; | ||||
| @@ -210,16 +214,15 @@ namespace OpenWifi::SecurityObjects { | ||||
|     void MFAChallengeResponse::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj, "uuid", uuid); | ||||
|         field_to_json(Obj, "answer", answer); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     bool MFAChallengeResponse::from_json(Poco::JSON::Object::Ptr &Obj) { | ||||
|     bool MFAChallengeResponse::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj,"uuid",uuid); | ||||
|             field_from_json(Obj,"answer",answer); | ||||
|             return true; | ||||
|         } catch (...) { | ||||
|  | ||||
|             std::cout << "Cannot parse: MFAChallengeResponse" << std::endl; | ||||
|         } | ||||
|         return false; | ||||
|  | ||||
| @@ -257,6 +260,7 @@ namespace OpenWifi::SecurityObjects { | ||||
| 		field_to_json(Obj,"oauthType",oauthType); | ||||
| 		field_to_json(Obj,"oauthUserInfo",oauthUserInfo); | ||||
|         field_to_json(Obj,"modified",modified); | ||||
|         field_to_json(Obj,"signingUp",signingUp); | ||||
|     }; | ||||
|  | ||||
|     bool UserInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| @@ -292,13 +296,28 @@ namespace OpenWifi::SecurityObjects { | ||||
| 			field_from_json(Obj,"oauthType",oauthType); | ||||
| 			field_from_json(Obj,"oauthUserInfo",oauthUserInfo); | ||||
|             field_from_json(Obj,"modified",modified); | ||||
|             field_from_json(Obj,"signingUp",signingUp); | ||||
|             return true; | ||||
|         } catch (const Poco::Exception &E) { | ||||
|  | ||||
|             std::cout << "Cannot parse: UserInfo" << std::endl; | ||||
|         } | ||||
|         return false; | ||||
|     }; | ||||
|  | ||||
|     void UserInfoList::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj,"users",users); | ||||
|     } | ||||
|  | ||||
|     bool UserInfoList::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj,"users",users); | ||||
|             return true; | ||||
|         } catch (...) { | ||||
|             std::cout << "Cannot parse: InternalServiceInfo" << std::endl; | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
| 	void InternalServiceInfo::to_json(Poco::JSON::Object &Obj) const { | ||||
| 		field_to_json(Obj,"privateURI",privateURI); | ||||
| 		field_to_json(Obj,"publicURI",publicURI); | ||||
| @@ -312,7 +331,7 @@ namespace OpenWifi::SecurityObjects { | ||||
| 			field_from_json(Obj,"token",token); | ||||
| 			return true; | ||||
| 		} catch (...) { | ||||
|  | ||||
|             std::cout << "Cannot parse: InternalServiceInfo" << std::endl; | ||||
| 		} | ||||
| 		return false; | ||||
| 	}; | ||||
| @@ -330,7 +349,7 @@ namespace OpenWifi::SecurityObjects { | ||||
| 			field_from_json(Obj, "services", services); | ||||
| 			return true; | ||||
| 		} catch(...) { | ||||
|  | ||||
|             std::cout << "Cannot parse: InternalSystemServices" << std::endl; | ||||
| 		} | ||||
| 		return false; | ||||
| 	}; | ||||
| @@ -352,7 +371,7 @@ namespace OpenWifi::SecurityObjects { | ||||
| 			field_from_json(Obj, "authenticationType", authenticationType); | ||||
| 			return true; | ||||
| 		} catch (...) { | ||||
|  | ||||
|             std::cout << "Cannot parse: SystemEndpoint" << std::endl; | ||||
| 		} | ||||
| 		return false; | ||||
| 	}; | ||||
| @@ -366,7 +385,7 @@ namespace OpenWifi::SecurityObjects { | ||||
| 			field_from_json(Obj, "endpoints", endpoints); | ||||
| 			return true; | ||||
| 		} catch (...) { | ||||
|  | ||||
|             std::cout << "Cannot parse: SystemEndpointList" << std::endl; | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
| @@ -385,7 +404,7 @@ namespace OpenWifi::SecurityObjects { | ||||
| 			field_from_json(Obj, "userInfo", userinfo); | ||||
| 			return true; | ||||
| 		} catch(...) { | ||||
|  | ||||
|             std::cout << "Cannot parse: UserInfoAndPolicy" << std::endl; | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
| @@ -396,14 +415,14 @@ namespace OpenWifi::SecurityObjects { | ||||
| 		field_to_json(Obj,"note", note); | ||||
| 	} | ||||
|  | ||||
| 	bool NoteInfo::from_json(Poco::JSON::Object::Ptr &Obj) { | ||||
| 	bool NoteInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| 		try { | ||||
| 			field_from_json(Obj,"created",created); | ||||
|             field_from_json(Obj,"created",created); | ||||
| 			field_from_json(Obj,"createdBy",createdBy); | ||||
| 			field_from_json(Obj,"note",note); | ||||
| 			field_from_json(Obj,"note", note); | ||||
| 			return true; | ||||
| 		} catch(...) { | ||||
|  | ||||
|             std::cout << "Cannot parse: NoteInfo" << std::endl; | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
| @@ -414,20 +433,20 @@ namespace OpenWifi::SecurityObjects { | ||||
| 	            SecurityObjects::NoteInfoVec NIV; | ||||
| 	            NIV = RESTAPI_utils::to_object_array<SecurityObjects::NoteInfo>(Obj->get("notes").toString()); | ||||
| 	            for(auto const &i:NIV) { | ||||
| 	                SecurityObjects::NoteInfo   ii{.created=(uint64_t)std::time(nullptr), .createdBy=UInfo.email, .note=i.note}; | ||||
| 	                SecurityObjects::NoteInfo   ii{.created=(uint64_t)Utils::Now(), .createdBy=UInfo.email, .note=i.note}; | ||||
| 	                Notes.push_back(ii); | ||||
| 	            } | ||||
| 	        } | ||||
| 	        return true; | ||||
| 	    } catch(...) { | ||||
|  | ||||
|             std::cout << "Cannot parse: MergeNotes" << std::endl; | ||||
| 	    } | ||||
| 	    return false; | ||||
| 	} | ||||
|  | ||||
| 	bool MergeNotes(const NoteInfoVec & NewNotes, const UserInfo &UInfo, NoteInfoVec & ExistingNotes) { | ||||
| 	    for(auto const &i:NewNotes) { | ||||
| 	        SecurityObjects::NoteInfo   ii{.created=(uint64_t)std::time(nullptr), .createdBy=UInfo.email, .note=i.note}; | ||||
| 	        SecurityObjects::NoteInfo   ii{.created=(uint64_t)Utils::Now(), .createdBy=UInfo.email, .note=i.note}; | ||||
| 	        ExistingNotes.push_back(ii); | ||||
| 	    } | ||||
|         return true; | ||||
| @@ -438,13 +457,13 @@ namespace OpenWifi::SecurityObjects { | ||||
| 		field_to_json<ResourceAccessType>(Obj,"access", access, ResourceAccessTypeToString); | ||||
| 	} | ||||
|  | ||||
| 	bool ProfileAction::from_json(Poco::JSON::Object::Ptr &Obj) { | ||||
| 	bool ProfileAction::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| 		try { | ||||
| 			field_from_json(Obj,"resource",resource); | ||||
| 			field_from_json<ResourceAccessType>(Obj,"access",access,ResourceAccessTypeFromString ); | ||||
| 			return true; | ||||
| 		} catch(...) { | ||||
|  | ||||
|             std::cout << "Cannot parse: ProfileAction" << std::endl; | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
| @@ -458,7 +477,7 @@ namespace OpenWifi::SecurityObjects { | ||||
| 		field_to_json(Obj,"notes", notes); | ||||
| 	} | ||||
|  | ||||
| 	bool SecurityProfile::from_json(Poco::JSON::Object::Ptr &Obj) { | ||||
| 	bool SecurityProfile::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| 		try { | ||||
| 			field_from_json(Obj,"id",id); | ||||
| 			field_from_json(Obj,"name",name); | ||||
| @@ -468,7 +487,7 @@ namespace OpenWifi::SecurityObjects { | ||||
| 			field_from_json(Obj,"notes",notes); | ||||
| 			return true; | ||||
| 		} catch(...) { | ||||
|  | ||||
|             std::cout << "Cannot parse: SecurityProfile" << std::endl; | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
| @@ -477,12 +496,12 @@ namespace OpenWifi::SecurityObjects { | ||||
| 		field_to_json(Obj, "profiles", profiles); | ||||
| 	} | ||||
|  | ||||
| 	bool SecurityProfileList::from_json(Poco::JSON::Object::Ptr &Obj) { | ||||
| 	bool SecurityProfileList::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| 		try { | ||||
| 			field_from_json(Obj,"profiles",profiles); | ||||
| 			return true; | ||||
| 		} catch(...) { | ||||
|  | ||||
|             std::cout << "Cannot parse: SecurityProfileList" << std::endl; | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
| @@ -503,7 +522,7 @@ namespace OpenWifi::SecurityObjects { | ||||
|         field_to_json(Obj,"userAction",userAction); | ||||
| 	} | ||||
|  | ||||
|     bool ActionLink::from_json(Poco::JSON::Object::Ptr &Obj) { | ||||
|     bool ActionLink::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| 	    try { | ||||
| 	        field_from_json(Obj,"id",id); | ||||
| 	        field_from_json(Obj,"action",action); | ||||
| @@ -520,7 +539,7 @@ namespace OpenWifi::SecurityObjects { | ||||
|             field_from_json(Obj,"userAction",userAction); | ||||
| 	        return true; | ||||
| 	    } catch(...) { | ||||
|  | ||||
|             std::cout << "Cannot parse: ActionLink" << std::endl; | ||||
| 	    } | ||||
| 	    return false; | ||||
| 	} | ||||
| @@ -531,14 +550,14 @@ namespace OpenWifi::SecurityObjects { | ||||
| 	    field_to_json(Obj,"data",data); | ||||
| 	} | ||||
|  | ||||
|     bool Preferences::from_json(Poco::JSON::Object::Ptr &Obj) { | ||||
|     bool Preferences::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| 	    try { | ||||
| 	        field_from_json(Obj,"id",id); | ||||
| 	        field_from_json(Obj,"modified",modified); | ||||
| 	        field_from_json(Obj,"data",data); | ||||
| 	        return true; | ||||
| 	    } catch(...) { | ||||
|  | ||||
|             std::cout << "Cannot parse: Preferences" << std::endl; | ||||
| 	    } | ||||
| 	    return false; | ||||
| 	} | ||||
| @@ -550,7 +569,7 @@ namespace OpenWifi::SecurityObjects { | ||||
| 	    field_to_json(Obj,"email",email); | ||||
| 	} | ||||
|  | ||||
|     bool SubMfaConfig::from_json(Poco::JSON::Object::Ptr &Obj) { | ||||
|     bool SubMfaConfig::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| 	    try { | ||||
| 	        field_from_json(Obj,"id",id); | ||||
| 	        field_from_json(Obj,"type",type); | ||||
| @@ -558,7 +577,7 @@ namespace OpenWifi::SecurityObjects { | ||||
| 	        field_from_json(Obj,"email",email); | ||||
| 	        return true; | ||||
| 	    } catch(...) { | ||||
|  | ||||
|             std::cout << "Cannot parse: SubMfaConfig" << std::endl; | ||||
| 	    } | ||||
| 	    return false; | ||||
| 	} | ||||
| @@ -572,9 +591,10 @@ namespace OpenWifi::SecurityObjects { | ||||
|         field_to_json(Obj,"expires",expires); | ||||
|         field_to_json(Obj,"idleTimeout",idleTimeout); | ||||
|         field_to_json(Obj,"revocationDate",revocationDate); | ||||
|         field_to_json(Obj,"lastRefresh", lastRefresh); | ||||
|     } | ||||
|  | ||||
|     bool Token::from_json(Poco::JSON::Object::Ptr &Obj) { | ||||
|     bool Token::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj,"token",token); | ||||
|             field_from_json(Obj,"refreshToken",refreshToken); | ||||
| @@ -584,9 +604,10 @@ namespace OpenWifi::SecurityObjects { | ||||
|             field_from_json(Obj,"expires",expires); | ||||
|             field_from_json(Obj,"idleTimeout",idleTimeout); | ||||
|             field_from_json(Obj,"revocationDate",revocationDate); | ||||
|             field_from_json(Obj,"lastRefresh", lastRefresh); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|             std::cout << "Cannot parse: Token" << std::endl; | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
| @@ -598,5 +619,80 @@ namespace OpenWifi::SecurityObjects { | ||||
|         field_to_json(Obj,"login",login); | ||||
|         field_to_json(Obj,"logout",logout); | ||||
|     } | ||||
|  | ||||
|     void ApiKeyAccessRight::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj, "service", service); | ||||
|         field_to_json(Obj, "access", access); | ||||
|     } | ||||
|  | ||||
|     bool ApiKeyAccessRight::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj, "service", service); | ||||
|             field_from_json(Obj, "access", access); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|             std::cout << "Cannot parse: Token" << std::endl; | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void ApiKeyAccessRightList::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj, "acls", acls); | ||||
|     } | ||||
|  | ||||
|     bool ApiKeyAccessRightList::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj, "acls", acls); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|             std::cout << "Cannot parse: Token" << std::endl; | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void ApiKeyEntry::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj, "id", id); | ||||
|         field_to_json(Obj, "userUuid", userUuid); | ||||
|         field_to_json(Obj, "name", name); | ||||
|         field_to_json(Obj, "apiKey", apiKey); | ||||
|         field_to_json(Obj, "salt", salt); | ||||
|         field_to_json(Obj, "description", description); | ||||
|         field_to_json(Obj, "expiresOn", expiresOn); | ||||
|         field_to_json(Obj, "rights", rights); | ||||
|         field_to_json(Obj, "lastUse", lastUse); | ||||
|     } | ||||
|  | ||||
|     bool ApiKeyEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj, "id", id); | ||||
|             field_from_json(Obj, "userUuid", userUuid); | ||||
|             field_from_json(Obj, "name", name); | ||||
|             field_from_json(Obj, "apiKey", apiKey); | ||||
|             field_from_json(Obj, "salt", salt); | ||||
|             field_from_json(Obj, "description", description); | ||||
|             field_from_json(Obj, "expiresOn", expiresOn); | ||||
|             field_from_json(Obj, "rights", rights); | ||||
|             field_from_json(Obj, "lastUse", lastUse); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|             std::cout << "Cannot parse: Token" << std::endl; | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void ApiKeyEntryList::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj, "apiKeys", apiKeys); | ||||
|     } | ||||
|  | ||||
|     bool ApiKeyEntryList::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj, "apiKeys", apiKeys); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|             std::cout << "Cannot parse: Token" << std::endl; | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -9,14 +9,17 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <string> | ||||
| #include <type_traits> | ||||
| #include "framework/OpenWifiTypes.h" | ||||
| #include "Poco/JSON/Object.h" | ||||
| #include "Poco/Data/LOB.h" | ||||
| #include "Poco/Data/LOBStream.h" | ||||
| #include "framework/utils.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     uint64_t Now(); | ||||
|     namespace SecurityObjects { | ||||
|  | ||||
|          | ||||
|         typedef std::string USER_ID_TYPE; | ||||
|  | ||||
|         struct AclTemplate { | ||||
| @@ -26,8 +29,13 @@ namespace OpenWifi { | ||||
|             bool Delete_ = true; | ||||
|             bool PortalLogin_ = true; | ||||
|  | ||||
|             AclTemplate()  noexcept = default; | ||||
|  | ||||
|             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); | ||||
|         }; | ||||
|  | ||||
|         static_assert( std::is_nothrow_move_constructible_v<AclTemplate> ); | ||||
|  | ||||
|         struct WebToken { | ||||
|             std::string access_token_; | ||||
| @@ -41,6 +49,7 @@ namespace OpenWifi { | ||||
|             uint64_t idle_timeout_=0; | ||||
|             AclTemplate acl_template_; | ||||
|             uint64_t created_=0; | ||||
|             uint64_t lastRefresh_=0; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| @@ -54,11 +63,12 @@ namespace OpenWifi { | ||||
|         std::string UserTypeToString(USER_ROLE U); | ||||
|  | ||||
|         struct NoteInfo { | ||||
|             uint64_t created = std::time(nullptr); | ||||
|             uint64_t    created=0; // = Utils::Now(); | ||||
|             std::string createdBy; | ||||
|             std::string note; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(Poco::JSON::Object::Ptr &Obj); | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|         typedef std::vector<NoteInfo>	NoteInfoVec; | ||||
|  | ||||
| @@ -68,7 +78,7 @@ namespace OpenWifi { | ||||
|             bool primary = false; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(Poco::JSON::Object::Ptr &Obj); | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|  | ||||
|         struct MfaAuthInfo { | ||||
| @@ -76,7 +86,7 @@ namespace OpenWifi { | ||||
|             std::string method; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(Poco::JSON::Object::Ptr &Obj); | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|  | ||||
|         struct UserLoginLoginExtensions { | ||||
| @@ -85,17 +95,17 @@ namespace OpenWifi { | ||||
|             std::string                     authenticatorSecret; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(Poco::JSON::Object::Ptr &Obj); | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|  | ||||
|         struct MFAChallengeRequest { | ||||
|             std::string uuid; | ||||
|             std::string question; | ||||
|             std::string method; | ||||
|             uint64_t    created = std::time(nullptr); | ||||
|             uint64_t    created = Utils::Now(); | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(Poco::JSON::Object::Ptr &Obj); | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|  | ||||
|         struct MFAChallengeResponse { | ||||
| @@ -103,7 +113,7 @@ namespace OpenWifi { | ||||
|             std::string answer; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(Poco::JSON::Object::Ptr &Obj); | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|  | ||||
|         struct UserInfo { | ||||
| @@ -138,12 +148,20 @@ namespace OpenWifi { | ||||
|             std::string oauthType; | ||||
|             std::string oauthUserInfo; | ||||
|             uint64_t    modified; | ||||
|             std::string signingUp; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|         typedef std::vector<UserInfo>   UserInfoVec; | ||||
|  | ||||
|         struct UserInfoList { | ||||
|             std::vector<UserInfo>   users; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|  | ||||
|         // bool append_from_json(Poco::JSON::Object::Ptr Obj, const UserInfo &UInfo, NoteInfoVec & Notes); | ||||
|         bool MergeNotes(Poco::JSON::Object::Ptr Obj, const UserInfo &UInfo, NoteInfoVec & Notes); | ||||
|         bool MergeNotes(const NoteInfoVec & NewNotes, const UserInfo &UInfo, NoteInfoVec & ExistingNotes); | ||||
| @@ -207,7 +225,7 @@ namespace OpenWifi { | ||||
|             std::string resource; | ||||
|             ResourceAccessType access; | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(Poco::JSON::Object::Ptr &Obj); | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|         typedef std::vector<ProfileAction>	ProfileActionVec; | ||||
|  | ||||
| @@ -219,21 +237,23 @@ namespace OpenWifi { | ||||
|             std::string role; | ||||
|             NoteInfoVec notes; | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(Poco::JSON::Object::Ptr &Obj); | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|         typedef std::vector<SecurityProfile> SecurityProfileVec; | ||||
|  | ||||
|         struct SecurityProfileList { | ||||
|             SecurityProfileVec profiles; | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(Poco::JSON::Object::Ptr &Obj); | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|  | ||||
|         enum LinkActions { | ||||
|             FORGOT_PASSWORD=1, | ||||
|             VERIFY_EMAIL, | ||||
|             SUB_FORGOT_PASSWORD, | ||||
|             SUB_VERIFY_EMAIL | ||||
|             SUB_VERIFY_EMAIL, | ||||
|             SUB_SIGNUP, | ||||
|             EMAIL_INVITATION | ||||
|         }; | ||||
|  | ||||
|         struct ActionLink { | ||||
| @@ -245,14 +265,14 @@ namespace OpenWifi { | ||||
|             std::string         locale; | ||||
|             std::string         message; | ||||
|             uint64_t            sent=0; | ||||
|             uint64_t            created=std::time(nullptr); | ||||
|             uint64_t            created=Utils::Now(); | ||||
|             uint64_t            expires=0; | ||||
|             uint64_t            completed=0; | ||||
|             uint64_t            canceled=0; | ||||
|             bool                userAction=true; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(Poco::JSON::Object::Ptr &Obj); | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|  | ||||
|         struct Preferences { | ||||
| @@ -260,7 +280,7 @@ namespace OpenWifi { | ||||
|             uint64_t                            modified; | ||||
|             Types::StringPairVec                data; | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(Poco::JSON::Object::Ptr &Obj); | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|  | ||||
|         struct SubMfaConfig { | ||||
| @@ -270,7 +290,7 @@ namespace OpenWifi { | ||||
|             std::string                         email; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(Poco::JSON::Object::Ptr &Obj); | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|  | ||||
|         struct Token { | ||||
| @@ -282,9 +302,10 @@ namespace OpenWifi { | ||||
|             uint64_t            expires=0; | ||||
|             uint64_t            idleTimeout=0; | ||||
|             uint64_t            revocationDate=0; | ||||
|             uint64_t            lastRefresh=0; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(Poco::JSON::Object::Ptr &Obj); | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|  | ||||
|         struct Avatar { | ||||
| @@ -292,7 +313,7 @@ namespace OpenWifi { | ||||
|             std::string             type; | ||||
|             uint64_t                created=0; | ||||
|             std::string             name; | ||||
|             Poco::Data::LOB<char>   avatar; | ||||
|             Poco::Data::BLOB        avatar; | ||||
|         }; | ||||
|  | ||||
|         struct LoginRecordInfo { | ||||
| @@ -304,5 +325,44 @@ namespace OpenWifi { | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|         }; | ||||
|  | ||||
|         struct ApiKeyAccessRight { | ||||
|             std::string     service; | ||||
|             std::string     access; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|  | ||||
|         struct ApiKeyAccessRightList { | ||||
|             std::vector<ApiKeyAccessRight>      acls; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|  | ||||
|         struct ApiKeyEntry { | ||||
|             Types::UUID_t           id; | ||||
|             Types::UUID_t           userUuid; | ||||
|             std::string             name; | ||||
|             std::string             description; | ||||
|             std::string             apiKey; | ||||
|             std::string             salt; | ||||
|             std::uint64_t           created; | ||||
|             std::uint64_t           expiresOn=0; | ||||
|             ApiKeyAccessRightList   rights; | ||||
|             std::uint64_t           lastUse=0; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|  | ||||
|         struct ApiKeyEntryList { | ||||
|             std::vector<ApiKeyEntry>    apiKeys; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|  | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -3,12 +3,11 @@ | ||||
| // | ||||
|  | ||||
| #include "RESTAPI_SubObjects.h" | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_utils.h" | ||||
|  | ||||
| using OpenWifi::RESTAPI_utils::field_to_json; | ||||
| using OpenWifi::RESTAPI_utils::field_from_json; | ||||
|  | ||||
|  | ||||
| namespace OpenWifi::SubObjects { | ||||
|  | ||||
|     void HomeDeviceMode::to_json(Poco::JSON::Object &Obj) const { | ||||
| @@ -280,6 +279,7 @@ namespace OpenWifi::SubObjects { | ||||
|         field_to_json(Obj, "ipv6", ipv6); | ||||
|         field_to_json(Obj, "tx", tx); | ||||
|         field_to_json(Obj, "rx", rx); | ||||
|         field_to_json(Obj, "manufacturer", manufacturer); | ||||
|     } | ||||
|  | ||||
|     bool Association::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| @@ -293,6 +293,7 @@ namespace OpenWifi::SubObjects { | ||||
|             field_from_json(Obj, "ipv6", ipv6); | ||||
|             field_from_json(Obj, "tx", tx); | ||||
|             field_from_json(Obj, "rx", rx); | ||||
|             field_from_json(Obj, "manufacturer", manufacturer); | ||||
|             return true; | ||||
|         } catch (...) { | ||||
|         } | ||||
| @@ -324,6 +325,7 @@ namespace OpenWifi::SubObjects { | ||||
|         field_to_json(Obj, "ipv6", ipv6); | ||||
|         field_to_json(Obj, "tx", tx); | ||||
|         field_to_json(Obj, "rx", rx); | ||||
|         field_to_json(Obj, "manufacturer", manufacturer); | ||||
|     } | ||||
|  | ||||
|     bool Client::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| @@ -335,6 +337,7 @@ namespace OpenWifi::SubObjects { | ||||
|             field_from_json(Obj, "ipv6", ipv6); | ||||
|             field_from_json(Obj, "tx", tx); | ||||
|             field_from_json(Obj, "rx", rx); | ||||
|             field_from_json(Obj, "manufacturer", manufacturer); | ||||
|             return true; | ||||
|         } catch (...) { | ||||
|         } | ||||
| @@ -433,6 +436,8 @@ namespace OpenWifi::SubObjects { | ||||
|         field_to_json(Obj, "rates", rates); | ||||
|         field_to_json(Obj, "he", he); | ||||
|         field_to_json(Obj, "rawInfo", rawInfo); | ||||
|         field_to_json(Obj, "allowDFS", allowDFS); | ||||
|         field_to_json(Obj, "mimo", mimo); | ||||
|     } | ||||
|  | ||||
|     bool RadioInformation::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| @@ -452,6 +457,8 @@ namespace OpenWifi::SubObjects { | ||||
|             field_from_json(Obj, "rates", rates); | ||||
|             field_from_json(Obj, "he", he); | ||||
|             field_from_json(Obj, "rawInfo", rawInfo); | ||||
|             field_from_json(Obj, "allowDFS", allowDFS); | ||||
|             field_from_json(Obj, "mimo", mimo); | ||||
|             return true; | ||||
|         } catch (...) { | ||||
|         } | ||||
| @@ -461,6 +468,7 @@ namespace OpenWifi::SubObjects { | ||||
|     void AccessPoint::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj, "id", id); | ||||
|         field_to_json(Obj, "macAddress", macAddress); | ||||
|         field_to_json(Obj, "serialNumber", serialNumber); | ||||
|         field_to_json(Obj, "name", name); | ||||
|         field_to_json(Obj, "deviceType", deviceType); | ||||
|         field_to_json(Obj, "subscriberDevices", subscriberDevices); | ||||
| @@ -473,12 +481,19 @@ namespace OpenWifi::SubObjects { | ||||
|         field_to_json(Obj, "radios", radios); | ||||
|         field_to_json(Obj, "automaticUpgrade", automaticUpgrade); | ||||
|         field_to_json(Obj, "configurationUUID", configurationUUID); | ||||
|         field_to_json(Obj, "currentFirmware", currentFirmware); | ||||
|         field_to_json(Obj, "currentFirmwareDate", currentFirmwareDate); | ||||
|         field_to_json(Obj, "latestFirmware", latestFirmware); | ||||
|         field_to_json(Obj, "latestFirmwareDate", latestFirmwareDate); | ||||
|         field_to_json(Obj, "newFirmwareAvailable", newFirmwareAvailable); | ||||
|         field_to_json(Obj, "latestFirmwareURI", latestFirmwareURI); | ||||
|     } | ||||
|  | ||||
|     bool AccessPoint::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj, "id", id); | ||||
|             field_from_json(Obj, "macAddress", macAddress); | ||||
|             field_from_json(Obj, "serialNumber", serialNumber); | ||||
|             field_from_json(Obj, "name", name); | ||||
|             field_from_json(Obj, "deviceType", deviceType); | ||||
|             field_from_json(Obj, "subscriberDevices", subscriberDevices); | ||||
| @@ -491,6 +506,12 @@ namespace OpenWifi::SubObjects { | ||||
|             field_from_json(Obj, "radios", radios); | ||||
|             field_from_json(Obj, "automaticUpgrade", automaticUpgrade); | ||||
|             field_from_json(Obj, "configurationUUID", configurationUUID); | ||||
|             field_from_json(Obj, "currentFirmware", currentFirmware); | ||||
|             field_from_json(Obj, "currentFirmwareDate", currentFirmwareDate); | ||||
|             field_from_json(Obj, "latestFirmware", latestFirmware); | ||||
|             field_from_json(Obj, "latestFirmwareDate", latestFirmwareDate); | ||||
|             field_from_json(Obj, "newFirmwareAvailable", newFirmwareAvailable); | ||||
|             field_from_json(Obj, "latestFirmwareURI", latestFirmwareURI); | ||||
|             return true; | ||||
|         } catch (...) { | ||||
|         } | ||||
| @@ -544,4 +565,38 @@ namespace OpenWifi::SubObjects { | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void StatsEntry::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj, "timestamp", timestamp); | ||||
|         field_to_json(Obj, "tx", tx); | ||||
|         field_to_json(Obj, "rx", rx); | ||||
|     } | ||||
|  | ||||
|     bool StatsEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj, "timestamp", timestamp); | ||||
|             field_from_json(Obj, "tx", tx); | ||||
|             field_from_json(Obj, "rx", rx); | ||||
|             return true; | ||||
|         } catch (...) { | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void StatsBlock::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj, "modified", modified); | ||||
|         field_to_json(Obj, "external", external); | ||||
|         field_to_json(Obj, "internal", internal); | ||||
|     } | ||||
|  | ||||
|     bool StatsBlock::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj, "modified", modified); | ||||
|             field_from_json(Obj, "external", external); | ||||
|             field_from_json(Obj, "internal", internal); | ||||
|             return true; | ||||
|         } catch (...) { | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
| } | ||||
| @@ -24,6 +24,7 @@ namespace OpenWifi::SubObjects { | ||||
|         int             subnetMaskV6=0; | ||||
|         std::string     startIPV6; | ||||
|         std::string     endIPV6; | ||||
|         std::string     leaseTime; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| @@ -156,6 +157,7 @@ namespace OpenWifi::SubObjects { | ||||
|         std::string     ipv6; | ||||
|         uint64_t        tx=0; | ||||
|         uint64_t        rx=0; | ||||
|         std::string     manufacturer; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| @@ -178,6 +180,7 @@ namespace OpenWifi::SubObjects { | ||||
|         std::string     ipv6; | ||||
|         uint64_t        tx=0; | ||||
|         uint64_t        rx=0; | ||||
|         std::string     manufacturer; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| @@ -238,6 +241,8 @@ namespace OpenWifi::SubObjects { | ||||
|         uint64_t                maximumClients = 64; | ||||
|         RadioRates              rates; | ||||
|         RadioHE                 he; | ||||
|         bool                    allowDFS=false; | ||||
|         std::string             mimo; | ||||
|         std::vector<std::string>    rawInfo; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
| @@ -247,6 +252,7 @@ namespace OpenWifi::SubObjects { | ||||
|     struct AccessPoint { | ||||
|         std::string                 id; | ||||
|         std::string                 macAddress; | ||||
|         std::string                 serialNumber; | ||||
|         std::string                 name; | ||||
|         std::string                 deviceType; | ||||
|         SubscriberDeviceList        subscriberDevices; | ||||
| @@ -259,6 +265,12 @@ namespace OpenWifi::SubObjects { | ||||
|         std::vector<RadioInformation>   radios; | ||||
|         bool                        automaticUpgrade = true; | ||||
|         std::string                 configurationUUID; | ||||
|         std::string                 currentFirmware; | ||||
|         uint64_t                    currentFirmwareDate; | ||||
|         std::string                 latestFirmware; | ||||
|         uint64_t                    latestFirmwareDate; | ||||
|         bool                        newFirmwareAvailable; | ||||
|         std::string                 latestFirmwareURI; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| @@ -288,6 +300,23 @@ namespace OpenWifi::SubObjects { | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     struct StatsEntry { | ||||
|         uint64_t        timestamp=0; | ||||
|         uint64_t        tx=0; | ||||
|         uint64_t        rx=0; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     struct StatsBlock { | ||||
|         uint64_t                    modified=0; | ||||
|         std::vector<StatsEntry>     external, internal; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
| } | ||||
|  | ||||
| #endif //OWSUB_RESTAPI_SUBOBJECTS_H | ||||
|   | ||||
| @@ -3,12 +3,14 @@ | ||||
| // | ||||
|  | ||||
| #include "GW_SDK.h" | ||||
| #include "Daemon.h" | ||||
| #include "Poco/Net/HTTPResponse.h" | ||||
|  | ||||
| #include "framework/MicroServiceNames.h" | ||||
| #include "framework/OpenAPIRequests.h" | ||||
|  | ||||
| namespace OpenWifi::SDK::GW { | ||||
|  | ||||
|     bool SendFirmwareUpgradeCommand( const std::string & serialNumber, const std::string & URI, uint64_t When  ) { | ||||
|     bool SendFirmwareUpgradeCommand( const std::string & serialNumber, const std::string & URI, [[maybe_unused]] uint64_t When  ) { | ||||
|         Types::StringPairVec    QueryData; | ||||
|         Poco::JSON::Object      Body; | ||||
|  | ||||
|   | ||||
| @@ -2,11 +2,9 @@ | ||||
| // Created by stephane bourque on 2021-10-05. | ||||
| // | ||||
|  | ||||
| #ifndef OWFMS_GW_SDK_H | ||||
| #define OWFMS_GW_SDK_H | ||||
| #pragma once | ||||
|  | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include <string> | ||||
|  | ||||
| namespace OpenWifi::SDK::GW { | ||||
|  | ||||
| @@ -14,4 +12,3 @@ namespace OpenWifi::SDK::GW { | ||||
|  | ||||
| }; | ||||
|  | ||||
| #endif //OWFMS_GW_SDK_H | ||||
|   | ||||
| @@ -2,7 +2,8 @@ | ||||
| // Created by stephane bourque on 2021-10-04. | ||||
| // | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/OpenAPIRequests.h" | ||||
| #include "framework/MicroServiceNames.h" | ||||
|  | ||||
| namespace OpenWifi::SDK::Prov { | ||||
|     bool GetFirmwareOptions( const std::string & serialNumber, std::string &firmwareUpgrade, | ||||
|   | ||||
| @@ -2,10 +2,9 @@ | ||||
| // Created by stephane bourque on 2021-10-04. | ||||
| // | ||||
|  | ||||
| #ifndef OWFMS_PROV_SDK_H | ||||
| #define OWFMS_PROV_SDK_H | ||||
| #pragma once | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include <string> | ||||
|  | ||||
| namespace OpenWifi::SDK::Prov { | ||||
|  | ||||
| @@ -14,5 +13,3 @@ namespace OpenWifi::SDK::Prov { | ||||
|  | ||||
| }; | ||||
|  | ||||
|  | ||||
| #endif //OWFMS_PROV_SDK_H | ||||
|   | ||||
| @@ -11,6 +11,7 @@ | ||||
| namespace OpenWifi { | ||||
|  | ||||
|     int Storage::Start() { | ||||
|         poco_information(Logger(),"Starting..."); | ||||
|         std::lock_guard		Guard(Mutex_); | ||||
|  | ||||
|         StorageClass::Start(); | ||||
| @@ -27,9 +28,10 @@ namespace OpenWifi { | ||||
|     } | ||||
|  | ||||
|     void Storage::Stop() { | ||||
|         poco_information(Logger(),"Stopping..."); | ||||
|         std::lock_guard		Guard(Mutex_); | ||||
|         Logger().notice("Stopping."); | ||||
|         StorageClass::Stop(); | ||||
|         poco_information(Logger(),"Stopped..."); | ||||
|     } | ||||
|  | ||||
|     std::string Storage::TrimRevision(const std::string &R) { | ||||
|   | ||||
| @@ -6,10 +6,8 @@ | ||||
| //	Arilia Wireless Inc. | ||||
| // | ||||
|  | ||||
| #ifndef UCENTRAL_USTORAGESERVICE_H | ||||
| #define UCENTRAL_USTORAGESERVICE_H | ||||
| #pragma once | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/StorageClass.h" | ||||
|  | ||||
| #include "RESTObjects/RESTAPI_FMSObjects.h" | ||||
| @@ -53,4 +51,3 @@ namespace OpenWifi { | ||||
|  | ||||
| }  // namespace | ||||
|  | ||||
| #endif //UCENTRAL_USTORAGESERVICE_H | ||||
|   | ||||
							
								
								
									
										77
									
								
								src/framework/ALBserver.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								src/framework/ALBserver.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,77 @@ | ||||
| // | ||||
| // Created by stephane bourque on 2022-10-25. | ||||
| // | ||||
|  | ||||
| #include "ALBserver.h" | ||||
|  | ||||
| #include "framework/utils.h" | ||||
| #include "framework/MicroServiceFuncs.h" | ||||
| #include "fmt/format.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
| 	void ALBRequestHandler::handleRequest([[maybe_unused]] Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response) { | ||||
| 		Utils::SetThreadName("alb-request"); | ||||
| 		try { | ||||
| 			if((id_ % 100) == 0) { | ||||
| 				Logger_.debug(fmt::format("ALB-REQUEST({}): ALB Request {}.", Request.clientAddress().toString(), id_)); | ||||
| 			} | ||||
| 			Response.setChunkedTransferEncoding(true); | ||||
| 			Response.setContentType("text/html"); | ||||
| 			Response.setDate(Poco::Timestamp()); | ||||
| 			Response.setStatus(Poco::Net::HTTPResponse::HTTP_OK); | ||||
| 			Response.setKeepAlive(true); | ||||
| 			Response.set("Connection", "keep-alive"); | ||||
| 			Response.setVersion(Poco::Net::HTTPMessage::HTTP_1_1); | ||||
| 			std::ostream &Answer = Response.send(); | ||||
| 			Answer << "process Alive and kicking!"; | ||||
| 		} catch (...) { | ||||
|  | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	ALBRequestHandlerFactory::ALBRequestHandlerFactory(Poco::Logger & L): | ||||
| 		Logger_(L) { | ||||
| 	} | ||||
|  | ||||
| 	ALBRequestHandler* ALBRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest& request) { | ||||
| 		if (request.getURI() == "/") | ||||
| 			return new ALBRequestHandler(Logger_, req_id_++); | ||||
| 		else | ||||
| 			return nullptr; | ||||
| 	} | ||||
|  | ||||
| 	ALBHealthCheckServer::ALBHealthCheckServer() : | ||||
| 		  SubSystemServer("ALBHealthCheckServer", "ALB-SVR", "alb") | ||||
| 	{ | ||||
| 	} | ||||
|  | ||||
| 	int ALBHealthCheckServer::Start() { | ||||
| 		if(MicroServiceConfigGetBool("alb.enable",false)) { | ||||
|             poco_information(Logger(),"Starting..."); | ||||
| 			Running_=true; | ||||
| 			Port_ = (int)MicroServiceConfigGetInt("alb.port",15015); | ||||
| 			Poco::Net::IPAddress Addr(Poco::Net::IPAddress::wildcard( | ||||
| 				Poco::Net::Socket::supportsIPv6() ? Poco::Net::AddressFamily::IPv6 | ||||
| 												  : Poco::Net::AddressFamily::IPv4)); | ||||
| 			Poco::Net::SocketAddress SockAddr(Addr, Port_); | ||||
| 			Poco::Net::ServerSocket ClientSocket(SockAddr, 64); | ||||
|  | ||||
| 			Socket_ = std::make_unique<Poco::Net::ServerSocket>(SockAddr, Port_); | ||||
| 			auto Params = new Poco::Net::HTTPServerParams; | ||||
| 			Params->setName("ws:alb"); | ||||
| 			Server_ = std::make_unique<Poco::Net::HTTPServer>(new ALBRequestHandlerFactory(Logger()), *Socket_, Params); | ||||
| 			Server_->start(); | ||||
| 		} | ||||
|  | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	void ALBHealthCheckServer::Stop() { | ||||
| 		poco_information(Logger(),"Stopping..."); | ||||
| 		if(Running_) | ||||
| 			Server_->stopAll(true); | ||||
| 		poco_information(Logger(),"Stopped..."); | ||||
| 	} | ||||
|  | ||||
| } // namespace OpenWifi | ||||
							
								
								
									
										63
									
								
								src/framework/ALBserver.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								src/framework/ALBserver.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | ||||
| // | ||||
| // Created by stephane bourque on 2022-10-25. | ||||
| // | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "framework/SubSystemServer.h" | ||||
|  | ||||
| #include "Poco/Net/HTTPRequestHandler.h" | ||||
| #include "Poco/Net/HTTPServerRequest.h" | ||||
| #include "Poco/Net/HTTPServerResponse.h" | ||||
| #include "Poco/Net/HTTPRequestHandlerFactory.h" | ||||
| #include "Poco/Net/HTTPServer.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
| 	class ALBRequestHandler: public Poco::Net::HTTPRequestHandler { | ||||
| 	  public: | ||||
| 		explicit ALBRequestHandler(Poco::Logger & L, uint64_t id) | ||||
|                 : Logger_(L), id_(id) { | ||||
|         } | ||||
|  | ||||
| 		void handleRequest([[maybe_unused]] Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response) override; | ||||
|  | ||||
| 	  private: | ||||
| 		Poco::Logger 	& Logger_; | ||||
| 		uint64_t 		id_; | ||||
| 	}; | ||||
|  | ||||
| 	class ALBRequestHandlerFactory: public Poco::Net::HTTPRequestHandlerFactory | ||||
| 	{ | ||||
| 	  public: | ||||
| 		explicit ALBRequestHandlerFactory(Poco::Logger & L); | ||||
| 		ALBRequestHandler* createRequestHandler(const Poco::Net::HTTPServerRequest& request) override; | ||||
|  | ||||
| 	  private: | ||||
| 		Poco::Logger	                            &Logger_; | ||||
| 		inline static std::atomic_uint64_t 			req_id_=1; | ||||
| 	}; | ||||
|  | ||||
| 	class ALBHealthCheckServer : public SubSystemServer { | ||||
| 	  public: | ||||
| 		ALBHealthCheckServer(); | ||||
|  | ||||
| 		static auto instance() { | ||||
| 			static auto instance = new ALBHealthCheckServer; | ||||
| 			return instance; | ||||
| 		} | ||||
|  | ||||
| 		int Start() override; | ||||
| 		void Stop() override; | ||||
|  | ||||
| 	  private: | ||||
| 		std::unique_ptr<Poco::Net::HTTPServer>   	Server_; | ||||
| 		std::unique_ptr<Poco::Net::ServerSocket> 	Socket_; | ||||
| 		int                                     	Port_ = 0; | ||||
| 		mutable std::atomic_bool                    Running_=false; | ||||
| 	}; | ||||
|  | ||||
| 	inline auto ALBHealthCheckServer() { return ALBHealthCheckServer::instance(); } | ||||
|  | ||||
| } // namespace OpenWifi | ||||
|  | ||||
| @@ -4,8 +4,14 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "Poco/Logger.h" | ||||
| #include "Poco/JSON/Parser.h" | ||||
| #include "Poco/Net/HTTPServerRequest.h" | ||||
| #include "Poco/Net/HTTPServerResponse.h" | ||||
| #include "Poco/Net/HTTPSClientSession.h" | ||||
| #include "Poco/URI.h" | ||||
|  | ||||
| #include "framework/MicroServiceFuncs.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     inline void API_Proxy( Poco::Logger &Logger, | ||||
| @@ -15,7 +21,7 @@ namespace OpenWifi { | ||||
|                     const char * PathRewrite, | ||||
|                     uint64_t msTimeout_ = 10000 ) { | ||||
|         try { | ||||
|             auto Services = MicroService::instance().GetServices(ServiceType); | ||||
|             auto Services = MicroServiceGetServices(ServiceType); | ||||
|             for(auto const &Svc:Services) { | ||||
|                 Poco::URI   SourceURI(Request->getURI()); | ||||
|                 Poco::URI	DestinationURI(Svc.PrivateEndPoint); | ||||
| @@ -35,7 +41,7 @@ namespace OpenWifi { | ||||
|                     ProxyRequest.add("Authorization", Request->get("Authorization")); | ||||
|                 } else { | ||||
|                     ProxyRequest.add("X-API-KEY", Svc.AccessKey); | ||||
|                     ProxyRequest.add("X-INTERNAL-NAME", MicroService::instance().PublicEndPoint()); | ||||
|                     ProxyRequest.add("X-INTERNAL-NAME", MicroServicePublicEndPoint()); | ||||
|                 } | ||||
|  | ||||
|                 if(Request->getMethod() == Poco::Net::HTTPRequest::HTTP_DELETE) { | ||||
|   | ||||
							
								
								
									
										102
									
								
								src/framework/AppServiceRegistry.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								src/framework/AppServiceRegistry.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,102 @@ | ||||
| // | ||||
| // Created by stephane bourque on 2022-10-25. | ||||
| // | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <string> | ||||
| #include <fstream> | ||||
| #include <iomanip> | ||||
| #include <iostream> | ||||
|  | ||||
| #include "Poco/StreamCopier.h" | ||||
| #include "Poco/File.h" | ||||
|  | ||||
| #include "framework/MicroServiceFuncs.h" | ||||
|  | ||||
| #include "nlohmann/json.hpp" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
|  | ||||
| 	class AppServiceRegistry { | ||||
| 	  public: | ||||
| 		AppServiceRegistry() { | ||||
| 			FileName = MicroServiceDataDirectory() + "/registry.json"; | ||||
| 			Poco::File F(FileName); | ||||
|  | ||||
| 			try { | ||||
| 				if(F.exists()) { | ||||
| 					std::ostringstream  OS; | ||||
| 					std::ifstream       IF(FileName); | ||||
| 					Poco::StreamCopier::copyStream(IF, OS); | ||||
| 					Registry_ = nlohmann::json::parse(OS.str()); | ||||
| 				} | ||||
| 			} catch (...) { | ||||
| 				Registry_ = nlohmann::json::parse("{}"); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		static AppServiceRegistry & instance() { | ||||
| 			static auto instance_= new AppServiceRegistry; | ||||
| 			return *instance_; | ||||
| 		} | ||||
|  | ||||
| 		inline ~AppServiceRegistry() { | ||||
| 			Save(); | ||||
| 		} | ||||
|  | ||||
| 		inline void Save() { | ||||
| 			std::istringstream  IS( to_string(Registry_)); | ||||
| 			std::ofstream       OF; | ||||
| 			OF.open(FileName,std::ios::binary | std::ios::trunc); | ||||
| 			Poco::StreamCopier::copyStream(IS, OF); | ||||
| 		} | ||||
|  | ||||
| 		inline void Set(const char *Key, uint64_t Value ) { | ||||
| 			Registry_[Key] = Value; | ||||
| 			Save(); | ||||
| 		} | ||||
|  | ||||
| 		inline void Set(const char *Key, const std::string &Value ) { | ||||
| 			Registry_[Key] = Value; | ||||
| 			Save(); | ||||
| 		} | ||||
|  | ||||
| 		inline void Set(const char *Key, bool Value ) { | ||||
| 			Registry_[Key] = Value; | ||||
| 			Save(); | ||||
| 		} | ||||
|  | ||||
| 		inline bool Get(const char *Key, bool & Value ) { | ||||
| 			if(Registry_[Key].is_boolean()) { | ||||
| 				Value = Registry_[Key].get<bool>(); | ||||
| 				return true; | ||||
| 			} | ||||
| 			return false; | ||||
| 		} | ||||
|  | ||||
| 		inline bool Get(const char *Key, uint64_t & Value ) { | ||||
| 			if(Registry_[Key].is_number_unsigned()) { | ||||
| 				Value = Registry_[Key].get<uint64_t>(); | ||||
| 				return true; | ||||
| 			} | ||||
| 			return false; | ||||
| 		} | ||||
|  | ||||
| 		inline bool Get(const char *Key, std::string & Value ) { | ||||
| 			if(Registry_[Key].is_string()) { | ||||
| 				Value = Registry_[Key].get<std::string>(); | ||||
| 				return true; | ||||
| 			} | ||||
| 			return false; | ||||
| 		} | ||||
|  | ||||
| 	  private: | ||||
| 		std::string         FileName; | ||||
| 		nlohmann::json      Registry_; | ||||
| 	}; | ||||
|  | ||||
| 	inline auto AppServiceRegistry() { return AppServiceRegistry::instance(); } | ||||
|  | ||||
| } | ||||
							
								
								
									
										129
									
								
								src/framework/AuthClient.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								src/framework/AuthClient.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,129 @@ | ||||
| // | ||||
| // Created by stephane bourque on 2022-10-25. | ||||
| // | ||||
|  | ||||
| #include "Poco/Net/HTTPServerResponse.h" | ||||
|  | ||||
| #include "framework/AuthClient.h" | ||||
| #include "framework/MicroServiceNames.h" | ||||
| #include "framework/OpenAPIRequests.h" | ||||
| #include "framework/utils.h" | ||||
| #include "fmt/format.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
| 	bool AuthClient::RetrieveTokenInformation(const std::string & SessionToken, | ||||
| 										 SecurityObjects::UserInfoAndPolicy & UInfo, | ||||
| 										 std::uint64_t TID, | ||||
| 										 bool & Expired, bool & Contacted, bool Sub) { | ||||
| 		try { | ||||
| 			Types::StringPairVec QueryData; | ||||
| 			QueryData.push_back(std::make_pair("token",SessionToken)); | ||||
|             std::string     AlternateURIForLogging = fmt::format("{}?token={}",  Sub ? "/api/v1/validateSubToken" : "/api/v1/validateToken", Utils::SanitizeToken(SessionToken)); | ||||
| 			OpenAPIRequestGet	Req(    uSERVICE_SECURITY, | ||||
| 								  Sub ? "/api/v1/validateSubToken" : "/api/v1/validateToken", | ||||
| 								  QueryData, | ||||
| 								  10000, | ||||
| 								  AlternateURIForLogging | ||||
|                                   ); | ||||
| 			Poco::JSON::Object::Ptr Response; | ||||
|  | ||||
| 			auto StatusCode = Req.Do(Response); | ||||
| 			if(StatusCode==Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT) { | ||||
| 				Contacted = false; | ||||
| 				return false; | ||||
| 			} | ||||
|  | ||||
| 			Contacted = true; | ||||
| 			if(StatusCode==Poco::Net::HTTPServerResponse::HTTP_OK) { | ||||
| 				if(Response->has("tokenInfo") && Response->has("userInfo")) { | ||||
| 					UInfo.from_json(Response); | ||||
| 					if(IsTokenExpired(UInfo.webtoken)) { | ||||
| 						Expired = true; | ||||
| 						return false; | ||||
| 					} | ||||
| 					Expired = false; | ||||
| 					Cache_.update(SessionToken, UInfo); | ||||
| 					return true; | ||||
| 				} else { | ||||
| 					return false; | ||||
| 				} | ||||
| 			} | ||||
| 		} catch (...) { | ||||
| 			poco_error(Logger(),fmt::format("Failed to retrieve token={} for TID={}", Utils::SanitizeToken(SessionToken), TID)); | ||||
| 		} | ||||
| 		Expired = false; | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	bool AuthClient::IsAuthorized(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, | ||||
| 							 std::uint64_t TID, | ||||
| 							 bool & Expired, bool & Contacted, bool Sub) { | ||||
| 		auto User = Cache_.get(SessionToken); | ||||
| 		if(!User.isNull()) { | ||||
| 			if(IsTokenExpired(User->webtoken)) { | ||||
| 				Expired = true; | ||||
| 				Cache_.remove(SessionToken); | ||||
| 				return false; | ||||
| 			} | ||||
| 			Expired = false; | ||||
| 			UInfo = *User; | ||||
| 			return true; | ||||
| 		} | ||||
| 		return RetrieveTokenInformation(SessionToken, UInfo, TID, Expired, Contacted, Sub); | ||||
| 	} | ||||
|  | ||||
|     bool AuthClient::RetrieveApiKeyInformation(const std::string & SessionToken, | ||||
|                                               SecurityObjects::UserInfoAndPolicy & UInfo, | ||||
|                                               std::uint64_t TID, | ||||
|                                               bool & Expired, bool & Contacted) { | ||||
|         try { | ||||
|             Types::StringPairVec QueryData; | ||||
|             QueryData.push_back(std::make_pair("apikey",SessionToken)); | ||||
|             std::string     AlternateURIForLogging = fmt::format("/api/v1/validateApiKey?apiKey={}", Utils::SanitizeToken(SessionToken)); | ||||
|             OpenAPIRequestGet	Req(    uSERVICE_SECURITY, | ||||
|                                          "/api/v1/validateApiKey" , | ||||
|                                          QueryData, | ||||
|                                          10000, | ||||
|                                          AlternateURIForLogging); | ||||
|             Poco::JSON::Object::Ptr Response; | ||||
|  | ||||
|             auto StatusCode = Req.Do(Response); | ||||
|             if(StatusCode==Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT) { | ||||
|                 Contacted = false; | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             Contacted = true; | ||||
|             if(StatusCode==Poco::Net::HTTPServerResponse::HTTP_OK) { | ||||
|                 if(Response->has("tokenInfo") && Response->has("userInfo") && Response->has("expiresOn")) { | ||||
|                     UInfo.from_json(Response); | ||||
|                     Expired = false; | ||||
|                     ApiKeyCache_.update(SessionToken, ApiKeyCacheEntry{ .UserInfo = UInfo, .ExpiresOn = Response->get("expiresOn")}); | ||||
|                     return true; | ||||
|                 } else { | ||||
|                     return false; | ||||
|                 } | ||||
|             } | ||||
|         } catch (...) { | ||||
|             poco_error(Logger(),fmt::format("Failed to retrieve api key={} for TID={}", Utils::SanitizeToken(SessionToken), TID)); | ||||
|         } | ||||
|         Expired = false; | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     bool AuthClient::IsValidApiKey(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy &UInfo, | ||||
|                                    std::uint64_t TID, bool &Expired, bool &Contacted) { | ||||
|         auto User = ApiKeyCache_.get(SessionToken); | ||||
|         if (!User.isNull()) { | ||||
|             if(User->ExpiresOn < Utils::Now()) { | ||||
|                 Expired = false; | ||||
|                 UInfo = User->UserInfo; | ||||
|                 return true; | ||||
|             } | ||||
| 			ApiKeyCache_.remove(SessionToken); | ||||
|         } | ||||
|         return RetrieveApiKeyInformation(SessionToken, UInfo, TID, Expired, Contacted); | ||||
|     } | ||||
|  | ||||
| } // namespace OpenWifi | ||||
							
								
								
									
										79
									
								
								src/framework/AuthClient.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								src/framework/AuthClient.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,79 @@ | ||||
| // | ||||
| // Created by stephane bourque on 2022-10-25. | ||||
| // | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "framework/SubSystemServer.h" | ||||
| #include "RESTObjects/RESTAPI_SecurityObjects.h" | ||||
| #include "Poco/ExpireLRUCache.h" | ||||
| #include "framework/utils.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
| 	class AuthClient : public SubSystemServer { | ||||
|  | ||||
| 	  public: | ||||
| 		explicit AuthClient() noexcept: | ||||
| 			 SubSystemServer("Authentication", "AUTH-CLNT", "authentication") | ||||
| 		{ | ||||
| 		} | ||||
|  | ||||
| 		static auto instance() { | ||||
| 			static auto instance_ = new AuthClient; | ||||
| 			return instance_; | ||||
| 		} | ||||
|  | ||||
|         struct ApiKeyCacheEntry { | ||||
|             OpenWifi::SecurityObjects::UserInfoAndPolicy    UserInfo; | ||||
|             std::uint64_t                                   ExpiresOn; | ||||
|         }; | ||||
|  | ||||
|         inline int Start() override { | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		inline void Stop() override { | ||||
| 			poco_information(Logger(),"Stopping..."); | ||||
| 			std::lock_guard	G(Mutex_); | ||||
| 			Cache_.clear(); | ||||
| 			poco_information(Logger(),"Stopped..."); | ||||
| 		} | ||||
|  | ||||
| 		inline void RemovedCachedToken(const std::string &Token) { | ||||
| 			Cache_.remove(Token); | ||||
|             ApiKeyCache_.remove(Token); | ||||
| 		} | ||||
|  | ||||
| 		inline static bool IsTokenExpired(const SecurityObjects::WebToken &T) { | ||||
| 			return ((T.expires_in_+T.created_) < Utils::Now()); | ||||
| 		} | ||||
|  | ||||
| 		bool RetrieveTokenInformation(const std::string & SessionToken, | ||||
| 			SecurityObjects::UserInfoAndPolicy & UInfo, | ||||
| 			std::uint64_t TID, | ||||
| 		bool & Expired, bool & Contacted, bool Sub=false); | ||||
|  | ||||
|         bool RetrieveApiKeyInformation(const std::string & SessionToken, | ||||
|                                       SecurityObjects::UserInfoAndPolicy & UInfo, | ||||
|                                       std::uint64_t TID, | ||||
|                                       bool & Expired, bool & Contacted); | ||||
|  | ||||
| 		bool IsAuthorized(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, | ||||
| 								 std::uint64_t TID, | ||||
| 								 bool & Expired, bool & Contacted, bool Sub = false); | ||||
|  | ||||
|         bool IsValidApiKey(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, | ||||
|                           std::uint64_t TID, | ||||
|                           bool & Expired, bool & Contacted); | ||||
|  | ||||
| 	  private: | ||||
|  | ||||
| 		Poco::ExpireLRUCache<std::string,OpenWifi::SecurityObjects::UserInfoAndPolicy>      Cache_{512,1200000 }; | ||||
|         Poco::ExpireLRUCache<std::string,ApiKeyCacheEntry>                                  ApiKeyCache_{512,1200000 }; | ||||
| 	}; | ||||
|  | ||||
| 	inline auto AuthClient() { return AuthClient::instance(); } | ||||
|  | ||||
| } // namespace OpenWifi | ||||
|  | ||||
							
								
								
									
										155
									
								
								src/framework/CIDR.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								src/framework/CIDR.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,155 @@ | ||||
| // | ||||
| // Created by stephane bourque on 2022-10-25. | ||||
| // | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <string> | ||||
|  | ||||
| #include "Poco/Net/IPAddress.h" | ||||
| #include "Poco/StringTokenizer.h" | ||||
|  | ||||
| #include "framework/OpenWifiTypes.h" | ||||
|  | ||||
| namespace OpenWifi::CIDR { | ||||
|  | ||||
| 	static bool cidr_match(const in_addr &addr, const in_addr &net, uint8_t bits) { | ||||
| 		if (bits == 0) { | ||||
| 			return true; | ||||
| 		} | ||||
| 		return !((addr.s_addr ^ net.s_addr) & htonl(0xFFFFFFFFu << (32 - bits))); | ||||
| 	} | ||||
|  | ||||
| 	static bool cidr6_match(const in6_addr &address, const in6_addr &network, uint8_t bits) { | ||||
| 	#ifdef __linux__ | ||||
| 		const uint32_t *a = address.s6_addr32; | ||||
| 		const uint32_t *n = network.s6_addr32; | ||||
| 	#else | ||||
| 		const uint32_t *a = address.__u6_addr.__u6_addr32; | ||||
| 		const uint32_t *n = network.__u6_addr.__u6_addr32; | ||||
| 	#endif | ||||
| 		int bits_whole, bits_incomplete; | ||||
| 		bits_whole = bits >> 5;		   // number of whole u32 | ||||
| 		bits_incomplete = bits & 0x1F; // number of bits in incomplete u32 | ||||
| 		if (bits_whole) { | ||||
| 			if (memcmp(a, n, bits_whole << 2) != 0) { | ||||
| 				return false; | ||||
| 			} | ||||
| 		} | ||||
| 		if (bits_incomplete) { | ||||
| 			uint32_t mask = htonl((0xFFFFFFFFu) << (32 - bits_incomplete)); | ||||
| 			if ((a[bits_whole] ^ n[bits_whole]) & mask) { | ||||
| 				return false; | ||||
| 			} | ||||
| 		} | ||||
| 		return true; | ||||
| 	} | ||||
|  | ||||
| 	static bool ConvertStringToLong(const char *S, unsigned long &L) { | ||||
| 		char *end; | ||||
| 		L = std::strtol(S, &end, 10); | ||||
| 		return end != S; | ||||
| 	} | ||||
|  | ||||
| 	static bool CidrIPinRange(const Poco::Net::IPAddress &IP, const std::string &Range) { | ||||
| 		Poco::StringTokenizer TimeTokens(Range, "/", Poco::StringTokenizer::TOK_TRIM); | ||||
|  | ||||
| 		Poco::Net::IPAddress RangeIP; | ||||
| 		if (Poco::Net::IPAddress::tryParse(TimeTokens[0], RangeIP)) { | ||||
| 			if (TimeTokens.count() == 2) { | ||||
| 				if (RangeIP.family() == Poco::Net::IPAddress::IPv4) { | ||||
| 					unsigned long MaskLength; | ||||
| 					if (ConvertStringToLong(TimeTokens[1].c_str(), MaskLength)) { | ||||
| 						return cidr_match(*static_cast<const in_addr *>(RangeIP.addr()), | ||||
| 										  *static_cast<const in_addr *>(IP.addr()), MaskLength); | ||||
| 					} | ||||
| 				} else if (RangeIP.family() == Poco::Net::IPAddress::IPv6) { | ||||
| 					unsigned long MaskLength; | ||||
| 					if (ConvertStringToLong(TimeTokens[1].c_str(), MaskLength)) { | ||||
| 						return cidr6_match(*static_cast<const in6_addr *>(RangeIP.addr()), | ||||
| 										   *static_cast<const in6_addr *>(IP.addr()), MaskLength); | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			return false; | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	// | ||||
| 	//  Ranges can be a single IP, of IP1-IP2, of A set of IPs: IP1,IP2,IP3, or a cidr IP/24 | ||||
| 	//  These can work for IPv6 too... | ||||
| 	// | ||||
| 	static bool ValidateRange(const std::string &R) { | ||||
|  | ||||
| 		auto Tokens = Poco::StringTokenizer(R, "-"); | ||||
| 		if (Tokens.count() == 2) { | ||||
| 			Poco::Net::IPAddress a, b; | ||||
| 			if (!Poco::Net::IPAddress::tryParse(Tokens[0], a) && | ||||
| 				Poco::Net::IPAddress::tryParse(Tokens[1], b)) | ||||
| 				return false; | ||||
| 			return a.family() == b.family(); | ||||
| 		} | ||||
|  | ||||
| 		Tokens = Poco::StringTokenizer(R, ","); | ||||
| 		if (Tokens.count() > 1) { | ||||
| 			return std::all_of(Tokens.begin(), Tokens.end(), [](const std::string &A) { | ||||
| 				Poco::Net::IPAddress a; | ||||
| 				return Poco::Net::IPAddress::tryParse(A, a); | ||||
| 			}); | ||||
| 		} | ||||
|  | ||||
| 		Tokens = Poco::StringTokenizer(R, "/"); | ||||
| 		if (Tokens.count() == 2) { | ||||
| 			Poco::Net::IPAddress a; | ||||
| 			if (!Poco::Net::IPAddress::tryParse(Tokens[0], a)) | ||||
| 				return false; | ||||
| 			if (std::atoi(Tokens[1].c_str()) == 0) | ||||
| 				return false; | ||||
| 			return true; | ||||
| 		} | ||||
|  | ||||
| 		Poco::Net::IPAddress a; | ||||
| 		return Poco::Net::IPAddress::tryParse(R, a); | ||||
| 	} | ||||
|  | ||||
| 	static bool IpInRange(const Poco::Net::IPAddress &target, const std::string &R) { | ||||
|  | ||||
| 		auto Tokens = Poco::StringTokenizer(R, "-"); | ||||
| 		if (Tokens.count() == 2) { | ||||
| 			auto a = Poco::Net::IPAddress::parse(Tokens[0]); | ||||
| 			auto b = Poco::Net::IPAddress::parse(Tokens[1]); | ||||
| 			if (target.family() != a.family()) | ||||
| 				return false; | ||||
| 			return (a <= target && b >= target); | ||||
| 		} | ||||
|  | ||||
| 		Tokens = Poco::StringTokenizer(R, ","); | ||||
| 		if (Tokens.count() > 1) { | ||||
| 			return std::any_of(Tokens.begin(), Tokens.end(), [target](const std::string &Element) { | ||||
| 				return Poco::Net::IPAddress::parse(Element) == target; | ||||
| 			}); | ||||
| 		} | ||||
|  | ||||
| 		Tokens = Poco::StringTokenizer(R, "/"); | ||||
| 		if (Tokens.count() == 2) { | ||||
| 			return CidrIPinRange(target, R); | ||||
| 		} | ||||
|  | ||||
| 		return Poco::Net::IPAddress::parse(R) == target; | ||||
| 	} | ||||
|  | ||||
| 	[[nodiscard]] inline bool IpInRanges(const std::string &IP, const Types::StringVec &R) { | ||||
| 		Poco::Net::IPAddress Target; | ||||
|  | ||||
| 		if (!Poco::Net::IPAddress::tryParse(IP, Target)) | ||||
| 			return false; | ||||
|  | ||||
| 		return std::any_of(cbegin(R), cend(R), | ||||
| 						   [Target](const std::string &i) { return IpInRange(Target, i); }); | ||||
| 	} | ||||
|  | ||||
| 	[[nodiscard]] inline bool ValidateIpRanges(const Types::StringVec &Ranges) { | ||||
| 		return std::all_of(cbegin(Ranges), cend(Ranges), ValidateRange); | ||||
| 	} | ||||
| } | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -5,7 +5,7 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <nlohmann/json-schema.hpp> | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/SubSystemServer.h" | ||||
|  | ||||
| using nlohmann::json; | ||||
| using nlohmann::json_schema::json_validator; | ||||
| @@ -14,9 +14,8 @@ namespace OpenWifi { | ||||
|     class ConfigurationValidator : public  SubSystemServer { | ||||
|     public: | ||||
|  | ||||
|         static ConfigurationValidator *instance() { | ||||
|             if(instance_== nullptr) | ||||
|                 instance_ = new ConfigurationValidator; | ||||
|         static auto instance() { | ||||
|             static auto instance_ = new ConfigurationValidator; | ||||
|             return instance_; | ||||
|         } | ||||
|  | ||||
| @@ -27,18 +26,17 @@ namespace OpenWifi { | ||||
|         void reinitialize(Poco::Util::Application &self) override; | ||||
|  | ||||
|     private: | ||||
|         static  ConfigurationValidator * instance_; | ||||
|         bool            Initialized_=false; | ||||
|         bool            Working_=false; | ||||
|         void            Init(); | ||||
|         std::unique_ptr<json_validator>  Validator_=std::make_unique<json_validator>(nullptr, my_format_checker); | ||||
|         nlohmann::json  RootSchema_; | ||||
|  | ||||
|         ConfigurationValidator(): | ||||
|             SubSystemServer("configvalidator", "CFG-VALIDATOR", "config.validator") { | ||||
|             SubSystemServer("ConfigValidator", "CFG-VALIDATOR", "config.validator") { | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     inline ConfigurationValidator * ConfigurationValidator() { return ConfigurationValidator::instance(); } | ||||
|     inline auto ConfigurationValidator() { return ConfigurationValidator::instance(); } | ||||
|     inline bool ValidateUCentralConfiguration(const std::string &C, std::string &Error) { return ConfigurationValidator::instance()->Validate(C, Error); } | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										49
									
								
								src/framework/EventBusManager.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/framework/EventBusManager.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | ||||
| // | ||||
| // Created by stephane bourque on 2022-10-26. | ||||
| // | ||||
|  | ||||
| #include "framework/EventBusManager.h" | ||||
| #include "framework/KafkaManager.h" | ||||
| #include "framework/utils.h" | ||||
| #include "framework/MicroServiceFuncs.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
| 	EventBusManager::EventBusManager(Poco::Logger &L) : | ||||
| 		Logger_(L) { | ||||
| 	} | ||||
|  | ||||
| 	void EventBusManager::run() { | ||||
| 		Running_ = true; | ||||
| 		Utils::SetThreadName("fmwk:EventMgr"); | ||||
| 		auto Msg = MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_JOIN); | ||||
| 		KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,MicroServicePrivateEndPoint(),Msg, false); | ||||
| 		while(Running_) { | ||||
| 			Poco::Thread::trySleep((unsigned long)MicroServiceDaemonBusTimer()); | ||||
| 			if(!Running_) | ||||
| 				break; | ||||
| 			Msg = MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE); | ||||
| 			KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,MicroServicePrivateEndPoint(),Msg, false); | ||||
| 		} | ||||
| 		Msg = MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_LEAVE); | ||||
| 		KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,MicroServicePrivateEndPoint(),Msg, false); | ||||
| 	}; | ||||
|  | ||||
| 	void EventBusManager::Start() { | ||||
|         poco_information(Logger(),"Starting..."); | ||||
| 		if(KafkaManager()->Enabled()) { | ||||
| 			Thread_.start(*this); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	void EventBusManager::Stop() { | ||||
| 		if(KafkaManager()->Enabled()) { | ||||
| 			poco_information(Logger(),"Stopping..."); | ||||
| 			Running_ = false; | ||||
| 			Thread_.wakeUp(); | ||||
| 			Thread_.join(); | ||||
| 			poco_information(Logger(),"Stopped..."); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| } // namespace OpenWifi | ||||
							
								
								
									
										28
									
								
								src/framework/EventBusManager.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/framework/EventBusManager.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| // | ||||
| // Created by stephane bourque on 2022-10-26. | ||||
| // | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "Poco/Runnable.h" | ||||
| #include "Poco/Logger.h" | ||||
| #include "Poco/Thread.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
| 	class EventBusManager : public Poco::Runnable { | ||||
| 	  public: | ||||
| 		explicit EventBusManager(Poco::Logger &L); | ||||
| 		void run() final; | ||||
| 		void Start(); | ||||
| 		void Stop(); | ||||
| 		inline Poco::Logger & Logger() { return Logger_; } | ||||
|  | ||||
| 	  private: | ||||
| 		mutable std::atomic_bool 	Running_ = false; | ||||
| 		Poco::Thread		Thread_; | ||||
| 		Poco::Logger		&Logger_; | ||||
| 	}; | ||||
|  | ||||
| } // namespace OpenWifi | ||||
|  | ||||
							
								
								
									
										365
									
								
								src/framework/KafkaManager.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										365
									
								
								src/framework/KafkaManager.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,365 @@ | ||||
| // | ||||
| // Created by stephane bourque on 2022-10-25. | ||||
| // | ||||
|  | ||||
| #include "KafkaManager.h" | ||||
|  | ||||
| #include "framework/MicroServiceFuncs.h" | ||||
| #include "fmt/format.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
| 	void KafkaLoggerFun([[maybe_unused]] cppkafka::KafkaHandleBase & handle, int level, const std::string & facility, const std::string &message) { | ||||
| 		switch ((cppkafka::LogLevel) level) { | ||||
| 		case cppkafka::LogLevel::LogNotice: { | ||||
| 			poco_notice(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message)); | ||||
| 		} | ||||
| 		break; | ||||
| 		case cppkafka::LogLevel::LogDebug: { | ||||
| 			poco_debug(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message)); | ||||
| 		} | ||||
| 		break; | ||||
| 		case cppkafka::LogLevel::LogInfo: { | ||||
| 			poco_information(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message)); | ||||
| 		} | ||||
| 		break; | ||||
| 		case cppkafka::LogLevel::LogWarning: { | ||||
| 			poco_warning(KafkaManager()->Logger(), fmt::format("kafka-log: facility: {} message: {}",facility, message)); | ||||
| 		} | ||||
| 		break; | ||||
| 		case cppkafka::LogLevel::LogAlert: | ||||
| 		case cppkafka::LogLevel::LogCrit: { | ||||
| 			poco_critical(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message)); | ||||
| 		} | ||||
| 		break; | ||||
| 		case cppkafka::LogLevel::LogErr: | ||||
| 		case cppkafka::LogLevel::LogEmerg: | ||||
| 		default: { | ||||
| 			poco_error(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message)); | ||||
| 		} | ||||
| 		break; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	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)); | ||||
| 	} | ||||
|  | ||||
| 	inline void AddKafkaSecurity(cppkafka::Configuration & Config) { | ||||
| 		auto CA = MicroServiceConfigGetString("openwifi.kafka.ssl.ca.location",""); | ||||
| 		auto Certificate = MicroServiceConfigGetString("openwifi.kafka.ssl.certificate.location",""); | ||||
| 		auto Key = MicroServiceConfigGetString("openwifi.kafka.ssl.key.location",""); | ||||
| 		auto Password = MicroServiceConfigGetString("openwifi.kafka.ssl.key.password",""); | ||||
|  | ||||
| 		if(CA.empty() || Certificate.empty() || Key.empty()) | ||||
| 			return; | ||||
|  | ||||
| 		Config.set("ssl.ca.location", CA); | ||||
| 		Config.set("ssl.certificate.location", Certificate); | ||||
| 		Config.set("ssl.key.location", Key); | ||||
| 		if(!Password.empty()) | ||||
| 			Config.set("ssl.key.password", Password); | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	void KafkaManager::initialize(Poco::Util::Application & self) { | ||||
| 		SubSystemServer::initialize(self); | ||||
| 		KafkaEnabled_ = MicroServiceConfigGetBool("openwifi.kafka.enable",false); | ||||
| 	} | ||||
|  | ||||
| 	inline void KafkaProducer::run() { | ||||
|         Poco::Logger &Logger_ = Poco::Logger::create("KAFKA-PRODUCER", KafkaManager()->Logger().getChannel()); | ||||
|         poco_information(Logger_,"Starting..."); | ||||
|  | ||||
| 		Utils::SetThreadName("Kafka:Prod"); | ||||
| 		cppkafka::Configuration Config({ | ||||
| 			{ "client.id", MicroServiceConfigGetString("openwifi.kafka.client.id", "") }, | ||||
| 			{ "metadata.broker.list", MicroServiceConfigGetString("openwifi.kafka.brokerlist", "") } | ||||
| 		}); | ||||
|  | ||||
| 		AddKafkaSecurity(Config); | ||||
|  | ||||
| 		Config.set_log_callback(KafkaLoggerFun); | ||||
| 		Config.set_error_callback(KafkaErrorFun); | ||||
|  | ||||
| 		KafkaManager()->SystemInfoWrapper_ = 	R"lit({ "system" : { "id" : )lit" + | ||||
| 											 std::to_string(MicroServiceID()) + | ||||
| 											 R"lit( , "host" : ")lit" + MicroServicePrivateEndPoint() + | ||||
| 											 R"lit(" } , "payload" : )lit" ; | ||||
|  | ||||
| 		cppkafka::Producer	Producer(Config); | ||||
| 		Running_ = true; | ||||
|  | ||||
| 		Poco::AutoPtr<Poco::Notification>	Note(Queue_.waitDequeueNotification()); | ||||
| 		while(Note && Running_) { | ||||
| 			try { | ||||
| 				auto Msg = dynamic_cast<KafkaMessage *>(Note.get()); | ||||
| 				if (Msg != nullptr) { | ||||
| 					Producer.produce( | ||||
| 						cppkafka::MessageBuilder(Msg->Topic()).key(Msg->Key()).payload(Msg->Payload())); | ||||
| 				} | ||||
| 			} catch (const cppkafka::HandleException &E) { | ||||
| 				poco_warning(Logger_,fmt::format("Caught a Kafka exception (producer): {}", E.what())); | ||||
| 			} catch( const Poco::Exception &E) { | ||||
| 				Logger_.log(E); | ||||
| 			} catch (...) { | ||||
| 				poco_error(Logger_,"std::exception"); | ||||
| 			} | ||||
| 			Note = Queue_.waitDequeueNotification(); | ||||
| 		} | ||||
|         poco_information(Logger_,"Stopped..."); | ||||
| 	} | ||||
|  | ||||
| 	inline void KafkaConsumer::run() { | ||||
| 		Utils::SetThreadName("Kafka:Cons"); | ||||
|  | ||||
|         Poco::Logger &Logger_ = Poco::Logger::create("KAFKA-CONSUMER", KafkaManager()->Logger().getChannel()); | ||||
|  | ||||
|         poco_information(Logger_,"Starting..."); | ||||
|  | ||||
| 		cppkafka::Configuration Config({ | ||||
| 			{ "client.id", MicroServiceConfigGetString("openwifi.kafka.client.id","") }, | ||||
| 			{ "metadata.broker.list", MicroServiceConfigGetString("openwifi.kafka.brokerlist","") }, | ||||
| 			{ "group.id", MicroServiceConfigGetString("openwifi.kafka.group.id","") }, | ||||
| 			{ "enable.auto.commit", MicroServiceConfigGetBool("openwifi.kafka.auto.commit",false) }, | ||||
| 			{ "auto.offset.reset", "latest" } , | ||||
| 			{ "enable.partition.eof", false } | ||||
| 		}); | ||||
|  | ||||
| 		AddKafkaSecurity(Config); | ||||
|  | ||||
| 		Config.set_log_callback(KafkaLoggerFun); | ||||
| 		Config.set_error_callback(KafkaErrorFun); | ||||
|  | ||||
| 		cppkafka::TopicConfiguration topic_config = { | ||||
| 			{ "auto.offset.reset", "smallest" } | ||||
| 		}; | ||||
|  | ||||
| 		// Now configure it to be the default topic config | ||||
| 		Config.set_default_topic_configuration(topic_config); | ||||
|  | ||||
| 		cppkafka::Consumer Consumer(Config); | ||||
| 		Consumer.set_assignment_callback([&](cppkafka::TopicPartitionList& partitions) { | ||||
| 			if(!partitions.empty()) { | ||||
| 				poco_information(Logger_,fmt::format("Partition assigned: {}...", | ||||
| 																 partitions.front().get_partition())); | ||||
| 			} | ||||
| 		}); | ||||
| 		Consumer.set_revocation_callback([&](const cppkafka::TopicPartitionList& partitions) { | ||||
| 			if(!partitions.empty()) { | ||||
|                 poco_information(Logger_,fmt::format("Partition revocation: {}...", | ||||
| 																 partitions.front().get_partition())); | ||||
| 			} | ||||
| 		}); | ||||
|  | ||||
| 		bool AutoCommit = MicroServiceConfigGetBool("openwifi.kafka.auto.commit",false); | ||||
| 		auto BatchSize = MicroServiceConfigGetInt("openwifi.kafka.consumer.batchsize",20); | ||||
|  | ||||
| 		Types::StringVec    Topics; | ||||
| 		KafkaManager()->Topics(Topics); | ||||
| 		Consumer.subscribe(Topics); | ||||
|  | ||||
| 		Running_ = true; | ||||
| 		while(Running_) { | ||||
| 			try { | ||||
| 				std::vector<cppkafka::Message> MsgVec = Consumer.poll_batch(BatchSize, std::chrono::milliseconds(100)); | ||||
| 				for(auto const &Msg:MsgVec) { | ||||
| 					if (!Msg) | ||||
| 						continue; | ||||
| 					if (Msg.get_error()) { | ||||
| 						if (!Msg.is_eof()) { | ||||
| 							poco_error(Logger_,fmt::format("Error: {}", Msg.get_error().to_string())); | ||||
| 						} | ||||
| 						if(!AutoCommit) | ||||
| 							Consumer.async_commit(Msg); | ||||
| 						continue; | ||||
| 					} | ||||
| 					KafkaManager()->Dispatch(Msg.get_topic(), Msg.get_key(),Msg.get_payload() ); | ||||
| 					if (!AutoCommit) | ||||
| 						Consumer.async_commit(Msg); | ||||
| 				} | ||||
| 			} catch (const cppkafka::HandleException &E) { | ||||
| 				poco_warning(Logger_,fmt::format("Caught a Kafka exception (consumer): {}", E.what())); | ||||
| 			} catch (const Poco::Exception &E) { | ||||
| 				Logger_.log(E); | ||||
| 			} catch (...) { | ||||
| 				poco_error(Logger_,"std::exception"); | ||||
| 			} | ||||
| 		} | ||||
| 		Consumer.unsubscribe(); | ||||
|         poco_information(Logger_,"Stopped..."); | ||||
| 	} | ||||
|  | ||||
| 	void KafkaProducer::Start() { | ||||
| 		if(!Running_) { | ||||
| 			Running_=true; | ||||
| 			Worker_.start(*this); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	void KafkaProducer::Stop() { | ||||
| 		if(Running_) { | ||||
| 			Running_=false; | ||||
| 			Queue_.wakeUpAll(); | ||||
| 			Worker_.join(); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	void KafkaProducer::Produce(const std::string &Topic, const std::string &Key, const std::string &Payload) { | ||||
| 		std::lock_guard	G(Mutex_); | ||||
| 		Queue_.enqueueNotification( new KafkaMessage(Topic,Key,Payload)); | ||||
| 	} | ||||
|  | ||||
| 	void KafkaConsumer::Start() { | ||||
| 		if(!Running_) { | ||||
| 			Running_=true; | ||||
| 			Worker_.start(*this); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	void KafkaConsumer::Stop() { | ||||
| 		if(Running_) { | ||||
| 			Running_=false; | ||||
| 			Worker_.wakeUp(); | ||||
| 			Worker_.join(); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	void KafkaDispatcher::Start() { | ||||
| 		if(!Running_) { | ||||
| 			Running_=true; | ||||
| 			Worker_.start(*this); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	void KafkaDispatcher::Stop() { | ||||
| 		if(Running_) { | ||||
| 			Running_=false; | ||||
| 			Queue_.wakeUpAll(); | ||||
| 			Worker_.join(); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	auto KafkaDispatcher::RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F) { | ||||
| 		std::lock_guard G(Mutex_); | ||||
| 		auto It = Notifiers_.find(Topic); | ||||
| 		if(It == Notifiers_.end()) { | ||||
| 			Types::TopicNotifyFunctionList L; | ||||
| 			L.emplace(L.end(),std::make_pair(F,FunctionId_)); | ||||
| 			Notifiers_[Topic] = std::move(L); | ||||
| 		} else { | ||||
| 			It->second.emplace(It->second.end(),std::make_pair(F,FunctionId_)); | ||||
| 		} | ||||
| 		return FunctionId_++; | ||||
| 	} | ||||
|  | ||||
| 	void KafkaDispatcher::UnregisterTopicWatcher(const std::string &Topic, int Id) { | ||||
| 		std::lock_guard G(Mutex_); | ||||
| 		auto It = Notifiers_.find(Topic); | ||||
| 		if(It != Notifiers_.end()) { | ||||
| 			Types::TopicNotifyFunctionList & L = It->second; | ||||
| 			for(auto it=L.begin(); it!=L.end(); it++) | ||||
| 				if(it->second == Id) { | ||||
| 					L.erase(it); | ||||
| 					break; | ||||
| 				} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	void KafkaDispatcher::Dispatch(const std::string &Topic, const std::string &Key, const std::string &Payload) { | ||||
| 		std::lock_guard	G(Mutex_); | ||||
| 		auto It = Notifiers_.find(Topic); | ||||
| 		if(It!=Notifiers_.end()) { | ||||
| 			Queue_.enqueueNotification(new KafkaMessage(Topic, Key, Payload)); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	void KafkaDispatcher::run() { | ||||
|         Poco::Logger &Logger_ = Poco::Logger::create("KAFKA-DISPATCHER", KafkaManager()->Logger().getChannel()); | ||||
|         poco_information(Logger_,"Starting..."); | ||||
| 		Poco::AutoPtr<Poco::Notification>	Note(Queue_.waitDequeueNotification()); | ||||
| 		Utils::SetThreadName("kafka:dispatch"); | ||||
| 		while(Note && Running_) { | ||||
| 			auto Msg = dynamic_cast<KafkaMessage*>(Note.get()); | ||||
| 			if(Msg!= nullptr) { | ||||
| 				auto It = Notifiers_.find(Msg->Topic()); | ||||
| 				if (It != Notifiers_.end()) { | ||||
| 					const auto & FL = It->second; | ||||
| 					for(const auto &[CallbackFunc,_]:FL) { | ||||
| 						CallbackFunc(Msg->Key(), Msg->Payload()); | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			Note = Queue_.waitDequeueNotification(); | ||||
| 		} | ||||
|         poco_information(Logger_,"Stopped..."); | ||||
| 	} | ||||
|  | ||||
| 	void KafkaDispatcher::Topics(std::vector<std::string> &T) { | ||||
| 		T.clear(); | ||||
| 		for(const auto &[TopicName,_]:Notifiers_) | ||||
| 			T.push_back(TopicName); | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	int KafkaManager::Start() { | ||||
| 		if(!KafkaEnabled_) | ||||
| 			return 0; | ||||
|         ConsumerThr_.Start(); | ||||
| 		ProducerThr_.Start(); | ||||
| 		Dispatcher_.Start(); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	void KafkaManager::Stop()  { | ||||
| 		if(KafkaEnabled_) { | ||||
| 			poco_information(Logger(),"Stopping..."); | ||||
| 			Dispatcher_.Stop(); | ||||
| 			ProducerThr_.Stop(); | ||||
| 			ConsumerThr_.Stop(); | ||||
| 			poco_information(Logger(),"Stopped..."); | ||||
| 			return; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	void KafkaManager::PostMessage(const std::string &topic, const std::string & key, const std::string &PayLoad, bool WrapMessage ) { | ||||
| 		if(KafkaEnabled_) { | ||||
| 			ProducerThr_.Produce(topic,key,WrapMessage ? WrapSystemId(PayLoad) : PayLoad); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	void KafkaManager::Dispatch(const std::string &Topic, const std::string & Key, const std::string &Payload) { | ||||
| 		Dispatcher_.Dispatch(Topic, Key, Payload); | ||||
| 	} | ||||
|  | ||||
| 	[[nodiscard]] std::string KafkaManager::WrapSystemId(const std::string & PayLoad) { | ||||
| 		return SystemInfoWrapper_ + PayLoad + "}"; | ||||
| 	} | ||||
|  | ||||
| 	uint64_t KafkaManager::RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F) { | ||||
| 		if(KafkaEnabled_) { | ||||
| 			return Dispatcher_.RegisterTopicWatcher(Topic,F); | ||||
| 		} else { | ||||
| 			return 0; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	void KafkaManager::UnregisterTopicWatcher(const std::string &Topic, uint64_t Id) { | ||||
| 		if(KafkaEnabled_) { | ||||
| 			Dispatcher_.UnregisterTopicWatcher(Topic, Id); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	void KafkaManager::Topics(std::vector<std::string> &T) { | ||||
| 		Dispatcher_.Topics(T); | ||||
| 	} | ||||
|  | ||||
| 	void KafkaManager::PartitionAssignment(const cppkafka::TopicPartitionList& partitions) { | ||||
| 		poco_information(Logger(),fmt::format("Partition assigned: {}...", partitions.front().get_partition())); | ||||
| 	} | ||||
|  | ||||
| 	void KafkaManager::PartitionRevocation(const cppkafka::TopicPartitionList& partitions) { | ||||
| 		poco_information(Logger(),fmt::format("Partition revocation: {}...",partitions.front().get_partition())); | ||||
| 	} | ||||
|  | ||||
| } // namespace OpenWifi | ||||
							
								
								
									
										122
									
								
								src/framework/KafkaManager.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								src/framework/KafkaManager.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,122 @@ | ||||
| // | ||||
| // Created by stephane bourque on 2022-10-25. | ||||
| // | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "Poco/Notification.h" | ||||
| #include "Poco/NotificationQueue.h" | ||||
|  | ||||
| #include "framework/SubSystemServer.h" | ||||
| #include "framework/OpenWifiTypes.h" | ||||
| #include "framework/utils.h" | ||||
| #include "framework/KafkaTopics.h" | ||||
|  | ||||
| #include "cppkafka/cppkafka.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
| 	class KafkaMessage: public Poco::Notification { | ||||
| 	  public: | ||||
| 		KafkaMessage( const std::string &Topic, const std::string &Key, const std::string & Payload) : | ||||
| 			Topic_(Topic), Key_(Key), Payload_(Payload) { | ||||
| 		} | ||||
|  | ||||
| 		inline const std::string & Topic() { return Topic_; } | ||||
| 		inline const std::string & Key() { return Key_; } | ||||
| 		inline const std::string & Payload() { return Payload_; } | ||||
|  | ||||
| 	  private: | ||||
| 		std::string	Topic_; | ||||
| 		std::string	Key_; | ||||
| 		std::string	Payload_; | ||||
| 	}; | ||||
|  | ||||
| 	class KafkaProducer : public Poco::Runnable { | ||||
|         public: | ||||
|             void run () override; | ||||
|             void Start(); | ||||
|             void Stop(); | ||||
|             void Produce(const std::string &Topic, const std::string &Key, const std::string &Payload); | ||||
|  | ||||
| 	  private: | ||||
|             std::recursive_mutex  		Mutex_; | ||||
|             Poco::Thread        		Worker_; | ||||
|             mutable std::atomic_bool    Running_=false; | ||||
|             Poco::NotificationQueue		Queue_; | ||||
|     }; | ||||
|  | ||||
| 	class KafkaConsumer : public Poco::Runnable { | ||||
| 	  public: | ||||
| 		void run() override; | ||||
| 		void Start(); | ||||
| 		void Stop(); | ||||
|  | ||||
| 	  private: | ||||
| 		std::recursive_mutex  	    Mutex_; | ||||
| 		Poco::Thread        	    Worker_; | ||||
| 		mutable std::atomic_bool    Running_=false; | ||||
| 	}; | ||||
|  | ||||
| 	class KafkaDispatcher : public Poco::Runnable { | ||||
| 	  public: | ||||
| 		void Start(); | ||||
| 		void Stop(); | ||||
| 		auto RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F); | ||||
| 		void UnregisterTopicWatcher(const std::string &Topic, int Id); | ||||
| 		void Dispatch(const std::string &Topic, const std::string &Key, const std::string &Payload); | ||||
| 		void run() override; | ||||
| 		void Topics(std::vector<std::string> &T); | ||||
|  | ||||
| 	  private: | ||||
| 		std::recursive_mutex  		Mutex_; | ||||
| 		Types::NotifyTable      	Notifiers_; | ||||
| 		Poco::Thread        		Worker_; | ||||
| 		mutable std::atomic_bool    Running_=false; | ||||
| 		uint64_t          			FunctionId_=1; | ||||
| 		Poco::NotificationQueue		Queue_; | ||||
| 	}; | ||||
|  | ||||
| 	class KafkaManager : public SubSystemServer { | ||||
| 	  public: | ||||
|  | ||||
| 		friend class KafkaConsumer; | ||||
| 		friend class KafkaProducer; | ||||
|  | ||||
| 		inline void initialize(Poco::Util::Application & self) override; | ||||
|  | ||||
| 		static auto instance() { | ||||
| 			static auto instance_ = new KafkaManager; | ||||
| 			return instance_; | ||||
| 		} | ||||
|  | ||||
| 		int Start() override; | ||||
| 		void Stop() override; | ||||
|  | ||||
| 		void PostMessage(const std::string &topic, const std::string & key, const std::string &PayLoad, bool WrapMessage = true  ); | ||||
| 		void Dispatch(const std::string &Topic, const std::string & Key, const std::string &Payload); | ||||
| 		[[nodiscard]] std::string WrapSystemId(const std::string & PayLoad); | ||||
| 		[[nodiscard]] inline bool Enabled() const { return KafkaEnabled_; } | ||||
| 		uint64_t RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F); | ||||
| 		void UnregisterTopicWatcher(const std::string &Topic, uint64_t Id); | ||||
| 		void Topics(std::vector<std::string> &T); | ||||
|  | ||||
| 	  private: | ||||
| 		bool 				KafkaEnabled_ = false; | ||||
| 		std::string 		SystemInfoWrapper_; | ||||
| 		KafkaProducer       ProducerThr_; | ||||
|         KafkaConsumer       ConsumerThr_; | ||||
| 		KafkaDispatcher     Dispatcher_; | ||||
|  | ||||
| 		void PartitionAssignment(const cppkafka::TopicPartitionList& partitions); | ||||
| 		void PartitionRevocation(const cppkafka::TopicPartitionList& partitions); | ||||
|  | ||||
| 		KafkaManager() noexcept: | ||||
| 			SubSystemServer("KafkaManager", "KAFKA-SVR", "openwifi.kafka") { | ||||
| 		} | ||||
| 	}; | ||||
|  | ||||
| 	inline auto KafkaManager() { return KafkaManager::instance(); } | ||||
|  | ||||
| } // namespace OpenWifi | ||||
|  | ||||
| @@ -8,6 +8,7 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <string> | ||||
| namespace OpenWifi::KafkaTopics { | ||||
| 	static const std::string HEALTHCHECK{"healthcheck"}; | ||||
| 	static const std::string STATE{"state"}; | ||||
| @@ -18,6 +19,7 @@ namespace OpenWifi::KafkaTopics { | ||||
| 	static const std::string SERVICE_EVENTS{"service_events"}; | ||||
| 	static const std::string DEVICE_EVENT_QUEUE{"device_event_queue"}; | ||||
| 	static const std::string DEVICE_TELEMETRY{"device_telemetry"}; | ||||
|     static const std::string PROVISIONING_CHANGE{"provisioning_change"}; | ||||
|  | ||||
| 	namespace ServiceEvents { | ||||
| 		static const std::string EVENT_JOIN{"join"}; | ||||
|   | ||||
							
								
								
									
										712
									
								
								src/framework/MicroService.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										712
									
								
								src/framework/MicroService.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,712 @@ | ||||
| // | ||||
| // Created by stephane bourque on 2022-10-26. | ||||
| // | ||||
|  | ||||
| #include "Poco/FileChannel.h" | ||||
| #include "Poco/ConsoleChannel.h" | ||||
| #include "Poco/PatternFormatter.h" | ||||
| #include "Poco/FormattingChannel.h" | ||||
| #include "Poco/AsyncChannel.h" | ||||
| #include "Poco/NullChannel.h" | ||||
| #include "Poco/SplitterChannel.h" | ||||
| #include "Poco/Net/HTTPStreamFactory.h" | ||||
| #include "Poco/Net/HTTPSStreamFactory.h" | ||||
| #include "Poco/Net/FTPSStreamFactory.h" | ||||
| #include "Poco/Net/FTPStreamFactory.h" | ||||
| #include "Poco/Net/SSLManager.h" | ||||
| #include "Poco/JSON/JSONException.h" | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/MicroServiceErrorHandler.h" | ||||
| #include "framework/UI_WebSocketClientServer.h" | ||||
| #include "framework/MicroServiceNames.h" | ||||
| #include "framework/AuthClient.h" | ||||
| #include "framework/ALBserver.h" | ||||
| #include "framework/KafkaManager.h" | ||||
| #include "framework/RESTAPI_GenericServerAccounting.h" | ||||
| #include "framework/RESTAPI_ExtServer.h" | ||||
| #include "framework/RESTAPI_IntServer.h" | ||||
| #include "framework/utils.h" | ||||
| #include "framework/WebSocketLogger.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
| 	void MicroService::Exit(int Reason) { | ||||
| 		std::exit(Reason); | ||||
| 	} | ||||
|  | ||||
| 	void MicroService::BusMessageReceived([[maybe_unused]] const std::string &Key, const std::string & Payload) { | ||||
| 		std::lock_guard G(InfraMutex_); | ||||
| 		try { | ||||
| 			Poco::JSON::Parser P; | ||||
| 			auto Object = P.parse(Payload).extract<Poco::JSON::Object::Ptr>(); | ||||
|  | ||||
| 			if (Object->has(KafkaTopics::ServiceEvents::Fields::ID) && | ||||
| 				Object->has(KafkaTopics::ServiceEvents::Fields::EVENT)) { | ||||
| 				uint64_t 	ID = Object->get(KafkaTopics::ServiceEvents::Fields::ID); | ||||
| 				auto 		Event = Object->get(KafkaTopics::ServiceEvents::Fields::EVENT).toString(); | ||||
| 				if (ID != ID_) { | ||||
| 					if(	Event==KafkaTopics::ServiceEvents::EVENT_JOIN || | ||||
| 						Event==KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE || | ||||
| 						Event==KafkaTopics::ServiceEvents::EVENT_LEAVE ) { | ||||
| 						if(	Object->has(KafkaTopics::ServiceEvents::Fields::TYPE) && | ||||
| 							Object->has(KafkaTopics::ServiceEvents::Fields::PUBLIC) && | ||||
| 							Object->has(KafkaTopics::ServiceEvents::Fields::PRIVATE) && | ||||
| 							Object->has(KafkaTopics::ServiceEvents::Fields::VRSN) && | ||||
| 							Object->has(KafkaTopics::ServiceEvents::Fields::KEY)) { | ||||
| 							auto PrivateEndPoint = Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString(); | ||||
| 							if (Event == KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE && Services_.find(PrivateEndPoint) != Services_.end()) { | ||||
| 								Services_[PrivateEndPoint].LastUpdate = Utils::Now(); | ||||
| 							} else if (Event == KafkaTopics::ServiceEvents::EVENT_LEAVE) { | ||||
| 								Services_.erase(PrivateEndPoint); | ||||
| 								poco_debug(logger(),fmt::format("Service {} ID={} leaving system.",Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString(),ID)); | ||||
| 							} else if (Event == KafkaTopics::ServiceEvents::EVENT_JOIN || Event == KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE) { | ||||
| 								poco_debug(logger(),fmt::format("Service {} ID={} joining system.",Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString(),ID)); | ||||
| 								Services_[PrivateEndPoint] = Types::MicroServiceMeta{ | ||||
| 									.Id = ID, | ||||
| 									.Type = Poco::toLower(Object->get(KafkaTopics::ServiceEvents::Fields::TYPE).toString()), | ||||
| 									.PrivateEndPoint = Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString(), | ||||
| 									.PublicEndPoint = Object->get(KafkaTopics::ServiceEvents::Fields::PUBLIC).toString(), | ||||
| 									.AccessKey = Object->get(KafkaTopics::ServiceEvents::Fields::KEY).toString(), | ||||
| 									.Version = Object->get(KafkaTopics::ServiceEvents::Fields::VRSN).toString(), | ||||
| 									.LastUpdate = Utils::Now() }; | ||||
|  | ||||
| 								std::string SvcList; | ||||
| 								for (const auto &Svc: Services_) { | ||||
| 									if(SvcList.empty()) | ||||
| 										SvcList = Svc.second.Type; | ||||
| 									else | ||||
| 										SvcList += ", " + Svc.second.Type; | ||||
| 								} | ||||
| 								poco_information(logger(),fmt::format("Current list of microservices: {}", SvcList)); | ||||
| 							} | ||||
| 						} else { | ||||
| 							poco_error(logger(),fmt::format("KAFKA-MSG: invalid event '{}', missing a field.",Event)); | ||||
| 						} | ||||
| 					} else if (Event==KafkaTopics::ServiceEvents::EVENT_REMOVE_TOKEN) { | ||||
| 						if(Object->has(KafkaTopics::ServiceEvents::Fields::TOKEN)) { | ||||
| 	#ifndef TIP_SECURITY_SERVICE | ||||
| 							AuthClient()->RemovedCachedToken(Object->get(KafkaTopics::ServiceEvents::Fields::TOKEN).toString()); | ||||
| 	#endif | ||||
| 						} else { | ||||
| 							poco_error(logger(),fmt::format("KAFKA-MSG: invalid event '{}', missing token",Event)); | ||||
| 						} | ||||
| 					} else { | ||||
| 						poco_error(logger(),fmt::format("Unknown Event: {} Source: {}", Event, ID)); | ||||
| 					} | ||||
| 				} | ||||
| 			} else { | ||||
| 				poco_error(logger(),"Bad bus message."); | ||||
| 			} | ||||
|  | ||||
| 			auto i=Services_.begin(); | ||||
| 			auto now = Utils::Now(); | ||||
| 			for(;i!=Services_.end();) { | ||||
| 				if((now - i->second.LastUpdate)>60) { | ||||
| 					i = Services_.erase(i); | ||||
| 				} else | ||||
| 					++i; | ||||
| 			} | ||||
|  | ||||
| 		} catch (const Poco::Exception &E) { | ||||
| 			logger().log(E); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	Types::MicroServiceMetaVec MicroService::GetServices(const std::string & Type) { | ||||
| 		std::lock_guard G(InfraMutex_); | ||||
|  | ||||
| 		auto T = Poco::toLower(Type); | ||||
| 		Types::MicroServiceMetaVec	Res; | ||||
| 		for(const auto &[_,ServiceRec]:Services_) { | ||||
| 			if(ServiceRec.Type==T) | ||||
| 				Res.push_back(ServiceRec); | ||||
| 		} | ||||
| 		return Res; | ||||
| 	} | ||||
|  | ||||
| 	Types::MicroServiceMetaVec MicroService::GetServices() { | ||||
| 		std::lock_guard G(InfraMutex_); | ||||
|  | ||||
| 		Types::MicroServiceMetaVec	Res; | ||||
| 		for(const auto &[_,ServiceRec]:Services_) { | ||||
| 			Res.push_back(ServiceRec); | ||||
| 		} | ||||
| 		return Res; | ||||
| 	} | ||||
|  | ||||
| 	void MicroService::LoadConfigurationFile() { | ||||
| 		std::string Location = Poco::Environment::get(DAEMON_CONFIG_ENV_VAR,"."); | ||||
| 		ConfigFileName_ = ConfigFileName_.empty() ? Location + "/" + DAEMON_PROPERTIES_FILENAME : ConfigFileName_; | ||||
| 		Poco::Path ConfigFile(ConfigFileName_); | ||||
|  | ||||
| 		if(!ConfigFile.isFile()) | ||||
| 		{ | ||||
| 			std::cerr << DAEMON_APP_NAME << ": Configuration " | ||||
| 					  << ConfigFile.toString() << " does not seem to exist. Please set " + DAEMON_CONFIG_ENV_VAR | ||||
| 													  + " env variable the path of the " + DAEMON_PROPERTIES_FILENAME + " file." << std::endl; | ||||
| 			std::exit(Poco::Util::Application::EXIT_CONFIG); | ||||
| 		} | ||||
|  | ||||
| 		// 	    loadConfiguration(ConfigFile.toString()); | ||||
| 		PropConfigurationFile_ = new Poco::Util::PropertyFileConfiguration(ConfigFile.toString()); | ||||
| 		configPtr()->addWriteable(PropConfigurationFile_, PRIO_DEFAULT); | ||||
| 	} | ||||
|  | ||||
| 	void MicroService::Reload() { | ||||
| 		LoadConfigurationFile(); | ||||
| 		LoadMyConfig(); | ||||
| 	} | ||||
|  | ||||
| 	void MicroService::LoadMyConfig() { | ||||
| 		NoAPISecurity_ = ConfigGetBool("openwifi.security.restapi.disable",false); | ||||
| 		std::string KeyFile = ConfigPath("openwifi.service.key",""); | ||||
| 		if(!KeyFile.empty()) { | ||||
| 			std::string KeyFilePassword = ConfigPath("openwifi.service.key.password", ""); | ||||
| 			AppKey_ = Poco::SharedPtr<Poco::Crypto::RSAKey>(new Poco::Crypto::RSAKey("", KeyFile, KeyFilePassword)); | ||||
| 			Cipher_ = CipherFactory_.createCipher(*AppKey_); | ||||
| 			Signer_.setRSAKey(AppKey_); | ||||
| 			Signer_.addAllAlgorithms(); | ||||
| 			NoBuiltInCrypto_ = false; | ||||
| 		} else { | ||||
| 			NoBuiltInCrypto_ = true; | ||||
| 		} | ||||
|  | ||||
| 		ID_ = Utils::GetSystemId(); | ||||
| 		if(!DebugMode_) | ||||
| 			DebugMode_ = ConfigGetBool("openwifi.system.debug",false); | ||||
| 		MyPrivateEndPoint_ = ConfigGetString("openwifi.system.uri.private"); | ||||
| 		MyPublicEndPoint_ = ConfigGetString("openwifi.system.uri.public"); | ||||
| 		UIURI_ = ConfigGetString("openwifi.system.uri.ui"); | ||||
| 		MyHash_ = Utils::ComputeHash(MyPublicEndPoint_); | ||||
| 	} | ||||
|  | ||||
| 	void MicroService::InitializeLoggingSystem() { | ||||
| 		static auto initialized = false; | ||||
|  | ||||
| 		if(!initialized) { | ||||
| 			initialized = true; | ||||
| 			LoadConfigurationFile(); | ||||
|  | ||||
| 			auto LoggingDestination = MicroService::instance().ConfigGetString("logging.type", "file"); | ||||
| 			auto LoggingFormat = MicroService::instance().ConfigGetString("logging.format", | ||||
| 																		  "%Y-%m-%d %H:%M:%S.%i %s: [%p][thr:%I] %t"); | ||||
| 			auto UseAsyncLogs_ = MicroService::instance().ConfigGetBool("logging.asynch", true); | ||||
| 			auto DisableWebSocketLogging = MicroService::instance().ConfigGetBool("logging.websocket",false); | ||||
|  | ||||
| 			if (LoggingDestination == "null") { | ||||
| 				Poco::AutoPtr<Poco::NullChannel> DevNull(new Poco::NullChannel); | ||||
| 				Poco::Logger::root().setChannel(DevNull); | ||||
| 			} else if (LoggingDestination == "console") { | ||||
|                 SetConsoleLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat); | ||||
| 			} else if (LoggingDestination == "colorconsole") { | ||||
|                 SetColorConsoleLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat); | ||||
| 			} else if (LoggingDestination == "sql") { | ||||
|                 SetSQLLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat); | ||||
| 			} else if (LoggingDestination == "syslog") { | ||||
|                 SetSyslogLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat); | ||||
| 			} else { | ||||
|                 SetFileLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat, DAEMON_ROOT_ENV_VAR); | ||||
|             } | ||||
|  | ||||
| 			auto Level = Poco::Logger::parseLevel(MicroService::instance().ConfigGetString("logging.level", "debug")); | ||||
| 			Poco::Logger::root().setLevel(Level); | ||||
| 			if(!DisableWebSocketLogging) { | ||||
| 				static const UI_WebSocketClientServer::NotificationTypeIdVec Notifications = { | ||||
| 					{1, "log"}}; | ||||
| 				UI_WebSocketClientServer()->RegisterNotifications(Notifications); | ||||
| 			} | ||||
| 		} | ||||
|     } | ||||
|  | ||||
|     void MicroService::SetConsoleLogs(bool UseAsync, bool DisableWebSocketLogging, const std::string & FormatterPattern) { | ||||
|  | ||||
|         Poco::AutoPtr<Poco::ConsoleChannel> Console(new Poco::ConsoleChannel); | ||||
|         Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter); | ||||
|         Formatter->setProperty("pattern", FormatterPattern); | ||||
|         Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(new Poco::FormattingChannel(Formatter, Console)); | ||||
|  | ||||
|         if(DisableWebSocketLogging) { | ||||
|             if(UseAsync) { | ||||
|                 Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(FormattingChannel)); | ||||
|                 Poco::Logger::root().setChannel(Async); | ||||
|             } else { | ||||
|                 Poco::Logger::root().setChannel(FormattingChannel); | ||||
|             } | ||||
|         } else { | ||||
|             Poco::AutoPtr<WebSocketLogger>			WSLogger(new WebSocketLogger); | ||||
|             Poco::AutoPtr<Poco::SplitterChannel>	Splitter(new Poco::SplitterChannel); | ||||
|             Splitter->addChannel(WSLogger); | ||||
|             Splitter->addChannel(FormattingChannel); | ||||
|             if(UseAsync) { | ||||
|                 Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(Splitter)); | ||||
|                 Poco::Logger::root().setChannel(Async); | ||||
|             } else { | ||||
|                 Poco::Logger::root().setChannel(Splitter); | ||||
|             } | ||||
|         } | ||||
| 		Poco::Logger::root().information(fmt::format("Enabled console logs: asynch={} websocket={}",UseAsync,DisableWebSocketLogging)); | ||||
|     } | ||||
|  | ||||
|     void MicroService::SetColorConsoleLogs(bool UseAsync, bool DisableWebSocketLogging, const std::string & FormatterPattern) { | ||||
|  | ||||
|         Poco::AutoPtr<Poco::ColorConsoleChannel> Console(new Poco::ColorConsoleChannel); | ||||
|         Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter); | ||||
|         Formatter->setProperty("pattern", FormatterPattern); | ||||
|         Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(new Poco::FormattingChannel(Formatter, Console)); | ||||
|  | ||||
|         if(DisableWebSocketLogging) { | ||||
|             if(UseAsync) { | ||||
|                 Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(FormattingChannel)); | ||||
|                 Poco::Logger::root().setChannel(Async); | ||||
|             } else { | ||||
|                 Poco::Logger::root().setChannel(FormattingChannel); | ||||
|             } | ||||
|         } else { | ||||
|             Poco::AutoPtr<WebSocketLogger>			WSLogger(new WebSocketLogger); | ||||
|             Poco::AutoPtr<Poco::SplitterChannel>	Splitter(new Poco::SplitterChannel); | ||||
|             Splitter->addChannel(WSLogger); | ||||
|             Splitter->addChannel(FormattingChannel); | ||||
|             if(UseAsync) { | ||||
|                 Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(Splitter)); | ||||
|                 Poco::Logger::root().setChannel(Async); | ||||
|             } else { | ||||
|                 Poco::Logger::root().setChannel(Splitter); | ||||
|             } | ||||
|         } | ||||
| 		Poco::Logger::root().information(fmt::format("Enabled color console logs: asynch={} websocket={}",UseAsync,DisableWebSocketLogging)); | ||||
|     } | ||||
|  | ||||
|     void MicroService::SetSQLLogs([[maybe_unused]] bool UseAsync,[[maybe_unused]]  bool DisableWebSocketLogging,[[maybe_unused]]  const std::string & FormatterPattern) { | ||||
|         //"CREATE TABLE T_POCO_LOG (Source VARCHAR, Name VARCHAR, ProcessId INTEGER, Thread VARCHAR, ThreadId INTEGER, Priority INTEGER, Text VARCHAR, DateTime DATE)" | ||||
|     } | ||||
|  | ||||
|     void MicroService::SetSyslogLogs([[maybe_unused]] bool UseAsync,[[maybe_unused]]  bool DisableWebSocketLogging,[[maybe_unused]]  const std::string & FormatterPattern) { | ||||
|  | ||||
|     } | ||||
|  | ||||
|     void MicroService::SetFileLogs(bool UseAsync, bool DisableWebSocketLogging, const std::string & FormatterPattern, const std::string & root_env_var) { | ||||
|         std::string DefaultLogPath = fmt::format("${}/logs",root_env_var); | ||||
|         auto LoggingLocationDir = MicroService::instance().ConfigPath("logging.path", DefaultLogPath); | ||||
|         Poco::File      LD(LoggingLocationDir); | ||||
|         try { | ||||
|             if(!LD.exists()) { | ||||
|                 LD.createDirectory(); | ||||
|             } | ||||
|         } catch(const Poco::Exception &E) { | ||||
|             std::cout << "Cannot create " << LD.path() << "  Error: " << E.message() << std::endl; | ||||
|         } | ||||
|         auto LoggingLocationDirFilePattern = LoggingLocationDir + "/log"; | ||||
|  | ||||
|         Poco::AutoPtr<Poco::FileChannel> FileChannel(new Poco::FileChannel); | ||||
|         FileChannel->setProperty("rotation", "10 M"); | ||||
|         FileChannel->setProperty("archive", "timestamp"); | ||||
|         FileChannel->setProperty("purgeCount", "10"); | ||||
|         FileChannel->setProperty("path", LoggingLocationDirFilePattern); | ||||
|  | ||||
|         Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter); | ||||
|         Formatter->setProperty("pattern", FormatterPattern); | ||||
|         Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(new Poco::FormattingChannel(Formatter, FileChannel)); | ||||
|  | ||||
|         if(DisableWebSocketLogging) { | ||||
|             if(UseAsync) { | ||||
|                 Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(FormattingChannel)); | ||||
|                 Poco::Logger::root().setChannel(Async); | ||||
|             } else { | ||||
|                 Poco::Logger::root().setChannel(FormattingChannel); | ||||
|             } | ||||
|         } else { | ||||
|             Poco::AutoPtr<WebSocketLogger>			WSLogger(new WebSocketLogger); | ||||
|             Poco::AutoPtr<Poco::SplitterChannel>	Splitter(new Poco::SplitterChannel); | ||||
|             Splitter->addChannel(WSLogger); | ||||
|             Splitter->addChannel(FormattingChannel); | ||||
|             if(UseAsync) { | ||||
|                 Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(Splitter)); | ||||
|                 Poco::Logger::root().setChannel(Async); | ||||
|             } else { | ||||
|                 Poco::Logger::root().setChannel(Splitter); | ||||
|             } | ||||
|         } | ||||
| 		Poco::Logger::root().information(fmt::format("Enabled file logs: asynch={} websocket={}",UseAsync,DisableWebSocketLogging)); | ||||
|     } | ||||
|  | ||||
| 	void DaemonPostInitialization(Poco::Util::Application &self); | ||||
|  | ||||
| 	void MicroService::initialize(Poco::Util::Application &self) { | ||||
| 		// add the default services | ||||
| 		LoadConfigurationFile(); | ||||
| 		InitializeLoggingSystem(); | ||||
|  | ||||
| 		SubSystems_.push_back(KafkaManager()); | ||||
| 		SubSystems_.push_back(ALBHealthCheckServer()); | ||||
| 		SubSystems_.push_back(RESTAPI_ExtServer()); | ||||
| 		SubSystems_.push_back(RESTAPI_IntServer()); | ||||
| 	#ifndef TIP_SECURITY_SERVICE | ||||
| 		SubSystems_.push_back(AuthClient()); | ||||
| 	#endif | ||||
| 		Poco::Net::initializeSSL(); | ||||
| 		Poco::Net::HTTPStreamFactory::registerFactory(); | ||||
| 		Poco::Net::HTTPSStreamFactory::registerFactory(); | ||||
| 		Poco::Net::FTPStreamFactory::registerFactory(); | ||||
| 		Poco::Net::FTPSStreamFactory::registerFactory(); | ||||
|  | ||||
| 		Poco::File	DataDir(ConfigPath("openwifi.system.data")); | ||||
| 		DataDir_ = DataDir.path(); | ||||
| 		if(!DataDir.exists()) { | ||||
| 			try { | ||||
| 				DataDir.createDirectory(); | ||||
| 			} catch (const Poco::Exception &E) { | ||||
| 				logger().log(E); | ||||
| 			} | ||||
| 		} | ||||
| 		WWWAssetsDir_ = ConfigPath("openwifi.restapi.wwwassets",""); | ||||
| 		if(WWWAssetsDir_.empty()) | ||||
| 			WWWAssetsDir_ = DataDir_; | ||||
|  | ||||
| 		LoadMyConfig(); | ||||
|  | ||||
| 		InitializeSubSystemServers(); | ||||
| 		ServerApplication::initialize(self); | ||||
| 		DaemonPostInitialization(self); | ||||
|  | ||||
| 		Types::TopicNotifyFunction F = [this](const std::string &Key,const std::string &Payload) { this->BusMessageReceived(Key, Payload); }; | ||||
| 		KafkaManager()->RegisterTopicWatcher(KafkaTopics::SERVICE_EVENTS, F); | ||||
| 	} | ||||
|  | ||||
| 	void MicroService::uninitialize() { | ||||
| 		// add your own uninitialization code here | ||||
| 		ServerApplication::uninitialize(); | ||||
| 	} | ||||
|  | ||||
| 	void MicroService::reinitialize(Poco::Util::Application &self) { | ||||
| 		ServerApplication::reinitialize(self); | ||||
| 		// add your own reinitialization code here | ||||
| 	} | ||||
|  | ||||
| 	void MicroService::defineOptions(Poco::Util::OptionSet &options) { | ||||
| 		ServerApplication::defineOptions(options); | ||||
|  | ||||
| 		options.addOption( | ||||
| 			Poco::Util::Option("help", "", "display help information on command line arguments") | ||||
| 				.required(false) | ||||
| 				.repeatable(false) | ||||
| 				.callback(Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleHelp))); | ||||
|  | ||||
| 		options.addOption( | ||||
| 			Poco::Util::Option("file", "", "specify the configuration file") | ||||
| 				.required(false) | ||||
| 				.repeatable(false) | ||||
| 				.argument("file") | ||||
| 				.callback(Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleConfig))); | ||||
|  | ||||
| 		options.addOption( | ||||
| 			Poco::Util::Option("debug", "", "to run in debug, set to true") | ||||
| 				.required(false) | ||||
| 				.repeatable(false) | ||||
| 				.callback(Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleDebug))); | ||||
|  | ||||
| 		options.addOption( | ||||
| 			Poco::Util::Option("logs", "", "specify the log directory and file (i.e. dir/file.log)") | ||||
| 				.required(false) | ||||
| 				.repeatable(false) | ||||
| 				.argument("dir") | ||||
| 				.callback(Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleLogs))); | ||||
|  | ||||
| 		options.addOption( | ||||
| 			Poco::Util::Option("version", "", "get the version and quit.") | ||||
| 				.required(false) | ||||
| 				.repeatable(false) | ||||
| 				.callback(Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleVersion))); | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	void MicroService::handleHelp([[maybe_unused]] const std::string &name, [[maybe_unused]] const std::string &value) { | ||||
| 		HelpRequested_ = true; | ||||
| 		displayHelp(); | ||||
| 		stopOptionsProcessing(); | ||||
| 	} | ||||
|  | ||||
| 	void MicroService::handleVersion([[maybe_unused]] const std::string &name, [[maybe_unused]] const std::string &value) { | ||||
| 		HelpRequested_ = true; | ||||
| 		std::cout << Version() << std::endl; | ||||
| 		stopOptionsProcessing(); | ||||
| 	} | ||||
|  | ||||
| 	void MicroService::handleDebug([[maybe_unused]] const std::string &name, const std::string &value) { | ||||
| 		if(value == "true") | ||||
| 			DebugMode_ = true ; | ||||
| 	} | ||||
|  | ||||
| 	void MicroService::handleLogs([[maybe_unused]] const std::string &name, const std::string &value) { | ||||
| 		LogDir_ = value; | ||||
| 	} | ||||
|  | ||||
| 	void MicroService::handleConfig([[maybe_unused]] const std::string &name, const std::string &value) { | ||||
| 		ConfigFileName_ = value; | ||||
| 	} | ||||
|  | ||||
| 	void MicroService::displayHelp() { | ||||
| 		Poco::Util::HelpFormatter helpFormatter(options()); | ||||
| 		helpFormatter.setCommand(commandName()); | ||||
| 		helpFormatter.setUsage("OPTIONS"); | ||||
| 		helpFormatter.setHeader("A " + DAEMON_APP_NAME + " implementation for TIP."); | ||||
| 		helpFormatter.format(std::cout); | ||||
| 	} | ||||
|  | ||||
| 	void MicroService::InitializeSubSystemServers() { | ||||
| 		for(auto i:SubSystems_) { | ||||
| 			addSubsystem(i); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	void MicroService::StartSubSystemServers() { | ||||
| 		AddActivity("Starting"); | ||||
| 		for(auto i:SubSystems_) { | ||||
| 			i->Start(); | ||||
| 		} | ||||
| 		EventBusManager_ = std::make_unique<EventBusManager>(Poco::Logger::create("EventBusManager",Poco::Logger::root().getChannel(),Poco::Logger::root().getLevel())); | ||||
| 		EventBusManager_->Start(); | ||||
| 	} | ||||
|  | ||||
| 	void MicroService::StopSubSystemServers() { | ||||
| 		AddActivity("Stopping"); | ||||
| 		EventBusManager_->Stop(); | ||||
| 		for(auto i=SubSystems_.rbegin(); i!=SubSystems_.rend(); ++i) { | ||||
| 			(*i)->Stop(); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	[[nodiscard]] std::string MicroService::CreateUUID() { | ||||
| 		static std::random_device              rd; | ||||
| 		static std::mt19937_64                 gen(rd()); | ||||
| 		static std::uniform_int_distribution<> dis(0, 15); | ||||
| 		static std::uniform_int_distribution<> dis2(8, 11); | ||||
|  | ||||
| 		std::stringstream ss; | ||||
| 		int i; | ||||
| 		ss << std::hex; | ||||
| 		for (i = 0; i < 8; i++) { | ||||
| 			ss << dis(gen); | ||||
| 		} | ||||
| 		ss << "-"; | ||||
| 		for (i = 0; i < 4; i++) { | ||||
| 			ss << dis(gen); | ||||
| 		} | ||||
| 		ss << "-4"; | ||||
| 		for (i = 0; i < 3; i++) { | ||||
| 			ss << dis(gen); | ||||
| 		} | ||||
| 		ss << "-"; | ||||
| 		ss << dis2(gen); | ||||
| 		for (i = 0; i < 3; i++) { | ||||
| 			ss << dis(gen); | ||||
| 		} | ||||
| 		ss << "-"; | ||||
| 		for (i = 0; i < 12; i++) { | ||||
| 			ss << dis(gen); | ||||
| 		}; | ||||
| 		return ss.str(); | ||||
| 	} | ||||
|  | ||||
| 	bool MicroService::SetSubsystemLogLevel(const std::string &SubSystem, const std::string &Level) { | ||||
| 		try { | ||||
| 			auto P = Poco::Logger::parseLevel(Level); | ||||
| 			auto Sub = Poco::toLower(SubSystem); | ||||
|  | ||||
| 			if (Sub == "all") { | ||||
| 				for (auto i : SubSystems_) { | ||||
| 					i->Logger().setLevel(P); | ||||
| 				} | ||||
| 				return true; | ||||
| 			} else { | ||||
| 				for (auto i : SubSystems_) { | ||||
| 					if (Sub == Poco::toLower(i->Name())) { | ||||
| 						i->Logger().setLevel(P); | ||||
| 						return true; | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} catch (const Poco::Exception & E) { | ||||
| 			std::cerr << "Exception" << std::endl; | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	void MicroService::Reload(const std::string &Sub) { | ||||
| 		for (auto i : SubSystems_) { | ||||
| 			if (Poco::toLower(Sub) == Poco::toLower(i->Name())) { | ||||
| 				i->reinitialize(Poco::Util::Application::instance()); | ||||
| 				return; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	Types::StringVec MicroService::GetSubSystems() const { | ||||
| 		Types::StringVec Result; | ||||
| 		for(auto i:SubSystems_) | ||||
| 			Result.push_back(Poco::toLower(i->Name())); | ||||
| 		return Result; | ||||
| 	} | ||||
|  | ||||
| 	Types::StringPairVec MicroService::GetLogLevels() { | ||||
| 		Types::StringPairVec Result; | ||||
|  | ||||
| 		for(auto &i:SubSystems_) { | ||||
| 			auto P = std::make_pair( i->Name(), Utils::LogLevelToString(i->GetLoggingLevel())); | ||||
| 			Result.push_back(P); | ||||
| 		} | ||||
| 		return Result; | ||||
| 	} | ||||
|  | ||||
| 	const Types::StringVec & MicroService::GetLogLevelNames() { | ||||
| 		static Types::StringVec LevelNames{"none", "fatal", "critical", "error", "warning", "notice", "information", "debug", "trace" }; | ||||
| 		return LevelNames; | ||||
| 	} | ||||
|  | ||||
| 	uint64_t MicroService::ConfigGetInt(const std::string &Key,uint64_t Default) { | ||||
| 		return (uint64_t) config().getInt64(Key,Default); | ||||
| 	} | ||||
|  | ||||
| 	uint64_t MicroService::ConfigGetInt(const std::string &Key) { | ||||
| 		return config().getInt(Key); | ||||
| 	} | ||||
|  | ||||
| 	uint64_t MicroService::ConfigGetBool(const std::string &Key,bool Default) { | ||||
| 		return config().getBool(Key,Default); | ||||
| 	} | ||||
|  | ||||
| 	uint64_t MicroService::ConfigGetBool(const std::string &Key) { | ||||
| 		return config().getBool(Key); | ||||
| 	} | ||||
|  | ||||
| 	std::string MicroService::ConfigGetString(const std::string &Key,const std::string & Default) { | ||||
| 		return config().getString(Key, Default); | ||||
| 	} | ||||
|  | ||||
| 	std::string MicroService::ConfigGetString(const std::string &Key) { | ||||
| 		return config().getString(Key); | ||||
| 	} | ||||
|  | ||||
| 	std::string MicroService::ConfigPath(const std::string &Key,const std::string & Default) { | ||||
| 		std::string R = config().getString(Key, Default); | ||||
| 		return Poco::Path::expand(R); | ||||
| 	} | ||||
|  | ||||
| 	std::string MicroService::ConfigPath(const std::string &Key) { | ||||
| 		std::string R = config().getString(Key); | ||||
| 		return Poco::Path::expand(R); | ||||
| 	} | ||||
|  | ||||
| 	std::string MicroService::Encrypt(const std::string &S) { | ||||
| 		if(NoBuiltInCrypto_) { | ||||
| 			return S; | ||||
| 		} | ||||
| 		return Cipher_->encryptString(S, Poco::Crypto::Cipher::Cipher::ENC_BASE64);; | ||||
| 	} | ||||
|  | ||||
| 	std::string MicroService::Decrypt(const std::string &S) { | ||||
| 		if(NoBuiltInCrypto_) { | ||||
| 			return S; | ||||
| 		} | ||||
| 		return Cipher_->decryptString(S, Poco::Crypto::Cipher::Cipher::ENC_BASE64);; | ||||
| 	} | ||||
|  | ||||
| 	std::string MicroService::MakeSystemEventMessage( const std::string & Type ) const { | ||||
| 		Poco::JSON::Object	Obj; | ||||
| 		Obj.set(KafkaTopics::ServiceEvents::Fields::EVENT,Type); | ||||
| 		Obj.set(KafkaTopics::ServiceEvents::Fields::ID,ID_); | ||||
| 		Obj.set(KafkaTopics::ServiceEvents::Fields::TYPE,Poco::toLower(DAEMON_APP_NAME)); | ||||
| 		Obj.set(KafkaTopics::ServiceEvents::Fields::PUBLIC,MyPublicEndPoint_); | ||||
| 		Obj.set(KafkaTopics::ServiceEvents::Fields::PRIVATE,MyPrivateEndPoint_); | ||||
| 		Obj.set(KafkaTopics::ServiceEvents::Fields::KEY,MyHash_); | ||||
| 		Obj.set(KafkaTopics::ServiceEvents::Fields::VRSN,Version_); | ||||
| 		std::stringstream ResultText; | ||||
| 		Poco::JSON::Stringifier::stringify(Obj, ResultText); | ||||
| 		return ResultText.str(); | ||||
| 	} | ||||
|  | ||||
| 	[[nodiscard]] bool MicroService::IsValidAPIKEY(const Poco::Net::HTTPServerRequest &Request) { | ||||
| 		try { | ||||
| 			auto APIKEY = Request.get("X-API-KEY"); | ||||
| 			return APIKEY == MyHash_; | ||||
| 		} catch (const Poco::Exception &E) { | ||||
| 			logger().log(E); | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	void MicroService::SavePID() { | ||||
| 		try { | ||||
| 			std::ofstream O; | ||||
| 			O.open(MicroService::instance().DataDir() + "/pidfile",std::ios::binary | std::ios::trunc); | ||||
| 			O << Poco::Process::id(); | ||||
| 			O.close(); | ||||
| 		} catch (...) | ||||
| 		{ | ||||
| 			std::cout << "Could not save system ID" << std::endl; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	int MicroService::main([[maybe_unused]] const ArgVec &args) { | ||||
| 		MicroServiceErrorHandler	ErrorHandler(*this); | ||||
| 		Poco::ErrorHandler::set(&ErrorHandler); | ||||
|  | ||||
| 		if (!HelpRequested_) { | ||||
| 			SavePID(); | ||||
|  | ||||
| 			Poco::Logger &logger = Poco::Logger::get(DAEMON_APP_NAME); | ||||
| 			logger.notice(fmt::format("Starting {} version {}.",DAEMON_APP_NAME, Version())); | ||||
|  | ||||
| 			if(Poco::Net::Socket::supportsIPv6()) | ||||
| 				poco_information(logger,"System supports IPv6."); | ||||
| 			else | ||||
| 				poco_information(logger,"System does NOT support IPv6."); | ||||
|  | ||||
| 			if (config().getBool("application.runAsDaemon", false)) { | ||||
| 				poco_information(logger,"Starting as a daemon."); | ||||
| 			} | ||||
|  | ||||
| 			poco_information(logger,fmt::format("System ID set to {}",ID_)); | ||||
| 			StartSubSystemServers(); | ||||
| 			waitForTerminationRequest(); | ||||
| 			StopSubSystemServers(); | ||||
| 			logger.notice(fmt::format("Stopped {}...",DAEMON_APP_NAME)); | ||||
| 		} | ||||
|  | ||||
| 		return Application::EXIT_OK; | ||||
| 	} | ||||
|  | ||||
| 	void MicroService::AddActivity(const std::string &Activity) { | ||||
| 		if(!DataDir_.empty()) { | ||||
| 			std::string ActivityFile{ DataDir_ + "/activity.log"}; | ||||
| 			try { | ||||
| 				std::ofstream of(ActivityFile,std::ios_base::app | std::ios_base::out ); | ||||
| 				auto t = std::chrono::system_clock::now(); | ||||
| 				std::time_t now = std::chrono::system_clock::to_time_t(t); | ||||
| 				of << Activity << " at " << std::ctime(&now) ; | ||||
| 			} catch (...) { | ||||
|  | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	[[nodiscard]] std::string MicroService::Sign(Poco::JWT::Token &T, const std::string &Algo) { | ||||
| 		if(NoBuiltInCrypto_) { | ||||
| 			return T.toString(); | ||||
| 		} else { | ||||
| 			return Signer_.sign(T,Algo); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	void MicroService::DeleteOverrideConfiguration() { | ||||
| 		Poco::File	F(DataDir_ + ExtraConfigurationFilename); | ||||
|  | ||||
| 		try { | ||||
| 			if(F.exists()) | ||||
| 				F.remove(); | ||||
| 		} catch (...) { | ||||
|  | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| } | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										212
									
								
								src/framework/MicroServiceErrorHandler.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										212
									
								
								src/framework/MicroServiceErrorHandler.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,212 @@ | ||||
| // | ||||
| // Created by stephane bourque on 2022-09-29. | ||||
| // | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "fmt/format.h" | ||||
| #include "Poco/Util/Application.h" | ||||
| #include "Poco/ErrorHandler.h" | ||||
| #include "Poco/Net/NetException.h" | ||||
| #include "Poco/Net/SSLException.h" | ||||
| #include "Poco/JSON/Template.h" | ||||
| #include "Poco/JSON/JSONException.h" | ||||
| #include "Poco/Thread.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
| 	class MicroServiceErrorHandler : public Poco::ErrorHandler { | ||||
| 	  public: | ||||
| 		explicit MicroServiceErrorHandler(Poco::Util::Application &App) : App_(App) { | ||||
| 		} | ||||
|  | ||||
| 		inline void exception(const Poco::Exception & Base) override { | ||||
| 			try { | ||||
| 				if(Poco::Thread::current()!= nullptr) { | ||||
| 					t_name = Poco::Thread::current()->getName(); | ||||
| 					t_id = Poco::Thread::current()->id(); | ||||
| 				} else { | ||||
| 					t_name = "startup_code"; | ||||
| 					t_id = 0; | ||||
| 				} | ||||
|  | ||||
| 				App_.logger().log(Base); | ||||
| 				Base.rethrow(); | ||||
|  | ||||
| 			} catch (const Poco::Net::InvalidCertificateException &E) { | ||||
| 				poco_error(App_.logger(), fmt::format("Poco::Net::InvalidCertificateException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||
| 													  t_name, t_id, E.code(), | ||||
| 													  E.displayText(), | ||||
| 													  E.message(), | ||||
| 													  E.what())); | ||||
| 			} catch (const Poco::Net::InvalidSocketException &E) { | ||||
| 				poco_error(App_.logger(), fmt::format("Poco::Net::InvalidSocketException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||
| 													  t_name, t_id, E.code(), | ||||
| 													  E.displayText(), | ||||
| 													  E.message(), | ||||
| 													  E.what())); | ||||
| 			} catch (const Poco::Net::WebSocketException &E) { | ||||
| 				poco_error(App_.logger(), fmt::format("Poco::Net::WebSocketException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||
| 													  t_name, t_id, E.code(), | ||||
| 													  E.displayText(), | ||||
| 													  E.message(), | ||||
| 													  E.what())); | ||||
| 			} catch (const Poco::Net::ConnectionResetException &E) { | ||||
| 				poco_error(App_.logger(), fmt::format("Poco::Net::ConnectionResetException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||
| 													  t_name, t_id, E.code(), | ||||
| 													  E.displayText(), | ||||
| 													  E.message(), | ||||
| 													  E.what())); | ||||
| 			} catch (const Poco::Net::CertificateValidationException &E) { | ||||
| 				poco_error(App_.logger(), fmt::format("Poco::Net::CertificateValidationException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||
| 													  t_name, t_id, E.code(), | ||||
| 													  E.displayText(), | ||||
| 													  E.message(), | ||||
| 													  E.what())); | ||||
| 			} catch (const Poco::Net::SSLConnectionUnexpectedlyClosedException &E) { | ||||
| 				poco_error(App_.logger(), fmt::format("Poco::Net::SSLConnectionUnexpectedlyClosedException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||
| 													  t_name, t_id, E.code(), | ||||
| 													  E.displayText(), | ||||
| 													  E.message(), | ||||
| 													  E.what())); | ||||
| 			} catch (const Poco::Net::SSLContextException &E) { | ||||
| 				poco_error(App_.logger(), fmt::format("Poco::Net::SSLContextException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||
| 													  t_name, t_id, E.code(), | ||||
| 													  E.displayText(), | ||||
| 													  E.message(), | ||||
| 													  E.what())); | ||||
| 			} catch (const Poco::Net::SSLException &E) { | ||||
| 				poco_error(App_.logger(), fmt::format("Poco::Net::SSLException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||
| 													  t_name, t_id, E.code(), | ||||
| 													  E.displayText(), | ||||
| 													  E.message(), | ||||
| 													  E.what())); | ||||
|  | ||||
| 			} catch (const Poco::Net::InvalidAddressException &E) { | ||||
| 				poco_error(App_.logger(), fmt::format("Poco::Net::InvalidAddressException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||
| 													  t_name, t_id, E.code(), | ||||
| 													  E.displayText(), | ||||
| 													  E.message(), | ||||
| 													  E.what())); | ||||
|  | ||||
| 			} catch (const Poco::Net::NetException &E) { | ||||
| 				poco_error(App_.logger(), fmt::format("Poco::Net::NetException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||
| 													  t_name, t_id, E.code(), | ||||
| 													  E.displayText(), | ||||
| 													  E.message(), | ||||
| 													  E.what())); | ||||
|  | ||||
| 			} catch (const Poco::IOException &E) { | ||||
| 				poco_error(App_.logger(), fmt::format("Poco::IOException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||
| 													  t_name, t_id, E.code(), | ||||
| 													  E.displayText(), | ||||
| 													  E.message(), | ||||
| 													  E.what())); | ||||
| 			} catch (const Poco::TimeoutException &E) { | ||||
| 				poco_error(App_.logger(), fmt::format("Poco::TimeoutException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||
| 													  t_name, t_id, E.code(), | ||||
| 													  E.displayText(), | ||||
| 													  E.message(), | ||||
| 													  E.what())); | ||||
| 			} catch (const Poco::NoThreadAvailableException &E) { | ||||
| 				poco_error(App_.logger(), fmt::format("Poco::NoThreadAvailableException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||
| 													  t_name, t_id, E.code(), | ||||
| 													  E.displayText(), | ||||
| 													  E.message(), | ||||
| 													  E.what())); | ||||
| 			} catch (const Poco::OutOfMemoryException &E) { | ||||
| 				poco_error(App_.logger(), fmt::format("Poco::OutOfMemoryException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||
| 													  t_name, t_id, E.code(), | ||||
| 													  E.displayText(), | ||||
| 													  E.message(), | ||||
| 													  E.what())); | ||||
| 			} catch (const Poco::BadCastException &E) { | ||||
| 				poco_error(App_.logger(), fmt::format("Poco::BadCastException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||
| 													  t_name, t_id, E.code(), | ||||
| 													  E.displayText(), | ||||
| 													  E.message(), | ||||
| 													  E.what())); | ||||
| 			} catch (const Poco::DataException &E) { | ||||
| 				poco_error(App_.logger(), fmt::format("Poco::DataException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||
| 													  t_name, t_id, E.code(), | ||||
| 													  E.displayText(), | ||||
| 													  E.message(), | ||||
| 													  E.what())); | ||||
| 			} catch (const Poco::PoolOverflowException &E) { | ||||
| 				poco_error(App_.logger(), fmt::format("Poco::PoolOverflowException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||
| 													  t_name, t_id, E.code(), | ||||
| 													  E.displayText(), | ||||
| 													  E.message(), | ||||
| 													  E.what())); | ||||
| 			} catch (const Poco::SystemException &E) { | ||||
| 				poco_error(App_.logger(), fmt::format("Poco::SystemException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||
| 													  t_name, t_id, E.code(), | ||||
| 													  E.displayText(), | ||||
| 													  E.message(), | ||||
| 													  E.what())); | ||||
| 			} catch (const Poco::RuntimeException &E) { | ||||
| 				poco_error(App_.logger(), fmt::format("Poco::RuntimeException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||
| 													  t_name, t_id, E.code(), | ||||
| 													  E.displayText(), | ||||
| 													  E.message(), | ||||
| 													  E.what())); | ||||
| 			} catch (const Poco::JSON::JSONTemplateException &E) { | ||||
| 				poco_error(App_.logger(), fmt::format("Poco::JSON::JSONTemplateException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||
| 													  t_name, t_id, E.code(), | ||||
| 													  E.displayText(), | ||||
| 													  E.message(), | ||||
| 													  E.what())); | ||||
| 			} catch (const Poco::JSON::JSONException &E) { | ||||
| 				poco_error(App_.logger(), fmt::format("Poco::JSON::JSONException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||
| 													  t_name, t_id, E.code(), | ||||
| 													  E.displayText(), | ||||
| 													  E.message(), | ||||
| 													  E.what())); | ||||
| 			} catch (const Poco::ApplicationException &E) { | ||||
| 				poco_error(App_.logger(), fmt::format("Poco::ApplicationException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||
| 													  t_name, t_id, E.code(), | ||||
| 													  E.displayText(), | ||||
| 													  E.message(), | ||||
| 													  E.what())); | ||||
| 			} catch (const Poco::Exception &E) { | ||||
| 				poco_error(App_.logger(), fmt::format("Poco::Exception thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||
| 													  t_name, t_id, E.code(), | ||||
| 													  E.displayText(), | ||||
| 													  E.message(), | ||||
| 													  E.what())); | ||||
| 			} catch (...) { | ||||
| 				poco_error(App_.logger(), fmt::format("Poco:Generic thr_name={}",t_name, t_id)); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		inline void exception(const std::exception & E) override { | ||||
| 			if(Poco::Thread::current()!= nullptr) { | ||||
| 				t_name = Poco::Thread::current()->getName(); | ||||
| 				t_id = Poco::Thread::current()->id(); | ||||
| 			} else { | ||||
| 				t_name = "startup_code"; | ||||
| 				t_id = 0; | ||||
| 			} | ||||
| 			poco_warning(App_.logger(), fmt::format("std::exception in {}: {} thr_id={}", | ||||
| 													t_name,E.what(), | ||||
| 													t_id)); | ||||
| 		} | ||||
|  | ||||
| 		inline void exception() override { | ||||
| 			if(Poco::Thread::current()!= nullptr) { | ||||
| 				t_name = Poco::Thread::current()->getName(); | ||||
| 				t_id = Poco::Thread::current()->id(); | ||||
| 			} else { | ||||
| 				t_name = "startup_code"; | ||||
| 				t_id = 0; | ||||
| 			} | ||||
| 			poco_warning(App_.logger(), fmt::format("generic exception in {} thr_id={}", | ||||
| 													t_name, t_id)); | ||||
| 		} | ||||
| 	  private: | ||||
| 		Poco::Util::Application	&App_; | ||||
| 		std::string		t_name; | ||||
| 		int 			t_id=0; | ||||
| 	}; | ||||
|  | ||||
| } | ||||
							
								
								
									
										132
									
								
								src/framework/MicroServiceExtra.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								src/framework/MicroServiceExtra.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,132 @@ | ||||
| // | ||||
| // Created by stephane bourque on 2022-10-26. | ||||
| // | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <string> | ||||
| #include <map> | ||||
|  | ||||
| #include "Poco/BasicEvent.h" | ||||
| #include "Poco/ExpireLRUCache.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
| 	class ConfigurationEntry { | ||||
| 	  public: | ||||
| 		template <typename T> explicit ConfigurationEntry(T def) : | ||||
| 											 Default_(def), | ||||
| 											 Current_(def){ | ||||
| 		} | ||||
|  | ||||
| 		template <typename T> explicit ConfigurationEntry(T def, T cur, const std::string  &Hint="") : | ||||
| 																				  Default_(def), | ||||
| 																				  Current_(cur), | ||||
| 																				  Hint_(Hint){ | ||||
| 		} | ||||
|  | ||||
| 		inline ConfigurationEntry()=default; | ||||
| 		inline ~ConfigurationEntry()=default; | ||||
|  | ||||
| 		template <typename T> explicit operator T () const { return std::get<T>(Current_); } | ||||
| 		inline ConfigurationEntry & operator=(const char *v) { Current_ = std::string(v); return *this;} | ||||
| 		template <typename T> ConfigurationEntry &  operator=(T v) { Current_ = (T) v; return *this;} | ||||
|  | ||||
| 		void reset() { | ||||
| 			Current_ = Default_; | ||||
| 		} | ||||
|  | ||||
| 	  private: | ||||
| 		std::variant<bool,uint64_t,std::string> Default_, Current_; | ||||
| 		std::string Hint_; | ||||
| 	}; | ||||
| 	inline std::string to_string(const ConfigurationEntry &v) { return (std::string) v; } | ||||
|  | ||||
| 	typedef std::map<std::string,ConfigurationEntry>    ConfigurationMap_t; | ||||
|  | ||||
| 	template <typename T> class FIFO { | ||||
| 	  public: | ||||
| 		explicit FIFO(uint32_t Size) : | ||||
| 									   Size_(Size) { | ||||
| 			Buffer_ = new T [Size_]; | ||||
| 		} | ||||
|  | ||||
| 		~FIFO() { | ||||
| 			delete [] Buffer_; | ||||
| 		} | ||||
|  | ||||
| 		mutable Poco::BasicEvent<bool> Writable_; | ||||
| 		mutable Poco::BasicEvent<bool> Readable_; | ||||
|  | ||||
| 		inline bool Read(T &t) { | ||||
| 			{ | ||||
| 				std::lock_guard M(Mutex_); | ||||
| 				if (Write_ == Read_) { | ||||
| 					return false; | ||||
| 				} | ||||
|  | ||||
| 				t = Buffer_[Read_++]; | ||||
| 				if (Read_ == Size_) { | ||||
| 					Read_ = 0; | ||||
| 				} | ||||
| 				Used_--; | ||||
| 			} | ||||
| 			bool flag = true; | ||||
| 			Writable_.notify(this, flag); | ||||
| 			return true; | ||||
| 		} | ||||
|  | ||||
| 		inline bool Write(const T &t) { | ||||
| 			{ | ||||
| 				std::lock_guard M(Mutex_); | ||||
|  | ||||
| 				Buffer_[Write_++] = t; | ||||
| 				if (Write_ == Size_) { | ||||
| 					Write_ = 0; | ||||
| 				} | ||||
| 				Used_++; | ||||
| 				MaxEverUsed_ = std::max(Used_,MaxEverUsed_); | ||||
| 			} | ||||
| 			bool flag = true; | ||||
| 			Readable_.notify(this, flag); | ||||
| 			return false; | ||||
| 		} | ||||
|  | ||||
| 		inline bool isFull() { | ||||
| 			std::lock_guard M(Mutex_); | ||||
| 			return Used_==Buffer_->capacity(); | ||||
| 		} | ||||
|  | ||||
| 		inline auto MaxEverUser() const { return MaxEverUsed_; } | ||||
|  | ||||
| 	  private: | ||||
| 		std::recursive_mutex    Mutex_; | ||||
| 		uint32_t 				Size_=0; | ||||
| 		uint32_t        		Read_=0; | ||||
| 		uint32_t        		Write_=0; | ||||
| 		uint32_t 				Used_=0; | ||||
| 		uint32_t 				MaxEverUsed_=0; | ||||
| 		T	  					* Buffer_ = nullptr; | ||||
| 	}; | ||||
|  | ||||
| 	template <class Record, typename KeyType = std::string, int Size=256, int Expiry=60000> class RecordCache { | ||||
| 	  public: | ||||
| 		explicit RecordCache( KeyType Record::* Q) : | ||||
| 												   MemberOffset(Q){ | ||||
| 												   }; | ||||
| 		inline auto update(const Record &R) { | ||||
| 			return Cache_.update(R.*MemberOffset, R); | ||||
| 		} | ||||
| 		inline auto get(const KeyType &K) { | ||||
| 			return Cache_.get(K); | ||||
| 		} | ||||
| 		inline auto remove(const KeyType &K) { | ||||
| 			return Cache_.remove(K); | ||||
| 		} | ||||
| 		inline auto remove(const Record &R) { | ||||
| 			return Cache_.remove(R.*MemberOffset); | ||||
| 		} | ||||
| 	  private: | ||||
| 		KeyType Record::* MemberOffset; | ||||
| 		Poco::ExpireLRUCache<KeyType,Record>  Cache_{Size,Expiry}; | ||||
| 	}; | ||||
| } | ||||
							
								
								
									
										121
									
								
								src/framework/MicroServiceFuncs.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								src/framework/MicroServiceFuncs.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,121 @@ | ||||
| // | ||||
| // Created by stephane bourque on 2022-10-25. | ||||
| // | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/MicroServiceFuncs.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     const std::string &MicroServiceDataDirectory() { return MicroService::instance().DataDir(); } | ||||
|  | ||||
|     Types::MicroServiceMetaVec MicroServiceGetServices(const std::string &Type) { | ||||
|         return MicroService::instance().GetServices(Type); | ||||
|     } | ||||
|  | ||||
|     Types::MicroServiceMetaVec MicroServiceGetServices() { | ||||
|         return MicroService::instance().GetServices(); | ||||
|     } | ||||
|  | ||||
|     std::string MicroServicePublicEndPoint() { return MicroService::instance().PublicEndPoint(); } | ||||
|  | ||||
|     std::string MicroServiceConfigGetString(const std::string &Key, const std::string &DefaultValue) { | ||||
|         return MicroService::instance().ConfigGetString(Key, DefaultValue); | ||||
|     } | ||||
|  | ||||
|     bool MicroServiceConfigGetBool(const std::string &Key, bool DefaultValue) { | ||||
|         return MicroService::instance().ConfigGetBool(Key, DefaultValue); | ||||
|     } | ||||
|  | ||||
|     std::uint64_t MicroServiceConfigGetInt(const std::string &Key, std::uint64_t DefaultValue) { | ||||
|         return MicroService::instance().ConfigGetInt(Key, DefaultValue); | ||||
|     } | ||||
|  | ||||
|     std::string MicroServicePrivateEndPoint() { return MicroService::instance().PrivateEndPoint(); } | ||||
|  | ||||
|     std::uint64_t MicroServiceID() { return MicroService::instance().ID(); } | ||||
|  | ||||
|     bool MicroServiceIsValidAPIKEY(const Poco::Net::HTTPServerRequest &Request) { | ||||
|         return MicroService::instance().IsValidAPIKEY(Request); | ||||
|     } | ||||
|  | ||||
|     bool MicroServiceNoAPISecurity() { return MicroService::instance().NoAPISecurity(); } | ||||
|  | ||||
|     void MicroServiceLoadConfigurationFile() { MicroService::instance().LoadConfigurationFile(); } | ||||
|  | ||||
|     void MicroServiceReload() { MicroService::instance().Reload(); } | ||||
|  | ||||
|     void MicroServiceReload(const std::string &Type) { MicroService::instance().Reload(Type); } | ||||
|  | ||||
|     const Types::StringVec MicroServiceGetLogLevelNames() { | ||||
|         return MicroService::instance().GetLogLevelNames(); | ||||
|     } | ||||
|  | ||||
|     const Types::StringVec MicroServiceGetSubSystems() { | ||||
|         return MicroService::instance().GetSubSystems(); | ||||
|     } | ||||
|  | ||||
|     Types::StringPairVec MicroServiceGetLogLevels() { return MicroService::instance().GetLogLevels(); } | ||||
|  | ||||
|     bool MicroServiceSetSubsystemLogLevel(const std::string &SubSystem, const std::string &Level) { | ||||
|         return MicroService::instance().SetSubsystemLogLevel(SubSystem, Level); | ||||
|     } | ||||
|  | ||||
|     void MicroServiceGetExtraConfiguration(Poco::JSON::Object &Answer) { | ||||
|         MicroService::instance().GetExtraConfiguration(Answer); | ||||
|     } | ||||
|  | ||||
|     std::string MicroServiceVersion() { return MicroService::instance().Version(); } | ||||
|  | ||||
|     std::uint64_t MicroServiceUptimeTotalSeconds() { | ||||
|         return MicroService::instance().uptime().totalSeconds(); | ||||
|     } | ||||
|  | ||||
|     std::uint64_t MicroServiceStartTimeEpochTime() { | ||||
|         return MicroService::instance().startTime().epochTime(); | ||||
|     } | ||||
|  | ||||
|     std::string MicroServiceGetUIURI() { return MicroService::instance().GetUIURI(); } | ||||
|  | ||||
|     const SubSystemVec MicroServiceGetFullSubSystems() { | ||||
|         return MicroService::instance().GetFullSubSystems(); | ||||
|     } | ||||
|  | ||||
|     std::string MicroServiceCreateUUID() { return MicroService::CreateUUID(); } | ||||
|  | ||||
|     std::uint64_t MicroServiceDaemonBusTimer() { return MicroService::instance().DaemonBusTimer(); } | ||||
|  | ||||
|     std::string MicroServiceMakeSystemEventMessage(const std::string &Type) { | ||||
|         return MicroService::instance().MakeSystemEventMessage(Type); | ||||
|     } | ||||
|  | ||||
|     Poco::ThreadPool &MicroServiceTimerPool() { return MicroService::instance().TimerPool(); } | ||||
|  | ||||
|     std::string MicroServiceConfigPath(const std::string &Key, | ||||
|                                        const std::string &DefaultValue) { | ||||
|         return MicroService::instance().ConfigPath(Key, DefaultValue); | ||||
|     } | ||||
|  | ||||
|     std::string MicroServiceWWWAssetsDir() { | ||||
|         return MicroService::instance().WWWAssetsDir(); | ||||
|     } | ||||
|  | ||||
|     std::uint64_t MicroServiceRandom(std::uint64_t Start,std::uint64_t End) { | ||||
|         return MicroService::instance().Random(Start, End); | ||||
|     } | ||||
|  | ||||
|     std::uint64_t MicroServiceRandom(std::uint64_t Range) { | ||||
|         return MicroService::instance().Random(Range); | ||||
|     } | ||||
|  | ||||
|     std::string MicroServiceSign(Poco::JWT::Token &T, const std::string &Algo) { | ||||
|         return MicroService::instance().Sign(T, Algo); | ||||
|     } | ||||
|  | ||||
|     std::string MicroServiceGetPublicAPIEndPoint() { | ||||
|         return MicroService::instance().GetPublicAPIEndPoint(); | ||||
|     } | ||||
|  | ||||
| 	void MicroServiceDeleteOverrideConfiguration() { | ||||
| 		return MicroService::instance().DeleteOverrideConfiguration(); | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										56
									
								
								src/framework/MicroServiceFuncs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/framework/MicroServiceFuncs.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | ||||
| // | ||||
| // Created by stephane bourque on 2022-10-25. | ||||
| // | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <string> | ||||
|  | ||||
| #include "framework/OpenWifiTypes.h" | ||||
|  | ||||
| #include "Poco/Net/HTTPServerRequest.h" | ||||
| #include "Poco/JSON/Object.h" | ||||
| #include "Poco/ThreadPool.h" | ||||
| #include "Poco/JWT/Token.h" | ||||
|  | ||||
|  | ||||
| namespace OpenWifi { | ||||
| 	class SubSystemServer; | ||||
| 	using SubSystemVec=std::vector<SubSystemServer *>; | ||||
| 	const std::string & MicroServiceDataDirectory(); | ||||
| 	Types::MicroServiceMetaVec MicroServiceGetServices(const std::string & Type); | ||||
|     Types::MicroServiceMetaVec MicroServiceGetServices(); | ||||
| 	std::string MicroServicePublicEndPoint(); | ||||
| 	std::string MicroServiceConfigGetString(const std::string &Key, const std::string &DefaultValue); | ||||
| 	bool MicroServiceConfigGetBool(const std::string &Key, bool DefaultValue); | ||||
| 	std::uint64_t MicroServiceConfigGetInt(const std::string &Key, std::uint64_t DefaultValue); | ||||
| 	std::string MicroServicePrivateEndPoint(); | ||||
| 	std::uint64_t MicroServiceID(); | ||||
| 	bool MicroServiceIsValidAPIKEY(const Poco::Net::HTTPServerRequest &Request); | ||||
| 	bool MicroServiceNoAPISecurity(); | ||||
| 	void MicroServiceLoadConfigurationFile(); | ||||
| 	void MicroServiceReload(); | ||||
| 	void MicroServiceReload(const std::string &Type); | ||||
| 	const Types::StringVec MicroServiceGetLogLevelNames(); | ||||
| 	const Types::StringVec MicroServiceGetSubSystems(); | ||||
| 	Types::StringPairVec MicroServiceGetLogLevels(); | ||||
| 	bool MicroServiceSetSubsystemLogLevel(const std::string &SubSystem, const std::string &Level); | ||||
| 	void MicroServiceGetExtraConfiguration(Poco::JSON::Object &Answer); | ||||
| 	std::string MicroServiceVersion(); | ||||
| 	std::uint64_t MicroServiceUptimeTotalSeconds(); | ||||
| 	std::uint64_t MicroServiceStartTimeEpochTime(); | ||||
| 	std::string MicroServiceGetUIURI(); | ||||
| 	const SubSystemVec MicroServiceGetFullSubSystems(); | ||||
| 	std::string MicroServiceCreateUUID(); | ||||
| 	std::uint64_t MicroServiceDaemonBusTimer(); | ||||
| 	std::string MicroServiceMakeSystemEventMessage( const std::string & Type ); | ||||
| 	Poco::ThreadPool & MicroServiceTimerPool(); | ||||
| 	std::string MicroServiceConfigPath(const std::string &Key, | ||||
| 									   const std::string &DefaultValue); | ||||
|     std::string MicroServiceWWWAssetsDir(); | ||||
|     std::uint64_t MicroServiceRandom(std::uint64_t Start,std::uint64_t End); | ||||
|     std::uint64_t MicroServiceRandom(std::uint64_t Range); | ||||
|     std::string MicroServiceSign(Poco::JWT::Token &T, const std::string &Algo); | ||||
|     std::string MicroServiceGetPublicAPIEndPoint(); | ||||
| 	void MicroServiceDeleteOverrideConfiguration(); | ||||
| } | ||||
							
								
								
									
										22
									
								
								src/framework/MicroServiceNames.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/framework/MicroServiceNames.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| // | ||||
| // Created by stephane bourque on 2022-10-25. | ||||
| // | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <string> | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
| 	static const std::string uSERVICE_SECURITY{"owsec"}; | ||||
| 	static const std::string uSERVICE_GATEWAY{"owgw"}; | ||||
| 	static const std::string uSERVICE_FIRMWARE{ "owfms"}; | ||||
| 	static const std::string uSERVICE_TOPOLOGY{ "owtopo"}; | ||||
| 	static const std::string uSERVICE_PROVISIONING{ "owprov"}; | ||||
| 	static const std::string uSERVICE_OWLS{ "owls"}; | ||||
| 	static const std::string uSERVICE_SUBCRIBER{ "owsub"}; | ||||
| 	static const std::string uSERVICE_INSTALLER{ "owinst"}; | ||||
| 	static const std::string uSERVICE_ANALYTICS{ "owanalytics"}; | ||||
| 	static const std::string uSERVICE_OWRRM{ "owrrm"}; | ||||
|  | ||||
| } | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user