Commit c2d2a53b authored by Michal 'vorner' Vaner's avatar Michal 'vorner' Vaner
Browse files

[2378] The copy mode of ZoneLoader

At least its basic version. Error handling must still be tested and done.
parent 3da9d619
......@@ -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());
}
......
......@@ -13,3 +13,73 @@
// PERFORMANCE OF THIS SOFTWARE.
#include <datasrc/zone_loader.h>
#include <datasrc/client.h>
#include <datasrc/data_source.h>
#include <datasrc/iterator.h>
#include <datasrc/zone.h>
#include <dns/rrset.h>
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");
}
}
}
}
......@@ -16,6 +16,7 @@
#define DATASRC_ZONE_LOADER_H
#include <cstdlib> // For size_t
#include <boost/shared_ptr.hpp>
namespace isc {
namespace dns {
......@@ -24,8 +25,12 @@ class Name;
}
namespace datasrc {
// Forward declaration
// Forward declarations
class DataSourceClient;
class ZoneIterator;
typedef boost::shared_ptr<ZoneIterator> ZoneIteratorPtr;
class ZoneUpdater;
typedef boost::shared_ptr<ZoneUpdater> 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_;
};
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment