From b279ae0950da1f8eb1dd7375433ba2855541b65b Mon Sep 17 00:00:00 2001 From: Guilherme Maciel Ferreira Date: Wed, 23 Mar 2011 17:11:04 +0100 Subject: [PATCH] Added the requirement "If XX servers don't reply, it has to notify another system (e.g. execute a script)" - moved the class PingStatusNotifier from ping to notify directory. - included a new class that encapsulate the process of system notification --- src/CMakeLists.txt | 3 +- src/main.cpp | 2 +- src/notify/pingstatusnotifier.cpp | 100 ++++++++++++++++++++++++++++++++++ src/notify/pingstatusnotifier.h | 46 ++++++++++++++++ src/notify/statusnotifiercommand.cpp | 99 +++++++++++++++++++++++++++++++++ src/notify/statusnotifiercommand.h | 39 +++++++++++++ src/ping/pinganalyzer.cpp | 2 +- src/ping/pingscheduler.cpp | 2 +- src/ping/pingstatusnotifier.cpp | 83 ---------------------------- src/ping/pingstatusnotifier.h | 40 -------------- 10 files changed, 289 insertions(+), 127 deletions(-) create mode 100644 src/notify/pingstatusnotifier.cpp create mode 100644 src/notify/pingstatusnotifier.h create mode 100644 src/notify/statusnotifiercommand.cpp create mode 100644 src/notify/statusnotifiercommand.h delete mode 100644 src/ping/pingstatusnotifier.cpp delete mode 100644 src/ping/pingstatusnotifier.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index aadb2a3..1701940 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -27,10 +27,11 @@ set(SOURCES icmp/icmpheader.cpp icmp/icmppacket.cpp icmp/ipv4header.cpp + notify/pingstatusnotifier.cpp + notify/statusnotifiercommand.cpp ping/boostpinger.cpp ping/pinganalyzer.cpp ping/pingscheduler.cpp - ping/pingstatusnotifier.cpp main.cpp ) diff --git a/src/main.cpp b/src/main.cpp index 3e128ec..e8256d5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,8 +6,8 @@ #include "config/configurationreader.h" #include "config/host.h" +#include "notify/pingstatusnotifier.h" #include "ping/pingscheduler.h" -#include "ping/pingstatusnotifier.h" using namespace std; using namespace boost; diff --git a/src/notify/pingstatusnotifier.cpp b/src/notify/pingstatusnotifier.cpp new file mode 100644 index 0000000..d0dcc20 --- /dev/null +++ b/src/notify/pingstatusnotifier.cpp @@ -0,0 +1,100 @@ +#include "notify/pingstatusnotifier.h" + +#include + +#include + +using namespace std; + +//----------------------------------------------------------------------------- +// PingStatusNotifier +//----------------------------------------------------------------------------- + +PingStatusNotifier::PingStatusNotifier( + const int limit_hosts_down, + const string &status_notifier_cmd +) : + LimitHostsDown( limit_hosts_down ), + StatusNotifierCmd( status_notifier_cmd ), + HostsDownList() +{ + BOOST_ASSERT( 0 <= limit_hosts_down ); + BOOST_ASSERT( !status_notifier_cmd.empty() ); +} + +PingStatusNotifier::~PingStatusNotifier() +{ +} + +void PingStatusNotifier::notify_host_up( const string &host_address ) +{ + BOOST_ASSERT( !host_address.empty() ); + + cout << "- Link up: " << host_address << endl; // TODO + + add_host_up( host_address ); + + if ( !exceeded_host_down_count_limit() ) + { + notify_system_up(); + } + + // removed from the list? + BOOST_ASSERT( HostsDownList.count( host_address ) == 0 ); +} + +void PingStatusNotifier::notify_host_down( const string &host_address ) +{ + BOOST_ASSERT( !host_address.empty() ); + + cout << "- Link down: " << host_address << endl; // TODO + + add_host_down( host_address ); + + if ( exceeded_host_down_count_limit() ) + { + notify_system_down(); + } + + // inserted in the list? + BOOST_ASSERT( HostsDownList.count( host_address ) == 1 ); +} + +void PingStatusNotifier::add_host_up( const string &host_address ) +{ + if ( HostsDownList.count( host_address ) > 0 ) + { + HostsDownList.erase( host_address ); + } +} + +void PingStatusNotifier::add_host_down( const string &host_address ) +{ + HostsDownList.insert( host_address ); +} + +bool PingStatusNotifier::exceeded_host_down_count_limit() const +{ + int host_down_count = HostsDownList.size(); + return ( host_down_count >= LimitHostsDown ); +} + +void PingStatusNotifier::notify_system_up() +{ + StatusNotifierCmd.set_token_value( + StatusNotifierCommand::StatusToken, + "up" + ); + + StatusNotifierCmd.execute(); +} + +void PingStatusNotifier::notify_system_down() +{ + StatusNotifierCmd.set_token_value( + StatusNotifierCommand::StatusToken, + "down" + ); + + StatusNotifierCmd.execute(); +} diff --git a/src/notify/pingstatusnotifier.h b/src/notify/pingstatusnotifier.h new file mode 100644 index 0000000..7aca573 --- /dev/null +++ b/src/notify/pingstatusnotifier.h @@ -0,0 +1,46 @@ +#ifndef PINGSTATUSNOTIFIER_H +#define PINGSTATUSNOTIFIER_H + +#include +#include + +#include "notify/statusnotifiercommand.h" + +//----------------------------------------------------------------------------- +// PingStatusNotifier +//----------------------------------------------------------------------------- + +/** + * @brief This class is responsible for notify when the system is down, by + * keeping track of the number of hosts down. + * Scope: one object for many hosts. + */ +class PingStatusNotifier +{ +public: + PingStatusNotifier( + const int limit_hosts_down, + const std::string &status_notifier_cmd + ); + virtual ~PingStatusNotifier(); + + void notify_host_up( const std::string &host_address ); + void notify_host_down( const std::string &host_address ); + +private: + void add_host_up( const std::string &host_address ); + void add_host_down( const std::string &host_address ); + + bool exceeded_host_down_count_limit() const; + + void notify_system_up(); + void notify_system_down(); + +private: + const int LimitHostsDown; + StatusNotifierCommand StatusNotifierCmd; + std::set HostsDownList; + +}; + +#endif /* PINGSTATUSNOTIFIER_H */ diff --git a/src/notify/statusnotifiercommand.cpp b/src/notify/statusnotifiercommand.cpp new file mode 100644 index 0000000..bd4a75d --- /dev/null +++ b/src/notify/statusnotifiercommand.cpp @@ -0,0 +1,99 @@ +#include "notify/statusnotifiercommand.h" + +#include + +#include + +#include + +#include + +using namespace std; + +//----------------------------------------------------------------------------- +// StatusNotifierCommand +//----------------------------------------------------------------------------- + +const string StatusNotifierCommand::StatusToken = "${status}"; + +//----------------------------------------------------------------------------- + +StatusNotifierCommand::StatusNotifierCommand( + const string &status_notifier_cmd +) : + CommandStr( status_notifier_cmd ) +{ +} + +StatusNotifierCommand::~StatusNotifierCommand() +{ +} + +bool StatusNotifierCommand::set_token_value( + const string &token, + const string &value +) +{ + BOOST_ASSERT( !token.empty() ); + BOOST_ASSERT( !value.empty() ); + BOOST_ASSERT( !CommandStr.empty() ); + + size_t token_begin_pos = CommandStr.find( token ); + if ( token_begin_pos == string::npos ) + { + return false; // token string not found! + } + + const size_t token_size = token.length(); + CommandStr.replace( token_begin_pos, token_size, value ); + + // assert the token is no longer within the command string + BOOST_ASSERT( CommandStr.find( token ) == string::npos ); + + return true; +} + +bool StatusNotifierCommand::execute() +{ + BOOST_ASSERT( !CommandStr.empty() ); + + string app = get_application_string(); + string args = get_arguments_string(); + string secure_command = app + " " + args; + + cout << "- Command: " << secure_command << endl; // TODO + + int ret = system( secure_command.c_str() ); + if ( ret != 0 ) + return false; + + return true; +} + +string StatusNotifierCommand::get_application_string() const +{ + // retrieve the application name from within the command string + const size_t app_begin_pos = 0; + size_t app_end_pos = CommandStr.find( " " ); + if ( app_end_pos == string::npos ) + { + app_end_pos = CommandStr.find( "\n" ); + if ( app_end_pos == string::npos ) + { + return false; + } + } + + return CommandStr.substr( app_begin_pos, app_end_pos );; +} + +string StatusNotifierCommand::get_arguments_string() const +{ + // retrieve the arguments string from within the command string + const size_t args_begin_pos = CommandStr.find( " " ) + 1; + const size_t args_end_pos = CommandStr.length(); + string args = CommandStr.substr( args_begin_pos, args_end_pos ); + args = escape_shellarg( args ); + + return args; +} diff --git a/src/notify/statusnotifiercommand.h b/src/notify/statusnotifiercommand.h new file mode 100644 index 0000000..11c2f37 --- /dev/null +++ b/src/notify/statusnotifiercommand.h @@ -0,0 +1,39 @@ +#ifndef STATUSNOTIFIERCOMMAND_H +#define STATUSNOTIFIERCOMMAND_H + +#include + +//----------------------------------------------------------------------------- +// StatusNotifierCommand +//----------------------------------------------------------------------------- + +/** + * @brief This class provides methods to handle status-notifier-cmd + * configuration. + */ +class StatusNotifierCommand +{ +public: + static const std::string StatusToken; + +public: + explicit StatusNotifierCommand( const std::string &status_notifier_cmd ); + virtual ~StatusNotifierCommand(); + + bool set_token_value( + const std::string &token, + const std::string &value + ); + + bool execute(); + +private: + std::string get_application_string() const; + std::string get_arguments_string() const; + +private: + std::string CommandStr; + +}; + +#endif /* STATUSNOTIFIERCOMMAND_H */ diff --git a/src/ping/pinganalyzer.cpp b/src/ping/pinganalyzer.cpp index 6a0e510..d4af2da 100644 --- a/src/ping/pinganalyzer.cpp +++ b/src/ping/pinganalyzer.cpp @@ -4,7 +4,7 @@ #include -#include "ping/pingstatusnotifier.h" +#include "notify/pingstatusnotifier.h" using namespace std; using namespace boost; diff --git a/src/ping/pingscheduler.cpp b/src/ping/pingscheduler.cpp index 34ee5dd..5d020d6 100644 --- a/src/ping/pingscheduler.cpp +++ b/src/ping/pingscheduler.cpp @@ -5,8 +5,8 @@ #include #include "dns/dnsresolver.h" +#include "notify/pingstatusnotifier.h" #include "ping/boostpinger.h" -#include "ping/pingstatusnotifier.h" using namespace std; using namespace boost; diff --git a/src/ping/pingstatusnotifier.cpp b/src/ping/pingstatusnotifier.cpp deleted file mode 100644 index b4e49c7..0000000 --- a/src/ping/pingstatusnotifier.cpp +++ /dev/null @@ -1,83 +0,0 @@ -#include "ping/pingstatusnotifier.h" - -#include - -#include - -using namespace std; - -//----------------------------------------------------------------------------- -// PingStatusNotifier -//----------------------------------------------------------------------------- - -PingStatusNotifier::PingStatusNotifier( - const int limit_hosts_down, - const std::string &status_notifier_cmd -) : - LimitHostsDown( limit_hosts_down ), - StatusNotifierCmd( status_notifier_cmd ), - HostsDownList() -{ - BOOST_ASSERT( 0 <= limit_hosts_down ); - BOOST_ASSERT( !status_notifier_cmd.empty() ); -} - -PingStatusNotifier::~PingStatusNotifier() -{ -} - -void PingStatusNotifier::notify_host_up( const string &host_address ) -{ - BOOST_ASSERT( !host_address.empty() ); - - cerr << "- " << host_address << " - LINK IS UP /\\ " << endl; // TODO - - add_host_up( host_address ); - - if ( !exceeded_host_down_count_limit() ) - { - // alert the system is up - cerr << "SYSTEM IS UP /\\" << endl; - // execute the script - } - - BOOST_ASSERT( HostsDownList.count( host_address ) == 0 ); -} - -void PingStatusNotifier::notify_host_down( const string &host_address ) -{ - BOOST_ASSERT( !host_address.empty() ); - - cerr << "- " << host_address << " - LINK IS DOWN \\/" << endl; // TODO - - add_host_down( host_address ); - - if ( exceeded_host_down_count_limit() ) - { - // alert the system is down. - cerr << "****** DANGER WILL ROBINSON! THE SYSTEM IS DOWN \\/ *******" - << endl; // TODO - // execute the script - } - - BOOST_ASSERT( HostsDownList.count( host_address ) == 1 ); -} - -void PingStatusNotifier::add_host_up( const string &host_address ) -{ - if ( HostsDownList.count( host_address ) > 0 ) - { - HostsDownList.erase( host_address ); - } -} - -void PingStatusNotifier::add_host_down( const string &host_address ) -{ - HostsDownList.insert( host_address ); -} - -bool PingStatusNotifier::exceeded_host_down_count_limit() const -{ - int host_down_count = HostsDownList.size(); - return ( host_down_count >= LimitHostsDown ); -} diff --git a/src/ping/pingstatusnotifier.h b/src/ping/pingstatusnotifier.h deleted file mode 100644 index 45e5e4f..0000000 --- a/src/ping/pingstatusnotifier.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef PINGSTATUSNOTIFIER_H -#define PINGSTATUSNOTIFIER_H - -#include -#include - -//----------------------------------------------------------------------------- -// PingStatusNotifier -//----------------------------------------------------------------------------- - -/** - * @brief This class is responsible for notify when a host is down or up. And - * to keep track of which hosts are down. - * Scope: one object for many hosts. - */ -class PingStatusNotifier -{ -public: - PingStatusNotifier( - const int limit_hosts_down, - const std::string &status_notifier_cmd - ); - virtual ~PingStatusNotifier(); - - void notify_host_up( const std::string &host_address ); - void notify_host_down( const std::string &host_address ); - -private: - void add_host_up( const std::string &host_address ); - void add_host_down( const std::string &host_address ); - bool exceeded_host_down_count_limit() const; - -private: - int LimitHostsDown; - std::string StatusNotifierCmd; - std::set HostsDownList; - -}; - -#endif /* PINGSTATUSNOTIFIER_H */ -- 1.7.1