Split configuration responsability between different classes
authorGuilherme Maciel Ferreira <guilherme.maciel.ferreira@gmail.com>
Wed, 31 Aug 2011 03:00:34 +0000 (00:00 -0300)
committerGuilherme Maciel Ferreira <guilherme.maciel.ferreira@gmail.com>
Wed, 31 Aug 2011 03:00:34 +0000 (00:00 -0300)
src/config/configurationreader.cpp
src/config/configurationreader.h

index 9eee6fd..e709c97 100644 (file)
@@ -19,15 +19,13 @@ on this file might be covered by the GNU General Public License.
 */
 #include "config/configurationreader.h"
 
-#include <fstream>
-#include <iostream>
-#include <limits>
-
 #include <boost/assert.hpp>
-#include <boost/foreach.hpp>
 
 #include <logfunc.hpp>
 
+#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<string>()->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<string> ();
-        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<string>(), SourceNetworkInterfaceCmdDesc.c_str() )
-        ( NameServerCmdStr.c_str(), value<string>()->default_value( DefaultNameServer ), NameServerCmdDesc.c_str() )
-        ( PingProtocolCmdStr.c_str(), value<string>(), PingProtocolCmdDesc.c_str() )
-        ( HostsDownLimitCmdStr.c_str(), value<int>()->default_value( DefaultHostsDownLimit ), HostsDownLimitCmdDesc.c_str() )
-        ( PingFailLimitCmdStr.c_str(), value<int>()->default_value( DefaultPingFailLimit ), PingFailLimitCmdDesc.c_str() )
-        ( StatusNotifierCmdCmdStr.c_str(), value<string>(), StatusNotifierCmdCmdDesc.c_str() )
-        ( LinkUpIntervalCmdStr.c_str(), value<int>()->default_value( DefaultLinkUpIntervalInMin ), LinkUpIntervalCmdDesc.c_str() )
-        ( LinkDownIntervalCmdStr.c_str(), value<int>()->default_value( DefaultLinkDownIntervalInMin ), LinkDownIntervalCmdDesc.c_str() )
-        ( HostNameCmdStr.c_str(), value< vector<string> >(), HostNameCmdDesc.c_str() )
-        ( HostPortCmdStr.c_str(), value< vector<int> >(), HostPortCmdDesc.c_str() )
-        ( HostIntervalCmdStr.c_str(), value< vector<int> >(), 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<string> ();
-        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<string> ();
-        Config.set_nameserver( nameserver );
-
-        GlobalLogger.info() << NameServerCmdStr << "="
-                << nameserver << endl;
-    }
-
-    // ping-protocol
-    if ( vm.count( PingProtocolCmdStr ) > 0 )
-    {
-        string protocol_string = vm[ PingProtocolCmdStr ].as<string> ();
-        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<int> ();
-        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<int> ();
-        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<string>();
-        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<int>();
-        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<int>();
-        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<string> hosts_names = vm[ HostNameCmdStr ].as< vector<string> > ();
-        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<size_t>( 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<int> hosts_ports = vm[ HostPortCmdStr ].as< vector<int> >();
-        BOOST_FOREACH( int host_port, hosts_ports )
-        {
-            BOOST_ASSERT( ( 0 <= host_port ) && ( host_port <= numeric_limits<uint16_t>::max() ) );
-
-            HostItem host_item = *hosts_it;
-            host_item->set_port( static_cast<uint16_t>(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<int> hosts_intervals = vm[ HostIntervalCmdStr ].as< vector<int> >();
-        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;
-}
index 3365ce6..74152ea 100644 (file)
@@ -20,8 +20,6 @@ on this file might be covered by the GNU General Public License.
 #ifndef CONFIGURATIONREADER_H
 #define CONFIGURATIONREADER_H
 
-#include <string>
-
 #include <boost/program_options.hpp>
 
 #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