summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOssama Othman <ossama-othman@users.noreply.github.com>2000-07-13 03:06:02 +0000
committerOssama Othman <ossama-othman@users.noreply.github.com>2000-07-13 03:06:02 +0000
commitc03dddf83ed6cad116b43bd7c3f6b4e2a2f9aaad (patch)
tree6b3ac70b00fb714ec221d8e1d37a4a503edefe20
parent679049c04b670d4a7a801413167da30059611e88 (diff)
downloadATCD-c03dddf83ed6cad116b43bd7c3f6b4e2a2f9aaad.tar.gz
Initial work for new implementation of load balancer
-rw-r--r--TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Equal_To.cpp9
-rw-r--r--TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Equal_To.h79
-rw-r--r--TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Equal_To.inl33
-rw-r--r--TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Hash.cpp9
-rw-r--r--TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Hash.h71
-rw-r--r--TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Hash.inl23
-rw-r--r--TAO/orbsvcs/orbsvcs/LB_ObjectGroup_Map.h106
-rw-r--r--TAO/orbsvcs/orbsvcs/LB_Replica_Equal_To.cpp9
-rw-r--r--TAO/orbsvcs/orbsvcs/LB_Replica_Equal_To.h81
-rw-r--r--TAO/orbsvcs/orbsvcs/LB_Replica_Equal_To.inl37
-rw-r--r--TAO/orbsvcs/orbsvcs/LB_Replica_Hash.cpp9
-rw-r--r--TAO/orbsvcs/orbsvcs/LB_Replica_Hash.h72
-rw-r--r--TAO/orbsvcs/orbsvcs/LB_Replica_Hash.inl26
-rw-r--r--TAO/orbsvcs/orbsvcs/LB_Replica_Map.h91
-rw-r--r--TAO/orbsvcs/orbsvcs/LB_Replication_Manager.h6
-rw-r--r--TAO/orbsvcs/orbsvcs/LoadBalancing.idl301
-rw-r--r--TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Equal_To.cpp9
-rw-r--r--TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Equal_To.h79
-rw-r--r--TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Equal_To.inl33
-rw-r--r--TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Hash.cpp9
-rw-r--r--TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Hash.h71
-rw-r--r--TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Hash.inl23
-rw-r--r--TAO/orbsvcs/orbsvcs/LoadBalancing/LB_ObjectGroup_Map.h106
-rw-r--r--TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Equal_To.cpp9
-rw-r--r--TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Equal_To.h81
-rw-r--r--TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Equal_To.inl37
-rw-r--r--TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Hash.cpp9
-rw-r--r--TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Hash.h72
-rw-r--r--TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Hash.inl26
-rw-r--r--TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replica_Map.h91
-rw-r--r--TAO/orbsvcs/orbsvcs/LoadBalancing/LB_Replication_Manager.h6
-rw-r--r--TAO/orbsvcs/orbsvcs/LoadBalancing/LoadBalancingI.cpp587
-rw-r--r--TAO/orbsvcs/orbsvcs/LoadBalancing/LoadBalancingI.h273
-rw-r--r--TAO/orbsvcs/orbsvcs/LoadBalancing/ObjectGroupManager.cpp10
-rw-r--r--TAO/orbsvcs/orbsvcs/LoadBalancing/ReplicaLocator.cpp2
-rw-r--r--TAO/orbsvcs/orbsvcs/LoadBalancingI.cpp587
-rw-r--r--TAO/orbsvcs/orbsvcs/LoadBalancingI.h273
-rw-r--r--TAO/orbsvcs/orbsvcs/ObjectGroupManager.cpp10
-rw-r--r--TAO/orbsvcs/orbsvcs/ReplicaLocator.cpp2
-rw-r--r--TAO/orbsvcs/tests/LoadBalancing/GenericFactory.cpp238
-rw-r--r--TAO/orbsvcs/tests/LoadBalancing/HashReplicaFactory.cpp103
-rw-r--r--TAO/orbsvcs/tests/LoadBalancing/HashReplicaFactory.h31
-rw-r--r--TAO/orbsvcs/tests/LoadBalancing/LoadBalancer_test.cpp64
-rw-r--r--TAO/orbsvcs/tests/LoadBalancing/PropertyManager.cpp428
44 files changed, 4102 insertions, 129 deletions
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 <ossama@uci.edu>
+//
+// ============================================================================
+
+#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 <ossama@uci.edu>
+//
+// ============================================================================
+
+#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 <ossama@uci.edu>
+//
+// ============================================================================
+
+#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:
+ // <object_group>, <factory_creation_id>, <factory>, and
+ // <factory_creation_id>. 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<const char *>,
+ ACE_Equal_To<const char *>,
+ 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 <ossama@uci.edu>
+//
+// ============================================================================
+
+#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 <ossama@uci.edu>
+//
+// ============================================================================
+
+#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 <ossama@uci.edu>
+//
+// ============================================================================
+
+#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:
+ // <replica>, <location>, <factory>, and
+ // <factory_creation_id>. 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<Property> Properties;
+
+ typedef Name Location;
+ typedef sequence<Location> Locations;
+
+ typedef Properties Criteria;
+
+ struct FactoryInfo {
+ GenericFactory factory;
+ Location the_location;
+ Criteria the_criteria;
+ };
+ typedef sequence<FactoryInfo> 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 <ossama@uci.edu>
+//
+// ============================================================================
+
+#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 <ossama@uci.edu>
+//
+// ============================================================================
+
+#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 <ossama@uci.edu>
+//
+// ============================================================================
+
+#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:
+ // <object_group>, <factory_creation_id>, <factory>, and
+ // <factory_creation_id>. 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<const char *>,
+ ACE_Equal_To<const char *>,
+ 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 <ossama@uci.edu>
+//
+// ============================================================================
+
+#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 <ossama@uci.edu>
+//
+// ============================================================================
+
+#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 <ossama@uci.edu>
+//
+// ============================================================================
+
+#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:
+ // <replica>, <location>, <factory>, and
+ // <factory_creation_id>. 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<TAO_LB_ObjectGroup_Map> 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<TAO_LB_Replica_Map> 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 <ext_id> 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<TAO_LB_ObjectGroup_Map> 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<TAO_LB_Replica_Map> 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 <ext_id> 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 <lb> 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 <replica_group> 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;
+}