Browse Source

[2907] add ConfigurableClientList::getZoneTableAccessor

Paul Selkirk 12 years ago
parent
commit
a6f8022934

+ 30 - 1
src/lib/datasrc/client_list.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2012  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2013  Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -26,6 +26,7 @@
 #include <datasrc/logger.h>
 #include <dns/masterload.h>
 #include <util/memory_segment_local.h>
+#include <datasrc/zone_table_accessor_cache.h>
 
 #include <memory>
 #include <set>
@@ -399,5 +400,33 @@ ConfigurableClientList::getStatus() const {
     return (result);
 }
 
+boost::shared_ptr<const ZoneTableAccessor>
+ConfigurableClientList::getZoneTableAccessor(const std::string& datasrc_name,
+                                             bool use_cache) const
+{
+    if (!use_cache) {
+        isc_throw(isc::NotImplemented,
+              "getZoneTableAccessor only implemented for cache");
+    }
+
+    // Find the matching data source
+    BOOST_FOREACH(const DataSourceInfo& info, data_sources_) {
+        if (!datasrc_name.empty() && datasrc_name != info.name_) {
+            continue;
+        }
+
+        const internal::CacheConfig* config(info.getCacheConfig());
+        if (!config->isEnabled() && datasrc_name.empty())
+            continue;
+
+	// If caching is disabled for the data source, this will
+	// return an accessor to an effectivley empty table.
+        return (boost::shared_ptr<const ZoneTableAccessor>
+                (new internal::ZoneTableAccessorCache(*config)));
+    }
+
+    return (boost::shared_ptr<const ZoneTableAccessor>());
+}
+
 }
 }

+ 20 - 3
src/lib/datasrc/client_list.h

@@ -1,4 +1,4 @@
-// Copyright (C) 2012  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2013  Internet Systems Consortium, Inc. ("ISC")
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
@@ -22,6 +22,7 @@
 #include <cc/data.h>
 #include <exceptions/exceptions.h>
 #include "memory/zone_table_segment.h"
+#include <datasrc/zone_table_accessor.h>
 
 #include <vector>
 #include <boost/shared_ptr.hpp>
@@ -279,8 +280,8 @@ typedef boost::shared_ptr<ClientList> ClientListPtr;
 /// \brief Shared const pointer to the list.
 typedef boost::shared_ptr<const ClientList> ConstClientListPtr;
 
-/// \Concrete implementation of the ClientList, which is constructed based on
-///     configuration.
+/// \brief Concrete implementation of the ClientList, which is constructed
+/// based on configuration.
 ///
 /// This is the implementation which is expected to be used in the servers.
 /// However, it is expected most of the code will use it as the ClientList,
@@ -481,6 +482,22 @@ public:
     /// it might be, so it is just made public (there's no real reason to
     /// hide it).
     const DataSources& getDataSources() const { return (data_sources_); }
+
+    /// \brief Creates a ZoneTableAccessor object for the specified data
+    /// source.
+    ///
+    /// \param datasrc_name If not empty, the name of the data source
+    /// \param use_cache If true, create a zone table for in-memory cache.
+    /// \note At present, the only concrete implementation of
+    /// ZoneTableAccessor is ZoneTableAccessorCache, so \c use_cache must be
+    /// true.
+    /// \throw NotImplemented if \c use_cache is false.
+    /// \return A pointer to the accessor, or NULL if the requested data
+    /// source is not found or has its cache disabled.
+    boost::shared_ptr<const ZoneTableAccessor>
+    getZoneTableAccessor(const std::string& datasrc_name,
+                         bool use_cache) const;
+
 private:
     struct MutableResult;
     /// \brief Internal implementation of find.

+ 76 - 0
src/lib/datasrc/tests/client_list_unittest.cc

@@ -254,6 +254,8 @@ public:
     }
     ConfigurableClientList::CacheStatus doReload(
         const Name& origin, const string& datasrc_name = "");
+    void accessorIterate(boost::shared_ptr<const ZoneTableAccessor>accessor,
+        int numZones);
 
     const RRClass rrclass_;
     shared_ptr<TestedList> list_;
@@ -1128,6 +1130,80 @@ TEST_F(ListTest, reloadByDataSourceName) {
               doReload(Name("example.org"), "test_type4"));
 }
 
+void
+ListTest::accessorIterate(boost::shared_ptr<const ZoneTableAccessor>accessor,
+                          int numZones)
+{
+    // Confirm basic iterator behavior.
+    ZoneTableAccessor::IteratorPtr it = accessor->getIterator();
+    ASSERT_TRUE(it);
+    for (int i = 0; i < numZones; ++i) {
+        it->next();
+    }
+    EXPECT_TRUE(it->isLast());
+}
+
+TEST_F(ListTest, zoneTableAccessor) {
+    // empty configuration
+    const ConstElementPtr elem(new ListElement);
+    list_->configure(elem, true);
+    // null pointer treated as false
+    EXPECT_FALSE(list_->getZoneTableAccessor("", true));
+
+    // empty list
+    list_->configure(config_elem_, true);
+    EXPECT_FALSE(list_->getZoneTableAccessor("", true));
+
+    // allow_cache = false
+    list_->configure(config_elem_zones_, false);
+    EXPECT_FALSE(list_->getZoneTableAccessor("", true));
+    EXPECT_FALSE(list_->getZoneTableAccessor("type1", true));
+
+    // allow_cache = true, use_cache = false
+    list_->configure(config_elem_zones_, true);
+    EXPECT_THROW(list_->getZoneTableAccessor("", false), isc::NotImplemented);
+    EXPECT_THROW(list_->getZoneTableAccessor("type1", false),
+		 isc::NotImplemented);                 
+
+    const ConstElementPtr elem2(Element::fromJSON("["
+        "{"
+        "   \"type\": \"type1\","
+        "   \"cache-enable\": false,"
+        "   \"cache-zones\": [\"example.org\"],"
+        "   \"params\": [\"example.org\"]"
+        "},"
+        "{"
+        "   \"type\": \"type2\","
+        "   \"cache-enable\": true,"
+        "   \"cache-zones\": [\"example.com\"],"
+        "   \"params\": [\"example.com\"]"
+        "},"
+        "{"
+        "   \"type\": \"type3\","
+        "   \"cache-enable\": true,"
+        "   \"cache-zones\": [\"example.net\", \"example.info\"],"
+        "   \"params\": [\"example.net\", \"example.info\"]"
+        "}]"));
+    list_->configure(elem2, true);
+
+    // datasrc not found, returns NULL pointer
+    boost::shared_ptr<const ZoneTableAccessor>
+            z(list_->getZoneTableAccessor("bogus", true));
+    EXPECT_FALSE(z);
+
+    // datasrc has cache disabled, returns accessor to empty list
+    z = list_->getZoneTableAccessor("type1", true);
+    accessorIterate(z, 0);
+
+    // return first enabled datasrc
+    z = list_->getZoneTableAccessor("", true);
+    accessorIterate(z, 1);
+
+    // search by name
+    z = list_->getZoneTableAccessor("type3", true);
+    accessorIterate(z, 2);
+}
+
 // Check the status holds data
 TEST(DataSourceStatus, status) {
     const DataSourceStatus status("Test", SEGMENT_INUSE, "local");