BIND 10 trac2317, updated. e39b61088924933e1335760d21cfa10e0cfd5425 [2317] Created common function to get configured parameter from a storage.

BIND 10 source code commits bind10-changes at lists.isc.org
Tue Jan 8 19:49:53 UTC 2013


The branch, trac2317 has been updated
       via  e39b61088924933e1335760d21cfa10e0cfd5425 (commit)
      from  533c4afdae8ff16eb7d7b1f5529dd572e1098cf3 (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 e39b61088924933e1335760d21cfa10e0cfd5425
Author: Marcin Siodelski <marcin at isc.org>
Date:   Tue Jan 8 20:49:32 2013 +0100

    [2317] Created common function to get configured parameter from a storage.

-----------------------------------------------------------------------

Summary of changes:
 src/bin/dhcp4/config_parser.cc       |  180 +++++++++++++++++++---------------
 src/bin/dhcp4/config_parser.h        |   14 ---
 src/bin/dhcp4/ctrl_dhcp4_srv.cc      |    3 +-
 src/bin/dhcp6/config_parser.cc       |  119 +++++++---------------
 src/bin/dhcp6/config_parser.h        |   14 ---
 src/bin/dhcp6/ctrl_dhcp6_srv.cc      |    3 +-
 src/lib/dhcpsrv/dhcp_config_parser.h |   42 ++++++++
 7 files changed, 186 insertions(+), 189 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/bin/dhcp4/config_parser.cc b/src/bin/dhcp4/config_parser.cc
index b0c8e12..20c6f57 100644
--- a/src/bin/dhcp4/config_parser.cc
+++ b/src/bin/dhcp4/config_parser.cc
@@ -37,6 +37,17 @@ using namespace isc::asiolink;
 
 namespace {
 
+// Forward declarations of some of the parser classes.
+// They are used to define pointer types for these classes.
+class BooleanParser;
+class StringParser;
+class Uint32Parser;
+
+// Pointers to various parser objects.
+typedef boost::shared_ptr<BooleanParser> BooleanParserPtr;
+typedef boost::shared_ptr<StringParser> StringParserPtr;
+typedef boost::shared_ptr<Uint32Parser> Uint32ParserPtr;
+
 /// @brief auxiliary type used for storing element name and its parser
 typedef pair<string, ConstElementPtr> ConfigPair;
 
@@ -149,7 +160,7 @@ public:
           value_(false) {
         // Empty parameter name is invalid.
         if (param_name_.empty()) {
-            isc_throw(isc::dhcp::Dhcp4ConfigError, "parser logic error:"
+            isc_throw(isc::dhcp::DhcpConfigError, "parser logic error:"
                       << "empty parameter name provided");
         }
     }
@@ -160,7 +171,7 @@ public:
     ///
     /// @throw isc::InvalidOperation if a storage has not been set
     ///        prior to calling this function
-    /// @throw isc::dhcp::Dhcp4ConfigError if a provided parameter's
+    /// @throw isc::dhcp::DhcpConfigError if a provided parameter's
     ///        name is empty.
     virtual void build(ConstElementPtr value) {
         if (storage_ == NULL) {
@@ -168,7 +179,7 @@ public:
                       << " storage for the " << param_name_
                       << " value has not been set");
         } else if (param_name_.empty()) {
-            isc_throw(isc::dhcp::Dhcp4ConfigError, "parser logic error:"
+            isc_throw(isc::dhcp::DhcpConfigError, "parser logic error:"
                       << "empty parameter name provided");
         }
         // The Config Manager checks if user specified a
@@ -233,7 +244,7 @@ public:
           param_name_(param_name) {
         // Empty parameter name is invalid.
         if (param_name_.empty()) {
-            isc_throw(Dhcp4ConfigError, "parser logic error:"
+            isc_throw(DhcpConfigError, "parser logic error:"
                       << "empty parameter name provided");
         }
     }
@@ -245,7 +256,7 @@ public:
     ///        or the parameter name is empty.
     virtual void build(ConstElementPtr value) {
         if (param_name_.empty()) {
-            isc_throw(Dhcp4ConfigError, "parser logic error:"
+            isc_throw(DhcpConfigError, "parser logic error:"
                       << "empty parameter name provided");
         }
 
@@ -326,7 +337,7 @@ public:
         :storage_(&string_defaults), param_name_(param_name) {
         // Empty parameter name is invalid.
         if (param_name_.empty()) {
-            isc_throw(Dhcp4ConfigError, "parser logic error:"
+            isc_throw(DhcpConfigError, "parser logic error:"
                       << "empty parameter name provided");
         }
     }
@@ -460,7 +471,7 @@ public:
     /// interface name.
     /// @param pools_list list of pools defined for a subnet
     /// @throw InvalidOperation if storage was not specified (setStorage() not called)
-    /// @throw Dhcp4ConfigError when pool parsing fails
+    /// @throw DhcpConfigError when pool parsing fails
     void build(ConstElementPtr pools_list) {
         // setStorage() should have been called before build
         if (!pools_) {
@@ -500,7 +511,7 @@ public:
                     // be checked in Pool4 constructor.
                     len = boost::lexical_cast<int>(prefix_len);
                 } catch (...)  {
-                    isc_throw(Dhcp4ConfigError, "Failed to parse pool "
+                    isc_throw(DhcpConfigError, "Failed to parse pool "
                               "definition: " << text_pool->stringValue());
                 }
 
@@ -522,7 +533,7 @@ public:
                 continue;
             }
 
-            isc_throw(Dhcp4ConfigError, "Failed to parse pool definition:"
+            isc_throw(DhcpConfigError, "Failed to parse pool definition:"
                       << text_pool->stringValue() <<
                       ". Does not contain - (for min-max) nor / (prefix/len)");
         }
@@ -603,7 +614,7 @@ public:
     ///
     /// @param option_data_entries collection of entries that define value
     /// for a particular option.
-    /// @throw Dhcp4ConfigError if invalid parameter specified in
+    /// @throw DhcpConfigError if invalid parameter specified in
     /// the configuration.
     /// @throw isc::InvalidOperation if failed to set storage prior to
     /// calling build.
@@ -644,7 +655,7 @@ public:
                     parser = value_parser;
                 }
             } else {
-                isc_throw(Dhcp4ConfigError,
+                isc_throw(DhcpConfigError,
                           "Parser error: option-data parameter not supported: "
                           << param.first);
             }
@@ -718,36 +729,36 @@ private:
     /// is intitialized but this check is not needed here because it is done
     /// in the \ref build function.
     ///
-    /// @throw Dhcp4ConfigError if parameters provided in the configuration
+    /// @throw DhcpConfigError if parameters provided in the configuration
     /// are invalid.
     void createOption() {
         // Option code is held in the uint32_t storage but is supposed to
         // be uint16_t value. We need to check that value in the configuration
         // does not exceed range of uint16_t and is not zero.
-        uint32_t option_code = getUint32Param("code");
+        uint32_t option_code = getParam<uint32_t>("code", uint32_values_);
         if (option_code == 0) {
-            isc_throw(Dhcp4ConfigError, "Parser error: value of 'code' must not"
+            isc_throw(DhcpConfigError, "Parser error: value of 'code' must not"
                       << " be equal to zero. Option code '0' is reserved in"
                       << " DHCPv4.");
         } else if (option_code > std::numeric_limits<uint16_t>::max()) {
-            isc_throw(Dhcp4ConfigError, "Parser error: value of 'code' must not"
+            isc_throw(DhcpConfigError, "Parser error: value of 'code' must not"
                       << " exceed " << std::numeric_limits<uint16_t>::max());
         }
         // Check that the option name has been specified, is non-empty and does not
         // contain spaces.
         // @todo possibly some more restrictions apply here?
-        std::string option_name = getStringParam("name");
+        std::string option_name = getParam<std::string>("name", string_values_);
         if (option_name.empty()) {
-            isc_throw(Dhcp4ConfigError, "Parser error: option name must not be"
+            isc_throw(DhcpConfigError, "Parser error: option name must not be"
                       << " empty");
         } else if (option_name.find(" ") != std::string::npos) {
-            isc_throw(Dhcp4ConfigError, "Parser error: option name must not contain"
+            isc_throw(DhcpConfigError, "Parser error: option name must not contain"
                       << " spaces");
         }
 
         // Get option data from the configuration database ('data' field).
-        const std::string option_data = getStringParam("data");
-        const bool csv_format = getBooleanParam("csv-format");
+        const std::string option_data = getParam<std::string>("data", string_values_);
+        const bool csv_format = getParam<bool>("csv-format", boolean_values_);
         // Transform string of hexadecimal digits into binary format.
         std::vector<uint8_t> binary;
         std::vector<std::string> data_tokens;
@@ -764,7 +775,7 @@ private:
             try {
                 util::encode::decodeHex(option_data, binary);
             } catch (...) {
-                isc_throw(Dhcp4ConfigError, "Parser error: option data is not a valid"
+                isc_throw(DhcpConfigError, "Parser error: option data is not a valid"
                           << " string of hexadecimal digits: " << option_data);
             }
         }
@@ -781,13 +792,13 @@ private:
         // Currently we do not allow duplicated definitions and if there are
         // any duplicates we issue internal server error.
         if (num_defs > 1) {
-            isc_throw(Dhcp4ConfigError, "Internal error: currently it is not"
+            isc_throw(DhcpConfigError, "Internal error: currently it is not"
                       << " supported to initialize multiple option definitions"
                       << " for the same option code. This will be supported once"
                       << " there option spaces are implemented.");
         } else if (num_defs == 0) {
             if (csv_format) {
-                isc_throw(Dhcp4ConfigError, "the CSV option data format can be"
+                isc_throw(DhcpConfigError, "the CSV option data format can be"
                           " used to specify values for an option that has a"
                           " definition. The option with code " << option_code
                           << " does not have a definition.");
@@ -817,54 +828,13 @@ private:
                 option_descriptor_.option = option;
                 option_descriptor_.persistent = false;
             } catch (const isc::Exception& ex) {
-                isc_throw(Dhcp4ConfigError, "Parser error: option data does not match"
+                isc_throw(DhcpConfigError, "Parser error: option data does not match"
                           << " option definition (code " << option_code << "): "
                           << ex.what());
             }
         }
     }
 
-    /// @brief Get a parameter from the strings storage.
-    ///
-    /// @param param_id parameter identifier.
-    /// @throw Dhcp4ConfigError if parameter has not been found.
-    std::string getStringParam(const std::string& param_id) const {
-        StringStorage::const_iterator param = string_values_.find(param_id);
-        if (param == string_values_.end()) {
-            isc_throw(Dhcp4ConfigError, "Parser error: option-data parameter"
-                      << " '" << param_id << "' not specified");
-        }
-        return (param->second);
-    }
-
-    /// @brief Get a parameter from the uint32 values storage.
-    ///
-    /// @param param_id parameter identifier.
-    /// @throw Dhcp4ConfigError if parameter has not been found.
-    uint32_t getUint32Param(const std::string& param_id) const {
-        Uint32Storage::const_iterator param = uint32_values_.find(param_id);
-        if (param == uint32_values_.end()) {
-            isc_throw(Dhcp4ConfigError, "Parser error: option-data parameter"
-                      << " '" << param_id << "' not specified");
-        }
-        return (param->second);
-    }
-
-    /// @brief Get a parameter from the boolean values storage.
-    ///
-    /// @param param_id parameter identifier.
-    ///
-    /// @throw isc::dhcp::Dhcp6ConfigError if a parameter has not been found.
-    /// @return a value of the boolean parameter.
-    bool getBooleanParam(const std::string& param_id) const {
-        BooleanStorage::const_iterator param = boolean_values_.find(param_id);
-        if (param == boolean_values_.end()) {
-            isc_throw(isc::dhcp::Dhcp4ConfigError, "parser error: option-data parameter"
-                      << " '" << param_id << "' not specified");
-        }
-        return (param->second);
-    }
-
     /// Storage for uint32 values (e.g. option code).
     Uint32Storage uint32_values_;
     /// Storage for string values (e.g. option name or data).
@@ -901,7 +871,7 @@ public:
     /// for options within a single subnet and creates options' instances.
     ///
     /// @param option_data_list pointer to a list of options' data sets.
-    /// @throw Dhcp4ConfigError if option parsing failed.
+    /// @throw DhcpConfigError if option parsing failed.
     void build(ConstElementPtr option_data_list) {
         BOOST_FOREACH(ConstElementPtr option_value, option_data_list->listValue()) {
             boost::shared_ptr<OptionDataParser> parser(new OptionDataParser("option-data"));
@@ -975,12 +945,53 @@ public:
     ///
     /// @param option_def a configuration entry to be parsed.
     ///
-    /// @throw Dhcp4ConfigError if parsing was unsuccessful.
+    /// @throw DhcpConfigError if parsing was unsuccessful.
     void build(ConstElementPtr option_def) {
+        if (storage_ == NULL) {
+            isc_throw(DhcpConfigError, "parser logic error: storage must be set"
+                      " before parsing option definition data");
+        }
+        // Parse the elements that make up the option definition.
+        BOOST_FOREACH(ConfigPair param, option_def->mapValue()) {
+            std::string entry(param.first);
+            ParserPtr parser;
+            if (entry == "name" || entry == "type" || entry == "space") {
+                StringParserPtr
+                    str_parser(dynamic_cast<StringParser*>(StringParser::factory(entry)));
+                if (str_parser) {
+                    str_parser->setStorage(&string_values_);
+                    parser = str_parser;
+                }
+            } else if (entry == "code") {
+                Uint32ParserPtr
+                    code_parser(dynamic_cast<Uint32Parser*>(Uint32Parser::factory(entry)));
+                if (code_parser) {
+                    code_parser->setStorage(&uint32_values_);
+                    parser = code_parser;
+                }
+            } else if (entry == "array") {
+                BooleanParserPtr
+                    array_parser(dynamic_cast<BooleanParser*>(BooleanParser::factory(entry)));
+                if (array_parser) {
+                    array_parser->setStorage(&boolean_values_);
+                    parser = array_parser;
+                }
+            } else if (entry == "record_types") {
+                // do nothing yet
+            } else {
+                isc_throw(DhcpConfigError, "invalid parameter: " << entry);
+            }
+            
+            parser->build(param.second);
+            parser->commit();
+        }
+
+        createOptionDef();
     }
 
     /// @brief Stores the parsed option definition in a storage.
     void commit() {
+        
     }
 
     /// @brief Sets a pointer to a storage.
@@ -996,12 +1007,27 @@ public:
 
 private:
 
+    void createOptionDef() {
+        std::string name = getParam<std::string>("name", string_values_);
+        uint32_t code = getParam<uint32_t>("code", uint32_values_);
+        std::string type = getParam<std::string>("type", string_values_);
+        bool array_type = getParam<bool>("array", boolean_values_);
+        std::string space = getParam<std::string>("space", string_values_);
+    }
+
     /// Instance of option definition being created by this parser.
     OptionDefinitionPtr option_definition_;
 
     /// Pointer to a storage where the option definition will be
     /// added when \ref commit is called.
     OptionDefContainer* storage_;
+
+    /// Storage for boolean values.
+    BooleanStorage boolean_values_;
+    /// Storage for string values.
+    StringStorage string_values_;
+    /// Storage for uint32 values.
+    Uint32Storage uint32_values_;
 };
 
 /// @brief Parser for a list of option definitions.
@@ -1029,13 +1055,13 @@ public:
     ///
     /// @param option_def_list pointer to an element that holds entries
     /// that define option definitions.
-    /// @throw Dhcp4ConfigError if configuration parsing fails.
+    /// @throw DhcpConfigError if configuration parsing fails.
     void build(ConstElementPtr option_def_list) {
         if (!option_def_list) {
-            isc_throw(Dhcp4ConfigError, "parser error: a pointer to a list of"
+            isc_throw(DhcpConfigError, "parser error: a pointer to a list of"
                       << " option definitions is NULL");
         } else if (option_defs_ == NULL) {
-            isc_throw(Dhcp4ConfigError, "parser error: the storage for option"
+            isc_throw(DhcpConfigError, "parser error: the storage for option"
                       << " definitions must be set before parsing option"
                       << " definitions");
         }
@@ -1121,7 +1147,7 @@ public:
                 // Appropriate parsers are created in the createSubnet6ConfigParser
                 // and they should be limited to those that we check here for. Thus,
                 // if we fail to find a matching parser here it is a programming error.
-                isc_throw(Dhcp4ConfigError, "failed to find suitable parser");
+                isc_throw(DhcpConfigError, "failed to find suitable parser");
             }
         }
         // In order to create new subnet we need to get the data out
@@ -1146,7 +1172,7 @@ public:
     /// storing the values that are actually consumed here. Pool definitions
     /// created in other parsers are used here and added to newly created Subnet4
     /// objects. Subnet4 are then added to DHCP CfgMgr.
-    /// @throw Dhcp4ConfigError if there are any issues encountered during commit
+    /// @throw DhcpConfigError if there are any issues encountered during commit
     void commit() {
         if (subnet_) {
             CfgMgr::instance().addSubnet4(subnet_);
@@ -1191,11 +1217,11 @@ private:
 
     /// @brief Create a new subnet using a data from child parsers.
     ///
-    /// @throw isc::dhcp::Dhcp4ConfigError if subnet configuration parsing failed.
+    /// @throw isc::dhcp::DhcpConfigError if subnet configuration parsing failed.
     void createSubnet() {
         StringStorage::const_iterator it = string_values_.find("subnet");
         if (it == string_values_.end()) {
-            isc_throw(Dhcp4ConfigError,
+            isc_throw(DhcpConfigError,
                       "Mandatory subnet definition in subnet missing");
         }
         // Remove any spaces or tabs.
@@ -1210,7 +1236,7 @@ private:
         // need to get all characters preceding "/".
         size_t pos = subnet_txt.find("/");
         if (pos == string::npos) {
-            isc_throw(Dhcp4ConfigError,
+            isc_throw(DhcpConfigError,
                       "Invalid subnet syntax (prefix/len expected):" << it->second);
         }
 
@@ -1315,7 +1341,7 @@ private:
     ///
     /// @param name name of the parameter
     /// @return triplet with the parameter name
-    /// @throw Dhcp4ConfigError when requested parameter is not present
+    /// @throw DhcpConfigError when requested parameter is not present
     Triplet<uint32_t> getParam(const std::string& name) {
         uint32_t value = 0;
         bool found = false;
@@ -1334,7 +1360,7 @@ private:
         if (found) {
             return (Triplet<uint32_t>(value));
         } else {
-            isc_throw(Dhcp4ConfigError, "Mandatory parameter " << name
+            isc_throw(DhcpConfigError, "Mandatory parameter " << name
                       << " missing (no global default and no subnet-"
                       << "specific value)");
         }
diff --git a/src/bin/dhcp4/config_parser.h b/src/bin/dhcp4/config_parser.h
index 3247241..4f1ea32 100644
--- a/src/bin/dhcp4/config_parser.h
+++ b/src/bin/dhcp4/config_parser.h
@@ -28,20 +28,6 @@ namespace dhcp {
 
 class Dhcpv4Srv;
 
-/// An exception that is thrown if an error occurs while configuring an
-/// @c Dhcpv4Srv object.
-class Dhcp4ConfigError : public isc::Exception {
-public:
-
-    /// @brief constructor
-    ///
-    /// @param file name of the file, where exception occurred
-    /// @param line line of the file, where exception occurred
-    /// @param what text description of the issue that caused exception
-    Dhcp4ConfigError(const char* file, size_t line, const char* what)
-        : isc::Exception(file, line, what) {}
-};
-
 /// @brief Configure DHCPv4 server (@c Dhcpv4Srv) with a set of configuration values.
 ///
 /// This function parses configuration information stored in @c config_set
diff --git a/src/bin/dhcp4/ctrl_dhcp4_srv.cc b/src/bin/dhcp4/ctrl_dhcp4_srv.cc
index eb5d482..435a25e 100644
--- a/src/bin/dhcp4/ctrl_dhcp4_srv.cc
+++ b/src/bin/dhcp4/ctrl_dhcp4_srv.cc
@@ -19,6 +19,7 @@
 #include <cc/session.h>
 #include <config/ccsession.h>
 #include <dhcp/iface_mgr.h>
+#include <dhcpsrv/dhcp_config_parser.h>
 #include <dhcp4/ctrl_dhcp4_srv.h>
 #include <dhcp4/dhcp4_log.h>
 #include <dhcp4/spec_config.h>
@@ -121,7 +122,7 @@ void ControlledDhcpv4Srv::establishSession() {
 
     try {
         configureDhcp4Server(*this, config_session_->getFullConfig());
-    } catch (const Dhcp4ConfigError& ex) {
+    } catch (const DhcpConfigError& ex) {
         LOG_ERROR(dhcp4_logger, DHCP4_CONFIG_LOAD_FAIL).arg(ex.what());
     }
 
diff --git a/src/bin/dhcp6/config_parser.cc b/src/bin/dhcp6/config_parser.cc
index dd50c30..40d9a4b 100644
--- a/src/bin/dhcp6/config_parser.cc
+++ b/src/bin/dhcp6/config_parser.cc
@@ -161,7 +161,7 @@ public:
           value_(false) {
         // Empty parameter name is invalid.
         if (param_name_.empty()) {
-            isc_throw(isc::dhcp::Dhcp6ConfigError, "parser logic error:"
+            isc_throw(isc::dhcp::DhcpConfigError, "parser logic error:"
                       << "empty parameter name provided");
         }
     }
@@ -172,7 +172,7 @@ public:
     ///
     /// @throw isc::InvalidOperation if a storage has not been set
     ///        prior to calling this function
-    /// @throw isc::dhcp::Dhcp6ConfigError if a provided parameter's
+    /// @throw isc::dhcp::DhcpConfigError if a provided parameter's
     ///        name is empty.
     virtual void build(ConstElementPtr value) {
         if (storage_ == NULL) {
@@ -180,7 +180,7 @@ public:
                       << " storage for the " << param_name_
                       << " value has not been set");
         } else if (param_name_.empty()) {
-            isc_throw(isc::dhcp::Dhcp6ConfigError, "parser logic error:"
+            isc_throw(isc::dhcp::DhcpConfigError, "parser logic error:"
                       << "empty parameter name provided");
         }
         // The Config Manager checks if user specified a
@@ -249,7 +249,7 @@ public:
           param_name_(param_name) {
         // Empty parameter name is invalid.
         if (param_name_.empty()) {
-            isc_throw(Dhcp6ConfigError, "parser logic error:"
+            isc_throw(DhcpConfigError, "parser logic error:"
                       << "empty parameter name provided");
         }
     }
@@ -257,11 +257,11 @@ public:
     /// @brief Parses configuration configuration parameter as uint32_t.
     ///
     /// @param value pointer to the content of parsed values
-    /// @throw isc::dhcp::Dhcp6ConfigError if failed to parse
+    /// @throw isc::dhcp::DhcpConfigError if failed to parse
     ///        the configuration parameter as uint32_t value.
     virtual void build(ConstElementPtr value) {
         if (param_name_.empty()) {
-            isc_throw(isc::dhcp::Dhcp6ConfigError, "parser logic error:"
+            isc_throw(isc::dhcp::DhcpConfigError, "parser logic error:"
                       << "empty parameter name provided");
         }
 
@@ -291,7 +291,7 @@ public:
         }
         // Invalid value provided.
         if (parse_error) {
-            isc_throw(isc::dhcp::Dhcp6ConfigError, "Failed to parse value " << value->str()
+            isc_throw(isc::dhcp::DhcpConfigError, "Failed to parse value " << value->str()
                       << " as unsigned 32-bit integer.");
         }
     }
@@ -352,7 +352,7 @@ public:
           param_name_(param_name) {
         // Empty parameter name is invalid.
         if (param_name_.empty()) {
-            isc_throw(Dhcp6ConfigError, "parser logic error:"
+            isc_throw(DhcpConfigError, "parser logic error:"
                       << "empty parameter name provided");
         }
     }
@@ -362,10 +362,10 @@ public:
     /// Parses configuration parameter's value as string.
     ///
     /// @param value pointer to the content of parsed values
-    /// @throws Dhcp6ConfigError if the parsed parameter's name is empty.
+    /// @throws DhcpConfigError if the parsed parameter's name is empty.
     virtual void build(ConstElementPtr value) {
         if (param_name_.empty()) {
-            isc_throw(isc::dhcp::Dhcp6ConfigError, "parser logic error:"
+            isc_throw(isc::dhcp::DhcpConfigError, "parser logic error:"
                       << "empty parameter name provided");
         }
         value_ = value->str();
@@ -528,7 +528,7 @@ public:
                     // be checked in Pool6 constructor.
                     len = boost::lexical_cast<int>(prefix_len);
                 } catch (...)  {
-                    isc_throw(Dhcp6ConfigError, "failed to parse pool "
+                    isc_throw(DhcpConfigError, "failed to parse pool "
                               "definition: " << text_pool->stringValue());
                 }
 
@@ -550,7 +550,7 @@ public:
                 continue;
             }
 
-            isc_throw(Dhcp6ConfigError, "failed to parse pool definition:"
+            isc_throw(DhcpConfigError, "failed to parse pool definition:"
                       << text_pool->stringValue() <<
                       ". Does not contain - (for min-max) nor / (prefix/len)");
         }
@@ -632,7 +632,7 @@ public:
     ///
     /// @param option_data_entries collection of entries that define value
     /// for a particular option.
-    /// @throw Dhcp6ConfigError if invalid parameter specified in
+    /// @throw DhcpConfigError if invalid parameter specified in
     /// the configuration.
     /// @throw isc::InvalidOperation if failed to set storage prior to
     /// calling build.
@@ -674,7 +674,7 @@ public:
                     parser = value_parser;
                 }
             } else {
-                isc_throw(Dhcp6ConfigError,
+                isc_throw(DhcpConfigError,
                           "parser error: option-data parameter not supported: "
                           << param.first);
             }
@@ -748,37 +748,37 @@ private:
     /// is intitialized but this check is not needed here because it is done
     /// in the \ref build function.
     ///
-    /// @throw Dhcp6ConfigError if parameters provided in the configuration
+    /// @throw DhcpConfigError if parameters provided in the configuration
     /// are invalid.
     void createOption() {
 
         // Option code is held in the uint32_t storage but is supposed to
         // be uint16_t value. We need to check that value in the configuration
         // does not exceed range of uint16_t and is not zero.
-        uint32_t option_code = getUint32Param("code");
+        uint32_t option_code = getParam<uint32_t>("code", uint32_values_);
         if (option_code == 0) {
-            isc_throw(Dhcp6ConfigError, "Parser error: value of 'code' must not"
+            isc_throw(DhcpConfigError, "Parser error: value of 'code' must not"
                       << " be equal to zero. Option code '0' is reserved in"
                       << " DHCPv6.");
         } else if (option_code > std::numeric_limits<uint16_t>::max()) {
-            isc_throw(Dhcp6ConfigError, "Parser error: value of 'code' must not"
+            isc_throw(DhcpConfigError, "Parser error: value of 'code' must not"
                       << " exceed " << std::numeric_limits<uint16_t>::max());
         }
         // Check that the option name has been specified, is non-empty and does not
         // contain spaces.
         // @todo possibly some more restrictions apply here?
-        std::string option_name = getStringParam("name");
+        std::string option_name = getParam<std::string>("name", string_values_);
         if (option_name.empty()) {
-            isc_throw(Dhcp6ConfigError, "Parser error: option name must not be"
+            isc_throw(DhcpConfigError, "Parser error: option name must not be"
                       << " empty");
         } else if (option_name.find(" ") != std::string::npos) {
-            isc_throw(Dhcp6ConfigError, "Parser error: option name must not contain"
+            isc_throw(DhcpConfigError, "Parser error: option name must not contain"
                       << " spaces");
         }
 
         // Get option data from the configuration database ('data' field).
-        const std::string option_data = getStringParam("data");
-        const bool csv_format = getBooleanParam("csv-format");
+        const std::string option_data = getParam<std::string>("data", string_values_);
+        const bool csv_format = getParam<bool>("csv-format", boolean_values_);
         std::vector<uint8_t> binary;
         std::vector<std::string> data_tokens;
         if (csv_format) {
@@ -793,7 +793,7 @@ private:
             try {
                 isc::util::encode::decodeHex(option_data, binary);
             } catch (...) {
-                isc_throw(Dhcp6ConfigError, "Parser error: option data is not a valid"
+                isc_throw(DhcpConfigError, "Parser error: option data is not a valid"
                           << " string of hexadecimal digits: " << option_data);
             }
         }
@@ -810,13 +810,13 @@ private:
         // Currently we do not allow duplicated definitions and if there are
         // any duplicates we issue internal server error.
         if (num_defs > 1) {
-            isc_throw(Dhcp6ConfigError, "Internal error: currently it is not"
+            isc_throw(DhcpConfigError, "Internal error: currently it is not"
                       << " supported to initialize multiple option definitions"
                       << " for the same option code. This will be supported once"
                       << " there option spaces are implemented.");
         } else if (num_defs == 0) {
             if (csv_format) {
-                isc_throw(Dhcp6ConfigError, "the CSV option data format can be"
+                isc_throw(DhcpConfigError, "the CSV option data format can be"
                           " used to specify values for an option that has a"
                           " definition. The option with code " << option_code
                           << " does not have a definition.");
@@ -845,58 +845,13 @@ private:
                 option_descriptor_.option = option;
                 option_descriptor_.persistent = false;
             } catch (const isc::Exception& ex) {
-                isc_throw(Dhcp6ConfigError, "Parser error: option data does not match"
+                isc_throw(DhcpConfigError, "Parser error: option data does not match"
                           << " option definition (code " << option_code << "): "
                           << ex.what());
             }
         }
     }
 
-    /// @brief Get a parameter from the strings storage.
-    ///
-    /// @param param_id parameter identifier.
-    ///
-    /// @throw Dhcp6ConfigError if a parameter has not been found.
-    /// @return a value of the string parameter.
-    std::string getStringParam(const std::string& param_id) const {
-        StringStorage::const_iterator param = string_values_.find(param_id);
-        if (param == string_values_.end()) {
-            isc_throw(isc::dhcp::Dhcp6ConfigError, "parser error: option-data parameter"
-                      << " '" << param_id << "' not specified");
-        }
-        return (param->second);
-    }
-
-    /// @brief Get a parameter from the uint32 values storage.
-    ///
-    /// @param param_id parameter identifier.
-    ///
-    /// @throw Dhcp6ConfigError if a parameter has not been found.
-    /// @return a value of the uint32_t parameter.
-    uint32_t getUint32Param(const std::string& param_id) const {
-        Uint32Storage::const_iterator param = uint32_values_.find(param_id);
-        if (param == uint32_values_.end()) {
-            isc_throw(isc::dhcp::Dhcp6ConfigError, "parser error: option-data parameter"
-                      << " '" << param_id << "' not specified");
-        }
-        return (param->second);
-    }
-
-    /// @brief Get a parameter from the boolean values storage.
-    ///
-    /// @param param_id parameter identifier.
-    ///
-    /// @throw isc::dhcp::Dhcp6ConfigError if a parameter has not been found.
-    /// @return a value of the boolean parameter.
-    bool getBooleanParam(const std::string& param_id) const {
-        BooleanStorage::const_iterator param = boolean_values_.find(param_id);
-        if (param == boolean_values_.end()) {
-            isc_throw(isc::dhcp::Dhcp6ConfigError, "parser error: option-data parameter"
-                      << " '" << param_id << "' not specified");
-        }
-        return (param->second);
-    }
-
     /// Storage for uint32 values (e.g. option code).
     Uint32Storage uint32_values_;
     /// Storage for string values (e.g. option name or data).
@@ -933,7 +888,7 @@ public:
     /// for options within a single subnet and creates options' instances.
     ///
     /// @param option_data_list pointer to a list of options' data sets.
-    /// @throw Dhcp6ConfigError if option parsing failed.
+    /// @throw DhcpConfigError if option parsing failed.
     void build(ConstElementPtr option_data_list) {
         BOOST_FOREACH(ConstElementPtr option_value, option_data_list->listValue()) {
             boost::shared_ptr<OptionDataParser> parser(new OptionDataParser("option-data"));
@@ -1005,7 +960,7 @@ public:
     ///
     /// @param subnet pointer to the content of subnet definition
     ///
-    /// @throw isc::Dhcp6ConfigError if subnet configuration parsing failed.
+    /// @throw isc::DhcpConfigError if subnet configuration parsing failed.
     void build(ConstElementPtr subnet) {
 
         BOOST_FOREACH(ConfigPair param, subnet->mapValue()) {
@@ -1031,7 +986,7 @@ public:
                 // Appropriate parsers are created in the createSubnet6ConfigParser
                 // and they should be limited to those that we check here for. Thus,
                 // if we fail to find a matching parser here it is a programming error.
-                isc_throw(Dhcp6ConfigError, "failed to find suitable parser");
+                isc_throw(DhcpConfigError, "failed to find suitable parser");
             }
         }
 
@@ -1096,13 +1051,13 @@ private:
 
     /// @brief Create a new subnet using a data from child parsers.
     ///
-    /// @throw isc::dhcp::Dhcp6ConfigError if subnet configuration parsing failed.
+    /// @throw isc::dhcp::DhcpConfigError if subnet configuration parsing failed.
     void createSubnet() {
         
         // Find a subnet string.
         StringStorage::const_iterator it = string_values_.find("subnet");
         if (it == string_values_.end()) {
-            isc_throw(Dhcp6ConfigError,
+            isc_throw(DhcpConfigError,
                       "Mandatory subnet definition in subnet missing");
         }
         // Remove any spaces or tabs.
@@ -1116,7 +1071,7 @@ private:
         // need to get all characters preceding "/".
         size_t pos = subnet_txt.find("/");
         if (pos == string::npos) {
-            isc_throw(Dhcp6ConfigError,
+            isc_throw(DhcpConfigError,
                       "Invalid subnet syntax (prefix/len expected):" << it->second);
         }
 
@@ -1193,7 +1148,7 @@ private:
     /// @param config_id name od the entry
     ///
     /// @return parser object for specified entry name
-    /// @throw isc::dhcp::Dhcp6ConfigError if trying to create a parser
+    /// @throw isc::dhcp::DhcpConfigError if trying to create a parser
     ///        for unknown config element
     DhcpConfigParser* createSubnet6ConfigParser(const std::string& config_id) {
         FactoryMap factories;
@@ -1211,7 +1166,7 @@ private:
             // Used for debugging only.
             // return new DebugParser(config_id);
 
-            isc_throw(isc::dhcp::Dhcp6ConfigError,
+            isc_throw(isc::dhcp::DhcpConfigError,
                       "parser error: subnet6 parameter not supported: "
                       << config_id);
         }
@@ -1226,7 +1181,7 @@ private:
     ///
     /// @param name name of the parameter
     /// @return triplet with the parameter name
-    /// @throw Dhcp6ConfigError when requested parameter is not present
+    /// @throw DhcpConfigError when requested parameter is not present
     isc::dhcp::Triplet<uint32_t> getParam(const std::string& name) {
         uint32_t value = 0;
         bool found = false;
@@ -1245,7 +1200,7 @@ private:
         if (found) {
             return (isc::dhcp::Triplet<uint32_t>(value));
         } else {
-            isc_throw(isc::dhcp::Dhcp6ConfigError, "Mandatory parameter " << name
+            isc_throw(isc::dhcp::DhcpConfigError, "Mandatory parameter " << name
                       << " missing (no global default and no subnet-"
                       << "specific value)");
         }
diff --git a/src/bin/dhcp6/config_parser.h b/src/bin/dhcp6/config_parser.h
index 408d01f..6d7a807 100644
--- a/src/bin/dhcp6/config_parser.h
+++ b/src/bin/dhcp6/config_parser.h
@@ -27,20 +27,6 @@ namespace dhcp {
 
 class Dhcpv6Srv;
 
-/// An exception that is thrown if an error occurs while configuring an
-/// @c Dhcpv6Srv object.
-class Dhcp6ConfigError : public isc::Exception {
-public:
-
-    /// @brief constructor
-    ///
-    /// @param file name of the file, where exception occurred
-    /// @param line line of the file, where exception occurred
-    /// @param what text description of the issue that caused exception
-    Dhcp6ConfigError(const char* file, size_t line, const char* what)
-        : isc::Exception(file, line, what) {}
-};
-
 /// @brief Configures DHCPv6 server
 ///
 /// This function is called every time a new configuration is received. The extra
diff --git a/src/bin/dhcp6/ctrl_dhcp6_srv.cc b/src/bin/dhcp6/ctrl_dhcp6_srv.cc
index 8611365..ba3e2c2 100644
--- a/src/bin/dhcp6/ctrl_dhcp6_srv.cc
+++ b/src/bin/dhcp6/ctrl_dhcp6_srv.cc
@@ -19,6 +19,7 @@
 #include <cc/session.h>
 #include <config/ccsession.h>
 #include <dhcp/iface_mgr.h>
+#include <dhcpsrv/dhcp_config_parser.h>
 #include <dhcp6/config_parser.h>
 #include <dhcp6/ctrl_dhcp6_srv.h>
 #include <dhcp6/dhcp6_log.h>
@@ -121,7 +122,7 @@ void ControlledDhcpv6Srv::establishSession() {
 
     try {
         configureDhcp6Server(*this, config_session_->getFullConfig());
-    } catch (const Dhcp6ConfigError& ex) {
+    } catch (const DhcpConfigError& ex) {
         LOG_ERROR(dhcp6_logger, DHCP6_CONFIG_LOAD_FAIL).arg(ex.what());
     }
 
diff --git a/src/lib/dhcpsrv/dhcp_config_parser.h b/src/lib/dhcpsrv/dhcp_config_parser.h
index 7077552..6b4dd36 100644
--- a/src/lib/dhcpsrv/dhcp_config_parser.h
+++ b/src/lib/dhcpsrv/dhcp_config_parser.h
@@ -18,6 +18,20 @@
 namespace isc {
 namespace dhcp {
 
+/// An exception that is thrown if an error occurs while configuring
+/// DHCP server.
+class DhcpConfigError : public isc::Exception {
+public:
+
+    /// @brief constructor
+    ///
+    /// @param file name of the file, where exception occurred
+    /// @param line line of the file, where exception occurred
+    /// @param what text description of the issue that caused exception
+    DhcpConfigError(const char* file, size_t line, const char* what)
+        : isc::Exception(file, line, what) {}
+};
+
 /// @brief Forward declaration to DhcpConfigParser class.
 ///
 /// It is only needed here to define types that are
@@ -105,6 +119,34 @@ public:
     /// This method is expected to be called after @c build(), and only once.
     /// The result is undefined otherwise.
     virtual void commit() = 0;
+
+protected:
+
+    /// @brief Return the parsed entry from the provided storage.
+    ///
+    /// This method returns the parsed entry from the provided
+    /// storage. If the entry is not found, then exception is
+    /// thrown.
+    ///
+    /// @param param_id name of the configuration entry.
+    /// @param storage storage where the entry should be searched.
+    /// @tparam ReturnType type of the returned value.
+    /// @tparam StorageType type of the storage.
+    ///
+    /// @throw DhcpConfigError if the entry has not been found
+    /// in the storage.
+    template<typename ReturnType, typename StorageType>
+    ReturnType getParam(const std::string param_id,
+                        const StorageType& storage) const {
+        typename StorageType::const_iterator param = storage.find(param_id);
+        if (param == storage.end()) {
+            isc_throw(DhcpConfigError, "missing parameter '"
+                      << param_id << "'");
+        }
+        ReturnType value = param->second;
+        return (value);
+    }
+
 };
 
 



More information about the bind10-changes mailing list