1 // -*- C++ -*-
// -----------------------------------------------------------------------------
/*
* Osmius and its code is copyright of Peopleware S.L. Spain.
* http://www.peopleware.es
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* ( at your option ) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
// -----------------------------------------------------------------------------
/**
* @file osm_ag_insmanager.cpp
* @brief Implementation file for instance and event manager for every agent.
* Osmius - Peopleware.
*
* @author Jose Luis Marina <joseluis.marina@peopleware.es>
* @date 01-APR-2006.
*
*/
// -----------------------------------------------------------------------------
#include "osm_ag_insmanager.h"
#include "../cm/osm_cfgmanager.h"
//#include <ace/Log_Msg.h>
#if defined ( ACE_WIN32 )
#include <ace/OS.h>
#endif /* ( ACE_WIN32 ) */
// Specific module includes.
#include <ace/Get_Opt.h>
#include <ace/ARGV.h>
//#include <ace/Recursive_Thread_Mutex.h>
// -----------------------------------------------------------------------------
// Forwarded declaration CREATE_OSMIUS_INSTANCE
// -----------------------------------------------------------------------------
/**
* This funtion is used to create the appropiate instance type.
* @param instance_name Input - Instance Name.
* @param instance_type Input - Type of the instance - to be checked.
* @param conn_info Input - If needed is a string used in the connect( ) method.
* @param instance Output - This funtion will make a new over this pointer.
* @retval -1 in case of error. 0 for success.
*/
60 extern int CREATE_OSMIUS_INSTANCE( const ACE_TCHAR* instance_name,
const ACE_TCHAR* instance_type,
const ACE_TCHAR* conn_info ,
OSM_Instance_Base* &instance );
// -----------------------------------------------------------------------------
// Forwarded declaration CREATE_OSMIUS_EVENT
// -----------------------------------------------------------------------------
/**
* This funtion is used to create the appropiate events and associated actions.
* @param event_name Input - Name checked.
* @param instance_type Input - Type of the instance - to be checked.
* @param event_parameters Input - Parameters read from the config file.
* @param seconds Input - Seconds to be called.
* @param event Output - This funtion will make a new over this pointer.
* @retval -1 in case of error. 0 for success.
*/
77 extern int CREATE_OSMIUS_EVENT ( const ACE_TCHAR* event_name ,
const ACE_TCHAR* instance_type ,
const ACE_TCHAR* event_parameters,
int seconds ,
OSM_Event* &event );
/*----------------------------------------------------------------------------*/
/* OSM_Action_Base Implementation */
/*----------------------------------------------------------------------------*/
// OSM_Action_Base is an abstract class.
// User ( programmer ) must implement execute( ) and check_cmd_line( ).
/*----------------------------------------------------------------------------*/
/* OSM_Event Implementation */
/*----------------------------------------------------------------------------*/
int
94 OSM_Event::handle_timeout ( const ACE_Time_Value &tv, const void * )
{
//if ( OSM_CfgManager::instance( )->debug_mode( ) )
//{
// ACE_DEBUG( ( LM_DEBUG,
// ACE_TEXT( "( %P|%T ) OSM_Event: %s.%s.handle_timeout( %d )\n" ),
// this->osm_instance_->idn_instance( ), this->typ_event_, this->interval_ ) );
//}
ACE_Time_Value time_before = ACE_OS::gettimeofday( );
ACE_TCHAR aux_text[BUFSIZ+1]="" ;
int value=0 ;
OSM_Message* osmius_message=0 ;
ACE_OS::last_error( 0 );
// If something goes bad we must free this memory. Otherwise the msg_manager
// must do it we it finish sending the message.
ACE_NEW_NORETURN ( osmius_message, OSM_Message );
if ( 0 != ACE_OS::last_error( ) )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT(
"OSM_Event: handle_timeout( ) Could not create new message. [%d]\n" ),
ACE_OS::last_error( ) ) );
return -1;
}
// ---------------------------------------------------------------------------
// Form the new message field by field.
// ---------------------------------------------------------------------------
// -> TYP_MESSAGE
osmius_message->typ_alarm( OSM_TYP_ALARM_INFO );
/// Typ_Agent is now the same as TYP_INSTANCE
osmius_message->typ_agent ( this->osm_instance_->typ_instance( ), ACE_OS::strlen( this->osm_instance_->typ_instance( ) ) );
// -> COD_MASTER
if ( -1 == OSM_CfgManager::instance( )->get_value_str( "CODMST", aux_text, BUFSIZ ) )
{
ACE_ERROR_RETURN( ( LM_ERROR,
ACE_TEXT( "OSM_AG_Main: handle_timeout( ) Could not get CODMST\n" ) ),
-1 );
}
osmius_message->idn_master ( aux_text, ACE_OS::strlen( aux_text ) );
// -> COD_INSTANCE
osmius_message->idn_instance ( this->osm_instance_->idn_instance( ), ACE_OS::strlen( this->osm_instance_->idn_instance( ) ) );
// -> TYP_INSTANCE
osmius_message->typ_instance ( this->osm_instance_->typ_instance( ), ACE_OS::strlen( this->osm_instance_->typ_instance( ) ) );
// -> COD_MESSAGE
osmius_message->typ_event ( this->typ_event_, ACE_OS::strlen( this->typ_event_ ) );
// -> DAT_INIEVENT
osmius_message->dti_inievent ( time_before );
// -> VAL_MESSAGE
osmius_message->num_value ( "", 0 );
// -> VAL_TXT
osmius_message->txt_message ( "NULL", 0 );
ACE_Time_Value time_after;
if ( 0 == this->action_ )
{
ACE_ERROR( ( LM_ERROR, ACE_TEXT( "OSM_Event: Action NOT DEFINED: %s [%s]\n" ),
this->typ_event_,
this->osm_instance_->idn_instance( ) ) );
delete osmius_message;
return -1;
}
ACE_TCHAR event_text[OSM_MSG_MAXTXTLEN]="";
ACE_TCHAR val_text[OSM_MSG_MAXTXTLEN]="";
int val_len=OSM_MSG_MAXTXTLEN-1;
char user_text[OSM_MSG_MAXLENGTH]="-";
if ( -1 == this->osm_instance_->connect( ) )
{
value = -1;
time_after = ACE_OS::gettimeofday( );
osmius_message->dti_finevent( time_after );
osmius_message->typ_alarm ( OSM_TYP_ALARM_ERRO );
const ACE_TCHAR failed[]="NO_CONNECT - Connection Failed";
osmius_message->txt_message ( ACE_TEXT( failed ), sizeof( ACE_TEXT( failed ) ) );
ACE_OS::sprintf( aux_text, "%d", value );
osmius_message->num_value ( aux_text, ACE_OS::strlen( aux_text ) );
}
else
{
int res=0;
int recover = 0;
if ( -1 == this->action_->execute( this->cmd_line_ ,
ACE_OS::strlen( this->cmd_line_ ) ,
this->timeout_ ,
val_text ,
val_len ,
value ) )
{
res = -1;
OSM_CfgManager::instance( )->get_value_int( "RECVRY", &recover );
if ( recover ) // Try to execute once again.
{
osm_instance_->disconnect( 1 );
res = osm_instance_->connect( );
if ( -1 != res )
{
val_text[0]='\0';
res = this->action_->execute( this->cmd_line_ ,
ACE_OS::strlen( this->cmd_line_ ),
this->timeout_ ,
val_text ,
val_len ,
value );
}
}
}
if ( -1 == res )
{
ACE_ERROR( ( LM_ERROR, ACE_TEXT( "OSM_Event: execute action failed: %s [%s] Instance=[%s]\n" ),
this->cmd_line_,
val_text,
this->osm_instance_->idn_instance( ) ) );
time_after = ACE_OS::gettimeofday( );
osmius_message->dti_finevent( time_after );
if ( this->is_code( "AVAILABL" ) )
{
osmius_message->typ_alarm ( OSM_TYP_ALARM_CRIT );
}
else
{
osmius_message->typ_alarm ( OSM_TYP_ALARM_ERRO );
}
osmius_message->txt_message ( ACE_TEXT( val_text ), val_len );
ACE_OS::sprintf( aux_text, "%d", value );
osmius_message->num_value ( aux_text, ACE_OS::strlen( aux_text ) );
osm_instance_->disconnect( 1 ); // Force disconnection and free resources.
}
else
{
ACE_Time_Value time_after = ACE_OS::gettimeofday( );
time_after = ACE_OS::gettimeofday( );
osmius_message->dti_finevent( time_after );
event_text[0] = '\0';
ACE_OS::sprintf( aux_text, "%d", value );
osmius_message->num_value ( aux_text, ACE_OS::strlen( aux_text ) );
OSM_CfgManager::instance( )->get_param ( ( const ACE_TCHAR* ) this->action( )->ev_parameters( ), 'T', user_text, OSM_MSG_MAXLENGTH -10 );
if ( ACE_OS::strlen( user_text ) )
{
ACE_OS::sprintf( event_text, "%s[%d] %s ( w:%d a:%d s:%d t:%d )", user_text, value, val_text, this->warn_limit_, this->crit_limit_, this->silent_mode_, this->interval_ );
}
else
{
ACE_OS::sprintf( event_text, "%s:[%d] %s ( w:%d a:%d s:%d t:%d )", this->action( )->name( ), value, val_text, this->warn_limit_, this->crit_limit_, this->silent_mode_, this->interval_ );
}
osmius_message->txt_message ( event_text, ACE_OS::strlen( ACE_TEXT( event_text ) ) );
}
}
this->last_value_ = value;
//Try to disconnect
if ( -1 == this->osm_instance_->disconnect( ) )
{
ACE_ERROR( ( LM_ERROR, ACE_TEXT( "OSM_Event: DISCONNECTION FAILED\n" ) ) );
}
// --------------------------------------------------------------------
// Get the event criticity.
// --------------------------------------------------------------------
int cmp=1;
int cri=OSM_TYP_ALARM_ERRO;
if ( OSM_TYP_ALARM_ERRO != ACE_OS::atoi( osmius_message->typ_alarm( ) ) )
{
cri=OSM_TYP_ALARM_INFO;
if ( -1 != this->compare_mode_ ) // We have limits to check.
{
if ( OSM_COMPARE_GREATER == this->compare_mode_ )
{
cmp =1;
}
else
{
cmp =-1;
}
if ( cmp*this->crit_limit_ <= cmp*value )
{
cri = OSM_TYP_ALARM_CRIT;
}
else
{
if ( cmp*this->warn_limit_ <= cmp*value )
{
cri = OSM_TYP_ALARM_WARN;
}
}
}
}
osmius_message->typ_alarm( cri );
if ( ( this->silent_mode_ ) && ( cri == this->last_alarm_type_ ) ) //Last time we were also critical or warning or info or error
{
delete osmius_message;
return 0;
}
this->last_alarm_type_ = cri;
// Prepare the message to be sent.
osmius_message->encode( );
// Only for debugging.
// osmius_message->print( );
// Wrap the OSM_Message into ACE_Message_Block
ACE_Message_Block* mblk=0;
ACE_NEW_NORETURN( mblk, ACE_Message_Block( ( char* )osmius_message, sizeof( osmius_message ) ) );
// This is important!!
// We must set the write pointer to the end of data so length( ) could return
// the correct value.
mblk->wr_ptr( sizeof( OSM_MessageHeader )
+ ACE_OS::strlen( osmius_message->net_message_.data_ ) );
// The message manager is now the responsible for the message.
// The pointer to the instance manager is in our osm_instance owner.
if ( -1==this->osm_instance_->ins_manager( )->put( mblk, 0 ) )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "OSM_Event: Could not put Message into Ins_Manager\n" ) ) );
delete osmius_message;
delete mblk;
}
return 0;
};
/*----------------------------------------------------------------------------*/
int
332 OSM_Event::open( const ACE_TCHAR* name , OSM_Instance_Base* instance ,
const int interval ,
const int i_delay ,
const int timeout ,
const int mode ,
const int warn ,
const int alar ,
const int silent ,
340 const ACE_TCHAR* ev_params )
{
if ( OSM_CfgManager::instance( )->debug_mode( ) )
{
ACE_DEBUG( ( LM_DEBUG,
ACE_TEXT( "( %P|%T ) OSM_Event: open( ) Instance:[%s] - Event [%s]\n" ),
instance->idn_instance( ), name ) );
}
this->last_alarm_type_ = -1;
ACE_OS::strncpy( this->typ_event_, name, OSM_Message::CODLEN );
this->typ_event_[OSM_Message::CODLEN]=0;
this->osm_instance_ = instance;
if ( interval > 0 )
this->interval_ = interval;
else
this->interval_ = 1;
if ( i_delay > 0 )
this->initial_delay_ = i_delay;
else
this->initial_delay_ = 1;
if ( timeout < 0 )
this->timeout_=0;
else
this->timeout_=timeout;
if ( 0 != ev_params )
this->action_->ev_parameters( ev_params );
this->compare_mode_ = mode;
this->warn_limit_ = warn;
this->crit_limit_ = alar;
this->warn_limit_ = warn;
this->silent_mode_ = silent;
// Register ourselves with the Reactor.
ACE_Time_Value tv_interval( this->interval_ );
ACE_Time_Value tv_delay( this->initial_delay_ );
if ( -1 == ( this->timer_id_ =
this->reactor( )->schedule_timer( this, 0, tv_delay, tv_interval ) ) )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "OSM_Event: open( ) Could not schedule timer: %s\n" ),
name ) );
return -1;
}
this->action( )->set_name( name );
return 0;
}
/*----------------------------------------------------------------------------*/
int
394 OSM_Event::close( void )
{
if ( OSM_CfgManager::instance( )->debug_mode( ) )
{
ACE_DEBUG( ( LM_DEBUG,
ACE_TEXT( "( %P|%T ) OSM_Event: close( ) Instance:[%s] - Event [%s]\n" ),
this->osm_instance_->idn_instance( ), this->typ_event_ ) );
}
// Third param -> Dont_Call_Handle_Close
if ( -1 == this->reactor( )->cancel_timer( this->timer_id_, 0, 0 ) )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "OSM_Event: close( ) Could not cancel timer: %d\n" ),
this->timer_id_ ) );
}
delete this->action_;
this->action_=0;
return 0;
}
/*----------------------------------------------------------------------------*/
/* OSM_AG_InsManager Implementation */
/*----------------------------------------------------------------------------*/
// Static initialization.
OSM_AG_InsManager *OSM_AG_InsManager::instance_ = 0;
/*----------------------------------------------------------------------------*/
423 OSM_AG_InsManager* OSM_AG_InsManager::instance ( void )
{
if ( 0 == OSM_AG_InsManager::instance_ )
ACE_NEW_RETURN ( OSM_AG_InsManager::instance_, OSM_AG_InsManager( OSM_AG_MsgManager::instance( ) ), 0 );
return OSM_AG_InsManager::instance_;
}
/*----------------------------------------------------------------------------*/
int
432 OSM_AG_InsManager::create_instances( void )
{
const ACE_TCHAR ins_section[]="OSMIUS_INSTANCES";
ACE_OS::last_error( 0 );
ACE_Ini_ImpExp import_cfg( this->cfg_ );
if ( import_cfg.import_config( ACE_TEXT( this->config_file_ ) ) )
{
ACE_ERROR_RETURN ( ( LM_ERROR, ACE_TEXT (
"INS_Manager: create_instances( %s ) import_config failed\n" ),
this->config_file_ ), -1 );
}
if ( cfg_.open_section( cfg_.root_section( ), ACE_TEXT( ins_section ),
0 , this->cfg_section_ ) )
{
ACE_ERROR_RETURN ( ( LM_ERROR,
ACE_TEXT ( "INS_Manager: create_instances( %s ) open_sectionfailed )\n" ),
ins_section ), -1 );
}
// Count instances.
int s1=0;
ACE_TString buff;
while ( !this->cfg_.enumerate_sections( this->cfg_section_, s1, buff ) )
{
s1++;
}
// ACE_DEBUG( ( LM_DEBUG, ACE_TEXT(
// "( %P|%T ) INS_Manager - create_instances( ): Number of Detected Instances: %d \n" ), s1 ) );
// Create the instance array container with the number of elements equal to
// the number of instances read from the configuration file.
this->osm_instance_array_ = 0;
this->osm_instance_array_ = new OSM_Instance_Base*[s1];
if ( 0 == this->osm_instance_array_ )
{
ACE_ERROR_RETURN ( ( LM_ERROR,
ACE_TEXT ( "INS_Manager: Could not create Instance Array [%d]\n" ),
s1 ), -1 );
}
this->osm_instance_number_ = 0;
int ii;
for ( ii=0;ii < s1;ii++ ) this->osm_instance_array_[ii]=0;
ACE_Configuration_Section_Key instance_section;
ACE_TString type_buff;
ACE_TString conn_buff;
// Start reading from the begining.
int s2 = 0;
while ( !this->cfg_.enumerate_sections( this->cfg_section_, s2, buff ) )
{
s2++;
if ( s2 > s1 ) break; // More instances than the first time?
// -------------------------------------------------------------------------
// Get the instance Type and Connection info from the config_file
// [OSMIUS_INSTANCES]->[INSTANCENAME]->TYPE=XXXXXXXX, CONNECTION_INFO=XXXXX
// BLACKOUT=XXXXXXXXXXXX
// -------------------------------------------------------------------------
if ( cfg_.open_section( this->cfg_section_, ACE_TEXT( buff.c_str( ) ),
0 , instance_section ) )
{
ACE_ERROR_RETURN( ( LM_ERROR,
ACE_TEXT ( "INS_Manager: Could not open [%s] section!!\n" ),
buff.c_str( ) ), -1 );
}
if ( -1== this->cfg_.get_string_value ( instance_section, ACE_TEXT( "TYPE" ),
type_buff ) )
{
ACE_ERROR_RETURN ( ( LM_ERROR,
ACE_TEXT ( "INS_Manager: Could not get TYPE for [%s].\n" ),
buff.c_str( ) ), -1 );
}
if ( -1== this->cfg_.get_string_value ( instance_section,
ACE_TEXT( "CONNECTION_INFO" ),
conn_buff ) )
{
ACE_ERROR_RETURN ( ( LM_ERROR,
ACE_TEXT ( "INS_Manager: Could not get CONNECTION_INFO for [%s].\n" ),
buff.c_str( ) ), -1 );
}
if ( OSM_CfgManager::instance( )->debug_mode( ) )
{
ACE_DEBUG( ( LM_DEBUG, ACE_TEXT( "\t[%s] - %s\n" ),
buff.c_str( ), type_buff.c_str( ) ) );
}
this->osm_instance_array_[this->osm_instance_number_] = 0;
if ( -1 == CREATE_OSMIUS_INSTANCE(
buff.c_str( ) ,
type_buff.c_str( ) ,
conn_buff.c_str( ) ,
this->osm_instance_array_[this->osm_instance_number_] ) )
{
ACE_ERROR_RETURN( ( LM_ERROR,
ACE_TEXT ( "INS_Manager: Could not create instance %d [%s] type [%s]\n" ),
s2, buff.c_str( ), type_buff.c_str( ) ), -1 );
}
// -------------------------------------------------------------------------
// Open the instance
// -------------------------------------------------------------------------
int num_events=0;
if ( -1 == this->osm_instance_array_[this->osm_instance_number_]->open(
this->config_file_ ,
buff.c_str( ) ,
type_buff.c_str( ) ,
conn_buff.c_str( ) ,
this ,
&num_events ) )
{
ACE_ERROR_RETURN( ( LM_ERROR,
ACE_TEXT ( "INS_Manager: Could not open instance %d [%s] type\n" ),
s2, buff.c_str( ) ), -1 );
}
this->osm_instance_number_ = s2;
}
if ( s1 != s2 )
{
ACE_ERROR ( ( LM_ERROR, ACE_TEXT (
"INS_Manager - create_instances( ) Initial instances: %d End: %d\n" ),
s1, s2 ) );
}
return 0;
}
/*----------------------------------------------------------------------------*/
int
567 OSM_AG_InsManager::destroy_instances( void )
{
int i;
int result=0;
for ( i=0;i<this->osm_instance_number_;i++ )
{
if ( OSM_CfgManager::instance( )->debug_mode( ) )
{
ACE_DEBUG( ( LM_DEBUG, ACE_TEXT(
"( %P|%T ) INS_Manager - destroy_instances( ): index[%d] [%s]-[%s]\n" ),
i,
this->osm_instance_array_[i]->idn_instance( ),
this->osm_instance_array_[i]->typ_instance( ) ) );
}
if ( -1 == this->osm_instance_array_[i]->close( ) )
{
result = -1;
ACE_ERROR ( ( LM_ERROR, ACE_TEXT (
"INS_Manager - destroy_instances( ) Error closing: %d [%s]\n" ),
i, this->osm_instance_array_[i]->idn_instance( ) ) );
}
if ( 0 != this->osm_instance_array_[i] )
{
delete this->osm_instance_array_[i];
this->osm_instance_array_[i] = 0;
}
}
if ( this->osm_instance_number_ )
{
delete [] this->osm_instance_array_;
}
this->osm_instance_number_ = 0;
return result;
}
/*----------------------------------------------------------------------------*/
int
606 OSM_AG_InsManager::init ( int argc, ACE_TCHAR *argv[] )
{
// ---------------------------------------------------------------------------
// Parse Command Line.
// ---------------------------------------------------------------------------
ACE_Get_Opt get_opt ( argc, argv, ACE_TEXT ( "c:" ), 0 );
get_opt.long_option ( ACE_TEXT ( "config_file" ), 'c',
ACE_Get_Opt::ARG_REQUIRED );
for ( int c; ( c = get_opt ( ) ) != -1; )
{
switch ( c )
{
case 'c':
ACE_OS::strsncpy( this->config_file_, get_opt.opt_arg ( ), MAXPATHLEN );
break;
}
}
if ( OSM_CfgManager::instance( )->debug_mode( ) )
{
ACE_DEBUG( ( LM_DEBUG, ACE_TEXT(
"( %P|%T ) INS_Manager - init( ) Conf File: [%s]\n" ), this->config_file_ ) );
}
if ( -1 == this->cfg_.open( ) )
{
ACE_ERROR_RETURN( ( LM_ERROR,
ACE_TEXT( "INS_Manager - init_work( )open( [%s] )\n" ),
this->config_file_ ), -1 );
}
// ---------------------------------------------------------------------------
// Create instances objects reading from config_file.
// ---------------------------------------------------------------------------
if ( -1 == this->create_instances( ) )
{
destroy_instances( );
return -1;
}
if ( OSM_CfgManager::instance( )->debug_mode( ) )
{
ACE_DEBUG( ( LM_DEBUG, ACE_TEXT(
"( %P|%T ) INS_Manager- init_work( ) Osmius Instances Created: %d\n" ),
this->osm_instance_number_ ) );
}
return 0;
}
/*----------------------------------------------------------------------------*/
int
658 OSM_AG_InsManager::fini ( )
{
if ( OSM_CfgManager::instance( )->debug_mode( ) )
{
ACE_DEBUG( ( LM_DEBUG,
ACE_TEXT( "( %P|%T ) INS_Manager - fini( ). Exit service......\n" ) ) );
}
if ( -1 == this->destroy_instances( ) )
{
return -1;
}
return 0;
}
/*----------------------------------------------------------------------------*/
int
675 OSM_AG_InsManager::reload ( )
{
if ( OSM_CfgManager::instance( )->debug_mode( ) )
{
ACE_DEBUG( ( LM_DEBUG, ACE_TEXT( "( %P|%T ) INS_Manager - reload( )...........\n" ) ) );
}
if ( -1 == this->destroy_instances( ) )
{
return -1;
}
if ( -1 == this->create_instances( ) )
{
return -1;
}
if ( OSM_CfgManager::instance( )->debug_mode( ) )
{
ACE_DEBUG( ( LM_DEBUG, ACE_TEXT( "( %P|%T ) INS_Manager - reload( ) Ok.\n" ) ) );
}
return 0;
}
/*----------------------------------------------------------------------------*/
/* OSM_Instance_Base Implementation */
/*----------------------------------------------------------------------------*/
int
701 OSM_Instance_Base::open( const ACE_TCHAR* config_file ,
702 const ACE_TCHAR* idn_instance ,
703 const ACE_TCHAR* typ_instance ,
704 const ACE_TCHAR* conn_info ,
705 OSM_AG_InsManager* ins_man ,
int* event_num )
{
this->event_array_ = 0;
this->event_number_ = 0;
if ( OSM_CfgManager::instance( )->debug_mode( ) )
{
ACE_DEBUG( ( LM_DEBUG, ACE_TEXT(
"( %P|%T ) INS_Base - open( ) Config File: [%s] Instance: [%s]-[%s]...\n" ),
config_file, idn_instance, typ_instance ) );
}
if ( 0 == ins_man )
{
ACE_ERROR_RETURN( ( LM_ERROR,
ACE_TEXT( "INS_Base - open( ) Bad Instance Manager Pointer\n" ) ), -1 );
}
this->ins_manager_ = ins_man;
this->event_number_ = 0;
if ( ACE_OS::strlen( idn_instance ) > OSM_Message::CODLEN )
{
ACE_ERROR_RETURN( ( LM_ERROR,
ACE_TEXT( "INS_Base - open( ) Bad instance code length\n" ) ), -1 );
}
ACE_OS::strcpy( this->idn_instance_, idn_instance );
ACE_OS::strcpy( this->config_file_, config_file );
if ( ACE_OS::strlen( conn_info ) > BUFSIZ )
{
ACE_ERROR_RETURN( ( LM_ERROR,
ACE_TEXT( "INS_Base - open( ) Bad Connection info length\n" ) ), -1 );
}
ACE_OS::strcpy( this->connection_info_, conn_info );
if ( ACE_OS::strlen( typ_instance ) > OSM_Message::TYPLEN )
{
ACE_ERROR_RETURN( ( LM_ERROR,
ACE_TEXT( "INS_Base - open( ) Bad Instance Type length\n" ) ), -1 );
}
ACE_OS::strcpy( this->typ_instance_, typ_instance );
// ---------------------------------------------------------------------------
// Create event objects reading from config_file.
// ---------------------------------------------------------------------------
if ( -1 == this->create_events( ) )
{
destroy_events( );
return -1;
}
if ( OSM_CfgManager::instance( )->debug_mode( ) )
{
ACE_DEBUG( ( LM_DEBUG, ACE_TEXT(
"( %P|%T ) INS_Base - open( ) Osmius Events Created: %d\n" ),
this->event_number_ ) );
}
*event_num = this->event_number_;
return 0;
}
/*----------------------------------------------------------------------------*/
int
772 OSM_Instance_Base::destroy_events( void )
{
int i;
int result=0;
for ( i=0;i<this->event_number_;i++ )
{
if ( OSM_CfgManager::instance( )->debug_mode( ) )
{
ACE_DEBUG( ( LM_DEBUG, ACE_TEXT(
"( %P|%T ) INS_Base - destroy_events( ): %d [%s]\n" ),
i,
this->event_array_[i]->typ_event( ) ) );
}
if ( -1 == this->event_array_[i]->close( ) )
{
result = -1;
ACE_ERROR ( ( LM_ERROR, ACE_TEXT (
"INS_Base - destroy_events( ) Error closing: %d [%s]\n" ),
i, this->event_array_[i]->typ_event( ) ) );
}
if ( 0 != this->event_array_[i] )
{
delete this->event_array_[i];
this->event_array_[i] = 0;
}
}
delete [] this->event_array_;
this->event_number_ = 0;
return result;
}
/*----------------------------------------------------------------------------*/
int
807 OSM_Instance_Base::create_events( void )
{
ACE_Configuration_Heap cfg;
ACE_Configuration_Section_Key cfg_section;
ACE_OS::last_error( 0 );
if ( 0 != cfg.open( ) )
{
ACE_ERROR_RETURN ( ( LM_ERROR, ACE_TEXT (
"INS_Base: open cfg failed - %d\n" ),
ACE_OS::last_error( ) ), -1 );
}
ACE_Ini_ImpExp import_cfg( cfg );
if ( import_cfg.import_config( ACE_TEXT( this->config_file_ ) ) )
{
ACE_ERROR_RETURN ( ( LM_ERROR, ACE_TEXT (
"INS_Base: open( %s ) import_config failed\n" ),
this->config_file_ ), -1 );
}
// Open OSMIUS_INSTANCE section.
if ( cfg.open_section( cfg.root_section( ), ACE_TEXT( "OSMIUS_INSTANCES" ),
0 , cfg_section ) )
{
ACE_ERROR_RETURN ( ( LM_ERROR,
ACE_TEXT ( "INS_Base: create_events( ) open_section [root] failed )\n" ) ), -1 );
}
// Open idn_instance section ( inside OSMIUS_INSTANCES )
if ( cfg.open_section( cfg_section, ACE_TEXT( this->idn_instance_ ),
0 , cfg_section ) )
{
ACE_ERROR_RETURN ( ( LM_ERROR,
ACE_TEXT ( "INS_Base: open( ) open_section [%s]failed\n" ),
this->idn_instance_ ), -1 );
}
// Open EVENTS section ( inside [OSMIUS_INSTANCES]->[COD_INSTANCE]->[EVENTS] )
if ( cfg.open_section( cfg_section, ACE_TEXT( "EVENTS" ),
0 , cfg_section ) )
{
ACE_ERROR_RETURN ( ( LM_ERROR,
ACE_TEXT ( "INS_Base: open( ) open_section [%s]->[EVENTS]failed\n" ),
this->idn_instance_ ), -1 );
}
ACE_Configuration::VALUETYPE type;
u_int index1 = 0;
ACE_TString s_name;
// Get the events and create the array.
while ( !cfg.enumerate_values( cfg_section, index1, s_name, type ) )
{
index1++;
//if ( OSM_CfgManager::instance( )->debug_mode( ) )
//{
// ACE_DEBUG( ( LM_DEBUG, ACE_TEXT(
// "( %P|%T ) INS_Base EVENT %d : [%s]\n" ), index1, s_name.c_str( ) ) );
//}
}
if ( OSM_CfgManager::instance( )->debug_mode( ) )
{
ACE_DEBUG( ( LM_DEBUG, ACE_TEXT(
"( %P|%T ) INS_Base - create_events( ) Number of Detected Events: %d\n" ),
index1 ) );
}
// Create the event array container with the number of elements equal to
// the number of events read from the configuration file.
this->event_array_ = 0;
this->event_array_ = new OSM_Event*[index1];
if ( 0 == this->event_array_ )
{
ACE_ERROR_RETURN ( ( LM_ERROR,
ACE_TEXT ( "INS_Base: Could not create Event Array [%d]\n" ),
index1 ), -1 );
}
this->event_number_ = 0;
u_int ii;
for ( ii=0;ii<index1;ii++ ) this->event_array_[ii]=0;
// Start reading from the begining.
u_int index2 = 0;
int i_value=0;
int i_mode=-1;
int i_warning=0;
int i_alarm=0;
int i_silent=0;
ACE_TString s_value;
while ( !cfg.enumerate_values( cfg_section, index2, s_name, type ) )
{
index2++;
if ( index2 > index1 ) break; // More events than the first time?
// -------------------------------------------------------------------------
// Get event value.
// -------------------------------------------------------------------------
if ( -1== cfg.get_string_value ( cfg_section,
ACE_TEXT( s_name.c_str( ) ),
s_value ) )
{
ACE_ERROR_RETURN ( ( LM_ERROR,
ACE_TEXT ( "INS_Manager: Could not get value for [%s].\n" ),
s_name.c_str( ) ), -1 );
}
if ( -1==this->parse_event_cmdline( s_value.c_str( ), i_value, i_mode, i_warning, i_alarm, i_silent ) )
{
ACE_ERROR_RETURN ( ( LM_ERROR,
ACE_TEXT ( "INS_Manager: Could not parse this string( %s ) for [%s].\n" ),
s_value.c_str( ), s_name.c_str( ) ), -1 );
}
this->event_array_[this->event_number_] = 0;
if ( -1 == CREATE_OSMIUS_EVENT(
s_name.c_str( ) ,
this->typ_instance_ ,
s_value.c_str( ) ,
i_value ,
this->event_array_[this->event_number_] ) )
{
ACE_ERROR_RETURN( ( LM_ERROR,
ACE_TEXT ( "INS_Base: Could not create event %d [%s] type [%s]:%d\n" ),
index2, s_name.c_str( ), this->typ_instance_, i_value ), -1 );
}
// -------------------------------------------------------------------------
// Open the event
// -------------------------------------------------------------------------
// int open( const ACE_TCHAR* name , const OSM_Instance_Base* ins,
// const int interval, const int i_delay,
// const int timeout ,
// const int up_limit=0 , const int lw_limit=0 )
int initial_delay = i_value;
if ( i_value > 299 ) // Five minutes
{
initial_delay = 1 + ( int ) ( 300.0 * ( ACE_OS::rand( ) / ( RAND_MAX + 1.0 ) ) );
}
if ( -1 == this->event_array_[this->event_number_]->open(
s_name.c_str( ) ,
this ,
i_value ,
initial_delay ,
i_value ,
i_mode ,
i_warning ,
i_alarm ,
i_silent ,
s_value.c_str( ) ) )
{
ACE_ERROR_RETURN( ( LM_ERROR,
ACE_TEXT ( "INS_Manager: Could not open event %d [%s] type\n" ),
index2, s_name.c_str( ) ), -1 );
}
this->event_array_[this->event_number_]->action( )->instance( this );
this->event_number_ = index2;
}
return 0;
};
/*----------------------------------------------------------------------------*/
int
969 OSM_Instance_Base::close( void )
{
if ( OSM_CfgManager::instance( )->debug_mode( ) )
{
ACE_DEBUG( ( LM_DEBUG, ACE_TEXT(
"INS_Base - close( )\n" ) ) );
}
this->disconnect( 1 ); // Force = yes.
return this->destroy_events( );
}
/*----------------------------------------------------------------------------*/
int
983 OSM_Instance_Base::connect( void )
{
// noop connect.
return 0;
}
/*----------------------------------------------------------------------------*/
int
990 OSM_Instance_Base::disconnect( const int force )
{
// noop disconnect.
return 0;
}
/*----------------------------------------------------------------------------*/
OSM_AG_InsManager*
997 OSM_Instance_Base::ins_manager( )
{
return this->ins_manager_;
}
/*----------------------------------------------------------------------------*/
int
1004 OSM_Instance_Base::parse_event_cmdline ( const ACE_TCHAR* cmdline,
int &value,
int &mode,
int &warn,
int &alar,
int &silent )
{
int opt_t=0;
int opt_c=0;
int opt_w=0;
int opt_a=0;
int opt_s=0;
ACE_ARGV cmdline_args( cmdline );
ACE_Get_Opt get_opt ( cmdline_args.argc( ), cmdline_args.argv( ), ACE_TEXT ( "t:c:w:a:s" ), 0 );
mode = -1;
warn = alar = silent = 0;
for ( int c; ( c = get_opt ( ) ) != -1; )
{
switch ( c )
{
case 't':
// Value for the period in seconds.
value = ACE_OS::atoi( get_opt.opt_arg ( ) );
opt_t++;
break;
case 's':
// Silent Mode
silent = 1;
opt_s++;
break;
case 'a':
// Warning limit.
alar = ACE_OS::atoi( get_opt.opt_arg ( ) );
opt_a++;
break;
case 'w':
// Warning limit.
warn = ACE_OS::atoi( get_opt.opt_arg ( ) );
opt_w++;
break;
case 'c':
// Compare mode.
mode = ACE_OS::atoi( get_opt.opt_arg ( ) );
opt_c++;
break;
default:
break;
return -1;
}
}
if ( 1 != opt_t )
{
return -1;
}
if ( mode > -1 )
{
if ( ( 1 != opt_w )||( 1 != opt_a ) )
{
return -1;
}
}
if ( ( OSM_Event::OSM_COMPARE_GREATER != mode ) && ( OSM_Event::OSM_COMPARE_LESS != mode )&& ( -1 != mode ) )
{
mode = -1;
}
return 0;
}
/*----------------------------------------------------------------------------*/
int
1080 OSM_Instance_Base::check_conn_info( const ACE_TCHAR* conn_info )
{
// noop check.
return 0;
}
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* OSM_ACT_ExecuteProcess Implementation */
/*----------------------------------------------------------------------------*/
int
1091 OSM_ACT_ExecuteProcess::execute ( const ACE_TCHAR* cmd_line , const int cmd_len,
const int timeout,
1093 ACE_TCHAR* val_text,
int& val_len,
int & value )
{
// // Uncomment this if you want to trace this function.
// if ( OSM_CfgManager::instance( )->debug_mode( ) )
// {
// ACE_DEBUG( ( LM_DEBUG,
// ACE_TEXT( "( %P|%T ) OSM_Action: execute( ) [%s] TimeOut: %d\n" ),
// cmd_line, timeout ) );
// }
value = -1;
// Use your own command line checker method. See below.
if ( 0 == this->cmd_checked_ )
{
if ( -1 == this->check_cmd_line( cmd_line, cmd_len ) )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "( %P|%T ) OSM_Action : Bad command line [%s]\n" ),
cmd_line ) );
ACE_OS::sprintf( val_text, "Bad command line" );
val_len = ACE_OS::strlen( val_text );
return -1;
}
this->cmd_checked_ = 1;
}
// We could also check the command line parameters for our event into the cfg file.
// EVENT = -t timeout [-c 0, 1 -w warn -a alarm -s( ilent )]
// if ( OSM_CfgManager::instance( )->debug_mode( ) )
// {
// ACE_DEBUG( ( LM_DEBUG,
// ACE_TEXT( "( %P|%T ) OSM_Action: Config Parameters are [%s]\n" ),
// this->ev_parameters( ) ) );
// }
// Do whatever you must do to get the value and its text.
if ( 0 > this->process_.execute( cmd_line, "", "", value , 0, val_text, val_len ) )
{
ACE_ERROR ( ( LM_ERROR, ACE_TEXT (
"ACT_ExecuteProcess - execute( ) Failed command: [%s] exit code: %d.\n" ),
cmd_line,
value ) );
}
val_len=ACE_OS::strlen( val_text );
return 0;
}
/*----------------------------------------------------------------------------*/
int
1145 OSM_ACT_ExecuteProcess::check_cmd_line( const ACE_TCHAR* cmd_line,
const int cmd_len )
{
// Uncomment this if you want to trace this function ( and run with "-d" )
// if ( OSM_CfgManager::instance( )->debug_mode( ) )
// {
// ACE_DEBUG( ( LM_DEBUG,
// ACE_TEXT( "( %P|%T ) OSM_Action: check_cmd_line( ) [%s] %d\n" ),
// cmd_line, cmd_len ) );
// }
return 0;
}
/*----------------------------------------------------------------------------*/
/* OSM_ACT_IP4Interfaces Implementation */
/*----------------------------------------------------------------------------*/
1162 int OSM_ACT_IP4Interfaces::execute ( const ACE_TCHAR* cmd_line, const int cmd_len,
1163 const int timeout , ACE_TCHAR* val_text ,
int& val_len , int& value )
{
//Uncomment this if you want to trace this function.
//if ( OSM_CfgManager::instance( )->debug_mode( ) )
//{
// ACE_DEBUG( ( LM_DEBUG,
// ACE_TEXT( "( %P|%T ) OSM_Action: execute( ) [%s] TimeOut: %d\n" ),
// cmd_line, timeout ) );
//}
// Use your own command line checker method. See below.
// if ( -1 == this->check_cmd_line( cmd_line, cmd_len ) )
// {
// ACE_ERROR( ( LM_ERROR,
// ACE_TEXT( "( %P|%T ) OSM_Action : Bad command line [%s]\n" ),
// cmd_line ) );
// return -1;
// }
// We could also check the command line parameters for our event into the cfg file.
// EVENT = -t timeout [-c 0, 1 -w warn -a alarm -s( ilent )]
// if ( OSM_CfgManager::instance( )->debug_mode( ) )
// {
// ACE_DEBUG( ( LM_DEBUG,
// ACE_TEXT( "( %P|%T ) OSM_Action: Config Parameters are [%s]\n" ),
// this->ev_parameters( ) ) );
// }
int ret = ACE::get_ip_interfaces( this->num_if_, this->addr_array_ );
if ( 0 != ret )
{
ACE_ERROR( ( LM_ERROR, ACE_TEXT( "( %P|%T ) OSM_Action : could not get_ip_interfaces( )\n" ) ) );
value = -1;
return -1;
}
value = 0;
for ( size_t i=0; i < this->num_if_ ;i++ )
{
if ( AF_INET == this->addr_array_[i].get_type( ) )
{
value++;
}
}
if ( this->num_if_ )
{
delete [] this->addr_array_;
this->addr_array_ = 0;
}
this->num_if_ = 0;
ACE_OS::sprintf( val_text, "" );
val_len=0;
return 0;
}
/*----------------------------------------------------------------------------*/
// Don't need this.
//int OSM_ACT_IP4Interfaces::check_cmd_line( const ACE_TCHAR* cmd_line,
// const int cmd_len )
//{
//}
/*----------------------------------------------------------------------------*/
/* OSM_ACT_IP6Interfaces Implementation */
/*----------------------------------------------------------------------------*/
1228 int OSM_ACT_IP6Interfaces::execute ( const ACE_TCHAR* cmd_line, const int cmd_len,
1229 const int timeout , ACE_TCHAR* val_text ,
int& val_len , int& value )
{
//Uncomment this if you want to trace this function.
//if ( OSM_CfgManager::instance( )->debug_mode( ) )
//{
// ACE_DEBUG( ( LM_DEBUG,
// ACE_TEXT( "( %P|%T ) OSM_Action: execute( ) [%s] TimeOut: %d\n" ),
// cmd_line, timeout ) );
//}
// Use your own command line checker method. See below.
// if ( -1 == this->check_cmd_line( cmd_line, cmd_len ) )
// {
// ACE_ERROR( ( LM_ERROR,
// ACE_TEXT( "( %P|%T ) OSM_Action : Bad command line [%s]\n" ),
// cmd_line ) );
// return -1;
// }
// We could also check the command line parameters for our event into the cfg file.
// EVENT = -t timeout [-c 0, 1 -w warn -a alarm -s( ilent )]
// if ( OSM_CfgManager::instance( )->debug_mode( ) )
// {
// ACE_DEBUG( ( LM_DEBUG,
// ACE_TEXT( "( %P|%T ) OSM_Action: Config Parameters are [%s]\n" ),
// this->ev_parameters( ) ) );
// }
int ret = ACE::get_ip_interfaces( this->num_if_, this->addr_array_ );
if ( 0 != ret )
{
value = -1;
ACE_ERROR( ( LM_ERROR, ACE_TEXT( "( %P|%T ) OSM_Action : could not get_ip_interfaces( )\n" ) ) );
return -1;
}
value = 0;
for ( size_t i=0; i < this->num_if_ ;i++ )
{
if ( AF_INET6 == this->addr_array_[i].get_type( ) )
{
value++;
}
}
if ( this->num_if_ )
{
delete [] this->addr_array_;
this->addr_array_ = 0;
}
this->num_if_ = 0;
ACE_OS::sprintf( val_text, "" );
val_len=0;
return 0;
}
/*----------------------------------------------------------------------------*/
// Don't need this.
//int OSM_ACT_IP4Interfaces::check_cmd_line( const ACE_TCHAR* cmd_line,
// const int cmd_len )
//{
//}
/*----------------------------------------------------------------------------*/
/* OSM_ACT_ScanLog Implementation */
/*----------------------------------------------------------------------------*/
int
1296 OSM_ACT_ScanLog::execute ( const ACE_TCHAR* cmd_line , const int cmd_len ,
1297 const int timeout , ACE_TCHAR* val_text,
int& val_len , int& value )
{
// // Uncomment this if you want to trace this function.
// if ( OSM_CfgManager::instance( )->debug_mode( ) )
// {
// ACE_DEBUG( ( LM_DEBUG,
// ACE_TEXT( "( %P|%T ) OSM_Action: execute( ) [%s] TimeOut: %d\n" ),
// cmd_line, timeout ) );
// }
value = -1;
// Use your own command line checker method. See below.
if ( 0 == this->cmd_line_checked_ )
{
if ( -1 == this->check_cmd_line( cmd_line, cmd_len ) )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "( %P|%T ) OSM_Action : Bad command line [%s]\n" ),
cmd_line ) );
ACE_OS::sprintf( val_text, "Bad command line" );
val_len = ACE_OS::strlen( val_text );
return -1;
}
this->cmd_line_checked_ = 1;
}
// We could also check the command line parameters for our event into the cfg file.
// EVENT = -t timeout [-c 0, 1 -w warn -a alarm -s( ilent )]
// if ( OSM_CfgManager::instance( )->debug_mode( ) )
// {
// ACE_DEBUG( ( LM_DEBUG,
// ACE_TEXT( "( %P|%T ) OSM_Action: Config Parameters are [%s]\n" ),
// this->ev_parameters( ) ) );
// }
// Do whatever you must do to get the value and its text.
ACE_stat f_stat;
if ( ACE_OS::stat( this->log_file_, &f_stat ) )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "( %P|%T ) OSM_ACT_ScanLog : Cannot stat file [%s]\n" ),
this->log_file_ ) );
ACE_OS::sprintf( val_text, "Cannot stat file [%s]", this->log_file_ );
val_len = ACE_OS::strlen( val_text );
return -1;
}
if ( f_stat.st_size < this->last_size_ )
{
this->last_size_ = 0;
}
if ( f_stat.st_size == this->last_size_ )
{
value=0;
val_text[0] = 0;
val_len = ACE_OS::strlen( val_text );
return 0;
}
this->fd_ = ACE_OS::fopen( this->log_file_, ACE_LIB_TEXT( "r" ) );
if ( 0 == this->fd_ )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "( %P|%T ) OSM_ACT_ScanLog : Cannot open file [%s]\n" ),
this->log_file_ ) );
ACE_OS::sprintf( val_text, "Cannot open file [%s]", this->log_file_ );
val_len = ACE_OS::strlen( val_text );
return -1;
}
this->auxbuf_[0] = 0;
ACE_OS::fseek( this->fd_, this->last_size_, SEEK_SET );
value=0;
char* p=0;
while ( ACE_OS::fgets( this->auxbuf_, OSM_SCANLOG_BUFSIZ, this->fd_ ) )
{
for ( int i=0; i < OSM_SCANLOG_BUFSIZ; i++ )
{
if ( ( 0x0D == this->auxbuf_[i] ) || ( 0x0A == this->auxbuf_[i] ) )
{
this->auxbuf_[i] = 0;
break;
}
}
p = ACE_OS::strstr( this->auxbuf_, this->string_ );
if ( p )
{
value =1 ;
ACE_OS::sprintf( val_text, "%s[%s] -> [%s]", this->log_file_, this->string_, p );
break;
}
this->auxbuf_[0] = 0;
}
this->last_size_ = f_stat.st_size;
val_len=ACE_OS::strlen( val_text );
if ( 0 != ACE_OS::fclose( this->fd_ ) )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "( %P|%T ) OSM_ACT_ScanLog : Cannot close file [%s]\n" ),
this->log_file_ ) );
}
return 0;
}
/*----------------------------------------------------------------------------*/
int
1409 OSM_ACT_ScanLog::check_cmd_line( const ACE_TCHAR* cmd_line,
const int cmd_len )
{
// Uncomment this if you want to trace this function ( and run with "-d" )
//if ( OSM_CfgManager::instance( )->debug_mode( ) )
//{
// ACE_DEBUG( ( LM_DEBUG,
// ACE_TEXT( "( %P|%T ) OSM_Action: check_cmd_line( ) [%s] %d\n" ),
// cmd_line, cmd_len ) );
//}
// Check the Command Line.
if ( this->cmd_line_checked_ )
{
return 0;
}
// Check the Command Line.
int opt_l=0;
int opt_s=0;
ACE_ARGV cmd_args( cmd_line );
ACE_Get_Opt get_opt ( cmd_args.argc( ), cmd_args.argv( ), ACE_TEXT ( "l:s:" ), 0 );
ACE_TCHAR aux[BUFSIZ+1];
int len;
for ( int c; ( c = get_opt ( ) ) != -1; )
{
switch ( c )
{
case 'l':
// LogFile full path
ACE_OS::strcpy( aux, get_opt.opt_arg ( ) );
len = ACE_OS::strlen( aux );
if ( ( len > BUFSIZ ) || ( len < 2 ) ) return -1;
aux[len]='\0';
ACE_OS::strcpy( this->log_file_, aux );
opt_l++;
break;
case 's':
// String to search
ACE_OS::strcpy( aux, get_opt.opt_arg ( ) );
len = ACE_OS::strlen( aux );
if ( ( len > BUFSIZ ) ) return -1;
aux[len]='\0';
ACE_OS::strcpy( this->string_, aux );
opt_s++;
break;
default:
break;
}
}
if ( ( 1 != opt_l ) || ( 1!=opt_s ) ) // Logfile name and string to search are mandatory.
{
return -1;
}
this->cmd_line_checked_ = 1;
return 0;
}
1 // -*- C++ -*-
// -----------------------------------------------------------------------------
/*
* Osmius and its code is copyright of Peopleware S.L. Spain.
* http://www.peopleware.es
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* ( at your option ) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
// -----------------------------------------------------------------------------
/**
* @file osm_ag_insmanager.h
* @brief Definition file for the main classes to build an Osmius agent and instance and event manager.
* Osmius - Peopleware.
*
* @author Jose Luis Marina <joseluis.marina@peopleware.es>
* @date 24-MAY-2006
*/
// -----------------------------------------------------------------------------
#ifndef _OSM_AG_INSMANAGER_H_
#define _OSM_AG_INSMANAGER_H_
//#if !defined ( ACE_LACKS_PRAGMA_ONCE )
//# pragma once
//#endif /* ACE_LACKS_PRAGMA_ONCE */
//#include <ace/Event_Handler.h>
//#include <ace/Reactor.h>
//#include <ace/Configuration.h>
#include "osm_ag_msgmanager.h"
#include "../cm/osm_message.h"
// Forwarded declaration.
49 class OSM_Instance_Base;
/**
* @class OSM_Action_Base
*
* @brief Defines Base class to all action classes like execute query, execute shell, etc...
*
* We must derive from this class when creating a new action. An action is every
* thing an event must execute to retrieve its own value. An action could be the
* execution of an SQL query to Oracle or MySql, or the execution of a command
* under Solaris, HP-UX, AIX, Linux or Windows boxes.
*
*/
62 class OSM_Action_Base
{
public:
enum
{
OSM_MAX_ACTION_NAME_LEN = 8
};
/// Default Constructor
70 OSM_Action_Base( ) {};
/// Destructor
73 virtual ~OSM_Action_Base( ) {};
/// Returns 1 if the name of the action is equal to the name in the parameter.
76 int is_name( const ACE_TCHAR* nm )
{
if ( 0 == ACE_OS::strncmp( this->name_, nm, ACE_OS::strlen( this->name_ ) ) )
{
return 1;
}
return 0;
};
/**
* Executes the action using the command line and returns the associated text
* and value.
* @param cmd_line Input - Command line used to execute this action.
* @param cmd_len Input - Command line length.
* @param timeout Input - Wait timeout seconds before aborting execution.
* @param val_text Output - Text of the resulting action.
* @param val_len Output - Text length.
* @param value Output - Final value of the action.
* @retval -1 in case of error. 0 for success.
*/
97 virtual int execute( const ACE_TCHAR* cmd_line, const int cmd_len ,
98 const int timeout , ACE_TCHAR* val_text,
int& val_len , int& value ) = 0;
/**
* Checks the command line. You should overwrite this method to handle issues
* like semantic and sintactic checking or security stuff.
* E.g. You could return error if your SQL string contains the words UPDATE,
* DELETE or INSERT.
* @param cmd_line Input - Command line used to execute this action.
* @param cmd_len Input - Command line length.
* @retval -1 in case of error. 0 for success.
*/
110 virtual int check_cmd_line( const ACE_TCHAR* cmd_line, const int cmd_len ) {return 0;};
/**
* Sets the name of the action.
* @param nm Input - Name.
*/
116 void set_name( const ACE_TCHAR* nm )
{
ACE_OS::strncpy( name_, nm, OSM_MAX_ACTION_NAME_LEN );
name_[OSM_MAX_ACTION_NAME_LEN]=0;
};
/**
* Sets the instance.
* @param ins Input - Instance pointer.
*/
126 void instance( OSM_Instance_Base* ins )
{
this->osm_instance_=ins;
};
/**
* Return a pointer to the instance.
*/
134 const OSM_Instance_Base* instance( void ) const
{
return this->osm_instance_;
};
/**
* Sets the parameters used in our Event config file.
* @param param Input - Parameters ( command line like ).
*/
143 void ev_parameters( const ACE_TCHAR* param )
{
ACE_OS::strncpy( ev_parameters_, param, BUFSIZ );
ev_parameters_[BUFSIZ]=0;
};
/**
* Return pointer to parameters.
*/
152 const ACE_TCHAR* ev_parameters( void ) const
{
return this->ev_parameters_;
};
/**
* Return pointer to my name.
*/
160 const ACE_TCHAR* name( void ) const
{
return this->name_;
};
private:
/// Parameter Key os name. Must be unique.
167 ACE_TCHAR name_[OSM_MAX_ACTION_NAME_LEN + 1];
/// We must know who our instance is to manage connection to different
/// kind of instances ( ftp, oracle, mysql, temperature sensor, ... ) and
/// specific data structures. We'll make it easy ; )
172 OSM_Instance_Base* osm_instance_;
/// Parameters located on the config file of our Event.
/// We can choose to parse them and use or ignore them
176 ACE_TCHAR ev_parameters_[BUFSIZ+1];
};
// Forwarded declaration.
181 class OSM_AG_InsManager;
/**
* @class OSM_Event
*
* @brief Event class to monitor a certain event into an Osmius Instance.
*
* This class derives from ACE_Event_Handler so we can register timers with
* the chosen Reactor implementation. It has implemented the handle_time_out( )
* hook method, and this method in turn will call its associated action
* execute( ) method.
* In the open( ) method we'll register with the reactor, keep our timed_id info,
* and check every thing. In close( ) we'll cancel future timers, deregister our-
* selves with the Reactor and perform cleaning activities.
*/
196 class OSM_Event : public ACE_Event_Handler
{
public:
/// Compare types. 0-Greater Than 1-Less than
enum OSM_TYP_COMPARE
{
OSM_COMPARE_GREATER=0,
OSM_COMPARE_LESS =1
};
/// Constructor.
207 OSM_Event ( ACE_Reactor *r= ACE_Reactor::instance( ) ):
last_value_( -1 ) , timer_id_( -1 ), interval_( -1 ),
initial_delay_( 5 ),
compare_mode_( -1 ), warn_limit_( -1 ), crit_limit_( -1 ) ,
silent_mode_( 0 ), last_alarm_type_( -1 )
{this->reactor( r );};
/// Hook method called when object is signaled by timers.
215 virtual int handle_timeout ( const ACE_Time_Value &tv,
const void * );
/**
* Initializes the Event parameters. An event is basically an action plus
* a command line.
* @param name Input - Event Name.
* @param instance Input - This event creator instance.
* @param interval Input - The reactor timer interval seconds.
* @param i_delay Input - The reactor timer interval seconds.
* @param timeout Input - Timeout for the action.
* @param mode Input - Compare mode.
* @param warn Input - Warning Limit
* @param alar Input - Critical Alarm Limit
* @param silent Input - Silent mode 0-Off 1-On
* @param ev_params Input - Complete command line parameters in config file.
* @retval -1 in case of error. 0 for success.
*/
232 int open( const ACE_TCHAR* name , OSM_Instance_Base* instance,
const int interval , const int i_delay,
const int timeout ,
const int mode=0 ,
const int warn=0 ,
const int alar=0 ,
const int silent=0 ,
239 const ACE_TCHAR* ev_params=0 );
/**
* Cleaning activities:
* Cancel future timer calls.
* Deregister the timer from the ACE Reactor framework.
* Delete our action.
* @retval -1 in case of error. 0 for success.
*/
248 int close( void );
/// Returns 1 if the name of the action is equal to the name in the parameter.
251 int is_code( const ACE_TCHAR* nm )
{
if ( 0 == ACE_OS::strncmp( this->typ_event_, nm, ACE_OS::strlen( this->typ_event_ ) ) )
{
return 1;
}
return 0;
};
/// Return a pointer to local typ_event.
262 const ACE_TCHAR* typ_event( void )
{
return this->typ_event_;
};
/// Return a pointer to command line char string.
268 const ACE_TCHAR* cmd_line( void )
{
return this->cmd_line_;
};
/// Sets the command line
273 void cmd_line( const ACE_TCHAR* cmd_line, const int len )
{
int i;
if ( len > BUFSIZ )
{
i = BUFSIZ;
}
else
{
i = len;
}
ACE_OS::strncpy( cmd_line_, cmd_line, i );
cmd_line_[i]=0;
};
/// Returns a pointer to the local action.
289 OSM_Action_Base* action( void )
{
return this->action_;
}
/// Set the action to be executed when this Event is called.
295 void action( OSM_Action_Base* action )
{
this->action_ = action;
}
private:
/// Event Unique Code
302 ACE_TCHAR typ_event_ [OSM_Message::CODLEN + 1];
/// Command Line used to call action_->execute( ... )
304 ACE_TCHAR cmd_line_ [BUFSIZ+1];
/// Value state returned in the last execution.
// Just in case we need to remember it.
int last_value_;
/// When we register a timer with the ACE Reactor framework we get this number
/// We'll use it to cancel the timer in configuration changes.
long timer_id_;
/// Time in seconds this event must be called back and execute an action.
312 time_t interval_;
/// Seconds to wait before the first timer expiration.
314 time_t initial_delay_;
/// Time in seconds to wait for hte action to complete.
316 time_t timeout_;
/// A pointer to our instance.
318 OSM_Instance_Base* osm_instance_;
/// Comparison Mode 0-greater 1-less
int compare_mode_;
/// Limit for warning.
int warn_limit_;
/// Limit for critical
int crit_limit_;
/// Silent mode 0-No 1-Yes
/// If Yes we'll send only the message when there are changes of alarm type.
int silent_mode_;
/// Last Message alarm type.
int last_alarm_type_;
/// This is our way to execute this event.
334 OSM_Action_Base* action_;
};
/**
* @class OSM_Instance_Base
*
* @brief Instance class to monitor.It's a collection of event to supervise.
*
* This all Instances Base class with common stuff implemented letting us to -
* using inheritance - only codify our instance type specific job. Reading
* from the config file we must be able to create all the necessary objects and
* start monitoring the instance.
*/
348 class OSM_Instance_Base
{
public:
/// Constructor.
352 OSM_Instance_Base( ) : event_number_( 0 ), connected_( 0 ) {};
/**
* This procedure creates the array of events reading configuration from the
* section [OSMIUS_INSTANCES]->[IDN]->[EVENTS] of the ConfigFile.
* Also register the different events with the Reactor ( timers )
* @param config_file Input - Configuration file.
* @param idn_instance Input - Instance ID. Also is the section in the cfg file.
* @param typ_instance Input - Instance Type.
* @param con_info Input - Connection Info.
* @param InsManager Input - Instance Manager pointer
* @param event_num Output - Return the number of associated events.
* @retval -1 in case of error. n > 1 for success n=number of events.
*/
366 int open( const ACE_TCHAR* config_file , const ACE_TCHAR* idn_instance ,
367 const ACE_TCHAR* typ_instance , const ACE_TCHAR* con_info ,
368 OSM_AG_InsManager* InsManager , int* event_num );
/**
* Frees the memory allocated by the local array of events. Previously performs
* the deregistration of timers within the reactor.
* @retval -1 in case of error. n > 1 for success n=number of events deregistered.
*/
375 virtual int close( );
/**
* Returns the instance Id or code.
*/
380 ACE_TCHAR* idn_instance( void )
{
return this->idn_instance_;
};
/**
* Returns the instance type.
*/
388 ACE_TCHAR* typ_instance( void )
{
return this->typ_instance_;
};
/**
* Try to connect to whatever kind of instance you are coding.
* It uses the connection string to perform the connection.
* When inherite from this class you may add connection structure and new
* methods.
* @retval -1 in case of error.0 for success.
*/
400 virtual int connect( void );
/**
* Disconnect from the current instance. Instance connection structure
* cleaning.
* @retval -1 in case of error.0 for success.
*/
407 virtual int disconnect( const int force=0 );
/// Returns a pointer to the Instance Manager.
410 OSM_AG_InsManager* ins_manager( );
/**
* Checks the connection information.
* @retval -1 in case of error.0 for success.
*/
416 virtual int check_conn_info( const ACE_TCHAR* conn_info );
/// Returns connection state.
419 int connected( )
{
return this->connected_;
};
/// Sets connection state.
425 void connected( const int connected )
{
this->connected_ = connected;
};
private:
/// Destroy the array of events after call their close( ) method.
433 int destroy_events( void );
/**
* Create the array of events and call their open( ) method.
* @retval -1 in case of error.0 for success.
*/
439 int create_events( void );
/// Print out the instance retrieved info and associated events. Debug porpuse.
442 void print( );
/**
* Checks the command line of the event read from the config file.
* Normally the command line is:
* -t SECONDS_TO_EXECUTE_THIS_EVENT -c COMPARE_MODE -w WARN_LIMIT -a ALAR_LIMIT -s
* @param cmdline - command line to parse * -t SECONDS_TO_EXECUTE_THIS_EVENT -c COMPARE_MODE -w WARN_LIMIT -a ALAR_LIMIT -s
* @param value - number of seconds to execute this event in a periodic way.
* @param mode - Type of compare mode.
* @param warn - Warning limit.
* @param alar - Critical limit
* @param silent - Silent mode
* @retval -1 in case of error.0 for success.
*/
456 int parse_event_cmdline( const ACE_TCHAR* cmdline,
int &value,
int &mode,
int &warn,
int &alar,
int &silent );
/// Instance unique identification.
465 ACE_TCHAR idn_instance_ [OSM_Message::CODLEN + 1];
/// Instance Type.
467 ACE_TCHAR typ_instance_ [OSM_Message::TYPLEN + 1];
/// Absolute Path to configuration file
469 ACE_TCHAR config_file_ [MAXPATHLEN + 1];
///
471 ACE_TCHAR connection_info_ [BUFSIZ];
/// Number of events read from the config fiel and active.
long event_number_;
/// Array of events to be polled.
477 OSM_Event** event_array_ ; // Shouldn't it be a container instead?.
/// Pointer to the Instance Manager Service. Used to send messages.
480 OSM_AG_InsManager* ins_manager_;
/// Connection state.
int connected_;
};
/*----------------------------------------------------------------------------*/
/* OSM_AG_InsManager */
/*----------------------------------------------------------------------------*/
/**
* @class OSM_AG_InsManager
*
* @brief Creates instances and events from config_file and start monitoring.
*
* With this service read how many instances and events we must monitor. We
* create all the needed objects and register the events ( inherited from
* ACE_EVent_Handler ) and all the timers with the Reactor.
* Instance Manage can re-read the configuration file shutting down and freeing
* the memory correctly.
*/
500 class OSM_AG_InsManager
{
protected:
/// Factory that actively connects the OSM_AG_MsgSender.
504 OSM_Instance_Base** osm_instance_array_;
/// Number of instances managed by me.
int osm_instance_number_;
/// The OSM_AG_MsgManager used to send messages via its put( ) method.
508 OSM_AG_MsgManager* msg_manager_;
/// Complete path to configuration file.
510 ACE_TCHAR config_file_[MAXPATHLEN+1];
/// Configuragtion Heap
512 ACE_Configuration_Heap cfg_;
/// Used to fetch different section or instances
514 ACE_Configuration_Section_Key cfg_section_;
private:
/// Constructor.
518 OSM_AG_InsManager( OSM_AG_MsgManager* msg_manager ): osm_instance_number_( 0 )
{ this->msg_manager_ = msg_manager;};
/**
* Frees allocated memory.
* @retval -1 in case of error.0 for success.
*/
525 int destroy_instances( void );
/**
* Creates the necessary instance objects.
* @retval -1 in case of error.0 for success.
*/
531 int create_instances( void );
/// Reference to the singleton instance.
static OSM_AG_InsManager* instance_;
public:
/// Returns singleton.
539 static OSM_AG_InsManager *instance ( void );
/// Make initial task to run the MSG_Manager Service within Osmius agent.
542 int init( int argc, ACE_TCHAR *argv[] );
/// Perform the final task to end the MSG_Manager Service.
544 int fini ( );
/**
* Reload Configuration: Frees allocated memory, if any, and restarts the
* instances and events registering them with the reactor.
* @retval -1 in case of error.0 for success.
*/
551 int reload( );
/**
* Used tu send messages wrapped into ACE_Message_Block to whatever site.
* @retval -1 in case of error.0 for success.
*/
557 int put( ACE_Message_Block* mblk, ACE_Time_Value* tm )
{
if ( 0 != this->msg_manager_ )
{
return this->msg_manager_->put( mblk, tm );
}
return -1;
}
};
/**
* @class OSM_ACT_ExecuteProcess
*
* @brief This action can execute a command in the host machine in a portable way.
*
*
*/
575 class OSM_ACT_ExecuteProcess : public OSM_Action_Base
{
public:
/// Constructor.
580 OSM_ACT_ExecuteProcess( ) : cmd_checked_( 0 ) {};
/**
* Executes the action using the command line and returns the associated text
* and value.
* @param cmd_line Input - Command line used to execute this action.
* @param cmd_len Input - Command line length.
* @param timeout Input - Wait timeout seconds before aborting execution.
* @param val_text Output - Standard and error output of the process.
* @param val_len Output - Output length.
* @param value Output - Exit code.
* @retval -1 in case of error. 0 for success.
*/
592 int execute( const ACE_TCHAR* cmd_line, const int cmd_len,
593 const int timeout, ACE_TCHAR* val_text,
int& val_len, int &value );
/**
* Checks the command line. You should overwrite this method to handle issues
* like semantic and sintactic checking or security stuff.
* @param cmd_line Input - Command line used to execute this action.
* @param cmd_len Input - Command line length.
* @retval -1 in case of error. 0 for success.
*/
603 int check_cmd_line( const ACE_TCHAR* cmd_line, const int cmd_len );
private:
int value_;
/// Process structure to execute against local host machine in a portable way.
609 OSM_Process process_;
/// To keep if we've already checked the command line.
int cmd_checked_;
};
/**
* @class OSM_ACT_IP4Interfaces
*
* @brief Retrieves number of active IP4 interfaces
*
*/
622 class OSM_ACT_IP4Interfaces : public OSM_Action_Base
{
public:
/// Constructor.
626 OSM_ACT_IP4Interfaces( ): num_if_( 0 )
{
};
/**
* Executes the action using the command line and returns the associated text
* and value.
* @param cmd_line Input - Command line used to execute this action.
* @param cmd_len Input - Command line length.
* @param timeout Input - Wait timeout seconds before aborting execution.
* @param val_text Output - Text of the resulting action.
* @param val_len Output - Text length.
* @param value Output - Uptime seconds.
* @retval -1 in case of error. 0 for success.
*/
641 int execute( const ACE_TCHAR* cmd_line, const int cmd_len ,
642 const int timeout , ACE_TCHAR* val_text,
int& val_len , int& value );
/**
* Checks the command line.
* @param cmd_line Input - Command line used to execute this action.
* @param cmd_len Input - Command line length.
* @retval -1 in case of error. 0 for success.
*/
//int check_cmd_line( const ACE_TCHAR* cmd_line, const int cmd_len );
private:
654 size_t num_if_;
655 ACE_INET_Addr* addr_array_;
};
/**
* @class OSM_ACT_IP6Interfaces
*
* @brief Retrieves number of active IP6 interfaces
*
*/
664 class OSM_ACT_IP6Interfaces : public OSM_Action_Base
{
public:
/// Constructor.
668 OSM_ACT_IP6Interfaces( ): num_if_( 0 )
{
};
/**
* Executes the action using the command line and returns the associated text
* and value.
* @param cmd_line Input - Command line used to execute this action.
* @param cmd_len Input - Command line length.
* @param timeout Input - Wait timeout seconds before aborting execution.
* @param val_text Output - Text of the resulting action.
* @param val_len Output - Text length.
* @param value Output - Uptime seconds.
* @retval -1 in case of error. 0 for success.
*/
683 int execute( const ACE_TCHAR* cmd_line, const int cmd_len ,
684 const int timeout , ACE_TCHAR* val_text,
int& val_len , int& value );
/**
* Checks the command line.
* @param cmd_line Input - Command line used to execute this action.
* @param cmd_len Input - Command line length.
* @retval -1 in case of error. 0 for success.
*/
//int check_cmd_line( const ACE_TCHAR* cmd_line, const int cmd_len );
private:
696 size_t num_if_;
697 ACE_INET_Addr* addr_array_;
};
/**
* @class OSM_ACT_ScanLog
*
* @brief Search if a string has been written in a log file.
*
*/
707 class OSM_ACT_ScanLog : public OSM_Action_Base
{
public:
enum
{
OSM_SCANLOG_BUFSIZ = 8*1024
};
/// Constructor.
716 OSM_ACT_ScanLog( ): cmd_line_checked_( 0 ), last_size_( 0 )
{
log_file_ [0] = 0;
string_ [0] = 0;
};
/**
* Executes the action using the command line and returns the associated text
* and value.
* @param cmd_line Input - Command line used to execute this action.
* @param cmd_len Input - Command line length.
* @param timeout Input - Wait timeout seconds before aborting execution.
* @param val_text Output - Text of the resulting action.
* @param val_len Output - Text length.
* @param value Output - Uptime seconds.
* @retval -1 in case of error. 0 for success.
*/
733 int execute( const ACE_TCHAR* cmd_line, const int cmd_len ,
734 const int timeout , ACE_TCHAR* val_text,
int& val_len , int& value );
/**
* Checks the command line.
* @param cmd_line Input - Command line used to execute this action.
* @param cmd_len Input - Command line length.
* @retval -1 in case of error. 0 for success.
*/
743 int check_cmd_line( const ACE_TCHAR* cmd_line, const int cmd_len );
private:
int cmd_line_checked_;
long last_size_;
748 FILE* fd_;
749 ACE_TCHAR log_file_[BUFSIZ+1];
750 ACE_TCHAR string_[BUFSIZ+1];
751 ACE_TCHAR auxbuf_[OSM_SCANLOG_BUFSIZ+1];
};
#endif /* _OSM_AG_INSMANAGER_H_ */
1 // -*- C++ -*-
// -----------------------------------------------------------------------------
/*
* Osmius and its code is copyright of Peopleware S.L. Spain.
* http://www.peopleware.es
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* ( at your option ) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
// -----------------------------------------------------------------------------
/**
* @file osm_ag_msgmanager.cpp
* @brief Implementation file for the MSG_MANAGER service of Osmius Agents.
*
* @author Jose Luis Marina <joseluis.marina@peopleware.es>
* @date 15-JUN-2006
*/
// -----------------------------------------------------------------------------
// These are standard includes for any program
#include "osm_ag_msgmanager.h"
#include "../cm/osm_message.h"
#if defined ( ACE_WIN32 )
#include <ace/OS.h>
#endif /* ( ACE_WIN32 ) */
//#include "../cm/osm_cfgmanager.h"
//#include <ace/OS.h>
//#include <ace/Log_Msg.h>
// Specific module includes.
#include <ace/Get_Opt.h>
#include <ace/Signal.h>
/*----------------------------------------------------------------------------*/
/* OSM_AG_MsgSender Implementation */
/*----------------------------------------------------------------------------*/
int
54 OSM_AG_MsgSender::open ( void *connector )
{
ACE_TCHAR aux_str[BUFSIZ+1]="N";
this->mode_= -1;
// Lets see if we have a command to send messages.
if ( -1 == OSM_CfgManager::instance( )->get_value_str( "SNDCMD", aux_str, BUFSIZ ) )
{
ACE_OS::strcpy( aux_str, "N" );
}
if ( ( 1 == ACE_OS::strlen( aux_str ) )&&( 'N' == aux_str[0] ) )
{
this->mode_ = OSM_SNDMODE_NET;
ACE_OS::strcpy( this->command_, "" );
}
else
{
ACE_OS::strcpy( this->command_, aux_str );
#ifdef ACE_WIN32
if ( ACE_DIRECTORY_SEPARATOR_CHAR_A != this->command_[2] )
{
ACE_ERROR ( ( LM_ERROR,
ACE_TEXT ( "AG_MsgSender - open( ) Command [%s] needs to be an absolute path\n" ),
this->command_ ) );
return -1;
}
#else
if ( ACE_DIRECTORY_SEPARATOR_CHAR_A != this->command_[0] )
{
ACE_ERROR ( ( LM_ERROR,
ACE_TEXT ( "AG_MsgSender - open( ) Command [%s] needs to be an absolute path\n" ),
this->command_ ) );
return -1;
}
#endif
if ( connector )
{
this->mode_ = OSM_SNDMODE_BOZ;
}
else
{
this->mode_ = OSM_SNDMODE_CMD;
}
}
if ( 0 == connector && ( ( OSM_SNDMODE_BOZ == this->mode_ )||( OSM_SNDMODE_NET == this->mode_ ) ) )
{
ACE_ERROR ( ( LM_ERROR, ACE_TEXT ( "AG_MsgSender - open( ) Bad Connector\n" ) ) );
return -1;
}
if ( connector )
{
// Assign the connector.
connector_ = static_cast<OSM_AG_MsgConnector *> ( connector );
// Try to set the maximum buffer size for the sockect,
int bufsiz = ACE_DEFAULT_MAX_SOCKET_BUFSIZ;
peer ( ).set_option ( SOL_SOCKET, SO_SNDBUF, &bufsiz, sizeof bufsiz );
// Register with the singleton reactor for incomming data in the socket.
// If we receive data it seems the server has disconnect from us.
// We will handle this situation in handle_input( ).
if ( reactor ( )->register_handler
( this, ACE_Event_Handler::READ_MASK ) == -1 )
{
ACE_ERROR ( ( LM_ERROR, ACE_TEXT (
"AG_MsgSender - open( ) Could Not register with the Reactor\n" ) ) );
return -1;
}
}
#if defined( OSM_NO_THREADS )
return 0;
#endif // OSM_NO_THREADS
int i_qsize=0;
// Get the max queue size parameter for the Message Sender ( in kbytes ).
if ( -1 == OSM_CfgManager::instance( )->get_value_int( "MSGQSI", &i_qsize ) )
{
ACE_ERROR ( ( LM_ERROR,
ACE_TEXT ( "AG_MsgSender - Could not get MSGQSI. Using 16.\n" ) ) );
i_qsize = 16 * 1024;
}
else
{
i_qsize = i_qsize * 1024;
}
// Get the timeout parameter for network operations.
if ( -1 == OSM_CfgManager::instance( )->get_value_int( "TIMOUT", &this->i_timeout_ ) )
{
ACE_ERROR ( ( LM_ERROR,
ACE_TEXT( "AG_MsgSender - svc( ) Could not get TIMOUT\n" ) ) );
this->i_timeout_ = 120;
}
// Get the time buffer parameter to wait until send messages.
if ( -1 == OSM_CfgManager::instance( )->get_value_int( "TIMBUF", &this->i_timbuf_ ) )
{
ACE_ERROR ( ( LM_ERROR,
ACE_TEXT( "AG_MsgSender - svc( ) Could not get TIMBUF\n" ) ) );
this->i_timbuf_ = 20;
}
if ( this->i_timbuf_ < 0 ) this->i_timbuf_ = 0;
// Lets see if the queue is active. If it is we activate our selves ( svc( ) ).
if ( ACE_Message_Queue_Base::ACTIVATED == msg_queue ( )->activate ( ) )
{
msg_queue ( )->high_water_mark ( i_qsize );
return activate ( THR_NEW_LWP | THR_DETACHED ); //( THR_SCOPE_SYSTEM );
}
ACE_DEBUG ( ( LM_DEBUG, ACE_TEXT(
"AG_MsgSender - Queue not activated. Service already executing?\n" ) ) );
return 0;
}
/*----------------------------------------------------------------------------*/
int
175 OSM_AG_MsgSender::put( ACE_Message_Block *mblk, ACE_Time_Value *tm )
{
// We can choose to process the message or to differ it into the message
// queue, and process them into the svc( ) method. We chose the last option.
int retval;
// Statistics
if ( OSM_CfgManager::instance( )->debug_mode( ) )
{
ACE_Thread_Mutex mutex;
ACE_Guard <ACE_Thread_Mutex> guard ( mutex );
OSM_CfgManager::instance( )->counter( OSM_STAT_EVENTS,
OSM_CfgManager::instance( )->counter( OSM_STAT_EVENTS ) + 1 );
}
// ------------------------------------------------------------------------------------
#if defined( OSM_NO_THREADS )
if ( ( 0 == mblk->size ( ) ) )
{
mblk->release ( );
ACE_Reactor::instance ( )->end_reactor_event_loop ( );
return 0;
}
retval=1;
this->send( &mblk, ( size_t& )retval );
return 0;
#endif // OSM_NO_THREADS
// ------------------------------------------------------------------------------------
while ( ( retval = putq ( mblk, tm ) ) == -1 )
{
if ( msg_queue ( )->state ( ) != ACE_Message_Queue_Base::PULSED )
break;
}
return retval;
}
/*----------------------------------------------------------------------------*/
int
213 OSM_AG_MsgSender::handle_input( ACE_HANDLE h )
{
ACE_DEBUG ( ( LM_DEBUG, ACE_TEXT(
"AG_MsgSender - handle_input( ) called.It seems the Master Agent is down.\n" ) ) );
peer ( ).close ( );
reactor ( )->remove_handler
( h, ACE_Event_Handler::READ_MASK
| ACE_Event_Handler::DONT_CALL );
msg_queue ( )->pulse ( );
return 0;
}
/*----------------------------------------------------------------------------*/
226 int OSM_AG_MsgSender::handle_close ( ACE_HANDLE handle, ACE_Reactor_Mask mask )
{
if ( OSM_CfgManager::instance( )->debug_mode( ) )
{
ACE_DEBUG( ( LM_DEBUG,
ACE_TEXT( "( %P|%T ) AG_Sender: handle_close( ) called.\n" ) ) );
}
ACE_OS::closesocket ( handle );
this->peer( ).close( );
PARENT::handle_close ( handle, mask );
return 0;
}
/*----------------------------------------------------------------------------*/
int
245 OSM_AG_MsgSender::svc( )
{
ACE_Message_Block *chunk[ACE_IOV_MAX];
size_t message_index = 0;
ACE_Time_Value time_of_last_send ( ACE_OS::gettimeofday ( ) );
ACE_Time_Value timeout;
// Lets avoid interruptions while working on this.
ACE_Sig_Action no_sigpipe ( ( ACE_SignalHandler ) SIG_IGN );
ACE_Sig_Action original_action;
no_sigpipe.register_action ( SIGPIPE, &original_action );
// ---------------------------------------------------------------------------
// Read for ever.
// ---------------------------------------------------------------------------
for ( ;; )
{
if ( message_index == 0 )
{
timeout = ACE_OS::gettimeofday ( );
timeout += this->i_timeout_;
}
ACE_Message_Block *mblk = 0;
ACE_OS::last_error( 0 );
// -------------------------------
// Read messages from the queue. |
// -------------------------------
if ( getq ( mblk, &timeout ) == -1 )
{
if ( ACE_OS::last_error( ) == ESHUTDOWN )
{
if ( this->connector_->reconnect ( ) == -1 ) break;
continue;
}
else if ( ACE_OS::last_error( ) != EWOULDBLOCK ) break;
else if ( message_index == 0 ) continue;
}
else // Read one message.
{
// If someone has send a MB_STOP message we must quit.
if ( ( 0 == mblk->size ( ) )
&& ( mblk->msg_type ( ) == ACE_Message_Block::MB_STOP ) )
{
mblk->release ( );
break;
}
// else... put the message into the bulk vector.
chunk[message_index] = mblk;
++message_index;
}
// If chuck[] array is full or we've reached the timeout -> send messages.
if ( message_index >= ACE_IOV_MAX ||
( ACE_OS::gettimeofday ( ) - time_of_last_send
>= ACE_Time_Value( this->i_timbuf_ ) ) || !this->i_timbuf_ )
{
if ( send ( chunk, message_index ) == -1 ) break; // Sent failed.
time_of_last_send = ACE_OS::gettimeofday ( );
}
}
// Send the last messages. We are shutting down.
if ( message_index > 0 ) send ( chunk, message_index );
// Restore interruptions.
no_sigpipe.restore_action ( SIGPIPE, original_action );
if ( OSM_CfgManager::instance( )->debug_mode( ) )
{
ACE_ERROR ( ( LM_ERROR, ACE_TEXT (
"AG_MsgSender - svc( ) exit MB_STOP Received or reconnect failed\n" ) ) );
}
// We must shutdown the complete process.
// ACE_Message_Block *shutdown_message = 0;
// ACE_NEW_RETURN
// ( shutdown_message,
// ACE_Message_Block ( 0, ACE_Message_Block::MB_STOP ), -1 );
// this->put ( shutdown_message );
// AKI REVISAR O BORRAR SI TODO VA BIEN
//-> ACE_Reactor::instance ( )->end_reactor_event_loop ( );
return -1;
}
/*----------------------------------------------------------------------------*/
int
330 OSM_AG_MsgSender::send( ACE_Message_Block *chunk[], size_t &count )
{
iovec iov[ACE_IOV_MAX];
size_t iov_size;
int result = 0;
OSM_Message* osm_msg=0;
int exit_code=0;
int output_len=BUFSIZ;
// Statistics
if ( OSM_CfgManager::instance( )->debug_mode( ) )
{
OSM_CfgManager::instance( )->counter( OSM_STAT_MSGSND,
OSM_CfgManager::instance( )->counter( OSM_STAT_MSGSND ) + count );
}
for ( iov_size = 0; iov_size < count; ++iov_size )
{
osm_msg= ( OSM_Message* ) chunk[iov_size]->rd_ptr( );
iov[iov_size].iov_base = ( char * )&osm_msg->net_message_;
// This lenght( ) mut be set using rd_ptr( ) and wr_ptr( )!!
iov[iov_size].iov_len = chunk[iov_size]->length( );
// Only for debug porpuses.
// osm_msg->print( );
if ( ( OSM_SNDMODE_CMD == this->mode_ )||( OSM_SNDMODE_BOZ == this->mode_ ) )
{
// The parameters always are in the same order:
// 1 - typ_agent
// 2 - typ_instance
// 3 - idn_instance
// 4 - typ_event
// 5 - typ_alarm
// 6 - dti_inievent
// 7 - dti_finevent
// 8 - num_value
// 9 - "txt_message"
ACE_OS::sprintf( this->exec_command_, "%s %s %s %s %s %s %s %s %s \"%s\"",
this->command_ ,
osm_msg->typ_agent( ) ,
osm_msg->typ_instance( ) ,
osm_msg->idn_instance( ) ,
osm_msg->typ_event( ) ,
osm_msg->typ_alarm( ) ,
osm_msg->dti_inievent( ) ,
osm_msg->dti_finevent( ) ,
osm_msg->num_value( ) ,
osm_msg->txt_message( ) );
// We're using timeout = 0 after several probes on HP-UX...
// We don't need to store the output of the command so we assign 0 to output_len.
// Comment out next line to store the command output.
output_len = 0;
if ( 0 > this->process_.execute( this->exec_command_, "", "", exit_code , 0, this->output_, output_len ) )
{
ACE_ERROR ( ( LM_ERROR, ACE_TEXT (
"AG_MsgSender - send( ) Could not execute command: [%s] exit code: %d.\n" ),
this->exec_command_,
exit_code ) );
}
}
}
if ( ( OSM_SNDMODE_NET == this->mode_ )||( OSM_SNDMODE_BOZ == this->mode_ ) )
{
while ( -1 == peer( ).sendv_n( iov, iov_size ) )
{
// Send failed so we'll try to reconnect and send again.
if ( this->connector_->reconnect ( ) == -1 )
{
ACE_ERROR ( ( LM_ERROR, ACE_TEXT (
"AG_MsgSender - send( ) Could not reconnect to server.\n" ) ) );
result = -1;
break;
}
}
}
while ( iov_size > 0 ) {
delete chunk[--iov_size]->rd_ptr( ); // Delete OSM_Message.
chunk[iov_size]->release ( ); chunk[iov_size] = 0; // Delete ACE_Msg_Block.
}
count = iov_size;
return result;
}
/*----------------------------------------------------------------------------*/
/* OSM_AG_MsgConnector Implementation */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* If we want to use SSL use implement theese methods.*/
int
423 OSM_AG_MsgConnector::open ( ACE_Reactor *r, int flags )
{
if ( PARENT::open ( r, flags ) != 0 ) return -1;
// SSL stuff...
return 0;
}
/*----------------------------------------------------------------------------*/
int
432 OSM_AG_MsgConnector::connect_svc_handler
433 ( OSM_AG_MsgSender *&svc_handler,
434 const ACE_SOCK_Connector::PEER_ADDR &remote_addr,
435 ACE_Time_Value *timeout,
436 const ACE_SOCK_Connector::PEER_ADDR &local_addr,
int reuse_addr, int flags, int perms )
{
if ( PARENT::connect_svc_handler
( svc_handler, remote_addr, timeout,
local_addr, reuse_addr, flags, perms ) == -1 ) return -1;
remote_addr_ = remote_addr;
return 0;
}
/*----------------------------------------------------------------------------*/
int
448 OSM_AG_MsgConnector::connect_svc_handler
449 ( OSM_AG_MsgSender *&svc_handler,
450 OSM_AG_MsgSender *&sh_copy,
451 const ACE_SOCK_Connector::PEER_ADDR &remote_addr,
452 ACE_Time_Value *timeout,
453 const ACE_SOCK_Connector::PEER_ADDR &local_addr,
int reuse_addr, int flags, int perms )
{
sh_copy = svc_handler;
return this->connect_svc_handler ( svc_handler, remote_addr, timeout,
local_addr, reuse_addr, flags, perms );
}
/*----------------------------------------------------------------------------*/
int
463 OSM_AG_MsgConnector::reconnect ( )
{
// Get the number of retries.
int i_reconn_tries;
if ( -1 == OSM_CfgManager::instance( )->get_value_int( "RECONN", &i_reconn_tries ) )
{
ACE_ERROR ( ( LM_ERROR, ACE_TEXT (
"MsgConnector - Could not get RECONN parameter\n" ) ) );
i_reconn_tries = 4;
}
if ( OSM_CfgManager::instance( )->debug_mode( ) )
{
ACE_DEBUG( ( LM_DEBUG,
ACE_TEXT ( "( %P|%T ) MSG_Connector: reconnect( ) to Master. Trying %d times\n" ),
i_reconn_tries ) );
}
ACE_Time_Value timeout ( 1 );
int i;
for ( i = 0; i < i_reconn_tries ; ++i )
{
// Statistics
if ( OSM_CfgManager::instance( )->debug_mode( ) )
{
OSM_CfgManager::instance( )->counter( OSM_STAT_RECONN,
OSM_CfgManager::instance( )->counter( OSM_STAT_RECONN ) + 1 );
}
ACE_Synch_Options options ( ACE_Synch_Options::USE_TIMEOUT, timeout );
if ( i > 0 ) ACE_OS::sleep ( timeout );
if ( connect ( svc_handler_, remote_addr_, options ) == 0 )
{
break;
}
timeout *= 2;
}
if ( i == i_reconn_tries )
{
ACE_ERROR ( ( LM_ERROR,
ACE_TEXT( "( %P|%T ) MSG_Connector: reconnect( ) failed after %d retries\n" ),
i_reconn_tries ) );
return -1;
}
return 0;
}
/*----------------------------------------------------------------------------*/
/* OSM_AG_MsgManager Implementation */
/*----------------------------------------------------------------------------*/
// Static initialization.
OSM_AG_MsgManager *OSM_AG_MsgManager::instance_ = 0;
/*----------------------------------------------------------------------------*/
516 OSM_AG_MsgManager* OSM_AG_MsgManager::instance ( void )
{
if ( 0 == OSM_AG_MsgManager::instance_ )
ACE_NEW_RETURN ( OSM_AG_MsgManager::instance_, OSM_AG_MsgManager, 0 );
return OSM_AG_MsgManager::instance_;
}
/*----------------------------------------------------------------------------*/
int
525 OSM_AG_MsgManager::init ( int argc, ACE_TCHAR *argv[] )
{
u_short master_port = 1970;
ACE_TCHAR cmd[MAXPATHLEN+1]="";
int opt_m=0;
int opt_C=0;
ACE_Get_Opt get_opt ( argc, argv, ACE_TEXT ( "m:C:" ), 0 );
get_opt.long_option ( ACE_TEXT ( "master_port" ), 'm',
ACE_Get_Opt::ARG_REQUIRED );
get_opt.long_option ( ACE_TEXT ( "send_command" ), 'C',
ACE_Get_Opt::ARG_REQUIRED );
for ( int c; ( c = get_opt ( ) ) != -1; )
{
switch ( c )
{
case 'm':
master_port = static_cast<u_short> ( ACE_OS::atoi ( get_opt.opt_arg ( ) ) );
opt_m++;
break;
case 'C':
ACE_OS::strcpy( cmd, get_opt.opt_arg ( ) );
opt_C++;
break;
}
}
if ( ( opt_m !=1 )||( opt_C !=1 )||( !opt_m )&&( !opt_C ) )
{
if ( !master_port )
{
ACE_ERROR( ( LM_ERROR, ACE_TEXT (
"MSG_Manager - PORTMA or SNDCMD needed.\n\tQuitting...\n" ) ) );
return -1;
}
}
if ( master_port )
{
//En windows parece que no funciona
//ACE_INET_Addr master_addr ( master_port );
// Command Manager Accept and Sent Commands
ACE_TCHAR szmaster[2*MAXHOSTNAMELEN+1];
ACE_OS::sprintf( szmaster, "127.0.0.1:%d", master_port );
ACE_INET_Addr master_addr ( szmaster );
if ( OSM_CfgManager::instance( )->debug_mode( ) )
{
ACE_DEBUG ( ( LM_DEBUG, ACE_TEXT (
"( %P|%T ) MSG_Manager - init_work( ) Sending Messages to Port: %d Connecting\n" ),
master_port ) );
}
ACE_OS::last_error( 0 );
OSM_AG_MsgSender *m_sender = &this->msg_sender_;
if ( -1 == this->connector_.connect ( m_sender, master_addr ) )
{
ACE_ERROR( ( LM_ERROR, ACE_TEXT (
"MSG_Manager - Could not initialize.\n\tQuitting...\n" ),
master_port ) );
this->connector_.close ( );
return -1; // If the master is not there we don't even start.
}
}
if ( ACE_OS::strlen( cmd ) > 2 )
{
if ( OSM_CfgManager::instance( )->debug_mode( ) )
{
ACE_DEBUG ( ( LM_DEBUG, ACE_TEXT (
"( %P|%T ) MSG_Manager - init_work( ) Sending Command is: [%s]\n" ),
cmd ) );
}
FILE* pf = ACE_OS::fopen( cmd, ACE_LIB_TEXT( "r" ) );
if ( 0 == pf )
{
ACE_ERROR( ( LM_ERROR, ACE_TEXT (
"MSG_Manager - Could not read open [%s].\n\tQuitting...\n" ),
cmd ) );
return -1;
}
ACE_OS::fclose( pf );
if ( !master_port )
{
if ( -1 == this->msg_sender_.open( 0 ) )
{
return -1;
}
}
}
else
{
if ( !master_port )
{
ACE_ERROR( ( LM_ERROR, ACE_TEXT (
"MSG_Manager - PORTMA Needed.\n\tQuitting...\n" ) ) );
return -1;
}
}
return 0;
}
/*----------------------------------------------------------------------------*/
631 int OSM_AG_MsgManager::fini ( )
{
if ( OSM_CfgManager::instance( )->debug_mode( ) )
{
ACE_DEBUG( ( LM_DEBUG,
ACE_TEXT ( "MSG_Manager - fini( ) Ending MSG_Manager Service.\n" ) ) );
}
ACE_Message_Block *shutdown_message = 0;
ACE_NEW_RETURN
( shutdown_message,
ACE_Message_Block ( 0, ACE_Message_Block::MB_STOP ), -1 );
this->put ( shutdown_message );
this->msg_sender( )->wait( );
this->connector_.close ( );
return this->msg_sender( )->close( );
}
/*----------------------------------------------------------------------------*/
// -*- C++ -*-
// -----------------------------------------------------------------------------
/*
* Osmius and its code is copyright of Peopleware S.L. Spain.
* http://www.peopleware.es
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* ( at your option ) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
// -----------------------------------------------------------------------------
/**
* @file osm_ag_msgmanager.h
* @brief Interface and definition file for the Agent MSG_MANAGER service.
* Osmius - Peopleware.
*
* @author Jose Luis Marina <joseluis.marina@peopleware.es>
* @date 07-APR-2006
*/
// -----------------------------------------------------------------------------
#ifndef _OSM_AG_MSGMANAGER_H_
#define _OSM_AG_MSGMANAGER_H_
#include "../cm/osm_cfgmanager.h"
// include appropriate socket and address includes
//#include <ace/SOCK_Stream.h>
//#include <ace/INET_Addr.h>
// Specific includes.
#include <ace/Svc_Handler.h>
#include <ace/SOCK_Connector.h>
#include <ace/Connector.h>
// -----------------------------------------------------------------------------
// Explicit template instantiations. OBSOLETE.
// -----------------------------------------------------------------------------
//#if defined ( ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION )
#if defined ( OSM_NO_THREADS )
52 template class ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>; // NO_THREADS ACE_MT_SYNCH o ACE_NULL_SYNCH
#endif // OSM_NO_THREADS
#if !defined ( OSM_NO_THREADS )
55 template class ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_MT_SYNCH>; // NO_THREADS ACE_MT_SYNCH o ACE_NULL_SYNCH
#endif // !OSM_NO_THREADS
//#elif defined ( ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA )
//#if defined ( OSM_NO_THREADS )
//#pragma instantiate ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>; // NO_THREADS ACE_MT_SYNCH o ACE_NULL_SYNCH
//#endif //!OSM_NO_THREADS
//#if !defined ( OSM_NO_THREADS )
//#pragma instantiate ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_MT_SYNCH>; // NO_THREADS ACE_MT_SYNCH o ACE_NULL_SYNCH
//#endif //!OSM_NO_THREADS
//#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
// -----------------------------------------------------------------------------
/// Indexes for the statistical values. See osm_master_agent.h
// -----------------------------------------------------------------------------
enum
{
/// Number of sended messages.
OSM_STAT_MSGSND = 0,
/// Number of reconnections.
OSM_STAT_RECONN = 1,
/// Events processed
OSM_STAT_EVENTS = 2
};
/*----------------------------------------------------------------------------*/
// Forwarded declarations.
80 class OSM_AG_MsgConnector;
/*----------------------------------------------------------------------------*/
/* OSM_AG_MsgSender */
/*----------------------------------------------------------------------------*/
/**
* @class OSM_AG_MsgSender
*
* @brief Send message to the master agent in bulk groups.
*
* We use the put( ) method to access this class and send the Blk to the local
* queue. The svc( ) method will run its own thread to send messages in the
* queue to the server through the Connector.
* Implements the active service part in the Connector Pattern.
*
*/
#if defined ( OSM_NO_THREADS )
class ACE_Svc_Export OSM_AG_MsgSender
: public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> // NO_THREADS ACE_NULL_SYNCH o ACE_MT_SYNCH
#endif
#if !defined ( OSM_NO_THREADS )
class OSM_AG_MsgSender
: public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_MT_SYNCH> // NO_THREADS ACE_NULL_SYNCH o ACE_MT_SYNCH
#endif
{
public:
enum
{
/// Sending mode: Over the NET.
OSM_SNDMODE_NET = 0,
/// Sending mode: Execute a command.
OSM_SNDMODE_CMD = 1,
/// Sending mode: Both net and command.
OSM_SNDMODE_BOZ = 2
};
#if defined ( OSM_NO_THREADS )
/// typedef PARENT
typedef ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> PARENT;
#endif
#if !defined ( OSM_NO_THREADS )
/// typedef PARENT
typedef ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_MT_SYNCH> PARENT;
#endif
/**
* This is the initialization hook method. It will receive the connector, and
* after initialization tasks will activate the object ( run svc( ) method ).
* @retval -1 in case of error.
*/
virtual int open( void* conn );
/**
* This is the entry point into the class to process messages.
* Basically it puts the mblk in the local queue.
*/
virtual int put( ACE_Message_Block* mblk, ACE_Time_Value* = 0 );
/**
* handle_close( ) will be called when a client agent quits.
* So lets close the socket
*/
virtual int handle_close ( ACE_HANDLE h= ACE_INVALID_HANDLE,
ACE_Reactor_Mask mask = 0 );
protected:
/**
* Timeout for queue and networking operations
*/
int i_timeout_;
/**
* Time buffer for messages.
*/
int i_timbuf_;
/**
* Connector used to send messages to the server.
*/
OSM_AG_MsgConnector *connector_;
/**
* Processor used to execute command if supplied.
*/
OSM_Process process_;
/**
* Sender Mode
*/
int mode_;
/**
* Command to execute when "sending" messages.
*/
ACE_TCHAR command_[MAXPATHLEN+1];
/**
* Character string to hold the execute command
*/
ACE_TCHAR exec_command_[BUFSIZ+1];
/**
* Character string to hold the output of the command
*/
ACE_TCHAR output_[BUFSIZ+1];
/**
* Will be called when the server disconnects.
*/
virtual int handle_input( ACE_HANDLE h );
/**
* Active object main( )
* Waits "for ever" for messages in the queue and sends them to the master
* agent.
* Internally uses two parameters to send the buffer: The maximum number of
* messages in the buffer, and a number of seconds since the last sent.
* These to parameters are: ACE_IOV_MAX and TIMBUF ( this is in cfg file ).
*/
virtual int svc( );
/**
* Sends the messages in bulk operations.
*/
virtual int send ( ACE_Message_Block *chunk[], size_t &count );
};
/*----------------------------------------------------------------------------*/
/* OSM_AG_MsgConnector */
/*----------------------------------------------------------------------------*/
/**
* @class OSM_AG_MsgConnector
*
* @brief Active connection to connect and keep the stream with the server.
*
* This is a "classical" ACE connector. We've added ( copying from ACE code )
*/
class OSM_AG_MsgConnector
: public ACE_Connector<OSM_AG_MsgSender, ACE_SOCK_CONNECTOR>
{
public:
/// To make fast reference to the upper class.
typedef ACE_Connector<OSM_AG_MsgSender, ACE_SOCK_CONNECTOR>
PARENT;
/// Constructor. Initialize the sender object.
OSM_AG_MsgConnector ( OSM_AG_MsgSender* handler = 0 )
: svc_handler_ ( handler ) {};
// /**
// * Open method. Call the base class open( ).
// * @retval -1 in case of error.
// */
virtual int open ( ACE_Reactor *r = ACE_Reactor::instance ( ), int flags = 0 );
/**
* Try to reconnect "RECONN" times using 2( n ) exponential intervals.
* @retval -1 in case of error.
*/
int reconnect ( );
protected:
// /**
// * Create and authenticate the connection. Hook method.
// * @retval -1 in case of error.
// */
virtual int connect_svc_handler
( OSM_AG_MsgSender *&svc_handler,
const ACE_SOCK_Connector::PEER_ADDR &remote_addr,
ACE_Time_Value *timeout,
const ACE_SOCK_Connector::PEER_ADDR &local_addr,
int reuse_addr, int flags, int perms );
/**
* Create and authenticate the connection. Hook method.
* @retval -1 in case of error.
*/
virtual int connect_svc_handler
( OSM_AG_MsgSender *&svc_handler,
OSM_AG_MsgSender *&sh_copy,
const ACE_SOCK_Connector::PEER_ADDR &remote_addr,
ACE_Time_Value *timeout,
const ACE_SOCK_Connector::PEER_ADDR &local_addr,
int reuse_addr, int flags, int perms );
/// Message sending Service.
OSM_AG_MsgSender *svc_handler_;
/// Master Agent address ( Local Port ) receiving messages.
ACE_INET_Addr remote_addr_;
};
/*----------------------------------------------------------------------------*/
/* OSM_AG_MsgManager */
/*----------------------------------------------------------------------------*/
/**
* @class OSM_AG_MsgManager
*
* @brief Receives, validates message events from agents and send them to master
*
* With this service we receive messages from events via our put( ) method.
* We store those messages into a Message Queue so the code to execute those
* events don't need to wait too much time and could continue doing their job.
* We send the messages in the queue to the master in bulk clusters of messages
* to improve performance using several threads ( This could be with a
* configurable parameter ).
* To do this we use a Connector using a message sender class.
* Implements a singleton.
*/
class OSM_AG_MsgManager
{
protected:
/// Factory that actively connects the OSM_AG_MsgSender.
OSM_AG_MsgConnector connector_;
/// The OSM_AG_MsgSender connected by OSM_AG_MsgConnector.
OSM_AG_MsgSender msg_sender_;
public:
/// Returns singleton.
static OSM_AG_MsgManager *instance ( void );
/// Make initial task to run the MSG_Manager Service within Osmius agent.
int init( int argc, ACE_TCHAR *argv[] );
/// Perform the final task to end the MSG_Manager Service.
int fini ( );
/// Just pass the call to Msg_Sender put( ).
int put( ACE_Message_Block* mblk, ACE_Time_Value* tm=0 )
{
return this->msg_sender_.put( mblk, tm );
}
/// Return a pointer to the local MSG_Sender.
OSM_AG_MsgSender* msg_sender( void )
{
return &this->msg_sender_;
}
private:
/// Constructor.
OSM_AG_MsgManager( )
: connector_( &msg_sender_ ) {};
/// Reference to the singleton instance.
static OSM_AG_MsgManager* instance_;
};
/*----------------------------------------------------------------------------*/
#endif /* _OSM_AG_MSGMANAGER_H_*/
1 // -*- C++ -*-
// -----------------------------------------------------------------------------
/*
* Osmius and its code is copyright of Peopleware S.L. Spain.
* http://www.peopleware.es
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* ( at your option ) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
// -----------------------------------------------------------------------------
/**
* @file osm_agent_basic.cpp
* @brief Basic Agent main program and functions. Use it to build your own agent.
*
* @author Jose Luis Marina <joseluis.marina@peopleware.es>
* @date 18-MAY-2006
*/
// -----------------------------------------------------------------------------
// Specific module includes.
#include "osm_agent_basic.h"
#include "osm_ag_insmanager.h"
#include "../cm/osm_reactor.h"
// ACE includes
//#include <ace/OS.h>
//#include <ace/Log_Msg.h> // Logging, trace and debug facility.
//#include <ace/Version.h> // Always in main to retrieve ACE version.
// Especific ACE includes.
#include <ace/Get_Opt.h>
#include <ace/ARGV.h>
// -----------------------------------------------------------------------------
// Implementation of MAIN program classes
// -----------------------------------------------------------------------------
// Static initialization.
OSM_AG_Main *OSM_AG_Main::instance_=0;
/*----------------------------------------------------------------------------*/
53 OSM_AG_Main::OSM_AG_Main( void )
{
ACE_OS::strcpy( PROGRAM_NAME_, "OSMIUS_AGENT" );
}
/*----------------------------------------------------------------------------*/
OSM_AG_Main*
59 OSM_AG_Main::instance ( void )
{
if ( OSM_AG_Main::instance_ == 0 )
ACE_NEW_RETURN ( OSM_AG_Main::instance_, OSM_AG_Main, 0 );
return OSM_AG_Main::instance_;
}
/*----------------------------------------------------------------------------*/
68 void OSM_AG_Main::print_usage( void )
{
ACE_DEBUG ( ( LM_DEBUG,
ACE_TEXT ( "%s - Osmius %d.%d\n"
"osmius_agent -c config_file -m master_code -p master_port [-d] [-h]\n\n"
"\t-c complete path to config file\n"
"\t-m Master Agent code CHAR[%d]\n"
"\t-p Master Agent connection port \n"
"\t-d Debug mode. More messages printed to log file\n"
"\t-h Print this info\n"
"\n"
"Osmius and its code is copyright of Peopleware S.L. Spain.\n"
"\n"
"Osmius is Open Source Software under GPL.\n"
"Osmius is based on ACE C++ frameworks\n"
"\tACE version is ACE %s\n"
"More in http://www.osmius.net\n" ),
PROGRAM_NAME_ ,
OSM_MAX_VERSION,
OSM_MIN_VERSION,
OSM_Message::CODLEN,
ACE_VERSION ) ) ;
}
/*----------------------------------------------------------------------------*/
93 int OSM_AG_Main::parse_cmd_line( int argc, ACE_TCHAR *argv[] )
{
int opt_c=0;
int opt_p=0;
int opt_m=0;
ACE_TCHAR aux_char[BUFSIZ]="";
size_t aux_len;
ACE_Get_Opt get_opt ( argc, argv, ACE_TEXT ( "c:dhp:m:" ), 0 );
OSM_CfgManager::instance( )->debug_mode( 0 );
for ( int c; ( c = get_opt ( ) ) != -1; )
{
switch ( c )
{
case 'c':
// Config File
if ( -1 == this->set_config_file( get_opt.opt_arg ( ) ) )
return -1;
opt_c++;
break;
// case 'a':
// // Agent Code is obsolete!!
// ACE_OS::strcpy( aux_char, get_opt.opt_arg ( ) );
// aux_len = ACE_OS::strlen( aux_char );
// if ( aux_len != OSM_Message::CODLEN ) return -1;
// this->idn_agent( aux_char, aux_len );
// opt_a++;
// break;
case 'p':
// Master Agent Port!!
ACE_OS::strcpy( aux_char, get_opt.opt_arg ( ) );
this->prt_master_ = ACE_OS::atoi( aux_char );
// The port could be 0 if we have SNDCMD !!!!
opt_p++;
break;
case 'm':
// Master Code!!
ACE_OS::strcpy( aux_char, get_opt.opt_arg ( ) );
aux_len = ACE_OS::strlen( aux_char );
if ( aux_len != OSM_Message::CODLEN ) return -1;
this->idn_master( aux_char, aux_len );
opt_m++;
break;
case 'd':
OSM_CfgManager::instance( )->debug_mode( 1 );
break;
default:
return -1;
}
}
if ( ( 1 == opt_c )&&( 1 == opt_p )&&( 1 == opt_m ) )
{
return 0;
}
else
{
return -1;
}
}
/*----------------------------------------------------------------------------*/
int
156 OSM_AG_Main::set_config_file( ACE_TCHAR* file )
{
register int len;
len = ACE_OS::strlen( file );
if ( ( len < 1 )||( len > MAXPATHLEN ) ) return -1;
ACE_OS::strncpy( this->config_file_, file, len );
this->config_file_[len] = '\0';
return 0;
}
/*----------------------------------------------------------------------------*/
void
168 OSM_AG_Main::typ_agent ( const ACE_TCHAR *data, const size_t len )
{
ACE_OS::strncpy( this->typ_agent_, data, OSM_Message::CODLEN );
this->typ_agent_[OSM_Message::CODLEN]='\0';
};
/*----------------------------------------------------------------------------*/
const ACE_TCHAR *
176 OSM_AG_Main::typ_agent( void ) const
{
return this->typ_agent_;
};
/*----------------------------------------------------------------------------*/
void
183 OSM_AG_Main::idn_master ( const ACE_TCHAR *data, const size_t len )
{
ACE_OS::strncpy( this->idn_master_, data, OSM_Message::CODLEN );
this->idn_master_[OSM_Message::CODLEN]='\0';
};
/*----------------------------------------------------------------------------*/
const ACE_TCHAR *
191 OSM_AG_Main::idn_master( void ) const
{
return this->idn_master_;
};
/*----------------------------------------------------------------------------*/
int
198 OSM_AG_Main::prepare_msg_manager( ACE_TCHAR* cmd_line, int len )
{
ACE_TCHAR send_cmd[MAXPATHLEN+1]="";
ACE_OS::sprintf( cmd_line, ACE_TEXT( "-m %d" ), this->prt_master_ );
// We don't need this parameter. We use it only if exists.
OSM_CfgManager::instance( )->get_value_str( "SNDCMD",
send_cmd,
MAXPATHLEN );
if ( ( int )( ACE_OS::strlen( send_cmd ) +15 ) > len )
{
return -1;
}
if ( ACE_OS::strlen( send_cmd ) > 2 )
{
ACE_OS::strcat( cmd_line, " -C " );
ACE_OS::strcat( cmd_line, send_cmd );
}
return 0;
};
/*----------------------------------------------------------------------------*/
int
226 OSM_AG_Main::prepare_ins_manager( ACE_TCHAR* cmd_line, int len )
{
if ( 0 == ACE_OS::strlen( this->config_file_ ) )
{
return -1;
}
if ( ( int )( ACE_OS::strlen( this->config_file_ ) +3 ) > len )
{
return -1;
}
ACE_OS::sprintf( cmd_line, ACE_TEXT( "-c %s" ), this->config_file_ );
return 0;
};
/*----------------------------------------------------------------------------*/
int
244 OSM_AG_Main::init_work( int argc, ACE_TCHAR *argv[] )
{
ACE_TCHAR* env_s;
env_s = ACE_OS::getenv( "OSM_ROOT" );
if ( env_s == 0 )
{
ACE_ERROR_RETURN( ( LM_ERROR,
ACE_TEXT( "OSM_AG_Main: Env variable OSM_ROOT not defined!!\n" ) ),
-1 );
}
if ( ACE_LOG_MSG->open ( argv[0], ACE_Log_Msg::STDERR, ACE_TEXT( PROGRAM_NAME_ ) ) == -1 )
{
ACE_ERROR ( ( LM_ERROR, ACE_TEXT ( "OSM_AG_Main: Cannot open logger\n" ) ) );
}
// ---------------------------------------------------------------------------
// Parse Command Line
// ---------------------------------------------------------------------------
if ( -1 == parse_cmd_line( argc, argv ) )
{
print_usage( );
return -1;
}
if ( -1 == parse_config_file( this->config_file_ ) )
{
ACE_ERROR_RETURN( ( LM_ERROR,
ACE_TEXT( "OSM_AG_Main: Bad or missing parameter. Check the configuration file:\n"
"\t[%s]\n\n" ), this->config_file_ ), -1 );
}
// ---------------------------------------------------------------------------
// Add cfg parameters not in config file.
// ---------------------------------------------------------------------------
if ( 0 !=
OSM_CfgManager::instance( )->add_value_str( "OSROOT", env_s )
// + OSM_CfgManager::instance( )->add_value_str( "CODAGT", this->typ_agent( ) )
+ OSM_CfgManager::instance( )->add_value_str( "CODMST", this->idn_master( ) )
//+ OSM_CfgManager::instance( )->add_value_int( "TPREAC", 0 )
+ OSM_CfgManager::instance( )->add_value_int( "TIMBUF", 0 )
+ OSM_CfgManager::instance( )->add_value_int( "RECVRY", 1 )
+ OSM_CfgManager::instance( )->add_value_int( "MSGQSI", 16 )
+ OSM_CfgManager::instance( )->add_value_str( "OSMKEY", "OSMIUS_KEY" )
)
{
ACE_ERROR_RETURN( ( LM_ERROR,
ACE_TEXT( "OSM_AG_Main: Adding Config parameters\n" ) ),
-1 );
}
return 0;
}
/*----------------------------------------------------------------------------*/
300 int OSM_AG_Main::parse_config_file( ACE_TCHAR* config_file )
{
// ---------------------------------------------------------------------------
// Array of configuration elements.
// OSMIUS_CONFIGURE
// ---------------------------------------------------------------------------
const int num_cfg_elements=3; /** IMPORTANT **/
OSM_CfgElement CfgArray [num_cfg_elements];
//CfgArray[0].set_data ( "PORTMA", OSM_CFG_NUMBER );// Master Agent port. AKI ->> Should be by command line??
CfgArray[0].set_data ( "PORTCM", OSM_CFG_NUMBER );// Port to receive commands.
CfgArray[1].set_data ( "TIMOUT", OSM_CFG_NUMBER );// Timeout retry
CfgArray[2].set_data ( "RECONN", OSM_CFG_NUMBER );// Number of retries to connect server.
//CfgArray[4].set_data ( "OSMKEY", OSM_CFG_STRING );// Osmius Code.
//CfgArray[5].set_data ( "TPREAC", OSM_CFG_NUMBER );// Use Thread Pool Reactor Implementacion?
//CfgArray[6].set_data ( "TIMBUF", OSM_CFG_NUMBER );// Time buffer to wait for sending messages.
//CfgArray[7].set_data ( "RECVRY", OSM_CFG_NUMBER );// Try to recover.
// ---------------------------------------------------------------------------
// Check if all these parameters are in the configuration file
// with the right type.
// ---------------------------------------------------------------------------
if ( 0 != OSM_CfgManager::instance( )->open(
config_file_, PROGRAM_NAME_, CfgArray, num_cfg_elements, OSM_STAT_NUM ) )
{
return -1;
}
return 0;
}
/*----------------------------------------------------------------------------*/
330 int OSM_AG_Main::exit_work( void )
{
int result = 0;
// Shutdown INS_Manager
if ( -1 == OSM_AG_InsManager::instance( )->fini( ) )
{
ACE_ERROR( ( LM_ERROR, "OSM_AG_Main: exit_work( )- INS_Manager::fini( ) Failed\n" ) );
result = -1;
}
// Shutdown MSG_Manager
if ( -1 == OSM_AG_MsgManager::instance( )->fini( ) )
{
ACE_ERROR( ( LM_ERROR, "OSM_AG_Main: exit_work( )- MSG_Manager::fini( ) Failed\n" ) );
result = -1;
}
if ( OSM_CfgManager::instance( )->debug_mode( ) )
{
ACE_DEBUG( ( LM_DEBUG, ACE_TEXT( "( %P|%T ) OSM_AG_Main: exit_work( )\n" ) ) );
ACE_DEBUG( ( LM_DEBUG, ACE_TEXT( "\tProcessed Events.......: %d\n" ),
OSM_CfgManager::instance( )->counter( OSM_STAT_EVENTS ) ) );
ACE_DEBUG( ( LM_DEBUG, ACE_TEXT( "\tSended Messages........: %d\n" ),
OSM_CfgManager::instance( )->counter( OSM_STAT_MSGSND ) ) );
ACE_DEBUG( ( LM_DEBUG, ACE_TEXT( "\tReconnections..........: %d\n" ),
OSM_CfgManager::instance( )->counter( OSM_STAT_RECONN ) ) );
}
OSM_CfgManager::instance( )->close( );
return result;
}
//------------------------------------------------------------------------------
// Preparing Reactor and signal to quit gracefully!!
//------------------------------------------------------------------------------
// 1.- Convert OSM_Reactor into singleton -> OSM_REACTOR_S
typedef ACE_Singleton <OSM_Reactor, ACE_Thread_Mutex> OSM_REACTOR_S;
// 2.- Derive from OSM_SignalHandler_Base a new class and add MsgManager END
369 class OSM_EndSignal : public OSM_SignalHandler_Base
{
public:
// /// Default constructor.
// OSM_EndSignal ( int signum = SIGINT ): OSM_SignalHandler_Base ( signum )
// {
// };
/// Hook method called when object is signaled by OS.
378 int handle_signal ( int signum, siginfo_t * si= 0, ucontext_t * uc= 0 )
{
OSM_SignalHandler_Base::handle_signal( signum, si, uc );
ACE_OS::sleep( 1 );
// Shutdown every thing in a thread loop doing things
// In this case we must shut down the MSG_Manager
if ( -1 == OSM_AG_MsgManager::instance( )->fini( ) )
{
ACE_ERROR( ( LM_ERROR, "OSM_AG_Main: exit_work( )- MSG_Manager::fini( ) Failed\n" ) );
}
return -1; // And deregister the signal
};
};
// #############################################################################
// MAIN
// #############################################################################
int
399 ACE_TMAIN ( int argc, ACE_TCHAR *argv[] )
{
// Open OSM_REACTOR_S ( dinamyc memory )
if ( -1==OSM_REACTOR_S::instance( )->open( ) )
{
ACE_DEBUG( ( LM_DEBUG,
ACE_TEXT( "( %P|%T ) OSM_Main: Couldn't open reactor...\n" ) ) );
return 1;
}
if ( -1==OSM_AG_Main::instance( )->init_work( argc, argv ) )
{
return 1;
}
// ---------------------------------------------------------------------------
// Reactor
// ---------------------------------------------------------------------------
int num_reactor_threads = 1; // Default in Agent : Without Threads!!
if ( -1 == OSM_CfgManager::instance( )->get_value_int( "TPREAC", &num_reactor_threads ) )
{
// Default number of Threads ( >1 : Thread_Pool <=1 : Default Reactor.
num_reactor_threads = 1;
}
ACE_OS::last_error( 0 );
if ( -1 == OSM_REACTOR_S::instance( )->create_reactor( num_reactor_threads ) )
{
ACE_DEBUG( ( LM_DEBUG,
ACE_TEXT( "( %P|%T ) OSM_Main: Couldn't create reactor...\n" ) ) );
return 10;
}
// ---------------------------------------------------------------------------
// Prepare signals. Quit if SIGINT is triggered.
// ---------------------------------------------------------------------------
OSM_EndSignal signal_handler;
// ---------------------------------------------------------------------------
// Spawn the Message Manager.
// ---------------------------------------------------------------------------
if ( OSM_CfgManager::instance( )->debug_mode( ) )
{
ACE_DEBUG( ( LM_DEBUG,
ACE_TEXT( "( %P|%T ) OSM_Main: MSG_Manager Starting...\n" ) ) );
}
ACE_OS::last_error( 0 );
ACE_TCHAR cmd_line[BUFSIZ]="";
// Get the command line for the Message Manager.
if ( -1 == OSM_AG_Main::instance( )->prepare_msg_manager( cmd_line, BUFSIZ ) )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "OSM_Main: Could not prepare MSG_Manager. last_error:%d\n" ),
ACE_OS::last_error( ) ) );
OSM_AG_Main::instance( )->exit_work( );
return 4;
}
if ( OSM_CfgManager::instance( )->debug_mode( ) )
{
ACE_DEBUG( ( LM_DEBUG,
ACE_TEXT( "( %P|%T ) OSM_Main: MSG_Manager cmd_line is [%s]\n" ), cmd_line ) );
}
ACE_ARGV cmd_line_args( cmd_line );
// Pass the command line to the Msg_Manager main function: init( )
if ( -1 == OSM_AG_MsgManager::instance( )->init( cmd_line_args.argc( ),
cmd_line_args.argv( ) ) )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "OSM_AG_Main: Failed to initialize MSG_Manager.\n" ) ) );
OSM_AG_Main::instance( )->exit_work( );
return 5;
}
// So we have the MSG_Manager service connected to the local master agent
// and waiting for message to be inserted into its MSG_Sender Queue, and
// send them to the master through its Connector.
if ( OSM_CfgManager::instance( )->debug_mode( ) )
{
ACE_DEBUG( ( LM_DEBUG,
ACE_TEXT( "( %P|%T ) OSM_AG_Main: MSG_Manager Up and Runnig OK!!\n" ) ) );
}
// ---------------------------------------------------------------------------
// Spawn the Instance and Event Manager.
// ---------------------------------------------------------------------------
if ( OSM_CfgManager::instance( )->debug_mode( ) )
{
ACE_DEBUG( ( LM_DEBUG,
ACE_TEXT( "( %P|%T ) OSM_AG_Main: INS_Manager Starting...\n" ) ) );
}
if ( -1 == OSM_AG_Main::instance( )->prepare_ins_manager( cmd_line, BUFSIZ ) )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "OSM_AG_Main: Could not prepare INS_Manager. last_error:%d\n" ),
ACE_OS::last_error( ) ) );
OSM_AG_Main::instance( )->exit_work( );
return 14;
}
if ( OSM_CfgManager::instance( )->debug_mode( ) )
{
ACE_DEBUG( ( LM_DEBUG,
ACE_TEXT( "( %P|%T ) OSM_AG_Main: INS_Manager cmd_line is [%s]\n" ), cmd_line ) );
}
ACE_ARGV ins_cmd_line_args( cmd_line );
if ( -1 == OSM_AG_InsManager::instance( )->init( ins_cmd_line_args.argc( ),
ins_cmd_line_args.argv( ) ) )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "OSM_AG_Main: Failed to initialize INS_Manager. Argv:[%s] %d\n" ),
cmd_line, ins_cmd_line_args.argc( ) ) );
OSM_AG_Main::instance( )->exit_work( );
return 15;
}
if ( OSM_CfgManager::instance( )->debug_mode( ) )
{
ACE_DEBUG( ( LM_DEBUG,
ACE_TEXT( "( %P|%T ) OSM_AG_Main: INS_Manager Up and Runnig OK!!\n" ) ) );
}
// ---------------------------------------------------------------------------
// Spawn the Command Manager.
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// Run the event loop.
// ---------------------------------------------------------------------------
if ( OSM_CfgManager::instance( )->debug_mode( ) )
{
ACE_DEBUG( ( LM_DEBUG,
"( %P|%T ) OSM_AG_Main: Run reactor event loop in %d threads( )\n",
OSM_REACTOR_S::instance( )->num_threads( ) ) );
}
OSM_REACTOR_S::instance( )->run_reactor( );
// ---------------------------------------------------------------------------
// Bye!!
// ---------------------------------------------------------------------------
OSM_AG_Main::instance( )->exit_work( );
return 0;
}
1 // -*- C++ -*-
// -----------------------------------------------------------------------------
/*
* Osmius and its code is copyright of Peopleware S.L. Spain.
* http://www.peopleware.es
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* ( at your option ) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
// -----------------------------------------------------------------------------
/**
* @file osm_agent_basic.h
* @brief Basic agent for the Osmius infraestructure. Use it to build your own agent.
*
* @author Jose Luis Marina <joseluis.marina@peopleware.es>
* @date 18-MAY-2006
*/
// -----------------------------------------------------------------------------
#ifndef _OSM_AGENT_BASIC_H_
#define _OSM_AGENT_BASIC_H_
#include "../cm/osm_message.h"
#include <ace/Acceptor.h>
#include <ace/SOCK_Acceptor.h>
// -----------------------------------------------------------------------------
// Counters for statistical use.
// -----------------------------------------------------------------------------
enum
{
/// Number of statistics
OSM_STAT_NUM = 3
};
/**
* @class OSM_AG_Main
*
* @brief Manages Osmius Basic Agent init and exit tasks.
*
* It is in charge of the initial actions such as validate command options,
* validate config files open log-files and other common resources and to spawn
* the other services within the process.
* Also it must do all the end-of-process tasks.
*/
61 class OSM_AG_Main
{
public:
enum
{
OSM_MAX_VERSION = 8,
OSM_MIN_VERSION = 07,
MAX_THREADS_TPREACTOR = 8
};
/// Returns Singleton.
72 static OSM_AG_Main* instance ( void );
/// Exit tasks like closing files and sockets, free resources.
75 ~OSM_AG_Main( void );
/**
* Make all the initial tasks like check the command line, env variables,
* check config file, add config information, starts services, and open
* common resources.
* @retval -1 in case of error( ).
*/
83 int init_work ( int argc, ACE_TCHAR *argv[] );
/**
* Make all the final tasks like free resources, end services, close handles
* and store statistical information.
* @retval -1 in case of error.
*/
90 int exit_work( void );
/**
* Sets config_file private info.
* @retval -1 in case of error.
*/
95 int set_config_file( ACE_TCHAR* file );
/**
* Prepares the creation and spawn of the MSG_MANAGER service.
* returns the command line needed by init( ) to start the service.
* @retval -1 in case of error( ).
*/
102 int prepare_msg_manager( ACE_TCHAR* cmd_line, const int len );
/**
* Prepares the creation and spawn of the INS_MANAGER service.
* returns the command line needed by init( ) to start the service.
* @retval -1 in case of error( ).
*/
109 int prepare_ins_manager( ACE_TCHAR* cmd_line, const int len );
/**
* Sets agent code.
* @retval -1 in case of error.
*/
115 void typ_agent( const ACE_TCHAR* data, const size_t len );
/**
* Gets master agent code.
* @retval -1 in case of error.
*/
121 const ACE_TCHAR* typ_agent( void ) const;
/**
* Sets master agent code.
* @retval -1 in case of error.
*/
127 void idn_master( const ACE_TCHAR* data, const size_t len );
/**
* Gets master agent code.
* @retval -1 in case of error.
*/
133 const ACE_TCHAR* idn_master( void ) const;
private:
/// The constructor is private to ensure singleton.
137 OSM_AG_Main( void );
/// Prints usage and command line options.
139 void print_usage( void );
/**
* Parses command line.
* @retval -1 in case of error( ).
*/
144 int parse_cmd_line( int argc, ACE_TCHAR *argv[] );
/**
* Parses config file using an Array of OSM_CfgElement
* @retval -1 in case of error( ).
*/
150 int parse_config_file( ACE_TCHAR *cfg_file );
static OSM_AG_Main* instance_;
153 ACE_TCHAR config_file_ [MAXPATHLEN+1];
154 ACE_TCHAR PROGRAM_NAME_[MAXPATHLEN+1];
155 ACE_TCHAR idn_master_ [OSM_Message::CODLEN + 1];
156 ACE_TCHAR typ_agent_ [OSM_Message::CODLEN + 1]; // Actually this is the Instance Type.
int prt_master_; // Port where the master agent is listening for message events.
};
#endif // _OSM_AGENT_BASIC_H_
1 // -*- C++ -*-
// -----------------------------------------------------------------------------
/*
* Osmius and its code is copyright of Peopleware S.L. Spain.
* http://www.peopleware.es
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* ( at your option ) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
// -----------------------------------------------------------------------------
/**
* @file osm_ag_hpux.cpp
* @brief Implementation file for the HP-UX monitoring agent.
* Osmius - Peopleware.
*
* @author Manuel Fraga Castro <joseluis.marina [-at-] peopleware.es>
* @date 22-AUG-2006.
*/
// -----------------------------------------------------------------------------
// These are standard includes for any program
#include <ace/OS.h>
#include <ace/Log_Msg.h>
// Specific module includes.
#include <ace/Time_Value.h>
#include "../../cm/osm_cfgmanager.h"
/*******************************************************************************
* OSMIUS_HINT 04:
* Include at least our declaration file and other files needed in the
* implementation.
******************************************************************************/
#include "osm_ag_hpux.h"
/*----------------------------------------------------------------------------*/
/* Create Functions Implementation */
/*----------------------------------------------------------------------------*/
/*******************************************************************************
* OSMIUS_HINT 05:
* We have to implement the function used in
* OSM_AG_InsManager::create_instances( ) to return new objects of our new
* instance class.
******************************************************************************/
/**
* This funtion is used to create the appropiate instance type.
* @param instance_name Input - Instance Name.
* @param instance_type Input - Type of the instance - to be checked.
* @param conn_info Input - If needed is a string used in the connect( ) method.
* @param instance Input - This funtion will make a new over this pointer.
* @retval -1 in case of error. 0 for success.
*/
67 int CREATE_OSMIUS_INSTANCE( const ACE_TCHAR* instance_name,
const ACE_TCHAR* instance_type,
const ACE_TCHAR* conn_info ,
OSM_Instance_Base* &instance )
{
// ---------------------------------------------------------------------------
// Check instance_name.
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// Check instance_type.
// ---------------------------------------------------------------------------
// Choose a name( s ) for the types of instance your agent is about to monitor.
if ( 0 != ACE_OS::strncmp( instance_type, ACE_TEXT( INS_TYPE_01 ), OSM_Message::TYPLEN ) )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_INSTANCE: Bad Instance Type [%s]\n" ),
instance_type ) );
return -1;
}
// ---------------------------------------------------------------------------
// Check conn_info
// ---------------------------------------------------------------------------
// We don't have an operational connect nor disconnect functions so we don't
// have to check this info...
// ---------------------------------------------------------------------------
// Create the new object.
// ---------------------------------------------------------------------------
// We only have this HP-UX instance type: create it and return.
ACE_NEW_RETURN( instance, OSM_Instance_Hpux, -1 );
return 0;
}
/*******************************************************************************
* OSMIUS_HINT 05:
* We have to implement the function used in
* OSM_Instance_Base::create_events( ) to return new objects of our new events
* with the appropriate new action.
******************************************************************************/
/**
* This funtion is used to create the appropiate events and associated actions.
* @param event_name Input - Name checked.
* @param instance_type Input - Type of the instance - to be checked.
* @param ev_parameters Input - Parameters read from the config file.
* @param seconds Input - Seconds to be called.
* @param event Output - This funtion will make a new over this pointer.
* @retval -1 in case of error. 0 for success.
*/
119 int CREATE_OSMIUS_EVENT( const ACE_TCHAR* event_name ,
const ACE_TCHAR* instance_type,
const ACE_TCHAR* ev_parameters,
int seconds ,
OSM_Event* &event )
{
// Put here the minimum number of seconds needed by these events to complete.
// The interval between executions must be greater than this minimum.
// You can do this with a different value for each event if you want...
const int min_seconds = 4;
ACE_TCHAR user_param1 [BUFSIZ+1]="";
ACE_TCHAR cmd_query [BUFSIZ+1]="";
// ---------------------------------------------------------------------------
// Check instance_type.
// ---------------------------------------------------------------------------
if ( 0 != ACE_OS::strncmp( instance_type, INS_TYPE_01, OSM_Message::TYPLEN ) )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Unknown Instance Type [%s]\n" ),
instance_type ) );
return -1;
}
// ---------------------------------------------------------------------------
// Check if the number of seconds is appropiate with this event.
// ---------------------------------------------------------------------------
if ( min_seconds > seconds )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Interval %d is too low for this event.Must be greater than:%d\n" ),
seconds, min_seconds ) );
return -1;
}
OSM_Action_Base* p_action;
p_action = 0;
// ---------------------------------------------------------------------------
// Check event_name and create the event and associated action.
// ---------------------------------------------------------------------------
// ################### Percentage CPU System Usage ######################
if ( 0 == ACE_OS::strncmp( event_name, "HPCPUSYS", OSM_Message::CODLEN ) )
{
ACE_NEW_NORETURN( event, OSM_Event );
if ( 0 == event )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Coul not create new Event\n" ) ) );
return -1;
}
ACE_NEW_NORETURN( p_action, OSM_ACT_HpuxCpuSys );
if ( 0 == p_action )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_HpuxCpuSys\n" ) ) );
delete event;
event = 0;
return -1;
}
event->action( p_action );
event->cmd_line( "", 0 );
return 0;
}
// ################### Percentage CPU Users Usage ######################
if ( 0 == ACE_OS::strncmp( event_name, "HPCPUUSR", OSM_Message::CODLEN ) )
{
ACE_NEW_NORETURN( event, OSM_Event );
if ( 0 == event )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Coul not create new Event\n" ) ) );
return -1;
}
ACE_NEW_NORETURN( p_action, OSM_ACT_HpuxCpuUser );
if ( 0 == p_action )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_HpuxCpuUser\n" ) ) );
delete event;
event = 0;
return -1;
}
event->action( p_action );
event->cmd_line( "", 0 );
return 0;
}
// ################### Percentage Total CPU Usage ######################
if ( 0 == ACE_OS::strncmp( event_name, "HPCPUTOT", OSM_Message::CODLEN ) )
{
ACE_NEW_NORETURN( event, OSM_Event );
if ( 0 == event )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Coul not create new Event\n" ) ) );
return -1;
}
ACE_NEW_NORETURN( p_action, OSM_ACT_HpuxCpuTotal );
if ( 0 == p_action )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_HpuxCpuTotal\n" ) ) );
delete event;
event = 0;
return -1;
}
event->action( p_action );
event->cmd_line( "", 0 );
return 0;
}
// ############################# NULL Event ##################################
p_action = 0;
if ( 0 == ACE_OS::strncmp( event_name, "NULLEVNT", OSM_Message::CODLEN ) )
{
ACE_NEW_NORETURN( event, OSM_Event );
if ( 0 == event )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Coul not create new Event\n" ) ) );
return -1;
}
ACE_NEW_NORETURN( p_action, OSM_ACT_HpuxNull );
if ( 0 == p_action )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_HpuxNull\n" ) ) );
delete event;
event = 0;
return -1;
}
event->action( p_action );
event->cmd_line( "NULL", 4 );
return 0;
}
// ############################# Active IP4 Interfaces ######################
if ( 0 == ACE_OS::strncmp( event_name, "HPIP4INT", OSM_Message::CODLEN ) )
{
ACE_NEW_NORETURN( event, OSM_Event );
if ( 0 == event )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Coul not create new Event\n" ) ) );
return -1;
}
ACE_NEW_NORETURN( p_action, OSM_ACT_IP4Interfaces );
if ( 0 == p_action )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_IP4Interfaces\n" ) ) );
delete event;
event = 0;
return -1;
}
event->action( p_action );
event->cmd_line( "NULL", 4 );
return 0;
}
// ############################# Active IP6 Interfaces ######################
if ( 0 == ACE_OS::strncmp( event_name, "HPIP6INT", OSM_Message::CODLEN ) )
{
ACE_NEW_NORETURN( event, OSM_Event );
if ( 0 == event )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Coul not create new Event\n" ) ) );
return -1;
}
ACE_NEW_NORETURN( p_action, OSM_ACT_IP6Interfaces );
if ( 0 == p_action )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_IP6Interfaces\n" ) ) );
delete event;
event = 0;
return -1;
}
event->action( p_action );
event->cmd_line( "NULL", 4 );
return 0;
}
// ################### Number of total running processes ######################
if ( 0 == ACE_OS::strncmp( event_name, "HPNUMPRC", OSM_Message::CODLEN ) )
{
ACE_NEW_NORETURN( event, OSM_Event );
if ( 0 == event )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Coul not create new Event\n" ) ) );
return -1;
}
ACE_NEW_NORETURN( p_action, OSM_ACT_HpuxTotalProc );
if ( 0 == p_action )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_HpuxTotalProc\n" ) ) );
delete event;
event = 0;
return -1;
}
event->action( p_action );
event->cmd_line( "", 0 );
return 0;
}
// ####################### MB of Free Memory ##########################
if ( 0 == ACE_OS::strncmp( event_name, "HPFREMEM", OSM_Message::CODLEN ) )
{
ACE_NEW_NORETURN( event, OSM_Event );
if ( 0 == event )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Coul not create new Event\n" ) ) );
return -1;
}
ACE_NEW_NORETURN( p_action, OSM_ACT_HpuxFreeMem );
if ( 0 == p_action )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_HpuxFreeMem\n" ) ) );
delete event;
event = 0;
return -1;
}
event->action( p_action );
event->cmd_line( "", 0 );
return 0;
}
// ################### HP-UX uptime in seconds ######################
if ( 0 == ACE_OS::strncmp( event_name, "HPUPTIME", OSM_Message::CODLEN ) )
{
ACE_NEW_NORETURN( event, OSM_Event );
if ( 0 == event )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Coul not create new Event\n" ) ) );
return -1;
}
ACE_NEW_NORETURN( p_action, OSM_ACT_HpuxUpTime );
if ( 0 == p_action )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_HpuxUpTime\n" ) ) );
delete event;
event = 0;
return -1;
}
event->action( p_action );
event->cmd_line( "", 0 );
return 0;
}
// ############################# Process Down ######################
if ( 0 == ACE_OS::strncmp( event_name, "HPPRCDWN", OSM_Message::CODLEN ) )
{
ACE_NEW_NORETURN( event, OSM_Event );
if ( 0 == event )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Coul not create new Event\n" ) ) );
return -1;
}
ACE_NEW_NORETURN( p_action, OSM_ACT_HpuxProcessDown );
if ( 0 == p_action )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_HpuxProcessDown\n" ) ) );
delete event;
event = 0;
return -1;
}
event->action( p_action );
event->cmd_line( "", 0 );
if ( ACE_OS::strlen( ev_parameters ) )
{
OSM_CfgManager::instance( )->get_param ( ev_parameters, 'L', user_param1, BUFSIZ );
}
if ( ACE_OS::strlen( user_param1 ) < 3 )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Could not create new Action - OSM_ACT_HpuxProcessDown\n"
" Could not find -L parameters. List of processes.\n" ) ) );
delete p_action;
p_action = 0;
delete event;
event = 0;
return -1;
}
ACE_TCHAR procs[BUFSIZ];
ACE_OS::sprintf( procs, "-p %s", user_param1 );
event->cmd_line( procs, ACE_OS::strlen( procs ) );
return 0;
}
// ################### HP-UX number of cpus in the system ######################
if ( 0 == ACE_OS::strncmp( event_name, "HPNUMCPU", OSM_Message::CODLEN ) )
{
ACE_NEW_NORETURN( event, OSM_Event );
if ( 0 == event )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Coul not create new Event HPNUMCPU\n" ) ) );
return -1;
}
ACE_NEW_NORETURN( p_action, OSM_ACT_HpuxNumCpu );
if ( 0 == p_action )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_HpuxNumCpu\n" ) ) );
delete event;
event = 0;
return -1;
}
event->action( p_action );
event->cmd_line( "", 0 );
return 0;
}
// ################### HP-UX used memory percentage ######################
if ( 0 == ACE_OS::strncmp( event_name, "HPPRCMEM", OSM_Message::CODLEN ) )
{
ACE_NEW_NORETURN( event, OSM_Event );
if ( 0 == event )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Coul not create new Event HPPRCMEM\n" ) ) );
return -1;
}
ACE_NEW_NORETURN( p_action, OSM_ACT_HpuxPrcMem );
if ( 0 == p_action )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_HpuxPrcMem\n" ) ) );
delete event;
event = 0;
return -1;
}
event->action( p_action );
event->cmd_line( "", 0 );
return 0;
}
// ##################### HP-UX percentage of Used FileSystem ##################
if ( 0 == ACE_OS::strncmp( event_name, "HPPRCHFS", OSM_Message::CODLEN ) )
{
ACE_NEW_NORETURN( event, OSM_Event );
if ( 0 == event )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Coul not create new Event\n" ) ) );
return -1;
}
ACE_NEW_NORETURN( p_action, OSM_ACT_HpuxFSUsed );
if ( 0 == p_action )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_HpuxFSUsed\n" ) ) );
delete event;
event = 0;
return -1;
}
event->action( p_action );
event->cmd_line( "", 0 );
if ( ACE_OS::strlen( ev_parameters ) )
{
OSM_CfgManager::instance( )->get_param ( ev_parameters, 'L', user_param1, BUFSIZ );
}
if ( ACE_OS::strlen( user_param1 ) < 1 )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_HpuxFSUsed\n"
" Could not find -L parameters. List of filesystems.\n" ) ) );
delete p_action;
p_action = 0;
delete event;
event = 0;
return -1;
}
ACE_TCHAR procs[BUFSIZ];
ACE_OS::sprintf( procs, "-p %s", user_param1 );
event->cmd_line( procs, ACE_OS::strlen( procs ) );
return 0;
}
// ################### HP-UX percentage of used swap ######################
if ( 0 == ACE_OS::strncmp( event_name, "HPPRCSWP", OSM_Message::CODLEN ) )
{
ACE_NEW_NORETURN( event, OSM_Event );
if ( 0 == event )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Coul not create new Event HPPRCSWP\n" ) ) );
return -1;
}
ACE_NEW_NORETURN( p_action, OSM_ACT_HpuxPrcSwp );
if ( 0 == p_action )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_HpuxPrcSwp\n" ) ) );
delete event;
event = 0;
return -1;
}
event->action( p_action );
event->cmd_line( "", 0 );
return 0;
}
// ############################# Logfile Scan ######################
if ( 0 == ACE_OS::strncmp( event_name, "HPLOG0", OSM_Message::CODLEN-2 ) )
{
ACE_TCHAR auxbuf[BUFSIZ];
ACE_NEW_NORETURN( event, OSM_Event );
if ( 0 == event )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Coul not create new Event - HPLOG0\n" ) ) );
return -1;
}
ACE_NEW_NORETURN( p_action, OSM_ACT_ScanLog );
if ( 0 == p_action )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_ScanLog\n" ) ) );
delete event;
event = 0;
return -1;
}
event->action( p_action );
event->cmd_line( "", 0 );
// Get the full logfile path -L "/logdir/logfile.log".
user_param1[0] = '\0';
if ( ACE_OS::strlen( ev_parameters ) )
{
OSM_CfgManager::instance( )->get_param ( ev_parameters, 'L', user_param1, BUFSIZ );
}
if ( !ACE_OS::strlen( user_param1 ) )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_ScanLog\n"
" Could not find -L parameter. Logfile full path.\n" ) ) );
delete p_action;
p_action = 0;
delete event;
event = 0;
return -1;
}
else
{
ACE_OS::sprintf( cmd_query, "-l %s", user_param1 );
}
// Get the string to search within the logfile.
if ( ACE_OS::strlen( ev_parameters ) )
{
OSM_CfgManager::instance( )->get_param ( ev_parameters, 'S', user_param1, BUFSIZ );
}
if ( !ACE_OS::strlen( user_param1 ) )
{
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Coul not create new Action - OSM_ACT_ScanLog\n"
" Could not find -S parameter. String to search.\n" ) ) );
delete p_action;
p_action = 0;
delete event;
event = 0;
return -1;
}
else
{
ACE_OS::sprintf( auxbuf, " -s %s", user_param1 );
ACE_OS::strcat( cmd_query, auxbuf );
}
event->cmd_line( cmd_query, ACE_OS::strlen( cmd_query ) );
return 0;
}
// We have an unknown Event name. don't know what to do.
ACE_ERROR( ( LM_ERROR,
ACE_TEXT( "CREATE_OSMIUS_EVENT: Bad Event Name [%s]\n" ),
event_name ) );
return -1;
}
/*----------------------------------------------------------------------------*/
/* OSM_ACT_HpuxNull Implementation */
/*----------------------------------------------------------------------------*/
647 int OSM_ACT_HpuxNull::execute ( const ACE_TCHAR* cmd_line, const int cmd_len ,
648 const int timeout , ACE_TCHAR* val_text,
int& val_len , int& value )
{
//Uncomment this if you want to trace this function.
//if ( OSM_CfgManager::instance( )->debug_mode( ) )
//{
// ACE_DEBUG( ( LM_DEBUG,
// ACE_TEXT( "( %P|%t ) OSM_Action: execute( ) [%s] TimeOut: %d\n" ),
// cmd_line, timeout ) );
//}
// // Use your own command line checker method. See below.
// if ( -1 == this->check_cmd_line( cmd_line, cmd_len ) )
// {
// ACE_ERROR( ( LM_ERROR,
// ACE_TEXT( "( %P|%t ) OSM_Action : Bad command line [%s]\n" ),
// cmd_line ) );
// return -1;
// }
// We could also check the command line parameters for our event into the cfg file.
// EVENT = -t timeout [-c 0, 1 -w warn -a alarm -s( ilent )]
// if ( OSM_CfgManager::instance( )->debug_mode( ) )
// {
// ACE_DEBUG( ( LM_DEBUG,
// ACE_TEXT( "( %P|%t ) OSM_Action: Config Parameters are [%s]\n" ),
// this->ev_parameters( ) ) );
// }
// You can use the pointer to "our" instance ( this->osm_instance_ ) to access
// instance data. In this example we don't use it.
// Do whatever you must do to get the value and its text.
ACE_OS::strcpy( val_text, "NULL Event Text" );
val_len=15;
value = value_++;
return 0;
}
/*----------------------------------------------------------------------------*/
687 int OSM_ACT_HpuxNull::check_cmd_line( const ACE_TCHAR* cmd_line,
const int cmd_len )
{
// Uncomment this if you want to trace this function ( and run with "-d" )
//if ( OSM_CfgManager::instance( )->debug_mode( ) )
//{
// ACE_DEBUG( ( LM_DEBUG,
// ACE_TEXT( "( %P|%t ) OSM_Action: check_cmd_line( ) [%s] %d\n" ),
// cmd_line, cmd_len ) );
//}
// Check the Command Line.
return 0;
}
/*----------------------------------------------------------------------------*/
/* OSM_ACT_HpuxCpuSys Implementation */
/*----------------------------------------------------------------------------*/
706 int OSM_ACT_HpuxCpuSys::execute ( const ACE_TCHAR* cmd_line, const int cmd_len,
707 const int timeout , ACE_TCHAR* val_text ,
int& val_len , int& value )
{
//Uncomment this if you want to trace this function.
//if ( OSM_CfgManager::instance( )->debug_mode( ) )
//{
// ACE_DEBUG( ( LM_DEBUG,
// ACE_TEXT( "( %P|%t ) OSM_Action: execute( ) [%s] TimeOut: %d\n" ),
// cmd_line, timeout ) );
//}
// // Use your own command line checker method. See below.
// if ( -1 == this->check_cmd_line( cmd_line, cmd_len ) )
// {
// ACE_ERROR( ( LM_ERROR,
// ACE_TEXT( "( %P|%t ) OSM_Action : Bad command line [%s]\n" ),
// cmd_line ) );
// return -1;
// }
// We could also check the command line parameters for our event into the cfg file.
// EVENT = -t timeout [-c 0, 1 -w warn -a alarm -s( ilent )]
// if ( OSM_CfgManager::instance( )->debug_mode( ) )
// {
// ACE_DEBUG( ( LM_DEBUG,
// ACE_TEXT( "( %P|%t ) OSM_Action: Config Parameters are [%s]\n" ),
// this->ev_parameters( ) ) );
// }
ACE_TCHAR command[BUFSIZ+1]="";
ACE_OS::sprintf( command, "ksh -c \"vmstat 2 2 | tail -1 | awk '{ print $17 }'\"" );
value = 0;
if ( -1 == OSM_ACT_ExecuteProcess::execute( command, ACE_OS::strlen( command ),
timeout , val_text ,
val_len , value ) )
{
return -1;
}
value = ACE_OS::atoi( val_text );
if ( value < 0 )
{
value = -1;
ACE_OS::sprintf( val_text, "command [%s] failed!!", command );
val_len = ACE_OS::strlen( val_text );
return -1;
}
val_text[0] = '\0';
val_len = 0;
return 0;
}
/*----------------------------------------------------------------------------*/
/* OSM_ACT_HpuxCpuUser Implementation */
/*----------------------------------------------------------------------------*/
767 int OSM_ACT_HpuxCpuUser::execute ( const ACE_TCHAR* cmd_line, const int cmd_len,
768 const int timeout , ACE_TCHAR* val_text ,
int& val_len , int& value )
{
//Uncomment this if you want to trace this function.
//if ( OSM_CfgManager::instance( )->debug_mode( ) )
//{
// ACE_DEBUG( ( LM_DEBUG,
// ACE_TEXT( "( %P|%t ) OSM_Action: execute( ) [%s] TimeOut: %d\n" ),
// cmd_line, timeout ) );
//}
// // Use your own command line checker method. See below.
// if ( -1 == this->check_cmd_line( cmd_line, cmd_len ) )
// {
// ACE_ERROR( ( LM_ERROR,
// ACE_TEXT( "( %P|%t ) OSM_Action : Bad command line [%s]\n" ),
// cmd_line ) );
// return -1;
// }
// We could also check the command line parameters for our event into the cfg file.
// EVENT = -t timeout [-c 0, 1 -w warn -a alarm -s( ilent )]
// if ( OSM_CfgManager::instance( )->debug_mode( ) )
// {
// ACE_DEBUG( ( LM_DEBUG,
// ACE_TEXT( "( %P|%t ) OSM_Action: Config Parameters are [%s]\n" ),
// this->ev_parameters( ) ) );
// }
ACE_TCHAR command[BUFSIZ+1]="";
ACE_OS::sprintf( command, "ksh -c \"vmstat 2 2 | tail -1 | awk '{ print $16 }'\"" );
value = 0;
if ( -1 == OSM_ACT_ExecuteProcess::execute( command, ACE_OS::strlen( command ),
timeout , val_text ,
val_len , value ) )
{
return -1;
}
value = ACE_OS::atoi( val_text );
if ( value < 0 )
{
value = -1;
ACE_OS::sprintf( val_text, "command [%s] failed!!", command );
val_len = ACE_OS::strlen( val_text );
return -1;
}
val_text[0] = '\0';
val_len = 0;
return 0;
}
/*----------------------------------------------------------------------------*/
/* OSM_ACT_HpuxCpuTotal Implementation */
/*----------------------------------------------------------------------------*/
828 int OSM_ACT_HpuxCpuTotal::execute ( const ACE_TCHAR* cmd_line, const int cmd_len,
829 const int timeout , ACE_TCHAR* val_text ,
int& val_len , int& value )
{
//Uncomment this if you want to trace this function.
//if ( OSM_CfgManager::instance( )->debug_mode( ) )
//{
// ACE_DEBUG( ( LM_DEBUG,
// ACE_TEXT( "( %P|%t ) OSM_Action: execute( ) [%s] TimeOut: %d\n" ),
// cmd_line, timeout ) );
//}
// // Use your own command line checker method. See below.
// if ( -1 == this->check_cmd_line( cmd_line, cmd_len ) )
// {
// ACE_ERROR( ( LM_ERROR,
// ACE_TEXT( "( %P|%t ) OSM_Action : Bad command line [%s]\n" ),
// cmd_line ) );
// return -1;
// }
// We could also check the command line parameters for our event into the cfg file.
// EVENT = -t timeout [-c 0, 1 -w warn -a alarm -s( ilent )]
// if ( OSM_CfgManager::instance( )->debug_mode( ) )
// {
// ACE_DEBUG( ( LM_DEBUG,
// ACE_TEXT( "( %P|%t ) OSM_Action: Config Parameters are [%s]\n" ),
// this->ev_parameters( ) ) );
// }
ACE_TCHAR command[BUFSIZ+1]="";
ACE_OS::sprintf( command, "ksh -c \"vmstat | tail -1 | awk '{ print $18 }'\"" );
value = 0;
if ( -1 == OSM_ACT_ExecuteProcess::execute( command, ACE_OS::strlen( command ),
timeout , val_text ,
val_len , value ) )
{
return -1;
}
value = ACE_OS::atoi( val_text );
//This is to convert idle use percentage in non-idle
value = 100 - value;
if ( value < 0 )
{
value = -1;
ACE_OS::sprintf( val_text, "command [%s] failed!!", command );
val_len = ACE_OS::strlen( val_text );
return -1;
}
val_text[0] = '\0';
val_len = 0;
return 0;
}
/*----------------------------------------------------------------------------*/
/* OSM_ACT_HpuxTotalProc Implementation */
/*----------------------------------------------------------------------------*/
891 int OSM_ACT_HpuxTotalProc::execute ( const ACE_TCHAR* cmd_line, const int cmd_len,
892 const int timeout , ACE_TCHAR* val_text ,
int& val_len , int& value )
{
//Uncomment this if you want to trace this function.
//if ( OSM_CfgManager::instance( )->debug_mode( ) )
//{
// ACE_DEBUG( ( LM_DEBUG,
// ACE_TEXT( "( %P|%t ) OSM_Action: execute( ) [%s] TimeOut: %d\n" ),
// cmd_line, timeout ) );
//}
// // Use your own command line checker method. See below.
// if ( -1 == this->check_cmd_line( cmd_line, cmd_len ) )
// {
// ACE_ERROR( ( LM_ERROR,
// ACE_TEXT( "( %P|%t ) OSM_Action : Bad command line [%s]\n" ),
// cmd_line ) );
// return -1;
// }
// We could also check the command line parameters for our event into the cfg file.
// EVENT = -t timeout [-c 0, 1 -w warn -a alarm -s( ilent )]
// if ( OSM_CfgManager::instance( )->debug_mode( ) )
// {
// ACE_DEBUG( ( LM_DEBUG,
// ACE_TEXT( "( %P|%t ) OSM_Action: Config Parameters are [%s]\n" ),
// this->ev_parameters( ) ) );
// }
ACE_TCHAR command[BUFSIZ+1]="";
ACE_OS::sprintf( command, "ksh -c \"ps -e | wc -l\"" );
value = 0;
if ( -1 == OSM_ACT_ExecuteProcess::execute( command, ACE_OS::strlen( command ),
timeout , val_text ,
val_len , value ) )
{
return -1;
}
value = ACE_OS::atoi( val_text );
if ( value < 0 )
{
value = -1;
ACE_OS::sprintf( val_text, "command [%s] failed!!", command );
val_len = ACE_OS::strlen( val_text );
return -1;
}
val_text[0] = '\0';
val_len = 0;
return 0;
}
/*----------------------------------------------------------------------------*/
/* OSM_ACT_HpuxFreeMem Implementation */
/*----------------------------------------------------------------------------*/
952 int OSM_ACT_HpuxFreeMem::execute ( const ACE_TCHAR* cmd_line, const int cmd_len,
953 const int timeout , ACE_TCHAR* val_text ,
int& val_len , int& value )
{
//Uncomment this if you want to trace this function.
//if ( OSM_CfgManager::instance( )->debug_mode( ) )
//{
// ACE_DEBUG( ( LM_DEBUG,
// ACE_TEXT( "( %P|%t ) OSM_Action: execute( ) [%s] TimeOut: %d\n" ),
// cmd_line, timeout ) );
//}
// // Use your own command line checker method. See below.
// if ( -1 == this->check_cmd_line( cmd_line, cmd_len ) )
// {
// ACE_ERROR( ( LM_ERROR,
// ACE_TEXT( "( %P|%t ) OSM_Action : Bad command line [%s]\n" ),
// cmd_line ) );
// return -1;
// }
// We could also check the command line parameters for our event into the cfg file.
// EVENT = -t timeout [-c 0, 1 -w warn -a alarm -s( ilent )]
// if ( OSM_CfgManager::instance( )->debug_mode( ) )
// {
// ACE_DEBUG( ( LM_DEBUG,
// ACE_TEXT( "( %P|%t ) OSM_Action: Config Parameters are [%s]\n" ),
// this->ev_parameters( ) ) );
// }
ACE_TCHAR command[BUFSIZ+1]="";
ACE_OS::sprintf( command, "ksh -c \"vmstat | tail -1 | awk '{print ( $5*4 )/1024}'\"" );
value = 0;
if ( -1 == OSM_ACT_ExecuteProcess::execute( command, ACE_OS::strlen( command ),
timeout , val_text ,
val_len , value ) )
{
return -1;
}
value = ACE_OS::atoi( val_text );
if ( value < 0 )
{
value = -1;
ACE_OS::sprintf( val_text, "command [%s] failed!!", command );
val_len = ACE_OS::strlen( val_text );
return -1;
}
val_text[0] = '\0';
val_len = 0;
return 0;
}
/*----------------------------------------------------------------------------*/
/* OSM_ACT_HpuxUpTime Implementation */
/*----------------------------------------------------------------------------*/
1013 int OSM_ACT_HpuxUpTime::execute( const ACE_TCHAR* cmd_line, const int cmd_len ,
1014 const int timeout , ACE_TCHAR* val_text,
int& val_len , int& value )
{
//Uncomment this if you want to trace this function.
//if ( OSM_CfgManager::instance( )->debug_mode( ) )
//{
// ACE_DEBUG( ( LM_DEBUG,
// ACE_TEXT( "( %P|%t ) OSM_Action: execute( ) [%s] TimeOut: %d\n" ),
// cmd_line, timeout ) );
//}
// Use your own command line checker method. See below.
// if ( -1 == this->check_cmd_line( cmd_line, cmd_len ) )
// {
// ACE_ERROR( ( LM_ERROR,
// ACE_TEXT( "( %P|%t ) OSM_Action : Bad command line [%s]\n" ),
// cmd_line ) );
// return -1;
// }
// We could also check the command line parameters for our event into the cfg file.
// EVENT = -t timeout [-c 0, 1 -w warn -a alarm -s( ilent )]
// if ( OSM_CfgManager::instance( )->debug_mode( ) )
// {
// ACE_DEBUG( ( LM_DEBUG,
// ACE_TEXT( "( %P|%t ) OSM_Action: Config Parameters are [%s]\n" ),
// this->ev_parameters( ) ) );
// }
// Lets do important things .....
// Get uptime value in seconds in HP-UX.
struct pst_static pst;
pstat_getstatic ( &pst, sizeof ( pst ), ( size_t ) 1, 0 );
// {
// ACE_ERROR( ( LM_ERROR, ACE_TEXT( "( %P|%t ) OSM_Action : could not obtain HP-UX uptime\n" ) ) );
// value = -1;
// return -1;
// }
this->uptime_ = ( time( NULL ) - pst.boot_time );
value = this-> uptime_;
int days = value / 86400;
int hours = ( value/3600 ) - ( days * 24 );
int mins = ( value/60 ) - ( ( days * 1440 ) + ( hours * 60 ) );
OSM_Instance_Hpux* p = ( OSM_Instance_Hpux* ) this->instance( );
ACE_OS::sprintf( val_text, "Days[%d] Hours[%d] Mins[%d] [%s]",
days ,
hours ,
mins ,
p->hostname( ) );
val_len=ACE_OS::strlen( val_text );
//ACE_OS::sprintf( val_text, "Uptime:[%d]",
// this->uptime_ );
//val_len=ACE_OS::strlen( val_text );
return 0;
}
/*----------------------------------------------------------------------------*/
//int OSM_ACT_HpuxUpTime::check_cmd_line( const ACE_TCHAR* cmd_line,
// const int cmd_len )
//{
// // Uncomment this if you want to trace this function ( and run with "-d" )
// //if ( OSM_CfgManager::instance( )->debug_mode( ) )
// //{
// // ACE_DEBUG( ( LM_DEBUG,
// // ACE_TEXT( "( %P|%t ) OSM_Action: check_cmd_line( ) [%s] %d\n" ),
// // cmd_line, cmd_len ) );
// //}
//
// // Check the Command Line.
//
// return 0;
//}
/*----------------------------------------------------------------------------*/
/* OSM_ACT_HpuxProcessDown Implementation */
/*----------------------------------------------------------------------------*/
1094 int OSM_ACT_HpuxProcessDown::execute ( const ACE_TCHAR* cmd_line, const int cmd_len,
1095