diff options
Diffstat (limited to 'src/lib/database/backend_selector.h')
-rw-r--r-- | src/lib/database/backend_selector.h | 215 |
1 files changed, 215 insertions, 0 deletions
diff --git a/src/lib/database/backend_selector.h b/src/lib/database/backend_selector.h new file mode 100644 index 0000000..db207df --- /dev/null +++ b/src/lib/database/backend_selector.h @@ -0,0 +1,215 @@ +// Copyright (C) 2018-2022 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef BACKEND_SELECTOR_H +#define BACKEND_SELECTOR_H + +#include <cc/data.h> +#include <cc/cfg_to_element.h> +#include <cstdint> +#include <string> + +namespace isc { +namespace db { + +/// @brief Config Backend selector. +/// +/// Each Kea server using database as a configuration respository +/// may use multiple configuration backends simultaneously. The most +/// typical case is to use a single configuration backend per server, +/// but there are use cases when configuration information is distributed +/// accross multiple database instances. In the future, there may be +/// also caching mechanisms implemented, which will allow for storing +/// results of certain database queries in memory. +/// +/// From the server perspective, the most common use of the configuration +/// backend is to fetch entire configuration information from the +/// databases (upon startup) or fetch the latest updates to the +/// configuration, e.g. new subnet added, DHCP option modified etc. +/// In those cases, it is not so important from the server which backend +/// this data come from. Therefore, the server would fetch this information +/// from all available backends. +/// +/// When the server administrator wants to insert some new data into +/// the database, modify existing data or simply wants to check the +/// contents of one of the database instance, he would specify which +/// database backend he wants to direct queries to. +/// +/// The @c BackendSelector class provides means to specify whether +/// the queries should be directed to any backend (see server case +/// above) or to a specific backend (data insertion case above). +/// In addition, the @c BackendSelector allows for using various +/// criteria for selecting a backend to use. Currently those criteria +/// are: database type (e.g. mysql), database host and database port. +/// In order to use a specific port, the database host must also be +/// specified. Note that in a general case multiple backends of the +/// same type can be used simultaneously, e.g. multiple MySQL backends. +/// In that case, it may be necessary to specify host (and port) to +/// issue a query to the right one. +/// +/// The @c BackendSelector class may be extended in the future to provide +/// additional backend selection criteria. +class BackendSelector : public data::CfgToElement { +public: + + /// @brief Supported database types. + /// + /// The @c UNSPEC indicates that the database type is not specified + /// as selection criteria. + enum class Type { + MYSQL, + POSTGRESQL, + UNSPEC + }; + + /// @brief Default constructor. + /// + /// It sets the selector to "unspecified". When this selector is used + /// the backend pool will use "any" backend. This has a different meaning + /// for each type of query. See the @c BaseConfigBackendPool for details. + explicit BackendSelector(); + + /// @brief Constructor specifying backend type as a selection criteria. + /// + /// @param backend_type Type of the backend to be selected. + explicit BackendSelector(const Type& backend_type); + + /// @brief Constructor for specifying host and optionally port as a + /// selection criteria. + /// + /// @param host Hostname to be used for selecting a backend. + /// @param port Port number to be used for selecting a backend. This value + /// is optional and is ignored when set to 0. It must be used in conjunction + /// with hostname. + explicit BackendSelector(const std::string& host, const uint16_t port = 0); + + /// @brief Constructor for selecting a backend using JSON access map. + /// + /// The provided access map must have the same structure as an element + /// of the "config-databases" configuration parameter. However, it merely + /// takes into account: "type", "host" and "port" parameters. In addition, + /// these parameters are optional. The following are valid combinations: + /// + /// @code + /// { + /// "type": "mysql" + /// } + /// @endcode + /// + /// @code + /// { + /// "host": "somehost.example.org" + /// } + /// @endcode + /// + /// @code + /// { + /// "host": "somehost.example.org", + /// "port": 1234 + /// } + /// @endcode + /// + /// @code + /// { + /// "type": "mysql" + /// "host": "somehost.example.org", + /// } + /// @endcode + /// + /// @code + /// { + /// "type": "mysql" + /// "host": "somehost.example.org", + /// "port": 1234 + /// } + /// @endcode + /// + /// where "type" can be any of the supported backend types. + /// + /// This constructor is useful for creating backend selectors from the + /// received control commands. + /// + /// @param access_map Access map as provided above. + explicit BackendSelector(const data::ConstElementPtr& access_map); + + /// @brief Returns instance of the "unspecified" backend selector. + static const BackendSelector& UNSPEC(); + + /// @brief Checks if selector is "unspecified". + /// + /// @return true if backend type is @c UNSPEC, hostname is empty and + /// port number 0, false otherwise. + bool amUnspecified() const; + + /// @brief Returns backend type selected. + Type getBackendType() const { + return (backend_type_); + } + + /// @brief Returns host selected. + /// + /// @return host if specified or empty string if host is not + /// specified. + std::string getBackendHost() const { + return (host_); + } + + /// @brief Returns port selected. + /// + /// @return port number of the selected backend or 0 if port number + /// is not specified. + uint16_t getBackendPort() const { + return (port_); + } + + /// @brief Returns selections as text. + /// + /// @return Collection of comma separated selections, e.g. + /// "type=mysql,host=somehost.example.org,port=1234". + std::string toText() const; + + /// @brief Unparse a backend selector object. + /// + /// The caller must ensure that the selector type is specified. + /// + /// @return A pointer to unparsed backend selector configuration. + /// @throw BadValue If the backend selector type is unspecified. + virtual data::ElementPtr toElement() const; + + /// @brief Converts string to backend type. + /// + /// @param type Backend type as string. + static Type stringToBackendType(const std::string& type); + + /// @brief Converts backend type to string. + /// + /// @param type Backend type to be converted. + static std::string backendTypeToString(const Type& type); + +private: + + /// @brief Checks if the specified selector is valid. + /// + /// It checks if the port number is specified in conjunction with + /// host. + /// @throw BadValue if selector validation fails. + void validate() const; + + /// @brief Backend type selected. + Type backend_type_; + + /// @brief Host selected. + std::string host_; + + /// @brief Port number selected. + uint16_t port_; +}; + + +} // end of namespace isc::db +} // end of namespace isc + +#endif |