]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#3536] implement getDBVersion
authorRazvan Becheriu <razvan@isc.org>
Tue, 17 Sep 2024 20:43:15 +0000 (23:43 +0300)
committerRazvan Becheriu <razvan@isc.org>
Thu, 3 Oct 2024 18:04:37 +0000 (21:04 +0300)
24 files changed:
src/bin/dhcp4/main.cc
src/bin/dhcp4/tests/dhcp4_srv_unittest.cc
src/bin/dhcp6/main.cc
src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
src/bin/lfc/lfc_controller.cc
src/hooks/dhcp/mysql_hb/mysql_hb_callouts.cc
src/hooks/dhcp/mysql_hb/mysql_host_data_source.cc
src/hooks/dhcp/mysql_hb/mysql_host_data_source.h
src/hooks/dhcp/mysql_lb/mysql_lb_callouts.cc
src/hooks/dhcp/mysql_lb/mysql_lease_mgr.h
src/hooks/dhcp/pgsql_hb/pgsql_hb_callouts.cc
src/hooks/dhcp/pgsql_hb/pgsql_host_data_source.cc
src/hooks/dhcp/pgsql_hb/pgsql_host_data_source.h
src/hooks/dhcp/pgsql_lb/pgsql_lb_callouts.cc
src/hooks/dhcp/pgsql_lb/pgsql_lease_mgr.h
src/lib/dhcpsrv/host_data_source_factory.cc
src/lib/dhcpsrv/host_data_source_factory.h
src/lib/dhcpsrv/lease_mgr_factory.cc
src/lib/dhcpsrv/lease_mgr_factory.h
src/lib/dhcpsrv/memfile_lease_mgr.cc
src/lib/dhcpsrv/memfile_lease_mgr.h
src/lib/dhcpsrv/tests/host_data_source_factory_unittest.cc
src/lib/dhcpsrv/tests/lease_mgr_factory_unittest.cc
src/lib/dhcpsrv/tests/memfile_lease_mgr_unittest.cc

index 7979a0466642a0dc407c21b64659e50ee8540e96..7538b78f554b9a8d2055707d3fc5d23159010f91 100644 (file)
@@ -83,6 +83,9 @@ main(int argc, char* argv[]) {
     // The standard config file
     std::string config_file("");
 
+    // This is the DHCPv4 server
+    CfgMgr::instance().setFamily(AF_INET);
+
     while ((ch = getopt(argc, argv, "dvVWc:p:P:t:T:")) != -1) {
         switch (ch) {
         case 'd':
@@ -162,9 +165,6 @@ main(int argc, char* argv[]) {
         usage();
     }
 
-    // This is the DHCPv4 server
-    CfgMgr::instance().setFamily(AF_INET);
-
     if (check_mode) {
         try {
             // We need to initialize logging, in case any error messages are to be printed.
index 907e2ba5bcfe1288b178526520d700925c10c4d4..2a2c2b111e05f4e657ab2cbd80f3001b4ce7501f 100644 (file)
 
 #ifdef HAVE_MYSQL
 #include <mysql/testutils/mysql_schema.h>
+#include <hooks/dhcp/mysql_hb/mysql_host_data_source.h>
 #endif
 
 #ifdef HAVE_PGSQL
 #include <pgsql/testutils/pgsql_schema.h>
+#include <hooks/dhcp/pgsql_hb/pgsql_host_data_source.h>
 #endif
 
 #include <boost/scoped_ptr.hpp>
index fcfff7df53508669f7f3a87d1d5d0ab8e1106116..c2402ccec7e5cb4a67122bacead9f1a6b7980d25 100644 (file)
@@ -83,6 +83,9 @@ main(int argc, char* argv[]) {
     // The standard config file
     std::string config_file("");
 
+    // This is the DHCPv6 server
+    CfgMgr::instance().setFamily(AF_INET6);
+
     while ((ch = getopt(argc, argv, "dvVWc:p:P:t:T:")) != -1) {
         switch (ch) {
         case 'd':
@@ -162,9 +165,6 @@ main(int argc, char* argv[]) {
         usage();
     }
 
-    // This is the DHCPv6 server
-    CfgMgr::instance().setFamily(AF_INET6);
-
     if (check_mode) {
         try {
             // We need to initialize logging, in case any error messages are to be printed.
index b547b7082a64b46a85356062fd0c48407987ddb6..fc7fb7c1da2871ee927d8f1204afc6e15e740903 100644 (file)
 
 #ifdef HAVE_MYSQL
 #include <mysql/testutils/mysql_schema.h>
+#include <hooks/dhcp/mysql_hb/mysql_host_data_source.h>
 #endif
 
 #ifdef HAVE_PGSQL
 #include <pgsql/testutils/pgsql_schema.h>
+#include <hooks/dhcp/pgsql_hb/pgsql_host_data_source.h>
 #endif
 
 #include <boost/pointer_cast.hpp>
index 2a03e05d13e86c53bed4b8079739acd0cc2bd656..10d7a80cb5ee6ef3c2e28899e24d66e24680543b 100644 (file)
@@ -324,9 +324,9 @@ LFCController::getVersion(const bool extended) const{
     if (extended) {
         std::string db_version;
         if (protocol_version_ == 4) {
-            db_version = Memfile_LeaseMgr::getDBVersion(Memfile_LeaseMgr::V4);
+            db_version = Memfile_LeaseMgr::getDBVersionInternal(Memfile_LeaseMgr::V4);
         } else if (protocol_version_ == 6) {
-            db_version = Memfile_LeaseMgr::getDBVersion(Memfile_LeaseMgr::V6);
+            db_version = Memfile_LeaseMgr::getDBVersionInternal(Memfile_LeaseMgr::V6);
         }
 
         version_stream << " (" << EXTENDED_VERSION << ")";
index 0d0394f82b6b5e9220e7c521ff2fc1ab20b577f0..72394b19dfffb88a36e4ba895a37f2b68d897326 100644 (file)
@@ -52,7 +52,8 @@ int load(LibraryHandle& /* handle */) {
     }
 
     // Register MySQL HB factories with Host Managers
-    isc::dhcp::HostDataSourceFactory::registerFactory("mysql", MySqlHostDataSource::factory, true);
+    HostDataSourceFactory::registerFactory("mysql", MySqlHostDataSource::factory, true,
+                                           MySqlHostDataSource::getDBVersion);
 
     LOG_INFO(mysql_hb_logger, MYSQL_HB_INIT_OK);
     return (0);
@@ -63,7 +64,7 @@ int load(LibraryHandle& /* handle */) {
 /// @return 0 if deregistration was successful, 1 otherwise
 int unload() {
     // Unregister the factories and remove MySQL backends
-    isc::dhcp::HostDataSourceFactory::deregisterFactory("mysql", true);
+    HostDataSourceFactory::deregisterFactory("mysql", true);
 
     LOG_INFO(mysql_hb_logger, MYSQL_HB_DEINIT_OK);
     return (0);
index 3740044a624419d40a6f6976344daeb9cf748122..ac04d1fe2166ae3b9a01e12c5cad8b2d893276d9 100644 (file)
@@ -4217,5 +4217,14 @@ MySqlHostDataSource::factory(const isc::db::DatabaseConnection::ParameterMap& pa
     return (HostDataSourcePtr(new MySqlHostDataSource(parameters)));
 }
 
+std::string
+MySqlHostDataSource::getDBVersion() {
+    std::stringstream tmp;
+    tmp << "MySQL backend " << MYSQL_SCHEMA_VERSION_MAJOR;
+    tmp << "." << MYSQL_SCHEMA_VERSION_MINOR;
+    tmp << ", library " << mysql_get_client_info();
+    return (tmp.str());
+}
+
 }  // namespace dhcp
 }  // namespace isc
index 28f92c4b24521db54fbf46e58ab7f06044f08b6d..f32ed52d8414ffeea1d2993a3b4700bb717974ec 100644 (file)
@@ -540,17 +540,22 @@ public:
     /// @return The MySQL Host Manager.
     static HostDataSourcePtr
     factory(const isc::db::DatabaseConnection::ParameterMap& parameters);
+
+    /// @brief Local version of getDBVersion() class method
+    static std::string getDBVersion();
 };
 
+/// @brief Initialization structure used to register and deregister MySQL Host Mgr.
 struct MySqlHostDataSourceInit {
     // Constructor registers
     MySqlHostDataSourceInit() {
-        isc::dhcp::HostDataSourceFactory::registerFactory("mysql", MySqlHostDataSource::factory, true);
+        HostDataSourceFactory::registerFactory("mysql", MySqlHostDataSource::factory, true,
+                                               MySqlHostDataSource::getDBVersion);
     }
 
     // Destructor deregisters
     ~MySqlHostDataSourceInit() {
-        isc::dhcp::HostDataSourceFactory::deregisterFactory("mysql", true);
+        HostDataSourceFactory::deregisterFactory("mysql", true);
     }
 };
 
index 0d74d995a3fc397c2059226b72ad739e90c91400..97808d02066b919777c95f9103b019779d95f840 100644 (file)
@@ -52,7 +52,8 @@ int load(LibraryHandle& /* handle */) {
     }
 
     // Register MySQL LB factories with Lease Managers
-    LeaseMgrFactory::registerFactory("mysql", MySqlLeaseMgr::factory, true);
+    LeaseMgrFactory::registerFactory("mysql", MySqlLeaseMgr::factory, true,
+                                     MySqlLeaseMgr::getDBVersion);
 
     LOG_INFO(mysql_lb_logger, MYSQL_LB_INIT_OK);
     return (0);
index 1b44891ec6a3aa9d89b34a406104e7abba2a3b53..29791f188a7c0352e5cccd18e01f6ab0c62b4e0a 100644 (file)
@@ -1309,10 +1309,12 @@ public:
     factory(const isc::db::DatabaseConnection::ParameterMap& parameters);
 };
 
+/// @brief Initialization structure used to register and deregister MySQL Lease Mgr.
 struct MySqlLeaseMgrInit {
     // Constructor registers
     MySqlLeaseMgrInit() {
-        LeaseMgrFactory::registerFactory("mysql", MySqlLeaseMgr::factory, true);
+        LeaseMgrFactory::registerFactory("mysql", MySqlLeaseMgr::factory, true,
+                                         MySqlLeaseMgr::getDBVersion);
     }
 
     // Destructor deregisters
index 02158af4f955a39f2a5a3b48a14133cb19536898..8aa31e7b0a3ff3ff8c296d7c03044cfc80836454 100644 (file)
@@ -52,7 +52,8 @@ int load(LibraryHandle& /* handle */) {
     }
 
     // Register PgSQL HB factories with Host Managers
-    isc::dhcp::HostDataSourceFactory::registerFactory("postgresql", PgSqlHostDataSource::factory, true);
+    HostDataSourceFactory::registerFactory("postgresql", PgSqlHostDataSource::factory, true,
+                                           PgSqlHostDataSource::getDBVersion);
 
     LOG_INFO(pgsql_hb_logger, PGSQL_HB_INIT_OK);
     return (0);
@@ -63,7 +64,7 @@ int load(LibraryHandle& /* handle */) {
 /// @return 0 if deregistration was successful, 1 otherwise
 int unload() {
     // Unregister the factories and remove PgSQL backends
-    isc::dhcp::HostDataSourceFactory::deregisterFactory("postgresql", true);
+    HostDataSourceFactory::deregisterFactory("postgresql", true);
 
     LOG_INFO(pgsql_hb_logger, PGSQL_HB_DEINIT_OK);
     return (0);
index 4604d8f9ae09ff0ea9233c8c8a0f2a47adb9e5c0..efdf1eef50028e4c4e01c2225831c6c65ed38fde 100644 (file)
@@ -3382,5 +3382,14 @@ PgSqlHostDataSource::factory(const isc::db::DatabaseConnection::ParameterMap& pa
     return (HostDataSourcePtr(new PgSqlHostDataSource(parameters)));
 }
 
+std::string
+PgSqlHostDataSource::getDBVersion() {
+    std::stringstream tmp;
+    tmp << "PostgreSQL backend " << PGSQL_SCHEMA_VERSION_MAJOR;
+    tmp << "." << PGSQL_SCHEMA_VERSION_MINOR;
+    tmp << ", library " << PQlibVersion();
+    return (tmp.str());
+}
+
 }  // namespace dhcp
 }  // namespace isc
index a17306c6caea16b1e1763b6027ad9e23acae96a7..5ce41bf31f9f77cd4333bac3189ab74c98fb2f2e 100644 (file)
@@ -592,17 +592,22 @@ public:
     /// @return The PostgreSQL Host Manager.
     static HostDataSourcePtr
     factory(const isc::db::DatabaseConnection::ParameterMap& parameters);
+
+    /// @brief Local version of getDBVersion() class method
+    static std::string getDBVersion();
 };
 
+/// @brief Initialization structure used to register and deregister PostgreSQL Host Mgr.
 struct PgSqlHostDataSourceInit {
     // Constructor registers
     PgSqlHostDataSourceInit() {
-        isc::dhcp::HostDataSourceFactory::registerFactory("postgresql", PgSqlHostDataSource::factory, true);
+        HostDataSourceFactory::registerFactory("postgresql", PgSqlHostDataSource::factory, true,
+                                               PgSqlHostDataSource::getDBVersion);
     }
 
     // Destructor deregisters
     ~PgSqlHostDataSourceInit() {
-        isc::dhcp::HostDataSourceFactory::deregisterFactory("postgresql", true);
+        HostDataSourceFactory::deregisterFactory("postgresql", true);
     }
 };
 
index f1c3d2c5fdb8f118fe0f585114fa6aaab50475c2..7d299e698ef27d6874f78924778d559317e281ce 100644 (file)
@@ -52,7 +52,8 @@ int load(LibraryHandle& /* handle */) {
     }
 
     // Register PgSQL LB factories with Lease Managers
-    LeaseMgrFactory::registerFactory("postgresql", PgSqlLeaseMgr::factory, true);
+    LeaseMgrFactory::registerFactory("postgresql", PgSqlLeaseMgr::factory, true,
+                                     PgSqlLeaseMgr::getDBVersion);
 
     LOG_INFO(pgsql_lb_logger, PGSQL_LB_INIT_OK);
     return (0);
index adb8fe6bf7befac828da00f77a544074b48bb20e..1004c45a153b00b3a2ea72b6cebaf2e7e9b3663a 100644 (file)
@@ -1268,10 +1268,12 @@ public:
     factory(const isc::db::DatabaseConnection::ParameterMap& parameters);
 };
 
+/// @brief Initialization structure used to register and deregister PostgreSQL Lease Mgr.
 struct PgSqlLeaseMgrInit {
     // Constructor registers
     PgSqlLeaseMgrInit() {
-        LeaseMgrFactory::registerFactory("postgresql", PgSqlLeaseMgr::factory, true);
+        LeaseMgrFactory::registerFactory("postgresql", PgSqlLeaseMgr::factory, true,
+                                         PgSqlLeaseMgr::getDBVersion);
     }
 
     // Destructor deregisters
index 0a7c21b902197dc01b0a3c516ed593a530bb0946..ca7337292847da31a39abf7f37046c47b727b293 100644 (file)
@@ -26,7 +26,7 @@ using namespace std;
 namespace isc {
 namespace dhcp {
 
-map<string, HostDataSourceFactory::Factory> HostDataSourceFactory::map_;
+map<string, pair<HostDataSourceFactory::Factory, HostDataSourceFactory::DBVersion>> HostDataSourceFactory::map_;
 
 void
 HostDataSourceFactory::add(HostDataSourceList& sources,
@@ -51,14 +51,15 @@ HostDataSourceFactory::add(HostDataSourceList& sources,
             string with = (db_type == "postgresql" ? "pgsql" : db_type);
             isc_throw(InvalidType, "The type of host backend: '" << db_type
                       << "' is not compiled in. Did you forget to use --with-"
-                      << with << " during compilation?");
+                      << with << " during compilation or to load libdhcp_"
+                      << with << "_hb hook library?");
         }
         isc_throw(InvalidType, "The type of host backend: '" <<
                   db_type << "' is not supported");
     }
 
     // Call the factory and push the pointer on sources.
-    sources.push_back(index->second(parameters));
+    sources.push_back(index->second.first(parameters));
 
     // Check the factory did not return null.
     if (!sources.back()) {
@@ -114,11 +115,21 @@ HostDataSourceFactory::del(HostDataSourceList& sources,
 bool
 HostDataSourceFactory::registerFactory(const string& db_type,
                                        const Factory& factory,
-                                       bool no_log) {
+                                       bool no_log,
+                                       DBVersion db_version) {
     if (map_.count(db_type)) {
         return (false);
     }
-    map_.insert(pair<string, Factory>(db_type, factory));
+
+    static auto default_db_version = []() -> std::string {
+        return (std::string());
+    };
+
+    if (!db_version) {
+        db_version = default_db_version;
+    }
+
+    map_.insert(pair<string, pair<Factory, DBVersion>>(db_type, pair<Factory, DBVersion>(factory, db_version)));
 
     // We are dealing here with static logger initialization fiasco.
     // registerFactory may be called from constructors of static global
@@ -176,7 +187,7 @@ HostDataSourceFactory::getDBVersions() {
         if (!txt.str().empty()) {
             txt << " ";
         }
-        txt << x.first;
+        txt << x.second.second();
     }
 
     return (txt.str());
index 857c2b987b4c8417cff4a10da28c205b298cc36e..22609421e27677b3bcf6059838b0521cabe3bb79 100644 (file)
@@ -99,6 +99,9 @@ public:
     /// data source. In case of failure it must throw and not return null.
     typedef std::function<HostDataSourcePtr (const db::DatabaseConnection::ParameterMap&)> Factory;
 
+    /// @brief Type of host mgr version
+    typedef std::function<std::string ()> DBVersion;
+
     /// @brief Register a host data source factory
     ///
     /// Associate the factory to a database type in the map.
@@ -108,10 +111,13 @@ public:
     /// @param db_type database type
     /// @param factory host data source factory
     /// @param no_log do not log (default false)
+    /// @param db_version host mgr version
     /// @return true if the factory was successfully added to the map, false
     /// if it already exists.
     static bool registerFactory(const std::string& db_type,
-                                const Factory& factory, bool no_log = false);
+                                const Factory& factory,
+                                bool no_log = false,
+                                DBVersion db_version = DBVersion());
 
     /// @brief Deregister a host data source factory
     ///
@@ -143,7 +149,7 @@ public:
 
 private:
     /// @brief Factory map
-    static std::map<std::string, Factory> map_;
+    static std::map<std::string, std::pair<Factory, DBVersion>> map_;
 };
 
 } // end of isc::dhcp namespace
index b28afc7d4412030f49d3284c4dd05d8e54512bcf..fe6a3a94985cc15134ec38914910f09781ce5fc9 100644 (file)
@@ -24,7 +24,10 @@ using namespace std;
 namespace isc {
 namespace dhcp {
 
-map<string, LeaseMgrFactory::Factory> LeaseMgrFactory::map_;
+map<string, pair<LeaseMgrFactory::Factory, LeaseMgrFactory::DBVersion>> LeaseMgrFactory::map_;
+
+/// @brief Initializer.
+MemfileLeaseMgrInit memfile_init;
 
 TrackingLeaseMgrPtr&
 LeaseMgrFactory::getLeaseMgrPtr() {
@@ -48,14 +51,6 @@ LeaseMgrFactory::create(const std::string& dbaccess) {
                   "contain the 'type' keyword");
     }
 
-    // Factory method
-    auto memfile_factory = [](const DatabaseConnection::ParameterMap& parameters) -> TrackingLeaseMgrPtr {
-        LOG_INFO(dhcpsrv_logger, DHCPSRV_MEMFILE_DB)
-            .arg(DatabaseConnection::redactedAccessString(parameters));
-        return (TrackingLeaseMgrPtr(new Memfile_LeaseMgr(parameters)));
-    };
-    LeaseMgrFactory::registerFactory("memfile", memfile_factory, true);
-
     string db_type = it->second;
     auto index = map_.find(db_type);
 
@@ -67,7 +62,8 @@ LeaseMgrFactory::create(const std::string& dbaccess) {
             isc_throw(InvalidType, "The Kea server has not been compiled with "
                       "support for database type: " << db_type
                       << ". Did you forget to use --with-"
-                      << with << " during compilation?");
+                      << with << " during compilation or to load libdhcp_"
+                      << with << "_lb hook library?");
         }
         // Get here on no match
         LOG_ERROR(dhcpsrv_logger, DHCPSRV_UNKNOWN_DB).arg(parameters[type]);
@@ -76,7 +72,7 @@ LeaseMgrFactory::create(const std::string& dbaccess) {
     }
 
     // Call the factory.
-    getLeaseMgrPtr() = index->second(parameters);
+    getLeaseMgrPtr() = index->second.first(parameters);
 
     // Check the factory did not return null.
     if (!getLeaseMgrPtr()) {
@@ -94,7 +90,6 @@ LeaseMgrFactory::destroy() {
             .arg(getLeaseMgrPtr()->getType());
     }
     getLeaseMgrPtr().reset();
-    LeaseMgrFactory::deregisterFactory("memfile", true);
 }
 
 void
@@ -133,11 +128,21 @@ LeaseMgrFactory::instance() {
 bool
 LeaseMgrFactory::registerFactory(const string& db_type,
                                  const Factory& factory,
-                                 bool no_log) {
+                                 bool no_log,
+                                 DBVersion db_version) {
     if (map_.count(db_type)) {
         return (false);
     }
-    map_.insert(pair<string, Factory>(db_type, factory));
+
+    static auto default_db_version = []() -> std::string {
+        return (std::string());
+    };
+
+    if (!db_version) {
+        db_version = default_db_version;
+    }
+
+    map_.insert(pair<string, pair<Factory, DBVersion>>(db_type, pair<Factory, DBVersion>(factory, db_version)));
 
     // We are dealing here with static logger initialization fiasco.
     // registerFactory may be called from constructors of static global
@@ -195,7 +200,7 @@ LeaseMgrFactory::getDBVersions() {
         if (!txt.str().empty()) {
             txt << " ";
         }
-        txt << x.first;
+        txt << x.second.second();
     }
 
     return (txt.str());
index c4e829942652b770cb637497303120d3f29d5afd..fdf6934e2147d4750d0fd87aa93b40a88b22766c 100644 (file)
@@ -108,6 +108,9 @@ public:
     /// In case of failure it must throw and not return null.
     typedef std::function<TrackingLeaseMgrPtr (const db::DatabaseConnection::ParameterMap&)> Factory;
 
+    /// @brief Type of lease mgr version
+    typedef std::function<std::string ()> DBVersion;
+
     /// @brief Register a lease mgr factory
     ///
     /// Associate the factory to a database type in the map.
@@ -117,11 +120,13 @@ public:
     /// @param db_type database type
     /// @param factory lease mgr factory
     /// @param no_log do not log (default false)
+    /// @param db_version lease mgr version
     /// @return true if the factory was successfully added to the map, false
     /// if it already exists.
     static bool registerFactory(const std::string& db_type,
                                 const Factory& factory,
-                                bool no_log = false);
+                                bool no_log = false,
+                                DBVersion db_version = DBVersion());
 
     /// @brief Deregister a lease mgr factory
     ///
@@ -160,7 +165,7 @@ private:
     static TrackingLeaseMgrPtr& getLeaseMgrPtr();
 
     /// @brief Factory map
-    static std::map<std::string, Factory> map_;
+    static std::map<std::string, std::pair<Factory, DBVersion>> map_;
 };
 
 } // end of isc::dhcp namespace
index 6119999c62211cd73c58e79ecceb4a8446f45795..83542dc0ca6b7c1233a3268440e6d2ca721feb55 100644 (file)
@@ -1030,7 +1030,7 @@ Memfile_LeaseMgr::~Memfile_LeaseMgr() {
 }
 
 std::string
-Memfile_LeaseMgr::getDBVersion(Universe const& u) {
+Memfile_LeaseMgr::getDBVersionInternal(Universe const& u) {
     std::stringstream tmp;
     tmp << "Memfile backend ";
     if (u == V4) {
@@ -1045,9 +1045,9 @@ std::string
 Memfile_LeaseMgr::getDBVersion() {
     uint16_t family = CfgMgr::instance().getFamily();
     if (family == AF_INET6) {
-        return (Memfile_LeaseMgr::getDBVersion(Memfile_LeaseMgr::V6));
+        return (Memfile_LeaseMgr::getDBVersionInternal(Memfile_LeaseMgr::V6));
     } else {
-        return (Memfile_LeaseMgr::getDBVersion(Memfile_LeaseMgr::V4));
+        return (Memfile_LeaseMgr::getDBVersionInternal(Memfile_LeaseMgr::V4));
     }
 }
 
@@ -3459,5 +3459,12 @@ Memfile_LeaseMgr::writeLeases6Internal(const std::string& filename) {
     }
 }
 
+TrackingLeaseMgrPtr
+Memfile_LeaseMgr::factory(const isc::db::DatabaseConnection::ParameterMap& parameters) {
+    LOG_INFO(dhcpsrv_logger, DHCPSRV_MEMFILE_DB)
+        .arg(DatabaseConnection::redactedAccessString(parameters));
+    return (TrackingLeaseMgrPtr(new Memfile_LeaseMgr(parameters)));
+}
+
 }  // namespace dhcp
 }  // namespace isc
index 71229e7466e20189811aca6a009506744a9a9343..c283e6296ca3bffc91de2c8f3ae7276aa765407f 100644 (file)
@@ -13,6 +13,7 @@
 #include <dhcp/hwaddr.h>
 #include <dhcpsrv/csv_lease_file4.h>
 #include <dhcpsrv/csv_lease_file6.h>
+#include <dhcpsrv/lease_mgr_factory.h>
 #include <dhcpsrv/memfile_lease_limits.h>
 #include <dhcpsrv/memfile_lease_storage.h>
 #include <dhcpsrv/tracking_lease_mgr.h>
@@ -159,7 +160,7 @@ public:
     static std::string getDBVersion();
 
     /// @brief Local version of getDBVersion() class method
-    static std::string getDBVersion(Universe const& u);
+    static std::string getDBVersionInternal(Universe const& u);
 
     /// @brief Adds an IPv4 lease.
     ///
@@ -1562,6 +1563,30 @@ private:
     /// @param filename File name to write leases.
     /// Must be called from a thread-safe context.
     virtual void writeLeases6Internal(const std::string& filename);
+
+public:
+    /// @brief Factory class method.
+    ///
+    /// @param parameters A data structure relating keywords and values
+    ///        concerned with the database.
+    ///
+    /// @return The Memfile Lease Manager.
+    static TrackingLeaseMgrPtr
+    factory(const isc::db::DatabaseConnection::ParameterMap& parameters);
+};
+
+/// @brief Initialization structure used to register and deregister Memfile Lease Mgr.
+struct MemfileLeaseMgrInit {
+    // Constructor registers
+    MemfileLeaseMgrInit() {
+        LeaseMgrFactory::registerFactory("memfile", Memfile_LeaseMgr::factory, true,
+                                         Memfile_LeaseMgr::getDBVersion);
+    }
+
+    // Destructor deregisters
+    ~MemfileLeaseMgrInit() {
+        LeaseMgrFactory::deregisterFactory("memfile", true);
+    }
 };
 
 }  // namespace dhcp
index 22d65d4c583f3c1101623fa60f6f2838be9b7f5a..8de96723bf587bf14e9c1eccd627618f5478cc89 100644 (file)
@@ -25,7 +25,10 @@ namespace {
 
 // @brief Register memFactory 
 bool registerFactory() {
-    return (HostDataSourceFactory::registerFactory("mem", memFactory));
+    static auto db_version = []() -> std::string {
+        return (std::string("version 1"));
+    };
+    return (HostDataSourceFactory::registerFactory("mem", memFactory, false, db_version));
 }
 
 // @brief Derive mem1 class
@@ -63,7 +66,10 @@ mem2Factory(const DatabaseConnection::ParameterMap&) {
 
 // @brief Register mem2Factory
 bool registerFactory2() {
-    return (HostDataSourceFactory::registerFactory("mem2", mem2Factory));
+    static auto db_version = []() -> std::string {
+        return (std::string("version 2"));
+    };
+    return (HostDataSourceFactory::registerFactory("mem2", mem2Factory, false, db_version));
 }
 
 // @brief Factory function returning 0
@@ -187,6 +193,12 @@ TEST_F(HostDataSourceFactoryTest, multiple) {
     EXPECT_TRUE(registerFactory2());
     EXPECT_NO_THROW(HostDataSourceFactory::add(sources_, "type=mem2"));
 
+    EXPECT_EQ("version 2", HostDataSourceFactory::getDBVersions());
+
+    EXPECT_TRUE(registerFactory());
+
+    EXPECT_EQ("version 1  version 2", HostDataSourceFactory::getDBVersions());
+
     // Delete them
     EXPECT_TRUE(HostDataSourceFactory::del(sources_, "mem1"));
     EXPECT_TRUE(HostDataSourceFactory::del(sources_, "mem2"));
index f4741512f656afa90c6fff7df37648dfa5a97fc2..74e95b7dd9fdb3dbdb4e6aea682e0105b807b538 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <asiolink/io_address.h>
 #include <database/database_connection.h>
+#include <dhcpsrv/cfgmgr.h>
 #include <dhcpsrv/lease_mgr_factory.h>
 #include <dhcpsrv/memfile_lease_mgr.h>
 #include <dhcpsrv/tracking_lease_mgr.h>
@@ -40,7 +41,10 @@ memFactory(const DatabaseConnection::ParameterMap& parameters) {
 
 // @brief Register memFactory
 bool registerFactory() {
-    return (LeaseMgrFactory::registerFactory("mem", memFactory));
+    static auto db_version = []() -> std::string {
+        return (std::string("version 1"));
+    };
+    return (LeaseMgrFactory::registerFactory("mem", memFactory, false, db_version));
 }
 
 // @brief Derive mem1 class
@@ -86,7 +90,10 @@ mem2Factory(const DatabaseConnection::ParameterMap& parameters) {
 
 // @brief Register mem2Factory
 bool registerFactory2() {
-    return (LeaseMgrFactory::registerFactory("mem2", mem2Factory));
+    static auto db_version = []() -> std::string {
+        return (std::string("version 2"));
+    };
+    return (LeaseMgrFactory::registerFactory("mem2", mem2Factory, false, db_version));
 }
 
 // @brief Factory function returning 0
@@ -198,7 +205,8 @@ TEST_F(LeaseMgrFactoryTest, destroy) {
 }
 
 // Verify create and destroy class method on multiple backends
-TEST_F(LeaseMgrFactoryTest, multiple) {
+TEST_F(LeaseMgrFactoryTest, multipleV4) {
+    CfgMgr::instance().setFamily(AF_INET);
     // Add foo twice
     EXPECT_TRUE(registerFactory1());
     EXPECT_NO_THROW(LeaseMgrFactory::create("type=mem1 persist=false universe=4"));
@@ -212,6 +220,39 @@ TEST_F(LeaseMgrFactoryTest, multiple) {
     EXPECT_TRUE(LeaseMgrFactory::haveInstance());
     EXPECT_EQ(LeaseMgrFactory::instance().getType(), "mem2");
 
+    EXPECT_EQ("version 2 Memfile backend 3.0", LeaseMgrFactory::getDBVersions());
+
+    EXPECT_TRUE(registerFactory());
+
+    EXPECT_EQ("version 1  version 2 Memfile backend 3.0", LeaseMgrFactory::getDBVersions());
+
+    // Delete them
+    EXPECT_NO_THROW(LeaseMgrFactory::destroy());
+    EXPECT_FALSE(LeaseMgrFactory::haveInstance());
+}
+
+// Verify create and destroy class method on multiple backends
+TEST_F(LeaseMgrFactoryTest, multipleV6) {
+    CfgMgr::instance().setFamily(AF_INET6);
+    // Add foo twice
+    EXPECT_TRUE(registerFactory1());
+    EXPECT_NO_THROW(LeaseMgrFactory::create("type=mem1 persist=false universe=4"));
+    EXPECT_NO_THROW(LeaseMgrFactory::create("type=mem1 persist=false universe=6"));
+    EXPECT_TRUE(LeaseMgrFactory::haveInstance());
+    EXPECT_EQ(LeaseMgrFactory::instance().getType(), "mem1");
+
+    // Add mem2 once
+    EXPECT_TRUE(registerFactory2());
+    EXPECT_NO_THROW(LeaseMgrFactory::create("type=mem2 persist=false universe=6"));
+    EXPECT_TRUE(LeaseMgrFactory::haveInstance());
+    EXPECT_EQ(LeaseMgrFactory::instance().getType(), "mem2");
+
+    EXPECT_EQ("version 2 Memfile backend 5.0", LeaseMgrFactory::getDBVersions());
+
+    EXPECT_TRUE(registerFactory());
+
+    EXPECT_EQ("version 1  version 2 Memfile backend 5.0", LeaseMgrFactory::getDBVersions());
+
     // Delete them
     EXPECT_NO_THROW(LeaseMgrFactory::destroy());
     EXPECT_FALSE(LeaseMgrFactory::haveInstance());
index 9edf637dce4568e437c83dece380fa7ee3013a81..f22b5cdee009150b326bff573fcfed2a1b19db08 100644 (file)
@@ -2378,7 +2378,7 @@ TEST_F(MemfileLeaseMgrTest, checkVersion4) {
 
     // DBVersion too.
     EXPECT_EQ("Memfile backend " + s.str(),
-              lease_mgr->getDBVersion(Memfile_LeaseMgr::V4));
+              lease_mgr->getDBVersionInternal(Memfile_LeaseMgr::V4));
 }
 
 TEST_F(MemfileLeaseMgrTest, checkVersion6) {
@@ -2403,7 +2403,7 @@ TEST_F(MemfileLeaseMgrTest, checkVersion6) {
 
     // DBVersion too.
     EXPECT_EQ("Memfile backend " + s.str(),
-              lease_mgr->getDBVersion(Memfile_LeaseMgr::V6));
+              lease_mgr->getDBVersionInternal(Memfile_LeaseMgr::V6));
 }
 
 /// @brief Checks that complex user context can be read in v4.