Kea 2.7.3
lease_mgr_factory.cc
Go to the documentation of this file.
1// Copyright (C) 2012-2024 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
12#ifdef HAVE_MYSQL
14#endif
15#ifdef HAVE_PGSQL
17#endif
18
19#include <boost/algorithm/string.hpp>
20
21#include <algorithm>
22#include <iostream>
23#include <iterator>
24#include <map>
25#include <sstream>
26#include <utility>
27
28using namespace isc::db;
29using namespace std;
30
31namespace isc {
32namespace dhcp {
33
34map<string, LeaseMgrFactory::Factory> LeaseMgrFactory::map_;
35
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.
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()) {
54 isc_throw(InvalidParameter, "Database configuration parameters do not "
55 "contain the 'type' keyword");
56 }
57
58 // Code will be moved to appropriate hook library.
59#ifdef HAVE_MYSQL
60 // Factory method
61 auto mysql_factory = [](const DatabaseConnection::ParameterMap& parameters) -> TrackingLeaseMgrPtr {
64 return (TrackingLeaseMgrPtr(new MySqlLeaseMgr(parameters)));
65 };
66 LeaseMgrFactory::registerFactory("mysql", mysql_factory, true);
67#endif
68
69 // Code will be moved to appropriate hook library.
70#ifdef HAVE_PGSQL
71 // Factory method
72 auto pgsql_factory = [](const DatabaseConnection::ParameterMap& parameters) -> TrackingLeaseMgrPtr {
75 return (TrackingLeaseMgrPtr(new PgSqlLeaseMgr(parameters)));
76 };
77 LeaseMgrFactory::registerFactory("postgresql", pgsql_factory, true);
78#endif
79
80 // Factory method
81 auto memfile_factory = [](const DatabaseConnection::ParameterMap& parameters) -> TrackingLeaseMgrPtr {
84 return (TrackingLeaseMgrPtr(new Memfile_LeaseMgr(parameters)));
85 };
86 LeaseMgrFactory::registerFactory("memfile", memfile_factory, true);
87
88 string db_type = it->second;
89 auto index = map_.find(db_type);
90
91 // No match?
92 if (index == map_.end()) {
93 if ((db_type == "mysql") || (db_type == "postgresql")) {
95 string with = (db_type == "postgresql" ? "pgsql" : db_type);
96 isc_throw(InvalidType, "The Kea server has not been compiled with "
97 "support for database type: " << db_type
98 << ". Did you forget to use --with-"
99 << with << " during compilation?");
100 }
101 // Get here on no match
102 LOG_ERROR(dhcpsrv_logger, DHCPSRV_UNKNOWN_DB).arg(parameters[type]);
103 isc_throw(InvalidType, "Database access parameter 'type' does "
104 "not specify a supported database backend: " << parameters[type]);
105 }
106
107 // Call the factory.
108 getLeaseMgrPtr() = index->second(parameters);
109
110 // Check the factory did not return null.
111 if (!getLeaseMgrPtr()) {
112 isc_throw(Unexpected, "Lease database " << db_type <<
113 " factory returned null");
114 }
115}
116
117void
119 // Destroy current lease manager. This is a no-op if no lease manager
120 // is available.
121 if (getLeaseMgrPtr()) {
123 .arg(getLeaseMgrPtr()->getType());
124 }
125 getLeaseMgrPtr().reset();
126 LeaseMgrFactory::deregisterFactory("memfile", true);
127 // Code will be moved to appropriate hook library.
128#ifdef HAVE_MYSQL
130#endif
131 // Code will be moved to appropriate hook library.
132#ifdef HAVE_PGSQL
133 LeaseMgrFactory::deregisterFactory("postgresql", true);
134#endif
135}
136
137void
138LeaseMgrFactory::recreate(const std::string& dbaccess, bool preserve_callbacks) {
140 // Preserve the callbacks if needed.
141 if (preserve_callbacks && haveInstance()) {
142 callbacks = instance().callbacks_;
143 }
144
145 // Re-create the manager.
146 destroy();
147 create(dbaccess);
148
149 if (callbacks) {
150 // Copy the callbacks to the new instance. It should be fast
151 // because we merely copy the pointer.
152 instance().callbacks_ = callbacks;
153 }
154}
155
156bool
158 return (!!getLeaseMgrPtr());
159}
160
163 TrackingLeaseMgr* lmptr = getLeaseMgrPtr().get();
164 if (!lmptr) {
165 isc_throw(NoLeaseManager, "no current lease manager is available");
166 }
167 return (*lmptr);
168}
169
170bool
172 const Factory& factory,
173 bool no_log) {
174 if (map_.count(db_type)) {
175 return (false);
176 }
177 map_.insert(pair<string, Factory>(db_type, factory));
178
179 // We are dealing here with static logger initialization fiasco.
180 // registerFactory may be called from constructors of static global
181 // objects for built in backends. The logging is not initialized yet,
182 // so the LOG_DEBUG would throw.
183 if (!no_log) {
185 .arg(db_type);
186 }
187 return (true);
188}
189
190bool
191LeaseMgrFactory::deregisterFactory(const string& db_type, bool no_log) {
192 auto index = map_.find(db_type);
193 if (index != map_.end()) {
194 map_.erase(index);
195 if (!no_log) {
198 .arg(db_type);
199 }
200 return (true);
201 } else {
202 return (false);
203 }
204}
205
206bool
207LeaseMgrFactory::registeredFactory(const std::string& db_type) {
208 auto index = map_.find(db_type);
209 return (index != map_.end());
210}
211
212void
214 std::stringstream txt;
215
216 for (auto const& x : map_) {
217 if (!txt.str().empty()) {
218 txt << " ";
219 }
220 txt << x.first;
221 }
222
224 .arg(txt.str());
225}
226
227} // namespace dhcp
228} // namespace isc
A generic exception that is thrown if a parameter given to a method or function is considered invalid...
A generic exception that is thrown when an unexpected error condition occurs.
static std::string redactedAccessString(const ParameterMap &parameters)
Redact database access string.
static ParameterMap parse(const std::string &dbaccess)
Parse database access string.
std::map< std::string, std::string > ParameterMap
Database configuration parameter map.
Invalid type exception.
static void create(const std::string &dbaccess)
Create an instance of a lease manager.
static TrackingLeaseMgr & instance()
Return current lease manager.
static void destroy()
Destroy lease manager.
static bool registeredFactory(const std::string &db_type)
Check if a lease mgr factory was registered.
static bool registerFactory(const std::string &db_type, const Factory &factory, bool no_log=false)
Register a lease mgr factory.
static bool haveInstance()
Indicates if the lease manager has been instantiated.
static bool deregisterFactory(const std::string &db_type, bool no_log=false)
Deregister a lease mgr factory.
static void logRegistered()
Logs out all registered backends.
static void recreate(const std::string &dbaccess, bool preserve_callbacks=true)
Recreate an instance of a lease manager with optionally preserving registered callbacks.
Concrete implementation of a lease database backend using flat file.
MySQL Lease Manager.
No lease manager exception.
PostgreSQL Lease Manager.
Introduces callbacks into the LeaseMgr.
boost::shared_ptr< CallbackContainer > CallbackContainerPtr
Pointer to the callback container.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Definition macros.h:32
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
Definition macros.h:20
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition macros.h:14
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
Definition dhcpsrv_log.h:56
const isc::log::MessageID DHCPSRV_LEASE_MGR_BACKENDS_REGISTERED
const isc::log::MessageID DHCPSRV_MEMFILE_DB
const isc::log::MessageID DHCPSRV_PGSQL_DB
const isc::log::MessageID DHCPSRV_LEASE_MGR_BACKEND_DEREGISTER
const isc::log::MessageID DHCPSRV_CLOSE_DB
const isc::log::MessageID DHCPSRV_UNKNOWN_DB
const isc::log::MessageID DHCPSRV_LEASE_MGR_BACKEND_REGISTER
const isc::log::MessageID DHCPSRV_NOTYPE_DB
std::unique_ptr< TrackingLeaseMgr > TrackingLeaseMgrPtr
TrackingLeaseMgr pointer.
const int DHCPSRV_DBG_TRACE
DHCP server library logging levels.
Definition dhcpsrv_log.h:26
const isc::log::MessageID DHCPSRV_MYSQL_DB
Defines the logger used by the top-level component of kea-lfc.