BIND 10 trac1207, updated. f8848254849ec37587250cf9f6660aa20264495a [1207] improve load-from-sqlite3 unit test
BIND 10 source code commits
bind10-changes at lists.isc.org
Wed May 16 14:24:45 UTC 2012
The branch, trac1207 has been updated
via f8848254849ec37587250cf9f6660aa20264495a (commit)
via d19d162c3e89784b4e013e6892e7274c4bc0f861 (commit)
via abcaba769071a7e93cd40f55fc2b44e216991163 (commit)
via 393bf630eca3e1735e5d2c2dbf79bd79df6d9790 (commit)
via 1d668020a0e6e3f44a5037b55d8e2391ffd1b049 (commit)
via afcfd91930470d545841306b9d7dfb60863f6385 (commit)
via ba087ed8be288925fd4578efe89eefe1ea07ff31 (commit)
from 34561bdb8ee2ec934df4ff957839cd4e7d53e7be (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit f8848254849ec37587250cf9f6660aa20264495a
Author: Jelte Jansen <jelte at isc.org>
Date: Wed May 16 16:22:06 2012 +0200
[1207] improve load-from-sqlite3 unit test
instead of fighting the API to get empty zones in, actually change the zone in the database and reload
commit d19d162c3e89784b4e013e6892e7274c4bc0f861
Author: Jelte Jansen <jelte at isc.org>
Date: Wed May 16 15:40:00 2012 +0200
[1207] more review comments addressed
- RAII InMemoryClient's createInstance
- remove dead code
- added more comments
commit abcaba769071a7e93cd40f55fc2b44e216991163
Author: Jelte Jansen <jelte at isc.org>
Date: Wed May 16 13:49:32 2012 +0200
[1207] add comments
commit 393bf630eca3e1735e5d2c2dbf79bd79df6d9790
Author: Jelte Jansen <jelte at isc.org>
Date: Wed May 16 11:58:11 2012 +0200
[1207] initialize FakeClient in FakeContainer constructor
and store it as a scoped ptr
commit 1d668020a0e6e3f44a5037b55d8e2391ffd1b049
Author: Jelte Jansen <jelte at isc.org>
Date: Wed May 16 11:43:14 2012 +0200
[1207] minor cleanups after review
- fixed a few include statements
- amended a few comments
commit afcfd91930470d545841306b9d7dfb60863f6385
Author: Jelte Jansen <jelte at isc.org>
Date: Wed May 16 11:40:43 2012 +0200
[1207] FakeInMemoryClient -> FakeClient
it is no longer necessary to derive it from InMemoryClient, but it can be directly derived from DataSourceClient
commit ba087ed8be288925fd4578efe89eefe1ea07ff31
Author: Jelte Jansen <jelte at isc.org>
Date: Wed May 16 10:58:58 2012 +0200
[1207] Remove special MemoryDatasourceConfig
The special case is still there, but it's been moved into the general DataSourceConfig class; this makes later generalization easier.
It also allowed the removal of the specialized createAuthConfigParser (the overloaded version with the 'internal' argument), and the special case therein.
-----------------------------------------------------------------------
Summary of changes:
src/bin/auth/auth_config.cc | 113 ++++++++++++++-----------------
src/bin/auth/auth_srv.cc | 3 +-
src/bin/auth/auth_srv.h | 6 +-
src/bin/auth/command.cc | 3 +
src/bin/auth/tests/auth_srv_unittest.cc | 69 +++++++++++--------
src/bin/auth/tests/command_unittest.cc | 55 +++++++++------
src/lib/datasrc/client.h | 2 +
src/lib/datasrc/factory.cc | 1 -
src/lib/datasrc/factory.h | 8 ++-
src/lib/datasrc/memory_datasrc_link.cc | 31 ++++-----
10 files changed, 155 insertions(+), 136 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/bin/auth/auth_config.cc b/src/bin/auth/auth_config.cc
index f87fe65..7a80008 100644
--- a/src/bin/auth/auth_config.cc
+++ b/src/bin/auth/auth_config.cc
@@ -43,22 +43,26 @@ using namespace isc::datasrc;
using namespace isc::server_common::portconfig;
namespace {
-// Forward declaration
-AuthConfigParser*
-createAuthConfigParser(AuthSrv& server, const std::string& config_id,
- bool internal);
-
/// A derived \c AuthConfigParser class for the "datasources" configuration
/// identifier.
class DatasourcesConfig : public AuthConfigParser {
public:
- DatasourcesConfig(AuthSrv& server) : server_(server) {}
+ DatasourcesConfig(AuthSrv& server) : server_(server),
+ rrclass_(0) // dummy initial value
+ {}
virtual void build(ConstElementPtr config_value);
virtual void commit();
private:
AuthSrv& server_;
vector<boost::shared_ptr<AuthConfigParser> > datasources_;
set<string> configured_sources_;
+ // Workaround until we have complete datasource-agnostic
+ // setup; the in-memory datasource client must be specifically
+ // set, so we need to keep track of it, and set it specifically
+ // upon commit()
+ isc::datasrc::DataSourceClientContainerPtr memory_client_;
+ // Also need to keep track of its class for now
+ isc::dns::RRClass rrclass_;
};
/// A derived \c AuthConfigParser for the version value
@@ -86,15 +90,39 @@ DatasourcesConfig::build(ConstElementPtr config_value) {
isc_throw(AuthConfigError, "Data source type '" <<
datasrc_type->stringValue() << "' already configured");
}
-
- boost::shared_ptr<AuthConfigParser> datasrc_config =
- boost::shared_ptr<AuthConfigParser>(
- createAuthConfigParser(server_, string("datasources/") +
- datasrc_type->stringValue(),
- true));
- datasrc_config->build(datasrc_elem);
- datasources_.push_back(datasrc_config);
+ // Special handling of in-memory, pending datasource-agnostic config
+ // changes, see comment at memory_client_ member.
+ if (datasrc_type->stringValue() == std::string("memory")) {
+ // Apart from that it's not really easy to get at the default
+ // class value for the class here, it should probably really
+ // be a property of the instantiated data source. For now
+ // use hardcoded default IN.
+ ConstElementPtr rrclass_elem = datasrc_elem->get("class");
+ if (datasrc_elem->contains("class")) {
+ rrclass_ = RRClass(datasrc_elem->get("class")->stringValue());
+ } else{
+ rrclass_ = RRClass::IN();
+ }
+
+ // We'd eventually optimize building zones (in case of reloading) by
+ // selectively loading fresh zones. Right now we simply check the
+ // RR class is supported by the server implementation, by calling
+ // the get (it should throw on the wrong class).
+ (void)server_.getInMemoryClientContainer(rrclass_);
+
+ memory_client_ = isc::datasrc::DataSourceClientContainerPtr(
+ new isc::datasrc::DataSourceClientContainer("memory",
+ datasrc_elem));
+ } else {
+ boost::shared_ptr<AuthConfigParser> datasrc_config =
+ boost::shared_ptr<AuthConfigParser>(
+ createAuthConfigParser(server_, string("datasources/") +
+ datasrc_type->stringValue()));
+ datasrc_config->build(datasrc_elem);
+ datasources_.push_back(datasrc_config);
+
+ }
configured_sources_.insert(datasrc_type->stringValue());
}
}
@@ -108,48 +136,19 @@ DatasourcesConfig::commit() {
// 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_.setInMemoryClient(RRClass::IN(),
- isc::datasrc::DataSourceClientContainerPtr());
+ // Temporary workaround, see memory_client_ member description.
+ if (memory_client_) {
+ server_.setInMemoryClient(rrclass_, memory_client_);
+ } else {
+ server_.setInMemoryClient(RRClass::IN(),
+ isc::datasrc::DataSourceClientContainerPtr());
+ }
BOOST_FOREACH(boost::shared_ptr<AuthConfigParser> datasrc_config,
datasources_) {
datasrc_config->commit();
}
-}
-/// A derived \c AuthConfigParser class for the memory type datasource
-/// configuration. It does not correspond to the configuration syntax;
-/// it's instantiated for internal use.
-class MemoryDatasourceConfig : public AuthConfigParser {
-public:
- MemoryDatasourceConfig(AuthSrv& server) :
- server_(server),
- rrclass_(0) // XXX: dummy initial value
- {}
- virtual void build(ConstElementPtr config_value);
- virtual void commit() {
- server_.setInMemoryClient(rrclass_, memory_client_);
- }
-private:
- AuthSrv& server_;
- RRClass rrclass_;
- isc::datasrc::DataSourceClientContainerPtr memory_client_;
-};
-
-void
-MemoryDatasourceConfig::build(ConstElementPtr config_value) {
- // XXX: apparently we cannot retrieve the default RR class from the
- // module spec. As a temporary workaround we hardcode the default value.
- ConstElementPtr rrclass_elem = config_value->get("class");
- rrclass_ = RRClass(rrclass_elem ? rrclass_elem->stringValue() : "IN");
-
- // We'd eventually optimize building zones (in case of reloading) by
- // selectively loading fresh zones. Right now we simply check the
- // RR class is supported by the server implementation, by calling
- // the get (it should throw on the wrong class).
- (void)server_.getInMemoryClientContainer(rrclass_);
- memory_client_ = isc::datasrc::DataSourceClientContainerPtr(
- new isc::datasrc::DataSourceClientContainer("memory", config_value));
}
/// A derived \c AuthConfigParser class for the "statistics-internal"
@@ -246,12 +245,10 @@ private:
*/
AddrListPtr rollbackAddresses_;
};
+} // end of unnamed namespace
-// This is a generalized version of create function that can create
-// an AuthConfigParser object for "internal" use.
AuthConfigParser*
-createAuthConfigParser(AuthSrv& server, const std::string& config_id,
- bool internal)
+createAuthConfigParser(AuthSrv& server, const std::string& config_id)
{
// For the initial implementation we use a naive if-else blocks for
// simplicity. In future we'll probably generalize it using map-like
@@ -261,8 +258,6 @@ createAuthConfigParser(AuthSrv& server, const std::string& config_id,
return (new DatasourcesConfig(server));
} else if (config_id == "statistics-interval") {
return (new StatisticsIntervalConfig(server));
- } else if (internal && config_id == "datasources/memory") {
- return (new MemoryDatasourceConfig(server));
} else if (config_id == "listen_on") {
return (new ListenAddressConfig(server));
} else if (config_id == "_commit_throw") {
@@ -283,12 +278,6 @@ createAuthConfigParser(AuthSrv& server, const std::string& config_id,
config_id);
}
}
-} // end of unnamed namespace
-
-AuthConfigParser*
-createAuthConfigParser(AuthSrv& server, const std::string& config_id) {
- return (createAuthConfigParser(server, config_id, false));
-}
void
configureAuthServer(AuthSrv& server, ConstElementPtr config_set) {
diff --git a/src/bin/auth/auth_srv.cc b/src/bin/auth/auth_srv.cc
index b64e835..50eb931 100644
--- a/src/bin/auth/auth_srv.cc
+++ b/src/bin/auth/auth_srv.cc
@@ -410,8 +410,7 @@ AuthSrv::getInMemoryClient(const RRClass& rrclass) {
bool
AuthSrv::hasInMemoryClient() const {
- return (impl_->memory_client_container_ !=
- isc::datasrc::DataSourceClientContainerPtr());
+ return (impl_->memory_client_container_);
}
void
diff --git a/src/bin/auth/auth_srv.h b/src/bin/auth/auth_srv.h
index 0f01a10..6035a2e 100644
--- a/src/bin/auth/auth_srv.h
+++ b/src/bin/auth/auth_srv.h
@@ -257,9 +257,9 @@ public:
/// Returns the DataSourceClientContainer of the in-memory datasource
///
/// \exception InvalidParameter if the given class does not match
- /// the one in the memory data source
- /// \exception InvalidOperation if the memory datasource has not been set
- /// (callers can check with \c hasMemoryDataSource())
+ /// the one in the memory data source, or if the memory
+ /// datasource has not been set (callers can check with
+ /// \c hasMemoryDataSource())
///
/// \param rrclass The RR class of the requested in-memory data source.
/// \return A shared pointer to the in-memory data source, if configured;
diff --git a/src/bin/auth/command.cc b/src/bin/auth/command.cc
index 12f0b2b..750ea28 100644
--- a/src/bin/auth/command.cc
+++ b/src/bin/auth/command.cc
@@ -229,6 +229,9 @@ private:
" is not found in data source");
}
+ // It would appear that dynamic_cast does not work on all systems;
+ // it seems to confuse the RTTI system, resulting in NULL return
+ // values. So we use the more dangerous static_pointer_cast here.
old_zone_finder_ = boost::static_pointer_cast<InMemoryZoneFinder>(
result.zone_finder);
diff --git a/src/bin/auth/tests/auth_srv_unittest.cc b/src/bin/auth/tests/auth_srv_unittest.cc
index f731dd1..2f1f404 100644
--- a/src/bin/auth/tests/auth_srv_unittest.cc
+++ b/src/bin/auth/tests/auth_srv_unittest.cc
@@ -17,6 +17,7 @@
#include <vector>
#include <boost/shared_ptr.hpp>
+#include <boost/scoped_ptr.hpp>
#include <gtest/gtest.h>
@@ -90,6 +91,9 @@ protected:
}
~AuthSrvTest() {
+ // Clear the message now; depending on the RTTI implementation,
+ // type information may be lost if the message is cleared
+ // automatically later, so as a precaution we do it now.
parse_message->clear(Message::PARSE);
}
@@ -1112,7 +1116,7 @@ TEST_F(AuthSrvTest, processNormalQuery_reuseRenderer2) {
//
namespace {
-/// A the possible methods to throw in, either in FakeInMemoryClient or
+/// A the possible methods to throw in, either in FakeClient or
/// FakeZoneFinder
enum ThrowWhen {
THROW_NEVER,
@@ -1136,10 +1140,10 @@ checkThrow(ThrowWhen method, ThrowWhen throw_at, bool isc_exception) {
}
}
-/// \brief proxy class for the ZoneFinder returned by the InMemoryClient
-/// proxied by FakeInMemoryClient
+/// \brief proxy class for the ZoneFinder returned by the Client
+/// proxied by FakeClient
///
-/// See the documentation for FakeInMemoryClient for more information,
+/// See the documentation for FakeClient for more information,
/// all methods simply check whether they should throw, and if not, call
/// their proxied equivalent.
class FakeZoneFinder : public isc::datasrc::ZoneFinder {
@@ -1212,11 +1216,11 @@ private:
ConstRRsetPtr fake_rrset_;
};
-/// \brief Proxy InMemoryClient that can throw exceptions at specified times
+/// \brief Proxy FakeClient that can throw exceptions at specified times
///
-/// It is based on the memory client since that one is easy to override
-/// (with setInMemoryClient) with the current design of AuthSrv.
-class FakeInMemoryClient : public isc::datasrc::InMemoryClient {
+/// Currently it is used as an 'InMemoryClient' using setInMemoryClient,
+/// but it is in effect a general datasource client.
+class FakeClient : public isc::datasrc::DataSourceClient {
public:
/// \brief Create a proxy memory client
///
@@ -1228,9 +1232,9 @@ public:
/// throw std::exception
/// \param fake_rrset If non NULL, it will be used as an answer to
/// find() for that name and type.
- FakeInMemoryClient(isc::datasrc::DataSourceClientContainerPtr real_client,
- ThrowWhen throw_when, bool isc_exception,
- ConstRRsetPtr fake_rrset = ConstRRsetPtr()) :
+ FakeClient(isc::datasrc::DataSourceClientContainerPtr real_client,
+ ThrowWhen throw_when, bool isc_exception,
+ ConstRRsetPtr fake_rrset = ConstRRsetPtr()) :
real_client_ptr_(real_client),
throw_when_(throw_when),
isc_exception_(isc_exception),
@@ -1255,6 +1259,18 @@ public:
fake_rrset_))));
}
+ isc::datasrc::ZoneUpdaterPtr
+ getUpdater(const isc::dns::Name&, bool, bool) const {
+ isc_throw(isc::NotImplemented, "Update attempt on in fake data source");
+ }
+ std::pair<isc::datasrc::ZoneJournalReader::Result,
+ isc::datasrc::ZoneJournalReaderPtr>
+ getJournalReader(const isc::dns::Name&, uint32_t,
+ uint32_t) const
+ {
+ isc_throw(isc::NotImplemented, "Journaling isn't supported for "
+ "in memory data source");
+ }
private:
const isc::datasrc::DataSourceClientContainerPtr real_client_ptr_;
ThrowWhen throw_when_;
@@ -1268,25 +1284,25 @@ public:
///
/// The initializer creates a fresh instance of a memory datasource,
/// which is ignored for the rest (but we do not allow 'null' containers
- /// atm, and this is only needed in these tests)
+ /// atm, and this is only needed in these tests, this may be changed
+ /// if we generalize the container class a bit more)
///
- /// The client given will be deleted upon destruction of this container
- FakeContainer(isc::datasrc::DataSourceClient* client) :
+ /// It will also create a FakeClient, with the given arguments, which
+ /// is actually used when the instance is requested.
+ FakeContainer(isc::datasrc::DataSourceClientContainerPtr real_client,
+ ThrowWhen throw_when, bool isc_exception,
+ ConstRRsetPtr fake_rrset = ConstRRsetPtr()) :
DataSourceClientContainer("memory",
Element::fromJSON("{\"type\": \"memory\"}")),
- client_(client)
+ client_(new FakeClient(real_client, throw_when, isc_exception, fake_rrset))
{}
- ~FakeContainer() {
- delete client_;
- }
-
isc::datasrc::DataSourceClient& getInstance() {
return (*client_);
}
private:
- isc::datasrc::DataSourceClient* const client_;
+ const boost::scoped_ptr<isc::datasrc::DataSourceClient> client_;
};
} // end anonymous namespace for throwing proxy classes
@@ -1298,14 +1314,11 @@ private:
TEST_F(AuthSrvTest, queryWithInMemoryClientProxy) {
// Set real inmem client to proxy
updateConfig(&server, CONFIG_INMEMORY_EXAMPLE, true);
-
- isc::datasrc::InMemoryClient* fake_client(
- new FakeInMemoryClient(server.getInMemoryClientContainer(rrclass),
- THROW_NEVER, false));
EXPECT_TRUE(server.hasInMemoryClient());
isc::datasrc::DataSourceClientContainerPtr fake_client_container(
- new FakeContainer(fake_client));
+ new FakeContainer(server.getInMemoryClientContainer(rrclass),
+ THROW_NEVER, false));
server.setInMemoryClient(rrclass, fake_client_container);
createDataFromFile("nsec3query_nodnssec_fromWire.wire");
@@ -1332,12 +1345,10 @@ setupThrow(AuthSrv* server, const char *config, ThrowWhen throw_when,
// Set it to throw on findZone(), this should result in
// SERVFAIL on any exception
- isc::datasrc::InMemoryClient* fake_client(
- new FakeInMemoryClient(
+ isc::datasrc::DataSourceClientContainerPtr fake_client_container(
+ new FakeContainer(
server->getInMemoryClientContainer(isc::dns::RRClass::IN()),
throw_when, isc_exception, rrset));
- isc::datasrc::DataSourceClientContainerPtr fake_client_container(
- new FakeContainer(fake_client));
ASSERT_TRUE(server->hasInMemoryClient());
server->setInMemoryClient(isc::dns::RRClass::IN(), fake_client_container);
diff --git a/src/bin/auth/tests/command_unittest.cc b/src/bin/auth/tests/command_unittest.cc
index 24c7dc3..7dd91bf 100644
--- a/src/bin/auth/tests/command_unittest.cc
+++ b/src/bin/auth/tests/command_unittest.cc
@@ -23,6 +23,7 @@
#include <dns/name.h>
#include <dns/rrclass.h>
#include <dns/rrtype.h>
+#include <dns/rrttl.h>
#include <cc/data.h>
@@ -293,40 +294,50 @@ TEST_F(AuthCommandTest,
module_session.setLocalConfig(map);
server_.setConfigSession(&module_session);
- // The loadzone command needs the zone to be already loaded, because
- // it is used for reloading only
- isc::datasrc::DataSourceClientContainerPtr dsrc(
- new isc::datasrc::DataSourceClientContainer("memory",
- Element::fromJSON("{\"type\": \"memory\"}")));
- // The 'public' factory API does not allow for direct internal calls such
- // as addZone, so purely for this test we do a quick cast
- static_cast<InMemoryClient*>(&dsrc->getInstance())->addZone(
- ZoneFinderPtr(new InMemoryZoneFinder(RRClass::IN(),
- Name("example.org"))));
- server_.setInMemoryClient(RRClass::IN(), dsrc);
+ server_.updateConfig(map);
+
+ // Check that the A record at www.example.org does not exist
+ ASSERT_TRUE(server_.hasInMemoryClient());
+ EXPECT_EQ(ZoneFinder::NXDOMAIN, server_.getInMemoryClient(RRClass::IN())->
+ findZone(Name("example.org")).zone_finder->
+ find(Name("www.example.org"), RRType::A())->code);
+
+ // Add the record to the underlying sqlite database, by loading
+ // it as a separate datasource, and updating it
+ ConstElementPtr sql_cfg = Element::fromJSON("{ \"type\": \"sqlite3\","
+ "\"database_file\": \""
+ + test_db + "\"}");
+ DataSourceClientContainer sql_ds("sqlite3", sql_cfg);
+ ZoneUpdaterPtr sql_updater =
+ sql_ds.getInstance().getUpdater(Name("example.org"), false);
+ RRsetPtr rrset(new RRset(Name("www.example.org."), RRClass::IN(),
+ RRType::A(), RRTTL(60)));
+ rrset->addRdata(rdata::createRdata(rrset->getType(),
+ rrset->getClass(),
+ "192.0.2.1"));
+ sql_updater->addRRset(*rrset);
+ sql_updater->commit();
+
+ // This new record is in the database now, but should not be in the
+ // memory-datasource yet, so check again
+ EXPECT_EQ(ZoneFinder::NXDOMAIN, server_.getInMemoryClient(RRClass::IN())->
+ findZone(Name("example.org")).zone_finder->
+ find(Name("www.example.org"), RRType::A())->code);
// Now send the command to reload it
result_ = execAuthServerCommand(server_, "loadzone",
Element::fromJSON("{\"origin\": \"example.org\"}"));
checkAnswer(0);
- // Get the zone and look if there are data in it (the original one was
- // empty)
- ASSERT_TRUE(server_.hasInMemoryClient());
+ // And now it should be present too.
EXPECT_EQ(ZoneFinder::SUCCESS, server_.getInMemoryClient(RRClass::IN())->
findZone(Name("example.org")).zone_finder->
- find(Name("example.org"), RRType::SOA())->code);
+ find(Name("www.example.org"), RRType::A())->code);
- // Some error cases. First, the zone has no configuration.
- // The 'public' factory API does not allow for direct internal calls such
- // as addZone, so purely for this test we do a quick cast
- static_cast<InMemoryClient*>(&dsrc->getInstance())->addZone(
- ZoneFinderPtr(new InMemoryZoneFinder(RRClass::IN(),
- Name("example.com"))));
+ // Some error cases. First, the zone has no configuration. (note .com here)
result_ = execAuthServerCommand(server_, "loadzone",
Element::fromJSON("{\"origin\": \"example.com\"}"));
checkAnswer(1);
-
// The previous zone is not hurt in any way
EXPECT_EQ(ZoneFinder::SUCCESS, server_.getInMemoryClient(RRClass::IN())->
findZone(Name("example.org")).zone_finder->
diff --git a/src/lib/datasrc/client.h b/src/lib/datasrc/client.h
index d70c7c6..dab081f 100644
--- a/src/lib/datasrc/client.h
+++ b/src/lib/datasrc/client.h
@@ -371,6 +371,8 @@ public:
/// \exception NotImplemented Thrown if this method is not supported
/// by the datasource
///
+ /// \note This is a tentative API, and this method may likely to be
+ /// removed in the near future.
/// \return The number of zones known to this datasource
virtual unsigned int getZoneCount() const {
isc_throw(isc::NotImplemented,
diff --git a/src/lib/datasrc/factory.cc b/src/lib/datasrc/factory.cc
index da7270b..82b4df9 100644
--- a/src/lib/datasrc/factory.cc
+++ b/src/lib/datasrc/factory.cc
@@ -24,7 +24,6 @@
#include <datasrc/logger.h>
#include <exceptions/exceptions.h>
-#include <dns/masterload.h>
#include <dlfcn.h>
#include <cstdlib>
diff --git a/src/lib/datasrc/factory.h b/src/lib/datasrc/factory.h
index efa271a..2731f58 100644
--- a/src/lib/datasrc/factory.h
+++ b/src/lib/datasrc/factory.h
@@ -17,7 +17,6 @@
#include <datasrc/data_source.h>
#include <datasrc/client.h>
-#include <exceptions/exceptions.h>
#include <cc/data.h>
@@ -135,6 +134,13 @@ private:
///
/// extern "C" void destroyInstance(isc::data::DataSourceClient* instance);
/// \endcode
+///
+/// \note This class is relatively recent, and its design is not yet fully
+/// formed. We may want to split this into an abstract base container
+/// class, and a derived 'dyload' class, and perhaps then add non-dynamic
+/// derived classes as well. Currently, the class is actually derived in some
+/// of the tests, which is rather unclean (as this class as written is really
+/// intended to be used directly).
class DataSourceClientContainer : boost::noncopyable {
public:
/// \brief Constructor
diff --git a/src/lib/datasrc/memory_datasrc_link.cc b/src/lib/datasrc/memory_datasrc_link.cc
index d5a3f85..92b3cb1 100644
--- a/src/lib/datasrc/memory_datasrc_link.cc
+++ b/src/lib/datasrc/memory_datasrc_link.cc
@@ -33,6 +33,8 @@ using namespace isc::data;
namespace isc {
namespace datasrc {
+/// This exception is raised if there is an error in the configuration
+/// that has been passed; missing information, duplicate values, etc.
class InMemoryConfigError : public isc::Exception {
public:
InMemoryConfigError(const char* file, size_t line, const char* what) :
@@ -138,11 +140,10 @@ checkConfig(ConstElementPtr config, ElementPtr errors) {
}
if (!config->contains("zones")) {
// Assume empty list of zones
- //addError(errors, "No 'zones' element in memory backend config");
- //result = false;
} else if (!config->get("zones") ||
config->get("zones")->getType() != Element::list) {
- addError(errors, "'zones' element in memory backend config is not a list");
+ addError(errors,
+ "'zones' element in memory backend config is not a list");
result = false;
} else {
BOOST_FOREACH(ConstElementPtr zone_config,
@@ -161,9 +162,15 @@ checkConfig(ConstElementPtr config, ElementPtr errors) {
// client must be freshly allocated, and config_value should have been
// checked by the caller
void
-applyConfig(isc::datasrc::InMemoryClient* client,
+applyConfig(isc::datasrc::InMemoryClient& client,
isc::data::ConstElementPtr config_value)
{
+ // XXX: We have lost the context to get to the default values here,
+ // as a temporary workaround we hardcode the IN class here.
+ isc::dns::RRClass rrclass = RRClass::IN();
+ if (config_value->contains("class")) {
+ rrclass = RRClass(config_value->get("class")->stringValue());
+ }
ConstElementPtr zones_config = config_value->get("zones");
if (!zones_config) {
// XXX: Like the RR class, we cannot retrieve the default value here,
@@ -171,10 +178,6 @@ applyConfig(isc::datasrc::InMemoryClient* client,
return;
}
- isc::dns::RRClass rrclass = RRClass::IN();
- if (config_value->contains("class")) {
- rrclass = RRClass(config_value->get("class")->stringValue());
- }
BOOST_FOREACH(ConstElementPtr zone_config, zones_config->listValue()) {
ConstElementPtr origin = zone_config->get("origin");
@@ -220,7 +223,7 @@ applyConfig(isc::datasrc::InMemoryClient* client,
}
boost::shared_ptr<InMemoryZoneFinder> zone_finder(imzf);
- const result::Result result = client->addZone(zone_finder);
+ const result::Result result = client.addZone(zone_finder);
if (result == result::EXIST) {
isc_throw(InMemoryConfigError, "zone "<< origin->str()
<< " already exists");
@@ -250,21 +253,17 @@ createInstance(isc::data::ConstElementPtr config, std::string& error) {
error = "Configuration error: " + errors->str();
return (NULL);
}
- isc::datasrc::InMemoryClient* client = NULL;
try {
- client = new isc::datasrc::InMemoryClient();
- applyConfig(client, config);
- return (client);
+ std::auto_ptr<InMemoryClient> client(new isc::datasrc::InMemoryClient());
+ applyConfig(*client, config);
+ return (client.release());
} catch (const isc::Exception& isce) {
- delete client;
error = isce.what();
return (NULL);
} catch (const std::exception& exc) {
- delete client;
error = std::string("Error creating memory datasource: ") + exc.what();
return (NULL);
} catch (...) {
- delete client;
error = std::string("Error creating memory datasource, "
"unknown exception");
return (NULL);
More information about the bind10-changes
mailing list