From: Thomas Markwalder Date: Wed, 9 May 2018 19:18:49 +0000 (-0400) Subject: [5588] Cassandra shared lease stats support implemented X-Git-Tag: trac5549a_base~23^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=83318b90260bcd93bf9f0164706501895c1f9e99;p=thirdparty%2Fkea.git [5588] Cassandra shared lease stats support implemented Note this impl is done with calculate-on-demand SQL statements rather than stat tables pluse triggers. src/lib/dhcpsrv/cql_lease_mgr.* Added new SQL statements for lease stats queries CqlLeaseStatsQuery Constructors - added variants to support where clause params start() - modified to support query variants based on where clause params CqlSqlLeaseMgr Added start variants: - startSubnetLeaseStatsQuery4(const SubnetID& subnet_id) - startSubnetRangeLeaseStatsQuery4(const SubnetID& first_subnet_id, const SubnetID& last_subnet_id) src/lib/dhcpsrv/tests/cql_lease_mgr_unittest.cc New unit tests: - TEST_F(CqlLeaseMgrTest, leaseStatsQuery4) - TEST_F(CqlLeaseMgrTest, leaseStatsQuery6) --- diff --git a/src/lib/dhcpsrv/cql_lease_mgr.cc b/src/lib/dhcpsrv/cql_lease_mgr.cc index 8adef1019d..cdd2fe3ab1 100644 --- a/src/lib/dhcpsrv/cql_lease_mgr.cc +++ b/src/lib/dhcpsrv/cql_lease_mgr.cc @@ -1461,7 +1461,9 @@ CqlLease6Exchange::getExpiredLeases(const size_t &max_leases, /// class CqlLeaseStatsQuery : public LeaseStatsQuery { public: - /// @brief Constructor + /// @brief Constructor to query for all subnets' stats + /// + /// The query created will return statistics for all subnets /// /// @param conn An open connection to the database housing the lease data /// @param statement The lease data SQL prepared statement tag to execute @@ -1474,6 +1476,42 @@ public: subnet_id_(0), lease_type_(0), lease_state_(0) { } + /// @brief Constructor to query for a single subnet's stats + /// + /// The query created will return statistics for a single subnet + /// + /// @param conn An open connection to the database housing the lease data + /// @param statement The lease data SQL prepared statement tag to execute + /// @param fetch_type Indicates whether or not lease_type should be + /// @param subnet_id id of the subnet for which stats are desired + /// fetched from the result set (should be true for v6) + CqlLeaseStatsQuery(CqlConnection& conn, StatementTag& statement, + const bool fetch_type, const SubnetID& subnet_id) + : LeaseStatsQuery(subnet_id), conn_(conn), statement_(statement), + fetch_type_(fetch_type), cummulative_rows_(), + next_row_(cummulative_rows_.begin()), + subnet_id_(0), lease_type_(0), lease_state_(0) { + } + + /// @brief Constructor to query for the stats for a range of subnets + /// + /// The query created will return statistics for the inclusive range of + /// subnets described by first and last sunbet IDs. + /// + /// @param conn An open connection to the database housing the lease data + /// @param statement The lease data SQL prepared statement tag to execute + /// @param fetch_type Indicates whether or not lease_type should be + /// @param subnet_id id of the subnet for which stats are desired + /// fetched from the result set (should be true for v6) + CqlLeaseStatsQuery(CqlConnection& conn, StatementTag& statement, + const bool fetch_type, const SubnetID& first_subnet_id, + const SubnetID& last_subnet_id) + : LeaseStatsQuery(first_subnet_id, last_subnet_id), conn_(conn), + statement_(statement), fetch_type_(fetch_type), cummulative_rows_(), + next_row_(cummulative_rows_.begin()), + subnet_id_(0), lease_type_(0), lease_state_(0) { + } + /// @brief Destructor virtual ~CqlLeaseStatsQuery() {}; @@ -1539,10 +1577,19 @@ public: /// @brief Statement tags definitions /// @{ - // Return recalculated lease4 lease statistics - static constexpr StatementTag RECOUNT_LEASE4_STATS = "RECOUNT_LEASE4_STATS"; - // Return recalculated lease6 lease statistics - static constexpr StatementTag RECOUNT_LEASE6_STATS = "RECOUNT_LEASE6_STATS"; + // Return lease4 lease statistics for all subnets + static constexpr StatementTag ALL_LEASE4_STATS = "ALL_LEASE4_STATS"; + /// Return lease4 lease statistics for a single subnet + static constexpr StatementTag SUBNET_LEASE4_STATS = "SUBNET_LEASE4_STATS"; + /// Return lease4 lease statistics for a range of subnets + static constexpr StatementTag SUBNET_RANGE_LEASE4_STATS = "SUBNET_RANGE_LEASE4_STATS"; + + // Return lease6 lease statistics for all subnets + static constexpr StatementTag ALL_LEASE6_STATS = "ALL_LEASE6_STATS"; + /// Return lease6 lease statistics for a single subnet + static constexpr StatementTag SUBNET_LEASE6_STATS = "SUBNET_LEASE6_STATS"; + /// Return lease6 lease statistics for a range of subnets + static constexpr StatementTag SUBNET_RANGE_LEASE6_STATS = "SUBNET_RANGE_LEASE6_STATS"; /// @} /// @brief Cassandra statements @@ -1573,32 +1620,89 @@ private: int lease_state_; }; -constexpr StatementTag CqlLeaseStatsQuery::RECOUNT_LEASE4_STATS; -constexpr StatementTag CqlLeaseStatsQuery::RECOUNT_LEASE6_STATS; +constexpr StatementTag CqlLeaseStatsQuery::ALL_LEASE4_STATS; +constexpr StatementTag CqlLeaseStatsQuery::SUBNET_LEASE4_STATS; +constexpr StatementTag CqlLeaseStatsQuery::SUBNET_RANGE_LEASE4_STATS; +constexpr StatementTag CqlLeaseStatsQuery::ALL_LEASE6_STATS; +constexpr StatementTag CqlLeaseStatsQuery::SUBNET_LEASE6_STATS; +constexpr StatementTag CqlLeaseStatsQuery::SUBNET_RANGE_LEASE6_STATS; StatementMap CqlLeaseStatsQuery::tagged_statements_{ // Return subnet_id and state of each v4 lease - {RECOUNT_LEASE4_STATS, - {RECOUNT_LEASE4_STATS, + {ALL_LEASE4_STATS, + {ALL_LEASE4_STATS, + "SELECT " + "subnet_id, state " + "FROM lease4 " + }}, + + // Return state of each v4 lease for a single subnet + {SUBNET_LEASE4_STATS, + {SUBNET_LEASE4_STATS, + "SELECT " + "subnet_id, state " + "FROM lease4 " + "WHERE subnet_id = ? " + }}, + + // Return state of each v4 lease for a subnet range + {SUBNET_RANGE_LEASE4_STATS, + {SUBNET_RANGE_LEASE4_STATS, "SELECT " "subnet_id, state " "FROM lease4 " + "WHERE subnet_id >= ? and subnet_id <= ? " + "ALLOW FILTERING " }}, // Return subnet_id, lease_type, and state of each v6 lease - {RECOUNT_LEASE6_STATS, - {RECOUNT_LEASE6_STATS, + {ALL_LEASE6_STATS, + {ALL_LEASE6_STATS, + "SELECT " + "subnet_id, lease_type, state " + "FROM lease6 " + }}, + + // Return type and state of each v6 lease for a single subnet + {SUBNET_LEASE6_STATS, + {SUBNET_LEASE6_STATS, "SELECT " "subnet_id, lease_type, state " "FROM lease6 " + "WHERE subnet_id = ? " }}, + + // Return type and state of each v6 lease for single range + {SUBNET_RANGE_LEASE6_STATS, + {SUBNET_RANGE_LEASE6_STATS, + "SELECT " + "subnet_id, lease_type, state " + "FROM lease6 " + "WHERE subnet_id >= ? and subnet_id <= ? " + "ALLOW FILTERING " + }}, + }; void CqlLeaseStatsQuery::start() { - AnyArray data; // there are no where clause parameters - // This gets a collection of data for ALL leases, and + // Set up where clause parameters as needed + AnyArray data; + cass_int32_t first_subnet_id_data; + cass_int32_t last_subnet_id_data; + if (getSelectMode() != ALL_SUBNETS) { + first_subnet_id_data = static_cast(first_subnet_id_); + data.add(&first_subnet_id_data); + + if (getSelectMode() == SUBNET_RANGE) { + last_subnet_id_data = static_cast(last_subnet_id_); + data.add(&last_subnet_id_data); + } + } + + // This gets a collection of "raw" data for all leases that match + // the subnet selection criteria (all, range, or single subnets) // then rolls them up into cummulative_rows_ executeSelect(conn_, data, statement_); @@ -1722,6 +1826,11 @@ CqlLeaseStatsQuery::executeSelect(const CqlConnection& connection, const AnyArra createBindForSelect(return_values, statement_tag); CqlCommon::getData(row, return_values); + if (lease_state_ != Lease::STATE_DEFAULT && + lease_state_ != Lease::STATE_DECLINED) { + continue; + } + LeaseStatsRow raw_row(subnet_id_, static_cast(lease_type_), lease_state_, 1); @@ -2202,21 +2311,59 @@ CqlLeaseMgr::deleteExpiredReclaimedLeases6(const uint32_t secs) { LeaseStatsQueryPtr CqlLeaseMgr::startLeaseStatsQuery4() { LeaseStatsQueryPtr query( - new CqlLeaseStatsQuery(dbconn_, CqlLeaseStatsQuery::RECOUNT_LEASE4_STATS, + new CqlLeaseStatsQuery(dbconn_, CqlLeaseStatsQuery::ALL_LEASE4_STATS, false)); query->start(); return(query); } +LeaseStatsQueryPtr +CqlLeaseMgr::startSubnetLeaseStatsQuery4(const SubnetID& subnet_id) { + LeaseStatsQueryPtr query( + new CqlLeaseStatsQuery(dbconn_, CqlLeaseStatsQuery::SUBNET_LEASE4_STATS, + false, subnet_id)); + query->start(); + return(query); +} + +LeaseStatsQueryPtr +CqlLeaseMgr::startSubnetRangeLeaseStatsQuery4(const SubnetID& first_subnet_id, + const SubnetID& last_subnet_id) { + LeaseStatsQueryPtr query( + new CqlLeaseStatsQuery(dbconn_, CqlLeaseStatsQuery::SUBNET_RANGE_LEASE4_STATS, + false, first_subnet_id, last_subnet_id)); + query->start(); + return(query); +} + LeaseStatsQueryPtr CqlLeaseMgr::startLeaseStatsQuery6() { LeaseStatsQueryPtr query( - new CqlLeaseStatsQuery(dbconn_, CqlLeaseStatsQuery::RECOUNT_LEASE6_STATS, + new CqlLeaseStatsQuery(dbconn_, CqlLeaseStatsQuery::ALL_LEASE6_STATS, true)); query->start(); return(query); } +LeaseStatsQueryPtr +CqlLeaseMgr::startSubnetLeaseStatsQuery6(const SubnetID& subnet_id) { + LeaseStatsQueryPtr query( + new CqlLeaseStatsQuery(dbconn_, CqlLeaseStatsQuery::SUBNET_LEASE6_STATS, + true, subnet_id)); + query->start(); + return(query); +} + +LeaseStatsQueryPtr +CqlLeaseMgr::startSubnetRangeLeaseStatsQuery6(const SubnetID& first_subnet_id, + const SubnetID& last_subnet_id) { + LeaseStatsQueryPtr query( + new CqlLeaseStatsQuery(dbconn_, CqlLeaseStatsQuery::SUBNET_RANGE_LEASE6_STATS, + true, first_subnet_id, last_subnet_id)); + query->start(); + return(query); +} + size_t CqlLeaseMgr::wipeLeases4(const SubnetID & /*subnet_id*/) { /// @todo: Need to implement this, so wipe leases would work. diff --git a/src/lib/dhcpsrv/cql_lease_mgr.h b/src/lib/dhcpsrv/cql_lease_mgr.h index 92f933a88f..176cf252d4 100644 --- a/src/lib/dhcpsrv/cql_lease_mgr.h +++ b/src/lib/dhcpsrv/cql_lease_mgr.h @@ -376,22 +376,64 @@ public: /// /// It creates an instance of a CqlLeaseStatsQuery4 and then /// invokes its start method, which fetches its statistical data - /// result set by executing the RECOUNT_LEASE_STATS4 query. + /// result set by executing the ALL_LEASE_STATS4 query. /// The query object is then returned. /// /// @return The populated query as a pointer to an LeaseStatsQuery - virtual LeaseStatsQueryPtr startLeaseStatsQuery4() override; + virtual LeaseStatsQueryPtr startLeaseStatsQuery4(); + /// @brief Creates and runs the IPv4 lease stats query for a single subnet + /// + /// It creates an instance of a CqlLeaseStatsQuery4 for a single subnet + /// query and then invokes its start method in which the query constructs its + /// statistical data result set. The query object is then returned. + /// + /// @param subnet_id id of the subnet for which stats are desired + /// @return A populated LeaseStatsQuery + virtual LeaseStatsQueryPtr startSubnetLeaseStatsQuery4(const SubnetID& subnet_id); + + /// @brief Creates and runs the IPv4 lease stats query for a single subnet + /// + /// It creates an instance of a CqlLeaseStatsQuery4 for a subnet range + /// query and then invokes its start method in which the query constructs its + /// statistical data result set. The query object is then returned. + /// + /// @param first_subnet_id first subnet in the range of subnets + /// @param last_subnet_id last subnet in the range of subnets + /// @return A populated LeaseStatsQuery + virtual LeaseStatsQueryPtr startSubnetRangeLeaseStatsQuery4(const SubnetID& first_subnet_id, + const SubnetID& last_subnet_id); /// @brief Creates and runs the IPv6 lease stats query /// - /// It creates an instance of a CqllLeaseStatsQuery and then + /// It creates an instance of a CqlLeaseStatsQuery and then /// invokes its start method, which fetches its statistical data - /// result set by executing the RECOUNT_LEASE_STATS6 query. + /// result set by executing the ALL_LEASE_STATS6 query. /// The query object is then returned. /// /// @return The populated query as a pointer to an LeaseStatsQuery - virtual LeaseStatsQueryPtr startLeaseStatsQuery6() override; + virtual LeaseStatsQueryPtr startLeaseStatsQuery6(); + /// @brief Creates and runs the IPv6 lease stats query for a single subnet + /// + /// It creates an instance of a CqlLeaseStatsQuery6 for a single subnet + /// query and then invokes its start method in which the query constructs its + /// statistical data result set. The query object is then returned. + /// + /// @param subnet_id id of the subnet for which stats are desired + /// @return A populated LeaseStatsQuery + virtual LeaseStatsQueryPtr startSubnetLeaseStatsQuery6(const SubnetID& subnet_id); + + /// @brief Creates and runs the IPv6 lease stats query for a single subnet + /// + /// It creates an instance of a CqlLeaseStatsQuery6 for a subnet range + /// query and then invokes its start method in which the query constructs its + /// statistical data result set. The query object is then returned. + /// + /// @param first_subnet_id first subnet in the range of subnets + /// @param last_subnet_id last subnet in the range of subnets + /// @return A populated LeaseStatsQuery + virtual LeaseStatsQueryPtr startSubnetRangeLeaseStatsQuery6(const SubnetID& first_subnet_id, + const SubnetID& last_subnet_id); /// @brief Removes specified IPv4 leases. /// /// This rather dangerous method is able to remove all leases from specified diff --git a/src/lib/dhcpsrv/tests/cql_lease_mgr_unittest.cc b/src/lib/dhcpsrv/tests/cql_lease_mgr_unittest.cc index 58be7a15ad..74beea413a 100644 --- a/src/lib/dhcpsrv/tests/cql_lease_mgr_unittest.cc +++ b/src/lib/dhcpsrv/tests/cql_lease_mgr_unittest.cc @@ -767,4 +767,14 @@ TEST_F(CqlLeaseMgrTest, DISABLED_wipeLeases6) { testWipeLeases6(); } +// Tests v4 lease stats query variants. +TEST_F(CqlLeaseMgrTest, leaseStatsQuery4) { + testLeaseStatsQuery4(); +} + +// Tests v6 lease stats query variants. +TEST_F(CqlLeaseMgrTest, leaseStatsQuery6) { + testLeaseStatsQuery6(); +} + } // namespace