/// @param ltype type of lease for which the count is desired. Defaults to
/// Lease::TYPE_V4.
///
- /// @return count of leases
- /// @throw NotImplemented if a derivation does not override this.
+ /// @return number of leases
virtual size_t getClassLeaseCount(const ClientClass& client_class,
- const Lease::Type& ltype = Lease::TYPE_V4) const {
- // For now we throw, ultimately this should be pure virtual.
- isc_throw(NotImplemented, "LeaseMgr::getClassLeaseCount "
- << client_class << ":" << ltype);
- }
+ const Lease::Type& ltype = Lease::TYPE_V4) const = 0;
private:
/// The IOService object, used for all ASIO operations.
/// @param client_class client class for which the count is desired
/// @param ltype type of lease for which the count is desired. Defaults to
/// Lease::TYPE_V4.
+ ///
+ /// @return number of leases
virtual size_t getClassLeaseCount(const ClientClass& client_class,
- const Lease::Type& ltype = Lease::TYPE_V4) const override;
+ const Lease::Type& ltype = Lease::TYPE_V4) const override;
/// @brief Recount the leases per class for V4 leases.
///
{MySqlLeaseMgr::CHECK_LEASE4_LIMITS, "SELECT checkLease4Limits(?)"},
{MySqlLeaseMgr::CHECK_LEASE6_LIMITS, "SELECT checkLease6Limits(?)"},
{MySqlLeaseMgr::IS_JSON_SUPPORTED, "SELECT isJsonSupported()"},
+ {MySqlLeaseMgr::GET_LEASE4_COUNT_BY_CLASS,
+ "SELECT leases "
+ "FROM lease4_stat_by_client_class "
+ "WHERE client_class = ?"},
+ {MySqlLeaseMgr::GET_LEASE6_COUNT_BY_CLASS,
+ "SELECT leases "
+ "FROM lease6_stat_by_client_class "
+ "WHERE client_class = ? AND lease_type = ?"},
} }; // tagged_statements
} // namespace
return json_supported;
}
+size_t
+MySqlLeaseMgr::getClassLeaseCount(const ClientClass& client_class,
+ const Lease::Type& ltype /* = Lease::TYPE_V4*/) const {
+ // Get a context.
+ MySqlLeaseContextAlloc get_context(*this);
+ MySqlLeaseContextPtr ctx = get_context.ctx_;
+
+ // Create bindings.
+ MySqlBindingCollection in_bindings({
+ MySqlBinding::createString(client_class)
+ });
+ if (ltype != Lease::TYPE_V4) {
+ in_bindings.push_back(MySqlBinding::createInteger<uint8_t>(ltype));
+ }
+ MySqlBindingCollection out_bindings({
+ MySqlBinding::createInteger<int64_t>()
+ });
+
+ // Execute the select.
+ StatementIndex const stindex(ltype == Lease::TYPE_V4 ? GET_LEASE4_COUNT_BY_CLASS :
+ GET_LEASE6_COUNT_BY_CLASS);
+ size_t count(0);
+ ctx->conn_.selectQuery(stindex, in_bindings, out_bindings,
+ [&count] (MySqlBindingCollection const& result) {
+ count = result[0]->getInteger<int64_t>();
+ });
+
+ return count;
+}
+
LeaseStatsQueryPtr
MySqlLeaseMgr::startLeaseStatsQuery4() {
// Get a context
CHECK_LEASE4_LIMITS, // Check if allocated IPv4 leases are inside the set limits.
CHECK_LEASE6_LIMITS, // Check if allocated IPv6 leases are inside the set limits.
IS_JSON_SUPPORTED, // Checks if JSON support is enabled in the database.
+ GET_LEASE4_COUNT_BY_CLASS, // Fetches the IPv4 lease count for a given class.
+ GET_LEASE6_COUNT_BY_CLASS, // Fetches the IPv6 lease count for given class and lease type.
NUM_STATEMENTS // Number of statements
};
/// @return true if there is JSON support, false otherwise
bool isJsonSupported() const override;
+ /// @brief Returns the class lease count for a given class and lease type.
+ ///
+ /// @param client_class client class for which the count is desired
+ /// @param ltype type of lease for which the count is desired. Defaults to
+ /// Lease::TYPE_V4.
+ ///
+ /// @return number of leases
+ virtual size_t getClassLeaseCount(const ClientClass& client_class,
+ const Lease::Type& ltype = Lease::TYPE_V4) const override;
+
/// @brief Check Error and Throw Exception
///
/// This method invokes @ref MySqlConnection::checkError.
"is_json_supported",
"SELECT isJsonSupported()" },
+ // GET_LEASE4_COUNT_BY_CLASS
+ { 1, { OID_VARCHAR },
+ "get_lease4_count_by_class",
+ "SELECT leases "
+ "FROM lease4_stat_by_client_class "
+ "WHERE client_class = $1"},
+
+ // GET_LEASE6_COUNT_BY_CLASS
+ { 2, { OID_VARCHAR, OID_INT2 },
+ "get_lease6_count_by_class",
+ "SELECT leases "
+ "FROM lease6_stat_by_client_class "
+ "WHERE client_class = $1 AND lease_type = $2"},
+
// End of list sentinel
{ 0, { 0 }, NULL, NULL}
};
return json_supported;
}
+size_t
+PgSqlLeaseMgr::getClassLeaseCount(const ClientClass& client_class,
+ const Lease::Type& ltype /* = Lease::TYPE_V4*/) const {
+ // Get a context.
+ PgSqlLeaseContextAlloc get_context(*this);
+ PgSqlLeaseContextPtr ctx(get_context.ctx_);
+
+ // Create bindings.
+ PsqlBindArray bind_array;
+ bind_array.add(client_class);
+ if (ltype != Lease::TYPE_V4) {
+ bind_array.add(ltype);
+ }
+
+ // Execute the select.
+ StatementIndex const stindex(ltype == Lease::TYPE_V4 ? GET_LEASE4_COUNT_BY_CLASS :
+ GET_LEASE6_COUNT_BY_CLASS);
+ PgSqlResult r(PQexecPrepared(ctx->conn_,
+ tagged_statements[stindex].name,
+ tagged_statements[stindex].nbparams,
+ &bind_array.values_[0],
+ &bind_array.lengths_[0],
+ &bind_array.formats_[0], 0));
+ ctx->conn_.checkStatementError(r, tagged_statements[stindex]);
+
+ int rows = PQntuples(r);
+ if (rows == 0) {
+ // No entries means 0 leases.
+ return 0;
+ }
+
+ size_t count;
+ PgSqlExchange::getColumnValue(r, 0, 0, count);
+ return count;
+}
+
LeaseStatsQueryPtr
PgSqlLeaseMgr::startLeaseStatsQuery4() {
// Get a context
CHECK_LEASE4_LIMITS, // Check if allocated IPv4 leases are inside the set limits.
CHECK_LEASE6_LIMITS, // Check if allocated IPv6 leases are inside the set limits.
IS_JSON_SUPPORTED, // Checks if JSON support is enabled in the database.
+ GET_LEASE4_COUNT_BY_CLASS, // Fetches the IPv4 lease count for a given class.
+ GET_LEASE6_COUNT_BY_CLASS, // Fetches the IPv6 lease count for given class and lease type.
NUM_STATEMENTS // Number of statements
};
/// @return true if there is JSON support, false otherwise
bool isJsonSupported() const override;
+ /// @brief Returns the class lease count for a given class and lease type.
+ ///
+ /// @param client_class client class for which the count is desired
+ /// @param ltype type of lease for which the count is desired. Defaults to
+ /// Lease::TYPE_V4.
+ ///
+ /// @return number of leases
+ virtual size_t getClassLeaseCount(const ClientClass& client_class,
+ const Lease::Type& ltype = Lease::TYPE_V4) const override;
+
/// @brief Context RAII Allocator.
class PgSqlLeaseContextAlloc {
public:
isc_throw(NotImplemented, "ConcreteLeaseMgr::checkLimits6() not implemented");
}
- /// @brief Checks if JSON support is enabled in the database.
+ /// @brief Pretends to check if JSON support is enabled in the database.
///
/// @return true if there is JSON support, false otherwise
bool isJsonSupported() const override {
isc_throw(NotImplemented, "ConcreteLeaseMgr::isJsonSupported() not implemented");
}
+ /// @brief Pretends to return the class lease count for a given class and lease type.
+ ///
+ /// @param client_class client class for which the count is desired
+ /// @param ltype type of lease for which the count is desired. Defaults to
+ /// Lease::TYPE_V4.
+ ///
+ /// @return number of leases
+ virtual size_t getClassLeaseCount(const ClientClass& client_class,
+ const Lease::Type& ltype = Lease::TYPE_V4) const override {
+ isc_throw(NotImplemented, "ConcreteLeaseMgr::getClassLeaseCount() not implemented");
+ }
+
/// @brief Returns backend type.
///
/// Returns the type of the backend (e.g. "mysql", "memfile" etc.)
}
// brief Checks that a null user context allows allocation.
-// DISABLED_ until Memfile_LeaseMgr implements checkLimits6().
-TEST_F(MemfileLeaseMgrTest, DISABLED_checkLimitsNull6) {
+TEST_F(MemfileLeaseMgrTest, checkLimitsNull6) {
startBackend(V6);
std::string text;
ASSERT_NO_THROW_LOG(text = LeaseMgrFactory::instance().checkLimits6(nullptr));
EXPECT_TRUE(text.empty());
}
-// Checks a few V4 lease limit checking scenarios.
+// Checks a few v4 lease limit checking scenarios.
TEST_F(MemfileLeaseMgrTest, checkLimits4) {
startBackend(V4);
testLeaseLimits4();
}
-// Checks a few V4 lease limit checking scenarios.
+// Checks a few v6 lease limit checking scenarios.
TEST_F(MemfileLeaseMgrTest, checkLimits6) {
startBackend(V6);
testLeaseLimits6();
// Verifies that v4 class lease counts are correctly adjusted
// when leases have class lists.
-// Disabled until MySqlLeaseMgr implements LeaseMgr::getClassLeaseCount()
-TEST_F(MySqlLeaseMgrTest, DISABLED_classLeaseCount4) {
+TEST_F(MySqlLeaseMgrTest, classLeaseCount4) {
+ if (!LeaseMgrFactory::instance().isJsonSupported()) {
+ std::cout << "Skipped test because of lack of JSON support in the database." << std::endl;
+ return;
+ }
+
testClassLeaseCount4();
}
// Verifies that v6 IA_NA class lease counts are correctly adjusted
// when leases have class lists.
-// Disabled until MySqlLeaseMgr implements LeaseMgr::getClassLeaseCount()
-TEST_F(MySqlLeaseMgrTest, DISABLED_classLeaseCount6_NA) {
+TEST_F(MySqlLeaseMgrTest, classLeaseCount6_NA) {
+ if (!LeaseMgrFactory::instance().isJsonSupported()) {
+ std::cout << "Skipped test because of lack of JSON support in the database." << std::endl;
+ return;
+ }
+
testClassLeaseCount6(Lease::TYPE_NA);
}
// Verifies that v6 IA_PD class lease counts are correctly adjusted
// when leases have class lists.
-// Disabled until MySqlLeaseMgr implements LeaseMgr::getClassLeaseCount()
-TEST_F(MySqlLeaseMgrTest, DISABLED_classLeaseCount6_PD) {
+TEST_F(MySqlLeaseMgrTest, classLeaseCount6_PD) {
+ if (!LeaseMgrFactory::instance().isJsonSupported()) {
+ std::cout << "Skipped test because of lack of JSON support in the database." << std::endl;
+ return;
+ }
+
testClassLeaseCount6(Lease::TYPE_PD);
}
EXPECT_TRUE(text.empty());
}
-/// @brief Checks a few limit checking scenarios.
+/// @brief Checks a few v4 limit checking scenarios.
TEST_F(MySqlLeaseMgrTest, checkLimits4) {
// Limit checking should be precluded at reconfiguration time on systems
// that don't have JSON support in the database. It's fine if it throws.
testLeaseLimits4();
}
-/// @brief Checks a few limit checking scenarios.
+/// @brief Checks a few v6 limit checking scenarios.
TEST_F(MySqlLeaseMgrTest, checkLimits6) {
// Limit checking should be precluded at reconfiguration time on systems
// that don't have JSON support in the database. It's fine if it throws.
EXPECT_EQ(0, countRows(conn, "lease4"));
}
+// Verifies that v4 class lease counts are correctly adjusted
+// when leases have class lists.
+TEST_F(PgSqlLeaseMgrTest, classLeaseCount4) {
+ if (!LeaseMgrFactory::instance().isJsonSupported()) {
+ std::cout << "Skipped test because of lack of JSON support in the database." << std::endl;
+ return;
+ }
+
+ testClassLeaseCount4();
+}
+
+// Verifies that v6 IA_NA class lease counts are correctly adjusted
+// when leases have class lists.
+TEST_F(PgSqlLeaseMgrTest, classLeaseCount6_NA) {
+ if (!LeaseMgrFactory::instance().isJsonSupported()) {
+ std::cout << "Skipped test because of lack of JSON support in the database." << std::endl;
+ return;
+ }
+
+ testClassLeaseCount6(Lease::TYPE_NA);
+}
+
+// Verifies that v6 IA_PD class lease counts are correctly adjusted
+// when leases have class lists.
+TEST_F(PgSqlLeaseMgrTest, classLeaseCount6_PD) {
+ if (!LeaseMgrFactory::instance().isJsonSupported()) {
+ std::cout << "Skipped test because of lack of JSON support in the database." << std::endl;
+ return;
+ }
+
+ testClassLeaseCount6(Lease::TYPE_PD);
+}
+
/// @brief Checks that no exceptions are thrown when inquiring about JSON
/// support and prints an informative message.
TEST_F(PgSqlLeaseMgrTest, isJsonSupported) {
EXPECT_TRUE(text.empty());
}
-/// @brief Checks a few limit checking scenarios.
-TEST_F(PgSqlLeaseMgrTest, checkLimits) {
+/// @brief Checks a few v4 limit checking scenarios.
+TEST_F(PgSqlLeaseMgrTest, checkLimits4) {
// Limit checking should be precluded at reconfiguration time on systems
// that don't have JSON support in the database. It's fine if it throws.
if (!LeaseMgrFactory::instance().isJsonSupported()) {
"QUERY: SELECT * FROM JSON_ARRAY_ELEMENTS(json_cast(user_context)"
"->'ISC'->'limits'->'client-classes')\n"
"CONTEXT: PL/pgSQL function checklease4limits(text) line 10 at FOR over SELECT rows\n");
+ return;
+ }
+
+ // The rest of the checks are only for databases with JSON support.
+ testLeaseLimits4();
+}
+
+/// @brief Checks a few v6 limit checking scenarios.
+TEST_F(PgSqlLeaseMgrTest, checkLimits6) {
+ // Limit checking should be precluded at reconfiguration time on systems
+ // that don't have JSON support in the database. It's fine if it throws.
+ if (!LeaseMgrFactory::instance().isJsonSupported()) {
ASSERT_THROW_MSG(LeaseMgrFactory::instance().checkLimits6(
isc::data::Element::createMap()), isc::db::DbOperationError,
"Statement exec failed for: check_lease6_limits, status: 7sqlstate:[ 42883 ], "
}
// The rest of the checks are only for databases with JSON support.
- testLeaseLimits();
+ testLeaseLimits6();
}
} // namespace