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