From af2a4e792f7c5cc11db9fcc091358c6bbf520b9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Fri, 28 Apr 2017 09:51:52 +0300 Subject: [PATCH] MXS-1220: Process monitor parameters on resource creation When a monitor is created, any parameters given to it are immediately processed. This is done by processing the initial request as if it were an update to the monitor that was just created. Changed the order in which servers are linked to objects. The old relations are removed first and only after that are the new relations added. This fixed a problem when the monitor which monitors a server was being changed. Also fixed a few minor bugs. --- server/core/config_runtime.cc | 61 ++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/server/core/config_runtime.cc b/server/core/config_runtime.cc index 7b8d7d204..e72adc204 100644 --- a/server/core/config_runtime.cc +++ b/server/core/config_runtime.cc @@ -890,17 +890,18 @@ SERVER* runtime_create_server_from_json(json_t* json) if (server_contains_required_fields(json)) { const char* name = json_string_value(json_object_get(json, CN_NAME)); - const char* address = json_string_value(json_object_get(json, CN_ADDRESS)); + json_t* params = json_object_get(json, CN_PARAMETERS); + const char* address = json_string_value(json_object_get(params, CN_ADDRESS)); /** The port needs to be in string format */ char port[200]; // Enough to store any port value - int i = json_integer_value(json_object_get(json, CN_PORT)); + int i = json_integer_value(json_object_get(params, CN_PORT)); snprintf(port, sizeof(port), "%d", i); /** Optional parameters */ - const char* protocol = string_or_null(json, CN_PROTOCOL); - const char* authenticator = string_or_null(json, CN_AUTHENTICATOR); - const char* authenticator_options = string_or_null(json, CN_AUTHENTICATOR_OPTIONS); + const char* protocol = string_or_null(params, CN_PROTOCOL); + const char* authenticator = string_or_null(params, CN_AUTHENTICATOR); + const char* authenticator_options = string_or_null(params, CN_AUTHENTICATOR_OPTIONS); set relations; @@ -942,8 +943,8 @@ bool server_to_object_relations(SERVER* server, json_t* old_json, json_t* new_js old_relations.begin(), old_relations.end(), std::inserter(added_relations, added_relations.begin())); - if (link_server_to_objects(server, added_relations) && - unlink_server_from_objects(server, removed_relations)) + if (unlink_server_from_objects(server, removed_relations) && + link_server_to_objects(server, added_relations)) { rval = true; } @@ -991,14 +992,6 @@ bool runtime_alter_server_from_json(SERVER* server, json_t* new_json) return rval; } -static bool monitor_contains_required_fields(json_t* json) -{ - json_t* value; - - return (value = json_object_get(json, CN_NAME)) && json_is_string(value) && - (value = json_object_get(json, CN_MODULE)) && json_is_string(value); -} - const char* object_relation_types[] = { CN_SERVERS, @@ -1010,6 +1003,31 @@ static bool object_relation_is_valid(const string& type, const string& value) return type == CN_SERVERS && server_find_by_unique_name(value.c_str()); } +/** + * @brief Do a coarse validation of the monitor JSON + * + * @param json JSON to validate + * + * @return True of the JSON is valid + */ +static bool validate_monitor_json(json_t* json) +{ + bool rval = false; + json_t* value; + + if ((value = json_object_get(json, CN_NAME)) && json_is_string(value) && + (value = json_object_get(json, CN_MODULE)) && json_is_string(value)) + { + set relations; + if (extract_relations(json, relations, object_relation_types, object_relation_is_valid)) + { + rval = true; + } + } + + return rval; +} + static bool unlink_object_from_servers(const char* target, set& relations) { bool rval = true; @@ -1051,20 +1069,17 @@ MXS_MONITOR* runtime_create_monitor_from_json(json_t* json) { MXS_MONITOR* rval = NULL; - if (monitor_contains_required_fields(json)) + if (validate_monitor_json(json)) { const char* name = json_string_value(json_object_get(json, CN_NAME)); const char* module = json_string_value(json_object_get(json, CN_MODULE)); - set relations; - - if (extract_relations(json, relations, object_relation_types, object_relation_is_valid) && - runtime_create_monitor(name, module)) + if (runtime_create_monitor(name, module)) { rval = monitor_find(name); ss_dassert(rval); - if (!link_object_to_servers(rval->name, relations)) + if (!runtime_alter_monitor_from_json(rval, json)) { runtime_destroy_monitor(rval); rval = NULL; @@ -1095,8 +1110,8 @@ bool object_to_server_relations(const char* target, json_t* old_json, json_t* ne old_relations.begin(), old_relations.end(), std::inserter(added_relations, added_relations.begin())); - if (link_object_to_servers(target, added_relations) && - unlink_object_from_servers(target, removed_relations)) + if (unlink_object_from_servers(target, removed_relations) && + link_object_to_servers(target, added_relations)) { rval = true; }