Parcourir la source

small updates:
- improved log messages a bit
- supported the "remove" operation
- more documentation, some more tests


git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac446@3973 e5f2f494-b856-4b98-b285-d166d9295462

JINMEI Tatuya il y a 14 ans
Parent
commit
7ccec239ed

+ 12 - 3
src/bin/auth/auth_srv.cc

@@ -52,6 +52,7 @@
 #include <xfr/xfrout_client.h>
 
 #include <auth/common.h>
+#include <auth/config.h>
 #include <auth/auth_srv.h>
 
 using namespace std;
@@ -315,11 +316,16 @@ AuthSrv::setMemoryDataSrc(const isc::dns::RRClass& rrclass,
                   "Memory data source is not supported for RR class "
                   << rrclass);
     }
-    impl_->memory_datasrc_ = memory_datasrc;
     if (impl_->verbose_mode_) {
-        cerr << "[b10-auth] memory data source is configured for class "
-             << rrclass << endl;
+        if (!impl_->memory_datasrc_ && memory_datasrc) {
+            cerr << "[b10-auth] Memory data source is enabled for class "
+                 << rrclass << endl;
+        } else if (impl_->memory_datasrc_ && !memory_datasrc) {
+            cerr << "[b10-auth] Memory data source is disabled for class "
+                 << rrclass << endl;
+        }
     }
+    impl_->memory_datasrc_ = memory_datasrc;
 }
 
 void
@@ -641,6 +647,9 @@ AuthSrv::updateConfig(ConstElementPtr new_config) {
     try {
         // the ModuleCCSession has already checked if we have
         // the correct ElementPtr type as specified in our .spec file
+        if (new_config) {
+            configureAuthServer(*this, new_config);
+        }
         return (impl_->setDbFile(new_config));
     } catch (const isc::Exception& error) {
         if (impl_->verbose_mode_) {

+ 1 - 0
src/bin/auth/benchmarks/Makefile.am

@@ -9,6 +9,7 @@ CLEANFILES = *.gcno *.gcda
 noinst_PROGRAMS = query_bench
 query_bench_SOURCES = query_bench.cc
 query_bench_SOURCES += ../auth_srv.h ../auth_srv.cc
+query_bench_SOURCES += ../config.h ../config.cc
 
 query_bench_LDADD = $(top_builddir)/src/lib/dns/libdns++.la
 query_bench_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la

+ 13 - 7
src/bin/auth/config.cc

@@ -87,6 +87,15 @@ DatasourcesConfig::build(ConstElementPtr config_value) {
 
 void
 DatasourcesConfig::commit() {
+    // XXX a short term workaround: clear all data sources and then reset
+    // to new ones so that we can remove data sources that don't exist in
+    // the new configuration and have been used in the server.
+    // This could be inefficient and requires knowledge about
+    // server implementation details, and isn't scalable wrt the number of
+    // data source types, and should eventually be improved.
+    // Currently memory data source for class IN is the only possibility.
+    server_.setMemoryDataSrc(RRClass::IN(), AuthSrv::MemoryDataSrcPtr());
+
     BOOST_FOREACH(shared_ptr<AuthConfigParser> datasrc_config, datasources_) {
         datasrc_config->commit();
     }
@@ -102,7 +111,9 @@ public:
         rrclass_(0)              // XXX: dummy initial value
     {}
     virtual void build(ConstElementPtr config_value);
-    virtual void commit();
+    virtual void commit() {
+        server_.setMemoryDataSrc(rrclass_, memory_datasrc_);
+    }
 private:
     AuthSrv& server_;
     RRClass rrclass_;
@@ -152,11 +163,6 @@ MemoryDatasourceConfig::build(ConstElementPtr config_value) {
     }
 }
 
-void
-MemoryDatasourceConfig::commit() {
-    server_.setMemoryDataSrc(rrclass_, memory_datasrc_);
-}
-
 // This is a generalized version of create function that can create
 // a AuthConfigParser object for "internal" use.
 AuthConfigParser*
@@ -172,7 +178,7 @@ createAuthConfigParser(AuthSrv& server, const std::string& config_id,
     } else if (internal && config_id == "datasources/memory") {
         return (new MemoryDatasourceConfig(server));
     } else {
-        isc_throw(AuthConfigError, "Unknown configuration variable: " <<
+        isc_throw(AuthConfigError, "Unknown configuration identifier: " <<
                   config_id);
     }
 }

+ 6 - 2
src/bin/auth/config.h

@@ -109,6 +109,10 @@ public:
     /// allocation.  If it fails, it may throw a corresponding standard
     /// exception.
     ///
+    /// This method is not expected to be called more than once.  Although
+    /// multiple calls are not prohibited by the interface, the behavior
+    /// is undefined.
+    ///
     /// \param config_value The configuration value for the identifier
     /// corresponding to the derived class.
     virtual void build(isc::data::ConstElementPtr config_value) = 0;
@@ -120,8 +124,8 @@ public:
     /// Typically it would simply perform exception free assignment or swap
     /// operation on the value prepared in \c build().
     ///
-    /// This method is expected to be called after \c build().  The result
-    /// is undefined otherwise.
+    /// This method is expected to be called after \c build(), and only once.
+    /// The result is undefined otherwise.
     virtual void commit() = 0;
 };
 

+ 18 - 3
src/bin/auth/tests/auth_srv_unittest.cc

@@ -15,6 +15,7 @@
 // $Id$
 
 #include <config.h>
+#include <datasrc/memory_datasrc.h>
 #include <auth/auth_srv.h>
 #include <testutils/srv_unittest.h>
 
@@ -36,11 +37,12 @@ const char* const BADCONFIG_TESTDB =
 
 class AuthSrvTest : public SrvTestBase {
 protected:
-    AuthSrvTest() : server(true, xfrout) {
+    AuthSrvTest() : server(true, xfrout), rrclass(RRClass::IN()) {
         server.setXfrinSession(&notify_session);
     }
     MockXfroutClient xfrout;
     AuthSrv server;
+    const RRClass rrclass;
 };
 
 // Unsupported requests.  Should result in NOTIMP.
@@ -325,11 +327,11 @@ TEST_F(AuthSrvTest, notifyWithSessionMessageError) {
 }
 
 void
-updateConfig(AuthSrv* server, const char* const dbfile,
+updateConfig(AuthSrv* server, const char* const config_data,
              const bool expect_success)
 {
     ConstElementPtr config_answer =
-        server->updateConfig(Element::fromJSON(dbfile));
+        server->updateConfig(Element::fromJSON(config_data));
     EXPECT_EQ(Element::map, config_answer->getType());
     EXPECT_TRUE(config_answer->contains("result"));
 
@@ -381,6 +383,19 @@ TEST_F(AuthSrvTest, updateConfigFail) {
                 QR_FLAG | AA_FLAG, 1, 1, 1, 0);
 }
 
+TEST_F(AuthSrvTest, updateWithMemoryDataSrc) {
+    // Test configuring memory data source.  Detailed test cases are covered
+    // in the configuration tests.  We only check the AuthSrv interface here.
+
+    // By default memory data source isn't enabled
+    EXPECT_EQ(AuthSrv::MemoryDataSrcPtr(), server.getMemoryDataSrc(rrclass));
+    updateConfig(&server,
+                 "{\"datasources\": [{\"type\": \"memory\"}]}", true);
+    // after successful configuration, we should have one (with empty zoneset).
+    ASSERT_NE(AuthSrv::MemoryDataSrcPtr(), server.getMemoryDataSrc(rrclass));
+    EXPECT_EQ(0, server.getMemoryDataSrc(rrclass)->getZoneCount());
+}
+
 TEST_F(AuthSrvTest, cacheSlots) {
     // simple check for the get/set operations
     server.setCacheSlots(10);    // 10 = arbitrary choice

+ 45 - 2
src/bin/auth/tests/config_unittest.cc

@@ -37,7 +37,7 @@ namespace {
 class AuthConfigTest : public ::testing::Test {
 protected:
     AuthConfigTest() : rrclass(RRClass::IN()), server(true, xfrout) {}
-    RRClass rrclass;
+    const RRClass rrclass;
     MockXfroutClient xfrout;
     AuthSrv server;
 };
@@ -47,7 +47,7 @@ TEST_F(AuthConfigTest, datasourceConfig) {
     EXPECT_EQ(AuthSrv::MemoryDataSrcPtr(), server.getMemoryDataSrc(rrclass));
     configureAuthServer(server, Element::fromJSON(
                             "{\"datasources\": [{\"type\": \"memory\"}]}"));
-    // after successful configuration, we should have one (with empty zone).
+    // after successful configuration, we should have one (with empty zoneset).
     ASSERT_NE(AuthSrv::MemoryDataSrcPtr(), server.getMemoryDataSrc(rrclass));
     EXPECT_EQ(0, server.getMemoryDataSrc(rrclass)->getZoneCount());
 }
@@ -157,6 +157,49 @@ TEST_F(MemoryDatasrcConfigTest, addMultiZones) {
     EXPECT_EQ(3, server.getMemoryDataSrc(rrclass)->getZoneCount());
 }
 
+TEST_F(MemoryDatasrcConfigTest, replace) {
+    parser->build(Element::fromJSON(
+                      "[{\"type\": \"memory\","
+                      "  \"zones\": [{\"origin\": \"example.com\","
+                      "               \"file\": \"example.zone\"}]}]"));
+    parser->commit();
+    EXPECT_EQ(1, server.getMemoryDataSrc(rrclass)->getZoneCount());
+    EXPECT_EQ(isc::datasrc::result::SUCCESS,
+              server.getMemoryDataSrc(rrclass)->findZone(
+                  Name("example.com")).code);
+
+    // create a new parser, and install a new set of configuration.  It
+    // should replace the old one.
+    destroyAuthConfigParser(parser);
+    parser = createAuthConfigParser(server, "datasources"); 
+    parser->build(Element::fromJSON(
+                      "[{\"type\": \"memory\","
+                      "  \"zones\": [{\"origin\": \"example.org\","
+                      "               \"file\": \"example.org.zone\"},"
+                      "              {\"origin\": \"example.net\","
+                      "               \"file\": \"example.net.zone\"}]}]"));
+    parser->commit();
+    EXPECT_EQ(2, server.getMemoryDataSrc(rrclass)->getZoneCount());
+    EXPECT_EQ(isc::datasrc::result::NOTFOUND,
+              server.getMemoryDataSrc(rrclass)->findZone(
+                  Name("example.com")).code);
+}
+
+TEST_F(MemoryDatasrcConfigTest, remove) {
+    parser->build(Element::fromJSON(
+                      "[{\"type\": \"memory\","
+                      "  \"zones\": [{\"origin\": \"example.com\","
+                      "               \"file\": \"example.zone\"}]}]"));
+    parser->commit();
+    EXPECT_EQ(1, server.getMemoryDataSrc(rrclass)->getZoneCount());
+
+    destroyAuthConfigParser(parser);
+    parser = createAuthConfigParser(server, "datasources"); 
+    parser->build(Element::fromJSON("[]"));
+    parser->commit();
+    EXPECT_EQ(AuthSrv::MemoryDataSrcPtr(), server.getMemoryDataSrc(rrclass));
+}
+
 TEST_F(MemoryDatasrcConfigTest, adDuplicateZones) {
     EXPECT_THROW(parser->build(
                      Element::fromJSON(