diff --git a/include/maxscale/config.h b/include/maxscale/config.h index 5e0238081..491eced84 100644 --- a/include/maxscale/config.h +++ b/include/maxscale/config.h @@ -93,6 +93,8 @@ extern const char CN_SERVICES[]; extern const char CN_SERVICE[]; extern const char CN_SKIP_PERMISSION_CHECKS[]; extern const char CN_SOCKET[]; +extern const char CN_STATE[]; +extern const char CN_STATUS[]; extern const char CN_SSL[]; extern const char CN_SSL_CA_CERT[]; extern const char CN_SSL_CERT[]; diff --git a/server/core/config.cc b/server/core/config.cc index 1f405439a..fd1c4d269 100644 --- a/server/core/config.cc +++ b/server/core/config.cc @@ -104,6 +104,8 @@ const char CN_SERVICES[] = "services"; const char CN_SERVICE[] = "service"; const char CN_SKIP_PERMISSION_CHECKS[] = "skip_permission_checks"; const char CN_SOCKET[] = "socket"; +const char CN_STATE[] = "state"; +const char CN_STATUS[] = "status"; const char CN_SSL[] = "ssl"; const char CN_SSL_CA_CERT[] = "ssl_ca_cert"; const char CN_SSL_CERT[] = "ssl_cert"; @@ -156,7 +158,7 @@ static FEEDBACK_CONF feedback; char *version_string = NULL; static bool is_persisted_config = false; /**< True if a persisted configuration file is being parsed */ -static const char *service_params[] = +const char *config_service_params[] = { CN_TYPE, CN_ROUTER, @@ -183,7 +185,7 @@ static const char *service_params[] = NULL }; -static const char *listener_params[] = +const char *config_listener_params[] = { CN_AUTHENTICATOR_OPTIONS, CN_TYPE, @@ -202,7 +204,7 @@ static const char *listener_params[] = NULL }; -static const char *monitor_params[] = +const char *config_monitor_params[] = { CN_TYPE, CN_MODULE, @@ -220,14 +222,14 @@ static const char *monitor_params[] = NULL }; -static const char *filter_params[] = +const char *config_filter_params[] = { CN_TYPE, CN_MODULE, NULL }; -static const char *server_params[] = +const char *server_params[] = { CN_TYPE, CN_PROTOCOL, @@ -2035,23 +2037,23 @@ check_config_objects(CONFIG_CONTEXT *context) { if (!strcmp(type, CN_SERVICE)) { - param_set = service_params; + param_set = config_service_params; module = config_get_value(obj->parameters, CN_ROUTER); module_type = MODULE_ROUTER; } else if (!strcmp(type, CN_LISTENER)) { - param_set = listener_params; + param_set = config_listener_params; } else if (!strcmp(type, CN_MONITOR)) { - param_set = monitor_params; + param_set = config_monitor_params; module = config_get_value(obj->parameters, CN_MODULE); module_type = MODULE_MONITOR; } else if (!strcmp(type, CN_FILTER)) { - param_set = filter_params; + param_set = config_filter_params; module = config_get_value(obj->parameters, CN_MODULE); module_type = MODULE_FILTER; } @@ -2632,6 +2634,55 @@ void config_add_defaults(CONFIG_CONTEXT *ctx, const MXS_MODULE_PARAM *params) } } +static json_t* param_value_json(const MXS_CONFIG_PARAMETER* param, + const MXS_MODULE* mod) +{ + json_t* rval = NULL; + + for (int i = 0; mod->parameters[i].name; i++) + { + if (strcmp(mod->parameters[i].name, param->name) == 0) + { + switch (mod->parameters[i].type) + { + case MXS_MODULE_PARAM_COUNT: + case MXS_MODULE_PARAM_INT: + rval = json_integer(strtol(param->value, NULL, 10)); + break; + + case MXS_MODULE_PARAM_BOOL: + rval = json_boolean(config_truth_value(param->value)); + break; + + default: + rval = json_string(param->value); + break; + } + } + } + + return rval; +} + +void config_add_module_params_json(const MXS_MODULE* mod, MXS_CONFIG_PARAMETER* parameters, + const char** type_params, json_t* output) +{ + set param_set; + + for (int i = 0; type_params[i]; i++) + { + param_set.insert(type_params[i]); + } + + for (MXS_CONFIG_PARAMETER* p = parameters; p; p = p->next) + { + if (param_set.find(p->name) == param_set.end()) + { + json_object_set_new(output, p->name, param_value_json(p, mod)); + } + } +} + /** * Create a new router for a service * @param obj Service configuration context diff --git a/server/core/filter.cc b/server/core/filter.cc index 71db12b11..05180a64c 100644 --- a/server/core/filter.cc +++ b/server/core/filter.cc @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -34,6 +35,7 @@ #include "maxscale/modules.h" using std::string; +using std::set; static SPINLOCK filter_spin = SPINLOCK_INIT; /**< Protects the list of all filters */ static MXS_FILTER_DEF *allFilters = NULL; /**< The list of all filters */ @@ -212,7 +214,7 @@ dprintAllFilters(DCB *dcb) } if (ptr->obj && ptr->filter) { - ptr->obj->diagnostics(ptr->filter, NULL, dcb); + ptr->obj->diagnostics(ptr->filter, NULL, dcb); } else { @@ -472,12 +474,9 @@ filter_upstream(MXS_FILTER_DEF *filter, MXS_FILTER_SESSION *fsession, MXS_UPSTRE } return me; } - -json_t* filter_to_json(const MXS_FILTER_DEF* filter, const char* host) +json_t* filter_parameters_to_json(const MXS_FILTER_DEF* filter) { json_t* rval = json_object(); - json_object_set_new(rval, "name", json_string(filter->name)); - json_object_set_new(rval, "module", json_string(filter->module)); if (filter->options) { @@ -491,6 +490,21 @@ json_t* filter_to_json(const MXS_FILTER_DEF* filter, const char* host) json_object_set_new(rval, "options", arr); } + /** Add custom module parameters */ + const MXS_MODULE* mod = get_module(filter->module, MODULE_FILTER); + config_add_module_params_json(mod, filter->parameters, config_filter_params, rval); + + return rval; +} + +json_t* filter_to_json(const MXS_FILTER_DEF* filter, const char* host) +{ + json_t* rval = json_object(); + + json_object_set_new(rval, CN_NAME, json_string(filter->name)); + json_object_set_new(rval, CN_MODULE, json_string(filter->module)); + json_object_set_new(rval, CN_PARAMETERS, filter_parameters_to_json(filter)); + if (filter->obj && filter->filter) { json_t* diag = filter->obj->diagnostics_json(filter->filter, NULL); diff --git a/server/core/maxscale/config.h b/server/core/maxscale/config.h index d3004d4cc..7d56cf9fe 100644 --- a/server/core/maxscale/config.h +++ b/server/core/maxscale/config.h @@ -19,6 +19,7 @@ #include #include +#include MXS_BEGIN_DECLS @@ -34,6 +35,13 @@ enum MAX_PARAM_LEN = 256 }; +/** Object type specific parameter name lists */ +extern const char *config_service_params[]; +extern const char *config_listener_params[]; +extern const char *config_monitor_params[]; +extern const char *config_filter_params[]; +extern const char *config_server_params[]; + /** * @brief Generate default module parameters * @@ -111,4 +119,17 @@ SSL_LISTENER *make_ssl_structure(CONFIG_CONTEXT *obj, bool require_cert, int *er */ bool config_have_required_ssl_params(CONFIG_CONTEXT *obj); +/** + * @brief Add non-standard module type parameters to a JSON object + * + * @param mod Module whose parameters are inspected + * @param parameters List of configuration parameters for the module + * @param type_params NULL terminated list of default module type parameters + * @param output Output JSON object where the parameters are added + */ +void config_add_module_params_json(const MXS_MODULE* mod, + MXS_CONFIG_PARAMETER* parameters, + const char** type_params, + json_t* output); + MXS_END_DECLS diff --git a/server/core/monitor.cc b/server/core/monitor.cc index d3e6e9980..5a1d30469 100644 --- a/server/core/monitor.cc +++ b/server/core/monitor.cc @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -37,14 +38,15 @@ #include "maxscale/modules.h" using std::string; +using std::set; const char CN_BACKEND_CONNECT_ATTEMPTS[] = "backend_connect_attempts"; const char CN_BACKEND_READ_TIMEOUT[] = "backend_read_timeout"; const char CN_BACKEND_WRITE_TIMEOUT[] = "backend_write_timeout"; const char CN_BACKEND_CONNECT_TIMEOUT[] = "backend_connect_timeout"; const char CN_MONITOR_INTERVAL[] = "monitor_interval"; -const char CN_SCRIPT[] = "monitor_interval"; -const char CN_EVENTS[] = "monitor_interval"; +const char CN_SCRIPT[] = "script"; +const char CN_EVENTS[] = "events"; static MXS_MONITOR *allMonitors = NULL; static SPINLOCK monLock = SPINLOCK_INIT; @@ -995,7 +997,7 @@ bool mon_status_changed(MXS_MONITOR_SERVERS* mon_srv) bool rval = false; /* Previous status is -1 if not yet set */ - if (mon_srv->mon_prev_status != (uint32_t)-1) + if (mon_srv->mon_prev_status != static_cast(-1)) { unsigned int old_status = mon_srv->mon_prev_status & all_server_bits; @@ -1529,19 +1531,39 @@ static const char* monitor_state_to_string(int state) } } -json_t* monitor_to_json(const MXS_MONITOR* monitor, const char* host) +json_t* monitor_parameters_to_json(const MXS_MONITOR* monitor) { json_t* rval = json_object(); - json_object_set_new(rval, CN_NAME, json_string(monitor->name)); - json_object_set_new(rval, CN_MODULE, json_string(monitor->module_name)); json_object_set_new(rval, CN_MONITOR_INTERVAL, json_integer(monitor->interval)); json_object_set_new(rval, CN_BACKEND_CONNECT_TIMEOUT, json_integer(monitor->connect_timeout)); json_object_set_new(rval, CN_BACKEND_READ_TIMEOUT, json_integer(monitor->read_timeout)); json_object_set_new(rval, CN_BACKEND_WRITE_TIMEOUT, json_integer(monitor->write_timeout)); json_object_set_new(rval, CN_BACKEND_CONNECT_ATTEMPTS, json_integer(monitor->connect_attempts)); - json_object_set_new(rval, "state", json_string(monitor_state_to_string(monitor->state))); + /** Add custom module parameters */ + const MXS_MODULE* mod = get_module(monitor->module_name, MODULE_MONITOR); + config_add_module_params_json(mod, monitor->parameters, config_monitor_params, rval); + + /** Don't show the default value for events if no script is defined */ + if (json_object_get(rval, CN_SCRIPT) == NULL) + { + json_object_del(rval, CN_EVENTS); + } + + return rval; +} + +json_t* monitor_to_json(const MXS_MONITOR* monitor, const char* host) +{ + json_t* rval = json_object(); + + json_object_set_new(rval, CN_NAME, json_string(monitor->name)); + json_object_set_new(rval, CN_MODULE, json_string(monitor->module_name)); + json_object_set_new(rval, CN_STATE, json_string(monitor_state_to_string(monitor->state))); + + /** Monitor parameters */ + json_object_set_new(rval, CN_PARAMETERS, monitor_parameters_to_json(monitor)); if (monitor->handle && monitor->module->diagnostics) { diff --git a/server/core/service.cc b/server/core/service.cc index 22282f3f4..13a834833 100644 --- a/server/core/service.cc +++ b/server/core/service.cc @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -55,6 +56,7 @@ #include "maxscale/service.h" using std::string; +using std::set; /** Base value for server weights */ #define SERVICE_BASE_SERVER_WEIGHT 1000 @@ -2396,6 +2398,10 @@ json_t* service_parameters_to_json(const SERVICE* service) json_object_set_new(rval, CN_LOG_AUTH_WARNINGS, json_boolean(service->log_auth_warnings)); json_object_set_new(rval, CN_RETRY_ON_FAILURE, json_boolean(service->retry_start)); + /** Add custom module parameters */ + const MXS_MODULE* mod = get_module(service->routerModule, MODULE_ROUTER); + config_add_module_params_json(mod, service->svc_config_param, config_service_params, rval); + return rval; } @@ -2406,9 +2412,9 @@ json_t* service_to_json(const SERVICE* service, const char* host) json_t* rval = json_object(); /** General service information */ - json_object_set_new(rval, "name", json_string(service->name)); - json_object_set_new(rval, "router", json_string(service->routerModule)); - json_object_set_new(rval, "state", json_string(service_state_to_string(service->state))); + json_object_set_new(rval, CN_NAME, json_string(service->name)); + json_object_set_new(rval, CN_ROUTER, json_string(service->routerModule)); + json_object_set_new(rval, CN_STATE, json_string(service_state_to_string(service->state))); if (service->router && service->router_instance) {