Commit 60d9fe4e authored by Francis Dupont's avatar Francis Dupont
Browse files

[5528] Code and tests done

parent 51fd66d3
// Copyright (C) 2015-2017 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2015-2018 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
......@@ -38,6 +38,8 @@ using namespace std;
namespace isc {
namespace dhcp {
map<string, HostDataSourceFactory::Factory> HostDataSourceFactory::map_;
HostDataSourcePtr&
HostDataSourceFactory::getHostDataSourcePtr() {
static HostDataSourcePtr hostDataSourcePtr;
......@@ -45,7 +47,7 @@ HostDataSourceFactory::getHostDataSourcePtr() {
}
void
HostDataSourceFactory::create(const std::string& dbaccess) {
HostDataSourceFactory::create(const string& dbaccess) {
// Parse the access string and create a redacted string for logging.
DatabaseConnection::ParameterMap parameters =
DatabaseConnection::parse(dbaccess);
......@@ -57,38 +59,23 @@ HostDataSourceFactory::create(const std::string& dbaccess) {
"contain the 'type' keyword");
}
std::string db_type = it->second;
string db_type = it->second;
auto index = map_.find(db_type);
#ifdef HAVE_MYSQL
if (db_type == "mysql") {
LOG_INFO(dhcpsrv_logger, DHCPSRV_MYSQL_HOST_DB)
.arg(DatabaseConnection::redactedAccessString(parameters));
getHostDataSourcePtr().reset(new MySqlHostDataSource(parameters));
return;
// No match?
if (index == map_.end()) {
isc_throw(InvalidType, "Hosts database access parameter 'type': " <<
db_type << " is invalid");
}
#endif
#ifdef HAVE_PGSQL
if (db_type == "postgresql") {
LOG_INFO(dhcpsrv_logger, DHCPSRV_PGSQL_HOST_DB)
.arg(DatabaseConnection::redactedAccessString(parameters));
getHostDataSourcePtr().reset(new PgSqlHostDataSource(parameters));
return;
}
#endif
// Call the factory
getHostDataSourcePtr().reset(index->second(parameters));
#ifdef HAVE_CQL
if (db_type == "cql") {
LOG_INFO(dhcpsrv_logger, DHCPSRV_CQL_HOST_DB)
.arg(DatabaseConnection::redactedAccessString(parameters));
getHostDataSourcePtr().reset(new CqlHostDataSource(parameters));
return;
// Check the factory did not return NULL.
if (!getHostDataSourcePtr()) {
isc_throw(Unexpected, "Hosts database " << db_type <<
" factory returned NULL");
}
#endif
// Get here on no match.
isc_throw(InvalidType, "Hosts database access parameter 'type': " <<
db_type << " is invalid");
}
void
......@@ -102,17 +89,111 @@ HostDataSourceFactory::destroy() {
getHostDataSourcePtr().reset();
}
#if 0
BaseHostDataSource&
HostDataSourceFactory::instance() {
BaseHostDataSource* hdsptr = getHostDataSourcePtr().get();
if (hdsptr == NULL) {
isc_throw(NoHostDataSourceManager,
"no current host data source instance is available");
bool
HostDataSourceFactory::registerFactory(const string& db_type,
const Factory& factory) {
if (map_.count(db_type)) {
return (false);
}
map_.insert(pair<string, Factory>(db_type, factory));
return (true);
}
bool
HostDataSourceFactory::deregisterFactory(const string& db_type) {
auto index = map_.find(db_type);
if (index != map_.end()) {
map_.erase(index);
return (true);
} else {
return (false);
}
return (*hdsptr);
}
#endif
} // namespace dhcp
} // namespace isc
//
// Register database backends
//
using namespace isc::dhcp;
namespace {
#ifdef HAVE_MYSQL
struct MySqlHostDataSourceInit {
// Constructor registers
MySqlHostDataSourceInit() {
HostDataSourceFactory::registerFactory("mysql", factory);
}
// Destructor deregisters
~MySqlHostDataSourceInit() {
HostDataSourceFactory::deregisterFactory("mysql");
}
// Factory class method
static BaseHostDataSource*
factory(const DatabaseConnection::ParameterMap& parameters) {
LOG_INFO(dhcpsrv_logger, DHCPSRV_MYSQL_HOST_DB)
.arg(DatabaseConnection::redactedAccessString(parameters));
return (new MySqlHostDataSource(parameters));
}
};
// Database backend will be registered at object initialization
MySqlHostDataSourceInit mysql_init;
#endif
#ifdef HAVE_PGSQL
struct PgSqlHostDataSourceInit {
// Constructor registers
PgSqlHostDataSourceInit() {
HostDataSourceFactory::registerFactory("postgresql", factory);
}
// Destructor deregisters
~PgSqlHostDataSourceInit() {
HostDataSourceFactory::deregisterFactory("postgresql");
}
// Factory class method
static BaseHostDataSource*
factory(const DatabaseConnection::ParameterMap& parameters) {
LOG_INFO(dhcpsrv_logger, DHCPSRV_PGSQL_HOST_DB)
.arg(DatabaseConnection::redactedAccessString(parameters));
return (new PgSqlHostDataSource(parameters));
}
};
// Database backend will be registered at object initialization
PgSqlHostDataSourceInit mysql_init;
#endif
#ifdef HAVE_CQL
struct CqlHostDataSourceInit {
// Constructor registers
CqlHostDataSourceInit() {
HostDataSourceFactory::registerFactory("cql", factory);
}
// Destructor deregisters
~CqlHostDataSourceInit() {
HostDataSourceFactory::deregisterFactory("cql");
}
// Factory class method
static BaseHostDataSource*
factory(const DatabaseConnection::ParameterMap& parameters) {
LOG_INFO(dhcpsrv_logger, DHCPSRV_CQL_HOST_DB)
.arg(DatabaseConnection::redactedAccessString(parameters));
return (new CqlHostDataSource(parameters));
}
};
// Database backend will be registered at object initialization
CqlHostDataSourceInit mysql_init;
#endif
} // end of anonymous namespace
// Copyright (C) 2015-2016 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2015-2018 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
......@@ -11,8 +11,10 @@
#include <dhcpsrv/database_connection.h>
#include <exceptions/exceptions.h>
#include <boost/scoped_ptr.hpp>
#include <boost/function.hpp>
#include <string>
#include <map>
namespace isc {
namespace dhcp {
......@@ -77,6 +79,36 @@ public:
/// is encapsulated in this method to avoid a "static initialization
/// fiasco" if defined in an external static variable.
static HostDataSourcePtr& getHostDataSourcePtr();
/// @brief Type of host data source factory
///
/// A factory takes a parameter map and returns a pointer to a host
/// data source. In case of failure it must throw and not return NULL.
typedef boost::function<BaseHostDataSource*(const DatabaseConnection::ParameterMap&)> Factory;
/// @brief Register a host data source factory
///
/// Associate the factory to a database type in the map.
///
/// @param db_type database type
/// @param factory host data source factory
/// @return true if the factory was successfully added to the map, false
/// if it already exists.
static bool registerFactory(const std::string& db_type,
const Factory& factory);
/// @brief Deregister a host data source factory
///
/// Disassociate the factory to a database type in the map.
///
/// @param db_type database type
/// @return true if the factory was successfully removed from the map,
/// false if it was not found.
static bool deregisterFactory(const std::string& db_type);
private:
/// @brief Factory map
static std::map<std::string, Factory> map_;
};
......
......@@ -91,6 +91,7 @@ libdhcpsrv_unittests_SOURCES += dbaccess_parser_unittest.cc
libdhcpsrv_unittests_SOURCES += dhcp4o6_ipc_unittest.cc
libdhcpsrv_unittests_SOURCES += duid_config_parser_unittest.cc
libdhcpsrv_unittests_SOURCES += expiration_config_parser_unittest.cc
libdhcpsrv_unittests_SOURCES += host_data_source_factory_unittest.cc
libdhcpsrv_unittests_SOURCES += host_mgr_unittest.cc
libdhcpsrv_unittests_SOURCES += host_unittest.cc
libdhcpsrv_unittests_SOURCES += host_reservation_parser_unittest.cc
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment