-// Copyright (C) 2016 Deutsche Telekom AG.
+// Copyright (C) 2016-2017 Deutsche Telekom AG.
//
// Author: Andrei Pavel <andrei.pavel@qualitance.com>
//
#include <config.h>
+#include <dhcpsrv/cql_host_data_source.h>
+
#include <dhcp/libdhcp++.h>
#include <dhcp/option.h>
#include <dhcp/option_definition.h>
#include <dhcpsrv/cfg_option.h>
#include <dhcpsrv/cfgmgr.h>
-#include <dhcpsrv/cql_host_data_source.h>
-#include <dhcpsrv/cql_lease_mgr.h>
+#include <dhcpsrv/cql_exchange.h>
#include <dhcpsrv/db_exceptions.h>
#include <dhcpsrv/dhcpsrv_log.h>
#include <util/buffer.h>
#include <util/optional_value.h>
-#include <boost/algorithm/string/classification.hpp>
-#include <boost/algorithm/string/split.hpp>
-#include <boost/tuple/tuple.hpp>
-#include <boost/unordered_map.hpp>
+#include <openssl/md5.h> // for MD5_DIGEST_LENGTH
+#include <stdint.h> // for uint64_t
-#include <openssl/md5.h>
+#include <boost/algorithm/string/classification.hpp> // for boost::is_any_of
+#include <boost/algorithm/string/split.hpp> // for split
+#include <boost/assert.hpp> // for BOOST_ASSERT
+#include <boost/unordered_map.hpp> // for std::unordered_map
-#include <list>
-#include <vector>
+#include <iosfwd> // for size_t, std::stringstream
+#include <memory> // for std::unique_ptr
+#include <string> // for std::string
-using namespace isc;
using namespace isc::asiolink;
using namespace isc::dhcp;
using namespace isc::util;
/// @brief Host identifier consisting of DUID or hardware address
typedef std::vector<uint8_t> HostIdentifier;
-/// @brief Host identifier converted to Cassandra data type
-typedef std::vector<cass_byte_t> CassHostIdentifier;
-
-/// @brief Host identifier converted to Cassandra data type
-typedef std::vector<cass_byte_t> CassOptionBuffer;
-
/// @brief key for HostMap containing objects which uniquely identify a
/// host: host identifier, host identifier type, subnets for IPv4 and IPv6
-typedef boost::tuple<HostIdentifier,
- Host::IdentifierType,
- SubnetID,
- SubnetID,
- asiolink::IOAddress>
- HostKey;
+/// and the IPv4 reservation
+typedef std::
+ tuple<HostIdentifier, Host::IdentifierType, SubnetID, SubnetID, IOAddress>
+ HostKey;
+
+enum HostKeyComponent {
+ HOST_IDENTIFIER,
+ HOST_IDENTIFIER_TYPE,
+ IPv4_SUBNET_ID,
+ IPv6_SUBNET_ID,
+ IPv4_RESERVATION
+};
/// @brief Map used to merge reservations and options into a single host on
/// retrieve from database
-typedef boost::unordered_map<HostKey, HostPtr, boost::hash<HostKey> > HostMap;
+typedef std::unordered_map<HostKey, HostPtr, boost::hash<HostKey>> HostMap;
+
+typedef std::pair<HostKey, HostPtr> HostPair;
+
+/// @brief Wrapper used to specify option space alongside option descriptor
+struct OptionWrapper {
+ OptionWrapper(OptionDescriptorPtr option_descriptor,
+ std::string option_space)
+ : option_descriptor_(option_descriptor), option_space_(option_space) {
+ }
+ OptionDescriptorPtr option_descriptor_;
+ std::string option_space_;
+};
/// @brief Maximum size of an IPv4 address represented as a text string. 12
/// digits plus 3 full stops (dots).
-static const size_t ADDRESS4_TEXT_MAX_LENGTH = 15U;
+static constexpr size_t ADDRESS4_TEXT_MAX_LENGTH = 15u;
/// @brief Maximum size of an IPv6 address represented as a text string. 32
/// hexadecimal characters written in 8 groups of four, plus 7 colon
/// separators.
-static const size_t ADDRESS6_TEXT_MAX_LENGTH = 39U;
+static constexpr size_t ADDRESS6_TEXT_MAX_LENGTH = 39u;
/// @brief Maximum length of classes stored in a host_ipv4/6_client_classes
/// column.
-static const size_t CLIENT_CLASSES_MAX_LENGTH = 255U;
+static constexpr size_t CLIENT_CLASSES_MAX_LENGTH = 255u;
/// @brief Maximum length of the hostname stored in DNS. This length is
/// restricted by the length of the domain-name carried in the Client FQDN
/// Option (see RFC4702 and RFC4704).
-static const size_t HOSTNAME_MAX_LENGTH = 255U;
+static constexpr size_t HOSTNAME_MAX_LENGTH = 255u;
/// @brief Maximum length of option value
-static const size_t OPTION_VALUE_MAX_LENGTH = 4096U;
+static constexpr size_t OPTION_VALUE_MAX_LENGTH = 4096u;
/// @brief Maximum length of option value specified in textual format
-static const size_t OPTION_FORMATTED_VALUE_MAX_LENGTH = 8192U;
+static constexpr size_t OPTION_FORMATTED_VALUE_MAX_LENGTH = 8192u;
/// @brief Maximum length of option space name
-static const size_t OPTION_SPACE_MAX_LENGTH = 128U;
+static constexpr size_t OPTION_SPACE_MAX_LENGTH = 128u;
/// @brief Numeric value representing the last supported identifier. This value
/// is used to validate whether the identifier type stored in a database is
/// within bounds of supported identifiers.
-static const cass_int8_t MAX_IDENTIFIER_TYPE =
- static_cast<cass_int8_t>(Host::IDENT_CIRCUIT_ID);
+static constexpr cass_int32_t MAX_IDENTIFIER_TYPE =
+ static_cast<cass_int32_t>(Host::IDENT_CIRCUIT_ID);
/// @{
/// @brief Invalid values in the Cassandra database
-static const char NULL_RESERVED_IPV6_PREFIX_ADDRESS[] = "";
-static const cass_int32_t NULL_RESERVED_IPV6_PREFIX_LENGTH = 0;
-static const cass_int32_t NULL_RESERVED_IPV6_PREFIX_ADDRESS_TYPE = -1;
-static const cass_int32_t NULL_IAID = -1;
-static const cass_int32_t NULL_OPTION_UNIVERSE = -1;
-static const cass_int32_t NULL_OPTION_CODE = -1;
-static const CassOptionBuffer NULL_OPTION_VALUE = CassOptionBuffer();
-static const char NULL_OPTION_FORMATTED_VALUE[] = "";
-static const char NULL_OPTION_SPACE[] = "";
-static const cass_bool_t NULL_OPTION_IS_PERSISTENT = cass_false;
-static const char NULL_OPTION_CLIENT_CLASS[] = "";
-static const cass_int32_t NULL_OPTION_SUBNET_ID = -1;
+static constexpr char NULL_RESERVED_IPV6_PREFIX_ADDRESS[] = "::";
+static constexpr cass_int32_t NULL_RESERVED_IPV6_PREFIX_LENGTH = 0;
+static constexpr cass_int32_t NULL_RESERVED_IPV6_PREFIX_ADDRESS_TYPE = -1;
+static constexpr cass_int32_t NULL_IAID = -1;
+static constexpr cass_int32_t NULL_OPTION_UNIVERSE = -1;
+static constexpr cass_int32_t NULL_OPTION_CODE = -1;
+static const CassBlob NULL_OPTION_VALUE = CassBlob();
+static constexpr char NULL_OPTION_FORMATTED_VALUE[] = "";
+static constexpr char NULL_OPTION_SPACE[] = "";
+static constexpr cass_bool_t NULL_OPTION_IS_PERSISTENT = cass_false;
+static constexpr char NULL_OPTION_CLIENT_CLASS[] = "";
+static constexpr cass_int32_t NULL_OPTION_SUBNET_ID = -1;
+// static constexpr CassCollection* NULL_COLLECTION = NULL;
/// @}
/// @brief Invalid reservation used to check for an invalid IPv6Resrv formed
static const IPv6Resrv NULL_IPV6_RESERVATION =
IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("::"), 128);
-} // anonymous namespace
+} // namespace
namespace isc {
namespace dhcp {
-/// @{
-/// @brief Statement parameters
-// INSERT_HOST
-static const char* INSERT_HOST_PARAMS[] = {
- static_cast<const char*>("id"),
- static_cast<const char*>("host_identifier"),
- static_cast<const char*>("host_identifier_type"),
- static_cast<const char*>("host_ipv4_subnet_id"),
- static_cast<const char*>("host_ipv6_subnet_id"),
- static_cast<const char*>("host_ipv4_address"),
- static_cast<const char*>("hostname"),
- static_cast<const char*>("host_ipv4_client_classes"),
- static_cast<const char*>("host_ipv6_client_classes"),
- static_cast<const char*>("reserved_ipv6_prefix_address"),
- static_cast<const char*>("reserved_ipv6_prefix_length"),
- static_cast<const char*>("reserved_ipv6_prefix_address_type"),
- static_cast<const char*>("iaid"),
- static_cast<const char*>("option_universe"),
- static_cast<const char*>("option_code"),
- static_cast<const char*>("option_value"),
- static_cast<const char*>("option_formatted_value"),
- static_cast<const char*>("option_space"),
- static_cast<const char*>("option_is_persistent"),
- static_cast<const char*>("option_client_class"),
- static_cast<const char*>("option_subnet_id"),
- NULL};
-// GET_HOST_BY_HOST_ID
-static const char* GET_HOST_BY_HOST_ID_PARAMS[] = {
- static_cast<const char*>("host_identifier"),
- static_cast<const char*>("host_identifier_type"),
- NULL};
-// GET_HOST_BY_IPV4_ADDRESS
-static const char* GET_HOST_BY_IPV4_ADDRESS_PARAMS[] = {
- static_cast<const char*>("host_ipv4_address"),
- NULL};
-// GET_HOST_BY_IPV4_SUBNET_ID_AND_HOST_ID
-static const char* GET_HOST_BY_IPV4_SUBNET_ID_AND_HOST_ID_PARAMS[] = {
- static_cast<const char*>("host_ipv4_subnet_id"),
- static_cast<const char*>("host_identifier"),
- static_cast<const char*>("host_identifier_type"),
- NULL};
-// GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID,
-static const char* GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID_PARAMS[] = {
- static_cast<const char*>("host_ipv6_subnet_id"),
- static_cast<const char*>("host_identifier"),
- static_cast<const char*>("host_identifier_type"),
- NULL};
-// GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS,
-static const char* GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS_PARAMS[] = {
- static_cast<const char*>("host_ipv4_subnet_id"),
- static_cast<const char*>("host_ipv4_address"),
- NULL};
-// GET_HOST_BY_IPV6_PREFIX
-static const char* GET_HOST_BY_IPV6_PREFIX_PARAMS[] = {
- static_cast<const char*>("reserved_ipv6_prefix_address"),
- static_cast<const char*>("reserved_ipv6_prefix_length"),
- NULL};
-// GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS
-static const char* GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS_PARAMS[] = {
- static_cast<const char*>("host_ipv6_subnet_id"),
- static_cast<const char*>("reserved_ipv6_prefix_address"),
- NULL};
-// GET_VERSION
-static const char* GET_VERSION_PARAMS[] = {NULL};
-/// @}
-
-/// @brief Prepared CQL statements used by the backend to insert and retrieve
-/// hosts from the database.
-static CqlTaggedStatement tagged_statements[] = {
- // INSERT_HOST
- {INSERT_HOST_PARAMS, "INSERT_HOST",
- "INSERT INTO host_reservations ( "
- "id, "
- "host_identifier, "
- "host_identifier_type, "
- "host_ipv4_subnet_id, "
- "host_ipv6_subnet_id, "
- "host_ipv4_address, "
- "hostname, "
- "host_ipv4_client_classes, "
- "host_ipv6_client_classes, "
- "reserved_ipv6_prefix_address, "
- "reserved_ipv6_prefix_length, "
- "reserved_ipv6_prefix_address_type, "
- "iaid, "
- "option_universe, "
- "option_code, "
- "option_value, "
- "option_formatted_value, "
- "option_space, "
- "option_is_persistent, "
- "option_client_class, "
- "option_subnet_id "
- ") "
- "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) "
- "IF NOT EXISTS "
- },
-
- // GET_HOST_BY_HOST_ID
- {GET_HOST_BY_HOST_ID_PARAMS, "GET_HOST_BY_HOST_ID",
- "SELECT "
- "id, "
- "host_identifier, "
- "host_identifier_type, "
- "host_ipv4_subnet_id, "
- "host_ipv6_subnet_id, "
- "host_ipv4_address, "
- "hostname, "
- "host_ipv4_client_classes, "
- "host_ipv6_client_classes, "
- "reserved_ipv6_prefix_address, "
- "reserved_ipv6_prefix_length, "
- "reserved_ipv6_prefix_address_type, "
- "iaid, "
- "option_universe, "
- "option_code, "
- "option_value, "
- "option_formatted_value, "
- "option_space, "
- "option_is_persistent, "
- "option_client_class, "
- "option_subnet_id "
- "FROM host_reservations "
- "WHERE host_identifier = ? "
- "AND host_identifier_type = ? "
- "ALLOW FILTERING "
- },
-
- // GET_HOST_BY_IPV4_ADDRESS
- {GET_HOST_BY_IPV4_ADDRESS_PARAMS, "GET_HOST_BY_IPV4_ADDRESS",
- "SELECT "
- "id, "
- "host_identifier, "
- "host_identifier_type, "
- "host_ipv4_subnet_id, "
- "host_ipv6_subnet_id, "
- "host_ipv4_address, "
- "hostname, "
- "host_ipv4_client_classes, "
- "host_ipv6_client_classes, "
- "reserved_ipv6_prefix_address, "
- "reserved_ipv6_prefix_length, "
- "reserved_ipv6_prefix_address_type, "
- "iaid, "
- "option_universe, "
- "option_code, "
- "option_value, "
- "option_formatted_value, "
- "option_space, "
- "option_is_persistent, "
- "option_client_class, "
- "option_subnet_id "
- "FROM host_reservations "
- "WHERE host_ipv4_address = ? "
- "ALLOW FILTERING "
- },
-
- // GET_HOST_BY_IPV4_SUBNET_ID_AND_HOST_ID
- {GET_HOST_BY_IPV4_SUBNET_ID_AND_HOST_ID_PARAMS,
- "GET_HOST_BY_IPV4_SUBNET_ID_AND_HOST_ID",
- "SELECT "
- "id, "
- "host_identifier, "
- "host_identifier_type, "
- "host_ipv4_subnet_id, "
- "host_ipv6_subnet_id, "
- "host_ipv4_address, "
- "hostname, "
- "host_ipv4_client_classes, "
- "host_ipv6_client_classes, "
- "reserved_ipv6_prefix_address, "
- "reserved_ipv6_prefix_length, "
- "reserved_ipv6_prefix_address_type, "
- "iaid, "
- "option_universe, "
- "option_code, "
- "option_value, "
- "option_formatted_value, "
- "option_space, "
- "option_is_persistent, "
- "option_client_class, "
- "option_subnet_id "
- "FROM host_reservations "
- "WHERE host_ipv4_subnet_id = ? "
- "AND host_identifier = ? "
- "AND host_identifier_type = ? "
- "ALLOW FILTERING "
- },
-
- // GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID
- {GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID_PARAMS,
- "GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID",
- "SELECT "
- "id, "
- "host_identifier, "
- "host_identifier_type, "
- "host_ipv4_subnet_id, "
- "host_ipv6_subnet_id, "
- "host_ipv4_address, "
- "hostname, "
- "host_ipv4_client_classes, "
- "host_ipv6_client_classes, "
- "reserved_ipv6_prefix_address, "
- "reserved_ipv6_prefix_length, "
- "reserved_ipv6_prefix_address_type, "
- "iaid, "
- "option_universe, "
- "option_code, "
- "option_value, "
- "option_formatted_value, "
- "option_space, "
- "option_is_persistent, "
- "option_client_class, "
- "option_subnet_id "
- "FROM host_reservations "
- "WHERE host_ipv6_subnet_id = ? "
- "AND host_identifier = ? "
- "AND host_identifier_type = ? "
- "ALLOW FILTERING "
- },
-
- // GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS
- {GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS_PARAMS,
- "GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS",
- "SELECT "
- "id, "
- "host_identifier, "
- "host_identifier_type, "
- "host_ipv4_subnet_id, "
- "host_ipv6_subnet_id, "
- "host_ipv4_address, "
- "hostname, "
- "host_ipv4_client_classes, "
- "host_ipv6_client_classes, "
- "reserved_ipv6_prefix_address, "
- "reserved_ipv6_prefix_length, "
- "reserved_ipv6_prefix_address_type, "
- "iaid, "
- "option_universe, "
- "option_code, "
- "option_value, "
- "option_formatted_value, "
- "option_space, "
- "option_is_persistent, "
- "option_client_class, "
- "option_subnet_id "
- "FROM host_reservations "
- "WHERE host_ipv4_subnet_id = ? "
- "AND host_ipv4_address = ? "
- "ALLOW FILTERING "
- },
-
- // GET_HOST_BY_IPV6_PREFIX
- {GET_HOST_BY_IPV6_PREFIX_PARAMS, "GET_HOST_BY_IPV6_PREFIX",
- "SELECT "
- "id, "
- "host_identifier, "
- "host_identifier_type, "
- "host_ipv4_subnet_id, "
- "host_ipv6_subnet_id, "
- "host_ipv4_address, "
- "hostname, "
- "host_ipv4_client_classes, "
- "host_ipv6_client_classes, "
- "reserved_ipv6_prefix_address, "
- "reserved_ipv6_prefix_length, "
- "reserved_ipv6_prefix_address_type, "
- "iaid, "
- "option_universe, "
- "option_code, "
- "option_value, "
- "option_formatted_value, "
- "option_space, "
- "option_is_persistent, "
- "option_client_class, "
- "option_subnet_id "
- "FROM host_reservations "
- "WHERE reserved_ipv6_prefix_address = ? "
- "AND reserved_ipv6_prefix_length = ? "
- "ALLOW FILTERING "
- },
-
- // GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS
- {GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS_PARAMS,
- "GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS",
- "SELECT "
- "id, "
- "host_identifier, "
- "host_identifier_type, "
- "host_ipv4_subnet_id, "
- "host_ipv6_subnet_id, "
- "host_ipv4_address, "
- "hostname, "
- "host_ipv4_client_classes, "
- "host_ipv6_client_classes, "
- "reserved_ipv6_prefix_address, "
- "reserved_ipv6_prefix_length, "
- "reserved_ipv6_prefix_address_type, "
- "iaid, "
- "option_universe, "
- "option_code, "
- "option_value, "
- "option_formatted_value, "
- "option_space, "
- "option_is_persistent, "
- "option_client_class, "
- "option_subnet_id "
- "FROM host_reservations "
- "WHERE host_ipv6_subnet_id = ? "
- "AND reserved_ipv6_prefix_address = ? "
- "ALLOW FILTERING "
- },
-
- // GET_VERSION
- {GET_VERSION_PARAMS, "GET_VERSION",
- "SELECT version, minor FROM schema_version"},
-
- // End of list sentinel
- {NULL, NULL, NULL}}; // tagged_statements
-
/// @brief Provides mechanisms for sending and retrieving data from the
/// host_reservations table.
class CqlHostExchange : public virtual CqlExchange {
public:
- /// @brief Statement Tags
- ///
- /// The contents of the enum are indexes into the list of CQL statements
- enum StatementIndex {
- // Inserts all options belonging to any reservation from a single host.
- INSERT_HOST,
- // Retrieves host information, IPv6 reservations and both IPv4 and IPv6
- // options associated with the host.
- GET_HOST_BY_HOST_ID,
- // Retrieves host information along with the IPv4 options associated
- // with it.
- GET_HOST_BY_IPV4_ADDRESS,
- // Retrieves host information and IPv4 options using subnet identifier
- // and client's identifier (i.e. hardware address or DUID).
- GET_HOST_BY_IPV4_SUBNET_ID_AND_HOST_ID,
- // Retrieves host information, IPv6 reservations and IPv6 options
- // associated with a host using subnet identifier and client's
- // identifier (i.e. hardware address or DUID).
- GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID,
- // Retrieves host information and IPv4 options for the host using subnet
- // identifier and IPv4 reservation.
- GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS,
- // Retrieves host information, IPv6 reservations and IPv6 options
- // associated with a host using prefix and prefix length. This query
- // returns host information for a single host. However, multiple rows
- // are returned due to left joining IPv6 reservations and IPv6 options.
- // The number of rows returned is multiplication of number of existing
- // IPv6 reservations and IPv6 options.
- GET_HOST_BY_IPV6_PREFIX,
- // Retrieves host information and IPv6 options for the host using subnet
- // identifier and IPv6 reservation.
- GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS,
- // Get CQL schema version.
- GET_VERSION,
- // Number of statements
- NUM_STATEMENTS
- };
-
/// @brief Constructor
///
/// Specifies table columns.
- CqlHostExchange();
+ CqlHostExchange(CqlConnection& connection);
/// @brief Virtual destructor.
virtual ~CqlHostExchange();
/// Creates a bind array to receive @ref Host data from the Cassandra
/// database. After data is successfully received, @ref retrieve() can be
/// called to retrieve the @ref Host object. Called in @ref
- /// CqlExchange::executeRead().
+ /// CqlExchange::executeSelect().
///
/// @param data array of objects representing data being retrieved
- /// @param statement_index prepared statement being executed; defaults to an
+ /// @param statement_tag prepared statement being executed; defaults to an
/// invalid statement
- virtual void createBindForReceive(CqlDataArray& data,
- const int statement_index = -1);
+ virtual void
+ createBindForSelect(AnyArray& data,
+ StatementTag statement_tag = NULL) override;
/// @brief Binds @ref Host to data array to send data to the Cassandra
/// database.
/// @param option_space option space
/// @param option_descriptor structure used to hold option information
/// @param data array being filled with data from to the Host object
- void createBindForSend(const HostPtr& host,
- const OptionalValue<SubnetID>& subnet_id,
- const IPv6Resrv* const reservation,
- const std::string& option_space,
- const OptionDescriptor& option_descriptor,
- CqlDataArray& data);
+ /// @param statement_tag tag of the statement being executed
+ void createBindForMutation(const HostPtr& host,
+ const OptionalValue<SubnetID>& subnet_id,
+ const IPv6Resrv* const reservation,
+ const std::string& option_space,
+ const OptionDescriptor& option_descriptor,
+ StatementTag statement_tag,
+ AnyArray& data);
/// @brief Create unique hash for storage in table id.
///
/// @brief Copy received data into Host object
///
/// Copies information about the host into a newly created @ref Host object
- /// Called in @ref executeRead after @ref createBindForReceive().
+ /// Called in @ref executeSelect after @ref createBindForSelect().
///
/// @return Host Pointer to a @ref HostPtr object holding a pointer to the
/// @ref Host object returned.
- virtual void* retrieve();
+ virtual boost::any retrieve() override;
/// @brief Creates IPv6 reservation from the data contained in the
- /// currently processed row.
+ /// currently processed row.
///
- /// Called after createBindForReceive().
+ /// Called after createBindForSelect().
///
/// @return IPv6Resrv object (containing IPv6 address or prefix reservation)
const IPv6Resrv retrieveReservation() const;
/// @brief Retrieves option from members.
- OptionDescriptorPtr retrieveOption() const;
+ ///
+ /// Called after createBindForSelect().
+ ///
+ /// @return OptionDescriptorPtr object (containing the option from the
+ /// database)
+ const OptionWrapper retrieveOption() const;
+
+ /// @brief Statement tags definitions
+ /// @{
+ // Inserts all options belonging to any reservation from a single host.
+ static constexpr StatementTag INSERT_HOST = "INSERT_HOST";
+
+ // Retrieves host information, IPv6 reservations and both IPv4 and IPv6
+ // options associated with the host.
+ static constexpr StatementTag GET_HOST_BY_HOST_ID = "GET_HOST_BY_HOST_ID";
+
+ // Retrieves host information along with the IPv4 options associated
+ // with it.
+ static constexpr StatementTag GET_HOST_BY_IPV4_ADDRESS =
+ "GET_HOST_BY_IPV4_ADDRESS";
+ // Retrieves host information and IPv4 options using subnet identifier
+ // and client's identifier (i.e. hardware address or DUID).
+ static constexpr StatementTag GET_HOST_BY_IPV4_SUBNET_ID_AND_HOST_ID =
+ "GET_HOST_BY_IPV4_SUBNET_ID_AND_HOST_ID";
+ // Retrieves host information; IPv6 reservations and IPv6 options
+ // associated with a host using subnet identifier and client's
+ // identifier (i.e. hardware address or DUID).
+ static constexpr StatementTag GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID =
+ "GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID";
+ // Retrieves host information and IPv4 options for the host using subnet
+ // identifier and IPv4 reservation.
+ static constexpr StatementTag GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS =
+ "GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS";
+ // Retrieves host information, IPv6 reservations and IPv6 options
+ // associated with a host using prefix and prefix length. This query
+ // returns host information for a single host. However, multiple rows
+ // are returned due to left joining IPv6 reservations and IPv6 options.
+ // The number of rows returned is multiplication of number of existing
+ // IPv6 reservations and IPv6 options.
+ static constexpr StatementTag GET_HOST_BY_IPV6_PREFIX =
+ "GET_HOST_BY_IPV6_PREFIX";
+ // Retrieves host information and IPv6 options for the host using subnet
+ // identifier and IPv6 reservation.
+ static constexpr StatementTag GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS =
+ "GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS";
+ /// @}
+
+ /// @brief Cassandra statements
+ static StatementMap tagged_statements_;
private:
/// Pointer to Host object holding information being inserted into database.
HostPtr host_;
+ /// @brief Connection to the Cassandra database
+ CqlConnection& connection_;
+
/// @brief Primary key. Aggregates: host_identifier, host_identifier_type,
/// reserved_ipv6_prefix_address, reserved_ipv6_prefix_length, option_code,
/// option_space.
cass_int64_t id_;
/// @brief Client's identifier (e.g. DUID, HW address) in binary format
- CassHostIdentifier host_identifier_;
+ CassBlob host_identifier_;
/// @brief Type of the identifier in the host_identifier_
/// This value corresponds to the @ref Host::IdentifierType value.
/// @brief IPv4 subnet identifier
cass_int32_t host_ipv4_subnet_id_;
- /// @brief Ipv6 subnet identifier
+ /// @brief IPv6 subnet identifier
cass_int32_t host_ipv6_subnet_id_;
/// @brief Reserved IPv4 address
cass_int32_t option_code_;
/// @brief Option value
- CassOptionBuffer option_value_;
+ CassBlob option_value_;
/// @brief The textual value of an option
std::string option_formatted_value_;
cass_int32_t option_subnet_id_;
}; // CqlHostExchange
-CqlHostExchange::CqlHostExchange()
- : host_identifier_type_(0), host_ipv4_subnet_id_(0),
- host_ipv6_subnet_id_(0), host_ipv4_address_(0),
- reserved_ipv6_prefix_length_(0), reserved_ipv6_prefix_address_type_(0),
- iaid_(0), option_universe_(0), option_code_(0),
- option_is_persistent_(cass_false), option_subnet_id_(0) {
- parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
- "id", parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT,
- EXCHANGE_DATA_TYPE_INT64)));
- parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
- "host_identifier", parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT,
- EXCHANGE_DATA_TYPE_BYTES)));
- parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
- "host_identifier_type", parameters_.size(),
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32)));
- parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
- "host_ipv4_subnet_id", parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT,
- EXCHANGE_DATA_TYPE_INT32)));
- parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
- "host_ipv6_subnet_id", parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT,
- EXCHANGE_DATA_TYPE_INT32)));
- parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
- "host_ipv4_address", parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT,
- EXCHANGE_DATA_TYPE_INT32)));
- parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
- "hostname", parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT,
- EXCHANGE_DATA_TYPE_STRING)));
- parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
- "host_ipv4_client_classes", parameters_.size(),
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_STRING)));
- parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
- "host_ipv6_client_classes", parameters_.size(),
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_STRING)));
- parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
- "reserved_ipv6_prefix_address", parameters_.size(),
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_STRING)));
- parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
- "reserved_ipv6_prefix_length", parameters_.size(),
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32)));
- parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
- "reserved_ipv6_prefix_address_type", parameters_.size(),
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32)));
- parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
- "iaid", parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT,
- EXCHANGE_DATA_TYPE_INT32)));
- parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
- "option_universe", parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT,
- EXCHANGE_DATA_TYPE_INT32)));
- parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
- "option_code", parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT,
- EXCHANGE_DATA_TYPE_INT32)));
- parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
- "option_value", parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT,
- EXCHANGE_DATA_TYPE_BYTES)));
- parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
- "option_formatted_value", parameters_.size(),
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_STRING)));
- parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
- "option_space", parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT,
- EXCHANGE_DATA_TYPE_STRING)));
- parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
- "option_is_persistent", parameters_.size(),
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_BOOL)));
- parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
- "option_client_class", parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT,
- EXCHANGE_DATA_TYPE_STRING)));
- parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
- "option_subnet_id", parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT,
- EXCHANGE_DATA_TYPE_INT32)));
- parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo(
- "[applied]", parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT,
- EXCHANGE_DATA_TYPE_BOOL)));
- BOOST_ASSERT(parameters_.size() == 22U);
+constexpr StatementTag CqlHostExchange::INSERT_HOST;
+constexpr StatementTag CqlHostExchange::GET_HOST_BY_HOST_ID;
+constexpr StatementTag CqlHostExchange::GET_HOST_BY_IPV4_ADDRESS;
+constexpr StatementTag CqlHostExchange::GET_HOST_BY_IPV4_SUBNET_ID_AND_HOST_ID;
+constexpr StatementTag CqlHostExchange::GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID;
+constexpr StatementTag CqlHostExchange::GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS;
+constexpr StatementTag CqlHostExchange::GET_HOST_BY_IPV6_PREFIX;
+constexpr StatementTag CqlHostExchange::GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS;
+
+StatementMap CqlHostExchange::tagged_statements_ = {
+ {INSERT_HOST, //
+ {INSERT_HOST, //
+ "INSERT INTO host_reservations ( "
+ "id, "
+ "host_identifier, "
+ "host_identifier_type, "
+ "host_ipv4_subnet_id, "
+ "host_ipv6_subnet_id, "
+ "host_ipv4_address, "
+ "hostname, "
+ "host_ipv4_client_classes, "
+ "host_ipv6_client_classes, "
+ "reserved_ipv6_prefix_address, "
+ "reserved_ipv6_prefix_length, "
+ "reserved_ipv6_prefix_address_type, "
+ "iaid, "
+ "option_universe, "
+ "option_code, "
+ "option_value, "
+ "option_formatted_value, "
+ "option_space, "
+ "option_is_persistent, "
+ "option_client_class, "
+ "option_subnet_id "
+ ") VALUES ( "
+ // id
+ "?, "
+ // host
+ "?, ?, ?, ?, ?, ?, ?, ?, "
+ // denormalized reservation, option
+ "?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? "
+ ") "
+ "IF NOT EXISTS "
+ }},
+
+ {GET_HOST_BY_HOST_ID, //
+ {GET_HOST_BY_HOST_ID, //
+ "SELECT "
+ "id, "
+ "host_identifier, "
+ "host_identifier_type, "
+ "host_ipv4_subnet_id, "
+ "host_ipv6_subnet_id, "
+ "host_ipv4_address, "
+ "hostname, "
+ "host_ipv4_client_classes, "
+ "host_ipv6_client_classes, "
+ "reserved_ipv6_prefix_address, "
+ "reserved_ipv6_prefix_length, "
+ "reserved_ipv6_prefix_address_type, "
+ "iaid, "
+ "option_universe, "
+ "option_code, "
+ "option_value, "
+ "option_formatted_value, "
+ "option_space, "
+ "option_is_persistent, "
+ "option_client_class, "
+ "option_subnet_id "
+ "FROM host_reservations "
+ "WHERE host_identifier = ? "
+ "AND host_identifier_type = ? "
+ "ALLOW FILTERING "
+ }},
+
+ {GET_HOST_BY_IPV4_ADDRESS, //
+ {GET_HOST_BY_IPV4_ADDRESS, //
+ "SELECT "
+ "id, "
+ "host_identifier, "
+ "host_identifier_type, "
+ "host_ipv4_subnet_id, "
+ "host_ipv6_subnet_id, "
+ "host_ipv4_address, "
+ "hostname, "
+ "host_ipv4_client_classes, "
+ "host_ipv6_client_classes, "
+ "reserved_ipv6_prefix_address, "
+ "reserved_ipv6_prefix_length, "
+ "reserved_ipv6_prefix_address_type, "
+ "iaid, "
+ "option_universe, "
+ "option_code, "
+ "option_value, "
+ "option_formatted_value, "
+ "option_space, "
+ "option_is_persistent, "
+ "option_client_class, "
+ "option_subnet_id "
+ "FROM host_reservations "
+ "WHERE host_ipv4_address = ? "
+ "ALLOW FILTERING "
+ }},
+
+ {GET_HOST_BY_IPV4_SUBNET_ID_AND_HOST_ID, //
+ {GET_HOST_BY_IPV4_SUBNET_ID_AND_HOST_ID, //
+ "SELECT "
+ "id, "
+ "host_identifier, "
+ "host_identifier_type, "
+ "host_ipv4_subnet_id, "
+ "host_ipv6_subnet_id, "
+ "host_ipv4_address, "
+ "hostname, "
+ "host_ipv4_client_classes, "
+ "host_ipv6_client_classes, "
+ "reserved_ipv6_prefix_address, "
+ "reserved_ipv6_prefix_length, "
+ "reserved_ipv6_prefix_address_type, "
+ "iaid, "
+ "option_universe, "
+ "option_code, "
+ "option_value, "
+ "option_formatted_value, "
+ "option_space, "
+ "option_is_persistent, "
+ "option_client_class, "
+ "option_subnet_id "
+ "FROM host_reservations "
+ "WHERE host_ipv4_subnet_id = ? "
+ "AND host_identifier = ? "
+ "AND host_identifier_type = ? "
+ "ALLOW FILTERING "
+ }},
+
+ {GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID, //
+ {GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID, //
+ "SELECT "
+ "id, "
+ "host_identifier, "
+ "host_identifier_type, "
+ "host_ipv4_subnet_id, "
+ "host_ipv6_subnet_id, "
+ "host_ipv4_address, "
+ "hostname, "
+ "host_ipv4_client_classes, "
+ "host_ipv6_client_classes, "
+ "reserved_ipv6_prefix_address, "
+ "reserved_ipv6_prefix_length, "
+ "reserved_ipv6_prefix_address_type, "
+ "iaid, "
+ "option_universe, "
+ "option_code, "
+ "option_value, "
+ "option_formatted_value, "
+ "option_space, "
+ "option_is_persistent, "
+ "option_client_class, "
+ "option_subnet_id "
+ "FROM host_reservations "
+ "WHERE host_ipv6_subnet_id = ? "
+ "AND host_identifier = ? "
+ "AND host_identifier_type = ? "
+ "ALLOW FILTERING "
+ }},
+
+ {GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS, //
+ {GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS, //
+ "SELECT "
+ "id, "
+ "host_identifier, "
+ "host_identifier_type, "
+ "host_ipv4_subnet_id, "
+ "host_ipv6_subnet_id, "
+ "host_ipv4_address, "
+ "hostname, "
+ "host_ipv4_client_classes, "
+ "host_ipv6_client_classes, "
+ "reserved_ipv6_prefix_address, "
+ "reserved_ipv6_prefix_length, "
+ "reserved_ipv6_prefix_address_type, "
+ "iaid, "
+ "option_universe, "
+ "option_code, "
+ "option_value, "
+ "option_formatted_value, "
+ "option_space, "
+ "option_is_persistent, "
+ "option_client_class, "
+ "option_subnet_id "
+ "FROM host_reservations "
+ "WHERE host_ipv4_subnet_id = ? "
+ "AND host_ipv4_address = ? "
+ "ALLOW FILTERING "
+ }},
+
+ {GET_HOST_BY_IPV6_PREFIX, //
+ {GET_HOST_BY_IPV6_PREFIX, //
+ "SELECT "
+ "id, "
+ "host_identifier, "
+ "host_identifier_type, "
+ "host_ipv4_subnet_id, "
+ "host_ipv6_subnet_id, "
+ "host_ipv4_address, "
+ "hostname, "
+ "host_ipv4_client_classes, "
+ "host_ipv6_client_classes, "
+ "reserved_ipv6_prefix_address, "
+ "reserved_ipv6_prefix_length, "
+ "reserved_ipv6_prefix_address_type, "
+ "iaid, "
+ "option_universe, "
+ "option_code, "
+ "option_value, "
+ "option_formatted_value, "
+ "option_space, "
+ "option_is_persistent, "
+ "option_client_class, "
+ "option_subnet_id "
+ "FROM host_reservations "
+ "WHERE reserved_ipv6_prefix_address = ? "
+ "AND reserved_ipv6_prefix_length = ? "
+ "ALLOW FILTERING "
+ }},
+
+ {GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS, //
+ {GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS, //
+ "SELECT "
+ "id, "
+ "host_identifier, "
+ "host_identifier_type, "
+ "host_ipv4_subnet_id, "
+ "host_ipv6_subnet_id, "
+ "host_ipv4_address, "
+ "hostname, "
+ "host_ipv4_client_classes, "
+ "host_ipv6_client_classes, "
+ "reserved_ipv6_prefix_address, "
+ "reserved_ipv6_prefix_length, "
+ "reserved_ipv6_prefix_address_type, "
+ "iaid, "
+ "option_universe, "
+ "option_code, "
+ "option_value, "
+ "option_formatted_value, "
+ "option_space, "
+ "option_is_persistent, "
+ "option_client_class, "
+ "option_subnet_id "
+ "FROM host_reservations "
+ "WHERE host_ipv6_subnet_id = ? "
+ "AND reserved_ipv6_prefix_address = ? "
+ "ALLOW FILTERING "
+ }},
+
+};
+
+CqlHostExchange::CqlHostExchange(CqlConnection& connection)
+ : host_(NULL), connection_(connection), id_(0), host_identifier_type_(0),
+ host_ipv4_subnet_id_(0), host_ipv6_subnet_id_(0), host_ipv4_address_(0),
+ reserved_ipv6_prefix_length_(NULL_RESERVED_IPV6_PREFIX_LENGTH),
+ reserved_ipv6_prefix_address_type_(
+ NULL_RESERVED_IPV6_PREFIX_ADDRESS_TYPE),
+ iaid_(NULL_IAID), option_universe_(NULL_OPTION_UNIVERSE),
+ option_code_(NULL_OPTION_CODE),
+ option_is_persistent_(NULL_OPTION_IS_PERSISTENT),
+ option_subnet_id_(NULL_OPTION_SUBNET_ID) {
}
CqlHostExchange::~CqlHostExchange() {
}
void
-CqlHostExchange::createBindForReceive(CqlDataArray& data,
- const int /* statement_index = -1 */) {
+CqlHostExchange::createBindForSelect(AnyArray& data,
+ StatementTag /* statement_tag = NULL */) {
// Start with a fresh array.
data.clear();
+
// id: blob
- data.add(reinterpret_cast<void*>(&id_));
+ data.add(&id_);
+
// host_identifier: blob
- data.add(reinterpret_cast<void*>(&host_identifier_));
+ data.add(&host_identifier_);
// host_identifier_type: int
- data.add(reinterpret_cast<void*>(&host_identifier_type_));
+ data.add(&host_identifier_type_);
// host_ipv4_subnet_id: int
- data.add(reinterpret_cast<void*>(&host_ipv4_subnet_id_));
+ data.add(&host_ipv4_subnet_id_);
// host_ipv6_subnet_id: int
- data.add(reinterpret_cast<void*>(&host_ipv6_subnet_id_));
+ data.add(&host_ipv6_subnet_id_);
// host_ipv4_address: int
- data.add(reinterpret_cast<void*>(&host_ipv4_address_));
+ data.add(&host_ipv4_address_);
// hostname: text
- data.add(reinterpret_cast<void*>(&hostname_));
+ data.add(&hostname_);
// host_ipv4_client_classes: text
- data.add(reinterpret_cast<void*>(&host_ipv4_client_classes_));
+ data.add(&host_ipv4_client_classes_);
// host_ipv6_client_classes: text
- data.add(reinterpret_cast<void*>(&host_ipv6_client_classes_));
+ data.add(&host_ipv6_client_classes_);
+ /// @brief Denormalized reservation columns
+ /// @{
// reserved_ipv6_prefix_address: text
- data.add(reinterpret_cast<void*>(&reserved_ipv6_prefix_address_));
- // reserved_ipv6_prefix_length: int
- data.add(reinterpret_cast<void*>(&reserved_ipv6_prefix_length_));
+ data.add(&reserved_ipv6_prefix_address_);
// reserved_ipv6_prefix_length: int
- data.add(reinterpret_cast<void*>(&reserved_ipv6_prefix_address_type_));
+ data.add(&reserved_ipv6_prefix_length_);
+ // reserved_ipv6_prefix_address_type: int
+ data.add(&reserved_ipv6_prefix_address_type_);
// iaid: int
- data.add(reinterpret_cast<void*>(&iaid_));
+ data.add(&iaid_);
+ /// @}
+
+ /// @brief Denormalized option columns
+ /// @{
// option_universe: int
- data.add(reinterpret_cast<void*>(&option_universe_));
+ data.add(&option_universe_);
// option_code: int
- data.add(reinterpret_cast<void*>(&option_code_));
+ data.add(&option_code_);
// option_value: blob
- data.add(reinterpret_cast<void*>(&option_value_));
+ data.add(&option_value_);
// option_formatted_value: text
- data.add(reinterpret_cast<void*>(&option_formatted_value_));
+ data.add(&option_formatted_value_);
// option_space: text
- data.add(reinterpret_cast<void*>(&option_space_));
+ data.add(&option_space_);
// option_is_persistent: boolean
- data.add(reinterpret_cast<void*>(&option_is_persistent_));
+ data.add(&option_is_persistent_);
// option_client_class: text
- data.add(reinterpret_cast<void*>(&option_client_class_));
+ data.add(&option_client_class_);
// option_subnet_id: int
- data.add(reinterpret_cast<void*>(&option_subnet_id_));
+ data.add(&option_subnet_id_);
+ /// @}
}
void
-CqlHostExchange::createBindForSend(const HostPtr& host,
- const OptionalValue<SubnetID>& subnet_id,
- const IPv6Resrv* const reservation,
- const std::string& option_space,
- const OptionDescriptor& option_descriptor,
- CqlDataArray& data) {
+CqlHostExchange::createBindForMutation(
+ const HostPtr& host,
+ const OptionalValue<SubnetID>& subnet_id,
+ const IPv6Resrv* const reservation,
+ const std::string& option_space,
+ const OptionDescriptor& option_descriptor,
+ StatementTag statement_tag,
+ AnyArray& data) {
// Store host object to ensure it remains valid.
host_ = host;
// structure.
try {
// host_identifier: blob
- // Convert from std::vector<uint8_t> to std::vector<cass_byte_t>.
+ // Convert from std::vector<uint8_t> to
+ // std::vector<cass_byte_t>.
HostIdentifier host_identifier = host->getIdentifier();
- host_identifier_ = CassHostIdentifier(host_identifier.begin(),
- host_identifier.end());
+ host_identifier_ =
+ CassBlob(host_identifier.begin(), host_identifier.end());
if (host_identifier_.size() > DUID::MAX_DUID_LEN) {
- isc_throw(BadValue, "host identifier "
- << host_identifier_.data() << " of length "
- << host_identifier_.size()
- << " is greater than allowed of "
- << DUID::MAX_DUID_LEN);
+ isc_throw(
+ BadValue,
+ "CqlHostExchange::createBindForMutation(): host identifier "
+ << host_identifier_.data() << " of length "
+ << host_identifier_.size() << " is greater than allowed of "
+ << DUID::MAX_DUID_LEN);
}
- // host_identifier_type: int
+ // host_identifier_type: tinyint
host_identifier_type_ =
static_cast<cass_int32_t>(host->getIdentifierType());
if (host_identifier_type_ > MAX_IDENTIFIER_TYPE) {
- isc_throw(BadValue, "invalid host identifier type returned: "
- << host_identifier_type_);
+ isc_throw(BadValue,
+ "CqlHostExchange::createBindForMutation(): invalid "
+ "host identifier type returned: "
+ << host_identifier_type_);
}
// host_ipv4_subnet_id: int
// hostname: text
hostname_ = host->getHostname();
if (hostname_.size() > HOSTNAME_MAX_LENGTH) {
- isc_throw(BadValue, "hostname " << hostname_ << " of length "
- << hostname_.size()
- << " is greater than allowed of "
- << HOSTNAME_MAX_LENGTH);
+ isc_throw(BadValue,
+ "CqlHostExchange::createBindForMutation(): hostname "
+ << hostname_ << " of length " << hostname_.size()
+ << " is greater than allowed of "
+ << HOSTNAME_MAX_LENGTH);
}
// host_ipv4_client_classes: text
host_ipv4_client_classes_ = host->getClientClasses4().toText(",");
if (host_ipv4_client_classes_.size() > CLIENT_CLASSES_MAX_LENGTH) {
- isc_throw(BadValue, "IPv4 client classes "
- << host_ipv4_client_classes_
- << " of length "
- << host_ipv4_client_classes_.size()
- << " is greater than allowed of "
- << CLIENT_CLASSES_MAX_LENGTH);
+ isc_throw(BadValue,
+ "CqlHostExchange::createBindForMutation(): "
+ "IPv4 client classes "
+ << host_ipv4_client_classes_ << " of length "
+ << host_ipv4_client_classes_.size()
+ << " is greater than allowed of "
+ << CLIENT_CLASSES_MAX_LENGTH);
}
// host_ipv6_client_classes: text
host_ipv6_client_classes_ = host->getClientClasses6().toText(",");
if (host_ipv6_client_classes_.size() > CLIENT_CLASSES_MAX_LENGTH) {
- isc_throw(BadValue, "IPv6 client classes "
- << host_ipv6_client_classes_
- << " of length "
- << host_ipv6_client_classes_.size()
- << " is greater than allowed of "
- << CLIENT_CLASSES_MAX_LENGTH);
+ isc_throw(BadValue,
+ "CqlHostExchange::createBindForMutation(): "
+ "IPv6 client classes "
+ << host_ipv6_client_classes_ << " of length "
+ << host_ipv6_client_classes_.size()
+ << " is greater than allowed of "
+ << CLIENT_CLASSES_MAX_LENGTH);
}
if (reservation == NULL) {
+ // reserved_ipv6_prefix_address: text
reserved_ipv6_prefix_address_ = NULL_RESERVED_IPV6_PREFIX_ADDRESS;
+ // reserved_ipv6_prefix_length: int
reserved_ipv6_prefix_length_ = NULL_RESERVED_IPV6_PREFIX_LENGTH;
+ // reserved_ipv6_prefix_address_type: int
reserved_ipv6_prefix_address_type_ =
NULL_RESERVED_IPV6_PREFIX_ADDRESS_TYPE;
iaid_ = NULL_IAID;
reserved_ipv6_prefix_length_ =
static_cast<cass_int32_t>(reservation->getPrefixLen());
- // reserved_ipv6_prefix_address: int
+ // reserved_ipv6_prefix_address_type: int
reserved_ipv6_prefix_address_type_ =
reservation->getType() == IPv6Resrv::TYPE_NA ? 0 : 2;
// Add all parameters to bind array.
data.clear();
- data.add(reinterpret_cast<void*>(&id_));
- data.add(reinterpret_cast<void*>(&host_identifier_));
- data.add(reinterpret_cast<void*>(&host_identifier_type_));
- data.add(reinterpret_cast<void*>(&host_ipv4_subnet_id_));
- data.add(reinterpret_cast<void*>(&host_ipv6_subnet_id_));
- data.add(reinterpret_cast<void*>(&host_ipv4_address_));
- data.add(reinterpret_cast<void*>(&hostname_));
- data.add(reinterpret_cast<void*>(&host_ipv4_client_classes_));
- data.add(reinterpret_cast<void*>(&host_ipv6_client_classes_));
- data.add(reinterpret_cast<void*>(&reserved_ipv6_prefix_address_));
- data.add(reinterpret_cast<void*>(&reserved_ipv6_prefix_length_));
- data.add(reinterpret_cast<void*>(&reserved_ipv6_prefix_address_type_));
- data.add(reinterpret_cast<void*>(&iaid_));
- data.add(reinterpret_cast<void*>(&option_universe_));
- data.add(reinterpret_cast<void*>(&option_code_));
- data.add(reinterpret_cast<void*>(&option_value_));
- data.add(reinterpret_cast<void*>(&option_formatted_value_));
- data.add(reinterpret_cast<void*>(&option_space_));
- data.add(reinterpret_cast<void*>(&option_is_persistent_));
- data.add(reinterpret_cast<void*>(&option_client_class_));
- data.add(reinterpret_cast<void*>(&option_subnet_id_));
- } catch (const std::exception& ex) {
- isc_throw(DbOperationError, "could not create bind array from host "
- << host->getHostname()
- << ", reason: " << ex.what());
+
+ if (statement_tag == CqlHostExchange::INSERT_HOST) {
+ data.add(&id_);
+ data.add(&host_identifier_);
+ data.add(&host_identifier_type_);
+ data.add(&host_ipv4_subnet_id_);
+ data.add(&host_ipv6_subnet_id_);
+ data.add(&host_ipv4_address_);
+ data.add(&hostname_);
+ data.add(&host_ipv4_client_classes_);
+ data.add(&host_ipv6_client_classes_);
+ }
+ // Reservation
+ data.add(&reserved_ipv6_prefix_address_);
+ data.add(&reserved_ipv6_prefix_length_);
+ data.add(&reserved_ipv6_prefix_address_type_);
+ data.add(&iaid_);
+
+ // Option
+ data.add(&option_universe_);
+ data.add(&option_code_);
+ data.add(&option_value_);
+ data.add(&option_formatted_value_);
+ data.add(&option_space_);
+ data.add(&option_is_persistent_);
+ data.add(&option_client_class_);
+ data.add(&option_subnet_id_);
+
+ } catch (const Exception& ex) {
+ isc_throw(DbOperationError,
+ "CqlHostExchange::createBindForMutation(): "
+ "could not create bind array from host "
+ << host->getHostname() << ", reason: " << ex.what());
}
}
// Get key.
std::stringstream key_stream;
- key_stream << std::setw(10) << std::setfill('0') << host_ipv4_subnet_id_;
- key_stream << std::setw(10) << std::setfill('0') << host_ipv6_subnet_id_;
- key_stream << std::setw(ADDRESS4_TEXT_MAX_LENGTH) << host_ipv4_address_;
- key_stream << std::setw(ADDRESS6_TEXT_MAX_LENGTH)
+ key_stream << std::setw(10) << std::setfill('-') << host_ipv4_subnet_id_;
+ key_stream << std::setw(10) << std::setfill('-') << host_ipv6_subnet_id_;
+ key_stream << std::setw(ADDRESS4_TEXT_MAX_LENGTH) << std::setfill('-')
+ << host_ipv4_address_;
+ key_stream << std::setw(ADDRESS6_TEXT_MAX_LENGTH) << std::setfill('-')
<< reserved_ipv6_prefix_address_;
- key_stream << std::setw(4) << std::setfill('0')
+ key_stream << std::setw(4) << std::setfill('-')
<< reserved_ipv6_prefix_length_;
- key_stream << std::setw(4) << std::setfill('0') << option_code_;
- key_stream << std::setw(OPTION_SPACE_MAX_LENGTH) << option_space_;
+ key_stream << std::setw(4) << std::setfill('-') << option_code_;
+ key_stream << std::setw(OPTION_SPACE_MAX_LENGTH) << std::setfill('-')
+ << option_space_;
const std::string key = key_stream.str();
- const uint64_t md5 = md5Hash(key);
+ const cass_int64_t md5 = static_cast<cass_int64_t>(md5Hash(key));
- return static_cast<cass_int64_t>(md5);
+ return md5;
}
-void*
+boost::any
CqlHostExchange::retrieve() {
- uint64_t id = static_cast<uint64_t>(id_);
+ const uint64_t id = static_cast<uint64_t>(id_);
HostIdentifier host_identifier =
HostIdentifier(host_identifier_.begin(), host_identifier_.end());
- // Set the host identifier type in a variable of the appropriate data type.
+ // Set the host identifier type in a variable of the appropriate
+ // data type.
Host::IdentifierType host_identifier_type =
static_cast<Host::IdentifierType>(host_identifier_type_);
// Set IPv4 address reservation.
asiolink::IOAddress ipv4_reservation =
- asiolink::IOAddress(host_ipv4_address_);
+ asiolink::IOAddress(static_cast<uint32_t>(host_ipv4_address_));
Host* host = new Host(host_identifier.data(), host_identifier.size(),
host_identifier_type, ipv4_subnet_id, ipv6_subnet_id,
host->addReservation(reservation);
}
- OptionDescriptorPtr option_descriptor_ptr = retrieveOption();
- if (option_descriptor_ptr) {
- if (option_descriptor_ptr->option_->getUniverse() == Option::V4) {
- host->getCfgOption4()->add(*option_descriptor_ptr, option_space_);
- } else if (option_descriptor_ptr->option_->getUniverse() ==
+ OptionWrapper option_wrapper = retrieveOption();
+ if (option_wrapper.option_descriptor_) {
+ if (option_wrapper.option_descriptor_->option_->getUniverse() ==
+ Option::V4) {
+ host->getCfgOption4()->add(*option_wrapper.option_descriptor_,
+ option_wrapper.option_space_);
+ } else if (option_wrapper.option_descriptor_->option_->getUniverse() ==
Option::V6) {
- host->getCfgOption6()->add(*option_descriptor_ptr, option_space_);
+ host->getCfgOption6()->add(*option_wrapper.option_descriptor_,
+ option_wrapper.option_space_);
}
}
- return reinterpret_cast<void*>(host);
+ return host;
}
const IPv6Resrv
CqlHostExchange::retrieveReservation() const {
- // Set the IPv6 Reservation type (0 = IA_NA, 2 = IA_PD)
+ // Set the IPv6 Reservation type (0 = IA_NA, 2 = IA_PD).
IPv6Resrv::Type type;
switch (reserved_ipv6_prefix_address_type_) {
case 0:
return NULL_IPV6_RESERVATION;
default:
isc_throw(BadValue,
- "invalid IPv6 reservation type returned: "
+ "CqlHostExchange::retrieveReservation(): invalid IPv6 "
+ "reservation type returned: "
<< reserved_ipv6_prefix_address_type_
<< ". Only 0 (IA_NA) or 2 (IA_PD) are allowed.");
}
reserved_ipv6_prefix_length_);
}
-OptionDescriptorPtr
+const OptionWrapper
CqlHostExchange::retrieveOption() const {
// Options are held in a binary or textual format in the database.
// This is similar to having an option specified in a server
// this is most likely a standard option, for which we have a
// definition created within libdhcp++.
if (option_space_.empty() || option_universe_ == NULL_OPTION_UNIVERSE) {
- return OptionDescriptorPtr();
+ return OptionWrapper(OptionDescriptorPtr(), "");
}
OptionDefinitionPtr option_definition_ptr =
static_cast<uint16_t>(option_code_),
option_buffer.begin(), option_buffer.end()));
} else {
- // The option value may be specified in textual or binary format in the
- // database. If formatted_value is empty, the binary format is used.
+ // The option value may be specified in textual or binary format
+ // in the
+ // database. If formatted_value is empty, the binary format is
+ // used.
// Depending on the format we use a different variant of @ref
// optionFactory().
if (option_formatted_value_.empty()) {
static_cast<uint16_t>(option_code_), option_buffer.begin(),
option_buffer.end());
} else {
- // Spit the value specified in comma separated values format.
+ // Spit the value specified in comma separated values
+ // format.
std::vector<std::string> split_vector;
boost::split(split_vector, option_formatted_value_,
boost::is_any_of(","));
}
}
- return OptionDescriptorPtr(new OptionDescriptor(
- option, option_is_persistent_, option_formatted_value_));
+ return OptionWrapper(
+ OptionDescriptorPtr(new OptionDescriptor(option, option_is_persistent_,
+ option_formatted_value_)),
+ option_space_);
}
/// @brief Implementation of the @ref CqlHostDataSource.
public:
/// @brief Constructor.
///
- /// This constructor opens database connection and initializes prepared
+ /// This constructor opens database connection and initializes
+ /// prepared
/// statements used in the queries.
explicit CqlHostDataSourceImpl(
const CqlConnection::ParameterMap& parameters);
virtual ~CqlHostDataSourceImpl();
/// @brief Implementation of @ref CqlHostDataSource::add()
+ ///
+ /// See @ref CqlHostDataSource::add() for parameter details.
+ ///
+ /// @param host
virtual void add(const HostPtr& host);
/// @brief Implementation of @ref CqlHostDataSource::get4()
+ ///
+ /// See @ref CqlHostDataSource::get4() for parameter details.
+ ///
+ /// @param subnet_id
+ /// @param address
virtual ConstHostPtr get4(const SubnetID& subnet_id,
const asiolink::IOAddress& address) const;
/// @brief Implementation of @ref CqlHostDataSource::get4()
+ ///
+ /// See @ref CqlHostDataSource::get4() for parameter details.
+ ///
+ /// @param subnet_id
+ /// @param hwaddr
+ /// @param duid
virtual ConstHostPtr get4(const SubnetID& subnet_id,
const HWAddrPtr& hwaddr,
const DuidPtr& duid = DuidPtr()) const;
/// @brief Implementation of @ref CqlHostDataSource::get4()
+ ///
+ /// See @ref CqlHostDataSource::get4() for parameter details.
+ ///
+ /// @param subnet_id
+ /// @param identifier_type
+ /// @param identifier_begin
+ /// @param identifier_len
virtual ConstHostPtr get4(const SubnetID& subnet_id,
const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin,
const size_t identifier_len) const;
/// @brief Implementation of @ref CqlHostDataSource::get6()
+ ///
+ /// See @ref CqlHostDataSource::get6() for parameter details.
+ ///
+ /// @param prefix
+ /// @param prefix_len
virtual ConstHostPtr get6(const asiolink::IOAddress& prefix,
const uint8_t prefix_len) const;
/// @brief Implementation of @ref CqlHostDataSource::get6()
+ ///
+ /// See @ref CqlHostDataSource::get6() for parameter details.
+ ///
+ /// @param subnet_id
+ /// @param duid
+ /// @param hwaddr
virtual ConstHostPtr get6(const SubnetID& subnet_id,
const DuidPtr& duid,
const HWAddrPtr& hwaddr = HWAddrPtr()) const;
/// @brief Implementation of @ref CqlHostDataSource::get6()
+ ///
+ /// See @ref CqlHostDataSource::get6() for parameter details.
+ ///
+ /// @param subnet_id
+ /// @param identifier_type
+ /// @param identifier_begin
+ /// @param identifier_len
virtual ConstHostPtr get6(const SubnetID& subnet_id,
const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin,
const size_t identifier_len) const;
/// @brief Implementation of @ref CqlHostDataSource::get6()
+ ///
+ /// See @ref CqlHostDataSource::get6() for parameter details.
+ ///
+ /// @param subnet_id
+ /// @param address
virtual ConstHostPtr get6(const SubnetID& subnet_id,
const asiolink::IOAddress& address) const;
- /// @brief Implementation of @ref CqlHostDataSource::getAll
+ /// @brief Implementation of @ref CqlHostDataSource::getAll()
+ ///
+ /// See @ref CqlHostDataSource::getAll() for parameter details.
+ ///
+ /// @param hwaddr
+ /// @param duid
virtual ConstHostCollection getAll(const HWAddrPtr& hwaddr,
const DuidPtr& duid = DuidPtr()) const;
/// @brief Implementation of @ref CqlHostDataSource::getAll()
+ ///
+ /// See @ref CqlHostDataSource::getAll() for parameter details.
+ ///
+ /// @param identifier_type
+ /// @param identifier_begin
+ /// @param identifier_len
virtual ConstHostCollection
getAll(const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin,
const size_t identifier_len) const;
/// @brief Implementation of @ref CqlHostDataSource::getAll4()
+ ///
+ /// See @ref CqlHostDataSource::getAll4() for parameter details.
+ ///
+ /// @param address
virtual ConstHostCollection
getAll4(const asiolink::IOAddress& address) const;
virtual void rollback();
protected:
- /// @brief Adds any options found in the @ref Host object to a separate
+ /// @brief Adds any options found in the @ref Host object to a
+ /// separate
/// table entry.
///
- /// @param host @ref Host object from which options are retrieved and
+ /// @param host @ref Host object from which options are retrieved
+ /// and
/// inserted into the Cassandra database
- /// @param reservation reservation for the current denormalized table entry
+ /// @param reservation reservation for the current denormalized
+ /// table entry
/// @param option_spaces list of option spaces to search for
- /// @param cfg_option option configuration used to match option spaces in
+ /// @param cfg_option option configuration used to match option
+ /// spaces in
/// order to obtain actual options
virtual void insertHostWithOptions(
const HostPtr& host,
const std::list<std::string>& option_spaces = std::list<std::string>(),
const ConstCfgOptionPtr cfg_option = ConstCfgOptionPtr());
- /// @brief Adds any reservations found in the @ref Host object to a separate
+ /// @brief Adds any reservations found in the @ref Host object to a
+ /// separate
/// table entry.
///
- /// @param host @ref Host object from which reservations are retrieved and
+ /// @param host @ref Host object from which reservations are
+ /// retrieved and
/// inserted into the Cassandra database
- /// @param reservation reservation for the current denormalized table entry
- /// @param option_spaces4 list of option spaces for universe Option::V4 to
+ /// @param reservation reservation for the current denormalized
+ /// table entry
+ /// @param option_spaces4 list of option spaces for universe
+ /// Option::V4 to
/// search in
- /// @param cfg_option4 option configuration for universe Option::V4 used to
+ /// @param cfg_option4 option configuration for universe Option::V4
+ /// used to
/// match option spaces in order to obtain actual options
- /// @param option_spaces6 list of option spaces for universe Option::V6 to
+ /// @param option_spaces6 list of option spaces for universe
+ /// Option::V6 to
/// search in
- /// @param cfg_option6 option configuration for universe Option::V6 used to
+ /// @param cfg_option6 option configuration for universe Option::V6
+ /// used to
/// match option spaces in order to obtain actual options
virtual void
insertHostWithReservations(const HostPtr& host,
/// @brief Retrieves a single host.
///
- /// Calls @ref getHostCollection() and checks if a single host was returned.
+ /// Calls @ref getHostCollection() and checks if a single host was
+ /// returned.
///
- /// @param where_values array of bound objects used to filter the results
- /// @param statement_index prepared statement being executed
+ /// @param where_values array of bound objects used to filter the
+ /// results
+ /// @param statement_tag prepared statement being executed
///
/// @return one host or a null pointer to a host
///
- /// @throw MultipleRecords exception if two or more hosts are returned
- virtual ConstHostPtr
- getHost(const CqlDataArray& where_values,
- const CqlHostExchange::StatementIndex statement_index) const;
+ /// @throw MultipleRecords exception if two or more hosts are
+ /// returned
+ virtual ConstHostPtr getHost(StatementTag statement_tag,
+ AnyArray& where_values) const;
/// @brief Retrieves a collection of hosts.
///
- /// Calls @ref CqlExchange::executeRead().
+ /// Calls @ref CqlExchange::executeSelect().
///
- /// @param where_values array of bound objects used to filter the results
- /// @param statement_index prepared statement being executed
+ /// @param where_values array of bound objects used to filter the
+ /// results
+ /// @param statement_tag prepared statement being executed
///
/// @return a collection of hosts containing one or more hosts
- virtual ConstHostCollection getHostCollection(
- const CqlDataArray& where_values,
- const CqlHostExchange::StatementIndex statement_index) const;
+ virtual ConstHostCollection getHostCollection(StatementTag statement_tag,
+ AnyArray& where_values) const;
/// @brief Inserts a single host.
///
/// All information is available here. Calls @ref
- /// CqlExchange::executeWrite().
+ /// CqlExchange::executeMutation().
///
- /// @param host @ref Host object from which options are retrieved and
+ /// @param host @ref Host object from which options are retrieved
+ /// and
/// inserted into the Cassandra database
- /// @param subnet_id identifier of the subnet to which the host belongs
- /// @param reservation reservation for the current denormalized table entry
- /// @param option_space option space for the current denormalized table
+ /// @param subnet_id identifier of the subnet to which the host
+ /// belongs
+ /// @param reservation reservation for the current denormalized
+ /// table entry
+ /// @param option_space option space for the current denormalized
+ /// table
/// entry's option
- /// @param option_descriptor option descriptor containing information for
- /// the current denormalized table entry's option
+ /// @param option_descriptor option descriptor containing
+ /// information for the current denormalized table entry's option
virtual void insertHost(
const HostPtr& host,
const OptionalValue<SubnetID>& subnet_id = OptionalValue<SubnetID>(),
const std::string& option_space = NULL_OPTION_SPACE,
const OptionDescriptor& option_descriptor = OptionDescriptor(false));
- /// @brief Merge denormalized table entries that belong to the same host
+ /// @brief Merge denormalized table entries that belong to the same
+ /// host
/// into a single host, one by one.
///
- /// @param target_host host which can contain multiple reservations and
- /// options to which other distinct reservations and options are added.
- /// @param source_host host that is being search for new reservations and
+ /// @param target_host host which can contain multiple reservations
+ /// and
+ /// options to which other distinct reservations and options are
+ /// added.
+ /// @param source_host host that is being search for new
+ /// reservations and
/// options that will be merged into the old host.
- virtual void mergeHosts(HostPtr& target_host,
- const ConstHostPtr& source_host) const;
+ virtual void mergeHosts(const ConstHostPtr& source_host,
+ HostPtr& target_host) const;
private:
- /// @brief pointer to the exchange responsible for trading host information
- boost::shared_ptr<CqlHostExchange> host_exchange_;
- /// @brief pointer to the exchange responsible for retrieving schema version
- boost::shared_ptr<CqlVersionExchange> version_exchange_;
-
/// @brief CQL connection
mutable CqlConnection dbconn_;
}; // class CqlHostDataSourceImpl
-
/// @brief hash function for HostMap
///
/// @param key being hashed
hash_value(const HostKey& key) {
// Get key.
std::stringstream key_stream;
- HostIdentifier host_identifier = key.get<0>();
+ HostIdentifier host_identifier = std::get<HOST_IDENTIFIER>(key);
key_stream << std::setw(DUID::MAX_DUID_LEN) << std::setfill('0')
<< DUID(host_identifier).toText();
- key_stream << std::setw(2) << std::setfill('0') << key.get<1>();
- key_stream << std::setw(10) << std::setfill('0') << key.get<2>();
- key_stream << std::setw(10) << std::setfill('0') << key.get<3>();
+ key_stream << std::setw(2) << std::setfill('0')
+ << std::get<HOST_IDENTIFIER_TYPE>(key);
+ key_stream << std::setw(10) << std::setfill('0')
+ << std::get<IPv4_SUBNET_ID>(key);
+ key_stream << std::setw(10) << std::setfill('0')
+ << std::get<IPv6_SUBNET_ID>(key);
key_stream << std::setw(ADDRESS4_TEXT_MAX_LENGTH) << std::setfill('0')
- << key.get<4>();
+ << std::get<IPv4_RESERVATION>(key);
const std::string key_string = key_stream.str();
const uint64_t md5 = md5Hash(key_string);
/// @return true if keys are equal. Deep comparison is made.
bool
operator==(const HostKey& key1, const HostKey& key2) {
- return key1.get<0>() == key2.get<0>() && key1.get<1>() == key2.get<1>() &&
- key1.get<2>() == key2.get<2>() && key1.get<3>() == key2.get<3>() &&
- key1.get<4>() == key2.get<4>();
+ return std::get<HOST_IDENTIFIER>(key1) == std::get<HOST_IDENTIFIER>(key2) &&
+ std::get<HOST_IDENTIFIER_TYPE>(key1) ==
+ std::get<HOST_IDENTIFIER_TYPE>(key2) &&
+ std::get<IPv4_SUBNET_ID>(key1) == std::get<IPv4_SUBNET_ID>(key2) &&
+ std::get<IPv6_SUBNET_ID>(key1) == std::get<IPv6_SUBNET_ID>(key2) &&
+ std::get<IPv4_RESERVATION>(key1) == std::get<IPv4_RESERVATION>(key2);
}
CqlHostDataSourceImpl::CqlHostDataSourceImpl(
const CqlConnection::ParameterMap& parameters)
- : host_exchange_(new CqlHostExchange()),
- version_exchange_(new CqlVersionExchange()), dbconn_(parameters) {
+ : dbconn_(parameters) {
// Open the database.
dbconn_.openDatabase();
+
// Prepare all possible statements.
- dbconn_.prepareStatements(tagged_statements);
+ dbconn_.prepareStatements(CqlHostExchange::tagged_statements_);
+ dbconn_.prepareStatements(CqlVersionExchange::tagged_statements_);
}
CqlHostDataSourceImpl::~CqlHostDataSourceImpl() {
void
CqlHostDataSourceImpl::add(const HostPtr& host) {
- // Start transaction.
- CqlTransaction transaction(dbconn_);
-
- // Get option space names and vendor space names and combine them within a
+ // Get option space names and vendor space names and combine them
+ // within a
// single list.
// For IPv4:
ConstCfgOptionPtr cfg_option4 = host->getCfgOption4();
option_spaces6.insert(option_spaces6.end(), vendor_spaces6.begin(),
vendor_spaces6.end());
- // For every IPv6 reservation, add each of their options to the database.
+ // For every IPv6 reservation, add each of their options to the
+ // database.
IPv6ResrvRange reservations = host->getIPv6Reservations();
if (std::distance(reservations.first, reservations.second) > 0) {
for (IPv6ResrvIterator it = reservations.first;
cfg_option6);
}
} else {
- // If host has no reservation, add entries with null reservation.
+ // If host has no reservation, add entries with null
+ // reservation.
// Options could still be present.
insertHostWithReservations(host, NULL, option_spaces4, cfg_option4,
option_spaces6, cfg_option6);
}
- transaction.commit();
}
ConstHostPtr
static_cast<cass_int32_t>(address.toUint32());
// Bind to array.
- CqlDataArray where_values;
- where_values.add(reinterpret_cast<void*>(&host_ipv4_subnet_id));
- where_values.add(reinterpret_cast<void*>(&host_ipv4_address));
+ AnyArray where_values;
+ where_values.add(&host_ipv4_subnet_id);
+ where_values.add(&host_ipv4_address);
+
// Run statement.
- return getHost(*const_cast<const CqlDataArray*>(&where_values),
- CqlHostExchange::GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS);
+ ConstHostPtr result = getHost(
+ CqlHostExchange::GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS, where_values);
+
+ return result;
}
ConstHostPtr
CqlHostDataSourceImpl::get4(const SubnetID& subnet_id,
const HWAddrPtr& hwaddr,
const DuidPtr& duid) const {
- /// @todo: Rethink the logic in BaseHostDataSource::get4(subnet, hwaddr,
+ /// @todo: Rethink the logic in BaseHostDataSource::get4(subnet,
+ /// hwaddr,
/// duid)
if (hwaddr && duid) {
isc_throw(BadValue, "CqlHostDataSource::get4(3) called with both "
isc_throw(BadValue, "CqlHostDataSource::get4(3) called with neither "
"hwaddr or duid specified, one of them is "
"required");
- } else if (duid) {
- HostIdentifier duid_vector = duid->getDuid();
- // Delegate to get4(4).
- return get4(subnet_id, Host::IDENT_DUID, duid_vector.data(),
- duid_vector.size());
+ }
+
+ const HostIdentifier* host_identifier;
+ Host::IdentifierType host_identifier_type;
+ if (duid) {
+ host_identifier = &duid->getDuid();
+ host_identifier_type = Host::IDENT_DUID;
} else if (hwaddr) {
- // Delegate to get4(4).
- return get4(subnet_id, Host::IDENT_HWADDR, hwaddr->hwaddr_.data(),
- hwaddr->hwaddr_.size());
+ host_identifier = &hwaddr->hwaddr_;
+ host_identifier_type = Host::IDENT_HWADDR;
+ } else {
+ return ConstHostPtr();
}
- return ConstHostPtr();
+
+ // Delegate to get4(4).
+ ConstHostPtr result =
+ get4(subnet_id, host_identifier_type, host_identifier->data(),
+ host_identifier->size());
+
+ return result;
}
ConstHostPtr
const uint8_t* identifier_begin,
const size_t identifier_len) const {
// Convert to CQL data types.
- cass_int32_t host_ipv4_subnet_id = static_cast<cass_int32_t>(subnet_id);
- CassHostIdentifier host_identifier(identifier_begin,
- identifier_begin + identifier_len);
+ CassBlob host_identifier(identifier_begin,
+ identifier_begin + identifier_len);
cass_int32_t host_identifier_type =
static_cast<cass_int32_t>(identifier_type);
+ cass_int32_t host_ipv4_subnet_id = static_cast<cass_int32_t>(subnet_id);
// Bind to array.
- CqlDataArray where_values;
- where_values.add(reinterpret_cast<void*>(&host_ipv4_subnet_id));
- where_values.add(reinterpret_cast<void*>(&host_identifier));
- where_values.add(reinterpret_cast<void*>(&host_identifier_type));
+ AnyArray where_values;
+ where_values.add(&host_ipv4_subnet_id);
+ where_values.add(&host_identifier);
+ where_values.add(&host_identifier_type);
+
// Run statement.
- return getHost(*const_cast<const CqlDataArray*>(&where_values),
- CqlHostExchange::GET_HOST_BY_IPV4_SUBNET_ID_AND_HOST_ID);
+ ConstHostPtr result = getHost(
+ CqlHostExchange::GET_HOST_BY_IPV4_SUBNET_ID_AND_HOST_ID, where_values);
+
+ return result;
}
ConstHostPtr
std::string reserved_ipv6_prefix_address = prefix.toText();
cass_int32_t reserved_ipv6_prefix_length = prefix_len;
+ ConstHostPtr host;
// Bind to array.
- CqlDataArray where_values;
- where_values.add(reinterpret_cast<void*>(&reserved_ipv6_prefix_address));
- where_values.add(reinterpret_cast<void*>(&reserved_ipv6_prefix_length));
+ AnyArray where_values;
+ where_values.add(&reserved_ipv6_prefix_address);
+ where_values.add(&reserved_ipv6_prefix_length);
+
// Get host id.
- ConstHostPtr host = getHost(*const_cast<const CqlDataArray*>(&where_values),
- CqlHostExchange::GET_HOST_BY_IPV6_PREFIX);
+ host = getHost(CqlHostExchange::GET_HOST_BY_IPV6_PREFIX, where_values);
if (host == ConstHostPtr()) {
return ConstHostPtr();
// Get host.
HostIdentifier host_identifier = host->getIdentifier();
+ // Delegate to getAll(3).
ConstHostCollection collection =
getAll(host->getIdentifierType(), host_identifier.data(),
host_identifier.size());
return ConstHostPtr();
}
- if (collection.size() >= 2U) {
- isc_throw(
- MultipleRecords,
- "CqlHostDataSource::get6(2): multiple records were found in the "
- "database where only one was expected for statement "
- << dbconn_
- .tagged_statements_[CqlHostExchange::GET_HOST_BY_HOST_ID]
- .name_);
+ if (collection.size() >= 2u) {
+ isc_throw(MultipleRecords,
+ "CqlHostDataSource::get6(2): multiple records were "
+ "found in the "
+ "database where only one was expected for statement "
+ << CqlHostExchange::GET_HOST_BY_IPV6_PREFIX);
}
- return *collection.begin();
+ ConstHostPtr result = *collection.begin();
+
+ return result;
}
ConstHostPtr
CqlHostDataSourceImpl::get6(const SubnetID& subnet_id,
const DuidPtr& duid,
const HWAddrPtr& hwaddr) const {
- /// @todo: Rethink the logic in BaseHostDataSource::get6(subnet, hwaddr,
+ /// @todo: Rethink the logic in BaseHostDataSource::get6(subnet,
+ /// hwaddr,
/// duid)
if (hwaddr && duid) {
isc_throw(BadValue, "CqlHostDataSource::get6(3): both hardware address "
} else if (!hwaddr && !duid) {
isc_throw(BadValue, "CqlHostDataSource::get6(3): both hardware address "
"and DUID are specified, one of them is required");
- } else if (duid) {
- HostIdentifier duid_vector = duid->getDuid();
- // Delegate to get6(4).
- return get6(subnet_id, Host::IDENT_DUID, duid_vector.data(),
- duid_vector.size());
+ }
+
+ const HostIdentifier* host_identifier;
+ Host::IdentifierType host_identifier_type;
+ if (duid) {
+ host_identifier = &duid->getDuid();
+ host_identifier_type = Host::IDENT_DUID;
} else if (hwaddr) {
- // Delegate to get6(4).
- return get6(subnet_id, Host::IDENT_HWADDR, hwaddr->hwaddr_.data(),
- hwaddr->hwaddr_.size());
+ host_identifier = &hwaddr->hwaddr_;
+ host_identifier_type = Host::IDENT_HWADDR;
+ } else {
+ return ConstHostPtr();
}
- return ConstHostPtr();
+
+ // Delegate to get6(4).
+ ConstHostPtr result =
+ get6(subnet_id, host_identifier_type, host_identifier->data(),
+ host_identifier->size());
+
+ return result;
}
ConstHostPtr
const size_t identifier_len) const {
// Convert to CQL data types.
cass_int32_t host_ipv6_subnet_id = static_cast<cass_int32_t>(subnet_id);
- CassHostIdentifier host_identifier(identifier_begin,
- identifier_begin + identifier_len);
+ CassBlob host_identifier(identifier_begin,
+ identifier_begin + identifier_len);
cass_int32_t host_identifier_type =
static_cast<cass_int32_t>(identifier_type);
// Bind to array.
- CqlDataArray where_values;
- where_values.add(reinterpret_cast<void*>(&host_ipv6_subnet_id));
- where_values.add(reinterpret_cast<void*>(&host_identifier));
- where_values.add(reinterpret_cast<void*>(&host_identifier_type));
+ AnyArray where_values;
+ where_values.add(&host_ipv6_subnet_id);
+ where_values.add(&host_identifier);
+ where_values.add(&host_identifier_type);
+
// Run statement.
- return getHost(*const_cast<const CqlDataArray*>(&where_values),
- CqlHostExchange::GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID);
+ ConstHostPtr result = getHost(
+ CqlHostExchange::GET_HOST_BY_IPV6_SUBNET_ID_AND_HOST_ID, where_values);
+
+ return result;
}
ConstHostPtr
std::string reserved_ipv6_prefix_address = address.toText();
// Bind to array.
- CqlDataArray where_values;
- where_values.add(reinterpret_cast<void*>(&host_ipv6_subnet_id));
- where_values.add(reinterpret_cast<void*>(&reserved_ipv6_prefix_address));
+ AnyArray where_values;
+ where_values.add(&host_ipv6_subnet_id);
+ where_values.add(&reserved_ipv6_prefix_address);
+
// Run statement.
- return getHost(*const_cast<const CqlDataArray*>(&where_values),
- CqlHostExchange::GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS);
+ ConstHostPtr result = getHost(
+ CqlHostExchange::GET_HOST_BY_IPV6_SUBNET_ID_AND_ADDRESS, where_values);
+
+ return result;
}
ConstHostCollection
}
// Convert to CQL data types.
- CassHostIdentifier host_identifier;
cass_int32_t host_identifier_type;
+ CassBlob host_identifier;
if (duid) {
HostIdentifier duid_vector = duid->getDuid();
- host_identifier =
- CassHostIdentifier(duid_vector.begin(), duid_vector.end());
+ host_identifier = CassBlob(duid_vector.begin(), duid_vector.end());
host_identifier_type = static_cast<cass_int32_t>(Host::IDENT_DUID);
} else if (hwaddr) {
- host_identifier = CassHostIdentifier(hwaddr->hwaddr_.begin(),
- hwaddr->hwaddr_.end());
+ host_identifier =
+ CassBlob(hwaddr->hwaddr_.begin(), hwaddr->hwaddr_.end());
host_identifier_type = static_cast<cass_int32_t>(Host::IDENT_HWADDR);
}
// Bind to array.
- CqlDataArray where_values;
- where_values.add(reinterpret_cast<void*>(&host_identifier));
- where_values.add(reinterpret_cast<void*>(&host_identifier_type));
+ AnyArray where_values;
+ where_values.add(&host_identifier);
+ where_values.add(&host_identifier_type);
+
// Run statement.
- return getHostCollection(*const_cast<const CqlDataArray*>(&where_values),
- CqlHostExchange::GET_HOST_BY_HOST_ID);
+ ConstHostCollection result =
+ getHostCollection(CqlHostExchange::GET_HOST_BY_HOST_ID, where_values);
+
+ return result;
}
ConstHostCollection
const uint8_t* identifier_begin,
const size_t identifier_len) const {
// Convert to CQL data types.
- CassHostIdentifier host_identifier(identifier_begin,
- identifier_begin + identifier_len);
+ CassBlob host_identifier(identifier_begin,
+ identifier_begin + identifier_len);
cass_int32_t host_identifier_type =
static_cast<cass_int32_t>(identifier_type);
// Bind to array.
- CqlDataArray where_values;
- where_values.add(reinterpret_cast<void*>(&host_identifier));
- where_values.add(reinterpret_cast<void*>(&host_identifier_type));
+ AnyArray where_values;
+ where_values.add(&host_identifier);
+ where_values.add(&host_identifier_type);
+
// Run statement.
- return getHostCollection(*const_cast<const CqlDataArray*>(&where_values),
- CqlHostExchange::GET_HOST_BY_HOST_ID);
+ ConstHostCollection result =
+ getHostCollection(CqlHostExchange::GET_HOST_BY_HOST_ID, where_values);
+
+ return result;
}
ConstHostCollection
static_cast<cass_int32_t>(address.toUint32());
// Bind to array.
- CqlDataArray where_values;
- where_values.add(reinterpret_cast<void*>(&host_ipv4_address));
+ AnyArray where_values;
+ where_values.add(&host_ipv4_address);
+
// Run statement.
- return getHostCollection(*const_cast<const CqlDataArray*>(&where_values),
- CqlHostExchange::GET_HOST_BY_IPV4_ADDRESS);
+ ConstHostCollection result = getHostCollection(
+ CqlHostExchange::GET_HOST_BY_IPV4_ADDRESS, where_values);
+
+ return result;
}
std::string
CqlHostDataSourceImpl::getName() const {
- std::string name = "";
+ std::string name = NULL;
try {
name = dbconn_.getParameter("name");
} catch (...) {
- // Return an empty name
+ // Return an empty name.
}
return name;
}
VersionPair
CqlHostDataSourceImpl::getVersion() const {
- return version_exchange_->retrieveVersion(dbconn_,
- CqlHostExchange::GET_VERSION);
+ std::unique_ptr<CqlVersionExchange> version_exchange(
+ new CqlVersionExchange());
+ return version_exchange->retrieveVersion(dbconn_);
}
void
const std::list<std::string>& option_spaces
/* = std::list<std::string>() */,
const ConstCfgOptionPtr cfg_option /* = ConstCfgOptionPtr() */) {
- // For each option space retrieve all options and insert them into the
- // database.
+ // For each option space retrieve all options and insert them into
+ // the database.
bool option_found = false;
- for (std::list<std::string>::const_iterator space = option_spaces.begin();
- space != option_spaces.end(); ++space) {
- OptionContainerPtr options = cfg_option->getAll(*space);
+ for (const std::string& space : option_spaces) {
+ OptionContainerPtr options = cfg_option->getAll(space);
if (options && !options->empty()) {
- for (OptionContainer::const_iterator option = options->begin();
- option != options->end(); ++option) {
+ for (const OptionDescriptor& option : *options) {
option_found = true;
- insertHost(host, OptionalValue<SubnetID>(), reservation, *space,
- *option);
+ // @todo: Assign actual value to subnet id.
+ insertHost(host, OptionalValue<SubnetID>(), reservation, space,
+ option);
}
}
}
if (!option_found) {
+ // @todo: Assign actual value to subnet id.
insertHost(host, OptionalValue<SubnetID>(), reservation);
}
}
}
ConstHostPtr
-CqlHostDataSourceImpl::getHost(
- const CqlDataArray& where_values,
- const CqlHostExchange::StatementIndex statement_index) const {
+CqlHostDataSourceImpl::getHost(StatementTag statement_tag,
+ AnyArray& where_values) const {
ConstHostCollection collection =
- getHostCollection(where_values, statement_index);
+ getHostCollection(statement_tag, where_values);
if (collection.empty()) {
return ConstHostPtr();
}
- if (collection.size() >= 2U) {
+ if (collection.size() >= 2u) {
isc_throw(MultipleRecords,
- "multiple records were found in the database where only one "
+ "CqlHostDataSourceImpl::getHost(): multiple records were "
+ "found in the database where only one "
"was expected for statement "
- << dbconn_.tagged_statements_[statement_index].name_);
+ << statement_tag);
}
return *collection.begin();
}
ConstHostCollection
-CqlHostDataSourceImpl::getHostCollection(
- const CqlDataArray& where_values,
- const CqlHostExchange::StatementIndex statement_index) const {
+CqlHostDataSourceImpl::getHostCollection(StatementTag statement_tag,
+ AnyArray& where_values) const {
// Run statement.
- CqlDataArray collection = host_exchange_->executeRead(
- dbconn_, where_values, statement_index, false);
+ std::unique_ptr<CqlHostExchange> host_exchange(
+ new CqlHostExchange(dbconn_));
+ AnyArray collection = host_exchange->executeSelect(dbconn_, where_values,
+ statement_tag, false);
// Form HostPtr objects.
HostCollection host_collection;
- for (std::vector<void*>::const_iterator it = collection.begin();
- it != collection.end(); ++it) {
- host_collection.push_back(HostPtr(reinterpret_cast<Host*>(*it)));
+ for (boost::any& host : collection) {
+ host_collection.push_back(HostPtr(boost::any_cast<Host*>(host)));
}
- // Merge the denormalized table entries that belong to the same host into a
+ // Merge the denormalized table entries that belong to the same host
+ // into a
// single host.
HostMap map;
- for (HostCollection::iterator it = host_collection.begin();
- it != host_collection.end(); ++it) {
- HostKey key =
- HostKey((*it)->getIdentifier(), (*it)->getIdentifierType(),
- (*it)->getIPv4SubnetID(), (*it)->getIPv6SubnetID(),
- (*it)->getIPv4Reservation());
+ for (HostPtr& host : host_collection) {
+
+ HostKey key = HostKey(host->getIdentifier(), host->getIdentifierType(),
+ host->getIPv4SubnetID(), host->getIPv6SubnetID(),
+ host->getIPv4Reservation());
if (map.find(key) == map.end()) {
- map[key] = *it;
+ map[key] = host;
} else {
- mergeHosts(map[key], *it);
+ mergeHosts(host, map[key]);
}
}
ConstHostCollection result_collection;
- for (HostMap::const_iterator it = map.begin(); it != map.end(); ++it) {
- result_collection.push_back(it->second);
+ for (HostPair pair : map) {
+ result_collection.push_back(pair.second);
}
return result_collection;
}
void
CqlHostDataSourceImpl::insertHost(
const HostPtr& host,
- const OptionalValue<SubnetID>& subnet_id
- /* = OptionalValue<SubnetID>() */,
+ const OptionalValue<SubnetID>& subnet_id /* = OptionalValue<SubnetID>() */,
const IPv6Resrv* const reservation /* = NULL */,
const std::string& option_space /* = NULL_OPTION_SPACE */,
- const OptionDescriptor& option_descriptor
- /* = OptionDescriptorPtr */) {
- CqlDataArray assigned_values;
- // @todo: Assign actual value to subnet id.
- host_exchange_->createBindForSend(host, subnet_id, reservation,
- option_space, option_descriptor,
- assigned_values);
- host_exchange_->executeWrite(dbconn_, assigned_values,
- CqlHostExchange::INSERT_HOST);
+ const OptionDescriptor& option_descriptor /* = OptionDescriptorPtr */) {
+ AnyArray assigned_values;
+
+ std::unique_ptr<CqlHostExchange> host_exchange(
+ new CqlHostExchange(dbconn_));
+
+ try {
+ host_exchange->createBindForMutation(
+ host, subnet_id, reservation, option_space, option_descriptor,
+ CqlHostExchange::INSERT_HOST, assigned_values);
+
+
+ host_exchange->executeMutation(dbconn_, assigned_values,
+ CqlHostExchange::INSERT_HOST);
+ } catch (const StatementNotApplied& exception) {
+ isc_throw(DuplicateEntry, exception.what());
+ }
}
void
-CqlHostDataSourceImpl::mergeHosts(HostPtr& target_host,
- const ConstHostPtr& source_host) const {
+CqlHostDataSourceImpl::mergeHosts(const ConstHostPtr& source_host,
+ HostPtr& target_host) const {
// Merge reservations.
const IPv6ResrvRange reservations_range =
source_host->getIPv6Reservations();
return impl_->get6(subnet_id, address);
}
+bool
+CqlHostDataSource::del(const SubnetID& subnet_id,
+ const asiolink::IOAddress& addr) {
+ (void)subnet_id;
+ (void)addr;
+ isc_throw(NotImplemented, "CqlHostDataSource::del NotImplemented");
+}
+
+bool
+CqlHostDataSource::del4(const SubnetID& subnet_id,
+ const Host::IdentifierType& identifier_type,
+ const uint8_t* identifier_begin,
+ const size_t identifier_len) {
+ (void)subnet_id;
+ (void)identifier_type;
+ (void)identifier_begin;
+ (void)identifier_len;
+ isc_throw(NotImplemented, "CqlHostDataSource::del4 NotImplemented");
+}
+
+bool
+CqlHostDataSource::del6(const SubnetID& subnet_id,
+ const Host::IdentifierType& identifier_type,
+ const uint8_t* identifier_begin,
+ const size_t identifier_len) {
+ (void)subnet_id;
+ (void)identifier_type;
+ (void)identifier_begin;
+ (void)identifier_len;
+ isc_throw(NotImplemented, "CqlHostDataSource::del6 NotImplemented");
+}
+
std::string
CqlHostDataSource::getType() const {
return std::string("cql");
std::string
CqlHostDataSource::getDescription() const {
- return std::string(
- "Host data source that stores host information in the CQL database");
+ return std::string("Host data source that stores host information "
+ "in the CQL database");
}
VersionPair
impl_->rollback();
}
-}; // namespace dhcp
-}; // namespace isc
+} // namespace dhcp
+} // namespace isc
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <config.h>
+
+#include <asiolink/io_address.h>
+#include <boost/foreach.hpp>
#include <dhcp/dhcp6.h>
#include <dhcp/libdhcp++.h>
#include <dhcp/option4_addrlst.h>
#include <dhcp/option6_addrlst.h>
-#include <dhcp/option_string.h>
#include <dhcp/option_int.h>
+#include <dhcp/option_string.h>
#include <dhcp/option_vendor.h>
+#include <dhcpsrv/database_connection.h>
#include <dhcpsrv/host_data_source_factory.h>
#include <dhcpsrv/tests/generic_host_data_source_unittest.h>
#include <dhcpsrv/tests/test_utils.h>
#include <dhcpsrv/testutils/schema.h>
-#include <dhcpsrv/database_connection.h>
-#include <asiolink/io_address.h>
-#include <util/buffer.h>
-#include <boost/foreach.hpp>
#include <gtest/gtest.h>
+#include <util/buffer.h>
+
+#include <chrono>
#include <cstring>
#include <list>
-#include <string>
#include <sstream>
+#include <string>
#include <typeinfo>
using namespace std;
namespace dhcp {
namespace test {
-GenericHostDataSourceTest::GenericHostDataSourceTest()
- :hdsptr_() {
+GenericHostDataSourceTest::GenericHostDataSourceTest() : hdsptr_() {
LibDHCP::clearRuntimeOptionDefs();
}
GenericHostDataSourceTest::~GenericHostDataSourceTest() {
LibDHCP::clearRuntimeOptionDefs();
+ hdsptr_.reset();
}
std::vector<uint8_t>
// Let's use something that is easily printable. That's convenient
// if you need to enter MySQL queries by hand.
- static uint8_t ident[] = { 65, 66, 67, 68, 69, 70, 71, 72, 73, 74 };
+ static uint8_t ident[] = {65, 66, 67, 68, 69, 70, 71, 72, 73, 74};
- // Increase the identifier for the next time we use it.
- // This is primitive, but will work for 65k unique
- // identifiers.
if (new_identifier) {
+ // Increase the identifier for the next time we use it.
+ // This is primitive, but will work for 65k unique identifiers.
ident[sizeof(ident) - 1]++;
if (ident[sizeof(ident) - 1] == 0) {
ident[sizeof(ident) - 2]++;
std::vector<uint8_t> ident;
if (id == Host::IDENT_HWADDR) {
ident = generateHWAddr();
-
} else {
ident = generateIdentifier();
}
return (host);
}
-HostPtr GenericHostDataSourceTest::initializeHost6(std::string address,
- Host::IdentifierType identifier,
- bool prefix,
- bool new_identifier) {
+HostPtr
+GenericHostDataSourceTest::initializeHost6(std::string address,
+ Host::IdentifierType identifier,
+ bool prefix,
+ bool new_identifier) {
std::vector<uint8_t> ident;
switch (identifier) {
case Host::IDENT_HWADDR:
subnet4++;
subnet6++;
- HostPtr host(new Host(&ident[0], ident.size(), identifier, subnet4,
- subnet6, IOAddress("0.0.0.0")));
+ HostPtr host(new Host(&ident[0], ident.size(), identifier, subnet4, subnet6,
+ IOAddress("0.0.0.0")));
if (!prefix) {
// Create IPv6 reservation (for an address)
return (host);
}
+bool
+GenericHostDataSourceTest::reservationExists(const IPv6Resrv& resrv,
+ const IPv6ResrvRange& range) {
+ for (IPv6ResrvIterator it = range.first; it != range.second; ++it) {
+ if (resrv == it->second) {
+ return true;
+ }
+ }
+ return false;
+}
+
void
GenericHostDataSourceTest::compareHwaddrs(const ConstHostPtr& host1,
const ConstHostPtr& host2,
// Compare if both have or have not HWaddress set.
if ((host1->getHWAddress() && !host2->getHWAddress()) ||
(!host1->getHWAddress() && host2->getHWAddress())) {
-
// One host has hardware address set while the other has not.
// Let's see if it's a problem.
if (expect_match) {
ADD_FAILURE() << "Host comparison failed: host1 hwaddress="
- << host1->getHWAddress() << ", host2 hwaddress="
- << host2->getHWAddress();
+ << host1->getHWAddress()
+ << ", host2 hwaddress=" << host2->getHWAddress();
}
return;
}
// Now we know that either both or neither have hw address set.
// If host1 has it, we can proceed to value comparison.
if (host1->getHWAddress()) {
-
if (expect_match) {
// Compare the actual address if they match.
EXPECT_TRUE(*host1->getHWAddress() == *host2->getHWAddress());
// compare if both have or have not DUID set
if ((host1->getDuid() && !host2->getDuid()) ||
(!host1->getDuid() && host2->getDuid())) {
-
// One host has a DUID and the other doesn't.
// Let's see if it's a problem.
if (expect_match) {
ADD_FAILURE() << "DUID comparison failed: host1 duid="
- << host1->getDuid() << ", host2 duid="
- << host2->getDuid();
+ << host1->getDuid()
+ << ", host2 duid=" << host2->getDuid();
}
return;
}
// Now we know that either both or neither have DUID set.
// If host1 has it, we can proceed to value comparison.
if (host1->getDuid()) {
-
if (expect_match) {
EXPECT_TRUE(*host1->getDuid() == *host2->getDuid());
} else {
}
}
-void GenericHostDataSourceTest::compareHosts(const ConstHostPtr& host1,
- const ConstHostPtr& host2) {
-
+void
+GenericHostDataSourceTest::compareHosts(const ConstHostPtr& host1,
+ const ConstHostPtr& host2) {
// Let's compare HW addresses and expect match.
compareHwaddrs(host1, host2, true);
compareOptions(host1->getCfgOption6(), host2->getCfgOption6());
}
-bool GenericHostDataSourceTest::compareHostsForSort4(
- const ConstHostPtr& host1,
- const ConstHostPtr& host2) {
+bool
+GenericHostDataSourceTest::compareHostsForSort4(const ConstHostPtr& host1,
+ const ConstHostPtr& host2) {
if (host1->getIPv4SubnetID() < host2->getIPv4SubnetID()) {
return true;
}
return false;
}
-bool GenericHostDataSourceTest::compareHostsForSort6(
- const ConstHostPtr& host1,
- const ConstHostPtr& host2) {
+bool
+GenericHostDataSourceTest::compareHostsForSort6(const ConstHostPtr& host1,
+ const ConstHostPtr& host2) {
if (host1->getIPv6SubnetID() < host2->getIPv6SubnetID()) {
return true;
}
return (HWAddrPtr(new HWAddr(duid->getDuid(), HTYPE_ETHER)));
}
-
void
GenericHostDataSourceTest::compareReservations6(IPv6ResrvRange resrv1,
IPv6ResrvRange resrv2) {
-
// Compare number of reservations for both hosts
if (std::distance(resrv1.first, resrv1.second) !=
- std::distance(resrv2.first, resrv2.second)){
- ADD_FAILURE()<< "Reservation comparison failed, "
- "hosts got different number of reservations.";
+ std::distance(resrv2.first, resrv2.second)) {
+ ADD_FAILURE() << "Reservation comparison failed, "
+ "hosts got different number of reservations.";
return;
}
for (; resrv1.first != resrv1.second; resrv1.first++) {
IPv6ResrvIterator iter = resrv2.first;
while (iter != resrv2.second) {
- if((resrv1.first->second.getType() == iter->second.getType()) &&
- (resrv1.first->second.getPrefixLen() == iter->second.getPrefixLen()) &&
- (resrv1.first->second.getPrefix() == iter->second.getPrefix())) {
+ if ((resrv1.first->second.getType() ==
+ iter->second.getType()) &&
+ (resrv1.first->second.getPrefixLen() ==
+ iter->second.getPrefixLen()) &&
+ (resrv1.first->second.getPrefix() ==
+ iter->second.getPrefix())) {
break;
}
iter++;
if (iter == resrv2.second) {
- ADD_FAILURE()<< "Reservation comparison failed, "
- "no match for reservation: "
- << resrv1.first->second.getPrefix().toText();
+ ADD_FAILURE() << "Reservation comparison failed, "
+ "no match for reservation: "
+ << resrv1.first->second.getPrefix().toText();
}
}
}
EXPECT_EQ(vendor_spaces.size(), cfg1->getVendorIdsSpaceNames().size());
// Iterate over all option spaces existing in cfg2.
- BOOST_FOREACH(std::string space, option_spaces) {
+ BOOST_FOREACH (std::string space, option_spaces) {
// Retrieve options belonging to the current option space.
OptionContainerPtr options1 = cfg1->getAll(space);
OptionContainerPtr options2 = cfg2->getAll(space);
<< "failed for option space " << space;
// Iterate over all options within this option space.
- BOOST_FOREACH(OptionDescriptor desc1, *options1) {
+ BOOST_FOREACH (OptionDescriptor desc1, *options1) {
OptionDescriptor desc2 = cfg2->get(space, desc1.option_->getType());
// Compare persistent flag.
EXPECT_EQ(desc1.persistent_, desc2.persistent_)
- << "failed for option " << space << "." << desc1.option_->getType();
+ << "failed for option " << space << "."
+ << desc1.option_->getType();
// Compare formatted value.
EXPECT_EQ(desc1.formatted_value_, desc2.formatted_value_)
- << "failed for option " << space << "." << desc1.option_->getType();
+ << "failed for option " << space << "."
+ << desc1.option_->getType();
// Retrieve options.
Option* option1 = desc1.option_.get();
// the Option class.
EXPECT_TRUE(typeid(*option1) == typeid(*option2))
<< "Compared DHCP options, having option code "
- << desc1.option_->getType() << " and belonging to the "
- << space << " option space, are represented "
- "by different C++ classes: "
- << typeid(*option1).name() << " vs "
- << typeid(*option2).name();
+ << desc1.option_->getType() << " and belonging to the " << space
+ << " option space, are represented "
+ "by different C++ classes: "
+ << typeid(*option1).name() << " vs " << typeid(*option2).name();
// Because we use different C++ classes to represent different
// options, the simplest way to make sure that the options are
ASSERT_NO_THROW(option2->pack(buf2));
ASSERT_EQ(buf1.getLength(), buf2.getLength())
- << "failed for option " << space << "." << desc1.option_->getType();
- EXPECT_EQ(0, memcmp(buf1.getData(), buf2.getData(), buf1.getLength()))
- << "failed for option " << space << "." << desc1.option_->getType();
+ << "failed for option " << space << "."
+ << desc1.option_->getType();
+ EXPECT_EQ(0,
+ memcmp(buf1.getData(), buf2.getData(), buf1.getLength()))
+ << "failed for option " << space << "."
+ << desc1.option_->getType();
}
}
}
return (desc);
}
-
OptionDescriptor
GenericHostDataSourceTest::createVendorOption(const Option::Universe& universe,
const bool persist,
}
void
-GenericHostDataSourceTest::addTestOptions(const HostPtr& host,
- const bool formatted,
- const AddedOptions& added_options) const {
-
+GenericHostDataSourceTest::addTestOptions(
+ const HostPtr& host,
+ const bool formatted,
+ const AddedOptions& added_options) const {
OptionDefSpaceContainer defs;
if ((added_options == DHCP4_ONLY) || (added_options == DHCP4_AND_DHCP6)) {
opts->add(createOption<OptionUint8>(Option::V4, DHO_DEFAULT_IP_TTL,
false, formatted, 64),
DHCP4_OPTION_SPACE);
- opts->add(createOption<OptionUint32>(Option::V4, 1, false, formatted, 312131),
- "vendor-encapsulated-options");
- opts->add(createAddressOption<Option4AddrLst>(254, false, formatted, "192.0.2.3"),
+ opts->add(
+ createOption<OptionUint32>(Option::V4, 1, false, formatted, 312131),
+ "vendor-encapsulated-options");
+ opts->add(createAddressOption<Option4AddrLst>(254, false, formatted,
+ "192.0.2.3"),
DHCP4_OPTION_SPACE);
opts->add(createEmptyOption(Option::V4, 1, true), "isc");
- opts->add(createAddressOption<Option4AddrLst>(2, false, formatted, "10.0.0.5",
- "10.0.0.3", "10.0.3.4"),
+ opts->add(createAddressOption<Option4AddrLst>(
+ 2, false, formatted, "10.0.0.5", "10.0.0.3", "10.0.3.4"),
"isc");
// Add definitions for DHCPv4 non-standard options.
- defs.addItem(OptionDefinitionPtr(new OptionDefinition("vendor-encapsulated-1",
- 1, "uint32")),
+ defs.addItem(OptionDefinitionPtr(new OptionDefinition(
+ "vendor-encapsulated-1", 1, "uint32")),
"vendor-encapsulated-options");
- defs.addItem(OptionDefinitionPtr(new OptionDefinition("option-254", 254,
- "ipv4-address", true)),
+ defs.addItem(OptionDefinitionPtr(new OptionDefinition(
+ "option-254", 254, "ipv4-address", true)),
DHCP4_OPTION_SPACE);
- defs.addItem(OptionDefinitionPtr(new OptionDefinition("isc-1", 1, "empty")),
- "isc");
- defs.addItem(OptionDefinitionPtr(new OptionDefinition("isc-2", 2,
- "ipv4-address", true)),
+ defs.addItem(
+ OptionDefinitionPtr(new OptionDefinition("isc-1", 1, "empty")),
+ "isc");
+ defs.addItem(OptionDefinitionPtr(new OptionDefinition(
+ "isc-2", 2, "ipv4-address", true)),
"isc");
}
if ((added_options == DHCP6_ONLY) || (added_options == DHCP4_AND_DHCP6)) {
// Add DHCPv6 options.
CfgOptionPtr opts = host->getCfgOption6();
- opts->add(createOption<OptionString>(Option::V6, D6O_BOOTFILE_URL,
- true, formatted, "my-boot-file"),
+ opts->add(createOption<OptionString>(Option::V6, D6O_BOOTFILE_URL, true,
+ formatted, "my-boot-file"),
DHCP6_OPTION_SPACE);
- opts->add(createOption<OptionUint32>(Option::V6, D6O_INFORMATION_REFRESH_TIME,
+ opts->add(createOption<OptionUint32>(Option::V6,
+ D6O_INFORMATION_REFRESH_TIME,
false, formatted, 3600),
DHCP6_OPTION_SPACE);
opts->add(createVendorOption(Option::V6, false, formatted, 2495),
"2001:db8:1::1"),
DHCP6_OPTION_SPACE);
opts->add(createEmptyOption(Option::V6, 1, true), "isc2");
- opts->add(createAddressOption<Option6AddrLst>(2, false, formatted, "3000::1",
- "3000::2", "3000::3"),
+ opts->add(createAddressOption<Option6AddrLst>(
+ 2, false, formatted, "3000::1", "3000::2", "3000::3"),
"isc2");
// Add definitions for DHCPv6 non-standard options.
- defs.addItem(OptionDefinitionPtr(new OptionDefinition("option-1024", 1024,
- "ipv6-address", true)),
+ defs.addItem(OptionDefinitionPtr(new OptionDefinition(
+ "option-1024", 1024, "ipv6-address", true)),
DHCP6_OPTION_SPACE);
- defs.addItem(OptionDefinitionPtr(new OptionDefinition("option-1", 1, "empty")),
- "isc2");
- defs.addItem(OptionDefinitionPtr(new OptionDefinition("option-2", 2,
- "ipv6-address", true)),
+ defs.addItem(
+ OptionDefinitionPtr(new OptionDefinition("option-1", 1, "empty")),
+ "isc2");
+ defs.addItem(OptionDefinitionPtr(new OptionDefinition(
+ "option-2", 2, "ipv6-address", true)),
"isc2");
}
// Make sure that the host has been inserted and that the data can be
// retrieved.
- ConstHostPtr host_by_id = hdsptr_->get6(subnet_id, host->getIdentifierType(),
- &host->getIdentifier()[0],
- host->getIdentifier().size());
+ ConstHostPtr host_by_id =
+ hdsptr_->get6(subnet_id, host->getIdentifierType(),
+ &host->getIdentifier()[0], host->getIdentifier().size());
ASSERT_TRUE(host_by_id);
ASSERT_NO_FATAL_FAILURE(compareHosts(host, host_by_id));
// Close the database connection and reopen in "read-only" mode as
// specified by the "VALID_READONLY_DB" parameter.
HostDataSourceFactory::destroy();
- HostDataSourceFactory::create(connectionString(valid_db_type,
- VALID_NAME,
- VALID_HOST,
- VALID_READONLY_USER,
- VALID_PASSWORD,
- VALID_READONLY_DB));
+ HostDataSourceFactory::create(connectionString(
+ valid_db_type, VALID_NAME, VALID_HOST, VALID_READONLY_USER,
+ VALID_PASSWORD, VALID_READONLY_DB));
hdsptr_ = HostDataSourceFactory::getHostDataSourcePtr();
ASSERT_THROW(hdsptr_->rollback(), ReadOnlyDb);
// Reading from the database should still be possible, though.
- host_by_id = hdsptr_->get6(subnet_id, host->getIdentifierType(),
- &host->getIdentifier()[0],
- host->getIdentifier().size());
+ host_by_id =
+ hdsptr_->get6(subnet_id, host->getIdentifierType(),
+ &host->getIdentifier()[0], host->getIdentifier().size());
ASSERT_TRUE(host_by_id);
ASSERT_NO_FATAL_FAILURE(compareHosts(host, host_by_id));
}
-void GenericHostDataSourceTest::testBasic4(const Host::IdentifierType& id) {
+void
+GenericHostDataSourceTest::testBasic4(const Host::IdentifierType& id) {
// Make sure we have the pointer to the host data source.
ASSERT_TRUE(hdsptr_);
// Create a host reservation.
HostPtr host = initializeHost4("192.0.2.1", id);
- ASSERT_TRUE(host); // Make sure the host is generate properly.
+ ASSERT_TRUE(host); // Make sure the host is generate properly.
SubnetID subnet = host->getIPv4SubnetID();
// Try to add it to the host data source.
compareHosts(host, from_hds);
}
-
-void GenericHostDataSourceTest::testGetByIPv4(const Host::IdentifierType& id) {
+void
+GenericHostDataSourceTest::testGetByIPv4(const Host::IdentifierType& id) {
// Make sure we have a pointer to the host data source.
ASSERT_TRUE(hdsptr_);
}
void
-GenericHostDataSourceTest::testGet4ByIdentifier(const Host::IdentifierType& identifier_type) {
+GenericHostDataSourceTest::testGet4ByIdentifier(
+ const Host::IdentifierType& identifier_type) {
// Make sure we have a pointer to the host data source.
ASSERT_TRUE(hdsptr_);
SubnetID subnet1 = host1->getIPv4SubnetID();
SubnetID subnet2 = host2->getIPv4SubnetID();
- ConstHostPtr from_hds1 = hdsptr_->get4(subnet1,
- identifier_type,
- &host1->getIdentifier()[0],
- host1->getIdentifier().size());
+ ConstHostPtr from_hds1 =
+ hdsptr_->get4(subnet1, identifier_type, &host1->getIdentifier()[0],
+ host1->getIdentifier().size());
- ConstHostPtr from_hds2 = hdsptr_->get4(subnet2,
- identifier_type,
- &host2->getIdentifier()[0],
- host2->getIdentifier().size());
+ ConstHostPtr from_hds2 =
+ hdsptr_->get4(subnet2, identifier_type, &host2->getIdentifier()[0],
+ host2->getIdentifier().size());
// Now let's check if we got what we expected.
ASSERT_TRUE(from_hds1);
compareHosts(host2, from_hds2);
}
-void GenericHostDataSourceTest::testHWAddrNotClientId() {
+void
+GenericHostDataSourceTest::testHWAddrNotClientId() {
// Make sure we have a pointer to the host data source.
ASSERT_TRUE(hdsptr_);
DuidPtr duid = HWAddrToDuid(host->getHWAddress());
// Get the host by HW address (should succeed)
- ConstHostPtr by_hwaddr = hdsptr_->get4(subnet, Host::IDENT_HWADDR,
- &host->getIdentifier()[0],
- host->getIdentifier().size());
+ ConstHostPtr by_hwaddr =
+ hdsptr_->get4(subnet, Host::IDENT_HWADDR, &host->getIdentifier()[0],
+ host->getIdentifier().size());
// Get the host by DUID (should fail)
- ConstHostPtr by_duid = hdsptr_->get4(subnet, Host::IDENT_DUID,
- &host->getIdentifier()[0],
- host->getIdentifier().size());
+ ConstHostPtr by_duid =
+ hdsptr_->get4(subnet, Host::IDENT_DUID, &host->getIdentifier()[0],
+ host->getIdentifier().size());
// Now let's check if we got what we expected.
EXPECT_TRUE(by_hwaddr);
EXPECT_FALSE(by_duid);
}
-void GenericHostDataSourceTest::testClientIdNotHWAddr() {
+void
+GenericHostDataSourceTest::testClientIdNotHWAddr() {
// Make sure we have a pointer to the host data source.
ASSERT_TRUE(hdsptr_);
HWAddrPtr hwaddr = DuidToHWAddr(host->getDuid());
// Get the host by DUID (should succeed)
- ConstHostPtr by_duid = hdsptr_->get4(subnet, Host::IDENT_DUID,
- &host->getIdentifier()[0],
- host->getIdentifier().size());
-
+ ConstHostPtr by_duid =
+ hdsptr_->get4(subnet, Host::IDENT_DUID, &host->getIdentifier()[0],
+ host->getIdentifier().size());
// Get the host by HW address (should fail)
- ConstHostPtr by_hwaddr = hdsptr_->get4(subnet, Host::IDENT_HWADDR,
- &host->getIdentifier()[0],
- host->getIdentifier().size());
+ ConstHostPtr by_hwaddr =
+ hdsptr_->get4(subnet, Host::IDENT_HWADDR, &host->getIdentifier()[0],
+ host->getIdentifier().size());
// Now let's check if we got what we expected.
EXPECT_TRUE(by_duid);
void
GenericHostDataSourceTest::testHostname(std::string name, int num) {
-
// Make sure we have a pointer to the host data source.
ASSERT_TRUE(hdsptr_);
// Prepare a vector of hosts with unique hostnames
for (int i = 0; i < num; ++i) {
-
addr = IOAddress::increase(addr);
HostPtr host = initializeHost4(addr.toText(), Host::IDENT_DUID);
}
// Now add them all to the host data source.
- for (vector<HostPtr>::const_iterator it = hosts.begin();
- it != hosts.end(); ++it) {
+ for (vector<HostPtr>::const_iterator it = hosts.begin(); it != hosts.end();
+ ++it) {
// Try to add both of the to the host data source.
ASSERT_NO_THROW(hdsptr_->add(*it));
}
// And finally retrieve them one by one and check
// if the hostname was preserved.
- for (vector<HostPtr>::const_iterator it = hosts.begin();
- it != hosts.end(); ++it) {
-
+ for (vector<HostPtr>::const_iterator it = hosts.begin(); it != hosts.end();
+ ++it) {
ConstHostPtr from_hds;
- ASSERT_NO_THROW(from_hds = hdsptr_->get4(
- (*it)->getIPv4SubnetID(),
- (*it)->getIPv4Reservation()));
+ ASSERT_NO_THROW(from_hds = hdsptr_->get4((*it)->getIPv4SubnetID(),
+ (*it)->getIPv4Reservation()));
ASSERT_TRUE(from_hds);
EXPECT_EQ((*it)->getHostname(), from_hds->getHostname());
void
GenericHostDataSourceTest::testMultipleSubnets(int subnets,
const Host::IdentifierType& id) {
-
// Make sure we have a pointer to the host data source.
ASSERT_TRUE(hdsptr_);
// Now check that the reservations can be retrieved by IPv4 address from
// each subnet separately.
for (int i = 0; i < subnets; ++i) {
-
// Try to retrieve the host by IPv4 address.
- ConstHostPtr from_hds = hdsptr_->get4(i + 1000, host->getIPv4Reservation());
+ ConstHostPtr from_hds =
+ hdsptr_->get4(i + 1000, host->getIPv4Reservation());
ASSERT_TRUE(from_hds);
EXPECT_EQ(i + 1000, from_hds->getIPv4SubnetID());
// Try to retrieve the host by either HW address of client-id
- from_hds = hdsptr_->get4(i + 1000,
- id, &host->getIdentifier()[0],
+ from_hds = hdsptr_->get4(i + 1000, id, &host->getIdentifier()[0],
host->getIdentifier().size());
ASSERT_TRUE(from_hds);
EXPECT_EQ(i + 1000, from_hds->getIPv4SubnetID());
}
// Finally, check that the hosts can be retrieved by HW address or DUID
- ConstHostCollection all_by_id =
- hdsptr_->getAll(id, &host->getIdentifier()[0],
- host->getIdentifier().size());
+ ConstHostCollection all_by_id = hdsptr_->getAll(
+ id, &host->getIdentifier()[0], host->getIdentifier().size());
ASSERT_EQ(subnets, all_by_id.size());
// Check that the returned values are as expected.
}
}
-void GenericHostDataSourceTest::testGet6ByHWAddr() {
+void
+GenericHostDataSourceTest::testGet6ByHWAddr() {
// Make sure we have the pointer to the host data source.
ASSERT_TRUE(hdsptr_);
SubnetID subnet1 = host1->getIPv6SubnetID();
SubnetID subnet2 = host2->getIPv6SubnetID();
- ConstHostPtr from_hds1 = hdsptr_->get6(subnet1, Host::IDENT_HWADDR,
- &host1->getIdentifier()[0],
- host1->getIdentifier().size());
+ ConstHostPtr from_hds1 =
+ hdsptr_->get6(subnet1, Host::IDENT_HWADDR, &host1->getIdentifier()[0],
+ host1->getIdentifier().size());
- ConstHostPtr from_hds2 = hdsptr_->get6(subnet2, Host::IDENT_HWADDR,
- &host2->getIdentifier()[0],
- host2->getIdentifier().size());
+ ConstHostPtr from_hds2 =
+ hdsptr_->get6(subnet2, Host::IDENT_HWADDR, &host2->getIdentifier()[0],
+ host2->getIdentifier().size());
// Now let's check if we got what we expected.
ASSERT_TRUE(from_hds1);
compareHosts(host2, from_hds2);
}
-void GenericHostDataSourceTest::testGet6ByClientId() {
+void
+GenericHostDataSourceTest::testGet6ByClientId() {
// Make sure we have the pointer to the host data source.
ASSERT_TRUE(hdsptr_);
SubnetID subnet1 = host1->getIPv6SubnetID();
SubnetID subnet2 = host2->getIPv6SubnetID();
- ConstHostPtr from_hds1 = hdsptr_->get6(subnet1, Host::IDENT_DUID,
- &host1->getIdentifier()[0],
- host1->getIdentifier().size());
+ ConstHostPtr from_hds1 =
+ hdsptr_->get6(subnet1, Host::IDENT_DUID, &host1->getIdentifier()[0],
+ host1->getIdentifier().size());
- ConstHostPtr from_hds2 = hdsptr_->get6(subnet2, Host::IDENT_DUID,
- &host2->getIdentifier()[0],
- host2->getIdentifier().size());
+ ConstHostPtr from_hds2 =
+ hdsptr_->get6(subnet2, Host::IDENT_DUID, &host2->getIdentifier()[0],
+ host2->getIdentifier().size());
// Now let's check if we got what we expected.
ASSERT_TRUE(from_hds1);
void
GenericHostDataSourceTest::testSubnetId6(int subnets, Host::IdentifierType id) {
-
// Make sure we have a pointer to the host data source.
ASSERT_TRUE(hdsptr_);
// Check that the reservations can be retrieved from each subnet separately.
for (int i = 0; i < subnets; ++i) {
-
// Try to retrieve the host
- ConstHostPtr from_hds = hdsptr_->get6(i + 1000, id, &host->getIdentifier()[0],
- host->getIdentifier().size());
+ ConstHostPtr from_hds =
+ hdsptr_->get6(i + 1000, id, &host->getIdentifier()[0],
+ host->getIdentifier().size());
ASSERT_TRUE(from_hds) << "failed for i=" << i;
EXPECT_EQ(i + 1000, from_hds->getIPv6SubnetID());
}
// Check that the hosts can all be retrieved by HW address or DUID
- ConstHostCollection all_by_id = hdsptr_->getAll(id, &host->getIdentifier()[0],
- host->getIdentifier().size());
+ ConstHostCollection all_by_id = hdsptr_->getAll(
+ id, &host->getIdentifier()[0], host->getIdentifier().size());
ASSERT_EQ(subnets, all_by_id.size());
// Check that the returned values are as expected.
}
}
-void GenericHostDataSourceTest::testGetByIPv6(Host::IdentifierType id,
- bool prefix) {
+void
+GenericHostDataSourceTest::testGetByIPv6(Host::IdentifierType id, bool prefix) {
// Make sure we have a pointer to the host data source.
ASSERT_TRUE(hdsptr_);
EXPECT_FALSE(hdsptr_->get6(IOAddress("2001:db8::5"), len));
}
-void GenericHostDataSourceTest::testGetBySubnetIPv6() {
+void
+GenericHostDataSourceTest::testGetBySubnetIPv6() {
// Make sure we have a pointer to the host data source.
ASSERT_TRUE(hdsptr_);
ASSERT_NO_THROW(hdsptr_->add(host4));
// And then try to retrieve them back.
- ConstHostPtr from_hds1 = hdsptr_->get6(host1->getIPv6SubnetID(),
- IOAddress("2001:db8:1::"));
- ConstHostPtr from_hds2 = hdsptr_->get6(host2->getIPv6SubnetID(),
- IOAddress("2001:db8:2::"));
- ConstHostPtr from_hds3 = hdsptr_->get6(host3->getIPv6SubnetID(),
- IOAddress("2001:db8:3::"));
- ConstHostPtr from_hds4 = hdsptr_->get6(host4->getIPv6SubnetID(),
- IOAddress("2001:db8:4::"));
+ ConstHostPtr from_hds1 =
+ hdsptr_->get6(host1->getIPv6SubnetID(), IOAddress("2001:db8:1::"));
+ ConstHostPtr from_hds2 =
+ hdsptr_->get6(host2->getIPv6SubnetID(), IOAddress("2001:db8:2::"));
+ ConstHostPtr from_hds3 =
+ hdsptr_->get6(host3->getIPv6SubnetID(), IOAddress("2001:db8:3::"));
+ ConstHostPtr from_hds4 =
+ hdsptr_->get6(host4->getIPv6SubnetID(), IOAddress("2001:db8:4::"));
// Make sure we got something back.
ASSERT_TRUE(from_hds1);
compareHosts(host4, from_hds4);
}
-
-void GenericHostDataSourceTest::testAddDuplicate6WithSameDUID() {
+void
+GenericHostDataSourceTest::testAddDuplicate6WithSameDUID() {
// Make sure we have the pointer to the host data source.
ASSERT_TRUE(hdsptr_);
ASSERT_THROW(hdsptr_->add(host), DuplicateEntry);
}
-void GenericHostDataSourceTest::testAddDuplicate6WithSameHWAddr() {
+void
+GenericHostDataSourceTest::testAddDuplicate6WithSameHWAddr() {
// Make sure we have the pointer to the host data source.
ASSERT_TRUE(hdsptr_);
ASSERT_THROW(hdsptr_->add(host), DuplicateEntry);
}
-void GenericHostDataSourceTest::testAddDuplicate4() {
+void
+GenericHostDataSourceTest::testAddDuplicate4() {
// Make sure we have the pointer to the host data source.
ASSERT_TRUE(hdsptr_);
EXPECT_NO_THROW(hdsptr_->add(host));
}
-void GenericHostDataSourceTest::testAddr6AndPrefix(){
+void
+GenericHostDataSourceTest::testAddr6AndPrefix() {
// Make sure we have the pointer to the host data source.
ASSERT_TRUE(hdsptr_);
ASSERT_NO_THROW(hdsptr_->add(host));
// Get this host by DUID
- ConstHostPtr from_hds = hdsptr_->get6(host->getIPv6SubnetID(),
- Host::IDENT_DUID,
- &host->getIdentifier()[0],
- host->getIdentifier().size());
+ ConstHostPtr from_hds =
+ hdsptr_->get6(host->getIPv6SubnetID(), Host::IDENT_DUID,
+ &host->getIdentifier()[0], host->getIdentifier().size());
// Make sure we got something back
ASSERT_TRUE(from_hds);
from_hds->getIPv6Reservations());
}
-void GenericHostDataSourceTest::testMultipleReservations(){
+void
+GenericHostDataSourceTest::testMultipleReservations() {
// Make sure we have the pointer to the host data source.
ASSERT_TRUE(hdsptr_);
uint8_t len = 128;
ASSERT_NO_THROW(hdsptr_->add(host));
-
ConstHostPtr from_hds = hdsptr_->get6(IOAddress("2001:db8::1"), len);
// Make sure we got something back
compareHosts(host, from_hds);
}
-void GenericHostDataSourceTest::testMultipleReservationsDifferentOrder(){
+void
+GenericHostDataSourceTest::testMultipleReservationsDifferentOrder() {
// Make sure we have the pointer to the host data source.
ASSERT_TRUE(hdsptr_);
uint8_t len = 128;
host2->addReservation(resv1);
// Check if reservations are the same
- compareReservations6(host1->getIPv6Reservations(), host2->getIPv6Reservations());
-
+ compareReservations6(host1->getIPv6Reservations(),
+ host2->getIPv6Reservations());
}
-void GenericHostDataSourceTest::testOptionsReservations4(const bool formatted) {
+void
+GenericHostDataSourceTest::testOptionsReservations4(const bool formatted) {
HostPtr host = initializeHost4("192.0.2.5", Host::IDENT_HWADDR);
// Add a bunch of DHCPv4 and DHCPv6 options for the host.
ASSERT_NO_THROW(addTestOptions(host, formatted, DHCP4_ONLY));
SubnetID subnet_id = host->getIPv4SubnetID();
// getAll4(address)
- ConstHostCollection hosts_by_addr = hdsptr_->getAll4(host->getIPv4Reservation());
+ ConstHostCollection hosts_by_addr =
+ hdsptr_->getAll4(host->getIPv4Reservation());
ASSERT_EQ(1, hosts_by_addr.size());
ASSERT_NO_FATAL_FAILURE(compareHosts(host, *hosts_by_addr.begin()));
// get4(subnet_id, identifier_type, identifier, identifier_size)
- ConstHostPtr host_by_id = hdsptr_->get4(subnet_id,
- host->getIdentifierType(),
- &host->getIdentifier()[0],
- host->getIdentifier().size());
+ ConstHostPtr host_by_id =
+ hdsptr_->get4(subnet_id, host->getIdentifierType(),
+ &host->getIdentifier()[0], host->getIdentifier().size());
ASSERT_NO_FATAL_FAILURE(compareHosts(host, host_by_id));
// get4(subnet_id, address)
- ConstHostPtr host_by_addr = hdsptr_->get4(subnet_id, IOAddress("192.0.2.5"));
+ ConstHostPtr host_by_addr =
+ hdsptr_->get4(subnet_id, IOAddress("192.0.2.5"));
ASSERT_NO_FATAL_FAILURE(compareHosts(host, host_by_addr));
}
-void GenericHostDataSourceTest::testOptionsReservations6(const bool formatted) {
+void
+GenericHostDataSourceTest::testOptionsReservations6(const bool formatted) {
HostPtr host = initializeHost6("2001:db8::1", Host::IDENT_DUID, false);
// Add a bunch of DHCPv4 and DHCPv6 options for the host.
ASSERT_NO_THROW(addTestOptions(host, formatted, DHCP6_ONLY));
SubnetID subnet_id = host->getIPv6SubnetID();
// get6(subnet_id, identifier_type, identifier, identifier_size)
- ConstHostPtr host_by_id = hdsptr_->get6(subnet_id, host->getIdentifierType(),
- &host->getIdentifier()[0],
- host->getIdentifier().size());
+ ConstHostPtr host_by_id =
+ hdsptr_->get6(subnet_id, host->getIdentifierType(),
+ &host->getIdentifier()[0], host->getIdentifier().size());
ASSERT_NO_FATAL_FAILURE(compareHosts(host, host_by_id));
// get6(address, prefix_len)
ASSERT_NO_FATAL_FAILURE(compareHosts(host, host_by_addr));
}
-void GenericHostDataSourceTest::testOptionsReservations46(const bool formatted) {
+void
+GenericHostDataSourceTest::testOptionsReservations46(const bool formatted) {
HostPtr host = initializeHost6("2001:db8::1", Host::IDENT_HWADDR, false);
// Add a bunch of DHCPv4 and DHCPv6 options for the host.
ASSERT_NO_THROW(hdsptr_->add(host));
// getAll(identifier_type, identifier, identifier_size)
- ConstHostCollection hosts_by_id = hdsptr_->getAll(host->getIdentifierType(),
- &host->getIdentifier()[0],
- host->getIdentifier().size());
+ ConstHostCollection hosts_by_id =
+ hdsptr_->getAll(host->getIdentifierType(), &host->getIdentifier()[0],
+ host->getIdentifier().size());
ASSERT_EQ(1, hosts_by_id.size());
ASSERT_NO_FATAL_FAILURE(compareHosts(host, *hosts_by_id.begin()));
}
// Fetch the host via:
// getAll(const Host::IdentifierType, const uint8_t* identifier_begin,
// const size_t identifier_len) const;
- hosts_by_id = hdsptr_->getAll(host->getIdentifierType(), &host->getIdentifier()[0],
- host->getIdentifier().size());
+ hosts_by_id =
+ hdsptr_->getAll(host->getIdentifierType(), &host->getIdentifier()[0],
+ host->getIdentifier().size());
ASSERT_EQ(1, hosts_by_id.size());
ASSERT_NO_FATAL_FAILURE(compareHosts(host, *hosts_by_id.begin()));
ASSERT_NO_FATAL_FAILURE(compareHosts(host, from_hds));
// Fetch the host via
- // get4(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
+ // get4(const SubnetID& subnet_id, const Host::IdentifierType&
+ // identifier_type,
// const uint8_t* identifier_begin, const size_t identifier_len) const;
- from_hds = hdsptr_->get4(subnet_id, host->getIdentifierType(), &host->getIdentifier()[0],
- host->getIdentifier().size());
+ from_hds =
+ hdsptr_->get4(subnet_id, host->getIdentifierType(),
+ &host->getIdentifier()[0], host->getIdentifier().size());
ASSERT_TRUE(from_hds);
ASSERT_NO_FATAL_FAILURE(compareHosts(host, from_hds));
// getAll(const Host::IdentifierType& identifier_type,
// const uint8_t* identifier_begin,
// const size_t identifier_len) const;
- hosts_by_id = hdsptr_->getAll(host->getIdentifierType(), &host->getIdentifier()[0],
- host->getIdentifier().size());
+ hosts_by_id =
+ hdsptr_->getAll(host->getIdentifierType(), &host->getIdentifier()[0],
+ host->getIdentifier().size());
ASSERT_EQ(1, hosts_by_id.size());
ASSERT_NO_FATAL_FAILURE(compareHosts(host, *hosts_by_id.begin()));
// get6(const SubnetID& subnet_id, const DuidPtr& duid,
// const HWAddrPtr& hwaddr = HWAddrPtr()) const;
- ConstHostPtr from_hds = hdsptr_->get6(subnet_id, DuidPtr(), host->getHWAddress());
+ ConstHostPtr from_hds =
+ hdsptr_->get6(subnet_id, DuidPtr(), host->getHWAddress());
ASSERT_TRUE(from_hds);
ASSERT_NO_FATAL_FAILURE(compareHosts(host, from_hds));
// Fetch the host via:
- // get6(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
+ // get6(const SubnetID& subnet_id, const Host::IdentifierType&
+ // identifier_type,
// const uint8_t* identifier_begin, const size_t identifier_len) const;
- from_hds = hdsptr_->get6(subnet_id, Host::IDENT_HWADDR,
- &host->getIdentifier()[0],
- host->getIdentifier().size());
+ from_hds =
+ hdsptr_->get6(subnet_id, Host::IDENT_HWADDR, &host->getIdentifier()[0],
+ host->getIdentifier().size());
ASSERT_TRUE(from_hds);
ASSERT_NO_FATAL_FAILURE(compareHosts(host, from_hds));
SubnetID subnet_id = host->getIPv6SubnetID();
// Fetch the host from the source.
- ConstHostPtr from_hds = hdsptr_->get6(subnet_id, Host::IDENT_HWADDR,
- &host->getIdentifier()[0],
- host->getIdentifier().size());
+ ConstHostPtr from_hds =
+ hdsptr_->get6(subnet_id, Host::IDENT_HWADDR, &host->getIdentifier()[0],
+ host->getIdentifier().size());
ASSERT_TRUE(from_hds);
// Verify they match.
// Fetch the host via:
// getAll(const Host::IdentifierType, const uint8_t* identifier_begin,
// const size_t identifier_len) const;
- hosts_by_id = hdsptr_->getAll(host->getIdentifierType(), &host->getIdentifier()[0],
- host->getIdentifier().size());
+ hosts_by_id =
+ hdsptr_->getAll(host->getIdentifierType(), &host->getIdentifier()[0],
+ host->getIdentifier().size());
ASSERT_EQ(1, hosts_by_id.size());
ASSERT_NO_FATAL_FAILURE(compareHosts(host, *hosts_by_id.begin()));
ASSERT_NO_FATAL_FAILURE(compareHosts(host, from_hds));
// Fetch the host via
- // get4(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
+ // get4(const SubnetID& subnet_id, const Host::IdentifierType&
+ // identifier_type,
// const uint8_t* identifier_begin, const size_t identifier_len) const;
- from_hds = hdsptr_->get4(subnet_id, host->getIdentifierType(), &host->getIdentifier()[0],
- host->getIdentifier().size());
+ from_hds =
+ hdsptr_->get4(subnet_id, host->getIdentifierType(),
+ &host->getIdentifier()[0], host->getIdentifier().size());
ASSERT_TRUE(from_hds);
ASSERT_NO_FATAL_FAILURE(compareHosts(host, from_hds));
} // namespace test
} // namespace dhcp
} // namespace isc
-