77#ifndef BASE_CONFIG_BACKEND_MGR_H
88#define BASE_CONFIG_BACKEND_MGR_H
99
10- #include < database/database_connection.h>
1110#include < config_backend/base_config_backend.h>
11+ #include < database/database_connection.h>
1212#include < exceptions/exceptions.h>
1313#include < boost/shared_ptr.hpp>
1414#include < functional>
1818namespace isc {
1919namespace cb {
2020
21+ // / @brief Base class for Configuration Backend Managers (CBM).
22+ // /
23+ // / Each Kea server supporting Configuration Backend feature implements
24+ // / a "manager" class which holds information about supported and
25+ // / configured backends and provides access to the backends. This is
26+ // / similar to @c HostMgr and @c LeaseMgr singletons being used by the
27+ // / DHCP servers.
28+ // /
29+ // / The Config Backend Managers are typically implemented as singletons
30+ // / which can be accessed from any place within the server code. This
31+ // / includes server configuration, data fetching during normal server
32+ // / operation and data management, including processing of control
33+ // / commands implemented within hooks libraries.
34+ // /
35+ // / The @c BaseConfigBackendMgr is a base class for all CBMs implemented
36+ // / for respective Kea servers. It includes mechanisms to register config
37+ // / backend factory functions and to create instances of the backends using
38+ // / those factory functions as a result of server configuration. The mechanism
39+ // / of factory functions registration is useful in cases when the config
40+ // / backend is implemented within the hook library. Such hook library
41+ // / registers factory function in its @c load function and the server
42+ // / simply calls this function to create the instance of this backend when
43+ // / instructed to do so via configuration. Similar mechanism exists in
44+ // / DHCP @c HostMgr.
45+ // /
46+ // / Unlike @c HostMgr, the CBMs do not directly expose API to fetch and
47+ // / manipulate the data in the database. This is done via, so called,
48+ // / Configuration Backends Pools. See @c BaseConfigBackendPool for
49+ // / details. The @c BaseConfigBackendMgr is provided with the pool type
50+ // / via class template parameter. Respective CBM implementations
51+ // / use their own pools, which provide APIs appropriate for those
52+ // / implementation.
53+ // /
54+ // / @tparam ConfgBackendPoolType Type of the configuration backend pool
55+ // / to be used by the manager. It must derive from @c BaseConfigBackendPool
56+ // / template class.
2157template <typename ConfigBackendPoolType>
2258class BaseConfigBackendMgr {
2359public:
2460
61+ // / @brief Pointer to the configuration backend pool.
2562 typedef boost::shared_ptr<ConfigBackendPoolType> ConfigBackendPoolPtr;
2663
64+ // / @brief Type of the backend factory function.
65+ // /
66+ // / Factory function returns a pointer to the instance of the configuration
67+ // / backend created.
2768 typedef std::function<typename ConfigBackendPoolType::ConfigBackendTypePtr
2869 (const db::DatabaseConnection::ParameterMap&)> Factory;
2970
71+ // / @brief Constructor.
3072 BaseConfigBackendMgr ()
31- : factories_(), backends_ (new ConfigBackendPoolType()) {
73+ : factories_(), pool_ (new ConfigBackendPoolType()) {
3274 }
3375
76+ // / @brief Registers new backend factory function for a given backend type.
77+ // /
78+ // / The typical usage of this function is to make the CBM aware of a
79+ // / configuration backend implementation. This implementation may exist
80+ // / in a hooks library. In such case, this function should be called from
81+ // / the @c load function in this library. When the backend is registered,
82+ // / the server will use it when required by the configuration, i.e. a
83+ // / user includes configuration backend of that type in the
84+ // / "config-databases" list.
85+ // /
86+ // / If the backend of the given type has already been registered, perhaps
87+ // / by another hooks library, the CBM will refuse to register another
88+ // / backend of the same type.
89+ // /
90+ // / @param db_type Backend type, e.g. "mysql".
91+ // / @param factory Pointer to the backend factory function.
92+ // /
93+ // / @return true if the backend has been successfully registered, false
94+ // / if another backend of this type already exists.
3495 bool registerBackendFactory (const std::string& db_type,
3596 const Factory& factory) {
97+ // Check if this backend has been already registered.
3698 if (factories_.count (db_type)) {
3799 return (false );
38100 }
39101
102+ // Register the new backend.
40103 factories_.insert (std::make_pair (db_type, factory));
41-
42104 return (true );
43105 }
44106
107+ // / @brief Create an instance of a configuration backend.
108+ // /
109+ // / This method uses provided @c dbaccess string representing database
110+ // / connection information to create an instance of the database
111+ // / backend. If the specified backend type is not supported, i.e. there
112+ // / is no relevant factory function registered, an exception is thrown.
113+ // /
114+ // / @param dbaccess Database access string being a collection of
115+ // / key=value pairs.
116+ // /
117+ // / @throw InvalidParameter if access string lacks database type value.
118+ // / @throw db::InvalidType if the type of the database backend is not
119+ // / supported.
120+ // / @throw Unexpected if the backend factory function returned NULL.
45121 void addBackend (const std::string& dbaccess) {
46- // Parse the access string and create a redacted string for logging .
122+ // Parse the access string into a map of parameters .
47123 db::DatabaseConnection::ParameterMap parameters =
48124 db::DatabaseConnection::parse (dbaccess);
49125
50- // Get the database type and open the corresponding database
126+ // Get the database type to locate a factory function.
51127 db::DatabaseConnection::ParameterMap::iterator it = parameters.find (" type" );
52128 if (it == parameters.end ()) {
53- isc_throw (InvalidParameter, " Host database configuration does not "
54- " contain the 'type' keyword" );
129+ isc_throw (InvalidParameter, " Config backend specification lacks the "
130+ " 'type' keyword" );
55131 }
56132
57133 std::string db_type = it->second ;
58134 auto index = factories_.find (db_type);
59135
60136 // No match?
61137 if (index == factories_.end ()) {
62- isc_throw (db::InvalidType, " The type of host backend: '" <<
63- db_type << " ' is not currently supported" );
138+ isc_throw (db::InvalidType, " The type of the configuration backend: '" <<
139+ db_type << " ' is not supported" );
64140 }
65141
66142 // Call the factory and push the pointer on sources.
@@ -70,23 +146,27 @@ class BaseConfigBackendMgr {
70146 " factory returned NULL" );
71147 }
72148
73- backends_->addBackend (backend);
149+ // Backend instance created successfully.
150+ pool_->addBackend (backend);
74151 }
75152
153+ // / @brief Removes all backends from the pool.
76154 void delAllBackends () {
77- backends_ ->delAllBackends ();
155+ pool_ ->delAllBackends ();
78156 }
79157
158+ // / @brief Returns underlying config backend pool.
80159 ConfigBackendPoolPtr getPool () const {
81- return (backends_ );
160+ return (pool_ );
82161 }
83162
84163protected:
85164
165+ // / @brief A map holding registered backend factory functions.
86166 std::map<std::string, Factory> factories_;
87167
88- ConfigBackendPoolPtr backends_;
89-
168+ // / @brief Pointer to the configuration backends pool.
169+ ConfigBackendPoolPtr pool_;
90170};
91171
92172} // end of namespace isc::cb
0 commit comments