From c03dddf83ed6cad116b43bd7c3f6b4e2a2f9aaad Mon Sep 17 00:00:00 2001 From: Ossama Othman Date: Thu, 13 Jul 2000 03:06:02 +0000 Subject: Initial work for new implementation of load balancer --- TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Equal_To.cpp | 9 + TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Equal_To.h | 79 +++ TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Equal_To.inl | 33 ++ TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Hash.cpp | 9 + TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Hash.h | 71 +++ TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Hash.inl | 23 + TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Map.h | 106 ++++ TAO/orbsvcs/orbsvcs/LB_Replica_Equal_To.cpp | 9 + TAO/orbsvcs/orbsvcs/LB_Replica_Equal_To.h | 81 +++ TAO/orbsvcs/orbsvcs/LB_Replica_Equal_To.inl | 37 ++ TAO/orbsvcs/orbsvcs/LB_Replica_Hash.cpp | 9 + TAO/orbsvcs/orbsvcs/LB_Replica_Hash.h | 72 +++ TAO/orbsvcs/orbsvcs/LB_Replica_Hash.inl | 26 + TAO/orbsvcs/orbsvcs/LB_Replica_Map.h | 91 ++++ TAO/orbsvcs/orbsvcs/LB_Replication_Manager.h | 6 + TAO/orbsvcs/orbsvcs/LoadBalancing.idl | 301 ++++++----- .../LoadBalancing/LB_ObjectGroup_Equal_To.cpp | 9 + .../LoadBalancing/LB_ObjectGroup_Equal_To.h | 79 +++ .../LoadBalancing/LB_ObjectGroup_Equal_To.inl | 33 ++ .../orbsvcs/LoadBalancing/LB_ObjectGroup_Hash.cpp | 9 + .../orbsvcs/LoadBalancing/LB_ObjectGroup_Hash.h | 71 +++ .../orbsvcs/LoadBalancing/LB_ObjectGroup_Hash.inl | 23 + .../orbsvcs/LoadBalancing/LB_ObjectGroup_Map.h | 106 ++++ .../orbsvcs/LoadBalancing/LB_Replica_Equal_To.cpp | 9 + .../orbsvcs/LoadBalancing/LB_Replica_Equal_To.h | 81 +++ .../orbsvcs/LoadBalancing/LB_Replica_Equal_To.inl | 37 ++ .../orbsvcs/LoadBalancing/LB_Replica_Hash.cpp | 9 + .../orbsvcs/LoadBalancing/LB_Replica_Hash.h | 72 +++ .../orbsvcs/LoadBalancing/LB_Replica_Hash.inl | 26 + TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Map.h | 91 ++++ .../orbsvcs/LoadBalancing/LB_Replication_Manager.h | 6 + .../orbsvcs/LoadBalancing/LoadBalancingI.cpp | 587 +++++++++++++++++++++ TAO/orbsvcs/orbsvcs/LoadBalancing/LoadBalancingI.h | 273 ++++++++++ .../orbsvcs/LoadBalancing/ObjectGroupManager.cpp | 10 + .../orbsvcs/LoadBalancing/ReplicaLocator.cpp | 2 +- TAO/orbsvcs/orbsvcs/LoadBalancingI.cpp | 587 +++++++++++++++++++++ TAO/orbsvcs/orbsvcs/LoadBalancingI.h | 273 ++++++++++ TAO/orbsvcs/orbsvcs/ObjectGroupManager.cpp | 10 + TAO/orbsvcs/orbsvcs/ReplicaLocator.cpp | 2 +- TAO/orbsvcs/tests/LoadBalancing/GenericFactory.cpp | 238 +++++++++ .../tests/LoadBalancing/HashReplicaFactory.cpp | 103 ++++ .../tests/LoadBalancing/HashReplicaFactory.h | 31 ++ .../tests/LoadBalancing/LoadBalancer_test.cpp | 64 +++ .../tests/LoadBalancing/PropertyManager.cpp | 428 +++++++++++++++ 44 files changed, 4102 insertions(+), 129 deletions(-) create mode 100644 TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Equal_To.cpp create mode 100644 TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Equal_To.h create mode 100644 TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Equal_To.inl create mode 100644 TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Hash.cpp create mode 100644 TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Hash.h create mode 100644 TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Hash.inl create mode 100644 TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Map.h create mode 100644 TAO/orbsvcs/orbsvcs/LB_Replica_Equal_To.cpp create mode 100644 TAO/orbsvcs/orbsvcs/LB_Replica_Equal_To.h create mode 100644 TAO/orbsvcs/orbsvcs/LB_Replica_Equal_To.inl create mode 100644 TAO/orbsvcs/orbsvcs/LB_Replica_Hash.cpp create mode 100644 TAO/orbsvcs/orbsvcs/LB_Replica_Hash.h create mode 100644 TAO/orbsvcs/orbsvcs/LB_Replica_Hash.inl create mode 100644 TAO/orbsvcs/orbsvcs/LB_Replica_Map.h create mode 100644 TAO/orbsvcs/orbsvcs/LB_Replication_Manager.h create mode 100644 TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Equal_To.cpp create mode 100644 TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Equal_To.h create mode 100644 TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Equal_To.inl create mode 100644 TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Hash.cpp create mode 100644 TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Hash.h create mode 100644 TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Hash.inl create mode 100644 TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Map.h create mode 100644 TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Equal_To.cpp create mode 100644 TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Equal_To.h create mode 100644 TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Equal_To.inl create mode 100644 TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Hash.cpp create mode 100644 TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Hash.h create mode 100644 TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Hash.inl create mode 100644 TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Map.h create mode 100644 TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replication_Manager.h create mode 100644 TAO/orbsvcs/orbsvcs/LoadBalancing/LoadBalancingI.cpp create mode 100644 TAO/orbsvcs/orbsvcs/LoadBalancing/LoadBalancingI.h create mode 100644 TAO/orbsvcs/orbsvcs/LoadBalancing/ObjectGroupManager.cpp create mode 100644 TAO/orbsvcs/orbsvcs/LoadBalancingI.cpp create mode 100644 TAO/orbsvcs/orbsvcs/LoadBalancingI.h create mode 100644 TAO/orbsvcs/orbsvcs/ObjectGroupManager.cpp create mode 100644 TAO/orbsvcs/tests/LoadBalancing/GenericFactory.cpp create mode 100644 TAO/orbsvcs/tests/LoadBalancing/HashReplicaFactory.cpp create mode 100644 TAO/orbsvcs/tests/LoadBalancing/HashReplicaFactory.h create mode 100644 TAO/orbsvcs/tests/LoadBalancing/LoadBalancer_test.cpp create mode 100644 TAO/orbsvcs/tests/LoadBalancing/PropertyManager.cpp diff --git a/TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Equal_To.cpp b/TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Equal_To.cpp new file mode 100644 index 00000000000..f86d26808f7 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Equal_To.cpp @@ -0,0 +1,9 @@ +// -*- C++ -*- + +#include "LB_Equal_To.h" + +#if !defined (__ACE_INLINE__) +#include "LB_Equal_To.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID (TAO_LoadBalancing, LB_Equal_To, "$Id$") diff --git a/TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Equal_To.h b/TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Equal_To.h new file mode 100644 index 00000000000..33eccb6d71f --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Equal_To.h @@ -0,0 +1,79 @@ +// -*- C++ -*- +// +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO_LoadBalancing +// +// = FILENAME +// LB_ObjectGroup_Equal_To.h +// +// = AUTHOR +// Ossama Othman +// +// ============================================================================ + +#ifndef TAO_LB_OBJECTGROUP_EQUAL_TO_H +#define TAO_LB_OBJECTGROUP_EQUAL_TO_H + +#include "ace/pre.h" + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "LoadbalancingC.h" + +class TAO_LB_ObjectGroup_Equal_To +{ + // = TITLE + // Function object that compares equality of two ObjectGroup + // references. + // + // = DESCRIPTION + // This class basically wraps the + // CORBA::Object::_is_equivalent() method so that it can be + // utilized by a Hash Map as a way to compare equality. + +public: + + int operator() (const TAO_LoadBalancing::ObjectGroup_ptr &lhs, + const TAO_LoadBalancing::ObjectGroup_ptr &rhs) const; + // Invokes the CORBA::Object::_is_equivalent() method to determine + // if both references refer to the same object group. However, this + // is a weak test since is_equivalent() can only conclusively + // determine if two references refer to the same object, but it + // cannot determine if two refereneces do not refer to the same + // object. +}; + +class TAO_LB_FactoryCreationId_Equal_To +{ + // = TITLE + // Function object that compares equality of two + // FactoryCreationId values. + // + // = DESCRIPTION + // This class extracts the actual value of the FactoryCreationId + // from the CORBA::Any the FactoryCreationId is typedefed to. + +public: + + int operator() ( + const TAO_LoadBalancing::FactoryCreationId &lhs, + const TAO_LoadBalancing::FactoryCreationId &rhs) const; + // Check if two FactoryCreationId values are the same. +}; + + +#if defined (__ACE_INLINE__) +#include "LB_ObjectGroup_Equal_To.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/post.h" + +#endif /* TAO_LB_OBJECTGROUP_EQUAL_TO_H */ diff --git a/TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Equal_To.inl b/TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Equal_To.inl new file mode 100644 index 00000000000..7547d068b72 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Equal_To.inl @@ -0,0 +1,33 @@ +// -*- C++ -*- +// +// $Id$ + +ACE_INLINE int +TAO_LB_ObjectGroup_Equal_To::operator() ( + const TAO_LoadBalancing::ObjectGroup_ptr &lhs, + const TAO_LoadBalancing::ObjectGroup_ptr &rhs) const +{ + // As with all CORBA objects, the + // TAO_LoadBalancing::ObjectGroup::is_equivalent() returns 1 if two + // references refer to the same object. However, it is possible + // that is_equivalent() may return 0 even if both references refer + // to the same object. + + return lhs->_is_equivalent (rhs); +} + + +ACE_INLINE int +TAO_LB_FactoryCreationId_Equal_To::operator() ( + const TAO_LoadBalancing::FactoryCreationId &lhs, + const TAO_LoadBalancing::FactoryCreationId &rhs) const +{ + // A Load Balancer FactoryCreationId is simply a CORBA::ULong. + + CORBA::ULong lhs_id, rhs_id; + + lhs >>= lhs_id; + rhs >>= rhs_id; + + return (lhs_id == rhs_id); +} diff --git a/TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Hash.cpp b/TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Hash.cpp new file mode 100644 index 00000000000..594e3bb1380 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Hash.cpp @@ -0,0 +1,9 @@ +// -*- C++ -*- + +#include "LB_Hash.h" + +#if !defined (__ACE_INLINE__) +#include "LB_Hash.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID (TAO_LoadBalancing, LB_Hash, "$Id$") diff --git a/TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Hash.h b/TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Hash.h new file mode 100644 index 00000000000..488fa7bbc93 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Hash.h @@ -0,0 +1,71 @@ +// -*- C++ -*- +// +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO_LoadBalancing +// +// = FILENAME +// LB_Hash.h +// +// = AUTHOR +// Ossama Othman +// +// ============================================================================ + +#ifndef TAO_LB_HASH_H +#define TAO_LB_HASH_H + +#include "ace/pre.h" + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "LoadbalancingC.h" + +class TAO_LB_ObjectGroup_Hash +{ + // = TITLE + // Hash function object for generating a hash for an ObjectGroup + // reference. + // + // = DESCRIPTION + // This class basically wraps the CORBA::Object::_hash() method + // so that it can be utilized by a Hash Map. + +public: + + CORBA::ULong operator() (const TAO_LoadBalancing::ObjectGroup_ptr &) const; + // Invokes the _hash() method on the ObjectGroup reference. +}; + + +class TAO_LB_FactoryCreationId_Hash +{ + // = TITLE + // Hash function object for generating a hash for a + // FactoryCreationId. + // + // = DESCRIPTION + // Create a hash based on the contents of the FactoryCreationId. + +public: + + CORBA::ULong operator() (const TAO_LoadBalancing::FactoryCreationId &) const; + // Generates a hash value based on the contents of the + // FactoryCreationId. +}; + + +#if defined (__ACE_INLINE__) +#include "LB_Hash.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/post.h" + +#endif /* TAO_LB_HASH_H */ diff --git a/TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Hash.inl b/TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Hash.inl new file mode 100644 index 00000000000..8bf5490a545 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Hash.inl @@ -0,0 +1,23 @@ +// -*- C++ -*- +// +// $Id$ + +ACE_INLINE CORBA::ULong +TAO_LB_ObjectGroup_Hash::operator() ( + const TAO_LoadBalancing::ObjectGroup_ptr &object_group) const +{ + CORBA::ULong max = 4294967295UL; // Maximum 32-bit unsigned integer + return object_group->_hash (max); +} + +ACE_INLINE CORBA::ULong +TAO_LB_FactoryCreationId_Hash::operator() ( + const TAO_LoadBalancing::FactoryCreationId &factory_creation_id) const +{ + // A Load Balancer FactoryCreationId is simply a CORBA::ULong. + + CORBA::ULong id; + factory_creation_id >>= id; + + return id; +} diff --git a/TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Map.h b/TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Map.h new file mode 100644 index 00000000000..52817547c36 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Map.h @@ -0,0 +1,106 @@ +// -*- C++ -*- +// +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO_LoadBalancing +// +// = FILENAME +// LB_ObjectGroup_Map.h +// +// = AUTHOR +// Ossama Othman +// +// ============================================================================ + +#ifndef TAO_LB_OBJECTGROUP_MAP_H +#define TAO_LB_OBJECTGROUP_MAP_H + +#include "ace/pre.h" + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Hash_Map_Manager.h" +#include "LB_Replica_Map.h" +#include "LB_ObjectGroup_Hash.h" +#include "LB_ObjectGroup_Equal_To.h" +#include "orbsvcs/LoadBalancingC.h" + +class TAO_LB_ObjectGroup_Map +{ + // = TITLE + // Map of RepositoryId to ObjectGroup reference, + // FactoryCreationId, replicas belonging to the ObjectGroup and + // corresponding replica-specific information. + // + // = DESCRIPTION + // Implementation to be used by the Load Balancer + // ReplicationManager. + +public: + + struct Map_Entry + { + // = TITLE + // Value field of the replica map. + // + // = DESCRIPTION + // Mapping from and to all of the following fields: + // , , , and + // . Therefore, we keep all the fields + // together in the map. + + CORBA::String_var type_id; + // The RepositoryId corresponding to all Replicas in the + // ObjectGroup. + + TAO_LoadBalancing::ObjectGroup_var object_group; + // Reference to the ObjectGroup. + + TAO_LoadBalancing::FactoryCreationId factory_creation_id; + // The FactoryCreationId corresponding to the ObjectGroup created by + // the Load Balancer GenericFactory. + + TAO_LB_Replica_Map replica_map; + // Hash map containing replica references and all related + // information for each replica. + }; + + typedef ACE_Hash_Map_Manager_Ex< + const char *, + Map_Entry *, + ACE_Hash, + ACE_Equal_To, + ACE_SYNCH_MUTEX> type_id_map; + // type_id hash map. + + typedef ACE_Hash_Map_Manager_Ex< + TAO_LoadBalancing::ObjectGroup_ptr, + Map_Entry *, + TAO_LB_ObjectGroup_Hash, + TAO_LB_ObjectGroup_Equal_To, + ACE_SYNCH_MUTEX> ObjectGroup_map; + // ObjectGroup hash map. + + typedef ACE_Hash_Map_Manager_Ex< + TAO_LoadBalancing::FactoryCreationId, + Map_Entry *, + TAO_LB_FactoryCreationId_Hash, + TAO_LB_FactoryCreationId_Equal_To, + ACE_SYNCH_MUTEX> FactoryCreationId_map; + // FactoryCreationId hash map. + + int bind (const char *type_id, + TAO_LoadBalancing::ObjectGroup_ptr object_group, + TAO_LoadBalancing::FactoryCreationId &factory_creation_id); +}; + +#include "ace/post.h" + +#endif /* TAO_LB_OBJECTGROUP_MAP_H */ diff --git a/TAO/orbsvcs/orbsvcs/LB_Replica_Equal_To.cpp b/TAO/orbsvcs/orbsvcs/LB_Replica_Equal_To.cpp new file mode 100644 index 00000000000..f6c98a690f7 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LB_Replica_Equal_To.cpp @@ -0,0 +1,9 @@ +// -*- C++ -*- + +#include "LB_Replica_Equal_To.h" + +#if !defined (__ACE_INLINE__) +#include "LB_Replica_Equal_To.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID (TAO_LoadBalancing, LB_Replica_Equal_To, "$Id$") diff --git a/TAO/orbsvcs/orbsvcs/LB_Replica_Equal_To.h b/TAO/orbsvcs/orbsvcs/LB_Replica_Equal_To.h new file mode 100644 index 00000000000..0192ebf7dc7 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LB_Replica_Equal_To.h @@ -0,0 +1,81 @@ +// -*- C++ -*- +// +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO_LoadBalancing +// +// = FILENAME +// LB_Replica_Equal_To.h +// +// = AUTHOR +// Ossama Othman +// +// ============================================================================ + +#ifndef TAO_LB_REPLICA_EQUAL_TO_H +#define TAO_LB_REPLICA_EQUAL_TO_H + +#include "ace/pre.h" + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "LoadbalancingC.h" + +class TAO_LB_Replica_Equal_To +{ + // = TITLE + // Function object for comparing equivalence of two Replica + // references. + // + // = DESCRIPTION + // This class basically wraps the + // CORBA::Object::_is_equivalent() method so that it can be + // utilized by a Hash Map to determine equivalence of two + // external IDs. + +public: + + int operator() (const CORBA::Object_ptr &lhs, + const CORBA::Object_ptr &rhs) const; + // Invokes the CORBA::Object::_is_equivalent() method to determine + // if both references refer to the same object group. However, this + // is a weak test since is_equivalent() can only conclusively + // determine if two references refer to the same object, but it + // cannot determine if two refereneces do not refer to the same + // object. +}; + +class TAO_LB_Location_Equal_To +{ + // = TITLE + // Function object for comparing equivalence of two Locations + // + // = DESCRIPTION + // This class iterates through the contents of the two Locations + // being compared. If any of the corresponding contents of the + // Locations do not match, then the Locations are not equal. + +public: + + int operator() (const TAO_LoadBalancing::Location &lhs, + const TAO_LoadBalancing::Location &rhs) const; + // Iterate through the contents of each Location until a mismatch + // occurs. If no mismatch is found, then the Locations are + // considered equal. +}; + + +#if defined (__ACE_INLINE__) +#include "LB_Replica_Equal_To.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/post.h" + +#endif /* TAO_LB_REPLICA_EQUAL_TO_H */ diff --git a/TAO/orbsvcs/orbsvcs/LB_Replica_Equal_To.inl b/TAO/orbsvcs/orbsvcs/LB_Replica_Equal_To.inl new file mode 100644 index 00000000000..29db9835b3c --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LB_Replica_Equal_To.inl @@ -0,0 +1,37 @@ +// -*- C++ -*- +// +// $Id$ + +ACE_INLINE int +TAO_LB_Replica_Equal_To::operator() ( + const CORBA::Object_ptr &lhs, + const CORBA::Object_ptr &rhs) const +{ + // As with all CORBA objects, the + // CORBA::Object::_is_equivalent() returns 1 if two + // references refer to the same object. However, it is possible + // that is_equivalent() may return 0 even if both references refer + // to the same object. + + return lhs->_is_equivalent (rhs); +} + + +ACE_INLINE int +TAO_LB_Location_Equal_To::operator() ( + const TAO_LoadBalancing::Location &lhs, + const TAO_LoadBalancing::Location &rhs) const +{ + size_t lhs_length = lhs.length (); + size_t rhs_length = rhs.length (); + + if (lhs_length != rhs_length) + return 0; + + for (size_t i = 0; i < lhs_length; ++i) + if (ACE_OS::strcmp (lhs[i].id, rhs[i].id) != 0 + || ACE_OS::strcmp (lhs[i].kind), rhs[i].kind != 0) + return 0; + + return 1; +} diff --git a/TAO/orbsvcs/orbsvcs/LB_Replica_Hash.cpp b/TAO/orbsvcs/orbsvcs/LB_Replica_Hash.cpp new file mode 100644 index 00000000000..d1d7a538067 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LB_Replica_Hash.cpp @@ -0,0 +1,9 @@ +// -*- C++ -*- + +#include "LB_Replica_Hash.h" + +#if !defined (__ACE_INLINE__) +#include "LB_Replica_Hash.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID (TAO_LoadBalancing, LB_Replica_Hash, "$Id$") diff --git a/TAO/orbsvcs/orbsvcs/LB_Replica_Hash.h b/TAO/orbsvcs/orbsvcs/LB_Replica_Hash.h new file mode 100644 index 00000000000..e220dadf48a --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LB_Replica_Hash.h @@ -0,0 +1,72 @@ +// -*- C++ -*- +// +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO_LoadBalancing +// +// = FILENAME +// LB_Replica_Hash.h +// +// = AUTHOR +// Ossama Othman +// +// ============================================================================ + +#ifndef TAO_LB_REPLICA_HASH_H +#define TAO_LB_REPLICA_HASH_H + +#include "ace/pre.h" + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/ACE.h" +#include "LoadbalancingC.h" + +class TAO_LB_Replica_Hash +{ + // = TITLE + // Hash function object for generating a hash for a Replica + // reference. + // + // = DESCRIPTION + // This class basically wraps the CORBA::Object::_hash() method + // so that it can be utilized by a Hash Map. + +public: + + CORBA::ULong operator() (const CORBA::::Object_ptr &replica) const; + // Invokes the _hash() method on the replica reference. +}; + + +class TAO_LB_Location_Hash +{ + // = TITLE + // Hash function object for generating a hash for a + // Location. + // + // = DESCRIPTION + // Create a hash based on the contents of the Location. + +public: + + CORBA::ULong operator() (const TAO_LoadBalancing::Location &) const; + // Generates a hash value based on the contents of the + // Location. +}; + + +#if defined (__ACE_INLINE__) +#include "LB_Replica_Hash.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/post.h" + +#endif /* TAO_LB_REPLICA_HASH_H */ diff --git a/TAO/orbsvcs/orbsvcs/LB_Replica_Hash.inl b/TAO/orbsvcs/orbsvcs/LB_Replica_Hash.inl new file mode 100644 index 00000000000..dedec714bf5 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LB_Replica_Hash.inl @@ -0,0 +1,26 @@ +// -*- C++ -*- +// +// $Id$ + +ACE_INLINE CORBA::ULong +TAO_LB_Replica_Hash::operator() ( + const CORBA::Object_ptr &replica) const +{ + CORBA::ULong max = 4294967295UL; // Maximum 32-bit unsigned integer + return replica->_hash (max); +} + +ACE_INLINE CORBA::ULong +TAO_LB_Location_Hash::operator() ( + const TAO_LoadBalancing::Location &location) const +{ + CORBA::ULong hash = 0; + + size_t location_length = location.length (); + + for (size_t i = 0; i < location_length; ++i) + hash += (ACE::hash_pjw (location[i].id) + ACE::hash_pjw (location[i].kind)); + + return hash; +} diff --git a/TAO/orbsvcs/orbsvcs/LB_Replica_Map.h b/TAO/orbsvcs/orbsvcs/LB_Replica_Map.h new file mode 100644 index 00000000000..e8995c3d31f --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LB_Replica_Map.h @@ -0,0 +1,91 @@ +// -*- C++ -*- +// +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO_LoadBalancing +// +// = FILENAME +// LB_Replica_Map.h +// +// = AUTHOR +// Ossama Othman +// +// ============================================================================ + +#ifndef TAO_LB_REPLICA_MAP_H +#define TAO_LB_REPLICA_MAP_H + +#include "ace/pre.h" + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Hash_Map_Manager.h" +#include "orbsvcs/LoadBalancingC.h" +#include "LB_Replica_Hash.h" +#include "LB_Replica_Equal_To.h" + +class TAO_LB_Replica_Map +{ + // = TITLE + // Map of replica references to location and factory. + // + // = DESCRIPTION + // Implementation to be used by the Load Balancer + // ReplicationManager. + +public: + + struct Map_Entry + { + // = TITLE + // Value field of the replica map. + // + // = DESCRIPTION + // We need a mapping from and to all of the following fields: + // , , , and + // . Therefore, we keep all the fields + // together in the map. + + CORBA::Object_var replica; + // Reference to the replica. + + TAO_LoadBalancer::FactoryInfo_var factory_info; + // Pointer to FactoryInfo structure associated with the replica. + + TAO_LoadBalancer::FactoryCreationId factory_creation_id; + // The FactoryCreationId corresponding to the replica created by + // the above factory. This factory creation ID is only valid if + // the corresponding factory reference above is not nil. + + TAO_LoadBalancer::Location &location = factory_info.the_location; + // The location where the replica resides. + }; + + typedef ACE_Hash_Map_Manager_Ex< + CORBA::Object_ptr, + Map_Entry *, + TAO_LB_Replica_Hash, + TAO_LB_Replica_Equal_To, + ACE_SYNCH_MUTEX> replica_map; + // replica hash map. + + typedef ACE_Hash_Map_Manager_Ex< + TAO_LoadBalancer::Location, + Map_Entry *, + TAO_LB_Location_Hash, + TAO_LB_Location_Equal_To, + ACE_SYNCH_MUTEX> location_map; + // location hash map. +}; + + +#include "ace/post.h" + +#endif /* TAO_LB_REPLICA_MAP_H */ diff --git a/TAO/orbsvcs/orbsvcs/LB_Replication_Manager.h b/TAO/orbsvcs/orbsvcs/LB_Replication_Manager.h new file mode 100644 index 00000000000..e900bfd1332 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LB_Replication_Manager.h @@ -0,0 +1,6 @@ +// -*- C++ -*- +// +// $Id$ + +CORBA::Object_ptr +TAO_LB_Replication_Manager:: diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing.idl b/TAO/orbsvcs/orbsvcs/LoadBalancing.idl index 690b8bbe43b..327730d2a8d 100644 --- a/TAO/orbsvcs/orbsvcs/LoadBalancing.idl +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing.idl @@ -4,7 +4,7 @@ // ============================================================================ // // = LIBRARY -// TAO_LoadBalancing +// TAO_LoadBalancing // // = FILENAME // LoadBalancing.idl @@ -17,7 +17,10 @@ #ifndef TAO_LOADBALANCING_IDL #define TAO_LOADBALANCING_IDL -module LoadBalancing +#include "CosNaming.idl" +#include "orb.idl" + +module TAO_LoadBalancing { // = TITLE // This module defines the interfaces and data types used in TAO's @@ -32,131 +35,175 @@ module LoadBalancing // example, some applications may choose to load balance access // to multiple dedicated lines, or separate network interfaces, // as well as more traditional load balancing metrics, such as - // CPU or disk load. - - interface ReplicaControl - { - // = TITLE - // An interface that specifies methods the Load Balancer - // invokes when informing the ReplicaControl of the - // underlying Object's load status. - - // = DESCRIPTION - // The ReplicaControl provides a means to control the load on - // the Object it is controlling without forcing existing - // Objects to change their interface. The LoadBalancer - // issues advisories to the ReplicaControl when it detects - // load levels that should be handled in a certain way. - - void high_load_advisory (); - // When the LoadBalancer detects a "high" load on a given Object - // via its ReplicaProxy, it issues a high load advisory to the - // ReplicaControl by invoking this method; typically causing the - // underlying object to stop accepting requests. - - void nominal_load_advisory (); - // If a "nominal" load is detected, then a nominal load advisory - // is issued, typically causing the Object to once again accept - // requests. - }; - - interface ReplicaProxy - { - // = TITLE - // This interface provides the methods that the - // ReplicaControl object invokes. - - // = DESCRIPTION - // The ReplicaProxy resides in the LoadBalancer. - // A ReplicaControl object obtains a reference to a - // ReplicaProxy from the LoadBalancer, and invokes the - // methods in the interface to send load information to the - // Load Balancer. - - exception InvalidLoad - { - // = TITLE - // An invalid load was sent to the ReplicaProxy. - }; - - exception NilControl - { - // = TITLE - // This exception indicates that a nil ReplicaControl - // reference was passed to the ReplicaProxy. - }; - - exception NilReplica - { - // = TITLE - // This exception indicates that the reference to the - // object being load balanced was nil. - }; - - exception NotConnected - { - // = TITLE - // This exception is thrown when an attempt is made to - // disconnect from the LoadBalancer but no connection is - // currently established. - }; - - oneway void current_load (in float load); - // Send current load to the Load Balancer. - // The application must ensure that all replicas use the same - // notion of load. - - void disconnect () raises (NotConnected); - // Disconnect the ReplicaControl from the Load Balancer. The - // Object that the ReplicaControl controls will be no longer be - // load balanced. - }; - - interface LoadBalancer - { - // = TITLE - // The LoadBalancer interface. - - // = DESCRIPTION - // The LoadBalancer distributes incoming requests for a given - // Object among several replicas of that Object, thus helping - // to ensure that loads are as well balanced across the - // systems the replicas are running on as possible. - - exception InvalidReplicaProxy - { - // = TITLE - // This exception indicates that an attempt was made to - // use a ReplicaProxy that is not registered with the - // LoadBalancer. - // @@ Ossama: where exactly is this exception used? Who - // can raise it!? - }; - - ReplicaProxy connect (in ReplicaControl control, - in Object replica) - raises (ReplicaProxy::NilControl, - ReplicaProxy::NilReplica); - // Register ReplicaControl with LoadBalancer, thus allowing the - // Object to be load balanced. - - Object group_identity (); - // Return the reference to the object that represents the - // Replica group being load balanced. This "group identity" - // object will cause the client to redirect its requests to a - // Replica that fits a specific load balancing criteria. - }; - - // @@ Ossama: we may want to add interfaces or operations to access - // the current list of loads, that would be useful for monitoring - // applications, and nice GUI-based demos. - // @@ Ossama: another idea: we have been using this stuff to make - // all the loads equal, but what if the objective is to keep the - // load below some value? Maybe we should provide some callback - // mechanism to let the application know: the load is too high and - // there is nothing i can do about it, add more CPUS or reduce the - // load! - // Such feedback would be very useful for some applications. + // CPU or power load. + + // Specification of Common Types and Exceptions for ReplicationManager + interface GenericFactory; + interface LoadNotifier; + + typedef unsigned long long ObjectGroupId; + typedef unsigned long ObjectGroupRefVersion; + + typedef CORBA::RepositoryId TypeId; + typedef Object ObjectGroup; + typedef CosNaming::Name Name; + typedef any Value; + + struct Property { + Name nam; + Value val; + }; + typedef sequence Properties; + + typedef Name Location; + typedef sequence Locations; + + typedef Properties Criteria; + + struct FactoryInfo { + GenericFactory factory; + Location the_location; + Criteria the_criteria; + }; + typedef sequence FactoryInfos; + + exception InterfaceNotFound {}; + exception ObjectGroupNotFound {}; + exception MemberNotFound {}; + exception ObjectNotFound {}; + exception MemberAlreadyPresent {}; + exception BadReplicationStyle {}; + exception ObjectNotCreated {}; + exception ObjectNotAdded {}; + exception PrimaryNotSet {}; + exception UnsupportedProperty { + Name nam; + }; + exception InvalidProperty { + Name nam; + Value val; + }; + exception NoFactory { + Location the_location; + TypeId type_id; + }; + exception InvalidCriteria { + Criteria invalid_criteria; + }; + exception CannotMeetCriteria { + Criteria unmet_criteria; + }; + + // Specification of PropertyManager Interface + // which ReplicationManager Inherits + interface PropertyManager { + void set_default_properties (in Properties props) + raises (InvalidProperty, + UnsupportedProperty); + + Properties get_default_properties (); + + void remove_default_properties (in Properties props) + raises (InvalidProperty, + UnsupportedProperty); + + void set_type_properties (in TypeId type_id, + in Properties overrides) + raises (InvalidProperty, + UnsupportedProperty); + + Properties get_type_properties (in TypeId type_id); + + void remove_type_properties (in TypeId type_id, + in Properties props) + raises (InvalidProperty, + UnsupportedProperty); + + void set_properties_dynamically (in ObjectGroup object_group, + in Properties overrides) + raises (ObjectGroupNotFound, + InvalidProperty, + UnsupportedProperty); + + Properties get_properties (in ObjectGroup object_group) + raises (ObjectGroupNotFound); + }; + + // Specification of ObjectGroupManager Interface + // which ReplicationManager Inherits + interface ObjectGroupManager { + ObjectGroup create_member (in ObjectGroup object_group, + in Location the_location, + in TypeId type_id, + in Criteria the_criteria) + raises (ObjectGroupNotFound, + MemberAlreadyPresent, + NoFactory, + ObjectNotCreated, + InvalidCriteria, + CannotMeetCriteria); + + ObjectGroup add_member (in ObjectGroup object_group, + in Location the_location, + in Object member) + raises (ObjectGroupNotFound, + // CORBA::INV_OBJREF, // @@ Missing declaration + MemberAlreadyPresent, + ObjectNotAdded); + + ObjectGroup remove_member (in ObjectGroup object_group, + in Location the_location) + raises (ObjectGroupNotFound, + MemberNotFound); + + ObjectGroup set_primary_member (in ObjectGroup object_group, + in Location the_location) + raises (ObjectGroupNotFound, + MemberNotFound, + PrimaryNotSet, + BadReplicationStyle); + + Locations locations_of_members (in ObjectGroup object_group) + raises (ObjectGroupNotFound); + + ObjectGroupId get_object_group_id (in ObjectGroup object_group) + raises (ObjectGroupNotFound); + + ObjectGroup get_object_group_ref (in ObjectGroup object_group) + raises (ObjectGroupNotFound); + + Object get_member_ref (in ObjectGroup object_group, + in Location loc) + raises (ObjectGroupNotFound, + MemberNotFound); + }; + + // Specification of GenericFactory Interface + // which ReplicationManager Inherits and Application Objects Implement + interface GenericFactory { + typedef any FactoryCreationId; + + Object create_object (in TypeId type_id, + in Criteria the_criteria, + out FactoryCreationId factory_creation_id) + raises (NoFactory, + ObjectNotCreated, + InvalidCriteria, + InvalidProperty, + CannotMeetCriteria); + + void delete_object (in FactoryCreationId factory_creation_id) + raises (ObjectNotFound); + }; + + // Specification of ReplicationManager Interface + interface ReplicationManager : PropertyManager, ObjectGroupManager, + GenericFactory { + void register_load_notifier (in LoadNotifier load_notifier); + + LoadNotifier get_load_notifier () + raises (InterfaceNotFound); + }; }; #endif /* TAO_LOADBALANCER_IDL */ diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Equal_To.cpp b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Equal_To.cpp new file mode 100644 index 00000000000..f86d26808f7 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Equal_To.cpp @@ -0,0 +1,9 @@ +// -*- C++ -*- + +#include "LB_Equal_To.h" + +#if !defined (__ACE_INLINE__) +#include "LB_Equal_To.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID (TAO_LoadBalancing, LB_Equal_To, "$Id$") diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Equal_To.h b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Equal_To.h new file mode 100644 index 00000000000..33eccb6d71f --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Equal_To.h @@ -0,0 +1,79 @@ +// -*- C++ -*- +// +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO_LoadBalancing +// +// = FILENAME +// LB_ObjectGroup_Equal_To.h +// +// = AUTHOR +// Ossama Othman +// +// ============================================================================ + +#ifndef TAO_LB_OBJECTGROUP_EQUAL_TO_H +#define TAO_LB_OBJECTGROUP_EQUAL_TO_H + +#include "ace/pre.h" + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "LoadbalancingC.h" + +class TAO_LB_ObjectGroup_Equal_To +{ + // = TITLE + // Function object that compares equality of two ObjectGroup + // references. + // + // = DESCRIPTION + // This class basically wraps the + // CORBA::Object::_is_equivalent() method so that it can be + // utilized by a Hash Map as a way to compare equality. + +public: + + int operator() (const TAO_LoadBalancing::ObjectGroup_ptr &lhs, + const TAO_LoadBalancing::ObjectGroup_ptr &rhs) const; + // Invokes the CORBA::Object::_is_equivalent() method to determine + // if both references refer to the same object group. However, this + // is a weak test since is_equivalent() can only conclusively + // determine if two references refer to the same object, but it + // cannot determine if two refereneces do not refer to the same + // object. +}; + +class TAO_LB_FactoryCreationId_Equal_To +{ + // = TITLE + // Function object that compares equality of two + // FactoryCreationId values. + // + // = DESCRIPTION + // This class extracts the actual value of the FactoryCreationId + // from the CORBA::Any the FactoryCreationId is typedefed to. + +public: + + int operator() ( + const TAO_LoadBalancing::FactoryCreationId &lhs, + const TAO_LoadBalancing::FactoryCreationId &rhs) const; + // Check if two FactoryCreationId values are the same. +}; + + +#if defined (__ACE_INLINE__) +#include "LB_ObjectGroup_Equal_To.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/post.h" + +#endif /* TAO_LB_OBJECTGROUP_EQUAL_TO_H */ diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Equal_To.inl b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Equal_To.inl new file mode 100644 index 00000000000..7547d068b72 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Equal_To.inl @@ -0,0 +1,33 @@ +// -*- C++ -*- +// +// $Id$ + +ACE_INLINE int +TAO_LB_ObjectGroup_Equal_To::operator() ( + const TAO_LoadBalancing::ObjectGroup_ptr &lhs, + const TAO_LoadBalancing::ObjectGroup_ptr &rhs) const +{ + // As with all CORBA objects, the + // TAO_LoadBalancing::ObjectGroup::is_equivalent() returns 1 if two + // references refer to the same object. However, it is possible + // that is_equivalent() may return 0 even if both references refer + // to the same object. + + return lhs->_is_equivalent (rhs); +} + + +ACE_INLINE int +TAO_LB_FactoryCreationId_Equal_To::operator() ( + const TAO_LoadBalancing::FactoryCreationId &lhs, + const TAO_LoadBalancing::FactoryCreationId &rhs) const +{ + // A Load Balancer FactoryCreationId is simply a CORBA::ULong. + + CORBA::ULong lhs_id, rhs_id; + + lhs >>= lhs_id; + rhs >>= rhs_id; + + return (lhs_id == rhs_id); +} diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Hash.cpp b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Hash.cpp new file mode 100644 index 00000000000..594e3bb1380 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Hash.cpp @@ -0,0 +1,9 @@ +// -*- C++ -*- + +#include "LB_Hash.h" + +#if !defined (__ACE_INLINE__) +#include "LB_Hash.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID (TAO_LoadBalancing, LB_Hash, "$Id$") diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Hash.h b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Hash.h new file mode 100644 index 00000000000..488fa7bbc93 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Hash.h @@ -0,0 +1,71 @@ +// -*- C++ -*- +// +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO_LoadBalancing +// +// = FILENAME +// LB_Hash.h +// +// = AUTHOR +// Ossama Othman +// +// ============================================================================ + +#ifndef TAO_LB_HASH_H +#define TAO_LB_HASH_H + +#include "ace/pre.h" + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "LoadbalancingC.h" + +class TAO_LB_ObjectGroup_Hash +{ + // = TITLE + // Hash function object for generating a hash for an ObjectGroup + // reference. + // + // = DESCRIPTION + // This class basically wraps the CORBA::Object::_hash() method + // so that it can be utilized by a Hash Map. + +public: + + CORBA::ULong operator() (const TAO_LoadBalancing::ObjectGroup_ptr &) const; + // Invokes the _hash() method on the ObjectGroup reference. +}; + + +class TAO_LB_FactoryCreationId_Hash +{ + // = TITLE + // Hash function object for generating a hash for a + // FactoryCreationId. + // + // = DESCRIPTION + // Create a hash based on the contents of the FactoryCreationId. + +public: + + CORBA::ULong operator() (const TAO_LoadBalancing::FactoryCreationId &) const; + // Generates a hash value based on the contents of the + // FactoryCreationId. +}; + + +#if defined (__ACE_INLINE__) +#include "LB_Hash.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/post.h" + +#endif /* TAO_LB_HASH_H */ diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Hash.inl b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Hash.inl new file mode 100644 index 00000000000..8bf5490a545 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Hash.inl @@ -0,0 +1,23 @@ +// -*- C++ -*- +// +// $Id$ + +ACE_INLINE CORBA::ULong +TAO_LB_ObjectGroup_Hash::operator() ( + const TAO_LoadBalancing::ObjectGroup_ptr &object_group) const +{ + CORBA::ULong max = 4294967295UL; // Maximum 32-bit unsigned integer + return object_group->_hash (max); +} + +ACE_INLINE CORBA::ULong +TAO_LB_FactoryCreationId_Hash::operator() ( + const TAO_LoadBalancing::FactoryCreationId &factory_creation_id) const +{ + // A Load Balancer FactoryCreationId is simply a CORBA::ULong. + + CORBA::ULong id; + factory_creation_id >>= id; + + return id; +} diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Map.h b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Map.h new file mode 100644 index 00000000000..52817547c36 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Map.h @@ -0,0 +1,106 @@ +// -*- C++ -*- +// +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO_LoadBalancing +// +// = FILENAME +// LB_ObjectGroup_Map.h +// +// = AUTHOR +// Ossama Othman +// +// ============================================================================ + +#ifndef TAO_LB_OBJECTGROUP_MAP_H +#define TAO_LB_OBJECTGROUP_MAP_H + +#include "ace/pre.h" + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Hash_Map_Manager.h" +#include "LB_Replica_Map.h" +#include "LB_ObjectGroup_Hash.h" +#include "LB_ObjectGroup_Equal_To.h" +#include "orbsvcs/LoadBalancingC.h" + +class TAO_LB_ObjectGroup_Map +{ + // = TITLE + // Map of RepositoryId to ObjectGroup reference, + // FactoryCreationId, replicas belonging to the ObjectGroup and + // corresponding replica-specific information. + // + // = DESCRIPTION + // Implementation to be used by the Load Balancer + // ReplicationManager. + +public: + + struct Map_Entry + { + // = TITLE + // Value field of the replica map. + // + // = DESCRIPTION + // Mapping from and to all of the following fields: + // , , , and + // . Therefore, we keep all the fields + // together in the map. + + CORBA::String_var type_id; + // The RepositoryId corresponding to all Replicas in the + // ObjectGroup. + + TAO_LoadBalancing::ObjectGroup_var object_group; + // Reference to the ObjectGroup. + + TAO_LoadBalancing::FactoryCreationId factory_creation_id; + // The FactoryCreationId corresponding to the ObjectGroup created by + // the Load Balancer GenericFactory. + + TAO_LB_Replica_Map replica_map; + // Hash map containing replica references and all related + // information for each replica. + }; + + typedef ACE_Hash_Map_Manager_Ex< + const char *, + Map_Entry *, + ACE_Hash, + ACE_Equal_To, + ACE_SYNCH_MUTEX> type_id_map; + // type_id hash map. + + typedef ACE_Hash_Map_Manager_Ex< + TAO_LoadBalancing::ObjectGroup_ptr, + Map_Entry *, + TAO_LB_ObjectGroup_Hash, + TAO_LB_ObjectGroup_Equal_To, + ACE_SYNCH_MUTEX> ObjectGroup_map; + // ObjectGroup hash map. + + typedef ACE_Hash_Map_Manager_Ex< + TAO_LoadBalancing::FactoryCreationId, + Map_Entry *, + TAO_LB_FactoryCreationId_Hash, + TAO_LB_FactoryCreationId_Equal_To, + ACE_SYNCH_MUTEX> FactoryCreationId_map; + // FactoryCreationId hash map. + + int bind (const char *type_id, + TAO_LoadBalancing::ObjectGroup_ptr object_group, + TAO_LoadBalancing::FactoryCreationId &factory_creation_id); +}; + +#include "ace/post.h" + +#endif /* TAO_LB_OBJECTGROUP_MAP_H */ diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Equal_To.cpp b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Equal_To.cpp new file mode 100644 index 00000000000..f6c98a690f7 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Equal_To.cpp @@ -0,0 +1,9 @@ +// -*- C++ -*- + +#include "LB_Replica_Equal_To.h" + +#if !defined (__ACE_INLINE__) +#include "LB_Replica_Equal_To.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID (TAO_LoadBalancing, LB_Replica_Equal_To, "$Id$") diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Equal_To.h b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Equal_To.h new file mode 100644 index 00000000000..0192ebf7dc7 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Equal_To.h @@ -0,0 +1,81 @@ +// -*- C++ -*- +// +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO_LoadBalancing +// +// = FILENAME +// LB_Replica_Equal_To.h +// +// = AUTHOR +// Ossama Othman +// +// ============================================================================ + +#ifndef TAO_LB_REPLICA_EQUAL_TO_H +#define TAO_LB_REPLICA_EQUAL_TO_H + +#include "ace/pre.h" + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "LoadbalancingC.h" + +class TAO_LB_Replica_Equal_To +{ + // = TITLE + // Function object for comparing equivalence of two Replica + // references. + // + // = DESCRIPTION + // This class basically wraps the + // CORBA::Object::_is_equivalent() method so that it can be + // utilized by a Hash Map to determine equivalence of two + // external IDs. + +public: + + int operator() (const CORBA::Object_ptr &lhs, + const CORBA::Object_ptr &rhs) const; + // Invokes the CORBA::Object::_is_equivalent() method to determine + // if both references refer to the same object group. However, this + // is a weak test since is_equivalent() can only conclusively + // determine if two references refer to the same object, but it + // cannot determine if two refereneces do not refer to the same + // object. +}; + +class TAO_LB_Location_Equal_To +{ + // = TITLE + // Function object for comparing equivalence of two Locations + // + // = DESCRIPTION + // This class iterates through the contents of the two Locations + // being compared. If any of the corresponding contents of the + // Locations do not match, then the Locations are not equal. + +public: + + int operator() (const TAO_LoadBalancing::Location &lhs, + const TAO_LoadBalancing::Location &rhs) const; + // Iterate through the contents of each Location until a mismatch + // occurs. If no mismatch is found, then the Locations are + // considered equal. +}; + + +#if defined (__ACE_INLINE__) +#include "LB_Replica_Equal_To.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/post.h" + +#endif /* TAO_LB_REPLICA_EQUAL_TO_H */ diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Equal_To.inl b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Equal_To.inl new file mode 100644 index 00000000000..29db9835b3c --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Equal_To.inl @@ -0,0 +1,37 @@ +// -*- C++ -*- +// +// $Id$ + +ACE_INLINE int +TAO_LB_Replica_Equal_To::operator() ( + const CORBA::Object_ptr &lhs, + const CORBA::Object_ptr &rhs) const +{ + // As with all CORBA objects, the + // CORBA::Object::_is_equivalent() returns 1 if two + // references refer to the same object. However, it is possible + // that is_equivalent() may return 0 even if both references refer + // to the same object. + + return lhs->_is_equivalent (rhs); +} + + +ACE_INLINE int +TAO_LB_Location_Equal_To::operator() ( + const TAO_LoadBalancing::Location &lhs, + const TAO_LoadBalancing::Location &rhs) const +{ + size_t lhs_length = lhs.length (); + size_t rhs_length = rhs.length (); + + if (lhs_length != rhs_length) + return 0; + + for (size_t i = 0; i < lhs_length; ++i) + if (ACE_OS::strcmp (lhs[i].id, rhs[i].id) != 0 + || ACE_OS::strcmp (lhs[i].kind), rhs[i].kind != 0) + return 0; + + return 1; +} diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Hash.cpp b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Hash.cpp new file mode 100644 index 00000000000..d1d7a538067 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Hash.cpp @@ -0,0 +1,9 @@ +// -*- C++ -*- + +#include "LB_Replica_Hash.h" + +#if !defined (__ACE_INLINE__) +#include "LB_Replica_Hash.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID (TAO_LoadBalancing, LB_Replica_Hash, "$Id$") diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Hash.h b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Hash.h new file mode 100644 index 00000000000..e220dadf48a --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Hash.h @@ -0,0 +1,72 @@ +// -*- C++ -*- +// +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO_LoadBalancing +// +// = FILENAME +// LB_Replica_Hash.h +// +// = AUTHOR +// Ossama Othman +// +// ============================================================================ + +#ifndef TAO_LB_REPLICA_HASH_H +#define TAO_LB_REPLICA_HASH_H + +#include "ace/pre.h" + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/ACE.h" +#include "LoadbalancingC.h" + +class TAO_LB_Replica_Hash +{ + // = TITLE + // Hash function object for generating a hash for a Replica + // reference. + // + // = DESCRIPTION + // This class basically wraps the CORBA::Object::_hash() method + // so that it can be utilized by a Hash Map. + +public: + + CORBA::ULong operator() (const CORBA::::Object_ptr &replica) const; + // Invokes the _hash() method on the replica reference. +}; + + +class TAO_LB_Location_Hash +{ + // = TITLE + // Hash function object for generating a hash for a + // Location. + // + // = DESCRIPTION + // Create a hash based on the contents of the Location. + +public: + + CORBA::ULong operator() (const TAO_LoadBalancing::Location &) const; + // Generates a hash value based on the contents of the + // Location. +}; + + +#if defined (__ACE_INLINE__) +#include "LB_Replica_Hash.inl" +#endif /* __ACE_INLINE__ */ + +#include "ace/post.h" + +#endif /* TAO_LB_REPLICA_HASH_H */ diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Hash.inl b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Hash.inl new file mode 100644 index 00000000000..dedec714bf5 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Hash.inl @@ -0,0 +1,26 @@ +// -*- C++ -*- +// +// $Id$ + +ACE_INLINE CORBA::ULong +TAO_LB_Replica_Hash::operator() ( + const CORBA::Object_ptr &replica) const +{ + CORBA::ULong max = 4294967295UL; // Maximum 32-bit unsigned integer + return replica->_hash (max); +} + +ACE_INLINE CORBA::ULong +TAO_LB_Location_Hash::operator() ( + const TAO_LoadBalancing::Location &location) const +{ + CORBA::ULong hash = 0; + + size_t location_length = location.length (); + + for (size_t i = 0; i < location_length; ++i) + hash += (ACE::hash_pjw (location[i].id) + ACE::hash_pjw (location[i].kind)); + + return hash; +} diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Map.h b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Map.h new file mode 100644 index 00000000000..e8995c3d31f --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Map.h @@ -0,0 +1,91 @@ +// -*- C++ -*- +// +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO_LoadBalancing +// +// = FILENAME +// LB_Replica_Map.h +// +// = AUTHOR +// Ossama Othman +// +// ============================================================================ + +#ifndef TAO_LB_REPLICA_MAP_H +#define TAO_LB_REPLICA_MAP_H + +#include "ace/pre.h" + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "ace/Hash_Map_Manager.h" +#include "orbsvcs/LoadBalancingC.h" +#include "LB_Replica_Hash.h" +#include "LB_Replica_Equal_To.h" + +class TAO_LB_Replica_Map +{ + // = TITLE + // Map of replica references to location and factory. + // + // = DESCRIPTION + // Implementation to be used by the Load Balancer + // ReplicationManager. + +public: + + struct Map_Entry + { + // = TITLE + // Value field of the replica map. + // + // = DESCRIPTION + // We need a mapping from and to all of the following fields: + // , , , and + // . Therefore, we keep all the fields + // together in the map. + + CORBA::Object_var replica; + // Reference to the replica. + + TAO_LoadBalancer::FactoryInfo_var factory_info; + // Pointer to FactoryInfo structure associated with the replica. + + TAO_LoadBalancer::FactoryCreationId factory_creation_id; + // The FactoryCreationId corresponding to the replica created by + // the above factory. This factory creation ID is only valid if + // the corresponding factory reference above is not nil. + + TAO_LoadBalancer::Location &location = factory_info.the_location; + // The location where the replica resides. + }; + + typedef ACE_Hash_Map_Manager_Ex< + CORBA::Object_ptr, + Map_Entry *, + TAO_LB_Replica_Hash, + TAO_LB_Replica_Equal_To, + ACE_SYNCH_MUTEX> replica_map; + // replica hash map. + + typedef ACE_Hash_Map_Manager_Ex< + TAO_LoadBalancer::Location, + Map_Entry *, + TAO_LB_Location_Hash, + TAO_LB_Location_Equal_To, + ACE_SYNCH_MUTEX> location_map; + // location hash map. +}; + + +#include "ace/post.h" + +#endif /* TAO_LB_REPLICA_MAP_H */ diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replication_Manager.h b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replication_Manager.h new file mode 100644 index 00000000000..e900bfd1332 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replication_Manager.h @@ -0,0 +1,6 @@ +// -*- C++ -*- +// +// $Id$ + +CORBA::Object_ptr +TAO_LB_Replication_Manager:: diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LoadBalancingI.cpp b/TAO/orbsvcs/orbsvcs/LoadBalancing/LoadBalancingI.cpp new file mode 100644 index 00000000000..14ba8a32ae4 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LoadBalancingI.cpp @@ -0,0 +1,587 @@ +// -*- C++ -*- +// +// $Id$ + +#include "LoadBalancingI.h" + +// Implementation skeleton constructor +TAO_LoadBalancing_ReplicationManager_i::TAO_LoadBalancing_ReplicationManager_i +(void) + : locator_ (this), + poa_ (), + next_oid_ (0), + object_group_map_ () +{ + (void) this->init (); +} + +// Implementation skeleton destructor +TAO_LoadBalancing_ReplicationManager_i::~TAO_LoadBalancing_ReplicationManager_i (void) +{ +} + +void +TAO_LoadBalancing_ReplicationManager_i::register_load_notifier ( + TAO_LoadBalancing::LoadNotifier_ptr /* load_notifier */) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT()); +} + +TAO_LoadBalancing::LoadNotifier_ptr +TAO_LoadBalancing_ReplicationManager_i::get_load_notifier (void) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::InterfaceNotFound)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT ()); +} + +void +TAO_LoadBalancing_ReplicationManager_i::set_default_properties ( + const TAO_LoadBalancing::Properties & /* props */) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::InvalidProperty, + TAO_LoadBalancing::UnsupportedProperty)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT()); +} + +TAO_LoadBalancing::Properties * +TAO_LoadBalancing_ReplicationManager_i::get_default_properties (void) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT ()); +} + +void +TAO_LoadBalancing_ReplicationManager_i::remove_default_properties ( + const TAO_LoadBalancing::Properties & /* props */) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::InvalidProperty, + TAO_LoadBalancing::UnsupportedProperty)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT ()); +} + +void +TAO_LoadBalancing_ReplicationManager_i::set_type_properties ( + const char * /* type_id */, + const TAO_LoadBalancing::Properties & /* overrides */) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::InvalidProperty, + TAO_LoadBalancing::UnsupportedProperty)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT ()); +} + +TAO_LoadBalancing::Properties * +TAO_LoadBalancing_ReplicationManager_i::get_type_properties ( + const char * /* type_id */) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT ()); +} + +void +TAO_LoadBalancing_ReplicationManager_i::remove_type_properties ( + const char * /* type_id */, + const TAO_LoadBalancing::Properties & /* props */) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::InvalidProperty, + TAO_LoadBalancing::UnsupportedProperty)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT ()); +} + +void +TAO_LoadBalancing_ReplicationManager_i::set_properties_dynamically ( + TAO_LoadBalancing::ObjectGroup_ptr /* object_group */, + const TAO_LoadBalancing::Properties & /* overrides */) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound, + TAO_LoadBalancing::InvalidProperty, + TAO_LoadBalancing::UnsupportedProperty)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT ()); +} + +TAO_LoadBalancing::Properties * +TAO_LoadBalancing_ReplicationManager_i::get_properties ( + TAO_LoadBalancing::ObjectGroup_ptr /* object_group */) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT ()); +} + +TAO_LoadBalancing::ObjectGroup_ptr +TAO_LoadBalancing_ReplicationManager_i::create_member ( + TAO_LoadBalancing::ObjectGroup_ptr /* object_group */, + const TAO_LoadBalancing::Location & /* the_location */, + const char * /* type_id */, + const TAO_LoadBalancing::Criteria & /* the_criteria */) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound, + TAO_LoadBalancing::MemberAlreadyPresent, + TAO_LoadBalancing::NoFactory, + TAO_LoadBalancing::ObjectNotCreated, + TAO_LoadBalancing::InvalidCriteria, + TAO_LoadBalancing::CannotMeetCriteria)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT ()); +} + +TAO_LoadBalancing::ObjectGroup_ptr +TAO_LoadBalancing_ReplicationManager_i::add_member ( + TAO_LoadBalancing::ObjectGroup_ptr /* object_group */, + const TAO_LoadBalancing::Location & /* the_location */, + CORBA::Object_ptr /* member */) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound, + TAO_LoadBalancing::MemberAlreadyPresent, + TAO_LoadBalancing::ObjectNotAdded)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT ()); +} + +TAO_LoadBalancing::ObjectGroup_ptr +TAO_LoadBalancing_ReplicationManager_i::remove_member ( + TAO_LoadBalancing::ObjectGroup_ptr /* object_group */, + const TAO_LoadBalancing::Location & /* the_location */) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound, + TAO_LoadBalancing::MemberNotFound)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT ()); +} + +TAO_LoadBalancing::ObjectGroup_ptr +TAO_LoadBalancing_ReplicationManager_i::set_primary_member ( + TAO_LoadBalancing::ObjectGroup_ptr /* object_group */, + const TAO_LoadBalancing::Location & /* the_location */) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound, + TAO_LoadBalancing::MemberNotFound, + TAO_LoadBalancing::PrimaryNotSet, + TAO_LoadBalancing::BadReplicationStyle)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT ()); +} + +TAO_LoadBalancing::Locations * +TAO_LoadBalancing_ReplicationManager_i::locations_of_members ( + TAO_LoadBalancing::ObjectGroup_ptr /* object_group */) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT ()); +} + +TAO_LoadBalancing::ObjectGroupId +TAO_LoadBalancing_ReplicationManager_i::get_object_group_id ( + TAO_LoadBalancing::ObjectGroup_ptr /* object_group */) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT ()); +} + +TAO_LoadBalancing::ObjectGroup_ptr +TAO_LoadBalancing_ReplicationManager_i::get_object_group_ref ( + TAO_LoadBalancing::ObjectGroup_ptr /* object_group */) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT ()); +} + +CORBA::Object_ptr +TAO_LoadBalancing_ReplicationManager_i::get_member_ref ( + TAO_LoadBalancing::ObjectGroup_ptr /* object_group */, + const TAO_LoadBalancing::Location & loc) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound, + TAO_LoadBalancing::MemberNotFound)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT ()); +} + +CORBA::Object_ptr +TAO_LoadBalancing_ReplicationManager_i::create_object ( + const char * type_id, + const TAO_LoadBalancing::Criteria & the_criteria, + TAO_LoadBalancing::GenericFactory::FactoryCreationId_out + factory_creation_id, + CORBA::Environment &ACE_TRY_ENV) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::NoFactory, + TAO_LoadBalancing::ObjectNotCreated, + TAO_LoadBalancing::InvalidCriteria, + TAO_LoadBalancing::InvalidProperty, + TAO_LoadBalancing::CannotMeetCriteria)) +{ + // Check if an ObjectGroup for the given type hasn't already been + // created. + if (this->object_group_map_.find_type_id (type_id) == 0) + ACE_THROW_RETURN (TAO_LoadBalancing::ObjectNotCreated ()); + + // List of invalid criteria. If this list has a length greater than + // zero, then the TAO_LoadBalancing::InvalidCriteria exception will + // be thrown. + TAO_Loadbalancing::Criteria invalid_criteria; + + int found_factory = 0; // If factory was found in the_criteria, then + // set to 1. + + // Parse the criteria. + int criteria_count = the_criteria.length (); + for (int i = 0; i < criteria_size; ++i) + { + CORBA::UShort initial_number_replicas = 0; + TAO_LoadBalancing::FactoryInfos factory_infos; + + // Obtain the InitialNumberReplicas from the_criteria. + if (this->get_initial_number_replicas (type_id, + the_criteria[i], + initial_number_replicas) != 0) + { + size_t length = invalid_criteria.length (); + invalid_criteria.length (length + 1); + invalid_criteria[length] = the_criteria[i]; + } + + // Obtain the FactoryInfos from the_criteria. This method also + // ensure that GenericFactories at different locations are used. + else if (this->get_factory_infos (type_id, + the_criteria[i], + factory_infos) == 0) + found_factory = 1; + + // Unknown property + else + ACE_THROW_RETURN (TAO_LoadBalancer::InvalidProperty ( + the_criteria[i].nam, + the_criteria[i].val), + CORBA::Object::_nil ()); + } + + if (invalid_criteria.length () != 0) + ACE_THROW_RETURN (TAO_LoadBalancing::InvalidCriteria (invalid_criteria), + CORBA::Object::_nil ()); + + if (found_factory == 0) + ACE_THROW_RETURN (TAO_LoadBalancing::NoFactory (), + CORBA::Object::_nil ()); + + return this->create_object_i (type_id, + initial_number_replicas, + factory_infos, + ACE_TRY_ENV); +} + +CORBA::Object_ptr +TAO_LoadBalancing_ReplicationManager_i::create_object_i ( + const char *type_id, + CORBA::UShort initial_number_replicas, + TAO_LoadBalancing::FactoryInfos &factory_infos, + CORBA::Environment &ACE_TRY_ENV) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::NoFactory, + TAO_LoadBalancing::ObjectNotCreated, + TAO_LoadBalancing::InvalidCriteria, + TAO_LoadBalancing::InvalidProperty, + TAO_LoadBalancing::CannotMeetCriteria)) +{ + size_t factory_infos_count = factory_infos.length (); + + // If the number of factories is less than the initial number of + // replicas, then the desired number of replicas cannot possibly be + // created. + if (factory_infos_count < initial_number_replicas) + ACE_THROW_RETURN (TAO_LoadBalancing::CannotMeetCriteria (), + CORBA::Object::_nil ()); + + TAO_LB_ObjectGroup_Map::Map_Entry *object_group_entry = 0; + ACE_NEW_THROW_EX (object_group_entry, + TAO_LB_ObjectGroup_Map::Map_Entry, + CORBA::NO_MEMORY ()); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + auto_ptr safe_object_group_entry ( + object_group_entry); + + for (int j = 0; j < factory_infos_count; ++j) + { + // The FactoryInfo::the_location member was used when + // determining which FactoryInfo + // member? + // @@ It looks like it is only used when the application + // control membership style is used. The application + // requests that a replica be created at a given + // "location," at which point the ReplicationManager + // searches through its registered FactoryInfos for a + // FactoryInfo with a "Location" member that matches + // the location at which to create the desired + // replica. + // @@ It is also used to ensure the only one replica of + // a given type is created at a given location. + + + TAO_LoadBalancing::FactoryInfo &factory_info = + factory_infos[j]; + + TAO_LoadBalancer::GenericFactory_ptr factory = + factory_info.factory; + + TAO_LoadBalancing::GenericFactory::FactoryCreationId_out + replica_factory_creation_id; + + CORBA::Object_var replica = + factory->create_object (type_id, + factory_info.the_criteria, + replica_factory_creation_id, + ACE_TRY_ENV); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + // @@ Should an "_is_a()" be performed here? While it appears + // to be the right thing to do, it can be expensive. + // + // Make sure an Object of the correct type was created. It is + // possible that an object of the wrong type was created if the + // type_id parameter does not match the type of object the + // GenericFactory creates. + CORBA::Boolean right_type_id = + replica->_is_a (type_id, ACE_TRY_ENV); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + if (!right_type_id) + { + // An Object of incorrect type was created. Delete it, and + // throw a NoFactory exception. + factory->delete_object (replica_factory_creation_id, + ACE_TRY_ENV); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + ACE_THROW_RETURN (TAO_LoadBalancer::NoFactory (), + CORBA::Object::_nil ()); + } + + // Create a new Replica_Map map entry. + TAO_LB_Replica_Map::Map_Entry *replica_entry = 0; + ACE_NEW_THROW_EX (replica_entry, + TAO_LB_Replica_Map::Map_Entry, + CORBA::NO_MEMORY ()); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + auto_ptr safe_replica_entry (replica_entry); + + replica_entry->replica = replica; + + TAO_LoadBalancer::FactoryInfo *new_factory_info = 0; + ACE_NEW_THROW_EX (new_factory_info, + TAO_LoadBalancer::FactoryInfo, + CORBA::NO_MEMORY ()); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + replica_entry->factory_info = new_factory_info; + + // Copy the FactoryInfo structure. A deep copy is actually + // performed here. + *new_factory_info = factory_info; + + replica_entry->factory_creation_id = replica_factory_creation_id; + + if (object_group_entry.replica_map.bind (replica_entry) != 0) + ACE_THROW_RETURN (TAO_LoadBalancer::ObjectNotCreated (), + CORBA::Object::_nil ()); + + // No longer need to protect the allocated Replica_Map. + safe_replica_entry.release (); + } + + // Create a reference for the ObjectGroup corresponding to the + // RepositoryId of the object being created. + + PortableServer::ObjectId_var oid; + this->get_ObjectId (oid.out ()); + + CORBA::Object_var object_group = + this->poa_->create_reference_with_id (oid.in (), + type_id, + ACE_TRY_ENV); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + object_group_entry.type_id = CORBA::string_dup (type_id); + object_group_entry.object_group = object_group; + + // @@ This is ugly, and needs to be cleaned up. + object_group_entry.factory_creation_id = this->next_oid_ - 1; + + // Now (indirectly) associate the ObjectId with the ObjectGroup + // reference. + if (this->object_group_map_.bind (type_id, object_group_entry) != 0) + ACE_THROW_RETURN (TAO_LoadBalancer::ObjectNotCreated (), + CORBA::Object::_nil ()); + + // No longer need to protect the allocated ObjectGroup_Map. + safe_object_group_entry.release (); + + return CORBA::Object::_duplicate (object_group.in ()); +} + +void +TAO_LoadBalancing_ReplicationManager_i::get_initial_number_replicas () +{ + +} + +void +TAO_LoadBalancing_ReplicationManager_i::get_factory_infos () +{ + +} + +void +TAO_LoadBalancing_ReplicationManager_i::delete_object ( + const TAO_LoadBalancing::GenericFactory::FactoryCreationId & factory_creation_id) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectNotFound)) +{ + ObjectGroup = this->object_groups_.find (factory_creation_id); + if (ObjectGroup == -1) + ACE_THROW (TAO_LoadBalancing::ObjectNotFound ()); + + // Delete the individual replicas at their local factories. + for (int i = 0; i < ObjectGroup.size (); ++i) + { + TAO_LoadBalancing::GenericFactory_ptr factory = + ObjectGroup[i].factory; + TAO_LoadBalancing::GenericFactory::FactoryCreationId + replica_factory_id = ObjectGroup[i].replica_factory_id; + factory->delete_object (replica_factory_id); + } + + // Now delete the ObjectGroup from the set of ObjectGroups. + this->object_groups_.unbind (factory_creation_id); +} + +int +TAO_LoadBalancing_ReplicationManager_i::init ( + PortableServer::POA_ptr root_poa) +{ + ACE_TRY_NEW_ENV + { + // Create a new transient servant manager object in the Root + // POA. + PortableServer::ServantManager_var servant_manager = + this->locator_._this (ACE_TRY_ENV); + ACE_TRY_CHECK; + + // Create the appropriate RequestProcessingPolicy + // (USE_SERVANT_MANAGER) and ServantRetentionPolicy (NON_RETAIN) + // for a ServantLocator. + PortableServer::RequestProcessingPolicy_var request = + root_poa->create_request_processing_policy ( + PortableServer::USE_SERVANT_MANAGER, + ACE_TRY_ENV); + ACE_TRY_CHECK; + + PortableServer::ServantRetentionPolicy_var retention = + root_poa->create_servant_retention_policy ( + PortableServer::NON_RETAIN, + ACE_TRY_ENV); + ACE_TRY_CHECK; + + // Create the PolicyList. + CORBA::PolicyList policy_list; + policy_list.length (2); + policy_list[0] = + PortableServer::RequestProcessingPolicy::_duplicate ( + request.in ()); + policy_list[1] = + PortableServer::ServantRetentionPolicy::_duplicate ( + retention.in ()); + + // Create the child POA with the above ServantManager policies. + // The ServantManager will be the ReplicaLocator. + PortableServer::POAManager_var poa_manager = + root_poa->the_POAManager (ACE_TRY_ENV); + ACE_TRY_CHECK; + this->poa_ = root_poa->create_POA ("TAO_LB_ReplicationManager_POA", + poa_manager.in (), + policy_list, + ACE_TRY_ENV); + ACE_TRY_CHECK; + + // Activate the child POA. + poa_manager->activate (ACE_TRY_ENV); + ACE_TRY_CHECK; + + request->destroy (ACE_TRY_ENV); + ACE_TRY_CHECK; + + retention->destroy (ACE_TRY_ENV); + ACE_TRY_CHECK; + + // Now set the ReplicaLocator as the child POA's Servant + // Manager. + this->poa_->set_servant_manager (servant_manager.in (), + ACE_TRY_ENV); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + // @@ Should we do anything here? + + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "(%P|%t) TAO_LB_ReplicationManager_i::init:"); + + return -1; + } + ACE_ENDTRY; + + return 0; +} + +void +TAO_LoadBalancing_ReplicationManager_i::get_ObjectId ( + PortableServer::ObjectId_out &oid) +{ + // Since the POA used by the ReplicationManager uses the NON_RETAIN + // policy, explicitly choose an ObjectId that is unique to a given + // type. + + // Make the ObjectId be the next value of the number of types that + // have been registered with the ReplicationManager. For example, + // if two types of objects have been registered with the + // ReplicationManager, then the ObjectId for the object currently + // being registered will be "3" since the object will be the third + // type of object registered with the ReplicationManager. + // Previously used values will not be reused to ensure that a + // ServantLocator does not inadvertently return a reference to an + // object that had a previously used ObjectId. Specifcally, the + // numerical value used for the ObjectId increases monotonically. + + char oid_str[BUFSIZ] = { 0 }; + ACE_OS::sprintf (oid_str, + "%ul", + this->next_oid_); + + oid = PortableServer::string_to_ObjectId (oid_str); + + // Increment the value for the next ObjectId. + this->next_oid_++; +} + +void +TAO_LoadBalancing_ReplicationManager_i::operator= ( + TAO_LoadBalancing::FactoryInfo &lhs, + const TAO_LoadBalancing::FactoryInfo &rhs) +{ + lhs.facgtory = + TAO_LoadBalancing::GenericFactory::_duplicate (rhs.factory); + + lhs.the_location = rhs.the_location; + + lhs.the_criteria = rhs.the_criteria; +} diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/LoadBalancingI.h b/TAO/orbsvcs/orbsvcs/LoadBalancing/LoadBalancingI.h new file mode 100644 index 00000000000..8d3d4a8a47e --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/LoadBalancingI.h @@ -0,0 +1,273 @@ +// -*- C++ -*- +// +// $Id$ + +#ifndef TAO_LOADBALANCINGI_H +#define TAO_LOADBALANCINGI_H + +#include "ace/pre.h" + +#include "ace/Synch.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "orbsvcs/LoadBalancingS.h" +#include "LB_ObjectGroup_Map.h" + +class TAO_LoadBalancing_ReplicationManager_i : + public virtual POA_TAO_LoadBalancing::ReplicationManager +{ +public: + + TAO_LoadBalancing_ReplicationManager_i (void); + + virtual ~TAO_LoadBalancing_ReplicationManager_i (void); + + virtual void register_load_notifier ( + TAO_LoadBalancing::LoadNotifier_ptr load_notifier) + ACE_THROW_SPEC ((CORBA::SystemException)); + // Register a load notifier with the load balancer + // ReplicationManager. + + virtual TAO_LoadBalancing::LoadNotifier_ptr get_load_notifier (void) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::InterfaceNotFound)); + // Return a reference to the load notifier in use. + + // = TAO_LoadBalancer::PropertyManager methods + + virtual void set_default_properties ( + const TAO_LoadBalancing::Properties & props) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::InvalidProperty, + TAO_LoadBalancing::UnsupportedProperty)); + // Set the default properties to be used by all object groups. + + virtual TAO_LoadBalancing::Properties * get_default_properties (void) + ACE_THROW_SPEC ((CORBA::SystemException)); + // Get the default properties used by all object groups. + + virtual void remove_default_properties ( + const TAO_LoadBalancing::Properties & props) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::InvalidProperty, + TAO_LoadBalancing::UnsupportedProperty)); + // Remove default properties. + + virtual void set_type_properties ( + const char * type_id, + const TAO_LoadBalancing::Properties & overrides) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::InvalidProperty, + TAO_LoadBalancing::UnsupportedProperty)); + // Set properties associated with a given Replica type. These + // properties override the default properties. + + virtual TAO_LoadBalancing::Properties * get_type_properties ( + const char * type_id) + ACE_THROW_SPEC ((CORBA::SystemException)); + // Return the properties associated with a give Replica type. These + // properties include the type-specific properties in use, in + // addition to the default properties that were not overridden. + + virtual void remove_type_properties ( + const char * type_id, + const TAO_LoadBalancing::Properties & props) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::InvalidProperty, + TAO_LoadBalancing::UnsupportedProperty)); + // Remove the given properties associated with the Replica type ID. + + virtual void set_properties_dynamically ( + TAO_LoadBalancing::ObjectGroup_ptr object_group, + const TAO_LoadBalancing::Properties & overrides) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound, + TAO_LoadBalancing::InvalidProperty, + TAO_LoadBalancing::UnsupportedProperty)); + // Dynamically set the properties associated with a given object + // group as the load balancer and replicas are being executed. + // These properties override the type-specific and default + // properties. + + virtual TAO_LoadBalancing::Properties * get_properties ( + TAO_LoadBalancing::ObjectGroup_ptr object_group) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound)); + // 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. + + // = TAO_LoadBalancer::ObjectGroupManager methods + + virtual TAO_LoadBalancing::ObjectGroup_ptr create_member ( + TAO_LoadBalancing::ObjectGroup_ptr object_group, + const TAO_LoadBalancing::Location & the_location, + const char * type_id, + const TAO_LoadBalancing::Criteria & the_criteria) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound, + TAO_LoadBalancing::MemberAlreadyPresent, + TAO_LoadBalancing::NoFactory, + TAO_LoadBalancing::ObjectNotCreated, + TAO_LoadBalancing::InvalidCriteria, + TAO_LoadBalancing::CannotMeetCriteria)); + // Create a member using the load balancer ObjectGroupManager, and + // add the created object to the ObjectGroup. + + virtual TAO_LoadBalancing::ObjectGroup_ptr add_member ( + TAO_LoadBalancing::ObjectGroup_ptr object_group, + const TAO_LoadBalancing::Location & the_location, + CORBA::Object_ptr member) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound, + TAO_LoadBalancing::MemberAlreadyPresent, + TAO_LoadBalancing::ObjectNotAdded)); + // Add an existing object to the ObjectGroup. + + virtual TAO_LoadBalancing::ObjectGroup_ptr remove_member ( + TAO_LoadBalancing::ObjectGroup_ptr object_group, + const TAO_LoadBalancing::Location & the_location) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound, + TAO_LoadBalancing::MemberNotFound)); + // Remove an object at a specific location from the given + // ObjectGroup. Deletion of application created objects must be + // deleted by the application. Objects created by the + // infrastructure (load balancer) will be deleted by the + // infrastructure. + + virtual TAO_LoadBalancing::Locations * locations_of_members ( + TAO_LoadBalancing::ObjectGroup_ptr object_group) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound)); + // Return the locations of the members in the given ObjectGroup. + + virtual TAO_LoadBalancing::ObjectGroupId get_object_group_id ( + TAO_LoadBalancing::ObjectGroup_ptr object_group) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound)); + // Return the ObjectGroupId for the given ObjectGroup. + + virtual TAO_LoadBalancing::ObjectGroup_ptr get_object_group_ref ( + TAO_LoadBalancing::ObjectGroup_ptr object_group) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound)); + // @@ Does this method make sense for load balanced objects? + + virtual CORBA::Object_ptr get_member_ref ( + TAO_LoadBalancing::ObjectGroup_ptr object_group, + const TAO_LoadBalancing::Location & loc) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound, + TAO_LoadBalancing::MemberNotFound)); + // Return the reference corresponding to the Replica of a given + // ObjectGroup at the given location. + + // = TAO_LoadBalancer::GenericFactory methods + + virtual CORBA::Object_ptr create_object ( + const char * type_id, + const TAO_LoadBalancing::Criteria & the_criteria, + TAO_LoadBalancing::GenericFactory::FactoryCreationId_out + factory_creation_id) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::NoFactory, + TAO_LoadBalancing::ObjectNotCreated, + TAO_LoadBalancing::InvalidCriteria, + TAO_LoadBalancing::InvalidProperty, + TAO_LoadBalancing::CannotMeetCriteria)); + // 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. + + virtual void delete_object ( + const TAO_LoadBalancing::GenericFactory::FactoryCreationId & + factory_creation_id) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectNotFound)); + // Delete the object corresponding to the provided + // FactoryCreationId. If the object is actually an ObjectGroup, + // then all members within the ObjectGroup will be deleted. + // Afterward, the ObjectGroup itself will be deleted. + +private: + + void create_object_i ( + const char * type_id, + CORBA::UShort initial_number_replicas, + TAO_LoadBalancing::FactoryInfos &factory_infos, + CORBA::Environment &ACE_TRY_ENV) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::NoFactory, + TAO_LoadBalancing::ObjectNotCreated, + TAO_LoadBalancing::InvalidCriteria, + TAO_LoadBalancing::InvalidProperty, + TAO_LoadBalancing::CannotMeetCriteria)); + // Helper method that creates replicas of the given type. + + int get_initial_number_replicas ( + const char *type_id, + const TAO_LoadBalancing::Criteria &the_criteria, + CORBA::UShort &initial_number_replicas) const; + // Extract the value of the InitialNumberReplicas property from + // the_criteria. + + int get_factory_infos ( + const char *type_id, + const TAO_LoadBalancing::Criteria &the_criteria, + TAO_LoadBalancing::FactoryInfos &factory_infos) const; + // Extract the value of the Factories property from the_criteria. + // This method ensures that the locations in the returned + // FactoryInfos are unique. This is necessary to ensure that only + // one replica of a given type is created by the load balancer at a + // given location. + + int init (PortableServer::POA_ptr root_poa); + // Create a POA with the appropriate policies to support + // ServantLocators (i.e. the ReplicaLocator). + + void get_ObjectId (PortableServer::ObjectId &oid, + TAO_LB_ObjectGroup_EXT_ID &ext_id); + // Get a new ObjectId to be used when creating a new ObjectGroup. + // An ObjectId created by this method will never be reused within + // the scope of a given ReplicationManager. A value suitable for + // use in a map association is also returned. + + void operator= (TAO_LoadBalancer::FactoryInfo &lhs, + const TAO_LoadBalancer::FactoryInfo &rhs); + // Assignment operator for TAO_LoadBalancer::FactoryInfo instances. + +private: + + TAO_LB_ReplicaLocator locator_; + // The object that tells the invoking client to forward its requests + // from the LoadBalancer to an actual replica. + + PortableServer::POA_var poa_; + // The POA that dispatches requests to the ReplicaLocator. + + CORBA::ULong next_oid_; + // ObjectId to be used for the next ObjectGroup that is created. + + TAO_LB_ObjectGroup_Map object_group_map_; + // Map between RepositoryId, ObjectGroup reference, replica list and + // factory creation ID. + + CORBA::ULong next_factory_num_; + // Value that is used when assigning a FactoryCreationId to the + // factory that was used to create a given ObjectGroup. The + // FactoryCreationId is typically comprised of this value in + // addition to another value that makes it unique to a given Load + // Balancer. + +}; + +#include "ace/post.h" + +#endif /* LOADBALANCINGI_H */ diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/ObjectGroupManager.cpp b/TAO/orbsvcs/orbsvcs/LoadBalancing/ObjectGroupManager.cpp new file mode 100644 index 00000000000..52daa7176ca --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/ObjectGroupManager.cpp @@ -0,0 +1,10 @@ +// -*- C++ -*- + +// $Id$ + +ACE_RCSID(orbsvcs, ObjectGroupManager, "$Id$") + +#if !defined (__ACE_INLINE__) +#include "LoadBalancer_i.i" +#endif /* __ACE_INLINE__ */ + diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancing/ReplicaLocator.cpp b/TAO/orbsvcs/orbsvcs/LoadBalancing/ReplicaLocator.cpp index a7e9c66d4dd..becce777cb3 100644 --- a/TAO/orbsvcs/orbsvcs/LoadBalancing/ReplicaLocator.cpp +++ b/TAO/orbsvcs/orbsvcs/LoadBalancing/ReplicaLocator.cpp @@ -32,7 +32,7 @@ TAO_LB_ReplicaLocator::preinvoke ( this->load_balancer_->replica (ACE_TRY_ENV); ACE_CHECK_RETURN (0); - // Throw a forward exception to force the client to redirect its + // Throw a ForwardRequest exception to force the client to redirect its // requests to the Replica chosen by the LoadBalancer. ACE_THROW_RETURN (PortableServer::ForwardRequest ( CORBA::Object::_duplicate (replica)), diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancingI.cpp b/TAO/orbsvcs/orbsvcs/LoadBalancingI.cpp new file mode 100644 index 00000000000..14ba8a32ae4 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancingI.cpp @@ -0,0 +1,587 @@ +// -*- C++ -*- +// +// $Id$ + +#include "LoadBalancingI.h" + +// Implementation skeleton constructor +TAO_LoadBalancing_ReplicationManager_i::TAO_LoadBalancing_ReplicationManager_i +(void) + : locator_ (this), + poa_ (), + next_oid_ (0), + object_group_map_ () +{ + (void) this->init (); +} + +// Implementation skeleton destructor +TAO_LoadBalancing_ReplicationManager_i::~TAO_LoadBalancing_ReplicationManager_i (void) +{ +} + +void +TAO_LoadBalancing_ReplicationManager_i::register_load_notifier ( + TAO_LoadBalancing::LoadNotifier_ptr /* load_notifier */) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT()); +} + +TAO_LoadBalancing::LoadNotifier_ptr +TAO_LoadBalancing_ReplicationManager_i::get_load_notifier (void) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::InterfaceNotFound)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT ()); +} + +void +TAO_LoadBalancing_ReplicationManager_i::set_default_properties ( + const TAO_LoadBalancing::Properties & /* props */) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::InvalidProperty, + TAO_LoadBalancing::UnsupportedProperty)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT()); +} + +TAO_LoadBalancing::Properties * +TAO_LoadBalancing_ReplicationManager_i::get_default_properties (void) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT ()); +} + +void +TAO_LoadBalancing_ReplicationManager_i::remove_default_properties ( + const TAO_LoadBalancing::Properties & /* props */) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::InvalidProperty, + TAO_LoadBalancing::UnsupportedProperty)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT ()); +} + +void +TAO_LoadBalancing_ReplicationManager_i::set_type_properties ( + const char * /* type_id */, + const TAO_LoadBalancing::Properties & /* overrides */) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::InvalidProperty, + TAO_LoadBalancing::UnsupportedProperty)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT ()); +} + +TAO_LoadBalancing::Properties * +TAO_LoadBalancing_ReplicationManager_i::get_type_properties ( + const char * /* type_id */) + ACE_THROW_SPEC ((CORBA::SystemException)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT ()); +} + +void +TAO_LoadBalancing_ReplicationManager_i::remove_type_properties ( + const char * /* type_id */, + const TAO_LoadBalancing::Properties & /* props */) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::InvalidProperty, + TAO_LoadBalancing::UnsupportedProperty)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT ()); +} + +void +TAO_LoadBalancing_ReplicationManager_i::set_properties_dynamically ( + TAO_LoadBalancing::ObjectGroup_ptr /* object_group */, + const TAO_LoadBalancing::Properties & /* overrides */) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound, + TAO_LoadBalancing::InvalidProperty, + TAO_LoadBalancing::UnsupportedProperty)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT ()); +} + +TAO_LoadBalancing::Properties * +TAO_LoadBalancing_ReplicationManager_i::get_properties ( + TAO_LoadBalancing::ObjectGroup_ptr /* object_group */) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT ()); +} + +TAO_LoadBalancing::ObjectGroup_ptr +TAO_LoadBalancing_ReplicationManager_i::create_member ( + TAO_LoadBalancing::ObjectGroup_ptr /* object_group */, + const TAO_LoadBalancing::Location & /* the_location */, + const char * /* type_id */, + const TAO_LoadBalancing::Criteria & /* the_criteria */) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound, + TAO_LoadBalancing::MemberAlreadyPresent, + TAO_LoadBalancing::NoFactory, + TAO_LoadBalancing::ObjectNotCreated, + TAO_LoadBalancing::InvalidCriteria, + TAO_LoadBalancing::CannotMeetCriteria)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT ()); +} + +TAO_LoadBalancing::ObjectGroup_ptr +TAO_LoadBalancing_ReplicationManager_i::add_member ( + TAO_LoadBalancing::ObjectGroup_ptr /* object_group */, + const TAO_LoadBalancing::Location & /* the_location */, + CORBA::Object_ptr /* member */) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound, + TAO_LoadBalancing::MemberAlreadyPresent, + TAO_LoadBalancing::ObjectNotAdded)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT ()); +} + +TAO_LoadBalancing::ObjectGroup_ptr +TAO_LoadBalancing_ReplicationManager_i::remove_member ( + TAO_LoadBalancing::ObjectGroup_ptr /* object_group */, + const TAO_LoadBalancing::Location & /* the_location */) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound, + TAO_LoadBalancing::MemberNotFound)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT ()); +} + +TAO_LoadBalancing::ObjectGroup_ptr +TAO_LoadBalancing_ReplicationManager_i::set_primary_member ( + TAO_LoadBalancing::ObjectGroup_ptr /* object_group */, + const TAO_LoadBalancing::Location & /* the_location */) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound, + TAO_LoadBalancing::MemberNotFound, + TAO_LoadBalancing::PrimaryNotSet, + TAO_LoadBalancing::BadReplicationStyle)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT ()); +} + +TAO_LoadBalancing::Locations * +TAO_LoadBalancing_ReplicationManager_i::locations_of_members ( + TAO_LoadBalancing::ObjectGroup_ptr /* object_group */) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT ()); +} + +TAO_LoadBalancing::ObjectGroupId +TAO_LoadBalancing_ReplicationManager_i::get_object_group_id ( + TAO_LoadBalancing::ObjectGroup_ptr /* object_group */) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT ()); +} + +TAO_LoadBalancing::ObjectGroup_ptr +TAO_LoadBalancing_ReplicationManager_i::get_object_group_ref ( + TAO_LoadBalancing::ObjectGroup_ptr /* object_group */) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT ()); +} + +CORBA::Object_ptr +TAO_LoadBalancing_ReplicationManager_i::get_member_ref ( + TAO_LoadBalancing::ObjectGroup_ptr /* object_group */, + const TAO_LoadBalancing::Location & loc) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound, + TAO_LoadBalancing::MemberNotFound)) +{ + ACE_THROW (CORBA::NO_IMPLEMENT ()); +} + +CORBA::Object_ptr +TAO_LoadBalancing_ReplicationManager_i::create_object ( + const char * type_id, + const TAO_LoadBalancing::Criteria & the_criteria, + TAO_LoadBalancing::GenericFactory::FactoryCreationId_out + factory_creation_id, + CORBA::Environment &ACE_TRY_ENV) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::NoFactory, + TAO_LoadBalancing::ObjectNotCreated, + TAO_LoadBalancing::InvalidCriteria, + TAO_LoadBalancing::InvalidProperty, + TAO_LoadBalancing::CannotMeetCriteria)) +{ + // Check if an ObjectGroup for the given type hasn't already been + // created. + if (this->object_group_map_.find_type_id (type_id) == 0) + ACE_THROW_RETURN (TAO_LoadBalancing::ObjectNotCreated ()); + + // List of invalid criteria. If this list has a length greater than + // zero, then the TAO_LoadBalancing::InvalidCriteria exception will + // be thrown. + TAO_Loadbalancing::Criteria invalid_criteria; + + int found_factory = 0; // If factory was found in the_criteria, then + // set to 1. + + // Parse the criteria. + int criteria_count = the_criteria.length (); + for (int i = 0; i < criteria_size; ++i) + { + CORBA::UShort initial_number_replicas = 0; + TAO_LoadBalancing::FactoryInfos factory_infos; + + // Obtain the InitialNumberReplicas from the_criteria. + if (this->get_initial_number_replicas (type_id, + the_criteria[i], + initial_number_replicas) != 0) + { + size_t length = invalid_criteria.length (); + invalid_criteria.length (length + 1); + invalid_criteria[length] = the_criteria[i]; + } + + // Obtain the FactoryInfos from the_criteria. This method also + // ensure that GenericFactories at different locations are used. + else if (this->get_factory_infos (type_id, + the_criteria[i], + factory_infos) == 0) + found_factory = 1; + + // Unknown property + else + ACE_THROW_RETURN (TAO_LoadBalancer::InvalidProperty ( + the_criteria[i].nam, + the_criteria[i].val), + CORBA::Object::_nil ()); + } + + if (invalid_criteria.length () != 0) + ACE_THROW_RETURN (TAO_LoadBalancing::InvalidCriteria (invalid_criteria), + CORBA::Object::_nil ()); + + if (found_factory == 0) + ACE_THROW_RETURN (TAO_LoadBalancing::NoFactory (), + CORBA::Object::_nil ()); + + return this->create_object_i (type_id, + initial_number_replicas, + factory_infos, + ACE_TRY_ENV); +} + +CORBA::Object_ptr +TAO_LoadBalancing_ReplicationManager_i::create_object_i ( + const char *type_id, + CORBA::UShort initial_number_replicas, + TAO_LoadBalancing::FactoryInfos &factory_infos, + CORBA::Environment &ACE_TRY_ENV) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::NoFactory, + TAO_LoadBalancing::ObjectNotCreated, + TAO_LoadBalancing::InvalidCriteria, + TAO_LoadBalancing::InvalidProperty, + TAO_LoadBalancing::CannotMeetCriteria)) +{ + size_t factory_infos_count = factory_infos.length (); + + // If the number of factories is less than the initial number of + // replicas, then the desired number of replicas cannot possibly be + // created. + if (factory_infos_count < initial_number_replicas) + ACE_THROW_RETURN (TAO_LoadBalancing::CannotMeetCriteria (), + CORBA::Object::_nil ()); + + TAO_LB_ObjectGroup_Map::Map_Entry *object_group_entry = 0; + ACE_NEW_THROW_EX (object_group_entry, + TAO_LB_ObjectGroup_Map::Map_Entry, + CORBA::NO_MEMORY ()); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + auto_ptr safe_object_group_entry ( + object_group_entry); + + for (int j = 0; j < factory_infos_count; ++j) + { + // The FactoryInfo::the_location member was used when + // determining which FactoryInfo + // member? + // @@ It looks like it is only used when the application + // control membership style is used. The application + // requests that a replica be created at a given + // "location," at which point the ReplicationManager + // searches through its registered FactoryInfos for a + // FactoryInfo with a "Location" member that matches + // the location at which to create the desired + // replica. + // @@ It is also used to ensure the only one replica of + // a given type is created at a given location. + + + TAO_LoadBalancing::FactoryInfo &factory_info = + factory_infos[j]; + + TAO_LoadBalancer::GenericFactory_ptr factory = + factory_info.factory; + + TAO_LoadBalancing::GenericFactory::FactoryCreationId_out + replica_factory_creation_id; + + CORBA::Object_var replica = + factory->create_object (type_id, + factory_info.the_criteria, + replica_factory_creation_id, + ACE_TRY_ENV); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + // @@ Should an "_is_a()" be performed here? While it appears + // to be the right thing to do, it can be expensive. + // + // Make sure an Object of the correct type was created. It is + // possible that an object of the wrong type was created if the + // type_id parameter does not match the type of object the + // GenericFactory creates. + CORBA::Boolean right_type_id = + replica->_is_a (type_id, ACE_TRY_ENV); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + if (!right_type_id) + { + // An Object of incorrect type was created. Delete it, and + // throw a NoFactory exception. + factory->delete_object (replica_factory_creation_id, + ACE_TRY_ENV); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + ACE_THROW_RETURN (TAO_LoadBalancer::NoFactory (), + CORBA::Object::_nil ()); + } + + // Create a new Replica_Map map entry. + TAO_LB_Replica_Map::Map_Entry *replica_entry = 0; + ACE_NEW_THROW_EX (replica_entry, + TAO_LB_Replica_Map::Map_Entry, + CORBA::NO_MEMORY ()); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + auto_ptr safe_replica_entry (replica_entry); + + replica_entry->replica = replica; + + TAO_LoadBalancer::FactoryInfo *new_factory_info = 0; + ACE_NEW_THROW_EX (new_factory_info, + TAO_LoadBalancer::FactoryInfo, + CORBA::NO_MEMORY ()); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + replica_entry->factory_info = new_factory_info; + + // Copy the FactoryInfo structure. A deep copy is actually + // performed here. + *new_factory_info = factory_info; + + replica_entry->factory_creation_id = replica_factory_creation_id; + + if (object_group_entry.replica_map.bind (replica_entry) != 0) + ACE_THROW_RETURN (TAO_LoadBalancer::ObjectNotCreated (), + CORBA::Object::_nil ()); + + // No longer need to protect the allocated Replica_Map. + safe_replica_entry.release (); + } + + // Create a reference for the ObjectGroup corresponding to the + // RepositoryId of the object being created. + + PortableServer::ObjectId_var oid; + this->get_ObjectId (oid.out ()); + + CORBA::Object_var object_group = + this->poa_->create_reference_with_id (oid.in (), + type_id, + ACE_TRY_ENV); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + object_group_entry.type_id = CORBA::string_dup (type_id); + object_group_entry.object_group = object_group; + + // @@ This is ugly, and needs to be cleaned up. + object_group_entry.factory_creation_id = this->next_oid_ - 1; + + // Now (indirectly) associate the ObjectId with the ObjectGroup + // reference. + if (this->object_group_map_.bind (type_id, object_group_entry) != 0) + ACE_THROW_RETURN (TAO_LoadBalancer::ObjectNotCreated (), + CORBA::Object::_nil ()); + + // No longer need to protect the allocated ObjectGroup_Map. + safe_object_group_entry.release (); + + return CORBA::Object::_duplicate (object_group.in ()); +} + +void +TAO_LoadBalancing_ReplicationManager_i::get_initial_number_replicas () +{ + +} + +void +TAO_LoadBalancing_ReplicationManager_i::get_factory_infos () +{ + +} + +void +TAO_LoadBalancing_ReplicationManager_i::delete_object ( + const TAO_LoadBalancing::GenericFactory::FactoryCreationId & factory_creation_id) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectNotFound)) +{ + ObjectGroup = this->object_groups_.find (factory_creation_id); + if (ObjectGroup == -1) + ACE_THROW (TAO_LoadBalancing::ObjectNotFound ()); + + // Delete the individual replicas at their local factories. + for (int i = 0; i < ObjectGroup.size (); ++i) + { + TAO_LoadBalancing::GenericFactory_ptr factory = + ObjectGroup[i].factory; + TAO_LoadBalancing::GenericFactory::FactoryCreationId + replica_factory_id = ObjectGroup[i].replica_factory_id; + factory->delete_object (replica_factory_id); + } + + // Now delete the ObjectGroup from the set of ObjectGroups. + this->object_groups_.unbind (factory_creation_id); +} + +int +TAO_LoadBalancing_ReplicationManager_i::init ( + PortableServer::POA_ptr root_poa) +{ + ACE_TRY_NEW_ENV + { + // Create a new transient servant manager object in the Root + // POA. + PortableServer::ServantManager_var servant_manager = + this->locator_._this (ACE_TRY_ENV); + ACE_TRY_CHECK; + + // Create the appropriate RequestProcessingPolicy + // (USE_SERVANT_MANAGER) and ServantRetentionPolicy (NON_RETAIN) + // for a ServantLocator. + PortableServer::RequestProcessingPolicy_var request = + root_poa->create_request_processing_policy ( + PortableServer::USE_SERVANT_MANAGER, + ACE_TRY_ENV); + ACE_TRY_CHECK; + + PortableServer::ServantRetentionPolicy_var retention = + root_poa->create_servant_retention_policy ( + PortableServer::NON_RETAIN, + ACE_TRY_ENV); + ACE_TRY_CHECK; + + // Create the PolicyList. + CORBA::PolicyList policy_list; + policy_list.length (2); + policy_list[0] = + PortableServer::RequestProcessingPolicy::_duplicate ( + request.in ()); + policy_list[1] = + PortableServer::ServantRetentionPolicy::_duplicate ( + retention.in ()); + + // Create the child POA with the above ServantManager policies. + // The ServantManager will be the ReplicaLocator. + PortableServer::POAManager_var poa_manager = + root_poa->the_POAManager (ACE_TRY_ENV); + ACE_TRY_CHECK; + this->poa_ = root_poa->create_POA ("TAO_LB_ReplicationManager_POA", + poa_manager.in (), + policy_list, + ACE_TRY_ENV); + ACE_TRY_CHECK; + + // Activate the child POA. + poa_manager->activate (ACE_TRY_ENV); + ACE_TRY_CHECK; + + request->destroy (ACE_TRY_ENV); + ACE_TRY_CHECK; + + retention->destroy (ACE_TRY_ENV); + ACE_TRY_CHECK; + + // Now set the ReplicaLocator as the child POA's Servant + // Manager. + this->poa_->set_servant_manager (servant_manager.in (), + ACE_TRY_ENV); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + // @@ Should we do anything here? + + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + "(%P|%t) TAO_LB_ReplicationManager_i::init:"); + + return -1; + } + ACE_ENDTRY; + + return 0; +} + +void +TAO_LoadBalancing_ReplicationManager_i::get_ObjectId ( + PortableServer::ObjectId_out &oid) +{ + // Since the POA used by the ReplicationManager uses the NON_RETAIN + // policy, explicitly choose an ObjectId that is unique to a given + // type. + + // Make the ObjectId be the next value of the number of types that + // have been registered with the ReplicationManager. For example, + // if two types of objects have been registered with the + // ReplicationManager, then the ObjectId for the object currently + // being registered will be "3" since the object will be the third + // type of object registered with the ReplicationManager. + // Previously used values will not be reused to ensure that a + // ServantLocator does not inadvertently return a reference to an + // object that had a previously used ObjectId. Specifcally, the + // numerical value used for the ObjectId increases monotonically. + + char oid_str[BUFSIZ] = { 0 }; + ACE_OS::sprintf (oid_str, + "%ul", + this->next_oid_); + + oid = PortableServer::string_to_ObjectId (oid_str); + + // Increment the value for the next ObjectId. + this->next_oid_++; +} + +void +TAO_LoadBalancing_ReplicationManager_i::operator= ( + TAO_LoadBalancing::FactoryInfo &lhs, + const TAO_LoadBalancing::FactoryInfo &rhs) +{ + lhs.facgtory = + TAO_LoadBalancing::GenericFactory::_duplicate (rhs.factory); + + lhs.the_location = rhs.the_location; + + lhs.the_criteria = rhs.the_criteria; +} diff --git a/TAO/orbsvcs/orbsvcs/LoadBalancingI.h b/TAO/orbsvcs/orbsvcs/LoadBalancingI.h new file mode 100644 index 00000000000..8d3d4a8a47e --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/LoadBalancingI.h @@ -0,0 +1,273 @@ +// -*- C++ -*- +// +// $Id$ + +#ifndef TAO_LOADBALANCINGI_H +#define TAO_LOADBALANCINGI_H + +#include "ace/pre.h" + +#include "ace/Synch.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "orbsvcs/LoadBalancingS.h" +#include "LB_ObjectGroup_Map.h" + +class TAO_LoadBalancing_ReplicationManager_i : + public virtual POA_TAO_LoadBalancing::ReplicationManager +{ +public: + + TAO_LoadBalancing_ReplicationManager_i (void); + + virtual ~TAO_LoadBalancing_ReplicationManager_i (void); + + virtual void register_load_notifier ( + TAO_LoadBalancing::LoadNotifier_ptr load_notifier) + ACE_THROW_SPEC ((CORBA::SystemException)); + // Register a load notifier with the load balancer + // ReplicationManager. + + virtual TAO_LoadBalancing::LoadNotifier_ptr get_load_notifier (void) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::InterfaceNotFound)); + // Return a reference to the load notifier in use. + + // = TAO_LoadBalancer::PropertyManager methods + + virtual void set_default_properties ( + const TAO_LoadBalancing::Properties & props) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::InvalidProperty, + TAO_LoadBalancing::UnsupportedProperty)); + // Set the default properties to be used by all object groups. + + virtual TAO_LoadBalancing::Properties * get_default_properties (void) + ACE_THROW_SPEC ((CORBA::SystemException)); + // Get the default properties used by all object groups. + + virtual void remove_default_properties ( + const TAO_LoadBalancing::Properties & props) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::InvalidProperty, + TAO_LoadBalancing::UnsupportedProperty)); + // Remove default properties. + + virtual void set_type_properties ( + const char * type_id, + const TAO_LoadBalancing::Properties & overrides) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::InvalidProperty, + TAO_LoadBalancing::UnsupportedProperty)); + // Set properties associated with a given Replica type. These + // properties override the default properties. + + virtual TAO_LoadBalancing::Properties * get_type_properties ( + const char * type_id) + ACE_THROW_SPEC ((CORBA::SystemException)); + // Return the properties associated with a give Replica type. These + // properties include the type-specific properties in use, in + // addition to the default properties that were not overridden. + + virtual void remove_type_properties ( + const char * type_id, + const TAO_LoadBalancing::Properties & props) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::InvalidProperty, + TAO_LoadBalancing::UnsupportedProperty)); + // Remove the given properties associated with the Replica type ID. + + virtual void set_properties_dynamically ( + TAO_LoadBalancing::ObjectGroup_ptr object_group, + const TAO_LoadBalancing::Properties & overrides) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound, + TAO_LoadBalancing::InvalidProperty, + TAO_LoadBalancing::UnsupportedProperty)); + // Dynamically set the properties associated with a given object + // group as the load balancer and replicas are being executed. + // These properties override the type-specific and default + // properties. + + virtual TAO_LoadBalancing::Properties * get_properties ( + TAO_LoadBalancing::ObjectGroup_ptr object_group) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound)); + // 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. + + // = TAO_LoadBalancer::ObjectGroupManager methods + + virtual TAO_LoadBalancing::ObjectGroup_ptr create_member ( + TAO_LoadBalancing::ObjectGroup_ptr object_group, + const TAO_LoadBalancing::Location & the_location, + const char * type_id, + const TAO_LoadBalancing::Criteria & the_criteria) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound, + TAO_LoadBalancing::MemberAlreadyPresent, + TAO_LoadBalancing::NoFactory, + TAO_LoadBalancing::ObjectNotCreated, + TAO_LoadBalancing::InvalidCriteria, + TAO_LoadBalancing::CannotMeetCriteria)); + // Create a member using the load balancer ObjectGroupManager, and + // add the created object to the ObjectGroup. + + virtual TAO_LoadBalancing::ObjectGroup_ptr add_member ( + TAO_LoadBalancing::ObjectGroup_ptr object_group, + const TAO_LoadBalancing::Location & the_location, + CORBA::Object_ptr member) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound, + TAO_LoadBalancing::MemberAlreadyPresent, + TAO_LoadBalancing::ObjectNotAdded)); + // Add an existing object to the ObjectGroup. + + virtual TAO_LoadBalancing::ObjectGroup_ptr remove_member ( + TAO_LoadBalancing::ObjectGroup_ptr object_group, + const TAO_LoadBalancing::Location & the_location) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound, + TAO_LoadBalancing::MemberNotFound)); + // Remove an object at a specific location from the given + // ObjectGroup. Deletion of application created objects must be + // deleted by the application. Objects created by the + // infrastructure (load balancer) will be deleted by the + // infrastructure. + + virtual TAO_LoadBalancing::Locations * locations_of_members ( + TAO_LoadBalancing::ObjectGroup_ptr object_group) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound)); + // Return the locations of the members in the given ObjectGroup. + + virtual TAO_LoadBalancing::ObjectGroupId get_object_group_id ( + TAO_LoadBalancing::ObjectGroup_ptr object_group) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound)); + // Return the ObjectGroupId for the given ObjectGroup. + + virtual TAO_LoadBalancing::ObjectGroup_ptr get_object_group_ref ( + TAO_LoadBalancing::ObjectGroup_ptr object_group) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound)); + // @@ Does this method make sense for load balanced objects? + + virtual CORBA::Object_ptr get_member_ref ( + TAO_LoadBalancing::ObjectGroup_ptr object_group, + const TAO_LoadBalancing::Location & loc) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectGroupNotFound, + TAO_LoadBalancing::MemberNotFound)); + // Return the reference corresponding to the Replica of a given + // ObjectGroup at the given location. + + // = TAO_LoadBalancer::GenericFactory methods + + virtual CORBA::Object_ptr create_object ( + const char * type_id, + const TAO_LoadBalancing::Criteria & the_criteria, + TAO_LoadBalancing::GenericFactory::FactoryCreationId_out + factory_creation_id) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::NoFactory, + TAO_LoadBalancing::ObjectNotCreated, + TAO_LoadBalancing::InvalidCriteria, + TAO_LoadBalancing::InvalidProperty, + TAO_LoadBalancing::CannotMeetCriteria)); + // 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. + + virtual void delete_object ( + const TAO_LoadBalancing::GenericFactory::FactoryCreationId & + factory_creation_id) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectNotFound)); + // Delete the object corresponding to the provided + // FactoryCreationId. If the object is actually an ObjectGroup, + // then all members within the ObjectGroup will be deleted. + // Afterward, the ObjectGroup itself will be deleted. + +private: + + void create_object_i ( + const char * type_id, + CORBA::UShort initial_number_replicas, + TAO_LoadBalancing::FactoryInfos &factory_infos, + CORBA::Environment &ACE_TRY_ENV) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::NoFactory, + TAO_LoadBalancing::ObjectNotCreated, + TAO_LoadBalancing::InvalidCriteria, + TAO_LoadBalancing::InvalidProperty, + TAO_LoadBalancing::CannotMeetCriteria)); + // Helper method that creates replicas of the given type. + + int get_initial_number_replicas ( + const char *type_id, + const TAO_LoadBalancing::Criteria &the_criteria, + CORBA::UShort &initial_number_replicas) const; + // Extract the value of the InitialNumberReplicas property from + // the_criteria. + + int get_factory_infos ( + const char *type_id, + const TAO_LoadBalancing::Criteria &the_criteria, + TAO_LoadBalancing::FactoryInfos &factory_infos) const; + // Extract the value of the Factories property from the_criteria. + // This method ensures that the locations in the returned + // FactoryInfos are unique. This is necessary to ensure that only + // one replica of a given type is created by the load balancer at a + // given location. + + int init (PortableServer::POA_ptr root_poa); + // Create a POA with the appropriate policies to support + // ServantLocators (i.e. the ReplicaLocator). + + void get_ObjectId (PortableServer::ObjectId &oid, + TAO_LB_ObjectGroup_EXT_ID &ext_id); + // Get a new ObjectId to be used when creating a new ObjectGroup. + // An ObjectId created by this method will never be reused within + // the scope of a given ReplicationManager. A value suitable for + // use in a map association is also returned. + + void operator= (TAO_LoadBalancer::FactoryInfo &lhs, + const TAO_LoadBalancer::FactoryInfo &rhs); + // Assignment operator for TAO_LoadBalancer::FactoryInfo instances. + +private: + + TAO_LB_ReplicaLocator locator_; + // The object that tells the invoking client to forward its requests + // from the LoadBalancer to an actual replica. + + PortableServer::POA_var poa_; + // The POA that dispatches requests to the ReplicaLocator. + + CORBA::ULong next_oid_; + // ObjectId to be used for the next ObjectGroup that is created. + + TAO_LB_ObjectGroup_Map object_group_map_; + // Map between RepositoryId, ObjectGroup reference, replica list and + // factory creation ID. + + CORBA::ULong next_factory_num_; + // Value that is used when assigning a FactoryCreationId to the + // factory that was used to create a given ObjectGroup. The + // FactoryCreationId is typically comprised of this value in + // addition to another value that makes it unique to a given Load + // Balancer. + +}; + +#include "ace/post.h" + +#endif /* LOADBALANCINGI_H */ diff --git a/TAO/orbsvcs/orbsvcs/ObjectGroupManager.cpp b/TAO/orbsvcs/orbsvcs/ObjectGroupManager.cpp new file mode 100644 index 00000000000..52daa7176ca --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/ObjectGroupManager.cpp @@ -0,0 +1,10 @@ +// -*- C++ -*- + +// $Id$ + +ACE_RCSID(orbsvcs, ObjectGroupManager, "$Id$") + +#if !defined (__ACE_INLINE__) +#include "LoadBalancer_i.i" +#endif /* __ACE_INLINE__ */ + diff --git a/TAO/orbsvcs/orbsvcs/ReplicaLocator.cpp b/TAO/orbsvcs/orbsvcs/ReplicaLocator.cpp index a7e9c66d4dd..becce777cb3 100644 --- a/TAO/orbsvcs/orbsvcs/ReplicaLocator.cpp +++ b/TAO/orbsvcs/orbsvcs/ReplicaLocator.cpp @@ -32,7 +32,7 @@ TAO_LB_ReplicaLocator::preinvoke ( this->load_balancer_->replica (ACE_TRY_ENV); ACE_CHECK_RETURN (0); - // Throw a forward exception to force the client to redirect its + // Throw a ForwardRequest exception to force the client to redirect its // requests to the Replica chosen by the LoadBalancer. ACE_THROW_RETURN (PortableServer::ForwardRequest ( CORBA::Object::_duplicate (replica)), diff --git a/TAO/orbsvcs/tests/LoadBalancing/GenericFactory.cpp b/TAO/orbsvcs/tests/LoadBalancing/GenericFactory.cpp new file mode 100644 index 00000000000..a8a8bef4faf --- /dev/null +++ b/TAO/orbsvcs/tests/LoadBalancing/GenericFactory.cpp @@ -0,0 +1,238 @@ + +#include "LB_test.h" + +ACE_RCSID (LB_test, GenericFactory, "$Id$") + +int +LB_test::create_object (void) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + this->object_group_ = + this->load_balancer->create_object (type_id, + the_criteria, + this->factory_creation_id_.out (), + ACE_TRY_ENV); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + ACE_TEXT ("Caught unexpected exception:")); + + return -1; + } + ACE_ENDTRY; + + return 0; +} + +int +LB_test::test_no_factory (void) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + // @@ TODO: Implement + } + ACE_CATCH (TAO_LoadBalancer::NoFactory, ex) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Successfully caught %s exception\n"), + ex._id ())); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT (" Replica TypeId: %s\n"), + ex.type_id)); + + TAO_LoadBalancer::Location &location = + ex.the_location; + + for (int i = 0; i < location.length (); ++i) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT (" Location[%d].id: %s\n") + ACE_TEXT (" kind: %s\n"), + location[i].id, + location[i].kind)); + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + ACE_TEXT ("Caught unexpected exception:")); + + return -1; + } + ACE_ENDTRY; + + return 0; +} + + +int +LB_test::test_object_not_created (void) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + // @@ TODO: Implement + } + ACE_CATCH (TAO_LoadBalancer::ObjectNotCreated, ex) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Successfully caught %s exception\n"), + ex._id ())); + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + ACE_TEXT ("Caught unexpected exception:")); + + return -1; + } + ACE_ENDTRY; + + return 0; +} + +int +LB_test::test_invalid_criteria (void) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + // @@ TODO: Implement + } + ACE_CATCH (TAO_LoadBalancer::InvalidCriteria, ex) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Successfully caught %s exception\n"), + ex._id ())); + + TAO_LoadBalancer::Criteria &invalid_criteria = + ex.invalid_criteria; + + for (int i = 0; i < properties.length (); ++i) + { + // Property values are not displayed since they are stored + // as Anys. + + TAO_LoadBalancer::Property &invalid_property = + invalid_criteria[i]; + + for (int j = 0; j < invalid_property.length (); ++j) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT (" invalid_criteria[%d].nam[%d].id: %s\n") + ACE_TEXT (" kind: %s\n"), + i, + j, + invalid_property[j].id, + invalid_property[j].kind)); + } + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + ACE_TEXT ("Caught unexpected exception:")); + + return -1; + } + ACE_ENDTRY; + + return 0; +} + +int +LB_test::test_cannot_meet_criteria (void) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + // @@ TODO: Implement + } + ACE_CATCH (TAO_LoadBalancer::CannotMeetCriteria, ex) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Successfully caught %s exception\n"), + ex._id ())); + + + TAO_LoadBalancer::Criteria &invalid_criteria = + ex.invalid_criteria; + + for (int i = 0; i < properties.length (); ++i) + { + // Property values are not displayed since they are stored + // as Anys. + + TAO_LoadBalancer::Property &unmet_property = + unmet_criteria[i]; + + for (int j = 0; j < unmet_property.length (); ++j) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT (" unmet_criteria[%d].nam[%d].id: %s\n") + ACE_TEXT (" kind: %s\n"), + i, + j, + unmet_property[j].id, + unmet_property[j].kind)); + } + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + ACE_TEXT ("Caught unexpected exception:")); + + return -1; + } + ACE_ENDTRY; + + return 0; +} + +int LB_test::delete_object (void) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + this->load_balancer->delete_object (this->factory_creation_id_.in () + ACE_TRY_ENV); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + ACE_TEXT ("Caught unexpected exception:")); + + return -1; + } + ACE_ENDTRY; + + return 0; +} + +int +LB_test::test_object_not_found (void) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + // @@ TODO: Implement + } + ACE_CATCH (TAO_LoadBalancer::ObjectNotFound, ex) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Successfully caught %s exception\n"), + ex._id ())); + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + ACE_TEXT ("Caught unexpected exception:")); + + return -1; + } + ACE_ENDTRY; + + return 0; +} diff --git a/TAO/orbsvcs/tests/LoadBalancing/HashReplicaFactory.cpp b/TAO/orbsvcs/tests/LoadBalancing/HashReplicaFactory.cpp new file mode 100644 index 00000000000..15063062c9b --- /dev/null +++ b/TAO/orbsvcs/tests/LoadBalancing/HashReplicaFactory.cpp @@ -0,0 +1,103 @@ +// -*- C++ -*- +// +// $Id$ + +#include "HashReplicaFactory.h" + +ACE_RCSID (LB_test, HashReplicaFactory, "$Id$") + +CORBA::Object_ptr +HashReplicaFactory::create_object ( + const char *type_id, + const TAO_LoadBalancing::Criteria &the_criteria, + TAO_LoadBalancing::GenericFactory::FactoryCreationId_out + factory_creation_id, + ACE_TRY_ENV) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::NoFactory, + TAO_LoadBalancing::ObjectNotCreated, + TAO_LoadBalancing::InvalidCriteria, + TAO_LoadBalancing::InvalidProperty, + TAO_LoadBalancing::CannotMeetCriteria)) +{ + // This factory is only designed to create HashReplica objects. + // However, a GenericFactory need not be limited to being able to + // only create one type of object. + + // Since this factory is only capable of creating HashReplica + // objects, throw an exception if the type_id does not match that of + // the HashReplica. + if (ACE_OS::strcmp (type_id, + this->replica_type_id_) != 0) + ACE_THROW_RETURN (TAO_LoadBalancing::NoFactory (the_location, + type_id), + CORBA::Object::_nil ()); + + this->parse_criteria (criteria, + ACE_TRY_ENV); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + HashReplica_i *hash_replica_servant = 0; + ACE_NEW_THROW_EX (hash_replica_servant, + HashReplica_i, + CORBA::NO_MEMORY ()); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + // Transfer ownership of the servant to the POA (HashReplica_i + // inherits from PortableServer::RefCountServantBase). + PortableServer::ServantBase_var tmp = hash_replica_servant; + + // Activate the HashReplica and obtain a reference to it. + this->hash_replica_ = + hash_replica_servant->_this (ACE_TRY_ENV); + ACE_CHECK_RETURN (CORBA::Object::_nil ()); + + factory_creation_id = ...FILL IN CREATION ID...; + + return HashReplica::_duplicate (this->hash_replica_.in ()); +} + +void +HashReplicaFactory::delete_object ( + const TAO_LoadBalancing::GenericFactory::FactoryCreationId + &factory_creation_id, + ACE_TRY_ENV) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancer::ObjectNotFound)) +{ + if (factory_creation_id != this->factory_creation_id_) + ACE_THROW (TAO_LoadBalancer::ObjectNotFound ()); + + // Get the POA used when activating the HashReplica + PortableServer::POA_var poa = + this->_default_POA (ACE_TRY_ENV); + ACE_CHECK; + + // Get the object ID associated with the HashReplica reference. + PortableServer::ObjectId_var oid = + poa->reference_to_id (this->hash_replica_.in (), + ACE_TRY_ENV); + ACE_CHECK; + + // Now deactivate the HashReplica. + poa->deactivate_object (oid.in (), ACE_TRY_ENV); + ACE_CHECK; + + // Decrease the reference count on the HashReplica. + this->hash_replica->_remove_ref (); +} + +void +HashReplicaFactory::parse_criteria ( + const TAO_LoadBalancer::Criteria &criteria, + CORBA::Environment &ACE_TRY_ENV) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::InvalidCriteria, + TAO_LoadBalancing::InvalidProperty, + TAO_LoadBalancing::CannotMeetCriteria)) +{ + // We don't use any criteria! + + if (criteria.length () != 0) + ACE_THROW (TAO_LoadBalancer::CannotMeetCriteria (criteria)); +} diff --git a/TAO/orbsvcs/tests/LoadBalancing/HashReplicaFactory.h b/TAO/orbsvcs/tests/LoadBalancing/HashReplicaFactory.h new file mode 100644 index 00000000000..81cccde4e63 --- /dev/null +++ b/TAO/orbsvcs/tests/LoadBalancing/HashReplicaFactory.h @@ -0,0 +1,31 @@ +// -*- C++ -*- +// +// $Id$ + +#include "orbsvcs/LoadBalancingS.h" + + +class HashReplicaFactory + : public virtual POA_TAO_LoadBalancing::GenericFactory +{ +public: + + virtual CORBA::Object_ptr create_object ( + const char *type_id, + const TAO_LoadBalancing::Criteria &the_criteria, + TAO_LoadBalancing::GenericFactory::FactoryCreationId_out + factory_creation_id) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::NoFactory, + TAO_LoadBalancing::ObjectNotCreated, + TAO_LoadBalancing::InvalidCriteria, + TAO_LoadBalancing::InvalidProperty, + TAO_LoadBalancing::CannotMeetCriteria)); + + virtual void delete_object ( + const TAO_LoadBalancing::GenericFactory::FactoryCreationId + &factory_creation_id) + ACE_THROW_SPEC ((CORBA::SystemException, + TAO_LoadBalancing::ObjectNotFound)); + +}; diff --git a/TAO/orbsvcs/tests/LoadBalancing/LoadBalancer_test.cpp b/TAO/orbsvcs/tests/LoadBalancing/LoadBalancer_test.cpp new file mode 100644 index 00000000000..186f9df75fa --- /dev/null +++ b/TAO/orbsvcs/tests/LoadBalancing/LoadBalancer_test.cpp @@ -0,0 +1,64 @@ +// -*- C++ -*- +// +// $Id$ + + +ACE_RCSID (LoadBalancer_test, LoadBalancer_test.cpp "$Id$") + +int +main (int argc, char *argv[]) +{ + // @@ activate Replica servant + // @@ Obtain reference to object + MyReplica_var replica = replica_servant._this (); + + // @@ Is _interface_repository_id() portable? + const char * type_id = replica->_interface_repository_id (); + + // Infrastructure-Controlled MembershipStyle + + // Obtain Reference to the TAO LoadBalancer ReplicationManager + CORBA::Object_var obj = resolve_initial_references ("TAO_LoadBalancer"); + TAO_LoadBalancer_var lb = TAO_LoadBalancer::_narrow (obj); + //@@ check if is nil + + // Set the default properties + TAO_LoadBalancer::Properties props; + // @@ actually set them (InitialNumberReplicas, + // MinimumNumberReplicas, etc) + + lb->set_default_properties (props); + + // Set the properties specific to my Object type + TAO_LoadBalancer::Properties overrides; + // @@ actually set them (InitialNumberReplicas, + // MinimumNumberReplicas, etc) + + lb->set_type_properties (type_id, + overrides); + + + + + + + + + // The factory ID + TAO_LoadBalancer::FactoryCreationID factory_creation_id; + + // Create a replicated object (object group) + obj = lb->create_object (type_id, + the_criteria, + factory_creation_id); + MyReplica_var replica_group = MyReplica::_narrow (obj); + // @@ check if is nil + + replica_group->some_method_available_on_replica (); + + + // Application-Controlled MembershipStyle + + + return 0; +} diff --git a/TAO/orbsvcs/tests/LoadBalancing/PropertyManager.cpp b/TAO/orbsvcs/tests/LoadBalancing/PropertyManager.cpp new file mode 100644 index 00000000000..80f92ed301e --- /dev/null +++ b/TAO/orbsvcs/tests/LoadBalancing/PropertyManager.cpp @@ -0,0 +1,428 @@ + +#include "LB_test.h" + +ACE_RCSID (LB_test, PropertyManager, "$Id$") + +int +LB_test::set_default_properties (void) +{ + if (this->test_invalid_property () != 0 + || this->test_unsupported_property != 0) + return -1; + + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + const int INIT_NUM_REPLICAS = 4; + const int MIN_NUM_REPLICAS = 3; + + const int DEFAULT_PROPERTY_COUNT = 3; + TAO_LoadBalancer::Properties properties; + properties.length (DEFAULT_PROPERTY_COUNT); + + // Default initial number of replicas + TAO_LoadBalancer::Property initial_number_replicas; + property.nam.length (1); + property.nam[0].id = CORBA::string_dup ("InitialNumberReplicas"); + property.val = INIT_NUM_REPLICAS; + properties[0] = initial_number_replicas; + + //Default minimum number of replicas + TAO_LoadBalancer::Property minimum_number_replicas; + property.nam.length (1); + property.nam[0].id = CORBA::string_dup ("MinimumNumberReplicas"); + property.val = MIN_NUM_REPLICAS; + properties[1] = minimum_number_replicas; + + // Default factories (simulated locations) + TAO_LoadBalancer::Property factories; + property.nam.length (1); + property.nam[0].id = CORBA::string_dup ("Factories"); + + TAO_LoadBalancer::FactoryInfos factory_infos; + factory_infos.length (INIT_NUM_REPLICAS); + for (int i = 0; i < factory_infos.length (); ++i) + { + TAO_LoadBalancer::FactoryInfo &factory_info = + factory_infos[i]; + + TAO_LoadBalancer::GenericFactory_var factory = + factory_servant[i]->_this (ACE_TRY_ENV); + ACE_TRY_CHECK; + + factory_info.factory = factory.in (); + + // Create a fake location for each factory. + char location[BUFSIZ] = { 0 }; + ACE_OS::sprintf (location, "%d", i); + factory_info.the_location.id = + CORBA::string_dup (location); + factory_info.the_location.kind = + CORBA::string_dup ("location number"); + + // @@ TODO: Add factory-specific Criteria. + // factory_info.the_criteria ... + } property.val = factory_infos; + properties[2] = factories; + + // @@ TODO: Add the following properties to the sequence of + // default properties: + // ReplicationStyle + // MembershipStyle + // ConsistencyStyle (?) + // LoadMonitoringStyle + // LoadMonitoringGranularity + // LoadMonitoringInterval + // CheckpointInterval (?) + + this->load_balancer->set_default_properties (properties, + ACE_TRY_ENV); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + ACE_TEXT ("Caught unexpected exception:")); + + return -1; + } + ACE_ENDTRY; + + + return 0; +} + +int +LB_test::test_invalid_property (void) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + TAO_LoadBalancer::Property property; + property.nam.length (1); + property.nam[0].id = CORBA::string_dup ("FOO_BAR_BAZ"); + + TAO_LoadBalancer::Properties properties; + properties.length (1); + properties[0] = property; + + this->load_balancer->set_default_properties (properties, + ACE_TRY_ENV); + ACE_TRY_CHECK; + } + ACE_CATCH (TAO_LoadBalancer::InvalidProperty, ex) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Successfully caught %s exception\n"), + ex._id ())); + + for (int j = 0; j < ex.nam.length (); ++j) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT (" nam[%d].id: %s\n") + ACE_TEXT (" kind: %s\n"), + j, + ex.nam[j].id, + ex.nam[j].kind)); + // @@ What's the best way to print the contents of a ex.val, + // i.e. an Any? + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + ACE_TEXT ("Caught unexpected exception:")); + + return -1; + } + ACE_ENDTRY; + + return 0; +} + +int +LB_test::test_unsupported_property (void) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + TAO_LoadBalancer::Property property; + property.nam.length (1); + property.nam[0].id = CORBA::string_dup ("FOO_BAR_BAZ"); + + TAO_LoadBalancer::Properties properties; + properties.length (1); + properties[0] = property; + + this->load_balancer->set_default_properties (properties, + ACE_TRY_ENV); + ACE_TRY_CHECK; + } + ACE_CATCH (TAO_LoadBalancer::UnsupportedProperty, ex) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Successfully caught %s exception\n"), + ex._id ())); + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + ACE_TEXT ("Caught unexpected exception:")); + + return -1; + } + ACE_ENDTRY; + + return 0; +} + +int +LB_test::get_default_properties (void) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + TAO_LoadBalancer::Properties properties = + this->load_balancer->get_default_properties (ACE_TRY_ENV); + ACE_TRY_CHECK; + + for (int i = 0; i < properties.length (); ++i) + { + // Property values are not displayed since they are stored + // as Anys. + + TAO_LoadBalancer::Property &property = properties[i]; + + for (int j = 0; j < property.length (); ++j) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("properties[%d].nam[%d].id = <%s>\n") + ACE_TEXT (" kind = <%s>\n"), + i, + j, + property[j].id, + property[j].kind)); + } + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + ACE_TEXT ("Caught unexpected exception:")); + + return -1; + } + + return 0; +} + +int +LB_test::remove_default_properties (void) +{ + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + TAO_LoadBalancer::Properties current_properties = + this->load_balancer->get_default_properties (ACE_TRY_ENV); + ACE_TRY_CHECK; + + // Make sure some default properties are already set. + if (current_properties.length () == 0) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("No default properties set")), + -1); + + // Remove the first default property. + TAO_LoadBalancer::Property &removed_property = + current_properties[0]; + + TAO_LoadBalancer::Properties removed_properties; + removed_properties.length (1); + removed_properties[0] = removed_property; + + this->load_balancer->remove_default_properties (removed_properties, + ACE_TRY_ENV); + ACE_TRY_CHECK; + + removed_properties = + this->load_balancer->get_default_properties (ACE_TRY_ENV); + ACE_TRY_CHECK; + + // @@ TODO: The following is a weak test. It needs improvement. + // + // Iterate through the sequence of id values in each property. + // If one in the properties after removal matches the its + // corresponding id in the property that was removed then no + // removal occurred. + for (int i = 0; i < removed_properties.length (); ++i) + for (int j = 0; j < removed_property.length (); ++j) + if (ACE_OS::strcmp (removed_property[j].id, + removed_properties[i][j].id) == 0) + return -1; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + ACE_TEXT ("Caught unexpected exception:")); + + return -1; + } + ACE_ENDTRY; + + return 0; +} + +int +LB_test::set_type_properties (void) +{ + // @@ TODO: Implement + + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + TAO_LoadBalancer::Properties overrides; + + this->load_balancer->set_type_properties (type_id, + overrides, + ACE_TRY_ENV); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + ACE_TEXT ("Caught unexpected exception:")); + + return -1; + } + ACE_ENDTRY; + + return 0; +} + +int +LB_test::get_type_properties (void) +{ + // @@ TODO: Implement + + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + TAO_LoadBalancer::Properties = + this->get_type_properties (type_id, ACE_TRY_ENV); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + ACE_TEXT ("Caught unexpected exception:")); + + return -1; + } + ACE_ENDTRY; + + return 0; +} + +int +LB_test::remove_type_properties (void) +{ + // @@ TODO: Implement + + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + TAO_LoadBalancer::Properties properties; + + this->load_balancer->remove_type_properties (type_id, + properties, + ACE_TRY_ENV); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + ACE_TEXT ("Caught unexpected exception:")); + + return -1; + } + ACE_ENDTRY; + + return 0; +} + +int +LB_test::set_properties_dynamically (void) +{ + // @@ TODO: Implement + + if (this->test_object_group_not_found () != 0) + return -1; + + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + + this->load_balancer->set_properties_dynamically (object_group, + overrides, + ACE_TRY_ENV); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + ACE_TEXT ("Caught unexpected exception:")); + + return -1; + } + ACE_ENDTRY; + + return 0; +} + +int +LB_test::test_object_group_not_found () +{ + // @@ TODO:: Implement + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + ACE_TRY_CHECK; + } + ACE_CATCH (TAO_LoadBalancer::ObjectGroupNotFound, ex) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Successfully caught %s exception\n"), + ex._id ())); + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + ACE_TEXT ("Caught unexpected exception:")); + + return -1; + } + ACE_ENDTRY; + + return 0; +} + +int +LB_test::get_properties (void) +{ + // @@ TODO: Implement + + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + TAO_LoadBalancer::Properties properties = + this->load_balancer->get_properties (object_group, + ACE_TRY_ENV); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + ACE_TEXT ("Caught unexpected exception:")); + + return -1; + } + ACE_ENDTRY; + + return 0; +} -- cgit v1.2.1