-// Copyright (C) 2016-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2016-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
void
-CfgDbAccess::createManagers(DatabaseConnection::DbLostCallback db_lost_callback) const {
+CfgDbAccess::createManagers() const {
// Recreate lease manager.
LeaseMgrFactory::destroy();
- LeaseMgrFactory::create(getLeaseDbAccessString(), db_lost_callback);
+ LeaseMgrFactory::create(getLeaseDbAccessString());
// Recreate host data source.
HostDataSourceFactory::destroy();
if (!host_db_access_.empty()) {
- HostMgr::create(getHostDbAccessString(), db_lost_callback);
+ HostMgr::create(getHostDbAccessString());
}
}
/// @brief Creates instance of lease manager and host data source
/// according to the configuration specified.
- ///
- /// @param db_lost_callback function to invoke if connectivity to
- /// either the lease or host managers, once established, is subsequently
- /// lost.
- void createManagers(DatabaseConnection::DbLostCallback db_lost_callback = 0) const;
+ void createManagers() const;
/// @brief Unparse an access string
///
ReconnectCtlPtr
DatabaseConnection::makeReconnectCtl() const {
ReconnectCtlPtr retry;
+ string name = "unknown";
unsigned int retries = 0;
unsigned int interval = 0;
// Assumes that parsing ensurse only valid values are present
+ try {
+ name = getParameter("type");
+ } catch (...) {
+ // Wasn't specified so we'll use default of "unknown".
+ }
+
std::string parm_str;
try {
parm_str = getParameter("max-reconnect-tries");
retries = boost::lexical_cast<unsigned int>(parm_str);
} catch (...) {
- // Wasn't specified so so we'll use default of 0;
+ // Wasn't specified so we'll use default of 0;
}
try {
parm_str = getParameter("reconnect-wait-time");
interval = boost::lexical_cast<unsigned int>(parm_str);
} catch (...) {
- // Wasn't specified so so we'll use default of 0;
+ // Wasn't specified so we'll use default of 0;
}
- retry.reset(new ReconnectCtl(retries, interval));
+ retry.reset(new ReconnectCtl(name, retries, interval));
return (retry);
}
bool
DatabaseConnection::invokeDbLostCallback() const {
- if (db_lost_callback_ != NULL) {
+ if (DatabaseConnection::db_lost_callback) {
// Invoke the callback, passing in a new instance of ReconnectCtl
- return (db_lost_callback_)(makeReconnectCtl());
+ return (DatabaseConnection::db_lost_callback)(makeReconnectCtl());
}
return (false);
}
+
+DatabaseConnection::DbLostCallback
+DatabaseConnection::db_lost_callback = 0;
+
};
};
class ReconnectCtl {
public:
/// @brief Constructor
+ /// @param backend_name name of the caller backend.
/// @param max_retries maximum number of reconnect attempts to make
/// @param retry_interval amount of time to between reconnect attempts
- ReconnectCtl(unsigned int max_retries, unsigned int retry_interval)
- : max_retries_(max_retries), retries_left_(max_retries),
- retry_interval_(retry_interval) {}
+ ReconnectCtl(const std::string& backend_name, unsigned int max_retries,
+ unsigned int retry_interval)
+ : backend_name_(backend_name), max_retries_(max_retries),
+ retries_left_(max_retries), retry_interval_(retry_interval) {}
+
+ /// @brief Returns the name of the caller backend.
+ std::string backendName() const {
+ return (backend_name_);
+ }
/// @brief Decrements the number of retries remaining
///
}
private:
+ /// @brief Caller backend name.
+ const std::string backend_name_;
+
/// @brief Maximum number of retry attempts to make
unsigned int max_retries_;
/// @brief Database configuration parameter map
typedef std::map<std::string, std::string> ParameterMap;
- /// @brief Defines a callback prototype for propogating events upward
- typedef boost::function<bool (ReconnectCtlPtr db_retry)> DbLostCallback;
-
/// @brief Constructor
///
/// @param parameters A data structure relating keywords and values
/// concerned with the database.
- /// @param db_lost_callback Optional call back function to invoke if a
- /// successfully open connection subsequently fails
- DatabaseConnection(const ParameterMap& parameters,
- DbLostCallback db_lost_callback = 0)
- :parameters_(parameters), db_lost_callback_(db_lost_callback) {
+ DatabaseConnection(const ParameterMap& parameters)
+ :parameters_(parameters) {
}
/// @brief Destructor
/// and set to false.
bool configuredReadOnly() const;
+ /// @brief Defines a callback prototype for propogating events upward
+ typedef boost::function<bool (ReconnectCtlPtr db_retry)> DbLostCallback;
+
/// @brief Invokes the connection's lost connectivity callback
///
/// This function may be called by derivations when the connectivity
/// callback.
bool invokeDbLostCallback() const;
+ /// @brief Optional call back function to invoke if a successfully
+ /// open connection subsequently fails
+ static DbLostCallback db_lost_callback;
+
private:
/// @brief List of parameters passed in dbconfig
/// intended to keep any DHCP-related parameters.
ParameterMap parameters_;
-protected:
-
- /// @brief Optional function to invoke if the connectivity is lost
- DbLostCallback db_lost_callback_;
};
}; // end of isc::dhcp namespace
-// 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
}
void
-HostDataSourceFactory::create(const std::string& dbaccess,
- DatabaseConnection::DbLostCallback db_lost_callback) {
+HostDataSourceFactory::create(const std::string& dbaccess) {
// Parse the access string and create a redacted string for logging.
DatabaseConnection::ParameterMap parameters =
DatabaseConnection::parse(dbaccess);
if (db_type == "postgresql") {
LOG_INFO(dhcpsrv_logger, DHCPSRV_PGSQL_HOST_DB)
.arg(DatabaseConnection::redactedAccessString(parameters));
- getHostDataSourcePtr().reset(new PgSqlHostDataSource(parameters,
- db_lost_callback));
+ getHostDataSourcePtr().reset(new PgSqlHostDataSource(parameters));
return;
}
#endif
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");
- }
- return (*hdsptr);
-}
-#endif
-
} // namespace dhcp
} // namespace isc
/// -end specific, although must include the "type" keyword which
/// gives the backend in use.
///
- /// @param db_lost_callback function to invoke if connectivity to host
- /// data source is lost.
- ///
/// @throw isc::InvalidParameter dbaccess string does not contain the "type"
/// keyword.
/// @throw isc::dhcp::InvalidType The "type" keyword in dbaccess does not
/// identify a supported backend.
- static void create(const std::string& dbaccess,
- DatabaseConnection::DbLostCallback db_lost_callback = 0);
+ static void create(const std::string& dbaccess);
/// @brief Destroy host data source
///
-// Copyright (C) 2014-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-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
}
void
-HostMgr::create(const std::string& access,
- DatabaseConnection::DbLostCallback db_lost_callback) {
+HostMgr::create(const std::string& access) {
getHostMgrPtr().reset(new HostMgr());
if (!access.empty()) {
// If the user specified parameters, let's pass them to the create
// method. It will destroy any prior instances and will create
// the new one.
- HostDataSourceFactory::create(access, db_lost_callback);
+ HostDataSourceFactory::create(access);
} else {
// Ok, no parameters were specified. We should destroy the existing
// instance.
HostDataSourceFactory::destroy();
}
- // Now store the host data source pointer. It may be NULL. That's ok as
- // NULL value indicates that there's no host data source configured.
+ // Now store the host data source pointer. It may be null. That's ok as
+ // null value indicates that there's no host data source configured.
getHostMgrPtr()->alternate_source_ =
HostDataSourceFactory::getHostDataSourcePtr();
}
/// However, the "type" parameter will be common and it will specify which
/// data source is to be used. Currently, no parameters are supported
/// and the parameter is ignored.
- ///
- /// @param db_lost_callback function to invoke if connectivity to
- /// the host database is lost.
- static void create(const std::string& access = "",
- DatabaseConnection::DbLostCallback db_lost_callback = 0);
+ static void create(const std::string& access = "");
/// @brief Returns a sole instance of the @c HostMgr.
///
}
void
-LeaseMgrFactory::create(const std::string& dbaccess,
- DatabaseConnection::DbLostCallback db_lost_callback) {
+LeaseMgrFactory::create(const std::string& dbaccess) {
const std::string type = "type";
// Parse the access string and create a redacted string for logging.
#ifdef HAVE_PGSQL
if (parameters[type] == string("postgresql")) {
LOG_INFO(dhcpsrv_logger, DHCPSRV_PGSQL_DB).arg(redacted);
- getLeaseMgrPtr().reset(new PgSqlLeaseMgr(parameters, db_lost_callback));
+ getLeaseMgrPtr().reset(new PgSqlLeaseMgr(parameters));
return;
}
#endif
/// -end specific, although must include the "type" keyword which
/// gives the backend in use.
///
- /// @param db_lost_callback function to invoke if connectivity to lease
- /// database is lost.
- ///
/// @throw isc::InvalidParameter dbaccess string does not contain the "type"
/// keyword.
/// @throw isc::dhcp::InvalidType The "type" keyword in dbaccess does not
/// identify a supported backend.
- static void create(const std::string& dbaccess,
- DatabaseConnection::DbLostCallback db_lost_callback = 0);
+ static void create(const std::string& dbaccess);
/// @brief Destroy lease manager
///
-// Copyright (C) 2016-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2016-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
: DatabaseConnection(parameters) {
}
- PgSqlConnection(const ParameterMap& parameters,
- DbLostCallback db_lost_callback)
- : DatabaseConnection(parameters, db_lost_callback) {
- }
-
/// @brief Destructor
virtual ~PgSqlConnection();
///
/// This constructor opens database connection and initializes prepared
/// statements used in the queries.
- PgSqlHostDataSourceImpl(const PgSqlConnection::ParameterMap& parameters,
- DatabaseConnection::DbLostCallback db_lost_callback);
+ PgSqlHostDataSourceImpl(const PgSqlConnection::ParameterMap& parameters);
/// @brief Destructor.
~PgSqlHostDataSourceImpl();
}; // end anonymous namespace
PgSqlHostDataSourceImpl::
-PgSqlHostDataSourceImpl(const PgSqlConnection::ParameterMap& parameters,
- DatabaseConnection::DbLostCallback db_lost_callback)
+PgSqlHostDataSourceImpl(const PgSqlConnection::ParameterMap& parameters)
: host_exchange_(new PgSqlHostWithOptionsExchange(PgSqlHostWithOptionsExchange::DHCP4_ONLY)),
host_ipv6_exchange_(new PgSqlHostIPv6Exchange(PgSqlHostWithOptionsExchange::DHCP6_ONLY)),
host_ipv46_exchange_(new PgSqlHostIPv6Exchange(PgSqlHostWithOptionsExchange::
DHCP4_AND_DHCP6)),
host_ipv6_reservation_exchange_(new PgSqlIPv6ReservationExchange()),
host_option_exchange_(new PgSqlOptionExchange()),
- conn_(parameters, db_lost_callback),
+ conn_(parameters),
is_readonly_(false) {
// Open the database.
/*********** PgSqlHostDataSource *********************/
PgSqlHostDataSource::
-PgSqlHostDataSource(const PgSqlConnection::ParameterMap& parameters,
- DatabaseConnection::DbLostCallback db_lost_callback)
- : impl_(new PgSqlHostDataSourceImpl(parameters, db_lost_callback)) {
+PgSqlHostDataSource(const PgSqlConnection::ParameterMap& parameters)
+ : impl_(new PgSqlHostDataSourceImpl(parameters)) {
}
PgSqlHostDataSource::~PgSqlHostDataSource() {
/// @param parameters A data structure relating keywords and values
/// concerned with the database.
///
- /// @param db_lost_callback function to invoke if connectivity to
- /// to host database is lost.
- ///
/// @throw isc::dhcp::NoDatabaseName Mandatory database name not given
/// @throw isc::dhcp::DbOpenError Error opening the database
/// @throw isc::dhcp::DbOperationError An operation on the open database has
/// failed.
- PgSqlHostDataSource(const DatabaseConnection::ParameterMap& parameters,
- DatabaseConnection::DbLostCallback db_lost_callback = 0);
+ PgSqlHostDataSource(const DatabaseConnection::ParameterMap& parameters);
/// @brief Virtual destructor.
/// Frees database resources and closes the database connection through
bool fetch_type_;
};
-PgSqlLeaseMgr::PgSqlLeaseMgr(const DatabaseConnection::ParameterMap& parameters,
- DatabaseConnection::DbLostCallback db_lost_callback)
+PgSqlLeaseMgr::PgSqlLeaseMgr(const DatabaseConnection::ParameterMap& parameters)
: LeaseMgr(), exchange4_(new PgSqlLease4Exchange()),
- exchange6_(new PgSqlLease6Exchange()), conn_(parameters, db_lost_callback) {
+ exchange6_(new PgSqlLease6Exchange()), conn_(parameters) {
conn_.openDatabase();
int i = 0;
for( ; tagged_statements[i].text != NULL ; ++i) {
/// @param parameters A data structure relating keywords and values
/// concerned with the database.
///
- /// @param db_lost_callback function to invoke if connectivity to
- /// to lease database is lost.
- ///
/// @throw isc::dhcp::NoDatabaseName Mandatory database name not given
/// @throw isc::dhcp::DbOpenError Error opening the database
/// @throw isc::dhcp::DbOperationError An operation on the open database has
/// failed.
- PgSqlLeaseMgr(const DatabaseConnection::ParameterMap& parameters,
- DatabaseConnection::DbLostCallback db_lost_callback = 0);
+ PgSqlLeaseMgr(const DatabaseConnection::ParameterMap& parameters);
/// @brief Destructor (closes database)
virtual ~PgSqlLeaseMgr();
ReconnectCtlPtr db_reconnect_ctl_;
};
-
-
/// @brief getParameter test
///
/// This test checks if the LeaseMgr can be instantiated and that it
/// DbLostCallback.
TEST_F(DatabaseConnectionCallbackTest, NoDbLostCallback) {
DatabaseConnection::ParameterMap pmap;
+ pmap[std::string("type")] = std::string("test");
pmap[std::string("max-reconnect-tries")] = std::string("3");
pmap[std::string("reconnect-wait-time")] = std::string("60");
DatabaseConnection datasrc(pmap);
EXPECT_FALSE(db_reconnect_ctl_);
}
-
-/// @brief NoDbLostCallback
+/// @brief dbLostCallback
///
/// This test verifies that DatabaseConnection::invokeDbLostCallback
/// safely invokes the registered DbLostCallback. It also tests
/// Create a Database configuration that includes the reconnect
/// control parameters.
DatabaseConnection::ParameterMap pmap;
+ pmap[std::string("type")] = std::string("test");
pmap[std::string("max-reconnect-tries")] = std::string("3");
pmap[std::string("reconnect-wait-time")] = std::string("60");
- /// Create the connection with a DbLostCallback.
- DatabaseConnection datasrc(pmap, boost::bind(&DatabaseConnectionCallbackTest
- ::dbLostCallback, this, _1));
+ /// Install the callback.
+ DatabaseConnection::db_lost_callback =
+ boost::bind(&DatabaseConnectionCallbackTest::dbLostCallback, this, _1);
+ /// Create the connection..
+ DatabaseConnection datasrc(pmap);
/// We should be able to invoke the callback and glean
/// the correct reconnect contorl parameters from it.
ASSERT_NO_THROW(ret = datasrc.invokeDbLostCallback());
EXPECT_TRUE(ret);
ASSERT_TRUE(db_reconnect_ctl_);
+ ASSERT_EQ("test", db_reconnect_ctl_->backendName());
ASSERT_EQ(3, db_reconnect_ctl_->maxRetries());
ASSERT_EQ(3, db_reconnect_ctl_->retriesLeft());
EXPECT_EQ(60, db_reconnect_ctl_->retryInterval());
EXPECT_EQ(3, db_reconnect_ctl_->maxRetries());
}
-
// This test checks that a database access string can be parsed correctly.
TEST(DatabaseConnectionTest, parse) {
-// Copyright (C) 2016-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2016-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
createPgSQLSchema();
callback_called = false;
+ DatabaseConnection::db_lost_callback = db_lost_callback;
EXPECT_THROW(HostDataSourceFactory::create(connectionString(
- PGSQL_VALID_TYPE, VALID_NAME, INVALID_HOST, VALID_USER, VALID_PASSWORD),
- db_lost_callback), DbOpenError);
+ PGSQL_VALID_TYPE, VALID_NAME, INVALID_HOST, VALID_USER, VALID_PASSWORD)),
+ DbOpenError);
EXPECT_FALSE(callback_called);
destroyPgSQLSchema();
createPgSQLSchema();
callback_called = false;
+ DatabaseConnection::db_lost_callback = db_lost_callback;
EXPECT_THROW(LeaseMgrFactory::create(connectionString(
- PGSQL_VALID_TYPE, VALID_NAME, INVALID_HOST, VALID_USER, VALID_PASSWORD),
- db_lost_callback),
+ PGSQL_VALID_TYPE, VALID_NAME, INVALID_HOST, VALID_USER, VALID_PASSWORD)),
DbOpenError);
EXPECT_FALSE(callback_called);