Commit 3c702b89 authored by Marcin Siodelski's avatar Marcin Siodelski
Browse files

[2545] Moved the DHCPv4 parser classes to the anonymous namespace.

parent 8b1a0145
......@@ -28,11 +28,26 @@
#include <map>
using namespace std;
using namespace isc;
using namespace isc::dhcp;
using namespace isc::data;
using namespace isc::asiolink;
namespace isc {
namespace dhcp {
namespace {
/// @brief Forward declaration to Dhcp4ConfigParser class.
///
/// It is only needed here to define types that are
/// based on this class before the class definition.
class Dhcp4ConfigParser;
/// @brief a pointer to configuration parser
typedef boost::shared_ptr<Dhcp4ConfigParser> ParserPtr;
/// @brief a collection of parsers
///
/// This container is used to store pointer to parsers for a given scope.
typedef std::vector<ParserPtr> ParserCollection;
/// @brief auxiliary type used for storing element name and its parser
typedef pair<string, ConstElementPtr> ConfigPair;
......@@ -63,6 +78,82 @@ StringStorage string_defaults;
/// @brief Global storage for options that will be used as defaults.
OptionStorage option_defaults;
/// @brief Base abstract class for all DHCPv4 parsers
///
/// Each instance of a class derived from this class parses one specific config
/// element. Sometimes elements are simple (e.g. a string) and sometimes quite
/// complex (e.g. a subnet). In such case, it is likely that a parser will
/// spawn child parsers to parse child elements in the configuration.
/// @todo: Merge this class with DhcpConfigParser in src/bin/dhcp6
class Dhcp4ConfigParser {
///
/// \name Constructors and Destructor
///
/// Note: The copy constructor and the assignment operator are
/// intentionally defined as private to make it explicit that this is a
/// pure base class.
//@{
private:
// Private construtor and assignment operator assures that nobody
// will be able to copy or assign a parser. There are no defined
// bodies for them.
Dhcp4ConfigParser(const Dhcp4ConfigParser& source);
Dhcp4ConfigParser& operator=(const Dhcp4ConfigParser& source);
protected:
/// \brief The default constructor.
///
/// This is intentionally defined as \c protected as this base class should
/// never be instantiated (except as part of a derived class).
Dhcp4ConfigParser() {}
public:
/// The destructor.
virtual ~Dhcp4ConfigParser() {}
//@}
/// \brief Prepare configuration value.
///
/// This method parses the "value part" of the configuration identifier
/// that corresponds to this derived class and prepares a new value to
/// apply to the server.
///
/// This method must validate the given value both in terms of syntax
/// and semantics of the configuration, so that the server will be
/// validly configured at the time of \c commit(). Note: the given
/// configuration value is normally syntactically validated, but the
/// \c build() implementation must also expect invalid input. If it
/// detects an error it may throw an exception of a derived class
/// of \c isc::Exception.
///
/// Preparing a configuration value will often require resource
/// allocation. If it fails, it may throw a corresponding standard
/// exception.
///
/// This method is not expected to be called more than once in the
/// life of the object. 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;
/// \brief Apply the prepared configuration value to the server.
///
/// This method is expected to be exception free, and, as a consequence,
/// it should normally not involve resource allocation.
/// Typically it would simply perform exception free assignment or swap
/// operation on the value prepared in \c build().
/// In some cases, however, it may be very difficult to meet this
/// condition in a realistic way, while the failure case should really
/// be very rare. In such a case it may throw, and, if the parser is
/// called via \c configureDhcp4Server(), the caller will convert the
/// exception as a fatal error.
///
/// This method is expected to be called after \c build(), and only once.
/// The result is undefined otherwise.
virtual void commit() = 0;
};
/// @brief a dummy configuration parser
///
/// It is a debugging parser. It does not configure anything,
......@@ -1106,6 +1197,11 @@ public:
ParserCollection subnets_;
};
} // anonymous namespace
namespace isc {
namespace dhcp {
/// @brief creates global parsers
///
/// This method creates global parsers that parse global parameters, i.e.
......@@ -1189,5 +1285,9 @@ configureDhcp4Server(Dhcpv4Srv& , ConstElementPtr config_set) {
return (answer);
}
const std::map<std::string, uint32_t>& getUint32Defaults() {
return (uint32_defaults);
}
}; // end of isc::dhcp namespace
}; // end of isc namespace
......@@ -35,7 +35,7 @@ typedef std::map<std::string, uint32_t> Uint32Storage;
typedef std::map<std::string, std::string> StringStorage;
/// An exception that is thrown if an error occurs while configuring an
/// \c Dhcpv4Srv object.
/// @c Dhcpv4Srv object.
class Dhcp4ConfigError : public isc::Exception {
public:
......@@ -48,97 +48,12 @@ public:
: isc::Exception(file, line, what) {}
};
/// @brief Base abstract class for all DHCPv4 parsers
/// @brief Configure DHCPv4 server (@c Dhcpv4Srv) with a set of configuration values.
///
/// Each instance of a class derived from this class parses one specific config
/// element. Sometimes elements are simple (e.g. a string) and sometimes quite
/// complex (e.g. a subnet). In such case, it is likely that a parser will
/// spawn child parsers to parse child elements in the configuration.
/// @todo: Merge this class with DhcpConfigParser in src/bin/dhcp6
class Dhcp4ConfigParser {
///
/// \name Constructors and Destructor
///
/// Note: The copy constructor and the assignment operator are
/// intentionally defined as private to make it explicit that this is a
/// pure base class.
//@{
private:
// Private construtor and assignment operator assures that nobody
// will be able to copy or assign a parser. There are no defined
// bodies for them.
Dhcp4ConfigParser(const Dhcp4ConfigParser& source);
Dhcp4ConfigParser& operator=(const Dhcp4ConfigParser& source);
protected:
/// \brief The default constructor.
///
/// This is intentionally defined as \c protected as this base class should
/// never be instantiated (except as part of a derived class).
Dhcp4ConfigParser() {}
public:
/// The destructor.
virtual ~Dhcp4ConfigParser() {}
//@}
/// \brief Prepare configuration value.
///
/// This method parses the "value part" of the configuration identifier
/// that corresponds to this derived class and prepares a new value to
/// apply to the server.
///
/// This method must validate the given value both in terms of syntax
/// and semantics of the configuration, so that the server will be
/// validly configured at the time of \c commit(). Note: the given
/// configuration value is normally syntactically validated, but the
/// \c build() implementation must also expect invalid input. If it
/// detects an error it may throw an exception of a derived class
/// of \c isc::Exception.
///
/// Preparing a configuration value will often require resource
/// allocation. If it fails, it may throw a corresponding standard
/// exception.
///
/// This method is not expected to be called more than once in the
/// life of the object. 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;
/// \brief Apply the prepared configuration value to the server.
///
/// This method is expected to be exception free, and, as a consequence,
/// it should normally not involve resource allocation.
/// Typically it would simply perform exception free assignment or swap
/// operation on the value prepared in \c build().
/// In some cases, however, it may be very difficult to meet this
/// condition in a realistic way, while the failure case should really
/// be very rare. In such a case it may throw, and, if the parser is
/// called via \c configureDhcp4Server(), the caller will convert the
/// exception as a fatal error.
///
/// This method is expected to be called after \c build(), and only once.
/// The result is undefined otherwise.
virtual void commit() = 0;
};
/// @brief a pointer to configuration parser
typedef boost::shared_ptr<Dhcp4ConfigParser> ParserPtr;
/// @brief a collection of parsers
///
/// This container is used to store pointer to parsers for a given scope.
typedef std::vector<ParserPtr> ParserCollection;
/// \brief Configure DHCPv4 server (\c Dhcpv4Srv) with a set of configuration values.
///
/// This function parses configuration information stored in \c config_set
/// and configures the \c server by applying the configuration to it.
/// This function parses configuration information stored in @c config_set
/// and configures the @c server by applying the configuration to it.
/// It provides the strong exception guarantee as long as the underlying
/// derived class implementations of \c DhcpConfigParser meet the assumption,
/// derived class implementations of @c DhcpConfigParser meet the assumption,
/// that is, it ensures that either configuration is fully applied or the
/// state of the server is intact.
///
......@@ -162,6 +77,16 @@ isc::data::ConstElementPtr
configureDhcp4Server(Dhcpv4Srv&,
isc::data::ConstElementPtr config_set);
/// @brief Returns the global uint32_t values storage.
///
/// This function must be only used by unit tests that need
/// to access uint32_t global storage to verify that the
/// Uint32Parser works as expected.
///
/// @return a reference to a global uint32 values storage.
const std::map<std::string, uint32_t>& getUint32Defaults();
}; // end of isc::dhcp namespace
}; // end of isc namespace
......
......@@ -35,12 +35,6 @@ using namespace isc::asiolink;
using namespace isc::data;
using namespace isc::config;
namespace isc {
namespace dhcp {
extern Uint32Storage uint32_defaults;
}
}
namespace {
class Dhcp4ParserTest : public ::testing::Test {
......@@ -55,7 +49,9 @@ public:
// Checks if global parameter of name have expected_value
void checkGlobalUint32(string name, uint32_t expected_value) {
Uint32Storage::const_iterator it = uint32_defaults.find(name);
const std::map<std::string, uint32_t>& uint32_defaults = getUint32Defaults();
std::map<std::string, uint32_t>::const_iterator it =
uint32_defaults.find(name);
if (it == uint32_defaults.end()) {
ADD_FAILURE() << "Expected uint32 with name " << name
<< " not found";
......@@ -728,6 +724,8 @@ TEST_F(Dhcp4ParserTest, optionDataLowerCase) {
/// and properly err of out of range values. As we can't call Uint32Parser
/// directly, we are exploiting the fact that it is used to parse global
/// parameter renew-timer and the results are stored in uint32_defaults.
/// We get the uint32_defaults using a getUint32Defaults functions which
/// is defined only to access the values from this test.
TEST_F(Dhcp4ParserTest, DISABLED_Uint32Parser) {
ConstElementPtr status;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment