1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
// Copyright (C) 2012-2024 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef LEASE_MGR_FACTORY_H
#define LEASE_MGR_FACTORY_H

#include <database/database_connection.h>
#include <dhcpsrv/tracking_lease_mgr.h>
#include <exceptions/exceptions.h>

#include <boost/scoped_ptr.hpp><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include <string><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.

namespace isc {
namespace dhcp {

/// @brief No lease manager exception
///
/// Thrown if an attempt is made to get a reference to the current lease
/// manager and none is currently available.
class NoLeaseManager : public Exception {
public:
    NoLeaseManager(const char* file, size_t line, const char* what) :
        isc::Exception(file, line, what) {}
};

/// @brief Lease Manager Factory
///
/// This class comprises nothing but static methods used to create a lease
/// manager.  It analyzes the database information passed to the creation
/// function and instantiates an appropriate lease manager based on the type
/// requested.
///
/// Strictly speaking these functions could be stand-alone functions.  However,
/// it is convenient to encapsulate them in a class for naming purposes.
///
/// @todo: Will need to develop some form of registration mechanism for
///        user-supplied backends (so that there is no need to modify the code).
class LeaseMgrFactory {
public:
    ~LeaseMgrFactory() {
        destroy();
    }

    /// @brief Create an instance of a lease manager.
    ///
    /// Each database backend has its own lease manager type.  This static
    /// method sets the "current" lease manager to be a manager of the
    /// appropriate type.  The actual lease manager is returned by the
    /// "instance" method.
    ///
    /// @note When called, the current lease manager is <b>always</b> destroyed
    ///       and a new one created - even if the parameters are the same.
    ///
    /// dbaccess is a generic way of passing parameters. Parameters are passed
    /// in the "name=value" format, separated by spaces.  The data MUST include
    /// a keyword/value pair of the form "type=dbtype" giving the database
    /// type, e.q. "mysql" or "sqlite3".
    ///
    /// @param dbaccess Database access parameters.  These are in the form of
    ///        "keyword=value" pairs, separated by spaces. They are backend-
    ///        -end specific, although must include the "type" keyword which
    ///        gives the backend in use.
    ///
    /// @throw isc::InvalidParameter dbaccess string does not contain the "type"
    ///        keyword.
    /// @throw isc::dhcp::InvalidType The "type" keyword in dbaccess does not
    ///        identify a supported backend.
    static void create(const std::string& dbaccess);

    /// @brief Destroy lease manager
    ///
    /// Destroys the current lease manager object.  This should have the effect
    /// of closing the database connection.  The method is a no-op if no
    /// lease manager is available.
    static void destroy();

    /// @brief Recreate an instance of a lease manager with optionally
    /// preserving registered callbacks.
    ///
    /// @param dbaccess Database access parameters.  These are in the form of
    ///        "keyword=value" pairs, separated by spaces. They are backend-
    ///        -end specific, although must include the "type" keyword which
    ///        gives the backend in use.
    /// @param preserve_callbacks a boolean flag indicating if all registered
    ///        @c TrackingLeaseMgr callbacks should be copied to the new
    ///        instance.
    static void recreate(const std::string& dbaccess,
                         bool preserve_callbacks = true);

    /// @brief Return current lease manager
    ///
    /// Returns an instance of the "current" lease manager.  An exception
    /// will be thrown if none is available.
    ///
    /// @throw isc::dhcp::NoLeaseManager No lease manager is available: use
    ///        create() to create one before calling this method.
    static TrackingLeaseMgr& instance();

    /// @brief Indicates if the lease manager has been instantiated.
    ///
    /// @return True if the lease manager instance exists, false otherwise.
    static bool haveInstance();

    /// @brief Type of lease mgr factory
    ///
    /// A factory takes a parameter map and returns a pointer to a lease mgr.
    /// 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.
    /// The no_log is to avoid logging before the logger is initialized
    /// as when called at global object initialization.
    ///
    /// @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,
                                DBVersion db_version = DBVersion());

    /// @brief Deregister a lease mgr factory
    ///
    /// Disassociate the factory to a database type in the map.
    /// The no_log is to avoid logging during global object deinitialization.
    ///
    /// @param db_type database type
    /// @param no_log do not log (default false)
    /// @return true if the factory was successfully removed from the map,
    /// false if it was not found.
    static bool deregisterFactory(const std::string& db_type,
                                  bool no_log = false);

    /// @brief Check if a lease mgr factory was registered
    ///
    /// @param db_type database type
    /// @return true if a factory was registered for db_type, false if not.
    static bool registeredFactory(const std::string& db_type);

    /// @brief Logs out all registered backends.
    ///
    /// We need a dedicated method for this, because we sometimes can't log
    /// the backend type when doing early initialization for backends
    /// initialized statically.
    static void logRegistered();

    /// @brief Return extended version info for registered backends.
    static std::list<std::string> getDBVersions();

private:
    /// @brief Hold pointer to lease manager
    ///
    /// Holds a pointer to the singleton lease manager.  The singleton
    /// is encapsulated in this method to avoid a "static initialization
    /// fiasco" if defined in an external static variable.
    static TrackingLeaseMgrPtr& getLeaseMgrPtr();

    /// @brief Factory map
    static std::map<std::string, std::pair<Factory, DBVersion>> map_;
};

} // end of isc::dhcp namespace
} // end of isc namespace

#endif // LEASE_MGR_FACTORY_H