From 1abb94ac5184d59a4a720678c3a56fc94bb59a6f Mon Sep 17 00:00:00 2001 From: Thomas Markwalder Date: Fri, 20 Jan 2017 08:57:41 -0500 Subject: [PATCH] [5110] Added support for setting configuration defaults to DCfgMgrBase src/lib/process/d_cfg_mgr.h src/lib/process/d_cfg_mgr.cc DCfgMgrBase::setCfgDefaults() - new virtual method so derivations can insert default values prior into a configuration DCfgMgrBase::parseConfig() - added call to setCfgDefaults() prior to calling parseConfig(). --- src/lib/process/d_cfg_mgr.cc | 9 ++++-- src/lib/process/d_cfg_mgr.h | 8 ++++++ src/lib/process/tests/d_cfg_mgr_unittests.cc | 30 ++++++++++++++++---- 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/src/lib/process/d_cfg_mgr.cc b/src/lib/process/d_cfg_mgr.cc index babf27b369..befadcf005 100644 --- a/src/lib/process/d_cfg_mgr.cc +++ b/src/lib/process/d_cfg_mgr.cc @@ -147,6 +147,11 @@ DCfgMgrBase::parseConfig(isc::data::ConstElementPtr config_set) { std::string element_id; try { + + // Make the configuration mutable so we can then insert default values. + ElementPtr mutable_cfg = boost::const_pointer_cast(config_set); + setCfgDefaults(mutable_cfg); + // Split the configuration into two maps. The first containing only // top-level scalar parameters (i.e. globals), the second containing // non-scalar or object elements (maps, lists, etc...). This allows @@ -156,7 +161,7 @@ DCfgMgrBase::parseConfig(isc::data::ConstElementPtr config_set) { ElementMap objects_map; isc::dhcp::ConfigPair config_pair; - BOOST_FOREACH(config_pair, config_set->mapValue()) { + BOOST_FOREACH(config_pair, mutable_cfg->mapValue()) { std::string element_id = config_pair.first; isc::data::ConstElementPtr element = config_pair.second; switch (element->getType()) { @@ -203,7 +208,7 @@ DCfgMgrBase::parseConfig(isc::data::ConstElementPtr config_set) { isc_throw(DCfgMgrBaseError, "Element required by parsing order is missing: " << element_id << " (" - << config_set->getPosition() << ")"); + << mutable_cfg->getPosition() << ")"); } } diff --git a/src/lib/process/d_cfg_mgr.h b/src/lib/process/d_cfg_mgr.h index 47f56f7a50..3c0b088b94 100644 --- a/src/lib/process/d_cfg_mgr.h +++ b/src/lib/process/d_cfg_mgr.h @@ -320,6 +320,14 @@ public: virtual std::string getConfigSummary(const uint32_t selection) = 0; protected: + /// @brief Adds default values to the given config + /// + /// Provides derviations a means to add defaults to a configuration + /// Element map prior to parsing it. + /// + /// @param mutable_config - configuration to which defaults should be added + virtual void setCfgDefaults(isc::data::ElementPtr mutable_config) { + } /// @brief Parses the an element using an alternate parsing mechanism /// diff --git a/src/lib/process/tests/d_cfg_mgr_unittests.cc b/src/lib/process/tests/d_cfg_mgr_unittests.cc index d2644e1180..f5407de91a 100644 --- a/src/lib/process/tests/d_cfg_mgr_unittests.cc +++ b/src/lib/process/tests/d_cfg_mgr_unittests.cc @@ -125,6 +125,20 @@ public: return (false); } + /// @brief Adds default elements to the given config + /// + /// Overrides the DCfgMgrBase implementation. + /// Adds the string parameter, "defaulted_parm" with a + /// value of "default value" to mutable_cfg if isn't + /// already there. + /// + /// @param mutable_cfg config to modify + virtual void setCfgDefaults(isc::data::ElementPtr mutable_cfg) { + if (!mutable_cfg->contains("defaulted_parm")) { + ConstElementPtr def(new StringElement("default value")); + mutable_cfg->set("defaulted_parm", def); + } + } /// @brief List of element ids which should be parsed by parseElement ElementIdList parsable_elements_; @@ -556,8 +570,12 @@ TEST_F(DStubCfgMgrTest, paramPosition) { EXPECT_EQ(pos.file_, isc::data::Element::ZERO_POSITION().file_); } -// Tests that elements not handled by the parseElement() method are +// Tests that: +// +// 1. Elements not handled by the parseElement() method are // handled by the old parsing mechanisms +// 2. Default values are supplied for elements not supplied in +// the configuration TEST_F(ParseElementMgrTest, basic) { // Create the test config string config = "{ \"bool_test\": true , \n" @@ -570,7 +588,7 @@ TEST_F(ParseElementMgrTest, basic) { // Add two elements to the list of elements handled by parseElement addToParsableElements("parse_one"); - addToParsableElements("parse_three"); + addToParsableElements("defaulted_parm"); // Verify that the configuration parses without error. answer_ = cfg_mgr_->parseConfig(config_set_); @@ -579,7 +597,7 @@ TEST_F(ParseElementMgrTest, basic) { ASSERT_TRUE(context); // Verify that the list of parsed elements is as expected - // It should have two entries: "parse_one" and "parse_three" + // It should have two entries: "parse_one" and "defaulted_parm" ASSERT_EQ(cfg_mgr_->parsed_elements_.size(), 2); EXPECT_TRUE(cfg_mgr_->parsed_elements_.contains("parse_one")); ConstElementPtr element = cfg_mgr_->parsed_elements_.get("parse_one"); @@ -589,9 +607,9 @@ TEST_F(ParseElementMgrTest, basic) { EXPECT_FALSE(cfg_mgr_->parsed_elements_.contains("parse_two")); // "parse_three" should be there - EXPECT_TRUE(cfg_mgr_->parsed_elements_.contains("parse_three")); - element = cfg_mgr_->parsed_elements_.get("parse_three"); - EXPECT_EQ(element->stringValue(), "3"); + EXPECT_TRUE(cfg_mgr_->parsed_elements_.contains("defaulted_parm")); + element = cfg_mgr_->parsed_elements_.get("defaulted_parm"); + EXPECT_EQ(element->stringValue(), "default value"); // Now verify the original mechanism elements were parsed correctly // Verify that the boolean parameter was parsed correctly by retrieving -- 2.47.3