From b768d3ca761c592d835ed5ffd03757762f4c2ceb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Thu, 10 Aug 2017 13:34:49 +0300 Subject: [PATCH] MXS-1356: Allow tee filter to be disabled at runtime Disabling the tee filter at runtime is desirable for cases where the branched service is not always needed. Migrations and pre-production setups are one where changes to the branched service are expected and splitting the queries would result in an error. --- Documentation/Filters/Tee-Filter.md | 17 ++++++++++ .../MaxScale-2.2.0-Release-Notes.md | 7 ++++ server/modules/filter/tee/tee.cc | 33 ++++++++++++++++++- server/modules/filter/tee/tee.hh | 11 +++++++ server/modules/filter/tee/teesession.cc | 3 +- 5 files changed, 69 insertions(+), 2 deletions(-) diff --git a/Documentation/Filters/Tee-Filter.md b/Documentation/Filters/Tee-Filter.md index 99fb0eec8..b7a03c0aa 100644 --- a/Documentation/Filters/Tee-Filter.md +++ b/Documentation/Filters/Tee-Filter.md @@ -99,6 +99,23 @@ sessions that are connected using this username are replicated. user=john ``` +## Module commands + +Read [Module Commands](../Reference/Module-Commands.md) documentation for +details about module commands. + +The tee filter supports the following module commands. + +### `tee disable [FILTER]` + +This commmad disables a tee filter instance. A disabled tee filter will not send +any queries to the target service. + +### `tee enable [FILTER]` + +Enable a disabled tee filter. This resumes the sending of queries to the target +service. + ## Examples ### Example 1 - Replicate all inserts into the orders table diff --git a/Documentation/Release-Notes/MaxScale-2.2.0-Release-Notes.md b/Documentation/Release-Notes/MaxScale-2.2.0-Release-Notes.md index c6d050e70..4bb0c3f23 100644 --- a/Documentation/Release-Notes/MaxScale-2.2.0-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-2.2.0-Release-Notes.md @@ -59,6 +59,13 @@ The `match` and `exclude` parameters were changed to use PCRE2 syntax for the regular expressions. The regular expression should be enclosed by slashes e.g. `match=/select.*from.*test/`. +A tee filter instance can be disabled with the new `tee disable [FILTER]` and +`tee enable [FILTER]` module commands. Refer to the +[module command documentation](../Reference/Module-Commands.md) for more +details on module commands and the +[Tee Filter documentation](../Filters/Tee-Filter.md) for details on the tee +filter specific commands. + ### Dbfwfilter The `function` type rule will now match a query that does not use a function diff --git a/server/modules/filter/tee/tee.cc b/server/modules/filter/tee/tee.cc index 5aa508c25..fd39bcd73 100644 --- a/server/modules/filter/tee/tee.cc +++ b/server/modules/filter/tee/tee.cc @@ -22,6 +22,7 @@ #include #include #include +#include #include "tee.hh" #include "local_client.hh" @@ -44,7 +45,8 @@ Tee::Tee(SERVICE* service, std::string user, std::string remote, m_match_code(match), m_exclude_code(exclude), m_match(match_string), - m_exclude(exclude_string) + m_exclude(exclude_string), + m_enabled(true) { } @@ -121,6 +123,7 @@ void Tee::diagnostics(DCB *dcb) dcb_printf(dcb, "\t\tExclude queries that match %s\n", m_exclude.c_str()); } + dcb_printf(dcb, "\t\tFilter enabled: %s\n", m_enabled ? "yes" : "no"); } /** @@ -159,9 +162,25 @@ json_t* Tee::diagnostics_json() const json_object_set_new(rval, "exclude", json_string(m_exclude.c_str())); } + json_object_set_new(rval, "enabled", json_boolean(m_enabled)); + return rval; } +static bool enable_tee(const MODULECMD_ARG *argv, json_t** output) +{ + Tee* instance = reinterpret_cast(filter_def_get_instance(argv->argv[0].value.filter)); + instance->set_enabled(true); + return true; +} + +static bool disable_tee(const MODULECMD_ARG *argv, json_t** output) +{ + Tee* instance = reinterpret_cast(filter_def_get_instance(argv->argv[0].value.filter)); + instance->set_enabled(false); + return true; +} + MXS_BEGIN_DECLS /** @@ -174,6 +193,18 @@ MXS_BEGIN_DECLS */ MXS_MODULE* MXS_CREATE_MODULE() { + modulecmd_arg_type_t argv[] = + { + { + MODULECMD_ARG_FILTER | MODULECMD_ARG_NAME_MATCHES_DOMAIN, + "Filter to modify" + } + }; + + modulecmd_register_command(MXS_MODULE_NAME, "enable", MODULECMD_TYPE_ACTIVE, + enable_tee, 1, argv, "Enable a tee filter instance"); + modulecmd_register_command(MXS_MODULE_NAME, "disable", MODULECMD_TYPE_ACTIVE, + disable_tee, 1, argv, "Disable a tee filter instance"); static MXS_MODULE info = { diff --git a/server/modules/filter/tee/tee.hh b/server/modules/filter/tee/tee.hh index a17e65309..bd694153f 100644 --- a/server/modules/filter/tee/tee.hh +++ b/server/modules/filter/tee/tee.hh @@ -67,6 +67,16 @@ public: return m_exclude_code; } + void set_enabled(bool value) + { + m_enabled = value; + } + + bool is_enabled() const + { + return m_enabled; + } + private: Tee(SERVICE* service, std::string user, std::string remote, pcre2_code* match, std::string match_string, @@ -79,4 +89,5 @@ private: pcre2_code* m_exclude_code; /* Compiled exclude pattern*/ std::string m_match; /* Pattern for matching queries */ std::string m_exclude; /* Pattern for excluding queries */ + bool m_enabled; }; diff --git a/server/modules/filter/tee/teesession.cc b/server/modules/filter/tee/teesession.cc index 0274ddfc5..1696f5af4 100644 --- a/server/modules/filter/tee/teesession.cc +++ b/server/modules/filter/tee/teesession.cc @@ -88,7 +88,8 @@ TeeSession* TeeSession::create(Tee* my_instance, MXS_SESSION* session) pcre2_match_data* md_match = NULL; pcre2_match_data* md_exclude = NULL; - if (my_instance->user_matches(session_get_user(session)) && + if (my_instance->is_enabled() && + my_instance->user_matches(session_get_user(session)) && my_instance->remote_matches(session_get_remote(session))) { match = my_instance->get_match();