#ifndef BASE_CONFIG_BACKEND_MGR_H
#define BASE_CONFIG_BACKEND_MGR_H
-#include <database/database_connection.h>
#include <config_backend/base_config_backend.h>
+#include <database/database_connection.h>
#include <exceptions/exceptions.h>
#include <boost/shared_ptr.hpp>
#include <functional>
namespace isc {
namespace cb {
+/// @brief Base class for Configuration Backend Managers (CBM).
+///
+/// Each Kea server supporting Configuration Backend feature implements
+/// a "manager" class which holds information about supported and
+/// configured backends and provides access to the backends. This is
+/// similar to @c HostMgr and @c LeaseMgr singletons being used by the
+/// DHCP servers.
+///
+/// The Config Backend Managers are typically implemented as singletons
+/// which can be accessed from any place within the server code. This
+/// includes server configuration, data fetching during normal server
+/// operation and data management, including processing of control
+/// commands implemented within hooks libraries.
+///
+/// The @c BaseConfigBackendMgr is a base class for all CBMs implemented
+/// for respective Kea servers. It includes mechanisms to register config
+/// backend factory functions and to create instances of the backends using
+/// those factory functions as a result of server configuration. The mechanism
+/// of factory functions registration is useful in cases when the config
+/// backend is implemented within the hook library. Such hook library
+/// registers factory function in its @c load function and the server
+/// simply calls this function to create the instance of this backend when
+/// instructed to do so via configuration. Similar mechanism exists in
+/// DHCP @c HostMgr.
+///
+/// Unlike @c HostMgr, the CBMs do not directly expose API to fetch and
+/// manipulate the data in the database. This is done via, so called,
+/// Configuration Backends Pools. See @c BaseConfigBackendPool for
+/// details. The @c BaseConfigBackendMgr is provided with the pool type
+/// via class template parameter. Respective CBM implementations
+/// use their own pools, which provide APIs appropriate for those
+/// implementation.
+///
+/// @tparam ConfgBackendPoolType Type of the configuration backend pool
+/// to be used by the manager. It must derive from @c BaseConfigBackendPool
+/// template class.
template<typename ConfigBackendPoolType>
class BaseConfigBackendMgr {
public:
+ /// @brief Pointer to the configuration backend pool.
typedef boost::shared_ptr<ConfigBackendPoolType> ConfigBackendPoolPtr;
+ /// @brief Type of the backend factory function.
+ ///
+ /// Factory function returns a pointer to the instance of the configuration
+ /// backend created.
typedef std::function<typename ConfigBackendPoolType::ConfigBackendTypePtr
(const db::DatabaseConnection::ParameterMap&)> Factory;
+ /// @brief Constructor.
BaseConfigBackendMgr()
- : factories_(), backends_(new ConfigBackendPoolType()) {
+ : factories_(), pool_(new ConfigBackendPoolType()) {
}
+ /// @brief Registers new backend factory function for a given backend type.
+ ///
+ /// The typical usage of this function is to make the CBM aware of a
+ /// configuration backend implementation. This implementation may exist
+ /// in a hooks library. In such case, this function should be called from
+ /// the @c load function in this library. When the backend is registered,
+ /// the server will use it when required by the configuration, i.e. a
+ /// user includes configuration backend of that type in the
+ /// "config-databases" list.
+ ///
+ /// If the backend of the given type has already been registered, perhaps
+ /// by another hooks library, the CBM will refuse to register another
+ /// backend of the same type.
+ ///
+ /// @param db_type Backend type, e.g. "mysql".
+ /// @param factory Pointer to the backend factory function.
+ ///
+ /// @return true if the backend has been successfully registered, false
+ /// if another backend of this type already exists.
bool registerBackendFactory(const std::string& db_type,
const Factory& factory) {
+ // Check if this backend has been already registered.
if (factories_.count(db_type)) {
return (false);
}
+ // Register the new backend.
factories_.insert(std::make_pair(db_type, factory));
-
return (true);
}
+ /// @brief Create an instance of a configuration backend.
+ ///
+ /// This method uses provided @c dbaccess string representing database
+ /// connection information to create an instance of the database
+ /// backend. If the specified backend type is not supported, i.e. there
+ /// is no relevant factory function registered, an exception is thrown.
+ ///
+ /// @param dbaccess Database access string being a collection of
+ /// key=value pairs.
+ ///
+ /// @throw InvalidParameter if access string lacks database type value.
+ /// @throw db::InvalidType if the type of the database backend is not
+ /// supported.
+ /// @throw Unexpected if the backend factory function returned NULL.
void addBackend(const std::string& dbaccess) {
- // Parse the access string and create a redacted string for logging.
+ // Parse the access string into a map of parameters.
db::DatabaseConnection::ParameterMap parameters =
db::DatabaseConnection::parse(dbaccess);
- // Get the database type and open the corresponding database
+ // Get the database type to locate a factory function.
db::DatabaseConnection::ParameterMap::iterator it = parameters.find("type");
if (it == parameters.end()) {
- isc_throw(InvalidParameter, "Host database configuration does not "
- "contain the 'type' keyword");
+ isc_throw(InvalidParameter, "Config backend specification lacks the "
+ "'type' keyword");
}
std::string db_type = it->second;
// No match?
if (index == factories_.end()) {
- isc_throw(db::InvalidType, "The type of host backend: '" <<
- db_type << "' is not currently supported");
+ isc_throw(db::InvalidType, "The type of the configuration backend: '" <<
+ db_type << "' is not supported");
}
// Call the factory and push the pointer on sources.
" factory returned NULL");
}
- backends_->addBackend(backend);
+ // Backend instance created successfully.
+ pool_->addBackend(backend);
}
+ /// @brief Removes all backends from the pool.
void delAllBackends() {
- backends_->delAllBackends();
+ pool_->delAllBackends();
}
+ /// @brief Returns underlying config backend pool.
ConfigBackendPoolPtr getPool() const {
- return (backends_);
+ return (pool_);
}
protected:
+ /// @brief A map holding registered backend factory functions.
std::map<std::string, Factory> factories_;
- ConfigBackendPoolPtr backends_;
-
+ /// @brief Pointer to the configuration backends pool.
+ ConfigBackendPoolPtr pool_;
};
} // end of namespace isc::cb