From: Michal 'vorner' Vaner Date: Tue, 27 Nov 2012 10:22:21 +0000 (+0100) Subject: [2378] The copy mode of ZoneLoader X-Git-Tag: bind10-1.0.0-beta-release~28^2~2^2~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c2d2a53b14e6330281b2c519e1bdd129d4de86b5;p=thirdparty%2Fkea.git [2378] The copy mode of ZoneLoader At least its basic version. Error handling must still be tested and done. --- diff --git a/src/lib/datasrc/tests/zone_loader_unittest.cc b/src/lib/datasrc/tests/zone_loader_unittest.cc index ea1f925d48..5c1f668b8b 100644 --- a/src/lib/datasrc/tests/zone_loader_unittest.cc +++ b/src/lib/datasrc/tests/zone_loader_unittest.cc @@ -140,24 +140,26 @@ protected: // Use the loader to load an unsigned zone. TEST_F(ZoneLoaderTest, copyUnsigned) { - prepareSource(Name("example.org"), "example.org"); - ZoneLoader loader(destination_client_, Name("example.org"), + prepareSource(Name::ROOT_NAME(), "root.zone"); + ZoneLoader loader(destination_client_, Name::ROOT_NAME(), source_client_); // It gets the updater directly in the constructor ASSERT_EQ(1, destination_client_.provided_updaters_.size()); - EXPECT_EQ(Name("example.org"), destination_client_.provided_updaters_[0]); + EXPECT_EQ(Name::ROOT_NAME(), destination_client_.provided_updaters_[0]); // Now load the whole zone loader.load(); EXPECT_TRUE(destination_client_.commit_called_); // We don't check the whole zone. We check the first and last and the // count, which should be enough. - EXPECT_EQ(7, destination_client_.rrsets_.size()); + + // The count is 34 because we expect the RRs to be separated. + EXPECT_EQ(34, destination_client_.rrsets_.size()); // Ensure known order. std::sort(destination_client_.rrsets_.begin(), destination_client_.rrsets_.end()); - EXPECT_EQ("TODO - check manually and copy-paste", + EXPECT_EQ(". 518400 IN NS a.root-servers.net.\n", destination_client_.rrsets_.front()); - EXPECT_EQ("TODO - check manually and copy-paste", + EXPECT_EQ("m.root-servers.net. 3600000 IN AAAA 2001:dc3::35\n", destination_client_.rrsets_.back()); } diff --git a/src/lib/datasrc/zone_loader.cc b/src/lib/datasrc/zone_loader.cc index 5b293d96ca..b050c086f8 100644 --- a/src/lib/datasrc/zone_loader.cc +++ b/src/lib/datasrc/zone_loader.cc @@ -13,3 +13,73 @@ // PERFORMANCE OF THIS SOFTWARE. #include + +#include +#include +#include +#include + +#include + +using isc::dns::Name; +using isc::dns::ConstRRsetPtr; + +namespace isc { +namespace datasrc { + +ZoneLoader::ZoneLoader(DataSourceClient& destination, const Name& zone_name, + DataSourceClient& source) : + // Separate the RRsets as that is possibly faster (the data source doesn't + // have to aggregate them) and also because our limit semantics. + iterator_(source.getIterator(zone_name, true)), + updater_(destination.getUpdater(zone_name, true, false)) +{ + // The getIterator should never return NULL. So we check it. + // Or should we throw instead? + assert(iterator_ != ZoneIteratorPtr()); + // In case the zone doesn't exist in the destination, throw + if (updater_ == ZoneUpdaterPtr()) { + isc_throw(DataSourceError, "Zone " << zone_name << " not found in " + "destination data source, can't fill it with data"); + } +} + +namespace { + +// Copy up to limit RRsets from source to destination +bool +copyRRsets(const ZoneUpdaterPtr& destination, const ZoneIteratorPtr& source, + size_t limit) +{ + size_t loaded = 0; + while (loaded < limit) { + const ConstRRsetPtr rrset(source->getNextRRset()); + if (rrset == ConstRRsetPtr()) { + // Done loading, no more RRsets in the input. + return (true); + } else { + destination->addRRset(*rrset); + } + ++loaded; + } + return (false); // Not yet, there may be more +} + +} + +bool +ZoneLoader::loadIncremental(size_t limit) { + if (iterator_ != ZoneIteratorPtr()) { + if (copyRRsets(updater_, iterator_, limit)) { + updater_->commit(); + return (true); + } else { + return (false); + } + } else { + isc_throw(isc::NotImplemented, "The master file way is not ready yet"); + } +} + +} +} diff --git a/src/lib/datasrc/zone_loader.h b/src/lib/datasrc/zone_loader.h index 54870e0a9d..4d22a7b89a 100644 --- a/src/lib/datasrc/zone_loader.h +++ b/src/lib/datasrc/zone_loader.h @@ -16,6 +16,7 @@ #define DATASRC_ZONE_LOADER_H #include // For size_t +#include namespace isc { namespace dns { @@ -24,8 +25,12 @@ class Name; } namespace datasrc { -// Forward declaration +// Forward declarations class DataSourceClient; +class ZoneIterator; +typedef boost::shared_ptr ZoneIteratorPtr; +class ZoneUpdater; +typedef boost::shared_ptr ZoneUpdaterPtr; /// \brief Class to load data into a data source client. /// @@ -85,7 +90,7 @@ public: /// before this call. /// \throw DataSourceError in case some error (possibly low-level) happens. void load() { - while (~loadIncremental(1000)) { // 1000 is arbitrary largish number + while (!loadIncremental(1000)) { // 1000 is arbitrary largish number // Body intentionally left blank. } } @@ -109,6 +114,11 @@ public: /// true). /// \throw DataSourceError in case some error (possibly low-level) happens. bool loadIncremental(size_t limit); +private: + /// \brief The iterator used as source of data in case of the copy mode. + const ZoneIteratorPtr iterator_; + /// \brief The destination zone updater + const ZoneUpdaterPtr updater_; }; }