diff options
author | wilson_d <wilson_d@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2003-12-22 01:44:39 +0000 |
---|---|---|
committer | wilson_d <wilson_d@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2003-12-22 01:44:39 +0000 |
commit | 8baa9efef6fb74b6882c89ca6b198784a89e8256 (patch) | |
tree | 8262d7e8599334f6f03607a19fbea89556dd952f /TAO/orbsvcs | |
parent | bee9b009502570c2ccda8417563f268d6a3c0087 (diff) | |
download | ATCD-8baa9efef6fb74b6882c89ca6b198784a89e8256.tar.gz |
ChangeLogTag: Sun Dec 21 19:35:44 2003 Dale Wilson <wilson_d@ociweb.com>
Diffstat (limited to 'TAO/orbsvcs')
155 files changed, 26137 insertions, 177 deletions
diff --git a/TAO/orbsvcs/FTRT_Event_Service/Factory_Service/EventChannelFactory_i.cpp b/TAO/orbsvcs/FTRT_Event_Service/Factory_Service/EventChannelFactory_i.cpp index 8f8985276c8..35a72e48214 100644 --- a/TAO/orbsvcs/FTRT_Event_Service/Factory_Service/EventChannelFactory_i.cpp +++ b/TAO/orbsvcs/FTRT_Event_Service/Factory_Service/EventChannelFactory_i.cpp @@ -22,17 +22,17 @@ EventChannelFactory_i::EventChannelFactory_i(const char* conf_filename, CORBA::O CORBA::Object_ptr EventChannelFactory_i::create_object ( const char * type_id, - const FT::Criteria & the_criteria, - FT::GenericFactory::FactoryCreationId_out factory_creation_id + const PortableGroup::Criteria & the_criteria, + PortableGroup::GenericFactory::FactoryCreationId_out factory_creation_id ACE_ENV_ARG_DECL ) ACE_THROW_SPEC (( CORBA::SystemException - , FT::NoFactory - , FT::ObjectNotCreated - , FT::InvalidCriteria - , FT::InvalidProperty - , FT::CannotMeetCriteria + , PortableGroup::NoFactory + , PortableGroup::ObjectNotCreated + , PortableGroup::InvalidCriteria + , PortableGroup::InvalidProperty + , PortableGroup::CannotMeetCriteria )) { @@ -42,17 +42,17 @@ CORBA::Object_ptr EventChannelFactory_i::create_object ( ACE_TRY { - file = fopen(conf_file, "r"); - if (file == 0) - ACE_TRY_THROW (FT::NoFactory()); + file = fopen(conf_file, "r"); + if (file == 0) + ACE_TRY_THROW (PortableGroup::NoFactory()); - ACE_Read_Buffer read_buf(file); + ACE_Read_Buffer read_buf(file); - while ((id_str = read_buf.read(' ')) != 0 && - (prog = read_buf.read('\n')) != 0) { - id_str[strlen(id_str)-1] = '\0'; - if (strcmp(id_str, type_id) == 0) { - return create_process(prog, the_criteria, factory_creation_id); + while ((id_str = read_buf.read(' ')) != 0 && + (prog = read_buf.read('\n')) != 0) { + id_str[strlen(id_str)-1] = '\0'; + if (strcmp(id_str, type_id) == 0) { + return create_process(prog, the_criteria, factory_creation_id); } } } @@ -65,16 +65,16 @@ CORBA::Object_ptr EventChannelFactory_i::create_object ( ACE_ENDTRY; ACE_CHECK_RETURN(CORBA::Object::_nil()); - ACE_THROW_RETURN(FT::ObjectNotCreated(), CORBA::Object::_nil()); + ACE_THROW_RETURN(PortableGroup::ObjectNotCreated(), CORBA::Object::_nil()); } void EventChannelFactory_i::delete_object ( - const FT::GenericFactory::FactoryCreationId & factory_creation_id + const PortableGroup::GenericFactory::FactoryCreationId & factory_creation_id ACE_ENV_ARG_DECL_NOT_USED ) ACE_THROW_SPEC (( CORBA::SystemException - , FT::ObjectNotFound + , PortableGroup::ObjectNotFound )) { ACE_TRACE("EventChannelFactory_i::delete_object"); @@ -89,8 +89,8 @@ void EventChannelFactory_i::delete_object ( CORBA::Object_ptr EventChannelFactory_i::create_process ( char * process_str, - const FT::Criteria & the_criteria, - FT::GenericFactory::FactoryCreationId_out factory_creation_id) + const PortableGroup::Criteria & the_criteria, + PortableGroup::GenericFactory::FactoryCreationId_out factory_creation_id) { ACE_TRACE("EventChannelFactory_i::create_process"); @@ -99,7 +99,7 @@ CORBA::Object_ptr EventChannelFactory_i::create_process ( // fill the factory_creation_id ACE_NEW_RETURN(factory_creation_id, - FT::GenericFactory::FactoryCreationId, + PortableGroup::GenericFactory::FactoryCreationId, CORBA::Object::_nil()); *factory_creation_id <<= (CORBA::ULong) ++id; diff --git a/TAO/orbsvcs/FTRT_Event_Service/Factory_Service/EventChannelFactory_i.h b/TAO/orbsvcs/FTRT_Event_Service/Factory_Service/EventChannelFactory_i.h index 28a1c8f668e..656df7363bf 100644 --- a/TAO/orbsvcs/FTRT_Event_Service/Factory_Service/EventChannelFactory_i.h +++ b/TAO/orbsvcs/FTRT_Event_Service/Factory_Service/EventChannelFactory_i.h @@ -21,39 +21,39 @@ # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ -class EventChannelFactory_i : public POA_FT::GenericFactory { +class EventChannelFactory_i : public POA_PortableGroup::GenericFactory { public: EventChannelFactory_i(const char* conf_filename, CORBA::ORB_ptr); virtual CORBA::Object_ptr create_object ( const char * type_id, - const FT::Criteria & the_criteria, - FT::GenericFactory::FactoryCreationId_out factory_creation_id + const PortableGroup::Criteria & the_criteria, + PortableGroup::GenericFactory::FactoryCreationId_out factory_creation_id ACE_ENV_ARG_DECL ) ACE_THROW_SPEC (( CORBA::SystemException - , FT::NoFactory - , FT::ObjectNotCreated - , FT::InvalidCriteria - , FT::InvalidProperty - , FT::CannotMeetCriteria + , PortableGroup::NoFactory + , PortableGroup::ObjectNotCreated + , PortableGroup::InvalidCriteria + , PortableGroup::InvalidProperty + , PortableGroup::CannotMeetCriteria )) ; virtual void delete_object ( - const FT::GenericFactory::FactoryCreationId & factory_creation_id + const PortableGroup::GenericFactory::FactoryCreationId & factory_creation_id ACE_ENV_ARG_DECL ) ACE_THROW_SPEC (( CORBA::SystemException - , FT::ObjectNotFound + , PortableGroup::ObjectNotFound )); private: CORBA::Object_ptr create_process ( char * process, - const FT::Criteria & the_criteria, - FT::GenericFactory::FactoryCreationId_out factory_creation_id); + const PortableGroup::Criteria & the_criteria, + PortableGroup::GenericFactory::FactoryCreationId_out factory_creation_id); const char* conf_file; int id; diff --git a/TAO/orbsvcs/FT_ReplicationManager/FT_DefaultFaultAnalyzer.cpp b/TAO/orbsvcs/FT_ReplicationManager/FT_DefaultFaultAnalyzer.cpp new file mode 100755 index 00000000000..c569626b386 --- /dev/null +++ b/TAO/orbsvcs/FT_ReplicationManager/FT_DefaultFaultAnalyzer.cpp @@ -0,0 +1,168 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FT_DefaultFaultAnalyzer.cpp + * + * $Id$ + * + * This file is part of TAO's implementation of Fault Tolerant CORBA. + * + * @author Steve Totten <totten_s@ociweb.com> + */ +//============================================================================= + +#include "FT_DefaultFaultAnalyzer.h" +#include "orbsvcs/CosNotifyCommC.h" +#include "orbsvcs/FT_NotifierC.h" +#include "orbsvcs/FT_FaultDetectorFactoryC.h" +#include "orbsvcs/FT_ReplicationManagerC.h" +#include "orbsvcs/FT_ReplicationManager/FT_FaultEventDescriptor.h" +#include <tao/debug.h> + +ACE_RCSID (FT_DefaultFaultAnalyzer, + FT_DefaultFaultAnalyzer, + "$Id$") + +/// Default constructor. +TAO::FT_DefaultFaultAnalyzer::FT_DefaultFaultAnalyzer () +{ +} + +/// Destructor. +TAO::FT_DefaultFaultAnalyzer::~FT_DefaultFaultAnalyzer () +{ +} + +// Validate the event to make sure it is one we can handle. +// If it is not an event we can handle, this function logs the error +// and returns -1. +int TAO::FT_DefaultFaultAnalyzer::validate_event_type ( + const CosNotification::StructuredEvent & event) +{ + int result = 0; + + // CORBA 3.0.2, section 23.4.5.1 states: + // + // The fault management specification defines one event type: + // ObjectCrashFault. As the name suggests, this event is + // generated by a Fault Detector when it detects that an object + // has crashed. + + // So, the event header's event_type.domain_name must be "FT_CORBA" + // and the event header's event_type.type_name must be "ObjectCrashFault". + // @@ why make string dups just to do a strcmp? + CORBA::String_var domain_name = CORBA::string_dup ( + event.header.fixed_header.event_type.domain_name); + CORBA::String_var type_name = CORBA::string_dup ( + event.header.fixed_header.event_type.type_name); + CORBA::String_var event_name = CORBA::string_dup ( + event.header.fixed_header.event_name); + + if (result == 0) + { + if (ACE_OS::strcmp (domain_name.in(), FT::FT_EVENT_TYPE_DOMAIN) != 0 || + ACE_OS::strcmp (type_name.in(), FT::FT_EVENT_TYPE_NAME) != 0) + { + if (TAO_debug_level > 6) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ( + "TAO::FT_DefaultFaultAnalyzer::validate_event_type: " + "Received invalid event type.\n" + "EventType domain: <%s>\n" + "EventType type: <%s>\n" + "EventName: <%s>\n"), + domain_name.in(), + type_name.in(), + event_name.in() + )); + } + result = -1; + } + } + + // CORBA 3.0.2, section 23.4.5.1 also states: + // + // The filterable_data part of the event body contains the + // identity of the crashed object as four name-value pairs: the + // fault tolerance domain identifier, the member’s location + // identifier, the repository identifier and the object group + // identifier. The Fault Notifier filters events based on the + // domain_name, the type_name, and the four identifiers. All + // other fields of the structured event may be set to null. + // + // The Fault Detector always sets the following fault event + // fields: domain_name, type_name, FTDomainId, and Location. + // + // So, at least "FTDomainId" and "Location" must be present: + if (result == 0) + { + if (event.filterable_data.length () >= 2) + { + // Check for FTDomainId. + if (ACE_OS::strcmp ( + event.filterable_data[0].name.in(), FT::FT_DOMAIN_ID) != 0) + { + if (TAO_debug_level > 6) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ( + "TAO::FT_DefaultFaultAnalyzer::validate_event_type: " + "Received invalid structured event.\n" + "filterable_data[0] must be \"FTDomainId\", not \"%s\"\n"), + event.filterable_data[0].name.in() + )); + } + result = -1; + } + else if (ACE_OS::strcmp ( + event.filterable_data[1].name.in(), FT::FT_LOCATION) != 0) + { + if (TAO_debug_level > 6) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ( + "TAO::FT_DefaultFaultAnalyzer::validate_event_type: " + "Received invalid structured event.\n" + "filterable_data[1] must be \"Location\", not \"%s\"\n"), + event.filterable_data[1].name.in() + )); + } + result = -1; + } + } + else + { + if (TAO_debug_level > 6) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ( + "TAO::FT_DefaultFaultAnalyzer::validate_event_type: " + "Received invalid structured event.\n" + "There must be at least two name/value pairs in " + "the filterable_data field, for \"FTDomainId\" and \"Location\".\n") + )); + } + result = -1; + } + } + + return result; +} + +/// Analyze a fault event. +int TAO::FT_DefaultFaultAnalyzer::analyze_fault_event ( + const CosNotification::StructuredEvent & event) +{ + if (TAO_debug_level > 6) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ( + "In TAO::FT_DefaultFaultAnalyzer::analyze_fault_event.\n") + )); + } + + // no-op + return 0; +} + diff --git a/TAO/orbsvcs/FT_ReplicationManager/FT_DefaultFaultAnalyzer.h b/TAO/orbsvcs/FT_ReplicationManager/FT_DefaultFaultAnalyzer.h new file mode 100755 index 00000000000..e5b1b0b8292 --- /dev/null +++ b/TAO/orbsvcs/FT_ReplicationManager/FT_DefaultFaultAnalyzer.h @@ -0,0 +1,86 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FT_DefaultFaultAnalyzer.h + * + * $Id$ + * + * This file is part of TAO's implementation of Fault Tolerant CORBA. + * This is the default implementation of a fault analyzer that + * implements the interface of the abstract base class + * TAO::FT_FaultAnalyzer. + * + * @author Steve Totten <totten_s@ociweb.com> + */ +//============================================================================= + + +#ifndef FT_DEFAULT_FAULT_ANALYZER_H_ +#define FT_DEFAULT_FAULT_ANALYZER_H_ + +#include /**/ "ace/pre.h" +#include <ace/ACE.h> + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "FT_ReplicationManagerLib_export.h" +#include "FT_FaultAnalyzer.h" + +namespace TAO +{ + + /** + * Default fault analyzer. + * + */ + class TAO_ReplicationManagerLib_Export FT_DefaultFaultAnalyzer + : public ::TAO::FT_FaultAnalyzer + { + + public: + /** + * Default constructor. + */ + FT_DefaultFaultAnalyzer (); + + /** + * Destructor. + */ + virtual ~FT_DefaultFaultAnalyzer (); + + public: + + /** + * Validate event type to make sure it is one we can handle. + * @param event The structured fault event, as from the Fault Notifier. + * @return 0 if it is a valid event type, -1 otherwise. + */ + virtual int validate_event_type ( + const CosNotification::StructuredEvent & event); + + /** + * Analyze a fault event. + * @param event The structured fault event, as from the Fault Notifier. + * @return 0 on success, -1 on failure. + */ + virtual int analyze_fault_event ( + const CosNotification::StructuredEvent & event); + + //////////////////// + // Forbidden methods + private: + /// Copy constructor. + FT_DefaultFaultAnalyzer (const FT_DefaultFaultAnalyzer & rhs); + /// Assignment operator. + FT_DefaultFaultAnalyzer & operator = (const FT_DefaultFaultAnalyzer & rhs); + + }; + +} // namespace TAO + +#include /**/ "ace/post.h" + +#endif /* FT_DEFAULT_FAULT_ANALYZER_H_ */ + diff --git a/TAO/orbsvcs/FT_ReplicationManager/FT_FaultAnalyzer.cpp b/TAO/orbsvcs/FT_ReplicationManager/FT_FaultAnalyzer.cpp new file mode 100755 index 00000000000..97f0af6e56c --- /dev/null +++ b/TAO/orbsvcs/FT_ReplicationManager/FT_FaultAnalyzer.cpp @@ -0,0 +1,29 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FT_FaultAnalyzer.cpp + * + * $Id$ + * + * This file is part of TAO's implementation of Fault Tolerant CORBA. + * + * @author Steve Totten <totten_s@ociweb.com> + */ +//============================================================================= + +#include "FT_FaultAnalyzer.h" + +ACE_RCSID (FT_FaultAnalyzer, + FT_FaultAnalyzer, + "$Id$") + +/// Default constructor. +TAO::FT_FaultAnalyzer::FT_FaultAnalyzer () +{ +} + +/// Destructor. +TAO::FT_FaultAnalyzer::~FT_FaultAnalyzer () +{ +} + diff --git a/TAO/orbsvcs/FT_ReplicationManager/FT_FaultAnalyzer.h b/TAO/orbsvcs/FT_ReplicationManager/FT_FaultAnalyzer.h new file mode 100755 index 00000000000..814162e6662 --- /dev/null +++ b/TAO/orbsvcs/FT_ReplicationManager/FT_FaultAnalyzer.h @@ -0,0 +1,85 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FT_FaultAnalyzer.h + * + * $Id$ + * + * This file is part of TAO's implementation of Fault Tolerant CORBA. + * + * @author Steve Totten <totten_s@ociweb.com> + */ +//============================================================================= + + +#ifndef FT_FAULT_ANALYZER_H_ +#define FT_FAULT_ANALYZER_H_ + +#include /**/ "ace/pre.h" +#include <ace/ACE.h> + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "FT_ReplicationManagerLib_export.h" +#include "orbsvcs/CosNotifyCommC.h" + +namespace TAO +{ + /** + * Abstract base class for application-defined fault analyzers. + * + */ + class TAO_ReplicationManagerLib_Export FT_FaultAnalyzer + { + + public: + /** + * Default constructor. + */ + FT_FaultAnalyzer (); + + /** + * Destructor. + */ + virtual ~FT_FaultAnalyzer (); + + public: + + /** + * Validate event type to make sure it is one we can handle. + * @param event The structured fault event, as from the Fault Notifier. + * @return 0 if it is a valid event type, -1 otherwise. + */ + virtual int validate_event_type ( + const CosNotification::StructuredEvent & event) = 0; + + /** + * Analyze a fault event. + * @param event The structured fault event, as from the Fault Notifier. + * @return 0 on success, -1 on failure. + */ + virtual int analyze_fault_event ( + const CosNotification::StructuredEvent & event) = 0; + + //////////////////// + // Forbidden methods + private: + /// Copy constructor. + FT_FaultAnalyzer (const FT_FaultAnalyzer & rhs); + /// Assignment operator. + FT_FaultAnalyzer & operator = (const FT_FaultAnalyzer & rhs); + + /////////////// + // Data Members + private: + + }; + +} // namespace TAO + +#include /**/ "ace/post.h" + +#endif /* FT_FAULT_ANALYZER_H_ */ + diff --git a/TAO/orbsvcs/FT_ReplicationManager/FT_FaultConsumer.cpp b/TAO/orbsvcs/FT_ReplicationManager/FT_FaultConsumer.cpp new file mode 100755 index 00000000000..0467dfde29e --- /dev/null +++ b/TAO/orbsvcs/FT_ReplicationManager/FT_FaultConsumer.cpp @@ -0,0 +1,297 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FT_FaultConsumer.cpp + * + * $Id$ + * + * This file is part of TAO's implementation of Fault Tolerant CORBA. + * This file provides the implementation of the TAO::FT_FaultConsumer + * class. The TAO::FT_FaultConsumer connects to the FaultNotifier to + * receive fault reports. It interacts with the ReplicationManager + * to process fault reports (e.g., to set a new primary on an object + * group or to create a new member of an object group). + * + * @author Steve Totten <totten_s@ociweb.com> + */ +//============================================================================= + +#include "FT_FaultConsumer.h" +#include "orbsvcs/FT_ReplicationManagerC.h" +#include "orbsvcs/FT_ReplicationManager/FT_FaultAnalyzer.h" +#include <tao/debug.h> + +ACE_RCSID (FT_FaultConsumer, + FT_FaultConsumer, + "$Id$") + +/// Default constructor. +TAO::FT_FaultConsumer::FT_FaultConsumer () + : poa_ (PortableServer::POA::_nil ()) + , fault_notifier_ (FT::FaultNotifier::_nil ()) + , fault_analyzer_ (0) + , consumer_id_ (0) + , consumer_ref_ (CosNotifyComm::StructuredPushConsumer::_nil ()) + , notifications_ (0) +{ +} + +/// Destructor. +TAO::FT_FaultConsumer::~FT_FaultConsumer () +{ +} + +/** +* Connect to the FT::FaultNotifier. +* Note: We make the following assumptions about what the +* application will do: +* - Create an instance of this consumer class. +* - Obtain the object reference of the FaultNotifier to which this +* consumer should connect. +* - Call this init() method, passing it the POA with which we +* have been activated, the FaultNotifier, and ReplicationManager +* object references. +*/ +int TAO::FT_FaultConsumer::init ( + PortableServer::POA_ptr poa, + FT::FaultNotifier_ptr fault_notifier, + TAO::FT_FaultAnalyzer * fault_analyzer + ACE_ENV_ARG_DECL) +{ + + if (TAO_debug_level > 1) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ( + "Enter TAO::FT_FaultConsumer::init.\n") + )); + } + + ACE_ASSERT (!CORBA::is_nil (poa)); + ACE_ASSERT (!CORBA::is_nil (fault_notifier)); + ACE_ASSERT (fault_analyzer != 0); + + // Duplicate the object references passed in. + this->poa_ = + PortableServer::POA::_duplicate (poa); + this->fault_notifier_ = + FT::FaultNotifier::_duplicate (fault_notifier); + + // We have no ownership responsibilities for the Fault Analyzer. + this->fault_analyzer_ = fault_analyzer; + + //@@ Should this init() method activate the consumer in the POA, or + // should the application do that? + // I don't think this object can activate itself because it doesn't + // know the policies on the POA. So, we assume the application has + // already activated us. + //@@ For now, let's try just activating it in the POA. + + // Activate this consumer in the POA. + this->object_id_ = this->poa_->activate_object (this ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + CORBA::Object_var obj = + this->poa_->id_to_reference (this->object_id_.in() ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + // Narrow it to CosNotifyComm::StructuredPushConsumer. + this->consumer_ref_ = CosNotifyComm::StructuredPushConsumer::_narrow ( + obj.in() ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + // Subscribe to the FaultNotifier. + CosNotifyFilter::Filter_var filter = CosNotifyFilter::Filter::_nil (); + this->consumer_id_ = fault_notifier_->connect_structured_fault_consumer ( + this->consumer_ref_.in(), filter ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (TAO_debug_level > 1) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ( + "Leave TAO::FT_FaultConsumer::init.\n") + )); + } + + // Success. + return 0; +} + +/** +* Clean house for process shut down. +* - Disconnect from FT::FaultNotifier. +* - Deactivate from the POA. +*/ +int TAO::FT_FaultConsumer::fini (ACE_ENV_SINGLE_ARG_DECL) +{ + + if (TAO_debug_level > 1) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Enter TAO::FT_FaultConsumer::fini.\n") + )); + } + + // Disconnect from the FaultNotifier. + // Swallow any exception. + ACE_TRY_NEW_ENV + { + if (!CORBA::is_nil (this->fault_notifier_.in())) + { + + if (TAO_debug_level > 1) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ( + "TAO::FT_FaultConsumer::fini: " + "Disconnecting consumer from FaultNotifier.\n") + )); + } + + this->fault_notifier_->disconnect_consumer ( + this->consumer_id_ ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (TAO_debug_level > 1) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ( + "TAO::FT_FaultConsumer::fini: " + "Deactivating from POA.\n") + )); + } + + // Deactivate ourself from the POA. + this->poa_->deactivate_object ( + this->object_id_.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + ACE_TEXT ( + "TAO::FT_FaultConsumer::fini: " + "Error disconnecting from notifier (ignored).\n") + ); + } + ACE_ENDTRY; + ACE_CHECK_RETURN(1); + + if (TAO_debug_level > 1) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ( + "TAO::FT_FaultConsumer::fini: " + "Setting our object reference to nil.\n") + )); + } + + this->consumer_ref_ = CosNotifyComm::StructuredPushConsumer::_nil (); + + if (TAO_debug_level > 1) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Leave TAO::FT_FaultConsumer::fini.\n") + )); + } + + // Success. + return 0; +} + +CosNotifyComm::StructuredPushConsumer_ptr +TAO::FT_FaultConsumer::consumer_ref () +{ + return CosNotifyComm::StructuredPushConsumer::_duplicate ( + this->consumer_ref_); +} + +size_t TAO::FT_FaultConsumer::notifications () const +{ + return this->notifications_; +} + + +/////////////////// +// CORBA operations + +// Receive and process an incoming fault event from the Fault Notifier. +// First, we validate the event to make sure it is something we can +// handle. Then, we analyze it. If it is not an event we can handle, +// we simply log the error and drop the event. +void TAO::FT_FaultConsumer::push_structured_event ( + const CosNotification::StructuredEvent &event + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ) + ACE_THROW_SPEC ((CORBA::SystemException, CosEventComm::Disconnected)) +{ + // Debugging support. + this->notifications_ += 1; + if (TAO_debug_level > 1) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ( + "TAO::FT_FaultConsumer::push_structured_event: " + "Received Fault notification(%d):\n"), + ACE_static_cast (unsigned int, this->notifications_) + )); + } + + int result = 0; + + // Make sure it is an event type we can handle. + if (result == 0) + { + result = this->fault_analyzer_->validate_event_type (event); + if (result != 0) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ( + "TAO::FT_FaultConsumer::push_structured_event: " + "Received invalid fault event type.\n") + )); + } + } + + // Analyze the event. + if (result == 0) + { + result = this->fault_analyzer_->analyze_fault_event (event); + if (result != 0) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ( + "TAO::FT_FaultConsumer::push_structured_event: " + "Could not analyze fault event.\n") + )); + } + } + + return; +} + +void TAO::FT_FaultConsumer::offer_change ( + const CosNotification::EventTypeSeq & added, + const CosNotification::EventTypeSeq & removed + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ) + ACE_THROW_SPEC ((CORBA::SystemException, CosNotifyComm::InvalidEventType)) +{ + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("TAO::FT_FaultConsumer::offer_change() call ignored.\n") + )); +} + +void TAO::FT_FaultConsumer::disconnect_structured_push_consumer ( + ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS + ) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + //TODO: For now, we are just ignoring the disconnect callback. + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("TAO::FT_FaultConsumer::disconnect_structured_push_consumer() " + "call ignored.\n") + )); +} + diff --git a/TAO/orbsvcs/FT_ReplicationManager/FT_FaultConsumer.h b/TAO/orbsvcs/FT_ReplicationManager/FT_FaultConsumer.h new file mode 100755 index 00000000000..4ce246a321a --- /dev/null +++ b/TAO/orbsvcs/FT_ReplicationManager/FT_FaultConsumer.h @@ -0,0 +1,167 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FT_FaultConsumer.h + * + * $Id$ + * + * This file is part of TAO's implementation of Fault Tolerant CORBA. + * + * @author Steve Totten <totten_s@ociweb.com> + */ +//============================================================================= + + +#ifndef FT_FAULT_CONSUMER_H_ +#define FT_FAULT_CONSUMER_H_ + +#include /**/ "ace/pre.h" +#include <ace/ACE.h> + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "orbsvcs/CosNotifyCommS.h" +#include "orbsvcs/FT_NotifierC.h" +#include "FT_ReplicationManagerLib_export.h" + +namespace TAO +{ + + /////////////////////// + // Forward declarations + class FT_FaultAnalyzer; + + /** + * Implement the CosNotifyComm::StructuredPushConsumer interface. + * + */ + class TAO_ReplicationManagerLib_Export FT_FaultConsumer + : public virtual POA_CosNotifyComm::StructuredPushConsumer + , public virtual PortableServer::RefCountServantBase + { + + ////////////////////// + // non-CORBA interface + + public: + /** + * Default constructor. + */ + FT_FaultConsumer (); + + /** + * Destructor. + */ + virtual ~FT_FaultConsumer (); + + /** + * Connect to the FT::FaultNotifier. + * Note: We make the following assumptions about what the + * application will do: + * - Create an instance of this consumer class. + * - Obtain the object reference of the FaultNotifier to which this + * consumer should connect. + * - Call this init() method, passing it the POA with which we + * have been activated, the FaultNotifier, and ReplicationManager + * object references. + */ + int init ( + PortableServer::POA_ptr poa, + FT::FaultNotifier_ptr fault_notifier, + TAO::FT_FaultAnalyzer * fault_analyzer + ACE_ENV_ARG_DECL); + + /** + * Clean house for process shut down. + * - Disconnect from FT::FaultNotifier. + * - Deactivate from the POA. + */ + int fini (ACE_ENV_SINGLE_ARG_DECL); + + /** + * Accessor for a duplicate of this consumer's object reference. + */ + CosNotifyComm::StructuredPushConsumer_ptr consumer_ref (); + + //@@ For testing purposes only, will be removed later. + /** + * Accessor for the number of notifications we have received. + */ + size_t notifications () const; + + public: + + /** + * @name POA_CosNotifyComm::StructuredPushConsumer Methods + * + * Methods required by the POA_CosNotifyComm::StructuredPushConsumer + * interface. + */ + //@{ + + //////////////// + // CORBA methods + virtual void push_structured_event ( + const CosNotification::StructuredEvent ¬ification + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ) + ACE_THROW_SPEC ((CORBA::SystemException, CosEventComm::Disconnected)); + + virtual void offer_change ( + const CosNotification::EventTypeSeq & added, + const CosNotification::EventTypeSeq & removed + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ) + ACE_THROW_SPEC ((CORBA::SystemException, CosNotifyComm::InvalidEventType)); + + virtual void disconnect_structured_push_consumer ( + ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS + ) + ACE_THROW_SPEC ((CORBA::SystemException)); + + //@} + + //////////////////// + // Forbidden methods + private: + /// Copy constructor. + FT_FaultConsumer (const FT_FaultConsumer & rhs); + /// Assignment operator. + FT_FaultConsumer & operator = (const FT_FaultConsumer & rhs); + + /////////////// + // Data Members + private: + + /// The POA with which we are activated. + PortableServer::POA_var poa_; + + /// The ObjectId from our activation in the POA. + PortableServer::ObjectId_var object_id_; + + /// The FaultNotifier's object reference. + FT::FaultNotifier_var fault_notifier_; + + /// Application-specific Fault Analyzer. + TAO::FT_FaultAnalyzer * fault_analyzer_; + + /// ConsumerId assigned by the notifier. + FT::FaultNotifier::ConsumerId consumer_id_; + + /// Our consumer object reference. + CosNotifyComm::StructuredPushConsumer_var consumer_ref_; + + ///TODO: Remove this later, it is just for testing. + // Keep track of how many notifications we have received. + size_t notifications_; + + }; + +} // namespace TAO + +#include /**/ "ace/post.h" + +#endif /* FT_FAULT_CONSUMER_H_ */ + diff --git a/TAO/orbsvcs/FT_ReplicationManager/FT_FaultEventDescriptor.cpp b/TAO/orbsvcs/FT_ReplicationManager/FT_FaultEventDescriptor.cpp new file mode 100755 index 00000000000..a8f7556b3f6 --- /dev/null +++ b/TAO/orbsvcs/FT_ReplicationManager/FT_FaultEventDescriptor.cpp @@ -0,0 +1,91 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FT_FaultEventDescriptor.cpp + * + * $Id$ + * + * This file is part of TAO's implementation of Fault Tolerant CORBA. + * This file provides the implementation of the + * TAO::FT_FaultEventDescriptor structure. The + * TAO::FT_FaultEventDescriptor is a helper type used during + * analysis of fault events. + * + * @author Steve Totten <totten_s@ociweb.com> + */ +//============================================================================= + +#include "FT_FaultEventDescriptor.h" + +ACE_RCSID (FT_FaultEventDescriptor, + FT_FaultEventDescriptor, + "$Id$") + +// Default constructor. +TAO::FT_FaultEventDescriptor::FT_FaultEventDescriptor () + : all_at_location_failed (0) + , all_of_type_at_location_failed (0) + , object_at_location_failed (0) + , object_is_primary (0) + , type_id (CORBA::string_dup ("")) + , object_group_id (PortableGroup::ObjectGroupId (0)) +{ +} + +// Debugging support. +void TAO::FT_FaultEventDescriptor::dump () +{ + // Get the location as a string. + ACE_CString loc_as_string; + for (CORBA::ULong li = 0; li < this->location->length(); ++li) + { + if (li > 0) loc_as_string += "/"; + // Assume only the "id" field of the CosNaming::Name is used. + loc_as_string += CORBA::string_dup (this->location[li].id); + } + + if (this->all_at_location_failed == 1) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ( + "TAO::FT_FaultEventDescriptor::dump: " + "All objects at location <%s> failed.\n"), + loc_as_string.c_str() + )); + } + + if (this->all_of_type_at_location_failed == 1) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ( + "TAO::FT_FaultEventDescriptor::dump: " + "All objects of type <%s> at location <%s> failed.\n"), + this->type_id.in(), + loc_as_string.c_str() + )); + } + + if (this->object_at_location_failed == 1) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ( + "TAO::FT_FaultEventDescriptor::dump: " + "Replica of type <%s> with ObjectGroupId <%Q> " + "at location <%s> failed.\n"), + this->type_id.in(), + this->object_group_id, + loc_as_string.c_str() + )); + } + + if (this->object_is_primary == 1) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ( + "TAO::FT_FaultEventDescriptor::dump: " + "Primary replica of ObjectGroupId <%Q> failed.\n"), + this->object_group_id + )); + } +} + diff --git a/TAO/orbsvcs/FT_ReplicationManager/FT_FaultEventDescriptor.h b/TAO/orbsvcs/FT_ReplicationManager/FT_FaultEventDescriptor.h new file mode 100755 index 00000000000..d0b64b49e4f --- /dev/null +++ b/TAO/orbsvcs/FT_ReplicationManager/FT_FaultEventDescriptor.h @@ -0,0 +1,76 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FT_FaultEventDescriptor.h + * + * $Id$ + * + * This file is part of TAO's implementation of Fault Tolerant CORBA. + * + * @author Steve Totten <totten_s@ociweb.com> + */ +//============================================================================= + + +#ifndef FT_FAULT_EVENT_DESCRIPTOR_H_ +#define FT_FAULT_EVENT_DESCRIPTOR_H_ + +#include /**/ "ace/pre.h" +#include <ace/ACE.h> + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "orbsvcs/FT_CORBAC.h" +#include "orbsvcs/PortableGroupC.h" +#include "FT_ReplicationManagerLib_export.h" + +namespace TAO +{ + /// Helper class for describing the properties in a fault event. + struct TAO_ReplicationManagerLib_Export FT_FaultEventDescriptor + { + public: + + /// Default constructor. + FT_FaultEventDescriptor (); + + /// Debugging support. + void dump (); + + ///////////////// + /// Data members. + + /// Flags indicating the "extent" of the fault. + int all_at_location_failed; + int all_of_type_at_location_failed; + int object_at_location_failed; + int object_is_primary; + + /// The location of the fault. + PortableGroup::Location_var location; + + /// The TypeId of the object that faulted. + PortableGroup::TypeId_var type_id; + + /// The ObjectGroupId of the faulted object. + PortableGroup::ObjectGroupId object_group_id; + + /// Other properties of the object group to which the fault relates. + PortableGroup::MembershipStyleValue membership_style; + FT::ReplicationStyleValue replication_style; + PortableGroup::MinimumNumberMembersValue minimum_number_members; + PortableGroup::InitialNumberMembersValue initial_number_members; + + /// The object group's factories. + PortableGroup::FactoryInfos_var factories; + + }; + +} // namespace TAO + +#include /**/ "ace/post.h" + +#endif /* FT_FAULT_EVENT_DESCRIPTOR_H_ */ + diff --git a/TAO/orbsvcs/FT_ReplicationManager/FT_Property_Validator.cpp b/TAO/orbsvcs/FT_ReplicationManager/FT_Property_Validator.cpp new file mode 100644 index 00000000000..205f9f96d63 --- /dev/null +++ b/TAO/orbsvcs/FT_ReplicationManager/FT_Property_Validator.cpp @@ -0,0 +1,242 @@ +#include "FT_Property_Validator.h" +#include "orbsvcs/PortableGroup/PG_Operators.h" +#include "orbsvcs/FT_ReplicationManagerC.h" + + +ACE_RCSID (PortableGroup, + FT_Property_Validator, + "$Id$") + + +TAO::FT_Property_Validator::FT_Property_Validator (void) + : replication_style_ (1), + membership_style_ (1), + consistency_style_ (1), + fault_monitoring_style_ (1), + fault_monitoring_granularity_ (1), + factories_ (1) +{ + this->replication_style_.length (1); + this->replication_style_[0].id = CORBA::string_dup (::FT::FT_REPLICATION_STYLE); + + this->membership_style_.length (1); + this->membership_style_[0].id = CORBA::string_dup (::FT::FT_MEMBERSHIP_STYLE); + + this->consistency_style_.length (1); + this->consistency_style_[0].id = CORBA::string_dup (::FT::FT_CONSISTENCY_STYLE); + + this->fault_monitoring_style_.length (1); + this->fault_monitoring_style_[0].id = CORBA::string_dup (::FT::FT_FAULT_MONITORING_STYLE); + + this->fault_monitoring_granularity_.length (1); + this->fault_monitoring_granularity_[0].id = CORBA::string_dup (::FT::FT_FAULT_MONITORING_GRANULARITY); + + this->factories_.length (1); + this->factories_[0].id = CORBA::string_dup (::FT::FT_FACTORIES); +} + + +TAO::FT_Property_Validator::~FT_Property_Validator (void) +{ +} + + +void +TAO::FT_Property_Validator::validate_property ( + const PortableGroup::Properties & props + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::InvalidProperty, + PortableGroup::UnsupportedProperty)) +{ + const CORBA::ULong len = props.length (); + + for (CORBA::ULong i = 0; i < len; ++i) + { + const PortableGroup::Property & property = props[i]; + + if (property.nam == this->replication_style_) + { + FT::ReplicationStyleValue value; + if (!(property.val >>= value) + || (value != FT::STATELESS + && value != FT::COLD_PASSIVE + && value != FT::WARM_PASSIVE + && value != FT::ACTIVE + && value != FT::ACTIVE_WITH_VOTING + && value != FT::SEMI_ACTIVE)) + ACE_THROW (PortableGroup::InvalidProperty (property.nam, + property.val)); + } + else if (property.nam == this->membership_style_) + { + PortableGroup::MembershipStyleValue value; + if (!(property.val >>= value) + || (value != PortableGroup::MEMB_APP_CTRL + && value != PortableGroup::MEMB_INF_CTRL)) + ACE_THROW (PortableGroup::InvalidProperty (property.nam, + property.val)); + } + else if (property.nam == this->consistency_style_) + { + FT::ConsistencyStyleValue value; + if (!(property.val >>= value) + || (value != FT::CONS_APP_CTRL + && value != FT::CONS_INF_CTRL)) + ACE_THROW (PortableGroup::InvalidProperty (property.nam, + property.val)); + } + else if (property.nam == this->fault_monitoring_style_) + { + FT::FaultMonitoringStyleValue value; + if (!(property.val >>= value) + || (value != FT::PULL + && value != FT::PUSH + && value != FT::NOT_MONITORED)) + ACE_THROW (PortableGroup::InvalidProperty (property.nam, + property.val)); + } + else if (property.nam == this->fault_monitoring_granularity_) + { + FT::FaultMonitoringGranularityValue value; + if (!(property.val >>= value) + || (value != FT::MEMB + && value != FT::LOC + && value != FT::LOC_AND_TYPE)) + ACE_THROW (PortableGroup::InvalidProperty (property.nam, + property.val)); + } + else if (property.nam == this->factories_) + { + const PortableGroup::FactoriesValue * factories; + if (!(property.val >>= factories)) + ACE_THROW (PortableGroup::InvalidProperty (property.nam, + property.val)); + else + { + const CORBA::ULong flen = factories->length (); + + if (flen == 0) + ACE_THROW (PortableGroup::InvalidProperty (property.nam, + property.val)); + + for (CORBA::ULong j = 0; j < flen; ++j) + { + const PortableGroup::FactoryInfo & factory_info = + (*factories)[j]; + + if (CORBA::is_nil (factory_info.the_factory.in ()) + || factory_info.the_location.length () == 0) + ACE_THROW (PortableGroup::InvalidProperty (property.nam, + property.val)); + } + } + } + } +} + +void +TAO::FT_Property_Validator::validate_criteria ( + const PortableGroup::Properties & props + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::InvalidCriteria, + PortableGroup::CannotMeetCriteria)) +{ + const CORBA::ULong len = props.length (); + PortableGroup::Criteria invalid_criteria; + + // Optimize for the worst case scenario where all properties are + // invalid. + invalid_criteria.length (len); + + /// The invalid criteria index. + CORBA::ULong p = 0; + + for (CORBA::ULong i = 0; i < len; ++i) + { + const PortableGroup::Property & property = props[i]; + CORBA::Long value; + + if (!(property.val >>= value)) + invalid_criteria[p++] = property; + else + { + if (property.nam == this->replication_style_) + { + if ( value != FT::STATELESS + && value != FT::COLD_PASSIVE + && value != FT::WARM_PASSIVE + && value != FT::ACTIVE + && value != FT::ACTIVE_WITH_VOTING + && value != FT::SEMI_ACTIVE ) + invalid_criteria[p++] = property; + } + else if (property.nam == this->membership_style_) + { + if ( value != PortableGroup::MEMB_APP_CTRL + && value != PortableGroup::MEMB_INF_CTRL ) + invalid_criteria[p++] = property; + } + else if (property.nam == this->consistency_style_) + { + if ( value != FT::CONS_APP_CTRL + && value != FT::CONS_INF_CTRL ) + invalid_criteria[p++] = property; + } + else if (property.nam == this->fault_monitoring_style_) + { + if ( value != FT::PULL + && value != FT::PUSH + && value != FT::NOT_MONITORED ) + invalid_criteria[p++] = property; + } + else if (property.nam == this->fault_monitoring_granularity_) + { + if ( value != FT::MEMB + && value != FT::LOC + && value != FT::LOC_AND_TYPE ) + invalid_criteria[p++] = property; + } + else if (property.nam == this->factories_) + { + PortableGroup::FactoriesValue * factories; + if (!(property.val >>= factories)) + invalid_criteria[p++] = property; + else + { + const CORBA::ULong flen = factories->length (); + + if (flen == 0) + invalid_criteria[p++] = property; + else + { + for (CORBA::ULong j = 0; j < flen; ++j) + { + const PortableGroup::FactoryInfo & factory_info = + (*factories)[j]; + + if (CORBA::is_nil (factory_info.the_factory.in ()) + || factory_info.the_location.length () == 0) + { + invalid_criteria[p++] = property; + break; + } + } + } + } + } + } + } + + if (p > 0) + { + // Reduce the length of the invalid criteria sequence in an + // effort to optimize the copying that will occur when the below + // exception is thrown. Reducing the length is fast since no + // deallocations should occur. + invalid_criteria.length (p); + + ACE_THROW (PortableGroup::InvalidCriteria (invalid_criteria)); + } +} diff --git a/TAO/orbsvcs/FT_ReplicationManager/FT_Property_Validator.h b/TAO/orbsvcs/FT_ReplicationManager/FT_Property_Validator.h new file mode 100644 index 00000000000..bfd26227174 --- /dev/null +++ b/TAO/orbsvcs/FT_ReplicationManager/FT_Property_Validator.h @@ -0,0 +1,93 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file FT__Property_Validator.h + * + * $Id$ + * + * @author Curt Hibbs <hibbs_c@ociweb.com> + */ +//============================================================================= + +#ifndef FT_PROPERTY_VALIDATOR_H +#define FT_PROPERTY_VALIDATOR_H + +#include /**/ "ace/pre.h" + +#include "orbsvcs/PortableGroup/PG_Default_Property_Validator.h" +#include "orbsvcs/PortableGroupC.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +namespace TAO +{ + /** + * @class FT_Property_Validator + * + * @brief Default property validator implementation. + * + * This Property_Validator verifies that all properties defined in the + * FT CORBA IDL are valid. + */ + class FT_Property_Validator : public TAO_PG_Default_Property_Validator + { + public: + + /// Constructor. + FT_Property_Validator (void); + + /// Destructor. + virtual ~FT_Property_Validator (void); + + /// Validate the given properties. Throw an exception when the + /// first invalid property is encountered. The remaining properties + /// will not be validated. + virtual + void validate_property (const PortableGroup::Properties & props + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::InvalidProperty, + PortableGroup::UnsupportedProperty)); + + /// Validate the given properties/criteria. All criteria + /// will be validated regardless of whether or not an invalid + /// property was encountered. + virtual + void validate_criteria (const PortableGroup::Properties & criteria + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::InvalidCriteria, + PortableGroup::CannotMeetCriteria)); + + private: + + /** + * @name Pre-initialize property Names. + * + * These properties are pre-initialized once to reduce property + * validation overhead. Note that the following properties are + * not validated since there are no restrictions for these values: + * InitialNumberMembers + * MinimumNumberMembers + * FaultMonitoringInterval + * CheckpointInterval + */ + //@{ + PortableGroup::Name replication_style_; + PortableGroup::Name membership_style_; + PortableGroup::Name consistency_style_; + PortableGroup::Name fault_monitoring_style_; + PortableGroup::Name fault_monitoring_granularity_; + PortableGroup::Name factories_; + //@} + + }; + +} // namespace TAO + +#include "ace/post.h" + +#endif /* FT_PROPERTY_VALIDATOR_H */ diff --git a/TAO/orbsvcs/FT_ReplicationManager/FT_ReplicationManager.cpp b/TAO/orbsvcs/FT_ReplicationManager/FT_ReplicationManager.cpp new file mode 100644 index 00000000000..320ab55f4a8 --- /dev/null +++ b/TAO/orbsvcs/FT_ReplicationManager/FT_ReplicationManager.cpp @@ -0,0 +1,1092 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FT_ReplicationManager.cpp + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * This file implements the FT_ReplicationManager class as declared in + * FT_Replication_Manager.h. + * + * @author Curt Hibbs <hibbs_c@ociweb.com> + */ +//============================================================================= +#include "FT_ReplicationManager.h" +#include "FT_Property_Validator.h" + +#include <ace/Get_Opt.h> +#include <tao/Messaging/Messaging.h> +#include <tao/IORTable/IORTable.h> +#include <tao/debug.h> +#include <orbsvcs/PortableGroup/PG_Object_Group.h> +#include <orbsvcs/PortableGroup/PG_Property_Set.h> +#include <orbsvcs/PortableGroup/PG_Properties_Encoder.h> +#include <orbsvcs/PortableGroup/PG_Property_Utils.h> +#include <orbsvcs/PortableGroup/PG_conf.h> + +#include <orbsvcs/FaultTolerance/FT_IOGR_Property.h> +#include <orbsvcs/FT_ReplicationManager/FT_ReplicationManagerFaultAnalyzer.h> + +ACE_RCSID (FT_ReplicationManager, + FT_ReplicationManager, + "$Id$") + + +// Use this macro at the beginning of CORBA methods +// to aid in debugging. +#define METHOD_ENTRY(name) \ + if (TAO_debug_level > 6) \ + { \ + ACE_DEBUG (( LM_DEBUG, \ + "Enter %s\n", #name \ + )); \ + } + +// Use this macro to return from CORBA methods +// to aid in debugging. Note that you can specify +// the return value after the macro, for example: +// METHOD_RETURN(Plugh::plover) xyzzy; is equivalent +// to return xyzzy; +// METHOD_RETURN(Plugh::troll); is equivalent to +// return; +// WARNING: THIS GENERATES TWO STATEMENTS!!! THE FOLLOWING +// will not do what you want it to: +// if (cave_is_closing) METHOD_RETURN(Plugh::pirate) aarrggh; +// Moral: Always use braces. +#define METHOD_RETURN(name) \ + if (TAO_debug_level > 6) \ + { \ + ACE_DEBUG (( LM_DEBUG, \ + "Leave %s\n", #name \ + )); \ + } \ + return /* value goes here */ + +#define TODO +//#define TODO int todo; // warn on todos + +TAO::FT_ReplicationManager::FT_ReplicationManager () + : orb_ (CORBA::ORB::_nil ()) + , poa_ (PortableServer::POA::_nil ()) + , ior_output_file_ (0) + , ns_name_ (0) + , naming_context_ (CosNaming::NamingContext::_nil ()) + , replication_manager_ref_ (FT::ReplicationManager::_nil ()) + , fault_notifier_ (FT::FaultNotifier::_nil ()) + , fault_notifier_ior_string_ (0) + , fault_consumer_ () + , factory_registry_ ("ReplicationManager::FactoryRegistry") + , quit_ (0) +{ + // init must be called before using this object. +} + +TAO::FT_ReplicationManager::~FT_ReplicationManager (void) +{ + // cleanup happens in fini +} + +//public +int TAO::FT_ReplicationManager::parse_args (int argc, char * argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "n:o:f:"); + int c; + + while ( (c = get_opts ()) != -1) + { + switch (c) + { + case 'o': + this->ior_output_file_ = get_opts.opt_arg (); + break; + + case 'n': + this->ns_name_ = get_opts.opt_arg (); + break; + + case 'f': + this->fault_notifier_ior_string_ = get_opts.opt_arg (); + break; + + case '?': + // fall thru + default: + ACE_ERROR_RETURN ( (LM_ERROR, + ACE_TEXT ("%T %n (%P|%t) - usage: %s") + ACE_TEXT (" -o <iorfile (for testing)>") + ACE_TEXT (" -f <fault notifier IOR (for testing)>") + ACE_TEXT (" -n <name-to-bind-in-NameService (for testing)>") + ACE_TEXT ("\n"), + argv [0]), + -1); + break; + } + } + // Indicates sucessful parsing of the command line + return 0; +} + +//public +const char * TAO::FT_ReplicationManager::identity () const +{ + return this->identity_.c_str (); +} + +//public +int TAO::FT_ReplicationManager::init (CORBA::ORB_ptr orb ACE_ENV_ARG_DECL) +{ + int result = 0; + + if (TAO_debug_level > 1) + { + ACE_DEBUG ( (LM_DEBUG, + ACE_TEXT ( + "%T %n (%P|%t) - Enter TAO::FT_ReplicationManager::init.\n") + )); + } + + + this->orb_ = CORBA::ORB::_duplicate (orb); + + // Get the RootPOA. + CORBA::Object_var poa_obj = this->orb_->resolve_initial_references ( + TAO_OBJID_ROOTPOA ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + this->poa_ = PortableServer::POA::_narrow ( + poa_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + + // initialize the FactoryRegistry + this->factory_registry_.init (this->orb_.in (), this->poa_.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + PortableGroup::FactoryRegistry_var factory_registry = this->factory_registry_.reference (); + + // @@: do we want to use the same poa to create object groups? + this->group_factory_.init ( + this->orb_.in (), + this->poa_.in (), + factory_registry.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + // Activate ourself in the POA. + PortableServer::ObjectId_var oid = this->poa_->activate_object ( + this ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + CORBA::Object_var this_obj = this->poa_->id_to_reference ( + oid.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + this->replication_manager_ref_ = FT::ReplicationManager::_narrow ( + this_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + // If we were given an initial IOR string for a Fault Notifier on the + // command line, convert it to an IOR, then register the fault + // notifier. + if (this->fault_notifier_ior_string_ != 0) + { + CORBA::Object_var notifier_obj = this->orb_->string_to_object ( + this->fault_notifier_ior_string_ ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + FT::FaultNotifier_var notifier = FT::FaultNotifier::_narrow ( + notifier_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + if (! CORBA::is_nil (notifier.in ())) + { + this->register_fault_notifier_i (notifier.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + } + else + { + ACE_ERROR_RETURN ( (LM_ERROR, + ACE_TEXT ( + "%T %n (%P|%t) - " + "Could not resolve notifier IOR.\n")), + -1); + } + } + + // Activate the RootPOA. + PortableServer::POAManager_var poa_mgr = + this->poa_->the_POAManager (ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + poa_mgr->activate (ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + // Register our IOR in the IORTable with the key-string + // "ReplicationManager". + CORBA::Object_var ior_table_obj = + this->orb_->resolve_initial_references ( + TAO_OBJID_IORTABLE ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + IORTable::Table_var ior_table = + IORTable::Table::_narrow (ior_table_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + if (CORBA::is_nil (ior_table.in ())) + { + ACE_ERROR_RETURN ( (LM_ERROR, + ACE_TEXT ("%T %n (%P|%t) - Unable to resolve the IORTable.\n")), + -1); + } + else + { + CORBA::String_var rm_ior_str = this->orb_->object_to_string ( + this->replication_manager_ref_.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + ior_table->bind ("ReplicationManager", rm_ior_str.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + } + + // Publish our IOR, either to a file or the Naming Service. + if (this->ior_output_file_ != 0) + { + this->identity_ = "file:"; + this->identity_ += this->ior_output_file_; + result = this->write_ior (); + } + + if (result == 0 && this->ns_name_ != 0) + { + this->identity_ = "name:"; + this->identity_ += this->ns_name_; + + CORBA::Object_var naming_obj = this->orb_->resolve_initial_references ( + TAO_OBJID_NAMESERVICE ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + this->naming_context_ = + CosNaming::NamingContext::_narrow ( + naming_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (CORBA::is_nil (this->naming_context_.in ())) + { + ACE_ERROR_RETURN ( (LM_ERROR, + ACE_TEXT ("%T %n (%P|%t) - Unable to find the Naming Service.\n")), + -1); + } + + this->this_name_.length (1); + this->this_name_[0].id = CORBA::string_dup (this->ns_name_); + + this->naming_context_->rebind ( + this->this_name_, + this->replication_manager_ref_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + } + + if (TAO_debug_level > 1) + { + if (result == 0) + { + ACE_DEBUG ( (LM_DEBUG, + ACE_TEXT ( + "%T %n (%P|%t) - Leave TAO::FT_ReplicationManager::init.\n") + )); + } + else + { + ACE_DEBUG ( (LM_DEBUG, + ACE_TEXT ( + "%T %n (%P|%t) - FT_ReplicationManager::init failed.\n") + )); + } + } + + //////////////////////////////// + // Initialize default properties + PortableGroup::Value value; + value <<= TAO_PG_MEMBERSHIP_STYLE; + this->properties_support_.set_default_property (PortableGroup::PG_MEMBERSHIP_STYLE, value ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(-1); + + value <<= TAO_PG_INITIAL_NUMBER_MEMBERS; + this->properties_support_.set_default_property (PortableGroup::PG_INITIAL_NUMBER_MEMBERS, value ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(-1); + + value <<= TAO_PG_MINIMUM_NUMBER_MEMBERS; + this->properties_support_.set_default_property (PortableGroup::PG_MINIMUM_NUMBER_MEMBERS, value ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(-1); + + value <<= FT::SEMI_ACTIVE; + this->properties_support_.set_default_property (FT::FT_REPLICATION_STYLE, value ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(-1); + + value <<= FT::CONS_APP_CTRL; + this->properties_support_.set_default_property ( FT::FT_CONSISTENCY_STYLE, value ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(-1); + + value <<= FT::PULL; + this->properties_support_.set_default_property (FT::FT_FAULT_MONITORING_STYLE, value ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(-1); + + value <<= FT::MEMB; + this->properties_support_.set_default_property (FT::FT_FAULT_MONITORING_GRANULARITY, value ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(-1); + +#if 0 + FaultMonitoringIntervalAndTimeoutValue times; + value <<= times; + this->properties_support_.set_default_property (FT::FT_FAULT_MONITORING_INTERVAL_AND_TIMEOUT, value ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(-1); +#endif + +#if 0 + value << interval; + this->properties_support_.set_default_property (FT::FT_CHECKPOINT_INTERVAL, value); +#endif + + + return result; +} + +//public +int TAO::FT_ReplicationManager::idle (int & result) +{ + ACE_UNUSED_ARG (result); + return this->quit_; +} + + +//public +int TAO::FT_ReplicationManager::fini (ACE_ENV_SINGLE_ARG_DECL) +{ + int result = 0; + + result = this->fault_consumer_.fini (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (this->ior_output_file_ != 0) + { + ACE_OS::unlink (this->ior_output_file_); + this->ior_output_file_ = 0; + } + if (this->ns_name_ != 0) + { + this->naming_context_->unbind (this->this_name_ ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + this->ns_name_ = 0; + } + + return result; +} + +//CORBA +void +TAO::FT_ReplicationManager::register_fault_notifier ( + FT::FaultNotifier_ptr fault_notifier + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException)) +{ + this->register_fault_notifier_i (fault_notifier ACE_ENV_ARG_PARAMETER); +} + +//private +void +TAO::FT_ReplicationManager::register_fault_notifier_i ( + FT::FaultNotifier_ptr fault_notifier + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException)) +{ + if (CORBA::is_nil (fault_notifier)) + { + ACE_ERROR ( (LM_ERROR, + ACE_TEXT ( + "%T %n (%P|%t) - " + "Bad Fault Notifier object reference provided.\n") + )); + ACE_THROW (CORBA::BAD_PARAM ( + CORBA::SystemException::_tao_minor_code ( + TAO_DEFAULT_MINOR_CODE, + EINVAL), + CORBA::COMPLETED_NO)); + } + + // Cache new Fault Notifier object reference. + this->fault_notifier_ = FT::FaultNotifier::_duplicate (fault_notifier); + + // Re-initialize our consumer. + // Swallow any exception. + int result = 0; + ACE_TRY_NEW_ENV + { + //@@ should we check to see if a notifier is already registered, rather than + // simply "unregistering"? + result = this->fault_consumer_.fini (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Note if the fini failed, we ignore it. It may not have been registered in the first place. + + // Create a fault analyzer. + TAO::FT_FaultAnalyzer * analyzer = 0; + ACE_NEW_NORETURN ( + analyzer, + TAO::FT_ReplicationManagerFaultAnalyzer (this)); + if (analyzer == 0) + { + ACE_ERROR ( (LM_ERROR, + ACE_TEXT ( + "%T %n (%P|%t) - " + "Error creating FaultAnalyzer.\n" + ) + )); + result = -1; + } + if (result == 0) + { + result = this->fault_consumer_.init ( + this->poa_.in (), + this->fault_notifier_.in (), + analyzer + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + ACE_TEXT ( + "TAO::FT_ReplicationManager::register_fault_notifier_i: " + "Error reinitializing FT_FaultConsumer.\n") + ); + result = -1; + } + ACE_ENDTRY; + + if (result != 0) + { + ACE_ERROR ( (LM_ERROR, + ACE_TEXT ( + "%T %n (%P|%t) - " + "Could not re-initialize FT_FaultConsumer.\n") + )); + + ACE_THROW (CORBA::INTERNAL ( + CORBA::SystemException::_tao_minor_code ( + TAO_DEFAULT_MINOR_CODE, + EINVAL), + CORBA::COMPLETED_NO)); + } +} + + +// Returns the reference of the Fault Notifier. +//CORBA +FT::FaultNotifier_ptr +TAO::FT_ReplicationManager::get_fault_notifier ( + ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException, FT::InterfaceNotFound)) +{ + if (CORBA::is_nil (this->fault_notifier_.in ())) + { + ACE_THROW_RETURN ( FT::InterfaceNotFound () , FT::FaultNotifier::_nil ()); + } + return FT::FaultNotifier::_duplicate (this->fault_notifier_.in ()); +} + + +// TAO-specific find factory registry +//CORBA +::PortableGroup::FactoryRegistry_ptr +TAO::FT_ReplicationManager::get_factory_registry ( + const PortableGroup::Criteria & selection_criteria + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException)) +{ + ACE_UNUSED_ARG (selection_criteria); + return this->factory_registry_.reference (); +} + +// TAO-specific shutdown operation. +//public +void TAO::FT_ReplicationManager::shutdown ( + ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException)) +{ + this->quit_ = 1; +} + +// Get the type_id associated with an object group. +//CORBA +char * TAO::FT_ReplicationManager::type_id ( + PortableGroup::ObjectGroup_ptr object_group + ACE_ENV_ARG_DECL) +{ + char * result = 0; + TAO::PG_Object_Group * group = 0; + if (this->group_factory_.find_group (object_group, group)) + { + result = group->get_type_id (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + } + else + { + ACE_THROW_RETURN (PortableGroup::ObjectGroupNotFound (), 0); + } + return result; +} + +////////////////////////////////////////////////////// +// PortableGroup::PropertyManager methods + +//CORBA +void +TAO::FT_ReplicationManager::set_default_properties ( + const PortableGroup::Properties & props + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException, + PortableGroup::InvalidProperty, + PortableGroup::UnsupportedProperty)) +{ + + this->properties_support_.set_default_properties (props); + //@@ validate properties? +} + +//CORBA +PortableGroup::Properties * +TAO::FT_ReplicationManager::get_default_properties ( + ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException)) +{ + return this->properties_support_.get_default_properties ( + ACE_ENV_SINGLE_ARG_PARAMETER); +} + +//CORBA +void +TAO::FT_ReplicationManager::remove_default_properties ( + const PortableGroup::Properties & props + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException, + PortableGroup::InvalidProperty, + PortableGroup::UnsupportedProperty)) +{ + this->properties_support_.remove_default_properties (props + ACE_ENV_ARG_PARAMETER); +} + +//CORBA +void +TAO::FT_ReplicationManager::set_type_properties ( + const char *type_id, + const PortableGroup::Properties & overrides + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException, + PortableGroup::InvalidProperty, + PortableGroup::UnsupportedProperty)) +{ + this->properties_support_.set_type_properties ( + type_id, + overrides + ACE_ENV_ARG_PARAMETER); +} + +//CORBA +PortableGroup::Properties * +TAO::FT_ReplicationManager::get_type_properties ( + const char *type_id + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException)) +{ + return this->properties_support_.get_type_properties (type_id + ACE_ENV_ARG_PARAMETER); +} + +//CORBA +void +TAO::FT_ReplicationManager::remove_type_properties ( + const char *type_id, + const PortableGroup::Properties & props + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException, + PortableGroup::InvalidProperty, + PortableGroup::UnsupportedProperty)) +{ + this->properties_support_.remove_type_properties ( + type_id, + props + ACE_ENV_ARG_PARAMETER); +} + +//CORBA +void +TAO::FT_ReplicationManager::set_properties_dynamically ( + PortableGroup::ObjectGroup_ptr object_group, + const PortableGroup::Properties & overrides + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException, + PortableGroup::ObjectGroupNotFound, + PortableGroup::InvalidProperty, + PortableGroup::UnsupportedProperty)) +{ + + TAO::PG_Object_Group * group = 0; + if (this->group_factory_.find_group (object_group, group)) + { + group->set_properties_dynamically (overrides ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } + else + { + ACE_THROW (PortableGroup::ObjectGroupNotFound ()); + } +} + +//CORBA +PortableGroup::Properties * +TAO::FT_ReplicationManager::get_properties ( + PortableGroup::ObjectGroup_ptr object_group + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException, + PortableGroup::ObjectGroupNotFound)) +{ + PortableGroup::Properties_var result; + ACE_NEW_THROW_EX (result, PortableGroup::Properties(), CORBA::NO_MEMORY ()); + + TAO::PG_Object_Group * group = 0; + if (this->group_factory_.find_group (object_group, group)) + { + group->get_properties (result ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } + else + { + ACE_THROW (PortableGroup::ObjectGroupNotFound ()); + } + return result._retn(); +} + + +////////////////////////////////////////////////////// +// FT::FTObjectGroupManager methods + +/// Sets the primary member of a group. +//CORBA +PortableGroup::ObjectGroup_ptr +TAO::FT_ReplicationManager::set_primary_member ( + PortableGroup::ObjectGroup_ptr object_group, + const PortableGroup::Location & the_location + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( ( + CORBA::SystemException + , PortableGroup::ObjectGroupNotFound + , PortableGroup::MemberNotFound + , FT::PrimaryNotSet + , FT::BadReplicationStyle + )) +{ + METHOD_ENTRY (TAO::FT_ReplicationManager::set_primary_member); + PortableGroup::ObjectGroup_var result = PortableGroup::ObjectGroup::_nil(); + TAO::PG_Object_Group * group = 0; + if (this->group_factory_.find_group (object_group, group)) + { + + PortableGroup::TagGroupTaggedComponent tag_component; + TAO_FT_IOGR_Property prop (tag_component); + + int sts = group->set_primary_member (&prop, the_location ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (FT_ObjectGroup::_nil ()); + if (sts) + { + result = group->reference (); + } + else + { + ACE_THROW_RETURN (FT::PrimaryNotSet (), PortableGroup::ObjectGroup::_nil ()); + } + } + else + { + ACE_THROW_RETURN (PortableGroup::ObjectGroupNotFound (), PortableGroup::ObjectGroup::_nil ()); + } + METHOD_RETURN (TAO::FT_ReplicationManager::set_primary_member) result._retn (); +} + +//CORBA +PortableGroup::ObjectGroup_ptr +TAO::FT_ReplicationManager::create_member ( + PortableGroup::ObjectGroup_ptr object_group, + const PortableGroup::Location & the_location, + const char * type_id, + const PortableGroup::Criteria & the_criteria + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException, + PortableGroup::ObjectGroupNotFound, + PortableGroup::MemberAlreadyPresent, + PortableGroup::NoFactory, + PortableGroup::ObjectNotCreated, + PortableGroup::InvalidCriteria, + PortableGroup::CannotMeetCriteria)) +{ + PortableGroup::ObjectGroup_var result = PortableGroup::ObjectGroup::_nil(); + TAO::PG_Object_Group * group = 0; + if (this->group_factory_.find_group (object_group, group)) + { + group->create_member (the_location, type_id, the_criteria ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (PortableGroup::ObjectGroup::_nil ()); + result = group->reference (); + } + else + { + if (TAO_debug_level > 0) + { + ACE_ERROR ( (LM_ERROR, + ACE_TEXT ("%T %n (%P|%t) - FT_ReplicationManager::create_member: unknown group\n") + )); + } + ACE_THROW_RETURN (PortableGroup::ObjectGroupNotFound (), result._retn ()); + } + return result._retn(); +} + + +//CORBA +PortableGroup::ObjectGroup_ptr +TAO::FT_ReplicationManager::add_member ( + PortableGroup::ObjectGroup_ptr object_group, + const PortableGroup::Location & the_location, + CORBA::Object_ptr member + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException, + PortableGroup::ObjectGroupNotFound, + PortableGroup::MemberAlreadyPresent, + PortableGroup::ObjectNotAdded)) +{ + METHOD_ENTRY (TAO::FT_ReplicationManager::add_member); + PortableGroup::ObjectGroup_var result = PortableGroup::ObjectGroup::_nil (); + + // Find the object group corresponding to this IOGR + TAO::PG_Object_Group * group = 0; + if (this->group_factory_.find_group (object_group, group)) + { + group->add_member ( + the_location, + member + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + result = group->reference (); + + } + else + { + if (TAO_debug_level > 0) + { + ACE_ERROR ( (LM_ERROR, + ACE_TEXT ("%T %n (%P|%t) - FT_ReplicationManager::add_member to unknown group\n") + )); + } + ACE_THROW_RETURN (PortableGroup::ObjectGroupNotFound (), result._retn ()); + } + METHOD_RETURN (TAO::FT_ReplicationManager::add_member) result._retn (); +} + +//CORBA +PortableGroup::ObjectGroup_ptr +TAO::FT_ReplicationManager::remove_member ( + PortableGroup::ObjectGroup_ptr object_group, + const PortableGroup::Location & the_location + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException, + PortableGroup::ObjectGroupNotFound, + PortableGroup::MemberNotFound)) +{ + PortableGroup::ObjectGroup_var result = PortableGroup::ObjectGroup::_nil (); + + // Find the object group corresponding to this IOGR + TAO::PG_Object_Group * group = 0; + if (this->group_factory_.find_group (object_group, group)) + { + group->remove_member (the_location ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (result._retn ()); + + group->minimum_populate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (result._retn ()); + //@@ how about the case where the member was removed successfully, + // but for one reason or another we were unable to bring the group + // back up to minimum_number_of_replicas? + + result = group->reference (); + } + else + { + ACE_THROW_RETURN (PortableGroup::ObjectGroupNotFound (), result._retn ()); + } + return result._retn (); +} + +//CORBA +PortableGroup::Locations * +TAO::FT_ReplicationManager::locations_of_members ( + PortableGroup::ObjectGroup_ptr object_group + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException, + PortableGroup::ObjectGroupNotFound)) +{ + PortableGroup::Locations * result = 0; + + // Find the object group corresponding to this IOGR + TAO::PG_Object_Group * group = 0; + if (this->group_factory_.find_group (object_group, group)) + { + result = group->locations_of_members ( + ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + } + else + { + if (TAO_debug_level > 0) + { + ACE_ERROR ( (LM_ERROR, + ACE_TEXT ("%T %n (%P|%t) - FT_ReplicationManager::locations_of_members: unknown group\n") + )); + } + ACE_THROW_RETURN (PortableGroup::ObjectGroupNotFound (), 0); + } + return result; +} + +//CORBA +PortableGroup::ObjectGroups * +TAO::FT_ReplicationManager::groups_at_location ( + const PortableGroup::Location & the_location + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException)) +{ + return this->group_factory_.groups_at_location (the_location ACE_ENV_ARG_PARAMETER); +} + +//CORBA +PortableGroup::ObjectGroupId +TAO::FT_ReplicationManager::get_object_group_id ( + PortableGroup::ObjectGroup_ptr object_group + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException, + PortableGroup::ObjectGroupNotFound)) +{ + PortableGroup::ObjectGroupId result = 0; + TAO::PG_Object_Group * group = 0; + if (this->group_factory_.find_group (object_group, group)) + { + group->get_object_group_id (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (result); + result = group->get_object_group_id (); + } + else + { + if (TAO_debug_level > 0) + { + ACE_ERROR ( (LM_ERROR, + ACE_TEXT ("%T %n (%P|%t) - FT_ReplicationManager::get_object_group_id: unknown group\n") + )); + } + ACE_THROW_RETURN (PortableGroup::ObjectGroupNotFound (), result); + } + return result; +} + +//CORBA +PortableGroup::ObjectGroup_ptr +TAO::FT_ReplicationManager::get_object_group_ref ( + PortableGroup::ObjectGroup_ptr object_group + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException, + PortableGroup::ObjectGroupNotFound)) +{ + PortableGroup::ObjectGroup_var result = PortableGroup::ObjectGroup::_nil (); + + // Find the object group corresponding to this IOGR + TAO::PG_Object_Group * group = 0; + if (this->group_factory_.find_group (object_group, group)) + { + result = group->reference (); + } + else + { + if (TAO_debug_level > 0) + { + ACE_ERROR ( (LM_ERROR, + ACE_TEXT ("%T %n (%P|%t) - FT_ReplicationManager::get_object_group_ref: unknown group\n") + )); + } + ACE_THROW_RETURN (PortableGroup::ObjectGroupNotFound (), result._retn ()); + } + return result._retn(); +} + +//CORBA, TAO specific +PortableGroup::ObjectGroup_ptr +TAO::FT_ReplicationManager::get_object_group_ref_from_id ( + PortableGroup::ObjectGroupId group_id + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( ( + CORBA::SystemException + , PortableGroup::ObjectGroupNotFound + )) +{ + PortableGroup::ObjectGroup_var result = PortableGroup::ObjectGroup::_nil (); + + // Find the object group corresponding to this IOGR + TAO::PG_Object_Group * group = 0; + if (this->group_factory_.find_group (group_id, group)) + { + result = group->reference (); + } + else + { + if (TAO_debug_level > 0) + { + ACE_ERROR ( (LM_ERROR, + ACE_TEXT ("%T %n (%P|%t) - FT_ReplicationManager::get_object_group_ref_from_id: unknown group\n") + )); + } + ACE_THROW_RETURN (PortableGroup::ObjectGroupNotFound (), result._retn ()); + } + return result._retn(); +} + +//CORBA +CORBA::Object_ptr +TAO::FT_ReplicationManager::get_member_ref ( + PortableGroup::ObjectGroup_ptr object_group, + const PortableGroup::Location & the_location + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException, + PortableGroup::ObjectGroupNotFound, + PortableGroup::MemberNotFound)) +{ + CORBA::Object_var result = CORBA::Object::_nil(); + + // Find the object group corresponding to this IOGR + TAO::PG_Object_Group * group = 0; + if (this->group_factory_.find_group (object_group, group)) + { + result = group->get_member_reference (the_location ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::Object::_nil()); + } + else + { + if (TAO_debug_level > 0) + { + ACE_ERROR ( (LM_ERROR, + ACE_TEXT ("%T %n (%P|%t) - FT_ReplicationManager::get_member_ref: unknown group\n") + )); + } + ACE_THROW_RETURN (PortableGroup::ObjectGroupNotFound (), result._retn ()); + } + return result._retn(); +} + + +////////////////////////////////////////////////////// +// PortableGroup::GenericFactory methods + +//CORBA +CORBA::Object_ptr +TAO::FT_ReplicationManager::create_object ( + const char * type_id, + const PortableGroup::Criteria & the_criteria, + PortableGroup::GenericFactory::FactoryCreationId_out factory_creation_id + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException, + PortableGroup::NoFactory, + PortableGroup::ObjectNotCreated, + PortableGroup::InvalidCriteria, + PortableGroup::InvalidProperty, + PortableGroup::CannotMeetCriteria)) +{ + METHOD_ENTRY (TAO::FT_ReplicationManager::create_object) + + //////////////////////////////// + // find the properties for this + // type of object group + TAO::PG_Property_Set * typeid_properties + = this->properties_support_.find_typeid_properties ( + type_id + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + TAO::PG_Object_Group * group + = this->group_factory_.create_group ( + type_id, + the_criteria, + typeid_properties + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + group->initial_populate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + //@@ on error we should remove the group from the Group_Factory + // doing this "right" will require a var-type pointer to the object group + // that knows about the factory, too. + + // Allocate a new FactoryCreationId for use as an "out" parameter. + PortableGroup::GenericFactory::FactoryCreationId_var factory_id = 0; + ACE_NEW_THROW_EX (factory_id, + PortableGroup::GenericFactory::FactoryCreationId, + CORBA::NO_MEMORY ( + CORBA::SystemException::_tao_minor_code ( + TAO_DEFAULT_MINOR_CODE, + ENOMEM), + CORBA::COMPLETED_NO)); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + PortableGroup::ObjectGroupId group_id = group->get_object_group_id (); + *factory_id <<= group_id; + factory_creation_id = factory_id._retn(); + + METHOD_RETURN (TAO::FT_ReplicationManager::create_object) group->reference (); +} + +//CORBA +void +TAO::FT_ReplicationManager::delete_object ( + const PortableGroup::GenericFactory::FactoryCreationId & factory_creation_id + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException, + PortableGroup::ObjectNotFound)) +{ + + PortableGroup::ObjectGroupId group_id = 0; + if (factory_creation_id >>= group_id) + { + this->group_factory_.delete_group ( + group_id + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } + else + { + ACE_THROW (PortableGroup::ObjectNotFound ()); + } +} + +//private +int TAO::FT_ReplicationManager::write_ior () +{ + int result = -1; + FILE* out = ACE_OS::fopen (this->ior_output_file_, "w"); + if (out) + { + CORBA::String_var ior_str = this->orb_->object_to_string ( + this->replication_manager_ref_.in ()); + ACE_OS::fprintf (out, "%s", ior_str.in ()); + ACE_OS::fclose (out); + result = 0; + } + else + { + ACE_ERROR ( (LM_ERROR, + ACE_TEXT ("%T %n (%P|%t) - Open failed for %s\n"), this->ior_output_file_ + )); + } + return result; +} + diff --git a/TAO/orbsvcs/FT_ReplicationManager/FT_ReplicationManager.h b/TAO/orbsvcs/FT_ReplicationManager/FT_ReplicationManager.h new file mode 100644 index 00000000000..d5969a02e3f --- /dev/null +++ b/TAO/orbsvcs/FT_ReplicationManager/FT_ReplicationManager.h @@ -0,0 +1,525 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FT_ReplicationManager.h + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * + * @author Curt Hibbs <hibbs_c@ociweb.com> + */ +//============================================================================= + + +#ifndef FT_REPLICATION_MANAGER_H_ +#define FT_REPLICATION_MANAGER_H_ + +#include /**/ "ace/pre.h" +#include <ace/ACE.h> + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include <orbsvcs/FT_ReplicationManagerS.h> +//#include <orbsvcs/PortableGroup/PG_PropertyManager.h> +//#include <orbsvcs/PortableGroup/PG_GenericFactory.h> +//#include <orbsvcs/PortableGroup/PG_ObjectGroupManager.h> +// Note: the new, improved versions... +//#include <orbsvcs/PortableGroup/PG_Object_Group_Map.h> +#include <orbsvcs/PortableGroup/PG_Properties_Support.h> +#include <orbsvcs/PortableGroup/PG_Group_Factory.h> + +#include <orbsvcs/PortableGroup/PG_FactoryRegistry.h> +#include <orbsvcs/FT_ReplicationManager/FT_FaultConsumer.h> + + +namespace TAO +{ + /** + * Implement the ReplicationManager interfaces. + * + * The ReplicationManager does most of its work by delegating to + * support objects. These include: + * + * TAO::PG_Group_Factory group_factory_; + * The group factory contains a collection of TAO::PG_Object_Groups + * It provides methods to create new groups, destroy old groups and + * find existing groups. + * + * TAO::PG_Object_Group + * These objects which can be found through the group factory provde + * methods to create and add group members, remove and delete group + * members and set group properties. + * + * TAO::PG_Properties_Support properties_support_; + * This object maintains sets of properties(TAO::PG_Property_Set). + * In particular it has one default property set, and a collection of + * property sets indexed by type_id. + * The default property set acts as a parent to the type_id property + * sets and the type_id property sets act as parents to the property + * sets contained in PG_Object_Group. + * + * FT::FaultNotifier_var fault_notifier_; + * This notification channel is "the" source of fault notifications. + * + * TAO::FT_FaultConsumer fault_consumer_; + * This object subscribes to the fault_notifier_as a fault consumer. It + * analyzes incoming fault notifications and calls appropriate ReplicationManager + * methods to respond to the fault. + * + * TAO::PG_FactoryRegistry factory_registry_; + * This object maintains a collection of factory registrations. When a factory + * is started it registeres itself with the ReplicationManager (delegated to this + * object). When a member needs to be created in an object group this factory + * registry is queried to find factories that can create the member. + */ + class FT_ReplicationManager + : public virtual POA_FT::ReplicationManager, + public virtual PortableServer::RefCountServantBase + { + + ////////////////////// + // non-CORBA interface + + public: + /** + * Default constructor. + * Call init after constructing the object to prepare it for use. + */ + FT_ReplicationManager (); + + /** + * Destructor. + * Actual cleanup happens in the fini function. + */ + virtual ~FT_ReplicationManager (); + + public: + + /** + * Parse command line arguments. + * @param argc traditional C argc + * @param argv traditional C argv + * @return zero for success; nonzero is process return code for failure. + */ + int parse_args (int argc, char * argv[]); + + /** + * Initialize this object. + * @param orb Our CORBA::ORB -- we keep var to it. + * @return zero for success; nonzero is process return code for failure. + */ + int init (CORBA::ORB_ptr orb ACE_ENV_ARG_DECL); + + /** + * Prepare to exit. + * @return zero for success; nonzero is process return code for failure. + */ + int fini (ACE_ENV_SINGLE_ARG_DECL); + + /** + * Idle-time activity. + * + * @param result is set to process return code if return value is non-zero. + * @return zero to continue; nonzero to exit + */ + int idle(int & result); + + + /** + * Identify this fault detector factory. + * @return a string to identify this object for logging/console message purposes. + */ + const char * identity () const; + + /** + * Get the type_id associated with an object group. + * @param object_group The ObjectGroup. + * @return String identifying the type id associated with the ObjectGroup. + */ + char * type_id (PortableGroup::ObjectGroup_ptr object_group + ACE_ENV_ARG_DECL); + + + ////////////////////// + // CORBA interface(s) + + public: + + /** + * @name POA_FT::ReplicationManager Methods + * + * Methods required by the POA_FT::ReplicationManager interface. + */ + //@{ + + /// Registers the Fault Notifier with the Replication Manager. + virtual void register_fault_notifier ( + FT::FaultNotifier_ptr fault_notifier + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + )); + + /// Returns the reference of the Fault Notifier. + virtual FT::FaultNotifier_ptr get_fault_notifier ( + ACE_ENV_SINGLE_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + , FT::InterfaceNotFound + )); + + /// TAO-specific find factory registry + virtual ::PortableGroup::FactoryRegistry_ptr get_factory_registry ( + const PortableGroup::Criteria & selection_criteria + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + )); + + /// TAO-specific shutdown operation. + virtual void shutdown ( + ACE_ENV_SINGLE_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + )); + + //@} + + /** + * @name PortableGroup::PropertyManager Methods + * + * Methods required by the PortableGroup::PropertyManager interface. + */ + //@{ + + /// Set the default properties to be used by all object groups. + virtual void set_default_properties ( + const PortableGroup::Properties & props + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::InvalidProperty, + PortableGroup::UnsupportedProperty)); + + /// Get the default properties used by all object groups. + virtual PortableGroup::Properties * get_default_properties ( + ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /// Remove default properties. + virtual void remove_default_properties ( + const PortableGroup::Properties & props + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::InvalidProperty, + PortableGroup::UnsupportedProperty)); + + /** + * Set properties associated with a given Replica type. These + * properties override the default properties on a name-by-name basis. + */ + virtual void set_type_properties ( + const char * type_id, + const PortableGroup::Properties & overrides + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::InvalidProperty, + PortableGroup::UnsupportedProperty)); + + /** + * Return the properties associated with a given Replica type. These + * properties include the type-specific properties in use, in + * addition to the default properties that were not overridden. + */ + virtual PortableGroup::Properties * get_type_properties ( + const char * type_id + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /// Remove the given properties associated with the Replica type ID. + virtual void remove_type_properties ( + const char * type_id, + const PortableGroup::Properties & props + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::InvalidProperty, + PortableGroup::UnsupportedProperty)); + + /** + * Dynamically set the properties associated with a given object + * group as the replication manager and replicas are being executed. + * These properties override the type-specific and default + * properties. + */ + virtual void set_properties_dynamically ( + PortableGroup::ObjectGroup_ptr object_group, + const PortableGroup::Properties & overrides + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectGroupNotFound, + PortableGroup::InvalidProperty, + PortableGroup::UnsupportedProperty)); + + /** + * Return the properties currently in use by the given object + * group. These properties include those that were set dynamically, + * type-specific properties that weren't overridden, properties that + * were used when the Replica was created, and default properties + * that weren't overridden. + */ + virtual PortableGroup::Properties * get_properties ( + PortableGroup::ObjectGroup_ptr object_group + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectGroupNotFound)); + + //@} + + /** + * @name FT::FTObjectGroupManager methods + * + * Methods required by the FT::FTObjectGroupManager + * interface. + */ + //@{ + + /// Create a member in an object group. + virtual PortableGroup::ObjectGroup_ptr create_member ( + PortableGroup::ObjectGroup_ptr object_group, + const PortableGroup::Location & the_location, + const char * type_id, + const PortableGroup::Criteria & the_criteria + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectGroupNotFound, + PortableGroup::MemberAlreadyPresent, + PortableGroup::NoFactory, + PortableGroup::ObjectNotCreated, + PortableGroup::InvalidCriteria, + PortableGroup::CannotMeetCriteria)); + + /// Add an existing object to the ObjectGroup. + virtual PortableGroup::ObjectGroup_ptr add_member ( + PortableGroup::ObjectGroup_ptr object_group, + const PortableGroup::Location & the_location, + CORBA::Object_ptr member + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectGroupNotFound, + PortableGroup::MemberAlreadyPresent, + PortableGroup::ObjectNotAdded)); + + /** + * Remove the member at a specific location from an + * ObjectGroup. Application created objects must be + * deleted by the application. Objects created by the + * infrastructure (replication manager) will be deleted by the + * infrastructure. + * For infrastructure-controlled membership: After the member + * is removed from the group the minumum number of members + * parameter will be checked and new members will be created + * as necessary (if possible.) + */ + virtual PortableGroup::ObjectGroup_ptr remove_member ( + PortableGroup::ObjectGroup_ptr object_group, + const PortableGroup::Location & the_location + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectGroupNotFound, + PortableGroup::MemberNotFound)); + + /// Return the locations of the members in the given ObjectGroup. + virtual PortableGroup::Locations * locations_of_members ( + PortableGroup::ObjectGroup_ptr object_group + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectGroupNotFound)); + + /// Return the locations of the members in the given ObjectGroup. + virtual PortableGroup::ObjectGroups * groups_at_location ( + const PortableGroup::Location & the_location + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /// Return the ObjectGroupId for the given ObjectGroup. + virtual PortableGroup::ObjectGroupId get_object_group_id ( + PortableGroup::ObjectGroup_ptr object_group + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectGroupNotFound)); + + /** + * Return an update the IOGR for an object group. If no changes have + * been made in the group the return value will be the same as the object_group + * parameter. + */ + virtual PortableGroup::ObjectGroup_ptr get_object_group_ref ( + PortableGroup::ObjectGroup_ptr object_group + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectGroupNotFound)); + + /** + * TAO-specific extension. + * Return the ObjectGroup reference for the given ObjectGroupId. + */ + virtual PortableGroup::ObjectGroup_ptr get_object_group_ref_from_id ( + PortableGroup::ObjectGroupId group_id + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + , PortableGroup::ObjectGroupNotFound + )); + + /** + * Return the reference corresponding to the Replica of a given + * ObjectGroup at the given location. + */ + virtual CORBA::Object_ptr get_member_ref ( + PortableGroup::ObjectGroup_ptr object_group, + const PortableGroup::Location & loc + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectGroupNotFound, + PortableGroup::MemberNotFound)); + + /// Sets the primary member of a group. + virtual PortableGroup::ObjectGroup_ptr set_primary_member ( + PortableGroup::ObjectGroup_ptr object_group, + const PortableGroup::Location & the_location + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + , PortableGroup::ObjectGroupNotFound + , PortableGroup::MemberNotFound + , FT::PrimaryNotSet + , FT::BadReplicationStyle + )); + + //@} + + /** + * @name PortableGroup::GenericFactory methods + * + * Methods required by the PortableGroup::GenericFactory interface. + */ + //@{ + + /** + * Create an object of the specified type that adheres to the + * restrictions defined by the provided Criteria. The out + * FactoryCreationId parameter may be passed to the delete_object() + * method to delete the object. + * + * Infrastructure controlled membership: The initial number of members + * property will be honored by creating new members and adding them to + * the group. + */ + virtual CORBA::Object_ptr create_object ( + const char * type_id, + const PortableGroup::Criteria & the_criteria, + PortableGroup::GenericFactory::FactoryCreationId_out + factory_creation_id + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::NoFactory, + PortableGroup::ObjectNotCreated, + PortableGroup::InvalidCriteria, + PortableGroup::InvalidProperty, + PortableGroup::CannotMeetCriteria)); + + /** + * Delete the object group corresponding to the provided + * FactoryCreationId. For infratructure-controlled membership + * all members will be deleted. For application-controlled membership + * the application is responsible for deleting group members. + */ + virtual void delete_object ( + const PortableGroup::GenericFactory::FactoryCreationId & + factory_creation_id + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectNotFound)); + + //@} + + ///////////////////////// + // Implementation methods + private: + /** + * Write this factory's IOR to a file + */ + int write_ior (void); + + /// Registers the Fault Notifier with the Replication Manager. + void register_fault_notifier_i ( + FT::FaultNotifier_ptr fault_notifier + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + )); + + //////////////// + // Forbidden methods + FT_ReplicationManager (const FT_ReplicationManager & rhs); + FT_ReplicationManager & operator = (const FT_ReplicationManager & rhs); + + /////////////// + // Data Members + private: + + /// The orb + CORBA::ORB_var orb_; + + /// The POA. + PortableServer::POA_var poa_; + + /// A file to which the factory's IOR should be written. + const char * ior_output_file_; + + /// A name to be used to register the factory with the name service. + const char * ns_name_; + CosNaming::NamingContext_var naming_context_; + CosNaming::Name this_name_; + + /// Our object reference. + FT::ReplicationManager_var replication_manager_ref_; + + /// A human-readable string to identify this Replication Manager. + ACE_CString identity_; + + /// an object that manages a collection of object groups + TAO::PG_Group_Factory group_factory_; + + /// an object that manages default and type_id related properties + TAO::PG_Properties_Support properties_support_; + + /// The fault notifier. + FT::FaultNotifier_var fault_notifier_; + /// set by command line -f option + const char * fault_notifier_ior_string_; + + /// The fault consumer. + TAO::FT_FaultConsumer fault_consumer_; + + /// The factory registry + TAO::PG_FactoryRegistry factory_registry_; + + /// Quit flag. + int quit_; + }; + +} // namespace TAO + +#include /**/ "ace/post.h" + +#endif /* FT_REPLICATION_MANAGER_H_ */ diff --git a/TAO/orbsvcs/FT_ReplicationManager/FT_ReplicationManager.mpc b/TAO/orbsvcs/FT_ReplicationManager/FT_ReplicationManager.mpc new file mode 100644 index 00000000000..c49e50d2b92 --- /dev/null +++ b/TAO/orbsvcs/FT_ReplicationManager/FT_ReplicationManager.mpc @@ -0,0 +1,25 @@ +project(*Lib): orbsvcslib, core, notification, fault_tolerance, ftorb, portablegroup { + sharedname = TAO_ReplicationManagerLib + dynamicflags = TAO_REPLICATIONMANAGERLIB_BUILD_DLL + avoids += minimum_corba + + Source_Files { + FT_FaultAnalyzer.cpp + FT_DefaultFaultAnalyzer.cpp + FT_FaultEventDescriptor.cpp + FT_FaultConsumer.cpp + } +} + +project : taoserver, orbsvcsexe, fault_tolerance, iormanip, ftorb { + exename = FT_ReplicationManager + libs += TAO_ReplicationManagerLib + after += FT_ReplicationManager_Lib + Source_Files { + FT_ReplicationManager.cpp + FT_ReplicationManager_Main.cpp + FT_Property_Validator.cpp + FT_ReplicationManagerFaultAnalyzer.cpp + } +} + diff --git a/TAO/orbsvcs/FT_ReplicationManager/FT_ReplicationManagerFaultAnalyzer.cpp b/TAO/orbsvcs/FT_ReplicationManager/FT_ReplicationManagerFaultAnalyzer.cpp new file mode 100755 index 00000000000..40ef13ae035 --- /dev/null +++ b/TAO/orbsvcs/FT_ReplicationManager/FT_ReplicationManagerFaultAnalyzer.cpp @@ -0,0 +1,1129 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FT_ReplicationManagerFaultAnalyzer.cpp + * + * $Id$ + * + * This file is part of TAO's implementation of Fault Tolerant CORBA. + * + * @author Steve Totten <totten_s@ociweb.com> + */ +//============================================================================= + +#include "FT_ReplicationManagerFaultAnalyzer.h" +#include "orbsvcs/CosNotifyCommC.h" +#include "orbsvcs/FT_NotifierC.h" +#include "orbsvcs/FT_ReplicationManager/FT_ReplicationManager.h" +#include "orbsvcs/FT_ReplicationManager/FT_FaultEventDescriptor.h" +#include "orbsvcs/PortableGroup/PG_Property_Utils.h" +#include "orbsvcs/PortableGroup/PG_Operators.h" +#include "orbsvcs/FaultTolerance/FT_IOGR_Property.h" +#include <tao/debug.h> +#include <iostream> + +ACE_RCSID (FT_ReplicationManagerFaultAnalyzer, + FT_ReplicationManagerFaultAnalyzer, + "$Id$") + +/// Constructor. +TAO::FT_ReplicationManagerFaultAnalyzer::FT_ReplicationManagerFaultAnalyzer ( + const TAO::FT_ReplicationManager * replication_manager) + : replication_manager_ ( + ACE_const_cast (TAO::FT_ReplicationManager *, replication_manager)) +{ +} + +/// Destructor. +TAO::FT_ReplicationManagerFaultAnalyzer::~FT_ReplicationManagerFaultAnalyzer () +{ +} + +// Validate the event to make sure it is one we can handle. +// If it is not an event we can handle, this function logs the error +// and returns -1. +int TAO::FT_ReplicationManagerFaultAnalyzer::validate_event_type ( + const CosNotification::StructuredEvent & event) +{ + // Delegate to base class. + //@@ Visual C++ 6.0 won't compile this if I include the namespace name + // on the base class. + // return TAO::FT_DefaultFaultAnalyzer::validate_event_type (event); + return FT_DefaultFaultAnalyzer::validate_event_type (event); +} + +/// Analyze a fault event. +int TAO::FT_ReplicationManagerFaultAnalyzer::analyze_fault_event ( + const CosNotification::StructuredEvent & event) +{ + int result = 0; + + const CosNotification::FilterableEventBody & filterable = + event.filterable_data; + CORBA::ULong item_count = filterable.length (); + if (TAO_debug_level > 6) + { + for (CORBA::ULong n_prop = 0; n_prop < item_count; ++n_prop) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT( + "TAO::FT_ReplicationManagerFaultAnalyzer::analyze_fault_event: " + "Property Name: <%s>\n"), + filterable[n_prop].name.in() + )); + } + } + + // Populate a TAO::FT_FaultEventDescriptor structure from the + // properties in the event. + TAO::FT_FaultEventDescriptor fault_event_desc; + + // Extract the location. + if (result == 0) + { + result = this->get_location ( + filterable[1].value, fault_event_desc.location.out()); + } + + // CORBA 3.0.2, section 23.4.5.1 states: + // + // The fault detector may or may not set the TypeId and + // ObjectGroupId fields with the following interpretations: + // - Neither is set if all objects at the given location have failed. + // - TypeId is set and ObjectGroupId is not set if all objects at + // the given location with the given type have failed. + // - Both are set if the member with the given ObjectGroupId at the + // given location has failed. + + if ((result == 0) && (item_count == 2)) + { + // All objects at location failed. + fault_event_desc.all_at_location_failed = 1; + } + + if ((result == 0) && (item_count == 3)) + { + // All objects of type at location failed. + fault_event_desc.all_of_type_at_location_failed = 1; + result = this->get_type_id ( + filterable[2].value, fault_event_desc.type_id.out()); + } + + if ((result == 0) && (item_count == 4)) + { + // An object (replica) at a location failed. + fault_event_desc.object_at_location_failed = 1; + result = this->get_type_id ( + filterable[2].value, fault_event_desc.type_id.out()); + if (result == 0) + { + result = this->get_object_group_id ( + filterable[3].value, fault_event_desc.object_group_id); + } + } + + // A specific object at a location failed. + if ((result == 0) && (fault_event_desc.object_at_location_failed == 1)) + { + result = this->single_replica_failure (fault_event_desc); + } + + // All objects at location failed. + if ((result == 0) && (fault_event_desc.all_at_location_failed == 1)) + { + result = this->location_failure (fault_event_desc); + } + + // All objects of type at location failed. + if ((result == 0) && (fault_event_desc.all_of_type_at_location_failed == 1)) + { + result = this->type_failure (fault_event_desc); + } + + // Debugging support. + if (TAO_debug_level > 6) + { + fault_event_desc.dump (); + } + + return result; +} + +// Extract a string type_id from CORBA::Any. +// Caller owns the string returned via <type_id>. +int TAO::FT_ReplicationManagerFaultAnalyzer::get_type_id ( + const CORBA::Any& val, PortableGroup::TypeId_out type_id) +{ + const char* type_id_value; + if ((val >>= type_id_value) == 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ( + "TAO::FT_ReplicationManagerFaultAnalyzer::get_type_id: " + "Could not extract TypeId value from any.\n")), + -1); + } + + // Make a deep copy of the TypeId string. + type_id = CORBA::string_dup (type_id_value); + return 0; +} + +// Extract the ObjectGroupId from CORBA::Any. +int TAO::FT_ReplicationManagerFaultAnalyzer::get_object_group_id ( + const CORBA::Any& val, PortableGroup::ObjectGroupId& id) +{ + PortableGroup::ObjectGroupId temp_id = (PortableGroup::ObjectGroupId)0; + if ((val >>= temp_id) == 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ( + "TAO::FT_ReplicationManagerFaultAnalyzer::get_object_group_id: " + "Could not extract ObjectGroupId value from any.\n")), + -1); + } + id = temp_id; + return 0; +} + +int TAO::FT_ReplicationManagerFaultAnalyzer::get_location ( + const CORBA::Any& val, PortableGroup::Location_out location) +{ + const PortableGroup::Location* temp_loc; + if ((val >>= temp_loc) == 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ( + "TAO::FT_ReplicationManagerFaultAnalyzer::get_location: " + "Could not extract Location value from fault event.\n")), + -1); + } + // Make a deep copy of the Location. + ACE_NEW_RETURN (location, PortableGroup::Location (*temp_loc), -1); + return 0; +} + +// +//TODO: Use TAO::PG_Property_Set to get property values from properties +// instead of all these specific "get" functions. +// + +// Get the MembershipStyle property. +int TAO::FT_ReplicationManagerFaultAnalyzer::get_membership_style ( + const PortableGroup::Properties & properties, + PortableGroup::MembershipStyleValue & membership_style) +{ + PortableGroup::Name prop_name (1); + prop_name.length (1); + prop_name[0].id = CORBA::string_dup (FT::FT_MEMBERSHIP_STYLE); + int result = 0; + + PortableGroup::Value value; + if (TAO_PG::get_property_value (prop_name, properties, value) + && ((value >>= membership_style) == 1)) + { + if (TAO_debug_level > 6) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ( + "TAO::FT_ReplicationManagerFaultAnalyzer::get_membership_style: " + "MembershipStyle is <%d>:\n"), + membership_style + )); + } + } + else + { + result = -1; + } + + return result; +} + +int TAO::FT_ReplicationManagerFaultAnalyzer::get_replication_style ( + const PortableGroup::Properties & properties, + FT::ReplicationStyleValue & replication_style) +{ + PortableGroup::Name prop_name (1); + prop_name.length (1); + prop_name[0].id = CORBA::string_dup (FT::FT_REPLICATION_STYLE); + int result = 0; + + PortableGroup::Value value; + if (TAO_PG::get_property_value (prop_name, properties, value) + && ((value >>= replication_style) == 1)) + { + if (TAO_debug_level > 6) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ( + "TAO::FT_ReplicationManagerFaultAnalyzer::get_replication_style: " + "ReplicationStyle is <%d>:\n"), + replication_style + )); + } + } + else + { + result = -1; + } + + return result; +} + +int TAO::FT_ReplicationManagerFaultAnalyzer::get_minimum_number_members ( + const PortableGroup::Properties & properties, + PortableGroup::MinimumNumberMembersValue & minimum_number_members) +{ + PortableGroup::Name prop_name (1); + prop_name.length (1); + prop_name[0].id = CORBA::string_dup (FT::FT_MINIMUM_NUMBER_MEMBERS); + int result = 0; + + PortableGroup::Value value; + if (TAO_PG::get_property_value (prop_name, properties, value) + && ((value >>= minimum_number_members) == 1)) + { + if (TAO_debug_level > 6) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ( + "TAO::FT_ReplicationManagerFaultAnalyzer::get_minimum_number_members: " + "MinimumNumberMembers is <%d>:\n"), + minimum_number_members + )); + } + } + else + { + result = -1; + } + + return result; +} + +int TAO::FT_ReplicationManagerFaultAnalyzer::get_initial_number_members ( + const PortableGroup::Properties & properties, + PortableGroup::InitialNumberMembersValue & initial_number_members) +{ + PortableGroup::Name prop_name (1); + prop_name.length (1); + prop_name[0].id = CORBA::string_dup (FT::FT_INITIAL_NUMBER_MEMBERS); + int result = 0; + + PortableGroup::Value value; + if (TAO_PG::get_property_value (prop_name, properties, value) + && ((value >>= initial_number_members) == 1)) + { + if (TAO_debug_level > 6) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ( + "TAO::FT_ReplicationManagerFaultAnalyzer::get_initial_number_members: " + "InitialNumberMembers is <%d>:\n"), + initial_number_members + )); + } + } + else + { + result = -1; + } + + return result; +} + +int TAO::FT_ReplicationManagerFaultAnalyzer::get_factories ( + const PortableGroup::Properties & properties, + PortableGroup::FactoryInfos_out factories) +{ + PortableGroup::Name prop_name (1); + prop_name.length (1); + prop_name[0].id = CORBA::string_dup (FT::FT_FACTORIES); + int result = 0; + + PortableGroup::FactoryInfos_var temp_factories; + PortableGroup::Value value; + if (TAO_PG::get_property_value (prop_name, properties, value) == 1) + { + if ((value >>= temp_factories) == 0) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ( + "TAO::FT_ReplicationManagerFaultAnalyzer::get_factories: " + "Could not extract Factories from properties.\n") + )); + result = -1; + } + else + { + // Make a deep copy of the Factories. + ACE_NEW_RETURN (factories, PortableGroup::FactoryInfos (temp_factories.in()), -1); + result = 0; + } + } + else + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ( + "TAO::FT_ReplicationManagerFaultAnalyzer::get_factories: " + "Could not find Factories property.\n") + )); + result = -1; + } + return result; +} + +int TAO::FT_ReplicationManagerFaultAnalyzer::is_primary_member ( + PortableGroup::ObjectGroup_ptr iogr, + const PortableGroup::Location & location, + int & object_is_primary) +{ + + // To determine if this was a primary that faulted: + // Get the TagFTGroupTaggedComponent from the IOGR and search + // for the primary, using the TAO_FT_IOGR_Property helper class. + // Then, compare the TypeId and Location of the failed object with + // those of the primary. If they match, it was a primary fault. + + int result = 0; + object_is_primary = 0; + + ACE_TRY_NEW_ENV + { + // Create an "empty" TAO_FT_IOGR_Property and use it to get the + // tagged component. + TAO_FT_IOGR_Property temp_ft_prop; + FT::TagFTGroupTaggedComponent ft_group_tagged_component; + CORBA::Boolean got_tagged_component = + temp_ft_prop.get_tagged_component ( + iogr, ft_group_tagged_component ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + if (got_tagged_component) + { + // Create a new TAO_FT_IOGR_Property with the tagged + // component. + TAO_FT_IOGR_Property ft_prop (ft_group_tagged_component); + + // Check to see if a primary is set. + CORBA::Boolean primary_is_set = ft_prop.is_primary_set ( + iogr ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + if (primary_is_set) + { + // Get the primary object. + CORBA::Object_var primary_obj = ft_prop.get_primary ( + iogr ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + if (CORBA::is_nil (primary_obj.in())) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ( + "TAO::FT_ReplicationManagerFaultAnalyzer::is_primary_member: " + "Could not get primary IOR from IOGR.\n")), + -1); + } + + // Get the object reference of the failed member. + CORBA::Object_var failed_obj = + this->replication_manager_->get_member_ref ( + iogr, location ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + if (CORBA::is_nil (failed_obj.in())) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ( + "TAO::FT_ReplicationManagerFaultAnalyzer::is_primary_member: " + "Could not get IOR of failed member from IOGR.\n")), + -1); + } + + // Are the two object refs (primary and failed) equivalent? + CORBA::Boolean equiv = primary_obj->_is_equivalent ( + failed_obj.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + if (equiv) + { + object_is_primary = 1; + result = 0; + } + } + else // primary is not set + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ( + "TAO::FT_ReplicationManagerFaultAnalyzer::is_primary_member: " + "Primary is not set on IOGR.\n") + )); + result = -1; + } + } + else // could not get tagged component + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ( + "TAO::FT_ReplicationManagerFaultAnalyzer::is_primary_member: " + "Could not get tagged component from IOGR.\n") + )); + result = -1; + } + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION ( + ACE_ANY_EXCEPTION, + ACE_TEXT ( + "TAO::FT_ReplicationManagerFaultAnalyzer::is_primary_member: ") + ); + result = -1; + } + ACE_ENDTRY; + + return result; +} + +// Handle a single replica failure. +int TAO::FT_ReplicationManagerFaultAnalyzer::single_replica_failure ( + TAO::FT_FaultEventDescriptor & fault_event_desc) +{ + int result = 0; + PortableGroup::ObjectGroup_var the_object_group = PortableGroup::ObjectGroup::_nil(); + PortableGroup::Properties_var properties; + + ACE_TRY_NEW_ENV + { + // Get the object group reference based on the ObjectGroupId. + the_object_group = + this->replication_manager_->get_object_group_ref_from_id ( + fault_event_desc.object_group_id + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // This should not happen, but let us be safe. + if (CORBA::is_nil (the_object_group.in())) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ( + "TAO::FT_ReplicationManagerFaultAnalyzer::single_replica_failure: " + "Could not get ObjectGroup reference from ObjectGroupId: <%Q>.\n"), + fault_event_desc.object_group_id + )); + ACE_TRY_THROW (PortableGroup::ObjectGroupNotFound ()); + } + + // Get the properties associated with this ObjectGroup. + properties = this->replication_manager_->get_properties ( + the_object_group.in() + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION ( + ACE_ANY_EXCEPTION, + ACE_TEXT ( + "TAO::FT_ReplicationManagerFaultAnalyzer::single_replica_failure: ") + ); + result = -1; + } + ACE_ENDTRY; + ACE_CHECK_RETURN (-1); //@@ is this necessary? + + if (result == 0) + { + // Get the MembershipStyle property. + PortableGroup::MembershipStyleValue membership_style; + result = this->get_membership_style (properties.in(), membership_style); + if (result != 0) + { + //@@ it seems a shame to fail here. We should at least remove the failed replica from the group. + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ( + "TAO::FT_ReplicationManagerFaultAnalyzer::single_replica_failure: " + "Could not extract MembershipStyle from properties on " + "ObjectGroup with id <%Q>.\n"), + fault_event_desc.object_group_id), + -1); + } + else + { + fault_event_desc.membership_style = membership_style; + if (TAO_debug_level > 6) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ( + "TAO::FT_ReplicationManagerFaultAnalyzer::single_replica_failure: " + "MembershipStyleValue = <%d>"), + fault_event_desc.membership_style + )); + } + } + + // Get the ReplicationStyle property. + FT::ReplicationStyleValue replication_style; + result = this->get_replication_style (properties.in(), replication_style); + if (result != 0) + { + //@@ it seems a shame to fail here. We should at least remove the failed replica from the group. + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ( + "TAO::FT_ReplicationManagerFaultAnalyzer::single_replica_failure: " + "Could not extract ReplicationStyle from properties on " + "ObjectGroup with id <%Q>.\n"), + fault_event_desc.object_group_id), + -1); + } + else + { + fault_event_desc.replication_style = replication_style; + if (TAO_debug_level > 6) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ( + "TAO::FT_ReplicationManagerFaultAnalyzer::single_replica_failure: " + "ReplicationStyleValue = <%d>"), + fault_event_desc.replication_style + )); + } + } + + // Get the MinimumNumberMembers property. + PortableGroup::MinimumNumberMembersValue minimum_number_members; + result = this->get_minimum_number_members ( + properties.in(), minimum_number_members); + if (result != 0) + { + // This is not a fatal error. It may be App Controlled. + result = 0; + if (TAO_debug_level > 3) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ( + "TAO::FT_ReplicationManagerFaultAnalyzer::single_replica_failure: " + "Could not extract MinimumNumberMembers from properties on " + "ObjectGroup with id <%Q>.\n"), + fault_event_desc.object_group_id)); + } + } + else + { + fault_event_desc.minimum_number_members = minimum_number_members; + if (TAO_debug_level > 6) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ( + "TAO::FT_ReplicationManagerFaultAnalyzer::single_replica_failure: " + "MinimumNumberMembers = <%d>"), + fault_event_desc.minimum_number_members + )); + } + } + + // Get the InitialNumberMembers property. + PortableGroup::InitialNumberMembersValue initial_number_members; + result = this->get_initial_number_members ( + properties.in(), initial_number_members); + if (result != 0) + { + // This is not a fatal error. It may be App Controlled. + result = 0; + if (TAO_debug_level > 3) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ( + "TAO::FT_ReplicationManagerFaultAnalyzer::single_replica_failure: " + "Could not extract InitialNumberMembers from properties on " + "ObjectGroup with id <%Q>.\n"), + fault_event_desc.object_group_id)); + } + } + else + { + fault_event_desc.initial_number_members = initial_number_members; + if (TAO_debug_level > 6) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ( + "TAO::FT_ReplicationManagerFaultAnalyzer::single_replica_failure: " + "InitialNumberMembers = <%d>"), + fault_event_desc.initial_number_members + )); + } + } + + // Get the Factories property. + result = this->get_factories ( + properties.in(), + fault_event_desc.factories.out()); + if (result != 0) + { + // This is not a fatal error. It may be App Controlled. + result = 0; + if (TAO_debug_level > 3) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ( + "TAO::FT_ReplicationManagerFaultAnalyzer::single_replica_failure: " + "Could not extract Factories from properties on " + "ObjectGroup with id <%Q>.\n"), + fault_event_desc.object_group_id)); + } + } + else + { + if (TAO_debug_level > 6) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ( + "TAO::FT_ReplicationManagerFaultAnalyzer::single_replica_failure: " + "Got Factories from properties on " + "ObjectGroup with id <%Q>.\n"), + fault_event_desc.object_group_id + )); + } + } + + } + + // If the ReplicationStyle is COLD_PASSIVE, WARM_PASSIVE, or + // SEMI_ACTIVE, we can see if it was the primary replica that + // failed. + if ((result == 0) && + (fault_event_desc.replication_style == FT::COLD_PASSIVE || + fault_event_desc.replication_style == FT::WARM_PASSIVE || + fault_event_desc.replication_style == FT::SEMI_ACTIVE)) + { + if (TAO_debug_level > 6) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ( + "TAO::FT_ReplicationManagerFaultAnalyzer::single_replica_failure: " + "Checking to see if failed replica was the primary for " + "ObjectGroup with id <%Q>.\n"), + fault_event_desc.object_group_id + )); + } + result = this->is_primary_member ( + the_object_group.in(), + fault_event_desc.location.in(), + fault_event_desc.object_is_primary); + } + + // If the MembershipStyle is FT::MEMB_INF_CTRL (infrastructure + // controlled) and the primary has faulted, establish a new primary. + // We get back a new object group. + if ((result == 0) && + (fault_event_desc.membership_style == FT::MEMB_INF_CTRL)) + { + + PortableGroup::ObjectGroup_var new_object_group; + result = this->remove_failed_member ( + the_object_group.in(), + fault_event_desc, + new_object_group.out()); + if (result == 0) + { + the_object_group = new_object_group; + } + + if (fault_event_desc.object_is_primary == 1) + { + if (TAO_debug_level > 6) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ( + "TAO::FT_ReplicationManagerFaultAnalyzer::single_replica_failure: " + "Setting new primary for " + "ObjectGroup with id <%Q>.\n"), + fault_event_desc.object_group_id + )); + } + result = this->set_new_primary ( + the_object_group.in(), + fault_event_desc, + new_object_group.out()); + if (result == 0) + { + the_object_group = new_object_group; + } + } + } + +#if 0 // According to the FT CORBA specification, this will be handled by the ObjectGroupManager::remove_member method + // If the MembershipStyle is FT::MEMB_INF_CTRL (infrastructure + // controlled) and the number of remaining members is less than + // the MinimumNumberMembers property, add new members. + // We get back a new object group. + if ((result == 0) && + (fault_event_desc.membership_style == FT::MEMB_INF_CTRL)) + { + if (TAO_debug_level > 6) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ( + "TAO::FT_ReplicationManagerFaultAnalyzer::single_replica_failure: " + "Potentially adding new members to " + "ObjectGroup with id <%Q>.\n"), + fault_event_desc.object_group_id + )); + } + result = this->add_members ( + the_object_group.in(), + fault_event_desc, + new_object_group.out()); + the_object_group = new_object_group; + } +#endif + return result; +} + +int TAO::FT_ReplicationManagerFaultAnalyzer::remove_failed_member ( + PortableGroup::ObjectGroup_ptr iogr, + TAO::FT_FaultEventDescriptor & fault_event_desc, + PortableGroup::ObjectGroup_out new_iogr) +{ + int result = 0; + new_iogr = PortableGroup::ObjectGroup::_nil (); + + ACE_TRY_NEW_ENV + { + // Remove the old primary member from the object group. + PortableGroup::ObjectGroup_var temp_iogr = + this->replication_manager_->remove_member ( + iogr, + fault_event_desc.location.in() + ACE_ENV_ARG_DECL); + ACE_TRY_CHECK; + new_iogr = temp_iogr._retn (); + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION ( + ACE_ANY_EXCEPTION, + "TAO::FT_ReplicationManagerFaultAnalyzer::remove_failed_member: "); + result = -1; + } + ACE_ENDTRY; + return result; +} + + +// Choose a new primary member for the ObjectGroup. +// Sets <new_iogr> and returns 0 on success. +// Returns -1 on failure. +int TAO::FT_ReplicationManagerFaultAnalyzer::set_new_primary ( + PortableGroup::ObjectGroup_ptr iogr, + TAO::FT_FaultEventDescriptor & fault_event_desc, + PortableGroup::ObjectGroup_out new_iogr) +{ + int result = 0; + new_iogr = PortableGroup::ObjectGroup::_nil (); + + ACE_TRY_NEW_ENV + { + // Get the locations of the remaining members of the object group. + PortableGroup::Locations_var locations = + this->replication_manager_->locations_of_members ( + iogr + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Choose the first location as our new primary location. + if (locations->length() >= 1) + { + new_iogr = this->replication_manager_->set_primary_member ( + iogr, + (*locations)[0] + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + else + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ( + "TAO::FT_ReplicationManagerFaultAnalyzer::set_new_primary: " + "No locations remaining in ObjectGroup with id <%Q>.\n"), + fault_event_desc.object_group_id), + -1); + } + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION ( + ACE_ANY_EXCEPTION, + "TAO::FT_ReplicationManagerFaultAnalyzer::set_new_primary: "); + result = -1; + } + ACE_ENDTRY; + + return result; +} + +#if 0 // this is handled by the remove_member method +// While the number of members in the object group is less than +// the MinimumNumberMembers property, add new members. +// Sets <new_iogr> and returns 0 on success. +// Returns -1 on failure. +int TAO::FT_ReplicationManagerFaultAnalyzer::add_members ( + PortableGroup::ObjectGroup_ptr iogr, + TAO::FT_FaultEventDescriptor & fault_event_desc, + PortableGroup::ObjectGroup_out new_iogr) +{ + int result = 0; + new_iogr = PortableGroup::ObjectGroup::_nil (); + + ACE_TRY_NEW_ENV + { + // Get current number of members in object group + // (same as number of locations). + PortableGroup::Locations_var locations = + this->replication_manager_->locations_of_members ( + iogr + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + CORBA::ULong num_members = locations->length(); + + // If it is less than the MinimumNumberMembers property, add + // new members. + if (num_members < fault_event_desc.minimum_number_members) + { + //@@ To create a member, we need to know the ObjectGroup, + // Location, TypeId, and Criteria. + + // Get the factory registry from the Replication Manager. + PortableGroup::Criteria fake_criteria; + PortableGroup::FactoryRegistry_var factory_registry = + this->replication_manager_->get_factory_registry ( + fake_criteria ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + + // @@ DLW SAYS: we need to find out the role played by this object + // group so we can use the correct set of factories. + // Get the list of factories for the type of the failed replica. + CORBA::String_var type_id; + PortableGroup::FactoryInfos_var factories_by_type = + factory_registry->list_factories_by_role ( + fault_event_desc.type_id.in(), type_id ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // + // Build a set of locations of factories for this type that we + // can use to create new members (i.e., at locations where + // members do not currently exist). + // + FT_Location_Set valid_locations; + + // For each factory that can be used for this type... + for (CORBA::ULong f=0; f<factories_by_type->length(); ++f) + { + // ...insert its location into valid_locations set. + valid_locations.insert (factories_by_type[f].the_location); + } + + // Now remove any locations where members already exist. + for (CORBA::ULong m=0; m<num_members; ++m) + { + if (valid_locations.find (locations[m])) + valid_locations.remove (locations[m]); + } + + // The valid_locations set now contains all the factory + // locations we can use to add members to this object group. + // So, now we add new members until we reach + // the value of the MinimumNumberMembers property. + PortableGroup::Location_var good_location; + for (FT_Location_Set::iterator iter (valid_locations); + iter.next (good_location.out()) && + fault_event_desc.minimum_number_members > num_members; + iter.advance(), ++num_members) + { + // Create a new member of the object group at this location. + new_iogr = this->replication_manager_->create_member ( + iogr, + good_location.in(), + fault_event_desc.type_id.in(), + fake_criteria + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Stop adding members when we reach the value of the + // MinimumNumberMembers property. + // if (num_members++ >= fault_event_desc.minimum_number_members) + // break; + } + + } + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION ( + ACE_ANY_EXCEPTION, + "TAO::FT_ReplicationManagerFaultAnalyzer::add_members: "); + result = -1; + } + ACE_ENDTRY; + + return result; +} +#endif // 0 + +// Handle a location failure. +int TAO::FT_ReplicationManagerFaultAnalyzer::location_failure ( + TAO::FT_FaultEventDescriptor & fault_event_desc) +{ + int result = 0; + + // To handle a location failure, we should: + // - Unregister all the factories at that location. + // (We do this first so that we don't try to create a new replica + // at that location for any of the affected object groups.) + // - Determine all the object groups that had members at that + // location. + // - Handle each one of them as a single replica failure. + + ACE_TRY_NEW_ENV + { + // Get the factory registry from the Replication Manager. + PortableGroup::Criteria fake_criteria; + PortableGroup::FactoryRegistry_var factory_registry = + this->replication_manager_->get_factory_registry ( + fake_criteria ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Unregister all factories at the failed location. + factory_registry->unregister_factory_by_location ( + fault_event_desc.location.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Determine all the object groups that had members at that + // location. + PortableGroup::ObjectGroups_var object_groups_at_location = + this->replication_manager_->groups_at_location ( + fault_event_desc.location.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Handle each one of them as a single replica failure. + for (CORBA::ULong i=0; + result==0 && i<object_groups_at_location->length(); + ++i) + { + // Get the object group id. + fault_event_desc.object_group_id = + this->replication_manager_->get_object_group_id ( + object_groups_at_location[i] ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Get type id of this object group. + fault_event_desc.type_id = + this->replication_manager_->type_id ( + object_groups_at_location[i] ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Handle it as a single replica failure. + result = this->single_replica_failure (fault_event_desc); + } + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION ( + ACE_ANY_EXCEPTION, + "TAO::FT_ReplicationManagerFaultAnalyzer::location_failure: "); + result = -1; + } + ACE_ENDTRY; + + return result; +} + +// Handle a type failure. +int TAO::FT_ReplicationManagerFaultAnalyzer::type_failure ( + TAO::FT_FaultEventDescriptor & fault_event_desc) +{ + int result = 0; + + // To handle a type failure, we should: + // - Unregister the factory at the location of the failure + // that is associated with the failed type. + // (We do this first so that we don't try to create a new replica + // with that factory for any of the affected object groups.) + // - Determine all the object groups that had members at that + // location of that type. + // - Handle each one of them as a single replica failure. + + ACE_TRY_NEW_ENV + { + // Get the factory registry from the Replication Manager. + PortableGroup::Criteria fake_criteria; + PortableGroup::FactoryRegistry_var factory_registry = + this->replication_manager_->get_factory_registry ( + fake_criteria ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Unregister the factory at the failed location associated with + // the role. + //@@ Using type_id as the role for now. + factory_registry->unregister_factory ( + fault_event_desc.type_id.in(), + fault_event_desc.location.in() + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Get all the object groups that had members at that + // location. + PortableGroup::ObjectGroups_var object_groups_at_location = + this->replication_manager_->groups_at_location ( + fault_event_desc.location.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // For each one, if it was of the same type as the failed type, + // handle it as a single replica failure. + for (CORBA::ULong i=0; + result==0 && i<object_groups_at_location->length(); + ++i) + { + // Get the object group id. + fault_event_desc.object_group_id = + this->replication_manager_->get_object_group_id ( + object_groups_at_location[i] ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Get type id of this object group. + PortableGroup::TypeId_var type_id = + this->replication_manager_->type_id ( + object_groups_at_location[i] ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // If the type id is the same as the failed type id... + if (ACE_OS::strcmp (type_id.in(), fault_event_desc.type_id.in()) == 0) + { + // Handle it as a single replica failure. + result = this->single_replica_failure (fault_event_desc); + } + } + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION ( + ACE_ANY_EXCEPTION, + "TAO::FT_ReplicationManagerFaultAnalyzer::type_failure: "); + result = -1; + } + ACE_ENDTRY; + + return result; +} + +// Template instantiations. +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + +template class ACE_Unbounded_Set<PortableGroup::Location>; +template class ACE_Unbounded_Set_Iterator<PortableGroup::Location>; + +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) + +#pragma instantiate ACE_Unbounded_Set<PortableGroup::Location> +#pragma instantiate ACE_Unbounded_Set_Iterator<PortableGroup::Location> + +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ + diff --git a/TAO/orbsvcs/FT_ReplicationManager/FT_ReplicationManagerFaultAnalyzer.h b/TAO/orbsvcs/FT_ReplicationManager/FT_ReplicationManagerFaultAnalyzer.h new file mode 100755 index 00000000000..f15238af5bf --- /dev/null +++ b/TAO/orbsvcs/FT_ReplicationManager/FT_ReplicationManagerFaultAnalyzer.h @@ -0,0 +1,194 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FT_ReplicationManagerFaultAnalyzer.h + * + * $Id$ + * + * This file is part of TAO's implementation of Fault Tolerant CORBA. + * This is the Replication Manager's implementation of a fault analyzer. + * + * @author Steve Totten <totten_s@ociweb.com> + */ +//============================================================================= + + +#ifndef FT_REPLICATION_MANAGER_FAULT_ANALYZER_H_ +#define FT_REPLICATION_MANAGER_FAULT_ANALYZER_H_ + +#include /**/ "ace/pre.h" +#include <ace/ACE.h> + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "orbsvcs/FT_ReplicationManager/FT_DefaultFaultAnalyzer.h" +#include "orbsvcs/FT_CORBAC.h" + +// Forward declarations. +template <class T> class ACE_Unbounded_Set; +template <class T> class ACE_Unbounded_Set_Iterator; + +namespace TAO +{ + + /////////////////////// + // Forward declarations + class FT_ReplicationManager; + struct FT_FaultEventDescriptor; + + typedef ACE_Unbounded_Set<PortableGroup::Location> FT_Location_Set; + + /** + * Replication Manager's fault analyzer. + * + */ + class FT_ReplicationManagerFaultAnalyzer + : public ::TAO::FT_DefaultFaultAnalyzer + { + + public: + /** + * Constructor. + * @param replication_manager Pointer to TAO::FT_ReplicationManager. + */ + FT_ReplicationManagerFaultAnalyzer ( + const TAO::FT_ReplicationManager * replication_manager); + + /** + * Destructor. + */ + virtual ~FT_ReplicationManagerFaultAnalyzer (); + + public: + + /** + * Validate event type to make sure it is one we can handle. + * @param event The structured fault event, as from the Fault Notifier. + * @return 0 if it is a valid event type, -1 otherwise. + */ + virtual int validate_event_type ( + const CosNotification::StructuredEvent & event); + + /** + * Analyze a fault event. + * @param event The structured fault event, as from the Fault Notifier. + * @return 0 on success, -1 on failure. + */ + virtual int analyze_fault_event ( + const CosNotification::StructuredEvent & event); + + //////////////////// + // Forbidden methods + private: + /// Default constructor. + FT_ReplicationManagerFaultAnalyzer (); + + /// Copy constructor. + FT_ReplicationManagerFaultAnalyzer ( + const FT_ReplicationManagerFaultAnalyzer & rhs); + + /// Assignment operator. + FT_ReplicationManagerFaultAnalyzer & operator = ( + const FT_ReplicationManagerFaultAnalyzer & rhs); + + ///////////////////////// + // Implementation methods + protected: + + /// Helper functions for fault analysis. + + // Extract the type id from a CORBA any. + int get_type_id (const CORBA::Any& val, PortableGroup::TypeId_out type_id); + + // Extract the ObjectGroupId from a CORBA any. + int get_object_group_id (const CORBA::Any& val, PortableGroup::ObjectGroupId& id); + + // Extract the PortableGroup::Location from a CORBA any. + int get_location (const CORBA::Any& val, PortableGroup::Location_out location); + + // Get the MembershipStyle property. + int get_membership_style ( + const PortableGroup::Properties & properties, + PortableGroup::MembershipStyleValue & membership_style); + + // Get the ReplicationStyle property. + int get_replication_style ( + const PortableGroup::Properties & properties, + FT::ReplicationStyleValue & replication_style); + + // Get the MinimumNumberMembers property. + int get_minimum_number_members ( + const PortableGroup::Properties & properties, + PortableGroup::MinimumNumberMembersValue & minimum_number_members); + + // Get the InitialNumberMembers property. + int get_initial_number_members ( + const PortableGroup::Properties & properties, + PortableGroup::InitialNumberMembersValue & initial_number_members); + + // Get the Factories property. + int get_factories ( + const PortableGroup::Properties & properties, + PortableGroup::FactoryInfos_out factories); + + // Handle a single replica failure. + int single_replica_failure ( + TAO::FT_FaultEventDescriptor & fault_event_desc); + + // Handle a location failure. + int location_failure ( + TAO::FT_FaultEventDescriptor & fault_event_desc); + + // Handle a type at location failure. + int type_failure ( + TAO::FT_FaultEventDescriptor & fault_event_desc); + + // Is the replica at location the primary member of its ObjectGroup? + // Sets <object_is_primary> and returns 0 on success. + // Returns -1 on failure. + int is_primary_member ( + const PortableGroup::ObjectGroup_ptr iogr, + const PortableGroup::Location & location, + int & object_is_primary); + + /// remove a failed member from a group + int remove_failed_member ( + PortableGroup::ObjectGroup_ptr iogr, + TAO::FT_FaultEventDescriptor & fault_event_desc, + PortableGroup::ObjectGroup_out new_iogr); + + + // Choose a new primary member for the ObjectGroup. + // Sets <new_iogr> and returns 0 on success. + // Returns -1 on failure. + int set_new_primary ( + PortableGroup::ObjectGroup_ptr iogr, + TAO::FT_FaultEventDescriptor & fault_event_desc, + PortableGroup::ObjectGroup_out new_iogr); + +#if 0 // this is handled by the remove_member method + // While the number of members in the object group is less than + // the MinimumNumberMembers property, add new members. + // Sets <new_iogr> and returns 0 on success. + // Returns -1 on failure. + int add_members ( + PortableGroup::ObjectGroup_ptr iogr, + TAO::FT_FaultEventDescriptor & fault_event_desc, + PortableGroup::ObjectGroup_out new_iogr); +#endif + + /////////////// + // Data Members + private: + FT_ReplicationManager * replication_manager_; + + }; + +} // namespace TAO + +#include /**/ "ace/post.h" + +#endif /* FT_REPLICATION_MANAGER_FAULT_ANALYZER_H_ */ + diff --git a/TAO/orbsvcs/FT_ReplicationManager/FT_ReplicationManagerLib_export.h b/TAO/orbsvcs/FT_ReplicationManager/FT_ReplicationManagerLib_export.h new file mode 100644 index 00000000000..fe2d2d3e322 --- /dev/null +++ b/TAO/orbsvcs/FT_ReplicationManager/FT_ReplicationManagerLib_export.h @@ -0,0 +1,54 @@ + +// -*- C++ -*- +// $Id$ +// Definition for Win32 Export directives. +// This file is generated automatically by generate_export_file.pl TAO_ReplicationManagerLib +// ------------------------------ +#ifndef TAO_REPLICATIONMANAGERLIB_EXPORT_H +#define TAO_REPLICATIONMANAGERLIB_EXPORT_H + +#include "ace/config-all.h" + +#if !defined (TAO_REPLICATIONMANAGERLIB_HAS_DLL) +# define TAO_REPLICATIONMANAGERLIB_HAS_DLL 1 +#endif /* ! TAO_REPLICATIONMANAGERLIB_HAS_DLL */ + +#if defined (TAO_REPLICATIONMANAGERLIB_HAS_DLL) && (TAO_REPLICATIONMANAGERLIB_HAS_DLL == 1) +# if defined (TAO_REPLICATIONMANAGERLIB_BUILD_DLL) +# define TAO_ReplicationManagerLib_Export ACE_Proper_Export_Flag +# define TAO_REPLICATIONMANAGERLIB_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define TAO_REPLICATIONMANAGERLIB_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else /* TAO_REPLICATIONMANAGERLIB_BUILD_DLL */ +# define TAO_ReplicationManagerLib_Export ACE_Proper_Import_Flag +# define TAO_REPLICATIONMANAGERLIB_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define TAO_REPLICATIONMANAGERLIB_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* TAO_REPLICATIONMANAGERLIB_BUILD_DLL */ +#else /* TAO_REPLICATIONMANAGERLIB_HAS_DLL == 1 */ +# define TAO_ReplicationManagerLib_Export +# define TAO_REPLICATIONMANAGERLIB_SINGLETON_DECLARATION(T) +# define TAO_REPLICATIONMANAGERLIB_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* TAO_REPLICATIONMANAGERLIB_HAS_DLL == 1 */ + +// Set TAO_REPLICATIONMANAGERLIB_NTRACE = 0 to turn on library specific tracing even if +// tracing is turned off for ACE. +#if !defined (TAO_REPLICATIONMANAGERLIB_NTRACE) +# if (ACE_NTRACE == 1) +# define TAO_REPLICATIONMANAGERLIB_NTRACE 1 +# else /* (ACE_NTRACE == 1) */ +# define TAO_REPLICATIONMANAGERLIB_NTRACE 0 +# endif /* (ACE_NTRACE == 1) */ +#endif /* !TAO_REPLICATIONMANAGERLIB_NTRACE */ + +#if (TAO_REPLICATIONMANAGERLIB_NTRACE == 1) +# define TAO_REPLICATIONMANAGERLIB_TRACE(X) +#else /* (TAO_REPLICATIONMANAGERLIB_NTRACE == 1) */ +# if !defined (ACE_HAS_TRACE) +# define ACE_HAS_TRACE +# endif /* ACE_HAS_TRACE */ +# define TAO_REPLICATIONMANAGERLIB_TRACE(X) ACE_TRACE_IMPL(X) +# include "ace/Trace.h" +#endif /* (TAO_REPLICATIONMANAGERLIB_NTRACE == 1) */ + +#endif /* TAO_REPLICATIONMANAGERLIB_EXPORT_H */ + +// End of auto generated file. diff --git a/TAO/orbsvcs/FT_ReplicationManager/FT_ReplicationManager_Main.cpp b/TAO/orbsvcs/FT_ReplicationManager/FT_ReplicationManager_Main.cpp new file mode 100644 index 00000000000..36b0a4962e1 --- /dev/null +++ b/TAO/orbsvcs/FT_ReplicationManager/FT_ReplicationManager_Main.cpp @@ -0,0 +1,35 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FT_ReplicationManager_Main.cpp + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * This file provides the main routine for a process that + * implements the FT_ReplicationManager interface. + * + * @author Curt Hibbs <hibbs_c@ociweb.com> + */ +//============================================================================= + +#include "FT_ReplicationManager.h" +#include <tao/Utils/Server_Main.h> + +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + TAO::Utils::Server_Main<TAO::FT_ReplicationManager> + server_main("ReplicationManager"); + return server_main.run(argc, argv); +} + +/////////////////////////////////// +// Template instantiation for +// inept compilers. + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + template class TAO::Utils::Server_Main<TAO::FT_ReplicationManager>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +# pragma instantiate TAO::Utils::Server_Main<TAO::FT_ReplicationManager> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ + diff --git a/TAO/orbsvcs/FT_ReplicationManager/README b/TAO/orbsvcs/FT_ReplicationManager/README new file mode 100644 index 00000000000..6308eaea08d --- /dev/null +++ b/TAO/orbsvcs/FT_ReplicationManager/README @@ -0,0 +1,12 @@ + +Run FT_ReplicationManager as follows: + + FT_ReplicationManager -o <file1.ior> + Starts the replication manager and writes in ior + to the specified file. + + FT_ReplicationManager + Starts the replication manager and registers it + with the naming service. + +s
\ No newline at end of file diff --git a/TAO/orbsvcs/Fault_Detector/FT_FaultDetectorFactory_i.cpp b/TAO/orbsvcs/Fault_Detector/FT_FaultDetectorFactory_i.cpp new file mode 100644 index 00000000000..12618b2bdea --- /dev/null +++ b/TAO/orbsvcs/Fault_Detector/FT_FaultDetectorFactory_i.cpp @@ -0,0 +1,722 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FT_FaultDetectorFactory_i.cpp + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= +#include "FT_FaultDetectorFactory_i.h" +#include "Fault_Detector_i.h" +#include "ace/Get_Opt.h" +#include "orbsvcs/CosNamingC.h" +#include "orbsvcs/PortableGroup/PG_Property_Set.h" + +// Use this macro at the beginning of CORBA methods +// to aid in debugging. +#define METHOD_ENTRY(name) \ + ACE_DEBUG (( LM_DEBUG, \ + "Enter %s\n", #name \ + )) + +// Use this macro to return from CORBA methods +// to aid in debugging. Note that you can specify +// the return value after the macro, for example: +// METHOD_RETURN(Plugh::plover) xyzzy; is equivalent +// to return xyzzy; +// METHOD_RETURN(Plugh::troll); is equivalent to +// return; +// WARNING: THIS GENERATES TWO STATEMENTS!!! THE FOLLOWING +// will not do what you want it to: +// if (cave_is_closing) METHOD_RETURN(Plugh::pirate) aarrggh; +// Moral: Always use braces. +#define METHOD_RETURN(name) \ + ACE_DEBUG (( LM_DEBUG, \ + "Leave %s\n", #name \ + )); \ + return /* value goes here */ + + +////////////////////////////////////////////////////// +// FT_FaultDetectorFactory_i Construction/destruction + +TAO::FT_FaultDetectorFactory_i::FT_FaultDetectorFactory_i () + : orb_ (0) + , poa_ (0) + , objectId_ (0) + , ior_output_file_ (0) + , ns_name_ (0) + , naming_context_ (0) + , this_name_ (1) + , quit_on_idle_ (0) + , domain_ (CORBA::string_dup("default_domain")) + , location_ (1) + , notifier_ (0) + , rm_register_ (1) + , replication_manager_ (0) + , registered_ (0) + , factory_registry_ (0) + , identity_ ("") + , empty_slots_ (0) + , quit_requested_ (0) + +{ + this->location_.length(1); + this->location_[0].id = CORBA::string_dup("default_location"); +} + +TAO::FT_FaultDetectorFactory_i::~FT_FaultDetectorFactory_i () +{ + //scope the guard + { + InternalGuard guard (this->internals_); + + // be sure all detectors are gone + // before this object disappears + shutdown_i (); + } + ACE_DECLARE_NEW_ENV; + fini (ACE_ENV_SINGLE_ARG_PARAMETER); + this->threadManager_.close (); +} + +//////////////////////////////////////////// +// FT_FaultDetectorFactory_i private methods + +void TAO::FT_FaultDetectorFactory_i::shutdown_i() +{ + // assume mutex is locked + for (size_t nDetector = 0; nDetector < this->detectors_.size(); ++nDetector) + { + Fault_Detector_i * detector = this->detectors_[nDetector]; + if (detector != 0) + { + detector->request_quit(); + } + } +} + +int TAO::FT_FaultDetectorFactory_i::write_ior() +{ + int result = -1; + FILE* out = ACE_OS::fopen (this->ior_output_file_, "w"); + if (out) + { + ACE_OS::fprintf (out, "%s", ACE_static_cast(const char *, this->ior_)); + ACE_OS::fclose (out); + result = 0; + } + else + { + ACE_ERROR ((LM_ERROR, + "Open failed for %s\n", ior_output_file_ + )); + } + return result; +} + +////////////////////////////////////////////////////// +// FT_FaultDetectorFactory_i public, non-CORBA methods + +int TAO::FT_FaultDetectorFactory_i::parse_args (int argc, char * argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "d:l:o:qr"); + int c; + + while ((c = get_opts ()) != -1) + { + switch (c) + { + case 'd': + { + this->domain_ = CORBA::string_dup (get_opts.opt_arg ()); + break; + } + case 'l': + { + this->location_.length(1); + this->location_[0].id = CORBA::string_dup(get_opts.opt_arg ()); + break; + } + case 'o': + { + this->ior_output_file_ = get_opts.opt_arg (); + break; + } + case 'r': + { + this->rm_register_ = ! this->rm_register_; + break; + } + case 'q': + { + this->quit_on_idle_ = 1; + break; + } + + case '?': + // fall thru + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s" + " -d <FT Domain>" + " -l <FT Location>" + " -o <iorfile>" + " -r <disable registering with replication manager>" + " -q{uit on idle}" + "\n", + argv [0]), + -1); + break; + } + } + // Indicates sucessful parsing of the command line + return 0; +} + +const char * TAO::FT_FaultDetectorFactory_i::identity () const +{ + return this->identity_.c_str(); +} + +int TAO::FT_FaultDetectorFactory_i::idle (int & result) +{ + ACE_UNUSED_ARG (result); + int quit = this->quit_requested_; + if (quit == 0 && this->detectors_.size() == this->empty_slots_) + { + // don't quitOnIdle until something has happened + if (this->quit_on_idle_ && this->empty_slots_ != 0) + { + ACE_ERROR (( LM_INFO, + "FaultDetectorFactory exits due to quit on idle option.\n" + )); + quit = 1; + } + } + + return quit; +} + + +int TAO::FT_FaultDetectorFactory_i::init (CORBA::ORB_ptr orb ACE_ENV_ARG_DECL) +{ + int result = 0; + this->orb_ = CORBA::ORB::_duplicate (orb); + + // Use the ROOT POA for now + CORBA::Object_var poa_object = + this->orb_->resolve_initial_references (TAO_OBJID_ROOTPOA + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (CORBA::is_nil (poa_object.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT (" (%P|%t) Unable to initialize the POA.\n")), + -1); + + // Get the POA object. + this->poa_ = + PortableServer::POA::_narrow (poa_object.in () + ACE_ENV_ARG_PARAMETER); + + ACE_CHECK_RETURN (-1); + + if (CORBA::is_nil(this->poa_.in ())) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT (" (%P|%t) Unable to narrow the POA.\n")), + -1); + } + + PortableServer::POAManager_var poa_manager = + this->poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + // Register with the POA. + + this->objectId_ = this->poa_->activate_object (this ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + // find my IOR + + CORBA::Object_var this_obj = + this->poa_->id_to_reference (objectId_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + this->ior_ = this->orb_->object_to_string (this_obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + this->identity_ = "FaultDetectorFactory"; + + /////////////////////////////// + // Register with ReplicationManager + if (this->rm_register_) + { + ACE_TRY_NEW_ENV + { + CORBA::Object_var rm_obj = orb->resolve_initial_references("ReplicationManager" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + this->replication_manager_ = ::FT::ReplicationManager::_narrow(rm_obj.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + if (!CORBA::is_nil (replication_manager_.in ())) + { + // capture the default notifier + this->notifier_ = this->replication_manager_->get_fault_notifier (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + // register with ReplicationManager::RegistrationFactory + PortableGroup::Criteria criteria(0); + this->factory_registry_ = this->replication_manager_->get_factory_registry (criteria ACE_ENV_ARG_PARAMETER) + ACE_TRY_CHECK; + + if (! CORBA::is_nil(factory_registry_.in ())) + { + PortableGroup::FactoryInfo info; + info.the_factory = ::PortableGroup::GenericFactory::_narrow(this_obj.in ()); + info.the_location = this->location_; + info.the_criteria.length(1); + info.the_criteria[0].nam.length(1); + info.the_criteria[0].nam[0].id = CORBA::string_dup(PortableGroup::role_criterion); + info.the_criteria[0].val <<= CORBA::string_dup(FT::FAULT_DETECTOR_ROLE_NAME); + + ACE_DEBUG ((LM_DEBUG, + "FaultDetector registering with ReplicationManager.\n" + )); + this->factory_registry_->register_factory( + FT::FAULT_DETECTOR_ROLE_NAME, + FT::FAULT_DETECTOR_ROLE_NAME, + info + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_DEBUG ((LM_DEBUG, + "FaultDetector Registration complete.\n" + )); + this->registered_ = 1; + } + else + { + ACE_ERROR ((LM_ERROR,"FaultNotifier: ReplicationManager doesn't have RegistrationFactory.\n" )); + } + } + else + { + ACE_ERROR ((LM_ERROR,"FaultNotifier: Can't resolve ReplicationManager, It will not be registered.\n" )); + } + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "ReplicaFactory: Exception resolving ReplicationManager. Factory will not be registered.\n" ); + } + ACE_ENDTRY; + } + else + { + ACE_DEBUG ((LM_DEBUG, + "FaultNotifier: ReplicationManager registration disabled.\n" + )); + } + + if (this->ior_output_file_ != 0) + { + this->identity_ = "file:"; + this->identity_ += this->ior_output_file_; + write_ior(); + } + + if (this->ns_name_ != 0) + { + this->identity_ = "name:"; + this->identity_ += this->ns_name_; + + CORBA::Object_var naming_obj = + this->orb_->resolve_initial_references ("NameService" ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (CORBA::is_nil(naming_obj.in ())){ + ACE_ERROR_RETURN ((LM_ERROR, + "%T %n (%P|%t) Unable to find the Naming Service\n"), + 1); + } + + this->naming_context_ = + ::CosNaming::NamingContext::_narrow (naming_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + this->this_name_.length (1); + this->this_name_[0].id = CORBA::string_dup (this->ns_name_); + + this->naming_context_->rebind (this->this_name_, this_obj.in() //CORBA::Object::_duplicate(this_obj) + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + } + + return result; +} + +int TAO::FT_FaultDetectorFactory_i::fini (ACE_ENV_SINGLE_ARG_DECL) +{ + if (this->ior_output_file_ != 0) + { + ACE_OS::unlink (this->ior_output_file_); + this->ior_output_file_ = 0; + } + if (this->ns_name_ != 0) + { + this->naming_context_->unbind (this_name_ + ACE_ENV_ARG_PARAMETER); + this->ns_name_ = 0; + } + + if (this->registered_) + { + this->factory_registry_->unregister_factory( + FT::FAULT_DETECTOR_ROLE_NAME, + this->location_ + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + this->registered_ = 0; + } + return 0; +} + + +CORBA::ULong TAO::FT_FaultDetectorFactory_i::allocate_id() +{ + CORBA::ULong id = this->detectors_.size(); + if (this->empty_slots_ != 0) + { + for(CORBA::ULong pos = 0; pos < id; ++pos) + { + if (this->detectors_[pos] == 0) + { + id = pos; + } + } + } + else + { + this->detectors_.push_back(0); + this->empty_slots_ += 1; + } + return id; +} + +void TAO::FT_FaultDetectorFactory_i::remove_detector(CORBA::ULong id, TAO::Fault_Detector_i * detector) +{ + InternalGuard guard (this->internals_); + if (id < this->detectors_.size()) + { + if(this->detectors_[id] == detector) + { + delete this->detectors_[id]; + this->detectors_[id] = 0; + this->empty_slots_ += 1; + if (this->empty_slots_ == this->detectors_.size()) + { + ACE_ERROR (( LM_INFO, + "FaultDetectorFactory is idle.\n" + )); + } + } + else + { + ACE_ERROR (( LM_ERROR, + "Remove detector %d mismatch.\n", + ACE_static_cast(int, id) + )); + } + } + else + { + ACE_ERROR (( LM_ERROR, + "Attempt to remove invalid detector %d. Limit %d.\n", + ACE_static_cast(int, id), + ACE_static_cast(int, this->detectors_.size()) + )); + } +} + +////////////////////////////////////////// +// FT_FaultDetectorFactory_i CORBA methods + +void TAO::FT_FaultDetectorFactory_i::change_properties ( + const PortableGroup::Properties & property_set + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + , PortableGroup::InvalidProperty + )) +{ + METHOD_ENTRY(TAO::FT_FaultDetectorFactory_i::change_properties); + + // TimeT is expressed in 10E-7 seconds (== 100 nSec == 0.1 uSec) + static const long timeT_per_uSec = 10L; + static const long uSec_per_sec = 1000000L; + + ::TAO::PG_Property_Set decoder(property_set); + + TimeBase::TimeT value = 0; + if( TAO::find (decoder, FT::FT_FAULT_MONITORING_INTERVAL, value) ) + { + // note: these should be unsigned long, but + // ACE_Time_Value wants longs. + long uSec = ACE_static_cast (long, (value / timeT_per_uSec) % uSec_per_sec); + long sec = ACE_static_cast (long, (value / timeT_per_uSec) / uSec_per_sec); + ACE_Time_Value atv(sec, uSec); + TAO::Fault_Detector_i::set_time_for_all_detectors(atv); + } + else + { + ACE_ERROR ((LM_ERROR, + "Throwing Invalid Property: %s\n", + FT::FT_FAULT_MONITORING_INTERVAL + )); + ::PortableGroup::InvalidProperty ex; + ex.nam.length(1); + ex.nam[0].id = CORBA::string_dup(FT::FT_FAULT_MONITORING_INTERVAL); + ACE_THROW (ex); + } + METHOD_RETURN(TAO::FT_FaultDetectorFactory_i::change_properties); +} + +void TAO::FT_FaultDetectorFactory_i::shutdown (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC (( + CORBA::SystemException + )) +{ + METHOD_ENTRY(TAO::FT_FaultDetectorFactory_i::shutdown); + InternalGuard guard (this->internals_); + shutdown_i (); + this->quit_requested_ = 1; + METHOD_RETURN(TAO::FT_FaultDetectorFactory_i::shutdown); +} + +CORBA::Object_ptr TAO::FT_FaultDetectorFactory_i::create_object ( + const char * type_id, + const PortableGroup::Criteria & the_criteria, + PortableGroup::GenericFactory::FactoryCreationId_out factory_creation_id + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + , PortableGroup::NoFactory + , PortableGroup::ObjectNotCreated + , PortableGroup::InvalidCriteria + , PortableGroup::InvalidProperty + , PortableGroup::CannotMeetCriteria + )) +{ + METHOD_ENTRY(TAO::FT_FaultDetectorFactory_i::create_object); + + ACE_UNUSED_ARG (type_id); //@@ use it + InternalGuard guard (this->internals_); + + ::TAO::PG_Property_Set decoder (the_criteria); + + // boolean, becomes true if a required parameter is missing + int missingParameter = 0; + const char * missingParameterName = 0; + + FT::FaultNotifier_ptr notifier; + if (! ::TAO::find (decoder, ::FT::FT_NOTIFIER, notifier) ) + { + if (! CORBA::is_nil (this->notifier_.in ())) + { + notifier = FT::FaultNotifier::_duplicate (this->notifier_.in ()); + } + else + { + ACE_ERROR ((LM_ERROR, + "FaultDetectorFactory::create_object: Missing parameter %s\n", + ::FT::FT_NOTIFIER + )); + missingParameter = 1; + missingParameterName = ::FT::FT_NOTIFIER; + } + } + + FT::PullMonitorable_ptr monitorable; + if (! ::TAO::find (decoder, ::FT::FT_MONITORABLE, monitorable) ) + { + ACE_ERROR ((LM_ERROR, + "FaultDetectorFactory::create_object: Missing parameter %s\n", + ::FT::FT_MONITORABLE + )); + missingParameter = 1; + missingParameterName = ::FT::FT_MONITORABLE; + } + + FT::FTDomainId domain_id = 0; + // note the cast in the next line makes ANY >>= work. + const char * domain_id_string = 0; + if (::TAO::find (decoder, ::FT::FT_DOMAIN_ID, domain_id_string) ) + { + // NOTE the assumption that we can assign a char * to a domain id + domain_id = ACE_const_cast (char *, domain_id_string); + } + else + { + domain_id = this->domain_; + +// ACE_ERROR ((LM_ERROR, +// "FaultDetectorFactory::create_object: Missing parameter %s\n", +// ::FT::FT_DOMAIN_ID +// )); +// missingParameter = 1; +// missingParameterName = ::FT::FT_DOMAIN_ID; + } + + PortableGroup::Location * object_location = 0; + if (! ::TAO::find (decoder, ::FT::FT_LOCATION, object_location) ) + { + object_location = & this->location_; + +// ACE_ERROR ((LM_ERROR, +// "FaultDetectorFactory::create_object: Missing parameter %s\n", +// ::FT::FT_LOCATION +// )); +// missingParameter = 1; +// missingParameterName = ::FT::FT_LOCATION; + } + + PortableGroup::TypeId object_type = 0; + const char * object_type_string; + if (::TAO::find (decoder, ::FT::FT_TYPE_ID, object_type_string)) + { + object_type = ACE_const_cast (char *, object_type_string); + } + else + { + object_type = ACE_const_cast (char *, "unknown"); + // Not required: missingParameter = 1; + ACE_DEBUG ((LM_DEBUG, "Object type not given.\n")); + } + + FT::ObjectGroupId group_id = 0; + if (! ::TAO::find (decoder, ::FT::FT_GROUP_ID, group_id) ) + { + // Not required: missingParameter = 1; + } + + if (missingParameter) + { + ACE_ERROR ((LM_ERROR, + "Throwing 'InvalidCriteria' due to missing %s\n", + missingParameterName + )); + ACE_THROW ( PortableGroup::InvalidCriteria() ); + } + + CORBA::ULong detectorId = allocate_id(); + + // NOTE: ACE_NEW is incompatable with auto_ptr + // so create a bare pointer first. + TAO::Fault_Detector_i * pFD = 0; + + ACE_NEW_NORETURN(pFD, TAO::Fault_Detector_i( + *this, + detectorId, + notifier, + monitorable, + domain_id, + *object_location, + object_type, + group_id)); + if (pFD == 0) + { + ACE_ERROR ((LM_ERROR, + "New FaultDetector_i returned NULL. Throwing ObjectNotCreated.\n" + )); + ACE_THROW ( PortableGroup::ObjectNotCreated() ); + } + auto_ptr<TAO::Fault_Detector_i> detector(pFD); + + ACE_NEW_NORETURN ( factory_creation_id, + PortableGroup::GenericFactory::FactoryCreationId); + if (factory_creation_id.ptr() == 0) + { + ACE_ERROR ((LM_ERROR, + "New factory_creation_id returned NULL. Throwing ObjectNotCreated.\n" + )); + + ACE_THROW ( PortableGroup::ObjectNotCreated() ); + } + (*factory_creation_id) <<= detectorId; + + (*detector).start(this->threadManager_); + + this->detectors_[detectorId] = detector.release(); + this->empty_slots_ -= 1; + + // since FaultDetector is not a CORBA object (it does not implement + // an interface.) we always return NIL; + METHOD_RETURN(TAO::FT_FaultDetectorFactory_i::create_object) + CORBA::Object::_nil(); +} + +void TAO::FT_FaultDetectorFactory_i::delete_object ( + const PortableGroup::GenericFactory::FactoryCreationId & factory_creation_id + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + , PortableGroup::ObjectNotFound + )) +{ + METHOD_ENTRY(TAO::FT_FaultDetectorFactory_i::delete_object); + + InternalGuard guard (this->internals_); + + CORBA::ULong detectorId; + factory_creation_id >>= detectorId; + if (detectorId < this->detectors_.size()) + { + if(this->detectors_[detectorId] != 0) + { + this->detectors_[detectorId]->request_quit(); + } + else + { + ACE_THROW(::PortableGroup::ObjectNotFound()); + } + } + else + { + ACE_THROW(::PortableGroup::ObjectNotFound()); + } + METHOD_RETURN(TAO::FT_FaultDetectorFactory_i::delete_object); +} + +CORBA::Boolean TAO::FT_FaultDetectorFactory_i::is_alive (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + METHOD_RETURN(TAO::FT_FaultDetectorFactory_i::is_alive) + 1; +} + +/////////////////////////////////// +// Template instantiation for +// competence-challenged compilers. + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + template class ACE_Vector<TAO::Fault_Detector_i *>; + template class ACE_Guard<ACE_SYNCH_MUTEX>; + template class auto_ptr<TAO::Fault_Detector_i>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +# pragma instantiate ACE_Vector<TAO::Fault_Detector_i *> +# pragma instantiate ACE_Guard<ACE_SYNCH_MUTEX> +# pragma instantiate auto_ptr<TAO::Fault_Detector_i>; +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/Fault_Detector/FT_FaultDetectorFactory_i.h b/TAO/orbsvcs/Fault_Detector/FT_FaultDetectorFactory_i.h new file mode 100644 index 00000000000..a6bd20f11f6 --- /dev/null +++ b/TAO/orbsvcs/Fault_Detector/FT_FaultDetectorFactory_i.h @@ -0,0 +1,347 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FT_FaultDetectorFactory_i.h + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * It declares the implementation of FaultDetectorFactory which + * creates and manages FaultDetectors as an agent for + * the ReplicationManager as defined in the FT CORBA specification. + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= + +#ifndef FT_FAULTDETECTORFACTORY_I_H_ +#define FT_FAULTDETECTORFACTORY_I_H_ +#include /**/ <ace/pre.h> +#include <ace/ACE.h> +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +////////////////////////////////// +// Classes declared in this header +namespace TAO +{ + class FT_FaultDetectorFactory_i; +} + +///////////////////////////////// +// Includes needed by this header +#include <ace/Vector_T.h> +#include <orbsvcs/FT_FaultDetectorFactoryS.h> +#include <orbsvcs/FT_ReplicationManagerC.h> +#include <ace/Thread_Manager.h> + +///////////////////// +// Forward references + +/** + * Implement the FaultDetectorFactory interface. + * + * Because each FaultDetector runs in a separate thread, care + * must be taken to insure that the thread comes to an end, and + * that the Fault_Detector_i object is deleted at the right time. + * Hence, the FaultDetector life cycle: + * Creation: + * The create_object method of the factory creates a Fault_Detector_i + * + * A pointer to the Fault_Detector_i is stored in the detectors_ table. + * + * The start method of the Fault_Detector_i is called to create a thread + * that will monotor the object-to-be-monitored. An ACE_Thread_Manager + * supplied by the factory is used to keep track of the thread. + * + * Destruction: + * + * If the factory wants the detector to go away, it calls the + * quitRequested method of the detector which sets a flag that must + * be checked regularly by the detector. + * + * If the object being monitored faults, the detector sends the + * notification message then sets its own quit requested flag. + * + * When a detector discovers the quit requested flag has been set + * it calls the remove_detector method of the factory, then ends + * the thread. + * + * The remove_detector method of the factory removes the detector from + * the detectors_ collection, then deletes the Fault_Detector_i object. + * + * Shutdown: + * + * The destructor of the factory calls the shutdown method of all + * remaining Fault_Detector_i objects. + * + * It then closes the ACE_Thread_Manager to ensure that all + * detector threads have departed before the factory itself is + * deleted. + * + */ + +namespace TAO +{ + ///////////////////// + // Forward references + class Fault_Detector_i; + + ///////////////////// + // Class Declarations + class FT_FaultDetectorFactory_i : public virtual POA_FT::FaultDetectorFactory + { + typedef ACE_Vector<Fault_Detector_i *> DetectorVec; + + ////////////////////// + // non-CORBA interface + public: + /** + * Default constructor. + */ + FT_FaultDetectorFactory_i (); + + /** + * Virtual destructor. + */ + virtual ~FT_FaultDetectorFactory_i (); + + /** + * Parse command line arguments. + * @param argc traditional C argc + * @param argv traditional C argv + * @return zero for success; nonzero is process return code for failure. + */ + int parse_args (int argc, char * argv[]); + + /** + * Initialize this object. + * @param orb our ORB -- we keep var to it. + * @return zero for success; nonzero is process return code for failure. + */ + int init (CORBA::ORB_ptr orb ACE_ENV_ARG_DECL); + + /** + * Prepare to exit. + * @return zero for success; nonzero is process return code for failure. + */ + int fini (ACE_ENV_SINGLE_ARG_DECL); + + /** + * Idle-time activity. + * + * @param result is set to process return code if return value is non-zero. + * @return zero to continue; nonzero to exit + */ + int idle(int & result); + + + /** + * Identify this fault detector factory. + * @return a string to identify this object for logging/console message purposes. + */ + const char * identity () const; + + /** + * Remove pointer to individual detector; delete Fault_Detector_i. + * See FaultDetector life cycle description. + * @param id the numerical id assigned to this FaultDetector. + * @param detector a pointer to the detector object (redundant for safety.) + */ + void remove_detector (CORBA::ULong id, Fault_Detector_i * detector); + + ////////////////// + // CORBA interface + // See IDL for documentation + + /////////////////////////////////////////////// + // CORBA interface FaultDetectorFactory methods + virtual void change_properties ( + const PortableGroup::Properties & property_set + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + , PortableGroup::InvalidProperty + )); + + virtual void shutdown (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC (( + CORBA::SystemException + )); + + ///////////////////////////////////////// + // CORBA interface GenericFactory methods + virtual CORBA::Object_ptr create_object ( + const char * type_id, + const PortableGroup::Criteria & the_criteria, + PortableGroup::GenericFactory::FactoryCreationId_out factory_creation_id + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + , PortableGroup::NoFactory + , PortableGroup::ObjectNotCreated + , PortableGroup::InvalidCriteria + , PortableGroup::InvalidProperty + , PortableGroup::CannotMeetCriteria + )); + + virtual void delete_object ( + const PortableGroup::GenericFactory::FactoryCreationId & factory_creation_id + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + , PortableGroup::ObjectNotFound + )); + + ////////////////////////////////////////// + // CORBA interface PullMonitorable methods + + virtual CORBA::Boolean is_alive (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + + ///////////////////////// + // Implementation methods + private: + /** + * Find or allocate an ID for a new detector + */ + CORBA::ULong allocate_id(); + + /** + * Write this factory's IOR to a file + */ + int write_ior (); + + /** + * Clean house for factory shut down. + */ + void shutdown_i (); + + /////////////// + // Data Members + private: + + /** + * Protect internal state. + * Mutex should be locked by corba methods, or by + * external (public) methods before calling implementation + * methods. + * Implementation methods should assume the mutex is + * locked if necessary. + */ + ACE_SYNCH_MUTEX internals_; + typedef ACE_Guard<ACE_SYNCH_MUTEX> InternalGuard; + + /** + * The orb + */ + CORBA::ORB_var orb_; + + /** + * The POA used to activate this object. + */ + PortableServer::POA_var poa_; + + /** + * The CORBA object id assigned to this object. + */ + PortableServer::ObjectId_var objectId_; + + + /** + * IOR of this object as assigned by orb. + */ + CORBA::String_var ior_; + + /** + * A file to which the factory's IOR should be written. + */ + const char * ior_output_file_; + + /** + * A name to be used to register the factory with the name service. + */ + const char * ns_name_; + + ::CosNaming::NamingContext_var naming_context_; + + ::CosNaming::Name this_name_; + + /** + * Quit on idle flag. + */ + int quit_on_idle_; + + /** + * the FT::Domain where we're operating + */ + PortableGroup::GroupDomainId domain_; + + /** + * the FT::Location within the domain + */ + PortableGroup::Location location_; + + /** + * the notifer to use by default + */ + + FT::FaultNotifier_var notifier_; + + /** + * bool: if true, register with ReplicationManager. + * default is true. -x turns it off. + */ + int rm_register_; + + /** + * the replication manager + */ + ::FT::ReplicationManager_var replication_manager_; + + /** + * bool: if true the registration with ReplicationManager was successful. + */ + int registered_; + + /** + * The factory registry with which to register. + */ + PortableGroup::FactoryRegistry_var factory_registry_; + + /** + * A human-readable string to distinguish this from other Notifiers. + */ + ACE_CString identity_; + + /** + * A manager for all FaultDetector threads. + */ + ACE_Thread_Manager threadManager_; + + /** + * A vector of FaultDetectors. Note that the FaultDetector ID + * is an index into this vector. + */ + DetectorVec detectors_; + + /** + * count of empty entries in detectors_ + * Used to determine when the factory is idle, and to avoid + * fruitless searches for empty slots. + */ + size_t empty_slots_; + + /** + * boolean: starts false. Set to true when it's time to quit. + */ + int quit_requested_; + }; +} // namespace TAO + +#include /**/ <ace/post.h> +#endif /* FT_FAULTDETECTORFACTORY_I_H_ */ diff --git a/TAO/orbsvcs/Fault_Detector/Fault_Detector.mpc b/TAO/orbsvcs/Fault_Detector/Fault_Detector.mpc new file mode 100644 index 00000000000..089f92cad95 --- /dev/null +++ b/TAO/orbsvcs/Fault_Detector/Fault_Detector.mpc @@ -0,0 +1,9 @@ +project : taoserver, orbsvcsexe, fault_tolerance { + exename = Fault_Detector + Source_Files { + Fault_Detector_i.cpp + Fault_Detector_Main.cpp + FT_FaultDetectorFactory_i.cpp + } +} + diff --git a/TAO/orbsvcs/Fault_Detector/Fault_Detector_Main.cpp b/TAO/orbsvcs/Fault_Detector/Fault_Detector_Main.cpp new file mode 100644 index 00000000000..a9bb89197d9 --- /dev/null +++ b/TAO/orbsvcs/Fault_Detector/Fault_Detector_Main.cpp @@ -0,0 +1,34 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FaultDetectorMain.cpp + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * This file provides the main routine for a process that + * implements the FaultDetectorFactory interface and manages + * a set of FaultDetectors. + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= + +#include <tao/Utils/Server_Main.h> +#include "FT_FaultDetectorFactory_i.h" + +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + TAO::Utils::Server_Main<TAO::FT_FaultDetectorFactory_i> server_main("TAO_FaultDetector"); + return server_main.run(argc, argv); +} + +/////////////////////////////////// +// Template instantiation for +// inept compilers. + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + template class TAO::Utils::Server_Main<TAO::FT_FaultDetectorFactory_i>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +# pragma instantiate TAO::Utils::Server_Main<TAO::FT_FaultDetectorFactory_i> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/Fault_Detector/Fault_Detector_i.cpp b/TAO/orbsvcs/Fault_Detector/Fault_Detector_i.cpp new file mode 100644 index 00000000000..7795ecf6cb2 --- /dev/null +++ b/TAO/orbsvcs/Fault_Detector/Fault_Detector_i.cpp @@ -0,0 +1,202 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file Fault_Detector_i.cpp + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * This file implements the Fault_Detector_i class as declared in Fault_Detector_i.h. + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= +#include "Fault_Detector_i.h" +#include "FT_FaultDetectorFactory_i.h" + +/////////////////////////////// +// Fault_Detector_i static data + +ACE_Time_Value TAO::Fault_Detector_i::sleep_time_(1,0); + + +///////////////////////////////////////// +// Fault_Detector_i public static methods + +void TAO::Fault_Detector_i::set_time_for_all_detectors(ACE_Time_Value value) +{ + sleep_time_ = value; +} + +//////////////////////////////////////////// +// Fault_Detector_i construction/destruction + +TAO::Fault_Detector_i::Fault_Detector_i ( + FT_FaultDetectorFactory_i & factory, + CORBA::ULong id, + FT::FaultNotifier_ptr & notifier, + FT::PullMonitorable_ptr & monitorable, + FT::FTDomainId domain_id, + const PortableGroup::Location & object_location, + PortableGroup::TypeId object_type, + PortableGroup::ObjectGroupId group_id + ) + : factory_(factory) + , id_(id) + , domain_id_(domain_id) + , object_location_(object_location) + , object_type_(object_type) + , group_id_(group_id) + , sleep_(0) // initially not signaled + , quit_requested_(0) +{ + this->notifier_ = FT::FaultNotifier::_duplicate(notifier); + this->monitorable_ = FT::PullMonitorable::_duplicate(monitorable); + ACE_DEBUG ((LM_DEBUG, + "Object type %s\n", object_type + )); +} + +TAO::Fault_Detector_i::~Fault_Detector_i () +{ +} + +//////////////////////////////////// +// Fault_Detector_i public interface + + +void TAO::Fault_Detector_i::request_quit() +{ + this->quit_requested_ = 1; + // wake up the thread + this->sleep_.signal (); +} + +void TAO::Fault_Detector_i::start(ACE_Thread_Manager & threadManager) +{ + threadManager.spawn(thr_func, this); +} + +/////////////////////////////////////////////////// +// Fault_Detector_i private implementation methods + +void TAO::Fault_Detector_i::run() +{ + while ( ! this->quit_requested_ ) + { + ACE_TRY_NEW_ENV + { + if (this->monitorable_->is_alive(ACE_ENV_SINGLE_ARG_PARAMETER)) + { + ACE_TRY_CHECK; + // use this rather than ACE_OS::sleep + // to allow the nap to be interruped see request_quit + this->sleep_.wait (&sleep_time_, 0); + } + else + { + ACE_ERROR ((LM_INFO, + "FaultDetector%d FAULT: not alive.\n", + id_ + )); + notify(); + this->quit_requested_ = 1; + } + } + ACE_CATCHANY // todo refine this + { + ACE_ERROR ((LM_ERROR, + "FaultDetector FAULT: exception.\n" + )); + notify(); + this->quit_requested_ = 1; + } + ACE_ENDTRY; + } + // warning: The following call will delete + // this object. Be careful not to reference + // member data after making this call. + // todo: use "scoped resource management" to make + // this exception-safe and stupid-return-safe. + this->factory_.remove_detector (this->id_, this); +} + +void TAO::Fault_Detector_i::notify() +{ + CosNotification::StructuredEvent_var vEvent; + ACE_NEW_NORETURN(vEvent, CosNotification::StructuredEvent ); + if (vEvent.ptr() != 0) + { + CORBA::ULong length = 2; + if( this->object_type_ != 0) + { + length = 3; + if (this->group_id_!= 0) + { + length = 4; + } + } + + vEvent->header.fixed_header.event_type.domain_name = FT::FT_EVENT_TYPE_DOMAIN; + vEvent->header.fixed_header.event_type.type_name = FT::FT_EVENT_TYPE_NAME; + vEvent->filterable_data.length(length); + vEvent->filterable_data[0].name = FT::FT_DOMAIN_ID; + (vEvent->filterable_data[0].value) <<= this->domain_id_; + vEvent->filterable_data[1].name = FT::FT_LOCATION; + (vEvent->filterable_data[1].value) <<= this->object_location_; + if (this->object_type_!= 0) + { + vEvent->filterable_data[2].name = FT::FT_TYPE_ID; + (vEvent->filterable_data[2].value) <<= this->object_type_; + if (this->group_id_!= 0) + { + vEvent->filterable_data[3].name = FT::FT_GROUP_ID; + vEvent->filterable_data[3].value <<= this->group_id_; + } + } + ACE_TRY_NEW_ENV + { + if (TAO_debug_level > 5) + { + ACE_ERROR ((LM_ERROR, + "call Fault Detector push Structured Event.\n" + )); + } + this->notifier_->push_structured_fault(vEvent.in() + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + if (TAO_debug_level > 5) + { + + ACE_ERROR ((LM_ERROR, + "return from Fault Detector push Structured Event.\n" + )); + } + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "Fault Detector cannot send notification."); + } + ACE_ENDTRY; + } + else + { + ACE_ERROR ((LM_ERROR, + "Fault Detector cannot create Structured Event.\n" + )); + } +} + + +///////////////////////////////////////////////////////// +// Fault_Detector_i private static implementation methods + +//static +ACE_THR_FUNC_RETURN TAO::Fault_Detector_i::thr_func (void * arg) +{ + TAO::Fault_Detector_i * detector = ACE_static_cast (TAO::Fault_Detector_i * , arg); + detector->run (); + return 0; +} + diff --git a/TAO/orbsvcs/Fault_Detector/Fault_Detector_i.h b/TAO/orbsvcs/Fault_Detector/Fault_Detector_i.h new file mode 100644 index 00000000000..caac2690042 --- /dev/null +++ b/TAO/orbsvcs/Fault_Detector/Fault_Detector_i.h @@ -0,0 +1,183 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file Fault_Detector_i.h + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * This file declares the Fault_Detector_i class. + * The class implements the FaultDetectors as defined + * in the specification. + * A FaultDetector monitors the health of replicas. + * It is *NOT* a CORBA object and does not implement an IDL interface. + * All CORBA interaction with a FaultDetector is via a FaultDetectorFactory. + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= + + +#ifndef FAULT_DETECTOR_I_H_ +#define FAULT_DETECTOR_I_H_ +#include /**/ <ace/pre.h> +#include <ace/ACE.h> +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +////////////////////////////////// +// Classes declared in this header +namespace TAO +{ + class Fault_Detector_i; +} + + +#include "orbsvcs/FT_NotifierC.h" +#include "orbsvcs/FT_ReplicaC.h" +#include "ace/Time_Value.h" + + +namespace TAO +{ + ////////////////////// + // Forward references + + class FT_FaultDetectorFactory_i; + + ////////////////////// + // Class declarations + + class Fault_Detector_i + { + /////////////////// + // Public interface + public: + /** + * Construct FaultDetector. + * @param factory to be notified when this detector goes away. + * @param id to use when notifyting the factory of detector departure. + * @param notifier to receive the fault notification if our monitorable faults. + * @param monitorable object to be monitored. + * @param domain_id data to include in fault notification. + * @param object_location data to include in fault notification. + * @param object_type data to include in fault notification. + * @param group_id data to include in fault notification. + */ + Fault_Detector_i ( + FT_FaultDetectorFactory_i & factory, + CORBA::ULong id, + FT::FaultNotifier_ptr & notifier, + FT::PullMonitorable_ptr & monitorable, + FT::FTDomainId domain_id, + const PortableGroup::Location & object_location, + PortableGroup::TypeId object_type, + PortableGroup::ObjectGroupId group_id + ); + /** + * destructor. + * Non-virtual because this class does not take part in + * inheritence. + */ + ~Fault_Detector_i (); + + /** + * Start the thread associated with this fault detector. + * @param threadManager to track this thread. + */ + void start(ACE_Thread_Manager & threadManager); + + /** + * Request that this detector shut itself down. + */ + void request_quit(); + + //////////////////////// + // Static public methods + public: + /** + * Set the polling time for all FaultDetectors in this process. + * @param value the time between polls. + */ + static void set_time_for_all_detectors (ACE_Time_Value value); + + ///////////////////////// + // implementation methods + private: + /** + * Send the notification message. + */ + void notify(); + + /** + * The method to be run in the fault detector thread. + */ + void run(); + + /** + * The startup function for the fault detector thread. + */ + static ACE_THR_FUNC_RETURN thr_func (void * arg); + + //////////////////// + // Forbidden methods + private: + Fault_Detector_i (); + Fault_Detector_i (Fault_Detector_i & rhs); + Fault_Detector_i & operator = (const Fault_Detector_i & rhs); + + /////////////// + // Static data + private: + /** + * Time between polls for all fault detectors in this process. + */ + static ACE_Time_Value sleep_time_; + + /////////////// + // Data members + private: + /** + * The factory that "owns" us." + */ + FT_FaultDetectorFactory_i & factory_; + + /** + * How the factory knows who we are. + */ + CORBA::ULong id_; + + /** + * Where to send fault notification messages. + */ + FT::FaultNotifier_var notifier_; + + /** + * What to monitor. + */ + FT::PullMonitorable_var monitorable_; + + /** + * Data for the notification message. + */ + FT::FTDomainId domain_id_; + PortableGroup::Location object_location_; + PortableGroup::TypeId object_type_; + PortableGroup::ObjectGroupId group_id_; + + /** + * An Event (in the Win32 sense) to implement interruptable sleep. + * Manual rather than auto because once quit is requested we never + * want to sleep again. + */ + ACE_Manual_Event sleep_; + + /** + * A boolean flag. If true, this fault detector should leave. + */ + int quit_requested_; + }; +} // namespace TAO +#include /**/ <ace/post.h> +#endif // FAULT_DETECTOR_I_H_ diff --git a/TAO/orbsvcs/Fault_Notifier/.cvsignore b/TAO/orbsvcs/Fault_Notifier/.cvsignore new file mode 100644 index 00000000000..26f0ac494ac --- /dev/null +++ b/TAO/orbsvcs/Fault_Notifier/.cvsignore @@ -0,0 +1,4 @@ +*.dsp +*.dsw +Release +Debug diff --git a/TAO/orbsvcs/Fault_Notifier/FT_Notifier_i.cpp b/TAO/orbsvcs/Fault_Notifier/FT_Notifier_i.cpp new file mode 100644 index 00000000000..f561ca45bc9 --- /dev/null +++ b/TAO/orbsvcs/Fault_Notifier/FT_Notifier_i.cpp @@ -0,0 +1,763 @@ +// -*- C++ -*- +//============================================================================= +/** + * @file FT_FaultNotifier_i.cpp + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= + +#include "FT_Notifier_i.h" + +#include "ace/Get_Opt.h" +// Use this macro at the beginning of CORBA methods +// to aid in debugging. +#define METHOD_ENTRY(name) \ + if (TAO_debug_level > 6) \ + { \ + ACE_DEBUG (( LM_DEBUG, \ + "Enter %s\n", #name \ + )); \ + } + +// Use this macro to return from CORBA methods +// to aid in debugging. Note that you can specify +// the return value after the macro, for example: +// METHOD_RETURN(Plugh::plover) xyzzy; is equivalent +// to return xyzzy; +// METHOD_RETURN(Plugh::troll); is equivalent to +// return; +// WARNING: THIS GENERATES TWO STATEMENTS!!! THE FOLLOWING +// will not do what you want it to: +// if (cave_is_closing) METHOD_RETURN(Plugh::pirate) aarrggh; +// Moral: Always use braces. +#define METHOD_RETURN(name) \ + if (TAO_debug_level > 6) \ + { \ + ACE_DEBUG (( LM_DEBUG, \ + "Leave %s\n", #name \ + )); \ + } \ + return /* value goes here */ + + +// Implementation skeleton constructor +TAO::FT_FaultNotifier_i::FT_FaultNotifier_i () + : orb_ (0) + , poa_ (0) + , object_id_ (0) + , ior_output_file_(0) + , ns_name_(0) + , naming_context_ (0) + , this_name_ (1) + , rm_register_ (1) + , replication_manager_ (0) + , registered_ (0) + , identity_ ("") + , proxy_infos_ (0) + , consumer_connects_(0) + , consumer_disconnects_(0) + , notify_channel_ (0) + , filter_factory_ (0) + , supplier_admin_ (0) + , consumer_admin_ (0) + , structured_proxy_push_consumer_ (0) + , sequence_proxy_push_consumer_ (0) + , quit_on_idle_(0) + , quitting_(0) + , gone_(0) +{ +} + +// Implementation skeleton destructor +TAO::FT_FaultNotifier_i::~FT_FaultNotifier_i () +{ + fini (ACE_ENV_SINGLE_ARG_PARAMETER); +} + + +int TAO::FT_FaultNotifier_i::idle(int &result ACE_ENV_ARG_DECL) +{ + static unsigned long linger = 0; + ACE_UNUSED_ARG(result); + if (gone_) + { + if ( linger == 0) + { + ACE_ERROR ((LM_ERROR, + "FaultNotifier (%P|%t) Begin linger.\n" + )); + } + if(++linger > 5)//10) + { + ACE_ERROR ((LM_ERROR, + "FaultNotifier (%P|%t) idle returnning gone\n" + )); + } + else + { + return 0; + } + } + return this->gone_; +} + +//////////////////////////////////////////// +// FT_FaultNotifier_i private methods + + +// TODO: find this a common home +int TAO::FT_FaultNotifier_i::write_ior() +{ + int result = -1; + FILE* out = ACE_OS::fopen (this->ior_output_file_, "w"); + if (out) + { + ACE_OS::fprintf (out, "%s", ACE_static_cast(const char *, this->ior_)); + ACE_OS::fclose (out); + result = 0; + } + else + { + ACE_ERROR ((LM_ERROR, + "%T %n (%P|%t) Open failed for %s\n", ior_output_file_ + )); + } + return result; +} + +////////////////////////////////////////////////////// +// FT_FaultNotifier_i public, non-CORBA methods + +int TAO::FT_FaultNotifier_i::parse_args (int argc, char * argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "o:rq"); + int c; + + while ((c = get_opts ()) != -1) + { + switch (c) + { + case 'o': + { + this->ior_output_file_ = get_opts.opt_arg (); + break; + } + case 'r': + { + this->rm_register_ = ! this->rm_register_; + break; + } + case 'q': + { + this->quit_on_idle_ = 1; + break; + } + case '?': + // fall thru + default: + { + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s" + " -o <iorfile>" + " -r disable registration with ReplicationManager" + " -q(uit on idle)" + "\n", + argv [0]), + -1); + break; + } + } + } + // Indicates sucessful parsing of the command line + return 0; +} + +const char * TAO::FT_FaultNotifier_i::identity () const +{ + return this->identity_.c_str(); +} + +PortableServer::POA_ptr TAO::FT_FaultNotifier_i::_default_POA (ACE_ENV_SINGLE_ARG_DECL) +{ + return this->poa_.in(); +} + + +void TAO::FT_FaultNotifier_i::_remove_ref (ACE_ENV_SINGLE_ARG_DECL) +{ + notify_channel_->destroy(ACE_ENV_SINGLE_ARG_DECL); + ACE_CHECK; + + ACE_ERROR ((LM_ERROR, + "FaultNotifier (%P|%t) _remove_ref setting gone\n" + )); + this->gone_ = 1; +} + +int TAO::FT_FaultNotifier_i::fini (ACE_ENV_SINGLE_ARG_DECL) +{ + if (this->ior_output_file_ != 0) + { + ACE_OS::unlink (this->ior_output_file_); + this->ior_output_file_ = 0; + } + if (this->ns_name_ != 0 && this->naming_context_.in() != 0) + { + this->naming_context_->unbind (this_name_ + ACE_ENV_ARG_PARAMETER); + this->ns_name_ = 0; + } + + if (this->registered_) + { + ACE_TRY + { + this->replication_manager_->register_fault_notifier(::FT::FaultNotifier::_nil ()); + ACE_TRY_CHECK; + ACE_DEBUG ((LM_DEBUG, + "FaultNotifier unregistered from ReplicationManager.\n" + )); + } + ACE_CATCHANY + { + ACE_DEBUG ((LM_DEBUG, + "FaultNotifier Can't unregister from ReplicationManager.\n" + )); + // complain, but otherwise ignore this error + // RM may be down. + } + ACE_ENDTRY; + + this->registered_ = 0; + } + return 0; +} + +int TAO::FT_FaultNotifier_i::init (CORBA::ORB_ptr orb ACE_ENV_ARG_DECL ) +{ + int result = 0; + this->orb_ = CORBA::ORB::_duplicate (orb); + + // Use the ROOT POA for now + CORBA::Object_var poa_object = + this->orb_->resolve_initial_references (TAO_OBJID_ROOTPOA + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (CORBA::is_nil (poa_object.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT (" (%P|%t) Unable to initialize the POA.\n")), + -1); + + // Get the POA object. + this->poa_ = + PortableServer::POA::_narrow (poa_object.in () + ACE_ENV_ARG_PARAMETER); + + ACE_CHECK_RETURN (-1); + + if (CORBA::is_nil(this->poa_.in ())) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT (" (%P|%t) Unable to narrow the POA.\n")), + -1); + } + + PortableServer::POAManager_var poa_manager = + this->poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN(-1); + + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN(-1); + + // Register with the POA. + + this->object_id_ = this->poa_->activate_object (this ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(-1); + + // find my IOR + + CORBA::Object_var this_obj = + this->poa_->id_to_reference (object_id_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(-1); + + this->ior_ = this->orb_->object_to_string (this_obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(-1); + + + //////////////////////////////////////////////// + // Register with coresident Notification Channel + CosNotifyChannelAdmin::EventChannelFactory_var notify_factory = + TAO_Notify_EventChannelFactory_i::create (poa_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(-1); + CosNotification::QoSProperties initial_qos; + CosNotification::AdminProperties initial_admin; + this->notify_channel_ = + notify_factory->create_channel (initial_qos, + initial_admin, + channel_id_ + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(-1); + + this->filter_factory_ = this->notify_channel_->default_filter_factory (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN(-1); + + /////////////////////////// + // Producer registration + + this->supplier_admin_ = this->notify_channel_->default_supplier_admin (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN(-1); + + ::CosNotifyChannelAdmin::ProxyID proxyId = 0; + + ////////////////////// + // structured producer + ::CosNotifyChannelAdmin::ProxyConsumer_var consumer + = this->supplier_admin_->obtain_notification_push_consumer ( + ::CosNotifyChannelAdmin::STRUCTURED_EVENT, + proxyId + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(-1); + + structured_proxy_push_consumer_ + = ::CosNotifyChannelAdmin::StructuredProxyPushConsumer::_narrow(consumer.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(-1); + if (CORBA::is_nil (this->structured_proxy_push_consumer_.in ())) + { + ACE_ERROR_RETURN ((LM_ERROR, + "%T %n (%P|%t) Should not occur: Unable to narrow Structured Proxy Push Consumer\n"), + 1); + } + + // todo: implement a push supplier if we want to receive disconnect notice + CosNotifyComm::StructuredPushSupplier_var stubPushSupplier = + CosNotifyComm::StructuredPushSupplier::_nil(); + + this->structured_proxy_push_consumer_->connect_structured_push_supplier (stubPushSupplier.in() + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(-1); + + //////////////////// + // Sequence producer + consumer + = this->supplier_admin_->obtain_notification_push_consumer ( + ::CosNotifyChannelAdmin::SEQUENCE_EVENT, + proxyId + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + this->sequence_proxy_push_consumer_ + = ::CosNotifyChannelAdmin::SequenceProxyPushConsumer::_narrow(consumer.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + if (CORBA::is_nil (this->sequence_proxy_push_consumer_.in ())) + { + ACE_ERROR_RETURN ((LM_ERROR, + "%T %n (%P|%t) Should not occur: Unable to narrow Sequence Proxy Push Consumer\n"), + 1); + } + + // todo: implement this if we want to receive disconnect notice + CosNotifyComm::SequencePushSupplier_var stubSeqPushSupplier = + CosNotifyComm::SequencePushSupplier::_nil(); + + this->sequence_proxy_push_consumer_->connect_sequence_push_supplier (stubSeqPushSupplier.in() + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(-1); + /////////////////////////// + // Consumer registration + + // find the channel administrator for consumers + this->consumer_admin_ = this->notify_channel_->default_consumer_admin (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN(-1); + if (CORBA::is_nil (this->consumer_admin_.in ())) + { + ACE_ERROR ((LM_ERROR, + "%T %n (%P|%t) NIL consumer admin\n" + )); + result = -1; + } + // everything else happens when subscriber shows up + + /////////////////////////////// + // Register with ReplicationManager + if (this->rm_register_) + { + ACE_TRY_NEW_ENV + { + CORBA::Object_var rm_obj = orb->resolve_initial_references("ReplicationManager" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + this->replication_manager_ = ::FT::ReplicationManager::_narrow(rm_obj.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + if (!CORBA::is_nil (replication_manager_.in ())) + { + // @@: should we check to see if there's already one registered? + FT::FaultNotifier_var notifier = FT::FaultNotifier::_narrow (this_obj.in ()); + if (! CORBA::is_nil (notifier.in ())) + { + this->replication_manager_->register_fault_notifier(notifier.in ()); + ACE_DEBUG ((LM_DEBUG, + "FaultNotifier registered with ReplicationManager.\n" + )); + this->registered_ = 1; + } + else + { + ACE_ERROR ((LM_ERROR, + "Error: Registration failed. This is not a FaultNotifier (should not occur.)\n" + )); + } + } + else + { + ACE_ERROR ((LM_ERROR,"FaultNotifier: Can't resolve ReplicationManager, It will not be registered.\n" )); + } + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "FaultNotifier: Exception resolving ReplicationManager. Notifier will not be registered.\n" ); + } + ACE_ENDTRY; + } + else + { + ACE_DEBUG ((LM_DEBUG, + "FaultNotifier: ReplicationManager registration disabled.\n" + )); + } + /////////////////////////////// + // Set up and ready for action + // publish our IOR + + if(result == 0) + { + if (this->ior_output_file_ != 0) + { + this->identity_ = "file:"; + this->identity_ += this->ior_output_file_; + result = write_ior(); + } + } + + if (result == 0) + { + if (this->ns_name_ != 0) + { + this->identity_ = "name:"; + this->identity_ += this->ns_name_; + + CORBA::Object_var naming_obj = + this->orb_->resolve_initial_references ("NameService" ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (CORBA::is_nil(naming_obj.in ())){ + ACE_ERROR_RETURN ((LM_ERROR, + "%T %n (%P|%t) Unable to find the Naming Service\n"), + 1); + } + + this->naming_context_ = + CosNaming::NamingContext::_narrow (naming_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + if (CORBA::is_nil(this->naming_context_.in ())) + { + ACE_ERROR_RETURN ((LM_ERROR, + "%T %n (%P|%t) Should not occur: Can't narrow initial reference to naming context.\n"), + 1); + } + this->this_name_.length (1); + this->this_name_[0].id = CORBA::string_dup (this->ns_name_); + + this->naming_context_->rebind (this->this_name_, this_obj.in() //CORBA::Object::_duplicate(this_obj) + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + } + } + + return result; +} + +/////////////////// +// CORBA METHODS + +void TAO::FT_FaultNotifier_i::push_structured_fault ( + const CosNotification::StructuredEvent & event + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + METHOD_ENTRY(TAO::FT_FaultNotifier_i::push_structured_fault); + + this->structured_proxy_push_consumer_->push_structured_event (event + ACE_ENV_ARG_PARAMETER); + + METHOD_RETURN(TAO::FT_FaultNotifier_i::push_structured_fault); +} + +void TAO::FT_FaultNotifier_i::push_sequence_fault ( + const CosNotification::EventBatch & events + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + METHOD_ENTRY(TAO::FT_FaultNotifier_i::push_sequence_fault); + + this->sequence_proxy_push_consumer_->push_structured_events (events + ACE_ENV_ARG_PARAMETER); + + METHOD_RETURN(TAO::FT_FaultNotifier_i::push_sequence_fault); +} + +::CosNotifyFilter::Filter_ptr TAO::FT_FaultNotifier_i::create_subscription_filter ( + const char * constraint_grammar + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException, CosNotifyFilter::InvalidGrammar)) +{ + METHOD_ENTRY(TAO::FT_FaultNotifier_i::create_subscription_filter); + ACE_UNUSED_ARG (constraint_grammar); //@@todo + + CosNotifyFilter::Filter_var filter = this->filter_factory_->create_filter ("ETCL"); + METHOD_RETURN(TAO::FT_FaultNotifier_i::create_subscription_filter) + filter._retn (); +} + +FT::FaultNotifier::ConsumerId TAO::FT_FaultNotifier_i::connect_structured_fault_consumer ( + CosNotifyComm::StructuredPushConsumer_ptr push_consumer, + CosNotifyFilter::Filter_ptr filter + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + METHOD_ENTRY(TAO::FT_FaultNotifier_i::connect_structured_fault_consumer); + + ///////////////////////// + // find a ProxyInfo entry + // use the first nil entry or a new entry if no nils found + + size_t infoPos = 0; + int looking = 1; + for ( size_t pos = 0; looking && pos < this->proxy_infos_.size (); ++pos) + { + ProxyInfo & pi = this->proxy_infos_[pos]; + if (CORBA::is_nil(pi.proxyVar_.in ())) + { + infoPos = pos; + looking = 0; + } + } + if (looking) + { + infoPos = this->proxy_infos_.size(); + this->proxy_infos_.push_back(ProxyInfo()); + } + + /////////////////////////////////////// + // Assign an ID, populate the ProxyInfo + FT::FaultNotifier::ConsumerId result = infoPos; + ProxyInfo & info = this->proxy_infos_[infoPos]; + info.proxyVar_ + = this->consumer_admin_->obtain_notification_push_supplier ( + ::CosNotifyChannelAdmin::STRUCTURED_EVENT, + info.proxyId_ + ACE_ENV_ARG_PARAMETER); + + this->consumer_connects_ += 1; + + ::CosNotifyChannelAdmin::StructuredProxyPushSupplier_var proxySupplier + = ::CosNotifyChannelAdmin::StructuredProxyPushSupplier::_narrow(info.proxyVar_.in () + ACE_ENV_ARG_PARAMETER); + + if ( CORBA::is_nil (proxySupplier.in ())) + { + // this is a shoould-not-occur situation. The consumer admin returned + // the wrong kind of object. + ACE_ERROR(( LM_ERROR, + "%T %n (%P|%t) Unexpected result: Wrong type of object returned from obtain_notification_push_supplier\n" + )); + } + else + { + proxySupplier->connect_structured_push_consumer ( push_consumer + ACE_ENV_ARG_PARAMETER); + + if (! CORBA::is_nil (filter)) + { + proxySupplier->add_filter(filter); + } + } + + METHOD_RETURN(TAO::FT_FaultNotifier_i::connect_structured_fault_consumer) result; +} + +FT::FaultNotifier::ConsumerId TAO::FT_FaultNotifier_i::connect_sequence_fault_consumer ( + CosNotifyComm::SequencePushConsumer_ptr push_consumer, + CosNotifyFilter::Filter_ptr filter + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + METHOD_ENTRY(TAO::FT_FaultNotifier_i::connect_sequence_fault_consumer); + ///////////////////////// + // find a ProxyInfo entry + // use the first nil entry or a new entry if no nils found + + size_t infoPos = 0; + int looking = 1; + for ( size_t pos = 0; looking && pos < this->proxy_infos_.size (); ++pos) + { + ProxyInfo & pi = this->proxy_infos_[pos]; + if (CORBA::is_nil(pi.proxyVar_.in ())) + { + infoPos = pos; + looking = 0; + } + } + if (looking) + { + infoPos = this->proxy_infos_.size(); + this->proxy_infos_.push_back(ProxyInfo()); + } + + /////////////////////////////////////// + // Assign an ID, populate the ProxyInfo + FT::FaultNotifier::ConsumerId result = infoPos; + ProxyInfo & info = this->proxy_infos_[infoPos]; + info.proxyVar_ + = this->consumer_admin_->obtain_notification_push_supplier ( + ::CosNotifyChannelAdmin::SEQUENCE_EVENT, + info.proxyId_ + ACE_ENV_ARG_PARAMETER); + + this->consumer_connects_ += 1; + + ::CosNotifyChannelAdmin::SequenceProxyPushSupplier_var proxySupplier + = ::CosNotifyChannelAdmin::SequenceProxyPushSupplier::_narrow(info.proxyVar_.in () + ACE_ENV_ARG_PARAMETER); + if ( CORBA::is_nil (proxySupplier.in ())) + { + // this is a shoould-not-occur situation. The consumer admin returned + // the wrong kind of object. + ACE_ERROR(( LM_ERROR, + "%T %n (%P|%t) Unexpected result: Wrong type of object returned from obtain_notification_push_supplier\n" + )); + } + else + { + proxySupplier->connect_sequence_push_consumer ( push_consumer + ACE_ENV_ARG_PARAMETER); + + if (! CORBA::is_nil (filter)) + { + proxySupplier->add_filter(filter); + } + } + METHOD_RETURN(TAO::FT_FaultNotifier_i::connect_sequence_fault_consumer) result; +} + +void TAO::FT_FaultNotifier_i::disconnect_consumer ( + FT::FaultNotifier::ConsumerId connection + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException, CosEventComm::Disconnected)) +{ + METHOD_ENTRY(TAO::FT_FaultNotifier_i::disconnect_consumer); + + size_t index = ACE_static_cast ( size_t, connection); + if (index < this->proxy_infos_.size()) + { + ProxyInfo & info = this->proxy_infos_[index]; + if (CORBA::is_nil(info.proxyVar_.in ()) ) + { + ACE_THROW(CosEventComm::Disconnected()); + } + else + { + ::CosNotifyChannelAdmin::StructuredProxyPushSupplier_var proxySupplier + = ::CosNotifyChannelAdmin::StructuredProxyPushSupplier::_narrow(info.proxyVar_.in () + ACE_ENV_ARG_PARAMETER); + if (! CORBA::is_nil (proxySupplier.in ())) + { + proxySupplier->disconnect_structured_push_supplier (); + info.proxyVar_ = ::CosNotifyChannelAdmin::ProxySupplier::_nil(); + } + else + { + ::CosNotifyChannelAdmin::SequenceProxyPushSupplier_var proxySupplier + = ::CosNotifyChannelAdmin::SequenceProxyPushSupplier::_narrow(info.proxyVar_.in () + ACE_ENV_ARG_PARAMETER); + if (! CORBA::is_nil (proxySupplier.in ())) + { + proxySupplier->disconnect_sequence_push_supplier (); + info.proxyVar_ = ::CosNotifyChannelAdmin::ProxySupplier::_nil(); + } + else + { + ACE_ERROR((LM_ERROR, + "%T %n (%P|%t) Unexpected proxy supplier type\n" + )); + ACE_THROW(CosEventComm::Disconnected()); + } + } + } + } + else + { + ACE_THROW(CosEventComm::Disconnected()); + } + + this->consumer_disconnects_ += 1; + if (this->quit_on_idle_) + { + if (! this->quitting_ + && this->consumer_connects_ == this->consumer_disconnects_) + { + ACE_ERROR((LM_ERROR, + "FaultNotifier (%P|%t) quit on idle: connects %d, disconnects %d\n", + ACE_static_cast (unsigned int, this->consumer_connects_), + ACE_static_cast (unsigned int, this->consumer_disconnects_) + )); + this->poa_->deactivate_object (this->object_id_.in () + ACE_ENV_ARG_PARAMETER); + this->quitting_ = 1; + } + } + + METHOD_RETURN(TAO::FT_FaultNotifier_i::disconnect_consumer); +} + +CORBA::Boolean TAO::FT_FaultNotifier_i::is_alive (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + METHOD_RETURN(TAO::FT_FaultNotifier_i::is_alive) 1; +} + +////////////// +// ProxyInfo + +TAO::FT_FaultNotifier_i::ProxyInfo::ProxyInfo () + : proxyId_ (0) + , proxyVar_ (::CosNotifyChannelAdmin::ProxySupplier::_nil()) +{ +} + +TAO::FT_FaultNotifier_i::ProxyInfo::ProxyInfo (const ProxyInfo & rhs) + : proxyId_ (rhs.proxyId_) + , proxyVar_ (rhs.proxyVar_) +{ +} +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + template class ACE_Guard<ACE_SYNCH_MUTEX>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +# pragma instantiate ACE_Guard<ACE_SYNCH_MUTEX> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/Fault_Notifier/FT_Notifier_i.h b/TAO/orbsvcs/Fault_Notifier/FT_Notifier_i.h new file mode 100644 index 00000000000..4c11a315af7 --- /dev/null +++ b/TAO/orbsvcs/Fault_Notifier/FT_Notifier_i.h @@ -0,0 +1,276 @@ +// -*- C++ -*- +// +// $Id$ +//============================================================================= +/** + * @file Fault_Notifier_i.h + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * This file declares the Fault_Notifier_i class. + * A FaultNotifer is a subset of a notification channel. It allows interested + * parties to subscribe to fault notifications. The most likely interested party + * is the ReplicationManager. + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= + +#ifndef TAO_FT_NOTIFIER_I_H_ +#define TAO_FT_NOTIFIER_I_H_ +#include /**/ "ace/pre.h" +#include "ace/ACE.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +////////////////////////////////// +// Classes declared in this header +namespace TAO +{ + class FT_FaultNotifier_i; +} + + +#include <orbsvcs/FT_NotifierS.h> +#include <orbsvcs/FT_ReplicationManagerC.h> +#include <orbsvcs/Notify/Notify_EventChannelFactory_i.h> +#include <ace/Vector_T.h> + +///////////////////// +// Forward references + +namespace TAO +{ + class FT_FaultNotifier_i : public virtual POA_FT::FaultNotifier + { + ////////////////////// + // non-CORBA interface + public: + /** + * Default constructor. + */ + FT_FaultNotifier_i (); + + /** + * Virtual destructor. + */ + virtual ~FT_FaultNotifier_i (); + + + /** + * Parse command line arguments. + * @param argc traditional C argc + * @param argv traditional C argv + * @return zero for success; nonzero is process return code for failure. + */ + int parse_args (int argc, char * argv[]); + + /** + * Initialize this object. + * @param orbManager our ORB -- we keep var to it. + * @return zero for success; nonzero is process return code for failure. + */ + int init (CORBA::ORB_ptr orb ACE_ENV_ARG_DECL); + + /** + * Prepare to exit + * @return zero for success; nonzero is process return code for failure. + */ + int fini (ACE_ENV_SINGLE_ARG_DECL); + + /** + * Identify this fault notifier. + * @return a string to identify this object for logging/console message purposes. + */ + const char * identity () const; + + /** + * idle time activity. + * @param result [out] status code to return from process + * @returns 0 to continue; nonzero to quit + */ + int idle(int &result ACE_ENV_ARG_DECL); + + ////////////////// + // CORBA interface + // See IDL for documentation + + virtual void push_structured_fault ( + const CosNotification::StructuredEvent & event + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void push_sequence_fault ( + const CosNotification::EventBatch & events + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual ::CosNotifyFilter::Filter_ptr create_subscription_filter ( + const char * constraint_grammar + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException, CosNotifyFilter::InvalidGrammar)); + + virtual FT::FaultNotifier::ConsumerId connect_structured_fault_consumer ( + CosNotifyComm::StructuredPushConsumer_ptr push_consumer, + CosNotifyFilter::Filter_ptr filter + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual FT::FaultNotifier::ConsumerId connect_sequence_fault_consumer ( + CosNotifyComm::SequencePushConsumer_ptr push_consumer, + CosNotifyFilter::Filter_ptr filter + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void disconnect_consumer ( + FT::FaultNotifier::ConsumerId connection + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException, CosEventComm::Disconnected)); + + ////////////////////////////////////////// + // CORBA interface PullMonitorable methods + virtual CORBA::Boolean is_alive (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + + + ///////////////////////////////////////// + // Override CORBA servant virtual methods + virtual PortableServer::POA_ptr _default_POA (ACE_ENV_SINGLE_ARG_DECL); + + virtual void _remove_ref (ACE_ENV_SINGLE_ARG_DECL); + + ///////////////////////// + // Implementation methods + private: + /** + * Write this notifier's IOR to a file + */ + int write_ior (); + + /////////////// + // Data Members + private: + + /** + * Protect internal state. + * Mutex should be locked by corba methods, or by + * external (public) methods before calling implementation + * methods. + * Implementation methods should assume the mutex is + * locked if necessary. + */ + ACE_SYNCH_MUTEX internals_; + typedef ACE_Guard<ACE_SYNCH_MUTEX> InternalGuard; + + /** + * The orb + */ + CORBA::ORB_var orb_; + + /** + * The POA used to activate this object. + */ + PortableServer::POA_var poa_; + + /** + * The CORBA object id assigned to this object. + */ + PortableServer::ObjectId_var object_id_; + + + /** + * IOR of this object as assigned by orb. + */ + CORBA::String_var ior_; + + /** + * A file to which the notifier's IOR should be written. + */ + const char * ior_output_file_; + + /** + * A name to be used to register the notifier with the name service. + */ + const char * ns_name_; + + CosNaming::NamingContext_var naming_context_; + + CosNaming::Name this_name_; + + /** + * bool: if true, register with ReplicationManager. + * default is true. -r turns it off. + */ + int rm_register_; + + /** + * the replication manager + */ + ::FT::ReplicationManager_var replication_manager_; + + /** + * bool: if true the registration with ReplicationManager was successful. + */ + int registered_; + + /** + * A human-readable string to distinguish this from other Notifiers. + */ + ACE_CString identity_; + + ///////////////////////////// + // + struct ProxyInfo + { + ::CosNotifyChannelAdmin::ProxyID proxyId_; + ::CosNotifyChannelAdmin::ProxySupplier_var proxyVar_; + + ProxyInfo (); + ProxyInfo (const ProxyInfo & rhs); + }; + + typedef ACE_Vector <ProxyInfo> ProxyInfoVec; + + ProxyInfoVec proxy_infos_; + + size_t consumer_connects_; + size_t consumer_disconnects_; + + ::CosNotifyChannelAdmin::ChannelID channel_id_; + ::CosNotifyChannelAdmin::EventChannel_var notify_channel_; + ::CosNotifyFilter::FilterFactory_var filter_factory_; + ::CosNotifyChannelAdmin::SupplierAdmin_var supplier_admin_; + ::CosNotifyChannelAdmin::ConsumerAdmin_var consumer_admin_; + + ::CosNotifyChannelAdmin::StructuredProxyPushConsumer_var structured_proxy_push_consumer_; + ::CosNotifyChannelAdmin::SequenceProxyPushConsumer_var sequence_proxy_push_consumer_; + + /* + * boolean quit when all consumers disconnect + */ + int quit_on_idle_; + + /** + * boolean: set true we've asked CORBA to deactivate + */ + int quitting_; + + /** + * boolean: set true when CORBA is done with this object. + */ + int gone_; + + }; +} // namespace TAO +#include /**/ "ace/post.h" + +#endif /* TAO_FT_NOTIFIER_I_H_ */ diff --git a/TAO/orbsvcs/Fault_Notifier/Fault_Notifier.mpc b/TAO/orbsvcs/Fault_Notifier/Fault_Notifier.mpc new file mode 100644 index 00000000000..750159d37ab --- /dev/null +++ b/TAO/orbsvcs/Fault_Notifier/Fault_Notifier.mpc @@ -0,0 +1,7 @@ +project : taoserver, orbsvcsexe, fault_tolerance, notification { + exename = Fault_Notifier + Source_Files { + FT_Notifier_i.cpp + Fault_Notifier_Main.cpp + } +} diff --git a/TAO/orbsvcs/Fault_Notifier/Fault_Notifier_Main.cpp b/TAO/orbsvcs/Fault_Notifier/Fault_Notifier_Main.cpp new file mode 100644 index 00000000000..3158b4bb20a --- /dev/null +++ b/TAO/orbsvcs/Fault_Notifier/Fault_Notifier_Main.cpp @@ -0,0 +1,37 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FaultNotifierMain.cpp + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * This file provides the main routine for a process that + * implements the FaultNotifier interface and manages + * a set of FaultNotifiers. + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= + +#include <tao/Utils/Server_Main.h> +#include "FT_Notifier_i.h" + +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + TAO::Utils::Server_Main<TAO::FT_FaultNotifier_i> server_main("TAO_FaultNotifier"); + return server_main.run(argc, argv); +} + +/////////////////////////////////// +// Template instantiation for +// inept compilers. + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + template class TAO::Utils::Server_Main<TAO::FT_FaultNotifier_i>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +# pragma instantiate TAO::Utils::Server_Main<TAO::FT_FaultNotifier_i> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ + + + diff --git a/TAO/orbsvcs/LoadBalancer/LoadBalancer.mpc b/TAO/orbsvcs/LoadBalancer/LoadBalancer.mpc index 1d7c4304b8f..e2139517b45 100644 --- a/TAO/orbsvcs/LoadBalancer/LoadBalancer.mpc +++ b/TAO/orbsvcs/LoadBalancer/LoadBalancer.mpc @@ -1,4 +1,4 @@ -project(CosLoadManager): namingexe, portableserver, core, loadbalancing { +project(CosLoadManager): namingexe, portableserver, core, iormanip, loadbalancing { requires += ami interceptors Source_Files { LoadManager.cpp diff --git a/TAO/orbsvcs/examples/FaultTolerance/Makefile b/TAO/orbsvcs/examples/FaultTolerance/Makefile new file mode 100644 index 00000000000..9d53bfd86fa --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/Makefile @@ -0,0 +1,26 @@ +#---------------------------------------------------------------------------- +# +# $Id$ +# +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +DIRS = RolyPoly + +ifndef TAO_ROOT + TAO_ROOT = $(ACE_ROOT)/TAO +endif + +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(ACE_ROOT)/include/makeinclude/macros.GNU +include $(TAO_ROOT)/rules.tao.GNU +include $(ACE_ROOT)/include/makeinclude/rules.common.GNU +include $(ACE_ROOT)/include/makeinclude/rules.nested.GNU +include $(ACE_ROOT)/include/makeinclude/rules.nolocal.GNU diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/CrashPoint.cpp b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/CrashPoint.cpp new file mode 100644 index 00000000000..19fed3a32ea --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/CrashPoint.cpp @@ -0,0 +1,7 @@ +// file : RolyPoly/CrashPoint.cpp +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#include "CrashPoint.h" + +short crash_point = 0; diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/CrashPoint.h b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/CrashPoint.h new file mode 100644 index 00000000000..69f2e1a0044 --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/CrashPoint.h @@ -0,0 +1,19 @@ +// file : RolyPoly/CrashPoint.h +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#ifndef CRASH_POINT_H +#define CRASH_POINT_H + +// Valid crash-point values: +// +// 0 no crash (default) +// +// 1 crash before logging the reply +// +// 2 crash after logging the reply but before replying to the client +// + +extern short crash_point; + +#endif // CRASH_POINT_H diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/Log.h b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/Log.h new file mode 100644 index 00000000000..a83d966dd69 --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/Log.h @@ -0,0 +1,10 @@ +// file : RolyPoly/Log.h +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#ifndef LOG_HPP +#define LOG_HPP + +#include "LogACE_RB_Tree.h" + +#endif // LOG_HPP diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/LogACE_RB_Tree.h b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/LogACE_RB_Tree.h new file mode 100644 index 00000000000..9b54d353315 --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/LogACE_RB_Tree.h @@ -0,0 +1,66 @@ +// file : RolyPoly/LogACE_RB_Tree.h +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#ifndef LOG_ACE_RB_TREE_H +#define LOG_ACE_RB_TREE_H + +#include <ace/RB_Tree.h> +#include <ace/Synch.h> + +template <typename RI, typename RV> +class Log +{ +public: + typedef RI RecordIdType; + typedef RV RecordValueType; + +private: + typedef + ACE_RB_Tree <RecordIdType, + RecordValueType, + ACE_Less_Than<RecordIdType>, + ACE_Null_Mutex> + Map_; + +public: + class Duplicate {}; + class NotFound {}; + + void + insert (RecordIdType const& ri, RecordValueType const& rv) + throw (Duplicate) + { + if (map_.bind (ri, rv) != 0) throw Duplicate (); + } + + bool + contains (RecordIdType const& ri) const + { + // Guess what: ACE_RB_Tree::find() is not const. + // + Map_& m = const_cast<Map_&> (map_); + + RecordValueType tmp; + + return m.find (ri, tmp) == 0; + } + + + RecordValueType const& + lookup (RecordIdType const& ri) const throw (NotFound) + { + Map_& m = const_cast<Map_&> (map_); + + typename Map_::ENTRY* entry; + + if (m.find (ri, entry) != 0) throw NotFound (); + + return entry->item (); + } + +private: + Map_ map_; +}; + +#endif // LOG_ACE_RB_TREE_H diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/LogStdMap.h b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/LogStdMap.h new file mode 100644 index 00000000000..29a5ff2be65 --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/LogStdMap.h @@ -0,0 +1,56 @@ +// file : RolyPoly/LogStdMap.h +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#ifndef LOG_STD_MAP_H +#define LOG_STD_MAP_H + +#include <map> + +template <typename RI, typename RV> +class Log +{ +public: + typedef RI RecordIdType; + typedef RV RecordValueType; + +private: + typedef + std::map <RecordIdType, RecordValueType> + Map_; + +public: + class Duplicate {}; + class NotFound {}; + + void + insert (RecordIdType const& ri, RecordValueType const& rv) + throw (Duplicate) + { + if (!map_.insert (std::make_pair (ri, rv)).second) + { + throw Duplicate (); + } + } + + bool + contains (RecordIdType const& ri) const + { + return map_.count (ri) != 0; + } + + + RecordValueType const& + lookup (RecordIdType const& ri) const throw (NotFound) + { + typename Map_::const_iterator i = map_.find (ri); + + if (i != map_.end ()) return i->second; + else throw NotFound (); + } + +private: + Map_ map_; +}; + +#endif // LOG_STD_MAP_H diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/Makefile b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/Makefile new file mode 100644 index 00000000000..ca15af36716 --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/Makefile @@ -0,0 +1,2648 @@ +#---------------------------------------------------------------------------- +# +# $Id$ +# +#---------------------------------------------------------------------------- + +#---------------------------------------------------------------------------- +# Local macros +#---------------------------------------------------------------------------- + +ifndef TAO_ROOT + TAO_ROOT = $(ACE_ROOT)/TAO +endif # ! TAO_ROOT + +IDL_FILES = RolyPoly +IDL_SRC = RolyPolyC.cpp RolyPolyS.cpp +BIN_UNCHECKED = client server + +SRC = $(addsuffix .cpp, $(BIN_UNCHECKED) CrashPoint RolyPoly_i ReplicaController ORB_Initializer) $(IDL_SRC) + +CLIENT_OBJS = client.o RolyPolyC.o +SERVER_OBJS = server.o RolyPoly_i.o ORB_Initializer.o ReplicaController.o CrashPoint.o $(IDL_SRC:.cpp=.o) + +TAO_IDLFLAGS += -Ge 1 +#---------------------------------------------------------------------------- +# Include macros and targets +#---------------------------------------------------------------------------- + +include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU +include $(ACE_ROOT)/include/makeinclude/macros.GNU +include $(TAO_ROOT)/rules.tao.GNU +ifeq ($(interceptors),1) + BIN=$(BIN_UNCHECKED) +endif #interceptors +include $(ACE_ROOT)/include/makeinclude/rules.common.GNU +include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU +include $(ACE_ROOT)/include/makeinclude/rules.local.GNU +include $(TAO_ROOT)/taoconfig.mk + +CPPFLAGS += -I$(TAO_ROOT)/orbsvcs + +TAO_CLNT_LIBS += -lTAO_FTORB -lTAO_Messaging +TAO_SRVR_LIBS += -lTAO_Messaging -lTMCast + +#---------------------------------------------------------------------------- +# Local targets +#---------------------------------------------------------------------------- + +.PRECIOUS: $(foreach ext, $(IDL_EXT), Test$(ext)) + +server: $(addprefix $(VDIR),$(SERVER_OBJS)) + $(LINK.cc) $(LDFLAGS) -o $@ $^ $(TAO_SRVR_LIBS) $(POSTLINK) + +client: $(addprefix $(VDIR),$(CLIENT_OBJS)) + $(LINK.cc) $(LDFLAGS) -o $@ $^ $(TAO_CLNT_LIBS) $(POSTLINK) + +realclean: clean + -$(RM) $(foreach ext, $(IDL_EXT), test$(ext)) + +# DO NOT DELETE THIS LINE -- g++dep uses it. +# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY. + + +.obj/client.o .obj/client.so .shobj/client.o .shobj/client.so: client.cpp $(ACE_ROOT)/ace/Get_Opt.h \ + $(ACE_ROOT)/ace/pre.h \ + $(ACE_ROOT)/ace/SStringfwd.h \ + $(ACE_ROOT)/ace/Basic_Types.h \ + $(ACE_ROOT)/ace/post.h \ + $(ACE_ROOT)/ace/ace_wchar.h \ + $(ACE_ROOT)/ace/ace_wchar.inl \ + $(ACE_ROOT)/ace/os_include/os_limits.h \ + $(ACE_ROOT)/ace/os_include/os_unistd.h \ + $(ACE_ROOT)/ace/os_include/sys/os_types.h \ + $(ACE_ROOT)/ace/os_include/os_stddef.h \ + $(ACE_ROOT)/ace/os_include/os_inttypes.h \ + $(ACE_ROOT)/ace/os_include/os_stdint.h \ + $(ACE_ROOT)/ace/os_include/os_stdio.h \ + $(ACE_ROOT)/ace/os_include/os_stdarg.h \ + $(ACE_ROOT)/ace/os_include/os_float.h \ + $(ACE_ROOT)/ace/os_include/os_stdlib.h \ + $(ACE_ROOT)/ace/os_include/sys/os_wait.h \ + $(ACE_ROOT)/ace/os_include/os_signal.h \ + $(ACE_ROOT)/ace/os_include/os_time.h \ + $(ACE_ROOT)/ace/os_include/os_ucontext.h \ + $(ACE_ROOT)/ace/os_include/sys/os_resource.h \ + $(ACE_ROOT)/ace/os_include/sys/os_time.h \ + $(ACE_ROOT)/ace/os_include/sys/os_select.h \ + $(ACE_ROOT)/ace/ACE_export.h \ + $(ACE_ROOT)/ace/Basic_Types.i \ + $(ACE_ROOT)/ace/Containers.h \ + $(ACE_ROOT)/ace/Containers.i \ + $(ACE_ROOT)/ace/Containers_T.h \ + $(ACE_ROOT)/ace/Node.h \ + $(ACE_ROOT)/ace/Node.cpp \ + $(ACE_ROOT)/ace/Array_Base.h \ + $(ACE_ROOT)/ace/Global_Macros.h \ + $(ACE_ROOT)/ace/OS_Export.h \ + $(ACE_ROOT)/ace/Malloc_Base.h \ + $(ACE_ROOT)/ace/os_include/sys/os_mman.h \ + $(ACE_ROOT)/ace/Array_Base.inl \ + $(ACE_ROOT)/ace/Array_Base.cpp \ + $(ACE_ROOT)/ace/os_include/os_errno.h \ + $(ACE_ROOT)/ace/Unbounded_Set.h \ + $(ACE_ROOT)/ace/Unbounded_Set.inl \ + $(ACE_ROOT)/ace/Unbounded_Set.cpp \ + $(ACE_ROOT)/ace/Log_Msg.h \ + $(ACE_ROOT)/ace/Default_Constants.h \ + $(ACE_ROOT)/ace/Log_Priority.h \ + $(ACE_ROOT)/ace/OS_Log_Msg_Attributes.h \ + $(ACE_ROOT)/ace/iosfwd.h \ + $(ACE_ROOT)/ace/OS_Log_Msg_Attributes.inl \ + $(ACE_ROOT)/ace/Unbounded_Queue.h \ + $(ACE_ROOT)/ace/Unbounded_Queue.inl \ + $(ACE_ROOT)/ace/Unbounded_Queue.cpp \ + $(ACE_ROOT)/ace/Containers_T.i \ + $(ACE_ROOT)/ace/Containers_T.cpp \ + $(ACE_ROOT)/ace/OS_Memory.h \ + $(ACE_ROOT)/ace/OS_Errno.h \ + $(ACE_ROOT)/ace/OS_Errno.inl \ + $(ACE_ROOT)/ace/OS_Memory.inl \ + $(ACE_ROOT)/ace/Get_Opt.i \ + $(TAO_ROOT)/tao/IORManipulation/IORManip_Loader.h \ + $(TAO_ROOT)/tao/IORManipulation/ior_manip_export.h \ + $(TAO_ROOT)/tao/Object_Loader.h \ + $(TAO_ROOT)/tao/Exception.h \ + $(TAO_ROOT)/tao/corbafwd.h \ + $(ACE_ROOT)/ace/CDR_Base.h \ + $(ACE_ROOT)/ace/CDR_Base.inl \ + $(TAO_ROOT)/tao/orbconf.h \ + $(ACE_ROOT)/ace/Synch_Traits.h \ + $(ACE_ROOT)/ace/Lock.h \ + $(ACE_ROOT)/ace/Lock.inl \ + $(TAO_ROOT)/tao/TAO_Export.h \ + $(TAO_ROOT)/tao/corbafwd.i \ + $(ACE_ROOT)/ace/CORBA_macros.h \ + $(ACE_ROOT)/ace/Exception_Macros.h \ + $(TAO_ROOT)/tao/Exception.i \ + $(ACE_ROOT)/ace/Service_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.i \ + $(ACE_ROOT)/ace/Svc_Conf_Tokens.h \ + $(ACE_ROOT)/ace/Event_Handler.h \ + $(ACE_ROOT)/ace/Atomic_Op.h \ + $(ACE_ROOT)/ace/Thread_Mutex.h \ + $(ACE_ROOT)/ace/OS.h \ + $(ACE_ROOT)/ace/OS_Dirent.h \ + $(ACE_ROOT)/ace/os_include/os_dirent.h \ + $(ACE_ROOT)/ace/OS_Dirent.inl \ + $(ACE_ROOT)/ace/OS_String.h \ + $(ACE_ROOT)/ace/OS_String.inl \ + $(ACE_ROOT)/ace/os_include/os_string.h \ + $(ACE_ROOT)/ace/os_include/os_strings.h \ + $(ACE_ROOT)/ace/os_include/os_ctype.h \ + $(ACE_ROOT)/ace/OS_TLI.h \ + $(ACE_ROOT)/ace/OS_TLI.inl \ + $(ACE_ROOT)/ace/os_include/os_dlfcn.h \ + $(ACE_ROOT)/ace/os_include/os_netdb.h \ + $(ACE_ROOT)/ace/os_include/netinet/os_in.h \ + $(ACE_ROOT)/ace/os_include/sys/os_socket.h \ + $(ACE_ROOT)/ace/os_include/sys/os_uio.h \ + $(ACE_ROOT)/ace/os_include/net/os_if.h \ + $(ACE_ROOT)/ace/os_include/sys/os_sem.h \ + $(ACE_ROOT)/ace/os_include/sys/os_ipc.h \ + $(ACE_ROOT)/ace/Time_Value.h \ + $(ACE_ROOT)/ace/Time_Value.inl \ + $(ACE_ROOT)/ace/Min_Max.h \ + $(ACE_ROOT)/ace/os_include/os_pthread.h \ + $(ACE_ROOT)/ace/os_include/os_assert.h \ + $(ACE_ROOT)/ace/os_include/os_fcntl.h \ + $(ACE_ROOT)/ace/os_include/sys/os_stat.h \ + $(ACE_ROOT)/ace/os_include/arpa/os_inet.h \ + $(ACE_ROOT)/ace/os_include/netinet/os_tcp.h \ + $(ACE_ROOT)/ace/os_include/sys/os_shm.h \ + $(ACE_ROOT)/ace/os_include/os_pwd.h \ + $(ACE_ROOT)/ace/os_include/os_stropts.h \ + $(ACE_ROOT)/ace/os_include/os_termios.h \ + $(ACE_ROOT)/ace/os_include/os_aio.h \ + $(ACE_ROOT)/ace/os_include/sys/os_un.h \ + $(ACE_ROOT)/ace/os_include/os_poll.h \ + $(ACE_ROOT)/ace/os_include/sys/os_msg.h \ + $(ACE_ROOT)/ace/os_include/sys/os_utsname.h \ + $(ACE_ROOT)/ace/os_include/os_syslog.h \ + $(ACE_ROOT)/ace/OS.i \ + $(ACE_ROOT)/ace/Thread_Mutex.inl \ + $(ACE_ROOT)/ace/Atomic_Op_T.h \ + $(ACE_ROOT)/ace/Atomic_Op_T.i \ + $(ACE_ROOT)/ace/Guard_T.h \ + $(ACE_ROOT)/ace/Guard_T.inl \ + $(ACE_ROOT)/ace/Guard_T.cpp \ + $(ACE_ROOT)/ace/Atomic_Op_T.cpp \ + $(ACE_ROOT)/ace/Atomic_Op.i \ + $(ACE_ROOT)/ace/Event_Handler.i \ + $(ACE_ROOT)/ace/DLL.h \ + $(ACE_ROOT)/ace/Service_Object.i \ + $(TAO_ROOT)/tao/Object_Loader.i \ + $(ACE_ROOT)/ace/Service_Config.h \ + $(ACE_ROOT)/ace/SString.h \ + $(ACE_ROOT)/ace/String_Base.h \ + $(ACE_ROOT)/ace/String_Base_Const.h \ + $(ACE_ROOT)/ace/String_Base.i \ + $(ACE_ROOT)/ace/String_Base.cpp \ + $(ACE_ROOT)/ace/ACE.h \ + $(ACE_ROOT)/ace/Flag_Manip.h \ + $(ACE_ROOT)/ace/Flag_Manip.i \ + $(ACE_ROOT)/ace/Handle_Ops.h \ + $(ACE_ROOT)/ace/Handle_Ops.i \ + $(ACE_ROOT)/ace/Lib_Find.h \ + $(ACE_ROOT)/ace/Lib_Find.i \ + $(ACE_ROOT)/ace/Init_ACE.h \ + $(ACE_ROOT)/ace/Init_ACE.i \ + $(ACE_ROOT)/ace/Sock_Connect.h \ + $(ACE_ROOT)/ace/Sock_Connect.i \ + $(ACE_ROOT)/ace/ACE.i \ + $(ACE_ROOT)/ace/Auto_Ptr.h \ + $(ACE_ROOT)/ace/Auto_Ptr.i \ + $(ACE_ROOT)/ace/Auto_Ptr.cpp \ + $(ACE_ROOT)/ace/SString.i \ + $(ACE_ROOT)/ace/XML_Svc_Conf.h \ + $(ACE_ROOT)/ace/Service_Config.i \ + $(ACE_ROOT)/ace/Reactor.h \ + $(ACE_ROOT)/ace/Handle_Set.h \ + $(ACE_ROOT)/ace/Handle_Set.i \ + $(ACE_ROOT)/ace/Timer_Queue.h \ + $(ACE_ROOT)/ace/Timer_Queue_T.h \ + $(ACE_ROOT)/ace/Free_List.h \ + $(ACE_ROOT)/ace/Free_List.i \ + $(ACE_ROOT)/ace/Free_List.cpp \ + $(ACE_ROOT)/ace/Timer_Queue_T.i \ + $(ACE_ROOT)/ace/Timer_Queue_T.cpp \ + $(ACE_ROOT)/ace/Signal.h \ + $(ACE_ROOT)/ace/Signal.i \ + $(ACE_ROOT)/ace/Reactor_Timer_Interface.h \ + $(ACE_ROOT)/ace/Null_Mutex.h \ + $(ACE_ROOT)/ace/Reactor.i \ + $(ACE_ROOT)/ace/Reactor_Impl.h \ + $(TAO_ROOT)/tao/IORManipulation/IORC.h \ + $(TAO_ROOT)/tao/corba.h \ + $(TAO_ROOT)/tao/Typecode.h \ + $(ACE_ROOT)/ace/Hash_Map_Manager_T.h \ + $(ACE_ROOT)/ace/Functor.h \ + $(ACE_ROOT)/ace/Functor.i \ + $(ACE_ROOT)/ace/Functor_T.h \ + $(ACE_ROOT)/ace/Functor_T.i \ + $(ACE_ROOT)/ace/Functor_T.cpp \ + $(ACE_ROOT)/ace/Hash_Map_Manager_T.i \ + $(ACE_ROOT)/ace/Hash_Map_Manager_T.cpp \ + $(TAO_ROOT)/tao/Pseudo_VarOut_T.h \ + $(TAO_ROOT)/tao/Pseudo_VarOut_T.inl \ + $(TAO_ROOT)/tao/Pseudo_VarOut_T.cpp \ + $(TAO_ROOT)/tao/Typecode.i \ + $(TAO_ROOT)/tao/Any_Impl_T.h \ + $(TAO_ROOT)/tao/Any.h \ + $(ACE_ROOT)/ace/CDR_Stream.h \ + $(ACE_ROOT)/ace/Message_Block.h \ + $(ACE_ROOT)/ace/Message_Block.i \ + $(ACE_ROOT)/ace/Message_Block_T.h \ + $(ACE_ROOT)/ace/Message_Block_T.i \ + $(ACE_ROOT)/ace/Message_Block_T.cpp \ + $(ACE_ROOT)/ace/CDR_Stream.i \ + $(TAO_ROOT)/tao/Any.i \ + $(TAO_ROOT)/tao/Any_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Impl_T.cpp \ + $(TAO_ROOT)/tao/Marshal.h \ + $(TAO_ROOT)/tao/Marshal.i \ + $(TAO_ROOT)/tao/CDR.h \ + $(TAO_ROOT)/tao/CDR.i \ + $(TAO_ROOT)/tao/Environment.h \ + $(TAO_ROOT)/tao/Environment.i \ + $(TAO_ROOT)/tao/Any_Basic_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Basic_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Basic_Impl_T.cpp \ + $(TAO_ROOT)/tao/Any_Special_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Special_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Special_Impl_T.cpp \ + $(TAO_ROOT)/tao/Any_Special_Basic_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Special_Basic_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Special_Basic_Impl_T.cpp \ + $(TAO_ROOT)/tao/debug.h \ + $(TAO_ROOT)/tao/Any_Array_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Array_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Array_Impl_T.cpp \ + $(TAO_ROOT)/tao/Any_Dual_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Dual_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Dual_Impl_T.cpp \ + $(TAO_ROOT)/tao/CORBA_String.h \ + $(TAO_ROOT)/tao/Managed_Types.h \ + $(TAO_ROOT)/tao/Managed_Types.i \ + $(TAO_ROOT)/tao/CORBA_String.inl \ + $(TAO_ROOT)/tao/NVList.h \ + $(TAO_ROOT)/tao/NVList.i \ + $(TAO_ROOT)/tao/Object.h \ + $(TAO_ROOT)/tao/Policy_ForwardC.h \ + $(TAO_ROOT)/tao/Sequence.h \ + $(TAO_ROOT)/tao/Sequence.i \ + $(TAO_ROOT)/tao/Sequence_T.h \ + $(TAO_ROOT)/tao/Sequence_T.i \ + $(TAO_ROOT)/tao/Sequence_T.cpp \ + $(TAO_ROOT)/tao/Objref_VarOut_T.h \ + $(TAO_ROOT)/tao/varbase.h \ + $(TAO_ROOT)/tao/Objref_VarOut_T.inl \ + $(TAO_ROOT)/tao/Objref_VarOut_T.cpp \ + $(TAO_ROOT)/tao/Seq_Var_T.h \ + $(TAO_ROOT)/tao/Seq_Var_T.inl \ + $(TAO_ROOT)/tao/Seq_Var_T.cpp \ + $(TAO_ROOT)/tao/Seq_Out_T.h \ + $(TAO_ROOT)/tao/Seq_Out_T.inl \ + $(TAO_ROOT)/tao/Seq_Out_T.cpp \ + $(TAO_ROOT)/tao/Policy_ForwardC.i \ + $(TAO_ROOT)/tao/IOP_IORC.h \ + $(TAO_ROOT)/tao/OctetSeqC.h \ + $(TAO_ROOT)/tao/OctetSeqC.i \ + $(TAO_ROOT)/tao/VarOut_T.h \ + $(TAO_ROOT)/tao/VarOut_T.inl \ + $(TAO_ROOT)/tao/VarOut_T.cpp \ + $(TAO_ROOT)/tao/IOP_IORC.i \ + $(TAO_ROOT)/tao/Object.i \ + $(TAO_ROOT)/tao/LocalObject.h \ + $(TAO_ROOT)/tao/LocalObject.i \ + $(TAO_ROOT)/tao/Principal.h \ + $(TAO_ROOT)/tao/Principal.i \ + $(TAO_ROOT)/tao/ORB.h \ + $(TAO_ROOT)/tao/ServicesC.h \ + $(TAO_ROOT)/tao/ServicesC.i \ + $(TAO_ROOT)/tao/ObjectIdListC.h \ + $(TAO_ROOT)/tao/ObjectIdListC.i \ + $(TAO_ROOT)/tao/objectid.h \ + $(TAO_ROOT)/tao/PolicyC.h \ + $(TAO_ROOT)/tao/CurrentC.h \ + $(TAO_ROOT)/tao/CurrentC.i \ + $(TAO_ROOT)/tao/Remote_Object_Proxy_Impl.h \ + $(TAO_ROOT)/tao/Object_Proxy_Impl.h \ + $(TAO_ROOT)/tao/PolicyC.i \ + $(TAO_ROOT)/tao/ORB.i \ + $(TAO_ROOT)/tao/BoundsC.h \ + $(TAO_ROOT)/tao/BoundsC.i \ + $(TAO_ROOT)/tao/DomainC.h \ + $(TAO_ROOT)/tao/DomainC.i \ + $(TAO_ROOT)/tao/WrongTransactionC.h \ + $(TAO_ROOT)/tao/WrongTransactionC.i \ + $(TAO_ROOT)/tao/StringSeqC.h \ + $(TAO_ROOT)/tao/StringSeqC.i \ + $(TAO_ROOT)/tao/Object_KeyC.h \ + $(TAO_ROOT)/tao/Object_KeyC.i \ + $(TAO_ROOT)/tao/Array_VarOut_T.h \ + $(TAO_ROOT)/tao/Array_VarOut_T.inl \ + $(TAO_ROOT)/tao/Array_VarOut_T.cpp \ + $(TAO_ROOT)/tao/PortableInterceptorC.h \ + $(TAO_ROOT)/tao/PI_ForwardC.h \ + $(TAO_ROOT)/tao/PI_ForwardC.i \ + $(TAO_ROOT)/tao/DynamicC.h \ + $(TAO_ROOT)/tao/DynamicC.i \ + $(TAO_ROOT)/tao/Messaging_SyncScopeC.h \ + $(TAO_ROOT)/tao/Messaging_SyncScopeC.i \ + $(TAO_ROOT)/tao/IOPC.h \ + $(TAO_ROOT)/tao/IOP_CodecC.h \ + $(TAO_ROOT)/tao/IOP_CodecC.i \ + $(TAO_ROOT)/tao/IOPC.i \ + $(TAO_ROOT)/tao/PortableInterceptorC.i \ + $(TAO_ROOT)/tao/IORManipulation/IORC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/FaultTolerance/FT_Service_Activate.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/FaultTolerance/fault_tol_export.h \ + $(TAO_ROOT)/tao/Services_Activate.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/FaultTolerance/FT_IOGR_Property.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/FT_CORBA_ORBC.h \ + $(TAO_ROOT)/tao/TimeBaseC.h \ + $(TAO_ROOT)/tao/TimeBaseC.i \ + $(TAO_ROOT)/tao/GIOPC.h \ + $(TAO_ROOT)/tao/GIOPC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/PortableGroupC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/PortableGroup/portablegroup_export.h \ + $(TAO_ROOT)/tao/Messaging/Messaging.h \ + $(TAO_ROOT)/tao/Messaging/messaging_export.h \ + $(TAO_ROOT)/tao/Messaging/MessagingC.h \ + $(TAO_ROOT)/tao/Messaging/Messaging_SyncScope_PolicyC.h \ + $(TAO_ROOT)/tao/Messaging/Messaging_SyncScope_PolicyC.i \ + $(TAO_ROOT)/tao/Messaging/Messaging_RT_PolicyC.h \ + $(TAO_ROOT)/tao/Messaging/Messaging_RT_PolicyC.i \ + $(TAO_ROOT)/tao/Messaging/Messaging_No_ImplC.h \ + $(TAO_ROOT)/tao/Messaging/Messaging_No_ImplC.i \ + $(TAO_ROOT)/tao/Valuetype/Value_VarOut_T.h \ + $(TAO_ROOT)/tao/Valuetype/Value_VarOut_T.inl \ + $(TAO_ROOT)/tao/Valuetype/Value_VarOut_T.cpp \ + $(TAO_ROOT)/tao/Valuetype/ValueBase.h \ + $(TAO_ROOT)/tao/Valuetype/valuetype_export.h \ + $(ACE_ROOT)/ace/Synch_T.h \ + $(ACE_ROOT)/ace/Synch.h \ + $(ACE_ROOT)/ace/Auto_Event.h \ + $(ACE_ROOT)/ace/Event.h \ + $(ACE_ROOT)/ace/Event.inl \ + $(ACE_ROOT)/ace/Auto_Event.inl \ + $(ACE_ROOT)/ace/Barrier.h \ + $(ACE_ROOT)/ace/Condition_Thread_Mutex.h \ + $(ACE_ROOT)/ace/Condition_Thread_Mutex.inl \ + $(ACE_ROOT)/ace/Barrier.inl \ + $(ACE_ROOT)/ace/Condition_Recursive_Thread_Mutex.h \ + $(ACE_ROOT)/ace/Recursive_Thread_Mutex.h \ + $(ACE_ROOT)/ace/Recursive_Thread_Mutex.inl \ + $(ACE_ROOT)/ace/Condition_Recursive_Thread_Mutex.inl \ + $(ACE_ROOT)/ace/Manual_Event.h \ + $(ACE_ROOT)/ace/Manual_Event.inl \ + $(ACE_ROOT)/ace/Mutex.h \ + $(ACE_ROOT)/ace/Mutex.inl \ + $(ACE_ROOT)/ace/Null_Barrier.h \ + $(ACE_ROOT)/ace/Null_Condition.h \ + $(ACE_ROOT)/ace/Null_Semaphore.h \ + $(ACE_ROOT)/ace/RW_Mutex.h \ + $(ACE_ROOT)/ace/RW_Mutex.inl \ + $(ACE_ROOT)/ace/RW_Thread_Mutex.h \ + $(ACE_ROOT)/ace/RW_Thread_Mutex.inl \ + $(ACE_ROOT)/ace/Semaphore.h \ + $(ACE_ROOT)/ace/Semaphore.inl \ + $(ACE_ROOT)/ace/Thread_Semaphore.h \ + $(ACE_ROOT)/ace/Thread_Semaphore.inl \ + $(ACE_ROOT)/ace/TSS_Adapter.h \ + $(ACE_ROOT)/ace/TSS_Adapter.inl \ + $(ACE_ROOT)/ace/Synch.i \ + $(ACE_ROOT)/ace/Lock_Adapter_T.h \ + $(ACE_ROOT)/ace/Lock_Adapter_T.inl \ + $(ACE_ROOT)/ace/Lock_Adapter_T.cpp \ + $(ACE_ROOT)/ace/Reverse_Lock_T.h \ + $(ACE_ROOT)/ace/Reverse_Lock_T.inl \ + $(ACE_ROOT)/ace/Reverse_Lock_T.cpp \ + $(ACE_ROOT)/ace/TSS_T.h \ + $(ACE_ROOT)/ace/TSS_T.inl \ + $(ACE_ROOT)/ace/TSS_T.cpp \ + $(ACE_ROOT)/ace/Thread.h \ + $(ACE_ROOT)/ace/Thread_Adapter.h \ + $(ACE_ROOT)/ace/Base_Thread_Adapter.h \ + $(ACE_ROOT)/ace/Base_Thread_Adapter.inl \ + $(ACE_ROOT)/ace/Thread_Adapter.inl \ + $(ACE_ROOT)/ace/Thread.i \ + $(ACE_ROOT)/ace/Condition_T.h \ + $(ACE_ROOT)/ace/Condition_T.inl \ + $(ACE_ROOT)/ace/Condition_T.cpp \ + $(ACE_ROOT)/ace/Synch_T.i \ + $(ACE_ROOT)/ace/Synch_T.cpp \ + $(TAO_ROOT)/tao/Valuetype/ValueBase.inl \ + $(TAO_ROOT)/tao/Valuetype/ValueFactory.h \ + $(TAO_ROOT)/tao/Valuetype/ValueFactory.inl \ + $(TAO_ROOT)/tao/Messaging/MessagingC.i \ + $(TAO_ROOT)/tao/Messaging/TAO_ExtC.h \ + $(TAO_ROOT)/tao/Messaging/TAO_ExtC.i \ + $(TAO_ROOT)/tao/TAOC.h \ + $(TAO_ROOT)/tao/TAOC.i \ + $(TAO_ROOT)/tao/Valuetype/Valuetype_Adapter_Impl.h \ + $(TAO_ROOT)/tao/Valuetype_Adapter.h \ + $(TAO_ROOT)/tao/Valuetype/Sequence_T.h \ + $(TAO_ROOT)/tao/Valuetype/Sequence_T.inl \ + $(TAO_ROOT)/tao/Valuetype/Sequence_T.cpp \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosNamingC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosNamingC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/PortableGroupC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/FT_CORBA_ORBC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/FaultTolerance/FT_IOGR_Property.i \ + RolyPolyC.h RolyPolyC.i + +.obj/server.o .obj/server.so .shobj/server.o .shobj/server.so: server.cpp $(ACE_ROOT)/ace/Get_Opt.h \ + $(ACE_ROOT)/ace/pre.h \ + $(ACE_ROOT)/ace/SStringfwd.h \ + $(ACE_ROOT)/ace/Basic_Types.h \ + $(ACE_ROOT)/ace/post.h \ + $(ACE_ROOT)/ace/ace_wchar.h \ + $(ACE_ROOT)/ace/ace_wchar.inl \ + $(ACE_ROOT)/ace/os_include/os_limits.h \ + $(ACE_ROOT)/ace/os_include/os_unistd.h \ + $(ACE_ROOT)/ace/os_include/sys/os_types.h \ + $(ACE_ROOT)/ace/os_include/os_stddef.h \ + $(ACE_ROOT)/ace/os_include/os_inttypes.h \ + $(ACE_ROOT)/ace/os_include/os_stdint.h \ + $(ACE_ROOT)/ace/os_include/os_stdio.h \ + $(ACE_ROOT)/ace/os_include/os_stdarg.h \ + $(ACE_ROOT)/ace/os_include/os_float.h \ + $(ACE_ROOT)/ace/os_include/os_stdlib.h \ + $(ACE_ROOT)/ace/os_include/sys/os_wait.h \ + $(ACE_ROOT)/ace/os_include/os_signal.h \ + $(ACE_ROOT)/ace/os_include/os_time.h \ + $(ACE_ROOT)/ace/os_include/os_ucontext.h \ + $(ACE_ROOT)/ace/os_include/sys/os_resource.h \ + $(ACE_ROOT)/ace/os_include/sys/os_time.h \ + $(ACE_ROOT)/ace/os_include/sys/os_select.h \ + $(ACE_ROOT)/ace/ACE_export.h \ + $(ACE_ROOT)/ace/Basic_Types.i \ + $(ACE_ROOT)/ace/Containers.h \ + $(ACE_ROOT)/ace/Containers.i \ + $(ACE_ROOT)/ace/Containers_T.h \ + $(ACE_ROOT)/ace/Node.h \ + $(ACE_ROOT)/ace/Node.cpp \ + $(ACE_ROOT)/ace/Array_Base.h \ + $(ACE_ROOT)/ace/Global_Macros.h \ + $(ACE_ROOT)/ace/OS_Export.h \ + $(ACE_ROOT)/ace/Malloc_Base.h \ + $(ACE_ROOT)/ace/os_include/sys/os_mman.h \ + $(ACE_ROOT)/ace/Array_Base.inl \ + $(ACE_ROOT)/ace/Array_Base.cpp \ + $(ACE_ROOT)/ace/os_include/os_errno.h \ + $(ACE_ROOT)/ace/Unbounded_Set.h \ + $(ACE_ROOT)/ace/Unbounded_Set.inl \ + $(ACE_ROOT)/ace/Unbounded_Set.cpp \ + $(ACE_ROOT)/ace/Log_Msg.h \ + $(ACE_ROOT)/ace/Default_Constants.h \ + $(ACE_ROOT)/ace/Log_Priority.h \ + $(ACE_ROOT)/ace/OS_Log_Msg_Attributes.h \ + $(ACE_ROOT)/ace/iosfwd.h \ + $(ACE_ROOT)/ace/OS_Log_Msg_Attributes.inl \ + $(ACE_ROOT)/ace/Unbounded_Queue.h \ + $(ACE_ROOT)/ace/Unbounded_Queue.inl \ + $(ACE_ROOT)/ace/Unbounded_Queue.cpp \ + $(ACE_ROOT)/ace/Containers_T.i \ + $(ACE_ROOT)/ace/Containers_T.cpp \ + $(ACE_ROOT)/ace/OS_Memory.h \ + $(ACE_ROOT)/ace/OS_Errno.h \ + $(ACE_ROOT)/ace/OS_Errno.inl \ + $(ACE_ROOT)/ace/OS_Memory.inl \ + $(ACE_ROOT)/ace/Get_Opt.i RolyPoly_i.h \ + RolyPolyS.h RolyPolyC.h \ + $(TAO_ROOT)/tao/corba.h \ + $(TAO_ROOT)/tao/corbafwd.h \ + $(ACE_ROOT)/ace/CDR_Base.h \ + $(ACE_ROOT)/ace/CDR_Base.inl \ + $(TAO_ROOT)/tao/orbconf.h \ + $(ACE_ROOT)/ace/Synch_Traits.h \ + $(ACE_ROOT)/ace/Lock.h \ + $(ACE_ROOT)/ace/Lock.inl \ + $(TAO_ROOT)/tao/TAO_Export.h \ + $(TAO_ROOT)/tao/corbafwd.i \ + $(TAO_ROOT)/tao/Typecode.h \ + $(ACE_ROOT)/ace/Hash_Map_Manager_T.h \ + $(ACE_ROOT)/ace/Functor.h \ + $(ACE_ROOT)/ace/Functor.i \ + $(ACE_ROOT)/ace/ACE.h \ + $(ACE_ROOT)/ace/Flag_Manip.h \ + $(ACE_ROOT)/ace/Flag_Manip.i \ + $(ACE_ROOT)/ace/OS.h \ + $(ACE_ROOT)/ace/OS_Dirent.h \ + $(ACE_ROOT)/ace/os_include/os_dirent.h \ + $(ACE_ROOT)/ace/OS_Dirent.inl \ + $(ACE_ROOT)/ace/OS_String.h \ + $(ACE_ROOT)/ace/OS_String.inl \ + $(ACE_ROOT)/ace/os_include/os_string.h \ + $(ACE_ROOT)/ace/os_include/os_strings.h \ + $(ACE_ROOT)/ace/os_include/os_ctype.h \ + $(ACE_ROOT)/ace/OS_TLI.h \ + $(ACE_ROOT)/ace/OS_TLI.inl \ + $(ACE_ROOT)/ace/os_include/os_dlfcn.h \ + $(ACE_ROOT)/ace/os_include/os_netdb.h \ + $(ACE_ROOT)/ace/os_include/netinet/os_in.h \ + $(ACE_ROOT)/ace/os_include/sys/os_socket.h \ + $(ACE_ROOT)/ace/os_include/sys/os_uio.h \ + $(ACE_ROOT)/ace/os_include/net/os_if.h \ + $(ACE_ROOT)/ace/os_include/sys/os_sem.h \ + $(ACE_ROOT)/ace/os_include/sys/os_ipc.h \ + $(ACE_ROOT)/ace/Time_Value.h \ + $(ACE_ROOT)/ace/Time_Value.inl \ + $(ACE_ROOT)/ace/Min_Max.h \ + $(ACE_ROOT)/ace/os_include/os_pthread.h \ + $(ACE_ROOT)/ace/os_include/os_assert.h \ + $(ACE_ROOT)/ace/os_include/os_fcntl.h \ + $(ACE_ROOT)/ace/os_include/sys/os_stat.h \ + $(ACE_ROOT)/ace/os_include/arpa/os_inet.h \ + $(ACE_ROOT)/ace/os_include/netinet/os_tcp.h \ + $(ACE_ROOT)/ace/os_include/sys/os_shm.h \ + $(ACE_ROOT)/ace/os_include/os_pwd.h \ + $(ACE_ROOT)/ace/os_include/os_stropts.h \ + $(ACE_ROOT)/ace/os_include/os_termios.h \ + $(ACE_ROOT)/ace/os_include/os_aio.h \ + $(ACE_ROOT)/ace/os_include/sys/os_un.h \ + $(ACE_ROOT)/ace/os_include/os_poll.h \ + $(ACE_ROOT)/ace/os_include/sys/os_msg.h \ + $(ACE_ROOT)/ace/os_include/sys/os_utsname.h \ + $(ACE_ROOT)/ace/os_include/os_syslog.h \ + $(ACE_ROOT)/ace/OS.i \ + $(ACE_ROOT)/ace/Handle_Ops.h \ + $(ACE_ROOT)/ace/Handle_Ops.i \ + $(ACE_ROOT)/ace/Lib_Find.h \ + $(ACE_ROOT)/ace/Lib_Find.i \ + $(ACE_ROOT)/ace/Init_ACE.h \ + $(ACE_ROOT)/ace/Init_ACE.i \ + $(ACE_ROOT)/ace/Sock_Connect.h \ + $(ACE_ROOT)/ace/Sock_Connect.i \ + $(ACE_ROOT)/ace/ACE.i \ + $(ACE_ROOT)/ace/Functor_T.h \ + $(ACE_ROOT)/ace/Functor_T.i \ + $(ACE_ROOT)/ace/Functor_T.cpp \ + $(ACE_ROOT)/ace/Hash_Map_Manager_T.i \ + $(ACE_ROOT)/ace/Guard_T.h \ + $(ACE_ROOT)/ace/Guard_T.inl \ + $(ACE_ROOT)/ace/Guard_T.cpp \ + $(ACE_ROOT)/ace/Hash_Map_Manager_T.cpp \ + $(ACE_ROOT)/ace/Thread_Mutex.h \ + $(ACE_ROOT)/ace/Thread_Mutex.inl \ + $(TAO_ROOT)/tao/Exception.h \ + $(ACE_ROOT)/ace/CORBA_macros.h \ + $(ACE_ROOT)/ace/Exception_Macros.h \ + $(TAO_ROOT)/tao/Exception.i \ + $(TAO_ROOT)/tao/Pseudo_VarOut_T.h \ + $(TAO_ROOT)/tao/Pseudo_VarOut_T.inl \ + $(TAO_ROOT)/tao/Pseudo_VarOut_T.cpp \ + $(TAO_ROOT)/tao/Typecode.i \ + $(TAO_ROOT)/tao/Any_Impl_T.h \ + $(TAO_ROOT)/tao/Any.h \ + $(ACE_ROOT)/ace/CDR_Stream.h \ + $(ACE_ROOT)/ace/Message_Block.h \ + $(ACE_ROOT)/ace/Message_Block.i \ + $(ACE_ROOT)/ace/Message_Block_T.h \ + $(ACE_ROOT)/ace/Message_Block_T.i \ + $(ACE_ROOT)/ace/Message_Block_T.cpp \ + $(ACE_ROOT)/ace/CDR_Stream.i \ + $(TAO_ROOT)/tao/Any.i \ + $(TAO_ROOT)/tao/Any_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Impl_T.cpp \ + $(TAO_ROOT)/tao/Marshal.h \ + $(TAO_ROOT)/tao/Marshal.i \ + $(TAO_ROOT)/tao/CDR.h \ + $(TAO_ROOT)/tao/CDR.i \ + $(TAO_ROOT)/tao/Environment.h \ + $(TAO_ROOT)/tao/Environment.i \ + $(ACE_ROOT)/ace/Auto_Ptr.h \ + $(ACE_ROOT)/ace/Auto_Ptr.i \ + $(ACE_ROOT)/ace/Auto_Ptr.cpp \ + $(TAO_ROOT)/tao/Any_Basic_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Basic_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Basic_Impl_T.cpp \ + $(TAO_ROOT)/tao/Any_Special_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Special_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Special_Impl_T.cpp \ + $(TAO_ROOT)/tao/Any_Special_Basic_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Special_Basic_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Special_Basic_Impl_T.cpp \ + $(TAO_ROOT)/tao/debug.h \ + $(TAO_ROOT)/tao/Any_Array_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Array_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Array_Impl_T.cpp \ + $(TAO_ROOT)/tao/Any_Dual_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Dual_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Dual_Impl_T.cpp \ + $(TAO_ROOT)/tao/CORBA_String.h \ + $(TAO_ROOT)/tao/Managed_Types.h \ + $(TAO_ROOT)/tao/Managed_Types.i \ + $(TAO_ROOT)/tao/CORBA_String.inl \ + $(TAO_ROOT)/tao/NVList.h \ + $(TAO_ROOT)/tao/NVList.i \ + $(TAO_ROOT)/tao/Object.h \ + $(TAO_ROOT)/tao/Policy_ForwardC.h \ + $(TAO_ROOT)/tao/Sequence.h \ + $(TAO_ROOT)/tao/Sequence.i \ + $(TAO_ROOT)/tao/Sequence_T.h \ + $(TAO_ROOT)/tao/Sequence_T.i \ + $(TAO_ROOT)/tao/Sequence_T.cpp \ + $(TAO_ROOT)/tao/Objref_VarOut_T.h \ + $(TAO_ROOT)/tao/varbase.h \ + $(TAO_ROOT)/tao/Objref_VarOut_T.inl \ + $(TAO_ROOT)/tao/Objref_VarOut_T.cpp \ + $(TAO_ROOT)/tao/Seq_Var_T.h \ + $(TAO_ROOT)/tao/Seq_Var_T.inl \ + $(TAO_ROOT)/tao/Seq_Var_T.cpp \ + $(TAO_ROOT)/tao/Seq_Out_T.h \ + $(TAO_ROOT)/tao/Seq_Out_T.inl \ + $(TAO_ROOT)/tao/Seq_Out_T.cpp \ + $(TAO_ROOT)/tao/Policy_ForwardC.i \ + $(TAO_ROOT)/tao/IOP_IORC.h \ + $(TAO_ROOT)/tao/OctetSeqC.h \ + $(TAO_ROOT)/tao/OctetSeqC.i \ + $(TAO_ROOT)/tao/VarOut_T.h \ + $(TAO_ROOT)/tao/VarOut_T.inl \ + $(TAO_ROOT)/tao/VarOut_T.cpp \ + $(TAO_ROOT)/tao/IOP_IORC.i \ + $(TAO_ROOT)/tao/Object.i \ + $(TAO_ROOT)/tao/LocalObject.h \ + $(TAO_ROOT)/tao/LocalObject.i \ + $(TAO_ROOT)/tao/Principal.h \ + $(TAO_ROOT)/tao/Principal.i \ + $(TAO_ROOT)/tao/ORB.h \ + $(TAO_ROOT)/tao/ServicesC.h \ + $(TAO_ROOT)/tao/ServicesC.i \ + $(TAO_ROOT)/tao/ObjectIdListC.h \ + $(TAO_ROOT)/tao/ObjectIdListC.i \ + $(TAO_ROOT)/tao/objectid.h \ + $(TAO_ROOT)/tao/PolicyC.h \ + $(TAO_ROOT)/tao/CurrentC.h \ + $(TAO_ROOT)/tao/CurrentC.i \ + $(TAO_ROOT)/tao/Remote_Object_Proxy_Impl.h \ + $(TAO_ROOT)/tao/Object_Proxy_Impl.h \ + $(TAO_ROOT)/tao/PolicyC.i \ + $(TAO_ROOT)/tao/ORB.i \ + $(TAO_ROOT)/tao/BoundsC.h \ + $(TAO_ROOT)/tao/BoundsC.i \ + $(TAO_ROOT)/tao/DomainC.h \ + $(TAO_ROOT)/tao/DomainC.i \ + $(TAO_ROOT)/tao/WrongTransactionC.h \ + $(TAO_ROOT)/tao/WrongTransactionC.i \ + $(TAO_ROOT)/tao/StringSeqC.h \ + $(TAO_ROOT)/tao/StringSeqC.i \ + $(TAO_ROOT)/tao/Object_KeyC.h \ + $(TAO_ROOT)/tao/Object_KeyC.i \ + $(TAO_ROOT)/tao/Array_VarOut_T.h \ + $(TAO_ROOT)/tao/Array_VarOut_T.inl \ + $(TAO_ROOT)/tao/Array_VarOut_T.cpp \ + $(TAO_ROOT)/tao/PortableInterceptorC.h \ + $(TAO_ROOT)/tao/PI_ForwardC.h \ + $(TAO_ROOT)/tao/PI_ForwardC.i \ + $(TAO_ROOT)/tao/DynamicC.h \ + $(TAO_ROOT)/tao/DynamicC.i \ + $(TAO_ROOT)/tao/Messaging_SyncScopeC.h \ + $(TAO_ROOT)/tao/Messaging_SyncScopeC.i \ + $(TAO_ROOT)/tao/IOPC.h \ + $(TAO_ROOT)/tao/IOP_CodecC.h \ + $(TAO_ROOT)/tao/IOP_CodecC.i \ + $(TAO_ROOT)/tao/IOPC.i \ + $(TAO_ROOT)/tao/PortableInterceptorC.i \ + RolyPolyC.i \ + $(TAO_ROOT)/tao/PortableServer/PortableServer.h \ + $(TAO_ROOT)/tao/PortableServer/portableserver_export.h \ + $(TAO_ROOT)/tao/PortableServer/PortableServerC.h \ + $(TAO_ROOT)/tao/PortableServer/PortableServerC.i \ + $(TAO_ROOT)/tao/PortableServer/Servant_Base.h \ + $(TAO_ROOT)/tao/Abstract_Servant_Base.h \ + $(ACE_ROOT)/ace/Atomic_Op.h \ + $(ACE_ROOT)/ace/Atomic_Op_T.h \ + $(ACE_ROOT)/ace/Atomic_Op_T.i \ + $(ACE_ROOT)/ace/Atomic_Op_T.cpp \ + $(ACE_ROOT)/ace/Atomic_Op.i \ + $(TAO_ROOT)/tao/PortableServer/Servant_Base.i \ + $(TAO_ROOT)/tao/PortableServer/Collocated_Object.h \ + $(TAO_ROOT)/tao/PortableServer/Collocated_Object.i \ + $(TAO_ROOT)/tao/PortableServer/ThruPOA_Object_Proxy_Impl.h \ + $(TAO_ROOT)/tao/PortableServer/Direct_Object_Proxy_Impl.h \ + RolyPolyS_T.h RolyPolyS_T.i RolyPolyS_T.cpp RolyPolyS.i StateUpdate.h \ + CrashPoint.h ORB_Initializer.h + +.obj/CrashPoint.o .obj/CrashPoint.so .shobj/CrashPoint.o .shobj/CrashPoint.so: CrashPoint.cpp CrashPoint.h + +.obj/RolyPoly_i.o .obj/RolyPoly_i.so .shobj/RolyPoly_i.o .shobj/RolyPoly_i.so: RolyPoly_i.cpp RolyPoly_i.h RolyPolyS.h RolyPolyC.h \ + $(TAO_ROOT)/tao/corba.h \ + $(ACE_ROOT)/ace/pre.h \ + $(ACE_ROOT)/ace/post.h \ + $(ACE_ROOT)/ace/ace_wchar.h \ + $(ACE_ROOT)/ace/ace_wchar.inl \ + $(TAO_ROOT)/tao/corbafwd.h \ + $(ACE_ROOT)/ace/CDR_Base.h \ + $(ACE_ROOT)/ace/Basic_Types.h \ + $(ACE_ROOT)/ace/os_include/os_limits.h \ + $(ACE_ROOT)/ace/os_include/os_unistd.h \ + $(ACE_ROOT)/ace/os_include/sys/os_types.h \ + $(ACE_ROOT)/ace/os_include/os_stddef.h \ + $(ACE_ROOT)/ace/os_include/os_inttypes.h \ + $(ACE_ROOT)/ace/os_include/os_stdint.h \ + $(ACE_ROOT)/ace/os_include/os_stdio.h \ + $(ACE_ROOT)/ace/os_include/os_stdarg.h \ + $(ACE_ROOT)/ace/os_include/os_float.h \ + $(ACE_ROOT)/ace/os_include/os_stdlib.h \ + $(ACE_ROOT)/ace/os_include/sys/os_wait.h \ + $(ACE_ROOT)/ace/os_include/os_signal.h \ + $(ACE_ROOT)/ace/os_include/os_time.h \ + $(ACE_ROOT)/ace/os_include/os_ucontext.h \ + $(ACE_ROOT)/ace/os_include/sys/os_resource.h \ + $(ACE_ROOT)/ace/os_include/sys/os_time.h \ + $(ACE_ROOT)/ace/os_include/sys/os_select.h \ + $(ACE_ROOT)/ace/ACE_export.h \ + $(ACE_ROOT)/ace/Basic_Types.i \ + $(ACE_ROOT)/ace/Default_Constants.h \ + $(ACE_ROOT)/ace/CDR_Base.inl \ + $(TAO_ROOT)/tao/orbconf.h \ + $(ACE_ROOT)/ace/Global_Macros.h \ + $(ACE_ROOT)/ace/OS_Export.h \ + $(ACE_ROOT)/ace/Synch_Traits.h \ + $(ACE_ROOT)/ace/Lock.h \ + $(ACE_ROOT)/ace/Lock.inl \ + $(TAO_ROOT)/tao/TAO_Export.h \ + $(TAO_ROOT)/tao/corbafwd.i \ + $(TAO_ROOT)/tao/Typecode.h \ + $(ACE_ROOT)/ace/Hash_Map_Manager_T.h \ + $(ACE_ROOT)/ace/Functor.h \ + $(ACE_ROOT)/ace/Functor.i \ + $(ACE_ROOT)/ace/ACE.h \ + $(ACE_ROOT)/ace/Flag_Manip.h \ + $(ACE_ROOT)/ace/Flag_Manip.i \ + $(ACE_ROOT)/ace/OS.h \ + $(ACE_ROOT)/ace/OS_Dirent.h \ + $(ACE_ROOT)/ace/OS_Errno.h \ + $(ACE_ROOT)/ace/os_include/os_errno.h \ + $(ACE_ROOT)/ace/OS_Errno.inl \ + $(ACE_ROOT)/ace/os_include/os_dirent.h \ + $(ACE_ROOT)/ace/OS_Dirent.inl \ + $(ACE_ROOT)/ace/OS_String.h \ + $(ACE_ROOT)/ace/OS_String.inl \ + $(ACE_ROOT)/ace/os_include/os_string.h \ + $(ACE_ROOT)/ace/os_include/os_strings.h \ + $(ACE_ROOT)/ace/os_include/os_ctype.h \ + $(ACE_ROOT)/ace/OS_Memory.h \ + $(ACE_ROOT)/ace/OS_Memory.inl \ + $(ACE_ROOT)/ace/OS_TLI.h \ + $(ACE_ROOT)/ace/OS_TLI.inl \ + $(ACE_ROOT)/ace/os_include/os_dlfcn.h \ + $(ACE_ROOT)/ace/os_include/sys/os_mman.h \ + $(ACE_ROOT)/ace/os_include/os_netdb.h \ + $(ACE_ROOT)/ace/os_include/netinet/os_in.h \ + $(ACE_ROOT)/ace/os_include/sys/os_socket.h \ + $(ACE_ROOT)/ace/os_include/sys/os_uio.h \ + $(ACE_ROOT)/ace/os_include/net/os_if.h \ + $(ACE_ROOT)/ace/os_include/sys/os_sem.h \ + $(ACE_ROOT)/ace/os_include/sys/os_ipc.h \ + $(ACE_ROOT)/ace/Time_Value.h \ + $(ACE_ROOT)/ace/Time_Value.inl \ + $(ACE_ROOT)/ace/Min_Max.h \ + $(ACE_ROOT)/ace/os_include/os_pthread.h \ + $(ACE_ROOT)/ace/os_include/os_assert.h \ + $(ACE_ROOT)/ace/os_include/os_fcntl.h \ + $(ACE_ROOT)/ace/os_include/sys/os_stat.h \ + $(ACE_ROOT)/ace/iosfwd.h \ + $(ACE_ROOT)/ace/os_include/arpa/os_inet.h \ + $(ACE_ROOT)/ace/os_include/netinet/os_tcp.h \ + $(ACE_ROOT)/ace/os_include/sys/os_shm.h \ + $(ACE_ROOT)/ace/os_include/os_pwd.h \ + $(ACE_ROOT)/ace/os_include/os_stropts.h \ + $(ACE_ROOT)/ace/os_include/os_termios.h \ + $(ACE_ROOT)/ace/os_include/os_aio.h \ + $(ACE_ROOT)/ace/os_include/sys/os_un.h \ + $(ACE_ROOT)/ace/os_include/os_poll.h \ + $(ACE_ROOT)/ace/os_include/sys/os_msg.h \ + $(ACE_ROOT)/ace/os_include/sys/os_utsname.h \ + $(ACE_ROOT)/ace/os_include/os_syslog.h \ + $(ACE_ROOT)/ace/OS.i \ + $(ACE_ROOT)/ace/Handle_Ops.h \ + $(ACE_ROOT)/ace/Handle_Ops.i \ + $(ACE_ROOT)/ace/Lib_Find.h \ + $(ACE_ROOT)/ace/Lib_Find.i \ + $(ACE_ROOT)/ace/Init_ACE.h \ + $(ACE_ROOT)/ace/Init_ACE.i \ + $(ACE_ROOT)/ace/Sock_Connect.h \ + $(ACE_ROOT)/ace/Sock_Connect.i \ + $(ACE_ROOT)/ace/ACE.i \ + $(ACE_ROOT)/ace/Functor_T.h \ + $(ACE_ROOT)/ace/Functor_T.i \ + $(ACE_ROOT)/ace/Functor_T.cpp \ + $(ACE_ROOT)/ace/Log_Msg.h \ + $(ACE_ROOT)/ace/Log_Priority.h \ + $(ACE_ROOT)/ace/OS_Log_Msg_Attributes.h \ + $(ACE_ROOT)/ace/OS_Log_Msg_Attributes.inl \ + $(ACE_ROOT)/ace/Hash_Map_Manager_T.i \ + $(ACE_ROOT)/ace/Guard_T.h \ + $(ACE_ROOT)/ace/Guard_T.inl \ + $(ACE_ROOT)/ace/Guard_T.cpp \ + $(ACE_ROOT)/ace/Hash_Map_Manager_T.cpp \ + $(ACE_ROOT)/ace/Malloc_Base.h \ + $(ACE_ROOT)/ace/Unbounded_Queue.h \ + $(ACE_ROOT)/ace/Node.h \ + $(ACE_ROOT)/ace/Node.cpp \ + $(ACE_ROOT)/ace/Unbounded_Queue.inl \ + $(ACE_ROOT)/ace/Unbounded_Queue.cpp \ + $(ACE_ROOT)/ace/Thread_Mutex.h \ + $(ACE_ROOT)/ace/Thread_Mutex.inl \ + $(TAO_ROOT)/tao/Exception.h \ + $(ACE_ROOT)/ace/CORBA_macros.h \ + $(ACE_ROOT)/ace/Exception_Macros.h \ + $(ACE_ROOT)/ace/SStringfwd.h \ + $(TAO_ROOT)/tao/Exception.i \ + $(TAO_ROOT)/tao/Pseudo_VarOut_T.h \ + $(TAO_ROOT)/tao/Pseudo_VarOut_T.inl \ + $(TAO_ROOT)/tao/Pseudo_VarOut_T.cpp \ + $(TAO_ROOT)/tao/Typecode.i \ + $(TAO_ROOT)/tao/Any_Impl_T.h \ + $(TAO_ROOT)/tao/Any.h \ + $(ACE_ROOT)/ace/CDR_Stream.h \ + $(ACE_ROOT)/ace/Message_Block.h \ + $(ACE_ROOT)/ace/Message_Block.i \ + $(ACE_ROOT)/ace/Message_Block_T.h \ + $(ACE_ROOT)/ace/Message_Block_T.i \ + $(ACE_ROOT)/ace/Message_Block_T.cpp \ + $(ACE_ROOT)/ace/CDR_Stream.i \ + $(TAO_ROOT)/tao/Any.i \ + $(TAO_ROOT)/tao/Any_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Impl_T.cpp \ + $(TAO_ROOT)/tao/Marshal.h \ + $(TAO_ROOT)/tao/Marshal.i \ + $(TAO_ROOT)/tao/CDR.h \ + $(TAO_ROOT)/tao/CDR.i \ + $(TAO_ROOT)/tao/Environment.h \ + $(TAO_ROOT)/tao/Environment.i \ + $(ACE_ROOT)/ace/Auto_Ptr.h \ + $(ACE_ROOT)/ace/Auto_Ptr.i \ + $(ACE_ROOT)/ace/Auto_Ptr.cpp \ + $(TAO_ROOT)/tao/Any_Basic_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Basic_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Basic_Impl_T.cpp \ + $(TAO_ROOT)/tao/Any_Special_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Special_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Special_Impl_T.cpp \ + $(TAO_ROOT)/tao/Any_Special_Basic_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Special_Basic_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Special_Basic_Impl_T.cpp \ + $(TAO_ROOT)/tao/debug.h \ + $(TAO_ROOT)/tao/Any_Array_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Array_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Array_Impl_T.cpp \ + $(TAO_ROOT)/tao/Any_Dual_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Dual_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Dual_Impl_T.cpp \ + $(TAO_ROOT)/tao/CORBA_String.h \ + $(TAO_ROOT)/tao/Managed_Types.h \ + $(TAO_ROOT)/tao/Managed_Types.i \ + $(TAO_ROOT)/tao/CORBA_String.inl \ + $(TAO_ROOT)/tao/NVList.h \ + $(TAO_ROOT)/tao/NVList.i \ + $(TAO_ROOT)/tao/Object.h \ + $(TAO_ROOT)/tao/Policy_ForwardC.h \ + $(TAO_ROOT)/tao/Sequence.h \ + $(TAO_ROOT)/tao/Sequence.i \ + $(TAO_ROOT)/tao/Sequence_T.h \ + $(TAO_ROOT)/tao/Sequence_T.i \ + $(TAO_ROOT)/tao/Sequence_T.cpp \ + $(TAO_ROOT)/tao/Objref_VarOut_T.h \ + $(TAO_ROOT)/tao/varbase.h \ + $(TAO_ROOT)/tao/Objref_VarOut_T.inl \ + $(TAO_ROOT)/tao/Objref_VarOut_T.cpp \ + $(TAO_ROOT)/tao/Seq_Var_T.h \ + $(TAO_ROOT)/tao/Seq_Var_T.inl \ + $(TAO_ROOT)/tao/Seq_Var_T.cpp \ + $(TAO_ROOT)/tao/Seq_Out_T.h \ + $(TAO_ROOT)/tao/Seq_Out_T.inl \ + $(TAO_ROOT)/tao/Seq_Out_T.cpp \ + $(TAO_ROOT)/tao/Policy_ForwardC.i \ + $(TAO_ROOT)/tao/IOP_IORC.h \ + $(TAO_ROOT)/tao/OctetSeqC.h \ + $(TAO_ROOT)/tao/OctetSeqC.i \ + $(TAO_ROOT)/tao/VarOut_T.h \ + $(TAO_ROOT)/tao/VarOut_T.inl \ + $(TAO_ROOT)/tao/VarOut_T.cpp \ + $(TAO_ROOT)/tao/IOP_IORC.i \ + $(TAO_ROOT)/tao/Object.i \ + $(TAO_ROOT)/tao/LocalObject.h \ + $(TAO_ROOT)/tao/LocalObject.i \ + $(TAO_ROOT)/tao/Principal.h \ + $(TAO_ROOT)/tao/Principal.i \ + $(TAO_ROOT)/tao/ORB.h \ + $(TAO_ROOT)/tao/ServicesC.h \ + $(TAO_ROOT)/tao/ServicesC.i \ + $(TAO_ROOT)/tao/ObjectIdListC.h \ + $(TAO_ROOT)/tao/ObjectIdListC.i \ + $(TAO_ROOT)/tao/objectid.h \ + $(TAO_ROOT)/tao/PolicyC.h \ + $(TAO_ROOT)/tao/CurrentC.h \ + $(TAO_ROOT)/tao/CurrentC.i \ + $(TAO_ROOT)/tao/Remote_Object_Proxy_Impl.h \ + $(TAO_ROOT)/tao/Object_Proxy_Impl.h \ + $(TAO_ROOT)/tao/PolicyC.i \ + $(TAO_ROOT)/tao/ORB.i \ + $(TAO_ROOT)/tao/BoundsC.h \ + $(TAO_ROOT)/tao/BoundsC.i \ + $(TAO_ROOT)/tao/DomainC.h \ + $(TAO_ROOT)/tao/DomainC.i \ + $(TAO_ROOT)/tao/WrongTransactionC.h \ + $(TAO_ROOT)/tao/WrongTransactionC.i \ + $(TAO_ROOT)/tao/StringSeqC.h \ + $(TAO_ROOT)/tao/StringSeqC.i \ + $(TAO_ROOT)/tao/Object_KeyC.h \ + $(TAO_ROOT)/tao/Object_KeyC.i \ + $(TAO_ROOT)/tao/Array_VarOut_T.h \ + $(TAO_ROOT)/tao/Array_VarOut_T.inl \ + $(TAO_ROOT)/tao/Array_VarOut_T.cpp \ + $(TAO_ROOT)/tao/PortableInterceptorC.h \ + $(TAO_ROOT)/tao/PI_ForwardC.h \ + $(TAO_ROOT)/tao/PI_ForwardC.i \ + $(TAO_ROOT)/tao/DynamicC.h \ + $(TAO_ROOT)/tao/DynamicC.i \ + $(TAO_ROOT)/tao/Messaging_SyncScopeC.h \ + $(TAO_ROOT)/tao/Messaging_SyncScopeC.i \ + $(TAO_ROOT)/tao/IOPC.h \ + $(TAO_ROOT)/tao/IOP_CodecC.h \ + $(TAO_ROOT)/tao/IOP_CodecC.i \ + $(TAO_ROOT)/tao/IOPC.i \ + $(TAO_ROOT)/tao/PortableInterceptorC.i \ + RolyPolyC.i \ + $(TAO_ROOT)/tao/PortableServer/PortableServer.h \ + $(TAO_ROOT)/tao/PortableServer/portableserver_export.h \ + $(TAO_ROOT)/tao/PortableServer/PortableServerC.h \ + $(TAO_ROOT)/tao/PortableServer/PortableServerC.i \ + $(TAO_ROOT)/tao/PortableServer/Servant_Base.h \ + $(TAO_ROOT)/tao/Abstract_Servant_Base.h \ + $(ACE_ROOT)/ace/Atomic_Op.h \ + $(ACE_ROOT)/ace/Atomic_Op_T.h \ + $(ACE_ROOT)/ace/Atomic_Op_T.i \ + $(ACE_ROOT)/ace/Atomic_Op_T.cpp \ + $(ACE_ROOT)/ace/Atomic_Op.i \ + $(TAO_ROOT)/tao/PortableServer/Servant_Base.i \ + $(TAO_ROOT)/tao/PortableServer/Collocated_Object.h \ + $(TAO_ROOT)/tao/PortableServer/Collocated_Object.i \ + $(TAO_ROOT)/tao/PortableServer/ThruPOA_Object_Proxy_Impl.h \ + $(TAO_ROOT)/tao/PortableServer/Direct_Object_Proxy_Impl.h \ + RolyPolyS_T.h RolyPolyS_T.i RolyPolyS_T.cpp RolyPolyS.i StateUpdate.h + +.obj/ReplicaController.o .obj/ReplicaController.so .shobj/ReplicaController.o .shobj/ReplicaController.so: ReplicaController.cpp \ + $(ACE_ROOT)/ace/UUID.h \ + $(ACE_ROOT)/ace/pre.h \ + $(ACE_ROOT)/ace/OS.h \ + $(ACE_ROOT)/ace/post.h \ + $(ACE_ROOT)/ace/ace_wchar.h \ + $(ACE_ROOT)/ace/ace_wchar.inl \ + $(ACE_ROOT)/ace/OS_Dirent.h \ + $(ACE_ROOT)/ace/OS_Export.h \ + $(ACE_ROOT)/ace/OS_Errno.h \ + $(ACE_ROOT)/ace/os_include/os_errno.h \ + $(ACE_ROOT)/ace/OS_Errno.inl \ + $(ACE_ROOT)/ace/os_include/os_dirent.h \ + $(ACE_ROOT)/ace/os_include/sys/os_types.h \ + $(ACE_ROOT)/ace/os_include/os_stddef.h \ + $(ACE_ROOT)/ace/os_include/os_limits.h \ + $(ACE_ROOT)/ace/os_include/os_unistd.h \ + $(ACE_ROOT)/ace/os_include/os_inttypes.h \ + $(ACE_ROOT)/ace/os_include/os_stdint.h \ + $(ACE_ROOT)/ace/os_include/os_stdio.h \ + $(ACE_ROOT)/ace/os_include/os_stdarg.h \ + $(ACE_ROOT)/ace/OS_Dirent.inl \ + $(ACE_ROOT)/ace/OS_String.h \ + $(ACE_ROOT)/ace/Basic_Types.h \ + $(ACE_ROOT)/ace/os_include/os_float.h \ + $(ACE_ROOT)/ace/os_include/os_stdlib.h \ + $(ACE_ROOT)/ace/os_include/sys/os_wait.h \ + $(ACE_ROOT)/ace/os_include/os_signal.h \ + $(ACE_ROOT)/ace/os_include/os_time.h \ + $(ACE_ROOT)/ace/os_include/os_ucontext.h \ + $(ACE_ROOT)/ace/os_include/sys/os_resource.h \ + $(ACE_ROOT)/ace/os_include/sys/os_time.h \ + $(ACE_ROOT)/ace/os_include/sys/os_select.h \ + $(ACE_ROOT)/ace/ACE_export.h \ + $(ACE_ROOT)/ace/Basic_Types.i \ + $(ACE_ROOT)/ace/OS_String.inl \ + $(ACE_ROOT)/ace/os_include/os_string.h \ + $(ACE_ROOT)/ace/os_include/os_strings.h \ + $(ACE_ROOT)/ace/os_include/os_ctype.h \ + $(ACE_ROOT)/ace/OS_Memory.h \ + $(ACE_ROOT)/ace/OS_Memory.inl \ + $(ACE_ROOT)/ace/OS_TLI.h \ + $(ACE_ROOT)/ace/OS_TLI.inl \ + $(ACE_ROOT)/ace/os_include/os_dlfcn.h \ + $(ACE_ROOT)/ace/os_include/sys/os_mman.h \ + $(ACE_ROOT)/ace/os_include/os_netdb.h \ + $(ACE_ROOT)/ace/os_include/netinet/os_in.h \ + $(ACE_ROOT)/ace/os_include/sys/os_socket.h \ + $(ACE_ROOT)/ace/os_include/sys/os_uio.h \ + $(ACE_ROOT)/ace/os_include/net/os_if.h \ + $(ACE_ROOT)/ace/os_include/sys/os_sem.h \ + $(ACE_ROOT)/ace/os_include/sys/os_ipc.h \ + $(ACE_ROOT)/ace/Time_Value.h \ + $(ACE_ROOT)/ace/Time_Value.inl \ + $(ACE_ROOT)/ace/Default_Constants.h \ + $(ACE_ROOT)/ace/Global_Macros.h \ + $(ACE_ROOT)/ace/Min_Max.h \ + $(ACE_ROOT)/ace/os_include/os_pthread.h \ + $(ACE_ROOT)/ace/os_include/os_assert.h \ + $(ACE_ROOT)/ace/os_include/os_fcntl.h \ + $(ACE_ROOT)/ace/os_include/sys/os_stat.h \ + $(ACE_ROOT)/ace/iosfwd.h \ + $(ACE_ROOT)/ace/os_include/arpa/os_inet.h \ + $(ACE_ROOT)/ace/os_include/netinet/os_tcp.h \ + $(ACE_ROOT)/ace/os_include/sys/os_shm.h \ + $(ACE_ROOT)/ace/os_include/os_pwd.h \ + $(ACE_ROOT)/ace/os_include/os_stropts.h \ + $(ACE_ROOT)/ace/os_include/os_termios.h \ + $(ACE_ROOT)/ace/os_include/os_aio.h \ + $(ACE_ROOT)/ace/os_include/sys/os_un.h \ + $(ACE_ROOT)/ace/os_include/os_poll.h \ + $(ACE_ROOT)/ace/os_include/sys/os_msg.h \ + $(ACE_ROOT)/ace/os_include/sys/os_utsname.h \ + $(ACE_ROOT)/ace/os_include/os_syslog.h \ + $(ACE_ROOT)/ace/OS.i \ + $(ACE_ROOT)/ace/SString.h \ + $(ACE_ROOT)/ace/SStringfwd.h \ + $(ACE_ROOT)/ace/String_Base.h \ + $(ACE_ROOT)/ace/String_Base_Const.h \ + $(ACE_ROOT)/ace/String_Base.i \ + $(ACE_ROOT)/ace/Malloc_Base.h \ + $(ACE_ROOT)/ace/String_Base.cpp \ + $(ACE_ROOT)/ace/ACE.h \ + $(ACE_ROOT)/ace/Flag_Manip.h \ + $(ACE_ROOT)/ace/Flag_Manip.i \ + $(ACE_ROOT)/ace/Handle_Ops.h \ + $(ACE_ROOT)/ace/Handle_Ops.i \ + $(ACE_ROOT)/ace/Lib_Find.h \ + $(ACE_ROOT)/ace/Lib_Find.i \ + $(ACE_ROOT)/ace/Init_ACE.h \ + $(ACE_ROOT)/ace/Init_ACE.i \ + $(ACE_ROOT)/ace/Sock_Connect.h \ + $(ACE_ROOT)/ace/Sock_Connect.i \ + $(ACE_ROOT)/ace/ACE.i \ + $(ACE_ROOT)/ace/Auto_Ptr.h \ + $(ACE_ROOT)/ace/Auto_Ptr.i \ + $(ACE_ROOT)/ace/Auto_Ptr.cpp \ + $(ACE_ROOT)/ace/SString.i \ + $(ACE_ROOT)/ace/Singleton.h \ + $(ACE_ROOT)/ace/TSS_T.h \ + $(ACE_ROOT)/ace/Lock.h \ + $(ACE_ROOT)/ace/Lock.inl \ + $(ACE_ROOT)/ace/Thread_Mutex.h \ + $(ACE_ROOT)/ace/Thread_Mutex.inl \ + $(ACE_ROOT)/ace/TSS_T.inl \ + $(ACE_ROOT)/ace/TSS_T.cpp \ + $(ACE_ROOT)/ace/Thread.h \ + $(ACE_ROOT)/ace/Thread_Adapter.h \ + $(ACE_ROOT)/ace/Base_Thread_Adapter.h \ + $(ACE_ROOT)/ace/OS_Log_Msg_Attributes.h \ + $(ACE_ROOT)/ace/OS_Log_Msg_Attributes.inl \ + $(ACE_ROOT)/ace/Base_Thread_Adapter.inl \ + $(ACE_ROOT)/ace/Thread_Adapter.inl \ + $(ACE_ROOT)/ace/Thread.i \ + $(ACE_ROOT)/ace/Log_Msg.h \ + $(ACE_ROOT)/ace/Log_Priority.h \ + $(ACE_ROOT)/ace/Guard_T.h \ + $(ACE_ROOT)/ace/Guard_T.inl \ + $(ACE_ROOT)/ace/Guard_T.cpp \ + $(ACE_ROOT)/ace/Singleton.i \ + $(ACE_ROOT)/ace/Singleton.cpp \ + $(ACE_ROOT)/ace/Object_Manager.h \ + $(ACE_ROOT)/ace/Recursive_Thread_Mutex.h \ + $(ACE_ROOT)/ace/Recursive_Thread_Mutex.inl \ + $(ACE_ROOT)/ace/Object_Manager.i \ + $(ACE_ROOT)/ace/Managed_Object.h \ + $(ACE_ROOT)/ace/Managed_Object.i \ + $(ACE_ROOT)/ace/Managed_Object.cpp \ + $(ACE_ROOT)/ace/Framework_Component.h \ + $(ACE_ROOT)/ace/Framework_Component.inl \ + $(ACE_ROOT)/ace/Framework_Component_T.h \ + $(ACE_ROOT)/ace/Framework_Component_T.inl \ + $(ACE_ROOT)/ace/Framework_Component_T.cpp \ + $(ACE_ROOT)/ace/Synch_Traits.h \ + $(ACE_ROOT)/ace/UUID.inl \ + $(ACE_ROOT)/ace/Thread_Manager.h \ + $(ACE_ROOT)/ace/Thread_Exit.h \ + $(ACE_ROOT)/ace/Thread_Control.h \ + $(ACE_ROOT)/ace/Thread_Control.inl \ + $(ACE_ROOT)/ace/Condition_Thread_Mutex.h \ + $(ACE_ROOT)/ace/Condition_Thread_Mutex.inl \ + $(ACE_ROOT)/ace/Unbounded_Queue.h \ + $(ACE_ROOT)/ace/Node.h \ + $(ACE_ROOT)/ace/Node.cpp \ + $(ACE_ROOT)/ace/Unbounded_Queue.inl \ + $(ACE_ROOT)/ace/Unbounded_Queue.cpp \ + $(ACE_ROOT)/ace/Containers.h \ + $(ACE_ROOT)/ace/Containers.i \ + $(ACE_ROOT)/ace/Containers_T.h \ + $(ACE_ROOT)/ace/Array_Base.h \ + $(ACE_ROOT)/ace/Array_Base.inl \ + $(ACE_ROOT)/ace/Array_Base.cpp \ + $(ACE_ROOT)/ace/Unbounded_Set.h \ + $(ACE_ROOT)/ace/Unbounded_Set.inl \ + $(ACE_ROOT)/ace/Unbounded_Set.cpp \ + $(ACE_ROOT)/ace/Containers_T.i \ + $(ACE_ROOT)/ace/Containers_T.cpp \ + $(ACE_ROOT)/ace/Free_List.h \ + $(ACE_ROOT)/ace/Free_List.i \ + $(ACE_ROOT)/ace/Free_List.cpp \ + $(ACE_ROOT)/ace/Thread_Manager.i \ + $(ACE_ROOT)/ace/TMCast/Group.hpp \ + $(ACE_ROOT)/ace/INET_Addr.h \ + $(ACE_ROOT)/ace/Addr.h \ + $(ACE_ROOT)/ace/Addr.i \ + $(ACE_ROOT)/ace/INET_Addr.i \ + $(ACE_ROOT)/ace/TMCast/Export.hpp \ + $(TAO_ROOT)/tao/PortableServer/Servant_Base.h \ + $(TAO_ROOT)/tao/PortableServer/PortableServerC.h \ + $(TAO_ROOT)/tao/CurrentC.h \ + $(TAO_ROOT)/tao/Object.h \ + $(TAO_ROOT)/tao/Policy_ForwardC.h \ + $(TAO_ROOT)/tao/Sequence.h \ + $(TAO_ROOT)/tao/corbafwd.h \ + $(ACE_ROOT)/ace/CDR_Base.h \ + $(ACE_ROOT)/ace/CDR_Base.inl \ + $(TAO_ROOT)/tao/orbconf.h \ + $(TAO_ROOT)/tao/TAO_Export.h \ + $(TAO_ROOT)/tao/corbafwd.i \ + $(TAO_ROOT)/tao/Managed_Types.h \ + $(TAO_ROOT)/tao/Managed_Types.i \ + $(ACE_ROOT)/ace/CORBA_macros.h \ + $(ACE_ROOT)/ace/Exception_Macros.h \ + $(TAO_ROOT)/tao/Sequence.i \ + $(TAO_ROOT)/tao/Sequence_T.h \ + $(TAO_ROOT)/tao/Sequence_T.i \ + $(TAO_ROOT)/tao/Sequence_T.cpp \ + $(TAO_ROOT)/tao/CDR.h \ + $(ACE_ROOT)/ace/CDR_Stream.h \ + $(ACE_ROOT)/ace/Message_Block.h \ + $(ACE_ROOT)/ace/Message_Block.i \ + $(ACE_ROOT)/ace/Message_Block_T.h \ + $(ACE_ROOT)/ace/Message_Block_T.i \ + $(ACE_ROOT)/ace/Message_Block_T.cpp \ + $(ACE_ROOT)/ace/CDR_Stream.i \ + $(TAO_ROOT)/tao/CDR.i \ + $(TAO_ROOT)/tao/Objref_VarOut_T.h \ + $(TAO_ROOT)/tao/varbase.h \ + $(TAO_ROOT)/tao/Objref_VarOut_T.inl \ + $(TAO_ROOT)/tao/Objref_VarOut_T.cpp \ + $(TAO_ROOT)/tao/Environment.h \ + $(TAO_ROOT)/tao/Pseudo_VarOut_T.h \ + $(TAO_ROOT)/tao/Pseudo_VarOut_T.inl \ + $(TAO_ROOT)/tao/Pseudo_VarOut_T.cpp \ + $(TAO_ROOT)/tao/Environment.i \ + $(TAO_ROOT)/tao/Seq_Var_T.h \ + $(TAO_ROOT)/tao/Seq_Var_T.inl \ + $(TAO_ROOT)/tao/Seq_Var_T.cpp \ + $(TAO_ROOT)/tao/Seq_Out_T.h \ + $(TAO_ROOT)/tao/Seq_Out_T.inl \ + $(TAO_ROOT)/tao/Seq_Out_T.cpp \ + $(TAO_ROOT)/tao/Policy_ForwardC.i \ + $(TAO_ROOT)/tao/IOP_IORC.h \ + $(TAO_ROOT)/tao/OctetSeqC.h \ + $(TAO_ROOT)/tao/OctetSeqC.i \ + $(TAO_ROOT)/tao/VarOut_T.h \ + $(TAO_ROOT)/tao/VarOut_T.inl \ + $(TAO_ROOT)/tao/VarOut_T.cpp \ + $(TAO_ROOT)/tao/IOP_IORC.i \ + $(TAO_ROOT)/tao/Object.i \ + $(TAO_ROOT)/tao/Any_Impl_T.h \ + $(TAO_ROOT)/tao/Any.h \ + $(TAO_ROOT)/tao/Typecode.h \ + $(ACE_ROOT)/ace/Hash_Map_Manager_T.h \ + $(ACE_ROOT)/ace/Functor.h \ + $(ACE_ROOT)/ace/Functor.i \ + $(ACE_ROOT)/ace/Functor_T.h \ + $(ACE_ROOT)/ace/Functor_T.i \ + $(ACE_ROOT)/ace/Functor_T.cpp \ + $(ACE_ROOT)/ace/Hash_Map_Manager_T.i \ + $(ACE_ROOT)/ace/Hash_Map_Manager_T.cpp \ + $(TAO_ROOT)/tao/Exception.h \ + $(TAO_ROOT)/tao/Exception.i \ + $(TAO_ROOT)/tao/Typecode.i \ + $(TAO_ROOT)/tao/Any.i \ + $(TAO_ROOT)/tao/Any_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Impl_T.cpp \ + $(TAO_ROOT)/tao/Marshal.h \ + $(TAO_ROOT)/tao/Marshal.i \ + $(TAO_ROOT)/tao/CurrentC.i \ + $(TAO_ROOT)/tao/PortableServer/portableserver_export.h \ + $(TAO_ROOT)/tao/PolicyC.h \ + $(TAO_ROOT)/tao/Remote_Object_Proxy_Impl.h \ + $(TAO_ROOT)/tao/Object_Proxy_Impl.h \ + $(TAO_ROOT)/tao/PolicyC.i \ + $(TAO_ROOT)/tao/Any_Dual_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Dual_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Dual_Impl_T.cpp \ + $(TAO_ROOT)/tao/CORBA_String.h \ + $(TAO_ROOT)/tao/CORBA_String.inl \ + $(TAO_ROOT)/tao/Any_Basic_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Basic_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Basic_Impl_T.cpp \ + $(TAO_ROOT)/tao/PortableServer/PortableServerC.i \ + $(TAO_ROOT)/tao/Abstract_Servant_Base.h \ + $(ACE_ROOT)/ace/Atomic_Op.h \ + $(ACE_ROOT)/ace/Atomic_Op_T.h \ + $(ACE_ROOT)/ace/Atomic_Op_T.i \ + $(ACE_ROOT)/ace/Atomic_Op_T.cpp \ + $(ACE_ROOT)/ace/Atomic_Op.i \ + $(TAO_ROOT)/tao/PortableServer/Servant_Base.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/FT_CORBA_ORBC.h \ + $(TAO_ROOT)/tao/corba.h \ + $(TAO_ROOT)/tao/Any_Special_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Special_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Special_Impl_T.cpp \ + $(TAO_ROOT)/tao/Any_Special_Basic_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Special_Basic_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Special_Basic_Impl_T.cpp \ + $(TAO_ROOT)/tao/debug.h \ + $(TAO_ROOT)/tao/Any_Array_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Array_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Array_Impl_T.cpp \ + $(TAO_ROOT)/tao/NVList.h \ + $(TAO_ROOT)/tao/NVList.i \ + $(TAO_ROOT)/tao/LocalObject.h \ + $(TAO_ROOT)/tao/LocalObject.i \ + $(TAO_ROOT)/tao/Principal.h \ + $(TAO_ROOT)/tao/Principal.i \ + $(TAO_ROOT)/tao/ORB.h \ + $(TAO_ROOT)/tao/ServicesC.h \ + $(TAO_ROOT)/tao/ServicesC.i \ + $(TAO_ROOT)/tao/ObjectIdListC.h \ + $(TAO_ROOT)/tao/ObjectIdListC.i \ + $(TAO_ROOT)/tao/objectid.h \ + $(TAO_ROOT)/tao/ORB.i \ + $(TAO_ROOT)/tao/BoundsC.h \ + $(TAO_ROOT)/tao/BoundsC.i \ + $(TAO_ROOT)/tao/DomainC.h \ + $(TAO_ROOT)/tao/DomainC.i \ + $(TAO_ROOT)/tao/WrongTransactionC.h \ + $(TAO_ROOT)/tao/WrongTransactionC.i \ + $(TAO_ROOT)/tao/StringSeqC.h \ + $(TAO_ROOT)/tao/StringSeqC.i \ + $(TAO_ROOT)/tao/Object_KeyC.h \ + $(TAO_ROOT)/tao/Object_KeyC.i \ + $(TAO_ROOT)/tao/Array_VarOut_T.h \ + $(TAO_ROOT)/tao/Array_VarOut_T.inl \ + $(TAO_ROOT)/tao/Array_VarOut_T.cpp \ + $(TAO_ROOT)/tao/PortableInterceptorC.h \ + $(TAO_ROOT)/tao/PI_ForwardC.h \ + $(TAO_ROOT)/tao/PI_ForwardC.i \ + $(TAO_ROOT)/tao/DynamicC.h \ + $(TAO_ROOT)/tao/DynamicC.i \ + $(TAO_ROOT)/tao/Messaging_SyncScopeC.h \ + $(TAO_ROOT)/tao/Messaging_SyncScopeC.i \ + $(TAO_ROOT)/tao/IOPC.h \ + $(TAO_ROOT)/tao/IOP_CodecC.h \ + $(TAO_ROOT)/tao/IOP_CodecC.i \ + $(TAO_ROOT)/tao/IOPC.i \ + $(TAO_ROOT)/tao/PortableInterceptorC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/FaultTolerance/fault_tol_export.h \ + $(TAO_ROOT)/tao/TimeBaseC.h \ + $(TAO_ROOT)/tao/TimeBaseC.i \ + $(TAO_ROOT)/tao/GIOPC.h \ + $(TAO_ROOT)/tao/GIOPC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/PortableGroupC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/PortableGroup/portablegroup_export.h \ + $(TAO_ROOT)/tao/Messaging/Messaging.h \ + $(TAO_ROOT)/tao/Messaging/messaging_export.h \ + $(TAO_ROOT)/tao/Messaging/MessagingC.h \ + $(TAO_ROOT)/tao/Messaging/Messaging_SyncScope_PolicyC.h \ + $(TAO_ROOT)/tao/Messaging/Messaging_SyncScope_PolicyC.i \ + $(TAO_ROOT)/tao/Messaging/Messaging_RT_PolicyC.h \ + $(TAO_ROOT)/tao/Messaging/Messaging_RT_PolicyC.i \ + $(TAO_ROOT)/tao/Messaging/Messaging_No_ImplC.h \ + $(TAO_ROOT)/tao/Messaging/Messaging_No_ImplC.i \ + $(TAO_ROOT)/tao/Valuetype/Value_VarOut_T.h \ + $(TAO_ROOT)/tao/Valuetype/Value_VarOut_T.inl \ + $(TAO_ROOT)/tao/Valuetype/Value_VarOut_T.cpp \ + $(TAO_ROOT)/tao/Valuetype/ValueBase.h \ + $(TAO_ROOT)/tao/Valuetype/valuetype_export.h \ + $(ACE_ROOT)/ace/Synch_T.h \ + $(ACE_ROOT)/ace/Synch.h \ + $(ACE_ROOT)/ace/Auto_Event.h \ + $(ACE_ROOT)/ace/Event.h \ + $(ACE_ROOT)/ace/Event.inl \ + $(ACE_ROOT)/ace/Auto_Event.inl \ + $(ACE_ROOT)/ace/Barrier.h \ + $(ACE_ROOT)/ace/Barrier.inl \ + $(ACE_ROOT)/ace/Condition_Recursive_Thread_Mutex.h \ + $(ACE_ROOT)/ace/Condition_Recursive_Thread_Mutex.inl \ + $(ACE_ROOT)/ace/Manual_Event.h \ + $(ACE_ROOT)/ace/Manual_Event.inl \ + $(ACE_ROOT)/ace/Mutex.h \ + $(ACE_ROOT)/ace/Mutex.inl \ + $(ACE_ROOT)/ace/Null_Barrier.h \ + $(ACE_ROOT)/ace/Null_Condition.h \ + $(ACE_ROOT)/ace/Null_Mutex.h \ + $(ACE_ROOT)/ace/Null_Semaphore.h \ + $(ACE_ROOT)/ace/RW_Mutex.h \ + $(ACE_ROOT)/ace/RW_Mutex.inl \ + $(ACE_ROOT)/ace/RW_Thread_Mutex.h \ + $(ACE_ROOT)/ace/RW_Thread_Mutex.inl \ + $(ACE_ROOT)/ace/Semaphore.h \ + $(ACE_ROOT)/ace/Semaphore.inl \ + $(ACE_ROOT)/ace/Thread_Semaphore.h \ + $(ACE_ROOT)/ace/Thread_Semaphore.inl \ + $(ACE_ROOT)/ace/TSS_Adapter.h \ + $(ACE_ROOT)/ace/TSS_Adapter.inl \ + $(ACE_ROOT)/ace/Synch.i \ + $(ACE_ROOT)/ace/Lock_Adapter_T.h \ + $(ACE_ROOT)/ace/Lock_Adapter_T.inl \ + $(ACE_ROOT)/ace/Lock_Adapter_T.cpp \ + $(ACE_ROOT)/ace/Reverse_Lock_T.h \ + $(ACE_ROOT)/ace/Reverse_Lock_T.inl \ + $(ACE_ROOT)/ace/Reverse_Lock_T.cpp \ + $(ACE_ROOT)/ace/Condition_T.h \ + $(ACE_ROOT)/ace/Condition_T.inl \ + $(ACE_ROOT)/ace/Condition_T.cpp \ + $(ACE_ROOT)/ace/Synch_T.i \ + $(ACE_ROOT)/ace/Synch_T.cpp \ + $(TAO_ROOT)/tao/Valuetype/ValueBase.inl \ + $(TAO_ROOT)/tao/Valuetype/ValueFactory.h \ + $(TAO_ROOT)/tao/Valuetype/ValueFactory.inl \ + $(TAO_ROOT)/tao/Messaging/MessagingC.i \ + $(TAO_ROOT)/tao/Messaging/TAO_ExtC.h \ + $(TAO_ROOT)/tao/Messaging/TAO_ExtC.i \ + $(TAO_ROOT)/tao/TAOC.h \ + $(TAO_ROOT)/tao/TAOC.i \ + $(TAO_ROOT)/tao/Valuetype/Valuetype_Adapter_Impl.h \ + $(ACE_ROOT)/ace/Service_Config.h \ + $(ACE_ROOT)/ace/XML_Svc_Conf.h \ + $(ACE_ROOT)/ace/Service_Config.i \ + $(ACE_ROOT)/ace/Reactor.h \ + $(ACE_ROOT)/ace/Handle_Set.h \ + $(ACE_ROOT)/ace/Handle_Set.i \ + $(ACE_ROOT)/ace/Timer_Queue.h \ + $(ACE_ROOT)/ace/Timer_Queue_T.h \ + $(ACE_ROOT)/ace/Event_Handler.h \ + $(ACE_ROOT)/ace/Event_Handler.i \ + $(ACE_ROOT)/ace/Timer_Queue_T.i \ + $(ACE_ROOT)/ace/Timer_Queue_T.cpp \ + $(ACE_ROOT)/ace/Signal.h \ + $(ACE_ROOT)/ace/Signal.i \ + $(ACE_ROOT)/ace/Reactor_Timer_Interface.h \ + $(ACE_ROOT)/ace/Reactor.i \ + $(ACE_ROOT)/ace/Reactor_Impl.h \ + $(ACE_ROOT)/ace/Svc_Conf_Tokens.h \ + $(TAO_ROOT)/tao/Valuetype_Adapter.h \ + $(ACE_ROOT)/ace/Service_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.i \ + $(ACE_ROOT)/ace/DLL.h \ + $(ACE_ROOT)/ace/Service_Object.i \ + $(TAO_ROOT)/tao/Valuetype/Sequence_T.h \ + $(TAO_ROOT)/tao/Valuetype/Sequence_T.inl \ + $(TAO_ROOT)/tao/Valuetype/Sequence_T.cpp \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosNamingC.h \ + $(TAO_ROOT)/orbsvcs/orbsvcs/CosNamingC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/PortableGroupC.i \ + $(TAO_ROOT)/orbsvcs/orbsvcs/FT_CORBA_ORBC.i \ + CrashPoint.h StateUpdate.h ReplicaController.h \ + $(ACE_ROOT)/ace/TMCast/GroupFwd.hpp \ + $(TAO_ROOT)/tao/PortableServer/PortableServer.h \ + Log.h LogACE_RB_Tree.h \ + $(ACE_ROOT)/ace/RB_Tree.h \ + $(ACE_ROOT)/ace/RB_Tree.i \ + $(ACE_ROOT)/ace/RB_Tree.cpp + +.obj/ORB_Initializer.o .obj/ORB_Initializer.so .shobj/ORB_Initializer.o .shobj/ORB_Initializer.so: ORB_Initializer.cpp \ + $(TAO_ROOT)/tao/corba.h \ + $(ACE_ROOT)/ace/pre.h \ + $(ACE_ROOT)/ace/post.h \ + $(ACE_ROOT)/ace/ace_wchar.h \ + $(ACE_ROOT)/ace/ace_wchar.inl \ + $(TAO_ROOT)/tao/corbafwd.h \ + $(ACE_ROOT)/ace/CDR_Base.h \ + $(ACE_ROOT)/ace/Basic_Types.h \ + $(ACE_ROOT)/ace/os_include/os_limits.h \ + $(ACE_ROOT)/ace/os_include/os_unistd.h \ + $(ACE_ROOT)/ace/os_include/sys/os_types.h \ + $(ACE_ROOT)/ace/os_include/os_stddef.h \ + $(ACE_ROOT)/ace/os_include/os_inttypes.h \ + $(ACE_ROOT)/ace/os_include/os_stdint.h \ + $(ACE_ROOT)/ace/os_include/os_stdio.h \ + $(ACE_ROOT)/ace/os_include/os_stdarg.h \ + $(ACE_ROOT)/ace/os_include/os_float.h \ + $(ACE_ROOT)/ace/os_include/os_stdlib.h \ + $(ACE_ROOT)/ace/os_include/sys/os_wait.h \ + $(ACE_ROOT)/ace/os_include/os_signal.h \ + $(ACE_ROOT)/ace/os_include/os_time.h \ + $(ACE_ROOT)/ace/os_include/os_ucontext.h \ + $(ACE_ROOT)/ace/os_include/sys/os_resource.h \ + $(ACE_ROOT)/ace/os_include/sys/os_time.h \ + $(ACE_ROOT)/ace/os_include/sys/os_select.h \ + $(ACE_ROOT)/ace/ACE_export.h \ + $(ACE_ROOT)/ace/Basic_Types.i \ + $(ACE_ROOT)/ace/Default_Constants.h \ + $(ACE_ROOT)/ace/CDR_Base.inl \ + $(TAO_ROOT)/tao/orbconf.h \ + $(ACE_ROOT)/ace/Global_Macros.h \ + $(ACE_ROOT)/ace/OS_Export.h \ + $(ACE_ROOT)/ace/Synch_Traits.h \ + $(ACE_ROOT)/ace/Lock.h \ + $(ACE_ROOT)/ace/Lock.inl \ + $(TAO_ROOT)/tao/TAO_Export.h \ + $(TAO_ROOT)/tao/corbafwd.i \ + $(TAO_ROOT)/tao/Typecode.h \ + $(ACE_ROOT)/ace/Hash_Map_Manager_T.h \ + $(ACE_ROOT)/ace/Functor.h \ + $(ACE_ROOT)/ace/Functor.i \ + $(ACE_ROOT)/ace/ACE.h \ + $(ACE_ROOT)/ace/Flag_Manip.h \ + $(ACE_ROOT)/ace/Flag_Manip.i \ + $(ACE_ROOT)/ace/OS.h \ + $(ACE_ROOT)/ace/OS_Dirent.h \ + $(ACE_ROOT)/ace/OS_Errno.h \ + $(ACE_ROOT)/ace/os_include/os_errno.h \ + $(ACE_ROOT)/ace/OS_Errno.inl \ + $(ACE_ROOT)/ace/os_include/os_dirent.h \ + $(ACE_ROOT)/ace/OS_Dirent.inl \ + $(ACE_ROOT)/ace/OS_String.h \ + $(ACE_ROOT)/ace/OS_String.inl \ + $(ACE_ROOT)/ace/os_include/os_string.h \ + $(ACE_ROOT)/ace/os_include/os_strings.h \ + $(ACE_ROOT)/ace/os_include/os_ctype.h \ + $(ACE_ROOT)/ace/OS_Memory.h \ + $(ACE_ROOT)/ace/OS_Memory.inl \ + $(ACE_ROOT)/ace/OS_TLI.h \ + $(ACE_ROOT)/ace/OS_TLI.inl \ + $(ACE_ROOT)/ace/os_include/os_dlfcn.h \ + $(ACE_ROOT)/ace/os_include/sys/os_mman.h \ + $(ACE_ROOT)/ace/os_include/os_netdb.h \ + $(ACE_ROOT)/ace/os_include/netinet/os_in.h \ + $(ACE_ROOT)/ace/os_include/sys/os_socket.h \ + $(ACE_ROOT)/ace/os_include/sys/os_uio.h \ + $(ACE_ROOT)/ace/os_include/net/os_if.h \ + $(ACE_ROOT)/ace/os_include/sys/os_sem.h \ + $(ACE_ROOT)/ace/os_include/sys/os_ipc.h \ + $(ACE_ROOT)/ace/Time_Value.h \ + $(ACE_ROOT)/ace/Time_Value.inl \ + $(ACE_ROOT)/ace/Min_Max.h \ + $(ACE_ROOT)/ace/os_include/os_pthread.h \ + $(ACE_ROOT)/ace/os_include/os_assert.h \ + $(ACE_ROOT)/ace/os_include/os_fcntl.h \ + $(ACE_ROOT)/ace/os_include/sys/os_stat.h \ + $(ACE_ROOT)/ace/iosfwd.h \ + $(ACE_ROOT)/ace/os_include/arpa/os_inet.h \ + $(ACE_ROOT)/ace/os_include/netinet/os_tcp.h \ + $(ACE_ROOT)/ace/os_include/sys/os_shm.h \ + $(ACE_ROOT)/ace/os_include/os_pwd.h \ + $(ACE_ROOT)/ace/os_include/os_stropts.h \ + $(ACE_ROOT)/ace/os_include/os_termios.h \ + $(ACE_ROOT)/ace/os_include/os_aio.h \ + $(ACE_ROOT)/ace/os_include/sys/os_un.h \ + $(ACE_ROOT)/ace/os_include/os_poll.h \ + $(ACE_ROOT)/ace/os_include/sys/os_msg.h \ + $(ACE_ROOT)/ace/os_include/sys/os_utsname.h \ + $(ACE_ROOT)/ace/os_include/os_syslog.h \ + $(ACE_ROOT)/ace/OS.i \ + $(ACE_ROOT)/ace/Handle_Ops.h \ + $(ACE_ROOT)/ace/Handle_Ops.i \ + $(ACE_ROOT)/ace/Lib_Find.h \ + $(ACE_ROOT)/ace/Lib_Find.i \ + $(ACE_ROOT)/ace/Init_ACE.h \ + $(ACE_ROOT)/ace/Init_ACE.i \ + $(ACE_ROOT)/ace/Sock_Connect.h \ + $(ACE_ROOT)/ace/Sock_Connect.i \ + $(ACE_ROOT)/ace/ACE.i \ + $(ACE_ROOT)/ace/Functor_T.h \ + $(ACE_ROOT)/ace/Functor_T.i \ + $(ACE_ROOT)/ace/Functor_T.cpp \ + $(ACE_ROOT)/ace/Log_Msg.h \ + $(ACE_ROOT)/ace/Log_Priority.h \ + $(ACE_ROOT)/ace/OS_Log_Msg_Attributes.h \ + $(ACE_ROOT)/ace/OS_Log_Msg_Attributes.inl \ + $(ACE_ROOT)/ace/Hash_Map_Manager_T.i \ + $(ACE_ROOT)/ace/Guard_T.h \ + $(ACE_ROOT)/ace/Guard_T.inl \ + $(ACE_ROOT)/ace/Guard_T.cpp \ + $(ACE_ROOT)/ace/Hash_Map_Manager_T.cpp \ + $(ACE_ROOT)/ace/Malloc_Base.h \ + $(ACE_ROOT)/ace/Unbounded_Queue.h \ + $(ACE_ROOT)/ace/Node.h \ + $(ACE_ROOT)/ace/Node.cpp \ + $(ACE_ROOT)/ace/Unbounded_Queue.inl \ + $(ACE_ROOT)/ace/Unbounded_Queue.cpp \ + $(ACE_ROOT)/ace/Thread_Mutex.h \ + $(ACE_ROOT)/ace/Thread_Mutex.inl \ + $(TAO_ROOT)/tao/Exception.h \ + $(ACE_ROOT)/ace/CORBA_macros.h \ + $(ACE_ROOT)/ace/Exception_Macros.h \ + $(ACE_ROOT)/ace/SStringfwd.h \ + $(TAO_ROOT)/tao/Exception.i \ + $(TAO_ROOT)/tao/Pseudo_VarOut_T.h \ + $(TAO_ROOT)/tao/Pseudo_VarOut_T.inl \ + $(TAO_ROOT)/tao/Pseudo_VarOut_T.cpp \ + $(TAO_ROOT)/tao/Typecode.i \ + $(TAO_ROOT)/tao/Any_Impl_T.h \ + $(TAO_ROOT)/tao/Any.h \ + $(ACE_ROOT)/ace/CDR_Stream.h \ + $(ACE_ROOT)/ace/Message_Block.h \ + $(ACE_ROOT)/ace/Message_Block.i \ + $(ACE_ROOT)/ace/Message_Block_T.h \ + $(ACE_ROOT)/ace/Message_Block_T.i \ + $(ACE_ROOT)/ace/Message_Block_T.cpp \ + $(ACE_ROOT)/ace/CDR_Stream.i \ + $(TAO_ROOT)/tao/Any.i \ + $(TAO_ROOT)/tao/Any_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Impl_T.cpp \ + $(TAO_ROOT)/tao/Marshal.h \ + $(TAO_ROOT)/tao/Marshal.i \ + $(TAO_ROOT)/tao/CDR.h \ + $(TAO_ROOT)/tao/CDR.i \ + $(TAO_ROOT)/tao/Environment.h \ + $(TAO_ROOT)/tao/Environment.i \ + $(ACE_ROOT)/ace/Auto_Ptr.h \ + $(ACE_ROOT)/ace/Auto_Ptr.i \ + $(ACE_ROOT)/ace/Auto_Ptr.cpp \ + $(TAO_ROOT)/tao/Any_Basic_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Basic_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Basic_Impl_T.cpp \ + $(TAO_ROOT)/tao/Any_Special_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Special_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Special_Impl_T.cpp \ + $(TAO_ROOT)/tao/Any_Special_Basic_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Special_Basic_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Special_Basic_Impl_T.cpp \ + $(TAO_ROOT)/tao/debug.h \ + $(TAO_ROOT)/tao/Any_Array_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Array_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Array_Impl_T.cpp \ + $(TAO_ROOT)/tao/Any_Dual_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Dual_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Dual_Impl_T.cpp \ + $(TAO_ROOT)/tao/CORBA_String.h \ + $(TAO_ROOT)/tao/Managed_Types.h \ + $(TAO_ROOT)/tao/Managed_Types.i \ + $(TAO_ROOT)/tao/CORBA_String.inl \ + $(TAO_ROOT)/tao/NVList.h \ + $(TAO_ROOT)/tao/NVList.i \ + $(TAO_ROOT)/tao/Object.h \ + $(TAO_ROOT)/tao/Policy_ForwardC.h \ + $(TAO_ROOT)/tao/Sequence.h \ + $(TAO_ROOT)/tao/Sequence.i \ + $(TAO_ROOT)/tao/Sequence_T.h \ + $(TAO_ROOT)/tao/Sequence_T.i \ + $(TAO_ROOT)/tao/Sequence_T.cpp \ + $(TAO_ROOT)/tao/Objref_VarOut_T.h \ + $(TAO_ROOT)/tao/varbase.h \ + $(TAO_ROOT)/tao/Objref_VarOut_T.inl \ + $(TAO_ROOT)/tao/Objref_VarOut_T.cpp \ + $(TAO_ROOT)/tao/Seq_Var_T.h \ + $(TAO_ROOT)/tao/Seq_Var_T.inl \ + $(TAO_ROOT)/tao/Seq_Var_T.cpp \ + $(TAO_ROOT)/tao/Seq_Out_T.h \ + $(TAO_ROOT)/tao/Seq_Out_T.inl \ + $(TAO_ROOT)/tao/Seq_Out_T.cpp \ + $(TAO_ROOT)/tao/Policy_ForwardC.i \ + $(TAO_ROOT)/tao/IOP_IORC.h \ + $(TAO_ROOT)/tao/OctetSeqC.h \ + $(TAO_ROOT)/tao/OctetSeqC.i \ + $(TAO_ROOT)/tao/VarOut_T.h \ + $(TAO_ROOT)/tao/VarOut_T.inl \ + $(TAO_ROOT)/tao/VarOut_T.cpp \ + $(TAO_ROOT)/tao/IOP_IORC.i \ + $(TAO_ROOT)/tao/Object.i \ + $(TAO_ROOT)/tao/LocalObject.h \ + $(TAO_ROOT)/tao/LocalObject.i \ + $(TAO_ROOT)/tao/Principal.h \ + $(TAO_ROOT)/tao/Principal.i \ + $(TAO_ROOT)/tao/ORB.h \ + $(TAO_ROOT)/tao/ServicesC.h \ + $(TAO_ROOT)/tao/ServicesC.i \ + $(TAO_ROOT)/tao/ObjectIdListC.h \ + $(TAO_ROOT)/tao/ObjectIdListC.i \ + $(TAO_ROOT)/tao/objectid.h \ + $(TAO_ROOT)/tao/PolicyC.h \ + $(TAO_ROOT)/tao/CurrentC.h \ + $(TAO_ROOT)/tao/CurrentC.i \ + $(TAO_ROOT)/tao/Remote_Object_Proxy_Impl.h \ + $(TAO_ROOT)/tao/Object_Proxy_Impl.h \ + $(TAO_ROOT)/tao/PolicyC.i \ + $(TAO_ROOT)/tao/ORB.i \ + $(TAO_ROOT)/tao/BoundsC.h \ + $(TAO_ROOT)/tao/BoundsC.i \ + $(TAO_ROOT)/tao/DomainC.h \ + $(TAO_ROOT)/tao/DomainC.i \ + $(TAO_ROOT)/tao/WrongTransactionC.h \ + $(TAO_ROOT)/tao/WrongTransactionC.i \ + $(TAO_ROOT)/tao/StringSeqC.h \ + $(TAO_ROOT)/tao/StringSeqC.i \ + $(TAO_ROOT)/tao/Object_KeyC.h \ + $(TAO_ROOT)/tao/Object_KeyC.i \ + $(TAO_ROOT)/tao/Array_VarOut_T.h \ + $(TAO_ROOT)/tao/Array_VarOut_T.inl \ + $(TAO_ROOT)/tao/Array_VarOut_T.cpp \ + $(TAO_ROOT)/tao/PortableInterceptorC.h \ + $(TAO_ROOT)/tao/PI_ForwardC.h \ + $(TAO_ROOT)/tao/PI_ForwardC.i \ + $(TAO_ROOT)/tao/DynamicC.h \ + $(TAO_ROOT)/tao/DynamicC.i \ + $(TAO_ROOT)/tao/Messaging_SyncScopeC.h \ + $(TAO_ROOT)/tao/Messaging_SyncScopeC.i \ + $(TAO_ROOT)/tao/IOPC.h \ + $(TAO_ROOT)/tao/IOP_CodecC.h \ + $(TAO_ROOT)/tao/IOP_CodecC.i \ + $(TAO_ROOT)/tao/IOPC.i \ + $(TAO_ROOT)/tao/PortableInterceptorC.i \ + $(TAO_ROOT)/tao/ORBInitInfo.h \ + $(TAO_ROOT)/tao/ORBInitInfo.inl \ + $(TAO_ROOT)/tao/ORB_Core.h \ + $(TAO_ROOT)/tao/Resource_Factory.h \ + $(ACE_ROOT)/ace/Service_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.i \ + $(ACE_ROOT)/ace/Svc_Conf_Tokens.h \ + $(ACE_ROOT)/ace/Event_Handler.h \ + $(ACE_ROOT)/ace/Atomic_Op.h \ + $(ACE_ROOT)/ace/Atomic_Op_T.h \ + $(ACE_ROOT)/ace/Atomic_Op_T.i \ + $(ACE_ROOT)/ace/Atomic_Op_T.cpp \ + $(ACE_ROOT)/ace/Atomic_Op.i \ + $(ACE_ROOT)/ace/Event_Handler.i \ + $(ACE_ROOT)/ace/DLL.h \ + $(ACE_ROOT)/ace/Service_Object.i \ + $(ACE_ROOT)/ace/Unbounded_Set.h \ + $(ACE_ROOT)/ace/Unbounded_Set.inl \ + $(ACE_ROOT)/ace/Unbounded_Set.cpp \ + $(TAO_ROOT)/tao/CONV_FRAMEC.h \ + $(TAO_ROOT)/tao/CONV_FRAMEC.i \ + $(ACE_ROOT)/ace/SString.h \ + $(ACE_ROOT)/ace/String_Base.h \ + $(ACE_ROOT)/ace/String_Base_Const.h \ + $(ACE_ROOT)/ace/String_Base.i \ + $(ACE_ROOT)/ace/String_Base.cpp \ + $(ACE_ROOT)/ace/SString.i \ + $(TAO_ROOT)/tao/params.h \ + $(TAO_ROOT)/tao/params.i \ + $(TAO_ROOT)/tao/Adapter.h \ + $(TAO_ROOT)/tao/Adapter.i \ + $(TAO_ROOT)/tao/PolicyFactory_Registry.h \ + $(ACE_ROOT)/ace/Map_Manager.h \ + $(ACE_ROOT)/ace/Map_Manager.i \ + $(ACE_ROOT)/ace/Map_Manager.cpp \ + $(ACE_ROOT)/ace/Null_Mutex.h \ + $(TAO_ROOT)/tao/Parser_Registry.h \ + $(TAO_ROOT)/tao/Parser_Registry.i \ + $(TAO_ROOT)/tao/Service_Callbacks.h \ + $(TAO_ROOT)/tao/Service_Callbacks.i \ + $(TAO_ROOT)/tao/Fault_Tolerance_Service.h \ + $(TAO_ROOT)/tao/Fault_Tolerance_Service.i \ + $(TAO_ROOT)/tao/Cleanup_Func_Registry.h \ + $(ACE_ROOT)/ace/Array_Base.h \ + $(ACE_ROOT)/ace/Array_Base.inl \ + $(ACE_ROOT)/ace/Array_Base.cpp \ + $(TAO_ROOT)/tao/Cleanup_Func_Registry.inl \ + $(TAO_ROOT)/tao/Object_Ref_Table.h \ + $(TAO_ROOT)/tao/ObjectKey_Table.h \ + $(ACE_ROOT)/ace/RB_Tree.h \ + $(ACE_ROOT)/ace/RB_Tree.i \ + $(ACE_ROOT)/ace/RB_Tree.cpp \ + $(TAO_ROOT)/tao/Interceptor_List.h \ + $(TAO_ROOT)/tao/Interceptor_List.inl \ + $(TAO_ROOT)/tao/PICurrent.h \ + $(TAO_ROOT)/tao/PICurrent.inl \ + $(ACE_ROOT)/ace/Thread_Manager.h \ + $(ACE_ROOT)/ace/Thread.h \ + $(ACE_ROOT)/ace/Thread_Adapter.h \ + $(ACE_ROOT)/ace/Base_Thread_Adapter.h \ + $(ACE_ROOT)/ace/Base_Thread_Adapter.inl \ + $(ACE_ROOT)/ace/Thread_Adapter.inl \ + $(ACE_ROOT)/ace/Thread.i \ + $(ACE_ROOT)/ace/Thread_Exit.h \ + $(ACE_ROOT)/ace/Thread_Control.h \ + $(ACE_ROOT)/ace/Thread_Control.inl \ + $(ACE_ROOT)/ace/Condition_Thread_Mutex.h \ + $(ACE_ROOT)/ace/Condition_Thread_Mutex.inl \ + $(ACE_ROOT)/ace/Containers.h \ + $(ACE_ROOT)/ace/Containers.i \ + $(ACE_ROOT)/ace/Containers_T.h \ + $(ACE_ROOT)/ace/Containers_T.i \ + $(ACE_ROOT)/ace/Containers_T.cpp \ + $(ACE_ROOT)/ace/Free_List.h \ + $(ACE_ROOT)/ace/Free_List.i \ + $(ACE_ROOT)/ace/Free_List.cpp \ + $(ACE_ROOT)/ace/Singleton.h \ + $(ACE_ROOT)/ace/TSS_T.h \ + $(ACE_ROOT)/ace/TSS_T.inl \ + $(ACE_ROOT)/ace/TSS_T.cpp \ + $(ACE_ROOT)/ace/Singleton.i \ + $(ACE_ROOT)/ace/Singleton.cpp \ + $(ACE_ROOT)/ace/Object_Manager.h \ + $(ACE_ROOT)/ace/Recursive_Thread_Mutex.h \ + $(ACE_ROOT)/ace/Recursive_Thread_Mutex.inl \ + $(ACE_ROOT)/ace/Object_Manager.i \ + $(ACE_ROOT)/ace/Managed_Object.h \ + $(ACE_ROOT)/ace/Managed_Object.i \ + $(ACE_ROOT)/ace/Managed_Object.cpp \ + $(ACE_ROOT)/ace/Framework_Component.h \ + $(ACE_ROOT)/ace/Framework_Component.inl \ + $(ACE_ROOT)/ace/Framework_Component_T.h \ + $(ACE_ROOT)/ace/Framework_Component_T.inl \ + $(ACE_ROOT)/ace/Framework_Component_T.cpp \ + $(ACE_ROOT)/ace/Thread_Manager.i \ + $(ACE_ROOT)/ace/Lock_Adapter_T.h \ + $(ACE_ROOT)/ace/Lock_Adapter_T.inl \ + $(ACE_ROOT)/ace/Lock_Adapter_T.cpp \ + $(TAO_ROOT)/tao/ORB_Core.i \ + ORB_Initializer.h ReplicaController.h \ + $(ACE_ROOT)/ace/TMCast/GroupFwd.hpp \ + $(ACE_ROOT)/ace/TMCast/Export.hpp \ + $(TAO_ROOT)/tao/PortableServer/PortableServer.h \ + $(TAO_ROOT)/tao/PortableServer/portableserver_export.h \ + $(TAO_ROOT)/tao/PortableServer/PortableServerC.h \ + $(TAO_ROOT)/tao/PortableServer/PortableServerC.i \ + Log.h LogACE_RB_Tree.h $(ACE_ROOT)/ace/Synch.h \ + $(ACE_ROOT)/ace/Auto_Event.h \ + $(ACE_ROOT)/ace/Event.h \ + $(ACE_ROOT)/ace/Event.inl \ + $(ACE_ROOT)/ace/Auto_Event.inl \ + $(ACE_ROOT)/ace/Barrier.h \ + $(ACE_ROOT)/ace/Barrier.inl \ + $(ACE_ROOT)/ace/Condition_Recursive_Thread_Mutex.h \ + $(ACE_ROOT)/ace/Condition_Recursive_Thread_Mutex.inl \ + $(ACE_ROOT)/ace/Manual_Event.h \ + $(ACE_ROOT)/ace/Manual_Event.inl \ + $(ACE_ROOT)/ace/Mutex.h \ + $(ACE_ROOT)/ace/Mutex.inl \ + $(ACE_ROOT)/ace/Null_Barrier.h \ + $(ACE_ROOT)/ace/Null_Condition.h \ + $(ACE_ROOT)/ace/Null_Semaphore.h \ + $(ACE_ROOT)/ace/RW_Mutex.h \ + $(ACE_ROOT)/ace/RW_Mutex.inl \ + $(ACE_ROOT)/ace/RW_Thread_Mutex.h \ + $(ACE_ROOT)/ace/RW_Thread_Mutex.inl \ + $(ACE_ROOT)/ace/Semaphore.h \ + $(ACE_ROOT)/ace/Semaphore.inl \ + $(ACE_ROOT)/ace/Thread_Semaphore.h \ + $(ACE_ROOT)/ace/Thread_Semaphore.inl \ + $(ACE_ROOT)/ace/TSS_Adapter.h \ + $(ACE_ROOT)/ace/TSS_Adapter.inl \ + $(ACE_ROOT)/ace/Synch.i \ + $(ACE_ROOT)/ace/Synch_T.h \ + $(ACE_ROOT)/ace/Reverse_Lock_T.h \ + $(ACE_ROOT)/ace/Reverse_Lock_T.inl \ + $(ACE_ROOT)/ace/Reverse_Lock_T.cpp \ + $(ACE_ROOT)/ace/Condition_T.h \ + $(ACE_ROOT)/ace/Condition_T.inl \ + $(ACE_ROOT)/ace/Condition_T.cpp \ + $(ACE_ROOT)/ace/Synch_T.i \ + $(ACE_ROOT)/ace/Synch_T.cpp + +.obj/RolyPolyC.o .obj/RolyPolyC.so .shobj/RolyPolyC.o .shobj/RolyPolyC.so: RolyPolyC.cpp RolyPolyC.h \ + $(TAO_ROOT)/tao/corba.h \ + $(ACE_ROOT)/ace/pre.h \ + $(ACE_ROOT)/ace/post.h \ + $(ACE_ROOT)/ace/ace_wchar.h \ + $(ACE_ROOT)/ace/ace_wchar.inl \ + $(TAO_ROOT)/tao/corbafwd.h \ + $(ACE_ROOT)/ace/CDR_Base.h \ + $(ACE_ROOT)/ace/Basic_Types.h \ + $(ACE_ROOT)/ace/os_include/os_limits.h \ + $(ACE_ROOT)/ace/os_include/os_unistd.h \ + $(ACE_ROOT)/ace/os_include/sys/os_types.h \ + $(ACE_ROOT)/ace/os_include/os_stddef.h \ + $(ACE_ROOT)/ace/os_include/os_inttypes.h \ + $(ACE_ROOT)/ace/os_include/os_stdint.h \ + $(ACE_ROOT)/ace/os_include/os_stdio.h \ + $(ACE_ROOT)/ace/os_include/os_stdarg.h \ + $(ACE_ROOT)/ace/os_include/os_float.h \ + $(ACE_ROOT)/ace/os_include/os_stdlib.h \ + $(ACE_ROOT)/ace/os_include/sys/os_wait.h \ + $(ACE_ROOT)/ace/os_include/os_signal.h \ + $(ACE_ROOT)/ace/os_include/os_time.h \ + $(ACE_ROOT)/ace/os_include/os_ucontext.h \ + $(ACE_ROOT)/ace/os_include/sys/os_resource.h \ + $(ACE_ROOT)/ace/os_include/sys/os_time.h \ + $(ACE_ROOT)/ace/os_include/sys/os_select.h \ + $(ACE_ROOT)/ace/ACE_export.h \ + $(ACE_ROOT)/ace/Basic_Types.i \ + $(ACE_ROOT)/ace/Default_Constants.h \ + $(ACE_ROOT)/ace/CDR_Base.inl \ + $(TAO_ROOT)/tao/orbconf.h \ + $(ACE_ROOT)/ace/Global_Macros.h \ + $(ACE_ROOT)/ace/OS_Export.h \ + $(ACE_ROOT)/ace/Synch_Traits.h \ + $(ACE_ROOT)/ace/Lock.h \ + $(ACE_ROOT)/ace/Lock.inl \ + $(TAO_ROOT)/tao/TAO_Export.h \ + $(TAO_ROOT)/tao/corbafwd.i \ + $(TAO_ROOT)/tao/Typecode.h \ + $(ACE_ROOT)/ace/Hash_Map_Manager_T.h \ + $(ACE_ROOT)/ace/Functor.h \ + $(ACE_ROOT)/ace/Functor.i \ + $(ACE_ROOT)/ace/ACE.h \ + $(ACE_ROOT)/ace/Flag_Manip.h \ + $(ACE_ROOT)/ace/Flag_Manip.i \ + $(ACE_ROOT)/ace/OS.h \ + $(ACE_ROOT)/ace/OS_Dirent.h \ + $(ACE_ROOT)/ace/OS_Errno.h \ + $(ACE_ROOT)/ace/os_include/os_errno.h \ + $(ACE_ROOT)/ace/OS_Errno.inl \ + $(ACE_ROOT)/ace/os_include/os_dirent.h \ + $(ACE_ROOT)/ace/OS_Dirent.inl \ + $(ACE_ROOT)/ace/OS_String.h \ + $(ACE_ROOT)/ace/OS_String.inl \ + $(ACE_ROOT)/ace/os_include/os_string.h \ + $(ACE_ROOT)/ace/os_include/os_strings.h \ + $(ACE_ROOT)/ace/os_include/os_ctype.h \ + $(ACE_ROOT)/ace/OS_Memory.h \ + $(ACE_ROOT)/ace/OS_Memory.inl \ + $(ACE_ROOT)/ace/OS_TLI.h \ + $(ACE_ROOT)/ace/OS_TLI.inl \ + $(ACE_ROOT)/ace/os_include/os_dlfcn.h \ + $(ACE_ROOT)/ace/os_include/sys/os_mman.h \ + $(ACE_ROOT)/ace/os_include/os_netdb.h \ + $(ACE_ROOT)/ace/os_include/netinet/os_in.h \ + $(ACE_ROOT)/ace/os_include/sys/os_socket.h \ + $(ACE_ROOT)/ace/os_include/sys/os_uio.h \ + $(ACE_ROOT)/ace/os_include/net/os_if.h \ + $(ACE_ROOT)/ace/os_include/sys/os_sem.h \ + $(ACE_ROOT)/ace/os_include/sys/os_ipc.h \ + $(ACE_ROOT)/ace/Time_Value.h \ + $(ACE_ROOT)/ace/Time_Value.inl \ + $(ACE_ROOT)/ace/Min_Max.h \ + $(ACE_ROOT)/ace/os_include/os_pthread.h \ + $(ACE_ROOT)/ace/os_include/os_assert.h \ + $(ACE_ROOT)/ace/os_include/os_fcntl.h \ + $(ACE_ROOT)/ace/os_include/sys/os_stat.h \ + $(ACE_ROOT)/ace/iosfwd.h \ + $(ACE_ROOT)/ace/os_include/arpa/os_inet.h \ + $(ACE_ROOT)/ace/os_include/netinet/os_tcp.h \ + $(ACE_ROOT)/ace/os_include/sys/os_shm.h \ + $(ACE_ROOT)/ace/os_include/os_pwd.h \ + $(ACE_ROOT)/ace/os_include/os_stropts.h \ + $(ACE_ROOT)/ace/os_include/os_termios.h \ + $(ACE_ROOT)/ace/os_include/os_aio.h \ + $(ACE_ROOT)/ace/os_include/sys/os_un.h \ + $(ACE_ROOT)/ace/os_include/os_poll.h \ + $(ACE_ROOT)/ace/os_include/sys/os_msg.h \ + $(ACE_ROOT)/ace/os_include/sys/os_utsname.h \ + $(ACE_ROOT)/ace/os_include/os_syslog.h \ + $(ACE_ROOT)/ace/OS.i \ + $(ACE_ROOT)/ace/Handle_Ops.h \ + $(ACE_ROOT)/ace/Handle_Ops.i \ + $(ACE_ROOT)/ace/Lib_Find.h \ + $(ACE_ROOT)/ace/Lib_Find.i \ + $(ACE_ROOT)/ace/Init_ACE.h \ + $(ACE_ROOT)/ace/Init_ACE.i \ + $(ACE_ROOT)/ace/Sock_Connect.h \ + $(ACE_ROOT)/ace/Sock_Connect.i \ + $(ACE_ROOT)/ace/ACE.i \ + $(ACE_ROOT)/ace/Functor_T.h \ + $(ACE_ROOT)/ace/Functor_T.i \ + $(ACE_ROOT)/ace/Functor_T.cpp \ + $(ACE_ROOT)/ace/Log_Msg.h \ + $(ACE_ROOT)/ace/Log_Priority.h \ + $(ACE_ROOT)/ace/OS_Log_Msg_Attributes.h \ + $(ACE_ROOT)/ace/OS_Log_Msg_Attributes.inl \ + $(ACE_ROOT)/ace/Hash_Map_Manager_T.i \ + $(ACE_ROOT)/ace/Guard_T.h \ + $(ACE_ROOT)/ace/Guard_T.inl \ + $(ACE_ROOT)/ace/Guard_T.cpp \ + $(ACE_ROOT)/ace/Hash_Map_Manager_T.cpp \ + $(ACE_ROOT)/ace/Malloc_Base.h \ + $(ACE_ROOT)/ace/Unbounded_Queue.h \ + $(ACE_ROOT)/ace/Node.h \ + $(ACE_ROOT)/ace/Node.cpp \ + $(ACE_ROOT)/ace/Unbounded_Queue.inl \ + $(ACE_ROOT)/ace/Unbounded_Queue.cpp \ + $(ACE_ROOT)/ace/Thread_Mutex.h \ + $(ACE_ROOT)/ace/Thread_Mutex.inl \ + $(TAO_ROOT)/tao/Exception.h \ + $(ACE_ROOT)/ace/CORBA_macros.h \ + $(ACE_ROOT)/ace/Exception_Macros.h \ + $(ACE_ROOT)/ace/SStringfwd.h \ + $(TAO_ROOT)/tao/Exception.i \ + $(TAO_ROOT)/tao/Pseudo_VarOut_T.h \ + $(TAO_ROOT)/tao/Pseudo_VarOut_T.inl \ + $(TAO_ROOT)/tao/Pseudo_VarOut_T.cpp \ + $(TAO_ROOT)/tao/Typecode.i \ + $(TAO_ROOT)/tao/Any_Impl_T.h \ + $(TAO_ROOT)/tao/Any.h \ + $(ACE_ROOT)/ace/CDR_Stream.h \ + $(ACE_ROOT)/ace/Message_Block.h \ + $(ACE_ROOT)/ace/Message_Block.i \ + $(ACE_ROOT)/ace/Message_Block_T.h \ + $(ACE_ROOT)/ace/Message_Block_T.i \ + $(ACE_ROOT)/ace/Message_Block_T.cpp \ + $(ACE_ROOT)/ace/CDR_Stream.i \ + $(TAO_ROOT)/tao/Any.i \ + $(TAO_ROOT)/tao/Any_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Impl_T.cpp \ + $(TAO_ROOT)/tao/Marshal.h \ + $(TAO_ROOT)/tao/Marshal.i \ + $(TAO_ROOT)/tao/CDR.h \ + $(TAO_ROOT)/tao/CDR.i \ + $(TAO_ROOT)/tao/Environment.h \ + $(TAO_ROOT)/tao/Environment.i \ + $(ACE_ROOT)/ace/Auto_Ptr.h \ + $(ACE_ROOT)/ace/Auto_Ptr.i \ + $(ACE_ROOT)/ace/Auto_Ptr.cpp \ + $(TAO_ROOT)/tao/Any_Basic_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Basic_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Basic_Impl_T.cpp \ + $(TAO_ROOT)/tao/Any_Special_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Special_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Special_Impl_T.cpp \ + $(TAO_ROOT)/tao/Any_Special_Basic_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Special_Basic_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Special_Basic_Impl_T.cpp \ + $(TAO_ROOT)/tao/debug.h \ + $(TAO_ROOT)/tao/Any_Array_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Array_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Array_Impl_T.cpp \ + $(TAO_ROOT)/tao/Any_Dual_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Dual_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Dual_Impl_T.cpp \ + $(TAO_ROOT)/tao/CORBA_String.h \ + $(TAO_ROOT)/tao/Managed_Types.h \ + $(TAO_ROOT)/tao/Managed_Types.i \ + $(TAO_ROOT)/tao/CORBA_String.inl \ + $(TAO_ROOT)/tao/NVList.h \ + $(TAO_ROOT)/tao/NVList.i \ + $(TAO_ROOT)/tao/Object.h \ + $(TAO_ROOT)/tao/Policy_ForwardC.h \ + $(TAO_ROOT)/tao/Sequence.h \ + $(TAO_ROOT)/tao/Sequence.i \ + $(TAO_ROOT)/tao/Sequence_T.h \ + $(TAO_ROOT)/tao/Sequence_T.i \ + $(TAO_ROOT)/tao/Sequence_T.cpp \ + $(TAO_ROOT)/tao/Objref_VarOut_T.h \ + $(TAO_ROOT)/tao/varbase.h \ + $(TAO_ROOT)/tao/Objref_VarOut_T.inl \ + $(TAO_ROOT)/tao/Objref_VarOut_T.cpp \ + $(TAO_ROOT)/tao/Seq_Var_T.h \ + $(TAO_ROOT)/tao/Seq_Var_T.inl \ + $(TAO_ROOT)/tao/Seq_Var_T.cpp \ + $(TAO_ROOT)/tao/Seq_Out_T.h \ + $(TAO_ROOT)/tao/Seq_Out_T.inl \ + $(TAO_ROOT)/tao/Seq_Out_T.cpp \ + $(TAO_ROOT)/tao/Policy_ForwardC.i \ + $(TAO_ROOT)/tao/IOP_IORC.h \ + $(TAO_ROOT)/tao/OctetSeqC.h \ + $(TAO_ROOT)/tao/OctetSeqC.i \ + $(TAO_ROOT)/tao/VarOut_T.h \ + $(TAO_ROOT)/tao/VarOut_T.inl \ + $(TAO_ROOT)/tao/VarOut_T.cpp \ + $(TAO_ROOT)/tao/IOP_IORC.i \ + $(TAO_ROOT)/tao/Object.i \ + $(TAO_ROOT)/tao/LocalObject.h \ + $(TAO_ROOT)/tao/LocalObject.i \ + $(TAO_ROOT)/tao/Principal.h \ + $(TAO_ROOT)/tao/Principal.i \ + $(TAO_ROOT)/tao/ORB.h \ + $(TAO_ROOT)/tao/ServicesC.h \ + $(TAO_ROOT)/tao/ServicesC.i \ + $(TAO_ROOT)/tao/ObjectIdListC.h \ + $(TAO_ROOT)/tao/ObjectIdListC.i \ + $(TAO_ROOT)/tao/objectid.h \ + $(TAO_ROOT)/tao/PolicyC.h \ + $(TAO_ROOT)/tao/CurrentC.h \ + $(TAO_ROOT)/tao/CurrentC.i \ + $(TAO_ROOT)/tao/Remote_Object_Proxy_Impl.h \ + $(TAO_ROOT)/tao/Object_Proxy_Impl.h \ + $(TAO_ROOT)/tao/PolicyC.i \ + $(TAO_ROOT)/tao/ORB.i \ + $(TAO_ROOT)/tao/BoundsC.h \ + $(TAO_ROOT)/tao/BoundsC.i \ + $(TAO_ROOT)/tao/DomainC.h \ + $(TAO_ROOT)/tao/DomainC.i \ + $(TAO_ROOT)/tao/WrongTransactionC.h \ + $(TAO_ROOT)/tao/WrongTransactionC.i \ + $(TAO_ROOT)/tao/StringSeqC.h \ + $(TAO_ROOT)/tao/StringSeqC.i \ + $(TAO_ROOT)/tao/Object_KeyC.h \ + $(TAO_ROOT)/tao/Object_KeyC.i \ + $(TAO_ROOT)/tao/Array_VarOut_T.h \ + $(TAO_ROOT)/tao/Array_VarOut_T.inl \ + $(TAO_ROOT)/tao/Array_VarOut_T.cpp \ + $(TAO_ROOT)/tao/PortableInterceptorC.h \ + $(TAO_ROOT)/tao/PI_ForwardC.h \ + $(TAO_ROOT)/tao/PI_ForwardC.i \ + $(TAO_ROOT)/tao/DynamicC.h \ + $(TAO_ROOT)/tao/DynamicC.i \ + $(TAO_ROOT)/tao/Messaging_SyncScopeC.h \ + $(TAO_ROOT)/tao/Messaging_SyncScopeC.i \ + $(TAO_ROOT)/tao/IOPC.h \ + $(TAO_ROOT)/tao/IOP_CodecC.h \ + $(TAO_ROOT)/tao/IOP_CodecC.i \ + $(TAO_ROOT)/tao/IOPC.i \ + $(TAO_ROOT)/tao/PortableInterceptorC.i \ + RolyPolyC.i $(TAO_ROOT)/tao/Stub.h \ + $(TAO_ROOT)/tao/MProfile.h \ + $(ACE_ROOT)/ace/Recursive_Thread_Mutex.h \ + $(ACE_ROOT)/ace/Recursive_Thread_Mutex.inl \ + $(TAO_ROOT)/tao/MProfile.i \ + $(TAO_ROOT)/tao/ORB_Core_Auto_Ptr.h \ + $(TAO_ROOT)/tao/ORB_Core_Auto_Ptr.inl \ + $(TAO_ROOT)/tao/Stub.i \ + $(TAO_ROOT)/tao/ORB_Core.h \ + $(TAO_ROOT)/tao/Resource_Factory.h \ + $(ACE_ROOT)/ace/Service_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.i \ + $(ACE_ROOT)/ace/Svc_Conf_Tokens.h \ + $(ACE_ROOT)/ace/Event_Handler.h \ + $(ACE_ROOT)/ace/Atomic_Op.h \ + $(ACE_ROOT)/ace/Atomic_Op_T.h \ + $(ACE_ROOT)/ace/Atomic_Op_T.i \ + $(ACE_ROOT)/ace/Atomic_Op_T.cpp \ + $(ACE_ROOT)/ace/Atomic_Op.i \ + $(ACE_ROOT)/ace/Event_Handler.i \ + $(ACE_ROOT)/ace/DLL.h \ + $(ACE_ROOT)/ace/Service_Object.i \ + $(ACE_ROOT)/ace/Unbounded_Set.h \ + $(ACE_ROOT)/ace/Unbounded_Set.inl \ + $(ACE_ROOT)/ace/Unbounded_Set.cpp \ + $(TAO_ROOT)/tao/CONV_FRAMEC.h \ + $(TAO_ROOT)/tao/CONV_FRAMEC.i \ + $(ACE_ROOT)/ace/SString.h \ + $(ACE_ROOT)/ace/String_Base.h \ + $(ACE_ROOT)/ace/String_Base_Const.h \ + $(ACE_ROOT)/ace/String_Base.i \ + $(ACE_ROOT)/ace/String_Base.cpp \ + $(ACE_ROOT)/ace/SString.i \ + $(TAO_ROOT)/tao/params.h \ + $(TAO_ROOT)/tao/params.i \ + $(TAO_ROOT)/tao/Adapter.h \ + $(TAO_ROOT)/tao/Adapter.i \ + $(TAO_ROOT)/tao/PolicyFactory_Registry.h \ + $(ACE_ROOT)/ace/Map_Manager.h \ + $(ACE_ROOT)/ace/Map_Manager.i \ + $(ACE_ROOT)/ace/Map_Manager.cpp \ + $(ACE_ROOT)/ace/Null_Mutex.h \ + $(TAO_ROOT)/tao/Parser_Registry.h \ + $(TAO_ROOT)/tao/Parser_Registry.i \ + $(TAO_ROOT)/tao/Service_Callbacks.h \ + $(TAO_ROOT)/tao/Service_Callbacks.i \ + $(TAO_ROOT)/tao/Fault_Tolerance_Service.h \ + $(TAO_ROOT)/tao/Fault_Tolerance_Service.i \ + $(TAO_ROOT)/tao/Cleanup_Func_Registry.h \ + $(ACE_ROOT)/ace/Array_Base.h \ + $(ACE_ROOT)/ace/Array_Base.inl \ + $(ACE_ROOT)/ace/Array_Base.cpp \ + $(TAO_ROOT)/tao/Cleanup_Func_Registry.inl \ + $(TAO_ROOT)/tao/Object_Ref_Table.h \ + $(TAO_ROOT)/tao/ObjectKey_Table.h \ + $(ACE_ROOT)/ace/RB_Tree.h \ + $(ACE_ROOT)/ace/RB_Tree.i \ + $(ACE_ROOT)/ace/RB_Tree.cpp \ + $(TAO_ROOT)/tao/Interceptor_List.h \ + $(TAO_ROOT)/tao/Interceptor_List.inl \ + $(TAO_ROOT)/tao/PICurrent.h \ + $(TAO_ROOT)/tao/PICurrent.inl \ + $(ACE_ROOT)/ace/Thread_Manager.h \ + $(ACE_ROOT)/ace/Thread.h \ + $(ACE_ROOT)/ace/Thread_Adapter.h \ + $(ACE_ROOT)/ace/Base_Thread_Adapter.h \ + $(ACE_ROOT)/ace/Base_Thread_Adapter.inl \ + $(ACE_ROOT)/ace/Thread_Adapter.inl \ + $(ACE_ROOT)/ace/Thread.i \ + $(ACE_ROOT)/ace/Thread_Exit.h \ + $(ACE_ROOT)/ace/Thread_Control.h \ + $(ACE_ROOT)/ace/Thread_Control.inl \ + $(ACE_ROOT)/ace/Condition_Thread_Mutex.h \ + $(ACE_ROOT)/ace/Condition_Thread_Mutex.inl \ + $(ACE_ROOT)/ace/Containers.h \ + $(ACE_ROOT)/ace/Containers.i \ + $(ACE_ROOT)/ace/Containers_T.h \ + $(ACE_ROOT)/ace/Containers_T.i \ + $(ACE_ROOT)/ace/Containers_T.cpp \ + $(ACE_ROOT)/ace/Free_List.h \ + $(ACE_ROOT)/ace/Free_List.i \ + $(ACE_ROOT)/ace/Free_List.cpp \ + $(ACE_ROOT)/ace/Singleton.h \ + $(ACE_ROOT)/ace/TSS_T.h \ + $(ACE_ROOT)/ace/TSS_T.inl \ + $(ACE_ROOT)/ace/TSS_T.cpp \ + $(ACE_ROOT)/ace/Singleton.i \ + $(ACE_ROOT)/ace/Singleton.cpp \ + $(ACE_ROOT)/ace/Object_Manager.h \ + $(ACE_ROOT)/ace/Object_Manager.i \ + $(ACE_ROOT)/ace/Managed_Object.h \ + $(ACE_ROOT)/ace/Managed_Object.i \ + $(ACE_ROOT)/ace/Managed_Object.cpp \ + $(ACE_ROOT)/ace/Framework_Component.h \ + $(ACE_ROOT)/ace/Framework_Component.inl \ + $(ACE_ROOT)/ace/Framework_Component_T.h \ + $(ACE_ROOT)/ace/Framework_Component_T.inl \ + $(ACE_ROOT)/ace/Framework_Component_T.cpp \ + $(ACE_ROOT)/ace/Thread_Manager.i \ + $(ACE_ROOT)/ace/Lock_Adapter_T.h \ + $(ACE_ROOT)/ace/Lock_Adapter_T.inl \ + $(ACE_ROOT)/ace/Lock_Adapter_T.cpp \ + $(TAO_ROOT)/tao/ORB_Core.i \ + $(TAO_ROOT)/tao/Invocation.h \ + $(TAO_ROOT)/tao/Synch_Reply_Dispatcher.h \ + $(TAO_ROOT)/tao/Reply_Dispatcher.h \ + $(TAO_ROOT)/tao/Reply_Dispatcher.i \ + $(TAO_ROOT)/tao/LF_Invocation_Event.h \ + $(TAO_ROOT)/tao/LF_Event.h \ + $(TAO_ROOT)/tao/LF_Event.inl \ + $(TAO_ROOT)/tao/LF_Invocation_Event.inl \ + $(TAO_ROOT)/tao/GIOP_Message_Version.h \ + $(TAO_ROOT)/tao/GIOP_Message_Version.inl \ + $(TAO_ROOT)/tao/operation_details.h \ + $(TAO_ROOT)/tao/Service_Context.h \ + $(TAO_ROOT)/tao/Service_Context.inl \ + $(TAO_ROOT)/tao/target_specification.h \ + $(TAO_ROOT)/tao/target_specification.i \ + $(TAO_ROOT)/tao/operation_details.i \ + $(TAO_ROOT)/tao/Transport.h \ + $(TAO_ROOT)/tao/Transport_Cache_Manager.h \ + $(TAO_ROOT)/tao/Cache_Entries.h \ + $(TAO_ROOT)/tao/Transport_Descriptor_Interface.h \ + $(TAO_ROOT)/tao/Transport_Descriptor_Interface.inl \ + $(ACE_ROOT)/ace/Recyclable.h \ + $(ACE_ROOT)/ace/Recyclable.inl \ + $(TAO_ROOT)/tao/Cache_Entries.inl \ + $(TAO_ROOT)/tao/Transport_Cache_Manager.inl \ + $(TAO_ROOT)/tao/Transport_Timer.h \ + $(TAO_ROOT)/tao/Incoming_Message_Queue.h \ + $(TAO_ROOT)/tao/Pluggable_Messaging_Utils.h \ + $(TAO_ROOT)/tao/Pluggable_Messaging_Utils.i \ + $(TAO_ROOT)/tao/Incoming_Message_Queue.inl \ + $(TAO_ROOT)/tao/Transport.inl \ + $(TAO_ROOT)/tao/Invocation.i \ + $(TAO_ROOT)/tao/PortableInterceptor.h \ + $(TAO_ROOT)/tao/RequestInfo_Util.h \ + $(TAO_ROOT)/tao/ClientRequestInfo_i.h \ + $(TAO_ROOT)/tao/ClientRequestInfo_i.inl \ + $(TAO_ROOT)/tao/ClientInterceptorAdapter.h \ + $(TAO_ROOT)/tao/ClientInterceptorAdapter.inl + +.obj/RolyPolyS.o .obj/RolyPolyS.so .shobj/RolyPolyS.o .shobj/RolyPolyS.so: RolyPolyS.cpp RolyPolyS.h RolyPolyC.h \ + $(TAO_ROOT)/tao/corba.h \ + $(ACE_ROOT)/ace/pre.h \ + $(ACE_ROOT)/ace/post.h \ + $(ACE_ROOT)/ace/ace_wchar.h \ + $(ACE_ROOT)/ace/ace_wchar.inl \ + $(TAO_ROOT)/tao/corbafwd.h \ + $(ACE_ROOT)/ace/CDR_Base.h \ + $(ACE_ROOT)/ace/Basic_Types.h \ + $(ACE_ROOT)/ace/os_include/os_limits.h \ + $(ACE_ROOT)/ace/os_include/os_unistd.h \ + $(ACE_ROOT)/ace/os_include/sys/os_types.h \ + $(ACE_ROOT)/ace/os_include/os_stddef.h \ + $(ACE_ROOT)/ace/os_include/os_inttypes.h \ + $(ACE_ROOT)/ace/os_include/os_stdint.h \ + $(ACE_ROOT)/ace/os_include/os_stdio.h \ + $(ACE_ROOT)/ace/os_include/os_stdarg.h \ + $(ACE_ROOT)/ace/os_include/os_float.h \ + $(ACE_ROOT)/ace/os_include/os_stdlib.h \ + $(ACE_ROOT)/ace/os_include/sys/os_wait.h \ + $(ACE_ROOT)/ace/os_include/os_signal.h \ + $(ACE_ROOT)/ace/os_include/os_time.h \ + $(ACE_ROOT)/ace/os_include/os_ucontext.h \ + $(ACE_ROOT)/ace/os_include/sys/os_resource.h \ + $(ACE_ROOT)/ace/os_include/sys/os_time.h \ + $(ACE_ROOT)/ace/os_include/sys/os_select.h \ + $(ACE_ROOT)/ace/ACE_export.h \ + $(ACE_ROOT)/ace/Basic_Types.i \ + $(ACE_ROOT)/ace/Default_Constants.h \ + $(ACE_ROOT)/ace/CDR_Base.inl \ + $(TAO_ROOT)/tao/orbconf.h \ + $(ACE_ROOT)/ace/Global_Macros.h \ + $(ACE_ROOT)/ace/OS_Export.h \ + $(ACE_ROOT)/ace/Synch_Traits.h \ + $(ACE_ROOT)/ace/Lock.h \ + $(ACE_ROOT)/ace/Lock.inl \ + $(TAO_ROOT)/tao/TAO_Export.h \ + $(TAO_ROOT)/tao/corbafwd.i \ + $(TAO_ROOT)/tao/Typecode.h \ + $(ACE_ROOT)/ace/Hash_Map_Manager_T.h \ + $(ACE_ROOT)/ace/Functor.h \ + $(ACE_ROOT)/ace/Functor.i \ + $(ACE_ROOT)/ace/ACE.h \ + $(ACE_ROOT)/ace/Flag_Manip.h \ + $(ACE_ROOT)/ace/Flag_Manip.i \ + $(ACE_ROOT)/ace/OS.h \ + $(ACE_ROOT)/ace/OS_Dirent.h \ + $(ACE_ROOT)/ace/OS_Errno.h \ + $(ACE_ROOT)/ace/os_include/os_errno.h \ + $(ACE_ROOT)/ace/OS_Errno.inl \ + $(ACE_ROOT)/ace/os_include/os_dirent.h \ + $(ACE_ROOT)/ace/OS_Dirent.inl \ + $(ACE_ROOT)/ace/OS_String.h \ + $(ACE_ROOT)/ace/OS_String.inl \ + $(ACE_ROOT)/ace/os_include/os_string.h \ + $(ACE_ROOT)/ace/os_include/os_strings.h \ + $(ACE_ROOT)/ace/os_include/os_ctype.h \ + $(ACE_ROOT)/ace/OS_Memory.h \ + $(ACE_ROOT)/ace/OS_Memory.inl \ + $(ACE_ROOT)/ace/OS_TLI.h \ + $(ACE_ROOT)/ace/OS_TLI.inl \ + $(ACE_ROOT)/ace/os_include/os_dlfcn.h \ + $(ACE_ROOT)/ace/os_include/sys/os_mman.h \ + $(ACE_ROOT)/ace/os_include/os_netdb.h \ + $(ACE_ROOT)/ace/os_include/netinet/os_in.h \ + $(ACE_ROOT)/ace/os_include/sys/os_socket.h \ + $(ACE_ROOT)/ace/os_include/sys/os_uio.h \ + $(ACE_ROOT)/ace/os_include/net/os_if.h \ + $(ACE_ROOT)/ace/os_include/sys/os_sem.h \ + $(ACE_ROOT)/ace/os_include/sys/os_ipc.h \ + $(ACE_ROOT)/ace/Time_Value.h \ + $(ACE_ROOT)/ace/Time_Value.inl \ + $(ACE_ROOT)/ace/Min_Max.h \ + $(ACE_ROOT)/ace/os_include/os_pthread.h \ + $(ACE_ROOT)/ace/os_include/os_assert.h \ + $(ACE_ROOT)/ace/os_include/os_fcntl.h \ + $(ACE_ROOT)/ace/os_include/sys/os_stat.h \ + $(ACE_ROOT)/ace/iosfwd.h \ + $(ACE_ROOT)/ace/os_include/arpa/os_inet.h \ + $(ACE_ROOT)/ace/os_include/netinet/os_tcp.h \ + $(ACE_ROOT)/ace/os_include/sys/os_shm.h \ + $(ACE_ROOT)/ace/os_include/os_pwd.h \ + $(ACE_ROOT)/ace/os_include/os_stropts.h \ + $(ACE_ROOT)/ace/os_include/os_termios.h \ + $(ACE_ROOT)/ace/os_include/os_aio.h \ + $(ACE_ROOT)/ace/os_include/sys/os_un.h \ + $(ACE_ROOT)/ace/os_include/os_poll.h \ + $(ACE_ROOT)/ace/os_include/sys/os_msg.h \ + $(ACE_ROOT)/ace/os_include/sys/os_utsname.h \ + $(ACE_ROOT)/ace/os_include/os_syslog.h \ + $(ACE_ROOT)/ace/OS.i \ + $(ACE_ROOT)/ace/Handle_Ops.h \ + $(ACE_ROOT)/ace/Handle_Ops.i \ + $(ACE_ROOT)/ace/Lib_Find.h \ + $(ACE_ROOT)/ace/Lib_Find.i \ + $(ACE_ROOT)/ace/Init_ACE.h \ + $(ACE_ROOT)/ace/Init_ACE.i \ + $(ACE_ROOT)/ace/Sock_Connect.h \ + $(ACE_ROOT)/ace/Sock_Connect.i \ + $(ACE_ROOT)/ace/ACE.i \ + $(ACE_ROOT)/ace/Functor_T.h \ + $(ACE_ROOT)/ace/Functor_T.i \ + $(ACE_ROOT)/ace/Functor_T.cpp \ + $(ACE_ROOT)/ace/Log_Msg.h \ + $(ACE_ROOT)/ace/Log_Priority.h \ + $(ACE_ROOT)/ace/OS_Log_Msg_Attributes.h \ + $(ACE_ROOT)/ace/OS_Log_Msg_Attributes.inl \ + $(ACE_ROOT)/ace/Hash_Map_Manager_T.i \ + $(ACE_ROOT)/ace/Guard_T.h \ + $(ACE_ROOT)/ace/Guard_T.inl \ + $(ACE_ROOT)/ace/Guard_T.cpp \ + $(ACE_ROOT)/ace/Hash_Map_Manager_T.cpp \ + $(ACE_ROOT)/ace/Malloc_Base.h \ + $(ACE_ROOT)/ace/Unbounded_Queue.h \ + $(ACE_ROOT)/ace/Node.h \ + $(ACE_ROOT)/ace/Node.cpp \ + $(ACE_ROOT)/ace/Unbounded_Queue.inl \ + $(ACE_ROOT)/ace/Unbounded_Queue.cpp \ + $(ACE_ROOT)/ace/Thread_Mutex.h \ + $(ACE_ROOT)/ace/Thread_Mutex.inl \ + $(TAO_ROOT)/tao/Exception.h \ + $(ACE_ROOT)/ace/CORBA_macros.h \ + $(ACE_ROOT)/ace/Exception_Macros.h \ + $(ACE_ROOT)/ace/SStringfwd.h \ + $(TAO_ROOT)/tao/Exception.i \ + $(TAO_ROOT)/tao/Pseudo_VarOut_T.h \ + $(TAO_ROOT)/tao/Pseudo_VarOut_T.inl \ + $(TAO_ROOT)/tao/Pseudo_VarOut_T.cpp \ + $(TAO_ROOT)/tao/Typecode.i \ + $(TAO_ROOT)/tao/Any_Impl_T.h \ + $(TAO_ROOT)/tao/Any.h \ + $(ACE_ROOT)/ace/CDR_Stream.h \ + $(ACE_ROOT)/ace/Message_Block.h \ + $(ACE_ROOT)/ace/Message_Block.i \ + $(ACE_ROOT)/ace/Message_Block_T.h \ + $(ACE_ROOT)/ace/Message_Block_T.i \ + $(ACE_ROOT)/ace/Message_Block_T.cpp \ + $(ACE_ROOT)/ace/CDR_Stream.i \ + $(TAO_ROOT)/tao/Any.i \ + $(TAO_ROOT)/tao/Any_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Impl_T.cpp \ + $(TAO_ROOT)/tao/Marshal.h \ + $(TAO_ROOT)/tao/Marshal.i \ + $(TAO_ROOT)/tao/CDR.h \ + $(TAO_ROOT)/tao/CDR.i \ + $(TAO_ROOT)/tao/Environment.h \ + $(TAO_ROOT)/tao/Environment.i \ + $(ACE_ROOT)/ace/Auto_Ptr.h \ + $(ACE_ROOT)/ace/Auto_Ptr.i \ + $(ACE_ROOT)/ace/Auto_Ptr.cpp \ + $(TAO_ROOT)/tao/Any_Basic_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Basic_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Basic_Impl_T.cpp \ + $(TAO_ROOT)/tao/Any_Special_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Special_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Special_Impl_T.cpp \ + $(TAO_ROOT)/tao/Any_Special_Basic_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Special_Basic_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Special_Basic_Impl_T.cpp \ + $(TAO_ROOT)/tao/debug.h \ + $(TAO_ROOT)/tao/Any_Array_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Array_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Array_Impl_T.cpp \ + $(TAO_ROOT)/tao/Any_Dual_Impl_T.h \ + $(TAO_ROOT)/tao/Any_Dual_Impl_T.inl \ + $(TAO_ROOT)/tao/Any_Dual_Impl_T.cpp \ + $(TAO_ROOT)/tao/CORBA_String.h \ + $(TAO_ROOT)/tao/Managed_Types.h \ + $(TAO_ROOT)/tao/Managed_Types.i \ + $(TAO_ROOT)/tao/CORBA_String.inl \ + $(TAO_ROOT)/tao/NVList.h \ + $(TAO_ROOT)/tao/NVList.i \ + $(TAO_ROOT)/tao/Object.h \ + $(TAO_ROOT)/tao/Policy_ForwardC.h \ + $(TAO_ROOT)/tao/Sequence.h \ + $(TAO_ROOT)/tao/Sequence.i \ + $(TAO_ROOT)/tao/Sequence_T.h \ + $(TAO_ROOT)/tao/Sequence_T.i \ + $(TAO_ROOT)/tao/Sequence_T.cpp \ + $(TAO_ROOT)/tao/Objref_VarOut_T.h \ + $(TAO_ROOT)/tao/varbase.h \ + $(TAO_ROOT)/tao/Objref_VarOut_T.inl \ + $(TAO_ROOT)/tao/Objref_VarOut_T.cpp \ + $(TAO_ROOT)/tao/Seq_Var_T.h \ + $(TAO_ROOT)/tao/Seq_Var_T.inl \ + $(TAO_ROOT)/tao/Seq_Var_T.cpp \ + $(TAO_ROOT)/tao/Seq_Out_T.h \ + $(TAO_ROOT)/tao/Seq_Out_T.inl \ + $(TAO_ROOT)/tao/Seq_Out_T.cpp \ + $(TAO_ROOT)/tao/Policy_ForwardC.i \ + $(TAO_ROOT)/tao/IOP_IORC.h \ + $(TAO_ROOT)/tao/OctetSeqC.h \ + $(TAO_ROOT)/tao/OctetSeqC.i \ + $(TAO_ROOT)/tao/VarOut_T.h \ + $(TAO_ROOT)/tao/VarOut_T.inl \ + $(TAO_ROOT)/tao/VarOut_T.cpp \ + $(TAO_ROOT)/tao/IOP_IORC.i \ + $(TAO_ROOT)/tao/Object.i \ + $(TAO_ROOT)/tao/LocalObject.h \ + $(TAO_ROOT)/tao/LocalObject.i \ + $(TAO_ROOT)/tao/Principal.h \ + $(TAO_ROOT)/tao/Principal.i \ + $(TAO_ROOT)/tao/ORB.h \ + $(TAO_ROOT)/tao/ServicesC.h \ + $(TAO_ROOT)/tao/ServicesC.i \ + $(TAO_ROOT)/tao/ObjectIdListC.h \ + $(TAO_ROOT)/tao/ObjectIdListC.i \ + $(TAO_ROOT)/tao/objectid.h \ + $(TAO_ROOT)/tao/PolicyC.h \ + $(TAO_ROOT)/tao/CurrentC.h \ + $(TAO_ROOT)/tao/CurrentC.i \ + $(TAO_ROOT)/tao/Remote_Object_Proxy_Impl.h \ + $(TAO_ROOT)/tao/Object_Proxy_Impl.h \ + $(TAO_ROOT)/tao/PolicyC.i \ + $(TAO_ROOT)/tao/ORB.i \ + $(TAO_ROOT)/tao/BoundsC.h \ + $(TAO_ROOT)/tao/BoundsC.i \ + $(TAO_ROOT)/tao/DomainC.h \ + $(TAO_ROOT)/tao/DomainC.i \ + $(TAO_ROOT)/tao/WrongTransactionC.h \ + $(TAO_ROOT)/tao/WrongTransactionC.i \ + $(TAO_ROOT)/tao/StringSeqC.h \ + $(TAO_ROOT)/tao/StringSeqC.i \ + $(TAO_ROOT)/tao/Object_KeyC.h \ + $(TAO_ROOT)/tao/Object_KeyC.i \ + $(TAO_ROOT)/tao/Array_VarOut_T.h \ + $(TAO_ROOT)/tao/Array_VarOut_T.inl \ + $(TAO_ROOT)/tao/Array_VarOut_T.cpp \ + $(TAO_ROOT)/tao/PortableInterceptorC.h \ + $(TAO_ROOT)/tao/PI_ForwardC.h \ + $(TAO_ROOT)/tao/PI_ForwardC.i \ + $(TAO_ROOT)/tao/DynamicC.h \ + $(TAO_ROOT)/tao/DynamicC.i \ + $(TAO_ROOT)/tao/Messaging_SyncScopeC.h \ + $(TAO_ROOT)/tao/Messaging_SyncScopeC.i \ + $(TAO_ROOT)/tao/IOPC.h \ + $(TAO_ROOT)/tao/IOP_CodecC.h \ + $(TAO_ROOT)/tao/IOP_CodecC.i \ + $(TAO_ROOT)/tao/IOPC.i \ + $(TAO_ROOT)/tao/PortableInterceptorC.i \ + RolyPolyC.i \ + $(TAO_ROOT)/tao/PortableServer/PortableServer.h \ + $(TAO_ROOT)/tao/PortableServer/portableserver_export.h \ + $(TAO_ROOT)/tao/PortableServer/PortableServerC.h \ + $(TAO_ROOT)/tao/PortableServer/PortableServerC.i \ + $(TAO_ROOT)/tao/PortableServer/Servant_Base.h \ + $(TAO_ROOT)/tao/Abstract_Servant_Base.h \ + $(ACE_ROOT)/ace/Atomic_Op.h \ + $(ACE_ROOT)/ace/Atomic_Op_T.h \ + $(ACE_ROOT)/ace/Atomic_Op_T.i \ + $(ACE_ROOT)/ace/Atomic_Op_T.cpp \ + $(ACE_ROOT)/ace/Atomic_Op.i \ + $(TAO_ROOT)/tao/PortableServer/Servant_Base.i \ + $(TAO_ROOT)/tao/PortableServer/Collocated_Object.h \ + $(TAO_ROOT)/tao/PortableServer/Collocated_Object.i \ + $(TAO_ROOT)/tao/PortableServer/ThruPOA_Object_Proxy_Impl.h \ + $(TAO_ROOT)/tao/PortableServer/Direct_Object_Proxy_Impl.h \ + RolyPolyS_T.h RolyPolyS_T.i RolyPolyS_T.cpp RolyPolyS.i \ + $(TAO_ROOT)/tao/PortableServer/Object_Adapter.h \ + $(TAO_ROOT)/tao/PortableServer/Key_Adapters.h \ + $(ACE_ROOT)/ace/Map_T.h \ + $(ACE_ROOT)/ace/Pair_T.h \ + $(ACE_ROOT)/ace/Pair_T.i \ + $(ACE_ROOT)/ace/Pair_T.cpp \ + $(ACE_ROOT)/ace/Map_Manager.h \ + $(ACE_ROOT)/ace/Map_Manager.i \ + $(ACE_ROOT)/ace/Map_Manager.cpp \ + $(ACE_ROOT)/ace/Active_Map_Manager.h \ + $(ACE_ROOT)/ace/Active_Map_Manager.i \ + $(ACE_ROOT)/ace/Active_Map_Manager_T.h \ + $(ACE_ROOT)/ace/Null_Mutex.h \ + $(ACE_ROOT)/ace/Active_Map_Manager_T.i \ + $(ACE_ROOT)/ace/Active_Map_Manager_T.cpp \ + $(ACE_ROOT)/ace/Map_T.i \ + $(ACE_ROOT)/ace/Map_T.cpp \ + $(TAO_ROOT)/tao/PortableServer/Key_Adapters.i \ + $(TAO_ROOT)/tao/PortableServer/poa_macros.h \ + $(TAO_ROOT)/tao/PortableServer/Active_Object_Map.h \ + $(TAO_ROOT)/tao/Server_Strategy_Factory.h \ + $(ACE_ROOT)/ace/Service_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.h \ + $(ACE_ROOT)/ace/Shared_Object.i \ + $(ACE_ROOT)/ace/Svc_Conf_Tokens.h \ + $(ACE_ROOT)/ace/Event_Handler.h \ + $(ACE_ROOT)/ace/Event_Handler.i \ + $(ACE_ROOT)/ace/DLL.h \ + $(ACE_ROOT)/ace/Service_Object.i \ + $(TAO_ROOT)/tao/PortableServer/Active_Object_Map.i \ + $(TAO_ROOT)/tao/Adapter.h \ + $(TAO_ROOT)/tao/Adapter.i \ + $(ACE_ROOT)/ace/Service_Config.h \ + $(ACE_ROOT)/ace/Unbounded_Set.h \ + $(ACE_ROOT)/ace/Unbounded_Set.inl \ + $(ACE_ROOT)/ace/Unbounded_Set.cpp \ + $(ACE_ROOT)/ace/SString.h \ + $(ACE_ROOT)/ace/String_Base.h \ + $(ACE_ROOT)/ace/String_Base_Const.h \ + $(ACE_ROOT)/ace/String_Base.i \ + $(ACE_ROOT)/ace/String_Base.cpp \ + $(ACE_ROOT)/ace/SString.i \ + $(ACE_ROOT)/ace/XML_Svc_Conf.h \ + $(ACE_ROOT)/ace/Service_Config.i \ + $(ACE_ROOT)/ace/Reactor.h \ + $(ACE_ROOT)/ace/Handle_Set.h \ + $(ACE_ROOT)/ace/Handle_Set.i \ + $(ACE_ROOT)/ace/Timer_Queue.h \ + $(ACE_ROOT)/ace/Timer_Queue_T.h \ + $(ACE_ROOT)/ace/Free_List.h \ + $(ACE_ROOT)/ace/Free_List.i \ + $(ACE_ROOT)/ace/Free_List.cpp \ + $(ACE_ROOT)/ace/Timer_Queue_T.i \ + $(ACE_ROOT)/ace/Timer_Queue_T.cpp \ + $(ACE_ROOT)/ace/Signal.h \ + $(ACE_ROOT)/ace/Signal.i \ + $(ACE_ROOT)/ace/Reactor_Timer_Interface.h \ + $(ACE_ROOT)/ace/Reactor.i \ + $(ACE_ROOT)/ace/Reactor_Impl.h \ + $(ACE_ROOT)/ace/Reverse_Lock_T.h \ + $(ACE_ROOT)/ace/Reverse_Lock_T.inl \ + $(ACE_ROOT)/ace/Reverse_Lock_T.cpp \ + $(ACE_ROOT)/ace/Condition_Thread_Mutex.h \ + $(ACE_ROOT)/ace/Condition_Thread_Mutex.inl \ + $(TAO_ROOT)/tao/PortableServer/Default_Policy_Validator.h \ + $(TAO_ROOT)/tao/Policy_Validator.h \ + $(TAO_ROOT)/tao/PortableServer/POA_Policy_Set.h \ + $(TAO_ROOT)/tao/PortableServer/POA_Policies.h \ + $(TAO_ROOT)/tao/PortableServer/POA_Policies.i \ + $(TAO_ROOT)/tao/Policy_Set.h \ + $(TAO_ROOT)/tao/Policy_Set.i \ + $(TAO_ROOT)/tao/PortableServer/POA_Policy_Set.i \ + $(TAO_ROOT)/tao/PortableServer/Object_Adapter.i \ + $(TAO_ROOT)/tao/PortableServer/Operation_Table.h \ + $(TAO_ROOT)/tao/TAO_Singleton.h \ + $(ACE_ROOT)/ace/TSS_T.h \ + $(ACE_ROOT)/ace/TSS_T.inl \ + $(ACE_ROOT)/ace/TSS_T.cpp \ + $(ACE_ROOT)/ace/Thread.h \ + $(ACE_ROOT)/ace/Thread_Adapter.h \ + $(ACE_ROOT)/ace/Base_Thread_Adapter.h \ + $(ACE_ROOT)/ace/Base_Thread_Adapter.inl \ + $(ACE_ROOT)/ace/Thread_Adapter.inl \ + $(ACE_ROOT)/ace/Thread.i \ + $(TAO_ROOT)/tao/TAO_Singleton.inl \ + $(TAO_ROOT)/tao/TAO_Singleton.cpp \ + $(ACE_ROOT)/ace/Synch_T.h \ + $(ACE_ROOT)/ace/Synch.h \ + $(ACE_ROOT)/ace/Auto_Event.h \ + $(ACE_ROOT)/ace/Event.h \ + $(ACE_ROOT)/ace/Event.inl \ + $(ACE_ROOT)/ace/Auto_Event.inl \ + $(ACE_ROOT)/ace/Barrier.h \ + $(ACE_ROOT)/ace/Barrier.inl \ + $(ACE_ROOT)/ace/Condition_Recursive_Thread_Mutex.h \ + $(ACE_ROOT)/ace/Recursive_Thread_Mutex.h \ + $(ACE_ROOT)/ace/Recursive_Thread_Mutex.inl \ + $(ACE_ROOT)/ace/Condition_Recursive_Thread_Mutex.inl \ + $(ACE_ROOT)/ace/Manual_Event.h \ + $(ACE_ROOT)/ace/Manual_Event.inl \ + $(ACE_ROOT)/ace/Mutex.h \ + $(ACE_ROOT)/ace/Mutex.inl \ + $(ACE_ROOT)/ace/Null_Barrier.h \ + $(ACE_ROOT)/ace/Null_Condition.h \ + $(ACE_ROOT)/ace/Null_Semaphore.h \ + $(ACE_ROOT)/ace/RW_Mutex.h \ + $(ACE_ROOT)/ace/RW_Mutex.inl \ + $(ACE_ROOT)/ace/RW_Thread_Mutex.h \ + $(ACE_ROOT)/ace/RW_Thread_Mutex.inl \ + $(ACE_ROOT)/ace/Semaphore.h \ + $(ACE_ROOT)/ace/Semaphore.inl \ + $(ACE_ROOT)/ace/Thread_Semaphore.h \ + $(ACE_ROOT)/ace/Thread_Semaphore.inl \ + $(ACE_ROOT)/ace/TSS_Adapter.h \ + $(ACE_ROOT)/ace/TSS_Adapter.inl \ + $(ACE_ROOT)/ace/Synch.i \ + $(ACE_ROOT)/ace/Lock_Adapter_T.h \ + $(ACE_ROOT)/ace/Lock_Adapter_T.inl \ + $(ACE_ROOT)/ace/Lock_Adapter_T.cpp \ + $(ACE_ROOT)/ace/Condition_T.h \ + $(ACE_ROOT)/ace/Condition_T.inl \ + $(ACE_ROOT)/ace/Condition_T.cpp \ + $(ACE_ROOT)/ace/Synch_T.i \ + $(ACE_ROOT)/ace/Synch_T.cpp \ + $(ACE_ROOT)/ace/Object_Manager.h \ + $(ACE_ROOT)/ace/Object_Manager.i \ + $(ACE_ROOT)/ace/Managed_Object.h \ + $(ACE_ROOT)/ace/Managed_Object.i \ + $(ACE_ROOT)/ace/Managed_Object.cpp \ + $(TAO_ROOT)/tao/TAO_Singleton_Manager.h \ + $(TAO_ROOT)/tao/TAO_Singleton_Manager.inl \ + $(ACE_ROOT)/ace/Hash_Map_Manager.h \ + $(TAO_ROOT)/tao/TAO_Server_Request.h \ + $(TAO_ROOT)/tao/Tagged_Profile.h \ + $(TAO_ROOT)/tao/GIOPC.h \ + $(TAO_ROOT)/tao/GIOPC.i \ + $(TAO_ROOT)/tao/Tagged_Profile.i \ + $(TAO_ROOT)/tao/Service_Context.h \ + $(TAO_ROOT)/tao/Service_Context.inl \ + $(TAO_ROOT)/tao/PICurrent.h \ + $(ACE_ROOT)/ace/Array_Base.h \ + $(ACE_ROOT)/ace/Array_Base.inl \ + $(ACE_ROOT)/ace/Array_Base.cpp \ + $(TAO_ROOT)/tao/PICurrent.inl \ + $(TAO_ROOT)/tao/TAO_Server_Request.i \ + $(TAO_ROOT)/tao/ORB_Core.h \ + $(TAO_ROOT)/tao/Resource_Factory.h \ + $(TAO_ROOT)/tao/CONV_FRAMEC.h \ + $(TAO_ROOT)/tao/CONV_FRAMEC.i \ + $(TAO_ROOT)/tao/params.h \ + $(TAO_ROOT)/tao/params.i \ + $(TAO_ROOT)/tao/PolicyFactory_Registry.h \ + $(TAO_ROOT)/tao/Parser_Registry.h \ + $(TAO_ROOT)/tao/Parser_Registry.i \ + $(TAO_ROOT)/tao/Service_Callbacks.h \ + $(TAO_ROOT)/tao/Service_Callbacks.i \ + $(TAO_ROOT)/tao/Fault_Tolerance_Service.h \ + $(TAO_ROOT)/tao/Fault_Tolerance_Service.i \ + $(TAO_ROOT)/tao/Cleanup_Func_Registry.h \ + $(TAO_ROOT)/tao/Cleanup_Func_Registry.inl \ + $(TAO_ROOT)/tao/Object_Ref_Table.h \ + $(TAO_ROOT)/tao/ObjectKey_Table.h \ + $(ACE_ROOT)/ace/RB_Tree.h \ + $(ACE_ROOT)/ace/RB_Tree.i \ + $(ACE_ROOT)/ace/RB_Tree.cpp \ + $(TAO_ROOT)/tao/Interceptor_List.h \ + $(TAO_ROOT)/tao/Interceptor_List.inl \ + $(ACE_ROOT)/ace/Thread_Manager.h \ + $(ACE_ROOT)/ace/Thread_Exit.h \ + $(ACE_ROOT)/ace/Thread_Control.h \ + $(ACE_ROOT)/ace/Thread_Control.inl \ + $(ACE_ROOT)/ace/Containers.h \ + $(ACE_ROOT)/ace/Containers.i \ + $(ACE_ROOT)/ace/Containers_T.h \ + $(ACE_ROOT)/ace/Containers_T.i \ + $(ACE_ROOT)/ace/Containers_T.cpp \ + $(ACE_ROOT)/ace/Singleton.h \ + $(ACE_ROOT)/ace/Singleton.i \ + $(ACE_ROOT)/ace/Singleton.cpp \ + $(ACE_ROOT)/ace/Framework_Component.h \ + $(ACE_ROOT)/ace/Framework_Component.inl \ + $(ACE_ROOT)/ace/Framework_Component_T.h \ + $(ACE_ROOT)/ace/Framework_Component_T.inl \ + $(ACE_ROOT)/ace/Framework_Component_T.cpp \ + $(ACE_ROOT)/ace/Thread_Manager.i \ + $(TAO_ROOT)/tao/ORB_Core.i \ + $(TAO_ROOT)/tao/Profile.h \ + $(TAO_ROOT)/tao/Tagged_Components.h \ + $(TAO_ROOT)/tao/Tagged_Components.i \ + $(TAO_ROOT)/tao/GIOP_Message_Version.h \ + $(TAO_ROOT)/tao/GIOP_Message_Version.inl \ + $(TAO_ROOT)/tao/Refcounted_ObjectKey.h \ + $(TAO_ROOT)/tao/Refcounted_ObjectKey.inl \ + $(TAO_ROOT)/tao/Profile.i \ + $(TAO_ROOT)/tao/Stub.h \ + $(TAO_ROOT)/tao/MProfile.h \ + $(TAO_ROOT)/tao/MProfile.i \ + $(TAO_ROOT)/tao/ORB_Core_Auto_Ptr.h \ + $(TAO_ROOT)/tao/ORB_Core_Auto_Ptr.inl \ + $(TAO_ROOT)/tao/Stub.i \ + $(TAO_ROOT)/tao/IFR_Client_Adapter.h \ + $(TAO_ROOT)/tao/PortableInterceptor.h \ + $(TAO_ROOT)/tao/RequestInfo_Util.h \ + $(TAO_ROOT)/tao/PortableServer/ServerRequestInfo.h \ + $(TAO_ROOT)/tao/PortableServer/ServerRequestInfo.inl \ + $(TAO_ROOT)/tao/PortableServer/ServerInterceptorAdapter.h \ + $(TAO_ROOT)/tao/PortableServer/ServerInterceptorAdapter.inl \ + $(ACE_ROOT)/ace/Dynamic_Service.h \ + $(ACE_ROOT)/ace/Dynamic_Service_Base.h \ + $(ACE_ROOT)/ace/Dynamic_Service.i \ + $(ACE_ROOT)/ace/Dynamic_Service.cpp + +# IF YOU PUT ANYTHING HERE IT WILL GO AWAY diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/ORB_Initializer.cpp b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/ORB_Initializer.cpp new file mode 100644 index 00000000000..0ed88e90501 --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/ORB_Initializer.cpp @@ -0,0 +1,49 @@ +// file : RolyPoly/ORB_Initializer.cpp +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#include "tao/corba.h" +#include "tao/ORBInitInfo.h" +#include "tao/ORB_Core.h" + +#include "ORB_Initializer.h" +#include "ReplicaController.h" + +void +ORB_Initializer::pre_init (PortableInterceptor::ORBInitInfo_ptr + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} + +void +ORB_Initializer::post_init (PortableInterceptor::ORBInitInfo_ptr info + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + // Allocate slot id. + // + state_slot_id (info->allocate_slot_id ()); + + // Register replica controller as server request interceptor. + // + TAO_ORBInitInfo* tao_info (dynamic_cast<TAO_ORBInitInfo*> (info)); + + CORBA::ORB_var orb (tao_info->orb_core ()->orb ()); + + PortableInterceptor::ServerRequestInterceptor_var interceptor; + + ACE_NEW_THROW_EX (interceptor, + ReplicaController (orb.in ()), + CORBA::NO_MEMORY ( + CORBA::SystemException::_tao_minor_code ( + TAO_DEFAULT_MINOR_CODE, + ENOMEM), + CORBA::COMPLETED_NO)); + + ACE_CHECK; + + info->add_server_request_interceptor (interceptor.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/ORB_Initializer.h b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/ORB_Initializer.h new file mode 100644 index 00000000000..0c1d6789351 --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/ORB_Initializer.h @@ -0,0 +1,28 @@ +// file : RolyPoly/ORB_Initializer.h +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#ifndef ORB_INITIALIZER_H +#define ORB_INITIALIZER_H + +#include "tao/LocalObject.h" +#include "tao/PortableInterceptorC.h" + +class ORB_Initializer : + public virtual PortableInterceptor::ORBInitializer, + public virtual TAO_Local_RefCounted_Object +{ +public: + + virtual void + pre_init (PortableInterceptor::ORBInitInfo_ptr info + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void + post_init (PortableInterceptor::ORBInitInfo_ptr info + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); +}; + +#endif /* ORB_INITIALIZER_H */ diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/README b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/README new file mode 100644 index 00000000000..786b42a81d9 --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/README @@ -0,0 +1,105 @@ + + +Overview + +RolyPoly is a simple example that shows how to increase application +reliability by using replication to tolerate faults. It allows you +to start two replicas of the same object which are logically seen as +one object by a client. Furthermore, you can terminate one of the +replicas without interrupting the service provided by the object. + +RolyPoly is using request/reply logging to suppress repeated +requests (thus guaranteeing exactly-once semantic) and state +synchronization (to ensure all replicas are in a consistent +state). Since replicas are generally distributed across multiple +nodes in the network, logging and state synchronizations are +done using multicast group communication protocol. + +In order to make it illustrative, each replica can be set to +fail in one of the predefined places called crash points. The +following crash point numbers are defined: + +0 - no crash point (default). + +1 - fail before reply logging/state synchronization. + +2 - fail after reply logging/state synchronization but before + returning reply to the client. + +Essential difference between crash point 1 and 2 is that in +the second case there should be reply replay while in the +first case request is simply re-executed (this can be observed +in the trace messages of the replicas). + + +Execution Scenario + +In this example scenario we will start three replicas. For one +of them (let us call it primary) we will specify a crash point +other than 0. Then we will start a client to execute requests +on the resulting object. After a few requests, primary will +fail and we will be able to observe transparent shifting of +client to the other replica. Also we will be able to make sure +that, after this shifting, object is still in expected state +(i.e. the sequence of returned numbers is not interrupted and +that, in case of the crash point 2, request is not re-executed). + +Note, due to the underlying group communication architecture, +the group with only one member (replica in our case) can only +exist for a very short period of time. This, in turn, means +that we need to start first two replicas virtually at the same +time. This is also a reason why we need three replicas instead +of two - if one replica is going to fail then the other one +won't live very long alone. For more information on the reasons +why it works this way please see documentation for TMCast +available at $(ACE_ROOT)/ace/TMCast/README. + +Suppose we have node0, node1 and node2 on which we are going +to start our replicas (it could be the same node). Then, to +start our replicas we can execute the following commands: + +node0$ ./server -o replica-0.ior -c 2 +node1$ ./server -o replica-1.ior +node2$ ./server -o replica-2.ior + +When all replicas are up we can start the client: + +$ ./client -k file://replica-0.ior -k file://replica-1.ior + +In this scenario, after executing a few requests, replica-0 +will fail in crash point 2. After that, replica-1 will continue +executing client requests. You can see what's going on with +replicas by looking at various trace messages printed during +execution. + + +Architecture + +The biggest part of the replication logic is carried out by +the ReplicaController. In particular it performs the +following tasks: + +* management of distributed request/reply log + +* state synchronization + +* repeated request suppression + + +Object implementation (interface RolyPoly in our case) can use +two different strategies for delivering state update to the +ReplicaController: + +* push model: client calls Checkpointable::associate_state + to associate the state update with current request. + +* pull model: ReplicaController will call Checkpointable::get_state + implemented by the servant. + +This two model can be used simultaneously. In RolyPoly interface +implementation you can comment out corresponding piece of code to +chose one of the strategies. + +-- +Boris Kolpackov <boris@dre.vanderbilt.edu> + diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/ReplicaController.cpp b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/ReplicaController.cpp new file mode 100644 index 00000000000..bf3c1e9bf0b --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/ReplicaController.cpp @@ -0,0 +1,506 @@ +// file : RolyPoly/ReplicaController.cpp +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#include "ace/UUID.h" +#include "ace/Thread_Manager.h" +#include "ace/TMCast/Group.hpp" + +#include "tao/PortableServer/Servant_Base.h" + +#include "orbsvcs/FT_CORBA_ORBC.h" + +#include "CrashPoint.h" +#include "StateUpdate.h" +#include "ReplicaController.h" + + +// State slot. +// +// + +namespace +{ + PortableInterceptor::SlotId state_slot_id_; +} + +PortableInterceptor::SlotId +state_slot_id () +{ + return state_slot_id_; +} + +void +state_slot_id (PortableInterceptor::SlotId slot_id) +{ + state_slot_id_ = slot_id; +} + +Checkpointable:: +~Checkpointable () +{ +} + +CORBA::Any* Checkpointable:: +get_state () +{ + return 0; +} + +void Checkpointable:: +associate_state (CORBA::ORB_ptr orb, CORBA::Any const& state) +{ + CORBA::Object_var pic_obj = + orb->resolve_initial_references ("PICurrent"); + + PortableInterceptor::Current_var pic = + PortableInterceptor::Current::_narrow (pic_obj.in ()); + + pic->set_slot (state_slot_id (), state); +} + +// ReplyLogger +// +// + +ReplicaController:: +~ReplicaController () +{ +} + +ReplicaController:: +ReplicaController (CORBA::ORB_ptr orb) + : orb_ (CORBA::ORB::_duplicate (orb)) +{ + CORBA::Object_var poa_object = + orb_->resolve_initial_references ("RootPOA"); + + root_poa_ = PortableServer::POA::_narrow (poa_object.in ()); + + // Generate member id + ACE_Utils::UUID uuid; + ACE_Utils::UUID_GENERATOR::instance ()->init (); + ACE_Utils::UUID_GENERATOR::instance ()->generateUUID (uuid); + + ACE_INET_Addr address (10000, "239.255.0.1"); + + ACE_DEBUG ((LM_DEBUG, "Becoming a member with id %s\n", + uuid.to_string ()->c_str ())); + + group_.reset (new TMCast::Group (address, uuid.to_string ()->c_str ())); + + int r = ACE_Thread_Manager::instance ()->spawn ( + &ReplicaController::listener_thunk, this); + + if (r < 0) + { + orb_->shutdown (0); + } +} + +void ReplicaController:: +listener () +{ + try + { + for (char buffer[1024];;) + { + size_t n = group_->recv (buffer, sizeof (buffer)); + + ACE_HEX_DUMP ((LM_DEBUG, buffer, n)); + + TAO_InputCDR cdr (buffer, n); + + CORBA::OctetSeq object_id; + PortableInterceptor::AdapterName adapter_name; + CORBA::String_var client_id; + CORBA::Long retention_id; + CORBA::OctetSeq reply; + CORBA::Any state; + + cdr >> object_id; + cdr >> adapter_name; + cdr >> client_id.out (); + cdr >> retention_id; + cdr >> reply; + cdr >> state; + + if (!cdr.good_bit ()) + { + ACE_DEBUG ((LM_DEBUG, "CDR failed\n")); + //@@ what to do? + } + + ACE_DEBUG ((LM_DEBUG, + "Received log for %s with rid %i\n", + client_id.in (), + retention_id)); + + + RecordId rid (client_id.in (), retention_id); + + CORBA::OctetSeq_var tmp (new CORBA::OctetSeq (reply)); + log_.insert (rid, tmp); + + // Update state. + CORBA::TypeCode_var tc = state.type (); + + if (tc->kind () != CORBA::tk_null) + { + PortableServer::POA_var poa = resolve_poa (adapter_name); + + PortableServer::ServantBase_var servant = + poa->id_to_servant (object_id); + + Checkpointable* target = + dynamic_cast<Checkpointable*> (servant.in ()); + + if (target) target->set_state (state); + } + } + } + catch (TMCast::Group::Failed const&) + { + ACE_DEBUG ((LM_DEBUG, + "Group failure. Perhaps, I am alone in the group.\n")); + } + catch (TMCast::Group::InsufficienSpace const&) + { + ACE_DEBUG ((LM_DEBUG, "Group::InsufficienSpace\n")); + } + + orb_->shutdown (0); +} + +PortableServer::POA_ptr ReplicaController:: +resolve_poa (PortableInterceptor::AdapterName const&) +{ + //@@ Assume for now it's a root poa. + return PortableServer::POA::_duplicate (root_poa_.in ()); +} + + +void* ReplicaController:: +listener_thunk (void* p) +{ + ReplicaController* obj = reinterpret_cast<ReplicaController*> (p); + obj->listener(); + return 0; +} + +namespace +{ + FT::FTRequestServiceContext* + extract_context ( + PortableInterceptor::ServerRequestInfo_ptr ri + ACE_ENV_ARG_DECL) ACE_THROW_SPEC ((CORBA::SystemException)); +} + +void +ReplicaController::tao_ft_interception_point ( + PortableInterceptor::ServerRequestInfo_ptr ri, + CORBA::OctetSeq_out ocs + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)) +{ + FT::FTRequestServiceContext_var ftr ( + extract_context (ri ACE_ENV_ARG_PARAMETER)); + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) Received request from %s with rid %i\n", + ftr->client_id.in (), + ftr->retention_id)); + + // Check if this request is eligible for replay. + + RecordId rid (ftr->client_id.in (), ftr->retention_id); + + if (log_.contains (rid)) + { + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) Replaying reply for %s with rid %i\n", + ftr->client_id.in (), + ftr->retention_id)); + + CORBA::OctetSeq_var copy (log_.lookup (rid)); // make a copy + + ocs = copy._retn (); + } + + return; +} + +void +ReplicaController::send_reply ( + PortableInterceptor::ServerRequestInfo_ptr ri + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + FT::FTRequestServiceContext_var ftr ( + extract_context (ri ACE_ENV_ARG_PARAMETER)); + + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) Sending reply for %s with rid %i\n", + ftr->client_id.in (), + ftr->retention_id)); + + + // Prepare reply for logging. + + CORBA::Any_var result = + ri->result (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + TAO_OutputCDR cdr; + result->impl ()->marshal_value (cdr); + + Dynamic::ParameterList_var pl = + ri->arguments (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + CORBA::ULong len = pl->length (); + + for (CORBA::ULong index = 0; index != len ; ++index) + { + //@@ No chance for PARAM_OUT + if ((*pl)[index].mode == CORBA::PARAM_INOUT) + { + (*pl)[index].argument.impl ()->marshal_value (cdr); + } + } + + CORBA::OctetSeq_var reply; + + ACE_NEW (reply, CORBA::OctetSeq (cdr.total_length ())); + + reply->length (cdr.total_length ()); + + CORBA::Octet* buf = reply->get_buffer (); + + // @@ What if this throws an exception?? We don't have any way to + // check whether this succeeded + for (ACE_Message_Block const* mb = cdr.begin (); + mb != 0; + mb = mb->cont ()) + { + ACE_OS::memcpy (buf, mb->rd_ptr (), mb->length ()); + buf += mb->length (); + } + + // Logging the reply and state update. + // + + // First send message to members. + // + { + // Extract state update. + + CORBA::OctetSeq_var oid = ri->object_id (); + PortableInterceptor::AdapterName_var an = ri->adapter_name (); + + CORBA::Any_var state = ri->get_slot (state_slot_id ()); + + CORBA::TypeCode_var tc = state->type (); + + if (tc->kind () == CORBA::tk_null) + { + ACE_DEBUG ((LM_DEBUG, "Slot update is void\n")); + + PortableServer::POA_var poa = resolve_poa (an); + + PortableServer::ServantBase_var servant = + poa->id_to_servant (oid); + + Checkpointable* target = + dynamic_cast<Checkpointable*> (servant.in ()); + + if (target) + { + CORBA::Any_var tmp = target->get_state (); + + if (tmp != 0) state = tmp._retn (); + } + } + + TAO_OutputCDR cdr; + + cdr << oid; + cdr << an; + cdr << ftr->client_id.in (); + cdr << ftr->retention_id; + cdr << reply.in (); + cdr << *state; + + size_t size = cdr.total_length (); + + CORBA::OctetSeq_var msg; + + ACE_NEW (msg, CORBA::OctetSeq (size)); + + msg->length (size); + + { + CORBA::Octet* buf (msg->get_buffer ()); + + for (ACE_Message_Block const* mb = cdr.begin (); + mb != 0; + mb = mb->cont ()) + { + ACE_OS::memcpy (buf, mb->rd_ptr (), mb->length ()); + buf += mb->length (); + } + } + + CORBA::Octet* buf (msg->get_buffer ()); + + // Crash point 1. + // + if (crash_point == 1 && ftr->retention_id > 2) exit (1); + + try + { + while (true) + { + try + { + group_->send (buf, size); + ACE_DEBUG ((LM_DEBUG, "Sent log record of length %i\n", size)); + break; + } + catch (TMCast::Group::Aborted const&) + { + ACE_DEBUG ((LM_DEBUG, "Retrying to send log record.\n")); + } + } + } + catch (TMCast::Group::Failed const&) + { + ACE_DEBUG ((LM_DEBUG, + "Group failure. Perhaps, I am alone in the group.\n")); + } + } + + + // Now perform local logging. + // + RecordId rid (ftr->client_id.in (), ftr->retention_id); + + // This is slow but eh-safe ;-). + // + log_.insert (rid, reply); + + + // Crash point 2. + // + if (crash_point == 2 && ftr->retention_id > 2) exit (1); +} + + +namespace +{ + FT::FTRequestServiceContext* + extract_context (PortableInterceptor::ServerRequestInfo_ptr ri + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) + { + IOP::ServiceContext_var svc = + ri->get_request_service_context (IOP::FT_REQUEST + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + TAO_InputCDR cdr (ACE_reinterpret_cast (const char*, + svc->context_data.get_buffer ()), + svc->context_data.length ()); + + CORBA::Boolean byte_order; + + if ((cdr >> ACE_InputCDR::to_boolean (byte_order)) == 0) + { + //@@ what to throw? + ACE_THROW (CORBA::BAD_CONTEXT ()); + } + + cdr.reset_byte_order (ACE_static_cast (int,byte_order)); + + // Funny, the following two lines should normally translate + // just to one ctor call. But because we have to use this + // ACE_NEW macro hackery we have a default ctor call plus + // assignment operator call. Yet another example how the + // majority is being penalized by some broken platforms. + // + FT::FTRequestServiceContext_var req; + + //@@ completed status maybe wrong + // + ACE_NEW_THROW_EX (req, + FT::FTRequestServiceContext, + CORBA::NO_MEMORY ( + CORBA::SystemException::_tao_minor_code ( + TAO_DEFAULT_MINOR_CODE, + ENOMEM), + CORBA::COMPLETED_NO)); + + cdr >> *req; + + if (!cdr.good_bit ()) + { + //@@ what to throw? + ACE_THROW (CORBA::UNKNOWN ()); + } + + return req._retn (); + } +} + + +char* +ReplicaController::name (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + return CORBA::string_dup ("ReplicaController"); +} + +void +ReplicaController::send_exception ( + PortableInterceptor::ServerRequestInfo_ptr + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)) +{ +} + +void +ReplicaController::send_other ( + PortableInterceptor::ServerRequestInfo_ptr + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)) +{ +} + +void +ReplicaController::destroy (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} + +void +ReplicaController::receive_request_service_contexts ( + PortableInterceptor::ServerRequestInfo_ptr + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)) +{ + +} + +void +ReplicaController::receive_request ( + PortableInterceptor::ServerRequestInfo_ptr + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)) +{ +} diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/ReplicaController.h b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/ReplicaController.h new file mode 100644 index 00000000000..571df6cabfe --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/ReplicaController.h @@ -0,0 +1,136 @@ +// file : RolyPoly/ReplicaController.h +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#ifndef REPLICA_CONTROLLER_H +#define REPLICA_CONTROLLER_H + +#include "ace/TMCast/GroupFwd.hpp" + +#include "tao/corba.h" +#include "tao/PortableServer/PortableServer.h" +#include "tao/PortableInterceptorC.h" +#include "tao/LocalObject.h" + +#include "Log.h" + +// State management +// +// + +PortableInterceptor::SlotId +state_slot_id (); + +void +state_slot_id (PortableInterceptor::SlotId slot_id); + +// ReplicaController +// +// + +class ReplicaController + : public virtual PortableInterceptor::ServerRequestInterceptor, + public virtual TAO_Local_RefCounted_Object +{ +public: + virtual + ~ReplicaController (); + + ReplicaController (CORBA::ORB_ptr orb); + +public: + virtual char * + name (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void + destroy (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void + tao_ft_interception_point ( + PortableInterceptor::ServerRequestInfo_ptr ri, + CORBA::OctetSeq_out ocs + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)); + + virtual void + receive_request_service_contexts ( + PortableInterceptor::ServerRequestInfo_ptr ri + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)); + + virtual void + receive_request ( + PortableInterceptor::ServerRequestInfo_ptr ri + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)); + + virtual void + send_reply ( + PortableInterceptor::ServerRequestInfo_ptr ri + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void + send_exception ( + PortableInterceptor::ServerRequestInfo_ptr ri + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)); + + virtual void + send_other ( + PortableInterceptor::ServerRequestInfo_ptr ri + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableInterceptor::ForwardRequest)); + +private: + static void* + listener_thunk (void* p); + + void + listener (); + + PortableServer::POA_ptr + resolve_poa (PortableInterceptor::AdapterName const& name); + +private: + + class RecordId + { + public: + RecordId (char const* client_id, CORBA::Long retention_id) + : client_id_ (CORBA::string_dup (client_id)), + retention_id_ (retention_id) + { + } + + friend bool + operator< (RecordId const& a, RecordId const& b) + { + int r (ACE_OS::strcmp (a.client_id_.in (), b.client_id_.in ())); + + return (r < 0) || (r == 0 && a.retention_id_ < b.retention_id_); + } + + private: + CORBA::String_var client_id_; + CORBA::Long retention_id_; + }; + + typedef + Log<RecordId, CORBA::OctetSeq_var> + Log_; + + Log_ log_; + CORBA::ORB_var orb_; + PortableServer::POA_var root_poa_; + auto_ptr<TMCast::Group> group_; +}; + +#endif /* REPLICA_CONTROLLER_H */ diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/RolyPoly.idl b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/RolyPoly.idl new file mode 100644 index 00000000000..7ab87e6d98d --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/RolyPoly.idl @@ -0,0 +1,15 @@ +// file : RolyPoly/RolyPoly.idl +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +interface RolyPoly +{ + exception E + { + string s; + }; + + short number (inout string m) raises (E); + + oneway void shutdown (); +}; diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/RolyPoly_i.cpp b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/RolyPoly_i.cpp new file mode 100644 index 00000000000..cf1c40d004f --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/RolyPoly_i.cpp @@ -0,0 +1,71 @@ +// file : RolyPoly/RolyPoly_i.cpp +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#include "RolyPoly_i.h" +#include "StateUpdate.h" + +RolyPoly_i::RolyPoly_i (CORBA::ORB_ptr orb) + : number_ (0) + , orb_ (CORBA::ORB::_duplicate (orb)) +{ +} + +RolyPoly_i::~RolyPoly_i (void) +{ +} + +CORBA::Any* RolyPoly_i:: +get_state () +{ + /* + CORBA::Any_var state (new CORBA::Any); + + *state <<= this->number_; + + return state._retn (); + */ + + return 0; +} + + +void RolyPoly_i:: +set_state (CORBA::Any const& state) +{ + state >>= this->number_; +} + + +CORBA::Short +RolyPoly_i::number (char *&str + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + CORBA::string_free (str); + + str = CORBA::string_dup ("Greetings from RolyPoly."); + + ++this->number_; + + + // Preppare state update. + // + + CORBA::Any a; + + a <<= this->number_; + + associate_state (orb_.in (), a); + + return this->number_; +} + +void +RolyPoly_i::shutdown (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + ACE_DEBUG ((LM_DEBUG, "Server is shutting down.\n")); + + this->orb_->shutdown (0 ACE_ENV_ARG_PARAMETER); +} diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/RolyPoly_i.h b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/RolyPoly_i.h new file mode 100644 index 00000000000..a9fd7a706a0 --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/RolyPoly_i.h @@ -0,0 +1,44 @@ +// file : RolyPoly/RolyPoly_i.h +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#ifndef ROLY_POLY_I_H +#define ROLY_POLY_I_H + +#include "RolyPolyS.h" +#include "StateUpdate.h" + +class RolyPoly_i : public virtual POA_RolyPoly, + public virtual Checkpointable +{ +public: + RolyPoly_i (CORBA::ORB_ptr orb); + + ~RolyPoly_i (void); + + // Checkpointable + // + virtual CORBA::Any* + get_state (); + + virtual void + set_state (CORBA::Any const& state); + + + // RolyPoly + // + virtual CORBA::Short + number (char *&s ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void + shutdown (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + +private: + CORBA::Short number_; + + CORBA::ORB_var orb_; +}; + +#endif /* ROLY_POLY_I_H */ diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/StateUpdate.h b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/StateUpdate.h new file mode 100644 index 00000000000..2d9aec49fe8 --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/StateUpdate.h @@ -0,0 +1,27 @@ +// file : RolyPoly/StateUpdate.h +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#ifndef STATE_UPDATE_H +#define STATE_UPDATE_H + +#include "tao/corba.h" + +class Checkpointable +{ +public: + virtual + ~Checkpointable (); + + virtual CORBA::Any* + get_state (); + + static void + associate_state (CORBA::ORB_ptr orb, CORBA::Any const& state); + + virtual void + set_state (CORBA::Any const& state) = 0; +}; + + +#endif // STATE_UPDATE_H diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/client.cpp b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/client.cpp new file mode 100644 index 00000000000..84f906ae40b --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/client.cpp @@ -0,0 +1,197 @@ +// file : RolyPoly/client.cpp +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#include "ace/Get_Opt.h" + +// IOR manipulation. +#include "tao/IORManipulation/IORManip_Loader.h" +#include "orbsvcs/FaultTolerance/FT_Service_Activate.h" +#include "orbsvcs/FaultTolerance/FT_IOGR_Property.h" + +#include "RolyPolyC.h" + +const char *ior1 = 0; +const char *ior2 = 0; + + +int +parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "k:"); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'k': + if (ior1 == 0) ior1 = get_opts.opt_arg (); + else ior2 = get_opts.opt_arg (); + break; + default: + ACE_ERROR_RETURN ((LM_ERROR, + "Usage: %s " + "-k IOR_1 -k IOR_2\n", + argv[0]), + -1); + } + + return 0; +} + +int +main (int argc, char *argv[]) +{ + int status = 0; + + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + CORBA::ORB_var orb = CORBA::ORB_init (argc, + argv, + "Client ORB" + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (::parse_args (argc, argv) != 0) return -1; + + // Start out with the first IOR. Interaction with the second + // IOR occurs during the various interceptions executed during + // this test. + + CORBA::Object_var object; + + if (ior2 != 0) + { + // merge case + + CORBA::Object_var object_primary; + CORBA::Object_var object_secondary; + + object_primary = orb->string_to_object ( + ior1 ACE_ENV_ARG_PARAMETER); + + ACE_CHECK_RETURN (-1); + + object_secondary = orb->string_to_object ( + ior2 ACE_ENV_ARG_PARAMETER); + + ACE_CHECK_RETURN (-1); + + // Get an object reference for the ORBs IORManipultion object! + CORBA::Object_ptr IORM = + orb->resolve_initial_references (TAO_OBJID_IORMANIPULATION, + 0 + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + TAO_IOP::TAO_IOR_Manipulation_ptr iorm = + TAO_IOP::TAO_IOR_Manipulation::_narrow (IORM ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + + // Create the list + TAO_IOP::TAO_IOR_Manipulation::IORList iors (2); + iors.length(2); + iors [0] = CORBA::Object::_duplicate (object_primary.in ()); + iors [1] = CORBA::Object::_duplicate (object_secondary.in ()); + + // Create a merged set 1; + object = iorm->merge_iors (iors ACE_ENV_ARG_PARAMETER); + + ACE_CHECK_RETURN (-1); + + + FT::TagFTGroupTaggedComponent ft_tag_component; + + // Property values + + // Major and Minor revision numbers + ft_tag_component.object_group_ref_version = 0; + + // Domain id + const char *id = "iogr_testing"; + ft_tag_component.group_domain_id = id; + + // Object group id + ft_tag_component.object_group_id = + (CORBA::ULongLong) 10; + + // Version + ft_tag_component.object_group_ref_version = + (CORBA::ULong) 5; + + // Construct the IOGR Property class + TAO_FT_IOGR_Property iogr_prop (ft_tag_component); + + // Set the property + CORBA::Boolean retval = iorm->set_property (&iogr_prop, + object.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + retval = iorm->set_primary (&iogr_prop, + object_primary.in (), + object.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + } + else + { + object = orb->string_to_object (ior1 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + + RolyPoly_var server = + RolyPoly::_narrow (object.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (CORBA::is_nil (server.in ())) + { + ACE_ERROR_RETURN ((LM_ERROR, + "Object reference is nil\n"), + 1); + } + + CORBA::Short number = 0; + + + for (int i = 1; i < 500; ++i) + { + CORBA::String_var str; + + try + { + number = server->number (str.inout () + ACE_ENV_ARG_PARAMETER); + } + catch (RolyPoly::E const& e) + { + ACE_DEBUG ((LM_INFO, + "client: received exception %s .\n", + e.s.in ())); + continue; + } + + ACE_TRY_CHECK; + + ACE_DEBUG ((LM_INFO, + "client: received %d\n", + number)); + sleep (1); + } + + server->shutdown (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "Caught exception:"); + return -1; + } + ACE_ENDTRY; + + return status; +} diff --git a/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/server.cpp b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/server.cpp new file mode 100644 index 00000000000..c2b701832cd --- /dev/null +++ b/TAO/orbsvcs/examples/FaultTolerance/RolyPoly/server.cpp @@ -0,0 +1,138 @@ +// file : RolyPoly/server.cpp +// author : Boris Kolpackov <boris@dre.vanderbilt.edu> +// cvs-id : $Id$ + +#include "ace/Get_Opt.h" + +#include "RolyPoly_i.h" +#include "CrashPoint.h" +#include "ORB_Initializer.h" + +const char *ior_file = 0; + +int +parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "o:c:"); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'o': + ior_file = get_opts.opt_arg (); + break; + case 'c': + crash_point = ACE_OS::atoi (get_opts.opt_arg ()); + break; + default: + ACE_ERROR_RETURN ((LM_ERROR, + "Usage: %s " + "-o <IOR> " + "-c <CrashPoint>\n", + argv[0]), + -1); + } + + return 0; +} + +int +main (int argc, char *argv[]) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + if (::parse_args (argc, argv) != 0) return -1; + + ORB_Initializer *temp_initializer = 0; + ACE_NEW_RETURN (temp_initializer, + ORB_Initializer, + -1); // No exceptions yet! + + PortableInterceptor::ORBInitializer_var orb_initializer = + temp_initializer; + + PortableInterceptor::register_orb_initializer (orb_initializer.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CORBA::ORB_var orb = + CORBA::ORB_init (argc, argv, "Server ORB" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CORBA::Object_var poa_object = + orb->resolve_initial_references ("RootPOA" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (CORBA::is_nil (poa_object.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + " (%P|%t) Unable to initialize the POA.\n"), + 1); + + PortableServer::POA_var root_poa = + PortableServer::POA::_narrow (poa_object.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + PortableServer::POAManager_var poa_manager = + root_poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + RolyPoly_i* roly_poly_impl; + + ACE_NEW_RETURN (roly_poly_impl, + RolyPoly_i (orb.in ()), + 1); + + PortableServer::ServantBase_var owner_transfer (roly_poly_impl); + + RolyPoly_var t = + roly_poly_impl->_this (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + CORBA::PolicyList policies; // Empty policy list. + + CORBA::String_var ior = + orb->object_to_string (t.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + FILE *output_file= ACE_OS::fopen (ior_file, "w"); + if (output_file == 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "Cannot open output file <%s> for writing " + "IOR: %s", + ior.in ()), + 1); + } + + ACE_OS::fprintf (output_file, "%s", ior.in ()); + ACE_OS::fclose (output_file); + + ACE_DEBUG ((LM_DEBUG, "Server is ready\n")); + + // Run the ORB event loop. + orb->run (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + root_poa->destroy (1, 1 ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + orb->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + + ACE_DEBUG ((LM_DEBUG, "Event loop finished.\n")); + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "Caught exception:"); + return -1; + } + ACE_ENDTRY; + + return 0; +} diff --git a/TAO/orbsvcs/orbsvcs/CosEvent/CEC_TypedConsumerAdmin.cpp b/TAO/orbsvcs/orbsvcs/CosEvent/CEC_TypedConsumerAdmin.cpp index 721ca9fb449..2dca79b6574 100644 --- a/TAO/orbsvcs/orbsvcs/CosEvent/CEC_TypedConsumerAdmin.cpp +++ b/TAO/orbsvcs/orbsvcs/CosEvent/CEC_TypedConsumerAdmin.cpp @@ -131,16 +131,22 @@ TAO_CEC_Propagate_Typed_Event::work (TAO_CEC_ProxyPushSupplier *supplier // **************************************************************** +// Note the following are explicitly instantiated in CEC_ConsumerAdmin +// instantiating them here results in duplicate symbols from Solaris build: +// CC: Forte Developer 7 C++ 5.4 2002/03/09 +// template class TAO_ESF_Shutdown_Proxy<TAO_CEC_ProxyPushSupplier>; +// template class TAO_ESF_Worker<TAO_CEC_ProxyPushSupplier>; +// #pragma instantiate TAO_ESF_Shutdown_Proxy<TAO_CEC_ProxyPushSupplier> +// #pragma instantiate TAO_ESF_Worker<TAO_CEC_ProxyPushSupplier> + #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) template class TAO_ESF_Proxy_Admin<TAO_CEC_TypedEventChannel,TAO_CEC_ProxyPushSupplier,CosEventChannelAdmin::ProxyPushSupplier>; -template class TAO_ESF_Shutdown_Proxy<TAO_CEC_ProxyPushSupplier>; -template class TAO_ESF_Worker<TAO_CEC_ProxyPushSupplier>; +template class TAO_ESF_Proxy_Admin<TAO_CEC_TypedEventChannel,TAO_CEC_ProxyPullSupplier,CosEventChannelAdmin::ProxyPullSupplier>; #elif defined(ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) #pragma instantiate TAO_ESF_Proxy_Admin<TAO_CEC_TypedEventChannel,TAO_CEC_ProxyPushSupplier,CosEventChannelAdmin::ProxyPushSupplier> -#pragma instantiate TAO_ESF_Shutdown_Proxy<TAO_CEC_ProxyPushSupplier> -#pragma instantiate TAO_ESF_Worker<TAO_CEC_ProxyPushSupplier> +#pragma instantiate TAO_ESF_Proxy_Admin<TAO_CEC_TypedEventChannel,TAO_CEC_ProxyPullSupplier,CosEventChannelAdmin::ProxyPullSupplier> #endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/CosLoadBalancing.mpc b/TAO/orbsvcs/orbsvcs/CosLoadBalancing.mpc index c38732f666c..5e4a6973f43 100644 --- a/TAO/orbsvcs/orbsvcs/CosLoadBalancing.mpc +++ b/TAO/orbsvcs/orbsvcs/CosLoadBalancing.mpc @@ -1,4 +1,4 @@ -project : orbsvcslib, core, naming, portablegroup, messaging, ami { +project : orbsvcslib, core, naming, iormanip, portablegroup, messaging, ami { sharedname = TAO_CosLoadBalancing idlflags += -Wb,export_macro=TAO_LoadBalancing_Export -Wb,export_include=LoadBalancing/LoadBalancing_export.h dynamicflags = TAO_LOADBALANCING_BUILD_DLL diff --git a/TAO/orbsvcs/orbsvcs/FTORB.mpc b/TAO/orbsvcs/orbsvcs/FTORB.mpc index a60670276fb..577649492ab 100644 --- a/TAO/orbsvcs/orbsvcs/FTORB.mpc +++ b/TAO/orbsvcs/orbsvcs/FTORB.mpc @@ -1,4 +1,4 @@ -project(FTORB_Utils) : orbsvcslib, core, iormanip, portableserver { +project(FTORB_Utils) : orbsvcslib, core, iormanip, portableserver, messaging, portablegroup { sharedname = TAO_FTORB_Utils idlflags += -Wb,export_macro=TAO_FT_ORB_Utils_Export -Wb,export_include=FaultTolerance/FT_ORB_Utils_export.h -Wb,skel_export_include=tao/PortableServer/PolicyS.h dynamicflags = TAO_FT_ORB_UTILS_BUILD_DLL @@ -20,7 +20,7 @@ project(FTORB_Utils) : orbsvcslib, core, iormanip, portableserver { } } -project(FT_ClientORB) : orbsvcslib, core, iormanip, portableserver { +project(FT_ClientORB) : orbsvcslib, ftorbutils, core, iormanip, messaging, portablegroup{ sharedname = TAO_FT_ClientORB idlflags += -Wb,export_macro=TAO_FT_ClientORB_Export -Wb,export_include=FaultTolerance/FT_ClientORB_export.h -Wb,skel_export_include=tao/PortableServer/PolicyS.h dynamicflags = TAO_FT_CLIENTORB_BUILD_DLL @@ -47,7 +47,7 @@ project(FT_ClientORB) : orbsvcslib, core, iormanip, portableserver { } } -project(FT_ServerORB) : orbsvcslib, core, iormanip, portableserver { +project(FT_ServerORB) : orbsvcslib, ftorbutils, core, iormanip, messaging, portablegroup{ sharedname = TAO_FT_ServerORB idlflags += -Wb,export_macro=TAO_FT_ServerORB_Export -Wb,export_include=FaultTolerance/FT_ServerORB_export.h -Wb,skel_export_include=tao/PortableServer/PolicyS.h dynamicflags = TAO_FT_SERVERORB_BUILD_DLL diff --git a/TAO/orbsvcs/orbsvcs/FT_CORBA.idl b/TAO/orbsvcs/orbsvcs/FT_CORBA.idl index 7e287b6f389..144c2290bbe 100644 --- a/TAO/orbsvcs/orbsvcs/FT_CORBA.idl +++ b/TAO/orbsvcs/orbsvcs/FT_CORBA.idl @@ -3,12 +3,24 @@ #ifndef _FT_IDL_ #define _FT_IDL_ -// The OMG file has been split in to two portions. +// The OMG file has been devided into several portions: +// FT_CORBA.idl +// FT_CORBA_ORB.idl +// FT_Detector.idl +// FT_Notifier.idl +// FT_Replica.idl // The next include is TAO specific. #include "orbsvcs/FT_CORBA_ORB.idl" +#define FT_USES_PORTABLE_GROUP + +#ifdef FT_USES_PORTABLE_GROUP +# include "orbsvcs/PortableGroup.idl" +#else // FT_USES_PORTABLE_GROUP #include "orbsvcs/CosNaming.idl" // 98-10-19.idl +#endif // FT_USES_PORTABLE_GROUP + #include "orbsvcs/CosNotification.idl" // from telecom/98-11-03.idl #include "orbsvcs/CosNotifyFilter.idl" @@ -16,13 +28,127 @@ module FT { - /// Specification for the Common Types and Exceptions for - /// ReplicationManager - /// Forward declarations - interface GenericFactory; interface FaultNotifier; + typedef long ReplicationStyleValue; + const ReplicationStyleValue STATELESS = 0; + const ReplicationStyleValue COLD_PASSIVE = 1; + const ReplicationStyleValue WARM_PASSIVE = 2; + const ReplicationStyleValue ACTIVE = 3; + const ReplicationStyleValue ACTIVE_WITH_VOTING = 4; + const ReplicationStyleValue SEMI_ACTIVE = 5; + + typedef long ConsistencyStyleValue; + const ConsistencyStyleValue CONS_APP_CTRL = 0; + const ConsistencyStyleValue CONS_INF_CTRL = 1; + + typedef long FaultMonitoringStyleValue; + const FaultMonitoringStyleValue PULL = 0; + const FaultMonitoringStyleValue PUSH = 1; + const FaultMonitoringStyleValue NOT_MONITORED = 2; + + typedef long FaultMonitoringGranularityValue; + const FaultMonitoringGranularityValue MEMB = 0; + const FaultMonitoringGranularityValue LOC = 1; + const FaultMonitoringGranularityValue LOC_AND_TYPE = 2; + + struct FaultMonitoringIntervalAndTimeoutValue { + TimeBase::TimeT monitoring_interval; + TimeBase::TimeT timeout; + }; + + exception BadReplicationStyle {}; + exception PrimaryNotSet {}; + +#ifdef FT_USES_PORTABLE_GROUP + ///////////////////////////////////////// + // The following typedefs "import" + // definitions from the PortableGroup module + // definitions into the FT module. + // This is an interim step during the process + // of having FT depend on the commmon + // of PortableGroup module rather than defining + // everything itself. + + // this typedef trick doesn't work for exceptions, so they must + // use the PortableGroup:: prefix + typedef PortableGroup::_TypeId _TypeId; + typedef PortableGroup::ObjectGroup ObjectGroup; + typedef PortableGroup::Name Name; + typedef PortableGroup::Value Value; + typedef PortableGroup::Property Property; + typedef PortableGroup::Properties Properties; + typedef PortableGroup::Location Location; + typedef PortableGroup::Locations Locations; + typedef PortableGroup::Criteria Criteria; + + typedef PortableGroup::FactoryInfo FactoryInfo; + typedef PortableGroup::FactoryInfos FactoryInfos; + typedef PortableGroup::MembershipStyleValue MembershipStyleValue; + + typedef PortableGroup::FactoriesValue FactoriesValue; + typedef PortableGroup::InitialNumberMembersValue InitialNumberMembersValue; + typedef PortableGroup::MinimumNumberMembersValue MinimumNumberMembersValue; + typedef PortableGroup::PropertyManager PropertyManager; + typedef PortableGroup::ObjectGroupManager ObjectGroupManager; + typedef PortableGroup::GenericFactory GenericFactory; + + // Specification of FTObjectGroupManager Interface + // which ReplicationManager Inherits + interface FTObjectGroupManager : PortableGroup::ObjectGroupManager { + + ::PortableGroup::ObjectGroup set_primary_member(in ::PortableGroup::ObjectGroup object_group, + in ::PortableGroup::Location the_location) + raises(PortableGroup::ObjectGroupNotFound, + PortableGroup::MemberNotFound, + PrimaryNotSet, + BadReplicationStyle); + }; + + + /////////////////////////////////////////////////// + // names for properties used in Fault Tolerant CORBA + + /// FT::ReplicationStyle + const string FT_REPLICATION_STYLE = "org.omg.ft.ReplicationStyle"; + + /// FT::ConsistencyStyle + const string FT_CONSISTENCY_STYLE = "org.omg.ft.ConsistencyStyle"; + + /// FT::MembershipStyle + const string FT_MEMBERSHIP_STYLE = PortableGroup::PG_MEMBERSHIP_STYLE; + const PortableGroup::MembershipStyleValue MEMB_APP_CTRL = PortableGroup::MEMB_APP_CTRL; + const PortableGroup::MembershipStyleValue MEMB_INF_CTRL = PortableGroup::MEMB_INF_CTRL; + + /// FT::FaultMonitoringStyle + const string FT_FAULT_MONITORING_STYLE = "org.omg.ft.FaultMonitoringStyle"; + + /// FT::FaultMonitoringGranularity + const string FT_FAULT_MONITORING_GRANULARITY = "org.omg.ft.FaultMonitoringGranularity"; + + /// FT::InitialNumberMembers + const string FT_INITIAL_NUMBER_MEMBERS = PortableGroup::PG_INITIAL_NUMBER_MEMBERS; + + /// FT::MinimumNumberMembers + const string FT_MINIMUM_NUMBER_MEMBERS = PortableGroup::PG_MINIMUM_NUMBER_MEMBERS; + + /// Factories + const string FT_FACTORIES = PortableGroup::PG_FACTORIES; + + /// FT::FaultMonitoringIntervalAndTimeou + const string FT_FAULT_MONITORING_INTERVAL_AND_TIMEOUT = "org.omg.ft.FaultMonitoringIntervalAndTimeout"; + + /// FT::CheckpointInterval + const string FT_CHECKPOINT_INTERVAL = "org.omg.ft.CheckpointInterval"; + + // end of property names from FT CORBA specification + /////////////////////////////////////////////////// + + +#else // (not) FT_USES_PORTABLE_GROUP + interface GenericFactory; + /// Useful typedefs. typedef CORBA::RepositoryId _TypeId; typedef Object ObjectGroup; @@ -46,6 +172,7 @@ module FT typedef sequence<Location> Locations; typedef Properties Criteria; + /** * @struct FactoryInfo * @@ -81,8 +208,8 @@ module FT const FaultMonitoringGranularityValue LOC = 1; const FaultMonitoringGranularityValue LOC_AND_TYPE = 2; typedef FactoryInfos FactoriesValue; - typedef unsigned short InitialNumberReplicasValue; - typedef unsigned short MinimumNumberReplicasValue; + typedef unsigned short InitialNumberMembersValue; + typedef unsigned short MinimumNumberMembersValue; struct FaultMonitoringIntervalAndTimeoutValue { TimeBase::TimeT monitoring_interval; @@ -145,7 +272,8 @@ module FT raises(ObjectGroupNotFound, InvalidProperty, UnsupportedProperty); Properties get_properties(in ObjectGroup object_group) - raises(ObjectGroupNotFound); }; + raises(ObjectGroupNotFound); + }; // Specification of ObjectGroupManager Interface // which ReplicationManager Inherits @@ -191,7 +319,8 @@ module FT Object get_member_ref(in ObjectGroup object_group, in Location loc) - raises(ObjectGroupNotFound, MemberNotFound); }; + raises(ObjectGroupNotFound, MemberNotFound); + }; // Specification of GenericFactory Interface @@ -208,64 +337,15 @@ module FT CannotMeetCriteria); void delete_object(in FactoryCreationId factory_creation_id) - raises (ObjectNotFound); }; - - // Specification of ReplicationManager Interface - interface ReplicationManager : PropertyManager, - ObjectGroupManager, - GenericFactory { - void register_fault_notifier(in FaultNotifier fault_notifier); - FaultNotifier get_fault_notifier() - raises (InterfaceNotFound); }; - - // Specifications for Fault Management - // Specification of PullMonitorable Interface - // which Application Objects Inherit - interface PullMonitorable { boolean is_alive(); }; - - // Specification of FaultNotifier Interface - interface FaultNotifier { - typedef unsigned long long ConsumerId; - void push_structured_fault( in CosNotification::StructuredEvent - event); - void push_sequence_fault( in CosNotification::EventBatch events); - CosNotifyFilter::Filter create_subscription_filter (in string - constraint_grammar) - raises (CosNotifyFilter::InvalidGrammar); - ConsumerId connect_structured_fault_consumer(in CosNotifyComm::StructuredPushConsumer push_consumer, - in CosNotifyFilter::Filter filter) ; - - ConsumerId connect_sequence_fault_consumer(in - CosNotifyComm::SequencePushConsumer push_consumer, - in - CosNotifyFilter::Filter - filter); - - void disconnect_consumer( in ConsumerId connection) - raises(CosEventComm::Disconnected); }; - - // Specifications for Logging and Recovery - typedef sequence<octet> State; - - exception NoStateAvailable {}; - exception InvalidState {}; - - exception NoUpdateAvailable {}; - exception InvalidUpdate {}; - - // Specification of Checkpointable Interface - // which Updateable and Application Objects Inherit - interface Checkpointable { State get_state() - raises(NoStateAvailable); - void set_state(in State s) raises(InvalidState); }; - - // Specification of Updateable Interface - // which Application Objects Inherit - interface Updateable : Checkpointable { State get_update() - raises(NoUpdateAvailable); - void set_update(in State s) raises(InvalidUpdate); + raises (ObjectNotFound); }; +#endif // FT_USES_PORTABLE_GROUP + + // Specifications for Fault Management moved to FT_Replica.idl + // Specification of FaultNotifier Interface: moved to FT_Notifier.idl + // Specifications for Logging and Recovery: moved to FT_Replica.idl + // Specifications for Replication Manager moved to FT_ReplicationManager.idl }; diff --git a/TAO/orbsvcs/orbsvcs/FT_CORBA_ORB.idl b/TAO/orbsvcs/orbsvcs/FT_CORBA_ORB.idl index 013b1b8f6ee..85cdea881f5 100644 --- a/TAO/orbsvcs/orbsvcs/FT_CORBA_ORB.idl +++ b/TAO/orbsvcs/orbsvcs/FT_CORBA_ORB.idl @@ -10,6 +10,9 @@ #include "tao/GIOP.pidl" // from 98-03-01.idl #include "tao/Policy.pidl" +#include "PortableGroup.idl" + + #pragma prefix "omg.org" @@ -17,13 +20,13 @@ module FT { /// FTDomainId's are denoted as strings - typedef string FTDomainId; + typedef PortableGroup::GroupDomainId FTDomainId; /// The objectgroup id - typedef unsigned long long ObjectGroupId; + typedef PortableGroup::ObjectGroupId ObjectGroupId; /// The reference version of the object group - typedef unsigned long ObjectGroupRefVersion; + typedef PortableGroup::ObjectGroupRefVersion ObjectGroupRefVersion; /** * @struct TagFTGroupTaggedComponent @@ -31,13 +34,7 @@ module FT * @brief Contents of the Tagged_Component field with tag * TAG_FT_GROUP */ - struct TagFTGroupTaggedComponent - { - GIOP::Version version; - FTDomainId ft_domain_id; - ObjectGroupId object_group_id; - ObjectGroupRefVersion object_group_ref_version; - }; + typedef PortableGroup::TagGroupTaggedComponent TagFTGroupTaggedComponent; /** * @struct TagFTPrinaryTaggedComponent diff --git a/TAO/orbsvcs/orbsvcs/FT_FaultDetectorFactory.idl b/TAO/orbsvcs/orbsvcs/FT_FaultDetectorFactory.idl new file mode 100644 index 00000000000..b783eb46ace --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/FT_FaultDetectorFactory.idl @@ -0,0 +1,119 @@ +// -*- IDL -*- + +//============================================================================= +/** + * @file FT_FaultDetectorFactory.idl + * + * $Id$ + * + * @author: Dale Wilson, OCI <wilson_d@ociweb.com> + */ +//============================================================================= + +#ifndef _FT_DETECTOR_FACTORY_IDL_ +#define _FT_DETECTOR_FACTORY_IDL_ + +// A TAO specific addition to FT_CORBA. +// No interface was specified for the FaultDetector +// in the FT CORBA specification, so we decided to +// define a GenericFactory to create FaultDetectors and +// control the FaultDetectors through the GenericFactory +// interface (with extenstions.) + +#pragma prefix "omg.org" + +#include "orbsvcs/FT_CORBA.idl" +#include "orbsvcs/FT_Replica.idl" +#include "orbsvcs/PortableGroup.idl" + +module FT +{ + /////////////////////////////////////////////////// + // names for properties used in Fault Tolerant CORBA + /// TimeBase::TimeT how often to call is_alive(); + const string FT_FAULT_MONITORING_INTERVAL = "MonitoringInterval"; + + /// FT::FaultNotifier where to send fault reports + const string FT_NOTIFIER = "Notifier"; + + /// FT::PullMonitorable the object to monitor + const string FT_MONITORABLE = "Monitorable"; + + /////////////////////////////////////////// + // Names specified in the FT CORBA specification + + const string FT_EVENT_TYPE_DOMAIN = "FT_CORBA"; + const string FT_EVENT_TYPE_NAME = "ObjectCrashFault"; + + /// FT::FTDomainId domain to report to notifier + const string FT_DOMAIN_ID = "FTDomainId"; + + /// FT::Location location to report to notifier + const string FT_LOCATION = "Location"; + + /// FT::TypeId type to report to notifier + const string FT_TYPE_ID = "TypeId"; + + /// FT::ObjectGroupId group to report to notifier + const string FT_GROUP_ID = "GroupId"; + + // end of names from FT CORBA specification + /////////////////////////////////////////// + + ///////////////////////////// + // RoleName FaultDetectorFactory uses to register + // with Factory Registery + const string FAULT_DETECTOR_ROLE_NAME = "FT_FaultDetector"; + + /** + * A FaultDetectorFactory creates and manages a set of FaultDetectors. + * + * A FaultDetectorFactory acts as an agent for a ReplicationManager + * which needs to create one or more FaultDetectors at a particular + * location. + * + * At present, FaultDetectors monitor via the is_alive() method of + * the PullMonitorable interface which must be implemented by the + * object-to-be-monitored. Other monitoring techniques may be + * supported in the future. In particular heartbeat/watchdog + * monitoring is anticipated. + * + * Notifications of failing objects are sent to a FaultNotifier + * which is responsible for distributing them to interested parties. + * + * The implementation of the GenericFactory::create_object method + * creates a FaultDetector object to monitor a single monitorable. + * The FaultDetector is *not* a first-class CORBA object. The + * Object reference returned by create_object will be nil. You + * cannot interact directly with a FaultDetector. + * The only interaction that a FaultDetector needs after it is + * started is to tell it to change it's monitoring parameters, + * or to shut down. The change_properties () and shutdown () + * methods on the Factory provide the needed capabilities. + * + * The create_object requires the following criteria: + * FT::Notifier Notifier + * FT::PullMonitorable Monitorable + * PortableGroup::DomainId domain_id, + * PortableGroup::ObjectGroupId group_id, + * PortableGroup::Location object_location, + * PortableGroup::_TypeId object_type + */ + interface FaultDetectorFactory : ::PortableGroup::GenericFactory, PullMonitorable + { + /** + * Adjust properties on-the-fly. + * Applies to all FaultDetectors created by this factory. + * @param property_set is a set of properties that (may) have new values. + */ + void change_properties(in ::PortableGroup::Properties property_set) + raises (::PortableGroup::InvalidProperty); + + /** + * Ask the Fault Detector Factory to come to an orderly end. + */ + oneway void shutdown(); + }; +}; + +#endif // for #ifndef _FT_DETECTOR_FACTORY_IDL_ diff --git a/TAO/orbsvcs/orbsvcs/FT_Notifier.idl b/TAO/orbsvcs/orbsvcs/FT_Notifier.idl new file mode 100644 index 00000000000..bb1d839f388 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/FT_Notifier.idl @@ -0,0 +1,62 @@ +/* -*- IDL -*- */ +//============================================================================= +/** + * @file FT_Notifier.idl + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * This was original part of the OMG FT.idl file + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= + +#ifndef _FT_NOTIFIER_IDL_ +#define _FT_NOTIFIER_IDL_ + +/////////////////////////////// +// TAO specific includes +#include "orbsvcs/FT_CORBA_ORB.idl" +#include "orbsvcs/FT_Replica.idl" +// end of TAO specific includes +/////////////////////////////// + +#include "orbsvcs/CosNaming.idl" // 98-10-19.idl +#include "orbsvcs/CosNotification.idl" // from telecom/98-11-03.idl + +// added to OMG version: +#include "orbsvcs/CosNotifyFilter.idl" + +#pragma prefix "omg.org" + +module FT +{ + // Specifications for Fault Management + // Specification of FaultNotifier Interface + // TAO SPECIFIC: added inheritence from PullMonitorable + interface FaultNotifier : ::FT::PullMonitorable + { + typedef unsigned long long ConsumerId; + void push_structured_fault( in CosNotification::StructuredEvent + event); + void push_sequence_fault( in CosNotification::EventBatch events); + CosNotifyFilter::Filter create_subscription_filter (in string + constraint_grammar) + raises (CosNotifyFilter::InvalidGrammar); + ConsumerId connect_structured_fault_consumer(in CosNotifyComm::StructuredPushConsumer push_consumer, + in CosNotifyFilter::Filter filter) ; + + ConsumerId connect_sequence_fault_consumer(in + CosNotifyComm::SequencePushConsumer push_consumer, + in + CosNotifyFilter::Filter + filter); + + void disconnect_consumer( in ConsumerId connection) + raises(CosEventComm::Disconnected); + }; +}; + + +#endif // for #ifndef _FT_NOTIFIER_IDL_ diff --git a/TAO/orbsvcs/orbsvcs/FT_Replica.idl b/TAO/orbsvcs/orbsvcs/FT_Replica.idl new file mode 100644 index 00000000000..eb351729e6e --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/FT_Replica.idl @@ -0,0 +1,51 @@ +//$Id$ +// FT_replica.idl +#ifndef _FT_REPLICA_IDL_ +#define _FT_REPLICA_IDL_ + +// The OMG FT file has been split into sevaral pieces. This is one of them. +// It contains the interfaces that a typical FT Replica (replicated servant) +// will need to implement. + +#include "FT_CORBA.idl" // common FT definitions + +#pragma prefix "omg.org" + +module FT +{ + // Specification of PullMonitorable Interface + // which Application Objects Inherit + interface PullMonitorable { + boolean is_alive(); + }; + + // Specifications for Logging and Recovery + typedef sequence<octet> State; + + exception NoStateAvailable {}; + exception InvalidState {}; + + exception NoUpdateAvailable {}; + exception InvalidUpdate {}; + + // Specification of Checkpointable Interface + // which Updateable and Application Objects Inherit + interface Checkpointable { + State get_state() + raises(NoStateAvailable); + void set_state(in State s) + raises(InvalidState); + }; + + // Specification of Updateable Interface + // which Application Objects Inherit + interface Updateable : Checkpointable + { + State get_update() + raises(NoUpdateAvailable); + void set_update(in State s) + raises(InvalidUpdate); + }; +}; + +#endif // for #ifndef _FT_REPLICA_IDL_ diff --git a/TAO/orbsvcs/orbsvcs/FT_ReplicationManager.idl b/TAO/orbsvcs/orbsvcs/FT_ReplicationManager.idl new file mode 100644 index 00000000000..8f36d6b135a --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/FT_ReplicationManager.idl @@ -0,0 +1,75 @@ +/* -*- IDL -*- */ +//============================================================================= +/** + * @file FT_ReplicationManager.idl + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * This was original part of the OMG FT.idl file + * + * @author Curt Hibbs <hibbs_c@ociweb.com> + */ +//============================================================================= + +#ifndef _FT_REPLICATION_MANAGER_IDL_ +#define _FT_REPLICATION_MANAGER_IDL_ + +#include "orbsvcs/PortableGroup.idl" +#include "orbsvcs/FT_CORBA.idl" +#include "orbsvcs/FT_Replica.idl" +#include "orbsvcs/FT_Notifier.idl" + +#pragma prefix "omg.org" + +module FT +{ + exception InterfaceNotFound {}; + + // Specification of ReplicationManager Interface + interface ReplicationManager : ::PortableGroup::PropertyManager, + FTObjectGroupManager, + ::PortableGroup::GenericFactory + { + + /** + * Registers the Fault Notifier with the Replication Manager. + * @param fault_notifier where to send the fault information. + */ + void register_fault_notifier(in FaultNotifier fault_notifier); + + /** + * Returns the reference of the Fault Notifier. + * @returns the reference of the Fault Notifier. + */ + FaultNotifier get_fault_notifier() + raises (InterfaceNotFound); + + /** + * Find a registry for factories that create fault tolerant replicas. + * + * TAO-specific operation + * + * Factories in this registry will be used by the + * ReplicationManager's implementation of + * GenericFactory::create_object when infrastructure controlled + * membership is specified. + * + * The factory registry may also be used by applications that + * control their own membership but don't wish to address the + * issue of finding factories for replicas. + * + * @param selection_criteria to be used to choose among alternate registries (future enhancement.) + * @returns an implementation of FactoryRegistry + */ + ::PortableGroup::FactoryRegistry get_factory_registry (in ::PortableGroup::Criteria selection_criteria); + + /** + * TAO-specific shutdown operation. + */ + oneway void shutdown (); + }; +}; + + +#endif // _FT_REPLICATION_MANAGER_IDL_ diff --git a/TAO/orbsvcs/orbsvcs/FaultTolerance.mpc b/TAO/orbsvcs/orbsvcs/FaultTolerance.mpc index 0d200b3f18a..4afc05f7ea3 100644 --- a/TAO/orbsvcs/orbsvcs/FaultTolerance.mpc +++ b/TAO/orbsvcs/orbsvcs/FaultTolerance.mpc @@ -1,4 +1,4 @@ -project(FaultTolerance) : orbsvcslib, core, notification, ftorbutils { +project(FaultTolerance): orbsvcslib, core, notification, ftorb, portablegroup { sharedname = TAO_FaultTolerance idlflags += -Wb,export_macro=TAO_FT_Export -Wb,export_include=FaultTolerance/fault_tol_export.h -Wb,skel_export_include=tao/PortableServer/PolicyS.h dynamicflags = TAO_FT_BUILD_DLL @@ -7,12 +7,25 @@ project(FaultTolerance) : orbsvcslib, core, notification, ftorbutils { IDL_Files { FT_CORBA.idl - } + FT_Replica.idl + FT_Notifier.idl + FT_FaultDetectorFactory.idl + FT_ReplicationManager.idl + } Source_Files(ORBSVCS_COMPONENTS) { FaultTolerance { FT_CORBAC.cpp FT_CORBAS.cpp + FT_CORBAC.cpp + FT_ReplicaS.cpp + FT_ReplicaC.cpp + FT_NotifierS.cpp + FT_NotifierC.cpp + FT_FaultDetectorFactoryS.cpp + FT_FaultDetectorFactoryC.cpp + FT_ReplicationManagerS.cpp + FT_ReplicationManagerC.cpp } } } diff --git a/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_ClientPolicy_i.h b/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_ClientPolicy_i.h index f9e93824f1c..2a381028005 100755 --- a/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_ClientPolicy_i.h +++ b/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_ClientPolicy_i.h @@ -41,7 +41,7 @@ * to keep trying to connect to server object groups under certain * conditions. */ -class TAO_FT_ClientORB_Export TAO_FT_Request_Duration_Policy +class TAO_FT_Export TAO_FT_Request_Duration_Policy : public FT::RequestDurationPolicy, public TAO_Local_RefCounted_Object { diff --git a/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_ClientRequest_Interceptor.cpp b/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_ClientRequest_Interceptor.cpp index 6e096d5ca75..b1f3482ea6d 100644 --- a/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_ClientRequest_Interceptor.cpp +++ b/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_ClientRequest_Interceptor.cpp @@ -1,7 +1,6 @@ // $Id$ #include "FT_ClientRequest_Interceptor.h" - #include "orbsvcs/orbsvcs/FT_CORBA_ORBC.h" #include "tao/CORBA_String.h" @@ -15,7 +14,7 @@ #include "ace/OS_NS_sys_time.h" ACE_RCSID (FaultTolerance, - FT_ClientRequest_Interceptor, + FT_ORBInitializer, "$Id$") namespace TAO @@ -55,7 +54,6 @@ namespace TAO return CORBA::string_dup (this->name_); } - void FT_ClientRequest_Interceptor::destroy (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) ACE_THROW_SPEC ((CORBA::SystemException)) @@ -326,12 +324,13 @@ namespace TAO *this->lock_); ftrsc.retention_id = ++this->retention_id_; - tss->retention_id_ = ftrsc.retention_id; - // Generated one already. We don't generate another - // till we get a rely for this. - tss->clean_flag_ = false; - } + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) Retention id [%d]\n", + ftrsc.retention_id)); + tss->retention_id_ = ftrsc.retention_id; + tss->clean_flag_ = false; + } else { ftrsc.retention_id = @@ -379,7 +378,6 @@ namespace TAO return; } - TimeBase::TimeT FT_ClientRequest_Interceptor::request_expiration_time ( CORBA::Policy *policy diff --git a/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_IOGR_Property.cpp b/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_IOGR_Property.cpp index 2426f53c39f..835770b0500 100644 --- a/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_IOGR_Property.cpp +++ b/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_IOGR_Property.cpp @@ -273,11 +273,11 @@ TAO_FT_IOGR_Property::encode_properties ( // the version info CORBA::Boolean status = - cdr << this->ft_group_tagged_component_->version; + cdr << this->ft_group_tagged_component_->component_version; // the domain id status = status && - cdr << this->ft_group_tagged_component_->ft_domain_id.in (); + cdr << this->ft_group_tagged_component_->group_domain_id.in (); // Object group id status = status && diff --git a/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_IOGR_Property.i b/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_IOGR_Property.i new file mode 100644 index 00000000000..43e3c57df8d --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_IOGR_Property.i @@ -0,0 +1,31 @@ +// -*- C++ -*- +// +//$Id$ + +ACE_INLINE +TAO_FT_IOGR_Property::TAO_FT_IOGR_Property ( + FT::TagFTGroupTaggedComponent &ft_group) + :ft_group_tagged_component_ (&ft_group) +{ +} + +ACE_INLINE +TAO_FT_IOGR_Property::TAO_FT_IOGR_Property (void) + :ft_group_tagged_component_ (0) +{ +} + +ACE_INLINE +TAO_FT_IOGR_Property::~TAO_FT_IOGR_Property (void) +{ +} + +ACE_INLINE CORBA::Boolean +TAO_FT_IOGR_Property::reset_tagged_components ( + FT::TagFTGroupTaggedComponent &ft_group) +{ + this->ft_group_tagged_component_ = + &ft_group; + + return 1; +} diff --git a/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_ORBInitializer.cpp b/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_ORBInitializer.cpp new file mode 100644 index 00000000000..fb692cfe234 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_ORBInitializer.cpp @@ -0,0 +1,139 @@ +// -*- C++ -*- +// +// $Id$ + +#include "FT_ORBInitializer.h" +#include "FT_PolicyFactory.h" +#include "FT_ClientRequest_Interceptor.h" +#include "FT_ServerRequest_Interceptor.h" +#include "orbsvcs/FT_CORBA_ORBC.h" +#include "tao/Exception.h" + + +ACE_RCSID (FaultTolerance, + FT_ORBInitializer, + "$Id$") +void +TAO_FT_ORBInitializer::pre_init ( + PortableInterceptor::ORBInitInfo_ptr + ACE_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + +} + +void +TAO_FT_ORBInitializer::post_init ( + PortableInterceptor::ORBInitInfo_ptr info + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + this->register_policy_factories (info + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->register_server_request_interceptors (info + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->register_client_request_interceptors (info + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + + +} + +void +TAO_FT_ORBInitializer::register_policy_factories ( + PortableInterceptor::ORBInitInfo_ptr info + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + // Register the FTCORBA policy factories. + + PortableInterceptor::PolicyFactory_ptr temp_factory = + PortableInterceptor::PolicyFactory::_nil (); + PortableInterceptor::PolicyFactory_var policy_factory; + + // This policy factory is used for all FTCORBA related policies. + + ACE_NEW_THROW_EX (temp_factory, + TAO_FT_PolicyFactory, + CORBA::NO_MEMORY ( + CORBA::SystemException::_tao_minor_code ( + TAO_DEFAULT_MINOR_CODE, + ENOMEM), + CORBA::COMPLETED_NO)); + ACE_CHECK; + + policy_factory = temp_factory; + + // Bind the same policy factory to all RTCORBA related policy + // types since a single policy factory is used to create each of + // the different types of RTCORBA policies. + + CORBA::PolicyType type = FT::REQUEST_DURATION_POLICY; + info->register_policy_factory (type, + policy_factory.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + type = FT::HEARTBEAT_POLICY; + info->register_policy_factory (type, + policy_factory.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + type = FT::HEARTBEAT_ENABLED_POLICY; + info->register_policy_factory (type, + policy_factory.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // Transfer ownership of the policy factory to the registry. + (void) policy_factory._retn (); +} + +void +TAO_FT_ORBInitializer::register_server_request_interceptors ( + PortableInterceptor::ORBInitInfo_ptr info + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + PortableInterceptor::ServerRequestInterceptor_ptr sri = + PortableInterceptor::ServerRequestInterceptor::_nil (); + + ACE_NEW_THROW_EX (sri, + TAO::FT_ServerRequest_Interceptor, + CORBA::NO_MEMORY ()); + + PortableInterceptor::ServerRequestInterceptor_var + server_interceptor = sri; + + info->add_server_request_interceptor (server_interceptor.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} + + +void +TAO_FT_ORBInitializer::register_client_request_interceptors ( + PortableInterceptor::ORBInitInfo_ptr info + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + PortableInterceptor::ClientRequestInterceptor_ptr cri = + PortableInterceptor::ClientRequestInterceptor::_nil (); + + ACE_NEW_THROW_EX (cri, + TAO::FT_ClientRequest_Interceptor, + CORBA::NO_MEMORY ()); + + PortableInterceptor::ClientRequestInterceptor_var + client_interceptor = cri; + + info->add_client_request_interceptor (client_interceptor.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; +} diff --git a/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_ORBInitializer.h b/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_ORBInitializer.h new file mode 100644 index 00000000000..7381aa86228 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_ORBInitializer.h @@ -0,0 +1,77 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file FT_ORBInitializer.h + * + * $Id$ + * + * @author Balachandran Natarajan <bala@cs.wustl.edu> + */ +//============================================================================= +#ifndef TAO_FT_ORB_INITIALIZER_H +#define TAO_FT_ORB_INITIALIZER_H + +#include /**/ "ace/pre.h" + +#include "tao/corbafwd.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/PortableInterceptorC.h" +#include "tao/LocalObject.h" +#include "fault_tol_export.h" + +// This is to remove "inherits via dominance" warnings from MSVC. +// MSVC is being a little too paranoid. +#if defined(_MSC_VER) +#if (_MSC_VER >= 1200) +#pragma warning(push) +#endif /* _MSC_VER >= 1200 */ +#pragma warning(disable:4250) +#endif /* _MSC_VER */ + +/// RTCORBA ORB initializer. +class TAO_FT_Export TAO_FT_ORBInitializer : + public virtual PortableInterceptor::ORBInitializer, + public virtual TAO_Local_RefCounted_Object +{ +public: + + virtual void pre_init (PortableInterceptor::ORBInitInfo_ptr info + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void post_init (PortableInterceptor::ORBInitInfo_ptr info + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + +private: + + /// Register FTCORBA policy factories. + void register_policy_factories ( + PortableInterceptor::ORBInitInfo_ptr info + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /// Register the necessary interceptors. + void register_server_request_interceptors ( + PortableInterceptor::ORBInitInfo_ptr info + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + + void register_client_request_interceptors ( + PortableInterceptor::ORBInitInfo_ptr info + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); +}; + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +#pragma warning(pop) +#endif /* _MSC_VER */ + +#include /**/ "ace/post.h" + +#endif /* TAO_FT_ORB_INITIALIZER_H */ diff --git a/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_PolicyFactory.cpp b/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_PolicyFactory.cpp new file mode 100644 index 00000000000..2072fe7bbd1 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_PolicyFactory.cpp @@ -0,0 +1,37 @@ +// -*- C++ -*- +// +// $Id$ + +#include "FT_PolicyFactory.h" +#include "FT_Policy_i.h" +#include "orbsvcs/FT_CORBA_ORBC.h" +#include "tao/PolicyC.h" + + +ACE_RCSID (FaultTolerance, FT_PolicyFactory, "$Id$") + + + + +CORBA::Policy_ptr +TAO_FT_PolicyFactory::create_policy ( + CORBA::PolicyType type, + const CORBA::Any &val + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + CORBA::PolicyError)) +{ + + if (type == FT::REQUEST_DURATION_POLICY) + return TAO_FT_Request_Duration_Policy::create (val + ACE_ENV_ARG_PARAMETER); + else if (type == FT::HEARTBEAT_POLICY) + return TAO_FT_Heart_Beat_Policy::create (val + ACE_ENV_ARG_PARAMETER); + else if (type == FT::HEARTBEAT_ENABLED_POLICY) + return TAO_FT_Heart_Beat_Enabled_Policy::create (val + ACE_ENV_ARG_PARAMETER); + + ACE_THROW_RETURN (CORBA::PolicyError (CORBA::BAD_POLICY_TYPE), + CORBA::Policy::_nil ()); +} diff --git a/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_PolicyFactory.h b/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_PolicyFactory.h new file mode 100644 index 00000000000..584960de430 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_PolicyFactory.h @@ -0,0 +1,61 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file FT_PolicyFactory.h + * + * $Id$ + * + * @author Bala Natarajan <bala@cs.wustl.edu> + */ +//============================================================================= + + +#ifndef TAO_FT_POLICY_FACTORY_H +#define TAO_FT_POLICY_FACTORY_H + +#include /**/ "ace/pre.h" + +#include "tao/corbafwd.h" + + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "tao/PortableInterceptorC.h" +#include "tao/LocalObject.h" + +// This is to remove "inherits via dominance" warnings from MSVC. +// MSVC is being a little too paranoid. +#if defined(_MSC_VER) +#if (_MSC_VER >= 1200) +#pragma warning(push) +#endif /* _MSC_VER >= 1200 */ +#pragma warning(disable:4250) +#endif /* _MSC_VER */ + +#include "fault_tol_export.h" + +/// Policy factory for all FTCORBA related policies. +class TAO_FT_Export TAO_FT_PolicyFactory : + public PortableInterceptor::PolicyFactory, + public TAO_Local_RefCounted_Object +{ +public: + + virtual CORBA::Policy_ptr create_policy (CORBA::PolicyType type, + const CORBA::Any &value + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException, + CORBA::PolicyError)); +}; + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +#pragma warning(pop) +#endif /* _MSC_VER */ + + +#include /**/ "ace/post.h" + +#endif /* TAO_FT_POLICY_FACTORY_H */ diff --git a/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Policy_i.cpp b/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Policy_i.cpp new file mode 100644 index 00000000000..59b35423f5a --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Policy_i.cpp @@ -0,0 +1,255 @@ +//$Id$ +#include "FT_Policy_i.h" + +#include "tao/debug.h" + +#if !defined (__ACE_INLINE__) +#include "FT_Policy_i.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID(FaultTolerance, FT_Policy_i, "$Id$") + +TimeBase::TimeT +TAO_FT_Request_Duration_Policy::request_duration_policy_value (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + return this->request_duration_; +} + +CORBA::PolicyType +TAO_FT_Request_Duration_Policy::policy_type (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + return FT::REQUEST_DURATION_POLICY; +} + +CORBA::Policy_ptr +TAO_FT_Request_Duration_Policy::create (const CORBA::Any& val + ACE_ENV_ARG_DECL) +{ + TimeBase::TimeT value; + if ((val >>= value) == 0) + ACE_THROW_RETURN (CORBA::PolicyError (CORBA::BAD_POLICY_TYPE), + CORBA::Policy::_nil ()); + + TAO_FT_Request_Duration_Policy *tmp; + ACE_NEW_THROW_EX (tmp, + TAO_FT_Request_Duration_Policy (value), + CORBA::NO_MEMORY (TAO_DEFAULT_MINOR_CODE, + CORBA::COMPLETED_NO)); + ACE_CHECK_RETURN (CORBA::Policy::_nil ()); + + return tmp; +} + +TAO_FT_Request_Duration_Policy * +TAO_FT_Request_Duration_Policy::clone (void) const +{ + TAO_FT_Request_Duration_Policy *copy = 0; + ACE_NEW_RETURN (copy, + TAO_FT_Request_Duration_Policy (*this), + 0); + return copy; +} + +CORBA::Policy_ptr +TAO_FT_Request_Duration_Policy::copy (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + TAO_FT_Request_Duration_Policy* tmp; + ACE_NEW_THROW_EX (tmp, TAO_FT_Request_Duration_Policy (*this), + CORBA::NO_MEMORY (TAO_DEFAULT_MINOR_CODE, + CORBA::COMPLETED_NO)); + ACE_CHECK_RETURN (CORBA::Policy::_nil ()); + + return tmp; +} + +void +TAO_FT_Request_Duration_Policy::destroy (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} + +void +TAO_FT_Request_Duration_Policy::set_time_value (ACE_Time_Value &time_value) +{ + TimeBase::TimeT t = this->request_duration_; + TimeBase::TimeT seconds = t / 10000000u; + TimeBase::TimeT microseconds = (t % 10000000u) / 10; + time_value.set (ACE_U64_TO_U32 (seconds), + ACE_U64_TO_U32 (microseconds)); + + if (TAO_debug_level > 0) + { + CORBA::ULong msecs = + ACE_static_cast(CORBA::ULong, microseconds / 1000); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) Timeout is <%u>\n"), + msecs)); + } +} + + +/*****************************************************************/ + +FT::HeartbeatPolicyValue +TAO_FT_Heart_Beat_Policy::heartbeat_policy_value (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + FT::HeartbeatPolicyValue val; + val.heartbeat = this->heartbeat_; + val.heartbeat_interval = this->heartbeat_interval_; + val.heartbeat_timeout = this->heartbeat_timeout_; + + return val; +} + + +CORBA::Policy_ptr +TAO_FT_Heart_Beat_Policy::create (const CORBA::Any& val + ACE_ENV_ARG_DECL) +{ + FT::HeartbeatPolicyValue *value; + if ((val >>= value) == 0) + ACE_THROW_RETURN (CORBA::PolicyError (CORBA::BAD_POLICY_TYPE), + CORBA::Policy::_nil ()); + + TAO_FT_Heart_Beat_Policy *tmp; + ACE_NEW_THROW_EX (tmp, + TAO_FT_Heart_Beat_Policy (value->heartbeat, + value->heartbeat_interval, + value->heartbeat_timeout), + CORBA::NO_MEMORY (TAO_DEFAULT_MINOR_CODE, + CORBA::COMPLETED_NO)); + ACE_CHECK_RETURN (CORBA::Policy::_nil ()); + + return tmp; +} + + +CORBA::PolicyType +TAO_FT_Heart_Beat_Policy::policy_type (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + return FT::HEARTBEAT_POLICY; +} + + +CORBA::Policy_ptr +TAO_FT_Heart_Beat_Policy::copy (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + TAO_FT_Heart_Beat_Policy * tmp; + ACE_NEW_THROW_EX (tmp, TAO_FT_Heart_Beat_Policy (*this), + CORBA::NO_MEMORY (TAO_DEFAULT_MINOR_CODE, + CORBA::COMPLETED_NO)); + ACE_CHECK_RETURN (CORBA::Policy::_nil ()); + + return tmp; +} + +TAO_FT_Heart_Beat_Policy * +TAO_FT_Heart_Beat_Policy::clone (void) const +{ + TAO_FT_Heart_Beat_Policy *copy = 0; + ACE_NEW_RETURN (copy, + TAO_FT_Heart_Beat_Policy (*this), + 0); + return copy; +} + +void +TAO_FT_Heart_Beat_Policy::destroy (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} + +void +TAO_FT_Heart_Beat_Policy::set_time_value (ACE_Time_Value &time_value, + const TimeBase::TimeT &timebase) +{ + TimeBase::TimeT t = timebase; + TimeBase::TimeT seconds = t / 10000000u; + TimeBase::TimeT microseconds = (t % 10000000u) / 10; + time_value.set (ACE_U64_TO_U32 (seconds), + ACE_U64_TO_U32 (microseconds)); + + if (TAO_debug_level > 0) + { + CORBA::ULong msecs = + ACE_static_cast(CORBA::ULong, microseconds / 1000); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) Timeout is <%u>\n"), + msecs)); + } +} + +/******************************************************************/ + +CORBA::Boolean +TAO_FT_Heart_Beat_Enabled_Policy::heartbeat_enabled_policy_value ( + ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + return this->heartbeat_enabled_value_; +} + + +CORBA::Policy_ptr +TAO_FT_Heart_Beat_Enabled_Policy::create (const CORBA::Any& val + ACE_ENV_ARG_DECL) +{ + CORBA::Boolean value; + + if ((val >>= CORBA::Any::to_boolean (value)) == 0) + ACE_THROW_RETURN (CORBA::PolicyError (CORBA::BAD_POLICY_TYPE), + CORBA::Policy::_nil ()); + + TAO_FT_Heart_Beat_Enabled_Policy *tmp; + ACE_NEW_THROW_EX (tmp, + TAO_FT_Heart_Beat_Enabled_Policy (value), + CORBA::NO_MEMORY (TAO_DEFAULT_MINOR_CODE, + CORBA::COMPLETED_NO)); + ACE_CHECK_RETURN (CORBA::Policy::_nil ()); + + return tmp; +} + +CORBA::PolicyType +TAO_FT_Heart_Beat_Enabled_Policy::policy_type (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + return FT::HEARTBEAT_ENABLED_POLICY; +} + + +CORBA::Policy_ptr +TAO_FT_Heart_Beat_Enabled_Policy::copy (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + TAO_FT_Heart_Beat_Enabled_Policy * tmp; + ACE_NEW_THROW_EX (tmp, TAO_FT_Heart_Beat_Enabled_Policy (*this), + CORBA::NO_MEMORY (TAO_DEFAULT_MINOR_CODE, + CORBA::COMPLETED_NO)); + ACE_CHECK_RETURN (CORBA::Policy::_nil ()); + + return tmp; +} + +TAO_FT_Heart_Beat_Enabled_Policy * +TAO_FT_Heart_Beat_Enabled_Policy::clone (void) const +{ + TAO_FT_Heart_Beat_Enabled_Policy *copy = 0; + ACE_NEW_RETURN (copy, + TAO_FT_Heart_Beat_Enabled_Policy (*this), + 0); + return copy; +} + + +void +TAO_FT_Heart_Beat_Enabled_Policy::destroy (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ +} diff --git a/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Policy_i.h b/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Policy_i.h new file mode 100644 index 00000000000..74417f96e50 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Policy_i.h @@ -0,0 +1,213 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FT_Policy_i.h + * + * $Id$ + * + * @author Balachandran Natarajan <bala@cs.wustl.edu> + */ +//============================================================================= + + +#ifndef TAO_FT_POLICY_I_H +#define TAO_FT_POLICY_I_H +#include /**/ "ace/pre.h" + +#include "orbsvcs/FT_CORBA_ORBC.h" + +#if defined(_MSC_VER) +#if (_MSC_VER >= 1200) +#pragma warning(push) +#endif /* _MSC_VER >= 1200 */ +#pragma warning(disable:4250) +#endif /* _MSC_VER */ + +/** + * @class TAO_FT_Request_Duration_Policy + * + * @brief FT::RequestDurationPolicy implementation + * + * This policy controls the request duration in the ORB. The + * semantics are like this. On the server side, the server should + * retain the details of the request from the client (and the + * reply sent to it too) atleast for the time period specified by + * this policy value. On the client side, the client uses this + * value to calculate the expiration_id in the RequestService + * context. The expiration_id is a sort of timeout for the client + * to keep trying to connect to server object groups under certain + * conditions. + */ +class TAO_FT_Export TAO_FT_Request_Duration_Policy + : public FT::RequestDurationPolicy, + public TAO_Local_RefCounted_Object +{ +public: + + /// Constructor. + TAO_FT_Request_Duration_Policy (const TimeBase::TimeT& relative_expiry); + + /// Copy constructor. + TAO_FT_Request_Duration_Policy (const TAO_FT_Request_Duration_Policy &rhs); + + /// Helper method for the implementation of + /// CORBA::ORB::create_policy. + static CORBA::Policy_ptr create (const CORBA::Any& val + ACE_ENV_ARG_DECL_WITH_DEFAULTS); + + /// Returns a copy of <this>. + virtual TAO_FT_Request_Duration_Policy *clone (void) const; + + // = The FT::RequestDurationPolicy methods + virtual TimeBase::TimeT request_duration_policy_value (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual CORBA::PolicyType policy_type ( + ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual CORBA::Policy_ptr copy ( + ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void destroy ( + ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /// Change the CORBA representation to the ACE representation. + void set_time_value (ACE_Time_Value &time_value); + +private: + /// The attribute + TimeBase::TimeT request_duration_; +}; + + +/** + * @class TAO_FT_Heart_Beat_Policy + * + * @brief FT::HeartBeatPolicy + * + * If this policy is set, it enables the client ORB to send + * heartbeats to the server ORB over the open connections. + */ +class TAO_FT_Export TAO_FT_Heart_Beat_Policy + : public FT::HeartbeatPolicy, + public TAO_Local_RefCounted_Object +{ +public: + + /// Constructor. + TAO_FT_Heart_Beat_Policy (const CORBA::Boolean boolean, + const TimeBase::TimeT &interval, + const TimeBase::TimeT &timeout); + + /// Copy constructor. + TAO_FT_Heart_Beat_Policy (const TAO_FT_Heart_Beat_Policy &rhs); + + /// Helper method for the implementation of + /// CORBA::ORB::create_policy. + static CORBA::Policy_ptr create (const CORBA::Any& val + ACE_ENV_ARG_DECL_WITH_DEFAULTS); + + /// Returns a copy of <this>. + virtual TAO_FT_Heart_Beat_Policy *clone (void) const; + + // = The FT::HeartBeatPolicy methods + virtual FT::HeartbeatPolicyValue heartbeat_policy_value (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual CORBA::PolicyType policy_type ( + ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual CORBA::Policy_ptr copy ( + ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void destroy ( + ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /// Change the CORBA representation to the ACE representation. + void set_time_value (ACE_Time_Value &time_value, + const TimeBase::TimeT &timebase); + +private: + + // The attributes + /// <heartbeat_> indicates whether heartbeating is enabled or not. + CORBA::Boolean heartbeat_; + + /// Intervals in which heartbeat messages need to be sent + TimeBase::TimeT heartbeat_interval_; + + /// The timeouts for the heartbeats + TimeBase::TimeT heartbeat_timeout_; +}; + +/** + * @class TAO_FT_Heart_Beat_Enabled_Policy + * + * @brief FT::HeartBeatEnabledPolicy + * + * If this policy is set, it enables the server ORB to set + * the TAG_FT_HEARTBEAT_ENABLED component in the IOP profile of + * the IOR that it exposes + */ +class TAO_FT_Export TAO_FT_Heart_Beat_Enabled_Policy + : public FT::HeartbeatEnabledPolicy, + public TAO_Local_RefCounted_Object +{ +public: + + /// Constructor. + TAO_FT_Heart_Beat_Enabled_Policy (const CORBA::Boolean boolean); + + /// Copy constructor. + TAO_FT_Heart_Beat_Enabled_Policy ( + const TAO_FT_Heart_Beat_Enabled_Policy &rhs); + + static CORBA::Policy_ptr create (const CORBA::Any& val + ACE_ENV_ARG_DECL_WITH_DEFAULTS); + + // Helper method for the implementation of + // CORBA::ORB::create_policy. + + /// Returns a copy of <this>. + virtual TAO_FT_Heart_Beat_Enabled_Policy *clone (void) const; + + // = The FT::HeartBeatPolicy methods + virtual CORBA::Boolean heartbeat_enabled_policy_value ( + ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual CORBA::PolicyType policy_type ( + ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual CORBA::Policy_ptr copy ( + ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void destroy ( + ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + +private: + + /// indicates whether heartbeating is enabled or not. + CORBA::Boolean heartbeat_enabled_value_; +}; + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +#pragma warning(pop) +#endif /* _MSC_VER */ + +#if defined (__ACE_INLINE__) +#include "FT_Policy_i.inl" +#endif /* __ACE_INLINE__ */ + + +#include /**/ "ace/post.h" +#endif /* TAO_FT_POLICY_I_H */ diff --git a/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Policy_i.i b/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Policy_i.i new file mode 100644 index 00000000000..4caf44a0faf --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Policy_i.i @@ -0,0 +1,70 @@ +//$Id$ +ACE_INLINE +TAO_FT_Request_Duration_Policy::TAO_FT_Request_Duration_Policy ( + const TimeBase::TimeT &duration + ) + : request_duration_ (duration) +{ +} + +ACE_INLINE +TAO_FT_Request_Duration_Policy::TAO_FT_Request_Duration_Policy ( + const TAO_FT_Request_Duration_Policy &rhs + ) + : ACE_NESTED_CLASS (CORBA, Object) (), + ACE_NESTED_CLASS (CORBA, Policy) (), + ACE_NESTED_CLASS (CORBA, LocalObject) (), + FT::RequestDurationPolicy (), + TAO_Local_RefCounted_Object (), + request_duration_ (rhs.request_duration_) +{ +} + +ACE_INLINE +TAO_FT_Heart_Beat_Policy::TAO_FT_Heart_Beat_Policy ( + const CORBA::Boolean heartbeat, + const TimeBase::TimeT &interval, + const TimeBase::TimeT &timeout + ) + : heartbeat_ (heartbeat), + heartbeat_interval_ (interval), + heartbeat_timeout_ (timeout) +{ +} + +ACE_INLINE +TAO_FT_Heart_Beat_Policy::TAO_FT_Heart_Beat_Policy ( + const TAO_FT_Heart_Beat_Policy &rhs + ) + : ACE_NESTED_CLASS (CORBA, Object) (), + ACE_NESTED_CLASS (CORBA, Policy) (), + ACE_NESTED_CLASS (CORBA, LocalObject) (), + FT::HeartbeatPolicy (), + TAO_Local_RefCounted_Object (), + heartbeat_ (rhs.heartbeat_), + heartbeat_interval_ (rhs.heartbeat_interval_), + heartbeat_timeout_ (rhs.heartbeat_timeout_) +{ +} + + +ACE_INLINE +TAO_FT_Heart_Beat_Enabled_Policy::TAO_FT_Heart_Beat_Enabled_Policy ( + const CORBA::Boolean heartbeat + ) + : heartbeat_enabled_value_ (heartbeat) +{ +} + +ACE_INLINE +TAO_FT_Heart_Beat_Enabled_Policy::TAO_FT_Heart_Beat_Enabled_Policy ( + const TAO_FT_Heart_Beat_Enabled_Policy &rhs + ) + : ACE_NESTED_CLASS (CORBA, Object) (), + ACE_NESTED_CLASS (CORBA, Policy) (), + ACE_NESTED_CLASS (CORBA, LocalObject) (), + FT::HeartbeatEnabledPolicy (), + TAO_Local_RefCounted_Object (), + heartbeat_enabled_value_ (rhs.heartbeat_enabled_value_) +{ +} diff --git a/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Policy_i.inl b/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Policy_i.inl new file mode 100644 index 00000000000..579d6c3467b --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Policy_i.inl @@ -0,0 +1,73 @@ +//$Id$ +ACE_INLINE +TAO_FT_Request_Duration_Policy::TAO_FT_Request_Duration_Policy (const TimeBase::TimeT &duration) + :ACE_NESTED_CLASS (CORBA, Object) () + , ACE_NESTED_CLASS (CORBA, Policy) () + , ACE_NESTED_CLASS (CORBA, LocalObject) () + , TAO_Local_RefCounted_Object () + , request_duration_ (duration) +{ +} + +ACE_INLINE +TAO_FT_Request_Duration_Policy::TAO_FT_Request_Duration_Policy (const TAO_FT_Request_Duration_Policy &rhs) + :ACE_NESTED_CLASS (CORBA, Object) () + , ACE_NESTED_CLASS (CORBA, Policy) () + , ACE_NESTED_CLASS (CORBA, LocalObject) () + , FT::RequestDurationPolicy () + , TAO_Local_RefCounted_Object () + , request_duration_ (rhs.request_duration_) +{ +} + +ACE_INLINE +TAO_FT_Heart_Beat_Policy::TAO_FT_Heart_Beat_Policy ( + const CORBA::Boolean heartbeat, + const TimeBase::TimeT &interval, + const TimeBase::TimeT &timeout) + : ACE_NESTED_CLASS (CORBA, Object) () + , ACE_NESTED_CLASS (CORBA, Policy) () + , ACE_NESTED_CLASS (CORBA, LocalObject) () + , TAO_Local_RefCounted_Object () + , heartbeat_ (heartbeat) + , heartbeat_interval_ (interval) + , heartbeat_timeout_ (timeout) +{ +} + +ACE_INLINE +TAO_FT_Heart_Beat_Policy::TAO_FT_Heart_Beat_Policy (const TAO_FT_Heart_Beat_Policy &rhs) + : ACE_NESTED_CLASS (CORBA, Object) () + , ACE_NESTED_CLASS (CORBA, Policy) () + , ACE_NESTED_CLASS (CORBA, LocalObject) () + , FT::HeartbeatPolicy () + , TAO_Local_RefCounted_Object () + , heartbeat_ (rhs.heartbeat_) + , heartbeat_interval_ (rhs.heartbeat_interval_) + , heartbeat_timeout_ (rhs.heartbeat_timeout_) +{ +} + + +ACE_INLINE +TAO_FT_Heart_Beat_Enabled_Policy::TAO_FT_Heart_Beat_Enabled_Policy ( + const CORBA::Boolean heartbeat) + : ACE_NESTED_CLASS (CORBA, Object) () + , ACE_NESTED_CLASS (CORBA, Policy) () + , ACE_NESTED_CLASS (CORBA, LocalObject) () + , TAO_Local_RefCounted_Object () + , heartbeat_enabled_value_ (heartbeat) +{ +} + +ACE_INLINE +TAO_FT_Heart_Beat_Enabled_Policy::TAO_FT_Heart_Beat_Enabled_Policy ( + const TAO_FT_Heart_Beat_Enabled_Policy &rhs) + : ACE_NESTED_CLASS (CORBA, Object) () + , ACE_NESTED_CLASS (CORBA, Policy) () + , ACE_NESTED_CLASS (CORBA, LocalObject) () + , FT::HeartbeatEnabledPolicy () + , TAO_Local_RefCounted_Object () + , heartbeat_enabled_value_ (rhs.heartbeat_enabled_value_) +{ +} diff --git a/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Service_Activate.cpp b/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Service_Activate.cpp new file mode 100644 index 00000000000..f64ad373bb9 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Service_Activate.cpp @@ -0,0 +1,82 @@ +#include "FT_Service_Activate.h" +#include "FT_Service_Callbacks.h" +#include "FT_ORBInitializer.h" +#include "FT_Endpoint_Selector_Factory.h" +#include "tao/ORB_Core.h" +#include "tao/Service_Callbacks.h" +#include "ace/Dynamic_Service.h" + +ACE_RCSID(FaultTolerance, FT_Service_Activate, "$Id$") + +static bool initialized = false; + +TAO_FT_Service_Activate::TAO_FT_Service_Activate (void) +{ +} + +TAO_FT_Service_Activate::~TAO_FT_Service_Activate (void) +{ +} + + +TAO_Service_Callbacks * +TAO_FT_Service_Activate::activate_services (TAO_ORB_Core *orb_core) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + TAO_FT_Service_Callbacks *ft_service_callback = 0; + + // Construct service callback object + ACE_NEW_RETURN (ft_service_callback, + TAO_FT_Service_Callbacks (orb_core), + 0); + + + return ft_service_callback; +} + + +int +TAO_FT_Service_Activate::Initializer (void) +{ + if (initialized == false) + { + ACE_Service_Config::static_svcs ()-> + insert (&ace_svc_desc_TAO_FT_Service_Activate); + + PortableInterceptor::ORBInitializer_ptr temp_orb_initializer = + PortableInterceptor::ORBInitializer::_nil (); + PortableInterceptor::ORBInitializer_var orb_initializer; + + // Register the RTCORBA ORBInitializer. + ACE_NEW_RETURN (temp_orb_initializer, + TAO_FT_ORBInitializer, + -1); + + orb_initializer = temp_orb_initializer; + + PortableInterceptor::register_orb_initializer (orb_initializer.in ()); + + // Set the name of the endpoint selector factory + TAO_ORB_Core::set_endpoint_selector_factory ("FT_Endpoint_Selector_Factory"); + ACE_Service_Config::process_directive (ace_svc_desc_TAO_FT_Endpoint_Selector_Factory); + + initialized = true; + } + + return 0; +} + +ACE_FACTORY_DEFINE (TAO_FT,TAO_FT_Service_Activate) + +ACE_STATIC_SVC_DEFINE (TAO_FT_Service_Activate, + ACE_TEXT ("FT_Service_Activate"), + ACE_SVC_OBJ_T, + &ACE_SVC_NAME (TAO_FT_Service_Activate), + ACE_Service_Type::DELETE_THIS | ACE_Service_Type::DELETE_OBJ, + 0) + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +template class ACE_Dynamic_Service<TAO_FT_Service_Activate>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +#pragma instantiate ACE_Dynamic_Service<TAO_FT_Service_Activate> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Service_Callbacks.cpp b/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Service_Callbacks.cpp index bdde8993a50..389f5799c72 100644 --- a/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Service_Callbacks.cpp +++ b/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Service_Callbacks.cpp @@ -117,8 +117,8 @@ TAO_FT_Service_Callbacks::is_profile_equivalent (const TAO_Profile *this_p, that_cdr >> that_group_component; // check if domain id and group id are the same - if ((ACE_OS::strcmp (this_group_component.ft_domain_id, - that_group_component.ft_domain_id) == 0) && + if ((ACE_OS::strcmp (this_group_component.group_domain_id, + that_group_component.group_domain_id) == 0) && (this_group_component.object_group_id == that_group_component.object_group_id)) { diff --git a/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Service_Callbacks.i b/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Service_Callbacks.i new file mode 100644 index 00000000000..ca0908bbcf6 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/FaultTolerance/FT_Service_Callbacks.i @@ -0,0 +1 @@ +//$Id$ diff --git a/TAO/orbsvcs/orbsvcs/FtRtEvent/EventChannel/IOGR_Maker.cpp b/TAO/orbsvcs/orbsvcs/FtRtEvent/EventChannel/IOGR_Maker.cpp index 9c127c605fa..ec573287867 100644 --- a/TAO/orbsvcs/orbsvcs/FtRtEvent/EventChannel/IOGR_Maker.cpp +++ b/TAO/orbsvcs/orbsvcs/FtRtEvent/EventChannel/IOGR_Maker.cpp @@ -30,7 +30,7 @@ IOGR_Maker::init(CORBA::ORB_ptr orb iorm_ = resolve_init<TAO_IOP::TAO_IOR_Manipulation>(orb, TAO_OBJID_IORMANIPULATION ACE_ENV_ARG_PARAMETER); - ft_tag_component_.ft_domain_id = "ft_eventchannel"; + ft_tag_component_.group_domain_id = "ft_eventchannel"; ft_tag_component_.object_group_id = 0; ft_tag_component_.object_group_ref_version = 0; maker = this; @@ -217,7 +217,7 @@ IOGR_Maker::copy_ft_group_component(CORBA::Object_ptr ior) void IOGR_Maker::set_ft_domain_id(const char* domain_id) { - ft_tag_component_.ft_domain_id = domain_id; + ft_tag_component_.group_domain_id = domain_id; } void diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup.idl b/TAO/orbsvcs/orbsvcs/PortableGroup.idl index e9351869313..d92d23fa567 100644 --- a/TAO/orbsvcs/orbsvcs/PortableGroup.idl +++ b/TAO/orbsvcs/orbsvcs/PortableGroup.idl @@ -11,7 +11,7 @@ #ifndef _PORTABLEGROUP_IDL_ #define _PORTABLEGROUP_IDL_ -#include <CosNaming.idl> +#include "CosNaming.idl" #include <tao/IOP.pidl> #include <tao/GIOP.pidl> #include <orb.idl> @@ -20,6 +20,18 @@ module PortableGroup { typeprefix PortableGroup "omg.org"; + /// MembershipStyle + const string PG_MEMBERSHIP_STYLE = "org.omg.PortableGroup.MembershipStyle"; + + /// InitialNumberMembers + const string PG_INITIAL_NUMBER_MEMBERS = "org.omg.PortableGroup.InitialNumberMembers"; + + /// MinimumNumberMembers + const string PG_MINIMUM_NUMBER_MEMBERS = "org.omg.PortableGroup.MinimumNumberMembers"; + + /// Factories + const string PG_FACTORIES = "org.omg.PortableGroup.Factories"; + // Specification for Interoperable Object Group References typedef string GroupDomainId; typedef unsigned long long ObjectGroupId; @@ -74,6 +86,8 @@ module PortableGroup exception MemberAlreadyPresent {}; exception ObjectNotCreated {}; exception ObjectNotAdded {}; + /// TAO Specific: TypeConfict exception + exception TypeConflict {}; exception UnsupportedProperty { Name nam; Value val; @@ -166,6 +180,11 @@ module PortableGroup in Location loc) raises (ObjectGroupNotFound, MemberNotFound); + // TAO-specific extension. + ObjectGroup get_object_group_ref_from_id ( + in ObjectGroupId group_id) + raises (ObjectGroupNotFound); + }; // end ObjectGroupManager @@ -187,6 +206,108 @@ module PortableGroup }; // end GenericFactory + /////////////////////// + // The following FactoryRegistry interface is not included in the OMG PortableGroup IDL. + // It's an extension needed as part of implementing the FT CORBA specification. + + + /** + * a name for the role the object will play + * This allows multiple objects that implement the same interface (TypeId) + * to exist at a location as long as they play different roles. + */ + typedef CORBA::Identifier RoleName; + + /** + * Reserved criteria name for specifing role. + */ + const string role_criterion = "org.omg.portablegroup.Role"; + + /** + * Interface to allow generic factories for replicas to register themselves. + * Factories are distinguished by the role to be played by the created-object (role) and the + * location at which they create the object (FactoryInfo.the_location) + * + * Because this is an extension to the FT CORBA specification applications that wish to + * adhere to the specification as written should use the type id as the role name when + * interacting with the FactoryRegistry. + */ + interface FactoryRegistry + { + /** + * register a factory to create objects of the given type + * at the location given in the FactoryInfo. + * + * @param role the role the object-to-be-created plays. + * @param type_id type id of the object-to-be-created. + * @param factory_info information about the factory including its location. + * @throws MemberAlreadyPresent if there is already a factory for this type of object + * at this location. + * @throws TypeConflict if the specified type_id is different from the type_id previously + * registered for this role. + */ + void register_factory(in RoleName role, in _TypeId type_id, in FactoryInfo factory_info) + raises (MemberAlreadyPresent, TypeConflict); + + /** + * Remove the registration of a factory. + * @param role the role played by the object formerly created by this factory. + * @param location where the factory formerly created objects. + * @throws MemberNotPresent if no factory is available for the given role at this location. + */ + void unregister_factory(in RoleName role, in Location location) + raises (MemberNotFound); + + /** + * Remove the registration of all factories that create a particular type of object. + * If no factories exist for the given type, the registry is unchanged. + * This is not an error. + * @param type_id the type of object formerly created by the factories to be unregistered. + */ + void unregister_factory_by_role(in RoleName role); + + /** + * Remove the registration of all factories that create objects at a particular location. + * If the location is unknown the registry is unchanged. + * This is not an error. + * @param location where the factories formerly created objects. + */ + void unregister_factory_by_location(in Location location); + + /** + * List all the factories that create objects that fill a given role + * If the role is unknown, an empty list is returned. This is not an error. + * @param role the type of object the factories create. + * @param type_id what type of object is created to fill this role. + */ + FactoryInfos list_factories_by_role(in RoleName role, out _TypeId type_id); + + /** + * List all the factories that create a objects at a given location. + * If no factories are registered for this location, an empty list is returned. + * This is not an error. + * @param location where the factories create objects. + */ + FactoryInfos list_factories_by_location(in Location location); + + }; // end of FactoryRegistry + + + const string TAO_UPDATE_OBJECT_GROUP_METHOD_NAME = "tao_update_object_group"; + + interface TAO_UpdateObjectGroup { + /** + * Pseudo used method to update IOGR in Object Group Members + * TAO specific. The CORBA spec. doesn't address the issue. + */ + void tao_update_object_group ( + in string iogr, + in PortableGroup::ObjectGroupRefVersion version, + in boolean is_primary); + }; + + + }; // end PortableGroup #endif /* _PORTABLEGROUP_IDL_ */ diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup.mpc b/TAO/orbsvcs/orbsvcs/PortableGroup.mpc index 32b09fc9a80..fa91cd16695 100644 --- a/TAO/orbsvcs/orbsvcs/PortableGroup.mpc +++ b/TAO/orbsvcs/orbsvcs/PortableGroup.mpc @@ -1,4 +1,4 @@ -project(PortableGroup) : orbsvcslib, core, naming, svc_utils, portableserver, messaging { +project(PortableGroup) : orbsvcslib, core, naming, svc_utils, portableserver, messaging, iormanip { sharedname = TAO_PortableGroup idlflags += -Wb,export_macro=TAO_PortableGroup_Export -Wb,export_include=PortableGroup/portablegroup_export.h dynamicflags = TAO_PORTABLEGROUP_BUILD_DLL diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Default_Property_Validator.cpp b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Default_Property_Validator.cpp index f1dcc072034..eefa86f14c7 100644 --- a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Default_Property_Validator.cpp +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Default_Property_Validator.cpp @@ -18,6 +18,10 @@ TAO_PG_Default_Property_Validator::TAO_PG_Default_Property_Validator (void) this->factories_[0].id = CORBA::string_dup ("org.omg.PortableGroup.Factories"); } +TAO_PG_Default_Property_Validator::~TAO_PG_Default_Property_Validator (void) +{ +} + void TAO_PG_Default_Property_Validator::validate_property ( const PortableGroup::Properties & props diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Default_Property_Validator.h b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Default_Property_Validator.h index 8f591870bcb..d8371b44469 100644 --- a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Default_Property_Validator.h +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Default_Property_Validator.h @@ -28,7 +28,8 @@ * @brief Default property validator implementation. * * This Property_Validator verifies that all properties defined in the - * PortableGroup IDL module are valid. + * PortableGroup IDL module are valid. This property validator can be + * subclassed to validate a different property set. */ class TAO_PortableGroup_Export TAO_PG_Default_Property_Validator { @@ -37,10 +38,13 @@ public: /// Constructor. TAO_PG_Default_Property_Validator (void); + /// Destructor + virtual ~TAO_PG_Default_Property_Validator (void); + /// Validate the given properties. Throw an exception when the /// first invalid property is encountered. The remaining properties /// will not be validated. - void validate_property (const PortableGroup::Properties & props + virtual void validate_property (const PortableGroup::Properties & props ACE_ENV_ARG_DECL) ACE_THROW_SPEC ((CORBA::SystemException, PortableGroup::InvalidProperty, @@ -49,7 +53,7 @@ public: /// Validate the given properties/criteria. All criteria /// will be validated regardless of whether or not an invalid /// property was encountered. - void validate_criteria (const PortableGroup::Properties & criteria + virtual void validate_criteria (const PortableGroup::Properties & criteria ACE_ENV_ARG_DECL) ACE_THROW_SPEC ((CORBA::SystemException, PortableGroup::InvalidCriteria, @@ -61,8 +65,8 @@ private: * @name Pre-initialize property Names. * * These properties are pre-initialized once to reduce property - * validation overhead. Note that the InitialNumberMembers and - * MinimumNumberMembers properties are not validated since there are + * validation overhead. Note that the InitialNumberReplicas and + * MinimumNumberReplicas properties are not validated since there are * no restrictions imposed by TAO's PortableGroup implementation * regarding the number of such members. */ diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_FactoryRegistry.cpp b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_FactoryRegistry.cpp new file mode 100644 index 00000000000..e7c0929c9cc --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_FactoryRegistry.cpp @@ -0,0 +1,748 @@ +// -*- C++ -*- +// +// $Id$ + +#include "PG_FactoryRegistry.h" + +#include <ace/Get_Opt.h> +#include <ace/Vector_T.h> +#include <tao/PortableServer/ORB_Manager.h> +#include "PG_Operators.h" // operator == on CosNaming::Name + +// Use this macro at the beginning of CORBA methods +// to aid in debugging. +#define METHOD_ENTRY(name) \ + if (TAO_debug_level <= 6){} else \ + ACE_DEBUG (( LM_DEBUG, \ + "Enter %s\n", #name \ + )) + +// Use this macro to return from CORBA methods +// to aid in debugging. Note that you can specify +// the return value after the macro, for example: +// METHOD_RETURN(Plugh::plover) xyzzy; is equivalent +// to return xyzzy; +// METHOD_RETURN(Plugh::troll); is equivalent to +// return; +// WARNING: THIS GENERATES TWO STATEMENTS!!! THE FOLLOWING +// will not do what you want it to: +// if (cave_is_closing) METHOD_RETURN(Plugh::pirate) aarrggh; +// Moral: Always use braces. +#define METHOD_RETURN(name) \ + if (TAO_debug_level <= 6){} else \ + ACE_DEBUG (( LM_DEBUG, \ + "Leave %s\n", #name \ + )); \ + return /* value goes here */ + +TAO::PG_FactoryRegistry::PG_FactoryRegistry (const char * name) + : identity_(name) + , orb_ (0) + , poa_ (0) + , object_id_ (0) + , this_obj_ (0) + , ior_output_file_(0) + , ns_name_(0) + , naming_context_(0) + , this_name_(1) + , quit_on_idle_(0) + , quit_state_(LIVE) + , linger_(0) +{ +} + +TAO::PG_FactoryRegistry::~PG_FactoryRegistry (void) +{ +} + +////////////////////////////////////////////////////// +// PG_FactoryRegistry public, non-CORBA methods + +int TAO::PG_FactoryRegistry::parse_args (int argc, char * argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "o:n:q"); + int c; + + while ((c = get_opts ()) != -1) + { + switch (c) + { + case 'o': + { + this->ior_output_file_ = get_opts.opt_arg (); + break; + } + case 'n': + { + this->ns_name_ = get_opts.opt_arg(); + break; + } + case 'q': + { + this->quit_on_idle_ = 1; + break; + } + + case '?': + // fall thru + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s" + " -o <registry ior file>" + " -n <name to use to register with name service>" + " -q{uit on idle}" + "\n", + argv [0]), + -1); + break; + } + } + // Indicates sucessful parsing of the command line + return 0; +} + +const char * TAO::PG_FactoryRegistry::identity () const +{ + return this->identity_.c_str(); +} + + +void TAO::PG_FactoryRegistry::_remove_ref (ACE_ENV_SINGLE_ARG_DECL) +{ + this->quit_state_ = GONE; +} + +int TAO::PG_FactoryRegistry::idle (int & result) +{ + result = 0; + int quit = 0; + if (this->quit_state_ == GONE) + { + if (linger_ < 2) + { + ++linger_; + } + else + { + quit = 1; + } + } + return quit; +} + + +int TAO::PG_FactoryRegistry::fini (ACE_ENV_SINGLE_ARG_DECL) +{ + if (this->ior_output_file_ != 0) + { + ACE_OS::unlink (this->ior_output_file_); + this->ior_output_file_ = 0; + } + if (this->ns_name_ != 0) + { + this->naming_context_->unbind (this_name_ + ACE_ENV_ARG_PARAMETER); + this->ns_name_ = 0; + } + return 0; +} + + +void TAO::PG_FactoryRegistry::init (CORBA::ORB_ptr orb, PortableServer::POA_ptr poa ACE_ENV_ARG_DECL) +{ + ACE_ASSERT (CORBA::is_nil (this->orb_.in ())); + ACE_ASSERT (CORBA::is_nil (this->poa_.in ())); + this->orb_ = CORBA::ORB::_duplicate (orb); + this->poa_ = PortableServer::POA::_duplicate (poa); + ACE_ASSERT ( ! CORBA::is_nil (this->orb_.in ())); + ACE_ASSERT ( ! CORBA::is_nil (this->poa_.in ())); + + // Register with the POA. + this->object_id_ = this->poa_->activate_object (this ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // find my identity as a corba object + this->this_obj_ = + this->poa_->id_to_reference (object_id_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // and create a ior string + this->ior_ = this->orb_->object_to_string (this->this_obj_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + +} + +int TAO::PG_FactoryRegistry::init (CORBA::ORB_ptr orb ACE_ENV_ARG_DECL) +{ + int result = 0; + + this->orb_ = CORBA::ORB::_duplicate (orb); + + // Use the ROOT POA for now + CORBA::Object_var poa_object = + this->orb_->resolve_initial_references (TAO_OBJID_ROOTPOA + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (CORBA::is_nil (poa_object.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT (" (%P|%t) Unable to initialize the POA.\n")), + -1); + + // Get the POA object. + this->poa_ = + PortableServer::POA::_narrow (poa_object.in () + ACE_ENV_ARG_PARAMETER); + + ACE_CHECK_RETURN (-1); + + if (CORBA::is_nil (this->poa_.in())) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT (" (%P|%t) Unable to narrow the POA.\n")), + -1); + } + + PortableServer::POAManager_var poa_manager = + this->poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN(-1); + + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN(-1); + + // Register with the POA. + this->object_id_ = this->poa_->activate_object (this ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(-1); + + // find my identity as a corba object + this->this_obj_ = + this->poa_->id_to_reference (object_id_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(-1); + + + // and create a ior string + this->ior_ = this->orb_->object_to_string (this->this_obj_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(-1); + + + if (this->ior_output_file_ != 0) + { + this->identity_ = "file:"; + this->identity_ += this->ior_output_file_; + result = write_ior_file (this->ior_output_file_, this->ior_); + } + + if (this->ns_name_ != 0) + { + this->identity_ = "name:"; + this->identity_ += this->ns_name_; + + CORBA::Object_var naming_obj = + this->orb_->resolve_initial_references ("NameService" ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(-1); + + if (CORBA::is_nil(naming_obj.in ())){ + ACE_ERROR_RETURN ((LM_ERROR, + "%T %n (%P|%t) Unable to find the Naming Service\n"), + 1); + } + + this->naming_context_ = + CosNaming::NamingContext::_narrow (naming_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(-1); + + this->this_name_.length (1); + this->this_name_[0].id = CORBA::string_dup (this->ns_name_); + + this->naming_context_->rebind (this->this_name_, this->this_obj_.in() //CORBA::Object::_duplicate(this_obj) + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN(-1); + } + + return result; +} + + +::PortableGroup::FactoryRegistry_ptr TAO::PG_FactoryRegistry::reference() +{ + // narrow and duplicate + return ::PortableGroup::FactoryRegistry::_narrow(this->this_obj_.in ()); +} + + +////////////////////////////////////////// +// PG_FactoryRegistry CORBA methods + +/* Reference:info + typedef CosNaming::Name Name; + typedef Name Location; + struct FactoryInfo { + GenericFactory the_factory; + Location the_location; + Criteria the_criteria; + }; + typedef sequence<FactoryInfo> FactoryInfos; +*/ + +TAO::PG_FactoryRegistry::RoleInfo::RoleInfo(size_t estimated_number_entries) + : infos_(estimated_number_entries) +{ +} + + +void TAO::PG_FactoryRegistry::register_factory ( + const char * role, + const char * type_id, + const PortableGroup::FactoryInfo & factory_info + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + , PortableGroup::MemberAlreadyPresent + , PortableGroup::TypeConflict)) +{ + METHOD_ENTRY(TAO::PG_FactoryRegistry::register_factory); + + RoleInfo * role_info; + auto_ptr<RoleInfo> safe_entry; + if (this->registry_.find(role, role_info) != 0) + { + ACE_DEBUG(( LM_DEBUG, + "%s: adding new role: %s:%s\n", this->identity_.c_str(), role, type_id + )); + // Note the 5. It's a guess about the number of factories + // that might exist for any particular role object. + // todo: make it a parameter. + ACE_NEW_THROW_EX (role_info, RoleInfo(5), + CORBA::NO_MEMORY()); + safe_entry = auto_ptr<RoleInfo>(role_info); + role_info->type_id_ = type_id; + } + else + { + if (role_info->type_id_ != type_id) + { + ACE_THROW ( PortableGroup::TypeConflict() ); + } + } + + PortableGroup::FactoryInfos & infos = role_info->infos_;; + size_t length = infos.length(); + for (size_t nInfo = 0; nInfo < length; ++nInfo) + { + PortableGroup::FactoryInfo & info = infos[nInfo]; + if (info.the_location == factory_info.the_location) + { + ACE_ERROR(( LM_ERROR, + "%s: Attempt to register duplicate location %s for role: %s\n" , + this->identity_.c_str(), + ACE_static_cast(const char *, info.the_location[0].id), + role)); + ACE_THROW (PortableGroup::MemberAlreadyPresent() ); + } + } + + infos.length(length + 1); + infos[length] = factory_info; + + if (safe_entry.get() != 0) + { + this->registry_.bind(role, safe_entry.release()); + } + + ACE_DEBUG(( LM_DEBUG, + "%s: Added factory: [%d] %s@%s \n", + this->identity_.c_str(), + ACE_static_cast(int,length + 1), + role, + ACE_static_cast(const char *, factory_info.the_location[0].id) + )); + + METHOD_RETURN(TAO::PG_FactoryRegistry::register_factory); +} + +void TAO::PG_FactoryRegistry::unregister_factory ( + const char * role, + const PortableGroup::Location & location + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException, PortableGroup::MemberNotFound)) +{ + METHOD_ENTRY(TAO::PG_FactoryRegistry::unregister_factory); + + RoleInfo * role_info; + if (this->registry_.find(role, role_info) == 0) + { + PortableGroup::FactoryInfos & infos = role_info->infos_; + int found = 0; + size_t length = infos.length(); + for (size_t nInfo = 0; !found && nInfo < length; ++nInfo) + { + PortableGroup::FactoryInfo & info = infos[nInfo]; + if (info.the_location == location) + { + found = 1; + + ACE_ERROR(( LM_INFO, + "%s: Unregistering factory %s@%s\n", + this->identity_.c_str(), + role, + ACE_static_cast(const char *, location[0].id) + )); + if (length > 1) + { + // if this is not the last entry + if (nInfo + 1 < length) + { + // move last entry into newly-emptied slot + infos[nInfo] = infos[length - 1]; + nInfo = length -1; + } + infos.length(nInfo); + } + else + { + ACE_ASSERT ( length == 1 ); + if (this->registry_.unbind (role) == 0) + { + ACE_DEBUG(( LM_INFO, + "%s: No more factories registered for %s\n", + this->identity_.c_str(), + role + )); + delete role_info; + } + else + { + ACE_ERROR ((LM_ERROR, + "%s: LOGIC ERROR AT " __FILE__ " (%d): Entry to be deleted disappeared\n", + this->identity_.c_str(), + __LINE__)); + } + } + } + } + } + else + { + ACE_ERROR(( LM_ERROR, + "%s, Attempt to unregister factory for unknown role %s\n", + this->identity_.c_str(), + role + )); + ACE_THROW ( PortableGroup::MemberNotFound() ); + } + + ////////////////////// + // request complete + // check quit-on-idle + if (registry_.current_size() == 0 && quit_state_ == LIVE) + { + ACE_ERROR(( LM_INFO, + "%s is idle\n", + identity() + )); + if (quit_on_idle_) + { + this->poa_->deactivate_object (this->object_id_.in () + ACE_ENV_ARG_PARAMETER); + quit_state_ = DEACTIVATED; + } + } + + METHOD_RETURN(TAO::PG_FactoryRegistry::unregister_factory); +} + +void TAO::PG_FactoryRegistry::unregister_factory_by_role ( + const char * role + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + METHOD_ENTRY(TAO::PG_FactoryRegistry::unregister_factory_by_role); + + RoleInfo * role_info; + if (this->registry_.unbind(role, role_info) == 0) + { + ACE_DEBUG(( LM_DEBUG, + "%s: Unregistering all factories for role %s\n", + this->identity_.c_str(), + role + )); + // delete the entire set of factories for this location. + delete role_info; + } + else + { + ACE_ERROR(( LM_INFO, + "%s: Unregister_factory_by_role: unknown role: %s\n", + this->identity_.c_str(), + role + )); + } + + ///////////////////// + // Function complete + // check quit options + if (registry_.current_size() == 0 && quit_state_ == LIVE) + { + ACE_ERROR(( LM_INFO, + "%s is idle\n", + identity() + )); + if (quit_on_idle_) + { + this->poa_->deactivate_object (this->object_id_.in () + ACE_ENV_ARG_PARAMETER); + quit_state_ = DEACTIVATED; + } + } + + METHOD_RETURN(TAO::PG_FactoryRegistry::unregister_factory_by_role); +} + +void TAO::PG_FactoryRegistry::unregister_factory_by_location ( + const PortableGroup::Location & location + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + METHOD_ENTRY(TAO::PG_FactoryRegistry::unregister_factory_by_location); + + //////////////////////////////////////////// + // a vector of roles that need to be deleted. + ACE_Vector<ACE_CString> emptyRoles; + + // iterate through the registery + for (RegistryType_Iterator it = this->registry_.begin(); + it != this->registry_.end(); + ++it) + { + RegistryType_Entry & entry = *it; + ACE_CString & role = entry.ext_id_; + RoleInfo * role_info = entry.int_id_; + + PortableGroup::FactoryInfos & infos = role_info->infos_; + // ACE_ERROR((LM_INFO, "unregister_factory_by_location: Checking role %s\n", role.c_str() )); + + int found = 0; + size_t length = infos.length(); + for (size_t nInfo = 0; !found && nInfo < length; ++nInfo) + { + PortableGroup::FactoryInfo & info = infos[nInfo]; + if (info.the_location == location) + { + + ACE_ERROR((LM_INFO, + "%s: Unregister_factory_by_location: Removing: [%d] %s@%s\n", + this->identity_.c_str(), + ACE_static_cast (int, nInfo), + role.c_str(), + ACE_static_cast (const char *, location[0].id) + )); + found = 1; + if (length > 1) + { + while (nInfo + 1 < length) + { + ACE_ERROR((LM_INFO, + "%s: Unregister_factory_by_location: Move: [%d] %s to [%d]\n", + this->identity_.c_str(), + (int)nInfo + 1, role.c_str(), (int)nInfo + )); + infos[nInfo] = infos[nInfo + 1]; + nInfo += 1; + } + ACE_ERROR((LM_INFO, + "%s: unregister_factory_by_location: New length [%d] %s\n", + this->identity_.c_str(), + (int)nInfo, role.c_str() + )); + infos.length(nInfo); + } + else + { + ACE_ERROR((LM_INFO, + "%s: Removed all entries for %s\n", + this->identity_.c_str(), + role.c_str() + )); + ACE_ASSERT ( length == 1 ); + // remember entries to be deleted + emptyRoles.push_back(entry.ext_id_); + } + } + } + } + + // now remove any roles that became empty + + for (size_t nRole = 0; nRole < emptyRoles.size(); ++nRole) + { + ACE_ERROR((LM_INFO, + "%s: Remove role %s\n", + this->identity_.c_str(), + emptyRoles[nRole].c_str() + )); + RoleInfo * role_info; + if (this->registry_.unbind(emptyRoles[nRole], role_info) == 0) + { + delete role_info; + } + else + { + ACE_ERROR ((LM_ERROR, + "%s: LOGIC ERROR AT " __FILE__ " (%d): Role to be deleted disappeared\n", + this->identity_.c_str(), + __LINE__)); + } + } + ////////////////////////// + // If all types are gone... + if (registry_.current_size() == 0 && quit_state_ == LIVE) + { + ACE_ERROR(( LM_INFO, + "%s is idle\n", + identity() + )); + if (quit_on_idle_) + { + this->poa_->deactivate_object (this->object_id_.in () + ACE_ENV_ARG_PARAMETER); + quit_state_ = DEACTIVATED; + } + } + + METHOD_RETURN(TAO::PG_FactoryRegistry::unregister_factory_by_location); +} + +::PortableGroup::FactoryInfos * TAO::PG_FactoryRegistry::list_factories_by_role ( + const char * role, + CORBA::String_out type_id + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + METHOD_ENTRY(TAO::PG_FactoryRegistry::list_factories_by_role); + + // allocate stucture to be returned. + PortableGroup::FactoryInfos_var result = 0; + ACE_NEW_THROW_EX (result, ::PortableGroup::FactoryInfos(), + CORBA::NO_MEMORY (TAO_DEFAULT_MINOR_CODE, CORBA::COMPLETED_NO)); + + RoleInfo * role_info = 0; + if (this->registry_.find(role, role_info) == 0) + { + type_id = CORBA::string_dup(role_info->type_id_.c_str()); + (*result) = role_info->infos_; + } + else + { + type_id = CORBA::string_dup(""); + ACE_ERROR(( LM_INFO, + "%s: list_factories_by_role: unknown role %s\n", + this->identity_.c_str(), + role + )); + } + METHOD_RETURN(TAO::PG_FactoryRegistry::list_factories_by_role) result._retn(); +} + +::PortableGroup::FactoryInfos * TAO::PG_FactoryRegistry::list_factories_by_location ( + const PortableGroup::Location & location + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + METHOD_ENTRY(TAO::PG_FactoryRegistry::list_factories_by_location); + ::PortableGroup::FactoryInfos_var result; + ACE_NEW_THROW_EX (result, ::PortableGroup::FactoryInfos(this->registry_.current_size()), + CORBA::NO_MEMORY (TAO_DEFAULT_MINOR_CODE, CORBA::COMPLETED_NO)); + + size_t result_length = 0; + + // iterate through the registery + for (RegistryType_Iterator it = this->registry_.begin(); + it != this->registry_.end(); + ++it) + { + RegistryType_Entry & entry = *it; + RoleInfo * role_info = entry.int_id_; + + PortableGroup::FactoryInfos & found_infos = role_info->infos_; + // iterate through the entry for this type + int found = 0; + size_t length = found_infos.length(); + for (size_t nInfo = 0; !found && nInfo < length; ++nInfo) + { + PortableGroup::FactoryInfo & info = found_infos[nInfo]; + if (info.the_location == location) + { + found = 1; + result_length += 1; + result->length(result_length); + (*result)[result_length-1] = info; + } + } + } + + METHOD_RETURN(TAO::PG_FactoryRegistry::list_factories_by_location) result._retn(); +} + +////////////////////////////// +// Implementation methods + +int TAO::PG_FactoryRegistry::write_ior_file(const char * outputFile, const char * ior) +{ + int result = -1; + FILE* out = ACE_OS::fopen (outputFile, "w"); + if (out) + { + ACE_OS::fprintf (out, "%s", ior); + ACE_OS::fclose (out); + result = 0; + } + else + { + ACE_ERROR ((LM_ERROR, + "Open failed for %s\n", outputFile + )); + } + return result; +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + + template class ACE_Hash_Map_Manager < + ACE_CString, + TAO::PG_FactoryRegistry::RoleInfo *, + TAO::PG_FactoryRegistry::MapMutex>; + template class ACE_Hash_Map_Entry < + ACE_CString, + TAO::PG_FactoryRegistry::RoleInfo *>; + template class ACE_Hash_Map_Iterator < + ACE_CString, + TAO::PG_FactoryRegistry::RoleInfo *, + TAO::PG_FactoryRegistry::MapMutex>; + template class ACE_Vector<ACE_CString>; + +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) + +# pragma instantiate ACE_Hash_Map_Manager < + ACE_CString, + TAO::PG_FactoryRegistry::RoleInfo *, + TAO::PG_FactoryRegistry::MapMutex> +# pragma instantiate ACE_Hash_Map_Entry < + ACE_CString, + TAO::PG_FactoryRegistry::RoleInfo *> +# pragma instantiate ACE_Hash_Map_Iterator < + ACE_CString, + TAO::PG_FactoryRegistry::RoleInfo *, + TAO::PG_FactoryRegistry::MapMutex> +# pragma instantiate ACE_Vector<ACE_CString> + +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_FactoryRegistry.h b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_FactoryRegistry.h new file mode 100644 index 00000000000..e3d848eb1ea --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_FactoryRegistry.h @@ -0,0 +1,253 @@ +// -*- C++ -*- +//============================================================================= +/** + * @file PG_FactoryRegistry.h + * + * $Id$ + * + * This file declares the implementation of PortableGroup::FactoryRegistry. + * Eventually this should be folded into the Fault Tolerance ReplicationManager + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= + +#ifndef TAO_PG_FACTORYREGISTRY_H_ +#define TAO_PG_FACTORYREGISTRY_H_ +#include /**/ <ace/pre.h> +#include <ace/ACE.h> + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +////////////////////////////////// +// Classes declared in this header +namespace TAO +{ + class PG_FactoryRegistry; +} + +///////////////////////////////// +// Includes needed by this header +#include <orbsvcs/PortableGroupS.h> +#include <ace/Hash_Map_Manager.h> + + +///////////////////// +// Forward references + +namespace TAO +{ + /** + * Implement the PortableGroup::FactoryRegistry interface + * Note FactoryRegistry is not part of the OMG standard. It was added + * as part of the TAO implementation of Fault Tolerant CORBA + */ + class TAO_PortableGroup_Export PG_FactoryRegistry : public virtual POA_PortableGroup::FactoryRegistry + { + struct RoleInfo + { + ACE_CString type_id_; + PortableGroup::FactoryInfos infos_; + + RoleInfo(size_t estimated_number_entries = 5); + }; + typedef ACE_Null_Mutex MapMutex; + typedef ACE_Hash_Map_Manager <ACE_CString, RoleInfo *, MapMutex> RegistryType; + typedef ACE_Hash_Map_Entry <ACE_CString, RoleInfo *> RegistryType_Entry; + typedef ACE_Hash_Map_Iterator <ACE_CString, RoleInfo *, MapMutex> RegistryType_Iterator; + + ////////////////////// + // non-CORBA interface + public: + /// Constructor + PG_FactoryRegistry (const char * name = "FactoryRegistry"); + + /// virtual Destructor + virtual ~PG_FactoryRegistry (void); + + /** + * Parse command line arguments. + * @param argc traditional C argc + * @param argv traditional C argv + * @return zero for success; nonzero is process return code for failure. + */ + int parse_args (int argc, char * argv[]); + + /** + * Initialize this object. + * @param orbManager our ORB -- we keep var to it. + * @return zero for success; nonzero is process return code for failure. + */ + int init (CORBA::ORB_ptr orb ACE_ENV_ARG_DECL); + + /** + * alternative init using designated poa + */ + void init (CORBA::ORB_ptr orb, PortableServer::POA_ptr poa ACE_ENV_ARG_DECL); + + /** + * Prepare to exit. + * @return zero for success; nonzero is process return code for failure. + */ + int fini (ACE_ENV_SINGLE_ARG_DECL); + + /** + * Processing to happen when the ORB's event loop is idle. + * @param result is a place to return status to be returned by the process + * @returns 0 to continue. 1 to quit. + */ + int idle(int & result); + + /** + * Identify this object. + * @return a string to identify this object for logging/console message purposes. + */ + const char * identity () const; + + /** + * An object reference to the this object. + * Duplicated by the call so it may (and probably should) be assigned to a _var.. + */ + ::PortableGroup::FactoryRegistry_ptr reference(); + + //////////////////////////////// + // override servant base methods + virtual void _remove_ref (ACE_ENV_SINGLE_ARG_DECL); + + ////////////////// + // CORBA interface + // See IDL for documentation + + virtual void register_factory ( + const char * role, + const char * type_id, + const PortableGroup::FactoryInfo & factory_info + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + , PortableGroup::MemberAlreadyPresent + , PortableGroup::TypeConflict)); + + virtual void unregister_factory ( + const char * role, + const PortableGroup::Location & location + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException, PortableGroup::MemberNotFound)); + + virtual void unregister_factory_by_role ( + const char * role + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)); + + + virtual void unregister_factory_by_location ( + const PortableGroup::Location & location + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual ::PortableGroup::FactoryInfos * list_factories_by_role ( + const char * role, + CORBA::String_out type_id + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual ::PortableGroup::FactoryInfos * list_factories_by_location ( + const PortableGroup::Location & location + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)); + + ///////////////////////// + // Implementation methods + private: + /** + * Write this factory's IOR to a file + */ + int write_ior_file (const char * outputFile, const char * ior); + + /////////////// + // Data Members + private: + + /** + * A human-readable string to distinguish this from other Notifiers. + */ + ACE_CString identity_; + + /** + * Protect internal state. + * Mutex should be locked by corba methods, or by + * external (public) methods before calling implementation + * methods. + * Implementation methods should assume the mutex is + * locked if necessary. + */ + ACE_Mutex internals_; + typedef ACE_Guard<ACE_Mutex> InternalGuard; + + /** + * The orb + */ + CORBA::ORB_var orb_; + + /** + * The POA used to activate this object. + */ + PortableServer::POA_var poa_; + + /** + * The CORBA object id assigned to this object. + */ + PortableServer::ObjectId_var object_id_; + + /** + * This objects identity as a CORBA object. + */ + CORBA::Object_var this_obj_; + + /** + * IOR of this object as assigned by poa. + */ + CORBA::String_var ior_; + + /** + * A file to which the factory's IOR should be written. + */ + const char * ior_output_file_; + + /** + * A name to be used to register the factory with the name service. + */ + const char * ns_name_; + + CosNaming::NamingContext_var naming_context_; + + CosNaming::Name this_name_; + + /** + * Quit on idle flag. + */ + int quit_on_idle_; + + /** + * State of the quit process + */ + enum {LIVE, DEACTIVATED, GONE} quit_state_; + + int linger_; + + RegistryType registry_; + + }; +} // namespace TAO + +#include /**/ <ace/post.h> + +#endif // TAO_PG_FACTORYREGISTRY_H_ diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.cpp b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.cpp new file mode 100644 index 00000000000..810f444574a --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.cpp @@ -0,0 +1,271 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file PG_Group_Factory.cpp + * + * $Id$ + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= + +#include "PG_Group_Factory.h" +#include "PG_Property_Utils.h" +#include "PG_conf.h" +#include "orbsvcs/PortableGroupC.h" +#include "PG_Object_Group.h" +#include <orbsvcs/orbsvcs/PortableGroup/PG_Utils.h> + +ACE_RCSID (PortableGroup, + PG_Group_Factory, + "$Id$") + + +TAO::PG_Group_Factory::PG_Group_Factory () + : orb_ (CORBA::ORB::_nil()) + , poa_ (PortableServer::POA::_nil()) + , manipulator_ () + , domain_id_ ("default-domain") + +{ +} + +TAO::PG_Group_Factory::~PG_Group_Factory (void) +{ + for (Group_Map_Iterator it = this->group_map_.begin (); + it != this->group_map_.end (); + ++it) + { + TAO::PG_Object_Group * group = (*it).int_id_; + delete group; + } + this->group_map_.unbind_all (); +} + + +void TAO::PG_Group_Factory::init ( + CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + PortableGroup::FactoryRegistry_ptr factory_registry + ACE_ENV_ARG_DECL) +{ + ACE_ASSERT (CORBA::is_nil (this->orb_.in ())); + ACE_ASSERT (CORBA::is_nil (this->poa_.in ())); + ACE_ASSERT (CORBA::is_nil (this->factory_registry_.in ())); + + this->orb_ = CORBA::ORB::_duplicate(orb); + this->poa_ = PortableServer::POA::_duplicate (poa); + this->factory_registry_ = PortableGroup::FactoryRegistry::_duplicate (factory_registry); + + + ACE_ASSERT (!CORBA::is_nil (this->orb_.in ())); + ACE_ASSERT (!CORBA::is_nil (this->poa_.in ())); + ACE_ASSERT (!CORBA::is_nil (this->factory_registry_.in ())); + + this->manipulator_.init (orb, poa ACE_ENV_ARG_PARAMETER); +// ACE_CHECK; +} + + +TAO::PG_Object_Group * TAO::PG_Group_Factory::create_group ( + const char * type_id, + const PortableGroup::Criteria & the_criteria, + TAO::PG_Property_Set * typeid_properties + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::NoFactory, + PortableGroup::ObjectNotCreated, + PortableGroup::InvalidCriteria, + PortableGroup::InvalidProperty, + PortableGroup::CannotMeetCriteria)) +{ + /////////////////////////////////// + // Create an empty group reference + + PortableGroup::ObjectGroupId group_id = 0; + PortableGroup::ObjectGroup_var empty_group = + this->manipulator_.create_object_group ( + type_id, + this->domain_id_, + group_id + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + + // pick up the object group information as assigned by + // ObjectGroupManager + + PortableGroup::TagGroupTaggedComponent tagged_component; + if (! TAO::PG_Utils::get_tagged_component (empty_group, tagged_component)) + { + ACE_THROW_RETURN (PortableGroup::ObjectNotCreated(), 0); + } + + TAO::PG_Object_Group * objectGroup = 0; + + ACE_NEW_THROW_EX ( + objectGroup, + TAO::PG_Object_Group ( + this->orb_.in (), + this->factory_registry_.in (), + this->manipulator_, + empty_group.in (), + tagged_component, + type_id, + the_criteria, + typeid_properties + ), + CORBA::NO_MEMORY()); + + if (this->group_map_.bind (group_id, objectGroup) != 0) + { + delete objectGroup; + ACE_THROW_RETURN (PortableGroup::ObjectNotCreated(), 0); + } + return objectGroup; +} + +void TAO::PG_Group_Factory::delete_group (PortableGroup::ObjectGroup_ptr object_group + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectNotFound)) +{ + if (! destroy_group (object_group)) + { + ACE_THROW (PortableGroup::ObjectNotFound ()); + } +} + + +void TAO::PG_Group_Factory::delete_group (PortableGroup::ObjectGroupId group_id + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectNotFound)) +{ + if (! destroy_group (group_id)) + { + ACE_THROW (PortableGroup::ObjectNotFound ()); + } +} + + // insert group. Take ownership +int TAO::PG_Group_Factory::insert_group ( ::TAO::PG_Object_Group * group) +{ + return insert_group (group->get_object_group_id(), group); +} + +int TAO::PG_Group_Factory::insert_group (PortableGroup::ObjectGroupId group_id, ::TAO::PG_Object_Group * group) +{ + return (this->group_map_.bind (group_id, group) == 0); +} + +int TAO::PG_Group_Factory::find_group (PortableGroup::ObjectGroupId group_id, ::TAO::PG_Object_Group *& group) const +{ + return (this->group_map_.find (group_id , group) == 0); +} + +int TAO::PG_Group_Factory::find_group (PortableGroup::ObjectGroup_ptr object_group, ::TAO::PG_Object_Group *& group) const +{ + int result = 0; + PortableGroup::TagGroupTaggedComponent tc; + if (TAO::PG_Utils::get_tagged_component (object_group, tc)) + { + result = find_group (tc.object_group_id, group); + } + return result; +} + +int TAO::PG_Group_Factory::destroy_group (PortableGroup::ObjectGroupId group_id) +{ + ::TAO::PG_Object_Group * group; + int result = (this->group_map_.unbind (group_id, group) == 0); + if (result) + { + delete group; + } + return result; +} + +int TAO::PG_Group_Factory::destroy_group (PortableGroup::ObjectGroup_ptr object_group) +{ + PortableGroup::TagGroupTaggedComponent tc; + TAO::PG_Utils::get_tagged_component (object_group, tc); + return destroy_group (tc.object_group_id); +} + + + +PortableGroup::ObjectGroups * +TAO::PG_Group_Factory::groups_at_location ( + const PortableGroup::Location & the_location + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException)) +{ + size_t upper_limit = this->group_map_.current_size (); + PortableGroup::ObjectGroups * result = 0; + ACE_NEW_THROW_EX ( + result, + PortableGroup::ObjectGroups (upper_limit), + CORBA::NO_MEMORY()); + ACE_CHECK_RETURN (0); + + result->length(upper_limit); + + size_t group_count = 0; + for (Group_Map_Iterator it = this->group_map_.begin (); + it != this->group_map_.end (); + ++it) + { + TAO::PG_Object_Group * group = (*it).int_id_; + if (group->has_member_at (the_location)) + { + (*result)[group_count] = group->reference (); + ++group_count; + } + } + result->length (group_count); + return result; +} + + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + + template class ACE_Hash_Map_Manager_Ex< + PortableGroup::ObjectGroupId, + ::TAO::PG_Object_Group *, + ACE_Hash<ACE_UINT64>, + ACE_Equal_To<ACE_UINT64>, + TAO_SYNCH_MUTEX>; + + template class ACE_Hash_Map_Entry < + PortableGroup::ObjectGroupId, + ::TAO::PG_Object_Group *>; + + template class ACE_Hash_Map_Iterator_Ex < + PortableGroup::ObjectGroupId, + ::TAO::PG_Object_Group *, + ACE_Hash<ACE_UINT64>, + ACE_Equal_To<ACE_UINT64>, + TAO_SYNCH_MUTEX>; + +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) + +# pragma instantiate ACE_Hash_Map_Manager_Ex< + PortableGroup::ObjectGroupId, + ::TAO::PG_Object_Group *, + ACE_Hash<ACE_UINT64>, + ACE_Equal_To<ACE_UINT64>, + TAO_SYNCH_MUTEX>; + +# pragma instantiate ACE_Hash_Map_Entry < + PortableGroup::ObjectGroupId, + ::TAO::PG_Object_Group *>; + +# pragma instantiate ACE_Hash_Map_Iterator_Ex < + PortableGroup::ObjectGroupId, + ::TAO::PG_Object_Group *, + ACE_Hash<ACE_UINT64>, + ACE_Equal_To<ACE_UINT64>, + TAO_SYNCH_MUTEX>; + +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.h b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.h new file mode 100644 index 00000000000..2068c254865 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Group_Factory.h @@ -0,0 +1,176 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file PG_Group_Factory.h + * + * $Id$ + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= + +#ifndef TAO_PG_GROUP_FACTORY_H +#define TAO_PG_GROUP_FACTORY_H + +#include /**/ <ace/pre.h> + +#include <ace/ACE.h> + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include <tao/PortableServer/PortableServerC.h> +#include <orbsvcs/PortableGroupC.h> +#include "PG_Object_Group_Manipulator.h" + +////////////////// +// Forward reference +namespace TAO +{ + class PG_Property_Set; +} // namespace TAO_PG + + + +namespace TAO +{ + ///////////////////// + // forward references + class PG_Object_Group; + + /** + * class PG_Group_Factory + */ + class TAO_PortableGroup_Export PG_Group_Factory + { + //////////////////////////////////////////////////////////// + // typedef private implementation classes + typedef ACE_Hash_Map_Manager_Ex< + PortableGroup::ObjectGroupId, + ::TAO::PG_Object_Group *, + ACE_Hash<ACE_UINT64>, + ACE_Equal_To<ACE_UINT64>, + TAO_SYNCH_MUTEX> Group_Map; + + typedef ACE_Hash_Map_Entry <PortableGroup::ObjectGroupId, ::TAO::PG_Object_Group *> Group_Map_Entry; + + typedef ACE_Hash_Map_Iterator_Ex < + PortableGroup::ObjectGroupId, + ::TAO::PG_Object_Group *, + ACE_Hash<ACE_UINT64>, + ACE_Equal_To<ACE_UINT64>, + TAO_SYNCH_MUTEX> Group_Map_Iterator; + + public: + + /// Constructor. + PG_Group_Factory (); + + /// Destructor. + ~PG_Group_Factory (); + + void init ( + CORBA::ORB_ptr orb, + PortableServer::POA_ptr poa, + PortableGroup::FactoryRegistry_ptr factory_registry + ACE_ENV_ARG_DECL); + + + TAO::PG_Object_Group * create_group ( + const char * type_id, + const PortableGroup::Criteria & the_criteria, + TAO::PG_Property_Set * typeid_properties + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::NoFactory, + PortableGroup::ObjectNotCreated, + PortableGroup::InvalidCriteria, + PortableGroup::InvalidProperty, + PortableGroup::CannotMeetCriteria)); + + + void delete_group (PortableGroup::ObjectGroup_ptr object_group + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectNotFound)); + + + void delete_group (PortableGroup::ObjectGroupId group_id + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::ObjectNotFound)); + + PortableGroup::ObjectGroups * + groups_at_location ( + const PortableGroup::Location & the_location + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException)); + + + + /** + * insert existing group. Take ownership + * note: uses group id extracted from group object + * @return bool true if insertion successful + */ + int insert_group ( ::TAO::PG_Object_Group * group); + + /** + * insert group. Take ownership + * @return bool true if insertion successful + */ + int insert_group (PortableGroup::ObjectGroupId group_id, ::TAO::PG_Object_Group * group); + + /** + * find group + * @return bool true if found + */ + int find_group (PortableGroup::ObjectGroupId group_id, ::TAO::PG_Object_Group *& group) const; + + /** + * find group + * note: uses group id extracted from object_group + * @return bool true if found + */ + int find_group (PortableGroup::ObjectGroup_ptr object_group, ::TAO::PG_Object_Group *& group) const; + + /** + * remove group from map and delete it. + * @return bool true if found + */ + int destroy_group (PortableGroup::ObjectGroupId object_group_id); + + /** + * remove group from map and delete it. + * note: uses group id extracted from object_group + * @return bool true if found + */ + int destroy_group (PortableGroup::ObjectGroup_ptr object_group); + + private: + + private: + + CORBA::ORB_var orb_; + + /// Reference to the POA used to create object group references. + PortableServer::POA_var poa_; + + /// The factory registry for replica factories + PortableGroup::FactoryRegistry_var factory_registry_; + + ::TAO::PG_Object_Group_Manipulator manipulator_; + + const char * domain_id_; + + Group_Map group_map_; + + + }; +} // namespace TAO + +#include /**/ "ace/post.h" + +#endif /* TAO_PG_GROUP_FACTORY_H */ diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Group_Guard.h b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Group_Guard.h index eaa065a6d6c..8fd7d844619 100644 --- a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Group_Guard.h +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Group_Guard.h @@ -84,7 +84,7 @@ private: /// Flag that dictates whether or not the destructor will perform /// cleanup. int released_; - + }; diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_ObjectGroupManager.cpp b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_ObjectGroupManager.cpp index 5a245b82a30..6cf36f1f4db 100644 --- a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_ObjectGroupManager.cpp +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_ObjectGroupManager.cpp @@ -469,6 +469,39 @@ TAO_PG_ObjectGroupManager::get_member_ref ( CORBA::Object::_nil ()); } +PortableGroup::ObjectGroup_ptr +TAO_PG_ObjectGroupManager::get_object_group_ref_from_id ( + PortableGroup::ObjectGroupId group_id + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + , PortableGroup::ObjectGroupNotFound + )) +{ + //@@ If we change the PG's concept of ObjectGroupId from + // PortableServer::ObjectId to PortableGroup::ObjectGroupId, can + // just call TAO_PG_ObjectGroupManager::object_group() here. + + TAO_PG_ObjectGroup_Map_Entry * group_entry = 0; + { + ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, + guard, + this->lock_, + PortableGroup::ObjectGroup::_nil ()); + + if (this->object_group_map_.find (group_id, group_entry) != 0) + ACE_THROW_RETURN (PortableGroup::ObjectGroupNotFound (), + PortableGroup::ObjectGroup::_nil ()); + } + + if (group_entry == 0) + ACE_THROW_RETURN (CORBA::INTERNAL (), + PortableGroup::ObjectGroup::_nil ()); + + return + PortableGroup::ObjectGroup::_duplicate (group_entry->object_group.in ()); +} PortableGroup::ObjectGroup_ptr TAO_PG_ObjectGroupManager::create_object_group ( diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_ObjectGroupManager.h b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_ObjectGroupManager.h index ab17a05ce25..947aa585a71 100644 --- a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_ObjectGroupManager.h +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_ObjectGroupManager.h @@ -138,6 +138,18 @@ public: ACE_THROW_SPEC ((CORBA::SystemException, PortableGroup::ObjectGroupNotFound, PortableGroup::MemberNotFound)); + /** + * TAO-specific extension. + * Return the ObjectGroup reference for the given ObjectGroupId. + */ + virtual PortableGroup::ObjectGroup_ptr get_object_group_ref_from_id ( + PortableGroup::ObjectGroupId group_id + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ) + ACE_THROW_SPEC (( + CORBA::SystemException + , PortableGroup::ObjectGroupNotFound + )); //@} diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group.cpp b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group.cpp new file mode 100644 index 00000000000..9d98700bbcc --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group.cpp @@ -0,0 +1,807 @@ +// -*- C++ -*- +// +// $Id$ + +#include "PG_Object_Group.h" +#include "PG_conf.h" + +#include <ace/Get_Opt.h> +#include <ace/Vector_T.h> +#include <tao/PortableServer/ORB_Manager.h> +#include <orbsvcs/PortableGroup/PG_Operators.h> // Borrow operator == on CosNaming::Name +#include <orbsvcs/PortableGroup/PG_Utils.h> + +#define TODO int todo; +//#define TODO + + +TAO::PG_Object_Group::MemberInfo::MemberInfo ( + CORBA::Object_ptr member, + const PortableGroup::Location & location) + : member_ (CORBA::Object::_duplicate (member)) + , factory_(PortableGroup::GenericFactory::_nil()) + , location_ (location) + , is_primary_ (0) +{ +} + +TAO::PG_Object_Group::MemberInfo::MemberInfo ( + CORBA::Object_ptr member, + const PortableGroup::Location & location, + PortableGroup::GenericFactory_ptr factory, + PortableGroup::GenericFactory::FactoryCreationId factory_id) + : member_ (CORBA::Object::_duplicate (member)) + , factory_ (PortableGroup::GenericFactory::_duplicate (factory)) + , factory_id_ (factory_id) + , location_ (location) + , is_primary_ (0) +{ +} + +TAO::PG_Object_Group::MemberInfo::~MemberInfo () +{ + if( ! CORBA::is_nil (this->factory_.in())) + { + ACE_TRY_NEW_ENV + { + this->factory_->delete_object (this->factory_id_); + } + ACE_CATCHANY; + { + // ignore this. It may have faulted and gone away. + // (and besides, we're in a destructor. + } + ACE_ENDTRY; + } +} + + +TAO::PG_Object_Group::PG_Object_Group ( + CORBA::ORB_ptr orb, + PortableGroup::FactoryRegistry_ptr factory_registry, + TAO::PG_Object_Group_Manipulator & manipulator, + CORBA::Object_ptr empty_group, + const PortableGroup::TagGroupTaggedComponent & tagged_component, + const char * type_id, + const PortableGroup::Criteria & the_criteria, + TAO::PG_Property_Set * type_properties) + : internals_() + , orb_ (CORBA::ORB::_duplicate (orb)) + , factory_registry_ (PortableGroup::FactoryRegistry::_duplicate (factory_registry)) + , manipulator_ (manipulator) + , empty_ (1) + , role_ (type_id) + , type_id_ (CORBA::string_dup (type_id)) + , tagged_component_ (tagged_component) + , reference_ (CORBA::Object::_duplicate(empty_group)) + , members_ () + , primary_location_(0) + , properties_ (the_criteria, type_properties) + , initial_number_members_ (0) + , minimum_number_members_ (0) + , group_specific_factories_ () +{ +} + +TAO::PG_Object_Group::~PG_Object_Group () +{ + for (MemberMap_Iterator it = this->members_.begin(); + it != this->members_.end(); + ++it) + { + MemberInfo * member = (*it).int_id_; + delete member; + } + this->members_.unbind_all (); +} + +#if 0 // may want this again someday +///////////////////// +// q&d debug function +static void dump_ior (const char * base, const char * ext, unsigned long version, const char * iogr) +{ + char filename[1000]; + ACE_OS::sprintf(filename, "%s_%lu.%s", base, version, ext ); + + FILE * iorfile = ACE_OS::fopen(filename, "w"); + ACE_OS::fwrite (iogr, 1, ACE_OS::strlen(iogr), iorfile); + ACE_OS::fclose (iorfile); +} +#endif // may want this again someday + +PortableGroup::ObjectGroup_ptr TAO::PG_Object_Group::reference()const +{ + // const cast to simulate mutable + InternalGuard guard(ACE_const_cast (TAO::PG_Object_Group *, this)->internals_); + return PortableGroup::ObjectGroup::_duplicate (this->reference_); +} + +void TAO::PG_Object_Group::get_group_specific_factories (PortableGroup::FactoryInfos & result) const +{ + // const cast to simulate mutable + InternalGuard guard(ACE_const_cast (TAO::PG_Object_Group *, this)->internals_); + // copy is needed to have some semblance of thread safeness. + // if performance is an issue avoid this method. + result = this->group_specific_factories_; +} + +const PortableGroup::Location & TAO::PG_Object_Group::get_primary_location() const +{ + // const cast to simulate mutable + InternalGuard guard(ACE_const_cast (TAO::PG_Object_Group *, this)->internals_); + return this->primary_location_; +} + + +PortableGroup::ObjectGroup_ptr TAO::PG_Object_Group::add_member_to_iogr( + CORBA::Object_ptr member + ACE_ENV_ARG_DECL) +{ + // assume internals is locked + + PortableGroup::ObjectGroup_var result = PortableGroup::ObjectGroup::_nil(); + //////////////////////////// + // @@ HACK ALERT + // The PortableGroup::ObjectGroupManager creates an object reference containing + // a dummy entry so it will have a place to store the tagged group component. + // If this is the first entry, we need to remove that entry once we have a *real* member. + // This can be avoided when we get support for TAG_MULTIPLE_COMPONENTS + // For now, we already have a copy of the tagGroupTagged component and we're going to use + // it below wen we increment the group version so we can clean out the dummy entry. + PortableGroup::ObjectGroup_var cleaned = PortableGroup::ObjectGroup::_duplicate (this->reference_.in ()); + if (this->empty_) + { + // remove the original profile. It's a dummy entry supplied by create_object. + cleaned = + this->manipulator_.remove_profiles (cleaned.in (), this->reference_.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (PortableGroup::ObjectGroup::_nil()); + this->empty_ = 0; + } + + // create a list of references to be merged + TAO_IOP::TAO_IOR_Manipulation::IORList iors (2); + iors.length (2); + iors [0] = CORBA::Object::_duplicate (cleaned.in()); + iors [1] = CORBA::Object::_duplicate (member); + + // Now merge the list into one new IOGR + result = + this->manipulator_.merge_iors (iors ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (PortableGroup::ObjectGroup::_nil ()); + return result._retn (); +} + +void TAO::PG_Object_Group::add_member ( + const PortableGroup::Location & the_location, + CORBA::Object_ptr member + ACE_ENV_ARG_PARAMETER) + ACE_THROW_SPEC ( (CORBA::SystemException, + PortableGroup::ObjectNotAdded)) + +{ + InternalGuard guard(this->internals_); + + ///////////////////////////////////////// + // Convert the new member to a string IOR + // This keeps a clean IOR (not and IOGR!) + // while we add it to a group. We need a + // IORs, not IOGRs to send new IOGRs out + // to replicas. + + CORBA::String_var member_ior_string = orb_->object_to_string (member ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + PortableGroup::ObjectGroup_var new_reference = add_member_to_iogr (member ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + + // Convert new member back to a (non group) ior. + CORBA::Object_var member_ior = this->orb_->string_to_object (member_ior_string ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + MemberInfo * info = 0; + ACE_NEW_THROW_EX (info, MemberInfo(member_ior.in(), the_location), + CORBA::NO_MEMORY()); + + if (this->members_.bind (the_location, info) != 0) + { + ACE_THROW(CORBA::NO_MEMORY()); + } + + this->reference_ = new_reference; // note var-to-var assignment does a duplicate + if (this->increment_version ()) + { + this->distribute_iogr (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + } + else + { + ACE_THROW (PortableGroup::ObjectNotAdded()); + } + + if (TAO_debug_level > 6) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("PG (%P|%t) exit Object_Group add_member \n") + )); + } +} + +int TAO::PG_Object_Group::set_primary_member ( + TAO_IOP::TAO_IOR_Property * prop, + const PortableGroup::Location & the_location + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC (( + CORBA::SystemException + , PortableGroup::MemberNotFound + )) +{ + InternalGuard guard(this->internals_); + int result = 1; + MemberInfo * info; + if (this->members_.find (the_location, info) == 0) + { + int cleared = 0; + this->primary_location_ = the_location; + for (MemberMap_Iterator it = this->members_.begin(); + !cleared && it != this->members_.end(); + ++it) + { + cleared = (*it).int_id_->is_primary_; + (*it).int_id_->is_primary_ = 0; + } + info->is_primary_ = 1; + + int set_ok = this->manipulator_.set_primary (prop, this->reference_.in (), info->member_.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + if (! set_ok) + { + if (TAO_debug_level > 3) + { + ACE_ERROR ( (LM_ERROR, + ACE_TEXT ("%T %n (%P|%t) - Can't set primary in IOGR .\n") + )); + } +//@@: ACE_THROW (FT::PrimaryNotSet()); + result = 0; + } + + if (result && this->increment_version()) + { + this->distribute_iogr (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + } + else + { + if (TAO_debug_level > 3) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT("TAO-PG (%P|%t) - set_primary_location throwing PrimaryNotSet because increment version failed.\n") + )); + } +//@@: ACE_THROW (FT::PrimaryNotSet()); + result = 0; + } + } + else + { + if (TAO_debug_level > 3) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO-PG (%P|%t) - set_primary_location throwing MemberNotFound.\n") + )); + } + ACE_THROW (PortableGroup::MemberNotFound()); + } + return result; +} + + +void TAO::PG_Object_Group::remove_member ( + const PortableGroup::Location & the_location + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException, + PortableGroup::MemberNotFound)) +{ + InternalGuard guard(this->internals_); + MemberInfo * info; + if (this->members_.unbind (the_location, info) == 0) + { + if (this->members_.current_size() > 0) + { + this->reference_ = + this->manipulator_.remove_profiles (this->reference_.in (), info->member_.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } + else + { + empty_ = 1; + } + + delete info; + + if (the_location == this->primary_location_) + { + this->primary_location_.length(0); + } + + if (this->increment_version ()) + { + this->distribute_iogr (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + } + + } + else + { + if (TAO_debug_level > 6) + { + + ACE_DEBUG ((LM_DEBUG, + "TAO-PG (%P|%t) - remove_member throwing MemberNotFound.\n" + )); + } + ACE_THROW (PortableGroup::MemberNotFound() ); + } +} + + +PortableGroup::ObjectGroupId TAO::PG_Object_Group::get_object_group_id () const +{ + // const cast to simulate mutable + InternalGuard guard(ACE_const_cast (TAO::PG_Object_Group *, this)->internals_); + return this->tagged_component_.object_group_id; +} + +void TAO::PG_Object_Group::set_properties_dynamically ( + const PortableGroup::Properties & overrides + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::InvalidProperty, + PortableGroup::UnsupportedProperty)) +{ + InternalGuard guard(this->internals_); + this->properties_.decode (overrides ACE_ENV_ARG_PARAMETER); + //@@ int todo_override_rather_than_replace? +} + +void TAO::PG_Object_Group::get_properties (PortableGroup::Properties_var & result ACE_ENV_ARG_DECL) const + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + // const cast to simulate mutable + InternalGuard guard(ACE_const_cast (TAO::PG_Object_Group *, this)->internals_); + this->properties_.export_properties(*result ACE_ENV_ARG_PARAMETER); +} + + +PortableGroup::TypeId TAO::PG_Object_Group::get_type_id () const +{ + // const cast to simulate mutable + InternalGuard guard(ACE_const_cast (TAO::PG_Object_Group *, this)->internals_); + return CORBA::string_dup(this->type_id_); +} + + +/////////////////// +// Internal method + +int TAO::PG_Object_Group::increment_version () +{ + // assume internals is locked + int result = 0; + this->tagged_component_.object_group_ref_version += 1; + if (TAO_debug_level > 3) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("%T %n (%P|%t) - Setting IOGR version to %u\n"), + ACE_static_cast(unsigned, this->tagged_component_.object_group_ref_version) + )); + } + + // Set the version + if ( TAO::PG_Utils::set_tagged_component (this->reference_, this->tagged_component_) ) + { + result = 1; + } + return result; +} + + +////////////////// +// Internal method +void TAO::PG_Object_Group::distribute_iogr (ACE_ENV_ARG_DECL) +{ + // assume internals is locked + CORBA::String_var iogr = this->orb_->object_to_string (this->reference_.in() ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + +// size_t n_rep = 0; // for dump_ior below + for ( MemberMap_Iterator it = this->members_.begin(); + it != this->members_.end(); + ++it) + { + MemberInfo const * info = (*it).int_id_; + // + // Unchecked narrow means the member doesn't have to actually implement the TAO_UpdateObjectGroup interface + // PortableGroup::TAO_UpdateObjectGroup_var uog = PortableGroup::TAO_UpdateObjectGroup::_unchecked_narrow ( info->member_); + // but it doesn work: error message at replica is: + // TAO-FT (2996|976) - Wrong version information within the interceptor [1 | 0] + // TAO_Perfect_Hash_OpTable:find for operation 'tao_update_object_group' (length=23) failed + // back to using _narrow + PortableGroup::TAO_UpdateObjectGroup_var uog = PortableGroup::TAO_UpdateObjectGroup::_narrow ( info->member_.in ()); + if (! CORBA::is_nil (uog.in ()) ) + { + ACE_TRY_NEW_ENV + { + if (TAO_debug_level > 3) + { + ACE_DEBUG ((LM_DEBUG, + "PG (%P|%t) - Object_Group pushing IOGR to %s member: %s@%s.\n", + (info->is_primary_ ? "Primary" : "Backup"), + this->role_.c_str(), + ACE_static_cast(const char *, info->location_[0].id) + )); + } +// dump_ior ("group", "iogr", this->tagged_component_.object_group_ref_version, iogr); +// CORBA::String_var replica_ior = this->orb_->object_to_string(uog.in() ACE_ENV_ARG_PARAMETER); +// dump_ior (info->location_[0].id, "ior", (this->tagged_component_.object_group_ref_version * 100) + n_rep++, replica_ior); + uog->tao_update_object_group (iogr, this->tagged_component_.object_group_ref_version, info->is_primary_ ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + } + ACE_CATCHANY + { + // we expect an exception + // tao_update_object_group is not a real method + } + ACE_ENDTRY; + } + else + { + ACE_ERROR ((LM_ERROR, + "TAO::PG_Object_Group::distribute iogr can't narrow member reference to PortableGroup::TAO_UpdateObjectGroup.\n" + )); + } + } +} + +PortableGroup::Locations * TAO::PG_Object_Group::locations_of_members (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + InternalGuard guard(this->internals_); + PortableGroup::Locations * result = 0; + + size_t count = this->members_.current_size (); + + ACE_NEW_THROW_EX ( + result, + PortableGroup::Locations (count), + CORBA::NO_MEMORY() ); + ACE_CHECK_RETURN (0); + + result->length (count); + + size_t pos = 0; + for (MemberMap_Iterator it = this->members_.begin(); + it != this->members_.end(); + this->members_.begin()) + { + const PortableGroup::Location & location = (*it).ext_id_; + PortableGroup::Location & out = (*result)[pos]; + out = location; + } + return result; +} + +CORBA::Object_ptr TAO::PG_Object_Group::get_member_reference ( + const PortableGroup::Location & the_location + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC (( + CORBA::SystemException, + PortableGroup::MemberNotFound)) +{ + InternalGuard guard(this->internals_); + CORBA::Object_var result = CORBA::Object::_nil (); + + MemberInfo * info; + if (this->members_.find (the_location, info) == 0) + { + result = CORBA::Object::_duplicate(info->member_.in ()); + } + else + { + ACE_THROW_RETURN (PortableGroup::MemberNotFound(), result._retn ()); + } + return result._retn (); +} + + +PortableGroup::MembershipStyleValue TAO::PG_Object_Group::get_membership_style () const +{ + PortableGroup::MembershipStyleValue membership_style = 0; + if (! TAO::find (properties_, PortableGroup::PG_MEMBERSHIP_STYLE, membership_style)) + { + membership_style = TAO_PG_MEMBERSHIP_STYLE; + } + return membership_style; +} + + +PortableGroup::MinimumNumberMembersValue TAO::PG_Object_Group::get_minimum_number_members () const +{ + PortableGroup::MinimumNumberMembersValue minimum_number_members = 0; + if (! TAO::find (properties_, PortableGroup::PG_MINIMUM_NUMBER_MEMBERS, minimum_number_members)) + { + minimum_number_members = TAO_PG_MINIMUM_NUMBER_MEMBERS; + } + return minimum_number_members; +} + +PortableGroup::InitialNumberMembersValue TAO::PG_Object_Group::get_initial_number_members () const +{ + PortableGroup::InitialNumberMembersValue initial_number_members = 0; + if (! TAO::find (properties_, PortableGroup::PG_INITIAL_NUMBER_MEMBERS, initial_number_members)) + { + initial_number_members = TAO_PG_INITIAL_NUMBER_MEMBERS; + } + return initial_number_members; +} + +void TAO::PG_Object_Group::create_member ( + const PortableGroup::Location & the_location, + const char * type_id, + const PortableGroup::Criteria & the_criteria + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException, + PortableGroup::MemberAlreadyPresent, + PortableGroup::NoFactory, + PortableGroup::ObjectNotCreated, + PortableGroup::InvalidCriteria, + PortableGroup::CannotMeetCriteria)) +{ + InternalGuard guard(this->internals_); + + if (0 != this->members_.find (the_location)) + { + // @@ what if factories were passed as criteria? + + CORBA::String_var factory_type; + PortableGroup::FactoryInfos_var factories = + this->factory_registry_->list_factories_by_role ( + role_.c_str(), + factory_type.out () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // @@ what if factory_type != type_id != this->type_id_ + + int created = 0; // bool + CORBA::ULong factory_count = factories->length (); + for (CORBA::ULong factory_pos = 0; + ! created && factory_pos < factory_count; + ++factory_pos) + { + const PortableGroup::FactoryInfo & factory_info = (*factories)[factory_pos]; + if (factory_info.the_location == the_location) + { + // @@ should we merge the_criteria with factory_info.the_criteria? + + PortableGroup::GenericFactory::FactoryCreationId_var fcid; + CORBA::Object_var member = factory_info.the_factory->create_object ( + type_id, + the_criteria, + fcid. out() + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // convert the new member to a stringified IOR to avoid contamination with group info + CORBA::String_var member_ior_string = orb_->object_to_string (member.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + PortableGroup::ObjectGroup_var new_reference = this->add_member_to_iogr (member.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + // Convert new member back to a (non group) ior. + CORBA::Object_var member_ior = this->orb_->string_to_object (member_ior_string ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + MemberInfo * info = 0; + ACE_NEW_THROW_EX (info, MemberInfo( + member_ior.in(), + the_location, + factory_info.the_factory, + fcid.in ()), + CORBA::NO_MEMORY()); + ACE_CHECK; + + if (this->members_.bind (the_location, info) != 0) + { + ACE_THROW(CORBA::NO_MEMORY()); + } + + this->reference_ = new_reference; // note var-to-var assignment does a duplicate + if (this->increment_version ()) + { + this->distribute_iogr (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + } + created = 1; + } + } + if (! created) + { + ACE_THROW (PortableGroup::NoFactory ()); + } + } + else + { + ACE_THROW (PortableGroup::MemberAlreadyPresent ()); + } + +} + +void TAO::PG_Object_Group::create_members (size_t count ACE_ENV_ARG_DECL) + ACE_THROW_SPEC (( + CORBA::SystemException, + PortableGroup::NoFactory + )) +{ + // assume internals is locked + // @@ what if factories were passed as criteria? + + CORBA::String_var factory_type; + PortableGroup::FactoryInfos_var factories = + this->factory_registry_->list_factories_by_role ( + role_.c_str(), + factory_type.out () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + CORBA::ULong factory_count = factories->length (); + if (factory_count > 0) + { + CORBA::ULong factory_pos = 0; + while (members_.current_size () < count && factory_pos < factory_count) + { + const PortableGroup::FactoryInfo & factory_info = (*factories)[factory_pos]; + const PortableGroup::Location & factory_location = factory_info.the_location; + if (0 != this->members_.find (factory_location)) + { + /////////////////////////////////////////// + // If a factory refuses to create a replica + // it's not fatal. + ACE_TRY_NEW_ENV + { + PortableGroup::GenericFactory::FactoryCreationId_var fcid; + CORBA::Object_var member = factory_info.the_factory->create_object ( + this->type_id_.in (), + factory_info.the_criteria, + fcid. out() + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // convert the new member to a stringified IOR to avoid contamination with group info + CORBA::String_var member_ior_string = orb_->object_to_string (member.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + PortableGroup::ObjectGroup_var new_reference = this->add_member_to_iogr (member.in () + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Convert new member back to a (non group) ior. + CORBA::Object_var member_ior = this->orb_->string_to_object (member_ior_string ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + MemberInfo * info = 0; + ACE_NEW_THROW_EX (info, MemberInfo( + member_ior.in(), + factory_location, + factory_info.the_factory, + fcid.in ()), + CORBA::NO_MEMORY()); + ACE_TRY_CHECK; + + if (this->members_.bind (factory_location, info) != 0) + { + ACE_TRY_THROW(CORBA::NO_MEMORY()); + } + this->reference_ = new_reference; // note var-to-var assignment does a duplicate + } + ACE_CATCHANY + { + // log, but otherwise ignore the errorf + if (TAO_debug_level > 0) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("PG (%P|%t) Replica Factory @ %s refused create_object request for type %s\n"), + ACE_static_cast (const char *, factory_info.the_location[0].id), + ACE_static_cast (const char *, this->type_id_.in ()) + )); + } + } + ACE_ENDTRY; + } + } + + if (this->increment_version ()) + { + this->distribute_iogr (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + } + } + else + { + ACE_THROW (PortableGroup::NoFactory()); + } +} + +void TAO::PG_Object_Group::initial_populate (ACE_ENV_SINGLE_ARG_DECL) +{ + InternalGuard guard(this->internals_); + if ( this->get_membership_style() == PortableGroup::MEMB_INF_CTRL ) + { + PortableGroup::InitialNumberMembersValue initial_number_members = this->get_initial_number_members (); + if (members_.current_size () < initial_number_members) + { + this->create_members (initial_number_members); + } + } +} + +void TAO::PG_Object_Group::minimum_populate (ACE_ENV_SINGLE_ARG_DECL) +{ + InternalGuard guard(this->internals_); + if ( this->get_membership_style() == PortableGroup::MEMB_INF_CTRL ) + { + PortableGroup::MinimumNumberMembersValue minimum_number_members = this->get_minimum_number_members (); + if (members_.current_size () < minimum_number_members) + { + this->create_members (minimum_number_members); + } + } +} + +int TAO::PG_Object_Group::has_member_at (const PortableGroup::Location & location ) +{ + return (0 == this->members_.find (location)); +} + + + + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + + template class ACE_Hash_Map_Manager_Ex < + PortableGroup::Location, + TAO::PG_Object_Group::MemberInfo *, + TAO_PG_Location_Hash, + TAO_PG_Location_Equal_To, + TAO_SYNCH_MUTEX>; + template class ACE_Hash_Map_Entry < + PortableGroup::Location, + TAO::PG_Object_Group::MemberInfo *>; + template class ACE_Hash_Map_Iterator_Ex < + PortableGroup::Location, + TAO::PG_Object_Group::MemberInfo *, + TAO_PG_Location_Hash, + TAO_PG_Location_Equal_To, + TAO_SYNCH_MUTEX>; + +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) + +# pragma instantiate ACE_Hash_Map_Manager_Ex < + PortableGroup::Location, + TAO::PG_Object_Group::MemberInfo *, + TAO_PG_Location_Hash, + TAO_PG_Location_Equal_To, + TAO::PG_Object_Group::MemberMapMutex> +# pragma instantiate ACE_Hash_Map_Entry <PortableGroup::Location, TAO::PG_Object_Group::MemberInfo *> +# pragma instantiate ACE_Hash_Map_Iterator_Ex < + PortableGroup::Location, + TAO::PG_Object_Group::MemberInfo *, + TAO_PG_Location_Hash, + TAO_PG_Location_Equal_To, + TAO::PG_Object_Group::MemberMapMutex> + +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group.h b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group.h new file mode 100644 index 00000000000..9b91b59d13b --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group.h @@ -0,0 +1,382 @@ +// -*- C++ -*- +//============================================================================= +/** + * @file PG_Object_Group.h + * + * $Id$ + * + * Manage all information related to an object group. + * @@ Note: the above description is optimistic. The hope is to eventually + * @@ consolidate all information related to an object group into this object. + * @@ however at the moment GenericFactory, ObjectGroupManager, and FT_ReplicationManager + * @@ have parallel collections of object group information. + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= + +#ifndef TAO_PG_OBJECT_GROUP_H_ +#define TAO_PG_OBJECT_GROUP_H_ +#include /**/ <ace/pre.h> +#include <ace/ACE.h> + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "PG_Property_Set.h" + +////////////////////////////////// +// Classes declared in this header +namespace TAO +{ + class PG_Object_Group; +} + +///////////////////////////////// +// Includes needed by this header +#include <orbsvcs/PortableGroupC.h> +#include <tao/PortableServer/PortableServer.h> +#include <ace/Hash_Map_Manager_T.h> +#include "PG_Location_Hash.h" +#include "PG_Location_Equal_To.h" +#include "PG_Object_Group_Manipulator.h" + +///////////////////// +// Forward references + +namespace TAO_IOP +{ + class TAO_IOR_Property; +} + +//////////////// +// Class declarations +namespace TAO +{ + /** + */ + class TAO_PortableGroup_Export PG_Object_Group + { + // Information about an object group member + struct MemberInfo + { + /// Reference to the member. + CORBA::Object_var member_; + + /// The factory that was used to create this object + /// nil if application created. + PortableGroup::GenericFactory_var factory_; + + /// FactoryCreationId assigned to the member. Empty if application created + PortableGroup::GenericFactory::FactoryCreationId factory_id_; + + /// Location where this member exists + PortableGroup::Location location_; + + + /// TRUE if this is primary member + CORBA::Boolean is_primary_; + + + /////////////// + // Methods + + /// Construct an application-supplied member. + MemberInfo (CORBA::Object_ptr member, const PortableGroup::Location & location); + + /// Construct a infrastructure-created member. + MemberInfo ( + CORBA::Object_ptr member, + const PortableGroup::Location & location, + PortableGroup::GenericFactory_ptr factory, + PortableGroup::GenericFactory::FactoryCreationId factory_id); + + /// Destructor + ~MemberInfo(); + }; + + typedef TAO_SYNCH_MUTEX MemberMapMutex; + typedef ACE_Hash_Map_Manager_Ex < + PortableGroup::Location, + MemberInfo *, + TAO_PG_Location_Hash, + TAO_PG_Location_Equal_To, + MemberMapMutex> MemberMap; + typedef ACE_Hash_Map_Entry <PortableGroup::Location, MemberInfo *> MemberMap_Entry; + typedef ACE_Hash_Map_Iterator_Ex < + PortableGroup::Location, + MemberInfo *, + TAO_PG_Location_Hash, + TAO_PG_Location_Equal_To, + MemberMapMutex> MemberMap_Iterator; + + ///////////////////// + // Construct/Destruct + public: + /** + * @@TODO DOC + */ + PG_Object_Group ( + CORBA::ORB_ptr orb, + PortableGroup::FactoryRegistry_ptr factory_registry, + TAO::PG_Object_Group_Manipulator & manipulator, + CORBA::Object_ptr empty_group, + const PortableGroup::TagGroupTaggedComponent & tagged_component, + const char * type_id, + const PortableGroup::Criteria & the_criteria, + TAO::PG_Property_Set * type_properties); + + + /// Destructor + ~PG_Object_Group (); + + ///////////////// + // public methods + + public: + /// return a duplicated reference to this group (IOGR) + PortableGroup::ObjectGroup_ptr reference()const; + + /** + * Note the caller receives a copy of the factoryinfos in the result argument. + * inefficient, but thread safe. + */ + void get_group_specific_factories (PortableGroup::FactoryInfos & result) const; + + /** + * get location of primary member + */ + const PortableGroup::Location & get_primary_location() const; + + /** + * returns a duplicate + * caller must release + */ + PortableGroup::TypeId get_type_id ()const; + + + /** + * @@TODO DOC + */ + PortableGroup::MembershipStyleValue get_membership_style() const; + + /** + * @@TODO DOC + */ + PortableGroup::MinimumNumberMembersValue get_minimum_number_members () const; + + /** + * @@TODO DOC + */ + PortableGroup::InitialNumberMembersValue get_initial_number_members () const; + + + + /** + * @@TODO DOC + */ + void set_properties_dynamically ( + const PortableGroup::Properties & overrides + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException, + PortableGroup::InvalidProperty, + PortableGroup::UnsupportedProperty)); + + /** + * @@TODO DOC + */ + void get_properties (PortableGroup::Properties_var & result) const + ACE_THROW_SPEC ((CORBA::SystemException)); + + /** + * @@TODO DOC + */ + PortableGroup::ObjectGroupId get_object_group_id () const; + + /** + * Add a new member to the group. + * @param the_location the location for the new member + * @param member the member to be added + */ + void add_member ( + const PortableGroup::Location & the_location, + CORBA::Object_ptr member + ACE_ENV_ARG_PARAMETER) + ACE_THROW_SPEC ( (CORBA::SystemException, + PortableGroup::ObjectNotAdded)); + + /** + * set the replica at the given location to be primary. + * Note: This should return void and throw FT::PrimaryNotSet + * but to avoid dependancies between PortableGroup and FaultTolerance + * it returns a boolean result. A false return means caller should + * throw FT::PrimaryNot_Set. + */ + int set_primary_member ( + TAO_IOP::TAO_IOR_Property * prop, + const PortableGroup::Location & the_location + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC (( + CORBA::SystemException + , PortableGroup::MemberNotFound + )); + + /** + * @@TODO DOC + */ + void remove_member ( + const PortableGroup::Location & the_location + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException, + PortableGroup::MemberNotFound)); + + + /** + * @@TODO DOC + */ + void create_member ( + const PortableGroup::Location & the_location, + const char * type_id, + const PortableGroup::Criteria & the_criteria + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException, + PortableGroup::MemberAlreadyPresent, + PortableGroup::NoFactory, + PortableGroup::ObjectNotCreated, + PortableGroup::InvalidCriteria, + PortableGroup::CannotMeetCriteria)); + + /** + * @@TODO DOC + */ + PortableGroup::Locations * locations_of_members (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /** + * @@TODO DOC + */ + CORBA::Object_ptr get_member_reference ( + const PortableGroup::Location & the_location + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC (( + CORBA::SystemException, + PortableGroup::MemberNotFound)); + + + /** + * @@TODO DOC + */ + void initial_populate (ACE_ENV_SINGLE_ARG_DECL); + + /** + * @@TODO DOC + */ + void minimum_populate (ACE_ENV_SINGLE_ARG_DECL); + + + /** + * @@TODO DOC + */ + int has_member_at (const PortableGroup::Location & location ); + + ///////////////////////// + // Implementation methods + private: + + int increment_version (); + + void distribute_iogr (ACE_ENV_ARG_DECL); + + PortableGroup::ObjectGroup_ptr add_member_to_iogr(CORBA::Object_ptr member ACE_ENV_ARG_DECL); + + + void create_members (size_t count ACE_ENV_ARG_DECL) + ACE_THROW_SPEC (( + CORBA::SystemException, + PortableGroup::NoFactory + )); + + + ///////////////////////// + // Forbidden methods + private: + PG_Object_Group (); + PG_Object_Group (const PG_Object_Group & rhs); + PG_Object_Group & operator = (const PG_Object_Group & rhs); + + + ///////////////// + // Static Methods + public: + + /////////////// + // Static Data + private: + + /////////////// + // Data Members + private: + + /** + * Protect internal state. + */ + TAO_SYNCH_MUTEX internals_; + typedef ACE_Guard<TAO_SYNCH_MUTEX> InternalGuard; + + CORBA::ORB_var orb_; + + /// Where to find the factories for replicas. + PortableGroup::FactoryRegistry_var factory_registry_; + + + // The object group manipulator + TAO::PG_Object_Group_Manipulator & manipulator_; + + /// boolean true if empty group + int empty_; + + ACE_CString role_; + PortableGroup::TypeId_var type_id_; + + /** + * the GroupTaggedComponent that defines this group + * contains: + * GIOP::Version component_version; + * TAO_String_Manager group_domain_id; + * PortableGroup::ObjectGroupId object_group_id; + * PortableGroup::ObjectGroupRefVersion object_group_ref_version; + */ + PortableGroup::TagGroupTaggedComponent tagged_component_; + + /** + * the reference (IOGR) to this group + */ + PortableGroup::ObjectGroup_var reference_; + + /** + * The CORBA object id assigned to this object group + */ + PortableServer::ObjectId_var object_id_; + + // group members + MemberMap members_; + + PortableGroup::Location primary_location_; + + // Miscellaneous properties passed to create_object when this group + // was initially created. To be used to create new members. + TAO::PG_Property_Set properties_; + + // Cached property information + + PortableGroup::InitialNumberMembersValue initial_number_members_; + PortableGroup::MinimumNumberMembersValue minimum_number_members_; + PortableGroup::FactoryInfos group_specific_factories_; + + }; +} // namespace TAO + +#include /**/ <ace/post.h> + +#endif // TAO_PG_OBJECT_GROUP_H_ diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Manipulator.cpp b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Manipulator.cpp new file mode 100644 index 00000000000..6c86aaec4f8 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Manipulator.cpp @@ -0,0 +1,188 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file PG_Object_Group_Manipulator.cpp + * + * $Id$ + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= + +#include "PG_Object_Group_Manipulator.h" +#include "PG_Utils.h" + +#include "tao/debug.h" + +ACE_RCSID (PortableGroup, + PG_Object_Group_Manipulator, + "$Id$") + +TAO::PG_Object_Group_Manipulator::PG_Object_Group_Manipulator () + : orb_ (CORBA::ORB::_nil ()) + , poa_ (PortableServer::POA::_nil ()) + , iorm_ () + , lock_ogid_ () + , next_ogid_ (1) // don't use ogid 0 +{ +} + +TAO::PG_Object_Group_Manipulator::~PG_Object_Group_Manipulator () +{ +} + +void TAO::PG_Object_Group_Manipulator::allocate_ogid (PortableGroup::ObjectGroupId & ogid) +{ + ACE_GUARD (TAO_SYNCH_MUTEX, guard, this->lock_ogid_); + + // The numerical value used for the ObjectId increases + // monotonically. + + ogid = this->next_ogid_; + this->next_ogid_ += 1; +} + +PortableServer::ObjectId * TAO::PG_Object_Group_Manipulator::convert_ogid_to_oid (PortableGroup::ObjectGroupId ogid) const +{ + // 4294967295 -- Largest 32 bit unsigned integer + char oid_str[11]; + ACE_OS::snprintf (oid_str, sizeof(oid_str), + "%lu", + ACE_static_cast (ACE_UINT32,ogid)); + oid_str[sizeof(oid_str) - 1] = '\0'; + + return PortableServer::string_to_ObjectId (oid_str); +} + +PortableGroup::ObjectGroup_ptr +TAO::PG_Object_Group_Manipulator::create_object_group ( + const char * type_id, + const char * domain_id, + PortableGroup::ObjectGroupId & group_id + ACE_ENV_ARG_DECL) +{ + allocate_ogid(group_id); + PortableServer::ObjectId_var oid = convert_ogid_to_oid (group_id); + + // Create a reference for the ObjectGroup + CORBA::Object_var object_group = + this->poa_->create_reference_with_id (group_id, + type_id + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + PortableGroup::TagGroupTaggedComponent tag_component; + + tag_component.component_version.major = (CORBA::Octet) 1; + tag_component.component_version.minor = (CORBA::Octet) 0; + tag_component.group_domain_id = domain_id; + tag_component.object_group_id = group_id; + tag_component.object_group_ref_version = 0; + + // Set the property + TAO::PG_Utils::set_tagged_component (object_group, + tag_component); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + return object_group._retn (); +} + +void +TAO::PG_Object_Group_Manipulator::init (CORBA::ORB_ptr orb, PortableServer::POA_ptr poa ACE_ENV_ARG_DECL) +{ + ACE_ASSERT (CORBA::is_nil (this->orb_.in ()) && !CORBA::is_nil (orb)); + this->orb_ = CORBA::ORB::_duplicate (orb); + + ACE_ASSERT (CORBA::is_nil (this->poa_.in ()) && !CORBA::is_nil (poa)); + this->poa_ = PortableServer::POA::_duplicate (poa); + + // Get an object reference for the ORBs IORManipulation object! + CORBA::Object_var IORM = this->orb_->resolve_initial_references ( + TAO_OBJID_IORMANIPULATION, 0 ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + this->iorm_ = TAO_IOP::TAO_IOR_Manipulation::_narrow ( + IORM.in () ACE_ENV_ARG_PARAMETER); +// ACE_CHECK; +} + +int TAO::PG_Object_Group_Manipulator::set_primary ( + TAO_IOP::TAO_IOR_Property * prop, + PortableGroup::ObjectGroup_ptr group, + CORBA::Object_ptr new_primary + ACE_ENV_ARG_DECL) const +{ + int sts = this->iorm_->is_primary_set (prop, group ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + if (sts) + { + (void)this->iorm_->remove_primary_tag (prop, group ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0); + } + /////note: iorm takes it's parameters in the "wrong" order for this call + return this->iorm_->set_primary (prop, new_primary, group ACE_ENV_ARG_PARAMETER); +} + +PortableGroup::ObjectGroup_ptr TAO::PG_Object_Group_Manipulator::merge_iors( + TAO_IOP::TAO_IOR_Manipulation::IORList & list ACE_ENV_ARG_DECL) const +{ + return this->iorm_->merge_iors (list ACE_ENV_ARG_PARAMETER); +} + +PortableGroup::ObjectGroup_ptr TAO::PG_Object_Group_Manipulator::remove_profiles( + PortableGroup::ObjectGroup_ptr group, + PortableGroup::ObjectGroup_ptr profile + ACE_ENV_ARG_DECL) const +{ + return this->iorm_->remove_profiles(group, profile ACE_ENV_ARG_PARAMETER); +} + +void dump_membership (const char * label, PortableGroup::ObjectGroup_ptr member) +{ + ACE_UNUSED_ARG (label); + ACE_UNUSED_ARG (member); +#if 0 + PortableGroup::TagFTGroupTaggedComponent ft_tag_component; + TAO_FT_IOGR_Property prop (ft_tag_component); + if (this->iorm_->is_primary_set (&prop, member)) + { + ACE_DEBUG ( (LM_DEBUG, + ACE_TEXT ("%T %n (%P|%t) - %s: PRIMARY member.\n"), + label + )); + } + else + { + ACE_DEBUG ( (LM_DEBUG, + ACE_TEXT ("%T %n (%P|%t) - %s: backup member.\n"), + label + )); + } + + PortableGroup::TagGroupTaggedComponent tag_component; + if (TAO::PG_Utils::get_tagged_component (member, tag_component)) + { + ACE_DEBUG ( (LM_DEBUG, + ACE_TEXT ("%T %n (%P|%t) - %s: Group: .") + ACE_TEXT (" version: %u\n"), + + label, + tag_component.object_group_ref_version + )); + } + else + { + ACE_DEBUG ( (LM_DEBUG, + ACE_TEXT ("%T %n (%P|%t) - %s: No group information found.\n"), + label + )); + } +#endif +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) + +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Manipulator.h b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Manipulator.h new file mode 100644 index 00000000000..e4a18ce8c72 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Object_Group_Manipulator.h @@ -0,0 +1,112 @@ +// -*- C++ -*- + +//============================================================================= +/** + * @file PG_Object_Group_Manipulator.h + * + * $Id$ + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= + + +#ifndef TAO_PG_OBJECT_GROUP_MANIPULATOR_H +#define TAO_PG_OBJECT_GROUP_MANIPULATOR_H + +#include /**/ "ace/pre.h" +#include "orbsvcs/PortableGroupS.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include <tao/IORManipulation/IORManip_Loader.h> + +namespace TAO +{ + + /** + * @class TAO::PG_Object_Group_Manipulator + * + * @brief PortableGroup::ObjectGroupManager implementation. + * + * The ObjectGroupManager provides the interface necessary to + * facilitate application-controlled object group membership. + */ + class TAO_PortableGroup_Export PG_Object_Group_Manipulator + { + public: + + /// Constructor. + PG_Object_Group_Manipulator (); + + /// Destructor. + ~PG_Object_Group_Manipulator (); + + /** + * Initializes the group creator. + */ + void init (CORBA::ORB_ptr orb, PortableServer::POA_ptr poa ACE_ENV_ARG_DECL); + + /** + * Create an empty object group. + */ + PortableGroup::ObjectGroup_ptr create_object_group ( + const char * type_id, + const char * domain_id, + PortableGroup::ObjectGroupId & group_id + ACE_ENV_ARG_DECL); + + PortableGroup::ObjectGroup_ptr remove_profiles ( + PortableGroup::ObjectGroup_ptr group, + PortableGroup::ObjectGroup_ptr profile + ACE_ENV_ARG_DECL) const; + + PortableGroup::ObjectGroup_ptr merge_iors ( + TAO_IOP::TAO_IOR_Manipulation::IORList & iors ACE_ENV_ARG_PARAMETER) const; + + int set_primary ( + TAO_IOP::TAO_IOR_Property * prop, + PortableGroup::ObjectGroup_ptr reference, + CORBA::Object_ptr new_primary + ACE_ENV_ARG_DECL) const; + + void dump_membership (const char * label, PortableGroup::ObjectGroup_ptr member) const; + + private: + + /** + * Allocate an ogid for a new object group + */ + void allocate_ogid (PortableGroup::ObjectGroupId & ogid); + + /** + * convert numeric OGID to Sequence<Octet> oid + */ + PortableServer::ObjectId * convert_ogid_to_oid (PortableGroup::ObjectGroupId ogid) const; + + private: + + /// The orb + CORBA::ORB_var orb_; + + /// Reference to the POA that created the object group references. + PortableServer::POA_var poa_; + + /// The ORBs IORManipulation object + TAO_IOP::TAO_IOR_Manipulation_var iorm_; + + /// Lock used to synchronize access to next_ogid_. + TAO_SYNCH_MUTEX lock_ogid_; + + /// Next ogid to be allocated. + PortableGroup::ObjectGroupId next_ogid_; + + }; +} //namespace TAO + + +#include /**/ "ace/post.h" + +#endif /* TAO::PG_OBJECT_GROUP_CREATOR_H */ diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Properties_Encoder.cpp b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Properties_Encoder.cpp new file mode 100644 index 00000000000..73a4497f2d6 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Properties_Encoder.cpp @@ -0,0 +1,68 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file PG_Properties_Encoder.cpp + * + * $Id$ + * + * This file implements classes to help manage the Properties + * defined in the Portable Object Group. + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= +#include "ace/pre.h" +#include "PG_Properties_Encoder.h" + +////////// +// Properties_Encoder +TAO_PG::Properties_Encoder::Properties_Encoder () +{ +} + +TAO_PG::Properties_Encoder::~Properties_Encoder () +{ +} + + +void TAO_PG::Properties_Encoder::add ( + const char * name, + const PortableGroup::Value & value) +{ + NamedValue nv(name, value); + values_.push_back(nv); +} + +void TAO_PG::Properties_Encoder::encode ( + PortableGroup::Properties * property_set) const +{ + ACE_ASSERT (property_set != 0); + size_t count = values_.size(); + property_set->length(count); + for( size_t nItem = 0; nItem < count; ++nItem ) + { + const NamedValue & nv = values_[nItem]; + PortableGroup::Property & property = (*property_set)[nItem]; + PortableGroup::Name & nsName = property.nam; + PortableGroup::Value & anyValue = property.val; + // assign the value + anyValue = (nv.second()); + + // assign the name + // @@: This restricts the name to a single level with no "kind" + // @@: remove this restriction (?) + nsName.length(1); + CosNaming::NameComponent & nc = nsName[0]; + + nc.id = CORBA::string_dup (nv.first().c_str()); + // nc.kind defaults to empty. Leave it that way (for now) + } +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + template class ACE_Pair< ACE_CString, PortableGroup::Value>; + template class ACE_Vector< TAO_PG::Properties_Encoder::NamedValue, 10 >; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +# pragma instantiate ACE_Pair< ACE_CString, PortableGroup::Value> +# pragma instantiate ACE_Vector< TAO_PG::Properties_Encoder::NamedValue, 10 > +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Properties_Encoder.h b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Properties_Encoder.h new file mode 100644 index 00000000000..ab5a4e56242 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Properties_Encoder.h @@ -0,0 +1,68 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file PG_Properties_Encoder.h + * + * $Id$ + * + * This file declares a class to help manage PortableGroup::Properties + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= +#ifndef TAO_PG_PROPERTIES_ENCODER_H +#define TAO_PG_PROPERTIES_ENCODER_H +#include "orbsvcs/PortableGroupS.h" +#include "orbsvcs/CosNamingC.h" +#include "portablegroup_export.h" + +#include "ace/Vector_T.h" +#include "ace/Pair_T.h" + +namespace TAO_PG +{ + /** + * A helper to assemble a set of properties into a PortableGroup::Properties structure. + * + * To use a Properties_Encoder: + * Create it. + * Add properties to it using the add method. + * Allocate a new PortableGroup::Properties. + * Use the encode method to transfer the properties into the + * PortableGroup::Properties. + */ + class TAO_PortableGroup_Export Properties_Encoder + { + typedef ACE_Pair< ACE_CString, PortableGroup::Value> NamedValue; + typedef ACE_Vector< NamedValue, 10 > NamedValueVec; + + public: + /** + * Construct an empty set of properties. + */ + Properties_Encoder (); + + /// standard destructor + ~Properties_Encoder (); + + /** + * add a name/value property to the Properties_Encoder. + */ + void add (const char * name, const PortableGroup::Value & value); + + /** + * Encode all properties in this Properties_Encoder into a PortableGroup::Properties. + * + */ + void encode (PortableGroup::Properties * property_set) const; + + private: + Properties_Encoder (const Properties_Encoder & rhs); + Properties_Encoder & operator = (const Properties_Encoder & rhs); + private: + NamedValueVec values_; + }; + +} //namespace TAO_PG + +#endif // TAO_PG_PROPERTIES_ENCODER_H diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Properties_Support.cpp b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Properties_Support.cpp new file mode 100644 index 00000000000..1569b65789a --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Properties_Support.cpp @@ -0,0 +1,174 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file PG_Properties_Support.cpp + * + * $Id$ + * + * This file implements classes to help manage PortableGroup::Properties + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= + +#include "PG_Properties_Support.h" + +TAO::PG_Properties_Support::PG_Properties_Support () +{ +} + +TAO::PG_Properties_Support::~PG_Properties_Support () +{ + +} + +void TAO::PG_Properties_Support::set_default_property (const char * name, + const PortableGroup::Value & value + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + this->default_properties_.set_property(name, value ACE_ENV_ARG_PARAMETER); +} + +void TAO::PG_Properties_Support::set_default_properties (const PortableGroup::Properties & props) +{ + this->default_properties_.decode (props); +} + +PortableGroup::Properties * +TAO::PG_Properties_Support::get_default_properties ( + ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC (( + CORBA::SystemException, + PortableGroup::InvalidProperty, + PortableGroup::UnsupportedProperty)) +{ + PortableGroup::Properties_var result; + ACE_NEW_THROW_EX ( result, PortableGroup::Properties(), CORBA::NO_MEMORY()); + this->default_properties_.export_properties (*result ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (PortableGroup::Properties::_nil()); + return result._retn (); +} + +void TAO::PG_Properties_Support::remove_default_properties ( + const PortableGroup::Properties & props + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + this->default_properties_.remove (props ACE_ENV_ARG_PARAMETER); +} + +void +TAO::PG_Properties_Support::set_type_properties ( + const char *type_id, + const PortableGroup::Properties & overrides + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException, + PortableGroup::InvalidProperty, + PortableGroup::UnsupportedProperty)) +{ + InternalGuard guard(this->internals_); + + TAO::PG_Property_Set * typeid_properties; + if ( 0 != this->properties_map_.find (type_id, typeid_properties)) + { + ACE_NEW_THROW_EX ( + typeid_properties, + TAO::PG_Property_Set (overrides, & this->default_properties_), + CORBA::NO_MEMORY()); + this->properties_map_.bind (type_id, typeid_properties); + } + typeid_properties->clear (); + typeid_properties->decode (overrides ACE_ENV_ARG_PARAMETER); + +} + +PortableGroup::Properties * +TAO::PG_Properties_Support::get_type_properties ( + const char *type_id + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException)) +{ + PortableGroup::Properties_var result; + ACE_NEW_THROW_EX (result, PortableGroup::Properties(), CORBA::NO_MEMORY ()); + + InternalGuard guard(this->internals_); + + TAO::PG_Property_Set * typeid_properties; + if ( 0 != this->properties_map_.find (type_id, typeid_properties)) + { + typeid_properties->export_properties (*result ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } + return result._retn (); +} + +void +TAO::PG_Properties_Support::remove_type_properties ( + const char *type_id, + const PortableGroup::Properties & props + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException)) +{ + // NOTE: do not actually delete the properties for this type. + // There may be object groups depending on these. + // Reference counted pointers could be used to allow property sets + // for unused typeids to be deleted. + + InternalGuard guard(this->internals_); + + TAO::PG_Property_Set * typeid_properties; + if ( 0 != this->properties_map_.find (type_id, typeid_properties)) + { + typeid_properties->remove (props ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + } +} + + +TAO::PG_Property_Set * +TAO::PG_Properties_Support::find_typeid_properties ( + const char *type_id + ACE_ENV_ARG_PARAMETER) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + InternalGuard guard(this->internals_); + + TAO::PG_Property_Set * typeid_properties = 0; + if ( 0 != this->properties_map_.find (type_id, typeid_properties)) + { + ACE_NEW_THROW_EX ( + typeid_properties, + TAO::PG_Property_Set (& this->default_properties_), + CORBA::NO_MEMORY()); + this->properties_map_.bind (type_id, typeid_properties); + } + return typeid_properties; +} + + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + + template class ACE_Hash_Map_Manager< + ACE_CString, + ::TAO::PG_Property_Set *, + TAO_SYNCH_MUTEX>; + + template class ACE_Hash_Map_Iterator< + ACE_CString, + ::TAO::PG_Property_Set *, + TAO_SYNCH_MUTEX>; + +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) + +# pragma instantiate ACE_Hash_Map_Manager< + ACE_CString, + ::TAO::PG_Property_Set *, + TAO_SYNCH_MUTEX> + +# pragma instantiate ACE_Hash_Map_Iterator< + ACE_CString, + ::TAO::PG_Property_Set *, + TAO_SYNCH_MUTEX> + +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Properties_Support.h b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Properties_Support.h new file mode 100644 index 00000000000..c46e04bcd3a --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Properties_Support.h @@ -0,0 +1,207 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file PG_Properties_Support.h + * + * $Id$ + * + * This file declares classes to help manage the PortableGroup::Properties + * It serves roughly the same purpose as PG_PropertiesManager, but takes a + * different approach that suits the needs of FT CORBA. + * It would be possible to replace PG_PropertiesManager, or implement it in + * terms of PG_Properties_Support at some time in the future. + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= +#ifndef TAO_PG_PROPERTIES_SUPPORT_H +#define TAO_PG_PROPERTIES_SUPPORT_H + +#include "PG_Property_Set.h" + +namespace TAO +{ + /** + * This Properties Support object manages Property Sets (TAO::PG_Property_Set). + * + * One set, default_properties_, + * acts as a "global" default set of properties. + * + * The collection, properties_map_, contains a set of properties for each + * PortableGroup::type_id. The default set acts as a "parent" for each of + * these type_id sets. + * + * Expected use: When an object group is created that implements the interface + * identified by type_id, the corresponding typed_id propery set acts as a + * parent to the Property set contained in the PG_Object_Group. + * + * This heirarchy of property sets provides the correct property behavior. A + * request for a propery to an ObjectGroup will be satisfied from: + * by the object group group property set, or + * the typed_id property set, or + * the default property set, or + * the request will fail.. + * + * Note that changes to type_id or default properties will be visible + * immediately at the ObjectGroup level. + */ + + class TAO_PortableGroup_Export PG_Properties_Support + { + typedef ACE_Hash_Map_Manager< + ACE_CString, + ::TAO::PG_Property_Set *, + TAO_SYNCH_MUTEX> Properties_Map; + typedef ACE_Hash_Map_Iterator< + ACE_CString, + ::TAO::PG_Property_Set *, + TAO_SYNCH_MUTEX> Properties_Map_Iterator; + + public: + PG_Properties_Support (); + ~PG_Properties_Support (); + + /** + * Set a single default property. + * Overwriting any value previously set for that property. + * Leaving all other properties untouched. + * @param name the name of the property to set + * @value an Any containing the value. + */ + void set_default_property (const char * name, + const PortableGroup::Value & value + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /** + * Update the default property set. + * + * Properties that appear in props are replaced in or added to the default + * property set. Properties that do not appear in props are unchanged. + * + * @param props the set of properties to update the defaults. + */ + void set_default_properties (const PortableGroup::Properties & props); + + /** + * Export the default properties in PortableGroup::Properties format. + * + * This produces the properties in a format suitable for use across + * a CORBA interface. + * The caller owns the resulting Properties and must release it to avoid + * resource leaks. + * @returns a newly allocated PortableGroup::Properties. + */ + PortableGroup::Properties * get_default_properties (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException, + PortableGroup::InvalidProperty, + PortableGroup::UnsupportedProperty)); + + /** + * Undefine default properties that appear in props. + * + * Properties that are defined in props are removed from the default + * property set. Removal is done by name. The property values do not + * have to match. There is no penalty for attempting to remove a property + * that does not exist. + * @param props a set of propertys to be removed by name. + */ + void remove_default_properties ( + const PortableGroup::Properties & props + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /** + * Override or define properties associated with a type_id. + * + * If a property set does not exist for type_id, a new one will be created. + * Any property included in overrides will be set or replaced in the type_id + * property set. Any property not in overrides will be unchanged. + * + * Contrary to the "throws" specification, this method does not attempt + * to validate the properties because doing so would unnecessarily constrain + * the uses to which this class could be put (although one could strategize the + * validation.) + */ + void set_type_properties ( + const char *type_id, + const PortableGroup::Properties & overrides + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC (( + CORBA::SystemException, + PortableGroup::InvalidProperty, + PortableGroup::UnsupportedProperty)); + + /** + * Export the property set in a PortableGroup::Properties format. + * + * This produces the properties associated with a type_id -- including + * any default properties that have not been overridden at the type_id level + * in a format suitable for use across a CORBA interface. + * + * The caller owns the resulting Properties and must release it to avoid + * resource leaks. + * + * Compare this method to find_typeid_properties which returns a pointer + * to the internal representation of the properties in TAO::PG_Property_Set + * format. This is more efficient, but suitable only for internal use. + * + * @param type_id identifies the set of properties to be exported. + * @returns a newly allocated PortableGroup::Properties that must be released by the caller. + */ + PortableGroup::Properties * get_type_properties ( + const char *type_id + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException)); + + /** + * Export the property set in a PortableGroup::Properties format. + * + * This method is intended to provide a parent + * for the property set in a newly-created Object Group of the given + * type_id. + * + * Callers who intend to send the property set across a CORBA interface + * should use the get_type_properties method. + * + * @param type_id identifies the set of properties to be found. + * @returns a pointer to a Property_Set owned by this Properties_Support object. + */ + TAO::PG_Property_Set * TAO::PG_Properties_Support::find_typeid_properties ( + const char *type_id + ACE_ENV_ARG_PARAMETER) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /** + * Undefine default properties that appear in props. + * + * Properties that are defined in props are removed from the type_id + * property set. Removal is done by name. The property values do not + * have to match. There is no penalty for attempting to remove a property + * that does not exist. + * @param props a set of propertys to be removed by name from the type_id set. + */ + void remove_type_properties ( + const char *type_id, + const PortableGroup::Properties & props + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException)); + + /////////////// + // Data Members + private: + /** + * Protect internal state. + */ + TAO_SYNCH_MUTEX internals_; + typedef ACE_Guard<TAO_SYNCH_MUTEX> InternalGuard; + + /// The default property set. + TAO::PG_Property_Set default_properties_; + + /// A collection of property sets indexed by type_id. + Properties_Map properties_map_; + }; +} //namespace TAO_PG + +#endif // TAO_PG_PROPERTIES_SUPPORT_H diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Property_Set.cpp b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Property_Set.cpp new file mode 100644 index 00000000000..51fe4ed25c4 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Property_Set.cpp @@ -0,0 +1,380 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file PG_Property_Set.cpp + * + * $Id$ + * + * This file implements classes to help manage the Properties + * defined in the Portable Object Group. + * + * Note: this started as a simple helper class to make decoding sets of properties + * easier, but expanded to provide more general support for managing sets of properties. + * + * A more appropriate name would be PG_Properties_Set. Maybe this can be changed someday. + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= +#include "PG_Property_Set.h" + +////////////////////// +// PG_Property_Set + +TAO::PG_Property_Set::PG_Property_Set() + : defaults_ (0) +{ +} + + +TAO::PG_Property_Set::PG_Property_Set ( + const PortableGroup::Properties & property_set + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) + : defaults_ (0) +{ + this->decode (property_set ACE_ENV_ARG_PARAMETER); +} + +TAO::PG_Property_Set::PG_Property_Set ( + const PortableGroup::Properties & property_set, + PG_Property_Set * defaults + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) + : defaults_ (defaults) +{ + this->decode (property_set ACE_ENV_ARG_PARAMETER); +} + + +TAO::PG_Property_Set::PG_Property_Set ( + PG_Property_Set * defaults) + : defaults_ (defaults) +{ +} + +TAO::PG_Property_Set::~PG_Property_Set () +{ + this->clear (); +} + +void TAO::PG_Property_Set::decode (const PortableGroup::Properties & property_set ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + InternalGuard guard(this->internals_); + + size_t count = property_set.length (); + for (size_t nItem = 0; nItem < count; ++nItem) + { + const PortableGroup::Property & property = property_set[nItem]; + const CosNaming::Name & nsName = property.nam; + // note assumption one level name with no kind + // @@ TODO: fix this + const CosNaming::NameComponent & nc = nsName[0]; + + this->set_property (ACE_static_cast (const char *, nc.id), property.val ACE_ENV_ARG_PARAMETER) + ACE_CHECK; + +#if 0 + ACE_CString name = ACE_static_cast (const char *, nc.id); + + const PortableGroup::Value * value_copy; + ACE_NEW_THROW_EX (value_copy, PortableGroup::Value (property.val), CORBA::NO_MEMORY ()); + ACE_CHECK; + + const PortableGroup::Value * replaced_value = 0; + if (0 == this->values_.rebind (name, value_copy, replaced_value)) + { + if (0 != replaced_value) + { + delete replaced_value; + } + } + else + { + if (TAO_debug_level > 3) + { + ACE_ERROR ( (LM_ERROR, + "%n\n%T: Property_set: rebind failed.\n" + )); + } + // @@ should throw something here + ACE_THROW (CORBA::NO_MEMORY ()); + } +#endif + } +} + +void TAO::PG_Property_Set::clear () +{ + InternalGuard guard(this->internals_); + for (ValueMapIterator it = this->values_.begin (); + it != this->values_.end (); + ++it) + { + ACE_TRY_NEW_ENV + { + delete (*it).int_id_; + } + ACE_CATCHANY + { + // ignore this (we might log it?) + } + ACE_ENDTRY; + } + this->values_.unbind_all (); +} + +void TAO::PG_Property_Set::remove (const PortableGroup::Properties & property_set) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + InternalGuard guard(this->internals_); + size_t count = property_set.length (); + for (size_t nItem = 0; nItem < count; ++nItem) + { + const PortableGroup::Property & property = property_set[nItem]; + const CosNaming::Name & nsName = property.nam; + // note assumption one level name with no kind + // @@ TODO: fix this + const CosNaming::NameComponent & nc = nsName[0]; + ACE_CString name = ACE_static_cast (const char *, nc.id); + + const PortableGroup::Value * deleted_value; + if ( 0 == this->values_.unbind (name, deleted_value)) + { + delete deleted_value; + } + else + { + // don't worry about it. + } + } +} + +void TAO::PG_Property_Set::set_property ( + const char * name, + const PortableGroup::Value & value + ACE_ENV_ARG_DECL) +{ + ACE_CString key (name); + PortableGroup::Value * value_copy; + ACE_NEW_THROW_EX ( + value_copy, PortableGroup::Value (value), + CORBA::NO_MEMORY ()); + ACE_CHECK; + + const PortableGroup::Value * replaced_value = 0; + if (0 == this->values_.rebind (name, value_copy, replaced_value)) + { + if (0 != replaced_value) + { + delete replaced_value; + } + } + else + { + if (TAO_debug_level > 3) + { + ACE_ERROR ( (LM_ERROR, + "%n\n%T: Property_set: rebind failed.\n" + )); + } + // @@ should throw something here + ACE_THROW (CORBA::NO_MEMORY ()); + } +} + + + +void TAO::PG_Property_Set::export_properties(PortableGroup::Properties & property_set) const +{ + ValueMap merged_values; + this->merge_properties (merged_values); + + property_set.length (merged_values.current_size ()); + + size_t pos = 0; + for (ValueMapIterator it = merged_values.begin (); + it != merged_values.end (); + ++it) + { + const ACE_CString & name = (*it).ext_id_; + const PortableGroup::Value * value = (*it).int_id_; + + PortableGroup::Property & property = property_set[pos]; + CosNaming::Name & nsName = property.nam; + //@@ note assumption: single level name, no kind + nsName.length(1); + CosNaming::NameComponent & nc = nsName[0]; + nc.id = CORBA::string_dup (name.c_str ()); + PortableGroup::Value & val = property.val; + val = *value; // NOTE: Any assignment does a deep copy + ++pos; + } + ACE_ASSERT (pos == property_set.length ()); +} + +void TAO::PG_Property_Set::merge_properties (ValueMap & merged_values) const +{ + InternalGuard guard(ACE_const_cast (TAO::PG_Property_Set *, this)->internals_); + if (0 != this->defaults_) + { + this->defaults_->merge_properties (merged_values); + } + // note AFICT ACE_Hash_Map does not support const iterators, hence the const cast. + ValueMap & mutable_values = ACE_const_cast (ValueMap &, this->values_); + for (ValueMapIterator it = mutable_values.begin (); + it != mutable_values.end (); + ++it) + { + merged_values.rebind ( (*it).ext_id_, (*it).int_id_); + } +} + + + +int TAO::PG_Property_Set::find ( + const ACE_CString & key, + const PortableGroup::Value *& pValue) const +{ + InternalGuard guard(ACE_const_cast (TAO::PG_Property_Set *, this)->internals_); + int found = (0 == this->values_.find (key, pValue)); + if (! found) + { + if (0 != this->defaults_) + { + found = this->defaults_->find (key, pValue); + } + } + return found; +} + +//#define PG_PS_UNIT_TEST +#ifdef PG_PS_UNIT_TEST +#include "PG_Properties_Encoder.h" + +int TAO_PG::test_encode_decode () +{ + int result = 1; + static const long testLong = 123456L; + static const char * testLongKey = "MyLong"; + + static const char * testString = "Now is the time for all good people."; + static const char * testStringKey = "plover"; + + static const double testDouble = 3.1415; + static const char * testDoubleKey = "pi"; + + PortableGroup::Properties_var property_set = new PortableGroup::Properties; + //scope encoder to be sure its gone before decoding + { + TAO_PG::Encoder encoder; + PortableGroup::Value value; + value <<= (CORBA::Long) testLong; + encoder.add (testLongKey, value); + + value <<= testString; + encoder.add (testStringKey, value); + + value <<= (CORBA::Double) testDouble; + encoder.add (testDoubleKey, value); + + encoder.encode (property_set); + } + + TAO::PG_Property_Set decoder (property_set); + + CORBA::Long longResult = 0; + if (find (decoder, testLongKey, longResult) ) + { + if (longResult != testLong) + { + ACE_ERROR ( (LM_ERROR, + "%n\n%T: %s = %d expecting %d\n", + testLongKey, + (int)longResult, + (int)testLong + )); + result = 0; + } + } + else + { + ACE_ERROR ( (LM_ERROR, + "%n\n%T: Can't find value for %s\n", testLongKey + )); + result = 0; + } + + const char * stringResult = ""; + if (find (decoder, testStringKey, stringResult)) + { + if (0 != ACE_OS::strcmp (testString, stringResult)) + { + ACE_ERROR ( (LM_ERROR, + "%n\n%T: %s = \"%s\" expecting \"%s\"\n", + testStringKey, + (int)stringResult, + (int)testString + )); + result = 0; + } + } + else + { + ACE_ERROR ( (LM_ERROR, + "%n\n%T: Can't find value for %s\n", testStringKey + )); + result = 0; + } + + + CORBA::Double doubleResult = 0.0; + if (find (decoder, testDoubleKey, doubleResult)) + { + if (doubleResult != testDouble) + { + ACE_ERROR ( (LM_ERROR, + "%n\n%T: %s = \"%f\" expecting \"%f\"\n", + testDoubleKey, + doubleResult, + testDouble + )); + result = 0; + } + } + else + { + ACE_ERROR ( (LM_ERROR, + "%n\n%T: Can't find value for %s\n", testDoubleKey + )); + result = 0; + } + + return result; +} +#endif // PG_PS_UNIT_TEST + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + template class ACE_Hash_Map_Manager< + ACE_CString, + const PortableGroup::Value *, + ACE_SYNCH_NULL_MUTEX>; + + typedef class ACE_Hash_Map_Iterator< + ACE_CString, + const PortableGroup::Value *, + ACE_SYNCH_NULL_MUTEX>; + +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) + +# pragma instantiate ACE_Hash_Map_Manager< + ACE_CString, + const PortableGroup::Value *, + ACE_SYNCH_NULL_MUTEX> +#pragma instantiate ACE_Hash_Map_Iterator< + ACE_CString, + const PortableGroup::Value *, + ACE_SYNCH_NULL_MUTEX> + +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Property_Set.h b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Property_Set.h new file mode 100644 index 00000000000..68264080acd --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Property_Set.h @@ -0,0 +1,187 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file PG_Property_Set.h + * + * $Id$ + * + * This file declares classes to help manage the Properties + * defined in the Portable Object Group. + * + * Note: this started as a simple helper class to make decoding sets of properties + * easier, but expanded to provide more general support for managing sets of properties. + * + * A more appropriate name would be PG_Properties_Set. Maybe this can be changed someday. + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= +#ifndef TAO_PG_PROPERTY_SET +#define TAO_PG_PROPERTY_SET +#include "portablegroup_export.h" +#include <orbsvcs/PortableGroupS.h> +#include <orbsvcs/CosNamingC.h> +#include <ace/Hash_Map_Manager.h> +#include <ace/SString.h> + +namespace TAO +{ + + /** + * The PG_Property_Set captures the set of properties from a PortableGroup::Properties + * structure in a more usable format (a hash map), and provides methods for + * operating on these properties. + * + * It supports "chains" of property sets to implement default value semantics. + * If a requested property is not found in this set, the default set(s) are searched. + * Thus, any property found at this level overrides the defaults. + * + * See: PG_Properties_Support for more details on use of this object. + * + * A PG_Property_Set may also be used for it's original purpose as a stand-alone + * helper class for extracting values from PortableGroup::Properties. + */ + + class TAO_PortableGroup_Export PG_Property_Set + { + typedef ACE_Hash_Map_Manager< + ACE_CString, + const PortableGroup::Value *, + ACE_SYNCH_NULL_MUTEX> ValueMap; + typedef ACE_Hash_Map_Iterator< + ACE_CString, + const PortableGroup::Value *, + ACE_SYNCH_NULL_MUTEX> ValueMapIterator; + + public: + + /** + * constructor: empty set with no defaults. + */ + PG_Property_Set(); + + /** + * constructor + * @param property_set the properties to be decoded + */ + PG_Property_Set (const PortableGroup::Properties & property_set ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /** + * constructor with defaults + * @param property_set the properties to be decoded + * @param defaults a propert set decoder that supplies default values. + */ + PG_Property_Set (const PortableGroup::Properties & property_set, PG_Property_Set * defaults ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /** + * constructor with defaults, but no properties (yet) + * (note this is not a copy constructor) + * @param defaults a propert set decoder that supplies default values. + */ + PG_Property_Set (PG_Property_Set * defaults); + + + ~PG_Property_Set (); + + /** + * general purpose find. returns a pointer to an Any + * if templated methods were available: + * template <typename TYPE > + * int find (const ACE_CString & key, TYPE & value) const; + * instead, see global function below + * @param key the (simple) name of the property + * @param pValue an out parameter to receive a pointer to the Any containing the value + * @returns boolean true if found + */ + int find (const ACE_CString & key, const PortableGroup::Value *& pValue)const; + + + /** + * Decode additional properties + * Duplicate values replace previous values. + * @param property_set the properties to be decoded + */ + void decode (const PortableGroup::Properties & property_set) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /** + * Clear properties + * Does not clear default properties. + */ + void clear (); + + void remove (const PortableGroup::Properties & property_set) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /** + * set or replace a single property + */ + void set_property ( + const char * name, + const PortableGroup::Value & value + ACE_ENV_ARG_DECL); + + + /** + * Export the properties to a PortableGroup::Properties + * + * This method is intended to be used to implement the PropertyManager::get_*_properties + * methods. If you want to access the properties for any purpose other than exporting + * them across a CORBA interface, it is much more efficient to use the find interface. + * + */ + void export_properties(PortableGroup::Properties & property_set) const; + + ///////////////////////// + // Implementation Methods + private: + /** + * populate a ValueMap with the properties known to this decoder + * including but overriding default values + */ + void merge_properties (ValueMap & merged_values) const; + + //////////////////// + // Forbidden methods + private: + PG_Property_Set(const PG_Property_Set & rhs); + PG_Property_Set & operator = (const PG_Property_Set & rhs); + + /////////////// + // Data Members + private: + /** + * Protect internal state. + */ + TAO_SYNCH_MUTEX internals_; + typedef ACE_Guard<TAO_SYNCH_MUTEX> InternalGuard; + + ValueMap values_; + /** + * a parent to another property decoder that provides default values + * these can be chained indefinitely. + * @@ TODO: reference counted pointers would be a good idea here. + */ + PG_Property_Set * defaults_; + }; + + +#ifdef PG_PS_UNIT_TEST + + /** + * unit test: encode and decode properties. + * Initialize CORBA before calling this function. + * Success is silent, failure prints on cerr. + * @returns 1 if test passed; 0 if test failed. + */ + int test_encode_decode(); +#endif // PG_PS_UNIT_TEST +} //namespace TAO + +//////////////////////////////////// +// include templated helper function +#include "PG_Property_Set_Find.h" + +#endif // TAO_PG_PROPERTY_SET diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Property_Set_Find.h b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Property_Set_Find.h new file mode 100644 index 00000000000..8afe09346a2 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Property_Set_Find.h @@ -0,0 +1,48 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file PG_Property_Set.h + * + * $Id$ + * + * This is a companion function for the properties docoder + * to work around compilers that don't support templated methods. + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= +#ifndef TAO_PG_PROPERTY_SET_FIND_H +#define TAO_PG_PROPERTY_SET_FIND_H +#include /**/ "ace/pre.h" +#include <ace/ACE.h> + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "portablegroup_export.h" + +#include "ace/Hash_Map_Manager.h" + +namespace TAO +{ + /** + * Find a value in a TAO::PG_Property_Set. + * This is a work-around for the lack of + * templated methods. + */ + template <typename TYPE> + int find (const PG_Property_Set & decoder, const ACE_CString & key, TYPE & value) + { + int result = 0; + PortableGroup::Value const * any; + if ( decoder.find (key, any)) + { + result = ((*any) >>= value); + } + return result; + } + +} //namespace TAO + +#endif // TAO_PG_PROPERTY_SET_FIND_H diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Utils.cpp b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Utils.cpp new file mode 100644 index 00000000000..5eb48d6ff1f --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Utils.cpp @@ -0,0 +1,169 @@ +#include "PG_Utils.h" +#include "tao/MProfile.h" +#include "tao/Profile.h" +#include "tao/Stub.h" +#include "tao/Tagged_Components.h" + +ACE_RCSID (PortableGroup, + PG_Utils, + "$Id$") +namespace TAO +{ + /*static*/ CORBA::Boolean + PG_Utils::set_tagged_component ( + PortableGroup::ObjectGroup *&ior, + PortableGroup::TagGroupTaggedComponent &tg) + { + if (ior->_stubobj () == 0) + return 0; + + // We need to apply the property for every profile in the IOR + TAO_MProfile &tmp_pfiles = + ior->_stubobj ()->base_profiles (); + + // Create the output CDR stream + TAO_OutputCDR cdr; + + IOP::TaggedComponent tagged_components; + tagged_components.tag = IOP::TAG_FT_GROUP; + + // Encode the property in to the tagged_components + CORBA::Boolean retval = + PG_Utils::encode_properties (cdr, + tg); + + if (retval == 0) + return retval; + + // Get the length of the CDR stream + CORBA::ULong length = ACE_static_cast (CORBA::ULong, + cdr.total_length ()); + + // Set the length + tagged_components.component_data.length (length); + + // Get the pointer to the underlying buffer + CORBA::Octet *buf = + tagged_components.component_data.get_buffer (); + + for (const ACE_Message_Block *i = cdr.begin (); + i != 0; + i = i->cont ()) + { + + ACE_OS::memcpy (buf, i->rd_ptr (), i->length ()); + buf += i->length (); + } + const IOP::TaggedComponent &tmp_tc = tagged_components; + + // Get the profile count. + CORBA::ULong count = + ior->_stubobj ()->base_profiles ().profile_count (); + + // Go through every profile and set the TaggedComponent field + for (CORBA::ULong p_idx = 0; p_idx < count ; ++p_idx) + { + // Get the tagged components in the profile + TAO_Tagged_Components &tag_comp = + tmp_pfiles.get_profile (p_idx)->tagged_components (); + + // Finally set the <tagged_component> in the + // <TAO_Tagged_Component> + tag_comp.set_component (tmp_tc); + } + + // Success + return 1; + } + + /*static*/ CORBA::Boolean + PG_Utils::get_tagged_component ( + PortableGroup::ObjectGroup *&ior, + PortableGroup::TagGroupTaggedComponent &tg) + { + if (ior->_stubobj () == 0) + return 0; + + TAO_MProfile &mprofile = + ior->_stubobj ()->base_profiles (); + + // Looking for a tagged component with a TAG_FT_GROUP flag. + IOP::TaggedComponent tc; + tc.tag = IOP::TAG_FT_GROUP; + + CORBA::ULong count = + mprofile.profile_count (); + + for (CORBA::ULong i = 0; + i < count; + i++) + { + + // Get the Tagged Components + const TAO_Tagged_Components &pfile_tagged = + mprofile.get_profile (i)->tagged_components (); + + // Look for the primary + if (pfile_tagged.get_component (tc) == 1) + { + TAO_InputCDR cdr (ACE_reinterpret_cast ( + const char*, + tc.component_data.get_buffer ()), + tc.component_data.length ()); + + CORBA::Boolean byte_order; + + cdr >> ACE_InputCDR::to_boolean (byte_order); + + if (!cdr.good_bit ()) + return 0; + + cdr.reset_byte_order (ACE_static_cast (int,byte_order)); + + cdr >> tg; + + if (cdr.good_bit ()) + return 1; + } + } + + return 0; + } + + CORBA::Boolean + PG_Utils::encode_properties ( + TAO_OutputCDR &cdr, + PortableGroup::TagGroupTaggedComponent &tg) + { + cdr << ACE_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER); + + if (!cdr.good_bit ()) + return 0; + + // the version info + cdr << tg.component_version; + + if (!cdr.good_bit ()) + return 0; + + // the domain id + cdr << tg.group_domain_id.in (); + + if (!cdr.good_bit ()) + return 0; + + // Object group id + cdr << tg.object_group_id; + + if (!cdr.good_bit ()) + return 0; + + // Object group reference version + cdr << tg.object_group_ref_version; + + if (!cdr.good_bit ()) + return 0; + + return cdr.good_bit (); + } +} diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Utils.h b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Utils.h new file mode 100644 index 00000000000..27c548d94c5 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_Utils.h @@ -0,0 +1,53 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file PG_Utils.h + * + * $Id$ + * + * Utility methods + * + * @author Balachandran Natarajan <bala@dre.vanderbilt.edu> + */ +//============================================================================= +#ifndef TAO_PORTABLEGROUP_UTILS_H +#define TAO_PORTABLEGROUP_UTILS_H +#include /**/ "ace/pre.h" +#include "orbsvcs/PortableGroupC.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +namespace TAO +{ + /** + * @class PG_Utils + * + * @brief Simple utility class + */ + class TAO_PortableGroup_Export PG_Utils + { + public: + + /// Set tagged component for the object group + static CORBA::Boolean set_tagged_component ( + PortableGroup::ObjectGroup *&ior, + PortableGroup::TagGroupTaggedComponent &t); + + /// Get tagged component for the object group + static CORBA::Boolean get_tagged_component ( + PortableGroup::ObjectGroup *&ior, + PortableGroup::TagGroupTaggedComponent &t); + + private: + static CORBA::Boolean encode_properties ( + TAO_OutputCDR &cdr, + PortableGroup::TagGroupTaggedComponent &tg); + }; +} + + + +#include /**/ "ace/post.h" +#endif /*TAO_PORTABLEGROUP_UTILS_H*/ diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_conf.h b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_conf.h index 65aff18f6a2..dcb0e3d5a5e 100644 --- a/TAO/orbsvcs/orbsvcs/PortableGroup/PG_conf.h +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PG_conf.h @@ -24,14 +24,14 @@ #include "orbsvcs/PortableGroupC.h" -#ifndef TAO_PG_MAX_OBJECT_GROUPS +#ifndef TAO_PG_MAX_OBJECT_GROUPS // @@ why create arbitrary limits? /// The maximum number of object groups to be managed by the /// ObjectGroupManager. This number is also equal to the number of /// factory sets managed by the GenericFactory. const size_t TAO_PG_MAX_OBJECT_GROUPS = 1024; #endif /* TAO_PG_MAX_NUMBER_OF_OBJECT_GROUPS */ -#ifndef TAO_PG_MAX_LOCATIONS +#ifndef TAO_PG_MAX_LOCATIONS // @@ why create arbitrary limits? /// The maximum number of locations to be managed by the /// ObjectGroupManager. const size_t TAO_PG_MAX_LOCATIONS = 1024; @@ -46,7 +46,7 @@ const PortableGroup::MembershipStyleValue TAO_PG_MEMBERSHIP_STYLE = #ifndef TAO_PG_INITIAL_NUMBER_MEMBERS /// The default initial number of object group members. const PortableGroup::InitialNumberMembersValue TAO_PG_INITIAL_NUMBER_MEMBERS = - 0; + 2; #endif /* TAO_PG_INITIAL_NUMBER_MEMBERS */ #ifndef TAO_PG_MINIMUM_NUMBER_MEMBERS diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/PortableGroup_Loader.h b/TAO/orbsvcs/orbsvcs/PortableGroup/PortableGroup_Loader.h index ccd5e32d50e..d322948b490 100644 --- a/TAO/orbsvcs/orbsvcs/PortableGroup/PortableGroup_Loader.h +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/PortableGroup_Loader.h @@ -34,7 +34,7 @@ * This class acts as a facade for the PortableGroup library to the * ORB. */ -class TAO_PortableGroup_Export TAO_PortableGroup_Loader +class TAO_PortableGroup_Export TAO_PortableGroup_Loader : public ACE_Service_Object { friend class TAO_POA_Hooks; @@ -59,7 +59,7 @@ ACE_FACTORY_DECLARE (TAO_PortableGroup, TAO_PortableGroup_Loader) typedef int (*TAO_Module_Initializer) (void); static TAO_Module_Initializer -TAO_Requires_PortableGroup_Initializer = +TAO_Requires_PortableGroup_Initializer = &TAO_PortableGroup_Loader::Initializer; #else diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/Portable_Group_Map.h b/TAO/orbsvcs/orbsvcs/PortableGroup/Portable_Group_Map.h index 6c45a728b36..0a551945a9c 100644 --- a/TAO/orbsvcs/orbsvcs/PortableGroup/Portable_Group_Map.h +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/Portable_Group_Map.h @@ -68,11 +68,11 @@ class TAO_PortableGroup_Export TAO_Portable_Group_Map { public: - /** - * @struct Map_Entry - * - * @brief Value field of the portable group map. - */ + /** + * @struct Map_Entry + * + * @brief Value field of the portable group map. + */ struct Map_Entry { /// The key. diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Acceptor.h b/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Acceptor.h index 0cfae0a2c2a..22f203370cb 100644 --- a/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Acceptor.h +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Acceptor.h @@ -109,7 +109,7 @@ protected: * virtual to allow a derived class implementation to be invoked * instead. */ - virtual int open_i (const ACE_INET_Addr &addr, + virtual int open_i (const ACE_INET_Addr &addr, ACE_Reactor *reactor); /// Parse protocol specific options. diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Connection_Handler.cpp b/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Connection_Handler.cpp index 7cf8dcd3b92..21e73eb6a08 100644 --- a/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Connection_Handler.cpp +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Connection_Handler.cpp @@ -224,11 +224,7 @@ int TAO_UIPMC_Connection_Handler::handle_close (ACE_HANDLE, ACE_Reactor_Mask) { - // No asserts here since the handler is registered with the Reactor - // and the handler ownership is given to the Reactor. When the - // Reactor closes, it will call handle_close() on the handler. It - // is however important to overwrite handle_close() to do nothing - // since the base class does too much. + ACE_ASSERT (0); return 0; } diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Transport.cpp b/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Transport.cpp index 8afe68d659b..9b04d83c7bd 100644 --- a/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Transport.cpp +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Transport.cpp @@ -87,6 +87,7 @@ TAO_UIPMC_Transport::TAO_UIPMC_Transport (TAO_UIPMC_Connection_Handler *handler, TAO_UIPMC_Transport::~TAO_UIPMC_Transport (void) { + ACE_ASSERT(this->connection_handler_ == 0); delete this->messaging_object_; } diff --git a/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Transport.h b/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Transport.h index 0026d265d16..2678c92d575 100644 --- a/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Transport.h +++ b/TAO/orbsvcs/orbsvcs/PortableGroup/UIPMC_Transport.h @@ -12,7 +12,7 @@ #ifndef TAO_UIPMC_TRANSPORT_H #define TAO_UIPMC_TRANSPORT_H -#include /**/ "ace/pre.h" +#include "ace/pre.h" #include "tao/Transport.h" @@ -128,5 +128,5 @@ private: #include "UIPMC_Transport.i" #endif /* __ACE_INLINE__ */ -#include /**/ "ace/post.h" +#include "ace/post.h" #endif /* TAO_UIPMC_TRANSPORT_H */ diff --git a/TAO/orbsvcs/tests/FT_App/.cvsignore b/TAO/orbsvcs/tests/FT_App/.cvsignore new file mode 100644 index 00000000000..8e4cf88d091 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/.cvsignore @@ -0,0 +1,16 @@ +*.dsp +*.dsw +*.ilk +*.pdb +*.plg +*.ncb +*.opt +*.exe +*.ior +*.dat +Release +Debug +FT_ReplicaC* +FT_ReplicaS* +FT_TestReplicaC* +FT_TestReplicaS* diff --git a/TAO/orbsvcs/tests/FT_App/FTAPP_Analyzer_Main.cpp b/TAO/orbsvcs/tests/FT_App/FTAPP_Analyzer_Main.cpp new file mode 100644 index 00000000000..36657366c10 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/FTAPP_Analyzer_Main.cpp @@ -0,0 +1,33 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FTAPP_Analyzer_Main.cpp + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * This file provides the main routine for a stub FaultAnalyzer + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= + +#include <tao/Utils/Server_Main.h> +#include "StubFaultAnalyzer.h" + +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + TAO::Utils::Server_Main<StubFaultAnalyzer> server_run("FaultAnalyzer"); + return server_run.run(argc, argv); +} + +/////////////////////////////////// +// Template instantiation for +// inept compilers. + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + template class TAO::Utils::Server_Main<StubFaultAnalyzer>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +# pragma instantiate TAO::Utils::Server_Main<StubFaultAnalyzer> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ + diff --git a/TAO/orbsvcs/tests/FT_App/FTAPP_FactoryRegistry_Main.cpp b/TAO/orbsvcs/tests/FT_App/FTAPP_FactoryRegistry_Main.cpp new file mode 100644 index 00000000000..af2524a1fe1 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/FTAPP_FactoryRegistry_Main.cpp @@ -0,0 +1,33 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FTAPP_FactoryRegistry_Main.cpp + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * This file provides the main routine for a stub FactoryRegistry + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= + +#include <tao/Utils/Server_Main.h> +#include <orbsvcs/PortableGroup/PG_FactoryRegistry.h> + +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + TAO::Utils::Server_Main<TAO::PG_FactoryRegistry> server_main("FactoryRegistry"); + return server_main.run(argc, argv); +} + +/////////////////////////////////// +// Template instantiation for +// inept compilers. + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + template class TAO::Utils::Server_Main<TAO::PG_FactoryRegistry>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +# pragma instantiate TAO::Utils::Server_Main<TAO::PG_FactoryRegistry> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ + diff --git a/TAO/orbsvcs/tests/FT_App/FTAPP_FaultConsumer_Main.cpp b/TAO/orbsvcs/tests/FT_App/FTAPP_FaultConsumer_Main.cpp new file mode 100644 index 00000000000..8236a0465d0 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/FTAPP_FaultConsumer_Main.cpp @@ -0,0 +1,33 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FTApp_FaultConsumer_Main.cpp + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * This file provides the main routine for a stub FaultConsumer. + * + * @author Steve Totten <totten_s@ociweb.com> + */ +//============================================================================= + +#include <tao/Utils/Server_Main.h> +#include "ReplicationManagerFaultConsumerAdapter.h" + +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + TAO::Utils::Server_Main<ReplicationManagerFaultConsumerAdapter> + server_main("FaultConsumer"); + return server_main.run(argc, argv); +} + +/////////////////////////////////// +// Template instantiation for +// inept compilers. + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + template class TAO::Utils::Server_Main<ReplicationManagerFaultConsumerAdapter>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +# pragma instantiate TAO::Utils::Server_Main<ReplicationManagerFaultConsumerAdapter> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/tests/FT_App/FTAPP_Notifier_Main.cpp b/TAO/orbsvcs/tests/FT_App/FTAPP_Notifier_Main.cpp new file mode 100644 index 00000000000..9c89038cdbb --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/FTAPP_Notifier_Main.cpp @@ -0,0 +1,34 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FTAPP_Notifier_Main.cpp + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * This file provides the main routine for a stub implementation + * of the FaultNotifier interface. + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= + +#include "StubFaultNotifier.h" +#include <tao/Utils/Server_Main.h> + +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + TAO::Utils::Server_Main<StubFaultNotifier> server_main("FaultNotifier"); + return server_main.run(argc, argv); +} + +/////////////////////////////////// +// Template instantiation for +// inept compilers. + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + template class TAO::Utils::Server_Main<StubFaultNotifier>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +# pragma instantiate TAO::Utils::Server_Main<StubFaultNotifier> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ + diff --git a/TAO/orbsvcs/tests/FT_App/FT_App.mpc b/TAO/orbsvcs/tests/FT_App/FT_App.mpc new file mode 100644 index 00000000000..0b91e76f89f --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/FT_App.mpc @@ -0,0 +1,135 @@ +project(*Server): taoserver, fault_tolerance, orbsvcsexe{ + exename = ft_replica + Source_Files { + FT_Replica.cpp + FT_TestReplica_i.cpp + FT_ReplicaFactory_i.cpp + } +// Custom folder: test scripts +// too bad this doesn't work! +// If you omit the generic_outputext, it creates an empty folder +// if you include the generic_outputext, it tries to "build" the .pl +// file which runs the test even when you don't want to. +// Define_Custom(Script) { +// inputext = .pl, .py, .rb +// generic_outputext = .txt +// } +// Script_Files { +// run_test_detector.pl +// } + + Documentation_Files { + README + FT_App.mpc + run_test_basic.pl // can the client talk to the server + run_test_detector.pl // does a detector notice a server fault + run_test_notifier.pl // does the notification get to an analyzer + run_test_fault_consumer.pl // Is the notification analyzed correctly + run_test_registry.pl // does the stand-along factory registry work + run_test_rmregistry.pl // does the factory registry in the RM work + run_test_replication_mgr.pl // + run_test_demo.pl // test it all together + } +} + +project(*Client): taoclient, fault_tolerance, orbsvcsexe { + exename = ft_client + includes += $(TAO_ROOT) + after += *Server + Source_Files { + FT_Client.cpp + } + Documentation_Files { + } +} + +project(*Notifier): taoserver, fault_tolerance, orbsvcsexe { + exename = ft_notifier + Source_Files { + FTAPP_Notifier_Main.cpp + StubFaultNotifier.cpp + } + + // explicitly omit IDL and doc files + IDL_Files { + } + Documentation_Files { + } +} + +project(*Analyzer): taoclient, fault_tolerance, orbsvcsexe { + exename = ft_analyzer + + Source_Files { + FTAPP_Analyzer_Main.cpp + StubFaultAnalyzer.cpp + StubFaultConsumer.cpp + StubBatchConsumer.cpp + } + + // explicitly omit IDL files + IDL_Files { + } + Documentation_Files { + } +} + +project(*FaultConsumer): taoserver, fault_tolerance, orbsvcsexe { + exename = ft_fault_consumer + libs += TAO_ReplicationManagerLib + Source_Files { + FTAPP_FaultConsumer_Main.cpp + ReplicationManagerFaultConsumerAdapter.cpp + } + + // explicitly omit IDL files + IDL_Files { + } + Documentation_Files { + } +} + +project(*FactoryRegistry): taoclient, fault_tolerance, orbsvcsexe { + exename = ft_registry + + Source_Files { + FTAPP_FactoryRegistry_Main.cpp + } + + Header_Files { + + } + // explicitly omit IDL files + IDL_Files { + } + Documentation_Files { + } +} + +project(*Creator): taoclient, fault_tolerance, orbsvcsexe { + exename = ft_create + + Source_Files { + FT_Creator.cpp + TAO_Object_Group_Creator.cpp + } + + // explicitly omit IDL files + IDL_Files { + } + + Documentation_Files { + } +} + +project(*RMController): taoclient, fault_tolerance, orbsvcsexe { + exename = replmgr_controller + Source_Files { + FT_ReplicationManagerController.cpp + } + // explicitly omit IDL files + IDL_Files { + } + Documentation_Files { + } +} diff --git a/TAO/orbsvcs/tests/FT_App/FT_Client.cpp b/TAO/orbsvcs/tests/FT_App/FT_Client.cpp new file mode 100644 index 00000000000..ddbe4984adf --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/FT_Client.cpp @@ -0,0 +1,621 @@ +// $Id$ + +#include "FT_TestReplicaC.h" +#include <ace/Vector_T.h> +#include <ace/SString.h> +#include <ace/Get_Opt.h> +#include <iostream> +#include <fstream> + +class FTClientMain +{ + typedef ACE_Vector<ACE_CString> StringVec; + public: + /////////////////////////// + // construction/destruction + FTClientMain (); + + ~FTClientMain (); + + ///////////////// + // initialization + int parse_args (int argc, char *argv[]); + + //////////// + // execution + int run (); + + ///////////////// + // implementation +private: + void usage (ostream & out)const; + void commandUsage (ostream & out); + int pass ( + long & counter, // inout + int & more, // out + ACE_CString & command, // inout + int retry // in + ); + + + int next_replica (ACE_ENV_SINGLE_ARG_DECL); + + //////////////////// + // forbidden methods + private: + FTClientMain (const FTClientMain & rhs); + FTClientMain & operator = (const FTClientMain & rhs); + + //////////////// + // Data members + private: + + CORBA::ORB_var orb_; + + int argc_; + char ** argv_; + const char * inFileName_; + std::ifstream inFile_; + std::istream *commandIn_; + + enum Verbosity{ + SILENT, + QUIET, + NORMAL, + NOISY, + LOUD} + verbose_; + + + StringVec replica_iors_; + size_t replica_pos_; + const char * replica_name_; + FT_TEST::TestReplica_var replica_; +}; + + +FTClientMain::FTClientMain () + : commandIn_(&std::cin) + , verbose_(NORMAL) + , replica_pos_(0) + , replica_name_("none") +{ +} + +FTClientMain::~FTClientMain () +{ + if (this->inFile_.is_open()) + { + this->inFile_.close(); + } +} + +void FTClientMain::commandUsage(ostream & out) +{ + out + << "Each command must be at the beginning of a separate line." << std::endl + << "Everything after the command (and operand if any) is ignored." << std::endl + << "Valid commands are:" << std::endl + << " Access via method call:" << std::endl + << " =N set counter to N" << std::endl + << " cN get counter and compare to N (c stands for \"check\""<< std::endl + << " +N increment counter by N" << std::endl + << " -N decrement counter by N" << std::endl + << " Access as attribute:" << std::endl + << " >N set attribute to N" << std::endl + << " < get attribite" << std::endl + << " Try methods to be used by fault tolerant infrastructure: " << std::endl + << " ! is_alive" << std::endl + << " s get_state" << std::endl + << " S set_state" << std::endl + << " u get_update" << std::endl + << " U set_update" << std::endl + << " Simulate failure:" << std::endl + << " dN die on condition:" << std::endl + << " d" << FT_TEST::TestReplica::NOT_YET << " don't die" << std::endl + << " d" << FT_TEST::TestReplica::RIGHT_NOW << " immediately" << std::endl + << " d" << FT_TEST::TestReplica::WHILE_IDLE << " while idle" << std::endl + << " (FT_TestReplica interface)" << std::endl + << " d" << FT_TEST::TestReplica::BEFORE_STATE_CHANGE << " before state change" << std::endl + << " d" << FT_TEST::TestReplica::BEFORE_REPLICATION << " after state change, before replication" << std::endl + << " d" << FT_TEST::TestReplica::BEFORE_REPLY << " after replication, before reply "<< std::endl + << " (Monitorable interface)" << std::endl + << " d" << FT_TEST::TestReplica::DURING_IS_ALIVE << " during is alive" << std::endl + << " d" << FT_TEST::TestReplica::DENY_IS_ALIVE << " is_alive returns false" << std::endl + << " (Updatable interface)" << std::endl + << " d" << FT_TEST::TestReplica::DURING_GET_UPDATE << " during get update" << std::endl + << " d" << FT_TEST::TestReplica::BEFORE_SET_UPDATE << " before set update" << std::endl + << " d" << FT_TEST::TestReplica::AFTER_SET_UPDATE << " after set update" << std::endl + << " (Checkpointable interface)" << std::endl + << " d" << FT_TEST::TestReplica::DURING_GET_STATE << " during get state" << std::endl + << " d" << FT_TEST::TestReplica::BEFORE_SET_STATE << " before set state" << std::endl + << " d" << FT_TEST::TestReplica::AFTER_SET_STATE << " after set state" << std::endl + << " Logistics commands:" << std::endl + << " # ignore this line (comment)." << std::endl + << " v set verbosity:" << std::endl + << " 0 don't check counter value." << std::endl + << " 1 only display counter value mismatch." << std::endl + << " 2 display counter value after every command (default)." << std::endl + << " 3 display commands." << std::endl + << " 4 display method calls." << std::endl + << " zN sleep N seconds." << std::endl + << " q quit (end the client, not the replica(s).)" << std::endl + << " q1 quit (end the client, and shutdown the currently active replica.)" << std::endl + << " ? help (this message)" << std::endl; +} + +int +FTClientMain::parse_args (int argc, char *argv[]) +{ + this->argc_ = argc; + this->argv_ = argv; + int result = 0; + + // note: dfnkx are simple_util options + // include them here so we can detect bad args + ACE_Get_Opt get_opts (argc, argv, "c:f:"); + int c; + + while (result == 0 && (c = get_opts ()) != -1) + { + switch (c) + { + case 'c': + { + this->inFileName_ = get_opts.opt_arg (); + this->inFile_.open(this->inFileName_); + if(this->inFile_.is_open() && this->inFile_.good()) + { + std::cout << "FT Client: Reading commands from " << this->inFileName_ << std::endl; + this->commandIn_ = & this->inFile_; + } + else + { + std::cout << "FT Client: Can't open input file: " << this->inFileName_ << std::endl; + result = -1; + } + break; + } + case 'f': + { + replica_iors_.push_back(get_opts.opt_arg ()); + break; + } + + default: + case '?': + usage(std::cerr); + result = 1; + } + } + return result; +} + +void FTClientMain::usage(ostream & out)const +{ + out << "usage" + << " -c <command file>" + << " [-f <ior file>]..." + << std::endl; +} + +int FTClientMain::pass ( + long & counter, + int & more, + ACE_CString & command, + int retry) +{ + int result = 0; + + ::FT::State_var state; + unsigned long stateValue = 0; + ::FT::State_var update; + unsigned long updateValue = 0; + + while(more && result == 0 && ! this->commandIn_->eof()) + { + if (! retry || command.length () == 0 ) + { + char buffer[1000]; + this->commandIn_->getline(buffer, sizeof(buffer)-1); + command = buffer; + } + retry = 0; + + if (command.length() >0) + { + char op = command[0]; + ACE_CString cdr = command.substr(1); + char * junque; + long operand = strtol(cdr.c_str(),&junque, 10); + + if (this->verbose_ >= NOISY) + { + std::cout << "FT Client: " << command << std::endl; + } + + // turn echo on (based on verbose) + // individual commands can turn it off + int echo = this->verbose_ >= QUIET; + + switch(op) + { + case '#': + { + echo = 0; + break; + } + case '=': + { + if (this->verbose_ >= LOUD) + { + std::cout << "FT Client: ->set(" << operand << ");" << std::endl; + } + this->replica_->set(operand ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + counter = operand; + break; + } + case 'c': + { + if (this->verbose_ >= LOUD) + { + std::cout << "FT Client: ->get();" << std::endl; + } + long value = this->replica_->counter(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + if (value == operand) + { + std::cout << "FT Client: Good: Read " << value << " expecting " << operand << std::endl; + counter = operand; + } + else + { + std::cout << "FT Client: Error: Read " << value << " expecting " << operand << std::endl; + } + echo = 0; + break; + + } + case '>': + { + if (this->verbose_ >= LOUD) + { + std::cout << "FT Client: ->counter(" << operand << ");" << std::endl; + } + this->replica_->counter(operand ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + counter = operand; + break; + } + case '+': + { + if (this->verbose_ >= LOUD) + { + std::cout << "FT Client: ->increment(" << operand << ");" << std::endl; + } + this->replica_->increment(operand ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + counter += operand; + break; + } + case '-': + { + if (this->verbose_ >= LOUD) + { + std::cout << "FT Client: ->increment(" << -operand << ");" << std::endl; + } + this->replica_->increment(-operand ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + counter -= operand; + break; + } + case '<': + { + if (this->verbose_ >= LOUD) + { + std::cout << "FT Client: ->counter();" << std::endl; + } + long attribute = this->replica_->counter(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + std::cout << "FT Client: Attribute: " << attribute << std::endl; + echo = 0; + break; + } + case '!': + { + if (this->verbose_ >= LOUD) + { + std::cout << "FT Client: ->is_alive();" << std::endl; + } + int alive = this->replica_->is_alive(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + std::cout << "FT Client: Is alive? " << alive << std::endl; + break; + } + case 'd': + { + if (this->verbose_ >= LOUD) + { + std::cout << "FT Client: ->die(" << operand << ");" << std::endl; + } + this->replica_->die(ACE_static_cast (FT_TEST::TestReplica::Bane, operand) ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + echo = 0; + break; + } + case 's': + { + if (this->verbose_ >= LOUD) + { + std::cout << "FT Client: ->get_state();" << std::endl; + } + state = this->replica_->get_state(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + stateValue = counter; + break; + } + case 'S': + { + if (state.in() != 0) + { + if (this->verbose_ >= LOUD) + { + std::cout << "FT Client: ->set_state(saved_state);" << std::endl; + } + this->replica_->set_state(state ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + counter = stateValue; + } + else + { + std::cout << "FT Client: Error: no saved state." << std::endl; + } + break; + } + case 'u': + { + if (this->verbose_ >= LOUD) + { + std::cout << "FT Client: ->get_update();" << std::endl; + } + update = this->replica_->get_update(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + updateValue = counter; + break; + } + case 'U': + { + if (update.in() != 0) + { + if (this->verbose_ >= LOUD) + { + std::cout << "FT Client: ->set_update(saved_update);" << std::endl; + } + this->replica_->set_update(update ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + counter = updateValue; + } + else + { + std::cout << "FT Client: ERROR: No saved update information." << std::endl; + } + break; + } + case 'v': + { + this->verbose_ = ACE_static_cast(Verbosity, operand); + break; + } + case 'z': + { + if (operand == 0) + { + operand = 1; + } + ACE_Time_Value tv (operand,0); + ACE_OS::sleep(tv); + break; + } + case 'q': + { + if (operand != 0) + { + ACE_TRY_NEW_ENV + { + if (this->verbose_ >= LOUD) + { + std::cout << "FT Client: ->shutdown();" << std::endl; + } + this->replica_->shutdown( ACE_ENV_SINGLE_ARG_PARAMETER); + // @@ Note: this is here because the corba event loop seems to go to sleep + // if there's nothing for it to do. + // not quite sure why, yet. Dale + this->replica_->is_alive(ACE_ENV_SINGLE_ARG_PARAMETER); + } + ACE_CATCHANY + { + std::cout << "FT Client: Ignoring expected exception during shutdown." << std::endl; + ; // ignore exception during shutdown + } + ACE_ENDTRY; + } + echo = 0; + more = 0; + break; + } + default: + { + if (op != '?') + { + std::cout << "FT Client: Unknown: " << command << std::endl; + } + commandUsage(std::cerr); + break; + } + } + if (echo && this->verbose_ >= QUIET) + { + if (this->verbose_ >= LOUD) + { + std::cout << "FT Client: ->get();" << std::endl; + } + + long value = this->replica_->get(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + if (value == counter) + { + if (this->verbose_ >= NORMAL) + { + std::cout << "FT Client: " << counter << std::endl;; + } + } + else + { + std::cout << "FT Client: Error: read " << value << " expecting " << counter << std::endl; + result = -1; + } + } + } + } + return result; +} + +int FTClientMain::next_replica (ACE_ENV_SINGLE_ARG_DECL) +{ + int result = 0; + if (this->replica_pos_ < this->replica_iors_.size()) + { + this->replica_name_ = this->replica_iors_[this->replica_pos_].c_str(); + this->replica_pos_ += 1; + CORBA::Object_var rep_obj = this->orb_->string_to_object (this->replica_name_ ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (0) + replica_ = FT_TEST::TestReplica::_narrow (rep_obj.in ()); + if (! CORBA::is_nil (replica_.in ())) + { + result = 1; + } + else + { + std::cerr << "FT Client: Can't resolve IOR: " << this->replica_name_ << std::endl; + } + } + else + { + std::cerr << "***OUT_OF_REPLICAS*** " << this->replica_pos_ << std::endl; + } + return result; +} + + +int FTClientMain::run () +{ + int result = 0; + + this->orb_ = CORBA::ORB_init(this->argc_, this->argv_ ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1) + + if (next_replica ()) + { + // retry information + ACE_CString command; + int retry = 0; + long counter = this->replica_->get(ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (this->verbose_ >= NORMAL) + { + std::cout << "FT Client: Initial counter " << counter << std::endl; + } + if (ACE_OS::isatty(fileno(stdin))) + { + std::cout << "FT Client: Commands(? for help):" << std::endl; + } + + int more = 1; + while (more && result == 0 && ! this->commandIn_->eof()) + { + ACE_TRY_NEW_ENV + { + result = pass (counter, more, command, retry); + ACE_TRY_CHECK; + } + ACE_CATCH (CORBA::SystemException, sysex) + { + std::cout << "FT Client: Caught system exception: " << std::endl; + ACE_PRINT_EXCEPTION (sysex, "FT Client"); + + retry = 0; + int handled = 0; + + handled = next_replica(); + if (handled) + { + std::cout << "FT Client: Recovering from fault." << std::endl; + std::cout << "FT Client: Activate " << this->replica_name_ << std::endl; + if (command.length () == 0) + { + std::cout << "FT Client: No command to retry." << std::endl; + } + else if (command[0] == 'd') + { + std::cout << "FT Client: Not retrying \"die\" command." << std::endl; + } + else if (sysex.completed () == CORBA::COMPLETED_YES) + { + std::cout << "FT Client: Last command completed. No retry needed." << std::endl; + } + else + { + if (sysex.completed () == CORBA::COMPLETED_MAYBE) + { + std::cout << "FT Client: Last command may have completed. Retrying anyway." << std::endl; + } + retry = 1; + std::cout << "FT Client: Retrying command: " << command << std::endl; + } + } + if (! handled) + { + std::cout << "FT Client: Exception not handled. Rethrow. " << std::endl; + ACE_RE_THROW; + } + } + ACE_ENDTRY; + } + } + else + { + std::cerr << "FT Client: Can't connect to replica." << std::endl; + } + return result; +} + + +int +main (int argc, char *argv[]) +{ + FTClientMain app; + int result = app.parse_args(argc, argv); + if (result == 0) + { + ACE_TRY_NEW_ENV + { + result = app.run (); + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "FT_Client::main\t\n"); + result = -1; + } + ACE_ENDTRY; + } + return result; +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + template class ACE_Vector<ACE_CString>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +# pragma ACE_Vector<ACE_CString> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/tests/FT_App/FT_Creator.cpp b/TAO/orbsvcs/tests/FT_App/FT_Creator.cpp new file mode 100644 index 00000000000..f8f39abca76 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/FT_Creator.cpp @@ -0,0 +1,293 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file TAO_Object_Group_Creator.cpp + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * Main wrapped around TAO_Object_Group_Creator + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= + +#include "FT_Creator.h" +#include <iostream> +#include <fstream> +#include <orbsvcs/PortableGroup/PG_Properties_Encoder.h> + +#include <ace/Get_Opt.h> + + +FTAPP::FT_Creator::FT_Creator () + : creator_ () + , orb_ (CORBA::ORB::_nil ()) + , registry_ior_(0) + , replication_manager_ (::FT::ReplicationManager::_nil ()) + , have_replication_manager_ (0) + , write_iors_ (0) + , write_iogr_ (0) + , ns_register_ (1) + , iogr_seq_ (0) + , prefix_ ("") +{ +} + +FTAPP::FT_Creator::~FT_Creator () +{ +} + +int +FTAPP::FT_Creator::parse_args (int argc, char *argv[]) +{ + int result = 0; + + ACE_Get_Opt get_opts (argc, argv, "r:ignf:u:p:"); + int c; + + while (result == 0 && (c = get_opts ()) != -1) + { + switch (c) + { + case 'r': + { + this->create_roles_.push_back (get_opts.opt_arg ()); + break; + } + case 'u': + { + this->unregister_roles_.push_back (get_opts.opt_arg ()); + break; + } + case 'f': + { + this->registry_ior_ = get_opts.opt_arg (); + break; + } + + case 'g': + { + this->write_iogr_ = !this->write_iogr_; + break; + } + + case 'i': + { + this->write_iors_ = ! this->write_iors_; + break; + } + + case 'n': + { + this->ns_register_ = !this->ns_register_; + break; + } + + case 'p': + { + this->prefix_ = get_opts.opt_arg(); + break; + } + + default: + { + std::cerr << "Creator: Unknown argument -" << (char) c << std::endl; + usage(std::cerr); + result = 1; + break; + } + case '?': + { + usage(std::cerr); + result = 1; + break; + } + } + } + + if ( this->create_roles_.size() == 0 && this->unregister_roles_.size() == 0) + { + std::cerr << "Creator: neither create (-t) nor kill (-u) specified. Nothing to do." << std::endl; + usage (std::cerr); + result = -1; + } + + return result; +} + +void FTAPP::FT_Creator::usage(ostream & out)const +{ + out << "usage\n" + << " -r <role for objects to be created>\n" + << " -f <factory registry ior file> (if not specified, ReplicationManager is used.)\n" + << " -u <role to be unregistered (for testing factory registry)>\n" + << " -i (toggle write ior for each object (default false))\n" + << " -p <prefix for registration & file names>\n" + << " -g (toggle write iogr to file (default false))\n" + << " -n (toggle register iogr with name service (default true))\n" + ; +} + + + +int FTAPP::FT_Creator::init (CORBA::ORB_ptr orb ACE_ENV_ARG_DECL) +{ + int result = 0; + this->orb_ = CORBA::ORB::_duplicate (orb); + + // if a factory IOR was specified on command line + if ( this->registry_ior_ != 0) + { + CORBA::Object_var registry_obj = this->orb_->string_to_object (this->registry_ior_ ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + PortableGroup::FactoryRegistry_var registry = PortableGroup::FactoryRegistry::_narrow(registry_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + if (! CORBA::is_nil (registry.in ())) + { + result = this->creator_.set_factory_registry(registry.in()); + } + } + + if (result == 0) + { + result = this->creator_.init (orb ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + } + + + if (result == 0 && this->ns_register_) + { + CORBA::Object_var naming_obj = + this->orb_->resolve_initial_references ("NameService" ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (CORBA::is_nil(naming_obj.in ())) + { + ACE_ERROR_RETURN ((LM_ERROR, + "%T %n (%P|%t) Unable to find the Naming Service\n"), + 1); + } + this->naming_context_= + CosNaming::NamingContext::_narrow (naming_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + } + + return result; +} + +int FTAPP::FT_Creator::run (ACE_ENV_SINGLE_ARG_DECL) +{ + int result = 0; + size_t typeCount = this->create_roles_.size(); + size_t nType = 0; + for ( nType = 0; result == 0 && nType < typeCount; ++nType) + { + const char * role = this->create_roles_[nType].c_str(); + std::cout << std::endl << "Creator: Creating group of " << role << std::endl; + PortableGroup::ObjectGroup_var group = this->creator_.create_group ( + role, + this->write_iors_ + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (1); + + if (this->write_iogr_) + { + CORBA::String_var iogr = this->orb_->object_to_string (group.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (1); + + char iogr_filename[1000]; + ACE_OS::snprintf (iogr_filename, sizeof(iogr_filename)-1, "%s%s_%d.iogr", + this->prefix_, + role, + this->iogr_seq_); + FILE * iogr_file = fopen (iogr_filename, "w"); + if (iogr_file != 0) + { + char const * siogr = ACE_static_cast (const char *, iogr); + fwrite (siogr, 1, strlen(siogr), iogr_file); + fclose (iogr_file); + } + else + { + std::cerr << "Can't open iogr output file " << iogr_filename << std::endl; + result = 1; + } + } + + if(this->ns_register_) + { + char iogr_name[1000]; + ACE_OS::snprintf (iogr_name, sizeof(iogr_name)-1, "%s_%s_%d", + this->prefix_, + role, + this->iogr_seq_); + + CosNaming::Name this_name (1); + this_name.length (1); + this_name[0].id = CORBA::string_dup (iogr_name); + + this->naming_context_->rebind (this_name, group.in() + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (1); + } + + iogr_seq_ += 1; + + } + + typeCount = this->unregister_roles_.size(); + for ( nType = 0; result == 0 && nType < typeCount; ++nType) + { + const char * role = this->unregister_roles_[nType].c_str(); + result = this->creator_.unregister_role (role); + } + + return result; +} + +int FTAPP::FT_Creator::fini () +{ + return this->creator_.fini(); +} + +int +main (int argc, char *argv[]) +{ + int result = 0; + ACE_TRY_NEW_ENV + { + CORBA::ORB_var orb = CORBA::ORB_init(argc, argv ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + FTAPP::FT_Creator app; + result = app.parse_args(argc, argv); + if (result == 0) + { + result = app.init (orb.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + if (result == 0) + { + result = app.run (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + } + if (result == 0) + { + result = app.fini(); + } + } + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "FT_Creator::main\t\n"); + result = -1; + } + ACE_ENDTRY; + return result; +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + template class ACE_Vector<ACE_CString>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +# pragma instantiate ACE_Vector<ACE_CString> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/tests/FT_App/FT_Creator.h b/TAO/orbsvcs/tests/FT_App/FT_Creator.h new file mode 100644 index 00000000000..c0ca6d8d2be --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/FT_Creator.h @@ -0,0 +1,111 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file TAO_FT_Creator.h + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * Main wrapped around TAO_Object_Group_Creator + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= + +#ifndef FT_CREATOR_H +#define FT_CREATOR_H +#include <ace/ACE.h> + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "TAO_Object_Group_Creator.h" + +namespace FTAPP +{ + class FT_Creator + { + typedef ACE_Vector<ACE_CString> StringVec; + public: + /////////////////////////// + // construction/destruction + FT_Creator (); + + ~FT_Creator (); + + ///////////////// + // initialization + int parse_args (int argc, char *argv[]); + + int init (CORBA::ORB_ptr orb ACE_ENV_ARG_DECL); + + //////////// + // execution + int run (ACE_ENV_SINGLE_ARG_DECL); + + //////////// + // shut down + int fini (); + + ///////////////// + // implementation + private: + void usage (ostream & out)const; + + //////////////////// + // forbidden methods + private: + FT_Creator (const FT_Creator & rhs); + FT_Creator & operator = (const FT_Creator & rhs); + + //////////////// + // Data members + private: + + TAO::Object_Group_Creator creator_; + CORBA::ORB_var orb_; + const char * registry_ior_; + StringVec create_roles_; + StringVec unregister_roles_; + + + CosNaming::NamingContext_var naming_context_; + + ::FT::ReplicationManager_var replication_manager_; + /** + * bool: true if we have a real replication manager + */ + int have_replication_manager_; + + /** + * bool: true if we should write individual IOR files + */ + int write_iors_; + + /** + * bool: true if we should write IOGR to a file + */ + int write_iogr_; + + /** + * bool: true if we should write IOGR to a Name Service + */ + int ns_register_; + + /** + * sequence number applied to created IOGRs + */ + unsigned long iogr_seq_; + + /** + * prefix for names + */ + const char * prefix_; + + + }; + +} // namespace TAO + +#endif // FT_CREATOR_H diff --git a/TAO/orbsvcs/tests/FT_App/FT_Replica.cpp b/TAO/orbsvcs/tests/FT_App/FT_Replica.cpp new file mode 100644 index 00000000000..43bd2b8b219 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/FT_Replica.cpp @@ -0,0 +1,28 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FT_Replica.cpp + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * Implement the FT_TEST::Replica IDL interface. + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= + +#include <tao/Utils/Server_Main.h> +#include "FT_ReplicaFactory_i.h" + +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + TAO::Utils::Server_Main<FT_ReplicaFactory_i> server_main("TestReplicaFactory"); + return server_main.run(argc, argv); +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + template class TAO::Utils::Server_Main<FT_ReplicaFactory_i>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +# pragma instantiate TAO::Utils::Server_Main<FT_ReplicaFactory_i> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/tests/FT_App/FT_ReplicaFactory_i.cpp b/TAO/orbsvcs/tests/FT_App/FT_ReplicaFactory_i.cpp new file mode 100644 index 00000000000..6347e0cfdc9 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/FT_ReplicaFactory_i.cpp @@ -0,0 +1,774 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FT_ReplicaFactory_i.cpp + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= +#include "FT_ReplicaFactory_i.h" +#include "FT_TestReplica_i.h" +#include <ace/Get_Opt.h> +#include <orbsvcs/CosNamingC.h> +#include <orbsvcs/PortableGroupC.h> +#include <tao/PortableServer/ORB_Manager.h> +#include <orbsvcs/PortableGroup/PG_Property_Set.h> + +// Use this macro at the beginning of CORBA methods +// to aid in debugging. +#define METHOD_ENTRY(name) \ + ACE_DEBUG (( LM_DEBUG, \ + "Enter %s\n", #name \ + )) + +// Use this macro to return from CORBA methods +// to aid in debugging. Note that you can specify +// the return value after the macro, for example: +// METHOD_RETURN(Plugh::plover) xyzzy; is equivalent +// to return xyzzy; +// METHOD_RETURN(Plugh::troll); is equivalent to +// return; +// WARNING: THIS GENERATES TWO STATEMENTS!!! THE FOLLOWING +// will not do what you want it to: +// if (cave_is_closing) METHOD_RETURN(Plugh::pirate) aarrggh; +// Moral: Always use braces. +#define METHOD_RETURN(name) \ + ACE_DEBUG (( LM_DEBUG, \ + "Leave %s\n", #name \ + )); \ + return /* value goes here */ + + +static const char * criterion_initial_value = "INITIAL_VALUE"; + +////////////////////////////////////////////////////// +// FT_ReplicaFactory_i Construction/destruction + +FT_ReplicaFactory_i::FT_ReplicaFactory_i () + : internals_ () + , orb_ (CORBA::ORB::_nil ()) + , poa_ (PortableServer::POA::_nil ()) + , object_id_ () + , ior_ () + , ior_output_file_ (0) + , identity_ () + , have_replication_manager_(0) + , replication_manager_(0) + , factory_registry_ior_(0) + , factory_registry_ (0) + , registered_(0) + , test_output_file_(0) + , ns_name_(0) + , naming_context_ (CosNaming::NamingContext::_nil ()) + , this_name_ () + , roles_ () + , location_ ("unknown") + , quit_on_idle_ (0) + , unregister_by_location_ (0) + , replicas_ () + , empty_slots_(0) + , quit_requested_(0) +{ + ACE_DEBUG((LM_DEBUG, "TestReplica type_id: %s\n", FT_TEST::_tc_TestReplica->id() )); +// ACE_DEBUG((LM_DEBUG, "Hobbit type_id: %s\n", FT_TEST::_tc_Hobbit->id() )); +// ACE_DEBUG((LM_DEBUG, "Elf type_id: %s\n", FT_TEST::_tc_Elf->id() )); +// ACE_DEBUG((LM_DEBUG, "Human type_id: %s\n", FT_TEST::_tc_Human->id() )); + +} + + +FT_ReplicaFactory_i::~FT_ReplicaFactory_i () +{ + //scope the guard + { + InternalGuard guard (this->internals_); + + // be sure all replicas are gone + // before this object disappears + shutdown_i (); + } +} + +//////////////////////////////////////////// +// FT_ReplicaFactory_i private methods + +CORBA::ULong FT_ReplicaFactory_i::allocate_id() +{ + // assume mutex is locked + CORBA::ULong id = this->replicas_.size(); + if (this->empty_slots_ != 0) + { + for(CORBA::ULong pos = 0; pos < id; ++pos) + { + if (this->replicas_[pos] == 0) + { + id = pos; + } + } + } + else + { + this->replicas_.push_back(0); + this->empty_slots_ += 1; + } + return id; +} + +void FT_ReplicaFactory_i::shutdown_i() +{ + // assume mutex is locked + for (size_t nReplica = 0; nReplica < this->replicas_.size(); ++nReplica) + { + FT_TestReplica_i * replica = this->replicas_[nReplica]; + if (replica != 0) + { + replica->request_quit(); + } + } +} + +int FT_ReplicaFactory_i::write_ior(const char * outputFile, const char * ior) +{ + int result = -1; + FILE* out = ACE_OS::fopen (outputFile, "w"); + if (out) + { + ACE_OS::fprintf (out, "%s", ior); + ACE_OS::fclose (out); + result = 0; + } + else + { + ACE_ERROR ((LM_ERROR, + "Open failed for %s\n", outputFile + )); + } + return result; +} + +////////////////////////////////////////////////////// +// FT_ReplicaFactory_i public, non-CORBA methods + +int FT_ReplicaFactory_i::parse_args (int argc, char * argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "o:n:f:i:l:t:qu"); + int c; + + while ((c = get_opts ()) != -1) + { + switch (c) + { + case 'o': + { + this->ior_output_file_ = get_opts.opt_arg (); + break; + } + case 'n': + { + this->ns_name_ = get_opts.opt_arg (); + break; + } + case 'f': + { + this->factory_registry_ior_ = get_opts.opt_arg (); + break; + } + case 'i': + { + this->roles_.push_back(get_opts.opt_arg ()); + break; + } + case 'l': + { + this->location_ = get_opts.opt_arg (); + break; + } + case 'q': + { + this->quit_on_idle_ = 1; + break; + } + case 'u': + { + this->unregister_by_location_ = 1; + break; + } + + case 't': + { + this->test_output_file_ = get_opts.opt_arg (); + break; + } + + case '?': + // fall thru + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s \n" + " -o <factory ior file>\n" + " -n <naming service registration name>\n" + " -f <factory registry ior file>\n" + " -i <registration: role>\n" + " -l <registration: location>\n" + " -t <test replica ior file>\n" + " -u{nregister by location}\n" + " -q{uit on idle}\n", + argv [0]), + -1); + break; + } + } + // Indicates sucessful parsing of the command line + return 0; +} + +const char * FT_ReplicaFactory_i::location () const +{ + return this->location_; +} + +const char * FT_ReplicaFactory_i::identity () const +{ + return this->identity_.c_str(); +} + +int FT_ReplicaFactory_i::idle (int & result) +{ + result = 0; + size_t replicaCount = this->replicas_.size(); + if (replicaCount != this->empty_slots_) + { + for (size_t nReplica = 0; result == 0 && nReplica < replicaCount; ++nReplica) + { + FT_TestReplica_i * replica = this->replicas_[nReplica]; + if (replica != 0) + { + // give the replica's idle processing a change + // ignore the return status (the replica should shut itself down + // unless result is non-zero. + // non-zero result means panic. + replica->idle(result); + } + } + } + + int quit = (this->quit_requested_ || result != 0); + if (!quit && this->replicas_.size() == this->empty_slots_) + { +/* if you re-enable this, add some kind of throttle to avoid noise. + ACE_ERROR (( LM_ERROR, + "ReplicaFactory is idle.\n" + )); +*/ + if (this->quit_on_idle_ && this->empty_slots_ != 0) + { + ACE_ERROR (( LM_ERROR, + "%s exits due to quit on idle option.\n", + identity() + )); + quit = 1; + } + } + + return quit; +} + + + +int FT_ReplicaFactory_i::init (CORBA::ORB_ptr orb ACE_ENV_ARG_DECL) +{ + int result = 0; + + this->orb_ = CORBA::ORB::_duplicate (orb); + + // Use the ROOT POA for now + CORBA::Object_var poa_object = + this->orb_->resolve_initial_references (TAO_OBJID_ROOTPOA + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (CORBA::is_nil (poa_object.in ())) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT (" (%P|%t) Unable to initialize the POA.\n")), + -1); + } + + // Get the POA object. + this->poa_ = + PortableServer::POA::_narrow (poa_object.in () + ACE_ENV_ARG_PARAMETER); + + ACE_CHECK_RETURN (-1); + if (CORBA::is_nil(this->poa_.in ())) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT (" (%P|%t) Unable to narrow the POA.\n")), + -1); + } + + PortableServer::POAManager_var poa_manager = + this->poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + // Register with the POA. + + this->object_id_ = this->poa_->activate_object (this ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + CORBA::Object_var this_obj = + this->poa_->id_to_reference (object_id_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + this->ior_ = this->orb_->object_to_string (this_obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (this->factory_registry_ior_ != 0) + { + if (ACE_OS::strcmp (this->factory_registry_ior_, "none") != 0) + { + CORBA::Object_var reg_obj = this->orb_->string_to_object(factory_registry_ior_ + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + this->factory_registry_ = ::PortableGroup::FactoryRegistry::_narrow(reg_obj.in ()); + if (CORBA::is_nil(this->factory_registry_.in ())) + { + ACE_ERROR (( LM_ERROR, + "Can't resolve Factory Registry IOR %s\n", + this->factory_registry_ior_ + )); + result = -1; + } + } + } + else // no -f option. Try RIR(RM) + { + /////////////////////////////// + // Find the ReplicationManager + ACE_TRY_NEW_ENV + { + CORBA::Object_var rm_obj = orb->resolve_initial_references("ReplicationManager" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + this->replication_manager_ = ::FT::ReplicationManager::_narrow(rm_obj.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + if (!CORBA::is_nil (replication_manager_.in ())) + { + this->have_replication_manager_ = 1; + // empty criteria + ::PortableGroup::Criteria criteria; + this->factory_registry_ = this->replication_manager_->get_factory_registry(criteria ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + if (CORBA::is_nil (this->factory_registry_.in ())) + { + ACE_ERROR ((LM_ERROR,"ReplicaFactory: ReplicationManager failed to return FactoryRegistry. Factory will not be registered.\n" )); + } + } + else + { + this->factory_registry_ = ::PortableGroup::FactoryRegistry::_narrow(rm_obj.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + if (!CORBA::is_nil(this->factory_registry_.in ())) + { + ACE_DEBUG ((LM_DEBUG,"Found a FactoryRegistry DBA ReplicationManager\n" )); + } + else + { + ACE_ERROR ((LM_ERROR,"ReplicaFactory: Can't resolve ReplicationManager.\n" )); + } + } + } + ACE_CATCHANY + { + if (this->test_output_file_ == 0) // ignore if this is a test run + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "ReplicaFactory: Exception resolving ReplicationManager. Factory will not be registered.\n" ); + } + } + ACE_ENDTRY; + + } + + if ( ! CORBA::is_nil (this->factory_registry_.in ())) + { + size_t roleCount = roles_.size(); + for (size_t nRole = 0; nRole < roleCount; ++nRole) + { + const char * roleName = this->roles_[nRole].c_str(); + + PortableGroup::FactoryInfo info; + info.the_factory = ::PortableGroup::GenericFactory::_narrow(this_obj.in ()); + info.the_location.length(1); + info.the_location[0].id = CORBA::string_dup(this->location_); + info.the_criteria.length(1); + info.the_criteria[0].nam.length(1); + info.the_criteria[0].nam[0].id = CORBA::string_dup(PortableGroup::role_criterion); + info.the_criteria[0].val <<= CORBA::string_dup(roleName); + + ACE_ERROR (( LM_INFO, + "Factory: %s@%s registering with factory registry\n", + roleName, + location_ + )); + + this->factory_registry_->register_factory( + roleName, + FT_TEST::_tc_TestReplica->id(), + info + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + } + this->registered_ = 1; + } + + int identified = 0; // bool + + if (this->roles_.size() > 0) + { + this->identity_ = "Factory"; + if (this->location_ != 0) + { + this->identity_ += "@"; + this->identity_ += this->location_; + } + identified = 1; + } + + if (this->ior_output_file_ != 0) + { + if (!identified) + { + this->identity_ = "file:"; + this->identity_ += this->ior_output_file_; + // note: don't set identified--ns identity overrides file identitiy + } + result = write_ior (this->ior_output_file_, this->ior_); + } + else + { + if (this->registered_) + { + // if we didn't register with a FactoryRegistry + // and no IOR file specified, + // then always try to register with name service + this->ns_name_ = "FT_ReplicaFactory"; + } + } + + if (this->ns_name_ != 0) + { + if (!identified) + { + this->identity_ = "name:"; + this->identity_ += this->ns_name_; + } + + CORBA::Object_var naming_obj = + this->orb_->resolve_initial_references ("NameService" ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (CORBA::is_nil(naming_obj.in ())){ + ACE_ERROR_RETURN ((LM_ERROR, + "%T %n (%P|%t) Unable to find the Naming Service\n"), + 1); + } + + this->naming_context_ = + CosNaming::NamingContext::_narrow (naming_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + this->this_name_.length (1); + this->this_name_[0].id = CORBA::string_dup (this->ns_name_); + + this->naming_context_->rebind (this->this_name_, this_obj.in() // CORBA::Object::_duplicate(this_obj) + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + } + + // if we're testing. Create a replica at startup time + if (this->test_output_file_ != 0) + { + // shouldn't be necessary, but create_replica assumes this + InternalGuard guard (this->internals_); + FT_TestReplica_i * replica = create_replica ("test"); + + PortableServer::POA_var poa = replica->_default_POA (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + ::CORBA::Object_var replica_obj = poa->servant_to_reference(replica ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + ::CORBA::String_var replicaIOR = this->orb_->object_to_string(replica_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + write_ior (this->test_output_file_, replicaIOR); + } + + return result; +} + +int FT_ReplicaFactory_i::fini (ACE_ENV_SINGLE_ARG_DECL) +{ + if (this->ior_output_file_ != 0) + { + ACE_OS::unlink (this->ior_output_file_); + this->ior_output_file_ = 0; + } + if (this->ns_name_ != 0) + { + this->naming_context_->unbind (this_name_ + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + this->ns_name_ = 0; + } + + if (registered_) + { + registered_ = 0; + + if (this->unregister_by_location_) + { + ACE_ERROR (( LM_INFO, + "%s: unregistering all factories at %s\n", + identity(), + location_ + )); + + PortableGroup::Location location(1); + location.length(1); + location[0].id = CORBA::string_dup(location_); + this->factory_registry_->unregister_factory_by_location ( + location + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + } + else + { + size_t roleCount = roles_.size(); + for (size_t nRole = 0; nRole < roleCount; ++nRole) + { + const char * roleName = this->roles_[nRole].c_str(); + ACE_ERROR (( LM_INFO, + "Factory for: %s@%s unregistering from factory registry\n", + roleName, + location_ + )); + + PortableGroup::Location location(1); + location.length(1); + location[0].id = CORBA::string_dup(location_); + this->factory_registry_->unregister_factory ( + roleName, + location + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + } + } + } + + return 0; +} + + +void FT_ReplicaFactory_i::remove_replica(CORBA::ULong id, FT_TestReplica_i * replica) +{ + InternalGuard guard (this->internals_); + if (id < this->replicas_.size()) + { + if(this->replicas_[id] == replica) + { + replica->fini(); + delete replica; + this->replicas_[id] = 0; + this->empty_slots_ += 1; + } + else + { + ACE_ERROR (( LM_ERROR, + "Remove replica %d mismatch.\n", + ACE_static_cast(int, id) + )); + } + } + else + { + ACE_ERROR (( LM_ERROR, + "Attempt to remove invalid replica %d. Limit %d.\n", + ACE_static_cast(int, id), + ACE_static_cast(int, this->replicas_.size()) + )); + } +} + +////////////////////////////////////////// +// FT_ReplicaFactory_i CORBA methods + +CORBA::Object_ptr FT_ReplicaFactory_i::create_object ( + const char * type_id, + const PortableGroup::Criteria & the_criteria, + PortableGroup::GenericFactory::FactoryCreationId_out factory_creation_id + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + , PortableGroup::NoFactory + , PortableGroup::ObjectNotCreated + , PortableGroup::InvalidCriteria + , PortableGroup::InvalidProperty + , PortableGroup::CannotMeetCriteria + )) +{ + METHOD_ENTRY(FT_ReplicaFactory_i::create_object); + ACE_UNUSED_ARG (type_id); + InternalGuard guard (this->internals_); + + ::TAO::PG_Property_Set decoder (the_criteria); + + // boolean, becomes true if a required parameter is missing + int missingParameter = 0; + const char * missingParameterName = 0; + + CORBA::Long initialValue = 0; + if (! ::TAO::find (decoder, criterion_initial_value, initialValue) ) + { + // not required. Otherwise: + // missingParameter = 1; + // missingParameterName = criterion_initial_value; + } + + const char * role = "replica"; + if (! ::TAO::find (decoder, PortableGroup::role_criterion, role) ) + { + ACE_ERROR((LM_INFO, + "Property \"%s\" not found?\n", PortableGroup::role_criterion + )); + // not required. Otherwise: + // missingParameter = 1; + // missingParameterName = PortableGroup::role_criterion; + } + + if (missingParameter) + { + ACE_ERROR ((LM_ERROR, + "Throwing 'InvalidCriteria' due to missing %s\n", + missingParameterName + )); + ACE_THROW ( PortableGroup::InvalidCriteria() ); + } + + FT_TestReplica_i * replica = create_replica(role); + if (replica == 0) + { + ACE_ERROR ((LM_ERROR, + "New Replica_i returned NULL. Throwing ObjectNotCreated.\n" + )); + ACE_THROW ( PortableGroup::ObjectNotCreated() ); + } + + ACE_NEW_THROW_EX ( factory_creation_id, + PortableGroup::GenericFactory::FactoryCreationId, + PortableGroup::ObjectNotCreated()); + CORBA::ULong factory_id = replica->factory_id(); + (*factory_creation_id) <<= factory_id; + + ACE_ERROR ((LM_INFO, + "Created %s@%s#%d.\n", role, this->location_, ACE_static_cast(int, factory_id) + )); + + + ::CORBA::Object_ptr replica_obj = replica->_default_POA()->servant_to_reference(replica); + METHOD_RETURN(FT_ReplicaFactory_i::create_object) replica_obj->_duplicate(replica_obj ACE_ENV_ARG_PARAMETER); +} + +FT_TestReplica_i * FT_ReplicaFactory_i::create_replica(const char * name) +{ + // assume mutex is locked + CORBA::ULong factoryId = allocate_id(); + + FT_TestReplica_i * pFTReplica = 0; + + ACE_NEW_NORETURN(pFTReplica, FT_TestReplica_i( + this, + name, + factoryId + )); + + this->replicas_[factoryId] = pFTReplica; + this->empty_slots_ -= 1; + + pFTReplica->init (this->orb_ ACE_ENV_ARG_PARAMETER); + return pFTReplica; +} + +void FT_ReplicaFactory_i::delete_object ( + const PortableGroup::GenericFactory::FactoryCreationId & factory_creation_id + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + , PortableGroup::ObjectNotFound + )) +{ + METHOD_ENTRY(FT_ReplicaFactory_i::delete_object); + + InternalGuard guard (this->internals_); + + CORBA::ULong factoryId; + factory_creation_id >>= factoryId; + if (factoryId < this->replicas_.size()) + { + if(this->replicas_[factoryId] != 0) + { + this->replicas_[factoryId]->request_quit(); + } + else + { + ACE_THROW(::PortableGroup::ObjectNotFound()); + } + } + else + { + ACE_THROW(::PortableGroup::ObjectNotFound()); + } + METHOD_RETURN(FT_ReplicaFactory_i::delete_object); +} + +CORBA::Boolean FT_ReplicaFactory_i::is_alive (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + METHOD_RETURN(FT_ReplicaFactory_i::is_alive) + 1; +} + +void FT_ReplicaFactory_i::shutdown (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC (( + CORBA::SystemException + )) +{ + METHOD_ENTRY(FT_FaultDetectorFactory_i::shutdown); + InternalGuard guard (this->internals_); + shutdown_i (); + this->quit_requested_ = 1; + METHOD_RETURN(FT_FaultDetectorFactory_i::shutdown); +} + + +/////////////////////////////////// +// Template instantiation for +// competence-challenged compilers. + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + template class ACE_Vector<FT_TestReplica_i *>; + template class ACE_Guard<ACE_Mutex>; + template class ACE_Vector<ACE_CString>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +# pragma instantiate ACE_Vector<FT_TestReplica_i *> +# pragma instantiate ACE_Guard<ACE_Mutex> +# pragma instantiate ACE_Vector<ACE_CString> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/tests/FT_App/FT_ReplicaFactory_i.h b/TAO/orbsvcs/tests/FT_App/FT_ReplicaFactory_i.h new file mode 100644 index 00000000000..b22d82204e9 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/FT_ReplicaFactory_i.h @@ -0,0 +1,293 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FT_ReplicaFactory_i.h + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * It declares the implementation of ReplicaFactory which + * creates and manages replicas as an agent for + * the ReplicationManager as defined in the FT CORBA specification. + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= + +#ifndef FT_REPLICAFACTORY_H_ +#define FT_REPLICAFACTORY_H_ +#include <ace/ACE.h> +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +////////////////////////////////// +// Classes declared in this header +class FT_ReplicaFactory_i; + +///////////////////////////////// +// Includes needed by this header +#include <ace/Vector_T.h> +#include "FT_TestReplicaS.h" +#include <ace/Thread_Manager.h> +#include <orbsvcs/FT_ReplicationManagerC.h> + +///////////////////// +// Forward references +class TAO_ORB_Manager; +class FT_TestReplica_i; + +/** + * Implement the GenericFactory interface. + */ +class FT_ReplicaFactory_i +//FT_TEST::ReplicaFactory + : public virtual POA_PortableGroup::GenericFactory +{ + typedef ACE_Vector<FT_TestReplica_i *> ReplicaVec; + typedef ACE_Vector<ACE_CString> StringVec; + + ////////////////////// + // non-CORBA interface +public: + /** + * Default constructor. + */ + FT_ReplicaFactory_i (); + + /** + * Virtual destructor. + */ + virtual ~FT_ReplicaFactory_i (); + + /** + * Parse command line arguments. + * @param argc traditional C argc + * @param argv traditional C argv + * @return zero for success; nonzero is process return code for failure. + */ + int parse_args (int argc, char * argv[]); + + /** + * Initialize this object. + * @param orb our ORB -- we keep var to it. + * @return zero for success; nonzero is process return code for failure. + */ + int init (CORBA::ORB_ptr orb ACE_ENV_ARG_DECL); + + /** + * Prepare to exit. + * @return zero for success; nonzero is process return code for failure. + */ + int fini (ACE_ENV_SINGLE_ARG_DECL); + + int idle(int & result); + + + /** + * Identify this replica factory. + * @return a string to identify this object for logging/console message purposes. + */ + const char * identity () const; + + const char * location () const; + + /** + * Remove pointer to individual replica; delete FT_TestReplica_i. + * See replica life cycle description. + * @param id the numerical id assigned to this replica. + * @param replica a pointer to the Replica object (redundant for safety.) + */ + void remove_replica (CORBA::ULong id, FT_TestReplica_i * replica); + + ////////////////// + // CORBA interface + // See IDL for documentation + + virtual void shutdown (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC (( + CORBA::SystemException + )); + + ///////////////////////////////////////// + // CORBA interface GenericFactory methods + virtual CORBA::Object_ptr create_object ( + const char * type_id, + const PortableGroup::Criteria & the_criteria, + PortableGroup::GenericFactory::FactoryCreationId_out factory_creation_id + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ) + ACE_THROW_SPEC (( + CORBA::SystemException + , PortableGroup::NoFactory + , PortableGroup::ObjectNotCreated + , PortableGroup::InvalidCriteria + , PortableGroup::InvalidProperty + , PortableGroup::CannotMeetCriteria + )); + + virtual void delete_object ( + const PortableGroup::GenericFactory::FactoryCreationId & factory_creation_id + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ) + ACE_THROW_SPEC (( + CORBA::SystemException + , PortableGroup::ObjectNotFound + )); + + ////////////////////////////////////////// + // CORBA interface PullMonitorable methods + + virtual CORBA::Boolean is_alive (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + ///////////////////////// + // Implementation methods +private: + /** + * Actual replica creation happens in this method. + * @param name becomes part of the objects identity. + */ + FT_TestReplica_i * create_replica(const char * name); + + /** + * Find or allocate an ID for a new replica + */ + CORBA::ULong allocate_id(); + + /** + * Write this factory's IOR to a file + */ + int write_ior (const char * outputFile, const char * ior); + + /** + * Clean house for factory shut down. + */ + void shutdown_i (); + + /////////////// + // Data Members +private: + + /** + * Protect internal state. + * Mutex should be locked by corba methods, or by + * external (public) methods before calling implementation + * methods. + * Implementation methods should assume the mutex is + * locked if necessary. + */ + ACE_SYNCH_MUTEX internals_; + typedef ACE_Guard<ACE_SYNCH_MUTEX> InternalGuard; + + /** + * The orb + */ + CORBA::ORB_var orb_; + + /** + * The POA used to activate this object. + */ + PortableServer::POA_var poa_; + + /** + * The CORBA object id assigned to this object. + */ + PortableServer::ObjectId_var object_id_; + + /** + * IOR of this object as assigned by poa + */ + CORBA::String_var ior_; + + /** + * A file to which the factory's IOR should be written. + */ + const char * ior_output_file_; + + /** + * A human-readable string to distinguish this from other Notifiers. + */ + ACE_CString identity_; + + /** + * bool: true if we found a replication manager + */ + int have_replication_manager_; + + /** + * The replication manager + */ + + ::FT::ReplicationManager_var replication_manager_; + + + /** + * The factory registry IOR + */ + const char * factory_registry_ior_; + + /** + * The factory registry with which to register. + */ + PortableGroup::FactoryRegistry_var factory_registry_; + + /** + * true if registered with FactoryRegistry + */ + int registered_; // bool + + /** + * A file to which the test replica's IOR will be written + */ + const char * test_output_file_; + + /** + * A name to be used to register the factory with the name service. + */ + const char * ns_name_; + + CosNaming::NamingContext_var naming_context_; + + CosNaming::Name this_name_; + + ///////////////// + // The roles used to register types + StringVec roles_; + + /** + * the PortableGroup::Location within the domain + */ + const char * location_; + + /** + * bool: quit on idle flag. + */ + int quit_on_idle_; + + /** + * bool: use a single call to unregister. + */ + int unregister_by_location_; + + /** + * A vector of Replicas. Note that the Replica ID + * is an index into this vector. + */ + ReplicaVec replicas_; + + /** + * count of entries in Replicas_ that have been deleted. + * Used to determine when the factory is idle and to avoid futile + * searches for empty slots. + */ + size_t empty_slots_; + + /** + * boolean: starts false. Set to true when it's time to quit. + */ + int quit_requested_; + +}; + +#endif /* FT_REPLICAFACTORY_H_ */ diff --git a/TAO/orbsvcs/tests/FT_App/FT_ReplicationManagerController.cpp b/TAO/orbsvcs/tests/FT_App/FT_ReplicationManagerController.cpp new file mode 100755 index 00000000000..96c660e4a7e --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/FT_ReplicationManagerController.cpp @@ -0,0 +1,197 @@ +// $Id$ + +#include "orbsvcs/FT_ReplicationManagerC.h" +#include <ace/Get_Opt.h> +#include <iostream> + +// A simple class for building a client that "controls' the +// Replication Manager (right now it just shuts it down). +class TAO_FT_ReplicationManagerController +{ +///////////////////////////// +// Public interface. +public: + TAO_FT_ReplicationManagerController (); + virtual ~TAO_FT_ReplicationManagerController (); + + int init (int & argc, char * argv[]); + int parse_args (int & argc, char* argv[]); + int run (); + +///////////////////////////// +// Forbidden. +private: + TAO_FT_ReplicationManagerController ( + const TAO_FT_ReplicationManagerController & rhs); + TAO_FT_ReplicationManagerController & operator = ( + const TAO_FT_ReplicationManagerController & rhs); + +///////////////////////////// +// Private implementation. +private: + void usage (ostream & out) const; + +///////////////////////////// +// Data members. +private: + CORBA::ORB_var orb_; + FT::ReplicationManager_var replication_manager_; + const char * rm_ior_; + int shutdown_; + +}; + +TAO_FT_ReplicationManagerController::TAO_FT_ReplicationManagerController () + : orb_ (CORBA::ORB::_nil()) + , replication_manager_ (FT::ReplicationManager::_nil()) + , rm_ior_ (0) + , shutdown_ (0) +{ +} + +TAO_FT_ReplicationManagerController::~TAO_FT_ReplicationManagerController () +{ +} + +int TAO_FT_ReplicationManagerController::init (int & argc, char * argv[]) +{ + int result = 0; + + ACE_TRY_NEW_ENV + { + // Initialize the ORB. + this->orb_ = CORBA::ORB_init (argc, argv, "" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + // Parse arguments. + result = this->parse_args (argc, argv); + if (result == 0) + { + CORBA::Object_var obj = CORBA::Object::_nil (); + if (this->rm_ior_ != 0) + { + obj = this->orb_->string_to_object ( + this->rm_ior_ ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + else + { + obj = this->orb_->resolve_initial_references ( + "ReplicationManager" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + this->replication_manager_ = FT::ReplicationManager::_narrow ( + obj.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + if (CORBA::is_nil (this->replication_manager_.in())) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ( + "TAO_FT_ReplicationManagerController::init: " + "Could not get Replication Manager's IOR.\n") + )); + result = -1; + } + } + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION ( + ACE_ANY_EXCEPTION, + ACE_TEXT ( + "TAO_FT_ReplicationManagerController::init: \n") + ); + result = -1; + } + ACE_ENDTRY; + + return result; +} + + +int TAO_FT_ReplicationManagerController::parse_args (int & argc, char * argv[]) +{ + int result = 0; + + ACE_Get_Opt get_opts (argc, argv, "k:x"); + int c; + + while (result == 0 && (c = get_opts ()) != -1) + { + switch (c) + { + case 'k': + { + this->rm_ior_ = get_opts.opt_arg (); + break; + } + + case 'x': + { + this->shutdown_ = 1; + break; + } + + default: + std::cerr << argv[0] << ": Unknown argument -" << (char) c << std::endl; + this->usage(std::cerr); + result = -1; + break; + + case '?': + this->usage(std::cerr); + result = -1; + } + } + + return result; +} + +void TAO_FT_ReplicationManagerController::usage (ostream & out) const +{ + out << "usage" + << " -k <replication manager ior file>" + << " -x (shutdown the Replication Manager)" + << std::endl; +} + +int TAO_FT_ReplicationManagerController::run () +{ + int result = 0; + + ACE_TRY_NEW_ENV + { + if (this->shutdown_ == 1) + { + this->replication_manager_->shutdown (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_TRY_CHECK; + ACE_Time_Value tv (0, 500000); + ACE_OS::sleep (tv); + } + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION ( + ACE_ANY_EXCEPTION, + ACE_TEXT ( + "TAO_FT_ReplicationManagerController::run: \n") + ); + result = -1; + } + ACE_ENDTRY; + + return result; +} + +int main (int argc, char * argv[]) +{ + int result = 0; + TAO_FT_ReplicationManagerController rmctrl; + result = rmctrl.init (argc, argv); + if (result == 0) + { + result = rmctrl.run (); + } + return result; +} + diff --git a/TAO/orbsvcs/tests/FT_App/FT_TestReplica.idl b/TAO/orbsvcs/tests/FT_App/FT_TestReplica.idl new file mode 100644 index 00000000000..b9d41ed7429 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/FT_TestReplica.idl @@ -0,0 +1,117 @@ +/* -*- IDL -*- */ +//============================================================================= +/** + * @file FT_TestReplica.idl + * + * $Id$ + * + * This file defines an interface used to test Fault Tolerant CORBA. + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= +// +#ifndef FT_TESTREPLICA_IDL +#define FT_TESTREPLICA_IDL + +#include "orbsvcs/FT_Replica.idl" + +module FT_TEST +{ + /** + * A FT_TEST::Replica provides a test target for a FT::FaultDetector + * It is Updateable (and therefore Checkpointable) + * and PullMonitorable + * It declares a simple counter that can be set, incremented, and read + * via method calls. The counter is also exposed as a property. + */ + interface TestReplica : ::FT::Updateable, ::FT::PullMonitorable, ::PortableGroup::TAO_UpdateObjectGroup + { + /** + * set the counter to an specific value. + * @param value is the number to be set. + */ + void set(in long value); + + /** + * add delta to the counter. + * @param delta is the number to be added: (delta may be positive, negative or zero). + * @returns the new value of the counter. + */ + long increment(in long delta); + + /** + * retrieve the current counter. + * @returns the value of the counter. + */ + long get(); + + + /** + * enumerate the points at which + * the test replica might be convinced to die. + */ + enum Bane + { + NOT_YET, // normal state, also used to revoke a previous request + RIGHT_NOW, // fault immediately during the die() call + WHILE_IDLE, // fault while not processing a request + // FT_TestReplica interface: + BEFORE_STATE_CHANGE, // after receiving request + BEFORE_REPLICATION, // after state change + BEFORE_REPLY, // after state replication + // FT::PullMonitorable interface: + DURING_IS_ALIVE, + DENY_IS_ALIVE, + // FT::Updatable interface: + DURING_GET_UPDATE, + BEFORE_SET_UPDATE, + AFTER_SET_UPDATE, + // FT::Checkpointable interface: + DURING_GET_STATE, + BEFORE_SET_STATE, + AFTER_SET_STATE, + // Reserved + CLEAN_EXIT // reserved for use by shutdown + }; + + + /** + * die a horrid death. + * @param when is an arbitrary code to indicate how and when to die. + */ + void die(in Bane when); + + + /** + * die a clean death. + */ + oneway void shutdown(); + + /** + * provide direct access to the counter. + * Suports the same functionality as set and get. + * Can you say "Encapsulization???" this is a test, remember. + */ + attribute long counter; + }; + + interface ReplicaFactory : ::PortableGroup::GenericFactory, ::FT::PullMonitorable + { + /** + * die a clean death. + */ + oneway void shutdown(); + }; + + /////////////////////// + // roles for unit tests + // A TestReplica can act as a... + +// typedef TestReplica Hobbit; +// typedef TestReplica Elf; +// typedef TestReplica Human; + +}; + +#endif // for #ifndef FT_TESTREPLICA_IDL diff --git a/TAO/orbsvcs/tests/FT_App/FT_TestReplica_i.cpp b/TAO/orbsvcs/tests/FT_App/FT_TestReplica_i.cpp new file mode 100644 index 00000000000..89b2b5c1aa2 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/FT_TestReplica_i.cpp @@ -0,0 +1,468 @@ +// $Id$ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FT_TestReplica_i.cpp + * + * $Id$ + * + * Implements CORBA interface TestReplica. + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= +// + +#include "FT_TestReplica_i.h" +#include "FT_ReplicaFactory_i.h" +#include <tao/PortableServer/ORB_Manager.h> +#include <iostream> +#include "FT_TestReplicaC.h" + +////////////////// +// TestReplica_i + +namespace +{ + /** + * Endian neutral store of long into indexable object. + * BUFFER can be sequence of Octet, unsigned char[], etc. + * + * TODO: Find this a good home. + * + * @param state an object that supports char & operator[] (size_t index); + * @param offset is the position within state where the first character should be stored. + * @param value is the data to be inserted into state. + */ + template<typename BUFFER> + void storeLong(BUFFER & state, size_t offset, long value) + { + state[offset ] = ACE_static_cast (unsigned char, value >> 24); + state[offset + 1] = ACE_static_cast (unsigned char, value >> 16); + state[offset + 2] = ACE_static_cast (unsigned char, value >> 8); + state[offset + 3] = ACE_static_cast (unsigned char, value ); + } + + /** + * Endian neutral load of long from indexable object. + * BUFFER can be sequence of Octet, unsigned char[], etc. + * + * TODO: Find this a good home. + * + * @param state an object that supports const char & operator[] (size_t index) const; + * @param offset is the position within state where the first character can be found + * @returns value is the data loaded from state. + */ + template<typename BUFFER> + long loadLong(const BUFFER & state, size_t offset) + { + long result + = ((state[offset ] & 0xFF) << 24) + | ((state[offset + 1] & 0xFF) << 16) + | ((state[offset + 2] & 0xFF) << 8) + | ((state[offset + 3] & 0xFF) ); + return result; + } +} + +// NO_RESPONSE ->no reinvocation + +#define FAULT_CODE CORBA::TRANSIENT + +// Macros to simplify suicide. +#define KEVORKIAN(value, method) \ + if (this->death_pending_ == (FT_TEST::TestReplica::value)){ \ + suicide (#value " in method " #method); \ + ACE_THROW (FAULT_CODE ( \ + CORBA::SystemException::_tao_minor_code ( \ + TAO_DEFAULT_MINOR_CODE, \ + EFAULT), \ + CORBA::COMPLETED_NO)); \ + } else ; + +#define KEVORKIAN_DURING(method) \ + if (this->death_pending_ == FT_TEST::TestReplica::BEFORE_REPLY ){\ + suicide ("read-only method " #method); \ + ACE_THROW (FAULT_CODE ( \ + CORBA::SystemException::_tao_minor_code ( \ + TAO_DEFAULT_MINOR_CODE, \ + EFAULT), \ + CORBA::COMPLETED_NO)); \ + } else ; + + +////////////////////////////////////////////////// +// class FT_TestReplica_i construction/destruction + +FT_TestReplica_i::FT_TestReplica_i (FT_ReplicaFactory_i * factory, const char * name, unsigned long factory_id) + : death_pending_ (FT_TEST::TestReplica::NOT_YET) + , verbose_ (1) + , name_ (name) + , factory_id_ (factory_id) + , factory_ (factory) + , orb_ (0) + , poa_ (0) + , object_id_ (0) +{ +// std::cout << name_.c_str() << '@' << this->factory_->location() << '#' << this->factory_id_ << " Construct" << std::endl; +} + +FT_TestReplica_i::~FT_TestReplica_i () +{ +// std::cout << name_.c_str() << '@' << this->factory_->location() << '#' << this->factory_id_ << " Destruct" << std::endl; +} + + +void FT_TestReplica_i::suicide(const char * note) +{ + std::cout << name_.c_str() << '@' << this->factory_->location() << '#' << this->factory_id_ << " Simulate FAULT_CODE fault: " << note << std::endl; + + // Tell the poa we aren't accepting future calls + this->poa_->deactivate_object (this->object_id_.in () + ACE_ENV_ARG_PARAMETER); +} + +///////////////////////////////////////////////////// +// class FT_TestReplica_i public, non-CORBA interface + + + +//static +const char * FT_TestReplica_i::repository_id() +{ + return FT_TEST::_tc_TestReplica->id(); +} + +int +FT_TestReplica_i::parse_args (int argc, char *argv[]) +{ + ACE_UNUSED_ARG (argc); + ACE_UNUSED_ARG (argv); + return 0; +} + +//static +const char * +FT_TestReplica_i::usage_options() +{ + return ""; +} + +unsigned long FT_TestReplica_i::factory_id()const +{ + return this->factory_id_; +} + +::PortableServer::POA_ptr FT_TestReplica_i::_default_POA (ACE_ENV_SINGLE_ARG_DECL) +{ + return ::PortableServer::POA::_duplicate(this->poa_.in () ACE_ENV_ARG_PARAMETER); +} + +PortableServer::ObjectId FT_TestReplica_i::object_id()const +{ + return this->object_id_.in(); +} + + +/** + * Initialize this object. + * @param orbManager our ORB -- we keep var to it. + * @return zero for success; nonzero is process return code for failure. + */ +int FT_TestReplica_i::init (CORBA::ORB_var & orb ACE_ENV_ARG_DECL) +{ + this->orb_ = orb; + + // Use the ROOT POA for now + CORBA::Object_var poa_object = + this->orb_->resolve_initial_references (TAO_OBJID_ROOTPOA + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (CORBA::is_nil (poa_object.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT (" (%P|%t) Unable to initialize the POA.\n")), + -1); + + // Get the POA object. + this->poa_ = + PortableServer::POA::_narrow (poa_object.in () + ACE_ENV_ARG_PARAMETER); + + ACE_CHECK_RETURN (-1); + + if (CORBA::is_nil(this->poa_.in ())) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT (" (%P|%t) Unable to narrow the POA.\n")), + -1); + } + + PortableServer::POAManager_var poa_manager = + this->poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + + // Register with the POA. + + this->object_id_ = this->poa_->activate_object (this ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + return 0; +} + +void FT_TestReplica_i::_remove_ref (ACE_ENV_SINGLE_ARG_DECL) +{ + ////////////////////////////////////////////////// + // WARNING: The following call invokes fini then deletes this object + this->factory_->remove_replica(this->factory_id_, this); +} + +int FT_TestReplica_i::fini (ACE_ENV_SINGLE_ARG_DECL) +{ + return 0; +} + + + +///////////////////////////////////////////////////// +// class FT_TestReplica_i: PullMonitorable interface +CORBA::Boolean FT_TestReplica_i::is_alive () + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + KEVORKIAN(DURING_IS_ALIVE, is_alive) + ACE_ERROR ((LM_ERROR, + "%s@%s#%d: is_alive: %d\n", + this->name_.c_str(), + this->factory_->location(), + this->factory_id_, + (this->death_pending_ != FT_TEST::TestReplica::DENY_IS_ALIVE) + )); + + return this->death_pending_ != FT_TEST::TestReplica::DENY_IS_ALIVE; +} + +///////////////////////////////////////////////////// +// class FT_TestReplica_i: Updateable interface +FT::State * FT_TestReplica_i::get_update () + ACE_THROW_SPEC ((CORBA::SystemException, FT::NoUpdateAvailable)) +{ + KEVORKIAN(DURING_GET_UPDATE, get_update) + long counter = load(); + ::FT::State_var vState = new ::FT::State; + vState->length(sizeof(counter)); + storeLong(vState, 0, counter); + return vState._retn(); +} + +void FT_TestReplica_i::set_update (const FT::State & s) + ACE_THROW_SPEC ((CORBA::SystemException, FT::InvalidUpdate)) +{ +#if defined(FT_TEST_LACKS_UPDATE) + ACE_THROW ( FT::InvalidUpdate () ); +#else // FT_TEST_LACKS_UPDATE + KEVORKIAN(BEFORE_SET_UPDATE, set_update) + long counter = loadLong<FT::State>(s, 0); + store(counter); + KEVORKIAN(AFTER_SET_UPDATE, set_update) +#endif // FT_TEST_LACKS_UPDATE +} + +///////////////////////////////////////////////////// +// class FT_TestReplica_i: Checkpointable interface +::FT::State * FT_TestReplica_i::get_state () + ACE_THROW_SPEC ((CORBA::SystemException, FT::NoStateAvailable)) +{ +#if defined(FT_TEST_LACKS_STATE) + ACE_THROW( FT::NoStateAvailable () ); +#else // FT_TEST_LACKS_STATE + KEVORKIAN(DURING_GET_STATE, get_state) + long counter = load(); + ::FT::State_var vState = new ::FT::State; + vState->length(sizeof(counter)); + storeLong(vState, 0, counter); + return vState._retn(); +#endif // FT_TEST_LACKS_STATE +} + +void FT_TestReplica_i::set_state (const FT::State & s) + ACE_THROW_SPEC ((CORBA::SystemException, FT::InvalidState)) +{ +#if defined(FT_TEST_LACKS_STATE) + ACE_THROW ( FT::InvalidState () ); +#else // FT_TEST_LACKS_STATE + KEVORKIAN(BEFORE_SET_STATE, set_state) + long counter = loadLong<FT::State>(s, 0); + store(counter); + KEVORKIAN(AFTER_SET_STATE, set_state) +#endif // FT_TEST_LACKS_STATE +} + +void FT_TestReplica_i::tao_update_object_group ( + const char * iogr, + PortableGroup::ObjectGroupRefVersion version, + CORBA::Boolean is_primary + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + ACE_UNUSED_ARG (iogr); + ACE_UNUSED_ARG (version); + ACE_UNUSED_ARG (is_primary); + + ACE_THROW (CORBA::NO_IMPLEMENT()); +} + +////////////////////////////// +// implement FT_TEST::Replica + +void FT_TestReplica_i::set (CORBA::Long value + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + KEVORKIAN(BEFORE_STATE_CHANGE, set) + long counter = value; + store(counter); + KEVORKIAN(BEFORE_REPLY, set) +} + +CORBA::Long FT_TestReplica_i::increment (CORBA::Long delta + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + KEVORKIAN(BEFORE_STATE_CHANGE, increment) + long counter = load (); + counter += delta; + store (counter); + KEVORKIAN(BEFORE_REPLY, increment) + return counter; +} + +CORBA::Long FT_TestReplica_i::get (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + KEVORKIAN_DURING(get) + long counter = load (); + return counter; +} + +CORBA::Long FT_TestReplica_i::counter (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + KEVORKIAN_DURING([get]counter) + long counter = load (); + return counter; +} + +void FT_TestReplica_i::counter (CORBA::Long counter + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + KEVORKIAN(BEFORE_STATE_CHANGE, [set]counter) + store (counter); + KEVORKIAN(BEFORE_REPLY, [set]counter) +} + +void FT_TestReplica_i::die (FT_TEST::TestReplica::Bane when + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + std::cout << name_.c_str() << '@' << this->factory_->location() << '#' << this->factory_id_ << " Received death threat: " << when << std::endl; + + this->death_pending_ = when; + KEVORKIAN(RIGHT_NOW, die) +} + +void FT_TestReplica_i::shutdown (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + std::cout << name_.c_str() << '@' << this->factory_->location() << '#' << this->factory_id_ << " Shut down requested" << std::endl; + this->death_pending_ = FT_TEST::TestReplica::CLEAN_EXIT; +} + +////////////////////////////////////////////// +// FT_TestReplica_i public non-CORBA interface +int FT_TestReplica_i::idle (int & result) +{ + int quit = 0; + if (this->death_pending_ == FT_TEST::TestReplica::WHILE_IDLE) + { + ACE_ERROR ((LM_ERROR, + "%s@%s#%d: Simulated fault WHILE_IDLE", + this->name_.c_str(), + this->factory_->location(), + ACE_static_cast(int, this->factory_id_ ) + )); + this->poa_->deactivate_object (this->object_id_.in () + ACE_ENV_ARG_PARAMETER); + result = 0; + quit = 1; + } + else if (this->death_pending_ == FT_TEST::TestReplica::CLEAN_EXIT) + { + this->poa_->deactivate_object (this->object_id_.in () + ACE_ENV_ARG_PARAMETER); + result = 0; + quit = 1; + } + return quit; +} + +void FT_TestReplica_i::request_quit() +{ + this->death_pending_ = FT_TEST::TestReplica::WHILE_IDLE; +} + + +void FT_TestReplica_i::store(long counter) +{ + FILE * f = ACE_OS::fopen("Persistent.dat", "w"); + if(f != 0) + { + unsigned char buffer[sizeof(long)]; + storeLong(buffer, 0, counter); + ACE_OS::fwrite(buffer, 1, sizeof(long), f); + ACE_OS::fclose(f); + if (this->verbose_) + { + std::cout << name_.c_str() << '@' << this->factory_->location() << '#' << this->factory_id_ << ": " << counter << std::endl; + } + } +} + +long FT_TestReplica_i::load () +{ + long counter = 0; + FILE * f = ACE_OS::fopen("Persistent.dat","r"); + if(f != 0) + { + unsigned char buffer[sizeof(long)]; + ACE_OS::fread(buffer, 1, sizeof(long), f); + ACE_OS::fclose(f); + counter = loadLong<unsigned char *>(buffer, 0); + } + return counter; +} + +/////////////////////////////////// +// Template instantiation for +// competence-challenged compilers. + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + template void storeLong <> (::FT::State_var & state, size_t offset, long value); + template long loadLong <> (const ::FT::State_var & state, size_t offset); + + template void storeLong <> (unsigned char * & state, size_t offset, long value); + template long loadLong <> (const unsigned char * & state, size_t offset); + +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +# pragma instantiate void storeLong(::FT::State_var & state, size_t offset, long value) +# pragma long loadLong(const ::FT::State_var & state, size_t offset) + +# pragma instantiate void storeLong(unsigned char * & state, size_t offset, long value) +# pragma long loadLong(const unsigned char * & state, size_t offset) + +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/tests/FT_App/FT_TestReplica_i.h b/TAO/orbsvcs/tests/FT_App/FT_TestReplica_i.h new file mode 100644 index 00000000000..2bbc53064b1 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/FT_TestReplica_i.h @@ -0,0 +1,217 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file FT_TestReplica_i.h + * + * $Id$ + * + * This file declares an implementation of CORBA interface TestReplica. + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= +// +#ifndef FT_TESTREPLICA_I_H_ +#define FT_TESTREPLICA_I_H_ +#include /**/ <ace/pre.h> + +#include <ace/ACE.h> +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "FT_TestReplicaS.h" + +//////////////////// +// Forward Reference +class FT_ReplicaFactory_i; + +/** + * Implement the TestReplica IDL interface. + * + * Persistent storage simulated by storing the counter + * in Persistent.dat. + */ +class FT_TestReplica_i : public virtual POA_FT_TEST::TestReplica +{ +public: + FT_TestReplica_i (FT_ReplicaFactory_i * factory, const char * name, unsigned long factory_id); + virtual ~FT_TestReplica_i (); + + /** + * parse command line arguments. + * remove any that are recognized, adjusting argc accordingly. + * @param argc classic C argc + * @param argv classic C argv + * @return 0 if ok, otherwise process exit code. + */ + int parse_args (int argc, char *argv[]); + + /** + * provide information to appear in a "usage" display. + * caller will display: + * usage: [program] <usageMessage()> [other usage] + * @returns c-style string containing "bare" usage options. + */ + const char * usage_options(); + + /** + * Initialize this object. + * @param orbManager our ORB -- we keep var to it. + * @return zero for success; nonzero is process return code for failure. + */ + int init (CORBA::ORB_var & orb ACE_ENV_ARG_DECL); + + /** + * Prepare to exit. + * @return zero for success; nonzero is process return code for failure. + */ + int fini (ACE_ENV_SINGLE_ARG_DECL); + + /** + * idle time activity. + * @param result [out] status code to return from process + * @returns 0 to continue; nonzero to quit + */ + int idle(int &result); + + void request_quit(); + + unsigned long factory_id()const; + + static const char * repository_id(); + + ::FT_TEST::TestReplica_ptr object_reference(); + + PortableServer::ObjectId object_id()const; + + ////////////////////////////////////////// + // Override CORBA servant virtual methods + virtual PortableServer::POA_ptr _default_POA (ACE_ENV_SINGLE_ARG_DECL); + + virtual void FT_TestReplica_i::_remove_ref (ACE_ENV_SINGLE_ARG_DECL); + +private: + /////////////////////////// + // override Replica methods + virtual void set (CORBA::Long value + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC (( CORBA::SystemException)); + + virtual CORBA::Long increment (CORBA::Long delta + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual CORBA::Long get (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual CORBA::Long counter (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void counter (CORBA::Long counter + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void die (FT_TEST::TestReplica::Bane when + ACE_ENV_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void shutdown (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /////////////////////////// + // override PullMonitorable + + virtual CORBA::Boolean is_alive (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + /////////////////////////// + // override Updatable + + virtual ::FT::State * get_update () + ACE_THROW_SPEC ((CORBA::SystemException, FT::NoUpdateAvailable)); + + virtual void set_update (const FT::State & s) + ACE_THROW_SPEC ((CORBA::SystemException, FT::InvalidUpdate)); + + virtual ::FT::State * get_state () + ACE_THROW_SPEC ((CORBA::SystemException, FT::NoStateAvailable)); + + virtual void set_state (const FT::State & s) + ACE_THROW_SPEC ((CORBA::SystemException, FT::InvalidState)); + + //////////////// + // Implement TAO_UpdateObjectGroup + + virtual void tao_update_object_group ( + const char * iogr, + PortableGroup::ObjectGroupRefVersion version, + CORBA::Boolean is_primary + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)); + + ///////////////// + // implementation +private: + /** + * Load the persistent data. + * returns the data loaded. + */ + long load(); + /** + * Store the persistent data. + * @param the data to be stored. + */ + void store(long value); + + void suicide(const char *); + + /////////////// + // data members +private: + /** + * a bane code for when we should die. + */ + FT_TEST::TestReplica::Bane death_pending_; + + /** + * verbosity level, settable by client. + */ + int verbose_; + + /** + * who am I? + */ + ACE_CString name_; + + /** + * The ID number assigned by the factory + */ + unsigned long factory_id_; + + /** + * the factory that created thsi replica + */ + FT_ReplicaFactory_i * factory_; + + /** + * The orb + */ + CORBA::ORB_var orb_; + + /** + * The POA used to activate this object. + */ + PortableServer::POA_var poa_; + + /** + * The CORBA object id assigned to this object. + */ + PortableServer::ObjectId_var object_id_; + +}; + +#include /**/ "ace/post.h" + +#endif /* FT_TESTREPLICA_I_H_ */ diff --git a/TAO/orbsvcs/tests/FT_App/README b/TAO/orbsvcs/tests/FT_App/README new file mode 100644 index 00000000000..33b790044b6 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/README @@ -0,0 +1,88 @@ +$Id$ + +This is a simple application intended to test Fault Tolerant Corba. + +The server implements GenericFactory as a factory that creates TestReplicas. +TestReplicas are defined in the IDL in FT_TestReplica.idl. + +FT_TEST::TestReplica inherits from PullMonitorable and Checkpointable +to provide access needed by FT Corba's FaultDetector and Orb. + +An FT_TEST::TestReplica contains a long counter. Methods are defined +to set, increment, and get the value of the counter. The counter +is also exposed as an attribute named counter. (i.e. set(x) is +exactly equivalent to counter(x), and get() is exactly equivalent +to counter()) + +In addition there is a method named die that lets the client request +a server "failure" at a variety of interesting times. See the "die" +command to find out when death can be scheduled. + +The client provides a command interface to operate on the server. +Tests may be run manually by typing commands, or may be automated by +reading the commands from a file. + +Commands consist of a single character followed by an optional number +(with no space between). For example: =10 sets the value of the counter +to 10. +5 increments the counter by 5 (thereby setting the value to 15). + +The '?' commmand lists the possible commands and their options. + +Additional programs: + ft_notifier is a stub implementation of a fault notifier for testing fault detectors. + ft_analyzer is a stub implementation of a fault analyzer for testing the fault notifier + ft_registry is an implementation of FactoryRegistry for testing GenericFactories. + +To run: +Start one or more FT_Replicas. Use a -o <filename> to tell the replica +where to write its ior.. + +Start the FT_Client with -f file1<,filen>... (i.e. a comma separated list +of replica IOR files. To read commands from a file, use -c <command file> + +The counter is persistent and will survive server failures. It's +stored in a file named persistent.dat. + +Replicas of the server may be run in separate directories to simulate +replicated stateful objects (each replica has its own distinct state), or +multiple replicas can be run in the same directory to simulate a server +with a shared state or one that executes real-world unsafe-to-repeat +action (i.e. "fire the retro rockets" or "expose the patient to +theraputic radiation.") + +Unit Tests based on this application: + + run_test_basic.pl + tests ft_client and ft_replica, thereby answering the question, + "who will test the tester?". + + run_test_detector.pl + uses ft_client, ft_replica, and ft_notifier (a "stub" fault notifier) + to test the Fault_Detector (from orbsvcs) + + run_test_notifier.pl + uses ft_client, ft_replica, Fault_Detector and ft_analyzer (a "stub" fault analyzer) + to test the Fault_Notifier (from orbsvcs) + + run_test_fault_consumer.pl + uses ft_client, ft_replica, Fault_Detector, Fault_Notifier to test + ft_fault_consumer (the implementation of a fault consumer) + + run_test_registry.pl + uses ft_client, ft_replica, and ft_creator to test ft_registry + (i.e. to test the implementation of PortableServer::FactoryRegistry) + + run_test_rmregistry.pl + uses ft_client, ft_replica, and ft_creator to test the FactoryRegistery + implementation in the ReplicationManager. + + + run_test_rmnotifier.pl + uses ft_client, ft_replica, Fault_Detector to test the connection between + the Fault_Notifier and the ReplicationManager + + demo.pl + tests the entire FT system. + + +See the internal documentation of the .pl files for more details. diff --git a/TAO/orbsvcs/tests/FT_App/ReplicationManagerFaultConsumerAdapter.cpp b/TAO/orbsvcs/tests/FT_App/ReplicationManagerFaultConsumerAdapter.cpp new file mode 100755 index 00000000000..e8a4cf3c9a3 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/ReplicationManagerFaultConsumerAdapter.cpp @@ -0,0 +1,383 @@ +// -*- C++ -*- +// +// $Id$ + +#include "ReplicationManagerFaultConsumerAdapter.h" +#include "ace/Get_Opt.h" +#include "orbsvcs/orbsvcs/PortableGroup/PG_Properties_Encoder.h" +#include "orbsvcs/FT_ReplicationManager/FT_DefaultFaultAnalyzer.h" +#include <iostream> +#include <fstream> + +ReplicationManagerFaultConsumerAdapter::ReplicationManagerFaultConsumerAdapter() + : orb_(CORBA::ORB::_nil()) + , quit_(0) + , readyFile_(0) + , detector_ior_(0) + , factory_(FT::FaultDetectorFactory::_nil()) + , notifier_ior_(0) + , notifier_(FT::FaultNotifier::_nil()) + , p_fault_consumer_(0) + , consumer_servant_(0) +{ +} + + +ReplicationManagerFaultConsumerAdapter::~ReplicationManagerFaultConsumerAdapter() +{ +} + +size_t ReplicationManagerFaultConsumerAdapter::notifications () const +{ + // Delegate to the FT_FaultConsumer. + return this->p_fault_consumer_->notifications (); +} + + +int ReplicationManagerFaultConsumerAdapter::parse_args (int argc, char * argv[]) +{ + int optionError = 0; + ACE_Get_Opt get_opts (argc, argv, "o:r:d:n:"); + int c; + while ((c = get_opts ()) != -1) + { + switch (c) + { + case 'r': + { + this->replica_iors_.push_back (get_opts.opt_arg ()); + break; + } + case 'd': + { + this->detector_ior_ = get_opts.opt_arg (); + break; + } + case 'n': + { + this->notifier_ior_ = get_opts.opt_arg (); + break; + } + case 'o': + { + this->readyFile_ = get_opts.opt_arg (); + break; + } + + default: + // fall thru + case '?': + { + break; + } + } + } + + if(! optionError) + { + if (0 == this->replica_iors_.size()) + { + ACE_ERROR ((LM_ERROR, + "-r option is required.\n" + )); + optionError = -1; + } + if (0 == this->detector_ior_) + { + ACE_ERROR ((LM_ERROR, + "-d option is required.\n" + )); + optionError = -1; + } + } + + if(optionError) + { + ACE_ERROR ((LM_ERROR, + "usage: %s" + " -r <replica.ior[ -r replica.ior]>" + " -d <detector.ior>" + " -o <this.ior>" + " -n <nameService name>" + "\n", + argv [0] + )); + } + return optionError; +} + +/** + * Register this object. + */ +int ReplicationManagerFaultConsumerAdapter::init ( + CORBA::ORB_ptr orb + ACE_ENV_ARG_DECL) +{ + ACE_DEBUG (( + LM_DEBUG, + ACE_TEXT ("Entered ReplicationManagerFaultConsumerAdapter::init.\n") + )); + + int result = 0; + this->orb_ = CORBA::ORB::_duplicate (orb); + + ////////////////////////////////////////// + // resolve reference to detector factory + ACE_DEBUG (( + LM_DEBUG, + ACE_TEXT ("ReplicationManagerFaultConsumerAdapter::init: ") + ACE_TEXT ("Getting ready to read iorDetectorFile.\n") + )); + + CORBA::Object_var detector_obj = this->orb_->string_to_object ( + this->detector_ior_ ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + this->factory_ = ::FT::FaultDetectorFactory::_narrow ( + detector_obj.in() ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + if (CORBA::is_nil (this->factory_.in())) + { + ACE_ERROR_RETURN (( + LM_ERROR, + ACE_TEXT ("ReplicationManagerFaultConsumerAdapter::init: ") + ACE_TEXT ("FaultDetectorFactory IOR is nil: %s\n"), + this->detector_ior_), + -1); + } + + ////////////////////////////////////////// + // resolve references to notifier + ACE_DEBUG (( + LM_DEBUG, + ACE_TEXT ("ReplicationManagerFaultConsumerAdapter::init: ") + ACE_TEXT ("Getting ready to read Notifier IOR file.\n") + )); + + CORBA::Object_var notifier_ior = this->orb_->string_to_object ( + this->notifier_ior_ ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + this->notifier_ = ::FT::FaultNotifier::_narrow ( + notifier_ior.in() ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + if (CORBA::is_nil (this->notifier_.in())) + { + ACE_ERROR_RETURN (( + LM_ERROR, + ACE_TEXT ("ReplicationManagerFaultConsumerAdapter::init: ") + ACE_TEXT ("FaultNotifier IOR is nil: %s\n"), + this->notifier_ior_), + -1); + } + + // Create the real FaultConsumer. + // + // Note: We have to hang onto the servant class pointer so we can + // invoke member functions on it, but we also give ownership of it + // to a PortableServer::ServantBase_var. + ACE_DEBUG (( + LM_DEBUG, + ACE_TEXT ("ReplicationManagerFaultConsumerAdapter::init: ") + ACE_TEXT ("Getting ready to create the real FaultConsumer.\n") + )); + + ACE_NEW_RETURN (this->p_fault_consumer_, TAO::FT_FaultConsumer (), -1); + if (this->p_fault_consumer_ != 0) + { + this->consumer_servant_ = this->p_fault_consumer_; + } + + ////////////////////////// + // Get ready to initialize the consumer. We need to provide it + // with the following: + // - The POA in which it is to be activated. + // - FT::FaultNotifier IOR. + // - FT::ReplicationManager IOR (fake it for now). + + // Get the RootPOA from the ORB. + CORBA::Object_var poa_obj = this->orb_->resolve_initial_references ( + "RootPOA" ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + PortableServer::POA_var poa = PortableServer::POA::_narrow ( + poa_obj.in() ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + // Create a fault analyzer. + TAO::FT_FaultAnalyzer * analyzer = 0; + ACE_NEW_RETURN (analyzer, TAO::FT_DefaultFaultAnalyzer (), -1); + + // Initialize the FaultConsumer. + // It will activate itself in the POA we pass it and connect to the + // Fault Notifier we pass it. + ACE_DEBUG (( + LM_DEBUG, + ACE_TEXT ("ReplicationManagerFaultConsumerAdapter::init: ") + ACE_TEXT ("Getting ready to initialize the real FaultConsumer.\n") + )); + + result = this->p_fault_consumer_->init ( + poa.in(), + this->notifier_.in(), + analyzer + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + if (result != 0) + { + ACE_ERROR_RETURN (( + LM_ERROR, + ACE_TEXT ("ReplicationManagerFaultConsumerAdapter::init: ") + ACE_TEXT ("Unable to initialize the real FaultConsumer.\n")), + result); + } + + this->identity_ = "ReplicationManagerFaultConsumerAdapter"; + + // Activate the RootPOA. + PortableServer::POAManager_var poa_manager = + poa->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + ///////////////////////// + // Set up fault detectors + if (result == 0) + { + //////////////////////////////////// + // resolve references to replicas + // create a fault detector for each replica + size_t replicaCount = this->replica_iors_.size(); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Number of replicas being monitored: (%u)\n"), + ACE_static_cast (unsigned int, replicaCount) + )); + for (size_t nRep = 0; result == 0 && nRep < replicaCount; ++nRep) + { + const char * iorName = this->replica_iors_[nRep]; + CORBA::Object_var replica_obj = this->orb_->string_to_object ( + iorName ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + FT::PullMonitorable_var replica = FT::PullMonitorable::_narrow ( + replica_obj.in() ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + if (CORBA::is_nil(replica.in())) + { + ACE_ERROR_RETURN (( + LM_ERROR, + ACE_TEXT ("ReplicationManagerFaultConsumerAdapter::init: ") + ACE_TEXT ("Can't resolve Replica IOR: %s\n"), + iorName), + -1); + } + else + { + this->replicas_.push_back(replica); + + CORBA::String_var type_id = CORBA::string_dup("FaultDetector"); + + TAO_PG::Properties_Encoder encoder; + + PortableGroup::Value value; + value <<= notifier_.in (); + encoder.add(::FT::FT_NOTIFIER, value); + + value <<= replica.in (); + encoder.add(::FT::FT_MONITORABLE, value); + + FT::FTDomainId domain_id = 0; + value <<= domain_id; + encoder.add(::FT::FT_DOMAIN_ID, value); + + PortableGroup::Location object_location; + object_location.length(2); + object_location[0].id = CORBA::string_dup("test"); + object_location[1].id = CORBA::string_dup("Location_A"); + value <<= object_location; + encoder.add(::FT::FT_LOCATION, value); + + PortableGroup::TypeId_var object_type = CORBA::string_dup ( + "IDL:org.omg/CosNaming/NamingContextExt:1.0"); + value <<= object_type; + encoder.add(::FT::FT_TYPE_ID, value); + + PortableGroup::ObjectGroupId group_id = + ACE_static_cast (PortableGroup::ObjectGroupId, 6191982); + value <<= group_id; + encoder.add(::FT::FT_GROUP_ID, value); + + // allocate and populate the criteria + PortableGroup::Criteria_var criteria; + ACE_NEW_NORETURN (criteria, + PortableGroup::Criteria); + if (criteria.ptr() == 0) + { + ACE_ERROR_RETURN (( + LM_ERROR, + ACE_TEXT ("ReplicationManagerFaultConsumerAdapter::init: ") + ACE_TEXT ("Error cannot allocate criteria.\n")), + -1); + } + else + { + encoder.encode(criteria); + PortableGroup::GenericFactory::FactoryCreationId_var factory_creation_id; + + this->factory_->create_object ( + type_id.in(), + criteria.in(), + factory_creation_id + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + } + } + } + + // Signal that we are ready to go. + if (result == 0 && this->readyFile_ != 0) + { + std::ofstream ready (this->readyFile_, ios::out); + ready << "ready" << std::endl; + ready.close(); + } + } + + return result; +} + +/** + * Return a string to identify this object for logging/console message purposes. + */ +const char * ReplicationManagerFaultConsumerAdapter::identity () const +{ + return this->identity_.c_str(); +} + +/** + * Clean house for process shut down. + */ +int ReplicationManagerFaultConsumerAdapter::fini (ACE_ENV_SINGLE_ARG_DECL) +{ + // Delegate to the FT_FaultConsumer. + return this->p_fault_consumer_->fini (ACE_ENV_SINGLE_ARG_PARAMETER); +} + + +int ReplicationManagerFaultConsumerAdapter::idle(int & result) +{ + ACE_UNUSED_ARG(result); + int quit = 0; + + if (this->replicas_.size() == this->p_fault_consumer_->notifications()) + { + quit = 1; + } + return quit; +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + template class ACE_Vector < const char * >; + template class ACE_Vector < FT::PullMonitorable_var > ; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +# pragma instantiate ACE_Vector < const char * > +# pragma instantiate ACE_Vector < FT::PullMonitorable_var > +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ + diff --git a/TAO/orbsvcs/tests/FT_App/ReplicationManagerFaultConsumerAdapter.h b/TAO/orbsvcs/tests/FT_App/ReplicationManagerFaultConsumerAdapter.h new file mode 100755 index 00000000000..f0301274ce0 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/ReplicationManagerFaultConsumerAdapter.h @@ -0,0 +1,150 @@ +// -*- C++ -*- +// +// $Id$ +#ifndef REPLICATION_MANAGER_FAULT_CONSUMER_ADAPTER_H +#define REPLICATION_MANAGER_FAULT_CONSUMER_ADAPTER_H +#include /**/ <ace/pre.h> +#include <ace/ACE.h> +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include <orbsvcs/FT_ReplicationManager/FT_FaultConsumer.h> +#include <orbsvcs/FT_NotifierC.h> +#include <orbsvcs/FT_FaultDetectorFactoryC.h> +#include <ace/Vector_T.h> + +///////////////////// +// Class declarations + +/** + * An adapter to the Replication Manager's fault consumer + * for use in unit testing Fault Notifier and Fault Consumer. + */ +class ReplicationManagerFaultConsumerAdapter +{ +public: + /** + * Default constructor. + */ + ReplicationManagerFaultConsumerAdapter (); + + /** + * virtual destructor. + */ + virtual ~ReplicationManagerFaultConsumerAdapter (); + + /** + * Parse command line arguments. + */ + int parse_args (int argc, char * argv[]); + + /** + * Initialize this object + */ + int init (CORBA::ORB_ptr orb ACE_ENV_ARG_DECL_WITH_DEFAULTS); + + /** + * Return a string to identify this object for logging/console message purposes. + */ + const char * identity () const; + + /** + * idle time activity. + * @param result [out] status code to return from process + * @returns 0 to continue; nonzero to quit + */ + int idle(int &result); + + /** + * Clean house for process shut down. + */ + int fini (ACE_ENV_SINGLE_ARG_DECL); + + + size_t notifications() const; + + ///////////////// + // Implementation +private: + + //////////////////// + // Forbidden methods +private: + ReplicationManagerFaultConsumerAdapter ( + const ReplicationManagerFaultConsumerAdapter & rhs); + ReplicationManagerFaultConsumerAdapter & operator = + (const ReplicationManagerFaultConsumerAdapter & rhs); + + ///////////////////////// + // Implementation methods +private: + + /////////////// + // Data Members +private: + /** + * The orb + */ + CORBA::ORB_var orb_; + + /** + * A human-readable string to distinguish this from other FaultConsumers. + */ + ACE_CString identity_; + + /** + * boolean: request quit + */ + int quit_; + + /** + * a file to write to to signal "ready" + */ + const char * readyFile_; + + /** + * Detecor's IOR + */ + const char * detector_ior_; + + /** + * The FaultDetectorFactory object reference. + */ + ::FT::FaultDetectorFactory_var factory_; + + /** + * A collection of replica IORs + */ + ACE_Vector < const char * > replica_iors_; + + /** + * A collection of replica references. + */ + ACE_Vector < FT::PullMonitorable_var > replicas_; + + /** + * A file from which the notifier's IOR should be read. + */ + const char * notifier_ior_; + + /** + * the fault notifier + */ + ::FT::FaultNotifier_var notifier_; + + /** + * consumer id assigned by the notifier + */ + ::FT::FaultNotifier::ConsumerId consumerId_; + + /** + * the real fault consumer + */ + TAO::FT_FaultConsumer* p_fault_consumer_; + PortableServer::ServantBase_var consumer_servant_; + +}; +#include /**/ <ace/post.h> + +#endif /* REPLICATION_MANAGER_FAULT_CONSUMER_ADAPTER_H */ diff --git a/TAO/orbsvcs/tests/FT_App/StubBatchConsumer.cpp b/TAO/orbsvcs/tests/FT_App/StubBatchConsumer.cpp new file mode 100644 index 00000000000..ae54dfa1af3 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/StubBatchConsumer.cpp @@ -0,0 +1,180 @@ +// -*- C++ -*- +// +// $Id$ + +#include "StubBatchConsumer.h" +#include <ace/Get_Opt.h> +#include <tao/PortableServer/ORB_Manager.h> +#include <orbsvcs/orbsvcs/PortableGroup/PG_Properties_Encoder.h> + +StubBatchConsumer::StubBatchConsumer () + : quit_(0) +{ +} + + +StubBatchConsumer::~StubBatchConsumer () +{ +} + + +int StubBatchConsumer::parse_args (int argc, char * argv[]) +{ + ACE_UNUSED_ARG (argc); + ACE_UNUSED_ARG (argv); + int optionError = 0; + // No options for now + return optionError; +} + + +::PortableServer::POA_ptr StubBatchConsumer::_default_POA (ACE_ENV_SINGLE_ARG_DECL) +{ + return ::PortableServer::POA::_duplicate(this->poa_.in () ACE_ENV_ARG_PARAMETER); +} + +PortableServer::ObjectId StubBatchConsumer::objectId()const +{ + return this->object_id_.in(); +} + + +/** + * register this object + */ +int StubBatchConsumer::init (CORBA::ORB_ptr orb, ::FT::FaultNotifier_var & notifier ACE_ENV_ARG_DECL) +{ + int result = 0; + this->orb_ = CORBA::ORB::_duplicate (orb); + this->notifier_ = notifier; + this->identity_ = "StubBatchConsumer"; + + + // Use the ROOT POA for now + CORBA::Object_var poa_object = + this->orb_->resolve_initial_references (TAO_OBJID_ROOTPOA + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (CORBA::is_nil (poa_object.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT (" (%P|%t) Unable to initialize the POA.\n")), + -1); + + // Get the POA . + this->poa_ = PortableServer::POA::_narrow (poa_object.in () + ACE_ENV_ARG_PARAMETER); + + ACE_CHECK_RETURN (-1); + + if (CORBA::is_nil(this->poa_.in ())) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT (" (%P|%t) Unable to narrow the POA.\n")), + -1); + } + + PortableServer::POAManager_var poa_manager = + this->poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + // Register with the POA. + + this->object_id_ = this->poa_->activate_object (this ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + // find my identity as an object + + CORBA::Object_var this_obj = + this->poa_->id_to_reference (object_id_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + CosNotifyFilter::Filter_var filter = CosNotifyFilter::Filter::_nil(); + + this->consumer_id_ = notifier->connect_sequence_fault_consumer( + CosNotifyComm::SequencePushConsumer::_narrow(this_obj.in ()), + filter.in ()); + + return result; +} + +/** + * Return a string to identify this object for logging/console message purposes. + */ +const char * StubBatchConsumer::identity () const +{ + return this->identity_.c_str(); +} + +/** + * Clean house for process shut down. + */ +void StubBatchConsumer::fini (ACE_ENV_SINGLE_ARG_DECL) +{ + this->notifier_->disconnect_consumer(this->consumer_id_ ACE_ENV_ARG_PARAMETER); +} + + +int StubBatchConsumer::idle(int & result) +{ + ACE_UNUSED_ARG(result); + return this->quit_; +} + +//////////////// +// CORBA methods + + +//virtual +void StubBatchConsumer::push_structured_events ( + const CosNotification::EventBatch & notifications + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + , CosEventComm::Disconnected + )) +{ + ACE_UNUSED_ARG (notifications); + //@@ sequence of structured event handling not written yet +} + +void StubBatchConsumer::offer_change ( + const CosNotification::EventTypeSeq & added, + const CosNotification::EventTypeSeq & removed + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException, CosNotifyComm::InvalidEventType)) +{ + ACE_UNUSED_ARG (added); + ACE_UNUSED_ARG (removed); + ACE_ERROR ((LM_ERROR, + "StubBatchConsumer: offer_change call ignored.\n" + )); + // @@ not implemented (not likely to be needed) +} + +//virtual +void StubBatchConsumer::disconnect_sequence_push_consumer ( + ACE_ENV_SINGLE_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + )) +{ + ACE_ERROR ((LM_ERROR, + "StubBatchConsumer:disconnect_sequence_push_consumer interpreted as quit request.\n" + )); + this->quit_ = 1; +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +// template instantiate ACE_Vector < const char * >; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +//# pragma instantiate ACE_Vector < const char * > +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ + diff --git a/TAO/orbsvcs/tests/FT_App/StubBatchConsumer.h b/TAO/orbsvcs/tests/FT_App/StubBatchConsumer.h new file mode 100644 index 00000000000..d81d9fa061c --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/StubBatchConsumer.h @@ -0,0 +1,149 @@ +// -*- C++ -*- +// +// $Id$ +#ifndef STUBBATCHCONSUMER_H +#define STUBBATCHCONSUMER_H +#include /**/ <ace/pre.h> +#include <ace/ACE.h> + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include <orbsvcs/CosNotifyChannelAdminS.h> +#include <orbsvcs/FT_NotifierC.h> + +////////////////////// +// Forward references + +///////////////////// +// Class declarations + +/** + * A stub fault consumer for use in unit testing Fault Notifier. + */ +class StubBatchConsumer + : public virtual POA_CosNotifyComm::SequencePushConsumer +{ +public: + /** + * Default constructor. + */ + StubBatchConsumer (); + + /** + * virtual destructor. + */ + virtual ~StubBatchConsumer (); + + ::PortableServer::POA_ptr _default_POA (ACE_ENV_SINGLE_ARG_DECL); + ::PortableServer::ObjectId objectId()const; + + /** + * Parse command line arguments. + */ + int parse_args (int argc, char * argv[]); + + /** + * Publish this objects IOR. + */ + int init (CORBA::ORB_ptr orbManager, ::FT::FaultNotifier_var & notifier ACE_ENV_ARG_DECL); + + /** + * Return a string to identify this object for logging/console message purposes. + */ + const char * identity () const; + + /** + * idle time activity. + * @param result [out] status code to return from process + * @returns 0 to continue; nonzero to quit + */ + int idle(int &result); + + /** + * Clean house for process shut down. + */ + void fini (ACE_ENV_SINGLE_ARG_DECL); + + +public: + + //////////////// + // CORBA methods + + virtual void push_structured_events ( + const CosNotification::EventBatch & notifications + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ) + ACE_THROW_SPEC (( + CORBA::SystemException + , CosEventComm::Disconnected + )); + + virtual void disconnect_sequence_push_consumer ( + ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS + ) + ACE_THROW_SPEC (( + CORBA::SystemException + )); + + virtual void offer_change ( + const CosNotification::EventTypeSeq & added, + const CosNotification::EventTypeSeq & removed + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ) + throw (CORBA::SystemException, CosNotifyComm::InvalidEventType); + + //////////////////// + // Forbidden methods +private: + StubBatchConsumer (const StubBatchConsumer & rhs); + StubBatchConsumer & operator = (const StubBatchConsumer & rhs); + + ///////////////////////// + // Implementation methods +private: + + /////////////// + // Data Members +private: + /** + * The orb + */ + CORBA::ORB_var orb_; + + /** + * The POA used to activate this object. + */ + PortableServer::POA_var poa_; + + /** + * The CORBA object id assigned to this object. + */ + PortableServer::ObjectId_var object_id_; + + /** + * A human-readable string to distinguish this from other FaultConsumers. + */ + ACE_CString identity_; + + /** + * boolean: request quit + */ + int quit_; + + /** + * the notifier + */ + ::FT::FaultNotifier_var notifier_; + + /** + * consumer id assigned by the notifier + */ + ::FT::FaultNotifier::ConsumerId consumer_id_; +}; + +#include /**/ <ace/post.h> + +#endif /* STUBBATCHCONSUMER_H */ diff --git a/TAO/orbsvcs/tests/FT_App/StubFaultAnalyzer.cpp b/TAO/orbsvcs/tests/FT_App/StubFaultAnalyzer.cpp new file mode 100644 index 00000000000..ab4d67fbe2b --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/StubFaultAnalyzer.cpp @@ -0,0 +1,275 @@ +// -*- C++ -*- +// +// $Id$ + +#include "StubFaultAnalyzer.h" +#include <ace/Get_Opt.h> +#include <tao/PortableServer/ORB_Manager.h> +#include <orbsvcs/PortableGroup/PG_Properties_Encoder.h> +#include <iostream> +#include <fstream> + +StubFaultAnalyzer::StubFaultAnalyzer () + : readyFile_(0) + , detector_ior_(0) + , notifier_ior_(0) +{ +} + + +StubFaultAnalyzer::~StubFaultAnalyzer () +{ +} + + +int StubFaultAnalyzer::parse_args (int argc, char * argv[]) +{ + int optionError = 0; + ACE_Get_Opt get_opts (argc, argv, "o:r:d:n:"); + int c; + while ((c = get_opts ()) != -1) + { + switch (c) + { + case 'r': + { + this->replicaIORs.push_back (get_opts.opt_arg ()); + break; + } + case 'd': + { + this->detector_ior_ = get_opts.opt_arg (); + break; + } + case 'n': + { + this->notifier_ior_ = get_opts.opt_arg (); + break; + } + case 'o': + { + this->readyFile_ = get_opts.opt_arg (); + break; + } + + default: + // fall thru + case '?': + { + break; + } + } + } + + if(! optionError) + { + if (0 == replicaIORs.size()) + { + ACE_ERROR ((LM_ERROR, + "at least one -r option is required.\n" + )); + optionError = -1; + } + + if (0 == this->detector_ior_) + { + ACE_ERROR ((LM_ERROR, + "-d option is required.\n" + )); + optionError = -1; + } + if (0 == this->notifier_ior_) + { + ACE_ERROR ((LM_ERROR, + "-n option is required.\n" + )); + optionError = -1; + } + } + + if(optionError) + { + ACE_ERROR ((LM_ERROR, + "usage: %s" + " -r <replica.ior[,replica.ior]>" + " -d <detector.ior>" + " -o <ready.file>" // note: not an IOR file. just an "I'm alive" indicator." + " -n <notifier.ior>" + "\n", + argv [0] + )); + } + return optionError; +} + +/** + * Register this object as necessary + */ +int StubFaultAnalyzer::init (CORBA::ORB_ptr orb ACE_ENV_ARG_DECL) +{ + int result = 0; + this->orb_ = CORBA::ORB::_duplicate (orb); + ////////////////////////////////////////// + // resolve reference to detector factory + CORBA::Object_var detector_obj = this->orb_->string_to_object(this->detector_ior_); + this->factory_ = ::FT::FaultDetectorFactory::_narrow(detector_obj.in ()); + if (CORBA::is_nil(this->factory_.in ())) + { + std::cerr << "Can't resolve Detector Factory IOR " << this->detector_ior_ << std::endl; + result = -1; + } + + ////////////////////////////////////////// + // resolve references to notifier + CORBA::Object_var not_obj = this->orb_->string_to_object(this->notifier_ior_); + this->notifier_ = ::FT::FaultNotifier::_narrow(not_obj.in ()); + if (CORBA::is_nil(this->notifier_.in ())) + { + std::cerr << "Can't resolve Notifier IOR " << this->notifier_ior_ << std::endl; + result = -1; + } + + + ////////////////////////////////// + // register fault consumers + if (result == 0) + { + result = this->faultConsumer_.init(orb, this->notifier_); + } + + if (result == 0) + { + result = this->batchConsumer_.init(orb, this->notifier_); + } + + ///////////////////////// + // Set up fault detectors + if (result == 0) + { + //////////////////////////////////// + // resolve references to replicas + // create a fault detector for each replica + size_t replicaCount = this->replicaIORs.size(); + for(size_t nRep = 0; result == 0 && nRep < replicaCount; ++nRep) + { + const char * iorName = this->replicaIORs[nRep]; + CORBA::Object_var rep_obj = this->orb_->string_to_object(iorName); + FT::PullMonitorable_var replica = FT::PullMonitorable::_narrow(rep_obj.in ()); + if (CORBA::is_nil(replica.in ())) + { + std::cerr << "Can't resolve Replica IOR " << iorName << std::endl; + result = -1; + } + else + { + this->replicas_.push_back(replica); + + CORBA::String_var type_id = CORBA::string_dup("FaultDetector"); + + TAO_PG::Properties_Encoder encoder; + + PortableGroup::Value value; + value <<= this->notifier_.in (); + encoder.add(::FT::FT_NOTIFIER, value); + + value <<= replica.in (); + encoder.add(::FT::FT_MONITORABLE, value); + + FT::FTDomainId domain_id = 0; + value <<= domain_id; + encoder.add(::FT::FT_DOMAIN_ID, value); + + PortableGroup::Location object_location; + object_location.length(1); + object_location[0].id = CORBA::string_dup("Test location"); + value <<= object_location; + encoder.add(::FT::FT_LOCATION, value); + + PortableGroup::TypeId object_type = CORBA::string_dup("dummy_type"); + value <<= object_type; + encoder.add(::FT::FT_TYPE_ID, value); + + FT::ObjectGroupId group_id = 0; + value <<= group_id; + encoder.add(::FT::FT_GROUP_ID, value); + + // allocate and populate the criteria + PortableGroup::Criteria_var criteria; + ACE_NEW_NORETURN (criteria, + PortableGroup::Criteria); + if (criteria.ptr() == 0) + { + ACE_ERROR((LM_ERROR, + "Error cannot allocate criteria.\n" + )); + result = -1; + } + else + { + encoder.encode(criteria); + PortableGroup::GenericFactory::FactoryCreationId_var factory_creation_id; + + ACE_DEBUG((LM_DEBUG, + "Call create_object with type: %s\n", type_id.in() + )); + this->factory_->create_object ( + type_id.in(), + criteria.in(), + factory_creation_id + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + } + } + } + + if (result == 0 && this->readyFile_ != 0) + { + std::ofstream ready(this->readyFile_, ios::out); + ready << "ready" << std::endl; + ready.close(); + } + } + return result; +} + + +/** + * Return a string to identify this object for logging/console message purposes. + */ +const char * StubFaultAnalyzer::identity () const +{ + return this->identity_.c_str(); +} + +/** + * Clean house for process shut down. + */ +int StubFaultAnalyzer::fini (ACE_ENV_SINGLE_ARG_DECL) +{ + this->faultConsumer_.fini(ACE_ENV_SINGLE_ARG_PARAMETER); + this->batchConsumer_.fini(ACE_ENV_SINGLE_ARG_PARAMETER); + return 0; +} + + +int StubFaultAnalyzer::idle(int & result) +{ + ACE_UNUSED_ARG(result); + int quit = 0; + + if (this->replicas_.size() == this->faultConsumer_.notifications()) + { + quit = 1; + } + return quit; +} + + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + template class ACE_Vector < const char * >; + template class ACE_Vector < FT::PullMonitorable_var > ; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +# pragma instantiate ACE_Vector < const char * > +# pragma instantiate ACE_Vector < FT::PullMonitorable_var > +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ + diff --git a/TAO/orbsvcs/tests/FT_App/StubFaultAnalyzer.h b/TAO/orbsvcs/tests/FT_App/StubFaultAnalyzer.h new file mode 100644 index 00000000000..cbf8eaf6e35 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/StubFaultAnalyzer.h @@ -0,0 +1,132 @@ +// -*- C++ -*- +// +// $Id$ +#ifndef STUBFAULTANALYZER_H +#define STUBFAULTANALYZER_H +#include /**/ <ace/pre.h> +#include <ace/ACE.h> + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "StubFaultConsumer.h" +#include "StubBatchConsumer.h" +#include <orbsvcs/FT_NotifierC.h> +#include <orbsvcs/FT_FaultDetectorFactoryC.h> + +#include "ace/Vector_T.h" + +////////////////////// +// Forward references + +///////////////////// +// Class declarations + +/** + * A stub fault analyzer for use in unit testing. + */ +class StubFaultAnalyzer +{ +public: + /** + * Default constructor. + */ + StubFaultAnalyzer (); + + /** + * destructor. + */ + ~StubFaultAnalyzer (); + + /** + * Parse command line arguments. + */ + int parse_args (int argc, char * argv[]); + + /** + * Initialize this object + */ + int init (CORBA::ORB_ptr orb); + + /** + * Return a string to identify this object for logging/console message purposes. + */ + const char * identity () const; + + /** + * idle time activity. + * @param result [out] status code to return from process + * @returns 0 to continue; nonzero to quit + */ + int idle(int &result); + + /** + * Prepare to exit. + * @return zero for success; nonzero is process return code for failure. + */ + int fini (ACE_ENV_SINGLE_ARG_DECL); + + ///////////////// + // Implementation +private: + int readIORFile(const char * fileName, CORBA::String_var & ior); + + /////////////// + // Data Members +private: + /** + * The orb + */ + CORBA::ORB_var orb_; + + /** + * The POA used to activate this object. + */ + PortableServer::POA_var poa_; + + /** + * The CORBA object id assigned to this object. + */ + PortableServer::ObjectId_var objectId_; + + /** + * A human-readable string to distinguish this from other Notifiers. + */ + ACE_CString identity_; + + /** + * a file to write to to signal "ready" + */ + const char * readyFile_; + + /** + * The detecor's IOR (-d option) + */ + const char * detector_ior_; + + ::FT::FaultDetectorFactory_var factory_; + + /** + * The notifier's IOR (-n option) + */ + const char * notifier_ior_; + + ::FT::FaultNotifier_var notifier_; + + /** + * A collection of files containing replica IORs + */ + ACE_Vector < const char * > replicaIORs; + + ACE_Vector < FT::PullMonitorable_var > replicas_; + + + StubFaultConsumer faultConsumer_; + StubBatchConsumer batchConsumer_; + +}; + +#include /**/ <ace/post.h> + +#endif /* STUBFAULTANALYZER_H */ diff --git a/TAO/orbsvcs/tests/FT_App/StubFaultConsumer.cpp b/TAO/orbsvcs/tests/FT_App/StubFaultConsumer.cpp new file mode 100644 index 00000000000..94d93e97483 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/StubFaultConsumer.cpp @@ -0,0 +1,318 @@ +// -*- C++ -*- +// +// $Id$ + +#include "StubFaultConsumer.h" +#include <ace/Get_Opt.h> +#include <tao/PortableServer/ORB_Manager.h> +#include <orbsvcs/orbsvcs/PortableGroup/PG_Properties_Encoder.h> + +StubFaultConsumer::StubFaultConsumer () + : quit_(0) + , notifications_(0) +{ +} + + +StubFaultConsumer::~StubFaultConsumer () +{ +} + +::PortableServer::POA_ptr StubFaultConsumer::_default_POA (ACE_ENV_SINGLE_ARG_DECL) +{ + return ::PortableServer::POA::_duplicate(this->poa_.in () ACE_ENV_ARG_PARAMETER); +} + +PortableServer::ObjectId StubFaultConsumer::objectId()const +{ + return this->object_id_.in(); +} + +size_t StubFaultConsumer::notifications () const +{ + return this->notifications_; +} + + +int StubFaultConsumer::parse_args (int argc, char * argv[]) +{ + int optionError = 0; +#ifndef NO_ARGS_FOR_NOW + ACE_UNUSED_ARG (argc); + ACE_UNUSED_ARG (argv); +#else // NO_ARGS_FOR_NOW + ACE_Get_Opt get_opts (argc, argv, ""); + int c; + while ((c = get_opts ()) != -1) + { + switch (c) + { + case 'r': + { + if (this->replicaIorBuffer_ == 0) + { + const char * repNames = get_opts.opt_arg (); + size_t repNameLen = ACE_OS::strlen(repNames); + + // make a working copy of the string + ACE_NEW_NORETURN(this->replicaIorBuffer_, + char[repNameLen + 1]); + if ( this->replicaIorBuffer_ != 0) + { + ACE_OS::memcpy(this->replicaIorBuffer_, repNames, repNameLen+1); + + // tokenize the string on ',' + // into iorReplicaFiles_ + char * pos = this->replicaIorBuffer_; + while (pos != 0) + { + this->iorReplicaFiles_.push_back(pos); + // find a comma delimiter, and + // chop the string there. + pos = ACE_OS::strchr (pos, ','); + if (pos != 0) + { + *pos = '\0'; + pos += 1; + } + } + } + else + { + ACE_ERROR ((LM_ERROR, + "Command line option error: -r can't allocate buffer.\n" + )); + optionError = -1; + } + } + else + { + ACE_ERROR ((LM_ERROR, + "Command line option error: -r specified more than once.\n" + )); + optionError = -1; + } + break; + } + case 'd': + { + this->iorDetectorFile_ = get_opts.opt_arg (); + break; + } + case 'n': + { + this->nsName_ = get_opts.opt_arg (); + break; + } + case 'o': + { + this->iorOutputFile_ = get_opts.opt_arg (); + break; + } + + default: + // fall thru + case '?': + { + break; + } + } + } + + if(! optionError) + { + if (0 == this->replicaIorBuffer_) + { + ACE_ERROR ((LM_ERROR, + "-r option is required.\n" + )); + optionError = -1; + } + if (0 == this->iorDetectorFile_) + { + ACE_ERROR ((LM_ERROR, + "-d option is required.\n" + )); + optionError = -1; + } + } + + if(optionError) + { + ACE_ERROR ((LM_ERROR, + "usage: %s" + " -r <replica.ior[,replica.ior]>" + " -d <detector.ior>" + " -o <this.ior>" + " -n <nameService name>" + "\n", + argv [0] + )); + } +#endif NO_ARGS_FOR_NOW + return optionError; +} + +/** + * Register this object. + */ +int StubFaultConsumer::init (CORBA::ORB_ptr orb, + ::FT::FaultNotifier_var & notifier + ACE_ENV_ARG_DECL) +{ + int result = 0; + this->orb_ = CORBA::ORB::_duplicate (orb); + this->notifier_ = notifier; + this->identity_ = "StubFaultConsumer"; + + + // Use the ROOT POA for now + CORBA::Object_var poa_object = + this->orb_->resolve_initial_references (TAO_OBJID_ROOTPOA + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (CORBA::is_nil (poa_object.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT (" (%P|%t) Unable to initialize the POA.\n")), + -1); + + // Get the POA object. + this->poa_ = + PortableServer::POA::_narrow (poa_object.in () + ACE_ENV_ARG_PARAMETER); + + ACE_CHECK_RETURN (-1); + if (CORBA::is_nil(this->poa_.in ())) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT (" (%P|%t) Unable to narrow the POA.\n")), + -1); + } + + PortableServer::POAManager_var poa_manager = + this->poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + // Register with the POA. + + this->object_id_ = this->poa_->activate_object (this ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + // find my identity as an object + + CORBA::Object_var this_obj = + this->poa_->id_to_reference (object_id_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + CosNotifyFilter::Filter_var filter = CosNotifyFilter::Filter::_nil(); + + this->consumer_id_ = notifier->connect_structured_fault_consumer( + CosNotifyComm::StructuredPushConsumer::_narrow(this_obj.in ()), + filter.in ()); + + return result; +} + +/** + * Return a string to identify this object for logging/console message purposes. + */ +const char * StubFaultConsumer::identity () const +{ + return this->identity_.c_str(); +} + +/** + * Clean house for process shut down. + */ +int StubFaultConsumer::fini (ACE_ENV_SINGLE_ARG_DECL) +{ + this->notifier_->disconnect_consumer(this->consumer_id_ ACE_ENV_ARG_PARAMETER); + return 0; +} + + +int StubFaultConsumer::idle(int & result) +{ + ACE_UNUSED_ARG(result); + return this->quit_; +} + +//////////////// +// CORBA methods +void StubFaultConsumer::push_structured_event( + const CosNotification::StructuredEvent ¬ification + ACE_ENV_ARG_DECL + ) + throw (CORBA::SystemException, CosEventComm::Disconnected) +{ + //////////////////////////////////////// + // keep track of how many we've received + this->notifications_ += 1; + ACE_ERROR ((LM_ERROR, + "FaultConsumer: Received Fault notification(%d):\n" + "FaultConsumer: Header EventType domain: %s\n" + "FaultConsumer: Header EventType type: %s\n" + "FaultConsumer: Header EventName: %s\n", + ACE_static_cast (unsigned int, this->notifications_), + ACE_static_cast (const char *, notification.header.fixed_header.event_type.domain_name), + ACE_static_cast (const char *, notification.header.fixed_header.event_type.type_name), + ACE_static_cast (const char *, notification.header.fixed_header.event_name) + )); + const CosNotification::FilterableEventBody & filterable = notification.filterable_data; + + size_t propertyCount = filterable.length (); + for (size_t nProp = 0; nProp < propertyCount; ++nProp) + { + const CosNotification::Property & property = filterable[nProp]; + + const char * property_name = ACE_static_cast (const char *, property.name); + const char * value = "<unknown>"; + if (property.value >>= value ) + { + // ok! + } + ACE_ERROR ((LM_ERROR, + "FaultConsumer: Property Name: %s=%s\n", + property_name, + value + )); + + +// int todo_finish_decode; + } + +} + +void StubFaultConsumer::offer_change ( + const CosNotification::EventTypeSeq & added, + const CosNotification::EventTypeSeq & removed + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException, CosNotifyComm::InvalidEventType)) +{ + ACE_UNUSED_ARG (added); + ACE_UNUSED_ARG (removed); + ACE_ERROR ((LM_ERROR, + "StubFaultConsumer: offer_change call ignored.\n" + )); +} + +void StubFaultConsumer::disconnect_structured_push_consumer(ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + ACE_ERROR ((LM_ERROR, + "StubFaultConsumer:disconnect_structured_push_consumer interpreted as quit request.\n" + )); + this->quit_ = 1; +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +// template instantiate ACE_Vector < const char * >; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +//# pragma instantiate ACE_Vector < const char * > +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/tests/FT_App/StubFaultConsumer.h b/TAO/orbsvcs/tests/FT_App/StubFaultConsumer.h new file mode 100644 index 00000000000..374b2e7b588 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/StubFaultConsumer.h @@ -0,0 +1,149 @@ +// -*- C++ -*- +// +// $Id$ +#ifndef STUBFAULTCONSUMER_H +#define STUBFAULTCONSUMER_H +#include /**/ <ace/pre.h> +#include <ace/ACE.h> + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "orbsvcs/CosNotifyChannelAdminS.h" +#include <orbsvcs/FT_NotifierC.h> + +////////////////////// +// Forward references + +///////////////////// +// Class declarations + +/** + * A stub fault consumer for use in unit testing Fault Notifier. + */ +class StubFaultConsumer + : public virtual POA_CosNotifyComm::StructuredPushConsumer +{ +public: + /** + * Default constructor. + */ + StubFaultConsumer (); + + /** + * virtual destructor. + */ + virtual ~StubFaultConsumer (); + + + ::PortableServer::POA_ptr _default_POA (ACE_ENV_SINGLE_ARG_DECL); + ::PortableServer::ObjectId objectId()const; + + /** + * Parse command line arguments. + */ + int parse_args (int argc, char * argv[]); + + /** + * Publish this objects IOR. + */ + int init (CORBA::ORB_ptr orb, ::FT::FaultNotifier_var & notifier + ACE_ENV_ARG_DECL); + + /** + * Return a string to identify this object for logging/console message purposes. + */ + const char * identity () const; + + /** + * idle time activity. + * @param result [out] status code to return from process + * @returns 0 to continue; nonzero to quit + */ + int idle(int &result); + + /** + * Clean house for process shut down. + */ + int fini (ACE_ENV_SINGLE_ARG_DECL); + + + size_t notifications() const; + +public: + + //////////////// + // CORBA methods + virtual void push_structured_event( + const CosNotification::StructuredEvent ¬ification + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ) + throw (CORBA::SystemException, CosEventComm::Disconnected); + + virtual void offer_change ( + const CosNotification::EventTypeSeq & added, + const CosNotification::EventTypeSeq & removed + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ) + throw (CORBA::SystemException, CosNotifyComm::InvalidEventType); + + virtual void disconnect_structured_push_consumer(ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + throw (CORBA::SystemException); + + //////////////////// + // Forbidden methods +private: + StubFaultConsumer (const StubFaultConsumer & rhs); + StubFaultConsumer & operator = (const StubFaultConsumer & rhs); + + ///////////////////////// + // Implementation methods +private: + + /////////////// + // Data Members +private: + /** + * The orb + */ + CORBA::ORB_var orb_; + + /** + * The POA used to activate this object. + */ + PortableServer::POA_var poa_; + + /** + * The CORBA object id assigned to this object. + */ + PortableServer::ObjectId_var object_id_; + + + /** + * A human-readable string to distinguish this from other FaultConsumers. + */ + ACE_CString identity_; + + /** + * boolean: request quit + */ + int quit_; + + /** + * the notifier + */ + ::FT::FaultNotifier_var notifier_; + + /** + * consumer id assigned by the notifier + */ + ::FT::FaultNotifier::ConsumerId consumer_id_; + + size_t notifications_; + +}; + +#include /**/ <ace/post.h> + +#endif /* STUBFAULTCONSUMER_H */ diff --git a/TAO/orbsvcs/tests/FT_App/StubFaultNotifier.cpp b/TAO/orbsvcs/tests/FT_App/StubFaultNotifier.cpp new file mode 100644 index 00000000000..4254cbe73ff --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/StubFaultNotifier.cpp @@ -0,0 +1,494 @@ +// -*- C++ -*- +// +// $Id$ + +#include "StubFaultNotifier.h" +#include <ace/Get_Opt.h> +#include <tao/PortableServer/ORB_Manager.h> +#include <orbsvcs/orbsvcs/PortableGroup/PG_Properties_Encoder.h> +#include <iostream> + +StubFaultNotifier::StubFaultNotifier () + : ior_output_file_(0) + , detector_ior_(0) + , ns_name_(0) +{ +} + + +StubFaultNotifier::~StubFaultNotifier () +{ +} + + +::PortableServer::POA_ptr StubFaultNotifier::_default_POA (ACE_ENV_SINGLE_ARG_DECL) +{ + return ::PortableServer::POA::_duplicate(this->poa_.in () ACE_ENV_ARG_PARAMETER); +} + +PortableServer::ObjectId StubFaultNotifier::objectId()const +{ + return this->object_id_.in(); +} + +int StubFaultNotifier::parse_args (int argc, char * argv[]) +{ + int optionError = 0; + ACE_Get_Opt get_opts (argc, argv, "o:r:d:n:"); + int c; + while ((c = get_opts ()) != -1) + { + switch (c) + { + case 'r': + { + this->iorReplicaFiles_.push_back( get_opts.opt_arg ()); + break; + } + case 'd': + { + this->detector_ior_ = get_opts.opt_arg (); + break; + } + case 'n': + { + this->ns_name_ = get_opts.opt_arg (); + break; + } + case 'o': + { + this->ior_output_file_ = get_opts.opt_arg (); + break; + } + + default: + // fall thru + case '?': + { + break; + } + } + } + + if(! optionError) + { + if (iorReplicaFiles_.size() == 0) + { + ACE_ERROR ((LM_ERROR, + "-r option is required.\n" + )); + optionError = -1; + } + if (0 == this->detector_ior_) + { + ACE_ERROR ((LM_ERROR, + "-d option is required.\n" + )); + optionError = -1; + } + } + + if(optionError) + { + ACE_ERROR ((LM_ERROR, + "usage: %s" + " -r <replica.ior [-r <replica2.ior]...>" + " -d <detector.ior>" + " -o <this.ior>" + " -n <nameService name>" + "\n", + argv [0] + )); + } + return optionError; +} + +/** + * Prepare to exit. + */ +int StubFaultNotifier::fini () +{ + if(this->ns_name_ != 0) + { + ACE_TRY_NEW_ENV + { + CORBA::Object_var naming_obj = + this->orb_->resolve_initial_references ("NameService" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + if (CORBA::is_nil(naming_obj.in ())){ + ACE_ERROR_RETURN ((LM_ERROR, + "%T %n (%P|%t) Unable to find the Naming Service\n"), + 1); + } + + CosNaming::NamingContext_var naming_context = + CosNaming::NamingContext::_narrow (naming_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + CosNaming::Name this_name (1); + this_name.length (1); + this_name[0].id = CORBA::string_dup (this->ns_name_); + + naming_context->unbind (this_name + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + } + ACE_ENDTRY; + } + return 0; +} + + +/** + * Publish this objects IOR. + */ +int StubFaultNotifier::init (CORBA::ORB_ptr orb ACE_ENV_ARG_DECL) +{ + int result = 0; + this->orb_ = CORBA::ORB::_duplicate (orb); + + // Use the ROOT POA for now + CORBA::Object_var poa_object = + this->orb_->resolve_initial_references (TAO_OBJID_ROOTPOA + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (CORBA::is_nil (poa_object.in ())) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT (" (%P|%t) Unable to initialize the POA.\n")), + -1); + + // Get the POA object. + this->poa_ = + PortableServer::POA::_narrow (poa_object.in () + ACE_ENV_ARG_PARAMETER); + + ACE_CHECK_RETURN (-1); + + if (CORBA::is_nil(this->poa_.in ())) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT (" (%P|%t) Unable to narrow the POA.\n")), + -1); + } + + PortableServer::POAManager_var poa_manager = + this->poa_->the_POAManager (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + poa_manager->activate (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + // Register with the POA. + + this->object_id_ = this->poa_->activate_object (this ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + // find my identity as a corba object + CORBA::Object_var this_obj = + this->poa_->id_to_reference (object_id_.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + ////////////////////////////////////////// + // resolve references to detector factory + + CORBA::Object_var obj = this->orb_->string_to_object(detector_ior_); + this->factory_ = ::FT::FaultDetectorFactory::_narrow(obj.in ()); + if (CORBA::is_nil(this->factory_.in ())) + { + std::cerr << "Can't resolve Detector Factory IOR " << this->detector_ior_ << std::endl; + result = -1; + } + if (result == 0) + { + //////////////////////////////////// + // resolve references to replicas + size_t replicaCount = this->iorReplicaFiles_.size(); + for(size_t nRep = 0; result == 0 && nRep < replicaCount; ++nRep) + { + const char * iorName = this->iorReplicaFiles_[nRep]; + CORBA::Object_var obj = this->orb_->string_to_object(iorName); + FT::PullMonitorable_var replica = FT::PullMonitorable::_narrow(obj.in ()); + if (CORBA::is_nil(replica.in ())) + { + std::cerr << "Can't resolve Replica IOR " << iorName << std::endl; + result = -1; + } + else + { + this->replicas_.push_back(replica); + + CORBA::String_var type_id = CORBA::string_dup("FaultDetector"); + + TAO_PG::Properties_Encoder encoder; + + PortableGroup::Value value; + ////////////////// + // FaultDetectorFactory gets picky about FaultNotifier's object type. + // coddle it. + ::FT::FaultNotifier_var notifier = ::FT::FaultNotifier::_narrow(this_obj.in ()); + value <<= notifier.in (); + encoder.add(::FT::FT_NOTIFIER, value); + + + value <<= replica.in (); + encoder.add(::FT::FT_MONITORABLE, value); + + FT::FTDomainId domain_id = 0; + value <<= domain_id; + encoder.add(::FT::FT_DOMAIN_ID, value); + + PortableGroup::Location object_location; + object_location.length(1); + object_location[0].id = CORBA::string_dup("Test location"); + value <<= object_location; + encoder.add(::FT::FT_LOCATION, value); + + PortableGroup::TypeId object_type = 0; + value <<= object_type; + encoder.add(::FT::FT_TYPE_ID, value); + + PortableGroup::ObjectGroupId group_id = 0; + value <<= group_id; + encoder.add(::FT::FT_GROUP_ID, value); + + // allocate and populate the criteria + PortableGroup::Criteria_var criteria; + ACE_NEW_NORETURN (criteria, + PortableGroup::Criteria); + if (criteria.ptr() == 0) + { + ACE_ERROR((LM_ERROR, + "Error cannot allocate criteria.\n" + )); + result = -1; + } + else + { + encoder.encode(criteria); + PortableGroup::GenericFactory::FactoryCreationId_var factory_creation_id; + + this->factory_->create_object ( + type_id.in(), + criteria.in(), + factory_creation_id + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + } + } + } + + if (this->ior_output_file_ != 0) + { + this->identity_ = "file:"; + this->identity_ += this->ior_output_file_; + result = write_ior_file(); + } + else + { + // if no IOR file specified, + // then always try to register with name service + this->ns_name_ = "FT_FaultNotifier"; + } + + if(this->ns_name_ != 0) + { + this->identity_ = "name:"; + this->identity_ += this->ns_name_; + + CORBA::Object_var naming_obj = + this->orb_->resolve_initial_references ("NameService" ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + if (CORBA::is_nil(naming_obj.in ())){ + ACE_ERROR_RETURN ((LM_ERROR, + "%T %n (%P|%t) Unable to find the Naming Service\n"), + 1); + } + + CosNaming::NamingContext_var naming_context = + CosNaming::NamingContext::_narrow (naming_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + + CosNaming::Name this_name (1); + this_name.length (1); + this_name[0].id = CORBA::string_dup (this->ns_name_); + + naming_context->rebind (this_name, this_obj.in() + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + } + } + return result; +} + +int StubFaultNotifier::write_ior_file() +{ + int result = -1; + FILE* out = ACE_OS::fopen (this->ior_output_file_, "w"); + if (out) + { + ACE_OS::fprintf (out, "%s", ACE_static_cast(const char *, this->ior_)); + ACE_OS::fclose (out); + result = 0; + } + return result; +} + +/** + * Return a string to identify this object for logging/console message purposes. + */ +const char * StubFaultNotifier::identity () const +{ + return this->identity_.c_str(); +} + +/** + * Clean house for process shut down. + */ +void StubFaultNotifier::shutdown_i () +{ + this->orb_->shutdown (0 ACE_ENV_ARG_PARAMETER); +} + +void StubFaultNotifier::push_structured_fault ( + const CosNotification::StructuredEvent & event + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + ACE_ERROR ((LM_ERROR, + "FaultNotifier: Received Fault notification:\n" + "FaultNotifier: Header EventType domain: %s\n" + "FaultNotifier: Header EventType type: %s\n" + "FaultNotifier: Header EventName: %s\n", + ACE_static_cast (const char *, event.header.fixed_header.event_type.domain_name), + ACE_static_cast (const char *, event.header.fixed_header.event_type.type_name), + ACE_static_cast (const char *, event.header.fixed_header.event_name) + )); + const CosNotification::FilterableEventBody & filterable = event.filterable_data; + + size_t propertyCount = filterable.length (); + for (size_t nProp = 0; nProp < propertyCount; ++nProp) + { + const CosNotification::Property & property = filterable[nProp]; + ACE_ERROR ((LM_ERROR, + "FaultNotifier: Property Name: %s\n", + ACE_static_cast (const char *, property.name) + )); + //@@ we could stand to decode more--just for completeness + } +} + + +void StubFaultNotifier::push_sequence_fault ( + const CosNotification::EventBatch & events + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + )) +{ + ACE_UNUSED_ARG (events); + ACE_THROW (CORBA::NO_IMPLEMENT()); +} + +::CosNotifyFilter::Filter_ptr StubFaultNotifier::create_subscription_filter ( + const char * constraint_grammar + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + , CosNotifyFilter::InvalidGrammar + )) +{ + ACE_UNUSED_ARG (constraint_grammar); + ACE_THROW (CORBA::NO_IMPLEMENT()); +} + + +FT::FaultNotifier::ConsumerId StubFaultNotifier::connect_structured_fault_consumer ( + CosNotifyComm::StructuredPushConsumer_ptr push_consumer, + CosNotifyFilter::Filter_ptr filter + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + )) +{ + ACE_UNUSED_ARG(push_consumer); + ACE_UNUSED_ARG(filter); + + ACE_THROW (CORBA::NO_IMPLEMENT()); +} + + +FT::FaultNotifier::ConsumerId StubFaultNotifier::connect_sequence_fault_consumer ( + CosNotifyComm::SequencePushConsumer_ptr push_consumer, + CosNotifyFilter::Filter_ptr filter + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + )) +{ + ACE_UNUSED_ARG(push_consumer); + ACE_UNUSED_ARG(filter); + + ACE_THROW (CORBA::NO_IMPLEMENT()); +} + +void StubFaultNotifier::disconnect_consumer ( + FT::FaultNotifier::ConsumerId connection + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException + , CosEventComm::Disconnected + )) +{ + ACE_UNUSED_ARG(connection); + + ACE_THROW (CORBA::NO_IMPLEMENT()); +} + +CORBA::Boolean StubFaultNotifier::is_alive (ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + return 1; +} + +int StubFaultNotifier::idle(int & result) +{ + ACE_UNUSED_ARG(result); + int quit = 0; + ACE_TRY_NEW_ENV + { + if(!CORBA::is_nil(this->factory_.in ())) + { + if (!this->factory_->is_alive( ACE_ENV_SINGLE_ARG_PARAMETER)) + { + quit = 1; + } + } + } + ACE_CATCHANY + { + quit = 1; + } + ACE_ENDTRY; + return quit; +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) + template class ACE_Vector < const char * >; + template class ACE_Vector < FT::PullMonitorable_var > ; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +# pragma instantiate ACE_Vector < const char * > +# pragma instantiate ACE_Vector < FT::PullMonitorable_var > +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/tests/FT_App/StubFaultNotifier.h b/TAO/orbsvcs/tests/FT_App/StubFaultNotifier.h new file mode 100644 index 00000000000..38a285cdce6 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/StubFaultNotifier.h @@ -0,0 +1,187 @@ +// -*- C++ -*- +// +// $Id$ +#ifndef STUBFAULTNOTIFIER_H_ +#define STUBFAULTNOTIFIER_H_ + +#include <ace/ACE.h> + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ +#include /**/ <ace/pre.h> + +#include <orbsvcs/FT_NotifierS.h> +#include <orbsvcs/FT_FaultDetectorFactoryC.h> +#include <ace/Vector_T.h> + +////////////////////// +// Forward references + +///////////////////// +// Class declarations + +/** + * A stub implementation of the FaultNotifier interface + */ +class StubFaultNotifier : public virtual POA_FT::FaultNotifier +{ + ////////////////////// + // non-CORBA interface +public: + /** + * Default constructor. + */ + StubFaultNotifier (); + + /** + * Virtual destructor. + */ + virtual ~StubFaultNotifier (); + + /** + * Parse command line arguments. + */ + int parse_args (int argc, char * argv[]); + + /** + * Initialize. + */ + int init (CORBA::ORB_ptr orb ACE_ENV_ARG_DECL); + + /** + * Prepare to exit. + */ + int fini (); + + /** + * Return a string to identify this object for logging/console message purposes. + */ + const char * identity () const; + + /** + * idle time activity. + * @param result [out] status code to return from process + * @returns 0 to continue; nonzero to quit + */ + int idle(int &result); + + // override virtuals +::PortableServer::POA_ptr _default_POA (ACE_ENV_SINGLE_ARG_DECL); + + PortableServer::ObjectId objectId()const; + + + /** + * Clean house for process shut down. + */ + void shutdown_i (); + + //////////////////////////////// + // CORBA interface FaultNotifier + + + virtual void push_structured_fault ( + const CosNotification::StructuredEvent & event + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void push_sequence_fault ( + const CosNotification::EventBatch & events + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual ::CosNotifyFilter::Filter_ptr create_subscription_filter ( + const char * constraint_grammar + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ) + ACE_THROW_SPEC ((CORBA::SystemException, CosNotifyFilter::InvalidGrammar)); + + virtual FT::FaultNotifier::ConsumerId connect_structured_fault_consumer ( + CosNotifyComm::StructuredPushConsumer_ptr push_consumer, + CosNotifyFilter::Filter_ptr filter + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual FT::FaultNotifier::ConsumerId connect_sequence_fault_consumer ( + CosNotifyComm::SequencePushConsumer_ptr push_consumer, + CosNotifyFilter::Filter_ptr filter + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ) + ACE_THROW_SPEC ((CORBA::SystemException)); + + virtual void disconnect_consumer ( + FT::FaultNotifier::ConsumerId connection + ACE_ENV_ARG_DECL_WITH_DEFAULTS + ) + ACE_THROW_SPEC ((CORBA::SystemException, CosEventComm::Disconnected)); + + ////////////////////////////////////////// + // CORBA interface PullMonitorable methods + virtual CORBA::Boolean is_alive (ACE_ENV_SINGLE_ARG_DECL_WITH_DEFAULTS) + ACE_THROW_SPEC ((CORBA::SystemException)); + + ///////////////// + // Implementation +private: + int write_ior_file(); + + /////////////// + // Data Members +private: + /** + * The orb + */ + CORBA::ORB_var orb_; + + /** + * The POA used to activate this object. + */ + PortableServer::POA_var poa_; + + /** + * The CORBA object id assigned to this object. + */ + PortableServer::ObjectId_var object_id_; + + /** + * IOR of this object as assigned by poa + */ + CORBA::String_var ior_; + + /** + * A file to which the factory's IOR should be written. + */ + const char * ior_output_file_; + + /** + * A file from which the detecor's IOR should be read. + */ + const char * detector_ior_; + + ::FT::FaultDetectorFactory_var factory_; + + /** + * A collection of files containing replica IORs + */ + ACE_Vector < const char * > iorReplicaFiles_; + + + ACE_Vector < FT::PullMonitorable_var > replicas_; + /** + * A name to be used to register with the name service. + */ + const char * ns_name_; + + /** + * A human-readable string to distinguish this from other Notifiers. + */ + ACE_CString identity_; +}; + +#include /**/ <ace/post.h> + +#endif /* STUBFAULTNOTIFIER_H_ */ diff --git a/TAO/orbsvcs/tests/FT_App/TAO_Object_Group_Creator.cpp b/TAO/orbsvcs/tests/FT_App/TAO_Object_Group_Creator.cpp new file mode 100644 index 00000000000..5da8173f8fa --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/TAO_Object_Group_Creator.cpp @@ -0,0 +1,470 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file TAO_Object_Group_Creator.cpp + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * Utility to Create Object Group + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= + +#include "TAO_Object_Group_Creator.h" +#include <iostream> +#include <fstream> +#include <orbsvcs/PortableGroup/PG_Properties_Encoder.h> +#include <orbsvcs/FT_FaultDetectorFactoryC.h> +#include <orbsvcs/PortableGroup/PG_Operators.h> + +#include <ace/Get_Opt.h> + +TAO::Object_Group_Creator::Object_Group_Creator () + : orb_(CORBA::ORB::_nil ()) + , registry_ (PortableGroup::FactoryRegistry::_nil ()) + , replication_manager_ (FT::ReplicationManager::_nil ()) + , detector_infos_ (0) + , have_replication_manager_ (0) +{ +} + +TAO::Object_Group_Creator::~Object_Group_Creator () +{ +} + +int TAO::Object_Group_Creator::set_factory_registry (PortableGroup::FactoryRegistry_ptr factory) +{ + this->registry_ = PortableGroup::FactoryRegistry::_duplicate (factory); + return CORBA::is_nil (this->registry_.in ()) ? -1 : 0 ; +} + + +int TAO::Object_Group_Creator::init (CORBA::ORB_ptr orb ACE_ENV_ARG_DECL) +{ + int result = 0; + this->orb_ = CORBA::ORB::_duplicate (orb); + + if (CORBA::is_nil (this->registry_.in ())) + { + /////////////////////////////// + // Find the ReplicationManager + ACE_TRY_NEW_ENV + { + CORBA::Object_var rm_obj = orb->resolve_initial_references ("ReplicationManager" ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + + this->replication_manager_ = ::FT::ReplicationManager::_narrow (rm_obj.in () ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + if (!CORBA::is_nil (this->replication_manager_.in ())) + { + this->have_replication_manager_ = 1; + // empty criteria + ::PortableGroup::Criteria criteria; + this->registry_ = this->replication_manager_->get_factory_registry (criteria ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + if (!CORBA::is_nil (this->registry_.in ())) + { + this->detector_infos_ = this->registry_->list_factories_by_role (FT::FAULT_DETECTOR_ROLE_NAME, this->detector_type_id_.out () + ACE_ENV_ARG_PARAMETER) + ACE_TRY_CHECK; + CORBA::ULong count = this->detector_infos_->length (); + ACE_DEBUG ( (LM_DEBUG, + "%T %n (%P|%t)Object_Group_Creator: found %u factories for FaultDetectors\n", + ACE_static_cast (unsigned, count) + )); + } + else + { + ACE_ERROR ( (LM_ERROR, + "%T %n (%P|%t) Object_Group_Creator: ReplicationManager failed to return FactoryRegistry.\n" + )); + ACE_TRY_THROW (CORBA::NO_IMPLEMENT ()); + } + } + else + { + ACE_ERROR ( (LM_ERROR, + "%T %n (%P|%t) Object_Group_Creator: resolve_initial_references for ReplicationManager failed.\n" + )); + ACE_TRY_THROW (CORBA::OBJECT_NOT_EXIST ()); + } + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "Creator: Exception resolving ReplicationManager,\n"); + + result = 1; + } + ACE_ENDTRY; + } + + return result; +} + +int TAO::Object_Group_Creator::unregister_role (const char * role ACE_ENV_ARG_DECL) +{ + int result = 0; + ACE_ERROR ( (LM_INFO, + "%T %n (%P|%t) Object_Group_Creator: Unregistering all factories for %s\n", + role + )); + this->registry_->unregister_factory_by_role (role ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (-1); + return result; +} + + + +int TAO::Object_Group_Creator::create_detector_for_replica ( + CORBA::Object_ptr replica, + const char * role, + const char * type_id, + PortableGroup::ObjectGroupId group_id, + const PortableGroup::Location & location + ACE_ENV_ARG_DECL) +{ + int result = 0; + + if (this->have_replication_manager_) + { + CORBA::ULong detector_count = this->detector_infos_->length (); + for (CORBA::ULong n_detector = 0; result == 0 && n_detector < detector_count; ++n_detector) + { + PortableGroup::FactoryInfo & info = (*this->detector_infos_)[n_detector]; + if ( info.the_location == location || n_detector + 1 == detector_count) + { + TAO_PG::Properties_Encoder encoder; + + PortableGroup::Value value; + + FT::PullMonitorable_ptr monitorable = FT::PullMonitorable::_narrow (replica); + value <<= monitorable; + encoder.add (::FT::FT_MONITORABLE, value); + + FT::FTDomainId domain_id = 0; + value <<= domain_id; + encoder.add (::FT::FT_DOMAIN_ID, value); + + value <<= location; + encoder.add (::FT::FT_LOCATION, value); + + value <<= type_id; + encoder.add (::FT::FT_TYPE_ID, value); + + value <<= group_id; + encoder.add (::FT::FT_GROUP_ID, value); + + value <<= CORBA::string_dup (role); + encoder.add (PortableGroup::role_criterion, value); + + // allocate and populate the criteria + PortableGroup::Criteria_var criteria; + ACE_NEW_NORETURN (criteria, + PortableGroup::Criteria); + if (criteria.ptr () == 0) + { + ACE_ERROR ( (LM_ERROR, + "%T %n (%P|%t)Object_Group_Creater: Error cannot allocate criteria.\n" + )); + result = -1; + } + else + { + encoder.encode (criteria); + PortableGroup::GenericFactory::FactoryCreationId_var factory_creation_id; + + info.the_factory->create_object ( + type_id, + criteria.in (), + factory_creation_id + ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + result = 1; + } + } + } + } + return result; +} + + +CORBA::Object_ptr TAO::Object_Group_Creator::create_infrastructure_managed_group ( + const char * type_id + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException )) +{ + CORBA::Object_var group = CORBA::Object::_nil (); + + PortableGroup::ObjectGroupId group_id = 0; + + if (this->have_replication_manager_) + { + // set typeid properties + PortableGroup::Properties properties (1); + properties.length (3); + + properties[0].nam.length (1); + properties[0].nam[0].id = PortableGroup::PG_MEMBERSHIP_STYLE; + properties[0].val <<= PortableGroup::MEMB_INF_CTRL; + + PortableGroup::InitialNumberMembersValue inm(2); + properties[1].nam.length (1); + properties[1].nam[0].id = PortableGroup::PG_INITIAL_NUMBER_MEMBERS; + properties[1].val <<= inm; + + PortableGroup::MinimumNumberMembersValue mnm(1); + properties[2].nam.length (1); + properties[2].nam[0].id = PortableGroup::PG_MINIMUM_NUMBER_MEMBERS; + properties[2].val <<= mnm; + + this->replication_manager_->set_type_properties ( + type_id, + properties + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (group._retn ()); + + ::PortableGroup::GenericFactory::FactoryCreationId_var creation_id; + PortableGroup::Criteria criteria (1); + criteria.length (1); + criteria[0].nam.length (1); + criteria[0].nam[0].id = PortableGroup::PG_MEMBERSHIP_STYLE; + criteria[0].val <<= PortableGroup::MEMB_APP_CTRL; + + group = this->replication_manager_->create_object ( + type_id, + criteria, + creation_id + ACE_ENV_ARG_PARAMETER + ); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + } + else + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT("%T %n (%P|%t): Object_Group_Creator: infrastructure managed group requires Replication Manager\n") + )); + } + return group._retn (); +} + +CORBA::Object_ptr TAO::Object_Group_Creator::create_group ( + const char * role, + int write_iors + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ( (CORBA::SystemException )) +{ + CORBA::Object_var group = CORBA::Object::_nil (); + + PortableGroup::ObjectGroupId group_id = 0; + CORBA::String_var type_id; + ::PortableGroup::FactoryInfos_var infos = this->registry_->list_factories_by_role (role, type_id + ACE_ENV_ARG_PARAMETER) + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + CORBA::ULong count = infos->length (); + ACE_ERROR ( (LM_INFO, + ACE_TEXT("%T %n (%P|%t): Object_Group_Creator: found %u factories for %s : %s\n"), + ACE_static_cast (unsigned, count), + role, + ACE_static_cast (const char *, type_id) + )); + + if (count > 0) + { + /////////////////////////// + // Begin with an empty IOGR + ::PortableGroup::GenericFactory::FactoryCreationId_var creation_id; + if (this->have_replication_manager_) + { + + ////////////////////////////////////////////////////// + // note infrastructure controlled because we want the + // ReplicationManager to manage the object after it's created. + // Initial number members = 0 because we do not want the Replication + // Manager to populate the group. + // Minimum number of members = 0 because we do not want the + // Replication Manager to replace failed members. + // Semi-active, because that's what we do. + PortableGroup::Criteria criteria (3); + criteria.length (4); + criteria[0].nam.length (1); + criteria[0].nam[0].id = PortableGroup::PG_MEMBERSHIP_STYLE; + criteria[0].val <<= PortableGroup::MEMB_INF_CTRL; + + criteria[1].nam.length (1); + criteria[1].nam[0].id = PortableGroup::PG_INITIAL_NUMBER_MEMBERS; + criteria[1].val <<= PortableGroup::InitialNumberMembersValue (0); + + criteria[2].nam.length (1); + criteria[2].nam[0].id = PortableGroup::PG_MINIMUM_NUMBER_MEMBERS; + criteria[2].val <<= PortableGroup::MinimumNumberMembersValue (0); + + criteria[3].nam.length (1); + criteria[3].nam[0].id = FT::FT_REPLICATION_STYLE; + criteria[3].val <<= FT::SEMI_ACTIVE; + + group = this->replication_manager_->create_object ( + type_id.in (), + criteria, + creation_id + ACE_ENV_ARG_PARAMETER + ); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + //@@ this is a bit of a hack + creation_id >>= group_id; + + } + + const PortableGroup::Location * first_location = 0; + + for (CORBA::ULong nFact = 0; nFact < count; ++nFact) + { + ::PortableGroup::FactoryInfo & info = infos[nFact]; + + const char * loc_name = info.the_location[0].id; + ACE_ERROR ( (LM_INFO, + "%T %n (%P|%t) Object_Group_Creator: Creating %s@%s\n", + role, + loc_name + )); + + PortableGroup::GenericFactory::FactoryCreationId_var factory_creation_id; + CORBA::Object_var created_obj = info.the_factory->create_object ( + type_id.in (), + info.the_criteria, + factory_creation_id.out () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + if ( !CORBA::is_nil (created_obj.in ()) ) + { +// that which was first shall now be last if (nFact == 0) + { + first_location = & info.the_location; + } + + // try to create a detector, but don't worry if it doesn't happen + (void) create_detector_for_replica ( + created_obj.in (), + role, + type_id.in (), + group_id, + info.the_location + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + const char * replica_ior = orb_->object_to_string (created_obj.in () ACE_ENV_ARG_PARAMETER ); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + + if (write_iors) + { + //////////////////////////////////// + // Somewhat of a hack + // guess at role of factory creation id + CORBA::ULong ulong_id = 0; + CORBA::Long long_id = 0; + if (factory_creation_id >>= ulong_id) + { + // ok + } + else if (factory_creation_id >>= long_id) + { + ulong_id = ACE_static_cast (CORBA::ULong, long_id); + } + else + { + ACE_ERROR ( (LM_ERROR, + "%T %n (%P|%t) Object_Group_Creator: Can't decypher factory creation id.\n" + )); + // Guessed wrong. Just use default value + } + + char replica_ior_filename[200]; // "${role}_$ (location)_${factory_id}.ior" + + ACE_OS::snprintf (replica_ior_filename, sizeof (replica_ior_filename)-1, "%s_%s_%lu.ior", + role, + loc_name, + ACE_static_cast (unsigned long, ulong_id)); + replica_ior_filename[sizeof (replica_ior_filename)-1] = '\0'; + + ACE_ERROR ( (LM_INFO, + "%T %n (%P|%t) Object_Group_Creator: Writing ior for created object to %s\n", + replica_ior_filename + )); + + if (write_ior_file (replica_ior_filename, replica_ior) != 0) + { + ACE_ERROR ( (LM_ERROR, + "%T %n (%P|%t) Object_Group_Creator: Error writing ior [%s] to %s\n", + replica_ior, + replica_ior_filename + )); + } + } + + if (this->have_replication_manager_) + { + group = this->replication_manager_->add_member ( + group.in (), + info.the_location, + created_obj.in () + ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + } + } + else + { + ACE_ERROR ( (LM_ERROR, + "%T %n (%P|%t) Object_Group_Creator: create_object returned nil????\n" + )); + } + } + + if (first_location != 0 && this->have_replication_manager_) + { + group = this->replication_manager_->set_primary_member (group.in (), * first_location ACE_ENV_ARG_PARAMETER); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + } + ACE_ERROR ( (LM_INFO, + "%T %n (%P|%t) Object_Group_Creator: Successfully created group of %s\n", + role + )); + } + + return group._retn (); +} + + +int TAO::Object_Group_Creator::fini () +{ + return 0; +} + +int TAO::Object_Group_Creator::write_ior_file (const char * outputFile, const char * ior) +{ + int result = -1; + FILE* out = ACE_OS::fopen (outputFile, "w"); + if (out) + { + ACE_OS::fprintf (out, "%s", ior); + ACE_OS::fclose (out); + result = 0; + } + else + { + ACE_ERROR ( (LM_ERROR, + "%T %n (%P|%t) Object_Group_Creator: Open failed for %s\n", outputFile + )); + } + return result; +} + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +// template ACE_Vector<ACE_CString>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +//# pragma instantiate ACE_Vector<ACE_CString> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/tests/FT_App/TAO_Object_Group_Creator.h b/TAO/orbsvcs/tests/FT_App/TAO_Object_Group_Creator.h new file mode 100644 index 00000000000..5bf6c6aae58 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/TAO_Object_Group_Creator.h @@ -0,0 +1,108 @@ +/* -*- C++ -*- */ +//============================================================================= +/** + * @file TAO_Object_Group_Creator.h + * + * $Id$ + * + * This file is part of Fault Tolerant CORBA. + * Utility to Create Object Group + * + * @author Dale Wilson <wilson_d@ociweb.com> + */ +//============================================================================= + +#ifndef TAO_OBJECT_GROUP_CREATOR_H +#define TAO_OBJECT_GROUP_CREATOR_H +#include <ace/ACE.h> + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include <orbsvcs/FT_ReplicationManagerC.h> +#include <orbsvcs/PortableGroupC.h> +#include <ace/SString.h> +#include <ace/Vector_T.h> + +namespace TAO +{ + class Object_Group_Creator + { + typedef ACE_Vector<ACE_CString> StringVec; + public: + /////////////////////////// + // construction/destruction + Object_Group_Creator (); + + ~Object_Group_Creator (); + + ///////////////// + // pre-init methods + int set_factory_registry (PortableGroup::FactoryRegistry_ptr factory); + + ///////////////// + // initialization + int init (CORBA::ORB_ptr orb ACE_ENV_ARG_DECL); + + ///////////////// + // functionality + CORBA::Object_ptr create_group( + const char * role, + int write_iors + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + + ///////////////// + // functionality + CORBA::Object_ptr create_infrastructure_managed_group( + const char * type_id + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)); + + int unregister_role(const char * role ACE_ENV_ARG_DECL); + + //////////// + // shut down + int fini (); + + ///////////////// + // implementation + private: + int write_ior_file(const char * outputFile, const char * ior); + + int create_detector_for_replica ( + CORBA::Object_ptr replica, + const char * role, + const char * type_id, + PortableGroup::ObjectGroupId group_id, + const PortableGroup::Location & location + ACE_ENV_ARG_DECL); + + //////////////////// + // forbidden methods + private: + Object_Group_Creator (const Object_Group_Creator & rhs); + Object_Group_Creator & operator = (const Object_Group_Creator & rhs); + + //////////////// + // Data members + private: + CORBA::ORB_var orb_; + PortableGroup::FactoryRegistry_var registry_; + + ::FT::ReplicationManager_var replication_manager_; + + ::PortableGroup::FactoryInfos_var detector_infos_; + CORBA::String_var detector_type_id_; + + + /** + * bool: true if we have a real replication manager + */ + int have_replication_manager_; + }; + +} // namespace TAO + +#endif // TAO_OBJECT_GROUP_CREATOR_H diff --git a/TAO/orbsvcs/tests/FT_App/replica.cmd b/TAO/orbsvcs/tests/FT_App/replica.cmd new file mode 100755 index 00000000000..6c242ad4a00 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/replica.cmd @@ -0,0 +1,9 @@ +@if "%1a" == "a" goto error +@if "%2a" == "a" goto error +release\ft_replica -o %1.ior -q -f none -l %1 -i %2 %3 %4 %5 %6 %7 %8 %9 +@goto end +@:error +@echo Usage %0 location role [options] +@:end +pause +exit diff --git a/TAO/orbsvcs/tests/FT_App/run_test_basic.pl b/TAO/orbsvcs/tests/FT_App/run_test_basic.pl new file mode 100755 index 00000000000..dea17745fb6 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/run_test_basic.pl @@ -0,0 +1,107 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +use lib '../../../../bin'; +use PerlACE::Run_Test; + +######################## +#command line options +#set defaults: +my($verbose) = 0; # 1: report perl actions before executing them +my($debug_builds) = 0; # 0: use exes from Release directories + +foreach $i (@ARGV) { + if ($i eq "--debug_build") + { + $debug_builds = 1; + } + elsif ($i eq "-v") + { + $verbose += 1; + } +} + +my($build_directory) = "/Release"; +if ( $debug_builds ) { + $build_directory = ""; +} + +if ( $verbose > 1) { + print "verbose: $verbose\n"; + print "debug_builds: $debug_builds -> $build_directory\n"; +} + +my($factory1_ior) = PerlACE::LocalFile ("factory1.ior"); +my($factory2_ior) = PerlACE::LocalFile ("factory2.ior"); +my($replica1_ior) = PerlACE::LocalFile ("replica1.ior"); +my($replica2_ior) = PerlACE::LocalFile ("replica2.ior"); +my($data_file) = PerlACE::LocalFile ("persistent.dat"); + +unlink $factory1_ior; +unlink $factory2_ior; +unlink $replica1_ior; +unlink $replica2_ior; +unlink $data_file; +my($status) = 0; + +my($SV1) = new PerlACE::Process ("./$build_directory/ft_replica", "-o $factory1_ior -t $replica1_ior -q -f none"); +my($SV2) = new PerlACE::Process ("./$build_directory/ft_replica", "-o $factory2_ior -t $replica2_ior -q -f none"); +my($CL) = new PerlACE::Process ("./$build_directory/ft_client", "-f file://$replica1_ior -f file://$replica2_ior -c testscript"); + +print "\nTest: Starting replica 1 " . $SV1->CommandLine . "\n" if ($verbose); +$SV1->Spawn (); + +print "waiting for replica 1's IOR\n" if ($verbose); + +if (PerlACE::waitforfile_timed ($replica1_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find replica 1 file <$replica1_ior>\n"; + $SV1->Kill (); $SV1->TimedWait (1); + exit 1; +} + +print "\nTest: Starting replica 2 " . $SV2->CommandLine . "\n" if ($verbose); +$SV2->Spawn (); + +print "waiting for replica 2's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($replica2_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find replica 2 file <$replica2_ior>\n"; + $SV1->Kill (); $SV1->TimedWait (1); + $SV2->Kill (); $SV2->TimedWait (1); + exit 1; +} + +print "\nTest: Starting client " . $CL->CommandLine . "\n" if ($verbose); + +$client = $CL->SpawnWaitKill (60); + +if ($client != 0) { + print STDERR "TEST ERROR: client returned $client\n"; + $status = 1; +} + +print "wait for server 1.\n" if ($verbose); +$server = $SV1->WaitKill (60); + +print "wait for server 2.\n" if ($verbose); +$server = $SV2->WaitKill (60); + +if ($server != 0) { + print STDERR "TEST ERROR: server returned $server\n"; + $status = 1; +} + +if ($status == 0) { +print "Clean up scratch files\n" if ($verbose); + +unlink $factory1_ior; +unlink $factory2_ior; +unlink $replica1_ior; +unlink $replica2_ior; +unlink $data_file; +} + +exit $status; diff --git a/TAO/orbsvcs/tests/FT_App/run_test_demo.pl b/TAO/orbsvcs/tests/FT_App/run_test_demo.pl new file mode 100755 index 00000000000..eb18a88023a --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/run_test_demo.pl @@ -0,0 +1,433 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +# Purpose: +# Integration test for all FT services. +# +# Command line options: +# --debug_build use exes from this directory +# if not specified use exes from ./release +# --no_simulate +# use real IOGR-based recovery. +# -v display test progress messages (repeating option increases verbosity +# Process being tested: +# FT_ReplicationManager +# Fault_Detector +# Fault_Notifier +# +# Processes used in test: +# FT_Replica * 3 +# implements GenericFactory interface to create TestReplicas +# TestReplica implements TestReplica interface. +# TestReplica implements PullMonitorable interface. +# FT_Client +# client for TestReplica interface. +# client for PullMonitorable. +# Object Group Creator +# Creates groups of objects. +# +# Test Scenario +# +# 1) Start the ReplicationManager (RM), +# 2) Start the Fault Notification Server(FN) +# 2.1) FN registers with RM. +# 2.2) RM registers as consumer with FN +# 3) Start FaultDetectorFactory at location shire (FD@shire) +# 3.1) FD@shire registers with RM +# 4) Start FaultDetectorFactory at location bree (FD@bree) +# 4.1) FD@bree registers with RM +# 5) Start Replica Factory at location shire (RF@shire) that can create hobbits +# 5.1) RF@shire registers with RM to create hobbit@shire +# 6) Start Replica Factory at location bree (RF@bree) that can create hobbits and elves. +# 6.1) RF@bree registers with RM to create hobbit@bree +# 6.1) RF@bree registers with RM to create elf@bree +# 6) Start Replica Factory at location rivendell (RF@rivendell) that can create elves. +# 6.1) RF@bree registers with RM to create elf@rivendell +# 7) Start ObjectGroupCreator (OGC) +# 7.1) OGC calls RM to create group of hobbits (IOGR1) +# 7.1.1) OGC calls RF@shire to create hobbit@shire[1] +# 7.1.1.1) OGC calls FD@shire to create FaultDetector for hobbit@shire[1] +# 7.1.1.2) OGC adds hobbit@shire[1] to IOGR1. +# 7.1.2) OGC calls RF@bree to craate hobbit@bree[1] +# 7.1.2.1) OGC calls FD@bree to create FaultDetector for hobbit@bree[1] +# 7.1.2.2) OGC adds hobbit@bree[1] to IOGR1. +# 7.2) OGC calls RM to create group of elves (IOGR2) +# 7.2.1) OGC calls RF@bree to create elf@bree[2] +# 7.2.1.1) OGC calls FD@bree to create FaultDetector for elf@bree[2] +# 7.2.1.2) OGC adds elf@bree[2] to IOGR2. +# 7.2.2) OGC calls RF@rivendell to create elf@rivendell[1] +# 7.2.2.1) OGC calls FD@shire to create FaultDetector for elf@rivendell[1] +# 7.2.2.2) OGC adds elf@rivendell[1] to IOGR2. +# 7.3) OGC calls RM to create group of hobbits (IOGR3) +# 7.3.1) OGC calls RF@shire to create hobbit@shire[2] +# 7.3.1.1) OGC calls FD@shire to create FaultDetector for hobbit@shire[2] +# 7.3.1.2) OGC adds hobbit@shire[2] to IOGR2. +# 7.3.2) OGC calls RF@bree to craate hobbit@bree[3] +# 7.3.2.1) OGC calls FD@bree to create FaultDetector for hobbit@bree[3] +# 7.3.2.2) OGC adds hobbit@bree[3] to IOGR3. +# 8) Start client1 with IOGR1 +# 8.1) Hobbit@shire[1] fails. FD sends notification FN. +# 8.1.1) FN sends notification to RM. +# 8.1.2) RM removes hobbit@shire[1] from IOGR1. +# 8.2) Client1 terminates itself and hobbit@bree[1]. +# 9) Start Cient2 with IOGR2. +# 9.1) Repeat 8.1 & 8.2 using IOGR3. +# 10) Start Cient3 with IOGR3. +# 10.1) Repeat 8.1 & 8.2 using IOGR3. +# 11) System manages to shut itself down. + +use lib '../../../../bin'; +#use lib '$ENV{ACE_ROOT}/bin'; +use PerlACE::Run_Test; + +######################## +#command line options +#set defaults: +my($verbose) = 0; # 1: report perl actions before executing them +my($debug_builds) = 0; # 0: use exes from Release directories +my($simulated) = 1; # 1: use "client simulated" fault tolerance + +foreach $i (@ARGV) { + if ($i eq "--debug_build") + { + $debug_builds = 1; + } + elsif ($i eq "--no_simulate") # reverse this once we have FT ORB support + { + $simulated = 0; + } + elsif ($i eq "-v") + { + $verbose += 1; + } +} + +my($build_directory) = "/Release"; +if ( $debug_builds ) { + $build_directory = ""; +} + +if ( $verbose > 1) { + print "verbose: $verbose\n"; + print "debug_builds: $debug_builds -> $build_directory\n"; + print "simulated: $simulated\n"; +} + +my($role1) = "hobbit"; +my($role2) = "elf"; + +my($location1) = "shire"; +my($location2) = "bree"; +my($location3) = "rivendell"; + +my ($rm_endpoint) = "-ORBEndpoint iiop://localhost:2833"; +my ($rm_initref) = "-ORBInitRef ReplicationManager=corbaloc::localhost:2833/ReplicationManager"; + +#define temp files +my($rm_ior) = PerlACE::LocalFile ("rm.ior"); +my($notifier_ior) = PerlACE::LocalFile ("notifier.ior"); +my($detector1_ior) = PerlACE::LocalFile ("detector1.ior"); +my($detector2_ior) = PerlACE::LocalFile ("detector2.ior"); +my($factory1_ior) = PerlACE::LocalFile ("factory1.ior"); +my($factory2_ior) = PerlACE::LocalFile ("factory2.ior"); +my($factory3_ior) = PerlACE::LocalFile ("factory3.ior"); +my($replica1_ior) = PerlACE::LocalFile ("${role1}_${location1}_0.ior"); +my($replica2_ior) = PerlACE::LocalFile ("${role1}_${location2}_0.ior"); +my($replica3_ior) = PerlACE::LocalFile ("${role2}_${location2}_1.ior"); +my($replica4_ior) = PerlACE::LocalFile ("${role2}_${location3}_0.ior"); +my($replica5_ior) = PerlACE::LocalFile ("${role1}_${location1}_1.ior"); +my($replica6_ior) = PerlACE::LocalFile ("${role1}_${location2}_2.ior"); + +my($replica1_iogr) = PerlACE::LocalFile ("${role1}_0.iogr"); +my($replica2_iogr) = PerlACE::LocalFile ("${role2}_1.iogr"); +my($replica3_iogr) = PerlACE::LocalFile ("${role1}_2.iogr"); + +my($client_data) = PerlACE::LocalFile ("persistent.dat"); + +#discard junk from previous tests +unlink $rm_ior; +unlink $notifier_ior; +unlink $detector1_ior; +unlink $detector2_ior; +unlink $factory1_ior; +unlink $factory2_ior; +unlink $factory3_ior; +unlink $replica1_ior; +unlink $replica2_ior; +unlink $replica3_ior; +unlink $replica4_ior; +unlink $replica5_ior; +unlink $replica6_ior; +unlink $replica1_iogr; +unlink $replica2_iogr; + +unlink $client_data; + +my($status) = 0; + +my($RM) = new PerlACE::Process ("$ENV{'TAO_ROOT'}/orbsvcs/FT_ReplicationManager$build_directory/FT_ReplicationManager", "-o $rm_ior $rm_endpoint"); +my($RMC) = new PerlACE::Process (".$build_directory/replmgr_controller", "$rm_initref -x"); +my($NOT) = new PerlACE::Process ("$ENV{'TAO_ROOT'}/orbsvcs/Fault_Notifier$build_directory/Fault_Notifier", "$rm_initref -o $notifier_ior -q"); +my($DET1) = new PerlACE::Process ("$ENV{'TAO_ROOT'}/orbsvcs/Fault_Detector$build_directory/Fault_Detector", "$rm_initref -o $detector1_ior -l $location1 -q"); +my($DET2) = new PerlACE::Process ("$ENV{'TAO_ROOT'}/orbsvcs/Fault_Detector$build_directory/Fault_Detector", "$rm_initref -o $detector2_ior -l $location2 -q"); +my($FAC1) = new PerlACE::Process (".$build_directory/ft_replica", "$rm_initref -o $factory1_ior -l $location1 -i $role1 -q"); +my($FAC2) = new PerlACE::Process (".$build_directory/ft_replica", "$rm_initref -o $factory2_ior -l $location2 -i $role1 -i $role2 -q"); +my($FAC3) = new PerlACE::Process (".$build_directory/ft_replica", "$rm_initref -o $factory3_ior -l $location3 -i $role2 -q"); + +my($OGC); +my($CL1); +my($CL2); +my($CL3); +if ($simulated) { + print "\nTEST: Preparing Client Mediated Fault Tolerance test.\n" if ($verbose); + $OGC= new PerlACE::Process (".$build_directory/ft_create", "$rm_initref -r $role1 -r $role2 -r $role1 -i -n"); + $CL1 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica1_ior -f file://$replica2_ior -c testscript"); + $CL2 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica3_ior -f file://$replica4_ior -c testscript"); + $CL3 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica5_ior -f file://$replica6_ior -c testscript"); +}else{ + print "\nTEST: Preparing IOGR based test.\n" if ($verbose); + $OGC = new PerlACE::Process (".$build_directory/ft_create", "$rm_initref -r $role1 -r $role2 -r $role1 -g -n"); + $CL1 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica1_iogr -c testscript"); + $CL2 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica2_iogr -c testscript"); + $CL3 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica3_iogr -c testscript"); +} + +####################### +# Start ReplicationManager + +print "\nTEST: Starting ReplicationManager " . $RM->CommandLine . "\n" if ($verbose); +$RM->Spawn (); + +print "TEST: waiting for registry's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($rm_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$rm_ior>\n"; + $RM->Kill (); $RM->TimedWait (1); + exit 1; +} + +####################### +# Start FaultNotifier +print "\nTEST: Starting FaultNotifier " . $NOT->CommandLine . "\n" if ($verbose); +$NOT->Spawn (); + +print "TEST: waiting for FaultNotifier's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($notifier_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$notifier_ior>\n"; + $RM->Kill (); $RM->TimedWait (1); + $NOT->Kill (); $NOT->TimedWait (1); + exit 1; +} + + +############################## +# Start FaultDetectorFactory 1 +print "\nTEST: Starting FaultDetectorFactory at $location1 " . $DET1->CommandLine . "\n" if ($verbose); +$DET1->Spawn (); + +print "TEST: waiting for FaultDetector's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($detector1_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$detector1_ior>\n"; + $RM->Kill (); $RM->TimedWait (1); + $NOT->Kill (); $NOT->TimedWait (1); + $DET1->Kill (); $DET1->TimedWait (1); + exit 1; +} + +############################## +# Start FaultDetectorFactory 2 +print "\nTEST: Starting FaultDetectorFactory at $location2 " . $DET2->CommandLine . "\n" if ($verbose); +$DET2->Spawn (); + +print "TEST: waiting for FaultDetector's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($detector2_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$detector2_ior>\n"; + $RM->Kill (); $RM->TimedWait (1); + $NOT->Kill (); $NOT->TimedWait (1); + $DET1->Kill (); $DET1->TimedWait (1); + $DET2->Kill (); $DET2->TimedWait (1); + exit 1; +} + + +################# +# Start Factories + +print "\nTEST: Starting replica factory at $location1 " . $FAC1->CommandLine . "\n" if ($verbose); +$FAC1->Spawn (); + +print "TEST: waiting for factory 1's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($factory1_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$factory1_ior>\n"; + $RM->Kill (); $RM->TimedWait (1); + $NOT->Kill (); $NOT->TimedWait (1); + $DET1->Kill (); $DET1->TimedWait (1); + $DET2->Kill (); $DET2->TimedWait (1); + $FAC1->Kill (); $FAC1->TimedWait (1); + exit 1; +} + +print "\nTEST: Starting replica factory at $location2 " . $FAC2->CommandLine . "\n" if ($verbose); +$FAC2->Spawn (); + +print "TEST: waiting for factory 2's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($factory2_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$factory2_ior>\n"; + $RM->Kill (); $RM->TimedWait (1); + $NOT->Kill (); $NOT->TimedWait (1); + $DET1->Kill (); $DET1->TimedWait (1); + $DET2->Kill (); $DET2->TimedWait (1); + $FAC1->Kill (); $FAC1->TimedWait (1); + $FAC2->Kill (); $FAC2->TimedWait (1); + exit 1; +} + +print "\nTEST: Starting replica factory at $location3 " . $FAC3->CommandLine . "\n" if ($verbose); +$FAC3->Spawn (); + +print "TEST: waiting for factory 3's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($factory3_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$factory3_ior>\n"; + $RM->Kill (); $RM->TimedWait (1); + $NOT->Kill (); $NOT->TimedWait (1); + $DET1->Kill (); $DET1->TimedWait (1); + $DET2->Kill (); $DET2->TimedWait (1); + $FAC1->Kill (); $FAC1->TimedWait (1); + $FAC2->Kill (); $FAC2->TimedWait (1); + $FAC3->Kill (); $FAC3->TimedWait (1); + exit 1; +} + +###################### +# Create object groups + +print "\nTEST: Starting object group creator " . $OGC->CommandLine . "\n" if ($verbose); +$OGC->Spawn (); + +print "\nTEST: wait for object group creator.\n" if ($verbose); +$config = $OGC->WaitKill (30); +if ($config != 0) { + print STDERR "TEST ERROR: Object Group Creator returned $config\n"; + $RM->Kill (); $RM->TimedWait (1); + $NOT->Kill (); $NOT->TimedWait (1); + $DET1->Kill (); $DET1->TimedWait (1); + $DET2->Kill (); $DET2->TimedWait (1); + $FAC1->Kill (); $FAC1->TimedWait (1); + $FAC2->Kill (); $FAC2->TimedWait (1); + $FAC3->Kill (); $FAC3->TimedWait (1); + exit 1; +} + +############# +# Run clients + +print "\nTEST: Starting client using first group of hobbits " . $CL1->CommandLine . "\n" if ($verbose); +$client = $CL1->SpawnWaitKill (60); + +if ($client != 0) { + print STDERR "TEST ERROR: client returned $client\n"; + $status = 1; +} + +print "\nTEST: Starting client using group of elves " . $CL2->CommandLine . "\n" if ($verbose); +$client2 = $CL2->SpawnWaitKill (60); + +if ($client2 != 0) { + print STDERR "TEST ERROR: client returned $client2\n"; + $status = 1; +} + +print "\nTEST: Starting client using second group of hobbits " . $CL3->CommandLine . "\n" if ($verbose); +$client3 = $CL3->SpawnWaitKill (60); + +if ($client3 != 0) { + print STDERR "TEST ERROR: client returned $client3\n"; + $status = 1; +} + +###################### +# Clean house and exit + +print "\nTEST: wait for factory 1.\n" if ($verbose); +$factory1 = $FAC1->WaitKill (30); +if ($factory1 != 0) { + print STDERR "TEST ERROR: replica returned $factory 1\n"; + $status = 1; +} + +print "\nTEST: wait for factory 2.\n" if ($verbose); +$factory2 = $FAC2->WaitKill (30); +if ($factory2 != 0) { + print STDERR "TEST ERROR: factory 2 returned $factory2\n"; + $status = 1; +} + +print "\nTEST: wait for factory 3.\n" if ($verbose); +$factory3 = $FAC3->WaitKill (30); +if ($factory3 != 0) { + print STDERR "TEST ERROR: factory 3 returned $factory3\n"; + $status = 1; +} + +print "\nTEST: wait for FaultDetectorFactory 1.\n" if ($verbose); +$detector1 = $DET1->WaitKill (30); +if ($detector1 != 0) { + print STDERR "TEST ERROR: FaultDetectorFactory returned $detector1\n"; + $status = 1; +} + +print "\nTEST: wait for FaultDetectorFactory 2.\n" if ($verbose); +$detector2 = $DET2->WaitKill (30); +if ($detector2 != 0) { + print STDERR "TEST ERROR: FaultDetectorFactory returned $detector2\n"; + $status = 1; +} + +print "\nTEST: shutting down the replication manager.\n" if ($verbose); +$controller = $RMC->SpawnWaitKill (300); +if ($controller != 0) { + print STDERR "TEST ERROR: replication manager controller returned $controller\n"; + $status = 1; +} + +print "\nTEST: wait for ReplicationManager.\n" if ($verbose); +#$RM->Kill (); +$repmgr = $RM->WaitKill (30); +if ($repmgr != 0) { + print STDERR "TEST ERROR: ReplicationManager returned $repmgr\n"; + $status = 1; +} + +print "\nTEST: wait for FaultNotifier.\n" if ($verbose); +$notifier = $NOT->WaitKill (30); +if ($notifier != 0) { + print STDERR "TEST ERROR: FaultNotifier returned $notifier\n"; + $status = 1; +} + +if ($status == 0 && 0) { + print "\nTEST: releasing scratch files.\n" if ($verbose); + unlink $rm_ior; + unlink $detector1_ior; + unlink $detector2_ior; + unlink $notifier_ior; + unlink $factory1_ior; + unlink $factory2_ior; + unlink $factory3_ior; + unlink $replica1_ior; + unlink $replica2_ior; + unlink $replica3_ior; + unlink $replica4_ior; + unlink $replica5_ior; + unlink $replica6_ior; + unlink $replica1_iogr; + unlink $replica2_iogr; + + unlink $client_data; +} + + +exit $status; diff --git a/TAO/orbsvcs/tests/FT_App/run_test_detector.pl b/TAO/orbsvcs/tests/FT_App/run_test_detector.pl new file mode 100755 index 00000000000..f7886fb6dab --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/run_test_detector.pl @@ -0,0 +1,221 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +# Purpose: +# To test the FaultDetectorFactory and FaultDetectors +# +# Command line options: +# --debug_build use exes from this directory +# if not specified use exes from ./release +# -v display test progress messages (repeating option increases verbosity +# +# Process being tested: +# Fault_Detector +# implements FaultDetectorFactory interface +# implements PullMonitorable interface +# +# Processes used in test: +# FT_Replica +# implements TestReplica interface. +# implements PullMonitorable. +# StubNotifier +# implements FaultNotifier interface (as a stub.) +# implements PullMonitorable. +# client for FaultDetectorFactory interface. +# FT_Client +# client for TestReplica interface. +# client for PullMonitorable. +# +# Test Scenario ( ***Test: marks behavior being tested): +# Start two FT_Replicas +# FT_Replicas write TestReplica IORs (FR#1 and FR#2) to files +# Start the Fault_Detector +# Fault_Detector writes its IOR (FDF) to a file +# Wait for IORs: FR#1, FR#2, and FDF +# Start the StubNotifier giving it IORS: FR#1, FR#2 and FDF +# StubNotifier calls FDF to create a FaultDetector +# for each Replica. +# StubNotifier writes FaultNotifier IOR (FN) to a file. +# Wait for IOR: FN +# Start FT_Client giving it IORS: FR#1 and FR#2. +# FT_Client interacts with FR#1. +# FT_Client asks FR#1 to fault. It does so. +# FT_Client notices fault and switches to FR#2. +# ***Test: FD#1 notices fault and notifies StubNotifier +# ***Test: FD#1 terminates +# FT_Client interacts with FR#2. +# FT_Client asks FR#2 to shut down. +# FT_Client shuts down. +# ***Test: FD#2 notices FR2 is gone, interprets this +# as a fault, and notifies StubNotifier. +# ***Test: FD#2 terminates. +# Shut down +# ***Test: FDF is idle, so it terminates. +# StubNotifier sees FDF terminate, so it terminates +# Cleanup +# Wait for all processes to terminate. +# Check termination status. +# Delete temp files. +# +use lib '../../../../bin'; +use PerlACE::Run_Test; + +######################## +#command line options +#set defaults: +my($verbose) = 0; # 1: report perl actions before executing them; 2 display settings from command line +my($debug_builds) = 0; # 0: use exes from Release directories +my($simulated) = 1; # 1: use "client simulated" fault tolerance + +foreach $i (@ARGV) { + if ($i eq "--debug_build") + { + $debug_builds = 1; + } + elsif ($i eq "-v") + { + $verbose += 1; + } +} + + +my($build_directory) = "/Release"; +if ( $debug_builds ) { + $build_directory = ""; +} + +if ( $verbose > 1) { + print "verbose: $verbose\n"; + print "debug_builds: $debug_builds -> $build_directory\n"; + print "simulated: $simulated\n"; +} + + +#define temp files +my($factory1_ior) = PerlACE::LocalFile ("factory1.ior"); +my($factory2_ior) = PerlACE::LocalFile ("factory2.ior"); +my($replica1_ior) = PerlACE::LocalFile ("replica1.ior"); +my($replica2_ior) = PerlACE::LocalFile ("replica2.ior"); +my($detector_ior) = PerlACE::LocalFile ("detector.ior"); +my($notifier_ior) = PerlACE::LocalFile ("notifier.ior"); +my($client_data) = PerlACE::LocalFile ("persistent.dat"); + +#discard junk from previous tests +unlink $factory1_ior; +unlink $factory2_ior; +unlink $replica1_ior; +unlink $replica2_ior; +unlink $detector_ior; +unlink $notifier_ior; +unlink #client_data + +my($status) = 0; + +my ($rm_endpoint) = "-ORBEndpoint iiop://localhost:2833"; +my ($rm_initref) = "-ORBInitRef ReplicationManager=corbaloc::localhost:2833/ReplicationManager"; + + +my($REP1) = new PerlACE::Process (".$build_directory/ft_replica", "-o $factory1_ior -f none -t $replica1_ior -l loc1 -i type1 -q"); +my($REP2) = new PerlACE::Process (".$build_directory/ft_replica", "-o $factory2_ior -f none -t $replica2_ior -l loc2 -i type1 -q"); +my($DET) = new PerlACE::Process ("$ENV{'TAO_ROOT'}/orbsvcs/Fault_Detector$build_directory/Fault_Detector", "$rm_initref -o $detector_ior -q"); +my($NOT) = new PerlACE::Process (".$build_directory/ft_notifier", "-o $notifier_ior -q -d file://$detector_ior -r file://$replica1_ior -r file://$replica2_ior"); +my($CL) = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica1_ior -f file://$replica2_ior -c testscript"); + +print "TEST: starting replica1 ". $REP1->CommandLine . "\n" if ($verbose); +$REP1->Spawn (); + +print "TEST: waiting for replica 1's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($replica1_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$replica1_ior>\n"; + $REP1->Kill (); $REP1->TimedWait (1); + exit 1; +} + +print "\nTEST: starting replica2 " . $REP2->CommandLine . "\n" if ($verbose); +$REP2->Spawn (); + +print "TEST: waiting for replica 2's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($replica2_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$replica2_ior>\n"; + $REP1->Kill (); $REP1->TimedWait (1); + $REP2->Kill (); $REP2->TimedWait (1); + exit 1; +} + +print "\nTEST: starting detector factory " . $DET->CommandLine . "\n" if ($verbose); +$DET->Spawn (); + +print "TEST: waiting for detector's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($detector_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$detector_ior>\n"; + $REP1->Kill (); $REP1->TimedWait (1); + $REP2->Kill (); $REP2->TimedWait (1); + $DET->Kill (); $DET2->TimedWait(1); + exit 1; +} + +print "\nTEST: starting notifier " . $NOT->CommandLine . "\n" if ($verbose); +$NOT->Spawn (); + +print "TEST: waiting for notifier's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($notifier_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$notifier_ior>\n"; + $REP1->Kill (); $REP1->TimedWait (1); + $REP2->Kill (); $REP2->TimedWait (1); + $DET->Kill (); $DET2->TimedWait(1); + $NOT->Kill (); $NOT->TimedWait(1); + exit 1; +} + +print "\nTEST: starting client." . $CL->CommandLine . "\n" if ($verbose); +$client = $CL->SpawnWaitKill (60); + +if ($client != 0) { + print STDERR "TEST ERROR: client returned $client\n"; + $status = 1; +} + +print "\nTEST: wait for replica 1.\n" if ($verbose); +$replica1 = $REP1->WaitKill (60); +if ($replica1 != 0) { + print STDERR "TEST ERROR: replica returned $replica1\n"; + $status = 1; +} + +print "\nTEST: wait for replica 2.\n" if ($verbose); +$replica2 = $REP2->WaitKill (60); +if ($replica2 != 0) { + print STDERR "TEST ERROR: replica returned $replica2\n"; + $status = 1; +} + +print "\nTEST: wait for detector factory to leave.\n" if ($verbose); +$detector = $DET->WaitKill (60); +if ($detector != 0) { + print STDERR "TEST ERROR: detector returned $detector\n"; + $status = 1; +} + +print "\nTEST: wait for notifier to leave.\n" if ($verbose); +$notifier = $NOT->WaitKill (60); +if ($notifier != 0) { + print STDERR "TEST ERROR: notifier returned $notifier\n"; + $status = 1; +} + +print "\nTEST: releasing scratch files.\n" if ($verbose); +unlink $factory1_ior; +unlink $factory2_ior; +unlink $replica1_ior; +unlink $replica2_ior; +unlink $detector_ior; +unlink $notifier_ior; + +#client's work file +unlink #client_data; + +exit $status; diff --git a/TAO/orbsvcs/tests/FT_App/run_test_fault_consumer.pl b/TAO/orbsvcs/tests/FT_App/run_test_fault_consumer.pl new file mode 100755 index 00000000000..bfb3f98db2a --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/run_test_fault_consumer.pl @@ -0,0 +1,270 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +# Purpose: +# To test the FaultConsumer +# +# Process being tested: +# Fault_Consumer +# implements FaultConsumer interface. +# Processes used in test: +# FT_Replica +# implements TestReplica interface. +# implements PullMonitorable. +# Fault_Detector +# implements FaultDetectorFactory interface +# implements PullMonitorable interface +# FT_Client +# client for TestReplica interface. +# client for PullMonitorable. +# Fault_Notifier +# implements the FaultNotifier interface. +# propagates fault reports to the FaultConsumer. +# +# Test Scenario (***Test: marks behavior being tested): +# Phase 1: +# Start two FT_Replicas +# FT_Replicas write TestReplica IORs (FR#1 and FR#2) to files +# Start the Fault_Detector +# Fault_Detector writes its IOR (FDF) to a file +# Start the Fault_Notifier +# Fault_Notifier writes its IOR (FN) to a file. +# Start the Fault_Consumer +# Subscribes to the Fault_Notifier for fault reports. +# Phase 2: +# Wait for IORs: FR#1, FR#2, FDF, and FN +# Start the StubAnalyzer giving it IORS: FR#1, FR#2 FDF, FN +# StubAnalyzer calls FDF to create a FaultDetector +# for each Replica. +# StubAnalyzer subscribes to Fault_Notifier +# StubAnalyzer writes dummy message(READY) to a file. +# Phase 3: +# Wait for READY +# Start FT_Client giving it IORS: FR#1 and FR#2. [1] +# FT_Client interacts with FR#1. +# FT_Client asks FR#1 to fault. It does so. +# FT_Client notices fault and switches to FR#2. [1] +# FD#1 notices fault and notifies Fault_Notifier +# FD#1 terminates +# ***Test: Fault_Notifier forwards notification to StubAnalyzer +# StubAnalyzer prints notification. +# FT_Client interacts with FR#2. +# FT_Client asks FR#2 to shut down. +# FT_Client shuts down. +# FD#2 notices FR2 is gone, interprets this +# as a fault, and sends notification to Fault_Notifier +# FD#2 terminates. +# ***Test: Fault_Notifier forwards notification to StubAnalyzer +# StubAnalyzer prints notification. +# Phase 4: shutting down. +# All FaultDetectors have terminated so the FaultDetectorFactory +# honors the "quit-on-idle" option on it's command line and exits. +# StubAnalyzer compares # fault notifications to # replicas. When +# they match, it "knows" that the test is over, so it shuts down. +# As it does so, it disconnects its fault consumers from the FaultNotifier. +# FaultNotifier notices the last fault consumer disconnecting and exits because +# the "quit-on-idle" option was specified on the command line. +# Phase 5: housekeeping +# Wait for all processes to terminate. +# Check termination status. +# Delete temp files. +# +# [1] Client mediated fault tolerance. These points will +# change when IOGR support is available. +use lib '../../../../bin'; +#use lib '$ENV{ACE_ROOT}/bin'; +use PerlACE::Run_Test; + +######################## +#command line options +#set defaults: +my($verbose) = 0; # 1: report perl actions before executing them +my($debug_builds) = 0; # 0: use exes from Release directories +my($simulated) = 1; # 1: use "client simulated" fault tolerance + +foreach $i (@ARGV) { + if ($i eq "--debug_build") + { + $debug_builds = 1; + } + elsif ($i eq "--no_simulate") # reverse this once we have FT ORB support + { + $simulated = 0; + } + elsif ($i eq "-v") + { + $verbose += 1; + } +} + + +my($build_directory) = "/Release"; +if ( $debug_builds ) { + $build_directory = ""; +} + +if ( $verbose > 1) { + print "verbose: $verbose\n"; + print "debug_builds: $debug_builds -> $build_directory\n"; + print "simulated: $simulated\n"; +} + + +#define temp files +my($factory1_ior) = PerlACE::LocalFile ("factory1.ior"); +my($factory2_ior) = PerlACE::LocalFile ("factory2.ior"); +my($replica1_ior) = PerlACE::LocalFile ("replica1.ior"); +my($replica2_ior) = PerlACE::LocalFile ("replica2.ior"); +my($detector_ior) = PerlACE::LocalFile ("detector.ior"); +my($notifier_ior) = PerlACE::LocalFile ("notifier.ior"); +my($ready_file) = PerlACE::LocalFile ("ready.file"); +my($client_data) = PerlACE::LocalFile ("persistent.dat"); + +#discard junk from previous tests +unlink $factory1_ior; +unlink $factory2_ior; +unlink $replica1_ior; +unlink $replica2_ior; +unlink $detector_ior; +unlink $notifier_ior; +unlink $ready_file; +unlink $client_data; + +my ($rm_endpoint) = "-ORBEndpoint iiop://localhost:2833"; +my ($rm_initref) = "-ORBInitRef ReplicationManager=corbaloc::localhost:2833/ReplicationManager"; + +my($status) = 0; + +my($REP1) = new PerlACE::Process (".$build_directory/ft_replica", "-f none -o $factory1_ior -t $replica1_ior -l loc1 -i type1 -q"); +my($REP2) = new PerlACE::Process (".$build_directory/ft_replica", "-f none -o $factory2_ior -t $replica2_ior -l loc2 -i type1 -q"); +my($DET) = new PerlACE::Process ("$ENV{'TAO_ROOT'}/orbsvcs/Fault_Detector$build_directory/Fault_Detector", "-r -o $detector_ior -q"); +my($NOT) = new PerlACE::Process ("$ENV{'TAO_ROOT'}/orbsvcs/Fault_Notifier$build_directory/Fault_Notifier", "-r -o $notifier_ior -q"); +my($CONS) = new PerlACE::Process (".$build_directory/ft_fault_consumer", "-o $ready_file -n file://$notifier_ior -q -d file://$detector_ior -r file://$replica1_ior -r file://$replica2_ior"); + +my($CL); +if ($simulated) { + print "\nTEST: Preparing Client Mediated Fault Tolerance test.\n" if ($verbose); + $CL = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica1_ior -f file://$replica2_ior -c testscript"); +}else{ + print "\nTEST: Preparing IOGR based test.\n" if ($verbose); + $CL = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica1_iogr -c testscript"); +} + +print "TEST: starting replica1 " . $REP1->CommandLine . "\n" if ($verbose); +$REP1->Spawn (); + +print "TEST: waiting for replica 1's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($replica1_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$replica1_ior>\n"; + $REP1->Kill (); $REP1->TimedWait (1); + exit 1; +} + +print "\nTEST: starting replica2 " . $REP2->CommandLine . "\n" if ($verbose); +$REP2->Spawn (); + +print "TEST: waiting for replica 2's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($replica2_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$replica2_ior>\n"; + $REP1->Kill (); $REP1->TimedWait (1); + $REP2->Kill (); $REP2->TimedWait (1); + exit 1; +} + +print "\nTEST: starting detector factory " . $DET->CommandLine . "\n" if ($verbose); +$DET->Spawn (); + +print "TEST: waiting for detector's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($detector_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$detector_ior>\n"; + $REP1->Kill (); $REP1->TimedWait (1); + $REP2->Kill (); $REP2->TimedWait (1); + $DET->Kill (); $DET->TimedWait(1); + exit 1; +} + +print "\nTEST: starting notifier " . $NOT->CommandLine . "\n" if ($verbose); +$NOT->Spawn (); + +print "TEST: waiting for notifier's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($notifier_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$notifier_ior>\n"; + $REP1->Kill (); $REP1->TimedWait (1); + $REP2->Kill (); $REP2->TimedWait (1); + $DET->Kill (); $DET->TimedWait(1); + $NOT->Kill (); $NOT->TimedWait(1); + exit 1; +} + +print "\nTEST: starting fault consumer " . $CONS->CommandLine . "\n" if ($verbose); +$CONS->Spawn (); + +print "TEST: waiting for READY.FILE from fault consumer\n" if ($verbose); +if (PerlACE::waitforfile_timed ($ready_file, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$ready_file>\n"; + $REP1->Kill (); $REP1->TimedWait (1); + $REP2->Kill (); $REP2->TimedWait (1); + $DET->Kill (); $DET->TimedWait(1); + $NOT->Kill (); $NOT->TimedWait(1); + $CONS->Kill (); $CONS->TimedWait(1); + exit 1; +} + +print "\nTEST: starting client " . $CL->CommandLine . "\n" if ($verbose); +$client = $CL->SpawnWaitKill (60); + +if ($client != 0) { + print STDERR "TEST ERROR: client returned $client\n"; + $status = 1; +} + +print "\nTEST: wait for replica 1.\n" if ($verbose); +$replica1 = $REP1->WaitKill (5); +if ($replica1 != 0) { + print STDERR "TEST ERROR: replica returned $replica1\n"; + $status = 1; +} + +print "\nTEST: wait for replica 2.\n" if ($verbose); +$replica2 = $REP2->WaitKill (5); +if ($replica2 != 0) { + print STDERR "TEST ERROR: replica returned $replica2\n"; + $status = 1; +} + +print "\nTEST: wait for detector factory to leave.\n" if ($verbose); +$detector = $DET->WaitKill (20); +if ($detector != 0) { + print STDERR "TEST ERROR: detector returned $detector\n"; + $status = 1; +} + +print "\nTEST: wait for notifier to leave.\n" if ($verbose); +$notifier = $NOT->WaitKill (20); +if ($notifier != 0) { + print STDERR "TEST ERROR: notifier returned $notifier\n"; + $status = 1; +} + +print "\nTEST: wait for fault consumer to leave.\n" if ($verbose); +$consumer = $CONS->WaitKill (20); +if ($consumer != 0) { + print STDERR "TEST ERROR: fault consumer returned $consumer\n"; + $status = 1; +} + +print "\nTEST: releasing scratch files.\n" if ($verbose); +unlink $replica1_ior; +unlink $replica2_ior; +unlink $detector_ior; +unlink $notifier_ior; +unlink $ready_file; + +#client's work file +unlink $client_data; + +exit $status; diff --git a/TAO/orbsvcs/tests/FT_App/run_test_notifier.pl b/TAO/orbsvcs/tests/FT_App/run_test_notifier.pl new file mode 100755 index 00000000000..521860b7ac3 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/run_test_notifier.pl @@ -0,0 +1,248 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +# Purpose: +# To test the FaultNotifier +# +# Command line options: +# --debug_build use exes from this directory +# if not specified use exes from ./release +# -v display test progress messages (repeating option increases verbosity +# +# Process being tested: +# Fault_Notifier +# implements FaultNotifier interface. +# Processes used in test: +# FT_Replica +# implements TestReplica interface. +# implements PullMonitorable. +# Fault_Detector +# implements FaultDetectorFactory interface +# implements PullMonitorable interface +# FT_Client +# client for TestReplica interface. +# client for PullMonitorable. +# StubAnalyzer +# Subscribes to Fault_Notfier +# +# Test Scenario (***Test: marks behavior being tested): +# Start two FT_Replicas +# FT_Replicas write TestReplica IORs (FR#1 and FR#2) to files +# Start the Fault_Detector +# Fault_Detector writes its IOR (FDF) to a file +# Start the Fault_Notifier +# Fault_Notifier writes its IOR (FN) to a file. +# Start the StubAnalyzer giving it IORS: FR#1, FR#2 FDF, FN +# StubAnalyzer calls FDF to create a FaultDetector +# for each Replica. +# StubAnalyzer subscribes to Fault_Notifier +# StubAnalyzer writes dummy message(READY) to a file. +# Wait for READY +# Start FT_Client giving it IORS: FR#1 and FR#2. +# FT_Client interacts with FR#1. +# FT_Client asks FR#1 to fault. It does so. +# FT_Client notices fault and switches to FR#2. +# FD#1 notices fault and notifies Fault_Notifier +# FD#1 terminates +# ***Test: Fault_Notifier forwards notification to StubAnalyzer +# StubAnalyzer prints notification. +# FT_Client interacts with FR#2. +# FT_Client asks FR#2 to shut down. +# FT_Client shuts down. +# FD#2 notices FR2 is gone, interprets this +# as a fault, and sends notification to Fault_Notifier +# FD#2 terminates. +# ***Test: Fault_Notifier forwards notification to StubAnalyzer +# StubAnalyzer prints notification. +# Shutting down. +# All FaultDetectors have terminated so the FaultDetectorFactory +# honors the "quit-on-idle" option on it's command line and exits. +# StubAnalyzer compares # fault notifications to # replicas. When +# they match, it knows that the test is over, so it shuts down. +# As it does so, it disconnects its fault consumers from the FaultNotifier. +# FaultNotifier notices the last fault consumer disconnecting and exits because +# the "quit-on-idle" option was specified on the command line. +# Housekeeping +# Wait for all processes to terminate. +# Check termination status. +# Delete temp files. +# +use lib '../../../../bin'; +#use lib '$ENV{ACE_ROOT}/bin'; +use PerlACE::Run_Test; + +######################## +#command line options +#set defaults: +my($verbose) = 0; # 1: report perl actions before executing them +my($debug_builds) = 0; # 0: use exes from Release directories + +foreach $i (@ARGV) { + if ($i eq "--debug_build") + { + $debug_builds = 1; + } + elsif ($i eq "-v") + { + $verbose += 1; + } +} + +my($build_directory) = "/Release"; +if ( $debug_builds ) { + $build_directory = ""; +} + +if ( $verbose > 1) { + print "verbose: $verbose\n"; + print "debug_builds: $debug_builds -> $build_directory\n"; +} + + +#define temp files +my($factory1_ior) = PerlACE::LocalFile ("factory1.ior"); +my($factory2_ior) = PerlACE::LocalFile ("factory2.ior"); +my($replica1_ior) = PerlACE::LocalFile ("replica1.ior"); +my($replica2_ior) = PerlACE::LocalFile ("replica2.ior"); +my($detector_ior) = PerlACE::LocalFile ("detector.ior"); +my($notifier_ior) = PerlACE::LocalFile ("notifier.ior"); +my($ready_file) = PerlACE::LocalFile ("ready.file"); +my($client_data) = PerlACE::LocalFile ("persistent.dat"); + +#discard junk from previous tests +unlink $factory1_ior; +unlink $factory2_ior; +unlink $replica1_ior; +unlink $replica2_ior; +unlink $detector_ior; +unlink $notifier_ior; +unlink $ready_file; +unlink $client_data; + +my($status) = 0; + +my($REP1) = new PerlACE::Process (".$build_directory/ft_replica", "-o $factory1_ior -f none -t $replica1_ior -l loc1 -i type1 -q"); +my($REP2) = new PerlACE::Process (".$build_directory/ft_replica", "-o $factory2_ior -f none -t $replica2_ior -l loc2 -i type1 -q"); +my($DET) = new PerlACE::Process ("$ENV{'TAO_ROOT'}/orbsvcs/Fault_Detector$build_directory/Fault_Detector", "-r -o $detector_ior -q"); +my($NOT) = new PerlACE::Process ("$ENV{'TAO_ROOT'}/orbsvcs/Fault_Notifier$build_directory/Fault_Notifier", "-r -o $notifier_ior -q"); +my($ANA) = new PerlACE::Process (".$build_directory/ft_analyzer", "-o $ready_file -n file://$notifier_ior -d file://$detector_ior -r file://$replica1_ior -r file://$replica2_ior -q"); +my($CL) = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica1_ior -f file://$replica2_ior -c testscript"); + +print "TEST: starting replica1 " . $REP1->CommandLine . "\n" if ($verbose); +$REP1->Spawn (); + +print "TEST: waiting for replica 1's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($replica1_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$replica1_ior>\n"; + $REP1->Kill (); $REP1->TimedWait (1); + exit 1; +} + +print "\nTEST: starting replica2 " . $REP2->CommandLine . "\n" if ($verbose); +$REP2->Spawn (); + +print "TEST: waiting for replica 2's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($replica2_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$replica2_ior>\n"; + $REP1->Kill (); $REP1->TimedWait (1); + $REP2->Kill (); $REP2->TimedWait (1); + exit 1; +} + +print "\nTEST: starting detector factory " . $DET->CommandLine . "\n" if ($verbose); +$DET->Spawn (); + +print "TEST: waiting for detector's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($detector_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$detector_ior>\n"; + $REP1->Kill (); $REP1->TimedWait (1); + $REP2->Kill (); $REP2->TimedWait (1); + $DET->Kill (); $DET2->TimedWait(1); + exit 1; +} + +print "\nTEST: starting notifier " . $NOT->CommandLine . "\n" if ($verbose); +$NOT->Spawn (); + +print "TEST: waiting for notifier's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($notifier_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$notifier_ior>\n"; + $REP1->Kill (); $REP1->TimedWait (1); + $REP2->Kill (); $REP2->TimedWait (1); + $DET->Kill (); $DET2->TimedWait(1); + $ANA->Kill (); $ANA->TimedWait(1); + exit 1; +} + +print "\nTEST: starting analyzer " . $ANA->CommandLine . "\n" if ($verbose); +$ANA->Spawn (); + +print "TEST: waiting for READY.FILE from analyzer\n" if ($verbose); +if (PerlACE::waitforfile_timed ($ready_file, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$ready_file>\n"; + $REP1->Kill (); $REP1->TimedWait (1); + $REP2->Kill (); $REP2->TimedWait (1); + $DET->Kill (); $DET2->TimedWait(1); + $NOT->Kill (); $NOT->TimedWait(1); + $ANA->Kill (); $ANA->TimedWait(1); + exit 1; +} + +print "\nTEST: starting client " . $CL->CommandLine . "\n" if ($verbose); +$client = $CL->SpawnWaitKill (60); + +if ($client != 0) { + print STDERR "TEST ERROR: client returned $client\n"; + $status = 1; +} + +print "\nTEST: wait for replica 1.\n" if ($verbose); +$replica1 = $REP1->WaitKill (5); +if ($replica1 != 0) { + print STDERR "TEST ERROR: replica returned $replica1\n"; + $status = 1; +} + +print "\nTEST: wait for replica 2.\n" if ($verbose); +$replica2 = $REP2->WaitKill (5); +if ($replica2 != 0) { + print STDERR "TEST ERROR: replica returned $replica2\n"; + $status = 1; +} + +print "\nTEST: wait for detector factory to leave.\n" if ($verbose); +$detector = $DET->WaitKill (20); +if ($detector != 0) { + print STDERR "TEST ERROR: detector returned $detector\n"; + $status = 1; +} + +print "\nTEST: wait for notifier to leave.\n" if ($verbose); +$notifier = $NOT->WaitKill (20); +if ($notifier != 0) { + print STDERR "TEST ERROR: notifier returned $notifier\n"; + $status = 1; +} + +print "\nTEST: wait for analyzer to leave.\n" if ($verbose); +$analyzer = $ANA->WaitKill (20); +if ($analyzer != 0) { + print STDERR "TEST ERROR: analyzer returned $analyzer\n"; + $status = 1; +} + +print "\nTEST: releasing scratch files.\n" if ($verbose); +unlink $replica1_ior; +unlink $replica2_ior; +unlink $detector_ior; +unlink $notifier_ior; +unlink $ready_file; + +#client's work file +unlink $client_data; + +exit $status; diff --git a/TAO/orbsvcs/tests/FT_App/run_test_registry.pl b/TAO/orbsvcs/tests/FT_App/run_test_registry.pl new file mode 100755 index 00000000000..dd73b739a52 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/run_test_registry.pl @@ -0,0 +1,438 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +# Purpose: +# To test the FactoryRegistry either as a stand-alone application or as part +# of the replication manager +# +# Command line options: +# --debug_build use exes from this directory +# if not specified use exes from ./release +# -r use ReplicationManager rather than stand-alone factory +# --no_simulate +# use real IOGR-based recovery. +# -v display test progress messages (repeating option increases verbosity +# +# Process being tested: +# FT_Registry +# implements PortableGroup::FactoryRegistry interface. +# or +# FT_ReplicationManager (if -r option is used) +# +# Processes used in test: +# FT_Replica * 3 +# implements GenericFactory interface to create TestReplicas +# TestReplica implements TestReplica interface. +# TestReplica implements PullMonitorable interface. +# FT_Client +# client for TestReplica interface. +# client for PullMonitorable. +# Object Group Creator +# Creates groups of objects. +# +# Test Scenario (***Test: marks behavior being tested): +# +# First the test starts a factory registry, +# Then starts three factories. Each factory exists at a separate location. +# The locations are named shire, bree, and rivendell. In a "real" system +# these locations would be on separate computers. +# +# The factory at the shire location knows how to create hobbits. +# The factory at the bree location knows how to create hobbits, elves, and humans. +# The factory at rivendell can create elves. +# Hobbits, elves, and humans are actually TestReplica objects. A creation parameter +# included as part of the registration information specifies which species they are. +# +# ***Test: The factories register themselves with the factory registry. Registration +# information includes the location, the type of object created, a object reference +# to the factory and set of parameters to be passed to the factory's create_object +# method. +# +# An object group creator is started and asked to create three object groups: +# a group of hobbits, a group of elves; and another group of hobbits. +# +# ***Test: the object group creator asks the registry for the set of factories +# that can create the type of object needed, then uses the create_object method +# for each factory to create the actual object. +# +# [temporary until IOGR's are working: The object group creator writes the +# IOR's of the create objects to files -- using a file naming convention to +# distinguish members of the group. It will be enhanced to assemble these +# IORs into an IOGR and either write the IOGR to a file or register it with +# the Naming Service.] +# +# The object group creator is also told to unregister all factories that create humans. +# ***Test: It does so using the unregister_factory_by_type method. +# +# Three clients are started, one at a time. Each client is given a reference +# to an object group +# +# [temporary until IOGRs and transparent reinvocaton work: each client is +# given references to the members of the group and manages its own recovery +# (client mediated fault tolerance)] +# +# Each client sends a few requests to first member of the object group. Eventually +# this member fails and the requests are then rerouted to the second (and last) +# member of the group. +# +# When a clients job is done, it exits and asks the remaining group member to +# exit, too. +# +# The factories are run with the quit-on-idle option so when the last object +# created at that location goes away, the factory exits. +# +# ***Test: As it exits the factory unregisters itself with the factory registry. +# ***Test: A command line option determines whether it uses a single +# unregister_factory_by_location call, or separate unregister_factory calles for +# each type of object created. In this test, the shire location uses unregister_factory, +# and bree and rivendell use unregister_factory_by_location. +# +# The factory registry is also run with the quit-on-idle option so when the last +# factory unregisters itself, the factory registry shuts down to end the test. + +use lib '../../../../bin'; +#use lib '$ENV{ACE_ROOT}/bin'; +use PerlACE::Run_Test; + +######################## +#command line options +#set defaults: +my($verbose) = 0; # 1: report perl actions before executing them +my($debug_builds) = 0; # 0: use exes from Release directories +my($simulated) = 1; # 1: use "client simulated" fault tolerance +my($use_rm) = 0; # 1: use replication manager; 0 use stand-alone factory registry + +foreach $i (@ARGV) { + if ($i eq "--debug_build") + { + $debug_builds = 1; + } + elsif ($i eq "-r") # use RegistrationManager + { + $use_rm = 1 + } + elsif ($i eq "--no_simulate") # reverse this once we have FT ORB support + { + $simulated = 0; + } + elsif ($i eq "-v") + { + $verbose += 1; + } + else + { + print "unknown option $i. Expecting: --debug_build, -r --no_simulate, -v\n"; + exit(-1); + } +} + +my($build_directory) = "/Release"; +if ( $debug_builds ) { + $build_directory = ""; +} + +if ( $verbose > 1) { + print "verbose: $verbose\n"; + print "debug_builds: $debug_builds -> $build_directory\n"; + print "simulated: $simulated\n"; +} + +my($species1) = "hobbit"; +my($species2) = "elf"; +my($species3) = "human"; +my($location1) = "shire"; +my($location2) = "bree"; +my($location3) = "rivendell"; +my($location4) = "rohan"; + +#define temp files +my($rm_ior) = PerlACE::LocalFile ("rm.ior"); +my($registry_ior) = PerlACE::LocalFile ("registry.ior"); +my($factory1_ior) = PerlACE::LocalFile ("factory1.ior"); +my($factory2_ior) = PerlACE::LocalFile ("factory2.ior"); +my($factory3_ior) = PerlACE::LocalFile ("factory3.ior"); +my($replica1_ior) = PerlACE::LocalFile ("${species1}_${location1}_0.ior"); +my($replica2_ior) = PerlACE::LocalFile ("${species1}_${location2}_0.ior"); +my($replica3_ior) = PerlACE::LocalFile ("${species2}_${location2}_1.ior"); +my($replica4_ior) = PerlACE::LocalFile ("${species2}_${location3}_0.ior"); +my($replica5_ior) = PerlACE::LocalFile ("${species1}_${location1}_1.ior"); +my($replica6_ior) = PerlACE::LocalFile ("${species1}_${location2}_2.ior"); + +my($replica1_iogr) = PerlACE::LocalFile ("${species1}_0.iogr"); +my($replica2_iogr) = PerlACE::LocalFile ("${species2}_1.iogr"); +my($replica3_iogr) = PerlACE::LocalFile ("${species1}_2.iogr"); + +my($client_data) = PerlACE::LocalFile ("persistent.dat"); + +#discard junk from previous tests +unlink $rm_ior; +unlink $registry_ior; +unlink $factory1_ior; +unlink $factory2_ior; +unlink $factory3_ior; +unlink $replica1_ior; +unlink $replica2_ior; +unlink $replica3_ior; +unlink $replica4_ior; +unlink $replica5_ior; +unlink $replica6_ior; +unlink $replica1_iogr; +unlink $replica2_iogr; + +unlink $client_data; + +my($status) = 0; + +my ($rm_endpoint) = "-ORBEndpoint iiop://localhost:2833"; +my ($registry_opt) = "-f file://$registry_ior"; + +if ($use_rm) { + $registry_opt = "-ORBInitRef ReplicationManager=corbaloc::localhost:2833/ReplicationManager"; +} + +my($RM) = new PerlACE::Process ("$ENV{'TAO_ROOT'}/orbsvcs/FT_ReplicationManager$build_directory/FT_ReplicationManager", "-ORBDebugLevel 0 -o $rm_ior $rm_endpoint"); +my($RMC) = new PerlACE::Process (".$build_directory/replmgr_controller", "$registry_opt -x"); +my($REG) = new PerlACE::Process (".$build_directory/ft_registry", "-o $registry_ior -q"); +my($FAC1) = new PerlACE::Process (".$build_directory/ft_replica", "-o $factory1_ior $registry_opt -l $location1 -i $species1 -q"); +my($FAC2) = new PerlACE::Process (".$build_directory/ft_replica", "-o $factory2_ior $registry_opt -l $location2 -i $species1 -i $species2 -i $species3 -q -u"); +my($FAC3) = new PerlACE::Process (".$build_directory/ft_replica", "-o $factory3_ior $registry_opt -l $location3 -i $species2 -q -u"); + # -n means no name service -i means write individual iors +my($CTR) = new PerlACE::Process (".$build_directory/ft_create", "$registry_opt -r $species1 -r $species2 -r $species1 -u $species3 -n -i"); + +my($CL1); +my($CL2); +my($CL3); +if ($simulated) +{ + print "\nTEST: Preparing Client Mediated Fault Tolerance test.\n" if ($verbose); + $CL1 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica1_ior -f file://$replica2_ior -c testscript"); + $CL2 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica3_ior -f file://$replica4_ior -c testscript"); + $CL3 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica5_ior -f file://$replica6_ior -c testscript"); +} +else +{ + print "\nTEST: Preparing IOGR based test.\n" if ($verbose); + $CL1 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica1_iogr -c testscript"); + $CL2 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica2_iogr -c testscript"); + $CL3 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica3_iogr -c testscript"); +} + +####################### +# Start FactoryRegistry +if ($use_rm) +{ + print "\nTEST: starting ReplicationManager " . $RM->CommandLine . "\n" if ($verbose); + $RM->Spawn (); + + print "TEST: waiting for registry's IOR\n" if ($verbose); + if (PerlACE::waitforfile_timed ($rm_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$rm_ior>\n"; + $RM->Kill (); $RM->TimedWait (1); + exit 1; + } +} +else +{ + print "\nTEST: starting registry " . $REG->CommandLine . "\n" if ($verbose); + $REG->Spawn (); + + print "TEST: waiting for registry's IOR\n" if ($verbose); + if (PerlACE::waitforfile_timed ($registry_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$registry_ior>\n"; + $REG->Kill (); $REG->TimedWait (1); + exit 1; + } +} + +################# +# Start Factories + +print "\nTEST: starting factory 1 " . $FAC1->CommandLine . "\n" if ($verbose); +$FAC1->Spawn (); + +print "TEST: waiting for factory 1's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($factory1_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$factory1_ior>\n"; + $REG->Kill (); $REG->TimedWait (1); + $FAC1->Kill (); $FAC1->TimedWait (1); + exit 1; +} + +print "\nTEST: starting factory 2 " . $FAC2->CommandLine . "\n" if ($verbose); +$FAC2->Spawn (); + +print "TEST: waiting for factory 2's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($factory2_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$factory2_ior>\n"; + $FAC1->Kill (); $FAC1->TimedWait (1); + $REG->Kill (); $REG->TimedWait (1); + $FAC2->Kill (); $FAC2->TimedWait (1); + exit 1; +} + +print "\nTEST: starting factory 3 " . $FAC3->CommandLine . "\n" if ($verbose); +$FAC3->Spawn (); + +print "TEST: waiting for factory 3's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($factory3_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$factory3_ior>\n"; + $FAC1->Kill (); $FAC1->TimedWait (1); + $FAC2->Kill (); $FAC2->TimedWait (1); + $REG->Kill (); $REG->TimedWait (1); + $FAC3->Kill (); $FAC3->TimedWait (1); + exit 1; +} + +###################### +# Create object groups + +print "\nTEST: starting object group creator " . $CTR->CommandLine . "\n" if ($verbose); +$CTR->Spawn (); + +print "TEST: waiting for Replica IOR files from object group creator\n" if ($verbose); +if (PerlACE::waitforfile_timed ($replica1_ior, 5) == -1){ + print STDERR "TEST ERROR: cannot find file <$replica1_ior>\n"; + $status = 1; +} +elsif (PerlACE::waitforfile_timed ($replica2_ior, 5) == -1){ + print STDERR "TEST ERROR: cannot find file <$replica2_ior> \n"; + $status = 1; +} +elsif (PerlACE::waitforfile_timed ($replica3_ior, 5) == -1){ + print STDERR "TEST ERROR: cannot find file <$replica3_ior> \n"; + $status = 1; +} +elsif (PerlACE::waitforfile_timed ($replica4_ior, 5) == -1){ + print STDERR "TEST ERROR: cannot find file <$replica4_ior> \n"; + $status = 1; +} +elsif (PerlACE::waitforfile_timed ($replica5_ior, 5) == -1){ + print STDERR "TEST ERROR: cannot find file <$replica5_ior> \n"; + $status = 1; +} +elsif (PerlACE::waitforfile_timed ($replica6_ior, 5) == -1){ + print STDERR "TEST ERROR: cannot find file <$replica6_ior> \n"; + $status = 1; +} + +if($status != 0){ + $FAC3->Kill (); $FAC3->TimedWait (1); + $FAC2->Kill (); $FAC2->TimedWait (1); + $FAC1->Kill (); $FAC1->TimedWait (1); + $REG->Kill (); $REG->TimedWait (1); + $CTR->Kill (); $CTR->TimedWait(1); + exit 1; +} + +print "\nTEST: wait for object group creator.\n" if ($verbose); +$config = $CTR->WaitKill (5); +if ($config != 0) { + print STDERR "TEST ERROR: configuration manager returned $config\n"; + $FAC3->Kill (); $FAC3->TimedWait (1); + $FAC2->Kill (); $FAC2->TimedWait (1); + $FAC1->Kill (); $FAC1->TimedWait (1); + $REG->Kill (); $REG->TimedWait (1); + exit 1; +} + + +############# +# Run clients + +print "\nTEST: starting client " . $CL1->CommandLine . "\n" if ($verbose); +$client = $CL1->SpawnWaitKill (60); + +if ($client != 0) { + print STDERR "TEST ERROR: client returned $client\n"; + $status = 1; +} + +print "\nTEST: starting client again " . $CL2->CommandLine . "\n" if ($verbose); +$client2 = $CL2->SpawnWaitKill (60); + +if ($client2 != 0) { + print STDERR "TEST ERROR: client returned $client2\n"; + $status = 1; +} + +print "\nTEST: starting client, one more time with feeling " . $CL3->CommandLine . "\n" if ($verbose); +$client3 = $CL3->SpawnWaitKill (60); + +if ($client3 != 0) { + print STDERR "TEST ERROR: client returned $client3\n"; + $status = 1; +} + +###################### +# Clean house and exit + +print "\nTEST: wait for factory 1.\n" if ($verbose); +$factory1 = $FAC1->WaitKill (30); +if ($factory1 != 0) { + print STDERR "TEST ERROR: replica returned $factory 1\n"; + $status = 1; +} + +print "\nTEST: wait for factory 2.\n" if ($verbose); +$factory2 = $FAC2->WaitKill (30); +if ($factory2 != 0) { + print STDERR "TEST ERROR: factory 2 returned $factory2\n"; + $status = 1; +} + +print "\nTEST: wait for factory 3.\n" if ($verbose); +$factory3 = $FAC3->WaitKill (30); +if ($factory3 != 0) { + print STDERR "TEST ERROR: factory 3 returned $factory3\n"; + $status = 1; +} + +if ($use_rm) +{ + print "\nTEST: shutting down the replication manager.\n" if ($verbose); + $controller = $RMC->SpawnWaitKill (300); + if ($controller != 0) { + print STDERR "TEST ERROR: replication manager controller returned $controller\n"; + $status = 1; + } + + print "\nTEST: wait for ReplicationManager.\n" if ($verbose); + #$RM->Kill (); + $repmgr = $RM->WaitKill (30); + if ($repmgr != 0) { + print STDERR "TEST ERROR: ReplicationManager returned $repmgr\n"; + $status = 1; + } +} +else +{ + print "\nTEST: wait for FactoryRegistry.\n" if ($verbose); + $registry = $REG->WaitKill (30); + if ($registry != 0) { + print STDERR "TEST ERROR: FactoryRegistry returned $registry\n"; + $status = 1; + } +} +print "\nTEST: releasing scratch files.\n" if ($verbose); +unlink $rm_ior; +unlink $registry_ior; +unlink $factory1_ior; +unlink $factory2_ior; +unlink $factory3_ior; +unlink $replica1_ior; +unlink $replica2_ior; +unlink $replica3_ior; +unlink $replica4_ior; +unlink $replica5_ior; +unlink $replica6_ior; +unlink $replica1_iogr; +unlink $replica2_iogr; + +unlink $client_data; + + +exit $status; diff --git a/TAO/orbsvcs/tests/FT_App/run_test_rmnotifier.pl b/TAO/orbsvcs/tests/FT_App/run_test_rmnotifier.pl new file mode 100755 index 00000000000..b5023240650 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/run_test_rmnotifier.pl @@ -0,0 +1,319 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +# Purpose: +# To test the FaultNotifier +# +# Process being tested: +# Fault_Notifier +# implements FaultNotifier interface. +# Processes used in test: +# ReplicationManager +# +# FT_Replica +# implements TestReplica interface. +# implements PullMonitorable. +# Fault_Detector +# implements FaultDetectorFactory interface +# implements PullMonitorable interface +# FT_Client +# client for TestReplica interface. +# client for PullMonitorable. +# StubAnalyzer +# Subscribes to Fault_Notfier +# +# Test Scenario (***Test: marks behavior being tested): +# Phase 1: +# Start two FT_Replicas +# FT_Replicas write TestReplica IORs (FR#1 and FR#2) to files +# Start the Fault_Detector +# Fault_Detector writes its IOR (FDF) to a file +# Start the Fault_Notifier +# Fault_Notifier writes its IOR (FN) to a file. +# Phase 2: +# Wait for IORs: FR#1, FR#2, FDF, and FN +# Start the StubAnalyzer giving it IORS: FR#1, FR#2 FDF, FN +# StubAnalyzer calls FDF to create a FaultDetector +# for each Replica. +# StubAnalyzer subscribes to Fault_Notifier +# StubAnalyzer writes dummy message(READY) to a file. +# Phase 3: +# Wait for READY +# Start FT_Client giving it IORS: FR#1 and FR#2. [1] +# FT_Client interacts with FR#1. +# FT_Client asks FR#1 to fault. It does so. +# FT_Client notices fault and switches to FR#2. [1] +# FD#1 notices fault and notifies Fault_Notifier +# FD#1 terminates +# ***Test: Fault_Notifier forwards notification to StubAnalyzer +# StubAnalyzer prints notification. +# FT_Client interacts with FR#2. +# FT_Client asks FR#2 to shut down. +# FT_Client shuts down. +# FD#2 notices FR2 is gone, interprets this +# as a fault, and sends notification to Fault_Notifier +# FD#2 terminates. +# ***Test: Fault_Notifier forwards notification to StubAnalyzer +# StubAnalyzer prints notification. +# Phase 4: shutting down. +# All FaultDetectors have terminated so the FaultDetectorFactory +# honors the "quit-on-idle" option on it's command line and exits. +# StubAnalyzer compares # fault notifications to # replicas. When +# they match, it "knows" that the test is over, so it shuts down. +# As it does so, it disconnects its fault consumers from the FaultNotifier. +# FaultNotifier notices the last fault consumer disconnecting and exits because +# the "quit-on-idle" option was specified on the command line. +# Phase 5: housekeeping +# Wait for all processes to terminate. +# Check termination status. +# Delete temp files. +# +# [1] Client mediated fault tolerance. These points will +# change when IOGR support is available. +use lib '../../../../bin'; +#use lib '$ENV{ACE_ROOT}/bin'; +use PerlACE::Run_Test; + +######################## +#command line options +#set defaults: +my($verbose) = 0; # 1: report perl actions before executing them +my($debug_builds) = 0; # 0: use exes from Release directories +my($simulated) = 1; # 1: use "client simulated" fault tolerance + +foreach $i (@ARGV) { + if ($i eq "--debug_build") + { + $debug_builds = 1; + } + elsif ($i eq "--no_simulate") # reverse this once we have FT ORB support + { + $simulated = 0; + } + elsif ($i eq "-v") + { + $verbose += 1; + } +} + + +my($build_directory) = "/Release"; +if ( $debug_builds ) { + $build_directory = ""; +} + +if ( $verbose > 1) { + print "verbose: $verbose\n"; + print "debug_builds: $debug_builds -> $build_directory\n"; + print "simulated: $simulated\n"; +} + +#define temp files +my ($rm_endpoint) = "-ORBEndpoint iiop://localhost:2833"; +my ($rm_initref) = "-ORBInitRef ReplicationManager=corbaloc::localhost:2833/ReplicationManager"; +my($rm_ior) = PerlACE::LocalFile ("rm.ior"); +my($factory1_ior) = PerlACE::LocalFile ("factory1.ior"); +my($factory2_ior) = PerlACE::LocalFile ("factory2.ior"); +my($replica1_ior) = PerlACE::LocalFile ("replica1.ior"); +my($replica2_ior) = PerlACE::LocalFile ("replica2.ior"); +my($detector_ior) = PerlACE::LocalFile ("detector.ior"); +my($notifier_ior) = PerlACE::LocalFile ("notifier.ior"); +my($ready_file) = PerlACE::LocalFile ("ready.file"); +my($client_data) = PerlACE::LocalFile ("persistent.dat"); + +#discard junk from previous tests +unlink $rm_ior; +unlink $factory1_ior; +unlink $factory2_ior; +unlink $replica1_ior; +unlink $replica2_ior; +unlink $detector_ior; +unlink $notifier_ior; +unlink $ready_file; +unlink $client_data; + +my($status) = 0; + +my($RM) = new PerlACE::Process ("$ENV{'TAO_ROOT'}/orbsvcs/FT_ReplicationManager$build_directory/FT_ReplicationManager", "-o $rm_ior $rm_endpoint"); +my($RMC) = new PerlACE::Process (".$build_directory/replmgr_controller", "$rm_initref -x"); +my($REP1) = new PerlACE::Process (".$build_directory/ft_replica", "-o $factory1_ior -f none -t $replica1_ior -l loc1 -i type1 -q"); +my($REP2) = new PerlACE::Process (".$build_directory/ft_replica", "-o $factory2_ior -f none -t $replica2_ior -l loc2 -i type1 -q"); +my($DET) = new PerlACE::Process ("$ENV{'TAO_ROOT'}/orbsvcs/Fault_Detector$build_directory/Fault_Detector", "$rm_initref -o $detector_ior -q"); +my($NOT) = new PerlACE::Process ("$ENV{'TAO_ROOT'}/orbsvcs/Fault_Notifier$build_directory/Fault_Notifier", "$rm_initref -o $notifier_ior -q"); +my($ANA) = new PerlACE::Process (".$build_directory/ft_analyzer", "-o $ready_file -n file://$notifier_ior -d file://$detector_ior -r file://$replica1_ior -r file://$replica2_ior -q"); + +my($CL); +if ($simulated) { + print "\nTEST: Preparing Client Mediated Fault Tolerance test.\n" if ($verbose); + $CL = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica1_ior -f file://$replica2_ior -c testscript"); +}else{ + print "\nTEST: Preparing IOGR based test.\n" if ($verbose); + $CL = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica1_iogr -c testscript"); +} + +####################### +# ReplicationManager + +print "\nTEST: starting ReplicationManager " . $RM->CommandLine . "\n" if ($verbose); +$RM->Spawn (); + +print "TEST: waiting for registry's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($rm_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$rm_ior>\n"; + $RM->Kill (); $RM->TimedWait (1); + exit 1; +} + +########## +# Notifier +print "\nTEST: starting notifier " . $NOT->CommandLine . "\n" if ($verbose); +$NOT->Spawn (); + +print "TEST: waiting for notifier's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($notifier_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$notifier_ior>\n"; + $RM->Kill (); $RM->TimedWait (1); + $NOT->Kill (); $NOT->TimedWait(1); + exit 1; +} + +########## +# Detector +print "\nTEST: starting detector factory " . $DET->CommandLine . "\n" if ($verbose); +$DET->Spawn (); + +print "TEST: waiting for detector's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($detector_ior, 20) == -1) { + print STDERR "TEST ERROR: cannot find file <$detector_ior>\n"; + $RM->Kill (); $RM->TimedWait (1); + $NOT->Kill (); $NOT->TimedWait(1); + $DET->Kill (); $DET2->TimedWait(1); + exit 1; +} + +########### +# Replica 1 +print "\nTEST: starting replica1 " . $REP1->CommandLine . "\n" if ($verbose); +$REP1->Spawn (); + +print "TEST: waiting for replica 1's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($replica1_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$replica1_ior>\n"; + $RM->Kill (); $RM->TimedWait (1); + $NOT->Kill (); $NOT->TimedWait(1); + $DET->Kill (); $DET->TimedWait(1); + $REP1->Kill (); $REP1->TimedWait (1); + exit 1; +} + +########### +# Replica 2 +print "\nTEST: starting replica2 " . $REP2->CommandLine . "\n" if ($verbose); +$REP2->Spawn (); + +print "TEST: waiting for replica 2's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($replica2_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$replica2_ior>\n"; + $RM->Kill (); $RM->TimedWait (1); + $NOT->Kill (); $NOT->TimedWait(1); + $DET->Kill (); $DET->TimedWait(1); + $REP1->Kill (); $REP1->TimedWait (1); + $REP2->Kill (); $REP2->TimedWait (1); + exit 1; +} + +########## +# Analyzer +print "\nTEST: starting analyzer " . $ANA->CommandLine . "\n" if ($verbose); +$ANA->Spawn (); + +print "TEST: waiting for READY.FILE from analyzer\n" if ($verbose); +if (PerlACE::waitforfile_timed ($ready_file, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$ready_file>\n"; + $RM->Kill (); $RM->TimedWait (1); + $NOT->Kill (); $NOT->TimedWait(1); + $DET->Kill (); $DET->TimedWait(1); + $REP1->Kill (); $REP1->TimedWait (1); + $REP2->Kill (); $REP2->TimedWait (1); + $DET->Kill (); $DET2->TimedWait(1); + $NOT->Kill (); $NOT->TimedWait(1); + $ANA->Kill (); $ANA->TimedWait(1); + exit 1; +} + +######## +# Client +print "\nTEST: starting client " . $CL->CommandLine . "\n" if ($verbose); +$client = $CL->SpawnWaitKill (60); + +if ($client != 0) { + print STDERR "TEST ERROR: client returned $client\n"; + $status = 1; +} + +print "\nTEST: wait for replica 1.\n" if ($verbose); +$replica1 = $REP1->WaitKill (5); +if ($replica1 != 0) { + print STDERR "TEST ERROR: replica returned $replica1\n"; + $status = 1; +} + +print "\nTEST: wait for replica 2.\n" if ($verbose); +$replica2 = $REP2->WaitKill (5); +if ($replica2 != 0) { + print STDERR "TEST ERROR: replica returned $replica2\n"; + $status = 1; +} + +print "\nTEST: wait for detector factory to leave.\n" if ($verbose); +$detector = $DET->WaitKill (20); +if ($detector != 0) { + print STDERR "TEST ERROR: detector returned $detector\n"; + $status = 1; +} + +print "\nTEST: wait for analyzer to leave.\n" if ($verbose); +$analyzer = $ANA->WaitKill (20); +if ($analyzer != 0) { + print STDERR "TEST ERROR: analyzer returned $analyzer\n"; + $status = 1; +} + +print "\nTEST: shutting down the replication manager.\n" if ($verbose); +$controller = $RMC->SpawnWaitKill (300); +if ($controller != 0) { + print STDERR "TEST ERROR: replication manager controller returned $controller\n"; + $status = 1; +} + +print "\nTEST: wait for ReplicationManager.\n" if ($verbose); +#$RM->Kill (); +$repmgr = $RM->WaitKill (30); +if ($repmgr != 0) { + print STDERR "TEST ERROR: ReplicationManager returned $repmgr\n"; + $status = 1; +} + +print "\nTEST: wait for notifier to leave.\n" if ($verbose); +$notifier = $NOT->WaitKill (20); +if ($notifier != 0) { + print STDERR "TEST ERROR: notifier returned $notifier\n"; + $status = 1; +} + +print "\nTEST: releasing scratch files.\n" if ($verbose); +unlink $rm_ior; +unlink $replica1_ior; +unlink $replica2_ior; +unlink $detector_ior; +unlink $notifier_ior; +unlink $ready_file; + +#client's work file +unlink $client_data; + +exit $status; diff --git a/TAO/orbsvcs/tests/FT_App/run_test_rmregistry.pl b/TAO/orbsvcs/tests/FT_App/run_test_rmregistry.pl new file mode 100755 index 00000000000..5facd17d085 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/run_test_rmregistry.pl @@ -0,0 +1,385 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# $Id$ +# -*- perl -*- + +# Purpose: +# To test the FactoryRegistry as a component of ReplicationManager +# +# Process being tested: +# FT_ReplicationManager +# implements PortableGroup::FactoryRegistry interface. +# Processes used in test: +# FT_Replica * 3 +# implements GenericFactory interface to create TestReplicas +# TestReplica implements TestReplica interface. +# TestReplica implements PullMonitorable interface. +# FT_Client +# client for TestReplica interface. +# client for PullMonitorable. +# Object Group Creator +# Creates groups of objects. +# +# Test Scenario (***Test: marks behavior being tested): +# +# First the test starts The ReplicationManager, +# Then starts three factories. Each factory exists at a separate location. +# The locations are named shire, bree, and rivendell. In a "real" system +# these locations would be on separate computers. +# +# The factory at the shire location knows how to create hobbits. +# The factory at the bree location knows how to create hobbits, elves, and humans. +# The factory at rivendell can create elves. +# Hobbits, elves, and humans are roles for TestReplica objects. A creation parameter +# included as part of the registration information specifies which role they are playing. +# +# ***Test: The factories register themselves with the factory registry in the ReplicationManager. +# Registration information includes: +# the role, +# the type of object created, +# the location, +# an object reference to the factory and +# a set of parameters to be passed to the factory's create_object method. +# +# An object group creator is started and asked to create three object groups: +# a group of hobbits, a group of elves; and another group of hobbits. +# +# ***Test: the object group creator asks the ReplicationManager::FactoryRegistry +# for the set of factories that can create objects for the desired role. +# Then it uses the create_object method for each factory to create the actual object. +# +# [temporary until IOGR's are working: The object group creator writes the +# IOR's of the create objects to files -- using a file naming convention to +# distinguish members of the group. It will be enhanced to assemble these +# IORs into an IOGR and either write the IOGR to a file or register it with +# the Naming Service.] +# +# The object group creator is also told to unregister all factories that create humans. +# ***Test: It does so using the unregister_factory_by_role method. +# +# Three clients are started, one at a time. Each client is given a reference +# to an object group +# +# [temporary until IOGRs and transparent reinvocaton work: each client is +# given references to the members of the group and manages its own recovery +# (client mediated fault tolerance)] +# +# Each client sends a few requests to first member of the object group. Eventually +# this member fails and the requests are then rerouted to the second (and last) +# member of the group. +# +# When a clients job is done, it exits and asks the remaining group member to +# exit, too. +# +# The factories are run with the quit-on-idle option so when the last object +# created at that location goes away, the factory exits. +# +# ***Test: As it exits the factory unregisters itself with the ReplicationManager::FactoryRegistry. +# ***Test: A command line option determines whether it uses a single +# unregister_factory_by_location call, or separate unregister_factory calles for +# each type of object created. In this test, the shire location uses unregister_factory, +# and bree and rivendell use unregister_factory_by_location. +# +# The factory registry is also run with the quit-on-idle option so when the last +# factory unregisters itself. +# The ReplicationManager is killed because it doesn't have a quit-on-idle option. + +use lib '../../../../bin'; +#use lib '$ENV{ACE_ROOT}/bin'; +use PerlACE::Run_Test; + +######################## +#command line options +#set defaults: +my($verbose) = 0; # 1: report perl actions before executing them +my($debug_builds) = 0; # 0: use exes from Release directories +my($simulated) = 1; # 1: use "client simulated" fault tolerance + +foreach $i (@ARGV) { + if ($i eq "--debug_build") + { + $debug_builds = 1; + } + elsif ($i eq "--no_simulate") # reverse this once we have FT ORB support + { + $simulated = 0; + } + elsif ($i eq "-v") + { + $verbose += 1; + } +} + +my($build_directory) = "/Release"; +if ( $debug_builds ) { + $build_directory = ""; +} + +if ( $verbose > 1) { + print "verbose: $verbose\n"; + print "debug_builds: $debug_builds -> $build_directory\n"; + print "simulated: $simulated\n"; +} + +my($role1) = "hobbit"; +my($role2) = "elf"; +my($role3) = "human"; + +my($location1) = "shire"; +my($location2) = "bree"; +my($location3) = "rivendell"; +my($location4) = "rohan"; + +my ($rm_endpoint) = "-ORBEndpoint iiop://localhost:2833"; +my ($rm_initref) = "-ORBInitRef ReplicationManager=corbaloc::localhost:2833/ReplicationManager"; + +#define temp files +my($rm_ior) = PerlACE::LocalFile ("rm.ior"); +my($factory1_ior) = PerlACE::LocalFile ("factory1.ior"); +my($factory2_ior) = PerlACE::LocalFile ("factory2.ior"); +my($factory3_ior) = PerlACE::LocalFile ("factory3.ior"); +my($replica1_ior) = PerlACE::LocalFile ("${role1}_${location1}_0.ior"); +my($replica2_ior) = PerlACE::LocalFile ("${role1}_${location2}_0.ior"); +my($replica3_ior) = PerlACE::LocalFile ("${role2}_${location2}_1.ior"); +my($replica4_ior) = PerlACE::LocalFile ("${role2}_${location3}_0.ior"); +my($replica5_ior) = PerlACE::LocalFile ("${role1}_${location1}_1.ior"); +my($replica6_ior) = PerlACE::LocalFile ("${role1}_${location2}_2.ior"); + +my($replica1_iogr) = PerlACE::LocalFile ("${role1}_0.iogr"); +my($replica2_iogr) = PerlACE::LocalFile ("${role2}_1.iogr"); +my($replica3_iogr) = PerlACE::LocalFile ("${role1}_2.iogr"); + +my($client_data) = PerlACE::LocalFile ("persistent.dat"); + +#discard junk from previous tests +unlink $rm_ior; +unlink $factory1_ior; +unlink $factory2_ior; +unlink $factory3_ior; +unlink $replica1_ior; +unlink $replica2_ior; +unlink $replica3_ior; +unlink $replica4_ior; +unlink $replica5_ior; +unlink $replica6_ior; +unlink $replica1_iogr; +unlink $replica2_iogr; + +unlink $client_data; + +my($status) = 0; + +my($RM) = new PerlACE::Process ("$ENV{'TAO_ROOT'}/orbsvcs/FT_ReplicationManager$build_directory/FT_ReplicationManager", "-ORBDebugLevel 0 -o $rm_ior $rm_endpoint"); +my($RMC) = new PerlACE::Process (".$build_directory/replmgr_controller", "$rm_initref -x"); +my($FAC1) = new PerlACE::Process (".$build_directory/ft_replica", "-o $factory1_ior $rm_initref -l $location1 -i $role1 -q"); +my($FAC2) = new PerlACE::Process (".$build_directory/ft_replica", "-o $factory2_ior $rm_initref -l $location2 -i $role1 -i $role2 -i $role3 -q -u"); +my($FAC3) = new PerlACE::Process (".$build_directory/ft_replica", "-o $factory3_ior $rm_initref -l $location3 -i $role2 -q -u"); +my($CTR) = new PerlACE::Process (".$build_directory/ft_create", "$rm_initref -n -r $role1 -r $role2 -r $role1 -u $role3 -i"); + +my($CL1); +my($CL2); +my($CL3); +if ($simulated) { + print "\nTEST: Preparing Client Mediated Fault Tolerance test.\n" if ($verbose); + $CL1 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica1_ior -f file://$replica2_ior -c testscript"); + $CL2 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica3_ior -f file://$replica4_ior -c testscript"); + $CL3 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica5_ior -f file://$replica6_ior -c testscript"); +}else{ + print "\nTEST: Preparing IOGR based test.\n" if ($verbose); + $CL1 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica1_iogr -c testscript"); + $CL2 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica2_iogr -c testscript"); + $CL3 = new PerlACE::Process (".$build_directory/ft_client", "-f file://$replica3_iogr -c testscript"); +} + +####################### +# Start ReplicationManager + +print "\nTEST: starting ReplicationManager " . $RM->CommandLine . "\n" if ($verbose); +$RM->Spawn (); + +print "TEST: waiting for registry's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($rm_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$rm_ior>\n"; + $RM->Kill (); $RM->TimedWait (1); + exit 1; +} + + +################# +# Start Factories + +print "\nTEST: starting factory 1 " . $FAC1->CommandLine . "\n" if ($verbose); +$FAC1->Spawn (); + +print "TEST: waiting for factory 1's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($factory1_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$factory1_ior>\n"; + $RM->Kill (); $RM->TimedWait (1); + $FAC1->Kill (); $FAC1->TimedWait (1); + exit 1; +} + +print "\nTEST: starting factory 2 " . $FAC2->CommandLine . "\n" if ($verbose); +$FAC2->Spawn (); + +print "TEST: waiting for factory 2's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($factory2_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$factory2_ior>\n"; + $FAC1->Kill (); $FAC1->TimedWait (1); + $RM->Kill (); $RM->TimedWait (1); + $FAC2->Kill (); $FAC2->TimedWait (1); + exit 1; +} + +print "\nTEST: starting factory 3 " . $FAC3->CommandLine . "\n" if ($verbose); +$FAC3->Spawn (); + +print "TEST: waiting for factory 3's IOR\n" if ($verbose); +if (PerlACE::waitforfile_timed ($factory3_ior, 5) == -1) { + print STDERR "TEST ERROR: cannot find file <$factory3_ior>\n"; + $FAC1->Kill (); $FAC1->TimedWait (1); + $FAC2->Kill (); $FAC2->TimedWait (1); + $RM->Kill (); $RM->TimedWait (1); + $FAC3->Kill (); $FAC3->TimedWait (1); + exit 1; +} + +###################### +# Create object groups + +print "\nTEST: starting object group creator " . $CTR->CommandLine . "\n" if ($verbose); +$CTR->Spawn (); + +print "TEST: waiting for Replica IOR files from object group creator\n" if ($verbose); +if (PerlACE::waitforfile_timed ($replica1_ior, 5) == -1){ + print STDERR "TEST ERROR: cannot find file <$replica1_ior>\n"; + $status = 1; +} +elsif (PerlACE::waitforfile_timed ($replica2_ior, 5) == -1){ + print STDERR "TEST ERROR: cannot find file <$replica2_ior> \n"; + $status = 1; +} +elsif (PerlACE::waitforfile_timed ($replica3_ior, 5) == -1){ + print STDERR "TEST ERROR: cannot find file <$replica3_ior> \n"; + $status = 1; +} +elsif (PerlACE::waitforfile_timed ($replica4_ior, 5) == -1){ + print STDERR "TEST ERROR: cannot find file <$replica4_ior> \n"; + $status = 1; +} +elsif (PerlACE::waitforfile_timed ($replica5_ior, 5) == -1){ + print STDERR "TEST ERROR: cannot find file <$replica5_ior> \n"; + $status = 1; +} +elsif (PerlACE::waitforfile_timed ($replica6_ior, 5) == -1){ + print STDERR "TEST ERROR: cannot find file <$replica6_ior> \n"; + $status = 1; +} + +if($status != 0){ + $FAC3->Kill (); $FAC3->TimedWait (1); + $FAC2->Kill (); $FAC2->TimedWait (1); + $FAC1->Kill (); $FAC1->TimedWait (1); + $RM->Kill (); $RM->TimedWait (1); + $CTR->Kill (); $CTR->TimedWait(1); + exit 1; +} + +print "\nTEST: wait for object group creator.\n" if ($verbose); +$config = $CTR->WaitKill (5); +if ($config != 0) { + print STDERR "TEST ERROR: configuration manager returned $config\n"; + $FAC3->Kill (); $FAC3->TimedWait (1); + $FAC2->Kill (); $FAC2->TimedWait (1); + $FAC1->Kill (); $FAC1->TimedWait (1); + $RM->Kill (); $RM->TimedWait (1); + exit 1; +} + + +############# +# Run clients + +print "\nTEST: starting client " . $CL1->CommandLine . "\n" if ($verbose); +$client = $CL1->SpawnWaitKill (60); + +if ($client != 0) { + print STDERR "TEST ERROR: client returned $client\n"; + $status = 1; +} + +print "\nTEST: starting client again " . $CL2->CommandLine . "\n" if ($verbose); +$client2 = $CL2->SpawnWaitKill (60); + +if ($client2 != 0) { + print STDERR "TEST ERROR: client returned $client2\n"; + $status = 1; +} + +print "\nTEST: starting client, one more time with feeling " . $CL3->CommandLine . "\n" if ($verbose); +$client3 = $CL3->SpawnWaitKill (60); + +if ($client3 != 0) { + print STDERR "TEST ERROR: client returned $client3\n"; + $status = 1; +} + +###################### +# Clean house and exit + +print "\nTEST: wait for factory 1.\n" if ($verbose); +$factory1 = $FAC1->WaitKill (30); +if ($factory1 != 0) { + print STDERR "TEST ERROR: replica returned $factory 1\n"; + $status = 1; +} + +print "\nTEST: wait for factory 2.\n" if ($verbose); +$factory2 = $FAC2->WaitKill (30); +if ($factory2 != 0) { + print STDERR "TEST ERROR: factory 2 returned $factory2\n"; + $status = 1; +} + +print "\nTEST: wait for factory 3.\n" if ($verbose); +$factory3 = $FAC3->WaitKill (30); +if ($factory3 != 0) { + print STDERR "TEST ERROR: factory 3 returned $factory3\n"; + $status = 1; +} + +print "\nTEST: shutting down the replication manager.\n" if ($verbose); +$controller = $RMC->SpawnWaitKill (300); +if ($controller != 0) { + print STDERR "TEST ERROR: replication manager controller returned $controller\n"; + $status = 1; +} + +print "\nTEST: wait for ReplicationManager.\n" if ($verbose); +#$RM->Kill (); +$repmgr = $RM->WaitKill (30); +if ($repmgr != 0) { + print STDERR "TEST ERROR: ReplicationManager returned $repmgr\n"; + $status = 1; +} + +print "\nTEST: releasing scratch files.\n" if ($verbose); +unlink $rm_ior; +unlink $factory1_ior; +unlink $factory2_ior; +unlink $factory3_ior; +unlink $replica1_ior; +unlink $replica2_ior; +unlink $replica3_ior; +unlink $replica4_ior; +unlink $replica5_ior; +unlink $replica6_ior; +unlink $replica1_iogr; +unlink $replica2_iogr; + +unlink $client_data; + + +exit $status; diff --git a/TAO/orbsvcs/tests/FT_App/testscript b/TAO/orbsvcs/tests/FT_App/testscript new file mode 100644 index 00000000000..a428a227ef3 --- /dev/null +++ b/TAO/orbsvcs/tests/FT_App/testscript @@ -0,0 +1,10 @@ +v3 echo commands +=0 ++5 +d3 FMI: d3 is before state change; d4 is before replication;d5 is before reply ++5 +c10 ++5 +z3 sleep for a while ++7 +q1 quit and bring down current primary replica diff --git a/TAO/orbsvcs/tests/FaultTolerance/GroupRef_Manipulation/GroupRef_Manipulation.mpc b/TAO/orbsvcs/tests/FaultTolerance/GroupRef_Manipulation/GroupRef_Manipulation.mpc index 2ec4d716749..efaf9f234d1 100644 --- a/TAO/orbsvcs/tests/FaultTolerance/GroupRef_Manipulation/GroupRef_Manipulation.mpc +++ b/TAO/orbsvcs/tests/FaultTolerance/GroupRef_Manipulation/GroupRef_Manipulation.mpc @@ -1,4 +1,4 @@ -project(*Server): taoserver, orbsvcsexe, iormanip, ftorb { +project(*Server): taoserver, orbsvcsexe, iormanip, ftorb, messaging{ requires += interceptors idlflags += -Gv -DCORBA3 -I$(TAO_ROOT) diff --git a/TAO/orbsvcs/tests/FaultTolerance/GroupRef_Manipulation/Makefile b/TAO/orbsvcs/tests/FaultTolerance/GroupRef_Manipulation/Makefile index 443f0ea0b13..b4f0aa70b33 100644 --- a/TAO/orbsvcs/tests/FaultTolerance/GroupRef_Manipulation/Makefile +++ b/TAO/orbsvcs/tests/FaultTolerance/GroupRef_Manipulation/Makefile @@ -58,7 +58,7 @@ include $(TAO_ROOT)/taoconfig.mk .PRECIOUS: $(foreach ext, $(IDL_EXT), test$(ext)) -TAO_FT_LIBS = -lTAO_FTORB -lTAO_IORManip +TAO_FT_LIBS = -lTAO_FTORB -lTAO_IORManip -lTAO_Messaging server: $(addprefix $(VDIR),$(SERVER_OBJS)) $(LINK.cc) $(LDFLAGS) -o $@ $^ $(TAO_FT_LIBS) $(TAO_SRVR_LIBS) $(POSTLINK) diff --git a/TAO/orbsvcs/tests/FaultTolerance/GroupRef_Manipulation/server.cpp b/TAO/orbsvcs/tests/FaultTolerance/GroupRef_Manipulation/server.cpp index 4522cdf4f60..ee1bd7e9d0e 100644 --- a/TAO/orbsvcs/tests/FaultTolerance/GroupRef_Manipulation/server.cpp +++ b/TAO/orbsvcs/tests/FaultTolerance/GroupRef_Manipulation/server.cpp @@ -64,12 +64,12 @@ add_ft_prop (CORBA::ORB_ptr o, // Property values // Major and Minor revision numbers - ft_tag_component.version.major = (CORBA::Octet) 1; - ft_tag_component.version.minor = (CORBA::Octet) 0; + ft_tag_component.component_version.major = (CORBA::Octet) 1; + ft_tag_component.component_version.minor = (CORBA::Octet) 0; // Domain id const char *id = "version_testing"; - ft_tag_component.ft_domain_id = id; + ft_tag_component.group_domain_id = id; // Object group id ft_tag_component.object_group_id = diff --git a/TAO/orbsvcs/tests/FaultTolerance/IOGR/FaultTolerance_IOGR.mpc b/TAO/orbsvcs/tests/FaultTolerance/IOGR/FaultTolerance_IOGR.mpc index 52f12659a37..ff0e21543c6 100644 --- a/TAO/orbsvcs/tests/FaultTolerance/IOGR/FaultTolerance_IOGR.mpc +++ b/TAO/orbsvcs/tests/FaultTolerance/IOGR/FaultTolerance_IOGR.mpc @@ -1,4 +1,4 @@ -project(*server): portableserver, orbsvcsexe, iormanip, ftorb { +project(*server): portableserver, orbsvcsexe, iormanip, ftorb, messaging { Source_Files { test_i.cpp server.cpp diff --git a/TAO/orbsvcs/tests/FaultTolerance/IOGR/Makefile b/TAO/orbsvcs/tests/FaultTolerance/IOGR/Makefile index 3c290a0aa6c..7bb5ee15d69 100644 --- a/TAO/orbsvcs/tests/FaultTolerance/IOGR/Makefile +++ b/TAO/orbsvcs/tests/FaultTolerance/IOGR/Makefile @@ -46,7 +46,7 @@ include $(TAO_ROOT)/taoconfig.mk .PRECIOUS: $(foreach ext, $(IDL_EXT), test$(ext)) -TAO_FT_LIBS = -lTAO_FTORB -lTAO_IORManip +TAO_FT_LIBS = -lTAO_FTORB -lTAO_IORManip -lTAO_Messaging server: $(addprefix $(VDIR),$(SERVER_OBJS)) $(LINK.cc) $(LDFLAGS) -o $@ $^ $(TAO_SRVR_LIBS) $(POSTLINK) diff --git a/TAO/orbsvcs/tests/FaultTolerance/IOGR/Manager.cpp b/TAO/orbsvcs/tests/FaultTolerance/IOGR/Manager.cpp index 4e175275ae1..e876e51290b 100644 --- a/TAO/orbsvcs/tests/FaultTolerance/IOGR/Manager.cpp +++ b/TAO/orbsvcs/tests/FaultTolerance/IOGR/Manager.cpp @@ -194,12 +194,12 @@ Manager::set_properties (ACE_ENV_SINGLE_ARG_DECL) // Property values // Major and Minor revision numbers - ft_tag_component.version.major = (CORBA::Octet) 1; - ft_tag_component.version.minor = (CORBA::Octet) 0; + ft_tag_component.component_version.major = (CORBA::Octet) 1; + ft_tag_component.component_version.minor = (CORBA::Octet) 0; // Domain id const char *id = "iogr_testing"; - ft_tag_component.ft_domain_id = id; + ft_tag_component.group_domain_id = id; // Object group id ft_tag_component.object_group_id = diff --git a/TAO/orbsvcs/tests/FaultTolerance/IOGRManipulation/FaultTolerance_IOGRManipulation.mpc b/TAO/orbsvcs/tests/FaultTolerance/IOGRManipulation/FaultTolerance_IOGRManipulation.mpc index a7d46dbeccb..7c3d36af851 100644 --- a/TAO/orbsvcs/tests/FaultTolerance/IOGRManipulation/FaultTolerance_IOGRManipulation.mpc +++ b/TAO/orbsvcs/tests/FaultTolerance/IOGRManipulation/FaultTolerance_IOGRManipulation.mpc @@ -1,3 +1,3 @@ -project(IOGRTest): portableserver, orbsvcsexe, iormanip, ftorb { +project(IOGRTest): taoserver, orbsvcsexe, iormanip, ftorb, messaging { exename = IOGRTest } diff --git a/TAO/orbsvcs/tests/FaultTolerance/IOGRManipulation/IOGRTest.cpp b/TAO/orbsvcs/tests/FaultTolerance/IOGRManipulation/IOGRTest.cpp index 00138a7f466..c0120577eab 100644 --- a/TAO/orbsvcs/tests/FaultTolerance/IOGRManipulation/IOGRTest.cpp +++ b/TAO/orbsvcs/tests/FaultTolerance/IOGRManipulation/IOGRTest.cpp @@ -144,12 +144,12 @@ main (int argc, char *argv[]) // Property values // Major and Minor revision numbers - ft_tag_component.version.major = (CORBA::Octet) 1; - ft_tag_component.version.minor = (CORBA::Octet) 0; + ft_tag_component.component_version.major = (CORBA::Octet) 1; + ft_tag_component.component_version.minor = (CORBA::Octet) 0; // Domain id const char *id = "iogr_regression"; - ft_tag_component.ft_domain_id = id; + ft_tag_component.group_domain_id = id; // Object group id ft_tag_component.object_group_id = diff --git a/TAO/orbsvcs/tests/FaultTolerance/IOGRManipulation/Makefile b/TAO/orbsvcs/tests/FaultTolerance/IOGRManipulation/Makefile index 5e3e771b81b..7772f454da9 100644 --- a/TAO/orbsvcs/tests/FaultTolerance/IOGRManipulation/Makefile +++ b/TAO/orbsvcs/tests/FaultTolerance/IOGRManipulation/Makefile @@ -12,7 +12,7 @@ ifndef TAO_ROOT TAO_ROOT = $(ACE_ROOT)/TAO endif # ! TAO_ROOT -LDLIBS = -lTAO_FTORB -lTAO_IORManip -lTAO_PortableServer -lTAO_Valuetype -lTAO_ObjRefTemplate -lTAO_IORInterceptor -lTAO +LDLIBS = -lTAO_Messaging -lTAO_FTORB -lTAO_IORManip -lTAO_PortableServer -lTAO_Valuetype -lTAO_ObjRefTemplate -lTAO_IORInterceptor -lTAO PROG_SRCS = IOGRTest.cpp |