From 03553783fb7abeda8242bb34c2e13c0e21d2e164 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Mon, 6 Aug 2018 02:38:20 +0300 Subject: [PATCH] MXS-1929: Process filter relationships for services The filter relationships of a service are now interpreted as an ordered list of filters being used by the service. As the relationship data in the JSON API specification is represented as an array, it does not prevent multiple relationships from appearing. For MaxScale, this means that interpreting the filter's order does not break it. --- server/core/config_runtime.cc | 58 ++++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 5 deletions(-) diff --git a/server/core/config_runtime.cc b/server/core/config_runtime.cc index 165ce215f..f93daf89d 100644 --- a/server/core/config_runtime.cc +++ b/server/core/config_runtime.cc @@ -40,6 +40,7 @@ #include "internal/filter.hh" typedef std::set StringSet; +typedef std::vector StringVector; static mxs::SpinLock crt_lock; @@ -1138,9 +1139,9 @@ static MXS_CONFIG_PARAMETER* extract_parameters_from_json(json_t* json) return ctx.parameters; } -static bool extract_relations(json_t* json, StringSet& relations, - const char* relation_type, - JsonValidator relation_check) +static bool extract_ordered_relations(json_t* json, StringVector& relations, + const char* relation_type, + JsonValidator relation_check) { bool rval = true; json_t* arr = mxs_json_pointer(json, relation_type); @@ -1163,7 +1164,7 @@ static bool extract_relations(json_t* json, StringSet& relations, if (relation_check(type_value, id_value)) { - relations.insert(id_value); + relations.push_back(id_value); } else { @@ -1180,6 +1181,16 @@ static bool extract_relations(json_t* json, StringSet& relations, return rval; } +static bool extract_relations(json_t* json, StringSet& relations, + const char* relation_type, + JsonValidator relation_check) +{ + StringVector values; + bool rval = extract_ordered_relations(json, values, relation_type, relation_check); + relations.insert(values.begin(), values.end()); + return rval; +} + static inline bool is_null_relation(json_t* json, const char* relation) { std::string str(relation); @@ -1685,6 +1696,11 @@ static bool object_relation_is_valid(const std::string& type, const std::string& return type == CN_SERVERS && server_find_by_unique_name(value.c_str()); } +static bool filter_relation_is_valid(const std::string& type, const std::string& value) +{ + return type == CN_FILTERS && filter_find(value.c_str()); +} + // // Constants for validate_object_json // @@ -1909,6 +1925,37 @@ bool object_to_server_relations(const char* target, json_t* old_json, json_t* ne return rval; } +bool service_to_filter_relations(Service* service, json_t* old_json, json_t* new_json) +{ + if (mxs_json_pointer(new_json, MXS_JSON_PTR_RELATIONSHIPS) == NULL) + { + // No relationships defined, nothing to change + return true; + } + + bool rval = false; + StringVector old_relations; + StringVector new_relations; + const char* filter_relation = MXS_JSON_PTR_RELATIONSHIPS_FILTERS; + + if (extract_ordered_relations(old_json, old_relations, filter_relation, filter_relation_is_valid) && + extract_ordered_relations(new_json, new_relations, filter_relation, filter_relation_is_valid)) + { + if (old_relations == new_relations || service->set_filters(new_relations)) + { + // Either no change in relationships took place or we successfully + // updated the filter relationships + rval = true; + } + } + else + { + runtime_error("Invalid object relations for '%s'", service->name); + } + + return rval; +} + bool runtime_alter_monitor_from_json(MXS_MONITOR* monitor, json_t* new_json) { bool rval = false; @@ -2023,7 +2070,8 @@ bool runtime_alter_service_from_json(Service* service, json_t* new_json) ss_dassert(old_json.get()); if (is_valid_resource_body(new_json) && - object_to_server_relations(service->name, old_json.get(), new_json)) + object_to_server_relations(service->name, old_json.get(), new_json) && + service_to_filter_relations(service, old_json.get(), new_json)) { rval = true; json_t* parameters = mxs_json_pointer(new_json, MXS_JSON_PTR_PARAMETERS);