Kea: lease_mgr_factory.cc Source File

| Kea 3.0.2-git

lease_mgr_factory.cc
Go to the documentation of this file.
1// Copyright (C) 2012-2025 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#include <config.h>
8
9#include <dhcpsrv/dhcpsrv_log.h>
10#include <dhcpsrv/lease_mgr_factory.h>
11#include <dhcpsrv/memfile_lease_mgr.h>
12#include <boost/algorithm/string.hpp>
13
14#include <algorithm>
15#include <iostream>
16#include <iterator>
17#include <map>
18#include <sstream>
19#include <utility>
20
21using namespace isc::db;
22using namespace std;
23
24namespace isc {
25namespace dhcp {
26
27map<string, pair<LeaseMgrFactory::Factory, LeaseMgrFactory::DBVersion>> LeaseMgrFactory::map_;
28
29namespace {
30
32isc::dhcp::MemfileLeaseMgrInit memfile_init;
33
34}
35
36 TrackingLeaseMgrPtr&
37LeaseMgrFactory::getLeaseMgrPtr() {
38 static TrackingLeaseMgrPtr lease_mgr_ptr;
39 return (lease_mgr_ptr);
40}
41
42void
43LeaseMgrFactory::create(const std::string& dbaccess) {
44 const std::string type = "type";
45
46 // Parse the access string and create a redacted string for logging.
47 DatabaseConnection::ParameterMap parameters = DatabaseConnection::parse(dbaccess);
48 std::string redacted = DatabaseConnection::redactedAccessString(parameters);
49
50 // Get the database type and open the corresponding database.
51 DatabaseConnection::ParameterMap::iterator it = parameters.find(type);
52 if (it == parameters.end()) {
53 LOG_ERROR(dhcpsrv_logger, DHCPSRV_NOTYPE_DB).arg(dbaccess);
54 isc_throw(InvalidParameter, "Database configuration parameters do not "
55 "contain the 'type' keyword");
56 }
57
58 string db_type = it->second;
59 auto index = map_.find(db_type);
60
61 // No match?
62 if (index == map_.end()) {
63 if ((db_type == "mysql") || (db_type == "postgresql")) {
64 LOG_ERROR(dhcpsrv_logger, DHCPSRV_UNKNOWN_DB).arg(db_type);
65 string libdhcp(db_type == "postgresql" ? "pgsql" : db_type);
66 isc_throw(InvalidType, "The Kea server has not been compiled with "
67 "support for lease database type: " << db_type
68 << ". Did you forget to use -D "
69 << db_type << "=enabled during setup or to load libdhcp_"
70 << libdhcp << " hook library?");
71 }
72 // Get here on no match
73 LOG_ERROR(dhcpsrv_logger, DHCPSRV_UNKNOWN_DB).arg(parameters[type]);
74 isc_throw(InvalidType, "Database access parameter 'type' does "
75 "not specify a supported database backend: " << parameters[type]);
76 }
77
78 // Call the factory.
79 getLeaseMgrPtr() = index->second.first(parameters);
80
81 // Check the factory did not return null.
82 if (!getLeaseMgrPtr()) {
83 isc_throw(Unexpected, "Lease database " << db_type <<
84 " factory returned null");
85 }
86}
87
88void
89LeaseMgrFactory::destroy() {
90 // Destroy current lease manager. This is a no-op if no lease manager
91 // is available.
92 if (getLeaseMgrPtr()) {
93 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE, DHCPSRV_CLOSE_DB)
94 .arg(getLeaseMgrPtr()->getType());
95 getLeaseMgrPtr().reset();
96 }
97}
98
99void
100LeaseMgrFactory::recreate(const std::string& dbaccess, bool preserve_callbacks) {
101 TrackingLeaseMgr::CallbackContainerPtr callbacks;
102 // Preserve the callbacks if needed.
103 if (preserve_callbacks && haveInstance()) {
104 callbacks = instance().callbacks_;
105 }
106
107 // Re-create the manager.
108 destroy();
109 create(dbaccess);
110
111 if (callbacks) {
112 // Copy the callbacks to the new instance. It should be fast
113 // because we merely copy the pointer.
114 instance().callbacks_ = callbacks;
115 }
116}
117
118bool
119LeaseMgrFactory::haveInstance() {
120 return (!!getLeaseMgrPtr());
121}
122
123 TrackingLeaseMgr&
124LeaseMgrFactory::instance() {
125 TrackingLeaseMgr* lmptr = getLeaseMgrPtr().get();
126 if (!lmptr) {
127 isc_throw(NoLeaseManager, "no current lease manager is available");
128 }
129 return (*lmptr);
130}
131
132bool
133LeaseMgrFactory::registerFactory(const string& db_type,
134 const Factory& factory,
135 bool no_log,
136 DBVersion db_version) {
137 if (map_.count(db_type)) {
138 return (false);
139 }
140
141 static auto default_db_version = []() -> std::string {
142 return (std::string());
143 };
144
145 if (!db_version) {
146 db_version = default_db_version;
147 }
148
149 map_.insert(pair<string, pair<Factory, DBVersion>>(db_type, pair<Factory, DBVersion>(factory, db_version)));
150
151 // We are dealing here with static logger initialization fiasco.
152 // registerFactory may be called from constructors of static global
153 // objects for built in backends. The logging is not initialized yet,
154 // so the LOG_DEBUG would throw.
155 if (!no_log) {
156 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE, DHCPSRV_LEASE_MGR_BACKEND_REGISTER)
157 .arg(db_type);
158 }
159 return (true);
160}
161
162bool
163LeaseMgrFactory::deregisterFactory(const string& db_type, bool no_log) {
164 auto index = map_.find(db_type);
165 if (index != map_.end()) {
166 map_.erase(index);
167 if (!no_log) {
168 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE,
169 DHCPSRV_LEASE_MGR_BACKEND_DEREGISTER)
170 .arg(db_type);
171 }
172 return (true);
173 } else {
174 return (false);
175 }
176}
177
178bool
179LeaseMgrFactory::registeredFactory(const std::string& db_type) {
180 auto index = map_.find(db_type);
181 return (index != map_.end());
182}
183
184void
185LeaseMgrFactory::logRegistered() {
186 std::stringstream txt;
187
188 for (auto const& x : map_) {
189 if (!txt.str().empty()) {
190 txt << " ";
191 }
192 txt << x.first;
193 }
194
195 LOG_INFO(dhcpsrv_logger, DHCPSRV_LEASE_MGR_BACKENDS_REGISTERED)
196 .arg(txt.str());
197}
198
199std::list<std::string>
200LeaseMgrFactory::getDBVersions() {
201 std::list<std::string> result;
202 for (auto const& x : map_) {
203 auto version = x.second.second();
204 if (!version.empty()) {
205 result.push_back(version);
206 }
207 }
208
209 return (result);
210}
211
212} // namespace dhcp
213} // namespace isc
isc::InvalidParameter
A generic exception that is thrown if a parameter given to a method or function is considered invalid...
Definition exceptions/exceptions.h:124
isc::Unexpected
A generic exception that is thrown when an unexpected error condition occurs.
Definition exceptions/exceptions.h:153
isc::db::DatabaseConnection::redactedAccessString
static std::string redactedAccessString(const ParameterMap &parameters)
Redact database access string.
Definition database_connection.cc:108
isc::db::DatabaseConnection::parse
static ParameterMap parse(const std::string &dbaccess)
Parse database access string.
Definition database_connection.cc:41
isc::db::DatabaseConnection::ParameterMap
std::map< std::string, std::string > ParameterMap
Database configuration parameter map.
Definition database_connection.h:137
isc::db::InvalidType
Invalid type exception.
Definition database_connection.h:62
isc::dhcp::LeaseMgrFactory::create
static void create(const std::string &dbaccess)
Create an instance of a lease manager.
Definition lease_mgr_factory.cc:43
isc::dhcp::LeaseMgrFactory::instance
static TrackingLeaseMgr & instance()
Return current lease manager.
Definition lease_mgr_factory.cc:124
isc::dhcp::LeaseMgrFactory::registerFactory
static bool registerFactory(const std::string &db_type, const Factory &factory, bool no_log=false, DBVersion db_version=DBVersion())
Register a lease mgr factory.
Definition lease_mgr_factory.cc:133
isc::dhcp::LeaseMgrFactory::getDBVersions
static std::list< std::string > getDBVersions()
Return extended version info for registered backends.
Definition lease_mgr_factory.cc:200
isc::dhcp::LeaseMgrFactory::Factory
std::function< TrackingLeaseMgrPtr(const db::DatabaseConnection::ParameterMap &)> Factory
Type of lease mgr factory.
Definition lease_mgr_factory.h:110
isc::dhcp::LeaseMgrFactory::destroy
static void destroy()
Destroy lease manager.
Definition lease_mgr_factory.cc:89
isc::dhcp::LeaseMgrFactory::registeredFactory
static bool registeredFactory(const std::string &db_type)
Check if a lease mgr factory was registered.
Definition lease_mgr_factory.cc:179
isc::dhcp::LeaseMgrFactory::DBVersion
std::function< std::string()> DBVersion
Type of lease mgr version.
Definition lease_mgr_factory.h:113
isc::dhcp::LeaseMgrFactory::haveInstance
static bool haveInstance()
Indicates if the lease manager has been instantiated.
Definition lease_mgr_factory.cc:119
isc::dhcp::LeaseMgrFactory::deregisterFactory
static bool deregisterFactory(const std::string &db_type, bool no_log=false)
Deregister a lease mgr factory.
Definition lease_mgr_factory.cc:163
isc::dhcp::LeaseMgrFactory::logRegistered
static void logRegistered()
Logs out all registered backends.
Definition lease_mgr_factory.cc:185
isc::dhcp::LeaseMgrFactory::recreate
static void recreate(const std::string &dbaccess, bool preserve_callbacks=true)
Recreate an instance of a lease manager with optionally preserving registered callbacks.
Definition lease_mgr_factory.cc:100
isc::dhcp::NoLeaseManager
No lease manager exception.
Definition lease_mgr_factory.h:25
isc::dhcp::TrackingLeaseMgr
Introduces callbacks into the LeaseMgr.
Definition tracking_lease_mgr.h:76
isc::dhcp::TrackingLeaseMgr::CallbackContainerPtr
boost::shared_ptr< CallbackContainer > CallbackContainerPtr
Pointer to the callback container.
Definition tracking_lease_mgr.h:153
isc::dhcp::TrackingLeaseMgr::callbacks_
CallbackContainerPtr callbacks_
The multi-index container holding registered callbacks.
Definition tracking_lease_mgr.h:296
version
int version()
returns Kea hooks version.
Definition d2/gss_tsig/version.cc:13
dhcpsrv_log.h
isc_throw
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition exceptions/exceptions.h:210
lease_mgr_factory.h
LOG_ERROR
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Definition macros.h:32
LOG_INFO
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
Definition macros.h:20
LOG_DEBUG
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition macros.h:14
memfile_lease_mgr.h
isc::db
Definition audit_entry.cc:14
isc::dhcp
Definition dhcp4/client_handler.cc:20
isc::dhcp::dhcpsrv_logger
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
Definition dhcpsrv_log.h:56
isc::dhcp::DHCPSRV_LEASE_MGR_BACKENDS_REGISTERED
const isc::log::MessageID DHCPSRV_LEASE_MGR_BACKENDS_REGISTERED
Definition dhcpsrv_messages.h:79
isc::dhcp::DHCPSRV_LEASE_MGR_BACKEND_DEREGISTER
const isc::log::MessageID DHCPSRV_LEASE_MGR_BACKEND_DEREGISTER
Definition dhcpsrv_messages.h:80
isc::dhcp::DHCPSRV_CLOSE_DB
const isc::log::MessageID DHCPSRV_CLOSE_DB
Definition dhcpsrv_messages.h:52
isc::dhcp::DHCPSRV_UNKNOWN_DB
const isc::log::MessageID DHCPSRV_UNKNOWN_DB
Definition dhcpsrv_messages.h:179
isc::dhcp::DHCPSRV_LEASE_MGR_BACKEND_REGISTER
const isc::log::MessageID DHCPSRV_LEASE_MGR_BACKEND_REGISTER
Definition dhcpsrv_messages.h:81
isc::dhcp::DHCPSRV_NOTYPE_DB
const isc::log::MessageID DHCPSRV_NOTYPE_DB
Definition dhcpsrv_messages.h:152
isc::dhcp::TrackingLeaseMgrPtr
std::unique_ptr< TrackingLeaseMgr > TrackingLeaseMgrPtr
TrackingLeaseMgr pointer.
Definition tracking_lease_mgr.h:306
isc::dhcp::DHCPSRV_DBG_TRACE
const int DHCPSRV_DBG_TRACE
DHCP server library logging levels.
Definition dhcpsrv_log.h:26
isc
Defines the logger used by the top-level component of kea-lfc.
Definition agent_parser.cc:148