static constexpr StatementTag GET_LEASE6_ADDR = "GET_LEASE6_ADDR";
static constexpr StatementTag GET_LEASE6_DUID_IAID = "GET_LEASE6_DUID_IAID";
static constexpr StatementTag GET_LEASE6_DUID_IAID_SUBID = "GET_LEASE6_DUID_IAID_SUBID";
+ static constexpr StatementTag GET_LEASE6_LIMIT = "GET_LEASE6_LIMIT";
+ static constexpr StatementTag GET_LEASE6_PAGE = "GET_LEASE6_PAGE";
+ static constexpr StatementTag GET_LEASE6_RANGE = "GET_LEASE6_RANGE";
// @}
private:
constexpr StatementTag CqlLease6Exchange::GET_LEASE6_ADDR;
constexpr StatementTag CqlLease6Exchange::GET_LEASE6_DUID_IAID;
constexpr StatementTag CqlLease6Exchange::GET_LEASE6_DUID_IAID_SUBID;
+constexpr StatementTag CqlLease6Exchange::GET_LEASE6_LIMIT;
+constexpr StatementTag CqlLease6Exchange::GET_LEASE6_PAGE;
+constexpr StatementTag CqlLease6Exchange::GET_LEASE6_RANGE;
StatementMap CqlLease6Exchange::tagged_statements_ = {
"AND subnet_id = ? "
"ALLOW FILTERING "}},
+ // Get range of IPv6 leases from first lease with a limit (paging)
+ {GET_LEASE6_LIMIT,
+ {GET_LEASE6_LIMIT,
+ "SELECT "
+ "address, valid_lifetime, expire, subnet_id, pref_lifetime, duid, iaid, "
+ "lease_type, prefix_len, fqdn_fwd, fqdn_rev, hostname, hwaddr, hwtype, "
+ "hwaddr_source, state "
+ "FROM lease6 "
+ "LIMIT ? "
+ "ALLOW FILTERING "}},
+
+ // Get range of IPv6 leases from address with a limit (paging)
+ {GET_LEASE6_PAGE,
+ {GET_LEASE6_PAGE,
+ "SELECT "
+ "address, valid_lifetime, expire, subnet_id, pref_lifetime, duid, iaid, "
+ "lease_type, prefix_len, fqdn_fwd, fqdn_rev, hostname, hwaddr, hwtype, "
+ "hwaddr_source, state "
+ "FROM lease6 "
+ "WHERE TOKEN(address) > TOKEN(?) "
+ "LIMIT ? "
+ "ALLOW FILTERING "}},
+
+ // Get range of IPv6 leases between two addresses
+ {GET_LEASE6_RANGE,
+ {GET_LEASE6_RANGE,
+ "SELECT "
+ "address, valid_lifetime, expire, subnet_id, pref_lifetime, duid, iaid, "
+ "lease_type, prefix_len, fqdn_fwd, fqdn_rev, hostname, hwaddr, hwtype, "
+ "hwaddr_source, state "
+ "FROM lease6 "
+ "WHERE address >= ? "
+ "AND address <= ? "
+ "ALLOW FILTERING "}},
};
CqlLease6Exchange::CqlLease6Exchange(const CqlConnection &connection)
void
CqlLease6Exchange::getLeaseCollection(StatementTag &statement_tag, AnyArray &data,
Lease6Collection &result) {
- LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_CQL_GET_ADDR4)
- .arg(statement_tag);
-
AnyArray collection = executeSelect(connection_, data, statement_tag);
// Transfer Lease6 objects to result.
isc_throw(NotImplemented, "getLeases6() is not implemented");
}
+Lease6Collection
+CqlLeaseMgr::getLeases6(const asiolink::IOAddress& lower_bound_address,
+ const LeasePageSize& page_size) const {
+ if (page_size.page_size_ == 0) {
+ isc_throw(OutOfRange, "page size of retrieved leases must not be 0");
+ }
+
+ if (page_size.page_size_ > std::numeric_limits<uint32_t>::max()) {
+ isc_throw(OutOfRange, "page size of retrieved leases must not be greater than "
+ << std::numeric_limits<uint32_t>::max());
+ }
+
+ LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_CQL_GET_PAGE6)
+ .arg(page_size.page_size_)
+ .arg(lower_bound_address.toText());
+
+ AnyArray data;
+
+ std::string lb_address_data;
+ if (!lower_bound_address.isV6Zero()) {
+ lb_address_data = lower_bound_address.toText();
+ if (lb_address_data.size() > ADDRESS6_TEXT_MAX_LEN) {
+ isc_throw(BadValue,
+ "CqlLeaseMgr::getLeases6(lower_bound_address, page_size): "
+ "address "
+ << lb_address_data << " of length " << lb_address_data.size()
+ << " exceeds maximum allowed length of "
+ << ADDRESS6_TEXT_MAX_LEN);
+ }
+ data.add(&lb_address_data);
+ }
+
+ cass_int32_t page_size_data = static_cast<cass_int32_t>(page_size.page_size_);
+ data.add(&page_size_data);
+
+ // Get the leases.
+ Lease6Collection result;
+ std::unique_ptr<CqlLease6Exchange> exchange6(new CqlLease6Exchange(dbconn_));
+ exchange6->getLeaseCollection(lower_bound_address.isV6Zero() ?
+ CqlLease6Exchange::GET_LEASE6_LIMIT :
+ CqlLease6Exchange::GET_LEASE6_PAGE,
+ data, result);
+
+ return (result);
+}
+
void
CqlLeaseMgr::getExpiredLeases4(Lease4Collection &expired_leases,
const size_t max_leases) const {
/// this backend.
virtual Lease6Collection getLeases6() const override;
+ /// @brief Returns range of IPv6 leases using paging.
+ ///
+ /// This method implements paged browsing of the lease database. The first
+ /// parameter specifies a page size. The second parameter is optional and
+ /// specifies the starting address of the range. This address is excluded
+ /// from the returned range. The IPv6 zero address (default) denotes that
+ /// the first page should be returned. There is no guarantee about the
+ /// order of returned leases.
+ ///
+ /// The typical usage of this method is as follows:
+ /// - Get the first page of leases by specifying IPv6 zero address as the
+ /// beginning of the range.
+ /// - Last address of the returned range should be used as a starting
+ /// address for the next page in the subsequent call.
+ /// - If the number of leases returned is lower than the page size, it
+ /// indicates that the last page has been retrieved.
+ /// - If there are no leases returned it indicates that the previous page
+ /// was the last page.
+ ///
+ /// @param lower_bound_address IPv4 address used as lower bound for the
+ /// returned range.
+ /// @param page_size maximum size of the page returned.
+ ///
+ /// @return Lease collection (may be empty if no IPv6 lease found).
+ virtual Lease6Collection
+ getLeases6(const asiolink::IOAddress& lower_bound_address,
+ const LeasePageSize& page_size) const override;
+
/// @brief Returns a collection of expired DHCPv4 leases.
///
/// This method returns at most @c max_leases expired leases. The leases
A debug message issued when the server is attempting to obtain a page
of leases beginning with the specified address.
+% DHCPSRV_CQL_GET_PAGE6 obtaining at most %1 IPv6 leases starting from address %2
+A debug message issued when the server is attempting to obtain a page
+of leases beginning with the specified address.
+
% DHCPSRV_CQL_GET_SUBID4 obtaining IPv4 leases for subnet ID %1
A debug message issued when the server is attempting to obtain all IPv4
leases for a given subnet identifier from the Cassandra database.
A debug message issued when the server is attempting to obtain a page
of leases beginning with the specified address.
+% DHCPSRV_MEMFILE_GET_PAGE6 obtaining at most %1 IPv6 leases starting from address %2
+A debug message issued when the server is attempting to obtain a page
+of leases beginning with the specified address.
+
% DHCPSRV_MEMFILE_GET6 obtaining all IPv6 leases
A debug message issued when the server is attempting to obtain all IPv6
leases from the memory file database.
A debug message issued when the server is attempting to obtain a page
of leases beginning with the specified address.
+% DHCPSRV_MYSQL_GET_PAGE6 obtaining at most %1 IPv6 leases starting from address %2
+A debug message issued when the server is attempting to obtain a page
+of leases beginning with the specified address.
+
% DHCPSRV_MYSQL_GET_ADDR6 obtaining IPv6 lease for address %1, lease type %2
A debug message issued when the server is attempting to obtain an IPv6
lease from the MySQL database for the specified address.
A debug message issued when the server is attempting to obtain a page
of leases beginning with the specified address.
+% DHCPSRV_PGSQL_GET_PAGE6 obtaining at most %1 IPv6 leases starting from address %2
+A debug message issued when the server is attempting to obtain a page
+of leases beginning with the specified address.
+
% DHCPSRV_PGSQL_GET_SUBID4 obtaining IPv4 leases for subnet ID %1
A debug message issued when the server is attempting to obtain all IPv4
leases for a given subnet identifier from the PostgreSQL database.
/// @return Lease collection (may be empty if no IPv6 lease found).
virtual Lease6Collection getLeases6() const = 0;
+ /// @brief Returns range of IPv6 leases using paging.
+ ///
+ /// This method implements paged browsing of the lease database. The first
+ /// parameter specifies a page size. The second parameter is optional and
+ /// specifies the starting address of the range. This address is excluded
+ /// from the returned range. The IPv6 zero address (default) denotes that
+ /// the first page should be returned. There is no guarantee about the
+ /// order of returned leases.
+ ///
+ /// The typical usage of this method is as follows:
+ /// - Get the first page of leases by specifying IPv6 zero address as the
+ /// beginning of the range.
+ /// - Last address of the returned range should be used as a starting
+ /// address for the next page in the subsequent call.
+ /// - If the number of leases returned is lower than the page size, it
+ /// indicates that the last page has been retrieved.
+ /// - If there are no leases returned it indicates that the previous page
+ /// was the last page.
+ ///
+ /// @param lower_bound_address IPv4 address used as lower bound for the
+ /// returned range.
+ /// @param page_size maximum size of the page returned.
+ ///
+ /// @return Lease collection (may be empty if no IPv6 lease found).
+ virtual Lease6Collection
+ getLeases6(const asiolink::IOAddress& lower_bound_address,
+ const LeasePageSize& page_size) const = 0;
+
/// @brief Returns a collection of expired DHCPv4 leases.
///
/// This method returns at most @c max_leases expired leases. The leases
return (collection);
}
+Lease6Collection
+Memfile_LeaseMgr::getLeases6(const asiolink::IOAddress& lower_bound_address,
+ const LeasePageSize& page_size) const {
+ LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MEMFILE_GET_PAGE6)
+ .arg(page_size.page_size_)
+ .arg(lower_bound_address.toText());
+
+ Lease6Collection collection;
+ const Lease6StorageAddressIndex& idx = storage6_.get<AddressIndexTag>();
+ Lease6StorageAddressIndex::const_iterator lb = idx.lower_bound(lower_bound_address);
+
+ // Exclude the lower bound address specified by the caller.
+ if ((lb != idx.end()) && ((*lb)->addr_ == lower_bound_address)) {
+ ++lb;
+ }
+
+ // Return all other leases being within the page size.
+ for (auto lease = lb;
+ (lease != idx.end()) && (std::distance(lb, lease) < page_size.page_size_);
+ ++lease) {
+ collection.push_back(Lease6Ptr(new Lease6(**lease)));
+ }
+
+ return (collection);
+}
+
void
Memfile_LeaseMgr::getExpiredLeases4(Lease4Collection& expired_leases,
const size_t max_leases) const {
/// @return Lease collection (may be empty if no IPv6 lease found).
virtual Lease6Collection getLeases6() const;
+ /// @brief Returns range of IPv6 leases using paging.
+ ///
+ /// This method implements paged browsing of the lease database. The first
+ /// parameter specifies a page size. The second parameter is optional and
+ /// specifies the starting address of the range. This address is excluded
+ /// from the returned range. The IPv6 zero address (default) denotes that
+ /// the first page should be returned. There is no guarantee about the
+ /// order of returned leases.
+ ///
+ /// The typical usage of this method is as follows:
+ /// - Get the first page of leases by specifying IPv6 zero address as the
+ /// beginning of the range.
+ /// - Last address of the returned range should be used as a starting
+ /// address for the next page in the subsequent call.
+ /// - If the number of leases returned is lower than the page size, it
+ /// indicates that the last page has been retrieved.
+ /// - If there are no leases returned it indicates that the previous page
+ /// was the last page.
+ ///
+ /// @param lower_bound_address IPv4 address used as lower bound for the
+ /// returned range.
+ /// @param page_size maximum size of the page returned.
+ ///
+ /// @return Lease collection (may be empty if no IPv6 lease found).
+ virtual Lease6Collection
+ getLeases6(const asiolink::IOAddress& lower_bound_address,
+ const LeasePageSize& page_size) const;
+
/// @brief Returns a collection of expired DHCPv4 leases.
///
/// This method returns at most @c max_leases expired leases. The leases
"FROM lease6 "
"WHERE duid = ? AND iaid = ? AND subnet_id = ? "
"AND lease_type = ?"},
+ {MySqlLeaseMgr::GET_LEASE6_PAGE,
+ "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 address > ? "
+ "ORDER BY address "
+ "LIMIT ?"},
+ {MySqlLeaseMgr::GET_LEASE6_RANGE,
+ "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 address >= ? AND address <= ?"},
{MySqlLeaseMgr::GET_LEASE6_SUBID,
"SELECT address, duid, valid_lifetime, "
"expire, subnet_id, pref_lifetime, "
return (result);
}
+Lease6Collection
+MySqlLeaseMgr::getLeases6(const asiolink::IOAddress& lower_bound_address,
+ const LeasePageSize& page_size) const {
+ LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MYSQL_GET_PAGE6)
+ .arg(page_size.page_size_)
+ .arg(lower_bound_address.toText());
+
+ // Prepare WHERE clause
+ MYSQL_BIND inbind[2];
+ memset(inbind, 0, sizeof(inbind));
+
+ // In IPv6 we compare addresses represented as strings. The IPv6 zero address
+ // is ::, so it is greater than any other address. In this special case, we
+ // just use 0 for comparison which should be lower than any real IPv6 address.
+ std::string lb_address_data = "0";
+ if (!lower_bound_address.isV6Zero()) {
+ lb_address_data = lower_bound_address.toText();
+ }
+
+ // Bind lower bound address
+ unsigned long lb_address_data_size = lb_address_data.size();
+ inbind[0].buffer_type = MYSQL_TYPE_STRING;
+ inbind[0].buffer = const_cast<char*>(lb_address_data.c_str());
+ inbind[0].buffer_length = lb_address_data_size;
+ inbind[0].length = &lb_address_data_size;
+
+ // Bind page size value
+ size_t* ps = const_cast<size_t*>(&page_size.page_size_);
+ inbind[1].buffer_type = MYSQL_TYPE_LONG;
+ inbind[1].buffer = reinterpret_cast<char*>(ps);
+ inbind[1].is_unsigned = MLM_TRUE;
+
+ // Get the leases
+ Lease6Collection result;
+ getLeaseCollection(GET_LEASE6_PAGE, inbind, result);
+
+ return (result);
+}
+
void
MySqlLeaseMgr::getExpiredLeases4(Lease4Collection& expired_leases,
const size_t max_leases) const {
/// @return Lease collection (may be empty if no IPv6 lease found).
virtual Lease6Collection getLeases6() const;
+ /// @brief Returns range of IPv6 leases using paging.
+ ///
+ /// This method implements paged browsing of the lease database. The first
+ /// parameter specifies a page size. The second parameter is optional and
+ /// specifies the starting address of the range. This address is excluded
+ /// from the returned range. The IPv6 zero address (default) denotes that
+ /// the first page should be returned. There is no guarantee about the
+ /// order of returned leases.
+ ///
+ /// The typical usage of this method is as follows:
+ /// - Get the first page of leases by specifying IPv6 zero address as the
+ /// beginning of the range.
+ /// - Last address of the returned range should be used as a starting
+ /// address for the next page in the subsequent call.
+ /// - If the number of leases returned is lower than the page size, it
+ /// indicates that the last page has been retrieved.
+ /// - If there are no leases returned it indicates that the previous page
+ /// was the last page.
+ ///
+ /// @param lower_bound_address IPv4 address used as lower bound for the
+ /// returned range.
+ /// @param page_size maximum size of the page returned.
+ ///
+ /// @return Lease collection (may be empty if no IPv6 lease found).
+ virtual Lease6Collection
+ getLeases6(const asiolink::IOAddress& lower_bound_address,
+ const LeasePageSize& page_size) const;
+
/// @brief Returns a collection of expired DHCPv4 leases.
///
/// This method returns at most @c max_leases expired leases. The leases
GET_LEASE4_CLIENTID_SUBID, // Get lease4 by client ID & subnet ID
GET_LEASE4_HWADDR, // Get lease4 by HW address
GET_LEASE4_HWADDR_SUBID, // Get lease4 by HW address & subnet ID
- GET_LEASE4_SUBID, // Get IPv4 leases by subnet ID
GET_LEASE4_PAGE, // Get page of leases beginning with an address
GET_LEASE4_RANGE, // Get range of leases between addresses
+ GET_LEASE4_SUBID, // Get IPv4 leases by subnet ID
GET_LEASE4_EXPIRE, // Get lease4 by expiration.
GET_LEASE6, // Get all IPv6 leases
GET_LEASE6_ADDR, // Get lease6 by address
GET_LEASE6_DUID_IAID, // Get lease6 by DUID and IAID
GET_LEASE6_DUID_IAID_SUBID, // Get lease6 by DUID, IAID and subnet ID
+ GET_LEASE6_PAGE, // Get page of leases beginning with an address
+ GET_LEASE6_RANGE, // Get range of leases between addresses
GET_LEASE6_SUBID, // Get IPv6 leases by subnet ID
GET_LEASE6_EXPIRE, // Get lease6 by expiration.
INSERT_LEASE4, // Add entry to lease4 table
"WHERE lease_type = $1 "
"AND duid = $2 AND iaid = $3 AND subnet_id = $4"},
+ // GET_LEASE6_PAGE
+ { 2, { OID_VARCHAR, OID_INT8 },
+ "get_lease6_page",
+ "SELECT address, duid, valid_lifetime, "
+ "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
+ "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
+ "hwaddr, hwtype, hwaddr_source, "
+ "state "
+ "FROM lease6 "
+ "WHERE address > $1 "
+ "ORDER BY address "
+ "LIMIT $2"},
+
+ // GET_LEASE6_RANGE
+ { 2, { OID_VARCHAR, OID_VARCHAR },
+ "get_lease6_range",
+ "SELECT address, duid, valid_lifetime, "
+ "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
+ "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
+ "hwaddr, hwtype, hwaddr_source, "
+ "state "
+ "FROM lease6 "
+ "WHERE address >= $1 AND address <= $2"},
+
// GET_LEASE6_SUBID
{ 1, { OID_INT8 },
"get_lease6_subid",
return (result);
}
+Lease6Collection
+PgSqlLeaseMgr::getLeases6(const asiolink::IOAddress& lower_bound_address,
+ const LeasePageSize& page_size) const {
+ LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_PGSQL_GET_PAGE6)
+ .arg(page_size.page_size_)
+ .arg(lower_bound_address.toText());
+
+ // Prepare WHERE clause
+ PsqlBindArray bind_array;
+
+ // In IPv6 we compare addresses represented as strings. The IPv6 zero address
+ // is ::, so it is greater than any other address. In this special case, we
+ // just use 0 for comparison which should be lower than any real IPv6 address.
+ std::string lb_address_data = "0";
+ if (!lower_bound_address.isV6Zero()) {
+ lb_address_data = lower_bound_address.toText();
+ }
+
+ // Bind lower bound address
+ bind_array.add(lb_address_data);
+
+ // Bind page size value
+ std::string page_size_data = boost::lexical_cast<std::string>(page_size.page_size_);
+ bind_array.add(page_size_data);
+
+ // Get the leases
+ Lease6Collection result;
+ getLeaseCollection(GET_LEASE6_PAGE, bind_array, result);
+
+ return (result);
+}
+
void
PgSqlLeaseMgr::getExpiredLeases4(Lease4Collection& expired_leases,
const size_t max_leases) const {
/// @return Lease collection (may be empty if no IPv6 lease found).
virtual Lease6Collection getLeases6() const;
+ /// @brief Returns range of IPv6 leases using paging.
+ ///
+ /// This method implements paged browsing of the lease database. The first
+ /// parameter specifies a page size. The second parameter is optional and
+ /// specifies the starting address of the range. This address is excluded
+ /// from the returned range. The IPv6 zero address (default) denotes that
+ /// the first page should be returned. There is no guarantee about the
+ /// order of returned leases.
+ ///
+ /// The typical usage of this method is as follows:
+ /// - Get the first page of leases by specifying IPv6 zero address as the
+ /// beginning of the range.
+ /// - Last address of the returned range should be used as a starting
+ /// address for the next page in the subsequent call.
+ /// - If the number of leases returned is lower than the page size, it
+ /// indicates that the last page has been retrieved.
+ /// - If there are no leases returned it indicates that the previous page
+ /// was the last page.
+ ///
+ /// @param lower_bound_address IPv4 address used as lower bound for the
+ /// returned range.
+ /// @param page_size maximum size of the page returned.
+ ///
+ /// @return Lease collection (may be empty if no IPv6 lease found).
+ virtual Lease6Collection
+ getLeases6(const asiolink::IOAddress& lower_bound_address,
+ const LeasePageSize& page_size) const;
+
/// @brief Returns a collection of expired DHCPv4 leases.
///
/// This method returns at most @c max_leases expired leases. The leases
GET_LEASE6_ADDR, // Get lease6 by address
GET_LEASE6_DUID_IAID, // Get lease6 by DUID and IAID
GET_LEASE6_DUID_IAID_SUBID, // Get lease6 by DUID, IAID and subnet ID
+ GET_LEASE6_PAGE, // Get page of IPv6 leases beginning with an address
+ GET_LEASE6_RANGE, // Get range of IPv6 leases between addresses
GET_LEASE6_SUBID, // Get IPv6 leases by subnet ID
GET_LEASE6_EXPIRE, // Get expired lease6
INSERT_LEASE4, // Add entry to lease4 table
testGetLease6DuidIaidSubnetIdSize();
}
+// Test that a range of IPv6 leases is returned with paging.
+TEST_F(CqlLeaseMgrTest, getLeases6Paged) {
+ testGetLeases6Paged();
+}
+
/// @brief Lease6 update tests
///
/// Checks that we are able to update a lease in the database.
Lease4Collection all_leases;
IOAddress last_address = IOAddress("0.0.0.0");
- for (auto i = 0; i < 1000; ++i) {
+ for (auto i = 0; i < 4; ++i) {
Lease4Collection page = lmptr_->getLeases4(last_address, LeasePageSize(3));
// Collect leases in a common structure. They may be out of order.
ASSERT_EQ(leases.size(), returned.size());
}
+void
+GenericLeaseMgrTest::testGetLeases6Paged() {
+ // Get the leases to be used for the test and add to the database.
+ vector<Lease6Ptr> leases = createLeases6();
+ for (size_t i = 0; i < leases.size(); ++i) {
+ EXPECT_TRUE(lmptr_->addLease(leases[i]));
+ }
+
+ Lease6Collection all_leases;
+
+ IOAddress last_address = IOAddress::IPV6_ZERO_ADDRESS();
+ for (auto i = 0; i < 4; ++i) {
+ Lease6Collection page = lmptr_->getLeases6(last_address, LeasePageSize(3));
+
+ // Collect leases in a common structure. They may be out of order.
+ for (Lease6Ptr lease : page) {
+ all_leases.push_back(lease);
+ }
+
+ // Empty page means there are no more leases.
+ if (page.empty()) {
+ break;
+
+ } else {
+ // Record last returned address because it is going to be used
+ // as an argument for the next call.
+ last_address = page[page.size() - 1]->addr_;
+ }
+ }
+
+ // Make sure that we got exactly the number of leases that we earlier
+ // stored in the database.
+ EXPECT_EQ(leases.size(), all_leases.size());
+
+ // Make sure that all leases that we stored in the lease database
+ // have been retrieved.
+ for (Lease6Ptr lease : leases) {
+ bool found = false;
+ for (Lease6Ptr returned_lease : all_leases) {
+ if (lease->addr_ == returned_lease->addr_) {
+ found = true;
+ break;
+ }
+ }
+ EXPECT_TRUE(found) << "lease for address " << lease->addr_.toText()
+ << " was not returned in any of the pages";
+ }
+}
+
void
GenericLeaseMgrTest::testGetLeases6DuidIaid() {
// Get the leases to be used for the test.
/// @brief Test method which returns all IPv6 leases.
void testGetLeases6();
+ /// @brief Test method which returns range of IPv6 leases with paging.
+ void testGetLeases6Paged();
+
/// @brief Basic Lease4 Checks
///
/// Checks that the addLease, getLease4(by address), getLease4(hwaddr,subnet_id),
return (Lease6Collection());
}
+ /// @brief Returns range of IPv6 leases using paging.
+ ///
+ /// This method implements paged browsing of the lease database. The first
+ /// parameter specifies a page size. The second parameter is optional and
+ /// specifies the starting address of the range. This address is excluded
+ /// from the returned range. The IPv6 zero address (default) denotes that
+ /// the first page should be returned. There is no guarantee about the
+ /// order of returned leases.
+ ///
+ /// The typical usage of this method is as follows:
+ /// - Get the first page of leases by specifying IPv6 zero address as the
+ /// beginning of the range.
+ /// - Last address of the returned range should be used as a starting
+ /// address for the next page in the subsequent call.
+ /// - If the number of leases returned is lower than the page size, it
+ /// indicates that the last page has been retrieved.
+ /// - If there are no leases returned it indicates that the previous page
+ /// was the last page.
+ ///
+ /// @param lower_bound_address IPv4 address used as lower bound for the
+ /// returned range.
+ /// @param page_size maximum size of the page returned.
+ ///
+ /// @return Lease collection (may be empty if no IPv6 lease found).
+ virtual Lease6Collection
+ getLeases6(const asiolink::IOAddress& /* lower_bound_address */,
+ const LeasePageSize& /* page_size */) const {
+ return (Lease6Collection());
+ };
/// @brief Returns expired DHCPv6 leases.
///
testGetLeases6();
}
+// Test that a range of IPv6 leases is returned with paging.
+TEST_F(MemfileLeaseMgrTest, getLeases6Paged) {
+ startBackend(V6);
+ testGetLeases6Paged();
+}
+
/// @brief Basic Lease6 Checks
///
/// Checks that the addLease, getLease6 (by address) and deleteLease (with an
testGetLeases6();
}
+// Test that a range of IPv6 leases is returned with paging.
+TEST_F(MySqlLeaseMgrTest, getLeases6Paged) {
+ testGetLeases6Paged();
+}
+
/// @brief Basic Lease4 Checks
///
/// Checks that the addLease, getLease4(by address), getLease4(hwaddr,subnet_id),
testGetLeases6();
}
+// Test that a range of IPv6 leases is returned with paging.
+TEST_F(PgSqlLeaseMgrTest, getLeases6Paged) {
+ testGetLeases6Paged();
+}
+
/// @brief Basic Lease4 Checks
///
/// Checks that the addLease, getLease4(by address), getLease4(hwaddr,subnet_id),