From: Marcin Siodelski Date: Tue, 8 Jan 2013 17:17:36 +0000 (+0100) Subject: [2317] Added parser classes for option definitions. X-Git-Tag: bind10-1.0.0-rc-release~100^2~2^2~20 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=533c4afdae8ff16eb7d7b1f5529dd572e1098cf3;p=thirdparty%2Fkea.git [2317] Added parser classes for option definitions. --- diff --git a/src/bin/dhcp4/config_parser.cc b/src/bin/dhcp4/config_parser.cc index a6b857df13..b0c8e12a54 100644 --- a/src/bin/dhcp4/config_parser.cc +++ b/src/bin/dhcp4/config_parser.cc @@ -956,6 +956,130 @@ public: ParserCollection parsers_; }; +/// @brief Parser for a single option definition. +/// +/// This parser creates an instance of a single option definition. +class OptionDefParser: DhcpConfigParser { +public: + + /// @brief Constructor. + /// + /// This constructor sets the pointer to the option definitions + /// storage to NULL. It must be set to point to the actual storage + /// before \ref build is called. + OptionDefParser(const std::string&) + : storage_(NULL) { + } + + /// @brief Parses an entry that describes single option definition. + /// + /// @param option_def a configuration entry to be parsed. + /// + /// @throw Dhcp4ConfigError if parsing was unsuccessful. + void build(ConstElementPtr option_def) { + } + + /// @brief Stores the parsed option definition in a storage. + void commit() { + } + + /// @brief Sets a pointer to a storage. + /// + /// The newly created instance of an option definition will be + /// added to a storage given by the argument. + /// + /// @param storage pointer to a storage where the option definition + /// will be added to. + void setStorage(OptionDefContainer* storage) { + storage_ = storage; + } + +private: + + /// 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_; +}; + +/// @brief Parser for a list of option definitions. +/// +/// This parser iterates over all configuration entries that define +/// option definitions and creates instances of these definitions. +/// If the parsing is successful, the collection of created definitions +/// is put into the provided storage. +class OptionDefListParser : DhcpConfigParser { +public: + + /// @brief Constructor. + /// + /// This constructor initializes the pointer to option definitions + /// storage to NULL value. This pointer has to be set to point to + /// the actual storage before the \ref build function is called. + OptionDefListParser(const std::string&) + : option_defs_(NULL) { + } + + /// @brief Parse configuration entries. + /// + /// This function parses configuration entries and creates instances + /// of option definitions. + /// + /// @param option_def_list pointer to an element that holds entries + /// that define option definitions. + /// @throw Dhcp4ConfigError 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" + << " option definitions is NULL"); + } else if (option_defs_ == NULL) { + isc_throw(Dhcp4ConfigError, "parser error: the storage for option" + << " definitions must be set before parsing option" + << " definitions"); + } + + BOOST_FOREACH(ConstElementPtr option_def, option_def_list->listValue()) { + boost::shared_ptr + parser(new OptionDefParser("single-option-def")); + parser->setStorage(&option_defs_local_); + parser->build(option_def); + } + } + + /// @brief Stores option definitions in the provided storage. + void commit() { + } + + /// @brief Create an OptionDefListParser object. + /// + /// @param param_name configuration entry holding option definitions. + /// + /// @return OptionDefListParser object. + static DhcpConfigParser* factory(const std::string& param_name) { + return (new OptionDefListParser(param_name)); + } + + /// @brief Set storage for option definition instances. + /// + /// @param storage pointer to the option definition storage + /// where created option instances should be stored. + void setStorage(OptionDefContainer* storage) { + option_defs_ = storage; + } + +private: + + /// Pointer to the container where option definitions should + /// be stored when \ref commit is called. + OptionDefContainer* option_defs_; + + /// Temporary storage for option definitions. It holds option + /// definitions before \ref commit is called. + OptionDefContainer option_defs_local_; +}; + /// @brief this class parses a single subnet /// /// This class parses the whole subnet definition. It creates parsers diff --git a/src/bin/dhcp4/tests/config_parser_unittest.cc b/src/bin/dhcp4/tests/config_parser_unittest.cc index c6af514977..7ccd923244 100644 --- a/src/bin/dhcp4/tests/config_parser_unittest.cc +++ b/src/bin/dhcp4/tests/config_parser_unittest.cc @@ -436,6 +436,37 @@ TEST_F(Dhcp4ParserTest, poolPrefixLen) { EXPECT_EQ(4000, subnet->getValid()); } +// The goal of this test is to check whether an option definition +// can be added to the dhcp4 option space. +TEST_F(Dhcp4ParserTest, optionDefAdd) { + + // Configuration string. + std::string config = + "{ \"option-def\": [ {" + " \"name\": \"foo\"," + " \"code\": 100," + " \"type\": \"ipv4-address\"," + " \"array\": False," + " \"record_types\": [ ]," + " \"space\": \"isc\"" + " } ]" + "}"; + ElementPtr json = Element::fromJSON(config); + + // Make sure that the particular option definition does not exist. + OptionDefinitionPtr def = CfgMgr::instance().getOptionDef("isc", 100); + ASSERT_FALSE(def); + + // Use the configuration string to create new option definition. + ConstElementPtr status; + EXPECT_NO_THROW(status = configureDhcp4Server(*srv_, json)); + ASSERT_TRUE(status); + + // The option definition should now be available in the CfgMgr. + def = CfgMgr::instance().getOptionDef("isc", 100); + ASSERT_TRUE(def); +} + // Goal of this test is to verify that global option // data is configured for the subnet if the subnet // configuration does not include options configuration.