summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrei Pavel <andrei.pavel@qualitance.com>2016-06-10 18:21:57 +0200
committerTomek Mrugalski <tomasz@isc.org>2016-06-23 14:32:22 +0200
commit829cac98a32f9467fb183a5bc421edcccb971cba (patch)
tree47ac75c859623f300ae21346067515b0cd881fc0
parentfixed compilation issues for cql unittests (diff)
downloadkea-829cac98a32f9467fb183a5bc421edcccb971cba.tar.xz
kea-829cac98a32f9467fb183a5bc421edcccb971cba.zip
fixed issues and refactored cassandra backend
-rwxr-xr-xAUTHORS3
-rw-r--r--COPYING2
-rw-r--r--src/lib/dhcpsrv/cql_connection.h8
-rw-r--r--src/lib/dhcpsrv/cql_lease_mgr.cc379
-rw-r--r--src/lib/dhcpsrv/cql_lease_mgr.h19
-rwxr-xr-xsrc/lib/dhcpsrv/lease_mgr.h59
-rw-r--r--src/lib/dhcpsrv/tests/cql_lease_mgr_unittest.cc21
7 files changed, 288 insertions, 203 deletions
diff --git a/AUTHORS b/AUTHORS
index 7f61f48f49..da3170ad42 100755
--- a/AUTHORS
+++ b/AUTHORS
@@ -97,6 +97,9 @@ We have received the following contributions:
- Angelo Failla, Facebook
2016-04: Fixes for transaction id generation in perfdhcp
+ - Razvan Becheriu, Qualitance
+ 2016-05: Added support for Cassandra
+
Kea uses log4cplus (http://sourceforge.net/projects/log4cplus/) for logging,
Boost (http://www.boost.org/) library for almost everything, and can use Botan
(http://botan.randombit.net/) or OpenSSL (https://www.openssl.org/) for
diff --git a/COPYING b/COPYING
index 75b58d2382..179ac9e894 100644
--- a/COPYING
+++ b/COPYING
@@ -9,3 +9,5 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
The ext/coroutine code is externally maintained and distributed under
the Boost Software License, Version 1.0. (See its accompanying file
LICENSE_1_0.txt.)
+
+The Cassandra backend code is distributed under the Apache License, Version 2.0.
diff --git a/src/lib/dhcpsrv/cql_connection.h b/src/lib/dhcpsrv/cql_connection.h
index 5e6997ec28..30bbeed1f0 100644
--- a/src/lib/dhcpsrv/cql_connection.h
+++ b/src/lib/dhcpsrv/cql_connection.h
@@ -78,16 +78,12 @@ public:
/// @brief Commit Transactions
///
- /// Commits all pending database operations.
- ///
- /// @throw DbOperationError If the commit failed.
+ /// This is a no-op for Cassandra.
virtual void commit();
/// @brief Rollback Transactions
///
- /// Rolls back all pending database operations.
- ///
- /// @throw DbOperationError If the rollback failed.
+ /// This is a no-op for Cassandra.
virtual void rollback();
/// @brief Check Error
diff --git a/src/lib/dhcpsrv/cql_lease_mgr.cc b/src/lib/dhcpsrv/cql_lease_mgr.cc
index 53a6287f9e..b186aecf06 100644
--- a/src/lib/dhcpsrv/cql_lease_mgr.cc
+++ b/src/lib/dhcpsrv/cql_lease_mgr.cc
@@ -34,8 +34,8 @@ using namespace std;
namespace isc {
namespace dhcp {
-static const size_t HOSTNAME_MAX_LEN = 255;
-static const size_t ADDRESS6_TEXT_MAX_LEN = 39;
+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:
/// @{
@@ -455,13 +455,12 @@ protected:
///< performed
uint32_t fqdn_rev_; ///< Has reverse DNS update been
///< performed
- char hostname_buffer_[HOSTNAME_MAX_LEN];
+ 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
@@ -469,20 +468,18 @@ public:
/// 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 = 2;
- // Set the column names (for error messages)
- size_t offset = 0;
- BOOST_ASSERT(2 == MAX_COLUMNS);
- parameters_.resize(MAX_COLUMNS);
- parameters_[offset++] = ExchangeColumnInfo("version",
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32);
- parameters_[offset++] = ExchangeColumnInfo("minor",
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32);
- BOOST_ASSERT(offset == MAX_COLUMNS);
+ 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);
}
};
-
/// @brief Exchange CQL and Lease4 Data
///
/// On any CQL operation, arrays of CQL BIND structures must be built to
@@ -504,36 +501,35 @@ public:
/// 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 = 11;
+ const size_t MAX_COLUMNS = 11U;
memset(client_id_buffer_, 0, sizeof(client_id_buffer_));
- // Set the column names (for error messages)
- size_t offset = 0;
- BOOST_STATIC_ASSERT(11 == MAX_COLUMNS);
- parameters_.resize(MAX_COLUMNS);
- parameters_[offset++] = ExchangeColumnInfo("address",
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32);
- parameters_[offset++] = ExchangeColumnInfo("hwaddr",
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_BYTES);
- parameters_[offset++] = ExchangeColumnInfo("client_id",
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_BYTES);
- parameters_[offset++] = ExchangeColumnInfo("valid_lifetime",
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT64);
- parameters_[offset++] = ExchangeColumnInfo("expire",
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_TIMESTAMP);
- parameters_[offset++] = ExchangeColumnInfo("subnet_id",
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32);
- parameters_[offset++] = ExchangeColumnInfo("fqdn_fwd",
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_BOOL);
- parameters_[offset++] = ExchangeColumnInfo("fqdn_rev",
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_BOOL);
- parameters_[offset++] = ExchangeColumnInfo("hostname",
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_STRING);
- parameters_[offset++] = ExchangeColumnInfo("state",
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32);
- parameters_[offset++] = ExchangeColumnInfo("limit",
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32);
- BOOST_ASSERT(offset == MAX_COLUMNS);
+ // Set the column names
+ size_t offset = 0U;
+ BOOST_STATIC_ASSERT(11U == MAX_COLUMNS);
+ parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo("address",
+ offset++, 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_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo("client_id",
+ offset++, 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_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo("expire",
+ offset++, 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_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo("fqdn_fwd",
+ offset++, 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_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo("hostname",
+ offset++, 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_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo("limit",
+ offset++, EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32)));
+ BOOST_ASSERT(parameters_.size() == MAX_COLUMNS);
}
/// @brief Create CQL_BIND objects for Lease4 Pointer
@@ -550,17 +546,18 @@ public:
// structure.
try {
- // address: uint32_t
+ // 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_);
+ // hwaddr: blob
hwaddr_ = lease_->hwaddr_->hwaddr_;
hwaddr_length_ = hwaddr_.size();
data.add(&hwaddr_);
- // client_id: varbinary(128)
+ // client_id: blob
if (lease_->client_id_) {
client_id_ = lease_->client_id_->getClientId();
} else {
@@ -569,10 +566,11 @@ public:
client_id_length_ = client_id_.size();
data.add(&client_id_);
- // valid lifetime: unsigned int
+ // valid lifetime: bigint
valid_lifetime_ = lease_->valid_lft_;
data.add(&valid_lifetime_);
- // expire: timestamp
+
+ // expire: bigint
// The lease structure holds the client last transmission time (cltt_)
// For convenience for external tools, this is converted to lease
// expiry time (expire). The relationship is given by:
@@ -582,7 +580,7 @@ public:
lease_->valid_lft_, expire_);
data.add(&expire_);
- // subnet_id: unsigned int
+ // 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_);
@@ -595,8 +593,8 @@ public:
fqdn_rev_ = lease_->fqdn_rev_;
data.add(&fqdn_rev_);
- // hostname: varchar(255)
- hostname_length_ = lease_->hostname_.length();
+ // 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());
@@ -608,7 +606,7 @@ public:
hostname_buffer_[hostname_length_] = '\0';
data.add(hostname_buffer_);
- // state: uint32_t
+ // state: int
state_ = lease_->state_;
data.add(&state_);
@@ -631,27 +629,27 @@ public:
CqlDataArray data;
CqlDataArray size;
- // address: uint32_t
+ // address: int
data.add(reinterpret_cast<void*>(&addr4_));
size.add(NULL);
- // hwaddr: varbinary(20)
+ // hwaddr: blob
data.add(reinterpret_cast<void*>(&hwaddr_buffer));
size.add(reinterpret_cast<void*>(&hwaddr_length_));
- // client_id: varbinary(128)
+ // client_id: blob
data.add(reinterpret_cast<void*>(&client_id_buffer));
size.add(reinterpret_cast<void*>(&client_id_length_));
- // lease_time: unsigned int
+ // valid_lifetime: bigint
data.add(reinterpret_cast<void*>(&valid_lifetime_));
size.add(NULL);
- // expire: timestamp
+ // expire: bigint
data.add(reinterpret_cast<void*>(&expire_));
size.add(NULL);
- // subnet_id: unsigned int
+ // subnet_id: int
data.add(reinterpret_cast<void*>(&subnet_id_));
size.add(NULL);
@@ -663,11 +661,11 @@ public:
data.add(reinterpret_cast<void*>(&fqdn_rev_));
size.add(NULL);
- // hostname: varchar(255)
+ // hostname: varchar
data.add(reinterpret_cast<void*>(&hostname_buffer));
size.add(reinterpret_cast<void*>(&hostname_length_));
- // state: uint32_t
+ // state: int
data.add(reinterpret_cast<void*>(&state_));
size.add(NULL);
@@ -675,10 +673,10 @@ public:
CqlLeaseMgr::getData(row, i, data, size, *this);
}
- // hwaddr: varbinary(20)
+ // hwaddr: blob
hwaddr_.assign(hwaddr_buffer, hwaddr_buffer + hwaddr_length_);
- // client_id: varbinary(128)
+ // client_id: blob
client_id_.assign(client_id_buffer, client_id_buffer +
client_id_length_);
if (client_id_length_ >= sizeof(client_id_buffer_)) {
@@ -690,7 +688,7 @@ public:
}
client_id_buffer_[client_id_length_] = '\0';
- // hostname: varchar(255)
+ // hostname: varchar
if (hostname_length_ >= sizeof(hostname_buffer_)) {
isc_throw(BadValue, "hostname value is too large: " <<
hostname_buffer);
@@ -727,10 +725,6 @@ public:
}
private:
-
- // Note: All array lengths are equal to the corresponding variable in the
- // schema.
- // Note: Arrays are declared fixed length for speed of creation
Lease4Ptr lease_; ///< Pointer to lease object
uint32_t addr4_; ///< IPv4 address
std::vector<uint8_t> client_id_; ///< Client identification
@@ -759,53 +753,51 @@ public:
///
/// The initialization of the variables here is nonly to satisfy cppcheck -
/// all variables are initialized/set in the methods before they are used.
- CqlLease6Exchange() : addr6_length_(0), duid_length_(0),
- iaid_(0), lease_type_(0), prefixlen_(0),
- pref_lifetime_(0), hwaddr_null_(false), hwtype_(0),
- hwaddr_source_(0) {
- const size_t MAX_COLUMNS = 17;
+ CqlLease6Exchange() : addr6_length_(0), duid_length_(0), iaid_(0),
+ lease_type_(0), prefixlen_(0), pref_lifetime_(0),
+ hwaddr_null_(false), hwtype_(0), hwaddr_source_(0) {
+ const size_t MAX_COLUMNS = 17U;
memset(addr6_buffer_, 0, sizeof(addr6_buffer_));
memset(duid_buffer_, 0, sizeof(duid_buffer_));
- // Set the column names (for error messages)
- size_t offset = 0;
- BOOST_STATIC_ASSERT(17 == MAX_COLUMNS);
- parameters_.resize(MAX_COLUMNS);
- parameters_[offset++] = ExchangeColumnInfo("address",
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_STRING);
- parameters_[offset++] = ExchangeColumnInfo("duid",
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_BYTES);
- parameters_[offset++] = ExchangeColumnInfo("valid_lifetime",
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT64);
- parameters_[offset++] = ExchangeColumnInfo("expire",
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_TIMESTAMP);
- parameters_[offset++] = ExchangeColumnInfo("subnet_id",
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32);
- parameters_[offset++] = ExchangeColumnInfo("pref_lifetime",
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT64);
- parameters_[offset++] = ExchangeColumnInfo("lease_type",
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32);
- parameters_[offset++] = ExchangeColumnInfo("iaid",
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32);
- parameters_[offset++] = ExchangeColumnInfo("prefix_len",
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32);
- parameters_[offset++] = ExchangeColumnInfo("fqdn_fwd",
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_BOOL);
- parameters_[offset++] = ExchangeColumnInfo("fqdn_rev",
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_BOOL);
- parameters_[offset++] = ExchangeColumnInfo("hostname",
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_STRING);
- parameters_[offset++] = ExchangeColumnInfo("hwaddr",
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_BYTES);
- parameters_[offset++] = ExchangeColumnInfo("hwtype",
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32);
- parameters_[offset++] = ExchangeColumnInfo("hwaddr_source",
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32);
- parameters_[offset++] = ExchangeColumnInfo("state",
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32);
- parameters_[offset++] = ExchangeColumnInfo("limit",
- EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32);
- BOOST_ASSERT(offset == MAX_COLUMNS);
+ // Set the column names
+ size_t offset = 0U;
+ BOOST_STATIC_ASSERT(17U == MAX_COLUMNS);
+ parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo("address",
+ offset++, EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_STRING)));
+ parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo("duid",
+ offset++, EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_STRING)));
+ parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo("valid_lifetime",
+ offset++, 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_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo("subnet_id",
+ offset++, EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32)));
+ parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo("pref_lifetime",
+ offset++, EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT64)));
+ parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo("lease_type",
+ offset++, EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32)));
+ parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo("iaid",
+ offset++, EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32)));
+ parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo("prefix_len",
+ offset++, 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_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo("fqdn_rev",
+ offset++, 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_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo("hwaddr",
+ offset++, EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_BYTES)));
+ parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo("hwtype",
+ offset++, EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32)));
+ parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo("hwaddr_source",
+ offset++, EXCHANGE_DATA_TYPE_IO_IN_OUT, EXCHANGE_DATA_TYPE_INT32)));
+ parameters_.push_back(ExchangeColumnInfoPtr(new ExchangeColumnInfo("state",
+ offset++, 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)));
+ BOOST_ASSERT(parameters_.size() == MAX_COLUMNS);
}
/// @brief Create CQL_BIND objects for Lease6 Pointer
@@ -822,7 +814,7 @@ public:
// Set up the structures for the various components of the lease4
// structure.
try {
- // address: varchar(39)
+ // address: varchar
std::string text_buffer = lease_->addr_.toText();
addr6_length_ = text_buffer.size();
if (addr6_length_ >= sizeof(addr6_buffer_)) {
@@ -835,20 +827,20 @@ public:
addr6_buffer_[addr6_length_] = '\0';
data.add(addr6_buffer_);
- // duid: varchar(128)
+ // duid: blob
if (!lease_->duid_) {
isc_throw(DbOperationError, "lease6 for address " <<
- addr6_buffer_ << " is missing mandatory client-id.");
+ addr6_buffer_ << " is missing mandatory client-id");
}
duid_ = lease_->duid_->getDuid();
duid_length_ = duid_.size();
data.add(&duid_);
- // valid lifetime: unsigned int
+ // valid lifetime: bigint
valid_lifetime_ = lease_->valid_lft_;
data.add(&valid_lifetime_);
- // expire: timestamp
+ // expire: bigint
// The lease structure holds the client last transmission time (cltt_)
// For convenience for external tools, this is converted to lease
// expiry time (expire). The relationship is given by:
@@ -858,27 +850,27 @@ public:
lease_->valid_lft_, expire_);
data.add(&expire_);
- // subnet_id: unsigned int
+ // 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_);
- // pref_lifetime: unsigned int
+ // pref_lifetime: bigint
// Can use lease_->preferred_lft_ directly as it is of type uint32_t.
pref_lifetime_ = lease_->preferred_lft_;
data.add(&pref_lifetime_);
- // lease_type: tinyint
+ // lease_type: int
// Must convert to uint8_t as lease_->type_ is a LeaseType variable.
lease_type_ = lease_->type_;
data.add(&lease_type_);
- // iaid: unsigned int
+ // iaid: int
// Can use lease_->iaid_ directly as it is of type uint32_t.
iaid_ = lease_->iaid_;
data.add(&iaid_);
- // prefix_len: unsigned tinyint
+ // prefix_len: int
// Can use lease_->prefixlen_ directly as it is uint32_t.
prefixlen_ = lease_->prefixlen_;
data.add(&prefixlen_);
@@ -891,8 +883,8 @@ public:
fqdn_rev_ = lease_->fqdn_rev_;
data.add(&fqdn_rev_);
- // hostname: varchar(255)
- hostname_length_ = lease_->hostname_.length();
+ // 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());
@@ -904,7 +896,7 @@ public:
hostname_buffer_[hostname_length_] = '\0';
data.add(hostname_buffer_);
- // hwaddr: varbinary(20) - hardware/MAC address
+ // hwaddr: blob
HWAddrPtr hwaddr = lease_->hwaddr_;
if (hwaddr) {
hwaddr_ = hwaddr->hwaddr_;
@@ -914,7 +906,7 @@ public:
hwaddr_length_ = hwaddr_.size();
data.add(&hwaddr_);
- // hwtype
+ // hwtype: int
if (hwaddr) {
hwtype_ = lease->hwaddr_->htype_;
} else {
@@ -922,7 +914,7 @@ public:
}
data.add(&hwtype_);
- /// Hardware source
+ // hwaddr_source: int
if (hwaddr) {
hwaddr_source_ = lease->hwaddr_->source_;
} else {
@@ -930,7 +922,7 @@ public:
}
data.add(&hwaddr_source_);
- // state: uint32_t
+ // state: int
state_ = lease_->state_;
data.add(&state_);
@@ -953,39 +945,39 @@ public:
CqlDataArray data;
CqlDataArray size;
- // address: varchar(39)
+ // address: varchar
data.add(reinterpret_cast<void*>(&address_buffer));
size.add(reinterpret_cast<void*>(&addr6_length_));
- // duid: varbinary(128)
+ // duid: blob
data.add(reinterpret_cast<void*>(&duid_buffer));
size.add(reinterpret_cast<void*>(&duid_length_));
- // lease_time: unsigned int
+ // valid_lifetime_: bigint
data.add(reinterpret_cast<void*>(&valid_lifetime_));
size.add(NULL);
- // expire: timestamp
+ // expire: bigint
data.add(reinterpret_cast<void*>(&expire_));
size.add(NULL);
- // subnet_id: unsigned int
+ // subnet_id: int
data.add(reinterpret_cast<void*>(&subnet_id_));
size.add(NULL);
- // pref_lifetime: unsigned int
+ // pref_lifetime: bigint
data.add(reinterpret_cast<void*>(&pref_lifetime_));
size.add(NULL);
- // lease_type: tinyint
+ // lease_type: int
data.add(reinterpret_cast<void*>(&lease_type_));
size.add(NULL);
- // iaid: unsigned int
+ // iaid: int
data.add(reinterpret_cast<void*>(&iaid_));
size.add(NULL);
- // prefix_len: unsigned tinyint
+ // prefix_len: int
data.add(reinterpret_cast<void*>(&prefixlen_));
size.add(NULL);
@@ -997,23 +989,23 @@ public:
data.add(reinterpret_cast<void*>(&fqdn_rev_));
size.add(NULL);
- // hostname: varchar(255)
+ // hostname: varchar
data.add(reinterpret_cast<void*>(&hostname_buffer));
size.add(reinterpret_cast<void*>(&hostname_length_));
- // hwaddr: varbinary(20)
+ // hwaddr: blob
data.add(reinterpret_cast<void*>(&hwaddr_buffer));
size.add(reinterpret_cast<void*>(&hwaddr_length_));
- // hardware type: unsigned short int (16 bits)
+ // hwtype: int
data.add(reinterpret_cast<void*>(&hwtype_));
size.add(NULL);
- // hardware source: unsigned int (32 bits)
+ // hwaddr_source: int
data.add(reinterpret_cast<void*>(&hwaddr_source_));
size.add(NULL);
- // state: uint32_t
+ // state: int
data.add(reinterpret_cast<void*>(&state_));
size.add(NULL);
@@ -1021,7 +1013,7 @@ public:
CqlLeaseMgr::getData(row, i, data, size, *this);
}
- // address: varchar(39)
+ // address: varchar
if (addr6_length_ >= sizeof(addr6_buffer_)) {
isc_throw(BadValue, "address value is too large: " <<
address_buffer);
@@ -1031,10 +1023,10 @@ public:
}
addr6_buffer_[addr6_length_] = '\0';
- // duid: varbinary(128)
+ // duid: blob
duid_.assign(duid_buffer, duid_buffer + duid_length_);
- // hostname: varchar(255)
+ // hostname: varchar
if (hostname_length_ >= sizeof(hostname_buffer_)) {
isc_throw(BadValue, "hostname value is too large: " <<
hostname_buffer);
@@ -1044,8 +1036,7 @@ public:
}
hostname_buffer_[hostname_length_] = '\0';
- // hardware address
- // hwaddr: varbinary(20)
+ // hwaddr: blob
hwaddr_.assign(hwaddr_buffer, hwaddr_buffer + hwaddr_length_);
if (lease_type_ != Lease::TYPE_NA && lease_type_ != Lease::TYPE_TA &&
@@ -1053,7 +1044,7 @@ public:
isc_throw(BadValue, "invalid lease type returned (" <<
static_cast<int>(lease_type_) << ") for lease with "
<< "address " << addr6_buffer_ << ". Only 0, 1, or 2 are "
- << "allowed.");
+ << "allowed");
}
isc::asiolink::IOAddress addr(addr6_buffer_);
@@ -1092,9 +1083,6 @@ public:
}
private:
- // Note: All array lengths are equal to the corresponding variable in the
- // schema.
- // Note: arrays are declared fixed length for speed of creation
Lease6Ptr lease_; ///< Pointer to lease object
char addr6_buffer_[ADDRESS6_TEXT_MAX_LEN + 1]; ///< Character
///< array form of V6 address
@@ -1132,20 +1120,19 @@ CqlLeaseMgr::getDBVersion() {
return (tmp.str());
}
-void
+ExchangeDataType
CqlLeaseMgr::getDataType(const StatementIndex stindex, int pindex,
- const SqlExchange& exchange, ExchangeDataType& type) {
+ const SqlExchange& exchange) {
if (CqlLeaseMgr::tagged_statements_[stindex].params_ &&
CqlLeaseMgr::tagged_statements_[stindex].params_[pindex]) {
- for (int i = 0; exchange.parameters_.size(); i++) {
- if (!strcmp(CqlLeaseMgr::tagged_statements_[stindex].params_[pindex],
- exchange.parameters_[i].column_)) {
- type = exchange.parameters_[i].type_;
- return;
- }
+ const ExchangeColumnInfoContainerName& idx = exchange.parameters_.get<1>();
+ const ExchangeColumnInfoContainerNameRange& range =
+ idx.equal_range(CqlLeaseMgr::tagged_statements_[stindex].params_[pindex]);
+ if (std::distance(range.first, range.second) > 0) {
+ return (*range.first)->type_;
}
}
- type = EXCHANGE_DATA_TYPE_NONE;
+ return EXCHANGE_DATA_TYPE_NONE;
}
void
@@ -1155,8 +1142,10 @@ CqlLeaseMgr::bindData(CassStatement* statement, const StatementIndex stindex,
return;
}
for (int i = 0; CqlLeaseMgr::tagged_statements_[stindex].params_[i]; i++) {
- ExchangeDataType type;
- CqlLeaseMgr::getDataType(stindex, i, exchange, type);
+ ExchangeDataType type = CqlLeaseMgr::getDataType(stindex, i, exchange);
+ if (type >= sizeof(CqlFunctions) / sizeof(CqlFunctions[0])) {
+ isc_throw(BadValue, "index " << stindex << " out of bounds");
+ }
CqlFunctions[type].sqlBindFunction_(statement, i, data.values_[i]);
}
}
@@ -1168,13 +1157,21 @@ CqlLeaseMgr::getData(const CassRow* row, int pindex, CqlDataArray& data,
if (pindex >= exchange.parameters_.size()) {
return;
}
- value = cass_row_get_column_by_name(row, exchange.parameters_[pindex].column_);
- if (NULL == value) {
- isc_throw(BadValue, "Column name "
- << exchange.parameters_[pindex].column_ << "doesn't exist");
+ const ExchangeColumnInfoContainerIndex& idx = exchange.parameters_.get<2>();
+ const ExchangeColumnInfoContainerIndexRange& range = idx.equal_range(pindex);
+ if (std::distance(range.first, range.second) > 0) {
+ std::string name = (*range.first)->name_;
+ ExchangeDataType type = (*range.first)->type_;
+ value = cass_row_get_column_by_name(row, name.c_str());
+ if (NULL == value) {
+ isc_throw(BadValue, "column name " << name << " doesn't exist");
+ }
+ if (type >= sizeof(CqlFunctions) / sizeof(CqlFunctions[0])) {
+ isc_throw(BadValue, "index " << type << " out of bounds");
+ }
+ CqlFunctions[type].sqlGetFunction_(value, data.values_[pindex],
+ reinterpret_cast<size_t *>(size.values_[pindex]));
}
- CqlFunctions[exchange.parameters_[pindex].type_].sqlGetFunction_(value,
- data.values_[pindex], reinterpret_cast<size_t *>(size.values_[pindex]));
}
bool
@@ -1185,10 +1182,17 @@ CqlLeaseMgr::addLeaseCommon(StatementIndex stindex,
CassFuture* future = NULL;
statement = cass_prepared_bind(dbconn_.statements_[stindex]);
+ if (NULL == statement) {
+ isc_throw(DbOperationError, "unable to bind statement");
+ }
CqlLeaseMgr::bindData(statement, stindex, data, exchange);
future = cass_session_execute(dbconn_.session_, statement);
+ if (NULL == future) {
+ cass_statement_free(statement);
+ isc_throw(DbOperationError, "unable to execute statement");
+ }
cass_future_wait(future);
std::string error;
dbconn_.checkStatementError(error, future, stindex, "unable to INSERT");
@@ -1241,10 +1245,17 @@ void CqlLeaseMgr::getLeaseCollection(StatementIndex stindex,
const CqlLeaseExchange& leaseExchange = static_cast<CqlLeaseExchange>(*exchange);
statement = cass_prepared_bind(dbconn_.statements_[stindex]);
+ if (NULL == statement) {
+ isc_throw(DbOperationError, "unable to bind statement");
+ }
CqlLeaseMgr::bindData(statement, stindex, data, leaseExchange);
future = cass_session_execute(dbconn_.session_, statement);
+ if (NULL == future) {
+ cass_statement_free(statement);
+ isc_throw(DbOperationError, "unable to execute statement");
+ }
cass_future_wait(future);
std::string error;
dbconn_.checkStatementError(error, future, "unable to GET");
@@ -1299,7 +1310,6 @@ CqlLeaseMgr::getLease(StatementIndex stindex, CqlDataArray& data,
}
}
-
void
CqlLeaseMgr::getLease(StatementIndex stindex, CqlDataArray& data,
Lease6Ptr& result) const {
@@ -1340,7 +1350,6 @@ CqlLeaseMgr::getLease4(const isc::asiolink::IOAddress& addr) const {
return (result);
}
-
Lease4Collection
CqlLeaseMgr::getLease4(const HWAddr& hwaddr) const {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
@@ -1359,7 +1368,6 @@ CqlLeaseMgr::getLease4(const HWAddr& hwaddr) const {
return (result);
}
-
Lease4Ptr
CqlLeaseMgr::getLease4(const HWAddr& hwaddr, SubnetID subnet_id) const {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
@@ -1382,7 +1390,6 @@ CqlLeaseMgr::getLease4(const HWAddr& hwaddr, SubnetID subnet_id) const {
return (result);
}
-
Lease4Collection
CqlLeaseMgr::getLease4(const ClientId& clientid) const {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
@@ -1438,7 +1445,6 @@ CqlLeaseMgr::getLease4(const ClientId& clientid, SubnetID subnet_id) const {
return (result);
}
-
Lease6Ptr
CqlLeaseMgr::getLease6(Lease::Type lease_type,
const isc::asiolink::IOAddress& addr) const {
@@ -1470,7 +1476,6 @@ CqlLeaseMgr::getLease6(Lease::Type lease_type,
return (result);
}
-
Lease6Collection
CqlLeaseMgr::getLeases6(Lease::Type lease_type,
const DUID& duid, uint32_t iaid) const {
@@ -1596,10 +1601,17 @@ CqlLeaseMgr::updateLeaseCommon(StatementIndex stindex,
CassFuture* future = NULL;
statement = cass_prepared_bind(dbconn_.statements_[stindex]);
+ if (NULL == statement) {
+ isc_throw(DbOperationError, "unable to bind statement");
+ }
CqlLeaseMgr::bindData(statement, stindex, data, exchange);
future = cass_session_execute(dbconn_.session_, statement);
+ if (NULL == future) {
+ cass_statement_free(statement);
+ isc_throw(DbOperationError, "unable to execute statement");
+ }
cass_future_wait(future);
std::string error;
dbconn_.checkStatementError(error, future, stindex, "unable to UPDATE");
@@ -1616,7 +1628,6 @@ CqlLeaseMgr::updateLeaseCommon(StatementIndex stindex,
cass_statement_free(statement);
}
-
void
CqlLeaseMgr::updateLease4(const Lease4Ptr& lease) {
const StatementIndex stindex = UPDATE_LEASE4;
@@ -1674,10 +1685,17 @@ CqlLeaseMgr::deleteLeaseCommon(StatementIndex stindex,
CassFuture* future = NULL;
statement = cass_prepared_bind(dbconn_.statements_[stindex]);
+ if (NULL == statement) {
+ isc_throw(DbOperationError, "unable to bind statement");
+ }
CqlLeaseMgr::bindData(statement, stindex, data, exchange);
future = cass_session_execute(dbconn_.session_, statement);
+ if (NULL == future) {
+ cass_statement_free(statement);
+ isc_throw(DbOperationError, "unable to execute statement");
+ }
cass_future_wait(future);
std::string error;
dbconn_.checkStatementError(error, future, stindex, "unable to DELETE");
@@ -1781,9 +1799,9 @@ CqlLeaseMgr::deleteExpiredReclaimedLeasesCommon(const uint32_t secs,
return (result);
}
-string
+std::string
CqlLeaseMgr::getName() const {
- string name = "";
+ std::string name = "";
try {
name = dbconn_.getParameter("name");
} catch (...) {
@@ -1792,9 +1810,9 @@ CqlLeaseMgr::getName() const {
return (name);
}
-string
+std::string
CqlLeaseMgr::getDescription() const {
- return (string("Cassandra Database"));
+ return std::string("Cassandra Database");
}
pair<uint32_t, uint32_t>
@@ -1808,8 +1826,15 @@ CqlLeaseMgr::getVersion() const {
CassFuture* future = NULL;
statement = cass_prepared_bind(dbconn_.statements_[GET_VERSION]);
+ if (NULL == statement) {
+ isc_throw(DbOperationError, "unable to bind statement");
+ }
future = cass_session_execute(dbconn_.session_, statement);
+ if (NULL == future) {
+ cass_statement_free(statement);
+ isc_throw(DbOperationError, "unable to execute statement");
+ }
cass_future_wait(future);
std::string error;
dbconn_.checkStatementError(error, future, "unable to GET");
diff --git a/src/lib/dhcpsrv/cql_lease_mgr.h b/src/lib/dhcpsrv/cql_lease_mgr.h
index 0c5f00dfc5..618b864e7f 100644
--- a/src/lib/dhcpsrv/cql_lease_mgr.h
+++ b/src/lib/dhcpsrv/cql_lease_mgr.h
@@ -33,17 +33,17 @@ namespace dhcp {
/// This vector is passed directly into the
/// CQL execute call.
///
-/// Note that the data values are stored as pointers. These pointers need to
-/// valid for the duration of the CQL statement execution. In other
-/// words populating them with pointers to values that go out of scope before
-/// statement is executed is a bad idea.
-
+/// Note that the data values are stored as pointers. These pointers need
+/// to be valid for the duration of the CQL statement execution. In other
+/// words populating them with pointers to values that go out of scope
+/// before statement is executed is a bad idea.
struct CqlDataArray {
- /// @brief Vector of pointers to the data values.
+ /// Add void pointer to a vector of pointers to the data values.
std::vector<void*> values_;
void add(void* value) {
values_.push_back(value);
}
+ /// Remove void pointer from a vector of pointers to the data values.
void remove(int index) {
if (values_.size() <= index) {
isc_throw(BadValue, "Index " << index << " out of bounds: [0, " <<
@@ -307,7 +307,6 @@ public:
virtual void getExpiredLeases6(Lease6Collection& ,
const size_t ) const;
-
/// @brief Returns a collection of expired DHCPv4 leases.
///
/// This method returns at most @c max_leases expired leases. The leases
@@ -321,7 +320,6 @@ public:
virtual void getExpiredLeases4(Lease4Collection& ,
const size_t ) const;
-
/// @brief Updates IPv4 lease.
///
/// Updates the record of the lease in the database (as identified by the
@@ -415,7 +413,6 @@ public:
/// This is a no-op for Cassandra.
virtual void rollback();
-
/// @brief Statement Tags
///
/// The contents of the enum are indexes into the list of compiled SQL
@@ -462,8 +459,8 @@ public:
/// @param param TODO
/// @param exchange Exchange object to use
/// @param type TODO
- static void getDataType(const StatementIndex stindex, int param,
- const SqlExchange& exchange, ExchangeDataType& type);
+ static ExchangeDataType getDataType(const StatementIndex stindex, int param,
+ const SqlExchange& exchange);
/// @brief TODO
///
diff --git a/src/lib/dhcpsrv/lease_mgr.h b/src/lib/dhcpsrv/lease_mgr.h
index 065416391d..c31f2dfa12 100755
--- a/src/lib/dhcpsrv/lease_mgr.h
+++ b/src/lib/dhcpsrv/lease_mgr.h
@@ -82,18 +82,69 @@ enum ExchangeDataTypeIO {
/// @brief Used to map the column name with internal backend storage data types.
struct ExchangeColumnInfo {
- ExchangeColumnInfo () : column_(NULL), type_io_(EXCHANGE_DATA_TYPE_IO_IN), type_(EXCHANGE_DATA_TYPE_NONE) {};
- ExchangeColumnInfo (const char *column, ExchangeDataTypeIO type_io, ExchangeDataType type) : column_(column), type_io_(type_io), type_(type) {};
- const char* column_;
+ ExchangeColumnInfo () : name_(""), index_(0), type_io_(EXCHANGE_DATA_TYPE_IO_IN),
+ type_(EXCHANGE_DATA_TYPE_NONE) {};
+ ExchangeColumnInfo (const char* name, const uint32_t index,
+ const ExchangeDataTypeIO type_io, const ExchangeDataType type) :
+ name_(name), index_(index), type_io_(type_io), type_(type) {};
+ std::string name_;
+ uint32_t index_;
ExchangeDataTypeIO type_io_;
ExchangeDataType type_;
};
+typedef boost::shared_ptr<ExchangeColumnInfo> ExchangeColumnInfoPtr;
+
+typedef boost::multi_index_container<
+ // Container comprises elements of ExchangeColumnInfoPtr type.
+ ExchangeColumnInfoPtr,
+ // Here we start enumerating various indexes.
+ boost::multi_index::indexed_by<
+ // Sequenced index allows accessing elements in the same way as elements
+ // in std::list.
+ // Sequenced is an index #0.
+ boost::multi_index::sequenced<>,
+ // Start definition of index #1.
+ boost::multi_index::hashed_non_unique<
+ boost::multi_index::member<
+ ExchangeColumnInfo,
+ std::string,
+ &ExchangeColumnInfo::name_
+ >
+ >,
+ // Start definition of index #2.
+ boost::multi_index::hashed_non_unique<
+ boost::multi_index::member<
+ ExchangeColumnInfo,
+ uint32_t,
+ &ExchangeColumnInfo::index_
+ >
+ >
+ >
+> ExchangeColumnInfoContainer;
+
+/// Pointer to the ExchangeColumnInfoContainer object.
+typedef boost::shared_ptr<ExchangeColumnInfoContainer> ExchangeColumnInfoContainerPtr;
+/// Type of the index #1 - name.
+typedef ExchangeColumnInfoContainer::nth_index<1>::type ExchangeColumnInfoContainerName;
+/// Pair of iterators to represent the range of ExchangeColumnInfo having the
+/// same name value. The first element in this pair represents
+/// the beginning of the range, the second element represents the end.
+typedef std::pair<ExchangeColumnInfoContainerName::const_iterator,
+ ExchangeColumnInfoContainerName::const_iterator> ExchangeColumnInfoContainerNameRange;
+/// Type of the index #2 - index.
+typedef ExchangeColumnInfoContainer::nth_index<2>::type ExchangeColumnInfoContainerIndex;
+/// Pair of iterators to represent the range of ExchangeColumnInfo having the
+/// same index value. The first element in this pair represents
+/// the beginning of the range, the second element represents the end.
+typedef std::pair<ExchangeColumnInfoContainerIndex::const_iterator,
+ ExchangeColumnInfoContainerIndex::const_iterator> ExchangeColumnInfoContainerIndexRange;
+
class SqlExchange {
public:
SqlExchange () {};
virtual ~SqlExchange() {};
- std::vector<ExchangeColumnInfo> parameters_; ///< Column names and types
+ ExchangeColumnInfoContainer parameters_; ///< Column names and types
};
/// @brief Abstract Lease Manager
///
diff --git a/src/lib/dhcpsrv/tests/cql_lease_mgr_unittest.cc b/src/lib/dhcpsrv/tests/cql_lease_mgr_unittest.cc
index 4923c43068..ffc31e8b55 100644
--- a/src/lib/dhcpsrv/tests/cql_lease_mgr_unittest.cc
+++ b/src/lib/dhcpsrv/tests/cql_lease_mgr_unittest.cc
@@ -1,8 +1,19 @@
-// Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2015 - 2016 Deutsche Telekom AG.
//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+// Author: Razvan Becheriu <razvan.becheriu@qualitance.com>
+// Author: Andrei Pavel <andrei.pavel@qualitance.com>
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
#include <config.h>
@@ -279,7 +290,7 @@ TEST_F(CqlLeaseMgrTest, getLease4ClientIdSubnetId) {
/// @brief Basic Lease4 Checks
///
-/// Checks that the addLease, getLease4(by address), getLease4(hwaddr,subnet_id),
+/// Checks that the addLease, getLease4(by address), getLease4(hwaddr, subnet_id),
/// updateLease4() and deleteLease (IPv4 address) can handle NULL client-id.
/// (client-id is optional and may not be present)
TEST_F(CqlLeaseMgrTest, lease4NullClientId) {