Browse Source

[2046] Implement the MasterFiles special case

Michal 'vorner' Vaner 13 years ago
parent
commit
7d3bb3bf33

+ 69 - 26
src/lib/datasrc/client_list.cc

@@ -30,11 +30,19 @@ namespace datasrc {
 
 
 ConfigurableClientList::DataSourceInfo::DataSourceInfo(
 ConfigurableClientList::DataSourceInfo::DataSourceInfo(
     DataSourceClient* data_src_client,
     DataSourceClient* data_src_client,
-    const DataSourceClientContainerPtr& container, bool hasCache) :
+    const DataSourceClientContainerPtr& container, bool has_cache) :
     data_src_client_(data_src_client),
     data_src_client_(data_src_client),
     container_(container)
     container_(container)
 {
 {
-    if (hasCache) {
+    if (has_cache) {
+        cache_.reset(new InMemoryClient);
+    }
+}
+
+ConfigurableClientList::DataSourceInfo::DataSourceInfo(bool has_cache) :
+    data_src_client_(NULL)
+{
+    if (has_cache) {
         cache_.reset(new InMemoryClient);
         cache_.reset(new InMemoryClient);
     }
     }
 }
 }
@@ -58,48 +66,83 @@ ConfigurableClientList::configure(const Element& config, bool allow_cache) {
             if (paramConf == ConstElementPtr()) {
             if (paramConf == ConstElementPtr()) {
                 paramConf.reset(new NullElement());
                 paramConf.reset(new NullElement());
             }
             }
-            // TODO: Special-case the master files type.
-            // Ask the factory to create the data source for us
-            const DataSourcePair ds(this->getDataSourceClient(type,
-                                                              paramConf));
             const bool want_cache(allow_cache &&
             const bool want_cache(allow_cache &&
                                   dconf->contains("cache-enable") &&
                                   dconf->contains("cache-enable") &&
                                   dconf->get("cache-enable")->boolValue());
                                   dconf->get("cache-enable")->boolValue());
-            // And put it into the vector
-            new_data_sources.push_back(DataSourceInfo(ds.first, ds.second,
-                                                      want_cache));
+
+            if (type == "MasterFiles") {
+                // In case the cache is not allowed, we just skip the master
+                // files (at least for now)
+                if (!allow_cache) {
+                    continue;
+                }
+                if (!want_cache) {
+                    isc_throw(ConfigurationError, "The cache must be enabled "
+                              "for the MasterFiles type");
+                }
+                new_data_sources.push_back(DataSourceInfo(true));
+            } else {
+                // Ask the factory to create the data source for us
+                const DataSourcePair ds(this->getDataSourceClient(type,
+                                                                  paramConf));
+                // And put it into the vector
+                new_data_sources.push_back(DataSourceInfo(ds.first, ds.second,
+                                                          want_cache));
+            }
+
             if (want_cache) {
             if (want_cache) {
-                if (!dconf->contains("cache-zones")) {
+                if (!dconf->contains("cache-zones") && type != "MasterFiles") {
                     isc_throw(isc::NotImplemented, "Auto-detection of zones "
                     isc_throw(isc::NotImplemented, "Auto-detection of zones "
                               "to cache is not yet implemented, supply "
                               "to cache is not yet implemented, supply "
                               "cache-zones parameter");
                               "cache-zones parameter");
                     // TODO: Auto-detect list of all zones in the
                     // TODO: Auto-detect list of all zones in the
                     // data source.
                     // data source.
                 }
                 }
-                const ConstElementPtr zones(dconf->get("cache-zones"));
+
+                // List the zones we are loading
+                vector<string> zones_origins;
+                if (type == "MasterFiles") {
+                    const map<string, ConstElementPtr>
+                        zones_files(paramConf->mapValue());
+                    for (map<string, ConstElementPtr>::const_iterator
+                         it(zones_files.begin()); it != zones_files.end();
+                         ++it) {
+                        zones_origins.push_back(it->first);
+                    }
+                } else {
+                    const ConstElementPtr zones(dconf->get("cache-zones"));
+                    for (size_t i(0); i < zones->size(); ++i) {
+                        zones_origins.push_back(zones->get(i)->stringValue());
+                    }
+                }
+
                 const shared_ptr<InMemoryClient>
                 const shared_ptr<InMemoryClient>
                     cache(new_data_sources.back().cache_);
                     cache(new_data_sources.back().cache_);
                 const DataSourceClient* const
                 const DataSourceClient* const
                     client(new_data_sources.back().data_src_client_);
                     client(new_data_sources.back().data_src_client_);
-                for (size_t i(0); i < zones->size(); ++i) {
-                    const Name origin(zones->get(i)->stringValue());
-                    const DataSourceClient::FindResult
-                        zone(client->findZone(origin));
-                    if (zone.code != result::SUCCESS) {
-                        // The data source does not contain the zone, it can't
-                        // be cached.
-                        isc_throw(ConfigurationError, "Unable to cache "
-                                  "non-existent zone " << origin);
-                    }
+                for (vector<string>::const_iterator it(zones_origins.begin());
+                     it != zones_origins.end(); ++it) {
+                    const Name origin(*it);
                     shared_ptr<InMemoryZoneFinder>
                     shared_ptr<InMemoryZoneFinder>
                         finder(new
                         finder(new
                             InMemoryZoneFinder(rrclass_, origin));
                             InMemoryZoneFinder(rrclass_, origin));
-                    ZoneIteratorPtr iterator(client->getIterator(origin));
-                    if (!iterator) {
-                        isc_throw(isc::Unexpected, "Got NULL iterator for "
-                                  "zone " << origin);
+                    if (type == "MasterFiles") {
+                        finder->load(paramConf->get(*it)->stringValue());
+                    } else {
+                        ZoneIteratorPtr iterator;
+                        try {
+                            iterator = client->getIterator(origin);
+                        }
+                        catch (const DataSourceError&) {
+                            isc_throw(ConfigurationError, "Unable to cache "
+                                      "non-existent zone " << origin);
+                        }
+                        if (!iterator) {
+                            isc_throw(isc::Unexpected, "Got NULL iterator for "
+                                      "zone " << origin);
+                        }
+                        finder->load(*iterator);
                     }
                     }
-                    finder->load(*iterator);
                     cache->addZone(finder);
                     cache->addZone(finder);
                 }
                 }
             }
             }

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

@@ -236,16 +236,11 @@ public:
     ///
     ///
     /// \todo The content yet to be defined.
     /// \todo The content yet to be defined.
     struct DataSourceInfo {
     struct DataSourceInfo {
-        /// \brief Default constructor.
-        ///
-        /// Don't use directly. It is here so the structure can live in
-        /// a vector.
-        DataSourceInfo() :
-            data_src_client_(NULL)
-        {}
+        // Plays a role of default constructor too (for vector)
+        DataSourceInfo(bool has_cache = false);
         DataSourceInfo(DataSourceClient* data_src_client,
         DataSourceInfo(DataSourceClient* data_src_client,
                        const DataSourceClientContainerPtr& container,
                        const DataSourceClientContainerPtr& container,
-                       bool hasCache);
+                       bool has_cache);
         DataSourceClient* data_src_client_;
         DataSourceClient* data_src_client_;
         DataSourceClientContainerPtr container_;
         DataSourceClientContainerPtr container_;
         boost::shared_ptr<InMemoryClient> cache_;
         boost::shared_ptr<InMemoryClient> cache_;

+ 7 - 2
src/lib/datasrc/tests/client_list_unittest.cc

@@ -150,7 +150,12 @@ public:
         } else if (name == Name("null.org")) {
         } else if (name == Name("null.org")) {
             return (ZoneIteratorPtr());
             return (ZoneIteratorPtr());
         } else {
         } else {
-            return (ZoneIteratorPtr(new Iterator(name)));
+            FindResult result(findZone(name));
+            if (result.code == isc::datasrc::result::SUCCESS) {
+                return (ZoneIteratorPtr(new Iterator(name)));
+            } else {
+                isc_throw(DataSourceError, "No such zone");
+            }
         }
         }
     }
     }
     const string type_;
     const string type_;
@@ -737,7 +742,7 @@ TEST_F(ListTest, masterFiles) {
                    true);
                    true);
 
 
     // If cache is not enabled, nothing is loaded
     // If cache is not enabled, nothing is loaded
-    list_->configure(*elem, true);
+    list_->configure(*elem, false);
     EXPECT_EQ(0, list_->getDataSources().size());
     EXPECT_EQ(0, list_->getDataSources().size());
 }
 }