MySQL 26.10.0
Source Code Documentation
router_app.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2015, 2026, Oracle and/or its affiliates.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is designed to work with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have either included with
14 the program or referenced in the documentation.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24*/
25
26#ifndef ROUTER_MYSQL_ROUTER_INCLUDED
27#define ROUTER_MYSQL_ROUTER_INCLUDED
28
30
31/** @file
32 * @brief Defining the main class MySQLRouter
33 *
34 * This file defines the main class `MySQLRouter`.
35 *
36 */
37
38#include "keyring_handler.h"
44#include "router_conf.h"
45
46#include <cstdint>
47#include <iostream> // cerr, cout
48#include <optional>
49#include <stdexcept>
50#include <string>
51#include <vector>
52
53static const size_t kHelpScreenWidth = 72;
54static const size_t kHelpScreenIndent = 8;
55
56static const std::string kSystemRouterName = "system";
57static const std::string kDefaultSystemUserName = "";
58
59class ConfigFiles;
60
61/** @class MySQLRouter
62 * @brief Manage the MySQL Router application.
63 *
64 * The class MySQLRouter manages the MySQL Router application. It handles the
65 * command arguments, finds valid configuration files, and starts all plugins.
66 *
67 * Since MySQL Router requires at least 1 configuration file to be available
68 * for reading, if no default configuration file location could be read and no
69 * explicit location was given, the application exits.
70 *
71 * The class depends on MySQL Harness to, among other things, load the
72 * configuration and initialize all request plugins.
73 *
74 * Example usage:
75 *
76 * int main(int argc, char** argv) {
77 * MySQLRouter router(argc, argv);
78 * router.start();
79 * }
80 *
81 */
83 public:
84 /** @brief Default constructor
85 *
86 * Default constructor of MySQL Router which will not initialize.
87 *
88 * Usage:
89 *
90 * MySQLRouter router;
91 * router.start();
92 *
93 */
95 : can_start_(false),
96 showing_info_(false),
97 out_stream_(std::cout),
98 err_stream_(std::cerr)
99#ifndef _WIN32
100 ,
101 sys_user_operations_(mysqlrouter::SysUserOperations::instance())
102#endif
103 ,
104 bootstrapper_(keyring_.get_ki()) {
105 }
106
107 /** @brief Constructor with command line arguments as vector
108 *
109 * Constructor of MySQL Router which will start with the given command
110 * line arguments as a vector of strings.
111 *
112 * Example usage:
113 *
114 * MySQLRouter router(argv[0],
115 * vector<string>({argv + 1, argv + argc}));
116 * router.start();
117 *
118 * @param program_name path of the started executable
119 * @param arguments a vector of strings
120 * @param out_stream output stream representing "stdout"
121 * @param err_stream output stream representing "stderr"
122 */
123#ifndef _WIN32
124 /// @param sys_user_operations system operations which provide chown, ...
125#endif
126 MySQLRouter(const std::string &program_name,
127 const std::vector<std::string> &arguments,
128 std::ostream &out_stream = std::cout,
129 std::ostream &err_stream = std::cerr
130#ifndef _WIN32
131 ,
132 mysqlrouter::SysUserOperationsBase *sys_user_operations =
134#endif
135 );
136
137 /** @brief Constructor with command line arguments
138 *
139 * Constructor of MySQL Router which will start with the given command
140 * line arguments given as the arguments argc and argv. Typically, argc
141 * and argv are passed on from the global main function.
142 *
143 * Example usage:
144 *
145 * int main(int argc, char** argv) {
146 * MySQLRouter router(argc, argv);
147 * router.start();
148 * }
149 *
150 * @param argc number of arguments
151 * @param argv pointer to first command line argument
152 * @param out_stream output stream representing "stdout"
153 * @param err_stream output stream representing "stderr"
154 */
155#ifndef _WIN32
156 /// @param sys_user_operations system operations which provide chown, ...
157#endif
158 MySQLRouter(const int argc, char **argv, std::ostream &out_stream,
159 std::ostream &err_stream
160#ifndef _WIN32
161 ,
162 mysqlrouter::SysUserOperationsBase *sys_user_operations =
164#endif
165 );
166
167 virtual ~MySQLRouter() = default;
168
169 /** @brief Initialize main logger
170 *
171 * Initializes main logger, according to options in the configuration.
172 *
173 * @param config Configuration to be used to initialize logger
174 * @param raw_mode If true, all messages are logged raw; if false, messages
175 * are subject formatting
176 * @param use_os_log If true, Windows EventLog will be used instead of STDERR;
177 * Currently this option is only meaningful on Windows
178 *
179 * @throws std::runtime_error on:
180 * - failure to initialize file or OS logger
181 * - bad configuration
182 *
183 * @note This function is static and public, because unlike
184 * create_plugin_loggers(), it's also meant to be called very early during
185 * startup, close to main().
186 */
188 bool raw_mode = false, bool use_os_log = false);
189
190 // Information member function
192
193 /** @brief Returns the MySQL Router version as string
194 *
195 * Returns the MySQL Router as a string. The string is a concatenation
196 * of version's major, minor and patch parts, for example `1.0.2`.
197 *
198 * @return string containing the version
199 */
200 std::string get_version() noexcept;
201
202 /** @brief Returns string version details.
203 *
204 * Returns string with name and version details, including:
205 *
206 * * name of the application,
207 * * version,
208 * * platform and architecture,
209 * * edition,
210 * * and a special part-of-clause.
211 *
212 * The architecture is either 32-bit or 64-bit. Edition is usually used to
213 * denote whether release is either GPLv2 license or commercial.
214 *
215 * The part-of clause is used to show which product family MySQL Router
216 * belongs to.
217 *
218 * @internal
219 * Most information can be defined while configuring using CMake and will
220 * become available through the router_config.h file (generated from
221 * router_config.h.in).
222 * @endinternal
223 *
224 * @return a string containing version details
225 */
226 std::string get_version_line() noexcept;
227
228 /** @brief Starts the MySQL Router application
229 *
230 * Starts the MySQL Router application, reading the configuration file(s) and
231 * loading and starting all plugins.
232 *
233 * Example:
234 *
235 * MySQLRouter router;
236 * router.start();
237 *
238 * Throws std::runtime_error on configuration or plugin errors.
239 *
240 * @internal
241 * We are using MySQL Harness to load and start the plugins. We give Harness
242 * a configuration files and it will parse it. Not that at this moment,
243 * Harness only accept one configuration file.
244 * @endinternal
245 */
246 void start();
247
248 /** @brief Stop and cleanup the MySQL Router application
249 *
250 * Cleanup to perform when the MySQL Router application shuts down.
251 *
252 * Example:
253 *
254 * MySQLRouter router;
255 * router.start();
256 * ...
257 * router.stop();
258 *
259 * Throws std::runtime_error on errors during cleanup.
260 *
261 * @internal
262 * We ensure that the Harness pidfile is removed if present.
263 * @endinternal
264 */
265 void stop();
266
267 /** @brief Gets list of default configuration files
268 *
269 * Returns a list of configuration files which will be read (if available)
270 * by default.
271 *
272 * @return std::vector<string>
273 */
274 const std::vector<std::string> &get_default_config_files() const noexcept {
276 }
277
278 /** @brief Gets list of configuration files passed using command line
279 *
280 * Returns a list of configuration files which were passed through command
281 * line options.
282 *
283 * @return std::vector<string>
284 */
285 const std::vector<std::string> &get_config_files() const noexcept {
286 return config_files_;
287 }
288
289 /** @brief Gets list of extra configuration files passed using command line
290 *
291 * Returns a list of extra configuration files which were passed through
292 * command line options.
293 *
294 * @return std::vector<string>
295 */
296 const std::vector<std::string> &get_extra_config_files() const noexcept {
297 return extra_config_files_;
298 }
299
300#if !defined(_MSC_VER) && !defined(UNIT_TESTS)
301 // MSVC produces different symbols for private vs public methods, which mean
302 // the #define private public trick for unit-testing private methods doesn't
303 // work. Thus, we turn private methods public in Windows.
304 private:
305#endif
306
307 /** @brief Initializes the MySQL Router application
308 *
309 * Initialized the MySQL Router application by
310 *
311 * * setting the default configuration files,
312 * * loading the command line options,
313 * * processing the given command line arguments,
314 * * and finding all the usable configuration files.
315 *
316 * The command line options are passed using the `arguments`
317 * argument. It should be a vector of strings. For example, to start
318 * MySQL Router using the `main()` functions `argc` and `argv`
319 * arguments:
320 *
321 * MySQLRouter router(vector<string>({argv + 1, argv + argc}));
322 * router.start();
323 *
324 * @internal
325 * We do not need the first command line argument, argv[0] since we do not
326 * use it.
327 * @endinternal
328 *
329 * @param program_name path to the executable.
330 * @param arguments command line arguments as vector of strings
331 */
332 virtual void init(const std::string &program_name,
333 const std::vector<std::string> &arguments);
334
335 /** @brief Prepares a command line option
336 *
337 * Prepares command line options for the MySQL Router `mysqlrouter`
338 * application.
339 *
340 * @internal
341 * Currently, to add options to the command line, you need to add it to the
342 * `prepare_command_options`-method using `CmdArgHandler::add_option()`.
343 * @endinternal
344 */
346
347 /** @brief Process command line options
348 *
349 * Processes command line options for the MySQL Router `mysqlrouter`
350 * application.
351 */
353 const std::vector<std::string> &arguments); // throws std::runtime_error
354
355 /** Validates the mutually exclusive TLS reload command-line options. */
357
358 /** Delivers a validated TLS reload request to an already running Router. */
359 void request_tls_reload();
360
361 /** @brief Finds all valid configuration files
362 *
363 * Finds all valid configuration files from the list of default
364 * configuration file locations.
365 *
366 * An exception of type `std::runtime_error` is thrown when no valid
367 * configuration file was found.
368 *
369 * @return returns a list of valid configuration file locations
370 *
371 */
372 std::vector<std::string> check_config_files();
373
374 /** @brief Shows the help screen on the console
375 *
376 * Shows the help screen on the console including
377 *
378 * * copyright and trademark notice,
379 * * command line usage,
380 * * default configuration file locations,
381 * * and options with their descriptions.
382 *
383 * Users would use the command line option `--help`:
384 *
385 * shell> mysqlrouter --help
386 */
387 void show_help();
388
389 /**
390 * @brief verify that option given by user is not used with bootstrap option
391 * (--bootstrap or -B).
392 *
393 * @throw std::runtime_error if called in bootstrap mode.
394 */
395 void assert_not_bootstrap_mode(const std::string &option_name) const;
396
397 /** @brief Shows command line usage and option description
398 *
399 * Shows command line usage and all available options together with their
400 * description. It is possible to prevent the option listing by setting the
401 * argument `include_options` to `false`.
402 *
403 * @internal
404 * This method is used by the `MySQLRouter::show_help()`. We keep a separate
405 * method so we could potentionally show the usage in other places or using
406 * different option combinations, for example after an error.
407 * @endinternal
408 *
409 * @param include_options bool whether we show the options and descriptions
410 */
411 void show_usage(bool include_options) noexcept;
412
413 /* @overload */
414 void show_usage() noexcept;
415
416 /** @brief Sets default configuration file locations
417 *
418 * Sets the default configuration file locations based on information
419 * found in the locations argument. The locations should be provided
420 * as a semicolon separated list.
421 *
422 * The previous loaded locations are first removed. If not new locations
423 * were provider (if locations argument is empty), then no configuration
424 * files will be available.
425 *
426 * Locations can include environment variable placeholders. These
427 * placeholders are replaced using the provided name. For example, user Jane
428 * executing MySQL Router:
429 *
430 * /opt/ENV{USER}/etc becomes /opt/jane/etc
431 *
432 * If the environment variable is not available, for example if
433 * MYSQL_ROUTER_HOME was not set before starting MySQL Router, every location
434 * using this environment variable will be ignored.
435 *
436 * @param locations a char* with semicolon separated file locations
437 */
438 void set_default_config_files(const char *locations) noexcept;
439
440 /*
441 * @brief returns id of the router.
442 *
443 * @throw bad_section
444 */
445 uint32_t get_router_id(mysql_harness::Config &config);
446
447 void init_keyring(mysql_harness::Config &config);
448
449 void init_dynamic_state(mysql_harness::Config &config);
450 // throws std::runtime_error
451 void init_loader(mysql_harness::LoaderConfig &config);
452
453 // throws std::runtime_error
454 mysql_harness::LoaderConfig *make_config(
455 const std::map<std::string, std::string> params,
456 const std::vector<std::string> &config_files);
457
458 /** @brief Tuple describing the MySQL Router version, with major, minor and
459 * patch level **/
460 std::tuple<const uint8_t, const uint8_t, const uint8_t> version_;
461
462 /** @brief Vector with default configuration file locations as strings **/
464 /** @brief Vector with extra configuration file locations as strings **/
466 /** @brief Vector with configuration files passed through command line
467 * arguments **/
469
470 /** @brief PID file location **/
472 bool pid_file_created_{false};
473
474 /** Request TLS material reload in a running Router and exit. */
475 bool reload_tls_{false};
476 std::string reload_tls_pid_;
477 std::optional<long long> reload_tls_target_pid_;
479
480 /** @brief CmdArgHandler object handling command line arguments **/
482 /** @brief Harness loader **/
483 std::unique_ptr<mysql_harness::Loader> loader_;
484 /** @brief Whether the MySQLRouter can start or not **/
486 /** @brief Whether we are showing information on command line, for example,
487 * using --help or --version **/
489
490 /**
491 * Path to origin of executable.
492 *
493 * This variable contain the directory that the executable is
494 * running from.
495 */
497
499
500 std::ostream &out_stream_;
501 std::ostream &err_stream_;
502
503 bool core_file_{false};
504
505#ifndef _WIN32
506 /** @brief Value of the --user parameter given on the command line if router
507 * is launched in bootstrap mode **/
508 std::string user_cmd_line_;
509
510 /** @brief Value of the --user parameter given on the command line. It is used
511 *to buffer the value of --user parameter till all command line parameters are
512 *parsed. If router is launched in bootstrap mode, then username_ is copied to
513 *user_cmd_line_, otherwise it is copied to bootstrap_options_["user"]
514 **/
515 std::string username_;
516
517 /** @brief Pointer to the object to be used to perform system specific
518 * user-related operations **/
520#endif
521
523
525#ifdef FRIEND_TEST
526 FRIEND_TEST(Bug24909259, PasswordPrompt_plain);
527 FRIEND_TEST(Bug24909259, PasswordPrompt_keyed);
528#endif
529};
530
531/** @brief Expose the configured application-level options (the ones
532 * from [DEFAULT] section that are not specific to any particular plugin and are
533 * relevant from the Cluster metadata perspective) **/
534void expose_router_configuration(const bool initial,
535 const mysql_harness::ConfigSection &section);
536
537#endif // ROUTER_MYSQL_ROUTER_INCLUDED
Defining the commandline argument handler class CmdArgHandler.
Handles command line arguments.
Definition: arg_handler.h:141
Definition: keyring_handler.h:34
Definition: router_conf.h:54
Manage the MySQL Router application.
Definition: router_app.h:82
std::ostream & out_stream_
Definition: router_app.h:500
void assert_not_bootstrap_mode(const std::string &option_name) const
verify that option given by user is not used with bootstrap option (–bootstrap or -B).
Definition: router_app.cc:960
KeyringHandler keyring_
Definition: router_app.h:498
void stop()
Stop and cleanup the MySQL Router application.
Definition: router_app.cc:879
void init_dynamic_state(mysql_harness::Config &config)
Definition: router_app.cc:503
const std::vector< std::string > & get_extra_config_files() const noexcept
Gets list of extra configuration files passed using command line.
Definition: router_app.h:296
void validate_tls_reload_options()
Validates the mutually exclusive TLS reload command-line options.
Definition: router_app.cc:244
bool showing_info_
Whether we are showing information on command line, for example, using –help or –version.
Definition: router_app.h:488
bool reload_tls_
Request TLS material reload in a running Router and exit.
Definition: router_app.h:475
std::string reload_tls_service_name_
Definition: router_app.h:478
void prepare_command_options() noexcept
Prepares a command line option.
Definition: router_app.cc:967
MySQLRouterConf bootstrapper_
Definition: router_app.h:524
uint32_t get_router_id(mysql_harness::Config &config)
Definition: router_app.cc:446
std::vector< std::string > check_config_files()
Finds all valid configuration files.
Definition: router_app.cc:917
std::string get_package_name() noexcept
void show_help()
Shows the help screen on the console.
Definition: router_app.cc:1101
bool core_file_
Definition: router_app.h:503
void parse_command_options(const std::vector< std::string > &arguments)
Process command line options.
Definition: router_app.cc:234
std::string user_cmd_line_
Value of the –user parameter given on the command line if router is launched in bootstrap mode.
Definition: router_app.h:508
std::string username_
Value of the –user parameter given on the command line.
Definition: router_app.h:515
std::vector< std::string > extra_config_files_
Vector with extra configuration file locations as strings.
Definition: router_app.h:465
virtual void init(const std::string &program_name, const std::vector< std::string > &arguments)
Initializes the MySQL Router application.
Definition: router_app.cc:330
void init_keyring(mysql_harness::Config &config)
Definition: router_app.cc:473
mysql_harness::LoaderConfig * make_config(const std::map< std::string, std::string > params, const std::vector< std::string > &config_files)
Definition: router_app.cc:579
void request_tls_reload()
Delivers a validated TLS reload request to an already running Router.
Definition: router_app.cc:299
bool pid_file_created_
Definition: router_app.h:472
const std::vector< std::string > & get_default_config_files() const noexcept
Gets list of default configuration files.
Definition: router_app.h:274
std::optional< long long > reload_tls_target_pid_
Definition: router_app.h:477
std::unique_ptr< mysql_harness::Loader > loader_
Harness loader.
Definition: router_app.h:483
std::string pid_file_path_
PID file location.
Definition: router_app.h:471
CmdArgHandler arg_handler_
CmdArgHandler object handling command line arguments.
Definition: router_app.h:481
std::string get_version() noexcept
Returns the MySQL Router version as string.
Definition: router_app.cc:908
mysql_harness::Path origin_
Path to origin of executable.
Definition: router_app.h:496
mysql_harness::SignalHandler signal_handler_
Definition: router_app.h:522
std::vector< std::string > default_config_files_
Vector with default configuration file locations as strings.
Definition: router_app.h:463
const std::vector< std::string > & get_config_files() const noexcept
Gets list of configuration files passed using command line.
Definition: router_app.h:285
void start()
Starts the MySQL Router application.
Definition: router_app.cc:618
MySQLRouter()
Default constructor.
Definition: router_app.h:94
std::vector< std::string > config_files_
Vector with configuration files passed through command line arguments.
Definition: router_app.h:468
virtual ~MySQLRouter()=default
void show_usage() noexcept
Definition: router_app.cc:1294
std::string reload_tls_pid_
Definition: router_app.h:476
static void init_main_logger(mysql_harness::LoaderConfig &config, bool raw_mode=false, bool use_os_log=false)
Initialize main logger.
Definition: router_app.cc:514
std::ostream & err_stream_
Definition: router_app.h:501
void set_default_config_files(const char *locations) noexcept
Sets default configuration file locations.
Definition: router_app.cc:890
mysqlrouter::SysUserOperationsBase * sys_user_operations_
Pointer to the object to be used to perform system specific user-related operations.
Definition: router_app.h:519
void init_loader(mysql_harness::LoaderConfig &config)
Definition: router_app.cc:605
bool can_start_
Whether the MySQLRouter can start or not.
Definition: router_app.h:485
std::tuple< const uint8_t, const uint8_t, const uint8_t > version_
Tuple describing the MySQL Router version, with major, minor and patch level.
Definition: router_app.h:460
std::string get_version_line() noexcept
Returns string version details.
Definition: router_app.cc:910
Configuration section.
Definition: config_parser.h:141
Configuration file handler for the loader.
Definition: loader_config.h:46
Class representing a path in a file system.
Definition: filesystem.h:63
Definition: signal_handler.h:41
Base class to allow multiple SysUserOperations implementations.
Definition: sys_user_operations.h:45
static SysUserOperations * instance()
Definition: sys_user_operations.cc:49
noexcept
The return type for any call_and_catch(f, args...) call where f(args...) returns Type.
Definition: call_and_catch.h:76
Singleton class that stores the application type.
Definition: component_application_type_name.h:31
Definition: mrs_component_embedded_mysql_session.h:29
Define std::hash<Gtid>.
Definition: gtid.h:355
std::vector< T, ut::allocator< T > > vector
Specialization of vector which uses allocator.
Definition: ut0new.h:2724
std::map< Key, Value, Compare, ut::allocator< std::pair< const Key, Value > > > map
Specialization of map which uses ut_allocator.
Definition: ut0new.h:2742
static const size_t kHelpScreenWidth
Definition: router_app.h:53
static const std::string kDefaultSystemUserName
Definition: router_app.h:57
static const std::string kSystemRouterName
Definition: router_app.h:56
static const size_t kHelpScreenIndent
Definition: router_app.h:54
void expose_router_configuration(const bool initial, const mysql_harness::ConfigSection &section)
Expose the configured application-level options (the ones from [DEFAULT] section that are not specifi...
Definition: router_app.cc:1353
Defining the main class MySQLRouter.