| 1 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 2 | |
| 3 | #include "dyncfg.h" |
| 4 | |
| 5 | static DICTIONARY *dyncfg_nodes = NULL; |
| 6 | |
| 7 | static int dyncfg_inline_callback(struct rrd_function_execute *rfe, void *data __maybe_unused) { |
| 8 | char tr[UUID_COMPACT_STR_LEN]; |
| 9 | uuid_unparse_lower_compact(*rfe->transaction, tr); |
| 10 | |
| 11 | bool cancelled = rfe->is_cancelled.cb ? rfe->is_cancelled.cb(rfe->is_cancelled.data) : false; |
| 12 | |
| 13 | int code; |
| 14 | if(cancelled) |
| 15 | code = HTTP_RESP_CLIENT_CLOSED_REQUEST; |
| 16 | else |
| 17 | code = dyncfg_node_find_and_call(dyncfg_nodes, tr, rfe->function, rfe->stop_monotonic_ut, &cancelled, |
| 18 | rfe->payload, rfe->user_access, rfe->source, rfe->result.wb); |
| 19 | |
| 20 | if(code == HTTP_RESP_CLIENT_CLOSED_REQUEST || (rfe->is_cancelled.cb && rfe->is_cancelled.cb(rfe->is_cancelled.data))) { |
| 21 | buffer_flush(rfe->result.wb); |
| 22 | code = HTTP_RESP_CLIENT_CLOSED_REQUEST; |
| 23 | } |
| 24 | |
| 25 | if(rfe->result.cb) |
| 26 | rfe->result.cb(rfe->result.wb, code, rfe->result.data); |
| 27 | |
| 28 | return code; |
| 29 | } |
| 30 | |
| 31 | bool dyncfg_add(RRDHOST *host, const char *id, const char *path, |
| 32 | DYNCFG_STATUS status, DYNCFG_TYPE type, DYNCFG_SOURCE_TYPE source_type, const char *source, |
| 33 | DYNCFG_CMDS cmds, HTTP_ACCESS view_access, HTTP_ACCESS edit_access, |
| 34 | dyncfg_cb_t cb, void *data) { |
| 35 | |
| 36 | struct dyncfg_node tmp = { |
| 37 | .cmds = cmds, |
| 38 | .type = type, |
| 39 | .cb = cb, |
| 40 | .data = data, |
| 41 | }; |
| 42 | dictionary_set(dyncfg_nodes, id, &tmp, sizeof(tmp)); |
| 43 | |
| 44 | if(!dyncfg_add_low_level(host, id, path, status, type, source_type, source, cmds, |
| 45 | 0, 0, true, view_access, edit_access, |
| 46 | dyncfg_inline_callback, NULL)) { |
| 47 | dictionary_del(dyncfg_nodes, id); |
| 48 | return false; |
| 49 | } |
| 50 | |
| 51 | return true; |
| 52 | } |
| 53 | |
| 54 | void dyncfg_del(RRDHOST *host, const char *id) { |
| 55 | dictionary_del(dyncfg_nodes, id); |
| 56 | dyncfg_del_low_level(host, id); |
| 57 | } |
| 58 | |
| 59 | void dyncfg_status(RRDHOST *host, const char *id, DYNCFG_STATUS status) { |
| 60 | dyncfg_status_low_level(host, id, status); |
| 61 | } |
| 62 | |
| 63 | void dyncfg_init(bool load_saved) { |
| 64 | dyncfg_nodes = dyncfg_nodes_dictionary_create(); |
| 65 | dyncfg_init_low_level(load_saved); |
| 66 | } |
| 67 | |
| 68 | void dyncfg_shutdown(void) { |
| 69 | if(dyncfg_nodes) { |
| 70 | dictionary_destroy(dyncfg_nodes); |
| 71 | dyncfg_nodes = NULL; |
| 72 | } |
| 73 | dyncfg_shutdown_low_level(); |
| 74 | } |