From f271c5cea184ba92b48b072e8db63eddbf9db0bb Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Wed, 6 Feb 2019 13:43:29 +0200 Subject: [PATCH] MXS-2314 Add 'cluster' parameter to service Using the cluster parameter, the servers of a service can be defined using a monitor. This change basically only introduces the parameter. --- Documentation/Changelog.md | 1 + .../Getting-Started/Configuration-Guide.md | 14 +++++ .../MaxScale-2.4.0-Release-Notes.md | 13 ++++ server/core/config.cc | 62 +++++++++++++++---- server/core/internal/service.hh | 13 ++++ server/core/service.cc | 13 ++++ 6 files changed, 103 insertions(+), 13 deletions(-) diff --git a/Documentation/Changelog.md b/Documentation/Changelog.md index 866351049..e77c81730 100644 --- a/Documentation/Changelog.md +++ b/Documentation/Changelog.md @@ -5,6 +5,7 @@ * Names starting with `@@` are reserved for use by MaxScale. * Names can no longer contain whitespace. * Servers can now be drained. +* The servers of a service can now be defined using a monitor. For more details, please refer to: diff --git a/Documentation/Getting-Started/Configuration-Guide.md b/Documentation/Getting-Started/Configuration-Guide.md index c22c2c6fb..d15cd64f4 100644 --- a/Documentation/Getting-Started/Configuration-Guide.md +++ b/Documentation/Getting-Started/Configuration-Guide.md @@ -1030,6 +1030,20 @@ in the name section of a block with a type parameter of server (see below). servers=server1,server2,server3 ``` +*NOTE* The `servers` parameter is mutually exclusive with the `cluster` parameter. + +#### `cluster` + +The servers the service uses are defined by the monitor specified as value +of this configuration parameter. + +``` +cluster=TheMonitor + +``` + +*NOTE* The `clusters` parameter is mutually exclusive with the `servers` parameter. + #### `user` The user parameter, along with the password parameter are used to define the diff --git a/Documentation/Release-Notes/MaxScale-2.4.0-Release-Notes.md b/Documentation/Release-Notes/MaxScale-2.4.0-Release-Notes.md index df4e20afb..fcfb3a439 100644 --- a/Documentation/Release-Notes/MaxScale-2.4.0-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-2.4.0-Release-Notes.md @@ -63,6 +63,19 @@ being drained is the master, then it will not be possible to connect unless `master_failure_mode` has been set to something else but the default `fail_instantly`. +### Cluster + +The servers a service uses can now be specified using the `cluster` +parameter of the service. +``` +[TheService] +... +cluster=TheMonitor +``` +In this case, the servers of the service will be defined by the +referred to monitor. Note that the parameters `servers` and `cluster` +are mutually exclusive. + ## Bug fixes [Here is a list of bugs fixed in MaxScale 2.4.0.](https://jira.mariadb.org/issues/?jql=project%20%3D%20MXS%20AND%20issuetype%20%3D%20Bug%20AND%20status%20%3D%20Closed%20AND%20fixVersion%20%3D%202.4.0) diff --git a/server/core/config.cc b/server/core/config.cc index 2c473abc2..4c5033bac 100644 --- a/server/core/config.cc +++ b/server/core/config.cc @@ -93,6 +93,7 @@ const char CN_AUTH_WRITE_TIMEOUT[] = "auth_write_timeout"; const char CN_AUTO[] = "auto"; const char CN_CACHE_SIZE[] = "cache_size"; const char CN_CLASSIFY[] = "classify"; +const char CN_CLUSTER[] = "cluster"; const char CN_CONNECTION_TIMEOUT[] = "connection_timeout"; const char CN_DATA[] = "data"; const char CN_DEFAULT[] = "default"; @@ -314,6 +315,7 @@ const MXS_MODULE_PARAM config_service_params[] = {CN_RETRY_ON_FAILURE, MXS_MODULE_PARAM_BOOL, "true"}, {CN_SESSION_TRACK_TRX_STATE, MXS_MODULE_PARAM_BOOL, "false"}, {CN_RETAIN_LAST_STATEMENTS, MXS_MODULE_PARAM_COUNT, "0"}, + {CN_CLUSTER, MXS_MODULE_PARAM_STRING}, {NULL} }; @@ -1402,6 +1404,11 @@ std::unordered_set get_dependencies(const std::vectorparameters, CN_CLUSTER)) + { + rval.insert(name_to_object(objects, obj, config_get_string(obj->parameters, CN_CLUSTER))); + } + if ((type == CN_MONITOR || type == CN_SERVICE) && config_get_value(obj->parameters, CN_SERVERS)) { for (std::string name : mxs::strtok(obj->parameters->get_string(CN_SERVERS), ",")) @@ -3679,6 +3686,16 @@ int create_new_service(CONFIG_CONTEXT* obj) auto router = obj->parameters->get_string(CN_ROUTER); mxb_assert(!router.empty()); + const string servers = obj->parameters->get_string(CN_SERVERS); + const string cluster = obj->parameters->get_string(CN_CLUSTER); + + if (!servers.empty() && !cluster.empty()) + { + MXS_ERROR("Service '%s' is configured with both 'servers' and 'cluster'. " + "Only one or the other is allowed.", obj->object); + return 1; + } + char* user = config_get_value(obj->parameters, CN_USER); char* auth = config_get_value(obj->parameters, CN_PASSWORD); const MXS_MODULE* module = get_module(router.c_str(), MODULE_ROUTER); @@ -3704,21 +3721,24 @@ int create_new_service(CONFIG_CONTEXT* obj) { int error_count = 0; - for (auto& a : mxs::strtok(obj->parameters->get_string(CN_SERVERS), ",")) + if (!servers.empty()) { - fix_object_name(a); + for (auto& a : mxs::strtok(servers, ",")) + { + fix_object_name(a); - if (auto s = Server::find_by_unique_name(a)) - { - serviceAddBackend(service, s); - } - else - { - MXS_ERROR("Unable to find server '%s' that is configured as part " - "of service '%s'.", - a.c_str(), - obj->object); - error_count++; + if (auto s = Server::find_by_unique_name(a)) + { + serviceAddBackend(service, s); + } + else + { + MXS_ERROR("Unable to find server '%s' that is configured as part " + "of service '%s'.", + a.c_str(), + obj->object); + error_count++; + } } } @@ -3731,6 +3751,22 @@ int create_new_service(CONFIG_CONTEXT* obj) error_count++; } } + + if (!cluster.empty()) + { + Monitor* pMonitor = monitor_find(cluster.c_str()); + + if (pMonitor) + { + service->m_monitor = pMonitor; + } + else + { + MXS_ERROR("Unable to find monitor '%s' that defines the cluster used by " + "service '%s'.", cluster.c_str(), obj->object); + error_count++; + } + } } else { diff --git a/server/core/internal/service.hh b/server/core/internal/service.hh index 90c0c9a40..303c51456 100644 --- a/server/core/internal/service.hh +++ b/server/core/internal/service.hh @@ -21,6 +21,8 @@ #include "filter.hh" +class Monitor; + /** * @file service.h - MaxScale internal service functions */ @@ -103,6 +105,9 @@ public: // TODO: Make these private mutable std::mutex lock; + // TODO: Make this private. + Monitor* m_monitor { nullptr }; /**< A possibly associated monitor */ + private: FilterList m_filters; /**< Ordered list of filters */ std::string m_name; /**< Name of the service */ @@ -399,5 +404,13 @@ json_t* service_relations_to_server(const SERVER* server, const char* host); */ json_t* service_relations_to_filter(const SFilterDef& filter, const char* host); +/** + * @brief Add server to all services associated with a monitor + * + * @param monitor A monitor. + * @param server A server. + */ +void service_add_server(Monitor* pMonitor, SERVER* pServer); + std::unique_ptr serviceGetList(void); std::unique_ptr serviceGetListenerList(void); diff --git a/server/core/service.cc b/server/core/service.cc index 1c04aed65..1ab504507 100644 --- a/server/core/service.cc +++ b/server/core/service.cc @@ -148,6 +148,19 @@ static std::string get_version_string(MXS_CONFIG_PARAMETER* params) return version_string; } +void service_add_server(Monitor* pMonitor, SERVER* pServer) +{ + LockGuard guard(this_unit.lock); + + for (Service* pService : this_unit.services) + { + if (pService->m_monitor == pMonitor) + { + serviceAddBackend(pService, pServer); + } + } +} + Service::Service(const std::string& service_name, const std::string& router_name, MXS_CONFIG_PARAMETER* params)