From 45c8372c2b4137691a38c2a04f4a5759a110f2f7 Mon Sep 17 00:00:00 2001 From: José Bollo Date: Mon, 20 Nov 2017 15:22:40 +0100 Subject: CMAKE: refactor options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The option ALLOW_NO_BINDER is removed and the option ONLY_DEVTOOLS is introduced. Change-Id: Ia19eb977ee25a3871582605028fdef75e552363f Signed-off-by: José Bollo --- CMakeLists.txt | 69 ++-- bindings/CMakeLists.txt | 2 - src/CMakeLists.txt | 21 +- src/devtools/CMakeLists.txt | 30 ++ src/devtools/exprefs.c | 198 ++++++++++++ src/devtools/genskel.c | 708 ++++++++++++++++++++++++++++++++++++++++++ src/devtools/json2c.c | 174 +++++++++++ src/devtools/monitor-api.json | 400 ++++++++++++++++++++++++ src/genskel/CMakeLists.txt | 30 -- src/genskel/exprefs.c | 198 ------------ src/genskel/genskel.c | 708 ------------------------------------------ src/genskel/json2c.c | 174 ----------- src/genskel/monitor-api.json | 400 ------------------------ 13 files changed, 1550 insertions(+), 1562 deletions(-) create mode 100644 src/devtools/CMakeLists.txt create mode 100644 src/devtools/exprefs.c create mode 100644 src/devtools/genskel.c create mode 100644 src/devtools/json2c.c create mode 100644 src/devtools/monitor-api.json delete mode 100644 src/genskel/CMakeLists.txt delete mode 100644 src/genskel/exprefs.c delete mode 100644 src/genskel/genskel.c delete mode 100644 src/genskel/json2c.c delete mode 100644 src/genskel/monitor-api.json diff --git a/CMakeLists.txt b/CMakeLists.txt index 568eb42b..541b6398 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,7 +89,6 @@ IF(cynara_FOUND) ENDIF(cynara_FOUND) IF(HAVE_LIBMAGIC AND libsystemd_FOUND AND libmicrohttpd_FOUND AND openssl_FOUND AND uuid_FOUND) - SET(WITH_BINDER TRUE) ADD_DEFINITIONS(-DUSE_MAGIC_MIME_TYPE) ELSE() IF(NOT HAVE_LIBMAGIC) @@ -108,10 +107,9 @@ ELSE() IF(NOT uuid_FOUND) MESSAGE(WARNING "Dependency to 'uuid' is missing") ENDIF() - IF(NOT ALLOW_NO_BINDER) - MESSAGE(FATAL_ERROR "Can't compile the binder, either define ALLOW_NO_BINDER or install dependencies") + IF(NOT ONLY_DEVTOOLS) + MESSAGE(FATAL_ERROR "Can't compile the binder, either define ONLY_DEVTOOLS or install dependencies") ENDIF() - SET(WITH_BINDER FALSE) ENDIF() ADD_DEFINITIONS(-DAFB_VERSION="${PROJECT_VERSION}") @@ -140,34 +138,41 @@ SET(link_libraries -lrt ) -SET(binding_install_dir ${CMAKE_INSTALL_FULL_LIBDIR}/afb) +ADD_SUBDIRECTORY(src/devtools) -########################################################################### -# activates the monitoring by default -if(INCLUDE_MONITORING AND WITH_BINDER) - add_definitions(-DWITH_MONITORING_OPTION) - INSTALL(DIRECTORY - ${CMAKE_CURRENT_SOURCE_DIR}/test/monitoring - DESTINATION - ${binding_install_dir} +IF(ONLY_DEVTOOLS) + MESSAGE(WARNING "Only DEVTOOLS are compiled, not the binder!") +ELSE() + SET(binding_install_dir ${CMAKE_INSTALL_FULL_LIBDIR}/afb) + + ########################################################################### + # activates the monitoring by default + if(INCLUDE_MONITORING AND NOT ONLY_DEVTOOLS) + add_definitions(-DWITH_MONITORING_OPTION) + INSTALL(DIRECTORY + ${CMAKE_CURRENT_SOURCE_DIR}/test/monitoring + DESTINATION + ${binding_install_dir} + ) + endif() + + ########################################################################### + + ADD_SUBDIRECTORY(src) + ADD_SUBDIRECTORY(src/tests) + ADD_SUBDIRECTORY(include) + ADD_SUBDIRECTORY(bindings) + + ############################################################ + # installs the pkgconfig files + CONFIGURE_FILE(afb-daemon.pc.in afb-daemon.pc @ONLY) + CONFIGURE_FILE(libafbwsc.pc.in libafbwsc.pc @ONLY) + + INSTALL(FILES + ${CMAKE_CURRENT_BINARY_DIR}/afb-daemon.pc + ${CMAKE_CURRENT_BINARY_DIR}/libafbwsc.pc + DESTINATION + ${CMAKE_INSTALL_LIBDIR}/pkgconfig ) -endif() - -########################################################################### - -ADD_SUBDIRECTORY(src) -ADD_SUBDIRECTORY(include) -ADD_SUBDIRECTORY(bindings) - -############################################################ -# installs the pkgconfig files -CONFIGURE_FILE(afb-daemon.pc.in afb-daemon.pc @ONLY) -CONFIGURE_FILE(libafbwsc.pc.in libafbwsc.pc @ONLY) - -INSTALL(FILES - ${CMAKE_CURRENT_BINARY_DIR}/afb-daemon.pc - ${CMAKE_CURRENT_BINARY_DIR}/libafbwsc.pc - DESTINATION - ${CMAKE_INSTALL_LIBDIR}/pkgconfig - ) +ENDIF() diff --git a/bindings/CMakeLists.txt b/bindings/CMakeLists.txt index 509c6cbf..4494e887 100644 --- a/bindings/CMakeLists.txt +++ b/bindings/CMakeLists.txt @@ -16,9 +16,7 @@ # limitations under the License. ########################################################################### -IF(WITH_BINDER) ADD_SUBDIRECTORY(intrinsics) ADD_SUBDIRECTORY(samples) ADD_SUBDIRECTORY(tutorial) -ENDIF(WITH_BINDER) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b8accc77..f0e1d448 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -16,20 +16,9 @@ # limitations under the License. ########################################################################### -if (NOT DEFINED ALLOW_NO_BINDER) - if (CMAKE_C_COMPILER_VERSION VERSION_LESS 4.9) - message(FATAL_ERROR "Require at least gcc-4.9") - endif(CMAKE_C_COMPILER_VERSION VERSION_LESS 4.9) -endif(ALLOW_NO_BINDER) - -INCLUDE(FindPkgConfig) - -ADD_SUBDIRECTORY(genskel) - -IF(WITH_BINDER) -########################################### - -ADD_SUBDIRECTORY(tests) +if (CMAKE_C_COMPILER_VERSION VERSION_LESS 4.9) + message(FATAL_ERROR "Require at least gcc-4.9") +endif(CMAKE_C_COMPILER_VERSION VERSION_LESS 4.9) ADD_DEFINITIONS(-DBINDING_INSTALL_DIR="${binding_install_dir}") # Always add INFER_EXTENSION (more details in afb-hreq.c) @@ -122,7 +111,3 @@ TARGET_LINK_LIBRARIES(afb-client-demo INSTALL(TARGETS afb-client-demo RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) -########################################### -ELSE(WITH_BINDER) - MESSAGE(WARNING "NOT compiling the binder! but tools are compiled") -ENDIF(WITH_BINDER) diff --git a/src/devtools/CMakeLists.txt b/src/devtools/CMakeLists.txt new file mode 100644 index 00000000..b1d63825 --- /dev/null +++ b/src/devtools/CMakeLists.txt @@ -0,0 +1,30 @@ +########################################################################### +# Copyright 2015, 2016, 2017 IoT.bzh +# +# author: José Bollo +# +# 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_EXECUTABLE(afb-genskel genskel.c) +ADD_EXECUTABLE(afb-exprefs exprefs.c) +ADD_EXECUTABLE(afb-json2c json2c.c) + +TARGET_LINK_LIBRARIES(afb-genskel ${link_libraries}) +TARGET_LINK_LIBRARIES(afb-exprefs ${link_libraries}) +TARGET_LINK_LIBRARIES(afb-json2c ${link_libraries}) + +INSTALL(TARGETS afb-genskel RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +INSTALL(TARGETS afb-exprefs RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +INSTALL(TARGETS afb-json2c RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + diff --git a/src/devtools/exprefs.c b/src/devtools/exprefs.c new file mode 100644 index 00000000..4ea44b4d --- /dev/null +++ b/src/devtools/exprefs.c @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2016, 2017 "IoT.bzh" + * Author José Bollo + * + * 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 simple program expands the object { "$ref": "#/path/to/a/target" } + * + * For example: + * + * { + * "type":{ + * "a": "int", + * "b": { "$ref": "#/type/a" } + * } + * } + * + * will be exapanded to + * + * { + * "type":{ + * "a": "int", + * "b": "int" + * } + * } + * + * Invocation: program [file|-]... + * + * without arguments, it reads the input. + */ + +#define _GNU_SOURCE +#include +#include +#include + +#include + +/** + * records path to the expanded node + */ +struct path +{ + struct json_object *object; /**< node being expanded */ + struct path *upper; /**< link to upper expanded nodes */ +}; + +/** + * root of the JSON being parsed + */ +struct json_object *root; + +/** + * Search for a reference of type "#/a/b/c" int the + * parsed JSON object + */ +struct json_object *search(const char *path) +{ + char *d; + struct json_object *i; + + /* does it match #/ at the beginning? */ + if (path[0] != '#' || (path[0] && path[1] != '/')) + return NULL; + + /* search from root to target */ + i = root; + d = strdupa(path+2); + d = strtok(d, "/"); + while(i && d) { + if (!json_object_object_get_ex(i, d, &i)) + return NULL; + d = strtok(NULL, "/"); + } + return i; +} + +/** + * Expands the node designated by path and returns its expanded form + */ +struct json_object *expand(struct path path) +{ + struct path *p; + struct json_object *o, *x; + int n, i; + struct json_object_iterator ji, jn; + + /* expansion depends of the type of the node */ + switch (json_object_get_type(path.object)) { + case json_type_object: + /* for object, look if it contains a property "$ref" */ + if (json_object_object_get_ex(path.object, "$ref", &o)) { + /* yes, reference, try to substitute its target */ + if (!json_object_is_type(o, json_type_string)) { + fprintf(stderr, "found a $ref not being string. Is: %s\n", json_object_get_string(o)); + exit(1); + } + x = search(json_object_get_string(o)); + if (!x) { + fprintf(stderr, "$ref not found. Was: %s\n", json_object_get_string(o)); + exit(1); + } + p = &path; + while(p) { + if (x == p->object) { + fprintf(stderr, "$ref recursive. Was: %s\n", json_object_get_string(o)); + exit(1); + } + p = p->upper; + } + /* cool found, return a new instance of the target */ + return json_object_get(x); + } + /* no, expand the values */ + ji = json_object_iter_begin(path.object); + jn = json_object_iter_end(path.object); + while (!json_object_iter_equal(&ji, &jn)) { + o = json_object_iter_peek_value(&ji); + x = expand((struct path){ .object = o, .upper = &path }); + if (x != o) + json_object_object_add(path.object, json_object_iter_peek_name(&ji), x); + json_object_iter_next(&ji); + } + break; + case json_type_array: + /* expand the values of arrays */ + i = 0; + n = json_object_array_length(path.object); + while (i != n) { + o = json_object_array_get_idx(path.object, i); + x = expand((struct path){ .object = o, .upper = &path }); + if (x != o) + json_object_array_put_idx(path.object, i, x); + i++; + } + break; + default: + /* otherwise no expansion */ + break; + } + /* return the given node */ + return path.object; +} + +/** + * process a file and prints its expansion on stdout + */ +void process(char *filename) +{ + /* translate - */ + if (!strcmp(filename, "-")) + filename = "/dev/stdin"; + + /* check access */ + if (access(filename, R_OK)) { + fprintf(stderr, "can't access file %s\n", filename); + exit(1); + } + + /* read the file */ + root = json_object_from_file(filename); + if (!root) { + fprintf(stderr, "reading file %s produced null\n", filename); + exit(1); + } + + /* expand */ + root = expand((struct path){ .object = root, .upper = NULL }); + + /* print the result */ + json_object_to_file_ext ("/dev/stdout", root, JSON_C_TO_STRING_PRETTY); + + /* clean up */ + json_object_put(root); +} + +/** process the list of files or stdin if none */ +int main(int ac, char **av) +{ + if (!*++av) + process("-"); + else { + do { process(*av); } while(*++av); + } + return 0; +} + diff --git a/src/devtools/genskel.c b/src/devtools/genskel.c new file mode 100644 index 00000000..62dfe3f4 --- /dev/null +++ b/src/devtools/genskel.c @@ -0,0 +1,708 @@ +/* + * Copyright (C) 2016, 2017 "IoT.bzh" + * Author José Bollo + * + * 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 simple program expands the object { "$ref": "#/path/to/a/target" } + * + * For example: + * + * { + * "type":{ + * "a": "int", + * "b": { "$ref": "#/type/a" } + * } + * } + * + * will be exapanded to + * + * { + * "type":{ + * "a": "int", + * "b": "int" + * } + * } + * + * Invocation: program [file|-]... + * + * without arguments, it reads the input. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include + +#include + +#define oom(x) do{if(!(x)){fprintf(stderr,"out of memory\n");exit(1);}}while(0) + +/** + * records path to the expanded node + */ +struct path +{ + struct json_object *object; /**< node being expanded */ + struct path *upper; /**< link to upper expanded nodes */ +}; + +/** + * root of the JSON being parsed + */ +struct json_object *root = NULL; +struct json_object *d_perms = NULL; +struct json_object *a_perms = NULL; +const char *preinit = NULL; +const char *init = NULL; +const char *onevent = NULL; +const char *api = NULL; +const char *scope = NULL; +const char *prefix = NULL; +const char *postfix = NULL; +char *capi = NULL; +int priv = -1; +int noconc = -1; + +/** + * Search for a reference of type "#/a/b/c" int the + * parsed JSON object + */ +struct json_object *search(const char *path) +{ + char *d; + struct json_object *i; + + /* does it match #/ at the beginning? */ + if (path[0] != '#' || (path[0] && path[1] != '/')) + return NULL; + + /* search from root to target */ + i = root; + d = strdupa(path+2); + d = strtok(d, "/"); + while(i && d) { + if (!json_object_object_get_ex(i, d, &i)) + return NULL; + d = strtok(NULL, "/"); + } + return i; +} + +/** + * Expands the node designated by path and returns its expanded form + */ +struct json_object *expand_$ref(struct path path) +{ + struct path *p; + struct json_object *o, *x; + int n, i; + struct json_object_iterator ji, jn; + + /* expansion depends of the type of the node */ + switch (json_object_get_type(path.object)) { + case json_type_object: + /* for object, look if it contains a property "$ref" */ + if (json_object_object_get_ex(path.object, "$ref", &o)) { + /* yes, reference, try to substitute its target */ + if (!json_object_is_type(o, json_type_string)) { + fprintf(stderr, "found a $ref not being string. Is: %s\n", json_object_get_string(o)); + exit(1); + } + x = search(json_object_get_string(o)); + if (!x) { + fprintf(stderr, "$ref not found. Was: %s\n", json_object_get_string(o)); + exit(1); + } + p = &path; + while(p) { + if (x == p->object) { + fprintf(stderr, "$ref recursive. Was: %s\n", json_object_get_string(o)); + exit(1); + } + p = p->upper; + } + /* cool found, return a new instance of the target */ + return json_object_get(x); + } + /* no, expand the values */ + ji = json_object_iter_begin(path.object); + jn = json_object_iter_end(path.object); + while (!json_object_iter_equal(&ji, &jn)) { + o = json_object_iter_peek_value(&ji); + x = expand_$ref((struct path){ .object = o, .upper = &path }); + if (x != o) + json_object_object_add(path.object, json_object_iter_peek_name(&ji), x); + json_object_iter_next(&ji); + } + break; + case json_type_array: + /* expand the values of arrays */ + i = 0; + n = json_object_array_length(path.object); + while (i != n) { + o = json_object_array_get_idx(path.object, i); + x = expand_$ref((struct path){ .object = o, .upper = &path }); + if (x != o) + json_object_array_put_idx(path.object, i, x); + i++; + } + break; + default: + /* otherwise no expansion */ + break; + } + + /* return the given node */ + return path.object; +} + +char *cify(const char *str) +{ + char *r = strdup(str); + int i = 0; + while (r && r[i]) { + if (!isalnum(r[i])) + r[i] = '_'; + i++; + } + return r; +} + +char *make_info(const char *text, int split) +{ + const char *a, *b; + char *desc, c, buf[3]; + size_t len; + int i, pos, e; + + /* estimated length */ + a = b = text; + len = 1; + while((c = *b++)) { + len += 1 + ('"' == c); + } + + len += 7 * (1 + len / 72); + desc = malloc(len); + oom(desc); + + len = pos = 0; + if (!split) + desc[len++] = '"'; + b = a; + while((c = *b++)) { + if (c == '"') { + buf[0] = '\\'; + buf[1] = '"'; + buf[2] = 0; + } + else if (c == '\\') { + switch ((c = *b++)) { + case 0: + b--; + break; + case '/': + buf[0] = '/'; + buf[1] = 0; + break; + default: + buf[0] = '\\'; + buf[1] = c; + buf[2] = 0; + break; + } + } + else { + buf[0] = c; + buf[1] = 0; + } + i = e = 0; + while (buf[i]) { + if (split) { + if (pos >= 77 && !e) { + desc[len++] = '"'; + desc[len++] = '\n'; + pos = 0; + } + if (pos == 0) { + desc[len++] = ' '; + desc[len++] = ' '; + desc[len++] = ' '; + desc[len++] = ' '; + desc[len++] = '"'; + pos = 5; + } + } + c = buf[i++]; + desc[len++] = c; + e = !e && c == '\\'; + pos++; + } + } + desc[len++] = '"'; + if (split) + desc[len++] = '\n'; + desc[len] = 0; + return desc; +} + +char *make_desc(struct json_object *o) +{ + return make_info(json_object_to_json_string_ext(root, 0), 1); +} + +struct json_object *permissions_of_verb(struct json_object *obj) +{ + struct json_object *x, *y; + + if (json_object_object_get_ex(obj, "x-permissions", &x)) + return x; + + if (json_object_object_get_ex(obj, "get", &x)) + if (json_object_object_get_ex(x, "x-permissions", &y)) + return y; + + return NULL; +} + +void print_perms() +{ + int i, n; + + n = a_perms ? json_object_array_length(a_perms) : 0; + if (n) { + printf("static const struct afb_auth _afb_auths_v2_%s[] = {\n" , capi); + i = 0; + while (i < n) { + printf("\t{ %s }", json_object_get_string(json_object_array_get_idx(a_perms, i))); + printf(",\n"+(++i == n)); + } + printf("};\n\n"); + } +} + +struct json_object *new_perm(struct json_object *obj, const char *desc) +{ + const char *tag; + char *b; + struct json_object *x, *y; + + tag = obj ? json_object_to_json_string_ext(obj, 0) : desc; + if (!json_object_object_get_ex(d_perms, tag, &y)) { + if (!d_perms) { + d_perms = json_object_new_object(); + a_perms = json_object_new_array(); + } + + asprintf(&b, "&_afb_auths_v2_%s[%d]", capi, json_object_array_length(a_perms)); + x = json_object_new_string(desc); + y = json_object_new_string(b); + json_object_array_add(a_perms, x); + json_object_object_add(d_perms, tag, y); + free(b); + } + return y; +} + +struct json_object *decl_perm(struct json_object *obj); + +struct json_object *decl_perm_a(const char *op, struct json_object *obj) +{ + int i, n; + char *a; + struct json_object *x, *y; + + x = NULL; + i = n = obj ? json_object_array_length(obj) : 0; + while (i) { + y = decl_perm(json_object_array_get_idx(obj, --i)); + if (!y) + ; + else if (!x) + x = y; + else if (x != y) { + asprintf(&a, ".type = afb_auth_%s, .first = %s, .next = %s", + op, json_object_get_string(y), json_object_get_string(x)); + x = new_perm(NULL, a); + free(a); + } + } + return x; +} + +struct json_object *decl_perm(struct json_object *obj) +{ + char *a; + struct json_object *x, *y; + + if (json_object_object_get_ex(d_perms, json_object_to_json_string_ext(obj, 0), &x)) + return x; + + if (json_object_object_get_ex(obj, "permission", &x)) { + asprintf(&a, ".type = afb_auth_Permission, .text = \"%s\"", json_object_get_string(x)); + y = new_perm(obj, a); + free(a); + } + else if (json_object_object_get_ex(obj, "anyOf", &x)) { + y = decl_perm_a("Or", x); + } + else if (json_object_object_get_ex(obj, "allOf", &x)) { + y = decl_perm_a("And", x); + } + else if (json_object_object_get_ex(obj, "not", &x)) { + x = decl_perm(x); + asprintf(&a, ".type = afb_auth_Not, .first = %s", json_object_get_string(x)); + y = new_perm(obj, a); + free(a); + } + else if (json_object_object_get_ex(obj, "LOA", &x)) + y = NULL; + else if (json_object_object_get_ex(obj, "session", &x)) + y = NULL; + else + y = NULL; + + return y; +} + +void declare_permissions(const char *name, struct json_object *obj) +{ + struct json_object *p; + + p = permissions_of_verb(obj); + if (p) + decl_perm(p); +} + + +#define SESSION_CLOSE 0x000001 +#define SESSION_RENEW 0x000010 +#define SESSION_CHECK 0x000100 +#define SESSION_LOA_1 0x001000 +#define SESSION_LOA_2 0x011000 +#define SESSION_LOA_3 0x111000 +#define SESSION_MASK 0x111111 + + +int get_session(struct json_object *obj); + +int get_session_a(int and, struct json_object *obj) +{ + int i, n, x, y; + + n = obj ? json_object_array_length(obj) : 0; + if (n == 0) + return 0; + + i = n; + x = get_session(json_object_array_get_idx(obj, --i)); + while (i) { + y = get_session(json_object_array_get_idx(obj, --i)); + if (and) + x &= y; + else + x |= y; + } + return x; +} + +int get_session(struct json_object *obj) +{ + int y; + const char *a; + struct json_object *x; + + y = 0; + if (json_object_object_get_ex(obj, "anyOf", &x)) { + y = get_session_a(1, x); + } + else if (json_object_object_get_ex(obj, "allOf", &x)) { + y = get_session_a(0, x); + } + else if (json_object_object_get_ex(obj, "not", &x)) { + y = ~get_session(x) & SESSION_MASK; + } + else if (json_object_object_get_ex(obj, "LOA", &x)) { + switch (json_object_get_int(x)) { + case 3: y = SESSION_LOA_3; break; + case 2: y = SESSION_LOA_2; break; + case 1: y = SESSION_LOA_1; break; + default: break; + } + } + else if (json_object_object_get_ex(obj, "session", &x)) { + a = json_object_get_string(x); + if (!strcmp(a, "check")) + y = SESSION_CHECK; + else if (!strcmp(a, "close")) + y = SESSION_CLOSE; + } + else if (json_object_object_get_ex(obj, "token", &x)) { + a = json_object_get_string(x); + if (!strcmp(a, "refresh")) + y = SESSION_RENEW; + } + + return y; +} + +void print_session(struct json_object *p) +{ + int s, c, l; + + s = p ? get_session(p) : 0; + c = 1; + if (s & SESSION_CHECK) { + printf("%s", "|AFB_SESSION_CHECK_V2" + c); + c = 0; + } + if (s & SESSION_LOA_3 & ~SESSION_LOA_2) + l = 3; + else if (s & SESSION_LOA_2 & ~SESSION_LOA_1) + l = 2; + else if (s & SESSION_LOA_1) + l = 1; + else + l = 0; + if (l) { + printf("%s%d_V2", "|AFB_SESSION_LOA_" + c, l); + c = 0; + } + if (s & SESSION_CLOSE) { + printf("%s", "|AFB_SESSION_CLOSE_V2" + c); + c = 0; + } + if (s & SESSION_RENEW) { + printf("%s", "|AFB_SESSION_REFRESH_V2" + c); + c = 0; + } + if (c) + printf("AFB_SESSION_NONE_V2"); +} + +void print_verb(const char *name) +{ + printf("%s%s%s" , prefix, name, postfix); +} + +void print_declare_verb(const char *name, struct json_object *obj) +{ + printf("%s void ", scope); + print_verb(name); + printf("(struct afb_req req);\n"); +} + +void print_struct_verb(const char *name, struct json_object *obj) +{ + struct json_object *p, *i; + const char *info; + + info = NULL; + if (json_object_object_get_ex(obj, "description", &i)) + info = json_object_get_string(i); + + p = permissions_of_verb(obj); + printf( + " {\n" + " .verb = \"%s\",\n" + " .callback = " + , name + ); + print_verb(name); + printf( + ",\n" + " .auth = %s,\n" + " .info = %s,\n" + " .session = " + , p && decl_perm(p) ? json_object_get_string(decl_perm(p)) : "NULL" + , info ? make_info(info, 0) : "NULL" + ); + print_session(p); + printf( + "\n" + " },\n" + ); +} + +void enum_verbs(void (*func)(const char *name, struct json_object *obj)) +{ + struct json_object_iterator ji, jn; + struct json_object *paths, *obj; + const char *name; + + /* search the verbs */ + paths = search("#/paths"); + if (!paths) + return; + + /* list the verbs and sort it */ + ji = json_object_iter_begin(paths); + jn = json_object_iter_end(paths); + while (!json_object_iter_equal(&ji, &jn)) { + name = json_object_iter_peek_name(&ji); + obj = json_object_iter_peek_value(&ji); + name += (*name == '/'); + func(name, obj); + json_object_iter_next(&ji); + } +} + +void getvarbool(int *var, const char *path, int defval) +{ + struct json_object *o; + + if (*var != 0 && *var != 1) { + o = search(path); + if (o && json_object_is_type(o, json_type_boolean)) + *var = json_object_get_boolean(o); + else + *var = !!defval; + } +} + +void getvar(const char **var, const char *path, const char *defval) +{ + struct json_object *o; + + if (!*var) { + o = search(path); + if (o && json_object_is_type(o, json_type_string)) + *var = json_object_get_string(o); + else + *var = defval; + } +} + +/** + * process a file and prints its expansion on stdout + */ +void process(char *filename) +{ + char *desc; + const char *info; + + /* translate - */ + if (!strcmp(filename, "-")) + filename = "/dev/stdin"; + + /* check access */ + if (access(filename, R_OK)) { + fprintf(stderr, "can't access file %s\n", filename); + exit(1); + } + + /* read the file */ + root = json_object_from_file(filename); + if (!root) { + fprintf(stderr, "reading file %s produced null\n", filename); + exit(1); + } + + /* create the description */ + desc = make_desc(root); + + /* expand references */ + root = expand_$ref((struct path){ .object = root, .upper = NULL }); + + /* get some names */ + getvar(&api, "#/info/x-binding-c-generator/api", NULL); + getvar(&preinit, "#/info/x-binding-c-generator/preinit", NULL); + getvar(&init, "#/info/x-binding-c-generator/init", NULL); + getvar(&onevent, "#/info/x-binding-c-generator/onevent", NULL); + getvar(&scope, "#/info/x-binding-c-generator/scope", "static"); + getvar(&prefix, "#/info/x-binding-c-generator/prefix", "afb_verb_"); + getvar(&postfix, "#/info/x-binding-c-generator/postfix", "_cb"); + getvarbool(&priv, "#/info/x-binding-c-generator/private", 0); + getvarbool(&noconc, "#/info/x-binding-c-generator/noconcurrency", 0); + getvar(&api, "#/info/title", "?"); + info = NULL; + getvar(&info, "#/info/description", NULL); + capi = cify(api); + + /* get the API name */ + printf( + "\n" + "static const char _afb_description_v2_%s[] =\n" + "%s" + ";\n" + "\n" + , capi, desc + ); + enum_verbs(declare_permissions); + print_perms(); + enum_verbs(print_declare_verb); + printf( + "\n" + "static const struct afb_verb_v2 _afb_verbs_v2_%s[] = {\n" + , capi + ); + enum_verbs(print_struct_verb); + printf( + " {\n" + " .verb = NULL,\n" + " .callback = NULL,\n" + " .auth = NULL,\n" + " .info = NULL,\n" + " .session = 0\n" + " }\n" + "};\n" + ); + printf( + "\n" + "%sconst struct afb_binding_v2 %s%s = {\n" + " .api = \"%s\",\n" + " .specification = _afb_description_v2_%s,\n" + " .info = %s,\n" + " .verbs = _afb_verbs_v2_%s,\n" + " .preinit = %s,\n" + " .init = %s,\n" + " .onevent = %s,\n" + " .noconcurrency = %d\n" + "};\n" + "\n" + , priv ? "static " : "" + , priv ? "_afb_binding_v2_" : "afbBindingV2" + , priv ? capi : "" + , api + , capi + , info ? make_info(info, 0) : "NULL" + , capi + , preinit ?: "NULL" + , init ?: "NULL" + , onevent ?: "NULL" + , !!noconc + ); + + /* clean up */ + json_object_put(root); + free(desc); +} + +/** process the list of files or stdin if none */ +int main(int ac, char **av) +{ + if (!*++av) + process("-"); + else { + do { process(*av); } while(*++av); + } + return 0; +} + + + + + diff --git a/src/devtools/json2c.c b/src/devtools/json2c.c new file mode 100644 index 00000000..109b6ee9 --- /dev/null +++ b/src/devtools/json2c.c @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2016, 2017 "IoT.bzh" + * Author José Bollo + * + * 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 simple program expands the object { "$ref": "#/path/to/a/target" } + * + * For example: + * + * { + * "type":{ + * "a": "int", + * "b": { "$ref": "#/type/a" } + * } + * } + * + * will be exapanded to + * + * { + * "type":{ + * "a": "int", + * "b": "int" + * } + * } + * + * Invocation: program [file|-]... + * + * without arguments, it reads the input. + */ + +#define _GNU_SOURCE +#include +#include +#include + +#include + +#define oom(x) do{if(!(x)){fprintf(stderr,"out of memory\n");exit(1);}}while(0) + +/** + * root of the JSON being parsed + */ +struct json_object *root = NULL; + +char *make_desc(struct json_object *o) +{ + const char *a, *b; + char *desc, c, buf[3]; + size_t len; + int i, pos, e; + + a = b = json_object_to_json_string_ext(root, 0); + len = 1; + while((c = *b++)) { + len += 1 + ('"' == c); + } + + len += 7 * (1 + len / 72); + desc = malloc(len); + oom(desc); + + len = pos = 0; + b = a; + while((c = *b++)) { + if (c == '"') { + buf[0] = '\\'; + buf[1] = '"'; + buf[2] = 0; + } + else if (c == '\\') { + switch ((c = *b++)) { + case 0: + b--; + break; + case '/': + buf[0] = '/'; + buf[1] = 0; + break; + default: + buf[0] = '\\'; + buf[1] = c; + buf[2] = 0; + break; + } + } + else { + buf[0] = c; + buf[1] = 0; + } + i = e = 0; + while (buf[i]) { + if (pos >= 77 && !e) { + desc[len++] = '"'; + desc[len++] = '\n'; + pos = 0; + } + if (pos == 0) { + desc[len++] = ' '; + desc[len++] = ' '; + desc[len++] = ' '; + desc[len++] = ' '; + desc[len++] = '"'; + pos = 5; + } + c = buf[i++]; + desc[len++] = c; + e = !e && c == '\\'; + pos++; + } + } + desc[len++] = '"'; + desc[len++] = '\n'; + desc[len] = 0; + return desc; +} + +/** + * process a file and prints its expansion on stdout + */ +void process(char *filename) +{ + char *desc; + + /* translate - */ + if (!strcmp(filename, "-")) + filename = "/dev/stdin"; + + /* check access */ + if (access(filename, R_OK)) { + fprintf(stderr, "can't access file %s\n", filename); + exit(1); + } + + /* read the file */ + root = json_object_from_file(filename); + if (!root) { + fprintf(stderr, "reading file %s produced null\n", filename); + exit(1); + } + + /* create the description */ + desc = make_desc(root); + + printf("%s", desc); + + /* clean up */ + json_object_put(root); + free(desc); +} + +/** process the list of files or stdin if none */ +int main(int ac, char **av) +{ + if (!*++av) + process("-"); + else { + do { process(*av); } while(*++av); + } + return 0; +} + + diff --git a/src/devtools/monitor-api.json b/src/devtools/monitor-api.json new file mode 100644 index 00000000..8361d572 --- /dev/null +++ b/src/devtools/monitor-api.json @@ -0,0 +1,400 @@ +{ + "openapi": "3.0.0", + "info": { + "description": "monitoring of bindings and internals", + "title": "monitor", + "version": "1.0", + "x-binding-c-generator": { + "api": "monitor", + "version": 2, + "prefix": "f_", + "postfix": "", + "preinit": null, + "init": null, + "onevent": null, + "scope": "static", + "private": true + } + }, + "servers": [ + { + "url": "ws://{host}:{port}/api/monitor", + "description": "The API server.", + "variables": { + "host": { + "default": "localhost" + }, + "port": { + "default": "1234" + } + }, + "x-afb-events": [ + { + "$ref": "#/components/schemas/afb-event" + } + ] + } + ], + "components": { + "schemas": { + "afb-reply": { + "$ref": "#/components/schemas/afb-reply-v1" + }, + "afb-event": { + "$ref": "#/components/schemas/afb-event-v1" + }, + "afb-reply-v1": { + "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-v1": { + "type": "object", + "required": [ "jtype", "event" ], + "properties": { + "jtype": { + "type": "string", + "const": "afb-event" + }, + "event": { "type": "string" }, + "data": { "type": "object" } + } + }, + "set-verbosity": { + "anyOf": [ + { "$ref": "#/components/schemas/verbosity-map" }, + { "$ref": "#/components/schemas/verbosity-level" } + ] + }, + "get-request": { + "type": "object", + "properties": { + "verbosity": { "$ref": "#/components/schemas/get-verbosity" }, + "apis": { "$ref": "#/components/schemas/get-apis" } + } + }, + "get-response": { + "type": "object", + "properties": { + "verbosity": { "$ref": "#/components/schemas/verbosity-map" }, + "apis": { "type": "object" } + } + }, + "get-verbosity": { + "anyOf": [ + { "type": "boolean" }, + { "type": "array", "items": { "type": "string" } }, + { "type": "object" } + ] + }, + "get-apis": { + "anyOf": [ + { "type": "boolean" }, + { "type": "array", "items": { "type": "string" } }, + { "type": "object" } + ] + }, + "verbosity-map": { + "type": "object", + "patternProperties": { "^.*$": { "$ref": "#/components/schemas/verbosity-level" } } + }, + "verbosity-level": { + "enum": [ "debug", 3, "info", 2, "notice", "warning", 1, "error", 0 ] + }, + "trace-add": { + "anyOf": [ + { "type": "array", "items": { "$ref": "#/components/schemas/trace-add-object" } }, + { "$ref": "#/components/schemas/trace-add-any" } + ] + }, + "trace-add-any": { + "anyOf": [ + { "$ref": "#/components/schemas/trace-add-request" }, + { "$ref": "#/components/schemas/trace-add-object" } + ] + }, + "trace-add-object": { + "type": "object", + "properties": { + "name": { "type": "string", "description": "name of the generated event", "default": "trace" }, + "tag": { "type": "string", "description": "tag for grouping traces", "default": "trace" }, + "api": { "type": "string", "description": "api for requests, daemons and services" }, + "verb": { "type": "string", "description": "verb for requests" }, + "session": { "type": "string", "description": "session for requests" }, + "pattern": { "type": "string", "description": "pattern for events" }, + "request": { "$ref": "#/components/schemas/trace-add-request" }, + "daemon": { "$ref": "#/components/schemas/trace-add-daemon" }, + "service": { "$ref": "#/components/schemas/trace-add-service" }, + "event": { "$ref": "#/components/schemas/trace-add-event" }, + "for": { "$ref": "#/components/schemas/trace-add" } + }, + "examples": [ + { "tag": "1", "for": [ "common", { "api": "xxx", "request": "*", "daemon": "*", "service": "*" } ] } + ] + }, + "trace-add-request": { + "anyOf": [ + { "type": "array", "items": { "$ref": "#/components/schemas/trace-request-names" } }, + { "$ref": "#/components/schemas/trace-request-names" } + ] + }, + "trace-request-names": { + "title": "name of traceable items of requests", + "enum": [ + "*", + "addref", + "all", + "args", + "begin", + "common", + "context", + "context_get", + "context_set", + "end", + "event", + "extra", + "fail", + "get", + "json", + "life", + "ref", + "result", + "session", + "session_close", + "session_set_LOA", + "simple", + "store", + "stores", + "subcall", + "subcall_result", + "subcalls", + "subcallsync", + "subcallsync_result", + "subscribe", + "success", + "unref", + "unstore", + "unsubscribe", + "vverbose" + ] + }, + "trace-add-daemon": { + "anyOf": [ + { "type": "array", "items": { "$ref": "#/components/schemas/trace-daemon-names" } }, + { "$ref": "#/components/schemas/trace-daemon-names" } + ] + }, + "trace-daemon-names": { + "title": "name of traceable items of daemons", + "enum": [ + "*", + "all", + "common", + "event_broadcast_after", + "event_broadcast_before", + "event_make", + "extra", + "get_event_loop", + "get_system_bus", + "get_user_bus", + "queue_job", + "require_api", + "require_api_result", + "rootdir_get_fd", + "rootdir_open_locale", + "unstore_req", + "vverbose" + ] + }, + "trace-add-service": { + "anyOf": [ + { "type": "array", "items": { "$ref": "#/components/schemas/trace-service-names" } }, + { "$ref": "#/components/schemas/trace-service-names" } + ] + }, + "trace-service-names": { + "title": "name of traceable items of services", + "enum": [ + "*", + "all", + "call", + "call_result", + "callsync", + "callsync_result", + "on_event_after", + "on_event_before", + "start_after", + "start_before" + ] + }, + "trace-add-event": { + "anyOf": [ + { "type": "array", "items": { "$ref": "#/components/schemas/trace-event-names" } }, + { "$ref": "#/components/schemas/trace-event-names" } + ] + }, + "trace-event-names": { + "title": "name of traceable items of events", + "enum": [ + "*", + "all", + "broadcast_after", + "broadcast_before", + "common", + "create", + "drop", + "extra", + "name", + "push_after", + "push_before" + ] + }, + "trace-drop": { + "anyOf": [ + { "type": "boolean" }, + { + "type": "object", + "properties": { + "event": { "anyOf": [ { "type": "string" }, { "type": "array", "items": "string" } ] }, + "tag": { "anyOf": [ { "type": "string" }, { "type": "array", "items": "string" } ] }, + "session": { "anyOf": [ { "type": "string" }, { "type": "array", "items": "string" } ] } + } + } + ] + } + }, + "x-permissions": { + "trace": { + "permission": "urn:AGL:permission:monitor:public:trace" + }, + "set": { + "permission": "urn:AGL:permission:monitor:public:set" + }, + "get": { + "permission": "urn:AGL:permission:monitor:public:get" + }, + "get-or-set": { + "anyOf": [ + { "$ref": "#/components/x-permissions/get" }, + { "$ref": "#/components/x-permissions/set" } + ] + } + } + }, + "paths": { + "/get": { + "description": "Get monitoring data.", + "get": { + "x-permissions": { + "$ref": "#/components/x-permissions/get-or-set" + }, + "parameters": [ + { + "in": "query", + "name": "verbosity", + "required": false, + "schema": { "$ref": "#/components/schemas/get-verbosity" } + }, + { + "in": "query", + "name": "apis", + "required": false, + "schema": { "$ref": "#/components/schemas/get-apis" } + } + ], + "responses": { + "200": { + "description": "A complex object array response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/afb-reply" + } + } + } + } + } + } + }, + "/set": { + "description": "Set monitoring actions.", + "get": { + "x-permissions": { + "$ref": "#/components/x-permissions/set" + }, + "parameters": [ + { + "in": "query", + "name": "verbosity", + "required": false, + "schema": { "$ref": "#/components/schemas/set-verbosity" } + } + ], + "responses": { + "200": { + "description": "A complex object array response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/afb-reply" + } + } + } + } + } + } + }, + "/trace": { + "description": "Set monitoring actions.", + "get": { + "x-permissions": { + "$ref": "#/components/x-permissions/trace" + }, + "parameters": [ + { + "in": "query", + "name": "add", + "required": false, + "schema": { "$ref": "#/components/schemas/trace-add" } + }, + { + "in": "query", + "name": "drop", + "required": false, + "schema": { "$ref": "#/components/schemas/trace-drop" } + } + ], + "responses": { + "200": { + "description": "A complex object array response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/afb-reply" + } + } + } + } + } + } + } + } +} diff --git a/src/genskel/CMakeLists.txt b/src/genskel/CMakeLists.txt deleted file mode 100644 index b1d63825..00000000 --- a/src/genskel/CMakeLists.txt +++ /dev/null @@ -1,30 +0,0 @@ -########################################################################### -# Copyright 2015, 2016, 2017 IoT.bzh -# -# author: José Bollo -# -# 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_EXECUTABLE(afb-genskel genskel.c) -ADD_EXECUTABLE(afb-exprefs exprefs.c) -ADD_EXECUTABLE(afb-json2c json2c.c) - -TARGET_LINK_LIBRARIES(afb-genskel ${link_libraries}) -TARGET_LINK_LIBRARIES(afb-exprefs ${link_libraries}) -TARGET_LINK_LIBRARIES(afb-json2c ${link_libraries}) - -INSTALL(TARGETS afb-genskel RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) -INSTALL(TARGETS afb-exprefs RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) -INSTALL(TARGETS afb-json2c RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) - diff --git a/src/genskel/exprefs.c b/src/genskel/exprefs.c deleted file mode 100644 index 4ea44b4d..00000000 --- a/src/genskel/exprefs.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (C) 2016, 2017 "IoT.bzh" - * Author José Bollo - * - * 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 simple program expands the object { "$ref": "#/path/to/a/target" } - * - * For example: - * - * { - * "type":{ - * "a": "int", - * "b": { "$ref": "#/type/a" } - * } - * } - * - * will be exapanded to - * - * { - * "type":{ - * "a": "int", - * "b": "int" - * } - * } - * - * Invocation: program [file|-]... - * - * without arguments, it reads the input. - */ - -#define _GNU_SOURCE -#include -#include -#include - -#include - -/** - * records path to the expanded node - */ -struct path -{ - struct json_object *object; /**< node being expanded */ - struct path *upper; /**< link to upper expanded nodes */ -}; - -/** - * root of the JSON being parsed - */ -struct json_object *root; - -/** - * Search for a reference of type "#/a/b/c" int the - * parsed JSON object - */ -struct json_object *search(const char *path) -{ - char *d; - struct json_object *i; - - /* does it match #/ at the beginning? */ - if (path[0] != '#' || (path[0] && path[1] != '/')) - return NULL; - - /* search from root to target */ - i = root; - d = strdupa(path+2); - d = strtok(d, "/"); - while(i && d) { - if (!json_object_object_get_ex(i, d, &i)) - return NULL; - d = strtok(NULL, "/"); - } - return i; -} - -/** - * Expands the node designated by path and returns its expanded form - */ -struct json_object *expand(struct path path) -{ - struct path *p; - struct json_object *o, *x; - int n, i; - struct json_object_iterator ji, jn; - - /* expansion depends of the type of the node */ - switch (json_object_get_type(path.object)) { - case json_type_object: - /* for object, look if it contains a property "$ref" */ - if (json_object_object_get_ex(path.object, "$ref", &o)) { - /* yes, reference, try to substitute its target */ - if (!json_object_is_type(o, json_type_string)) { - fprintf(stderr, "found a $ref not being string. Is: %s\n", json_object_get_string(o)); - exit(1); - } - x = search(json_object_get_string(o)); - if (!x) { - fprintf(stderr, "$ref not found. Was: %s\n", json_object_get_string(o)); - exit(1); - } - p = &path; - while(p) { - if (x == p->object) { - fprintf(stderr, "$ref recursive. Was: %s\n", json_object_get_string(o)); - exit(1); - } - p = p->upper; - } - /* cool found, return a new instance of the target */ - return json_object_get(x); - } - /* no, expand the values */ - ji = json_object_iter_begin(path.object); - jn = json_object_iter_end(path.object); - while (!json_object_iter_equal(&ji, &jn)) { - o = json_object_iter_peek_value(&ji); - x = expand((struct path){ .object = o, .upper = &path }); - if (x != o) - json_object_object_add(path.object, json_object_iter_peek_name(&ji), x); - json_object_iter_next(&ji); - } - break; - case json_type_array: - /* expand the values of arrays */ - i = 0; - n = json_object_array_length(path.object); - while (i != n) { - o = json_object_array_get_idx(path.object, i); - x = expand((struct path){ .object = o, .upper = &path }); - if (x != o) - json_object_array_put_idx(path.object, i, x); - i++; - } - break; - default: - /* otherwise no expansion */ - break; - } - /* return the given node */ - return path.object; -} - -/** - * process a file and prints its expansion on stdout - */ -void process(char *filename) -{ - /* translate - */ - if (!strcmp(filename, "-")) - filename = "/dev/stdin"; - - /* check access */ - if (access(filename, R_OK)) { - fprintf(stderr, "can't access file %s\n", filename); - exit(1); - } - - /* read the file */ - root = json_object_from_file(filename); - if (!root) { - fprintf(stderr, "reading file %s produced null\n", filename); - exit(1); - } - - /* expand */ - root = expand((struct path){ .object = root, .upper = NULL }); - - /* print the result */ - json_object_to_file_ext ("/dev/stdout", root, JSON_C_TO_STRING_PRETTY); - - /* clean up */ - json_object_put(root); -} - -/** process the list of files or stdin if none */ -int main(int ac, char **av) -{ - if (!*++av) - process("-"); - else { - do { process(*av); } while(*++av); - } - return 0; -} - diff --git a/src/genskel/genskel.c b/src/genskel/genskel.c deleted file mode 100644 index 62dfe3f4..00000000 --- a/src/genskel/genskel.c +++ /dev/null @@ -1,708 +0,0 @@ -/* - * Copyright (C) 2016, 2017 "IoT.bzh" - * Author José Bollo - * - * 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 simple program expands the object { "$ref": "#/path/to/a/target" } - * - * For example: - * - * { - * "type":{ - * "a": "int", - * "b": { "$ref": "#/type/a" } - * } - * } - * - * will be exapanded to - * - * { - * "type":{ - * "a": "int", - * "b": "int" - * } - * } - * - * Invocation: program [file|-]... - * - * without arguments, it reads the input. - */ - -#define _GNU_SOURCE -#include -#include -#include -#include - -#include - -#define oom(x) do{if(!(x)){fprintf(stderr,"out of memory\n");exit(1);}}while(0) - -/** - * records path to the expanded node - */ -struct path -{ - struct json_object *object; /**< node being expanded */ - struct path *upper; /**< link to upper expanded nodes */ -}; - -/** - * root of the JSON being parsed - */ -struct json_object *root = NULL; -struct json_object *d_perms = NULL; -struct json_object *a_perms = NULL; -const char *preinit = NULL; -const char *init = NULL; -const char *onevent = NULL; -const char *api = NULL; -const char *scope = NULL; -const char *prefix = NULL; -const char *postfix = NULL; -char *capi = NULL; -int priv = -1; -int noconc = -1; - -/** - * Search for a reference of type "#/a/b/c" int the - * parsed JSON object - */ -struct json_object *search(const char *path) -{ - char *d; - struct json_object *i; - - /* does it match #/ at the beginning? */ - if (path[0] != '#' || (path[0] && path[1] != '/')) - return NULL; - - /* search from root to target */ - i = root; - d = strdupa(path+2); - d = strtok(d, "/"); - while(i && d) { - if (!json_object_object_get_ex(i, d, &i)) - return NULL; - d = strtok(NULL, "/"); - } - return i; -} - -/** - * Expands the node designated by path and returns its expanded form - */ -struct json_object *expand_$ref(struct path path) -{ - struct path *p; - struct json_object *o, *x; - int n, i; - struct json_object_iterator ji, jn; - - /* expansion depends of the type of the node */ - switch (json_object_get_type(path.object)) { - case json_type_object: - /* for object, look if it contains a property "$ref" */ - if (json_object_object_get_ex(path.object, "$ref", &o)) { - /* yes, reference, try to substitute its target */ - if (!json_object_is_type(o, json_type_string)) { - fprintf(stderr, "found a $ref not being string. Is: %s\n", json_object_get_string(o)); - exit(1); - } - x = search(json_object_get_string(o)); - if (!x) { - fprintf(stderr, "$ref not found. Was: %s\n", json_object_get_string(o)); - exit(1); - } - p = &path; - while(p) { - if (x == p->object) { - fprintf(stderr, "$ref recursive. Was: %s\n", json_object_get_string(o)); - exit(1); - } - p = p->upper; - } - /* cool found, return a new instance of the target */ - return json_object_get(x); - } - /* no, expand the values */ - ji = json_object_iter_begin(path.object); - jn = json_object_iter_end(path.object); - while (!json_object_iter_equal(&ji, &jn)) { - o = json_object_iter_peek_value(&ji); - x = expand_$ref((struct path){ .object = o, .upper = &path }); - if (x != o) - json_object_object_add(path.object, json_object_iter_peek_name(&ji), x); - json_object_iter_next(&ji); - } - break; - case json_type_array: - /* expand the values of arrays */ - i = 0; - n = json_object_array_length(path.object); - while (i != n) { - o = json_object_array_get_idx(path.object, i); - x = expand_$ref((struct path){ .object = o, .upper = &path }); - if (x != o) - json_object_array_put_idx(path.object, i, x); - i++; - } - break; - default: - /* otherwise no expansion */ - break; - } - - /* return the given node */ - return path.object; -} - -char *cify(const char *str) -{ - char *r = strdup(str); - int i = 0; - while (r && r[i]) { - if (!isalnum(r[i])) - r[i] = '_'; - i++; - } - return r; -} - -char *make_info(const char *text, int split) -{ - const char *a, *b; - char *desc, c, buf[3]; - size_t len; - int i, pos, e; - - /* estimated length */ - a = b = text; - len = 1; - while((c = *b++)) { - len += 1 + ('"' == c); - } - - len += 7 * (1 + len / 72); - desc = malloc(len); - oom(desc); - - len = pos = 0; - if (!split) - desc[len++] = '"'; - b = a; - while((c = *b++)) { - if (c == '"') { - buf[0] = '\\'; - buf[1] = '"'; - buf[2] = 0; - } - else if (c == '\\') { - switch ((c = *b++)) { - case 0: - b--; - break; - case '/': - buf[0] = '/'; - buf[1] = 0; - break; - default: - buf[0] = '\\'; - buf[1] = c; - buf[2] = 0; - break; - } - } - else { - buf[0] = c; - buf[1] = 0; - } - i = e = 0; - while (buf[i]) { - if (split) { - if (pos >= 77 && !e) { - desc[len++] = '"'; - desc[len++] = '\n'; - pos = 0; - } - if (pos == 0) { - desc[len++] = ' '; - desc[len++] = ' '; - desc[len++] = ' '; - desc[len++] = ' '; - desc[len++] = '"'; - pos = 5; - } - } - c = buf[i++]; - desc[len++] = c; - e = !e && c == '\\'; - pos++; - } - } - desc[len++] = '"'; - if (split) - desc[len++] = '\n'; - desc[len] = 0; - return desc; -} - -char *make_desc(struct json_object *o) -{ - return make_info(json_object_to_json_string_ext(root, 0), 1); -} - -struct json_object *permissions_of_verb(struct json_object *obj) -{ - struct json_object *x, *y; - - if (json_object_object_get_ex(obj, "x-permissions", &x)) - return x; - - if (json_object_object_get_ex(obj, "get", &x)) - if (json_object_object_get_ex(x, "x-permissions", &y)) - return y; - - return NULL; -} - -void print_perms() -{ - int i, n; - - n = a_perms ? json_object_array_length(a_perms) : 0; - if (n) { - printf("static const struct afb_auth _afb_auths_v2_%s[] = {\n" , capi); - i = 0; - while (i < n) { - printf("\t{ %s }", json_object_get_string(json_object_array_get_idx(a_perms, i))); - printf(",\n"+(++i == n)); - } - printf("};\n\n"); - } -} - -struct json_object *new_perm(struct json_object *obj, const char *desc) -{ - const char *tag; - char *b; - struct json_object *x, *y; - - tag = obj ? json_object_to_json_string_ext(obj, 0) : desc; - if (!json_object_object_get_ex(d_perms, tag, &y)) { - if (!d_perms) { - d_perms = json_object_new_object(); - a_perms = json_object_new_array(); - } - - asprintf(&b, "&_afb_auths_v2_%s[%d]", capi, json_object_array_length(a_perms)); - x = json_object_new_string(desc); - y = json_object_new_string(b); - json_object_array_add(a_perms, x); - json_object_object_add(d_perms, tag, y); - free(b); - } - return y; -} - -struct json_object *decl_perm(struct json_object *obj); - -struct json_object *decl_perm_a(const char *op, struct json_object *obj) -{ - int i, n; - char *a; - struct json_object *x, *y; - - x = NULL; - i = n = obj ? json_object_array_length(obj) : 0; - while (i) { - y = decl_perm(json_object_array_get_idx(obj, --i)); - if (!y) - ; - else if (!x) - x = y; - else if (x != y) { - asprintf(&a, ".type = afb_auth_%s, .first = %s, .next = %s", - op, json_object_get_string(y), json_object_get_string(x)); - x = new_perm(NULL, a); - free(a); - } - } - return x; -} - -struct json_object *decl_perm(struct json_object *obj) -{ - char *a; - struct json_object *x, *y; - - if (json_object_object_get_ex(d_perms, json_object_to_json_string_ext(obj, 0), &x)) - return x; - - if (json_object_object_get_ex(obj, "permission", &x)) { - asprintf(&a, ".type = afb_auth_Permission, .text = \"%s\"", json_object_get_string(x)); - y = new_perm(obj, a); - free(a); - } - else if (json_object_object_get_ex(obj, "anyOf", &x)) { - y = decl_perm_a("Or", x); - } - else if (json_object_object_get_ex(obj, "allOf", &x)) { - y = decl_perm_a("And", x); - } - else if (json_object_object_get_ex(obj, "not", &x)) { - x = decl_perm(x); - asprintf(&a, ".type = afb_auth_Not, .first = %s", json_object_get_string(x)); - y = new_perm(obj, a); - free(a); - } - else if (json_object_object_get_ex(obj, "LOA", &x)) - y = NULL; - else if (json_object_object_get_ex(obj, "session", &x)) - y = NULL; - else - y = NULL; - - return y; -} - -void declare_permissions(const char *name, struct json_object *obj) -{ - struct json_object *p; - - p = permissions_of_verb(obj); - if (p) - decl_perm(p); -} - - -#define SESSION_CLOSE 0x000001 -#define SESSION_RENEW 0x000010 -#define SESSION_CHECK 0x000100 -#define SESSION_LOA_1 0x001000 -#define SESSION_LOA_2 0x011000 -#define SESSION_LOA_3 0x111000 -#define SESSION_MASK 0x111111 - - -int get_session(struct json_object *obj); - -int get_session_a(int and, struct json_object *obj) -{ - int i, n, x, y; - - n = obj ? json_object_array_length(obj) : 0; - if (n == 0) - return 0; - - i = n; - x = get_session(json_object_array_get_idx(obj, --i)); - while (i) { - y = get_session(json_object_array_get_idx(obj, --i)); - if (and) - x &= y; - else - x |= y; - } - return x; -} - -int get_session(struct json_object *obj) -{ - int y; - const char *a; - struct json_object *x; - - y = 0; - if (json_object_object_get_ex(obj, "anyOf", &x)) { - y = get_session_a(1, x); - } - else if (json_object_object_get_ex(obj, "allOf", &x)) { - y = get_session_a(0, x); - } - else if (json_object_object_get_ex(obj, "not", &x)) { - y = ~get_session(x) & SESSION_MASK; - } - else if (json_object_object_get_ex(obj, "LOA", &x)) { - switch (json_object_get_int(x)) { - case 3: y = SESSION_LOA_3; break; - case 2: y = SESSION_LOA_2; break; - case 1: y = SESSION_LOA_1; break; - default: break; - } - } - else if (json_object_object_get_ex(obj, "session", &x)) { - a = json_object_get_string(x); - if (!strcmp(a, "check")) - y = SESSION_CHECK; - else if (!strcmp(a, "close")) - y = SESSION_CLOSE; - } - else if (json_object_object_get_ex(obj, "token", &x)) { - a = json_object_get_string(x); - if (!strcmp(a, "refresh")) - y = SESSION_RENEW; - } - - return y; -} - -void print_session(struct json_object *p) -{ - int s, c, l; - - s = p ? get_session(p) : 0; - c = 1; - if (s & SESSION_CHECK) { - printf("%s", "|AFB_SESSION_CHECK_V2" + c); - c = 0; - } - if (s & SESSION_LOA_3 & ~SESSION_LOA_2) - l = 3; - else if (s & SESSION_LOA_2 & ~SESSION_LOA_1) - l = 2; - else if (s & SESSION_LOA_1) - l = 1; - else - l = 0; - if (l) { - printf("%s%d_V2", "|AFB_SESSION_LOA_" + c, l); - c = 0; - } - if (s & SESSION_CLOSE) { - printf("%s", "|AFB_SESSION_CLOSE_V2" + c); - c = 0; - } - if (s & SESSION_RENEW) { - printf("%s", "|AFB_SESSION_REFRESH_V2" + c); - c = 0; - } - if (c) - printf("AFB_SESSION_NONE_V2"); -} - -void print_verb(const char *name) -{ - printf("%s%s%s" , prefix, name, postfix); -} - -void print_declare_verb(const char *name, struct json_object *obj) -{ - printf("%s void ", scope); - print_verb(name); - printf("(struct afb_req req);\n"); -} - -void print_struct_verb(const char *name, struct json_object *obj) -{ - struct json_object *p, *i; - const char *info; - - info = NULL; - if (json_object_object_get_ex(obj, "description", &i)) - info = json_object_get_string(i); - - p = permissions_of_verb(obj); - printf( - " {\n" - " .verb = \"%s\",\n" - " .callback = " - , name - ); - print_verb(name); - printf( - ",\n" - " .auth = %s,\n" - " .info = %s,\n" - " .session = " - , p && decl_perm(p) ? json_object_get_string(decl_perm(p)) : "NULL" - , info ? make_info(info, 0) : "NULL" - ); - print_session(p); - printf( - "\n" - " },\n" - ); -} - -void enum_verbs(void (*func)(const char *name, struct json_object *obj)) -{ - struct json_object_iterator ji, jn; - struct json_object *paths, *obj; - const char *name; - - /* search the verbs */ - paths = search("#/paths"); - if (!paths) - return; - - /* list the verbs and sort it */ - ji = json_object_iter_begin(paths); - jn = json_object_iter_end(paths); - while (!json_object_iter_equal(&ji, &jn)) { - name = json_object_iter_peek_name(&ji); - obj = json_object_iter_peek_value(&ji); - name += (*name == '/'); - func(name, obj); - json_object_iter_next(&ji); - } -} - -void getvarbool(int *var, const char *path, int defval) -{ - struct json_object *o; - - if (*var != 0 && *var != 1) { - o = search(path); - if (o && json_object_is_type(o, json_type_boolean)) - *var = json_object_get_boolean(o); - else - *var = !!defval; - } -} - -void getvar(const char **var, const char *path, const char *defval) -{ - struct json_object *o; - - if (!*var) { - o = search(path); - if (o && json_object_is_type(o, json_type_string)) - *var = json_object_get_string(o); - else - *var = defval; - } -} - -/** - * process a file and prints its expansion on stdout - */ -void process(char *filename) -{ - char *desc; - const char *info; - - /* translate - */ - if (!strcmp(filename, "-")) - filename = "/dev/stdin"; - - /* check access */ - if (access(filename, R_OK)) { - fprintf(stderr, "can't access file %s\n", filename); - exit(1); - } - - /* read the file */ - root = json_object_from_file(filename); - if (!root) { - fprintf(stderr, "reading file %s produced null\n", filename); - exit(1); - } - - /* create the description */ - desc = make_desc(root); - - /* expand references */ - root = expand_$ref((struct path){ .object = root, .upper = NULL }); - - /* get some names */ - getvar(&api, "#/info/x-binding-c-generator/api", NULL); - getvar(&preinit, "#/info/x-binding-c-generator/preinit", NULL); - getvar(&init, "#/info/x-binding-c-generator/init", NULL); - getvar(&onevent, "#/info/x-binding-c-generator/onevent", NULL); - getvar(&scope, "#/info/x-binding-c-generator/scope", "static"); - getvar(&prefix, "#/info/x-binding-c-generator/prefix", "afb_verb_"); - getvar(&postfix, "#/info/x-binding-c-generator/postfix", "_cb"); - getvarbool(&priv, "#/info/x-binding-c-generator/private", 0); - getvarbool(&noconc, "#/info/x-binding-c-generator/noconcurrency", 0); - getvar(&api, "#/info/title", "?"); - info = NULL; - getvar(&info, "#/info/description", NULL); - capi = cify(api); - - /* get the API name */ - printf( - "\n" - "static const char _afb_description_v2_%s[] =\n" - "%s" - ";\n" - "\n" - , capi, desc - ); - enum_verbs(declare_permissions); - print_perms(); - enum_verbs(print_declare_verb); - printf( - "\n" - "static const struct afb_verb_v2 _afb_verbs_v2_%s[] = {\n" - , capi - ); - enum_verbs(print_struct_verb); - printf( - " {\n" - " .verb = NULL,\n" - " .callback = NULL,\n" - " .auth = NULL,\n" - " .info = NULL,\n" - " .session = 0\n" - " }\n" - "};\n" - ); - printf( - "\n" - "%sconst struct afb_binding_v2 %s%s = {\n" - " .api = \"%s\",\n" - " .specification = _afb_description_v2_%s,\n" - " .info = %s,\n" - " .verbs = _afb_verbs_v2_%s,\n" - " .preinit = %s,\n" - " .init = %s,\n" - " .onevent = %s,\n" - " .noconcurrency = %d\n" - "};\n" - "\n" - , priv ? "static " : "" - , priv ? "_afb_binding_v2_" : "afbBindingV2" - , priv ? capi : "" - , api - , capi - , info ? make_info(info, 0) : "NULL" - , capi - , preinit ?: "NULL" - , init ?: "NULL" - , onevent ?: "NULL" - , !!noconc - ); - - /* clean up */ - json_object_put(root); - free(desc); -} - -/** process the list of files or stdin if none */ -int main(int ac, char **av) -{ - if (!*++av) - process("-"); - else { - do { process(*av); } while(*++av); - } - return 0; -} - - - - - diff --git a/src/genskel/json2c.c b/src/genskel/json2c.c deleted file mode 100644 index 109b6ee9..00000000 --- a/src/genskel/json2c.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (C) 2016, 2017 "IoT.bzh" - * Author José Bollo - * - * 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 simple program expands the object { "$ref": "#/path/to/a/target" } - * - * For example: - * - * { - * "type":{ - * "a": "int", - * "b": { "$ref": "#/type/a" } - * } - * } - * - * will be exapanded to - * - * { - * "type":{ - * "a": "int", - * "b": "int" - * } - * } - * - * Invocation: program [file|-]... - * - * without arguments, it reads the input. - */ - -#define _GNU_SOURCE -#include -#include -#include - -#include - -#define oom(x) do{if(!(x)){fprintf(stderr,"out of memory\n");exit(1);}}while(0) - -/** - * root of the JSON being parsed - */ -struct json_object *root = NULL; - -char *make_desc(struct json_object *o) -{ - const char *a, *b; - char *desc, c, buf[3]; - size_t len; - int i, pos, e; - - a = b = json_object_to_json_string_ext(root, 0); - len = 1; - while((c = *b++)) { - len += 1 + ('"' == c); - } - - len += 7 * (1 + len / 72); - desc = malloc(len); - oom(desc); - - len = pos = 0; - b = a; - while((c = *b++)) { - if (c == '"') { - buf[0] = '\\'; - buf[1] = '"'; - buf[2] = 0; - } - else if (c == '\\') { - switch ((c = *b++)) { - case 0: - b--; - break; - case '/': - buf[0] = '/'; - buf[1] = 0; - break; - default: - buf[0] = '\\'; - buf[1] = c; - buf[2] = 0; - break; - } - } - else { - buf[0] = c; - buf[1] = 0; - } - i = e = 0; - while (buf[i]) { - if (pos >= 77 && !e) { - desc[len++] = '"'; - desc[len++] = '\n'; - pos = 0; - } - if (pos == 0) { - desc[len++] = ' '; - desc[len++] = ' '; - desc[len++] = ' '; - desc[len++] = ' '; - desc[len++] = '"'; - pos = 5; - } - c = buf[i++]; - desc[len++] = c; - e = !e && c == '\\'; - pos++; - } - } - desc[len++] = '"'; - desc[len++] = '\n'; - desc[len] = 0; - return desc; -} - -/** - * process a file and prints its expansion on stdout - */ -void process(char *filename) -{ - char *desc; - - /* translate - */ - if (!strcmp(filename, "-")) - filename = "/dev/stdin"; - - /* check access */ - if (access(filename, R_OK)) { - fprintf(stderr, "can't access file %s\n", filename); - exit(1); - } - - /* read the file */ - root = json_object_from_file(filename); - if (!root) { - fprintf(stderr, "reading file %s produced null\n", filename); - exit(1); - } - - /* create the description */ - desc = make_desc(root); - - printf("%s", desc); - - /* clean up */ - json_object_put(root); - free(desc); -} - -/** process the list of files or stdin if none */ -int main(int ac, char **av) -{ - if (!*++av) - process("-"); - else { - do { process(*av); } while(*++av); - } - return 0; -} - - diff --git a/src/genskel/monitor-api.json b/src/genskel/monitor-api.json deleted file mode 100644 index 8361d572..00000000 --- a/src/genskel/monitor-api.json +++ /dev/null @@ -1,400 +0,0 @@ -{ - "openapi": "3.0.0", - "info": { - "description": "monitoring of bindings and internals", - "title": "monitor", - "version": "1.0", - "x-binding-c-generator": { - "api": "monitor", - "version": 2, - "prefix": "f_", - "postfix": "", - "preinit": null, - "init": null, - "onevent": null, - "scope": "static", - "private": true - } - }, - "servers": [ - { - "url": "ws://{host}:{port}/api/monitor", - "description": "The API server.", - "variables": { - "host": { - "default": "localhost" - }, - "port": { - "default": "1234" - } - }, - "x-afb-events": [ - { - "$ref": "#/components/schemas/afb-event" - } - ] - } - ], - "components": { - "schemas": { - "afb-reply": { - "$ref": "#/components/schemas/afb-reply-v1" - }, - "afb-event": { - "$ref": "#/components/schemas/afb-event-v1" - }, - "afb-reply-v1": { - "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-v1": { - "type": "object", - "required": [ "jtype", "event" ], - "properties": { - "jtype": { - "type": "string", - "const": "afb-event" - }, - "event": { "type": "string" }, - "data": { "type": "object" } - } - }, - "set-verbosity": { - "anyOf": [ - { "$ref": "#/components/schemas/verbosity-map" }, - { "$ref": "#/components/schemas/verbosity-level" } - ] - }, - "get-request": { - "type": "object", - "properties": { - "verbosity": { "$ref": "#/components/schemas/get-verbosity" }, - "apis": { "$ref": "#/components/schemas/get-apis" } - } - }, - "get-response": { - "type": "object", - "properties": { - "verbosity": { "$ref": "#/components/schemas/verbosity-map" }, - "apis": { "type": "object" } - } - }, - "get-verbosity": { - "anyOf": [ - { "type": "boolean" }, - { "type": "array", "items": { "type": "string" } }, - { "type": "object" } - ] - }, - "get-apis": { - "anyOf": [ - { "type": "boolean" }, - { "type": "array", "items": { "type": "string" } }, - { "type": "object" } - ] - }, - "verbosity-map": { - "type": "object", - "patternProperties": { "^.*$": { "$ref": "#/components/schemas/verbosity-level" } } - }, - "verbosity-level": { - "enum": [ "debug", 3, "info", 2, "notice", "warning", 1, "error", 0 ] - }, - "trace-add": { - "anyOf": [ - { "type": "array", "items": { "$ref": "#/components/schemas/trace-add-object" } }, - { "$ref": "#/components/schemas/trace-add-any" } - ] - }, - "trace-add-any": { - "anyOf": [ - { "$ref": "#/components/schemas/trace-add-request" }, - { "$ref": "#/components/schemas/trace-add-object" } - ] - }, - "trace-add-object": { - "type": "object", - "properties": { - "name": { "type": "string", "description": "name of the generated event", "default": "trace" }, - "tag": { "type": "string", "description": "tag for grouping traces", "default": "trace" }, - "api": { "type": "string", "description": "api for requests, daemons and services" }, - "verb": { "type": "string", "description": "verb for requests" }, - "session": { "type": "string", "description": "session for requests" }, - "pattern": { "type": "string", "description": "pattern for events" }, - "request": { "$ref": "#/components/schemas/trace-add-request" }, - "daemon": { "$ref": "#/components/schemas/trace-add-daemon" }, - "service": { "$ref": "#/components/schemas/trace-add-service" }, - "event": { "$ref": "#/components/schemas/trace-add-event" }, - "for": { "$ref": "#/components/schemas/trace-add" } - }, - "examples": [ - { "tag": "1", "for": [ "common", { "api": "xxx", "request": "*", "daemon": "*", "service": "*" } ] } - ] - }, - "trace-add-request": { - "anyOf": [ - { "type": "array", "items": { "$ref": "#/components/schemas/trace-request-names" } }, - { "$ref": "#/components/schemas/trace-request-names" } - ] - }, - "trace-request-names": { - "title": "name of traceable items of requests", - "enum": [ - "*", - "addref", - "all", - "args", - "begin", - "common", - "context", - "context_get", - "context_set", - "end", - "event", - "extra", - "fail", - "get", - "json", - "life", - "ref", - "result", - "session", - "session_close", - "session_set_LOA", - "simple", - "store", - "stores", - "subcall", - "subcall_result", - "subcalls", - "subcallsync", - "subcallsync_result", - "subscribe", - "success", - "unref", - "unstore", - "unsubscribe", - "vverbose" - ] - }, - "trace-add-daemon": { - "anyOf": [ - { "type": "array", "items": { "$ref": "#/components/schemas/trace-daemon-names" } }, - { "$ref": "#/components/schemas/trace-daemon-names" } - ] - }, - "trace-daemon-names": { - "title": "name of traceable items of daemons", - "enum": [ - "*", - "all", - "common", - "event_broadcast_after", - "event_broadcast_before", - "event_make", - "extra", - "get_event_loop", - "get_system_bus", - "get_user_bus", - "queue_job", - "require_api", - "require_api_result", - "rootdir_get_fd", - "rootdir_open_locale", - "unstore_req", - "vverbose" - ] - }, - "trace-add-service": { - "anyOf": [ - { "type": "array", "items": { "$ref": "#/components/schemas/trace-service-names" } }, - { "$ref": "#/components/schemas/trace-service-names" } - ] - }, - "trace-service-names": { - "title": "name of traceable items of services", - "enum": [ - "*", - "all", - "call", - "call_result", - "callsync", - "callsync_result", - "on_event_after", - "on_event_before", - "start_after", - "start_before" - ] - }, - "trace-add-event": { - "anyOf": [ - { "type": "array", "items": { "$ref": "#/components/schemas/trace-event-names" } }, - { "$ref": "#/components/schemas/trace-event-names" } - ] - }, - "trace-event-names": { - "title": "name of traceable items of events", - "enum": [ - "*", - "all", - "broadcast_after", - "broadcast_before", - "common", - "create", - "drop", - "extra", - "name", - "push_after", - "push_before" - ] - }, - "trace-drop": { - "anyOf": [ - { "type": "boolean" }, - { - "type": "object", - "properties": { - "event": { "anyOf": [ { "type": "string" }, { "type": "array", "items": "string" } ] }, - "tag": { "anyOf": [ { "type": "string" }, { "type": "array", "items": "string" } ] }, - "session": { "anyOf": [ { "type": "string" }, { "type": "array", "items": "string" } ] } - } - } - ] - } - }, - "x-permissions": { - "trace": { - "permission": "urn:AGL:permission:monitor:public:trace" - }, - "set": { - "permission": "urn:AGL:permission:monitor:public:set" - }, - "get": { - "permission": "urn:AGL:permission:monitor:public:get" - }, - "get-or-set": { - "anyOf": [ - { "$ref": "#/components/x-permissions/get" }, - { "$ref": "#/components/x-permissions/set" } - ] - } - } - }, - "paths": { - "/get": { - "description": "Get monitoring data.", - "get": { - "x-permissions": { - "$ref": "#/components/x-permissions/get-or-set" - }, - "parameters": [ - { - "in": "query", - "name": "verbosity", - "required": false, - "schema": { "$ref": "#/components/schemas/get-verbosity" } - }, - { - "in": "query", - "name": "apis", - "required": false, - "schema": { "$ref": "#/components/schemas/get-apis" } - } - ], - "responses": { - "200": { - "description": "A complex object array response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/afb-reply" - } - } - } - } - } - } - }, - "/set": { - "description": "Set monitoring actions.", - "get": { - "x-permissions": { - "$ref": "#/components/x-permissions/set" - }, - "parameters": [ - { - "in": "query", - "name": "verbosity", - "required": false, - "schema": { "$ref": "#/components/schemas/set-verbosity" } - } - ], - "responses": { - "200": { - "description": "A complex object array response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/afb-reply" - } - } - } - } - } - } - }, - "/trace": { - "description": "Set monitoring actions.", - "get": { - "x-permissions": { - "$ref": "#/components/x-permissions/trace" - }, - "parameters": [ - { - "in": "query", - "name": "add", - "required": false, - "schema": { "$ref": "#/components/schemas/trace-add" } - }, - { - "in": "query", - "name": "drop", - "required": false, - "schema": { "$ref": "#/components/schemas/trace-drop" } - } - ], - "responses": { - "200": { - "description": "A complex object array response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/afb-reply" - } - } - } - } - } - } - } - } -} -- cgit 1.2.3-korg