]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#145] backend support for pool counters
authorRazvan Becheriu <razvan@isc.org>
Wed, 24 May 2023 12:04:49 +0000 (15:04 +0300)
committerRazvan Becheriu <razvan@isc.org>
Fri, 26 May 2023 15:40:52 +0000 (18:40 +0300)
15 files changed:
src/hooks/dhcp/stat_cmds/stat_cmds.cc
src/lib/dhcpsrv/alloc_engine.cc
src/lib/dhcpsrv/lease.cc
src/lib/dhcpsrv/lease.h
src/lib/dhcpsrv/lease_mgr.cc
src/lib/dhcpsrv/lease_mgr.h
src/lib/dhcpsrv/memfile_lease_mgr.cc
src/lib/dhcpsrv/memfile_lease_mgr.h
src/lib/dhcpsrv/mysql_lease_mgr.cc
src/lib/dhcpsrv/mysql_lease_mgr.h
src/lib/dhcpsrv/pgsql_lease_mgr.cc
src/lib/dhcpsrv/pgsql_lease_mgr.h
src/lib/dhcpsrv/tests/lease_unittest.cc
src/lib/dhcpsrv/tracking_lease_mgr.cc
src/lib/dhcpsrv/tracking_lease_mgr.h

index eb43ae771be2a8a7ccaded0f2074a03ca6019927..4697611419596ca59362be0012685f8a7ca9f8ff 100644 (file)
@@ -78,6 +78,8 @@ public:
                 os << "[subnets " << first_subnet_id_
                    << " through " << last_subnet_id_ << "]";
                 break;
+            default:
+                os << "unsupported";
             }
 
             return (os.str());
@@ -450,6 +452,8 @@ LeaseStatCmdsImpl::makeResultSet4(const ElementPtr& result_wrapper,
                 .startSubnetRangeLeaseStatsQuery4(params.first_subnet_id_,
                                                   params.last_subnet_id_);
         break;
+    default:
+        return (0);
     }
 
     // Create the result-set map.
@@ -579,6 +583,8 @@ LeaseStatCmdsImpl::makeResultSet6(const ElementPtr& result_wrapper,
                 .startSubnetRangeLeaseStatsQuery6(params.first_subnet_id_,
                                                   params.last_subnet_id_);
         break;
+    default:
+        return (0);
     }
 
     // Create the result-set map.
index ef2e7c06f93b2940bb67ea07a99d6c2418b59561..e98edf8c3508934b80c2dd2c03f7901166c842ad 100644 (file)
@@ -1796,6 +1796,11 @@ AllocEngine::reuseExpiredLease(Lease6Ptr& expired, ClientContext6& ctx,
         // Add(update) the extended information on the lease.
         updateLease6ExtendedInfo(expired, ctx);
 
+        const auto& pool = ctx.subnet_->getPool(ctx.currentIA().type_, expired->addr_, false);
+        if (pool) {
+            expired->pool_id_ = pool->getID();
+        }
+
         // for REQUEST we do update the lease
         LeaseMgrFactory::instance().updateLease6(expired);
 
@@ -1814,7 +1819,6 @@ AllocEngine::reuseExpiredLease(Lease6Ptr& expired, ClientContext6& ctx,
                                        "cumulative-assigned-nas" : "cumulative-assigned-pds"),
                 static_cast<int64_t>(1));
 
-            const auto& pool = ctx.subnet_->getPool(ctx.currentIA().type_,expired->addr_, false);
             if (pool) {
                 StatsMgr::instance().addValue(
                     StatsMgr::generateName("subnet", ctx.subnet_->getID(),
@@ -1985,6 +1989,11 @@ Lease6Ptr AllocEngine::createLease6(ClientContext6& ctx,
         // Add(update) the extended information on the lease.
         updateLease6ExtendedInfo(lease, ctx);
 
+        const auto& pool = ctx.subnet_->getPool(ctx.currentIA().type_, lease->addr_, false);
+        if (pool) {
+            lease->pool_id_ = pool->getID();
+        }
+
         // That is a real (REQUEST) allocation
         bool status = LeaseMgrFactory::instance().addLease(lease);
 
@@ -2004,7 +2013,6 @@ Lease6Ptr AllocEngine::createLease6(ClientContext6& ctx,
                                            "cumulative-assigned-nas" : "cumulative-assigned-pds"),
                     static_cast<int64_t>(1));
 
-                const auto& pool = ctx.subnet_->getPool(ctx.currentIA().type_, lease->addr_, false);
                 if (pool) {
                     StatsMgr::instance().addValue(
                         StatsMgr::generateName("subnet", ctx.subnet_->getID(),
@@ -2332,6 +2340,10 @@ AllocEngine::extendLease6(ClientContext6& ctx, Lease6Ptr lease) {
         // Now that the lease has been reclaimed, we can go ahead and update it
         // in the lease database.
         if (lease->reuseable_valid_lft_ == 0) {
+            const auto& pool = ctx.subnet_->getPool(ctx.currentIA().type_, lease->addr_, false);
+            if (pool) {
+                lease->pool_id_ = pool->getID();
+            }
             LeaseMgrFactory::instance().updateLease6(lease);
         }
 
@@ -4210,7 +4222,7 @@ AllocEngine::createLease4(const ClientContext4& ctx, const IOAddress& addr,
     }
 
     // Get the context appropriate lifetime.
-    uint32_t valid_lft = (ctx.offer_lft_ ? ctx.offer_lft_ :  getValidLft(ctx));
+    uint32_t valid_lft = (ctx.offer_lft_ ? ctx.offer_lft_ : getValidLft(ctx));
 
     time_t now = time(NULL);
 
@@ -4290,6 +4302,10 @@ AllocEngine::createLease4(const ClientContext4& ctx, const IOAddress& addr,
     }
 
     if (!ctx.fake_allocation_ || ctx.offer_lft_) {
+        const auto& pool = ctx.subnet_->getPool(Lease::TYPE_V4, lease->addr_, false);
+        if (pool) {
+            lease->pool_id_ = pool->getID();
+        }
         // That is a real (REQUEST) allocation
         bool status = LeaseMgrFactory::instance().addLease(lease);
         if (status) {
@@ -4305,22 +4321,18 @@ AllocEngine::createLease4(const ClientContext4& ctx, const IOAddress& addr,
                                        "cumulative-assigned-addresses"),
                 static_cast<int64_t>(1));
 
-            const auto& subnet = CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getBySubnetId(ctx.subnet_->getID());
-            if (subnet) {
-                const auto& pool = subnet->getPool(Lease::TYPE_V4, lease->addr_, false);
-                if (pool) {
-                    StatsMgr::instance().addValue(
-                        StatsMgr::generateName("subnet", subnet->getID(),
-                                               StatsMgr::generateName(".pool", pool->getID(),
-                                                                     "assigned-addresses")),
-                        static_cast<int64_t>(1));
+            if (pool) {
+                StatsMgr::instance().addValue(
+                    StatsMgr::generateName("subnet", ctx.subnet_->getID(),
+                                           StatsMgr::generateName(".pool", pool->getID(),
+                                                                 "assigned-addresses")),
+                    static_cast<int64_t>(1));
 
-                    StatsMgr::instance().addValue(
-                        StatsMgr::generateName("subnet", subnet->getID(),
-                                               StatsMgr::generateName(".pool", pool->getID(),
-                                                                     "cumulative-assigned-addresses")),
-                        static_cast<int64_t>(1));
-                }
+                StatsMgr::instance().addValue(
+                    StatsMgr::generateName("subnet", ctx.subnet_->getID(),
+                                           StatsMgr::generateName(".pool", pool->getID(),
+                                                                 "cumulative-assigned-addresses")),
+                    static_cast<int64_t>(1));
             }
 
             StatsMgr::instance().addValue("cumulative-assigned-addresses",
@@ -4363,7 +4375,7 @@ AllocEngine::renewLease4(const Lease4Ptr& lease,
         setLeaseReusable(lease, ctx);
     }
 
-    if (!ctx.fake_allocation_  || ctx.offer_lft_) {
+    if (!ctx.fake_allocation_ || ctx.offer_lft_) {
         // If the lease is expired we have to reclaim it before
         // re-assigning it to the client. The lease reclamation
         // involves execution of hooks and DNS update.
@@ -4424,6 +4436,11 @@ AllocEngine::renewLease4(const Lease4Ptr& lease,
     }
 
     if ((!ctx.fake_allocation_ || ctx.offer_lft_) && !skip && (lease->reuseable_valid_lft_ == 0)) {
+        const auto& pool = ctx.subnet_->getPool(Lease::TYPE_V4, lease->addr_, false);
+        if (pool) {
+            lease->pool_id_ = pool->getID();
+        }
+
         // for REQUEST we do update the lease
         LeaseMgrFactory::instance().updateLease4(lease);
 
@@ -4439,22 +4456,18 @@ AllocEngine::renewLease4(const Lease4Ptr& lease,
                                        "cumulative-assigned-addresses"),
                 static_cast<int64_t>(1));
 
-            const auto& subnet = CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getBySubnetId(ctx.subnet_->getID());
-            if (subnet) {
-                const auto& pool = subnet->getPool(Lease::TYPE_V4, lease->addr_, false);
-                if (pool) {
-                    StatsMgr::instance().addValue(
-                        StatsMgr::generateName("subnet", subnet->getID(),
-                                               StatsMgr::generateName(".pool", pool->getID(),
-                                                                      "assigned-addresses")),
-                        static_cast<int64_t>(1));
+            if (pool) {
+                StatsMgr::instance().addValue(
+                    StatsMgr::generateName("subnet", ctx.subnet_->getID(),
+                                           StatsMgr::generateName(".pool", pool->getID(),
+                                                                  "assigned-addresses")),
+                    static_cast<int64_t>(1));
 
-                    StatsMgr::instance().addValue(
-                        StatsMgr::generateName("subnet", subnet->getID(),
-                                               StatsMgr::generateName(".pool", pool->getID(),
-                                                                      "cumulative-assigned-addresses")),
-                        static_cast<int64_t>(1));
-                }
+                StatsMgr::instance().addValue(
+                    StatsMgr::generateName("subnet", ctx.subnet_->getID(),
+                                           StatsMgr::generateName(".pool", pool->getID(),
+                                                                  "cumulative-assigned-addresses")),
+                    static_cast<int64_t>(1));
             }
 
             StatsMgr::instance().addValue("cumulative-assigned-addresses",
@@ -4551,6 +4564,10 @@ AllocEngine::reuseExpiredLease4(Lease4Ptr& expired,
     }
 
     if (!ctx.fake_allocation_ || ctx.offer_lft_) {
+        const auto& pool = ctx.subnet_->getPool(Lease::TYPE_V4, expired->addr_, false);
+        if (pool) {
+            expired->pool_id_ = pool->getID();
+        }
         // for REQUEST we do update the lease
         LeaseMgrFactory::instance().updateLease4(expired);
 
@@ -4565,22 +4582,18 @@ AllocEngine::reuseExpiredLease4(Lease4Ptr& expired,
                                    "cumulative-assigned-addresses"),
             static_cast<int64_t>(1));
 
-        const auto& subnet = CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getBySubnetId(ctx.subnet_->getID());
-        if (subnet) {
-            const auto& pool = subnet->getPool(Lease::TYPE_V4, expired->addr_, false);
-            if (pool) {
-                StatsMgr::instance().addValue(
-                    StatsMgr::generateName("subnet", subnet->getID(),
-                                           StatsMgr::generateName(".pool", pool->getID(),
-                                                                  "assigned-addresses")),
-                    static_cast<int64_t>(1));
+        if (pool) {
+            StatsMgr::instance().addValue(
+                StatsMgr::generateName("subnet", ctx.subnet_->getID(),
+                                       StatsMgr::generateName(".pool", pool->getID(),
+                                                              "assigned-addresses")),
+                static_cast<int64_t>(1));
 
-                StatsMgr::instance().addValue(
-                    StatsMgr::generateName("subnet", subnet->getID(),
-                                           StatsMgr::generateName(".pool", pool->getID(),
-                                                                  "cumulative-assigned-addresses")),
-                    static_cast<int64_t>(1));
-            }
+            StatsMgr::instance().addValue(
+                StatsMgr::generateName("subnet", ctx.subnet_->getID(),
+                                       StatsMgr::generateName(".pool", pool->getID(),
+                                                              "cumulative-assigned-addresses")),
+                static_cast<int64_t>(1));
         }
 
         StatsMgr::instance().addValue("cumulative-assigned-addresses",
index debc08a81b7f69a7369cc06165d2688cd12f37de..d750c14faf9471916cf6386fe84bcf7eb2af5ca3 100644 (file)
@@ -309,34 +309,6 @@ Lease::syncCurrentExpirationTime(const Lease& from, Lease& to) {
     to.current_valid_lft_ = from.valid_lft_;
 }
 
-Lease4::Lease4(const Lease4& other)
-    : Lease(other.addr_, other.valid_lft_,
-            other.subnet_id_, other.cltt_, other.fqdn_fwd_,
-            other.fqdn_rev_, other.hostname_, other.hwaddr_) {
-
-    // Copy over fields derived from Lease.
-    state_ = other.state_;
-
-    // Copy the hardware address if it is defined.
-    if (other.hwaddr_) {
-        hwaddr_.reset(new HWAddr(*other.hwaddr_));
-    } else {
-        hwaddr_.reset();
-    }
-
-    if (other.client_id_) {
-        client_id_.reset(new ClientId(other.client_id_->getClientId()));
-    } else {
-        client_id_.reset();
-    }
-
-    if (other.getContext()) {
-        setContext(other.getContext());
-        relay_id_ = other.relay_id_;
-        remote_id_ = other.remote_id_;
-    }
-}
-
 Lease4::Lease4(const isc::asiolink::IOAddress& address,
                const HWAddrPtr& hw_address,
                const ClientIdPtr& client_id,
@@ -346,12 +318,14 @@ Lease4::Lease4(const isc::asiolink::IOAddress& address,
                const bool fqdn_fwd,
                const bool fqdn_rev,
                const std::string& hostname)
-
     : Lease(address, valid_lifetime, subnet_id, cltt, fqdn_fwd,
             fqdn_rev, hostname, hw_address),
       client_id_(client_id), remote_id_(), relay_id_() {
 }
 
+Lease4::Lease4() : Lease(0, 0, 0, 0, false, false, "", HWAddrPtr()) {
+}
+
 std::string
 Lease4::statesToText(const uint32_t state) {
     return (Lease::basicStatesToText(state));
@@ -405,44 +379,6 @@ Lease4::decline(uint32_t probation_period) {
     valid_lft_ = probation_period;
 }
 
-Lease4&
-Lease4::operator=(const Lease4& other) {
-    if (this != &other) {
-        addr_ = other.addr_;
-        valid_lft_ = other.valid_lft_;
-        current_valid_lft_ = other.current_valid_lft_;
-        reuseable_valid_lft_ = other.reuseable_valid_lft_;
-        cltt_ = other.cltt_;
-        current_cltt_ = other.current_cltt_;
-        subnet_id_ = other.subnet_id_;
-        pool_id_ = other.pool_id_;
-        hostname_ = other.hostname_;
-        fqdn_fwd_ = other.fqdn_fwd_;
-        fqdn_rev_ = other.fqdn_rev_;
-        state_ = other.state_;
-
-        // Copy the hardware address if it is defined.
-        if (other.hwaddr_) {
-            hwaddr_.reset(new HWAddr(*other.hwaddr_));
-        } else {
-            hwaddr_.reset();
-        }
-
-        if (other.client_id_) {
-            client_id_.reset(new ClientId(other.client_id_->getClientId()));
-        } else {
-            client_id_.reset();
-        }
-
-        if (other.getContext()) {
-            setContext(other.getContext());
-            relay_id_ = other.relay_id_;
-            remote_id_ = other.remote_id_;
-        }
-    }
-    return (*this);
-}
-
 isc::data::ElementPtr
 Lease4::toElement() const {
     // Prepare the map
index 733d1974a69f62de8884ed0bf83fd0531af1eaa4..f84302d276ed3d0ece06bf33e3ec2e064af5417d 100644 (file)
@@ -354,14 +354,7 @@ struct Lease4 : public Lease {
     /// @brief Default constructor
     ///
     /// Initialize fields that don't have a default constructor.
-    Lease4() : Lease(0, 0, 0, 0, false, false, "", HWAddrPtr())
-    {
-    }
-
-    /// @brief Copy constructor
-    ///
-    /// @param other the @c Lease4 object to be copied.
-    Lease4(const Lease4& other);
+    Lease4();
 
     /// @brief Returns Lease type
     ///
@@ -457,11 +450,6 @@ struct Lease4 : public Lease {
     bool belongsToClient(const HWAddrPtr& hw_address,
                          const ClientIdPtr& client_id) const;
 
-    /// @brief Assignment operator.
-    ///
-    /// @param other the @c Lease4 object to be assigned.
-    Lease4& operator=(const Lease4& other);
-
     /// @brief Compare two leases for equality
     ///
     /// @param other lease6 object with which to compare
@@ -719,7 +707,7 @@ template <isc::util::DhcpSpace D>
 using LeaseTPtr = boost::shared_ptr<LeaseT<D>>;
 /// @}
 
-}; // end of isc::dhcp namespace
-}; // end of isc namespace
+}  // end of isc::dhcp namespace
+}  // end of isc namespace
 
 #endif // LEASE_H
index b3109f7f5a7d9fa04834238a478b5cd3b7f5a8f2..55d370b6d7c3945e5a6a1eb2be1024c45457505d 100644 (file)
@@ -197,12 +197,44 @@ LeaseMgr::recountLeaseStats4() {
                                row.state_count_);
         }
     }
-    // Can not update counters at pool level. This would require retrieving all
-    // leases and matching them one by one to one possible pool.
+
+    query = startPoolLeaseStatsQuery4();
+    if (!query) {
+        /// NULL means not backend does not support recounting.
+        return;
+    }
+
+    // Get counts per state per subnet and pool. Iterate over the result set
+    // updating the subnet and pool and global values.
+    while (query->getNextRow(row)) {
+        if (row.lease_state_ == Lease::STATE_DEFAULT) {
+            // Add to subnet and pool level value.
+            stats_mgr.addValue(StatsMgr::generateName("subnet", row.subnet_id_,
+                                                      StatsMgr::generateName(".pool", row.pool_id_,
+                                                      "assigned-addresses")),
+                               row.state_count_);
+        } else if (row.lease_state_ == Lease::STATE_DECLINED) {
+            // Set subnet and pool level value.
+            stats_mgr.setValue(StatsMgr::generateName("subnet", row.subnet_id_,
+                                                      StatsMgr::generateName(".pool", row.pool_id_,
+                                                      "declined-addresses")),
+                               row.state_count_);
+
+            // Add to subnet and pool level value.
+            // Declined leases also count as assigned.
+            stats_mgr.addValue(StatsMgr::generateName("subnet", row.subnet_id_,
+                                                      StatsMgr::generateName(".pool", row.pool_id_,
+                                                      "assigned-addresses")),
+                               row.state_count_);
+        }
+    }
 }
 
-LeaseStatsQuery::LeaseStatsQuery()
-    : first_subnet_id_(0), last_subnet_id_(0), select_mode_(ALL_SUBNETS) {
+LeaseStatsQuery::LeaseStatsQuery(const SelectMode& select_mode)
+    : first_subnet_id_(0), last_subnet_id_(0), select_mode_(select_mode) {
+    if (select_mode != ALL_SUBNETS && select_mode != ALL_SUBNET_POOLS) {
+        isc_throw(BadValue, "LeaseStatsQuery: mode must be either ALL_SUBNETS or ALL_SUBNET_POOLS");
+    }
 }
 
 LeaseStatsQuery::LeaseStatsQuery(const SubnetID& subnet_id)
@@ -238,6 +270,11 @@ LeaseMgr::startLeaseStatsQuery4() {
     return(LeaseStatsQueryPtr());
 }
 
+LeaseStatsQueryPtr
+LeaseMgr::startPoolLeaseStatsQuery4() {
+    return(LeaseStatsQueryPtr());
+}
+
 LeaseStatsQueryPtr
 LeaseMgr::startSubnetLeaseStatsQuery4(const SubnetID& /* subnet_id */) {
     return(LeaseStatsQueryPtr());
@@ -419,12 +456,59 @@ LeaseMgr::recountLeaseStats6() {
                 break;
 
             default:
-                // We dont' support TYPE_TAs yet
+                // We don't support TYPE_TAs yet
+                break;
+        }
+    }
+
+    query = startPoolLeaseStatsQuery6();
+    if (!query) {
+        /// NULL means not backend does not support recounting.
+        return;
+    }
+
+    // Get counts per state per subnet and pool. Iterate over the result set
+    // updating the subnet and pool and global values.
+    while (query->getNextRow(row)) {
+        switch(row.lease_type_) {
+            case Lease::TYPE_NA:
+                if (row.lease_state_ == Lease::STATE_DEFAULT) {
+                    // Add to subnet and pool level value.
+                    stats_mgr.addValue(StatsMgr::generateName("subnet", row.subnet_id_,
+                                                              StatsMgr::generateName(".pool", row.pool_id_,
+                                                              "assigned-nas")),
+                                       row.state_count_);
+                } else if (row.lease_state_ == Lease::STATE_DECLINED) {
+                    // Set subnet and pool level value.
+                    stats_mgr.setValue(StatsMgr::generateName("subnet", row.subnet_id_,
+                                                              StatsMgr::generateName(".pool", row.pool_id_,
+                                                              "declined-addresses")),
+                                       row.state_count_);
+
+                    // Add to subnet and pool level value.
+                    // Declined leases also count as assigned.
+                    stats_mgr.addValue(StatsMgr::generateName("subnet", row.subnet_id_,
+                                                              StatsMgr::generateName(".pool", row.pool_id_,
+                                                              "assigned-nas")),
+                                       row.state_count_);
+                }
+                break;
+
+            case Lease::TYPE_PD:
+                if (row.lease_state_ == Lease::STATE_DEFAULT) {
+                    // Set subnet and pool level value.
+                    stats_mgr.setValue(StatsMgr::generateName("subnet", row.subnet_id_,
+                                                              StatsMgr::generateName(".pd-pool", row.pool_id_,
+                                                              "assigned-pds")),
+                                       row.state_count_);
+                }
+                break;
+
+            default:
+                // We don't support TYPE_TAs yet
                 break;
         }
     }
-    // Can not update counters at pool level. This would require retrieving all
-    // leases and matching them one by one to one possible pool.
 }
 
 LeaseStatsQueryPtr
@@ -432,6 +516,11 @@ LeaseMgr::startLeaseStatsQuery6() {
     return(LeaseStatsQueryPtr());
 }
 
+LeaseStatsQueryPtr
+LeaseMgr::startPoolLeaseStatsQuery6() {
+    return(LeaseStatsQueryPtr());
+}
+
 LeaseStatsQueryPtr
 LeaseMgr::startSubnetLeaseStatsQuery6(const SubnetID& /* subnet_id */) {
     return(LeaseStatsQueryPtr());
index 50277f0996087b2e09fa163ff23f291ad268dd81..a1259e54d6d03114d4cc448259468911a3cc795f 100644 (file)
@@ -64,7 +64,7 @@ public:
 struct LeaseStatsRow {
     /// @brief Default constructor
     LeaseStatsRow() :
-        subnet_id_(0), lease_type_(Lease::TYPE_NA),
+        subnet_id_(0), pool_id_(0), lease_type_(Lease::TYPE_NA),
         lease_state_(Lease::STATE_DEFAULT), state_count_(0) {
     }
 
@@ -75,9 +75,11 @@ struct LeaseStatsRow {
     /// @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
+    /// @param pool_id The pool id to which this data applies or 0 if it is not
+    /// used
     LeaseStatsRow(const SubnetID& subnet_id, const uint32_t lease_state,
-                  const int64_t state_count)
-        : subnet_id_(subnet_id), lease_type_(Lease::TYPE_NA),
+                  const int64_t state_count, uint32_t pool_id = 0)
+        : subnet_id_(subnet_id), pool_id_(pool_id), lease_type_(Lease::TYPE_NA),
           lease_state_(lease_state), state_count_(state_count) {
     }
 
@@ -87,9 +89,12 @@ struct LeaseStatsRow {
     /// @param lease_type The lease type for this state count
     /// @param lease_state The lease state counted
     /// @param state_count The count of leases in the lease state
+    /// @param pool_id The pool id to which this data applies or 0 if it is not
+    /// used
     LeaseStatsRow(const SubnetID& subnet_id, const Lease::Type& lease_type,
-                  const uint32_t lease_state, const int64_t state_count)
-        : subnet_id_(subnet_id), lease_type_(lease_type),
+                  const uint32_t lease_state, const int64_t state_count,
+                  uint32_t pool_id = 0)
+        : subnet_id_(subnet_id), pool_id_(pool_id), lease_type_(lease_type),
           lease_state_(lease_state), state_count_(state_count) {
     }
 
@@ -100,14 +105,21 @@ struct LeaseStatsRow {
         }
 
         if (subnet_id_ == rhs.subnet_id_ &&
+            pool_id_ < rhs.pool_id_) {
+            return (true);
+        }
+
+        if (subnet_id_ == rhs.subnet_id_ &&
+            pool_id_ == rhs.pool_id_ &&
             lease_type_ < rhs.lease_type_) {
-                return (true);
+            return (true);
         }
 
         if (subnet_id_ == rhs.subnet_id_ &&
+            pool_id_ == rhs.pool_id_ &&
             lease_type_ == rhs.lease_type_ &&
             lease_state_ < rhs.lease_state_) {
-                return (true);
+            return (true);
         }
 
         return (false);
@@ -115,10 +127,16 @@ struct LeaseStatsRow {
 
     /// @brief The subnet ID to which this data applies
     SubnetID subnet_id_;
+
+    /// @brief The pool ID to which this data applies
+    uint32_t pool_id_;
+
     /// @brief The lease_type 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_;
 };
@@ -134,12 +152,17 @@ public:
     typedef enum {
         ALL_SUBNETS,
         SINGLE_SUBNET,
-        SUBNET_RANGE
+        SUBNET_RANGE,
+        ALL_SUBNET_POOLS
     } SelectMode;
 
-    /// @brief Default constructor
+    /// @brief Constructor to query statistics for all subnets
+    ///
     /// The query created will return statistics for all subnets
-    LeaseStatsQuery();
+    ///
+    /// @param select_mode The selection criteria which is either ALL_SUBNETS or
+    /// ALL_SUBNET_POOLS
+    LeaseStatsQuery(const SelectMode& select_mode = ALL_SUBNETS);
 
     /// @brief Constructor to query for a single subnet's stats
     ///
@@ -600,6 +623,19 @@ public:
     /// @return A populated LeaseStatsQuery
     virtual LeaseStatsQueryPtr startLeaseStatsQuery4();
 
+    /// @brief Creates and runs the IPv4 lease stats query for all subnets and
+    /// pools
+    ///
+    /// LeaseMgr derivations implement this method such that it creates and
+    /// returns an instance of an LeaseStatsQuery whose result set has been
+    /// populated with up to date IPv4 lease statistical data for all subnets
+    /// and pools.
+    /// Each row of the result set is an LeaseStatRow which ordered ascending
+    /// by subnet ID and pool ID.
+    ///
+    /// @return A populated LeaseStatsQuery
+    virtual LeaseStatsQueryPtr startPoolLeaseStatsQuery4();
+
     /// @brief Creates and runs the IPv4 lease stats query for a single subnet
     ///
     /// LeaseMgr derivations implement this method such that it creates and
@@ -657,6 +693,19 @@ public:
     /// @return A populated LeaseStatsQuery
     virtual LeaseStatsQueryPtr startLeaseStatsQuery6();
 
+    /// @brief Creates and runs the IPv6 lease stats query for all subnets and
+    /// pools
+    ///
+    /// LeaseMgr derivations implement this method such that it creates and
+    /// returns an instance of an LeaseStatsQuery whose result set has been
+    /// populated with up to date IPv6 lease statistical data for all subnets
+    /// and pools.
+    /// Each row of the result set is an LeaseStatRow which ordered ascending
+    /// by subnet ID and pool ID.
+    ///
+    /// @return A populated LeaseStatsQuery
+    virtual LeaseStatsQueryPtr startPoolLeaseStatsQuery6();
+
     /// @brief Creates and runs the IPv6 lease stats query for a single subnet
     ///
     /// LeaseMgr derivations implement this method such that it creates and
index d86b7025c9570c79ee3d6d760bd2b1f801ae2415..62ac6c4f1cd4e66f6fec34445a31198c2e9af611 100644 (file)
@@ -266,8 +266,10 @@ class MemfileLeaseStatsQuery : public LeaseStatsQuery {
 public:
     /// @brief Constructor for all subnets query
     ///
-    MemfileLeaseStatsQuery()
-        : rows_(0), next_pos_(rows_.end()) {
+    /// @param select_mode The selection criteria which is either ALL_SUBNETS or
+    /// ALL_SUBNET_POOLS
+    MemfileLeaseStatsQuery(const SelectMode& select_mode = ALL_SUBNETS)
+        : LeaseStatsQuery(select_mode), rows_(0), next_pos_(rows_.end()) {
     };
 
     /// @brief Constructor for single subnet query
@@ -335,8 +337,11 @@ public:
     /// @brief Constructor for an all subnets query
     ///
     /// @param storage4 A pointer to the v4 lease storage to be counted
-    MemfileLeaseStatsQuery4(Lease4Storage& storage4)
-        : MemfileLeaseStatsQuery(), storage4_(storage4) {
+    /// @param select_mode The selection criteria which is either ALL_SUBNETS or
+    /// ALL_SUBNET_POOLS
+    MemfileLeaseStatsQuery4(Lease4Storage& storage4,
+                            const SelectMode& select_mode = ALL_SUBNETS)
+        : MemfileLeaseStatsQuery(select_mode), storage4_(storage4) {
     };
 
     /// @brief Constructor for a single subnet query
@@ -363,7 +368,35 @@ public:
     /// @brief Creates the IPv4 lease statistical data result set
     ///
     /// The result set is populated by iterating over the IPv4 leases in
-    /// storage, in ascending order by address, accumulating the lease state
+    /// storage, in ascending order by subnet id or by subnet id and pool id,
+    /// accumulating the lease state counts per subnet or per subnet and pool.
+    /// At the completion of all entries for a given subnet or pool, the counts
+    /// are used to create LeaseStatsRow instances which are appended to an
+    /// internal vector.  The process results in a vector containing one entry
+    /// per state per subnet or per subnet and pool.
+    ///
+    /// Currently the states counted are:
+    ///
+    /// - Lease::STATE_DEFAULT (i.e. assigned)
+    /// - Lease::STATE_DECLINED
+    void start() {
+        switch (getSelectMode()) {
+        case ALL_SUBNETS:
+        case SINGLE_SUBNET:
+        case SUBNET_RANGE:
+            startSubnets();
+            break;
+
+        case ALL_SUBNET_POOLS:
+            startSubnetPools();
+            break;
+        }
+    }
+
+    /// @brief Creates the IPv4 lease statistical data result set
+    ///
+    /// The result set is populated by iterating over the IPv4 leases in
+    /// storage, in ascending order by subnet id, accumulating the lease state
     /// counts per subnet.
     /// At the completion of all entries for a given subnet, the counts are
     /// used to create LeaseStatsRow instances which are appended to an
@@ -374,13 +407,14 @@ public:
     ///
     /// - Lease::STATE_DEFAULT (i.e. assigned)
     /// - Lease::STATE_DECLINED
-    void start() {
+    void startSubnets() {
         const Lease4StorageSubnetIdIndex& idx
             = storage4_.get<SubnetIdIndexTag>();
 
         // Set lower and upper bounds based on select mode
         Lease4StorageSubnetIdIndex::const_iterator lower;
         Lease4StorageSubnetIdIndex::const_iterator upper;
+
         switch (getSelectMode()) {
         case ALL_SUBNETS:
             lower = idx.begin();
@@ -396,6 +430,9 @@ public:
             lower = idx.lower_bound(getFirstSubnetID());
             upper = idx.upper_bound(getLastSubnetID());
             break;
+
+        default:
+            return;
         }
 
         // Return an empty set if there are no rows.
@@ -457,6 +494,122 @@ public:
         next_pos_ = rows_.begin();
     }
 
+    /// @brief Creates the IPv4 lease statistical data result set
+    ///
+    /// The result set is populated by iterating over the IPv4 leases in
+    /// storage, in ascending order by subnet id and pool id, accumulating the
+    /// lease state counts per subnet and pool.
+    /// At the completion of all entries for a given subnet or pool, the counts
+    /// are used to create LeaseStatsRow instances which are appended to an
+    /// internal vector.  The process results in a vector containing one entry
+    /// per state per subnet and pool.
+    ///
+    /// Currently the states counted are:
+    ///
+    /// - Lease::STATE_DEFAULT (i.e. assigned)
+    /// - Lease::STATE_DECLINED
+    void startSubnetPools() {
+        const Lease4StorageSubnetIdPoolIdIndex& idx
+            = storage4_.get<SubnetIdPoolIdIndexTag>();
+
+        // Set lower and upper bounds based on select mode
+        Lease4StorageSubnetIdPoolIdIndex::const_iterator lower;
+        Lease4StorageSubnetIdPoolIdIndex::const_iterator upper;
+
+        switch (getSelectMode()) {
+        case ALL_SUBNET_POOLS:
+            lower = idx.begin();
+            upper = idx.end();
+            break;
+
+        default:
+            return;
+        }
+
+        // Return an empty set if there are no rows.
+        if (lower == upper) {
+            return;
+        }
+
+        // Iterate over the leases in order by subnet and pool, accumulating per
+        // subnet and pool counts for each state of interest.  As we finish each
+        // subnet or pool, add the appropriate rows to our result set.
+        SubnetID cur_id = 0;
+        uint32_t cur_pool_id = 0;
+        int64_t assigned = 0;
+        int64_t declined = 0;
+        for (Lease4StorageSubnetIdPoolIdIndex::const_iterator lease = lower;
+             lease != upper; ++lease) {
+            // If we've hit the next pool, add rows for the current subnet and
+            // pool and wipe the accumulators
+            if ((*lease)->pool_id_ != cur_pool_id) {
+                if (assigned > 0) {
+                    rows_.push_back(LeaseStatsRow(cur_id,
+                                                  Lease::STATE_DEFAULT,
+                                                  assigned, cur_pool_id));
+                    assigned = 0;
+                }
+
+                if (declined > 0) {
+                    rows_.push_back(LeaseStatsRow(cur_id,
+                                                  Lease::STATE_DECLINED,
+                                                  declined, cur_pool_id));
+                    declined = 0;
+                }
+
+                // Update current pool id
+                cur_pool_id = (*lease)->pool_id_;
+            }
+
+            // If we've hit the next subnet, add rows for the current subnet
+            // and wipe the accumulators
+            if ((*lease)->subnet_id_ != cur_id) {
+                if (cur_id > 0) {
+                    if (assigned > 0) {
+                        rows_.push_back(LeaseStatsRow(cur_id,
+                                                      Lease::STATE_DEFAULT,
+                                                      assigned, cur_pool_id));
+                        assigned = 0;
+                    }
+
+                    if (declined > 0) {
+                        rows_.push_back(LeaseStatsRow(cur_id,
+                                                      Lease::STATE_DECLINED,
+                                                      declined, cur_pool_id));
+                        declined = 0;
+                    }
+                }
+
+                // Update current subnet id
+                cur_id = (*lease)->subnet_id_;
+
+                // Reset pool id
+                cur_pool_id = 0;
+            }
+
+            // Bump the appropriate accumulator
+            if ((*lease)->state_ == Lease::STATE_DEFAULT) {
+                ++assigned;
+            } else if ((*lease)->state_ == Lease::STATE_DECLINED) {
+                ++declined;
+            }
+        }
+
+        // Make the rows for last subnet
+        if (assigned > 0) {
+            rows_.push_back(LeaseStatsRow(cur_id, Lease::STATE_DEFAULT,
+                                          assigned, cur_pool_id));
+        }
+
+        if (declined > 0) {
+            rows_.push_back(LeaseStatsRow(cur_id, Lease::STATE_DECLINED,
+                                          declined, cur_pool_id));
+        }
+
+        // Reset the next row position back to the beginning of the rows.
+        next_pos_ = rows_.begin();
+    }
+
 private:
     /// @brief The Memfile storage containing the IPv4 leases to analyze
     Lease4Storage& storage4_;
@@ -477,8 +630,11 @@ public:
     /// @brief Constructor
     ///
     /// @param storage6 A pointer to the v6 lease storage to be counted
-    MemfileLeaseStatsQuery6(Lease6Storage& storage6)
-        : MemfileLeaseStatsQuery(), storage6_(storage6) {
+    /// @param select_mode The selection criteria which is either ALL_SUBNETS or
+    /// ALL_SUBNET_POOLS
+    MemfileLeaseStatsQuery6(Lease6Storage& storage6,
+                            const SelectMode& select_mode = ALL_SUBNETS)
+        : MemfileLeaseStatsQuery(select_mode), storage6_(storage6) {
     };
 
     /// @brief Constructor for a single subnet query
@@ -502,20 +658,49 @@ public:
     /// @brief Destructor
     virtual ~MemfileLeaseStatsQuery6() {};
 
+    /// @brief Creates the IPv6 lease statistical data result set
+    ///
+    /// The result set is populated by iterating over the IPv6 leases in
+    /// storage, in ascending order by subnet id or by subnet id and pool id,
+    /// accumulating the lease state counts per subnet or per subnet and pool.
+    /// At the completion of all entries for a given subnet or pool, the counts
+    /// are used to create LeaseStatsRow instances which are appended to an
+    /// internal vector.  The process results in a vector containing one entry
+    /// per state per subnet or per subnet and pool.
+    ///
+    /// Currently the states counted are:
+    ///
+    /// - Lease::STATE_DEFAULT (i.e. assigned)
+    /// - Lease::STATE_DECLINED
+    void start() {
+        switch (getSelectMode()) {
+        case ALL_SUBNETS:
+        case SINGLE_SUBNET:
+        case SUBNET_RANGE:
+            startSubnets();
+            break;
+
+        case ALL_SUBNET_POOLS:
+            startSubnetPools();
+            break;
+        }
+    }
+
     /// @brief Creates the IPv6 lease statistical data result set
     ///
     /// The result set is populated by iterating over the IPv6 leases in
     /// storage, in ascending order by subnet id, accumulating the lease state
-    /// counts per subnet. At the completion of all entries for a given subnet,
-    /// the counts are used to create LeaseStatsRow instances which are appended
-    /// to an internal vector.  The process results in a vector containing one
-    /// entry per state per lease type per subnet.
+    /// counts per subnet.
+    /// At the completion of all entries for a given subnet, the counts are
+    /// used to create LeaseStatsRow instances which are appended to an
+    /// internal vector.  The process results in a vector containing one entry
+    /// per state per subnet.
     ///
     /// Currently the states counted are:
     ///
     /// - Lease::STATE_DEFAULT (i.e. assigned)
     /// - Lease::STATE_DECLINED
-    virtual void start() {
+    virtual void startSubnets() {
         // Get the subnet_id index
         const Lease6StorageSubnetIdIndex& idx
             = storage6_.get<SubnetIdIndexTag>();
@@ -538,6 +723,9 @@ public:
             lower = idx.lower_bound(getFirstSubnetID());
             upper = idx.upper_bound(getLastSubnetID());
             break;
+
+        default:
+            return;
         }
 
         // Return an empty set if there are no rows.
@@ -624,6 +812,157 @@ public:
         next_pos_ = rows_.begin();
     }
 
+    /// @brief Creates the IPv6 lease statistical data result set
+    ///
+    /// The result set is populated by iterating over the IPv6 leases in
+    /// storage, in ascending order by subnet id and pool id, accumulating the
+    /// lease state counts per subnet and pool.
+    /// At the completion of all entries for a given subnet or pool, the counts
+    /// are used to create LeaseStatsRow instances which are appended to an
+    /// internal vector.  The process results in a vector containing one entry
+    /// per state per subnet and pool.
+    ///
+    /// Currently the states counted are:
+    ///
+    /// - Lease::STATE_DEFAULT (i.e. assigned)
+    /// - Lease::STATE_DECLINED
+    virtual void startSubnetPools() {
+        // Get the subnet_id index
+        const Lease6StorageSubnetIdPoolIdIndex& idx
+            = storage6_.get<SubnetIdPoolIdIndexTag>();
+
+        // Set lower and upper bounds based on select mode
+        Lease6StorageSubnetIdPoolIdIndex::const_iterator lower;
+        Lease6StorageSubnetIdPoolIdIndex::const_iterator upper;
+        switch (getSelectMode()) {
+        case ALL_SUBNET_POOLS:
+            lower = idx.begin();
+            upper = idx.end();
+            break;
+
+        default:
+            return;
+        }
+
+        // Return an empty set if there are no rows.
+        if (lower == upper) {
+            return;
+        }
+
+        // Iterate over the leases in order by subnet, accumulating per
+        // subnet counts for each state of interest.  As we finish each
+        // subnet, add the appropriate rows to our result set.
+        SubnetID cur_id = 0;
+        uint32_t cur_pool_id = 0;
+        int64_t assigned = 0;
+        int64_t declined = 0;
+        int64_t assigned_pds = 0;
+        for (Lease6StorageSubnetIdPoolIdIndex::const_iterator lease = lower;
+             lease != upper; ++lease) {
+            // If we've hit the next pool, add rows for the current subnet and
+            // pool and wipe the accumulators
+            if ((*lease)->pool_id_ != cur_pool_id) {
+                if (assigned > 0) {
+                    rows_.push_back(LeaseStatsRow(cur_id, Lease::TYPE_NA,
+                                                  Lease::STATE_DEFAULT,
+                                                  assigned, cur_pool_id));
+                    assigned = 0;
+                }
+
+                if (declined > 0) {
+                    rows_.push_back(LeaseStatsRow(cur_id, Lease::TYPE_NA,
+                                                  Lease::STATE_DECLINED,
+                                                  declined, cur_pool_id));
+                    declined = 0;
+                }
+
+                if (assigned_pds > 0) {
+                    rows_.push_back(LeaseStatsRow(cur_id, Lease::TYPE_PD,
+                                                  Lease::STATE_DEFAULT,
+                                                  assigned_pds, cur_pool_id));
+                    assigned_pds = 0;
+                }
+
+                // Update current pool id
+                cur_pool_id = (*lease)->pool_id_;
+            }
+
+            // If we've hit the next subnet, add rows for the current subnet
+            // and wipe the accumulators
+            if ((*lease)->subnet_id_ != cur_id) {
+                if (cur_id > 0) {
+                    if (assigned > 0) {
+                        rows_.push_back(LeaseStatsRow(cur_id, Lease::TYPE_NA,
+                                                      Lease::STATE_DEFAULT,
+                                                      assigned, cur_pool_id));
+                        assigned = 0;
+                    }
+
+                    if (declined > 0) {
+                        rows_.push_back(LeaseStatsRow(cur_id, Lease::TYPE_NA,
+                                                      Lease::STATE_DECLINED,
+                                                      declined, cur_pool_id));
+                        declined = 0;
+                    }
+
+                    if (assigned_pds > 0) {
+                        rows_.push_back(LeaseStatsRow(cur_id, Lease::TYPE_PD,
+                                                      Lease::STATE_DEFAULT,
+                                                      assigned_pds, cur_pool_id));
+                        assigned_pds = 0;
+                    }
+                }
+
+                // Update current subnet id
+                cur_id = (*lease)->subnet_id_;
+
+                // Reset pool id
+                cur_pool_id = 0;
+            }
+
+            // Bump the appropriate accumulator
+            if ((*lease)->state_ == Lease::STATE_DEFAULT) {
+                switch((*lease)->type_) {
+                case Lease::TYPE_NA:
+                    ++assigned;
+                    break;
+                case Lease::TYPE_PD:
+                    ++assigned_pds;
+                    break;
+                default:
+                    break;
+                }
+            } else if ((*lease)->state_ == Lease::STATE_DECLINED) {
+                // In theory only NAs can be declined
+                if (((*lease)->type_) == Lease::TYPE_NA) {
+                    ++declined;
+                }
+            }
+        }
+
+        // Make the rows for last subnet, unless there were no rows
+        if (assigned > 0) {
+            rows_.push_back(LeaseStatsRow(cur_id, Lease::TYPE_NA,
+                                          Lease::STATE_DEFAULT, assigned,
+                                          cur_pool_id));
+        }
+
+        if (declined > 0) {
+            rows_.push_back(LeaseStatsRow(cur_id, Lease::TYPE_NA,
+                                          Lease::STATE_DECLINED, declined,
+                                          cur_pool_id));
+        }
+
+        if (assigned_pds > 0) {
+            rows_.push_back(LeaseStatsRow(cur_id, Lease::TYPE_PD,
+                                          Lease::STATE_DEFAULT, assigned_pds,
+                                          cur_pool_id));
+        }
+
+        // Set the next row position to the beginning of the rows.
+        next_pos_ = rows_.begin();
+    }
+
 private:
     /// @brief The Memfile storage containing the IPv6 leases to analyze
     Lease6Storage& storage6_;
@@ -2097,6 +2436,19 @@ Memfile_LeaseMgr::startLeaseStatsQuery4() {
     return(query);
 }
 
+LeaseStatsQueryPtr
+Memfile_LeaseMgr::startPoolLeaseStatsQuery4() {
+    LeaseStatsQueryPtr query(new MemfileLeaseStatsQuery4(storage4_, LeaseStatsQuery::ALL_SUBNET_POOLS));
+    if (MultiThreadingMgr::instance().getMode()) {
+        std::lock_guard<std::mutex> lock(*mutex_);
+        query->start();
+    } else {
+        query->start();
+    }
+
+    return(query);
+}
+
 LeaseStatsQueryPtr
 Memfile_LeaseMgr::startSubnetLeaseStatsQuery4(const SubnetID& subnet_id) {
     LeaseStatsQueryPtr query(new MemfileLeaseStatsQuery4(storage4_, subnet_id));
@@ -2138,6 +2490,19 @@ Memfile_LeaseMgr::startLeaseStatsQuery6() {
     return(query);
 }
 
+LeaseStatsQueryPtr
+Memfile_LeaseMgr::startPoolLeaseStatsQuery6() {
+    LeaseStatsQueryPtr query(new MemfileLeaseStatsQuery6(storage6_, LeaseStatsQuery::ALL_SUBNET_POOLS));
+    if (MultiThreadingMgr::instance().getMode()) {
+        std::lock_guard<std::mutex> lock(*mutex_);
+        query->start();
+    } else {
+        query->start();
+    }
+
+    return(query);
+}
+
 LeaseStatsQueryPtr
 Memfile_LeaseMgr::startSubnetLeaseStatsQuery6(const SubnetID& subnet_id) {
     LeaseStatsQueryPtr query(new MemfileLeaseStatsQuery6(storage6_, subnet_id));
index 2afdb7aa2ba8d135df68f4eaa49d977ac01cd2dc..71ec646927b5ddd76c3c8ecb04794ebc0aa957ca 100644 (file)
@@ -1115,6 +1115,19 @@ public:
     /// @return The populated query as a pointer to an LeaseStatsQuery
     virtual LeaseStatsQueryPtr startLeaseStatsQuery4() override;
 
+    /// @brief Creates and runs the IPv4 lease stats query for all subnets and
+    /// pools
+    ///
+    /// LeaseMgr derivations implement this method such that it creates and
+    /// returns an instance of an LeaseStatsQuery whose result set has been
+    /// populated with up to date IPv4 lease statistical data for all subnets
+    /// and pools.
+    /// Each row of the result set is an LeaseStatRow which ordered ascending
+    /// by subnet ID and pool ID.
+    ///
+    /// @return A populated LeaseStatsQuery
+    virtual LeaseStatsQueryPtr startPoolLeaseStatsQuery4() override;
+
     /// @brief Creates and runs the IPv4 lease stats query for a single subnet
     ///
     /// It creates an instance of a MemfileLeaseStatsQuery4 for a single subnet
@@ -1146,6 +1159,19 @@ public:
     /// @return The populated query as a pointer to an LeaseStatsQuery.
     virtual LeaseStatsQueryPtr startLeaseStatsQuery6() override;
 
+    /// @brief Creates and runs the IPv6 lease stats query for all subnets and
+    /// pools
+    ///
+    /// LeaseMgr derivations implement this method such that it creates and
+    /// returns an instance of an LeaseStatsQuery whose result set has been
+    /// populated with up to date IPv6 lease statistical data for all subnets
+    /// and pools.
+    /// Each row of the result set is an LeaseStatRow which ordered ascending
+    /// by subnet ID and pool ID.
+    ///
+    /// @return A populated LeaseStatsQuery
+    virtual LeaseStatsQueryPtr startPoolLeaseStatsQuery6() override;
+
     /// @brief Creates and runs the IPv6 lease stats query for a single subnet
     ///
     /// It creates an instance of a MemfileLeaseStatsQuery6 for a single subnet
index 6506b28c0634555463ef684cdfba98a9507288c3..a7dc60ea15fa3b1752a8fb370c3eb9143d4c13f4 100644 (file)
@@ -166,7 +166,7 @@ tagged_statements = { {
                     "SELECT address, hwaddr, client_id, "
                         "valid_lifetime, expire, subnet_id, "
                         "fqdn_fwd, fqdn_rev, hostname, "
-                        "state, user_context, relay_id, remote_id "
+                        "state, user_context, relay_id, remote_id, pool_id "
                             "FROM lease4 "
                             "WHERE address > ? AND user_context IS NOT NULL "
                             "ORDER BY address "
@@ -345,7 +345,7 @@ tagged_statements = { {
                         "lease_type, iaid, prefix_len, "
                         "fqdn_fwd, fqdn_rev, hostname, "
                         "hwaddr, hwtype, hwaddr_source, "
-                        "state, user_context "
+                        "state, user_context, pool_id "
                             "FROM lease6 "
                             "WHERE address > ? AND user_context IS NOT NULL "
                             "ORDER BY address "
@@ -456,6 +456,9 @@ tagged_statements = { {
                         "FROM lease4_stat "
                         "WHERE subnet_id >= ? and subnet_id <= ? "
                         "ORDER BY subnet_id, state"},
+    {MySqlLeaseMgr::ALL_POOL_LEASE4_STATS,
+                    "SELECT subnet_id, pool_id, state, leases as state_count "
+                        "FROM lease4_pool_stat ORDER BY subnet_id, pool_id, state"},
     {MySqlLeaseMgr::ALL_LEASE6_STATS,
                     "SELECT subnet_id, lease_type, state, leases as state_count "
                         "FROM lease6_stat ORDER BY subnet_id, lease_type, state"},
@@ -469,9 +472,15 @@ tagged_statements = { {
                         "FROM lease6_stat "
                         "WHERE subnet_id >= ? and subnet_id <= ? "
                         "ORDER BY subnet_id, lease_type, state"},
-    {MySqlLeaseMgr::CHECK_LEASE4_LIMITS, "SELECT checkLease4Limits(?)"},
-    {MySqlLeaseMgr::CHECK_LEASE6_LIMITS, "SELECT checkLease6Limits(?)"},
-    {MySqlLeaseMgr::IS_JSON_SUPPORTED, "SELECT isJsonSupported()"},
+    {MySqlLeaseMgr::ALL_POOL_LEASE6_STATS,
+                    "SELECT subnet_id, pool_id, lease_type, state, leases as state_count "
+                        "FROM lease6_pool_stat ORDER BY subnet_id, pool_id, lease_type, state"},
+    {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 "
@@ -1797,15 +1806,17 @@ public:
     /// @param conn An open connection to the database housing the lease data
     /// @param statement_index Index of the query's prepared statement
     /// @param fetch_type Indicates if query supplies lease type
+    /// @param fetch_pool Indicates if query requires pool data
     /// @throw if statement index is invalid.
     MySqlLeaseStatsQuery(MySqlConnection& conn, const size_t statement_index,
-                         const bool fetch_type)
+                         const bool fetch_type, const bool fetch_pool = false)
         : conn_(conn), statement_index_(statement_index), statement_(NULL),
-          fetch_type_(fetch_type),
+          fetch_type_(fetch_type), fetch_pool_(fetch_pool),
           // Set the number of columns in the bind array based on fetch_type
           // This is the number of columns expected in the result set
-          bind_(fetch_type_ ? 4 : 3),
-          subnet_id_(0), lease_type_(0), state_(0), state_count_(0) {
+          bind_(fetch_type_ ? (fetch_pool_ ? 5 : 4) : (fetch_pool_ ? 4 : 3)),
+          subnet_id_(0), pool_id_(0), lease_type_(Lease::TYPE_NA),
+          state_(Lease::STATE_DEFAULT), state_count_(0) {
           validateStatement();
     }
 
@@ -1821,11 +1832,12 @@ public:
     MySqlLeaseStatsQuery(MySqlConnection& conn, const size_t statement_index,
                          const bool fetch_type, const SubnetID& subnet_id)
         : LeaseStatsQuery(subnet_id), conn_(conn), statement_index_(statement_index),
-          statement_(NULL), fetch_type_(fetch_type),
+          statement_(NULL), fetch_type_(fetch_type), fetch_pool_(false),
           // Set the number of columns in the bind array based on fetch_type
           // This is the number of columns expected in the result set
-          bind_(fetch_type_ ? 4 : 3),
-          subnet_id_(0), lease_type_(0), state_(0), state_count_(0) {
+          bind_(fetch_type_ ? 4 : 3), subnet_id_(0), pool_id_(0),
+          lease_type_(Lease::TYPE_NA), state_(Lease::STATE_DEFAULT),
+          state_count_(0) {
           validateStatement();
     }
 
@@ -1845,11 +1857,13 @@ public:
                          const bool fetch_type, const SubnetID& first_subnet_id,
                          const SubnetID& last_subnet_id)
         : LeaseStatsQuery(first_subnet_id, last_subnet_id), conn_(conn),
-          statement_index_(statement_index), statement_(NULL), fetch_type_(fetch_type),
+          statement_index_(statement_index), statement_(NULL),
+          fetch_type_(fetch_type), fetch_pool_(false),
           // Set the number of columns in the bind array based on fetch_type
           // This is the number of columns expected in the result set
-          bind_(fetch_type_ ? 4 : 3),
-          subnet_id_(0), lease_type_(0), state_(0), state_count_(0) {
+          bind_(fetch_type_ ? 4 : 3), subnet_id_(0), pool_id_(0),
+          lease_type_(Lease::TYPE_NA), state_(Lease::STATE_DEFAULT),
+          state_count_(0) {
           validateStatement();
     }
 
@@ -1867,7 +1881,7 @@ public:
     /// entire result set.
     void start() {
         // Set up where clause inputs if needed.
-        if (getSelectMode() != ALL_SUBNETS) {
+        if (getSelectMode() != ALL_SUBNETS && getSelectMode() != ALL_SUBNET_POOLS) {
             MYSQL_BIND inbind[2];
             memset(inbind, 0, sizeof(inbind));
 
@@ -1895,6 +1909,15 @@ public:
         bind_[col].is_unsigned = MLM_TRUE;
         ++col;
 
+        // Fetch the pool id if we were told to do so.
+        if (fetch_pool_) {
+            // pool id: uint32_t
+            bind_[col].buffer_type = MYSQL_TYPE_LONG;
+            bind_[col].buffer = reinterpret_cast<char*>(&pool_id_);
+            bind_[col].is_unsigned = MLM_TRUE;
+            ++col;
+        }
+
         // Fetch the lease type if we were told to do so.
         if (fetch_type_) {
             // lease type: uint32_t
@@ -1952,6 +1975,7 @@ public:
         int status = mysql_stmt_fetch(statement_);
         if (status == MLM_MYSQL_FETCH_SUCCESS) {
             row.subnet_id_ = static_cast<SubnetID>(subnet_id_);
+            row.pool_id_ = pool_id_;
             row.lease_type_ = static_cast<Lease::Type>(lease_type_);
             row.lease_state_ = state_;
             if (state_count_ >= 0) {
@@ -1997,12 +2021,18 @@ private:
     /// @brief Indicates if query supplies lease type
     bool fetch_type_;
 
+    /// @brief Indicates if query requires pool data
+    bool fetch_pool_;
+
     /// @brief Bind array used to store the query result set;
     std::vector<MYSQL_BIND> bind_;
 
     /// @brief Receives subnet ID when fetching a row
     uint32_t subnet_id_;
 
+    /// @brief Receives pool ID when fetching a row
+    uint32_t pool_id_;
+
     /// @brief Receives the lease type when fetching a row
     uint32_t lease_type_;
 
@@ -3584,6 +3614,19 @@ MySqlLeaseMgr::startLeaseStatsQuery4() {
     return(query);
 }
 
+LeaseStatsQueryPtr
+MySqlLeaseMgr::startPoolLeaseStatsQuery4() {
+    // Get a context
+    MySqlLeaseContextAlloc get_context(*this);
+    MySqlLeaseContextPtr ctx = get_context.ctx_;
+
+    LeaseStatsQueryPtr query(new MySqlLeaseStatsQuery(ctx->conn_,
+                                                      ALL_POOL_LEASE4_STATS,
+                                                      false, true));
+    query->start();
+    return(query);
+}
+
 LeaseStatsQueryPtr
 MySqlLeaseMgr::startSubnetLeaseStatsQuery4(const SubnetID& subnet_id) {
     // Get a context
@@ -3627,6 +3670,19 @@ MySqlLeaseMgr::startLeaseStatsQuery6() {
     return(query);
 }
 
+LeaseStatsQueryPtr
+MySqlLeaseMgr::startPoolLeaseStatsQuery6() {
+    // Get a context
+    MySqlLeaseContextAlloc get_context(*this);
+    MySqlLeaseContextPtr ctx = get_context.ctx_;
+
+    LeaseStatsQueryPtr query(new MySqlLeaseStatsQuery(ctx->conn_,
+                                                      ALL_POOL_LEASE6_STATS,
+                                                      true, true));
+    query->start();
+    return(query);
+}
+
 LeaseStatsQueryPtr
 MySqlLeaseMgr::startSubnetLeaseStatsQuery6(const SubnetID& subnet_id) {
     // Get a context
index 58d50a45ddb7d621ac4ae6599655fa99f1faa916..e1abd88bd22a20dcb503a43689380f88e1359070 100644 (file)
@@ -562,6 +562,19 @@ public:
     /// @return The populated query as a pointer to an LeaseStatsQuery
     virtual LeaseStatsQueryPtr startLeaseStatsQuery4() override;
 
+    /// @brief Creates and runs the IPv4 lease stats query for all subnets and
+    /// pools
+    ///
+    /// LeaseMgr derivations implement this method such that it creates and
+    /// returns an instance of an LeaseStatsQuery whose result set has been
+    /// populated with up to date IPv4 lease statistical data for all subnets
+    /// and pools.
+    /// Each row of the result set is an LeaseStatRow which ordered ascending
+    /// by subnet ID and pool ID.
+    ///
+    /// @return A populated LeaseStatsQuery
+    virtual LeaseStatsQueryPtr startPoolLeaseStatsQuery4() override;
+
     /// @brief Creates and runs the IPv4 lease stats query for a single subnet
     ///
     /// It creates an instance of a MySqlLeaseStatsQuery4 for a single subnet
@@ -594,6 +607,19 @@ public:
     /// @return The populated query as a pointer to an LeaseStatsQuery
     virtual LeaseStatsQueryPtr startLeaseStatsQuery6() override;
 
+    /// @brief Creates and runs the IPv6 lease stats query for all subnets and
+    /// pools
+    ///
+    /// LeaseMgr derivations implement this method such that it creates and
+    /// returns an instance of an LeaseStatsQuery whose result set has been
+    /// populated with up to date IPv6 lease statistical data for all subnets
+    /// and pools.
+    /// Each row of the result set is an LeaseStatRow which ordered ascending
+    /// by subnet ID and pool ID.
+    ///
+    /// @return A populated LeaseStatsQuery
+    virtual LeaseStatsQueryPtr startPoolLeaseStatsQuery6() override;
+
     /// @brief Creates and runs the IPv6 lease stats query for a single subnet
     ///
     /// It creates an instance of a MySqlLeaseStatsQuery6 for a single subnet
@@ -733,9 +759,11 @@ public:
         ALL_LEASE4_STATS,            // Fetches IPv4 lease statistics
         SUBNET_LEASE4_STATS,         // Fetched IPv4 lease stats for a single subnet.
         SUBNET_RANGE_LEASE4_STATS,   // Fetched IPv4 lease stats for a subnet range.
+        ALL_POOL_LEASE4_STATS,       // Fetches IPv4 lease pool statistics
         ALL_LEASE6_STATS,            // Fetches IPv6 lease statistics
         SUBNET_LEASE6_STATS,         // Fetched IPv6 lease stats for a single subnet.
         SUBNET_RANGE_LEASE6_STATS,   // Fetched IPv6 lease stats for a subnet range.
+        ALL_POOL_LEASE6_STATS,       // Fetches IPv6 lease pool statistics
         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.
index 4646ecf6291a656d030d21f7b315761eb4039685..9cd4b35acb5705bde8d98a74ab93f8b5021bb840 100644 (file)
@@ -44,24 +44,24 @@ PgSqlTaggedStatement tagged_statements[] = {
     // DELETE_LEASE4
     { 2, { OID_INT8, OID_TIMESTAMP },
       "delete_lease4",
-      "DELETE FROM lease4 WHERE address = $1 AND expire = $2"},
+      "DELETE FROM lease4 WHERE address = $1 AND expire = $2" },
 
     // DELETE_LEASE4_STATE_EXPIRED
     { 2, { OID_INT8, OID_TIMESTAMP },
       "delete_lease4_state_expired",
       "DELETE FROM lease4 "
-          "WHERE state = $1 AND expire < $2"},
+          "WHERE state = $1 AND expire < $2" },
 
     // DELETE_LEASE6
     { 2, { OID_VARCHAR, OID_TIMESTAMP },
       "delete_lease6",
-      "DELETE FROM lease6 WHERE address = $1 AND expire = $2"},
+      "DELETE FROM lease6 WHERE address = $1 AND expire = $2" },
 
     // DELETE_LEASE6_STATE_EXPIRED
     { 2, { OID_INT8, OID_TIMESTAMP },
       "delete_lease6_state_expired",
       "DELETE FROM lease6 "
-          "WHERE state = $1 AND expire < $2"},
+          "WHERE state = $1 AND expire < $2" },
 
     // GET_LEASE4
     { 0, { OID_NONE },
@@ -70,7 +70,7 @@ PgSqlTaggedStatement tagged_statements[] = {
         "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
         "fqdn_fwd, fqdn_rev, hostname, "
         "state, user_context, relay_id, remote_id, pool_id "
-      "FROM lease4"},
+      "FROM lease4" },
 
     // GET_LEASE4_ADDR
     { 1, { OID_INT8 },
@@ -80,7 +80,7 @@ PgSqlTaggedStatement tagged_statements[] = {
         "fqdn_fwd, fqdn_rev, hostname, "
         "state, user_context, relay_id, remote_id, pool_id "
       "FROM lease4 "
-      "WHERE address = $1"},
+      "WHERE address = $1" },
 
     // GET_LEASE4_CLIENTID
     { 1, { OID_BYTEA },
@@ -90,7 +90,7 @@ PgSqlTaggedStatement tagged_statements[] = {
         "fqdn_fwd, fqdn_rev, hostname, "
         "state, user_context, relay_id, remote_id, pool_id "
       "FROM lease4 "
-      "WHERE client_id = $1"},
+      "WHERE client_id = $1" },
 
     // GET_LEASE4_CLIENTID_SUBID
     { 2, { OID_BYTEA, OID_INT8 },
@@ -100,7 +100,7 @@ PgSqlTaggedStatement tagged_statements[] = {
         "fqdn_fwd, fqdn_rev, hostname, "
         "state, user_context, relay_id, remote_id, pool_id "
       "FROM lease4 "
-      "WHERE client_id = $1 AND subnet_id = $2"},
+      "WHERE client_id = $1 AND subnet_id = $2" },
 
     // GET_LEASE4_HWADDR
     { 1, { OID_BYTEA },
@@ -110,7 +110,7 @@ PgSqlTaggedStatement tagged_statements[] = {
         "fqdn_fwd, fqdn_rev, hostname, "
         "state, user_context, relay_id, remote_id, pool_id "
       "FROM lease4 "
-      "WHERE hwaddr = $1"},
+      "WHERE hwaddr = $1" },
 
     // GET_LEASE4_HWADDR_SUBID
     { 2, { OID_BYTEA, OID_INT8 },
@@ -120,7 +120,7 @@ PgSqlTaggedStatement tagged_statements[] = {
         "fqdn_fwd, fqdn_rev, hostname, "
         "state, user_context, relay_id, remote_id, pool_id "
       "FROM lease4 "
-      "WHERE hwaddr = $1 AND subnet_id = $2"},
+      "WHERE hwaddr = $1 AND subnet_id = $2" },
 
     // GET_LEASE4_PAGE
     { 2, { OID_INT8, OID_INT8 },
@@ -132,7 +132,7 @@ PgSqlTaggedStatement tagged_statements[] = {
       "FROM lease4 "
       "WHERE address > $1 "
       "ORDER BY address "
-      "LIMIT $2"},
+      "LIMIT $2" },
 
     // GET_LEASE4_UCTX_PAGE
     { 2, { OID_INT8, OID_INT8 },
@@ -140,7 +140,7 @@ PgSqlTaggedStatement tagged_statements[] = {
       "SELECT address, hwaddr, client_id, "
         "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
         "fqdn_fwd, fqdn_rev, hostname, "
-        "state, user_context, relay_id, remote_id "
+        "state, user_context, relay_id, remote_id, pool_id "
       "FROM lease4 "
       "WHERE address > $1 AND user_context IS NOT NULL "
       "ORDER BY address "
@@ -154,7 +154,7 @@ PgSqlTaggedStatement tagged_statements[] = {
         "fqdn_fwd, fqdn_rev, hostname, "
       "state, user_context, relay_id, remote_id, pool_id "
       "FROM lease4 "
-      "WHERE subnet_id = $1"},
+      "WHERE subnet_id = $1" },
 
     // GET_LEASE4_HOSTNAME
     { 1, { OID_VARCHAR },
@@ -164,7 +164,7 @@ PgSqlTaggedStatement tagged_statements[] = {
         "fqdn_fwd, fqdn_rev, hostname, "
       "state, user_context, relay_id, remote_id, pool_id "
       "FROM lease4 "
-      "WHERE lower(hostname) = $1"},
+      "WHERE lower(hostname) = $1" },
 
     // GET_LEASE4_EXPIRE
     { 3, { OID_INT8, OID_TIMESTAMP, OID_INT8 },
@@ -176,7 +176,7 @@ PgSqlTaggedStatement tagged_statements[] = {
       "FROM lease4 "
       "WHERE state != $1 AND valid_lifetime != 4294967295 AND expire < $2 "
       "ORDER BY expire "
-      "LIMIT $3"},
+      "LIMIT $3" },
 
     // GET_LEASE4_RELAYID
     { 3, { OID_BYTEA, OID_INT8, OID_INT8 },
@@ -188,7 +188,7 @@ PgSqlTaggedStatement tagged_statements[] = {
       "FROM lease4 "
       "WHERE relay_id = $1 and address > $2 "
       "ORDER BY address "
-      "LIMIT $3"},
+      "LIMIT $3" },
 
     // GET_LEASE4_RELAYID_QST
     { 4, { OID_BYTEA, OID_INT8, OID_INT8, OID_INT8 },
@@ -202,7 +202,7 @@ PgSqlTaggedStatement tagged_statements[] = {
       "and EXTRACT(EPOCH FROM expire) - (CASE valid_lifetime WHEN 4294967295 "
        "THEN 0 ELSE valid_lifetime END) >= $3 "
       "ORDER BY address "
-      "LIMIT $4"},
+      "LIMIT $4" },
 
     // GET_LEASE4_RELAYID_QSET
     { 5, { OID_BYTEA, OID_INT8, OID_INT8, OID_INT8, OID_INT8 },
@@ -218,7 +218,7 @@ PgSqlTaggedStatement tagged_statements[] = {
       "and EXTRACT(EPOCH FROM expire) - (CASE valid_lifetime WHEN 4294967295 "
        "THEN 0 ELSE valid_lifetime END) <= $4 "
       "ORDER BY address "
-      "LIMIT $5"},
+      "LIMIT $5" },
 
     // GET_LEASE4_RELAYID_QET
     { 4, { OID_BYTEA, OID_INT8, OID_INT8, OID_INT8 },
@@ -232,7 +232,7 @@ PgSqlTaggedStatement tagged_statements[] = {
       "and EXTRACT(EPOCH FROM expire) - (CASE valid_lifetime WHEN 4294967295 "
        "THEN 0 ELSE valid_lifetime END) <= $3 "
       "ORDER BY address "
-      "LIMIT $4"},
+      "LIMIT $4" },
 
     // GET_LEASE4_REMOTEID
     { 3, { OID_BYTEA, OID_INT8, OID_INT8 },
@@ -244,7 +244,7 @@ PgSqlTaggedStatement tagged_statements[] = {
       "FROM lease4 "
       "WHERE remote_id = $1 and address > $2 "
       "ORDER BY address "
-      "LIMIT $3"},
+      "LIMIT $3" },
 
     // GET_LEASE4_REMOTEID_QST
     { 4, { OID_BYTEA, OID_INT8, OID_INT8, OID_INT8 },
@@ -258,7 +258,7 @@ PgSqlTaggedStatement tagged_statements[] = {
       "and EXTRACT(EPOCH FROM expire) - (CASE valid_lifetime WHEN 4294967295 "
        "THEN 0 ELSE valid_lifetime END) >= $3 "
       "ORDER BY address "
-      "LIMIT $4"},
+      "LIMIT $4" },
 
     // GET_LEASE4_REMOTEID_QSET
     { 5, { OID_BYTEA, OID_INT8, OID_INT8, OID_INT8, OID_INT8 },
@@ -274,7 +274,7 @@ PgSqlTaggedStatement tagged_statements[] = {
       "and EXTRACT(EPOCH FROM expire) - (CASE valid_lifetime WHEN 4294967295 "
        "THEN 0 ELSE valid_lifetime END) <= $4 "
       "ORDER BY address "
-      "LIMIT $5"},
+      "LIMIT $5" },
 
     // GET_LEASE4_REMOTEID_QET
     { 4, { OID_BYTEA, OID_INT8, OID_INT8, OID_INT8 },
@@ -288,7 +288,7 @@ PgSqlTaggedStatement tagged_statements[] = {
       "and EXTRACT(EPOCH FROM expire) - (CASE valid_lifetime WHEN 4294967295 "
        "THEN 0 ELSE valid_lifetime END) <= $3 "
       "ORDER BY address "
-      "LIMIT $4"},
+      "LIMIT $4" },
 
     // GET_LEASE6
     { 0, { OID_NONE },
@@ -298,7 +298,7 @@ PgSqlTaggedStatement tagged_statements[] = {
         "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
         "hwaddr, hwtype, hwaddr_source, "
         "state, user_context, pool_id "
-      "FROM lease6"},
+      "FROM lease6" },
 
     // GET_LEASE6_ADDR
     { 2, { OID_VARCHAR, OID_INT2 },
@@ -309,7 +309,7 @@ PgSqlTaggedStatement tagged_statements[] = {
         "hwaddr, hwtype, hwaddr_source, "
         "state, user_context, pool_id "
       "FROM lease6 "
-      "WHERE address = $1 AND lease_type = $2"},
+      "WHERE address = $1 AND lease_type = $2" },
 
     // GET_LEASE6_DUID_IAID
     { 3, { OID_BYTEA, OID_INT8, OID_INT2 },
@@ -320,7 +320,7 @@ PgSqlTaggedStatement tagged_statements[] = {
         "hwaddr, hwtype, hwaddr_source, "
         "state, user_context, pool_id "
       "FROM lease6 "
-      "WHERE duid = $1 AND iaid = $2 AND lease_type = $3"},
+      "WHERE duid = $1 AND iaid = $2 AND lease_type = $3" },
 
     // GET_LEASE6_DUID_IAID_SUBID
     { 4, { OID_INT2, OID_BYTEA, OID_INT8, OID_INT8 },
@@ -332,7 +332,7 @@ PgSqlTaggedStatement tagged_statements[] = {
         "state, user_context, pool_id "
       "FROM lease6 "
       "WHERE lease_type = $1 "
-        "AND duid = $2 AND iaid = $3 AND subnet_id = $4"},
+        "AND duid = $2 AND iaid = $3 AND subnet_id = $4" },
 
     // GET_LEASE6_PAGE
     { 2, { OID_VARCHAR, OID_INT8 },
@@ -345,7 +345,7 @@ PgSqlTaggedStatement tagged_statements[] = {
       "FROM lease6 "
       "WHERE address > $1 "
       "ORDER BY address "
-      "LIMIT $2"},
+      "LIMIT $2" },
 
     // GET_LEASE6_UCTX_PAGE
     { 2, { OID_VARCHAR, OID_INT8 },
@@ -354,7 +354,7 @@ PgSqlTaggedStatement tagged_statements[] = {
         "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
         "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
         "hwaddr, hwtype, hwaddr_source, "
-        "state, user_context "
+        "state, user_context, pool_id "
       "FROM lease6 "
       "WHERE address > $1 AND user_context IS NOT NULL "
       "ORDER BY address "
@@ -382,7 +382,7 @@ PgSqlTaggedStatement tagged_statements[] = {
         "hwaddr, hwtype, hwaddr_source, "
         "state, user_context, pool_id "
       "FROM lease6 "
-      "WHERE subnet_id = $1"},
+      "WHERE subnet_id = $1" },
 
     // GET_LEASE6_DUID
     { 1, { OID_BYTEA },
@@ -393,7 +393,7 @@ PgSqlTaggedStatement tagged_statements[] = {
         "hwaddr, hwtype, hwaddr_source, "
         "state, user_context, pool_id "
       "FROM lease6 "
-      "WHERE duid = $1"},
+      "WHERE duid = $1" },
 
     // GET_LEASE6_HOSTNAME
     { 1, { OID_VARCHAR },
@@ -404,7 +404,7 @@ PgSqlTaggedStatement tagged_statements[] = {
         "hwaddr, hwtype, hwaddr_source, "
         "state, user_context, pool_id "
       "FROM lease6 "
-      "WHERE lower(hostname) = $1"},
+      "WHERE lower(hostname) = $1" },
 
     // GET_LEASE6_EXPIRE
     { 3, { OID_INT8, OID_TIMESTAMP, OID_INT8 },
@@ -418,7 +418,7 @@ PgSqlTaggedStatement tagged_statements[] = {
       "FROM lease6 "
       "WHERE state != $1 AND valid_lifetime != 4294967295 AND expire < $2 "
       "ORDER BY expire "
-      "LIMIT $3"},
+      "LIMIT $3" },
 
     // GET_LEASE6_LINK
     { 3, { OID_BYTEA, OID_BYTEA, OID_INT8 },
@@ -442,7 +442,7 @@ PgSqlTaggedStatement tagged_statements[] = {
       "INSERT INTO lease4(address, hwaddr, client_id, "
         "valid_lifetime, expire, subnet_id, fqdn_fwd, fqdn_rev, hostname, "
         "state, user_context, relay_id, remote_id, pool_id) "
-      "VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)"},
+      "VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)" },
 
     // INSERT_LEASE6
     { 19, { OID_VARCHAR, OID_BYTEA, OID_INT8, OID_TIMESTAMP, OID_INT8,
@@ -455,7 +455,7 @@ PgSqlTaggedStatement tagged_statements[] = {
         "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
         "hwaddr, hwtype, hwaddr_source, "
         "state, user_context, binaddr, pool_id) "
-      "VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19)"},
+      "VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19)" },
 
     // UPDATE_LEASE4
     { 16, { OID_INT8, OID_BYTEA, OID_BYTEA, OID_INT8, OID_TIMESTAMP, OID_INT8,
@@ -466,7 +466,7 @@ PgSqlTaggedStatement tagged_statements[] = {
         "client_id = $3, valid_lifetime = $4, expire = $5, "
         "subnet_id = $6, fqdn_fwd = $7, fqdn_rev = $8, hostname = $9, "
         "state = $10, user_context = $11, relay_id = $12, remote_id = $13, pool_id = $14 "
-      "WHERE address = $15 AND expire = $16"},
+      "WHERE address = $15 AND expire = $16" },
 
     // UPDATE_LEASE6
     { 21, { OID_VARCHAR, OID_BYTEA, OID_INT8, OID_TIMESTAMP, OID_INT8, OID_INT8,
@@ -480,13 +480,13 @@ PgSqlTaggedStatement tagged_statements[] = {
         "prefix_len = $9, fqdn_fwd = $10, fqdn_rev = $11, hostname = $12, "
         "hwaddr = $13, hwtype = $14, hwaddr_source = $15, "
         "state = $16, user_context = $17, binaddr = $18, pool_id = $19 "
-      "WHERE address = $20 AND expire = $21"},
+      "WHERE address = $20 AND expire = $21" },
 
     // ALL_LEASE4_STATS
     { 0, { OID_NONE },
       "all_lease4_stats",
       "SELECT subnet_id, state, leases as state_count"
-      "  FROM lease4_stat ORDER BY subnet_id, state"},
+      "  FROM lease4_stat ORDER BY subnet_id, state" },
 
     // SUBNET_LEASE4_STATS
     { 1, { OID_INT8 },
@@ -494,7 +494,7 @@ PgSqlTaggedStatement tagged_statements[] = {
       "SELECT subnet_id, state, leases as state_count"
       "  FROM lease4_stat "
       "  WHERE subnet_id = $1 "
-      "  ORDER BY state"},
+      "  ORDER BY state" },
 
     // SUBNET_RANGE_LEASE4_STATS
     { 2, { OID_INT8, OID_INT8 },
@@ -502,13 +502,19 @@ PgSqlTaggedStatement tagged_statements[] = {
       "SELECT subnet_id, state, leases as state_count"
       "  FROM lease4_stat "
       "  WHERE subnet_id >= $1 and subnet_id <= $2 "
-      "  ORDER BY subnet_id, state"},
+      "  ORDER BY subnet_id, state" },
+
+    // ALL_POOL_LEASE4_STATS
+    { 0, { OID_NONE },
+      "all_pool_lease4_stats",
+      "SELECT subnet_id, pool_id, state, leases as state_count"
+      "  FROM lease4_pool_stat ORDER BY subnet_id, pool_id, state" },
 
     // ALL_LEASE6_STATS,
     { 0, { OID_NONE },
-     "all_lease6_stats",
-     "SELECT subnet_id, lease_type, state, leases as state_count"
-     "  FROM lease6_stat ORDER BY subnet_id, lease_type, state" },
+      "all_lease6_stats",
+      "SELECT subnet_id, lease_type, state, leases as state_count"
+      "  FROM lease6_stat ORDER BY subnet_id, lease_type, state" },
 
     // SUBNET_LEASE6_STATS
     { 1, { OID_INT8 },
@@ -526,6 +532,12 @@ PgSqlTaggedStatement tagged_statements[] = {
       "  WHERE subnet_id >= $1 and subnet_id <= $2 "
       "  ORDER BY subnet_id, lease_type, state" },
 
+    // ALL_POOL_LEASE6_STATS,
+    { 0, { OID_NONE },
+      "all_pool_lease6_stats",
+      "SELECT subnet_id, pool_id, lease_type, state, leases as state_count"
+      "  FROM lease6_pool_stat ORDER BY subnet_id, pool_id, lease_type, state" },
+
     // CHECK_LEASE4_LIMITS
     { 1, { OID_TEXT },
       "check_lease4_limits",
@@ -546,14 +558,14 @@ PgSqlTaggedStatement tagged_statements[] = {
       "get_lease4_count_by_class",
       "SELECT leases "
           "FROM lease4_stat_by_client_class "
-          "WHERE client_class = $1"},
+          "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"},
+          "WHERE client_class = $1 AND lease_type = $2" },
 
     // End of list sentinel
     { 0,  { 0 }, NULL, NULL}
@@ -1274,10 +1286,11 @@ public:
     /// @param statement The lease data SQL prepared statement to execute
     /// @param fetch_type Indicates whether or not lease_type should be
     /// fetched from the result set
+    /// @param fetch_pool Indicates if query requires pool data
     PgSqlLeaseStatsQuery(PgSqlConnection& conn, PgSqlTaggedStatement& statement,
-                         const bool fetch_type)
+                         const bool fetch_type, const bool fetch_pool = false)
         : conn_(conn), statement_(statement), result_set_(), next_row_(0),
-         fetch_type_(fetch_type) {
+          fetch_type_(fetch_type), fetch_pool_(fetch_pool) {
     }
 
     /// @brief Constructor to query for a single subnet's stats
@@ -1291,7 +1304,7 @@ public:
     PgSqlLeaseStatsQuery(PgSqlConnection& conn, PgSqlTaggedStatement& statement,
                          const bool fetch_type, const SubnetID& subnet_id)
         : LeaseStatsQuery(subnet_id), conn_(conn), statement_(statement), result_set_(),
-          next_row_(0), fetch_type_(fetch_type) {
+          next_row_(0), fetch_type_(fetch_type), fetch_pool_(false) {
     }
 
     /// @brief Constructor to query for the stats for a range of subnets
@@ -1308,7 +1321,7 @@ public:
                          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),
-          result_set_(), next_row_(0), fetch_type_(fetch_type) {
+          result_set_(), next_row_(0), fetch_type_(fetch_type), fetch_pool_(false) {
     }
 
     /// @brief Destructor
@@ -1325,7 +1338,7 @@ public:
     /// a first and last subnet id for a subnet range.
     void start() {
 
-        if (getSelectMode() == ALL_SUBNETS) {
+        if (getSelectMode() == ALL_SUBNETS || getSelectMode() == ALL_SUBNET_POOLS) {
             // Run the query with no where clause parameters.
             result_set_.reset(new PgSqlResult(PQexecPrepared(conn_, statement_.name,
                                                              0, 0, 0, 0, 0)));
@@ -1378,6 +1391,13 @@ public:
         row.subnet_id_ = static_cast<SubnetID>(subnet_id);
         ++col;
 
+        // Fetch the pool id if we were told to do so.
+        if (fetch_pool_) {
+            PgSqlExchange::getColumnValue(*result_set_, next_row_ , col,
+                                          row.pool_id_);
+            ++col;
+        }
+
         // Fetch the lease type if we were told to do so.
         if (fetch_type_) {
             uint32_t lease_type;
@@ -1429,6 +1449,9 @@ protected:
     /// @brief Indicates if query supplies lease type
     bool fetch_type_;
 
+    /// @brief Indicates if query requires pool data
+    bool fetch_pool_;
+
     /// @brief Received negative state count showing a problem
     static bool negative_count_;
 };
@@ -2751,6 +2774,19 @@ PgSqlLeaseMgr::startLeaseStatsQuery4() {
     return(query);
 }
 
+LeaseStatsQueryPtr
+PgSqlLeaseMgr::startPoolLeaseStatsQuery4() {
+    // Get a context
+    PgSqlLeaseContextAlloc get_context(*this);
+    PgSqlLeaseContextPtr ctx = get_context.ctx_;
+
+    LeaseStatsQueryPtr query(new PgSqlLeaseStatsQuery(ctx->conn_,
+                                                      tagged_statements[ALL_POOL_LEASE4_STATS],
+                                                      false, true));
+    query->start();
+    return(query);
+}
+
 LeaseStatsQueryPtr
 PgSqlLeaseMgr::startSubnetLeaseStatsQuery4(const SubnetID& subnet_id) {
     // Get a context
@@ -2794,6 +2830,19 @@ PgSqlLeaseMgr::startLeaseStatsQuery6() {
     return(query);
 }
 
+LeaseStatsQueryPtr
+PgSqlLeaseMgr::startPoolLeaseStatsQuery6() {
+    // Get a context
+    PgSqlLeaseContextAlloc get_context(*this);
+    PgSqlLeaseContextPtr ctx = get_context.ctx_;
+
+    LeaseStatsQueryPtr query(new PgSqlLeaseStatsQuery(ctx->conn_,
+                                                      tagged_statements[ALL_POOL_LEASE6_STATS],
+                                                      true, true));
+    query->start();
+    return(query);
+}
+
 LeaseStatsQueryPtr
 PgSqlLeaseMgr::startSubnetLeaseStatsQuery6(const SubnetID& subnet_id) {
     // Get a context
index 95fda12d2ca12b8246737b62432fd16a67ee282e..12435dd0a7d1a76e4fb35e6b18f54cad9e9c8549 100644 (file)
@@ -538,6 +538,19 @@ public:
     /// @return The populated query as a pointer to an LeaseStatsQuery
     virtual LeaseStatsQueryPtr startLeaseStatsQuery4() override;
 
+    /// @brief Creates and runs the IPv4 lease stats query for all subnets and
+    /// pools
+    ///
+    /// LeaseMgr derivations implement this method such that it creates and
+    /// returns an instance of an LeaseStatsQuery whose result set has been
+    /// populated with up to date IPv4 lease statistical data for all subnets
+    /// and pools.
+    /// Each row of the result set is an LeaseStatRow which ordered ascending
+    /// by subnet ID and pool ID.
+    ///
+    /// @return A populated LeaseStatsQuery
+    virtual LeaseStatsQueryPtr startPoolLeaseStatsQuery4() override;
+
     /// @brief Creates and runs the IPv4 lease stats query for a single subnet
     ///
     /// It creates an instance of a PgSqlLeaseStatsQuery4 for a single subnet
@@ -570,6 +583,19 @@ public:
     /// @return The populated query as a pointer to an LeaseStatsQuery
     virtual LeaseStatsQueryPtr startLeaseStatsQuery6() override;
 
+    /// @brief Creates and runs the IPv6 lease stats query for all subnets and
+    /// pools
+    ///
+    /// LeaseMgr derivations implement this method such that it creates and
+    /// returns an instance of an LeaseStatsQuery whose result set has been
+    /// populated with up to date IPv6 lease statistical data for all subnets
+    /// and pools.
+    /// Each row of the result set is an LeaseStatRow which ordered ascending
+    /// by subnet ID and pool ID.
+    ///
+    /// @return A populated LeaseStatsQuery
+    virtual LeaseStatsQueryPtr startPoolLeaseStatsQuery6() override;
+
     /// @brief Creates and runs the IPv6 lease stats query for a single subnet
     ///
     /// It creates an instance of a PgSqlLeaseStatsQuery6 for a single subnet
@@ -709,9 +735,11 @@ public:
         ALL_LEASE4_STATS,            // Fetches IPv4 lease statistics
         SUBNET_LEASE4_STATS,         // Fetched IPv4 lease stats for a single subnet.
         SUBNET_RANGE_LEASE4_STATS,   // Fetched IPv4 lease stats for a subnet range.
+        ALL_POOL_LEASE4_STATS,       // Fetches IPv4 lease pool statistics
         ALL_LEASE6_STATS,            // Fetches IPv6 lease statistics
         SUBNET_LEASE6_STATS,         // Fetched IPv6 lease stats for a single subnet.
         SUBNET_RANGE_LEASE6_STATS,   // Fetched IPv6 lease stats for a subnet range.
+        ALL_POOL_LEASE6_STATS,       // Fetches IPv6 lease pool statistics
         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.
index 35cdb52394ab48aaf128cdde03050f9b71de200d..b63131b8885fe86c1429a118ed8bed52024c40e4 100644 (file)
@@ -142,118 +142,6 @@ TEST_F(Lease4Test, constructor) {
     }
 }
 
-// This test verifies that copy constructor copies Lease4 fields correctly.
-TEST_F(Lease4Test, copyConstructor) {
-
-    // Get current time for the use in Lease4.
-    const time_t current_time = time(0);
-
-    // Create the lease
-    Lease4 lease(0xffffffff, hwaddr_, clientid_, VALID_LIFETIME, current_time,
-                 SUBNET_ID);
-
-    // Declined is a non-default state. We'll see if the state will be copied
-    // or the default state will be set for the copied lease.
-    lease.state_ = Lease::STATE_DECLINED;
-
-    // Set an user context.
-    lease.setContext(Element::fromJSON("{ \"foobar\": 1234 }"));
-
-    // Set relay and remote id.
-    const std::vector<uint8_t> relay_id = { 0xaa, 0xbb, 0xcc };
-    lease.relay_id_ = relay_id;
-    const std::vector<uint8_t> remote_id = { 1, 2, 3 };
-    lease.remote_id_ = remote_id;
-
-    // Use copy constructor to copy the lease.
-    Lease4 copied_lease(lease);
-
-    // Both leases should be now equal. When doing this check we assume that
-    // the equality operator works correctly.
-    EXPECT_TRUE(lease == copied_lease);
-    // Client IDs are equal, but they should be in two distinct pointers.
-    EXPECT_FALSE(lease.client_id_ == copied_lease.client_id_);
-
-    // User context are equal and point to the same object.
-    ASSERT_TRUE(copied_lease.getContext());
-    EXPECT_TRUE(lease.getContext() == copied_lease.getContext());
-    EXPECT_TRUE(*lease.getContext() == *copied_lease.getContext());
-
-    // Relay and remote ids are equal.
-    EXPECT_TRUE(lease.relay_id_ == copied_lease.relay_id_);
-    EXPECT_TRUE(lease.remote_id_ == copied_lease.remote_id_);
-
-    // Hardware addresses are equal, but they should point to two objects,
-    // each holding the same data. The content should be equal...
-    EXPECT_TRUE(*lease.hwaddr_ == *copied_lease.hwaddr_);
-
-    // ... but it should point to different objects.
-    EXPECT_FALSE(lease.hwaddr_ == copied_lease.hwaddr_);
-
-    // Now let's check that the hwaddr pointer is copied even if it's null:
-    lease.hwaddr_.reset();
-    Lease4 copied_lease2(lease);
-    EXPECT_TRUE(lease == copied_lease2);
-}
-
-// This test verifies that the assignment operator copies all Lease4 fields
-// correctly.
-TEST_F(Lease4Test, operatorAssign) {
-
-    // Get the current time for the use in Lease4.
-    const time_t current_time = time(0);
-
-    // Create the lease
-    Lease4 lease(0xffffffff, hwaddr_, clientid_, VALID_LIFETIME, current_time,
-                 SUBNET_ID);
-
-    // Declined is a non-default state. We'll see if the state will be copied
-    // or the default state will be set for the copied lease.
-    lease.state_ = Lease::STATE_DECLINED;
-
-    // Set an user context.
-    lease.setContext(Element::fromJSON("{ \"foobar\": 1234 }"));
-
-    // Set relay and remote id.
-    const std::vector<uint8_t> relay_id = { 0xaa, 0xbb, 0xcc };
-    lease.relay_id_ = relay_id;
-    const std::vector<uint8_t> remote_id = { 1, 2, 3 };
-    lease.remote_id_ = remote_id;
-
-    // Create a default lease.
-    Lease4 assigned_lease;
-    // Use assignment operator to assign new lease.
-    assigned_lease = lease;
-
-    // Both leases should be now equal. When doing this check we assume that
-    // the equality operator works correctly.
-    EXPECT_TRUE(lease == assigned_lease);
-    // Client IDs are equal, but they should be in two distinct pointers.
-    EXPECT_FALSE(lease.client_id_ == assigned_lease.client_id_);
-
-    // User context are equal and point to the same object.
-    ASSERT_TRUE(assigned_lease.getContext());
-    EXPECT_TRUE(lease.getContext() == assigned_lease.getContext());
-    EXPECT_TRUE(*lease.getContext() == *assigned_lease.getContext());
-
-    // User context are equal and point to the same object.
-    ASSERT_TRUE(assigned_lease.getContext());
-    EXPECT_TRUE(lease.getContext() == assigned_lease.getContext());
-    EXPECT_TRUE(*lease.getContext() == *assigned_lease.getContext());
-
-    // Hardware addresses are equal, but they should point to two objects,
-    // each holding the same data. The content should be equal...
-    EXPECT_TRUE(*lease.hwaddr_ == *assigned_lease.hwaddr_);
-
-    // ... but it should point to different objects.
-    EXPECT_FALSE(lease.hwaddr_ == assigned_lease.hwaddr_);
-
-    // Now let's check that the hwaddr pointer is copied even if it's null:
-    lease.hwaddr_.reset();
-    assigned_lease = lease;
-    EXPECT_TRUE(lease == assigned_lease);
-}
-
 // This test verifies that it is correctly determined when the lease
 // belongs to the particular client identified by the client identifier
 // and hw address.
index a245c138f3a067fddf91d32fc66f77ee99141d86..d9301246ef3a0d56ab77ca6103257017fc783a44 100644 (file)
@@ -158,6 +158,5 @@ TrackingLeaseMgr::runCallbacksForSubnetID(CallbackType type, SubnetID subnet_id,
     }
 }
 
-
 } // end of namespace isc::dhcp
 } // end of namespace isc
index 31e91c6de84b80095503831be09d8a511c912dde..62928c5ac34f6e1fb2d2301aa9a860cf970fa9a8 100644 (file)
@@ -312,5 +312,4 @@ protected:
 } // end of namespace isc::dhcp
 } // end of namespace isc
 
-    
 #endif // TRACKING_LEASE_MGR_H