Skip to content

Commit ce11cf9

Browse files
author
Razvan Becheriu
committed
[#3536] implemented register and deregister in lease mgr factory
1 parent 6b0e53c commit ce11cf9

17 files changed

+412
-44
lines changed

src/bin/dhcp4/json_config_parser.cc

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <dhcpsrv/cfgmgr.h>
2626
#include <dhcpsrv/config_backend_dhcp4_mgr.h>
2727
#include <dhcpsrv/db_type.h>
28+
#include <dhcpsrv/lease_mgr_factory.h>
2829
#include <dhcpsrv/parsers/client_class_def_parser.h>
2930
#include <dhcpsrv/parsers/dhcp_parsers.h>
3031
#include <dhcpsrv/parsers/expiration_config_parser.h>
@@ -341,9 +342,6 @@ processDhcp4Config(isc::data::ConstElementPtr config_set) {
341342
// for option definitions. This is equivalent to committing empty container.
342343
LibDHCP::setRuntimeOptionDefs(OptionDefSpaceContainer());
343344

344-
// Print the list of known backends.
345-
HostDataSourceFactory::printRegistered();
346-
347345
// Answer will hold the result.
348346
ConstElementPtr answer;
349347

@@ -902,8 +900,15 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
902900
}
903901
}
904902

903+
// Print the list of known backends.
904+
LeaseMgrFactory::printRegistered();
905+
906+
// Print the list of known backends.
907+
HostDataSourceFactory::printRegistered();
908+
905909
// Moved from the commit block to add the config backend indication.
906910
if (status_code == CONTROL_RESULT_SUCCESS && (!check_only || extra_checks)) {
911+
907912
try {
908913
// If there are config backends, fetch and merge into staging config
909914
server.getCBControl()->databaseConfigFetch(srv_config,

src/bin/dhcp4/tests/dhcp4_test_utils.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -828,7 +828,7 @@ Dhcpv4SrvTest::configure(const std::string& config,
828828
ConstElementPtr json;
829829
try {
830830
json = parseJSON(config);
831-
} catch (const std::exception& ex){
831+
} catch (const std::exception& ex) {
832832
// Fatal failure on parsing error
833833
FAIL() << "parsing failure:"
834834
<< "config:" << config << std::endl

src/bin/dhcp6/json_config_parser.cc

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <dhcpsrv/cfg_option.h>
2525
#include <dhcpsrv/cfgmgr.h>
2626
#include <dhcpsrv/db_type.h>
27+
#include <dhcpsrv/lease_mgr_factory.h>
2728
#include <dhcpsrv/parsers/client_class_def_parser.h>
2829
#include <dhcpsrv/parsers/dhcp_parsers.h>
2930
#include <dhcpsrv/parsers/duid_config_parser.h>
@@ -443,9 +444,6 @@ processDhcp6Config(isc::data::ConstElementPtr config_set) {
443444
// for option definitions. This is equivalent to committing empty container.
444445
LibDHCP::setRuntimeOptionDefs(OptionDefSpaceContainer());
445446

446-
// Print the list of known backends.
447-
HostDataSourceFactory::printRegistered();
448-
449447
// Answer will hold the result.
450448
ConstElementPtr answer;
451449

@@ -1038,6 +1036,12 @@ configureDhcp6Server(Dhcpv6Srv& server, isc::data::ConstElementPtr config_set,
10381036
}
10391037
}
10401038

1039+
// Print the list of known backends.
1040+
LeaseMgrFactory::printRegistered();
1041+
1042+
// Print the list of known backends.
1043+
HostDataSourceFactory::printRegistered();
1044+
10411045
// Moved from the commit block to add the config backend indication.
10421046
if (status_code == CONTROL_RESULT_SUCCESS && (!check_only || extra_checks)) {
10431047
try {

src/bin/dhcp6/tests/dhcp6_test_utils.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ BaseServerTest::~BaseServerTest() {
5151
// Revert to original data directory.
5252
CfgMgr::instance().setDataDir(original_datadir_);
5353

54-
// Revert to unit test logging in case the test reconfigured logging.
54+
// Revert to unit test logging, in case the test reconfigured it.
5555
isc::log::initLogger();
5656
}
5757

@@ -606,7 +606,6 @@ Dhcpv6SrvTest::testReleaseBasic(Lease::Type type, const IOAddress& existing,
606606

607607
ObservationPtr stat = StatsMgr::instance().getObservation(name);
608608
ASSERT_TRUE(stat);
609-
uint64_t before = stat->getInteger().first;
610609

611610
// Let's create a RELEASE
612611
Pkt6Ptr rel = createMessage(DHCPV6_RELEASE, type, release_addr, prefix_len,

src/hooks/dhcp/lease_cmds/tests/lease_cmds4_unittest.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3519,12 +3519,12 @@ TEST_F(Lease4CmdsTest, lease4AddDeclinedLeasesMultiThreading) {
35193519
}
35203520

35213521
TEST_F(Lease4CmdsTest, lease4AddReleasedLeases) {
3522-
testLease4AddDeclinedLeases();
3522+
testLease4AddReleasedLeases();
35233523
}
35243524

35253525
TEST_F(Lease4CmdsTest, lease4AddReleasedLeasesMultiThreading) {
35263526
MultiThreadingTest mt(true);
3527-
testLease4AddDeclinedLeases();
3527+
testLease4AddReleasedLeases();
35283528
}
35293529

35303530
TEST_F(Lease4CmdsTest, lease4AddExisting) {

src/lib/dhcpsrv/dhcpsrv_messages.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ extern const isc::log::MessageID DHCPSRV_LEASE4_EXTENDED_INFO_SANITY_FAIL = "DHC
6969
extern const isc::log::MessageID DHCPSRV_LEASE4_EXTENDED_INFO_UPGRADED = "DHCPSRV_LEASE4_EXTENDED_INFO_UPGRADED";
7070
extern const isc::log::MessageID DHCPSRV_LEASE6_EXTENDED_INFO_SANITY_FAIL = "DHCPSRV_LEASE6_EXTENDED_INFO_SANITY_FAIL";
7171
extern const isc::log::MessageID DHCPSRV_LEASE6_EXTENDED_INFO_UPGRADED = "DHCPSRV_LEASE6_EXTENDED_INFO_UPGRADED";
72+
extern const isc::log::MessageID DHCPSRV_LEASE_MGR_BACKENDS_REGISTERED = "DHCPSRV_LEASE_MGR_BACKENDS_REGISTERED";
73+
extern const isc::log::MessageID DHCPSRV_LEASE_MGR_BACKEND_DEREGISTER = "DHCPSRV_LEASE_MGR_BACKEND_DEREGISTER";
74+
extern const isc::log::MessageID DHCPSRV_LEASE_MGR_BACKEND_REGISTER = "DHCPSRV_LEASE_MGR_BACKEND_REGISTER";
7275
extern const isc::log::MessageID DHCPSRV_LEASE_MGR_CALLBACK_EXCEPTION = "DHCPSRV_LEASE_MGR_CALLBACK_EXCEPTION";
7376
extern const isc::log::MessageID DHCPSRV_LEASE_MGR_CALLBACK_UNKNOWN_EXCEPTION = "DHCPSRV_LEASE_MGR_CALLBACK_UNKNOWN_EXCEPTION";
7477
extern const isc::log::MessageID DHCPSRV_LEASE_MGR_DB_OPEN_CONNECTION_WITH_RETRY_FAILED = "DHCPSRV_LEASE_MGR_DB_OPEN_CONNECTION_WITH_RETRY_FAILED";
@@ -339,6 +342,9 @@ const char* values[] = {
339342
"DHCPSRV_LEASE4_EXTENDED_INFO_UPGRADED", "extended info for lease %1 was upgraded",
340343
"DHCPSRV_LEASE6_EXTENDED_INFO_SANITY_FAIL", "extended info for lease %1 failed checks (%2)",
341344
"DHCPSRV_LEASE6_EXTENDED_INFO_UPGRADED", "extended info for lease %1 was upgraded",
345+
"DHCPSRV_LEASE_MGR_BACKENDS_REGISTERED", "the following lease backend types are available: %1",
346+
"DHCPSRV_LEASE_MGR_BACKEND_DEREGISTER", "deregistered lease backend type: %1",
347+
"DHCPSRV_LEASE_MGR_BACKEND_REGISTER", "registered lease backend type: %1",
342348
"DHCPSRV_LEASE_MGR_CALLBACK_EXCEPTION", "exception occurred in a lease manager callback for callback type %1, subnet id %2, and lease %3: %4",
343349
"DHCPSRV_LEASE_MGR_CALLBACK_UNKNOWN_EXCEPTION", "unknown exception occurred in a lease manager callback for callback type %1, subnet id %2, and lease %3",
344350
"DHCPSRV_LEASE_MGR_DB_OPEN_CONNECTION_WITH_RETRY_FAILED", "Failed to connect to database: %1 with error: %2",

src/lib/dhcpsrv/dhcpsrv_messages.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ extern const isc::log::MessageID DHCPSRV_LEASE4_EXTENDED_INFO_SANITY_FAIL;
7070
extern const isc::log::MessageID DHCPSRV_LEASE4_EXTENDED_INFO_UPGRADED;
7171
extern const isc::log::MessageID DHCPSRV_LEASE6_EXTENDED_INFO_SANITY_FAIL;
7272
extern const isc::log::MessageID DHCPSRV_LEASE6_EXTENDED_INFO_UPGRADED;
73+
extern const isc::log::MessageID DHCPSRV_LEASE_MGR_BACKENDS_REGISTERED;
74+
extern const isc::log::MessageID DHCPSRV_LEASE_MGR_BACKEND_DEREGISTER;
75+
extern const isc::log::MessageID DHCPSRV_LEASE_MGR_BACKEND_REGISTER;
7376
extern const isc::log::MessageID DHCPSRV_LEASE_MGR_CALLBACK_EXCEPTION;
7477
extern const isc::log::MessageID DHCPSRV_LEASE_MGR_CALLBACK_UNKNOWN_EXCEPTION;
7578
extern const isc::log::MessageID DHCPSRV_LEASE_MGR_DB_OPEN_CONNECTION_WITH_RETRY_FAILED;

src/lib/dhcpsrv/dhcpsrv_messages.mes

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,20 @@ the lease database. The operation started a retry to connect procedure.
410410
The database access string with password redacted is logged, along with the
411411
error and details for the reconnect procedure.
412412

413+
% DHCPSRV_LEASE_MGR_BACKENDS_REGISTERED the following lease backend types are available: %1
414+
This informational message lists all possible lease backends that could
415+
be used in lease-database.
416+
417+
% DHCPSRV_LEASE_MGR_BACKEND_DEREGISTER deregistered lease backend type: %1
418+
Logged at debug log level 40.
419+
This debug message is issued when a backend factory was deregistered.
420+
It is no longer possible to use lease backend of this type.
421+
422+
% DHCPSRV_LEASE_MGR_BACKEND_REGISTER registered lease backend type: %1
423+
Logged at debug log level 40.
424+
This debug message is issued when a backend factory was successfully
425+
registered. It is now possible to use lease backend of this type.
426+
413427
% DHCPSRV_LEASE_SANITY_FAIL The lease %1 with subnet-id %2 failed subnet-id checks (%3).
414428
This warning message is printed when the lease being loaded does not match the
415429
configuration. Due to lease-checks value, the lease will be loaded, but

src/lib/dhcpsrv/host_data_source_factory.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ using namespace isc::dhcp;
184184

185185
namespace {
186186

187+
// Code will be moved to appropriate hook library.
187188
#ifdef HAVE_MYSQL
188189
struct MySqlHostDataSourceInit {
189190
// Constructor registers
@@ -209,6 +210,7 @@ struct MySqlHostDataSourceInit {
209210
MySqlHostDataSourceInit mysql_init_;
210211
#endif
211212

213+
// Code will be moved to appropriate hook library.
212214
#ifdef HAVE_PGSQL
213215
struct PgSqlHostDataSourceInit {
214216
// Constructor registers

src/lib/dhcpsrv/lease_mgr_factory.cc

Lines changed: 113 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,11 @@ using namespace std;
3131
namespace isc {
3232
namespace dhcp {
3333

34-
boost::scoped_ptr<TrackingLeaseMgr>&
34+
map<string, LeaseMgrFactory::Factory> LeaseMgrFactory::map_;
35+
36+
TrackingLeaseMgrPtr&
3537
LeaseMgrFactory::getLeaseMgrPtr() {
36-
static boost::scoped_ptr<TrackingLeaseMgr> lease_mgr_ptr;
38+
static TrackingLeaseMgrPtr lease_mgr_ptr;
3739
return (lease_mgr_ptr);
3840
}
3941

@@ -45,47 +47,70 @@ LeaseMgrFactory::create(const std::string& dbaccess) {
4547
DatabaseConnection::ParameterMap parameters = DatabaseConnection::parse(dbaccess);
4648
std::string redacted = DatabaseConnection::redactedAccessString(parameters);
4749

48-
// Is "type" present?
49-
if (parameters.find(type) == parameters.end()) {
50+
// Get the database type and open the corresponding database
51+
DatabaseConnection::ParameterMap::iterator it = parameters.find(type);
52+
if (it == parameters.end()) {
5053
LOG_ERROR(dhcpsrv_logger, DHCPSRV_NOTYPE_DB).arg(dbaccess);
5154
isc_throw(InvalidParameter, "Database configuration parameters do not "
5255
"contain the 'type' keyword");
5356
}
5457

55-
// Yes, check what it is.
56-
if (parameters[type] == string("mysql")) {
58+
// Code will be moved to appropriate hook library.
5759
#ifdef HAVE_MYSQL
58-
LOG_INFO(dhcpsrv_logger, DHCPSRV_MYSQL_DB).arg(redacted);
59-
getLeaseMgrPtr().reset(new MySqlLeaseMgr(parameters));
60-
return;
61-
#else
62-
LOG_ERROR(dhcpsrv_logger, DHCPSRV_UNKNOWN_DB).arg("mysql");
63-
isc_throw(InvalidType, "The Kea server has not been compiled with "
64-
"support for database type: mysql");
60+
// Factory method
61+
auto mysql_factory = [](const DatabaseConnection::ParameterMap& parameters) -> TrackingLeaseMgrPtr {
62+
LOG_INFO(dhcpsrv_logger, DHCPSRV_MYSQL_DB)
63+
.arg(DatabaseConnection::redactedAccessString(parameters));
64+
return (TrackingLeaseMgrPtr(new MySqlLeaseMgr(parameters)));
65+
};
66+
LeaseMgrFactory::registerFactory("mysql", mysql_factory, true);
6567
#endif
66-
}
6768

68-
if (parameters[type] == string("postgresql")) {
69+
// Code will be moved to appropriate hook library.
6970
#ifdef HAVE_PGSQL
70-
LOG_INFO(dhcpsrv_logger, DHCPSRV_PGSQL_DB).arg(redacted);
71-
getLeaseMgrPtr().reset(new PgSqlLeaseMgr(parameters));
72-
return;
73-
#else
74-
LOG_ERROR(dhcpsrv_logger, DHCPSRV_UNKNOWN_DB).arg("postgresql");
75-
isc_throw(InvalidType, "The Kea server has not been compiled with "
76-
"support for database type: postgresql");
71+
// Factory method
72+
auto pgsql_factory = [](const DatabaseConnection::ParameterMap& parameters) -> TrackingLeaseMgrPtr {
73+
LOG_INFO(dhcpsrv_logger, DHCPSRV_PGSQL_DB)
74+
.arg(DatabaseConnection::redactedAccessString(parameters));
75+
return (TrackingLeaseMgrPtr(new PgSqlLeaseMgr(parameters)));
76+
};
77+
LeaseMgrFactory::registerFactory("postgresql", pgsql_factory, true);
7778
#endif
78-
}
79+
7980
if (parameters[type] == string("memfile")) {
8081
LOG_INFO(dhcpsrv_logger, DHCPSRV_MEMFILE_DB).arg(redacted);
8182
getLeaseMgrPtr().reset(new Memfile_LeaseMgr(parameters));
8283
return;
8384
}
8485

85-
// Get here on no match
86-
LOG_ERROR(dhcpsrv_logger, DHCPSRV_UNKNOWN_DB).arg(parameters[type]);
87-
isc_throw(InvalidType, "Database access parameter 'type' does "
88-
"not specify a supported database backend: " << parameters[type]);
86+
string db_type = it->second;
87+
auto index = map_.find(db_type);
88+
89+
// No match?
90+
if (index == map_.end()) {
91+
if ((db_type == "mysql") ||
92+
(db_type == "postgresql")) {
93+
LOG_ERROR(dhcpsrv_logger, DHCPSRV_UNKNOWN_DB).arg(db_type);
94+
string with = (db_type == "postgresql" ? "pgsql" : db_type);
95+
isc_throw(InvalidType, "The Kea server has not been compiled with "
96+
"support for database type: " << db_type
97+
<< ". Did you forget to use --with-"
98+
<< with << " during compilation?");
99+
}
100+
// Get here on no match
101+
LOG_ERROR(dhcpsrv_logger, DHCPSRV_UNKNOWN_DB).arg(parameters[type]);
102+
isc_throw(InvalidType, "Database access parameter 'type' does "
103+
"not specify a supported database backend: " << parameters[type]);
104+
}
105+
106+
// Call the factory.
107+
getLeaseMgrPtr() = index->second(parameters);
108+
109+
// Check the factory did not return NULL.
110+
if (!getLeaseMgrPtr()) {
111+
isc_throw(Unexpected, "Lease database " << db_type <<
112+
" factory returned NULL");
113+
}
89114
}
90115

91116
void
@@ -97,6 +122,14 @@ LeaseMgrFactory::destroy() {
97122
.arg(getLeaseMgrPtr()->getType());
98123
}
99124
getLeaseMgrPtr().reset();
125+
// Code will be moved to appropriate hook library.
126+
#ifdef HAVE_MYSQL
127+
LeaseMgrFactory::deregisterFactory("mysql", true);
128+
#endif
129+
// Code will be moved to appropriate hook library.
130+
#ifdef HAVE_PGSQL
131+
LeaseMgrFactory::deregisterFactory("postgresql", true);
132+
#endif
100133
}
101134

102135
void
@@ -132,5 +165,58 @@ LeaseMgrFactory::instance() {
132165
return (*lmptr);
133166
}
134167

168+
bool
169+
LeaseMgrFactory::registerFactory(const string& db_type,
170+
const Factory& factory,
171+
bool no_log) {
172+
if (map_.count(db_type)) {
173+
return (false);
174+
}
175+
map_.insert(pair<string, Factory>(db_type, factory));
176+
177+
// We are dealing here with static logger initialization fiasco.
178+
// registerFactory may be called from constructors of static global
179+
// objects for built in backends. The logging is not initialized yet,
180+
// so the LOG_DEBUG would throw.
181+
if (!no_log) {
182+
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE, DHCPSRV_LEASE_MGR_BACKEND_REGISTER)
183+
.arg(db_type);
184+
}
185+
return (true);
186+
}
187+
188+
bool
189+
LeaseMgrFactory::deregisterFactory(const string& db_type, bool no_log) {
190+
auto index = map_.find(db_type);
191+
if (index != map_.end()) {
192+
map_.erase(index);
193+
if (!no_log) {
194+
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE,
195+
DHCPSRV_LEASE_MGR_BACKEND_DEREGISTER)
196+
.arg(db_type);
197+
}
198+
return (true);
199+
} else {
200+
return (false);
201+
}
202+
}
203+
204+
bool
205+
LeaseMgrFactory::registeredFactory(const std::string& db_type) {
206+
auto index = map_.find(db_type);
207+
return (index != map_.end());
208+
}
209+
210+
void
211+
LeaseMgrFactory::printRegistered() {
212+
std::stringstream txt;
213+
214+
for (auto const& x : map_) {
215+
txt << x.first << " ";
216+
}
217+
218+
LOG_INFO(dhcpsrv_logger, DHCPSRV_LEASE_MGR_BACKENDS_REGISTERED).arg(txt.str());
219+
}
220+
135221
} // namespace dhcp
136222
} // namespace isc

0 commit comments

Comments
 (0)