From 948a0590042040edd092ef2888ca240068baaa65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Mon, 29 May 2017 11:27:34 +0300 Subject: [PATCH] MXS-1220: Add module commands to /maxscale/modules The module commands are now exposed as an additional sub-resource for the module type. --- include/maxscale/config.h | 4 +++ server/core/config.cc | 4 +++ server/core/load_utils.cc | 54 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/include/maxscale/config.h b/include/maxscale/config.h index 805e2a9ff..392513b1f 100644 --- a/include/maxscale/config.h +++ b/include/maxscale/config.h @@ -72,6 +72,8 @@ MXS_BEGIN_DECLS * that the sizeof(CN_) returns the actual size of that string. */ extern const char CN_ADDRESS[]; +extern const char CN_ARG_MAX[]; +extern const char CN_ARG_MIN[]; extern const char CN_ADMIN_AUTH[]; extern const char CN_ADMIN_ENABLED[]; extern const char CN_ADMIN_HOST[]; @@ -90,6 +92,7 @@ extern const char CN_AUTO[]; extern const char CN_CONNECTION_TIMEOUT[]; extern const char CN_DATA[]; extern const char CN_DEFAULT[]; +extern const char CN_DESCRIPTION[]; extern const char CN_ENABLE_ROOT_USER[]; extern const char CN_FEEDBACK[]; extern const char CN_FILTERS[]; @@ -107,6 +110,7 @@ extern const char CN_MAX_CONNECTIONS[]; extern const char CN_MAX_RETRY_INTERVAL[]; extern const char CN_MODULE[]; extern const char CN_MODULES[]; +extern const char CN_MODULE_COMMAND[]; extern const char CN_MONITORS[]; extern const char CN_MONITOR[]; extern const char CN_MS_TIMESTAMP[]; diff --git a/server/core/config.cc b/server/core/config.cc index c9bdad5e6..a392365ec 100644 --- a/server/core/config.cc +++ b/server/core/config.cc @@ -56,6 +56,8 @@ using std::set; using std::string; const char CN_ADDRESS[] = "address"; +const char CN_ARG_MAX[] = "arg_max"; +const char CN_ARG_MIN[] = "arg_min"; const char CN_ADMIN_AUTH[] = "admin_auth"; const char CN_ADMIN_ENABLED[] = "admin_enabled"; const char CN_ADMIN_HOST[] = "admin_host"; @@ -74,6 +76,7 @@ const char CN_AUTO[] = "auto"; const char CN_CONNECTION_TIMEOUT[] = "connection_timeout"; const char CN_DATA[] = "data"; const char CN_DEFAULT[] = "default"; +const char CN_DESCRIPTION[] = "description"; const char CN_ENABLE_ROOT_USER[] = "enable_root_user"; const char CN_FEEDBACK[] = "feedback"; const char CN_FILTERS[] = "filters"; @@ -91,6 +94,7 @@ const char CN_MAX_CONNECTIONS[] = "max_connections"; const char CN_MAX_RETRY_INTERVAL[] = "max_retry_interval"; const char CN_MODULE[] = "module"; const char CN_MODULES[] = "modules"; +const char CN_MODULE_COMMAND[] = "module_command"; const char CN_MONITORS[] = "monitors"; const char CN_MONITOR[] = "monitor"; const char CN_MS_TIMESTAMP[] = "ms_timestamp"; diff --git a/server/core/load_utils.cc b/server/core/load_utils.cc index c5ace36f1..0f6995d6a 100644 --- a/server/core/load_utils.cc +++ b/server/core/load_utils.cc @@ -48,6 +48,7 @@ #include #include #include +#include #include "maxscale/modules.h" #include "maxscale/config.h" @@ -407,6 +408,50 @@ void dprintAllModules(DCB *dcb) dcb_printf(dcb, "----------------+-----------------+---------+-------+-------------------------\n\n"); } +struct cb_param +{ + json_t* commands; + const char* domain; + const char* host; +}; + +bool modulecmd_cb(const MODULECMD *cmd, void *data) +{ + cb_param* d = static_cast(data); + + json_t* obj = json_object(); + json_object_set_new(obj, CN_ID, json_string(cmd->identifier)); + json_object_set_new(obj, CN_TYPE, json_string(CN_MODULE_COMMAND)); + + json_t* attr = json_object(); + json_object_set_new(attr, CN_ARG_MIN, json_integer(cmd->arg_count_min)); + json_object_set_new(attr, CN_ARG_MAX, json_integer(cmd->arg_count_max)); + + json_t* param = json_array(); + + for (int i = 0; i < cmd->arg_count_max; i++) + { + json_t* p = json_object(); + json_object_set_new(p, CN_DESCRIPTION, json_string(cmd->arg_types[i].description)); + json_object_set_new(p, CN_TYPE, json_string(modulecmd_argtype_to_str(&cmd->arg_types[i]))); + json_object_set_new(p, CN_REQUIRED, json_boolean(MODULECMD_ARG_IS_REQUIRED(&cmd->arg_types[i]))); + json_array_append_new(param, p); + } + + std::string s = d->domain; + s += "/"; + s += cmd->identifier; + ss_dassert(strcmp(d->domain, cmd->domain) == 0); + + json_object_set_new(obj, CN_LINKS, mxs_json_self_link(d->host, CN_MODULES, s.c_str())); + json_object_set_new(attr, CN_PARAMETERS, param); + json_object_set_new(obj, CN_ATTRIBUTES, attr); + + json_array_append_new(d->commands, obj); + + return true; +} + static json_t* module_json_data(const LOADED_MODULE *mod, const char* host) { json_t* obj = json_object(); @@ -417,9 +462,13 @@ static json_t* module_json_data(const LOADED_MODULE *mod, const char* host) json_t* attr = json_object(); json_object_set_new(attr, "module_type", json_string(mod->type)); json_object_set_new(attr, "version", json_string(mod->info->version)); - json_object_set_new(attr, "description", json_string(mod->info->description)); + json_object_set_new(attr, CN_DESCRIPTION, json_string(mod->info->description)); json_object_set_new(attr, "api", json_string(mxs_module_api_to_string(mod->info->modapi))); - json_object_set_new(attr, "status", json_string(mxs_module_status_to_string(mod->info->status))); + json_object_set_new(attr, CN_STATUS, json_string(mxs_module_status_to_string(mod->info->status))); + + json_t* commands = json_array(); + cb_param p = {commands, mod->module, host}; + modulecmd_foreach(mod->module, NULL, modulecmd_cb, &p); json_t* params = json_array(); @@ -451,6 +500,7 @@ static json_t* module_json_data(const LOADED_MODULE *mod, const char* host) json_array_append_new(params, p); } + json_object_set_new(attr, "commands", commands); json_object_set_new(attr, CN_PARAMETERS, params); json_object_set_new(obj, CN_ATTRIBUTES, attr); json_object_set_new(obj, CN_LINKS, mxs_json_self_link(host, CN_MODULES, mod->module));