Browse Source

[4294] Added abstract support for IPv6 lease stats recount to LeaseMgr

src/lib/dhcpsrv/lease_mgr.h
src/lib/dhcpsrv/lease_mgr.cc
    AddressStatsRow6 - new struct that contains a single row of IPv6 lease
    statistical data

    AddressStatsQuery6 - new base class for fulfilling the IPv6 statistical
    lease data query

    LeaseMgr::recountAddressStats6() - new method that recalculates per-subnet
    and global stats for IPv6 leases

    LeaseMgr::startAddressStatsQuery6() - new virtual method which creates
    then executes the IPv6 lease stats query
Thomas Markwalder 8 years ago
parent
commit
61bc7b004a

+ 114 - 6
src/lib/dhcpsrv/lease_mgr.cc

@@ -47,7 +47,7 @@ LeaseMgr::getLease6(Lease::Type type, const DUID& duid,
     return (*col.begin());
 }
 
-void 
+void
 LeaseMgr::recountAddressStats4() {
     using namespace stats;
 
@@ -68,8 +68,8 @@ LeaseMgr::recountAddressStats4() {
     stats_mgr.setValue("declined-reclaimed-addresses", zero);
 
     // Clear subnet level stats.  This ensures we don't end up with corner
-    // cases that leave stale values in place. 
-    const Subnet4Collection* subnets = 
+    // cases that leave stale values in place.
+    const Subnet4Collection* subnets =
         CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getAll();
 
     for (Subnet4Collection::const_iterator subnet = subnets->begin();
@@ -86,15 +86,15 @@ LeaseMgr::recountAddressStats4() {
                                                   "declined-reclaimed-addresses"),
                            zero);
     }
-   
+
     // Get counts per state per subnet. Iterate over the result set
-    // updating the subnet and global values. 
+    // updating the subnet and global values.
     AddressStatsRow4 row;
     while (query->getNextRow(row)) {
         switch(row.lease_state_) {
             case Lease::STATE_DEFAULT:
                 // Set subnet level value.
-                stats_mgr.setValue(StatsMgr::generateName("subnet", 
+                stats_mgr.setValue(StatsMgr::generateName("subnet",
                                                           row.subnet_id_,
                                                           "assigned-addresses"),
                                    row.state_count_);
@@ -123,6 +123,114 @@ LeaseMgr::startAddressStatsQuery4() {
     return(AddressStatsQuery4Ptr());
 }
 
+void
+LeaseMgr::recountAddressStats6() {
+    using namespace stats;
+
+    StatsMgr& stats_mgr = StatsMgr::instance();
+
+    AddressStatsQuery6Ptr query = startAddressStatsQuery6();
+    if (!query) {
+        /// NULL means not backend does not support recounting.
+        return;
+    }
+
+    // Zero out the global stats. (Ok, so currently there's only one
+    // that should be cleared.  "reclaimed-declined-addresses" never
+    // gets zeroed. @todo discuss with Tomek the rational of not
+    // clearing it when we clear the rest.
+    int64_t zero = 0;
+    stats_mgr.setValue("declined-addresses", zero);
+    stats_mgr.setValue("declined-reclaimed-addresses", zero);
+
+    // Clear subnet level stats.  This ensures we don't end up with corner
+    // cases that leave stale values in place.
+    const Subnet6Collection* subnets =
+        CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getAll();
+
+    for (Subnet6Collection::const_iterator subnet = subnets->begin();
+         subnet != subnets->end(); ++subnet) {
+        SubnetID subnet_id = (*subnet)->getID();
+        stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id,
+                                                  "assigned-nas"),
+                           zero);
+
+        stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id,
+                                                  "declined-nas"),
+                           zero);
+
+        stats_mgr.setValue(StatsMgr::
+                           generateName("subnet", subnet_id,
+                                        "declined-reclaimed-addresses"),
+                           zero);
+
+        stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id,
+                                                  "assigned-pds"),
+                           zero);
+    }
+
+    // Get counts per state per subnet. Iterate over the result set
+    // updating the subnet and global values.
+    AddressStatsRow6 row;
+    while (query->getNextRow(row)) {
+        switch(row.lease_type_) {
+            case Lease::TYPE_NA:
+                switch(row.lease_state_) {
+                    case Lease::STATE_DEFAULT:
+                        // Set subnet level value.
+                        stats_mgr.setValue(StatsMgr::
+                                           generateName("subnet",
+                                                        row.subnet_id_,
+                                                        "assigned-nas"),
+                                           row.state_count_);
+                        break;
+                    case Lease::STATE_DECLINED:
+                        // Set subnet level value.
+                        stats_mgr.setValue(StatsMgr::
+                                           generateName("subnet",
+                                                        row.subnet_id_,
+                                                        "declined-nas"),
+                                           row.state_count_);
+
+                        // Add to the global value.
+                        stats_mgr.addValue("declined-addresses",
+                                           row.state_count_);
+                        break;
+                    default:
+                        // Not one we're tracking.
+                        break;
+                }
+                break;
+
+            case Lease::TYPE_PD:
+                switch(row.lease_state_) {
+                    case Lease::STATE_DEFAULT:
+                        // Set subnet level value.
+                        stats_mgr.setValue(StatsMgr::
+                                           generateName("subnet",
+                                                        row.subnet_id_,
+                                                        "assigned-pds"),
+                                           row.state_count_);
+                        break;
+                    default:
+                        // Not one we're tracking.
+                        break;
+                }
+                break;
+
+            default:
+                // We dont' support TYPE_TAs yet
+                break;
+        }
+    }
+}
+
+AddressStatsQuery6Ptr
+LeaseMgr::startAddressStatsQuery6() {
+    return(AddressStatsQuery6Ptr());
+}
+
+
 std::string
 LeaseMgr::getDBVersion() {
     isc_throw(NotImplemented, "LeaseMgr::getDBVersion() called");

+ 110 - 13
src/lib/dhcpsrv/lease_mgr.h

@@ -153,7 +153,7 @@ public:
 /// and the number of leases in that state for that subnet ID.
 struct AddressStatsRow4 {
     /// @brief Default constructor
-    AddressStatsRow4() : 
+    AddressStatsRow4() :
         subnet_id_(0), lease_state_(Lease::STATE_DEFAULT), state_count_(0) {
     }
 
@@ -164,15 +164,15 @@ struct AddressStatsRow4 {
     /// @param state_count The count of leases in the lease state
     AddressStatsRow4(const SubnetID& subnet_id,
                      const Lease::LeaseState& lease_state,
-                     const int64_t state_count) 
-        : subnet_id_(subnet_id), lease_state_(lease_state), 
+                     const int64_t state_count)
+        : subnet_id_(subnet_id), lease_state_(lease_state),
           state_count_(state_count) {
     }
 
     /// @brief The subnet ID to which this data applies
     SubnetID subnet_id_;
     /// @brief The lease_state to which the count applies
-    uint32_t lease_state_;
+    Lease::LeaseState lease_state_;
     /// @brief state_count The count of leases in the lease state
     int64_t state_count_;
 };
@@ -188,12 +188,12 @@ public:
     /// @brief Default constructor
     AddressStatsQuery4() {};
 
-    /// @brief virtual destructor 
+    /// @brief virtual destructor
     virtual ~AddressStatsQuery4() {};
 
     /// @brief Executes the query
     ///
-    /// This method should conduct whatever steps are required to 
+    /// This method should conduct whatever steps are required to
     /// calculate the IPv4 lease statistical data by examining the
     /// IPv4 lease data and making that results available row by row.
     virtual void start() {};
@@ -210,6 +210,72 @@ public:
 /// @brief Defines a pointer to an AddressStatsQuery4.
 typedef boost::shared_ptr<AddressStatsQuery4> AddressStatsQuery4Ptr;
 
+/// @brief Contains a single row of IPv6 lease statistical data
+///
+/// The contents of the row consist of a subnet ID, a lease state,
+/// and the number of leases in that state for that subnet ID.
+struct AddressStatsRow6 {
+    /// @brief Default constructor
+    AddressStatsRow6() :
+        subnet_id_(0), lease_type_(Lease::TYPE_NA),
+        lease_state_(Lease::STATE_DEFAULT), state_count_(0) {
+    }
+
+    /// @brief Constructor
+    ///
+    /// @param subnet_id The subnet id to which this data applies
+    /// @param lease_state The lease state counted
+    /// @param state_count The count of leases in the lease state
+    AddressStatsRow6(const SubnetID& subnet_id, const Lease::Type& lease_type,
+                     const Lease::LeaseState& lease_state,
+                     const int64_t state_count)
+        : subnet_id_(subnet_id), lease_state_(lease_state),
+          state_count_(state_count) {
+    }
+
+    /// @brief The subnet ID to which this data applies
+    SubnetID subnet_id_;
+    /// @brief The lease_state to which the count applies
+    Lease::Type lease_type_;
+    /// @brief The lease_state to which the count applies
+    uint32_t lease_state_;
+    /// @brief state_count The count of leases in the lease state
+    int64_t state_count_;
+};
+
+/// @brief Base class for fulfilling IPv6 statistical lease data query
+///
+/// LeaseMgr derivations implement this class such that it provides
+/// upto date IPv6 statistical lease data organized as rows of
+/// AddressStatsRow6 instances.  The rows must be accessible in
+/// ascending order by subnet id.
+class AddressStatsQuery6 {
+public:
+    /// @brief Default constructor
+    AddressStatsQuery6() {};
+
+    /// @brief virtual destructor
+    virtual ~AddressStatsQuery6() {};
+
+    /// @brief Executes the query
+    ///
+    /// This method should conduct whatever steps are required to
+    /// calculate the IPv6 lease statistical data by examining the
+    /// IPv6 lease data and making that results available row by row.
+    virtual void start() {};
+
+    /// @brief Fetches the next row of data
+    ///
+    /// @param[out] row Storage into which the row is fetched
+    ///
+    /// @return True if a row was fetched, false if there are no
+    /// more rows.
+    virtual bool getNextRow(AddressStatsRow6& row) { return (false); };
+};
+
+/// @brief Defines a pointer to an AddressStatsQuery6.
+typedef boost::shared_ptr<AddressStatsQuery6> AddressStatsQuery6Ptr;
+
 /// @brief Abstract Lease Manager
 ///
 /// This is an abstract API for lease database backends. It provides unified
@@ -463,7 +529,7 @@ public:
 
     /// @brief Recalculates per-subnet and global stats for IPv4 leases
     ///
-    /// This method recalculates the following statistics: 
+    /// This method recalculates the following statistics:
     /// per-subnet:
     /// - assigned-addresses
     /// - declined-addresses
@@ -476,21 +542,52 @@ public:
     /// returns an instance of an AddressStats4Qry.  The query
     /// query contains a "result set"  where each row is an AddressStatRow4
     /// that contains a subnet id, a lease state, the number of leases in that
-    /// state and is ordered by subnet id.  The method iterates over the 
+    /// state and is ordered by subnet id.  The method iterates over the
     /// result set rows, setting the appropriate statistic per subnet and
-    /// adding to the approporate global statistic. 
+    /// adding to the approporate global statistic.
     void recountAddressStats4();
 
-    /// @brief Virtual method which creates and runs the IPv4 lease stats query 
+    /// @brief Virtual method which creates and runs the IPv4 lease stats query
     ///
     /// LeaseMgr derivations implement this method such that it creates and
-    /// returns an instance of an AddressStatsQuery whose result set has been 
-    /// populated with upto date IPv4 lease statistical data.  Each row of the 
-    /// result set is an AddressStatRow4 which ordered ascending by subnet ID.  
+    /// returns an instance of an AddressStatsQuery whose result set has been
+    /// populated with upto date IPv4 lease statistical data.  Each row of the
+    /// result set is an AddressStatRow4 which ordered ascending by subnet ID.
     ///
     /// @return A populated AddressStatsQuery4
     virtual AddressStatsQuery4Ptr startAddressStatsQuery4();
 
+    /// @brief Recalculates per-subnet and global stats for IPv6 leases
+    ///
+    /// This method recalculates the following statistics:
+    /// per-subnet:
+    /// - assigned-addresses
+    /// - declined-addresses
+    /// - declined-reclaimed-addresses (reset to zero)
+    /// - assigned-pds
+    /// global:
+    /// - declined-addresses
+    /// - declined-reclaimed-addresses (reset to zero)
+    ///
+    /// It invokes the virtual method, startAddressStatsQuery6(), which
+    /// returns an instance of an AddressStats6Qry.  The query
+    /// query contains a "result set"  where each row is an AddressStatRow6
+    /// that contains a subnet id, a lease state, the number of leases in that
+    /// state and is ordered by subnet id.  The method iterates over the
+    /// result set rows, setting the appropriate statistic per subnet and
+    /// adding to the approporate global statistic.
+    void recountAddressStats6();
+
+    /// @brief Virtual method which creates and runs the IPv6 lease stats query
+    ///
+    /// LeaseMgr derivations implement this method such that it creates and
+    /// returns an instance of an AddressStatsQuery whose result set has been
+    /// populated with upto date IPv6 lease statistical data.  Each row of the
+    /// result set is an AddressStatRow6 which ordered ascending by subnet ID.
+    ///
+    /// @return A populated AddressStatsQuery6
+    virtual AddressStatsQuery6Ptr startAddressStatsQuery6();
+
     /// @brief Return backend type
     ///
     /// Returns the type of the backend (e.g. "mysql", "memfile" etc.)

+ 0 - 7
src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.cc

@@ -2406,13 +2406,6 @@ GenericLeaseMgrTest::checkAddressStats4(const StatValMapList& expectedStats) {
     int64_t declined_addresses = 0;
     int64_t declined_reclaimed_addresses = 0;
 
-#if 0
-    isc::data::ConstElementPtr allstats = stats::StatsMgr::instance().getAll();
-    std::cout << "ALL: ";
-    allstats->toJSON(std::cout);
-    std::cout << std::endl;
-#endif
-
     // Iterate over all stats for each subnet
     for (int subnet_idx = 0; subnet_idx < expectedStats.size(); ++subnet_idx) {
         BOOST_FOREACH(StatValPair expectedStat, expectedStats[subnet_idx]) {