1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
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 file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <string><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.

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;<--- Function in derived class

    /// @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