Commit d4c441f4 authored by Razvan Becheriu's avatar Razvan Becheriu

refactored cassandra backend and fixed issues

parent c164ebc2
......@@ -42,3 +42,6 @@ config.h.in~
/local.zone.sqlite3
/logger_lockfile
/report.info
*.clang_complete
*.dirstamp
......@@ -13,6 +13,7 @@ endif
if HAVE_CQL
SHTESTS += cql_tests.sh
endif
noinst_SCRIPTS = $(SHTESTS)
EXTRA_DIST = dhcpdb_create_1.0.mysql
......
......@@ -235,8 +235,6 @@ ControlledDhcpv4Srv::processConfig(isc::data::ConstElementPtr config) {
}
}
return (answer);
}
......
......@@ -733,7 +733,5 @@ ParserContextPtr& globalContext() {
return (global_context_ptr);
}
}; // end of isc::dhcp namespace
}; // end of isc namespace
......@@ -73,6 +73,10 @@ void configure(const std::string& file_name) {
Daemon::configureLogger(json->get("Logging"),
CfgMgr::instance().getStagingCfg());
// Apply the new logger configuration to log4cplus. It is done before
// commit in case something goes wrong.
CfgMgr::instance().getStagingCfg()->applyLoggingCfg();
// Get Dhcp4 component from the config
dhcp4 = json->get("Dhcp4");
if (!dhcp4) {
......@@ -101,11 +105,6 @@ void configure(const std::string& file_name) {
isc_throw(isc::BadValue, reason);
}
// If configuration was parsed successfully, apply the new logger
// configuration to log4cplus. It is done before commit in case
// something goes wrong.
CfgMgr::instance().getStagingCfg()->applyLoggingCfg();
// Use new configuration.
/// @todo: This commit should be moved to
/// CtrlDhcp4Srv::commandConfigReloadHandler.
......
......@@ -171,8 +171,8 @@ ControlledDhcpv6Srv::processConfig(isc::data::ConstElementPtr config) {
return (answer);
}
} catch (const std::exception& ex) {
return (isc::config::createAnswer(1, "Failed to process configuration:"
+ string(ex.what())));
return (isc::config::createAnswer(1, "Failed to process configuration:" +
string(ex.what())));
}
// Re-open lease and host database with new parameters.
......@@ -182,8 +182,8 @@ ControlledDhcpv6Srv::processConfig(isc::data::ConstElementPtr config) {
cfg_db->createManagers();
} catch (const std::exception& ex) {
return (isc::config::createAnswer(1, "Unable to open database: "
+ std::string(ex.what())));
return (isc::config::createAnswer(1, "Unable to open database: " +
std::string(ex.what())));
}
// Regenerate server identifier if needed.
......
......@@ -79,6 +79,10 @@ void configure(const std::string& file_name) {
Daemon::configureLogger(json->get("Logging"),
CfgMgr::instance().getStagingCfg());
// Apply the new logger configuration to log4cplus. It is done before
// commit in case something goes wrong.
CfgMgr::instance().getStagingCfg()->applyLoggingCfg();
// Get Dhcp6 component from the config
dhcp6 = json->get("Dhcp6");
......@@ -108,11 +112,6 @@ void configure(const std::string& file_name) {
isc_throw(isc::BadValue, reason);
}
// If configuration was parsed successfully, apply the new logger
// configuration to log4cplus. It is done before commit in case
// something goes wrong.
CfgMgr::instance().getStagingCfg()->applyLoggingCfg();
// Use new configuration.
CfgMgr::instance().commit();
......
/perfdhcp
/perfdhcp.1
/perfdhcp.8
......@@ -127,6 +127,7 @@ libkea_dhcpsrv_la_SOURCES += logging.cc logging.h
libkea_dhcpsrv_la_SOURCES += logging_info.cc logging_info.h
libkea_dhcpsrv_la_SOURCES += memfile_lease_mgr.cc memfile_lease_mgr.h
libkea_dhcpsrv_la_SOURCES += memfile_lease_storage.h
libkea_dhcpsrv_la_SOURCES += sql_common.h
if HAVE_MYSQL
libkea_dhcpsrv_la_SOURCES += mysql_lease_mgr.cc mysql_lease_mgr.h
......@@ -141,10 +142,13 @@ libkea_dhcpsrv_la_SOURCES += pgsql_connection.cc pgsql_connection.h
libkea_dhcpsrv_la_SOURCES += pgsql_exchange.cc pgsql_exchange.h
libkea_dhcpsrv_la_SOURCES += pgsql_lease_mgr.cc pgsql_lease_mgr.h
endif
if HAVE_CQL
libkea_dhcpsrv_la_SOURCES += cql_lease_mgr.cc cql_lease_mgr.h
libkea_dhcpsrv_la_SOURCES += cql_connection.cc cql_connection.h
libkea_dhcpsrv_la_SOURCES += cql_exchange.cc cql_exchange.h
libkea_dhcpsrv_la_SOURCES += cql_lease_mgr.cc cql_lease_mgr.h
endif
libkea_dhcpsrv_la_SOURCES += pool.cc pool.h
libkea_dhcpsrv_la_SOURCES += srv_config.cc srv_config.h
libkea_dhcpsrv_la_SOURCES += subnet.cc subnet.h
......
......@@ -19,6 +19,7 @@
#include <dhcpsrv/database_connection.h>
#include <dhcpsrv/dhcpsrv_log.h>
#include <dhcpsrv/cql_exchange.h>
#include <inttypes.h>
#include <cassandra.h>
#include <vector>
......@@ -26,17 +27,6 @@
namespace isc {
namespace dhcp {
/// @brief Defines a single query
///
/// @param params_ Bind parameter names
/// @param name_ Short name of the query.
/// @param text_ Text representation of the actual query.
struct CqlTaggedStatement {
const char** params_;
const char* name_;
const char* text_;
};
// Defines CQL backend version: 2.3
const uint32_t CQL_DRIVER_VERSION_MAJOR = CASS_VERSION_MAJOR;
const uint32_t CQL_DRIVER_VERSION_MINOR = CASS_VERSION_MINOR;
......
......@@ -34,104 +34,8 @@ using namespace std;
namespace isc {
namespace dhcp {
static const size_t HOSTNAME_MAX_LEN = 255U;
static const size_t ADDRESS6_TEXT_MAX_LEN = 39U;
/// @name CqlBind auxiliary methods for binding data into Cassandra format:
/// @{
/// @todo These void* cast are unsafe. See ticket #4525.
static CassError CqlBindNone(CassStatement* statement, size_t index, void*) {
return cass_statement_bind_null(statement, index);
}
static CassError CqlBindBool(CassStatement* statement, size_t index,
void* value) {
return cass_statement_bind_bool(statement, index,
*(static_cast<cass_bool_t*>(value)));
}
static CassError CqlBindInt32(CassStatement* statement, size_t index,
void* value) {
return cass_statement_bind_int32(statement, index,
*(static_cast<cass_int32_t*>(value)));
}
static CassError CqlBindInt64(CassStatement* statement, size_t index,
void* value) {
return cass_statement_bind_int64(statement, index,
*(static_cast<cass_int64_t*>(value)));
}
static CassError CqlBindTimestamp(CassStatement* statement, size_t index,
void* value) {
return cass_statement_bind_int64(statement, index,
*(static_cast<cass_int64_t*>(value)));
}
static CassError CqlBindString(CassStatement* statement, size_t index,
void* value) {
return cass_statement_bind_string(statement, index,
(static_cast<const char*>(value)));
}
static CassError CqlBindBytes(CassStatement* statement, size_t index,
void* value) {
return cass_statement_bind_bytes(statement, index,
static_cast<std::vector<cass_byte_t>*>(value)->data(),
static_cast<std::vector<cass_byte_t>*>(value)->size());
}
/// @}
static CassError CqlGetNone(const CassValue*, void*, size_t*) {
return CASS_OK;
}
static CassError CqlGetBool(const CassValue* value, void* data, size_t*) {
return cass_value_get_bool(value, static_cast<cass_bool_t*>(data));
}
static CassError CqlGetInt32(const CassValue* value, void* data, size_t*) {
return cass_value_get_int32(value, static_cast<cass_int32_t*>(data));
}
static CassError CqlGetInt64(const CassValue* value, void* data, size_t*) {
return cass_value_get_int64(value, static_cast<cass_int64_t*>(data));
}
static CassError CqlGetTimestamp(const CassValue* value, void* data, size_t*) {
return cass_value_get_int64(value, static_cast<cass_int64_t*>(data));
}
static CassError CqlGetString(const CassValue* value, void* data,
size_t* size) {
return cass_value_get_string(value, static_cast<const char**>(data), size);
}
static CassError CqlGetBytes(const CassValue* value, void* data, size_t* size) {
return cass_value_get_bytes(value, static_cast<const cass_byte_t**>(data),
size);
}
typedef CassError (*CqlBindFunction)(CassStatement* statement, size_t index,
void* value);
typedef CassError (*CqlGetFunction)(const CassValue* value, void* data,
size_t* size);
struct CqlFunctionData {
CqlBindFunction sqlBindFunction_;
CqlGetFunction sqlGetFunction_;
};
static struct CqlFunctionData CqlFunctions[] = {
{CqlBindNone, CqlGetNone},
{CqlBindBool, CqlGetBool},
{CqlBindInt32, CqlGetInt32},
{CqlBindInt64, CqlGetInt64},
{CqlBindTimestamp, CqlGetTimestamp},
{CqlBindString, CqlGetString},
{CqlBindBytes, CqlGetBytes}
};
static const size_t HOSTNAME_MAX_LEN = 255U;
static const size_t ADDRESS6_TEXT_MAX_LEN = 39U;
/// @brief Catalog of all the SQL statements currently supported. Note
/// that the order columns appear in statement body must match the order they
......@@ -261,7 +165,8 @@ CqlTaggedStatement CqlLeaseMgr::tagged_statements_[] = {
{ delete_lease4_params,
"delete_lease4",
"DELETE FROM lease4 WHERE address = ? "
"IF EXISTS" },
"IF EXISTS"
},
// DELETE_LEASE4_STATE_EXPIRED
{ delete_expired_lease4_params,
......@@ -271,13 +176,15 @@ CqlTaggedStatement CqlLeaseMgr::tagged_statements_[] = {
"fqdn_fwd, fqdn_rev, hostname, state "
"FROM lease4 "
"WHERE state = ? AND expire < ? "
"ALLOW FILTERING" },
"ALLOW FILTERING"
},
// DELETE_LEASE6
{ delete_lease6_params,
"delete_lease6",
"DELETE FROM lease6 WHERE address = ? "
"IF EXISTS" },
"IF EXISTS"
},
// DELETE_LEASE6_STATE_EXPIRED
{ delete_expired_lease6_params,
......@@ -288,7 +195,8 @@ CqlTaggedStatement CqlLeaseMgr::tagged_statements_[] = {
"hwaddr, hwtype, hwaddr_source, state "
"FROM lease6 "
"WHERE state = ? AND expire < ? "
"ALLOW FILTERING" },
"ALLOW FILTERING"
},
// GET_LEASE4_ADDR
{ get_lease4_addr_params,
......@@ -297,7 +205,8 @@ CqlTaggedStatement CqlLeaseMgr::tagged_statements_[] = {
"valid_lifetime, expire, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, state "
"FROM lease4 "
"WHERE address = ?" },
"WHERE address = ?"
},
// GET_LEASE4_CLIENTID
{ get_lease4_clientid_params,
......@@ -306,7 +215,8 @@ CqlTaggedStatement CqlLeaseMgr::tagged_statements_[] = {
"valid_lifetime, expire, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, state "
"FROM lease4 "
"WHERE client_id = ?" },
"WHERE client_id = ?"
},
// GET_LEASE4_CLIENTID_SUBID
{ get_lease4_clientid_subid_params,
......@@ -316,7 +226,8 @@ CqlTaggedStatement CqlLeaseMgr::tagged_statements_[] = {
"fqdn_fwd, fqdn_rev, hostname, state "
"FROM lease4 "
"WHERE client_id = ? AND subnet_id = ? "
"ALLOW FILTERING" },
"ALLOW FILTERING"
},
// GET_LEASE4_HWADDR
{ get_lease4_hwaddr_params,
......@@ -325,7 +236,8 @@ CqlTaggedStatement CqlLeaseMgr::tagged_statements_[] = {
"valid_lifetime, expire, subnet_id, "
"fqdn_fwd, fqdn_rev, hostname, state "
"FROM lease4 "
"WHERE hwaddr = ?" },
"WHERE hwaddr = ?"
},
// GET_LEASE4_HWADDR_SUBID
{ get_lease4_hwaddr_subid_params,
......@@ -335,7 +247,8 @@ CqlTaggedStatement CqlLeaseMgr::tagged_statements_[] = {
"fqdn_fwd, fqdn_rev, hostname, state "
"FROM lease4 "
"WHERE hwaddr = ? AND subnet_id = ? "
"ALLOW FILTERING" },
"ALLOW FILTERING"
},
// GET_LEASE4_EXPIRE
{ get_lease4_expired_params,
......@@ -346,7 +259,8 @@ CqlTaggedStatement CqlLeaseMgr::tagged_statements_[] = {
"FROM lease4 "
"WHERE state = ? AND expire < ? "
"LIMIT ? "
"ALLOW FILTERING" },
"ALLOW FILTERING"
},
// GET_LEASE6_ADDR
{ get_lease6_addr_params,
......@@ -357,18 +271,20 @@ CqlTaggedStatement CqlLeaseMgr::tagged_statements_[] = {
"hwaddr, hwtype, hwaddr_source, state "
"FROM lease6 "
"WHERE address = ? AND lease_type = ? "
"ALLOW FILTERING" },
"ALLOW FILTERING"
},
// GET_LEASE6_DUID_IAID
{ get_lease6_duid_iaid_params,
"get_lease6_duid_iaid",
"SELECT address, duid, valid_lifetime, "
"expire, subnet_id, pref_lifetime, "
"lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
"hwaddr, hwtype, hwaddr_source, state "
"FROM lease6 "
"WHERE duid = ? AND iaid = ? AND lease_type = ? "
"ALLOW FILTERING" },
"get_lease6_duid_iaid",
"SELECT address, duid, valid_lifetime, "
"expire, subnet_id, pref_lifetime, "
"lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
"hwaddr, hwtype, hwaddr_source, state "
"FROM lease6 "
"WHERE duid = ? AND iaid = ? AND lease_type = ? "
"ALLOW FILTERING"
},
// GET_LEASE6_DUID_IAID_SUBID
{ get_lease6_duid_iaid_subid_params,
......@@ -379,7 +295,8 @@ CqlTaggedStatement CqlLeaseMgr::tagged_statements_[] = {
"hwaddr, hwtype, hwaddr_source, state "
"FROM lease6 "
"WHERE duid = ? AND iaid = ? AND subnet_id = ? AND lease_type = ? "
"ALLOW FILTERING" },
"ALLOW FILTERING"
},
// GET_LEASE6_EXPIRE
{ get_lease6_expired_params,
......@@ -391,12 +308,14 @@ CqlTaggedStatement CqlLeaseMgr::tagged_statements_[] = {
"FROM lease6 "
"WHERE state = ? AND expire < ? "
"LIMIT ? "
"ALLOW FILTERING" },
"ALLOW FILTERING"
},
// GET_VERSION
{ get_version_params,
"get_version",
"SELECT version, minor FROM schema_version" },
"SELECT version, minor FROM schema_version"
},
// INSERT_LEASE4
{ insert_lease4_params,
......@@ -405,7 +324,8 @@ CqlTaggedStatement CqlLeaseMgr::tagged_statements_[] = {
"valid_lifetime, expire, subnet_id, fqdn_fwd, fqdn_rev, hostname, "
"state) "
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) "
"IF NOT EXISTS" },
"IF NOT EXISTS"
},
// INSERT_LEASE6
{ insert_lease6_params,
......@@ -415,7 +335,8 @@ CqlTaggedStatement CqlLeaseMgr::tagged_statements_[] = {
"lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, hwaddr, "
"hwtype, hwaddr_source, state) "
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) "
"IF NOT EXISTS" },
"IF NOT EXISTS"
},
// UPDATE_LEASE4
{ update_lease4_params,
......@@ -424,7 +345,8 @@ CqlTaggedStatement CqlLeaseMgr::tagged_statements_[] = {
"client_id = ?, valid_lifetime = ?, expire = ?, "
"subnet_id = ?, fqdn_fwd = ?, fqdn_rev = ?, hostname = ?, state = ? "
"WHERE address = ? "
"IF EXISTS" },
"IF EXISTS"
},
// UPDATE_LEASE6
{ update_lease6_params,
......@@ -435,7 +357,8 @@ CqlTaggedStatement CqlLeaseMgr::tagged_statements_[] = {
"prefix_len = ?, fqdn_fwd = ?, fqdn_rev = ?, hostname = ?, "
"hwaddr = ?, hwtype = ?, hwaddr_source = ?, state = ? "
"WHERE address = ? "
"IF EXISTS" },
"IF EXISTS"
},
// End of list sentinel
{ NULL, NULL, NULL }
......@@ -449,47 +372,18 @@ CqlTaggedStatement CqlLeaseMgr::tagged_statements_[] = {
/// base to both of them, containing some common methods.
class CqlLeaseExchange : public CqlExchange {
public:
CqlLeaseExchange() : hwaddr_length_(0), expire_(0), subnet_id_(0),
valid_lifetime_(0), fqdn_fwd_(false), fqdn_rev_(false),
hostname_length_(0), state_(0) {
memset(hwaddr_buffer_, 0, sizeof(hwaddr_buffer_));
memset(hostname_buffer_, 0, sizeof(hostname_buffer_));
}
CqlLeaseExchange() : valid_lifetime_(0), expire_(0), subnet_id_(0),
fqdn_fwd_(cass_false), fqdn_rev_(cass_false),
state_(0) {}
protected:
std::vector<uint8_t> hwaddr_; ///< Hardware address
uint8_t hwaddr_buffer_[HWAddr::MAX_HWADDR_LEN];
///< Hardware address buffer
unsigned long hwaddr_length_; ///< Hardware address length
uint64_t expire_; ///< Lease expiry time
uint32_t subnet_id_; ///< Subnet identification
uint64_t valid_lifetime_; ///< Lease time
uint32_t fqdn_fwd_; ///< Has forward DNS update been
///< performed
uint32_t fqdn_rev_; ///< Has reverse DNS update been
///< performed
char hostname_buffer_[HOSTNAME_MAX_LEN + 1];
///< Client hostname
unsigned long hostname_length_; ///< Client hostname length
uint32_t state_; ///< Lease state
};
class CqlVersionExchange : public virtual CqlExchange {
public:
/// @brief Constructor
///
/// The initialization of the variables here is only to satisfy cppcheck -
/// all variables are initialized/set in the methods before they are used.
CqlVersionExchange() {
const size_t MAX_COLUMNS = 2U;
// Set the column names
size_t offset = 0U;
BOOST_STATIC_ASSERT(2U == MAX_COLUMNS);
parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo("version",
offset++, EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32)));
parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo("minor",
offset++, EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32)));
BOOST_ASSERT(parameters_.size() == MAX_COLUMNS);
}
std::vector<cass_byte_t> hwaddr_; ///< Hardware address
cass_int64_t valid_lifetime_; ///< Lease time
cass_int64_t expire_; ///< Lease expiry time
cass_int32_t subnet_id_; ///< Subnet identification
cass_bool_t fqdn_fwd_; ///< Has forward DNS update been performed
cass_bool_t fqdn_rev_; ///< Has reverse DNS update been performed
std::string hostname_; ///< Client hostname
cass_int32_t state_; ///< Lease state
};
/// @brief Exchange CQL and Lease4 Data
......@@ -511,38 +405,33 @@ public:
///
/// The initialization of the variables here is only to satisfy cppcheck -
/// all variables are initialized/set in the methods before they are used.
CqlLease4Exchange() : addr4_(0), client_id_length_(0),
client_id_null_(false) {
const size_t MAX_COLUMNS = 12U;
memset(client_id_buffer_, 0, sizeof(client_id_buffer_));
CqlLease4Exchange() : addr4_(0) {
// Set the column names
size_t offset = 0U;
BOOST_STATIC_ASSERT(12U == MAX_COLUMNS);
const size_t MAX_COLUMNS = 12U;
parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo("address",
offset++, EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32)));
parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32)));
parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo("hwaddr",
offset++, EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_BYTES)));
parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_BYTES)));
parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo("client_id",
offset++, EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_BYTES)));
parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_BYTES)));
parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo("valid_lifetime",
offset++, EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT64)));
parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT64)));
parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo("expire",
offset++, EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_TIMESTAMP)));
parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_TIMESTAMP)));
parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo("subnet_id",
offset++, EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32)));
parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32)));
parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo("fqdn_fwd",
offset++, EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_BOOL)));
parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_BOOL)));
parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo("fqdn_rev",
offset++, EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_BOOL)));
parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_BOOL)));
parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo("hostname",
offset++, EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_STRING)));
parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_STRING)));
parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo("state",
offset++, EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32)));
parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32)));
parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo("limit",
offset++, EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32)));
parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32)));
parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo("[applied]",
offset++, EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_BOOL)));
parameters_.size(), EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_BOOL)));
BOOST_ASSERT(parameters_.size() == MAX_COLUMNS);
}
......@@ -552,7 +441,7 @@ public:
/// the database.
void createBindForSend(const Lease4Ptr& lease, CqlDataArray& data) {
if (!lease) {
isc_throw(BadValue, "createBindForSend:: Lease4 object is NULL");
isc_throw(BadValue, "createBindForSend(): Lease4 object is NULL");
}
// Store lease object to ensure it remains valid.
lease_ = lease;
......@@ -563,24 +452,23 @@ public:
// address: int
// The address in the Lease structure is an IOAddress object.
// Convert this to an integer for storage.
addr4_ = static_cast<uint32_t>(lease_->addr_);
data.add(&addr4_);
addr4_ = static_cast<cass_int32_t>(uint32_t(lease_->addr_));
data.add(reinterpret_cast<void*>(&addr4_));
// hwaddr: blob
HWAddrPtr hwaddr = lease_->hwaddr_;
if (hwaddr) {
if (hwaddr->hwaddr_.size() > HWAddr::MAX_HWADDR_LEN) {
isc_throw(DbOperationError, "Hardware address length " <<
if (lease_->hwaddr_) {
if (lease_->hwaddr_->hwaddr_.size() > HWAddr::MAX_HWADDR_LEN) {
isc_throw(DbOperationError, "hardware address " <<
lease_->hwaddr_->toText() << " of length " <<
lease_->hwaddr_->hwaddr_.size() <<
" exceeds maximum allowed of " <<
" exceeds maximum allowed length of " <<
HWAddr::MAX_HWADDR_LEN);
}
hwaddr_ = hwaddr->hwaddr_;
hwaddr_ = lease_->hwaddr_->hwaddr_;
} else {
hwaddr_.clear();
}
hwaddr_length_ = hwaddr_.size();
data.add(&hwaddr_);
data.add(reinterpret_cast<void*>(&hwaddr_));
// client_id: blob
if (lease_->client_id_) {
......@@ -588,12 +476,11 @@ public:
} else {
client_id_.clear();
}
client_id_length_ = client_id_.size();
data.add(&client_id_);
data.add(reinterpret_cast<void*>(&client_id_));
// valid lifetime: bigint
valid_lifetime_ = lease_->valid_lft_;
data.add(&valid_lifetime_);
valid_lifetime_ = static_cast<cass_int32_t>(lease_->valid_lft_);
data.add(reinterpret_cast<void*>(&valid_lifetime_));
// expire: bigint
// The lease structure holds the client last transmission time (cltt_)
......@@ -603,42 +490,38 @@ public:
// expire = cltt_ + valid_lft_
CqlLeaseExchange::convertToDatabaseTime(lease_->cltt_,
lease_->valid_lft_, expire_);
data.add(&expire_);
data.add(reinterpret_cast<void*>(&expire_));
// subnet_id: int
// Can use lease_->subnet_id_ directly as it is of type uint32_t.
subnet_id_ = lease_->subnet_id_;
data.add(&subnet_id_);
subnet_id_ = static_cast<cass_int32_t>(lease_->subnet_id_);
data.add(reinterpret_cast<void*>(&subnet_id_));
// fqdn_fwd: boolean
fqdn_fwd_ = lease_->fqdn_fwd_;
data.add(&fqdn_fwd_);
fqdn_fwd_ = lease_->fqdn_fwd_ ? cass_true : cass_false;
data.add(reinterpret_cast<void*>(&fqdn_fwd_));
// fqdn_rev: boolean
fqdn_rev_ = lease_->fqdn_rev_;
data.add(&fqdn_rev_);
fqdn_rev_ = lease_->fqdn_rev_ ? cass_true : cass_false;
data.add(reinterpret_cast<void*>(&fqdn_rev_));
// hostname: varchar
hostname_length_ = lease_->hostname_.length();
if (hostname_length_ >= sizeof(hostname_buffer_)) {
isc_throw(BadValue, "hostname value is too large: " <<
lease_->hostname_.c_str());
}
if (hostname_length_) {
memcpy(hostname_buffer_, lease_->hostname_.c_str(),
hostname_length_);
if (lease_->hostname_.size() > HOSTNAME_MAX_LEN) {
isc_throw(BadValue, "hostname " << lease_->hostname_ <<
" of length " << lease_->hostname_.size() <<
" exceeds maximum allowed length of " <<
HOSTNAME_MAX_LEN);
}
hostname_buffer_[hostname_length_] = '\0';
data.add(hostname_buffer_);
hostname_ = lease_->hostname_;
data.add(reinterpret_cast<void*>(&hostname_));
// state: int
state_ = lease_->state_;
data.add(&state_);
state_ = static_cast<cass_int32_t>(lease_->state_);
data.add(reinterpret_cast<void*>(&state_));
} catch (const std::exception& ex) {
isc_throw(DbOperationError,
"Could not create bind array from Lease4: "
<< lease_->addr_.toText() << ", reason: " << ex.what());
"could not create bind array from Lease4: " <<
lease_->addr_.toText() << ", reason: " << ex.what());
}
}