Browse Source

[2499] Add an RRsetCollection around ZoneData

Mukund Sivaraman 12 years ago
parent
commit
45466d27ef

+ 1 - 0
src/lib/datasrc/memory/Makefile.am

@@ -15,6 +15,7 @@ libdatasrc_memory_la_SOURCES += rdataset.h rdataset.cc
 libdatasrc_memory_la_SOURCES += treenode_rrset.h treenode_rrset.cc
 libdatasrc_memory_la_SOURCES += rdata_serialization.h rdata_serialization.cc
 libdatasrc_memory_la_SOURCES += zone_data.h zone_data.cc
+libdatasrc_memory_la_SOURCES += rrset_collection.h rrset_collection.cc
 libdatasrc_memory_la_SOURCES += segment_object_holder.h
 libdatasrc_memory_la_SOURCES += logger.h logger.cc
 libdatasrc_memory_la_SOURCES += zone_table.h zone_table.cc

+ 57 - 0
src/lib/datasrc/memory/rrset_collection.cc

@@ -0,0 +1,57 @@
+// Copyright (C) 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
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <datasrc/memory/rrset_collection.h>
+#include <datasrc/memory/treenode_rrset.h>
+
+#include <exceptions/exceptions.h>
+
+using namespace isc;
+using namespace isc::dns;
+
+namespace isc {
+namespace datasrc {
+namespace memory {
+
+ConstRRsetPtr
+RRsetCollection::find(const isc::dns::Name& name,
+                      const isc::dns::RRClass& rrclass,
+                      const isc::dns::RRType& rrtype) const
+{
+    if (rrclass != rrclass_) {
+        // We could throw an exception here, but RRsetCollection is
+        // expected to support an arbitrary collection of RRsets, and it
+        // can be queried just as arbitrarily. So we just return nothing
+        // here.
+        return (ConstRRsetPtr());
+    }
+
+    const ZoneTree& tree = zone_data_.getZoneTree();
+    const ZoneNode *node = NULL;
+    ZoneTree::Result result = tree.find(name, &node);
+    if (result != ZoneTree::EXACTMATCH) {
+        return (ConstRRsetPtr());
+    }
+
+    const RdataSet* rdataset = RdataSet::find(node->getData(), rrtype);
+    if (rdataset == NULL) {
+        return (ConstRRsetPtr());
+    }
+
+    return (ConstRRsetPtr(new TreeNodeRRset(rrclass_, node, rdataset, true)));
+}
+
+} // end of namespace memory
+} // end of namespace datasrc
+} // end of namespace isc

+ 85 - 0
src/lib/datasrc/memory/rrset_collection.h

@@ -0,0 +1,85 @@
+// Copyright (C) 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
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef RRSET_COLLECTION_DATASRC_MEMORY_H
+#define RRSET_COLLECTION_DATASRC_MEMORY_H 1
+
+#include <dns/rrset_collection_base.h>
+#include <dns/rrclass.h>
+
+#include <datasrc/memory/zone_data.h>
+
+namespace isc {
+namespace datasrc {
+namespace memory {
+
+/// \brief In-memory derivation of \c isc::dns::RRsetCollectionBase.
+class RRsetCollection : public isc::dns::RRsetCollectionBase {
+public:
+    /// \brief Constructor.
+    ///
+    /// No reference (count via \c shared_ptr) to the \c ZoneData is
+    /// acquired. The RRsetCollection must not be used after its
+    /// \c ZoneData has been destroyed.
+    ///
+    /// \param zone_data The ZoneData to wrap around.
+    /// \param rrclass The RRClass of the records in the zone.
+    RRsetCollection(ZoneData& zone_data, const isc::dns::RRClass& rrclass) :
+        zone_data_(zone_data),
+        rrclass_(rrclass)
+    {}
+
+    /// \brief Destructor
+    virtual ~RRsetCollection() {}
+
+    /// \brief Find a matching RRset in the collection.
+    ///
+    /// Returns the RRset in the collection that exactly matches the
+    /// given \c name, \c rrclass and \c rrtype.  If no matching RRset
+    /// is found, \c NULL is returned.
+    ///
+    /// \throw isc::dns::RRsetCollectionError if \c find() results in
+    /// some underlying error.
+    ///
+    /// \param name The name of the RRset to search for.
+    /// \param rrclass The class of the RRset to search for.
+    /// \param rrtype The type of the RRset to search for.
+    /// \returns The RRset if found, \c NULL otherwise.
+    virtual isc::dns::ConstRRsetPtr find(const isc::dns::Name& name,
+                                         const isc::dns::RRClass& rrclass,
+                                         const isc::dns::RRType& rrtype) const;
+
+protected:
+    virtual RRsetCollectionBase::IterPtr getBeginning() {
+        isc_throw(NotImplemented, "This method is not implemented.");
+    }
+
+    virtual RRsetCollectionBase::IterPtr getEnd() {
+        isc_throw(NotImplemented, "This method is not implemented.");
+    }
+
+private:
+    ZoneData& zone_data_;
+    isc::dns::RRClass rrclass_;
+};
+
+} // end of namespace memory
+} // end of namespace datasrc
+} // end of namespace isc
+
+#endif  // RRSET_COLLECTION_DATASRC_MEMORY_H
+
+// Local Variables:
+// mode: c++
+// End:

+ 1 - 0
src/lib/datasrc/tests/memory/Makefile.am

@@ -32,6 +32,7 @@ run_unittests_SOURCES += ../../tests/faked_nsec3.h ../../tests/faked_nsec3.cc
 run_unittests_SOURCES += memory_segment_test.h
 run_unittests_SOURCES += segment_object_holder_unittest.cc
 run_unittests_SOURCES += memory_client_unittest.cc
+run_unittests_SOURCES += rrset_collection_unittest.cc
 run_unittests_SOURCES += zone_data_loader_unittest.cc
 run_unittests_SOURCES += zone_data_updater_unittest.cc
 run_unittests_SOURCES += zone_table_segment_test.h

+ 88 - 0
src/lib/datasrc/tests/memory/rrset_collection_unittest.cc

@@ -0,0 +1,88 @@
+// Copyright (C) 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
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+
+#include <datasrc/memory/rrset_collection.h>
+
+#include "memory_segment_test.h"
+
+#include <datasrc/memory/zone_data_loader.h>
+#include <datasrc/memory/segment_object_holder.h>
+#include <dns/rrttl.h>
+#include <dns/rdataclass.h>
+
+#include <gtest/gtest.h>
+
+using namespace isc::dns;
+using namespace isc::dns::rdata;
+using namespace std;
+using namespace isc::datasrc;
+using namespace isc::datasrc::memory;
+using namespace isc::datasrc::memory::detail;
+
+namespace {
+
+// Note: This class uses loadZoneData() to construct a ZoneData object,
+// which internally uses an RRsetCollection for validation. We assume
+// that loadZoneData() works at this point and test the RRsetCollection
+// around the ZoneData returned.
+class RRsetCollectionTest : public ::testing::Test {
+public:
+    RRsetCollectionTest() :
+        rrclass("IN"),
+        origin("example.org"),
+        zone_file(TEST_DATA_DIR "/rrset-collection.zone"),
+        zone_data_holder(mem_sgmt,
+                         loadZoneData(mem_sgmt, rrclass, origin, zone_file),
+                         rrclass),
+        collection(*zone_data_holder.get(), rrclass)
+    {}
+
+    const RRClass rrclass;
+    const Name origin;
+    std::string zone_file;
+    test::MemorySegmentTest mem_sgmt;
+    SegmentObjectHolder<ZoneData, RRClass> zone_data_holder;
+    RRsetCollection collection;
+};
+
+TEST_F(RRsetCollectionTest, find) {
+    const RRsetCollection& ccln = collection;
+    ConstRRsetPtr rrset = ccln.find(Name("www.example.org"), rrclass,
+                                    RRType::A());
+    EXPECT_TRUE(rrset);
+    EXPECT_EQ(RRType::A(), rrset->getType());
+    EXPECT_EQ(RRTTL(3600), rrset->getTTL());
+    EXPECT_EQ(RRClass("IN"), rrset->getClass());
+    EXPECT_EQ(Name("www.example.org"), rrset->getName());
+
+    // foo.example.org doesn't exist
+    rrset = ccln.find(Name("foo.example.org"), rrclass, RRType::A());
+    EXPECT_FALSE(rrset);
+
+    // www.example.org exists, but not with MX
+    rrset = ccln.find(Name("www.example.org"), rrclass, RRType::MX());
+    EXPECT_FALSE(rrset);
+
+    // www.example.org exists, with AAAA
+    rrset = ccln.find(Name("www.example.org"), rrclass, RRType::AAAA());
+    EXPECT_TRUE(rrset);
+
+    // www.example.org with AAAA does not exist in RRClass::CH()
+    rrset = ccln.find(Name("www.example.org"), RRClass::CH(),
+                            RRType::AAAA());
+    EXPECT_FALSE(rrset);
+}
+
+} // namespace

+ 1 - 0
src/lib/datasrc/tests/memory/testdata/Makefile.am

@@ -29,6 +29,7 @@ EXTRA_DIST += example.org-rrsigs.zone
 EXTRA_DIST += example.org-wildcard-dname.zone
 EXTRA_DIST += example.org-wildcard-ns.zone
 EXTRA_DIST += example.org-wildcard-nsec3.zone
+EXTRA_DIST += rrset-collection.zone
 
 EXTRA_DIST += 2503-test.zone
 EXTRA_DIST += 2504-test.zone

+ 17 - 0
src/lib/datasrc/tests/memory/testdata/rrset-collection.zone

@@ -0,0 +1,17 @@
+example.org.        3600    IN  SOA ( ; The SOA, split across lines for testing
+    ns1.example.org.
+    admin.example.org.
+    1234
+    3600
+    1800
+    2419200
+    7200
+    )
+; Check it accepts quoted name too
+"\101xample.org."        3600    IN  NS ns1.example.org.
+
+
+; Some empty lines here. They are to make sure the loader can skip them.
+www                 3600    IN  A 192.0.2.1 ; Test a relative name as well.
+                    3600    IN  AAAA    2001:db8::1 ; And initial whitespace hanling
+         ; Here be just some space, no RRs