From 23833e2f16999d92018a5ae91c5f51a9d60dd553 Mon Sep 17 00:00:00 2001 From: Guilherme Maciel Ferreira Date: Wed, 31 Aug 2011 00:00:34 -0300 Subject: [PATCH] Split configuration responsability between different classes --- src/config/configurationreader.cpp | 432 ++---------------------------------- src/config/configurationreader.h | 70 +------ 2 files changed, 21 insertions(+), 481 deletions(-) diff --git a/src/config/configurationreader.cpp b/src/config/configurationreader.cpp index 9eee6fd..e709c97 100644 --- a/src/config/configurationreader.cpp +++ b/src/config/configurationreader.cpp @@ -19,15 +19,13 @@ on this file might be covered by the GNU General Public License. */ #include "config/configurationreader.h" -#include -#include -#include - #include -#include #include +#include "config/configurationcommandline.h" +#include "config/configurationfile.h" + using namespace std; using boost::program_options::command_line_parser; using boost::program_options::options_description; @@ -41,49 +39,17 @@ using I2n::Logger::GlobalLogger; // ConfigurationReader //----------------------------------------------------------------------------- +/** + * @brief Default constructor. + */ ConfigurationReader::ConfigurationReader() : - Config(), - HelpCmdStr( "help" ), - HelpCmdDesc( "Print this help and exit." ), - VersionCmdStr( "version" ), - VersionCmdDesc( "Print the version string and exit." ), - DaemonCmdStr( "daemon" ), - DaemonCmdDesc( "Run the evil in background." ), - DefaultConfigFileName( "/etc/pingcheck.conf" ), - ConfigFileCmdStr( "config-file" ), - ConfigFileCmdDesc( "Name of the configuration file." ), - SourceNetworkInterfaceCmdStr( "source-network-interface" ), - SourceNetworkInterfaceCmdDesc( "The network interface from where the packets will be received and originated" ), - DefaultNameServer( "127.0.0.1" ), - NameServerCmdStr( "nameserver" ), - NameServerCmdDesc( "The local address from where the DNS query will be made." ), - PingProtocolCmdStr( "ping-protocol" ), - PingProtocolCmdDesc( "Defines which protocol will be used to ping the destination." ), - DefaultHostsDownLimit( 0 ), // no host down - HostsDownLimitCmdStr( "hosts-down-limit" ), - HostsDownLimitCmdDesc( "Limit of host that have to be down in order to notify." ), - DefaultPingFailLimit( 50 ), // 50 pings can fail at most - PingFailLimitCmdStr( "ping-fail-limit" ), - PingFailLimitCmdDesc( "Maximum percentage of pings that can fail for a given host." ), - StatusNotifierCmdCmdStr( "status-notifier-cmd" ), - StatusNotifierCmdCmdDesc( "The command to execute to alert about host status." ), - DefaultLinkUpIntervalInMin( 5 ), // 5 minutes - LinkUpIntervalCmdStr( "link-up-interval" ), - LinkUpIntervalCmdDesc( "How long the link must be responsive in order to consider it stable." ), - DefaultLinkDownIntervalInMin( 2 ), // 2 minutes - LinkDownIntervalCmdStr( "link-down-interval" ), - LinkDownIntervalCmdDesc( "How long the link must be offline in order to consider it down." ), - HostNameCmdStr( "host.name" ), - HostNameCmdDesc( "Host address" ), - DefaultHostPort( 80 ), // HTTP port - HostPortCmdStr( "host.port" ), - HostPortCmdDesc( "Host port number" ), - DefaultHostIntervalInSec( 60 ), // 60 seconds - HostIntervalCmdStr( "host.interval" ), - HostIntervalCmdDesc( "Interval between each ping to the host" ) + Config() { } +/** + * @brief Destructor. + */ ConfigurationReader::~ConfigurationReader() { } @@ -94,7 +60,7 @@ ConfigurationReader::~ConfigurationReader() * @param argc the number of arguments in command line. * @param argv a vector containing the command line elements. * - * @return true if the parsing was successful, otherwise returns false. + * @return @c true if the parsing was successful, otherwise returns @c false. */ bool ConfigurationReader::parse( const int argc, @@ -105,30 +71,25 @@ bool ConfigurationReader::parse( BOOST_ASSERT( argv != NULL ); variables_map vm; - - bool command_line_processed = process_command_line( argc, argv, vm ); + ConfigurationCommandLine command_line( argc, argv ); + bool command_line_processed = command_line.process( &vm ); if ( command_line_processed ) { - parse_generic_options( vm ); - - bool terminate_app = halt_on_generic_options( vm ); + bool terminate_app = command_line.parse( vm, &Config ); if ( terminate_app ) { return false; } } - bool configuration_file_processed = process_configuration_file( vm ); + string file_name = Config.get_config_file_name(); + ConfigurationFile file( file_name ); + bool configuration_file_processed = file.process( &vm ); + file.parse( vm, &Config ); bool input_processed = command_line_processed && configuration_file_processed; - if ( input_processed ) - { - return parse_configuration_options( vm ); - } - else - { - return false; - } + + return input_processed; } /** @@ -138,356 +99,3 @@ Configuration ConfigurationReader::get_configuration() const { return Config; } - -/** - * @return which options must abort the application. Like the --version. - */ -bool ConfigurationReader::halt_on_generic_options( const variables_map &vm ) const -{ - bool is_help = ( vm.count( HelpCmdStr ) > 0 ); - bool is_version = ( vm.count( VersionCmdStr ) > 0 ); - bool terminate_app = is_help || is_version; - - return terminate_app; -} - -options_description ConfigurationReader::get_generic_options() const -{ - options_description options( "Generic options" ); - options.add_options() - ( HelpCmdStr.c_str(), HelpCmdDesc.c_str() ) - ( VersionCmdStr.c_str(), VersionCmdDesc.c_str() ) - ( DaemonCmdStr.c_str(), DaemonCmdDesc.c_str() ) - ( ConfigFileCmdStr.c_str(), value()->default_value( DefaultConfigFileName ), ConfigFileCmdDesc.c_str() ) - ; - - return options; -} - -bool ConfigurationReader::parse_generic_options( - const variables_map& vm -) -{ - // help - if ( vm.count( HelpCmdStr ) > 0) - { - options_description generic = get_generic_options(); - options_description config = get_configuration_options(); - - options_description visible_options( "Allowed options" ); - visible_options.add( generic ).add( config ); - - cout << visible_options << endl; - return true; - } - - // version - if ( vm.count( VersionCmdStr ) > 0 ) - { - cout << PROJECT_NAME << " version " << VERSION_STRING << endl; - return true; - } - - // daemon - bool have_daemon = ( vm.count( DaemonCmdStr ) > 0 ); - Config.set_daemon( have_daemon ); - GlobalLogger.info() << DaemonCmdStr << "=" - << have_daemon << endl; - - // config-file - if ( vm.count( ConfigFileCmdStr ) > 0 ) - { - string config_file_name = vm[ ConfigFileCmdStr ].as (); - Config.set_config_file_name( config_file_name ); - - GlobalLogger.info() << ConfigFileCmdStr << "=" - << config_file_name << endl; - } - - return false; -} - -options_description ConfigurationReader::get_configuration_options() const -{ - options_description options( "Configuration" ); - options.add_options() - ( SourceNetworkInterfaceCmdStr.c_str(), value(), SourceNetworkInterfaceCmdDesc.c_str() ) - ( NameServerCmdStr.c_str(), value()->default_value( DefaultNameServer ), NameServerCmdDesc.c_str() ) - ( PingProtocolCmdStr.c_str(), value(), PingProtocolCmdDesc.c_str() ) - ( HostsDownLimitCmdStr.c_str(), value()->default_value( DefaultHostsDownLimit ), HostsDownLimitCmdDesc.c_str() ) - ( PingFailLimitCmdStr.c_str(), value()->default_value( DefaultPingFailLimit ), PingFailLimitCmdDesc.c_str() ) - ( StatusNotifierCmdCmdStr.c_str(), value(), StatusNotifierCmdCmdDesc.c_str() ) - ( LinkUpIntervalCmdStr.c_str(), value()->default_value( DefaultLinkUpIntervalInMin ), LinkUpIntervalCmdDesc.c_str() ) - ( LinkDownIntervalCmdStr.c_str(), value()->default_value( DefaultLinkDownIntervalInMin ), LinkDownIntervalCmdDesc.c_str() ) - ( HostNameCmdStr.c_str(), value< vector >(), HostNameCmdDesc.c_str() ) - ( HostPortCmdStr.c_str(), value< vector >(), HostPortCmdDesc.c_str() ) - ( HostIntervalCmdStr.c_str(), value< vector >(), HostIntervalCmdDesc.c_str() ) - ; - - return options; -} - -bool ConfigurationReader::parse_configuration_options( const variables_map &vm ) -{ - // source-network-interface - if ( vm.count( SourceNetworkInterfaceCmdStr ) > 0 ) - { - string source_network_interface = - vm[ SourceNetworkInterfaceCmdStr ].as (); - Config.set_source_network_interface( source_network_interface ); - - GlobalLogger.info() << SourceNetworkInterfaceCmdStr << "=" - << source_network_interface << endl; - } - - // nameserver - if ( vm.count( NameServerCmdStr ) > 0 ) - { - string nameserver = vm[ NameServerCmdStr ].as (); - Config.set_nameserver( nameserver ); - - GlobalLogger.info() << NameServerCmdStr << "=" - << nameserver << endl; - } - - // ping-protocol - if ( vm.count( PingProtocolCmdStr ) > 0 ) - { - string protocol_string = vm[ PingProtocolCmdStr ].as (); - PingProtocol protocol = get_ping_protocol_from_string( protocol_string ); - Config.set_ping_protocol( protocol ); - - GlobalLogger.info() << PingProtocolCmdStr << "=" - << protocol_string << endl; - } - - // hosts-down-limit - int host_down_limit = 0; - if ( vm.count( HostsDownLimitCmdStr ) > 0 ) - { - host_down_limit = vm[ HostsDownLimitCmdStr ].as (); - Config.set_hosts_down_limit( host_down_limit ); - - GlobalLogger.info() << HostsDownLimitCmdStr << "=" - << host_down_limit << endl; - } - - // ping-fail-limit - if ( vm.count( PingFailLimitCmdStr ) > 0 ) - { - int ping_fail_limit = vm[ PingFailLimitCmdStr ].as (); - Config.set_ping_fail_limit( ping_fail_limit ); - - GlobalLogger.info() << PingFailLimitCmdStr << "=" - << ping_fail_limit << endl; - } - - // status-notifier-cmd - if ( vm.count( StatusNotifierCmdCmdStr ) > 0 ) - { - string status_notifier_cmd = vm[ StatusNotifierCmdCmdStr ].as(); - Config.set_status_notifier_cmd( status_notifier_cmd ); - - GlobalLogger.info() << StatusNotifierCmdCmdStr << "=" - << status_notifier_cmd << endl; - } - - // link-up-interval - if ( vm.count( LinkUpIntervalCmdStr ) > 0 ) - { - int link_up_interval_in_min = vm[ LinkUpIntervalCmdStr ].as(); - Config.set_link_up_interval_in_min( link_up_interval_in_min ); - - GlobalLogger.info() << LinkUpIntervalCmdStr << "=" - << link_up_interval_in_min << endl; - } - - // link-down-interval - if ( vm.count( LinkDownIntervalCmdStr ) > 0 ) - { - int link_down_interval_in_min = vm[ LinkDownIntervalCmdStr ].as(); - Config.set_link_down_interval_in_min( link_down_interval_in_min ); - - GlobalLogger.info() << LinkDownIntervalCmdStr << "=" - << link_down_interval_in_min << endl; - } - - // [host] name - size_t hosts_names_count = 0; - if ( vm.count( HostNameCmdStr ) > 0 ) - { - HostList hosts_list; - - vector hosts_names = vm[ HostNameCmdStr ].as< vector > (); - BOOST_FOREACH( string host_name, hosts_names ) - { - BOOST_ASSERT( !host_name.empty() ); - - HostItem host_item( new Host( host_name ) ); - hosts_list.push_back( host_item ); - - GlobalLogger.info() << HostNameCmdStr << "=" - << host_name << endl; - } - - Config.set_hosts( hosts_list ); - - hosts_names_count = hosts_names.size(); - - BOOST_ASSERT( hosts_names_count >= static_cast( host_down_limit ) ); - } - - // [host] port - size_t host_port_count = 0; - if ( vm.count( HostPortCmdStr ) > 0 ) - { - HostList hosts_list = Config.get_hosts(); - HostList::iterator hosts_it = hosts_list.begin(); - - vector hosts_ports = vm[ HostPortCmdStr ].as< vector >(); - BOOST_FOREACH( int host_port, hosts_ports ) - { - BOOST_ASSERT( ( 0 <= host_port ) && ( host_port <= numeric_limits::max() ) ); - - HostItem host_item = *hosts_it; - host_item->set_port( static_cast(host_port) ); - ++hosts_it; - - GlobalLogger.info() << HostPortCmdStr << "=" << host_port << endl; - } - - host_port_count = hosts_ports.size(); - } - - // [host] interval - size_t hosts_interval_count = 0; - if ( vm.count( HostIntervalCmdStr ) > 0 ) - { - HostList hosts_list = Config.get_hosts(); - HostList::iterator hosts_it = hosts_list.begin(); - - vector hosts_intervals = vm[ HostIntervalCmdStr ].as< vector >(); - BOOST_FOREACH( int host_interval_in_sec, hosts_intervals ) - { - BOOST_ASSERT( 0 < host_interval_in_sec ); - - HostItem host_item = *hosts_it; - host_item->set_interval_in_sec( host_interval_in_sec ); - ++hosts_it; - - GlobalLogger.info() << HostIntervalCmdStr << "=" - << host_interval_in_sec << endl; - } - - hosts_interval_count = hosts_intervals.size(); - } - - // make sure there is always an interval for each host - if ( hosts_names_count != hosts_interval_count ) - { - GlobalLogger.error() << "Could not parse configuration file." << - " Missing an interval entry for one of the hosts." << endl; - return false; - } - - BOOST_ASSERT( hosts_names_count == host_port_count ); - BOOST_ASSERT( hosts_names_count == hosts_interval_count ); - - return true; -} - -/** - * @brief Reads and parses the command line, storing the parsed tokens in the - * variables_map. - * - * @param argc the number of arguments in command line. - * @param argv a vector containing the command line elements. - * @param vm the variables_map object to store configuration tokens. - */ -bool ConfigurationReader::process_command_line( - const int argc, - char *argv[], - variables_map &vm -) -{ - try - { - options_description generic = get_generic_options(); - options_description config = get_configuration_options(); - - options_description cmdline_options; - cmdline_options.add( generic ).add( config ); - - positional_options_description p; - (void) p.add( HostNameCmdStr.c_str(), -1 ); - - parsed_options parsed_opt = command_line_parser( argc, argv ). - options( cmdline_options ). - positional( p ). - allow_unregistered(). - run(); - store( parsed_opt, vm ); - notify( vm ); - } - catch ( const std::exception &ex ) - { - GlobalLogger.error() << ex.what() << endl; - return false; - } - - return true; -} - -/** - * @brief Reads and parses the configuration file. The file name is retrieved - * from the variables_map object. - * - * @param vm the variables_map object to store configuration tokens. - */ -bool ConfigurationReader::process_configuration_file( variables_map &vm ) -{ - string config_file_name = ""; - // parse the command line options to retrieve the config file name, if the - // config-file option was not specified in the command line, it will return - // the default file - if ( parse_configuration_options( vm ) ) - { - config_file_name = Config.get_config_file_name(); - } - - return process_configuration_file( config_file_name, vm ); -} - -/** - * @brief Reads and parses the configuration file. - * - * @param config_file_name the configuration file name to be parsed. - * @param vm the variables_map object to store configuration tokens. - */ -bool ConfigurationReader::process_configuration_file( - const string &config_file_name, - variables_map &vm -) const -{ - BOOST_ASSERT( !config_file_name.empty() ); - - ifstream ifs( config_file_name.c_str() ); - if ( !ifs ) - { - GlobalLogger.error() << "Error: could not open " - << config_file_name << " file." << endl; - return false; - } - else - { - options_description config = get_configuration_options(); - options_description config_file_options; - config_file_options.add( config ); - - parsed_options parsed_opt = parse_config_file( ifs, config_file_options ); - store( parsed_opt, vm ); - notify( vm ); - } - - return true; -} diff --git a/src/config/configurationreader.h b/src/config/configurationreader.h index 3365ce6..74152ea 100644 --- a/src/config/configurationreader.h +++ b/src/config/configurationreader.h @@ -20,8 +20,6 @@ on this file might be covered by the GNU General Public License. #ifndef CONFIGURATIONREADER_H #define CONFIGURATIONREADER_H -#include - #include #include "config/configuration.h" @@ -46,74 +44,8 @@ public: Configuration get_configuration() const; private: - bool halt_on_generic_options( - const boost::program_options::variables_map &vm - ) const; - boost::program_options::options_description get_generic_options() const; - bool parse_generic_options( - const boost::program_options::variables_map &vm - ); - - boost::program_options::options_description get_configuration_options() const; - bool parse_configuration_options( - const boost::program_options::variables_map &vm - ); - - bool process_command_line( - const int argc, - char *argv[], - boost::program_options::variables_map &vm - ); - bool process_configuration_file( - boost::program_options::variables_map &vm - ); - bool process_configuration_file( - const std::string &config_file_name, - boost::program_options::variables_map &vm - ) const; - -private: Configuration Config; - const std::string HelpCmdStr; - const std::string HelpCmdDesc; - const std::string VersionCmdStr; - const std::string VersionCmdDesc; - const std::string DaemonCmdStr; - const std::string DaemonCmdDesc; - const std::string DefaultConfigFileName; - const std::string ConfigFileCmdStr; - const std::string ConfigFileCmdDesc; - const std::string SourceNetworkInterfaceCmdStr; - const std::string SourceNetworkInterfaceCmdDesc; - const std::string DefaultNameServer; - const std::string NameServerCmdStr; - const std::string NameServerCmdDesc; - const std::string PingProtocolCmdStr; - const std::string PingProtocolCmdDesc; - const int DefaultHostsDownLimit; - const std::string HostsDownLimitCmdStr; - const std::string HostsDownLimitCmdDesc; - const int DefaultPingFailLimit; - const std::string PingFailLimitCmdStr; - const std::string PingFailLimitCmdDesc; - const std::string StatusNotifierCmdCmdStr; - const std::string StatusNotifierCmdCmdDesc; - const int DefaultLinkUpIntervalInMin; - const std::string LinkUpIntervalCmdStr; - const std::string LinkUpIntervalCmdDesc; - const int DefaultLinkDownIntervalInMin; - const std::string LinkDownIntervalCmdStr; - const std::string LinkDownIntervalCmdDesc; - const std::string HostNameCmdStr; - const std::string HostNameCmdDesc; - const int DefaultHostPort; - const std::string HostPortCmdStr; - const std::string HostPortCmdDesc; - const int DefaultHostIntervalInSec; - const std::string HostIntervalCmdStr; - const std::string HostIntervalCmdDesc; - }; -#endif /* CONFIGURATIONREADER_H */ +#endif // CONFIGURATIONREADER_H -- 1.7.1