2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-09-05 00:15:17 +00:00
Files
kea/src/lib/database/database_connection.h
2019-03-21 17:50:01 +02:00

250 lines
8.5 KiB
C++

// Copyright (C) 2015-2018 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 DATABASE_CONNECTION_H
#define DATABASE_CONNECTION_H
#include <cc/data.h>
#include <boost/noncopyable.hpp>
#include <boost/function.hpp>
#include <boost/shared_ptr.hpp>
#include <exceptions/exceptions.h>
#include <map>
#include <string>
namespace isc {
namespace db {
/// @brief Exception thrown if name of database is not specified
class NoDatabaseName : public Exception {
public:
NoDatabaseName(const char* file, size_t line, const char* what) :
isc::Exception(file, line, what) {}
};
/// @brief Exception thrown on failure to open database
class DbOpenError : public Exception {
public:
DbOpenError(const char* file, size_t line, const char* what) :
isc::Exception(file, line, what) {}
};
/// @brief Exception thrown on failure to execute a database function
class DbOperationError : public Exception {
public:
DbOperationError(const char* file, size_t line, const char* what) :
isc::Exception(file, line, what) {}
};
/// @brief Invalid type exception
///
/// Thrown when the factory doesn't recognize the type of the backend.
class InvalidType : public Exception {
public:
InvalidType(const char* file, size_t line, const char* what) :
isc::Exception(file, line, what) {}
};
/// @brief Invalid Timeout
///
/// Thrown when the timeout specified for the database connection is invalid.
class DbInvalidTimeout : public Exception {
public:
DbInvalidTimeout(const char* file, size_t line, const char* what) :
isc::Exception(file, line, what) {}
};
/// @brief Invalid 'readonly' value specification.
///
/// Thrown when the value of the 'readonly' boolean parameter is invalid.
class DbInvalidReadOnly : public Exception {
public:
DbInvalidReadOnly(const char* file, size_t line, const char* what) :
isc::Exception(file, line, what) {}
};
/// @brief Warehouses DB reconnect control values
///
/// When a DatabaseConnection loses connectivity to its backend, it
/// creates an instance of this class based on its configuration parameters and
/// passes the instance into connection's DB lost callback. This allows
/// the layer(s) above the connection to know how to proceed.
///
class ReconnectCtl {
public:
/// @brief Constructor
/// @param backend_type type of the caller backend.
/// @param max_retries maximum number of reconnect attempts to make
/// @param retry_interval amount of time to between reconnect attempts
ReconnectCtl(const std::string& backend_type, unsigned int max_retries,
unsigned int retry_interval)
: backend_type_(backend_type), max_retries_(max_retries),
retries_left_(max_retries), retry_interval_(retry_interval) {}
/// @brief Returns the type of the caller backend.
std::string backendType() const {
return (backend_type_);
}
/// @brief Decrements the number of retries remaining
///
/// Each call decrements the number of retries by one until zero is reached.
/// @return true the number of retries remaining is greater than zero.
bool checkRetries() {
return (retries_left_ ? --retries_left_ : false);
}
/// @brief Returns the maximum number of retries allowed.
unsigned int maxRetries() {
return (max_retries_);
}
/// @brief Returns the number for retries remaining
unsigned int retriesLeft() {
return (retries_left_);
}
/// @brief Returns the amount of time to wait between reconnect attempts
unsigned int retryInterval() {
return (retry_interval_);
}
private:
/// @brief Caller backend type.
const std::string backend_type_;
/// @brief Maximum number of retry attempts to make
unsigned int max_retries_;
/// @brief Number of attempts remaining
unsigned int retries_left_;
/// @brief The amount of time to wait between reconnect attempts
unsigned int retry_interval_;
};
/// @brief Pointer to an instance of ReconnectCtl
typedef boost::shared_ptr<ReconnectCtl> ReconnectCtlPtr;
/// @brief Common database connection class.
///
/// This class provides functions that are common for establishing
/// connection with different types of databases; enables operations
/// on access parameters strings. In particular, it provides a way
/// to parse parameters in key=value format. This class is expected
/// to be a base class for all @ref isc::dhcp::LeaseMgr and possibly
/// @ref isc::dhcp::BaseHostDataSource derived classes.
class DatabaseConnection : public boost::noncopyable {
public:
/// @brief Defines maximum value for time that can be reliably stored.
///
/// @todo: Is this common for MySQL and Postgres? Maybe we should have
/// specific values for each backend?
///
/// If I'm still alive I'll be too old to care. You fix it.
static const time_t MAX_DB_TIME;
/// @brief Database configuration parameter map
typedef std::map<std::string, std::string> ParameterMap;
/// @brief Constructor
///
/// @param parameters A data structure relating keywords and values
/// concerned with the database.
DatabaseConnection(const ParameterMap& parameters)
:parameters_(parameters) {
}
/// @brief Destructor
virtual ~DatabaseConnection(){};
/// @brief Instantiates a ReconnectCtl based on the connection's
/// reconnect parameters
/// @return pointer to the new ReconnectCtl object
virtual ReconnectCtlPtr makeReconnectCtl() const;
/// @brief Returns value of a connection parameter.
///
/// @param name Name of the parameter which value should be returned.
/// @return Value of one of the connection parameters.
/// @throw BadValue if parameter is not found
std::string getParameter(const std::string& name) const;
/// @brief Parse database access string
///
/// Parses the string of "keyword=value" pairs and separates them
/// out into the map.
///
/// @param dbaccess Database access string.
///
/// @return @ref ParameterMap of keyword/value pairs.
static ParameterMap parse(const std::string& dbaccess);
/// @brief Redact database access string
///
/// Takes the database parameters and returns a database access string
/// passwords replaced by asterisks. This string is used in log messages.
///
/// @param parameters Database access parameters (output of "parse").
///
/// @return Redacted database access string.
static std::string redactedAccessString(const ParameterMap& parameters);
/// @brief Convenience method checking if database should be opened with
/// read only access.
///
/// @return true if "readonly" parameter is specified and set to true;
/// false if "readonly" parameter is not specified or it is specified
/// and set to false.
bool configuredReadOnly() const;
/// @brief Defines a callback prototype for propogating events upward
typedef boost::function<bool (ReconnectCtlPtr db_retry)> DbLostCallback;
/// @brief Invokes the connection's lost connectivity callback
///
/// This function may be called by derivations when the connectivity
/// to their data server is lost. If connectivity callback was specified,
/// this function will instantiate a ReconnectCtl and pass it to the
/// callback.
///
/// @return Returns the result of the callback or false if there is no
/// callback.
bool invokeDbLostCallback() const;
/// @brief Unparse a parameter map
///
/// @param params the parameter map to unparse
/// @return a pointer to configuration
static isc::data::ElementPtr toElement(const ParameterMap& params);
/// @brief Unparse an access string
///
/// @param dbaccess the database access string
/// @return a pointer to configuration
static isc::data::ElementPtr toElementDbAccessString(const std::string& dbaccess);
/// @brief Optional call back function to invoke if a successfully
/// open connection subsequently fails
static DbLostCallback db_lost_callback;
private:
/// @brief List of parameters passed in dbconfig
///
/// That will be mostly used for storing database name, username,
/// password and other parameters required for DB access. It is not
/// intended to keep any DHCP-related parameters.
ParameterMap parameters_;
};
} // namespace db
} // namespace isc
#endif // DATABASE_CONNECTION_H