From 197d9acab4fb5097d3dce56227c2096abdc075bd Mon Sep 17 00:00:00 2001 From: Sebastien Douheret Date: Thu, 24 May 2018 15:48:18 +0200 Subject: Convert binding to use the controller Change-Id: Iae15b07ee768584d7a1a958fb7e119bca65c29e4 Signed-off-by: Sebastien Douheret --- .gitignore | 1 + .gitmodules | 8 +- .vscode/c_cpp_properties.json | 39 ++---- .vscode/launch.json | 5 +- .vscode/settings.json | 21 +++- CMakeLists.txt | 20 ++- LICENSE | 222 ++++++++++++++++++++++++++++---- README.md | 5 +- afb-helpers | 2 +- app-controller | 1 + conf.d/CMakeLists.txt | 20 +++ conf.d/app-templates | 2 +- conf.d/cmake/00-debian-osconfig.cmake | 1 + conf.d/cmake/00-default-osconfig.cmake | 1 + conf.d/cmake/config.cmake | 20 +-- conf.d/project/CMakeLists.txt | 20 +++ conf.d/project/etc/CMakeLists.txt | 31 +++++ conf.d/project/etc/xds-config.json | 27 ++++ conf.d/wgt/config.xml.in | 4 +- htdocs/d3js-graph.js | 2 +- htdocs/index.html | 4 +- htdocs/iotbzh-Binding.js | 2 +- src/CMakeLists.txt | 45 +++++++ src/plugins/CMakeLists.txt | 42 +++++++ src/plugins/supervisor-api.c | 164 ++++++++++++++++++++++++ src/plugins/supervisor-api.h | 36 ++++++ src/plugins/supervisor.c | 194 ++++++++++++++++++++++++++++ src/plugins/supervisor.h | 53 ++++++++ src/utils/list.c | 112 +++++++++++++++++ src/utils/list.h | 37 ++++++ src/xds-apidef.json | 154 +++++++++++++++++++++++ src/xds-binding.c | 157 +++++++++++++++++++++++ src/xds-binding.h | 32 +++++ xds-service/CMakeLists.txt | 42 ------- xds-service/supervisor-service.c | 179 -------------------------- xds-service/supervisor-service.h | 51 -------- xds-service/xds-service-api.c | 224 --------------------------------- xds-service/xds-service-api.h | 24 ---- xds-service/xds-service-apidef.h | 85 ------------- xds-service/xds-service-apidef.json | 152 ---------------------- 40 files changed, 1408 insertions(+), 833 deletions(-) create mode 160000 app-controller create mode 100644 conf.d/CMakeLists.txt create mode 100644 conf.d/cmake/00-debian-osconfig.cmake create mode 100644 conf.d/cmake/00-default-osconfig.cmake create mode 100644 conf.d/project/CMakeLists.txt create mode 100644 conf.d/project/etc/CMakeLists.txt create mode 100644 conf.d/project/etc/xds-config.json create mode 100644 src/CMakeLists.txt create mode 100644 src/plugins/CMakeLists.txt create mode 100644 src/plugins/supervisor-api.c create mode 100644 src/plugins/supervisor-api.h create mode 100644 src/plugins/supervisor.c create mode 100644 src/plugins/supervisor.h create mode 100644 src/utils/list.c create mode 100644 src/utils/list.h create mode 100644 src/xds-apidef.json create mode 100644 src/xds-binding.c create mode 100644 src/xds-binding.h delete mode 100644 xds-service/CMakeLists.txt delete mode 100644 xds-service/supervisor-service.c delete mode 100644 xds-service/supervisor-service.h delete mode 100644 xds-service/xds-service-api.c delete mode 100644 xds-service/xds-service-api.h delete mode 100644 xds-service/xds-service-apidef.h delete mode 100644 xds-service/xds-service-apidef.json diff --git a/.gitignore b/.gitignore index f8ce442..c1a510b 100644 --- a/.gitignore +++ b/.gitignore @@ -5,5 +5,6 @@ nbproject/private .*.sw* *.tar.gz __* +*apidef*h htdocs/node_modules htdocs/package-lock.json diff --git a/.gitmodules b/.gitmodules index 1900866..07a7d51 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,9 @@ [submodule "conf.d/app-templates"] path = conf.d/app-templates - url = https://gerrit.automotivelinux.org/gerrit/p/apps/app-templates.git -[submodule "ctl-utilities"] - path = ctl-utilities - url = https://gerrit.automotivelinux.org/gerrit/apps/app-controller-submodule + url = https://gerrit.automotivelinux.org/gerrit/apps/app-templates [submodule "afb-helpers"] path = afb-helpers url = https://gerrit.automotivelinux.org/gerrit/apps/app-afb-helpers-submodule +[submodule "app-controller"] + path = app-controller + url = https://gerrit.automotivelinux.org/gerrit/apps/app-controller-submodule diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 1c01abe..f7487f5 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -1,32 +1,11 @@ { "configurations": [ - { - "name": "Mac", - "includePath": [ - "/usr/include", - "/usr/local/include", - "${workspaceFolder}" - ], - "defines": [], - "intelliSenseMode": "clang-x64", - "browse": { - "path": [ - "/usr/include", - "/usr/local/include", - "${workspaceFolder}" - ], - "limitSymbolsToIncludedHeaders": true, - "databaseFilename": "" - }, - "macFrameworkPath": [ - "/System/Library/Frameworks", - "/Library/Frameworks" - ] - }, { "name": "Linux", "includePath": [ "${workspaceFolder}", + "${workspaceFolder}/afb-helpers", + "${workspaceFolder}/app-controller/ctl-lib", "/opt/AGL/include", "/usr/include/c++/4.8", "/usr/include/c++/4.8/x86_64-suse-linux", @@ -35,14 +14,18 @@ "/usr/local/include", "/usr/lib64/gcc/x86_64-suse-linux/4.8/include-fixed", "/usr/x86_64-suse-linux/include", - "/usr/include", - "${workspaceFolder}/afb-helpers" + "/usr/include" + ], + "defines": [ + "AFB_BINDING_PREV3", + "USE_API_DYN" ], - "defines": [], "intelliSenseMode": "clang-x64", "browse": { "path": [ "${workspaceFolder}", + "${workspaceFolder}/afb-helpers", + "${workspaceFolder}/app-controller/ctl-lib", "/opt/AGL/include", "/usr/include/c++/4.8", "/usr/include/c++/4.8/x86_64-suse-linux", @@ -82,5 +65,5 @@ } } ], - "version": 3 -} \ No newline at end of file + "version": 4 +} diff --git a/.vscode/launch.json b/.vscode/launch.json index b6f6fc5..b163338 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,6 +11,7 @@ "program": "/opt/AGL/bin/afb-daemon", "args": [ "--port=5678", + "--name=afb-xds", "--ws-client=unix:/tmp/supervisor", "--workdir=${workspaceRoot}/build/package/", "--ldpaths=lib", @@ -24,7 +25,9 @@ "cwd": "${workspaceRoot}/build/package", "environment": [ ], - "externalConsole": false, + "windows": { + "externalConsole": false + }, "MIMode": "gdb", "setupCommands": [ { diff --git a/.vscode/settings.json b/.vscode/settings.json index d2877c4..2777e9f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,9 +1,17 @@ { + "[json]": { + "editor.quickSuggestions": { + "strings": true + }, + "editor.tabSize": 2, + "editor.insertSpaces": true, + }, "files.associations": { "*.bb": "bat", "*.inc": "bat", "*.bbclass": "bat", "*.rules": "shellscript", + "Jenkinsfile": "declarative", "json.h": "c", "afb-binding.h": "c", "string.h": "c", @@ -28,11 +36,17 @@ "utility": "c", "supervisor-service.h": "c", "typeinfo": "c", - "istream": "c" + "istream": "c", + "xds-binding.h": "c", + "ctl-plugin.h": "c", + "unistd.h": "c", + "supervisor.h": "c", + "sstream": "c", + "stat.h": "c" }, - // Words to add to dictionary for a workspace. "cSpell.words": [ + "CTLP", "callbinder", "gotevent", "ldpaths", @@ -45,5 +59,6 @@ "replyok", "reqid", "roothttp" - ] + ], + "C_Cpp.intelliSenseEngineFallback": "Enabled" } diff --git a/CMakeLists.txt b/CMakeLists.txt index f757721..3cc33f2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,3 +1,21 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 3.3) +########################################################################### +# Copyright 2015, 2016, 2017 IoT.bzh +# +# author: Romain Forlot +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +########################################################################### + +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) include(${CMAKE_CURRENT_SOURCE_DIR}/conf.d/cmake/config.cmake) diff --git a/LICENSE b/LICENSE index 338fd9d..261eeb9 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,201 @@ -MIT License - -Copyright (c) 2017 IoT.bzh - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md index 155cb10..bef961d 100644 --- a/README.md +++ b/README.md @@ -47,10 +47,11 @@ afb-daemon --port=1234 --workdir=./build/package --ldpaths=lib --roothttp=htdocs cd $ROOT_DIR/agl-service-xds ./conf.d/autobuild/linux/autobuild build -afb-daemon --port=5678 --workdir=./build/package --ldpaths=lib --roothttp=htdocs --token= --ws-client=unix:/tmp/supervisor --ws-client=unix:/tmp/harvester -vv - +afb-daemon --port=5678 --name=afb-xds --workdir=./build/package --ldpaths=lib --roothttp=htdocs --token=1977 --ws-client=unix:/tmp/supervisor --ws-client=unix:/tmp/harvester -vv ``` +afb-client-demo -H 'localhost:5678/api?token=1977&uuid=magic' xds list + ## Deploy ### AGL diff --git a/afb-helpers b/afb-helpers index 9e88055..f9f7e1e 160000 --- a/afb-helpers +++ b/afb-helpers @@ -1 +1 @@ -Subproject commit 9e880552ea9f375de636b535c04b4729aaa1fa9a +Subproject commit f9f7e1e3d394024484df41e3d97d6b8505810f36 diff --git a/app-controller b/app-controller new file mode 160000 index 0000000..4a72302 --- /dev/null +++ b/app-controller @@ -0,0 +1 @@ +Subproject commit 4a723022410de1a72b03a4901537af4e0d27397b diff --git a/conf.d/CMakeLists.txt b/conf.d/CMakeLists.txt new file mode 100644 index 0000000..3beb009 --- /dev/null +++ b/conf.d/CMakeLists.txt @@ -0,0 +1,20 @@ +########################################################################### +# Copyright 2015, 2016, 2017 IoT.bzh +# +# author: Fulup Ar Foll +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +########################################################################### + +# This component should be included as a submodule and wont compile as standalone +project_subdirs_add() diff --git a/conf.d/app-templates b/conf.d/app-templates index a3c312e..e400fb3 160000 --- a/conf.d/app-templates +++ b/conf.d/app-templates @@ -1 +1 @@ -Subproject commit a3c312ece0a77310a9d8ecde1dd0f1267646f4ff +Subproject commit e400fb3543217ccd4e2b2a67b018bc947f09bd2c diff --git a/conf.d/cmake/00-debian-osconfig.cmake b/conf.d/cmake/00-debian-osconfig.cmake new file mode 100644 index 0000000..2ce0ad3 --- /dev/null +++ b/conf.d/cmake/00-debian-osconfig.cmake @@ -0,0 +1 @@ +list(APPEND PKG_REQUIRED_LIST lua-5.3>=5.3) diff --git a/conf.d/cmake/00-default-osconfig.cmake b/conf.d/cmake/00-default-osconfig.cmake new file mode 100644 index 0000000..a2b9325 --- /dev/null +++ b/conf.d/cmake/00-default-osconfig.cmake @@ -0,0 +1 @@ +list(APPEND PKG_REQUIRED_LIST lua>=5.3) diff --git a/conf.d/cmake/config.cmake b/conf.d/cmake/config.cmake index face63f..8ffa90d 100644 --- a/conf.d/cmake/config.cmake +++ b/conf.d/cmake/config.cmake @@ -18,9 +18,8 @@ # Project Info # ------------------ -set(PROJECT_NAME xds-service) -set(PROJECT_VERSION "1.0") -set(PROJECT_PRETTY_NAME "XDS collector service for AGL") +set(PROJECT_NAME xds) +set(PROJECT_PRETTY_NAME "XDS collector Service") set(PROJECT_DESCRIPTION "Provide an AGL XDS collector Binding") set(PROJECT_URL "https://github.com/iotbzh/agl-service-xds") set(PROJECT_ICON "icon.png") @@ -37,9 +36,6 @@ set(PROJECT_APP_TEMPLATES_DIR "conf.d/app-templates") # but used and must be built and linked. # set(PROJECT_LIBDIR "libs") -# Where are stored data for your application. Pictures, static resources must be placed in that folder. -# set(PROJECT_RESOURCES "data") - # Which directories inspect to find CMakeLists.txt target files # set(PROJECT_SRC_DIR_PATTERN "*") @@ -48,6 +44,9 @@ set(PROJECT_APP_TEMPLATES_DIR "conf.d/app-templates") set(CMAKE_BUILD_TYPE "DEBUG") #set(USE_EFENCE 1) +# Helpers Submodule parameters +set(AFB_HELPERS_QTWSCLIENT OFF CACHE BOOL "Adds QT5 WebSocket helpers from submodule") + # Kernel selection if needed. You can choose between a # mandatory version to impose a minimal version. # Or check Kernel minimal version and just print a Warning @@ -83,7 +82,6 @@ set(CMAKE_INSTALL_PREFIX $ENV{HOME}/opt) # Customize link option # ----------------------------- #list(APPEND link_libraries -an-option) -list(APPEND link_libraries afb-helpers) # Compilation options definition # Use CMake generator expressions to specify only for a specific language @@ -127,6 +125,12 @@ list(APPEND link_libraries afb-helpers) # -O2 # CACHE STRING "Compilation flags for RELEASE build type.") +set(CONTROL_SUPPORT_LUA 1) +add_definitions(-DCONTROL_PLUGIN_PATH="${CMAKE_BINARY_DIR}/package/lib/plugins:${CMAKE_BINARY_DIR}/package/var:${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}/lib/plugins") +add_definitions(-DCONTROL_CONFIG_PATH="${CMAKE_BINARY_DIR}/package/etc:${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}/etc") +add_definitions(-DCTL_PLUGIN_MAGIC=1286576532) +add_definitions(-DUSE_API_DYN=1) + # (BUG!!!) as PKG_CONFIG_PATH does not work [should be an env variable] # --------------------------------------------------------------------- set(CMAKE_PREFIX_PATH ${CMAKE_INSTALL_PREFIX}/lib64/pkgconfig ${CMAKE_INSTALL_PREFIX}/lib/pkgconfig) @@ -193,7 +197,7 @@ set(AFB_REMPORT "5678" CACHE PATH "Default binder listening port") # Print a helper message when every thing is finished # ---------------------------------------------------- -set(CLOSING_MESSAGE "Typical binding launch: afb-daemon --port=${AFB_REMPORT} --workdir=${CMAKE_BINARY_DIR}/package --ldpaths=lib --roothttp=htdocs --token=\"${AFB_TOKEN}\" --verbose --ws-client=unix:/tmp/supervisor --ws-client=unix:/tmp/harvester") +set(CLOSING_MESSAGE "Typical binding launch: afb-daemon --port=${AFB_REMPORT} --name=afb-xds --workdir=${CMAKE_BINARY_DIR}/package --ldpaths=lib --roothttp=htdocs --token=\"${AFB_TOKEN}\" --verbose --ws-client=unix:/tmp/supervisor --ws-client=unix:/tmp/harvester") set(PACKAGE_MESSAGE "Install widget file using in the target : afm-util install ${PROJECT_NAME}.wgt") # Optional schema validator about now only XML, LUA and JSON diff --git a/conf.d/project/CMakeLists.txt b/conf.d/project/CMakeLists.txt new file mode 100644 index 0000000..3beb009 --- /dev/null +++ b/conf.d/project/CMakeLists.txt @@ -0,0 +1,20 @@ +########################################################################### +# Copyright 2015, 2016, 2017 IoT.bzh +# +# author: Fulup Ar Foll +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +########################################################################### + +# This component should be included as a submodule and wont compile as standalone +project_subdirs_add() diff --git a/conf.d/project/etc/CMakeLists.txt b/conf.d/project/etc/CMakeLists.txt new file mode 100644 index 0000000..2b1e2cf --- /dev/null +++ b/conf.d/project/etc/CMakeLists.txt @@ -0,0 +1,31 @@ +########################################################################### +# Copyright 2017 IoT.bzh +# +# author: Fulup Ar Foll +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +########################################################################### + +################################################## +# Control Policy Config file +################################################## +PROJECT_TARGET_ADD(xds-config) + + file(GLOB CONF_FILES "*.json") + + add_input_files("${CONF_FILES}") + + SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES + LABELS "BINDING-CONFIG" + OUTPUT_NAME ${TARGET_NAME} + ) diff --git a/conf.d/project/etc/xds-config.json b/conf.d/project/etc/xds-config.json new file mode 100644 index 0000000..3646d3f --- /dev/null +++ b/conf.d/project/etc/xds-config.json @@ -0,0 +1,27 @@ +{ + "$schema": "http://iot.bzh/download/public/schema/json/ctl-schema.json", + "metadata": { + "uid": "XDS", + "version": "1.0", + "api": "xds", + "info": "XDS Data collection binding" + }, + "plugins": [{ + "uid": "supervisor", + "info": "Plugin to handle interface with supervisor", + "spath": "lib/plugins", + "libs": "supervisor.ctlso" + }], + + "onload": [], + + "controls": [{ + "uid": "list", + "action": "plugin://supervisor#list" + }, + { + "uid": "trace", + "action": "plugin://supervisor#trace" + } + ] +} diff --git a/conf.d/wgt/config.xml.in b/conf.d/wgt/config.xml.in index 7824795..7dab6c0 100644 --- a/conf.d/wgt/config.xml.in +++ b/conf.d/wgt/config.xml.in @@ -7,10 +7,10 @@ @PROJECT_AUTHOR@ <@PROJECT_AUTHOR_MAIL@> @PROJECT_LICENSE@ - + - + diff --git a/htdocs/d3js-graph.js b/htdocs/d3js-graph.js index 711ef50..16b8939 100644 --- a/htdocs/d3js-graph.js +++ b/htdocs/d3js-graph.js @@ -64,7 +64,7 @@ var links = [ function graphAGLBindings() { - callbinder('xds-service', 'list', {}) + callbinder('xds', 'list', {}) .then(function (res) { links = []; nodes = {}; diff --git a/htdocs/index.html b/htdocs/index.html index 2b0b605..7a3f4a8 100644 --- a/htdocs/index.html +++ b/htdocs/index.html @@ -28,13 +28,13 @@
- + - +
diff --git a/htdocs/iotbzh-Binding.js b/htdocs/iotbzh-Binding.js index ae32f83..1d28658 100644 --- a/htdocs/iotbzh-Binding.js +++ b/htdocs/iotbzh-Binding.js @@ -131,7 +131,7 @@ function init(elemID, api, verb, query) { function onopen() { // Request initial authorization - callbinder('xds-service', 'auth', ''); + callbinder('xds', 'auth', ''); document.getElementById("main").style.visibility = "visible"; document.getElementById("connected").innerHTML = "Binder WS Active"; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..df8cae1 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,45 @@ +########################################################################### +# Copyright 2018 IoT.bzh +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +########################################################################### + +# Add target to project dependency list +PROJECT_TARGET_ADD(xds) + + # Define project Targets + add_library(${TARGET_NAME} MODULE + ${TARGET_NAME}-binding.c + ) + + set(OPENAPI_DEF "xds-apidef" CACHE STRING "name and path to the JSON API definition without extension") + + target_compile_options(${TARGET_NAME} + PUBLIC -Wno-unused-variable + ) + + # Binder exposes a unique public entry point + SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES + PREFIX "afb-" + LABELS "BINDINGV2" + LINK_FLAGS ${BINDINGS_LINK_FLAG} + OUTPUT_NAME ${TARGET_NAME} + ) + + # Library dependencies (include updates automatically) + TARGET_LINK_LIBRARIES(${TARGET_NAME} + afb-helpers + ctl-utilities + ${link_libraries}) + +add_subdirectory("plugins") diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt new file mode 100644 index 0000000..1c1c557 --- /dev/null +++ b/src/plugins/CMakeLists.txt @@ -0,0 +1,42 @@ +########################################################################### +# Copyright 2015, 2016, 2017 IoT.bzh +# +# author: Romain Forlot +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +########################################################################### + +PROJECT_TARGET_ADD(supervisor) + + # Define targets + ADD_LIBRARY(${TARGET_NAME} MODULE + ${TARGET_NAME}-api.c + ${TARGET_NAME}.c + ../utils/list.c) + + # Alsa Plugin properties + SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES + LABELS "PLUGIN" + PREFIX "" + SUFFIX ".ctlso" + OUTPUT_NAME ${TARGET_NAME} + ) + + # Library dependencies (include updates automatically) + TARGET_LINK_LIBRARIES(${TARGET_NAME} + afb-helpers + ${link_libraries} + ) + + target_include_directories(${TARGET_NAME} + PRIVATE "${CMAKE_SOURCE_DIR}/app-controller/ctl-lib") diff --git a/src/plugins/supervisor-api.c b/src/plugins/supervisor-api.c new file mode 100644 index 0000000..0c1a5bc --- /dev/null +++ b/src/plugins/supervisor-api.c @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2018 "IoT.bzh" + * Author "Sebastien Douheret" + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include + +#include "ctl-plugin.h" +#include "supervisor-api.h" +#include "supervisor.h" +#include "wrap-json.h" + +CTLP_CAPI_REGISTER("supervisor"); + +CTLP_ONLOAD(plugin, ret) +{ + return 0; +} + +CTLP_CAPI(list, source, argsJ, eventJ) +{ + json_object *result, *item = NULL; + DAEMONS_T* daemons = NULL; + + getDaemons(source->api, &daemons); + if (daemons == NULL) { + AFB_ApiError(source->api, "failed"); + return ERROR; + } + + result = json_object_new_array(); + + for (int i = 0; i < daemons->count; i++) { + wrap_json_pack(&item, "{si ss sb sb so so so}", + "pid", daemons->daemons[i]->pid, + "name", daemons->daemons[i]->name, + "isServer", daemons->daemons[i]->isServer, + "isClient", daemons->daemons[i]->isClient, + "ws_servers", daemons->daemons[i]->ws_servers, + "ws_clients", daemons->daemons[i]->ws_clients, + "apis", daemons->daemons[i]->apis); + //, "config", daemons->daemons[i]->config); + json_object_array_add(result, item); + } + AFB_ReqSucess(source->request, result, NULL); + return 0; +} + +CTLP_CAPI(trace, source, argsJ, eventJ) +{ + int rc; + json_object* result = NULL; + DAEMONS_T* daemons = NULL; + const char* ws_name; + const char* wsn; + + if (wrap_json_unpack(argsJ, "{s:?s}", "ws", &ws_name)) { + AFB_ReqFail(source->request, "Failed", "Error processing arguments."); + return ERROR; + } + AFB_ApiNotice(source->api, "Trace ws: %s", ws_name); + + getDaemons(source->api, &daemons); + if (daemons == NULL || daemons->count <= 0) { + AFB_ReqFail(source->request, "failed", "No daemon found"); + } + + // search server and client pid + DAEMON_T *pid_s = NULL, *pid_c = NULL; + for (int i = 0; i < daemons->count; i++) { + AFB_ApiDebug(source->api, "_DEBUG_ svr %s", + json_object_to_json_string(daemons->daemons[i]->ws_servers)); + AFB_ApiDebug(source->api, "_DEBUG_ cli %s", + json_object_to_json_string(daemons->daemons[i]->ws_clients)); + + json_object* ws_servers = daemons->daemons[i]->ws_servers; + for (int j = 0; j < json_object_array_length(ws_servers); j++) { + + wsn = json_object_get_string(json_object_array_get_idx(ws_servers, j++)); + if (wsn && strstr(wsn, ws_name) != NULL) { + pid_s = daemons->daemons[i]; + break; + } + } + + json_object* ws_clients = daemons->daemons[i]->ws_clients; + for (int j = 0; j < json_object_array_length(ws_clients); j++) { + wsn = json_object_get_string(json_object_array_get_idx(ws_clients, j++)); + if (wsn && strstr(wsn, ws_name) != NULL) { + pid_c = daemons->daemons[i]; + break; + } + } + + if (pid_s != NULL && pid_c != NULL) { + if ((rc = trace_exchange(source->api, pid_s, pid_c)) < 0) { + AFB_ReqFailF(source->request, "failed", "Trace error %d", rc); + } + break; + } + } + + if (pid_s == NULL || pid_c == NULL) { + AFB_ReqFail(source->request, "failed", "Cannot determine Server or Client"); + return ERROR; + } + + AFB_ReqSucessF(source->request, result, "Tracing Server pid=%d <-> Client pid=%d", pid_s->pid, pid_c->pid); + + return 0; +} + +/* SEB TODO +void xds_event_cb(const char* evtname, json_object* j_event) +{ + int rc; + METRIC_T metric; + const char* type = NULL; + struct json_object* request = NULL; + + AFB_NOTICE("RECV Event %s : %s", evtname, + json_object_to_json_string(j_event)); + + if (strcmp(evtname, "supervisor/trace") != 0) { + return; + } + + if ((rc = wrap_json_unpack(j_event, "{s:?s}", "type", &type)) < 0) { + AFB_ERROR("Cannot decode event type"); + return; + } + + if (strcmp(type, "request") == 0) { + + if (!json_object_object_get_ex(j_event, "request", &request)) { + AFB_ERROR("Cannot decode event request"); + return; + } + metric.name = "trace"; + metric.data = request; + + rc = harvester_post_data(&metric); + if (rc < 0) { + AFB_ERROR("ERROR harvester_post_data: rc %d", rc); + } + } +} +*/ diff --git a/src/plugins/supervisor-api.h b/src/plugins/supervisor-api.h new file mode 100644 index 0000000..beadeca --- /dev/null +++ b/src/plugins/supervisor-api.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2018 "IoT.bzh" + * Author "Sebastien Douheret" + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include +#include "wrap-json.h" +#include "filescan-utils.h" + +#define SRV_HARVESTER_NAME "harvester" + +#define META_SOURCENAME GetBinderName(); +#define META_IDENTITY "" // FIXME + +#ifndef ERROR + #define ERROR -1 +#endif + +typedef struct metric_t { + char* name; + json_object* data; + struct timespec timestamp; +} METRIC_T; diff --git a/src/plugins/supervisor.c b/src/plugins/supervisor.c new file mode 100644 index 0000000..649713e --- /dev/null +++ b/src/plugins/supervisor.c @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2018 "IoT.bzh" + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#define _GNU_SOURCE +#include +#include +#include + +#include "ctl-plugin.h" +#include "supervisor-api.h" +#include "supervisor.h" +#include "wrap-json.h" + +struct afb_cred { + int refcount; + uid_t uid; + gid_t gid; + pid_t pid; + const char* user; + const char* label; + const char* id; +}; + +static const char* null_str = "null"; + +struct decode_daemon_str { + DAEMONS_T* daemons; + AFB_ApiT api; + const char* ignored_daemon; +}; + +static void decode_daemons_cb(void* closure, json_object* obj, const char* fName) +{ + int rc; + struct afb_cred cred; + json_object *j_response, *j_query, *j_config, *j_ws_servers, *j_ws_clients; + json_object *j_name, *j_apis; + struct decode_daemon_str* clStr = (struct decode_daemon_str*)closure; + DAEMON_T* daemon = calloc(sizeof(DAEMON_T), 1); + + if (!clStr->daemons) + return; + + if ((rc = wrap_json_unpack(obj, "{si si si ss ss ss}", "pid", &cred.pid, + "uid", &cred.uid, "gid", &cred.gid, "id", &cred.id, + "label", &cred.label, "user", &cred.user)) + < 0) { + // TODO + return; + } + + AFB_ApiInfo(clStr->api, "Get config of pid %d", cred.pid); + daemon->pid = cred.pid; + + // Get config + wrap_json_pack(&j_query, "{s:i}", "pid", cred.pid); + rc = AFB_ServiceSync(clStr->api, SRV_SUPERVISOR_NAME, "config", j_query, &j_response); + if (rc < 0) { + AFB_ApiError(clStr->api, "Cannot get config of pid %d", cred.pid); + return; + } + + AFB_ApiDebug(clStr->api, "%s config result, res=%s", SRV_SUPERVISOR_NAME, + json_object_to_json_string(j_response)); + + if (json_object_object_get_ex(j_response, "response", &j_config)) { + // FIXME : implement free + daemon->config = j_config; + + rc = wrap_json_unpack(j_config, "{s:o s:o s:o}", + "name", &j_name, + "ws_servers", &j_ws_servers, + "ws_clients", &j_ws_clients); + if (rc < 0) { + AFB_ApiError(clStr->api, "Error decoding config response %s", wrap_json_get_error_string(rc)); + return; + } + + daemon->name = json_object_is_type(j_name, json_type_null) ? null_str : json_object_get_string(j_name); + + // ignored some daemon + if (clStr->ignored_daemon != NULL && strstr(daemon->name, clStr->ignored_daemon) != NULL) { + free(daemon); + return; + } + + daemon->ws_servers = j_ws_servers; + daemon->isServer = (json_object_array_length(j_ws_servers) > 0); + daemon->ws_clients = j_ws_clients; + daemon->isClient = (json_object_array_length(j_ws_clients) > 0); + } + + // Get apis + // '{"pid":6262,"api":"monitor","verb":"get","args":{"apis":true}} + wrap_json_pack(&j_query, "{si ss ss s {sb}}", + "pid", cred.pid, + "api", "monitor", + "verb", "get", + "args", "apis", true); + rc = AFB_ServiceSync(clStr->api, SRV_SUPERVISOR_NAME, "do", j_query, &j_response); + if (rc < 0) { + AFB_ApiError(clStr->api, "Cannot get apis of pid %d", cred.pid); + return; + } else { + AFB_ApiDebug(clStr->api, "%s do ...get apis result, res=%s", SRV_SUPERVISOR_NAME, json_object_to_json_string(j_response)); + + if (json_object_object_get_ex(j_response, "response", &j_config) && json_object_object_get_ex(j_config, "apis", &j_apis)) { + daemon->apis = j_apis; + } + } + clStr->daemons->daemons[clStr->daemons->count] = daemon; + clStr->daemons->count++; +} + +int getDaemons(AFB_ApiT apiHandle, DAEMONS_T** daemons) +{ + int rc; + json_object *j_response, *j_daemons = NULL; + + *daemons = calloc(sizeof(DAEMONS_T), 1); + + if ((rc = AFB_ServiceSync(apiHandle, SRV_SUPERVISOR_NAME, "discover", NULL, + &j_response)) + < 0) { + return rc; + } + + if ((rc = AFB_ServiceSync(apiHandle, SRV_SUPERVISOR_NAME, "list", NULL, + &j_response)) + < 0) { + return rc; + } + + AFB_ApiDebug(apiHandle, "%s list result, res=%s", SRV_SUPERVISOR_NAME, json_object_to_json_string(j_response)); + + if (json_object_object_get_ex(j_response, "response", &j_daemons)) { + struct decode_daemon_str str = { + *daemons, + apiHandle, + GetBinderName() + }; + wrap_json_object_for_all(j_daemons, decode_daemons_cb, &str); + } + + return 0; +} + +int trace_exchange(AFB_ApiT apiHandle, DAEMON_T* svr, DAEMON_T* cli) +{ + int rc; + json_object *j_response, *j_query; + + if (svr == NULL || cli == NULL) { + return -1; + } + + wrap_json_pack(&j_query, "{s:i, s:{s:s}}", "pid", svr->pid, "add", + "request", "common"); + if ((rc = AFB_ServiceSync(apiHandle, SRV_SUPERVISOR_NAME, "trace", j_query, + &j_response)) + < 0) { + AFB_ApiError(apiHandle, "ERROR trace %d result: %s", svr->pid, + json_object_to_json_string(j_response)); + return rc; + } + + wrap_json_pack(&j_query, "{s:i}", "pid", cli->pid); + if ((rc = AFB_ServiceSync(apiHandle, SRV_SUPERVISOR_NAME, "trace", j_query, + &j_response)) + < 0) { + AFB_ApiError(apiHandle, "ERROR trace %d result: %s", cli->pid, + json_object_to_json_string(j_response)); + return rc; + } + + return 0; +} + +int supervisor_init(void) +{ + return 0; +} diff --git a/src/plugins/supervisor.h b/src/plugins/supervisor.h new file mode 100644 index 0000000..3311734 --- /dev/null +++ b/src/plugins/supervisor.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2018 "IoT.bzh" + * Author "Sebastien Douheret" + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include +#include "wrap-json.h" + +#define SRV_SUPERVISOR_NAME "supervisor" + +// FIXME Use chained list instead of static array +#define MAX_CLIENTS 32 +#define MAX_SERVERS 32 +#define MAX_DAEMONS 1024 + + +typedef struct daemon +{ + int pid; + const char* name; + bool isServer; + bool isClient; + //char *ws_clients[MAX_CLIENTS]; + //char *ws_servers[MAX_SERVERS]; + json_object *ws_clients; + json_object *ws_servers; + json_object *config; + json_object *apis; +} DAEMON_T; + +typedef struct daemons_result_ +{ + int count; + DAEMON_T *daemons[MAX_DAEMONS]; +} DAEMONS_T; + + +extern int getDaemons(AFB_ApiT apiHandle, DAEMONS_T **daemons); +extern int trace_exchange(AFB_ApiT apiHandle, DAEMON_T *svr, DAEMON_T *cli); +extern int supervisor_init(void); diff --git a/src/utils/list.c b/src/utils/list.c new file mode 100644 index 0000000..d47f761 --- /dev/null +++ b/src/utils/list.c @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2018 "IoT.bzh" + * Author "Romain Forlot" + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "list.h" +#include "string.h" + +void destroy_list(struct list *l) +{ + struct list *save; + while(l != NULL) { + save = l->next; + free(l); + l = save; + } +} + +void add_elt(struct list **l, const char *key, json_object *value) +{ + struct list *new_elt = malloc(sizeof(struct list)); + new_elt->key = key; + new_elt->value = value; + new_elt->next = NULL; + + if(*l) { + while((*l)->next != NULL) { + *l = (*l)->next; + } + (*l)->next = new_elt; + } + else { + *l = new_elt; + } +} + +void add_key(struct list **l, const char *key) +{ + struct list *new_elt = malloc(sizeof(struct list)); + new_elt->key = key; + new_elt->value = NULL; + new_elt->next = NULL; + + if(*l) { + while((*l)->next != NULL) { + *l = (*l)->next; + } + (*l)->next = new_elt; + } + else { + *l = new_elt; + } +} + +int set_value(struct list *l, json_object *val, int index) +{ + int i; + + for (i = 0; i < index; i++) { + l = l->next; + if ( l == NULL ) + return -1; + } + + l->value = val; + return 0; +} + +struct list *get_elt(struct list *l, int index) +{ + int i; + + for (i = 0; i < index; i++) { + l = l->next; + if ( l == NULL ) + return NULL; + } + + return l; +} + +struct list *find_elt_from_key(struct list *l, const char *key) +{ + while(l != NULL) { + if(strcasecmp(l->key, key) == 0) + return l; + l = l->next; + } + return NULL; +} + +json_object *find_key_value(struct list *l, const char *key) +{ + while(l != NULL) { + if(strcasecmp(l->key, key) == 0) + return l->value; + l = l->next; + } + return NULL; +} diff --git a/src/utils/list.h b/src/utils/list.h new file mode 100644 index 0000000..9f93cb6 --- /dev/null +++ b/src/utils/list.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2018 "IoT.bzh" + * Author "Romain Forlot" + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _LIST_H_ +#define _LIST_H_ + +#include +#include + +struct list { + const char *key; + json_object *value; + struct list *next; +}; + +void destroy_list(struct list *l); +void add_elt(struct list **l, const char *key, json_object *value); +void add_key(struct list **l, const char *key); +int set_value(struct list *l, json_object *val, int index); +struct list *get_elt(struct list *l, int index); +struct list *find_elt_from_key(struct list *l, const char *key); +json_object *find_key_value(struct list *l, const char *key); + +#endif diff --git a/src/xds-apidef.json b/src/xds-apidef.json new file mode 100644 index 0000000..949e3e8 --- /dev/null +++ b/src/xds-apidef.json @@ -0,0 +1,154 @@ +{ + "openapi": "3.0.0", + "$schema": "http://iot.bzh/download/openapi/schema-3.0/default-schema.json", + "info": { + "description": "", + "title": "xds", + "version": "4.0", + "x-binding-c-generator": { + "api": "xds", + "version": 2, + "prefix": "afv_", + "postfix": "", + "start": null , + "onevent": null, + "init": "init", + "scope": "", + "private": false + } + }, + "servers": [ + { + "url": "ws://{host}:{port}/api/monitor", + "description": "TS caching binding", + "variables": { + "host": { + "default": "localhost" + }, + "port": { + "default": "1234" + } + }, + "x-afb-events": [ + { + "$ref": "#/components/schemas/afb-event" + } + ] + } + ], + "components": { + "schemas": { + "afb-reply": { + "$ref": "#/components/schemas/afb-reply-v2" + }, + "afb-event": { + "$ref": "#/components/schemas/afb-event-v2" + }, + "afb-reply-v2": { + "title": "Generic response.", + "type": "object", + "required": [ "jtype", "request" ], + "properties": { + "jtype": { + "type": "string", + "const": "afb-reply" + }, + "request": { + "type": "object", + "required": [ "status" ], + "properties": { + "status": { "type": "string" }, + "info": { "type": "string" }, + "token": { "type": "string" }, + "uuid": { "type": "string" }, + "reqid": { "type": "string" } + } + }, + "response": { "type": "object" } + } + }, + "afb-event-v2": { + "type": "object", + "required": [ "jtype", "event" ], + "properties": { + "jtype": { + "type": "string", + "const": "afb-event" + }, + "event": { "type": "string" }, + "data": { "type": "object" } + } + } + }, + "x-permissions": { + "list": { + "permission": "urn:AGL:permission::platform:can:list " + }, + "trace": { + "permission": "urn:AGL:permission::platform:can:trace " + } + }, + "responses": { + "200": { + "description": "A complex object array response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/afb-reply" + } + } + } + } + } + }, + "paths": { + "/auth": { + "description": "Authenticate session to raise Level Of Assurance of the session", + "get": { + "x-permissions": { + "$ref": "#/components/x-permissions/list" + }, + "responses": { + "200": { + "$ref": "#/components/responses/200" + } + } + } + }, + "/list": { + "description": "list ", + "get": { + "x-permissions": { + "LOA": 1 + }, + "parameters": [], + "responses": { + "200": { + "$ref": "#/components/responses/200" + } + } + } + }, + "/trace": { + "description": "trace ", + "get": { + "x-permissions": { + "LOA": 1 + }, + "parameters": [{ + "in": "query", + "name": "ws", + "required": true, + "schema": { + "type": "string" + } + }], + "responses": { + "200": { + "$ref": "#/components/responses/200" + } + } + } + } + } +} diff --git a/src/xds-binding.c b/src/xds-binding.c new file mode 100644 index 0000000..4f7971f --- /dev/null +++ b/src/xds-binding.c @@ -0,0 +1,157 @@ +/* +* Copyright (C) 2016 "IoT.bzh" +* Author Fulup Ar Foll +* Author Romain Forlot +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#define _GNU_SOURCE +#include +#include +#include + +#include "xds-binding.h" + + +// default api to print log when apihandle not avaliable +afb_dynapi *AFB_default; + +// Config Section definition (note: controls section index should match handle +// retrieval in HalConfigExec) +static CtlSectionT ctrlSections[] = { + {.key = "plugins" , .loadCB = PluginConfig}, + {.key = "onload" , .loadCB = OnloadConfig}, + {.key = "controls", .loadCB = ControlConfig}, + {.key = "events" , .loadCB = EventConfig}, + {.key = NULL} +}; + +static void ctrlapi_ping(AFB_ReqT request) { + static int count = 0; + + count++; + AFB_ReqNotice(request, "Controller:ping count=%d", count); + AFB_ReqSucess(request, json_object_new_int(count), NULL); + + return; +} + +void ctrlapi_auth(AFB_ReqT request) +{ + AFB_ReqSetLOA(request, 1); + AFB_ReqSucess(request, NULL, NULL); +} + +static AFB_ApiVerbs CtrlApiVerbs[] = { + /* VERB'S NAME FUNCTION TO CALL SHORT DESCRIPTION */ + {.verb = "ping", .callback = ctrlapi_ping, .info = "ping test for API"}, + {.verb = "auth", .callback = ctrlapi_auth, .info = "Authenticate session to raise Level Of Assurance of the session"}, + {.verb = NULL} /* marker for end of the array */ +}; + +static int CtrlLoadStaticVerbs(afb_dynapi *apiHandle, AFB_ApiVerbs *verbs) { + int errcount = 0; + + for (int idx = 0; verbs[idx].verb; idx++) { + errcount += afb_dynapi_add_verb( + apiHandle, CtrlApiVerbs[idx].verb, NULL, CtrlApiVerbs[idx].callback, + (void *)&CtrlApiVerbs[idx], CtrlApiVerbs[idx].auth, 0); + } + + return errcount; +}; + +static int CtrlInitOneApi(AFB_ApiT apiHandle) { + int err = 0; + AFB_default = apiHandle; // hugely hack to make all V2 AFB_DEBUG to work in fileutils + + // retrieve section config from api handle + CtlConfigT *ctrlConfig = (CtlConfigT *)afb_dynapi_get_userdata(apiHandle); + err = CtlConfigExec(apiHandle, ctrlConfig); + if(err) { + AFB_ApiError(apiHandle, "Error at CtlConfigExec step"); + return err; + } + + return err; +} + +// next generation dynamic API-V3 mode +#include + +static int CtrlLoadOneApi(void *cbdata, AFB_ApiT apiHandle) { + CtlConfigT *ctrlConfig = (CtlConfigT *)cbdata; + + // save closure as api's data context + afb_dynapi_set_userdata(apiHandle, ctrlConfig); + + // add static controls verbs + int err = CtrlLoadStaticVerbs(apiHandle, CtrlApiVerbs); + if (err) { + AFB_ApiError(apiHandle, "CtrlLoadSection fail to register static V2 verbs"); + return ERROR; + } + + // load section for corresponding API + err = CtlLoadSections(apiHandle, ctrlConfig, ctrlSections); + + // declare an event event manager for this API; + afb_dynapi_on_event(apiHandle, CtrlDispatchApiEvent); + + // init API function (does not receive user closure ??? + afb_dynapi_on_init(apiHandle, CtrlInitOneApi); + + afb_dynapi_seal(apiHandle); + return err; +} + +int afbBindingVdyn(afb_dynapi *apiHandle) { + + AFB_default = apiHandle; + AFB_ApiNotice(apiHandle, "Controller in afbBindingVdyn"); + + const char *dirList = getenv("CONTROL_CONFIG_PATH"); + if (!dirList) + dirList = CONTROL_CONFIG_PATH; + + const char *configPath = CtlConfigSearch(apiHandle, dirList, ""); + if (!configPath) { + AFB_ApiError(apiHandle, "CtlPreInit: No %s* config found in %s ", GetBinderName(), dirList); + return ERROR; + } + + // load config file and create API + CtlConfigT *ctrlConfig = CtlLoadMetaData(apiHandle, configPath); + if (!ctrlConfig) { + AFB_ApiError(apiHandle, + "CtrlBindingDyn No valid control config file in:\n-- %s", + configPath); + return ERROR; + } + + if (!ctrlConfig->api) { + AFB_ApiError(apiHandle, + "CtrlBindingDyn API Missing from metadata in:\n-- %s", + configPath); + return ERROR; + } + + AFB_ApiNotice(apiHandle, "Controller API='%s' info='%s'", ctrlConfig->api, + ctrlConfig->info); + + // create one API per config file (Pre-V3 return code ToBeChanged) + int status = afb_dynapi_new_api(apiHandle, ctrlConfig->api, ctrlConfig->info, 1, CtrlLoadOneApi, ctrlConfig); + + return status; +} diff --git a/src/xds-binding.h b/src/xds-binding.h new file mode 100644 index 0000000..7ac00a0 --- /dev/null +++ b/src/xds-binding.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2016 "IoT.bzh" + * Author Fulup Ar Foll + * Author Romain Forlot + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef _CTL_BINDING_INCLUDE_ +#define _CTL_BINDING_INCLUDE_ + +#include +#include +#include +#include + +#ifndef ERROR + #define ERROR -1 +#endif + +#endif /* _CTL_BINDING_INCLUDE_ */ diff --git a/xds-service/CMakeLists.txt b/xds-service/CMakeLists.txt deleted file mode 100644 index 9ce0b81..0000000 --- a/xds-service/CMakeLists.txt +++ /dev/null @@ -1,42 +0,0 @@ -########################################################################### -# Copyright 2018 IoT.bzh -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -########################################################################### - -# Add target to project dependency list -PROJECT_TARGET_ADD(xds-service) - - # Define project Targets - file(GLOB sourcelist "*.c") - - # Define project Targets - ADD_LIBRARY(${TARGET_NAME} MODULE ${sourcelist}) - - target_compile_options(${TARGET_NAME} - PUBLIC -Wno-unused-variable - ) - - - # Binder exposes a unique public entry point - SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES - PREFIX "afb-" - LABELS "BINDINGV2" - LINK_FLAGS ${BINDINGS_LINK_FLAG} - OUTPUT_NAME ${TARGET_NAME} - ) - - TARGET_LINK_LIBRARIES(${TARGET_NAME} - afb-helpers - ${link_libraries} - ) diff --git a/xds-service/supervisor-service.c b/xds-service/supervisor-service.c deleted file mode 100644 index 96955fa..0000000 --- a/xds-service/supervisor-service.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (C) 2018 "IoT.bzh" - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#define _GNU_SOURCE -#include "supervisor-service.h" -#include "xds-service-api.h" -#include -#include -#include - -#include "curl-wrap.h" -#include "wrap-json.h" - -#define SRV_SUPERVISOR_NAME "supervisor" - -struct afb_cred { - int refcount; - uid_t uid; - gid_t gid; - pid_t pid; - const char* user; - const char* label; - const char* id; -}; - -static const char* null_str = "null"; - -static void decode_daemons_cb(void* closure, json_object* obj, - const char* resp) -{ - int rc; - struct afb_cred cred; - json_object *j_response, *j_query, *j_config, *j_ws_servers, *j_ws_clients; - json_object *j_name, *j_apis; - DAEMONS_T* daemons = (DAEMONS_T*)closure; - DAEMON_T* daemon = calloc(sizeof(DAEMON_T), 1); - - if (!daemons) - return; - - if ((rc = wrap_json_unpack(obj, "{si si si ss ss ss}", "pid", &cred.pid, - "uid", &cred.uid, "gid", &cred.gid, "id", &cred.id, - "label", &cred.label, "user", &cred.user)) - < 0) { - // TODO - return; - } - - AFB_INFO("Get config of pid %d", cred.pid); - daemon->pid = cred.pid; - - // Get config - wrap_json_pack(&j_query, "{s:i}", "pid", cred.pid); - rc = afb_service_call_sync(SRV_SUPERVISOR_NAME, "config", j_query, &j_response); - if (rc < 0) { - AFB_ERROR("Cannot get config of pid %d", cred.pid); - return; - } - - AFB_DEBUG("%s config result, res=%s", SRV_SUPERVISOR_NAME, - json_object_to_json_string(j_response)); - - if (json_object_object_get_ex(j_response, "response", &j_config)) { - // FIXME : implement free - daemon->config = j_config; - - rc = wrap_json_unpack(j_config, "{s:o s:o s:o}", - "name", &j_name, - "ws_servers", &j_ws_servers, - "ws_clients", &j_ws_clients); - if (rc < 0) { - AFB_ERROR("Error decoding config response %s", wrap_json_get_error_string(rc)); - return; - } - - daemon->name = json_object_is_type(j_name, json_type_null) ? null_str : json_object_get_string(j_name); - daemon->ws_servers = j_ws_servers; - daemon->isServer = (json_object_array_length(j_ws_servers) > 0); - daemon->ws_clients = j_ws_clients; - daemon->isClient = (json_object_array_length(j_ws_clients) > 0); - } - - // Get apis - // '{"pid":6262,"api":"monitor","verb":"get","args":{"apis":true}} - wrap_json_pack(&j_query, "{si ss ss s {sb}}", - "pid", cred.pid, - "api", "monitor", - "verb", "get", - "args", "apis", true); - rc = afb_service_call_sync(SRV_SUPERVISOR_NAME, "do", j_query, &j_response); - if (rc < 0) { - AFB_ERROR("Cannot get apis of pid %d", cred.pid); - return; - } else { - //AFB_DEBUG("%s do ...get apis result, res=%s", SRV_SUPERVISOR_NAME, - // json_object_to_json_string(j_response)); - - if (json_object_object_get_ex(j_response, "response", &j_config) && - json_object_object_get_ex(j_config, "apis", &j_apis)) { - daemon->apis = j_apis; - } - } - daemons->daemons[daemons->count] = daemon; - daemons->count++; -} - -int getDaemons(DAEMONS_T** daemons) -{ - int rc; - json_object *j_response, *j_daemons = NULL; - - *daemons = calloc(sizeof(DAEMONS_T), 1); - - if ((rc = afb_service_call_sync(SRV_SUPERVISOR_NAME, "discover", NULL, - &j_response)) - < 0) { - return rc; - } - - if ((rc = afb_service_call_sync(SRV_SUPERVISOR_NAME, "list", NULL, - &j_response)) - < 0) { - return rc; - } - - AFB_DEBUG("%s list result, res=%s", SRV_SUPERVISOR_NAME, - json_object_to_json_string(j_response)); - - if (json_object_object_get_ex(j_response, "response", &j_daemons)) { - wrap_json_object_for_all(j_daemons, &decode_daemons_cb, *daemons); - } - - return 0; -} - -int trace_exchange(DAEMON_T* svr, DAEMON_T* cli) -{ - int rc; - json_object *j_response, *j_query; - - if (svr == NULL || cli == NULL) { - return -1; - } - - wrap_json_pack(&j_query, "{s:i, s:{s:s}}", "pid", svr->pid, "add", - "request", "common"); - if ((rc = afb_service_call_sync(SRV_SUPERVISOR_NAME, "trace", j_query, - &j_response)) - < 0) { - AFB_ERROR("ERROR trace %d result: %s", svr->pid, - json_object_to_json_string(j_response)); - return rc; - } - - wrap_json_pack(&j_query, "{s:i}", "pid", cli->pid); - if ((rc = afb_service_call_sync(SRV_SUPERVISOR_NAME, "trace", j_query, - &j_response)) - < 0) { - AFB_ERROR("ERROR trace %d result: %s", cli->pid, - json_object_to_json_string(j_response)); - return rc; - } - - return 0; -} - -void supervisor_service_init(void) {} diff --git a/xds-service/supervisor-service.h b/xds-service/supervisor-service.h deleted file mode 100644 index 84fe36c..0000000 --- a/xds-service/supervisor-service.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2018 "IoT.bzh" - * Author "Sebastien Douheret" - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include -#include "wrap-json.h" - -// FIXME Use chained list instead of static array -#define MAX_CLIENTS 32 -#define MAX_SERVERS 32 -#define MAX_DAEMONS 1024 - - -typedef struct daemon -{ - int pid; - const char* name; - bool isServer; - bool isClient; - //char *ws_clients[MAX_CLIENTS]; - //char *ws_servers[MAX_SERVERS]; - json_object *ws_clients; - json_object *ws_servers; - json_object *config; - json_object *apis; -} DAEMON_T; - -typedef struct daemons_result_ -{ - int count; - DAEMON_T *daemons[MAX_DAEMONS]; -} DAEMONS_T; - - -extern int getDaemons(DAEMONS_T **daemons); -extern int trace_exchange(DAEMON_T *svr, DAEMON_T *cli); -extern void supervisor_service_init(void); diff --git a/xds-service/xds-service-api.c b/xds-service/xds-service-api.c deleted file mode 100644 index 08e6a59..0000000 --- a/xds-service/xds-service-api.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (C) 2018 "IoT.bzh" - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#define _GNU_SOURCE -#include "xds-service-api.h" -#include "supervisor-service.h" -#include "xds-service-apidef.h" -#include -#include -#include - -#define SRV_SUPERVISOR_NAME "supervisor" -#define SRV_HARVESTER_NAME "harvester" - -typedef struct metric_t { - char* name; - json_object* data; - struct timespec timestamp; -} METRIC_T; - -void list(struct afb_req request) -{ - json_object *result, *item = NULL; - DAEMONS_T* daemons = NULL; - - getDaemons(&daemons); - if (daemons == NULL) { - afb_req_fail(request, "failed", ""); - return; - } - - result = json_object_new_array(); - - for (int i = 0; i < daemons->count; i++) { - wrap_json_pack(&item, "{si ss sb sb so so so}", - "pid", daemons->daemons[i]->pid, - "name", daemons->daemons[i]->name, - "isServer", daemons->daemons[i]->isServer, - "isClient", daemons->daemons[i]->isClient, - "ws_servers", daemons->daemons[i]->ws_servers, - "ws_clients", daemons->daemons[i]->ws_clients, - "apis", daemons->daemons[i]->apis); - //, "config", daemons->daemons[i]->config); - json_object_array_add(result, item); - } - afb_req_success(request, result, NULL); -} - -void trace(struct afb_req request) -{ - int rc; - json_object* req_args = afb_req_json(request); - json_object* result = NULL; - DAEMONS_T* daemons = NULL; - const char* ws_name; - const char* wsn; - - if (wrap_json_unpack(req_args, "{s:?s}", "ws", &ws_name)) { - afb_req_fail(request, "Failed", "Error processing arguments."); - return; - } - AFB_INFO("Trace ws: %s", ws_name); - - getDaemons(&daemons); - if (daemons == NULL || daemons->count <= 0) { - afb_req_fail(request, "failed", "No daemon found"); - } - - // search server and client pid - DAEMON_T *pid_s = NULL, *pid_c = NULL; - for (int i = 0; i < daemons->count; i++) { - AFB_DEBUG("_DEBUG_ svr %s", - json_object_to_json_string(daemons->daemons[i]->ws_servers)); - AFB_DEBUG("_DEBUG_ cli %s", - json_object_to_json_string(daemons->daemons[i]->ws_clients)); - - json_object* ws_servers = daemons->daemons[i]->ws_servers; - for (int j = 0; j < json_object_array_length(ws_servers); j++) { - - wsn = json_object_get_string(json_object_array_get_idx(ws_servers, j++)); - if (wsn && strstr(wsn, ws_name) != NULL) { - pid_s = daemons->daemons[i]; - break; - } - } - - json_object* ws_clients = daemons->daemons[i]->ws_clients; - for (int j = 0; j < json_object_array_length(ws_clients); j++) { - wsn = json_object_get_string(json_object_array_get_idx(ws_clients, j++)); - if (wsn && strstr(wsn, ws_name) != NULL) { - pid_c = daemons->daemons[i]; - break; - } - } - - if (pid_s != NULL && pid_c != NULL) { - if ((rc = trace_exchange(pid_s, pid_c)) < 0) { - afb_req_fail_f(request, "failed", "Trace error %d", rc); - } - break; - } - } - - if (pid_s == NULL || pid_c == NULL) { - afb_req_fail(request, "failed", "Cannot determine Server or Client"); - return; - } - - afb_req_success_f(request, result, "Tracing Server pid=%d <-> Client pid=%d", - pid_s->pid, pid_c->pid); -} - -static int harvester_post_data(METRIC_T* metric) -{ - - int rc; - json_object *j_res, *j_query; - - if (!metric->timestamp.tv_sec && !metric->timestamp.tv_nsec) { - clock_gettime(CLOCK_MONOTONIC, &metric->timestamp); - } - - rc = wrap_json_pack(&j_query, "{s:s s:i s:{ s:s s:o s:i } }", "host", - "localhost", "port", 8086, "metric", "name", metric->name, - "value", metric->data, "timestamp", - metric->timestamp.tv_sec); - if (rc < 0) { - AFB_ERROR("Error packing metric, rc=%d", rc); - return rc; - } - - AFB_DEBUG("%s write: %s", SRV_HARVESTER_NAME, - json_object_to_json_string(j_query)); - - rc = afb_service_call_sync(SRV_HARVESTER_NAME, "write", j_query, &j_res); - if (rc < 0) { - AFB_ERROR("Error %s write : rc=%d, j_res=%s", SRV_HARVESTER_NAME, rc, - json_object_to_json_string(j_res)); - return rc; - } - return 0; -} - -void xds_event_cb(const char* evtname, json_object* j_event) -{ - int rc; - METRIC_T metric; - const char* type = NULL; - struct json_object* request = NULL; - - AFB_NOTICE("RECV Event %s : %s", evtname, - json_object_to_json_string(j_event)); - - if (strcmp(evtname, "supervisor/trace") != 0) { - return; - } - - if ((rc = wrap_json_unpack(j_event, "{s:?s}", "type", &type)) < 0) { - AFB_ERROR("Cannot decode event type"); - return; - } - - if (strcmp(type, "request") == 0) { - - if (!json_object_object_get_ex(j_event, "request", &request)) { - AFB_ERROR("Cannot decode event request"); - return; - } - metric.name = "trace"; - metric.data = request; - - rc = harvester_post_data(&metric); - if (rc < 0) { - AFB_ERROR("ERROR harvester_post_data: rc %d", rc); - } - } -} - -void auth(struct afb_req request) -{ - afb_req_session_set_LOA(request, 1); - afb_req_success(request, NULL, NULL); -} - -int init() -{ - -#if 0 // DEBUG - DAEMONS_T *daemons = NULL; - getDaemons(&daemons); - - if (daemons) { - if (daemons->count) { - AFB_DEBUG("_DEBUG_ daemons->count %d", daemons->count); - for (int i = 0; i < daemons->count; i++) { - AFB_DEBUG("pid %d : isServer %d, isClient %d, %s %s", - daemons->daemons[i]->pid, daemons->daemons[i]->isServer, - daemons->daemons[i]->isClient, - json_object_to_json_string(daemons->daemons[i]->ws_servers), - json_object_to_json_string(daemons->daemons[i]->ws_clients)); - } - free(daemons); - } else { - AFB_DEBUG("_DEBUG_ no dameons detected !"); - } - } -#endif - - supervisor_service_init(); - - return 0; -} diff --git a/xds-service/xds-service-api.h b/xds-service/xds-service-api.h deleted file mode 100644 index 8a95f77..0000000 --- a/xds-service/xds-service-api.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2018 "IoT.bzh" - * Author "Sebastien Douheret" - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#define AFB_BINDING_VERSION 2 -#include -#include "wrap-json.h" - -extern void xds_event_cb(const char *evtname, json_object *j_event); -extern int init(); diff --git a/xds-service/xds-service-apidef.h b/xds-service/xds-service-apidef.h deleted file mode 100644 index 5d53d89..0000000 --- a/xds-service/xds-service-apidef.h +++ /dev/null @@ -1,85 +0,0 @@ - -static const char _afb_description_v2_xds_service[] = - "{\"openapi\":\"3.0.0\",\"$schema\":\"http://iot.bzh/download/openapi/sch" - "ema-3.0/default-schema.json\",\"info\":{\"description\":\"TBD - TODO\",\"" - "title\":\"xds-service\",\"version\":\"4.0\",\"x-binding-c-generator\":{\"" - "api\":\"xds-service\",\"version\":2,\"prefix\":\"\",\"postfix\":\"\",\"s" - "tart\":null,\"onevent\":\"xds_event_cb\",\"init\":\"init\",\"scope\":\"\"" - ",\"private\":false}},\"servers\":[{}],\"components\":{\"schemas\":{\"afb" - "-reply\":{\"$ref\":\"#/components/schemas/afb-reply-v2\"},\"afb-event\":" - "{\"$ref\":\"#/components/schemas/afb-event-v2\"},\"afb-reply-v2\":{\"tit" - "le\":\"Generic response.\",\"type\":\"object\",\"required\":[\"jtype\",\"" - "request\"],\"properties\":{\"jtype\":{\"type\":\"string\",\"const\":\"af" - "b-reply\"},\"request\":{\"type\":\"object\",\"required\":[\"status\"],\"" - "properties\":{\"status\":{\"type\":\"string\"},\"info\":{\"type\":\"stri" - "ng\"},\"token\":{\"type\":\"string\"},\"uuid\":{\"type\":\"string\"},\"r" - "eqid\":{\"type\":\"string\"}}},\"response\":{\"type\":\"object\"}}},\"af" - "b-event-v2\":{\"type\":\"object\",\"required\":[\"jtype\",\"event\"],\"p" - "roperties\":{\"jtype\":{\"type\":\"string\",\"const\":\"afb-event\"},\"e" - "vent\":{\"type\":\"string\"},\"data\":{\"type\":\"object\"}}}},\"x-permi" - "ssions\":{\"list\":{\"permission\":\"urn:AGL:permission::platform:can:li" - "st \"},\"trace\":{\"permission\":\"urn:AGL:permission::platform:can:trac" - "e \"}},\"responses\":{\"200\":{\"description\":\"A complex object array " - "response\",\"content\":{\"application/json\":{\"schema\":{\"$ref\":\"#/c" - "omponents/schemas/afb-reply\"}}}}}},\"paths\":{\"/auth\":{\"description\"" - ":\"Authenticate session to raise Level Of Assurance of the session\",\"g" - "et\":{\"x-permissions\":{\"$ref\":\"#/components/x-permissions/list\"},\"" - "responses\":{\"200\":{\"$ref\":\"#/components/responses/200\"}}}},\"/lis" - "t\":{\"description\":\"list \",\"get\":{\"x-permissions\":{\"LOA\":1},\"" - "parameters\":[],\"responses\":{\"200\":{\"$ref\":\"#/components/response" - "s/200\"}}}},\"/trace\":{\"description\":\"trace \",\"get\":{\"x-permissi" - "ons\":{\"LOA\":1},\"parameters\":[{\"in\":\"query\",\"name\":\"ws\",\"re" - "quired\":true,\"schema\":{\"type\":\"string\"}}],\"responses\":{\"200\":" - "{\"$ref\":\"#/components/responses/200\"}}}}}}" -; - -static const struct afb_auth _afb_auths_v2_xds_service[] = { - { .type = afb_auth_Permission, .text = "urn:AGL:permission::platform:can:list " } -}; - - void auth(struct afb_req req); - void list(struct afb_req req); - void trace(struct afb_req req); - -static const struct afb_verb_v2 _afb_verbs_v2_xds_service[] = { - { - .verb = "auth", - .callback = auth, - .auth = &_afb_auths_v2_xds_service[0], - .info = "Authenticate session to raise Level Of Assurance of the session", - .session = AFB_SESSION_NONE_V2 - }, - { - .verb = "list", - .callback = list, - .auth = NULL, - .info = "list ", - .session = AFB_SESSION_LOA_1_V2 - }, - { - .verb = "trace", - .callback = trace, - .auth = NULL, - .info = "trace ", - .session = AFB_SESSION_LOA_1_V2 - }, - { - .verb = NULL, - .callback = NULL, - .auth = NULL, - .info = NULL, - .session = 0 - } -}; - -const struct afb_binding_v2 afbBindingV2 = { - .api = "xds-service", - .specification = _afb_description_v2_xds_service, - .info = "TBD - TODO", - .verbs = _afb_verbs_v2_xds_service, - .preinit = NULL, - .init = init, - .onevent = xds_event_cb, - .noconcurrency = 0 -}; - diff --git a/xds-service/xds-service-apidef.json b/xds-service/xds-service-apidef.json deleted file mode 100644 index 76e35b7..0000000 --- a/xds-service/xds-service-apidef.json +++ /dev/null @@ -1,152 +0,0 @@ -{ - "openapi": "3.0.0", - "$schema": "http://iot.bzh/download/openapi/schema-3.0/default-schema.json", - "info": { - "description": "TBD - TODO", - "title": "xds-service", - "version": "4.0", - "x-binding-c-generator": { - "api": "xds-service", - "version": 2, - "prefix": "", - "postfix": "", - "start": null, - "onevent": "xds_event_cb", - "init": "init", - "scope": "", - "private": false - } - }, - "servers": [{}], - "components": { - "schemas": { - "afb-reply": { - "$ref": "#/components/schemas/afb-reply-v2" - }, - "afb-event": { - "$ref": "#/components/schemas/afb-event-v2" - }, - "afb-reply-v2": { - "title": "Generic response.", - "type": "object", - "required": ["jtype", "request"], - "properties": { - "jtype": { - "type": "string", - "const": "afb-reply" - }, - "request": { - "type": "object", - "required": ["status"], - "properties": { - "status": { - "type": "string" - }, - "info": { - "type": "string" - }, - "token": { - "type": "string" - }, - "uuid": { - "type": "string" - }, - "reqid": { - "type": "string" - } - } - }, - "response": { - "type": "object" - } - } - }, - "afb-event-v2": { - "type": "object", - "required": ["jtype", "event"], - "properties": { - "jtype": { - "type": "string", - "const": "afb-event" - }, - "event": { - "type": "string" - }, - "data": { - "type": "object" - } - } - } - }, - "x-permissions": { - "list": { - "permission": "urn:AGL:permission::platform:can:list " - }, - "trace": { - "permission": "urn:AGL:permission::platform:can:trace " - } - }, - "responses": { - "200": { - "description": "A complex object array response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/afb-reply" - } - } - } - } - } - }, - "paths": { - "/auth": { - "description": "Authenticate session to raise Level Of Assurance of the session", - "get": { - "x-permissions": { - "$ref": "#/components/x-permissions/list" - }, - "responses": { - "200": { - "$ref": "#/components/responses/200" - } - } - } - }, - "/list": { - "description": "list ", - "get": { - "x-permissions": { - "LOA": 1 - }, - "parameters": [], - "responses": { - "200": { - "$ref": "#/components/responses/200" - } - } - } - }, - "/trace": { - "description": "trace ", - "get": { - "x-permissions": { - "LOA": 1 - }, - "parameters": [{ - "in": "query", - "name": "ws", - "required": true, - "schema": { - "type": "string" - } - }], - "responses": { - "200": { - "$ref": "#/components/responses/200" - } - } - } - } - } -} -- cgit 1.2.3-korg