Kea 2.7.6
host_data_source_factory.cc
Go to the documentation of this file.
1// Copyright (C) 2015-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
11#include <dhcpsrv/hosts_log.h>
12#include <log/logger_support.h>
13
14#include <boost/algorithm/string.hpp>
15
16#include <algorithm>
17#include <iostream>
18#include <iterator>
19#include <map>
20#include <sstream>
21#include <utility>
22
23using namespace isc::db;
24using namespace std;
25
26namespace isc {
27namespace dhcp {
28
29map<string, pair<HostDataSourceFactory::Factory, HostDataSourceFactory::DBVersion>> HostDataSourceFactory::map_;
30
31void
33 const string& dbaccess) {
34 // Parse the access string and create a redacted string for logging.
37
38 // Get the database type and open the corresponding database.
39 DatabaseConnection::ParameterMap::iterator it = parameters.find("type");
40 if (it == parameters.end()) {
41 isc_throw(InvalidParameter, "Host database configuration does not "
42 "contain the 'type' keyword");
43 }
44
45 string db_type = it->second;
46 auto index = map_.find(db_type);
47
48 // No match?
49 if (index == map_.end()) {
50 if ((db_type == "mysql") || (db_type == "postgresql")) {
51 string with = (db_type == "postgresql" ? "pgsql" : db_type);
52 isc_throw(InvalidType, "The Kea server has not been compiled with "
53 "support for host database type: " << db_type
54 << ". Did you forget to use --with-"
55 << with << " during compilation or to load libdhcp_"
56 << with << " hook library?");
57 }
58 isc_throw(InvalidType, "The type of host backend: '" <<
59 db_type << "' is not supported");
60 }
61
62 // Call the factory and push the pointer on sources.
63 sources.push_back(index->second.first(parameters));
64
65 // Check the factory did not return null.
66 if (!sources.back()) {
67 sources.pop_back();
68 isc_throw(Unexpected, "Hosts database " << db_type <<
69 " factory returned null");
70 }
71}
72
73bool
75 const string& db_type) {
76 for (auto it = sources.begin(); it != sources.end(); ++it) {
77 if ((*it)->getType() != db_type) {
78 continue;
79 }
81 .arg(db_type);
82 sources.erase(it);
83 return (true);
84 }
85 return (false);
86}
87
88bool
90 const string& db_type,
91 const string& dbaccess,
92 bool if_unusable) {
95 bool deleted = false;
96 if (if_unusable) {
97 deleted = true;
98 }
99
100 for (auto it = sources.begin(); it != sources.end(); ++it) {
101 if ((*it)->getType() != db_type || (*it)->getParameters() != parameters) {
102 continue;
103 }
104 if (if_unusable && (!(*it)->isUnusable())) {
105 deleted = false;
106 continue;
107 }
109 .arg((*it)->getType());
110 sources.erase(it);
111 return (true);
112 }
113 return (deleted);
114}
115
116bool
118 const Factory& factory,
119 bool no_log,
120 DBVersion db_version) {
121 if (map_.count(db_type)) {
122 return (false);
123 }
124
125 static auto default_db_version = []() -> std::string {
126 return (std::string());
127 };
128
129 if (!db_version) {
130 db_version = default_db_version;
131 }
132
133 map_.insert(pair<string, pair<Factory, DBVersion>>(db_type, pair<Factory, DBVersion>(factory, db_version)));
134
135 // We are dealing here with static logger initialization fiasco.
136 // registerFactory may be called from constructors of static global
137 // objects for built in backends. The logging is not initialized yet,
138 // so the LOG_DEBUG would throw.
139 if (!no_log) {
141 .arg(db_type);
142 }
143 return (true);
144}
145
146bool
147HostDataSourceFactory::deregisterFactory(const string& db_type, bool no_log) {
148 auto index = map_.find(db_type);
149 if (index != map_.end()) {
150 map_.erase(index);
151 if (!no_log) {
154 .arg(db_type);
155 }
156 return (true);
157 } else {
158 return (false);
159 }
160}
161
162bool
163HostDataSourceFactory::registeredFactory(const std::string& db_type) {
164 auto index = map_.find(db_type);
165 return (index != map_.end());
166}
167
168void
170 std::stringstream txt;
171
172 for (auto const& x : map_) {
173 if (!txt.str().empty()) {
174 txt << " ";
175 }
176 txt << x.first;
177 }
178
180 .arg(txt.str());
181}
182
183std::list<std::string>
185 std::list<std::string> result;
186 for (auto const& x : map_) {
187 auto version = x.second.second();
188 if (!version.empty()) {
189 result.push_back(version);
190 }
191 }
192
193 return (result);
194}
195
196} // namespace dhcp
197} // namespace isc
int version()
returns Kea hooks version.
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.
std::map< std::string, std::string > ParameterMap
Database configuration parameter map.
static ParameterMap parse(const std::string &dbaccess)
Parse database access string.
Invalid type exception.
static void logRegistered()
Logs out all registered backends.
std::function< HostDataSourcePtr(const db::DatabaseConnection::ParameterMap &)> Factory
Type of host data source factory.
static bool deregisterFactory(const std::string &db_type, bool no_log=false)
Deregister a host data source factory.
static void add(HostDataSourceList &sources, const std::string &dbaccess)
Create and add an instance of a host data source.
static bool registerFactory(const std::string &db_type, const Factory &factory, bool no_log=false, DBVersion db_version=DBVersion())
Register a host data source factory.
static std::list< std::string > getDBVersions()
Return extended version info for registered backends.
std::function< std::string()> DBVersion
Type of host mgr version.
static bool del(HostDataSourceList &sources, const std::string &db_type)
Delete a host data source.
static bool registeredFactory(const std::string &db_type)
Check if a host data source factory was registered.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Logging initialization functions.
#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 hosts_logger("hosts")
Logger for the HostMgr and the code it calls.
Definition hosts_log.h:51
const isc::log::MessageID HOSTS_BACKEND_DEREGISTER
std::vector< HostDataSourcePtr > HostDataSourceList
HostDataSource list.
const isc::log::MessageID HOSTS_CFG_CLOSE_HOST_DATA_SOURCE
const isc::log::MessageID HOSTS_BACKEND_REGISTER
const int DHCPSRV_DBG_TRACE
DHCP server library logging levels.
Definition dhcpsrv_log.h:26
const isc::log::MessageID HOSTS_BACKENDS_REGISTERED
Defines the logger used by the top-level component of kea-lfc.