summaryrefslogtreecommitdiff
path: root/TAO
diff options
context:
space:
mode:
authordai_y <dai_y@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2009-04-25 06:33:24 +0000
committerdai_y <dai_y@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2009-04-25 06:33:24 +0000
commita141ce4fafb180b7c43fb54aa2712e21e84c1421 (patch)
tree45376633c5911f7f225057cffa8905f09cf6a19e /TAO
parent7823aa89f51dbc0c20dc07c9e4db1077da4f4825 (diff)
downloadATCD-a141ce4fafb180b7c43fb54aa2712e21e84c1421.tar.gz
Sat Apr 25 06:25:37 UTC 2009 Yan Dai <dai_y@ociweb.com>
Diffstat (limited to 'TAO')
-rw-r--r--TAO/ChangeLog108
-rw-r--r--TAO/bin/tao_other_tests.lst1
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp55
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.h1
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Locator_Options.cpp11
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Locator_Options.h6
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Locator_Repository.cpp86
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Locator_Repository.h9
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Locator_XMLHandler.cpp22
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Locator_XMLHandler.h12
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Server_Info.cpp4
-rw-r--r--TAO/orbsvcs/ImplRepo_Service/Server_Info.h5
-rwxr-xr-xTAO/orbsvcs/tests/ImplRepo/ReconnectServer/ReconnectServer.mpc49
-rwxr-xr-xTAO/orbsvcs/tests/ImplRepo/ReconnectServer/client.cpp164
-rwxr-xr-xTAO/orbsvcs/tests/ImplRepo/ReconnectServer/run_test.pl151
-rwxr-xr-xTAO/orbsvcs/tests/ImplRepo/ReconnectServer/serverA.cpp127
-rwxr-xr-xTAO/orbsvcs/tests/ImplRepo/ReconnectServer/serverB.cpp134
-rwxr-xr-xTAO/orbsvcs/tests/ImplRepo/ReconnectServer/test.idl14
-rwxr-xr-xTAO/orbsvcs/tests/ImplRepo/ReconnectServer/test_i.cpp59
-rwxr-xr-xTAO/orbsvcs/tests/ImplRepo/ReconnectServer/test_i.h56
-rw-r--r--TAO/tao/ImR_Client/ImR_Client.cpp13
-rw-r--r--TAO/tao/ORB_Core.cpp10
-rw-r--r--TAO/tao/Synch_Invocation.cpp7
-rw-r--r--TAO/tao/params.cpp1
-rw-r--r--TAO/tao/params.h10
-rw-r--r--TAO/tao/params.inl13
26 files changed, 1089 insertions, 39 deletions
diff --git a/TAO/ChangeLog b/TAO/ChangeLog
index fc8b351e086..68613505a86 100644
--- a/TAO/ChangeLog
+++ b/TAO/ChangeLog
@@ -1,3 +1,111 @@
+Sat Apr 25 06:25:37 UTC 2009 Yan Dai <dai_y@ociweb.com>
+
+ Added IMR changes OCI prepared for some customers.
+
+ * orbsvcs/ImplRepo_Service/ImR_Locator_i.h:
+ * orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp:
+ * orbsvcs/ImplRepo_Service/Locator_Options.h:
+ * orbsvcs/ImplRepo_Service/Locator_Options.cpp:
+ * orbsvcs/ImplRepo_Service/Locator_Repository.h:
+ * orbsvcs/ImplRepo_Service/Locator_Repository.cpp:
+ * orbsvcs/ImplRepo_Service/Locator_XMLHandler.h:
+ * orbsvcs/ImplRepo_Service/Locator_XMLHandler.cpp:
+ * orbsvcs/ImplRepo_Service/Server_Info.h:
+ * orbsvcs/ImplRepo_Service/Server_Info.cpp:
+
+ - Added -UnregisterIfAddressReused IMR option to enable the address reuse
+ checking upon server registering via server_is_running. If a new server
+ reuses already registered server's address, the previous server will be
+ unregistered from IMR.
+ - Current implementation registers server per POA instead of per server
+ process. The ServerId info is added to ServerInfo to help identify if
+ different POAs are from same server process. The POA registering will
+ not affect the POAs registered with the same ServerId.
+
+ * tao/ImR_Client/ImR_Client.cpp:
+
+ Made server ID (set via -ORBServerId) info be part of the server
+ name info to pass to IMR. This info helps IMR to identify if two
+ poas created by same server process.
+
+ * tao/ORB_Core.cpp:
+ * tao/Synch_Invocation.cpp:
+ * tao/params.h:
+ * tao/params.inl:
+ * tao/params.cpp:
+
+ Added new ORB option -ORBForwardInvocationOnObjectNotExist to support
+ request forwarding to next available profile upon receiving OBJECT_NOT_EXIST
+ exception reply.
+
+ * orbsvcs/tests/ImplRepo/ReconnectServer/ReconnectServer.mpc:
+ * orbsvcs/tests/ImplRepo/ReconnectServer/client.cpp:
+ * orbsvcs/tests/ImplRepo/ReconnectServer/run_test.pl:
+ * orbsvcs/tests/ImplRepo/ReconnectServer/serverA.cpp:
+ * orbsvcs/tests/ImplRepo/ReconnectServer/serverB.cpp:
+ * orbsvcs/tests/ImplRepo/ReconnectServer/test.idl:
+ * orbsvcs/tests/ImplRepo/ReconnectServer/test_i.h:
+ * orbsvcs/tests/ImplRepo/ReconnectServer/test_i.cpp:
+
+ Added test case for the changes.
+
+ * bin/tao_other_tests.lst:
+
+ Added ImplRepo ReconnectServer test.
+
+Sat Apr 25 06:14:45 UTC 2009 Yan Dai <dai_y@ociweb.com>
+
+ * orbsvcs/ImplRepo_Service/ImR_Locator_i.h:
+ * orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp:
+ * orbsvcs/ImplRepo_Service/Locator_Options.h:
+ * orbsvcs/ImplRepo_Service/Locator_Options.cpp:
+ * orbsvcs/ImplRepo_Service/Locator_Repository.h:
+ * orbsvcs/ImplRepo_Service/Locator_Repository.cpp:
+ * orbsvcs/ImplRepo_Service/Locator_XMLHandler.h:
+ * orbsvcs/ImplRepo_Service/Locator_XMLHandler.cpp:
+ * orbsvcs/ImplRepo_Service/Server_Info.h:
+ * orbsvcs/ImplRepo_Service/Server_Info.cpp:
+
+ - Added -UnregisterIfAddressReused IMR option to enable the address reuse
+ checking upon server registering via server_is_running. If a new server
+ reuses already registered server's address, the previous server will be
+ unregistered from IMR.
+ - Current implementation registers server per POA instead of per server
+ process. The ServerId info is added to ServerInfo to help identify if
+ different POAs are from same server process. The POA registering will
+ not affect the POAs registered with the same ServerId.
+
+ * tao/ImR_Client/ImR_Client.cpp:
+
+ Made server ID (set via -ORBServerId) info be part of the server
+ name info to pass to IMR. This info helps IMR to identify if two
+ poas created by same server process.
+
+ * tao/ORB_Core.cpp:
+ * tao/Synch_Invocation.cpp:
+ * tao/params.h:
+ * tao/params.inl:
+ * tao/params.cpp:
+
+ Added new ORB option -ORBForwardInvocationOnObjectNotExist to support
+ request forwarding to next available profile upon receiving OBJECT_NOT_EXIST
+ exception reply.
+
+ * orbsvcs/tests/ImplRepo/ReconnectServer/ReconnectServer.mpc:
+ * orbsvcs/tests/ImplRepo/ReconnectServer/client.cpp:
+ * orbsvcs/tests/ImplRepo/ReconnectServer/run_test.pl:
+ * orbsvcs/tests/ImplRepo/ReconnectServer/serverA.cpp:
+ * orbsvcs/tests/ImplRepo/ReconnectServer/serverB.cpp:
+ * orbsvcs/tests/ImplRepo/ReconnectServer/test.idl:
+ * orbsvcs/tests/ImplRepo/ReconnectServer/test_i.h:
+ * orbsvcs/tests/ImplRepo/ReconnectServer/test_i.cpp:
+
+ Added test case for the changes.
+
+ * orbsvcs/ImplRepo_Service/ImR_Locator_i.h:
+
+ Added ImplRepo ReconnectServer test.
+
Fri Apr 24 15:17:37 UTC 2009 Johnny Willemsen <jwillemsen@remedy.nl>
* orbsvcs/tests/Notify/Bug_3646a_Regression/Consumer.cpp:
diff --git a/TAO/bin/tao_other_tests.lst b/TAO/bin/tao_other_tests.lst
index f076a470a40..1937b33c48d 100644
--- a/TAO/bin/tao_other_tests.lst
+++ b/TAO/bin/tao_other_tests.lst
@@ -117,6 +117,7 @@ TAO/orbsvcs/tests/ImplRepo/locked/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_
TAO/orbsvcs/tests/ImplRepo/scale/run_test.pl -servers 5 -objects 5: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !WCHAR !ACE_FOR_TAO !VxWorks !VxWorks_RTP !LabVIEW_RT !WinCE !FUZZ !LynxOS
TAO/orbsvcs/tests/ImplRepo/Bug_689_Regression/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !WCHAR !ACE_FOR_TAO !VxWorks !VxWorks_RTP !LabVIEW_RT !WinCE !FUZZ
TAO/orbsvcs/tests/ImplRepo/Bug_2604_Regression/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !WCHAR !ACE_FOR_TAO !VxWorks !VxWorks_RTP !LabVIEW_RT !WinCE !FUZZ !LynxOS
+TAO/orbsvcs/tests/ImplRepo/ReconnectServer/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !WCHAR !ACE_FOR_TAO !VxWorks !VxWorks_RTP !LabVIEW_RT !WinCE !FUZZ !LynxOS
TAO/orbsvcs/examples/ImR/Combined_Service/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !STATIC !ST !ACE_FOR_TAO !VxWorks !VxWorks_RTP !LabVIEW_RT !WinCE !FUZZ !LynxOS
TAO/orbsvcs/examples/CosEC/TypedSimple/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !NO_IFR !ACE_FOR_TAO !VxWorks !VxWorks_RTP !LabVIEW_RT !WinCE !FUZZ !WCHAR
TAO/orbsvcs/tests/CosEvent/Timeout/run_test.pl: !MINIMUM !CORBA_E_COMPACT !CORBA_E_MICRO !ST !NO_MESSAGING !ACE_FOR_TAO !VxWorks !VxWorks_RTP !LabVIEW_RT !WinCE !FUZZ !LynxOS
diff --git a/TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp b/TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp
index 78cf1a90d1f..d78d4e1ff44 100644
--- a/TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp
+++ b/TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.cpp
@@ -58,6 +58,7 @@ ImR_Locator_i::ImR_Locator_i (void)
, ins_locator_ (0)
, debug_ (0)
, read_only_ (false)
+ , unregister_if_address_reused_ (false)
{
// Visual C++ 6.0 is not smart enough to do a direct assignment
// while allocating the INS_Locator. So, we have to do it in
@@ -85,6 +86,7 @@ ImR_Locator_i::init_with_orb (CORBA::ORB_ptr orb, Options& opts)
read_only_ = opts.readonly ();
startup_timeout_ = opts.startup_timeout ();
ping_interval_ = opts.ping_interval ();
+ unregister_if_address_reused_ = opts.unregister_if_address_reused ();
CORBA::Object_var obj =
this->orb_->resolve_initial_references ("RootPOA");
@@ -791,7 +793,8 @@ ImR_Locator_i::add_or_update_server (const char* server,
if (this->debug_ > 1)
ACE_DEBUG ((LM_DEBUG, "ImR: Adding server <%s>.\n", server));
- this->repository_.add_server (server,
+ this->repository_.add_server ("",
+ server,
options.activator.in (),
options.command_line.in (),
options.environment,
@@ -965,30 +968,52 @@ ImR_Locator_i::shutdown_server (const char* server)
}
void
-ImR_Locator_i::server_is_running (const char* name,
+ImR_Locator_i::server_is_running (const char* id,
const char* partial_ior,
ImplementationRepository::ServerObject_ptr server)
{
- ACE_ASSERT (name != 0);
+ ACE_ASSERT (id != 0);
ACE_ASSERT (partial_ior != 0);
ACE_ASSERT (! CORBA::is_nil (server));
+ ACE_CString server_id;
+ ACE_CString name;
+
+ const char *pos = ACE_OS::strchr (id, ':');
+ if (pos)
+ {
+ ACE_CString idstr (id);
+ server_id = idstr.substr (0, pos - id);
+ name = idstr.substr (pos - id + 1);
+ }
+ else
+ {
+ name = id;
+ }
+
if (this->debug_ > 0)
- ACE_DEBUG ((LM_DEBUG, "ImR: Server %s is running at %s.\n", name, partial_ior));
+ ACE_DEBUG ((LM_DEBUG, "ImR: Server %s is running at %s.\n",
+ name.c_str (), partial_ior));
+
CORBA::String_var ior = orb_->object_to_string (server);
if (this->debug_ > 1)
- ACE_DEBUG ((LM_DEBUG, "ImR: Server %s callback at %s.\n", name, ior.in ()));
+ ACE_DEBUG ((LM_DEBUG, "ImR: Server %s callback at %s.\n",
+ name.c_str (), ior.in ()));
+
+ if (this->unregister_if_address_reused_)
+ this->repository_.unregister_if_address_reused (server_id, name, partial_ior);
Server_Info_Ptr info = this->repository_.get_server (name);
if (info.null ())
{
if (this->debug_ > 0)
- ACE_DEBUG ((LM_DEBUG, "ImR: Auto adding NORMAL server <%s>.\n", name));
+ ACE_DEBUG ((LM_DEBUG, "ImR: Auto adding NORMAL server <%s>.\n", name.c_str ()));
ImplementationRepository::EnvironmentList env (0);
- this->repository_.add_server (name,
+ this->repository_.add_server (server_id,
+ name,
"", // no activator
"", // no cmdline
ImplementationRepository::EnvironmentList (),
@@ -1002,22 +1027,32 @@ ImR_Locator_i::server_is_running (const char* name,
}
else
{
+ if (info->server_id != server_id)
+ {
+ if (! info->server_id.empty())
+ ACE_DEBUG ((LM_DEBUG,
+ ACE_TEXT ("ImR - WARNING: server \"%s\" changed server id from ")
+ ACE_TEXT ("\"%s\" to \"%s\" waiting PER_CLIENT clients.\n"),
+ name.c_str (), info->server_id.c_str (), server_id.c_str ()));
+ info->server_id = server_id;
+ }
+
if (info->activation_mode != ImplementationRepository::PER_CLIENT) {
info->ior = ior.in ();
info->partial_ior = partial_ior;
info->server = ImplementationRepository::ServerObject::_nil (); // Will connect at first access
-
+
int err = this->repository_.update_server (*info);
ACE_ASSERT (err == 0);
ACE_UNUSED_ARG (err);
- waiter_svt_.unblock_one (name, partial_ior, ior.in (), false);
+ waiter_svt_.unblock_one (name.c_str (), partial_ior, ior.in (), false);
} else {
// Note : There's no need to unblock all the waiting request until
// we know the final status of the server.
if (info->waiting_clients > 0)
{
- waiter_svt_.unblock_one (name, partial_ior, ior.in (), true);
+ waiter_svt_.unblock_one (name.c_str (), partial_ior, ior.in (), true);
}
else if (this->debug_ > 1)
{
diff --git a/TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.h b/TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.h
index 03ca0f0e594..7d6ecadacb3 100644
--- a/TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.h
+++ b/TAO/orbsvcs/ImplRepo_Service/ImR_Locator_i.h
@@ -150,6 +150,7 @@ private:
bool read_only_;
ACE_Time_Value startup_timeout_;
ACE_Time_Value ping_interval_;
+ bool unregister_if_address_reused_;
};
#include /**/ "ace/post.h"
diff --git a/TAO/orbsvcs/ImplRepo_Service/Locator_Options.cpp b/TAO/orbsvcs/ImplRepo_Service/Locator_Options.cpp
index 7c4c3009646..88408d3108e 100644
--- a/TAO/orbsvcs/ImplRepo_Service/Locator_Options.cpp
+++ b/TAO/orbsvcs/ImplRepo_Service/Locator_Options.cpp
@@ -38,6 +38,7 @@ Options::Options ()
, startup_timeout_(DEFAULT_START_TIMEOUT)
, readonly_ (false)
, service_command_(SC_NONE)
+, unregister_if_address_reused_ (false)
{
}
@@ -144,6 +145,11 @@ Options::parse_args (int &argc, ACE_TCHAR *argv[])
this->repo_mode_ = REPO_HEAP_FILE;
}
else if (ACE_OS::strcasecmp (shifter.get_current (),
+ ACE_TEXT ("-UnregisterIfAddressReused")) == 0)
+ {
+ this->unregister_if_address_reused_ = true;
+ }
+ else if (ACE_OS::strcasecmp (shifter.get_current (),
ACE_TEXT ("-r")) == 0)
{
this->repo_mode_ = REPO_REGISTRY;
@@ -503,3 +509,8 @@ Options::readonly (void) const
return this->readonly_;
}
+bool
+Options::unregister_if_address_reused (void) const
+{
+ return this->unregister_if_address_reused_;
+}
diff --git a/TAO/orbsvcs/ImplRepo_Service/Locator_Options.h b/TAO/orbsvcs/ImplRepo_Service/Locator_Options.h
index 49450048482..2cf290d07c5 100644
--- a/TAO/orbsvcs/ImplRepo_Service/Locator_Options.h
+++ b/TAO/orbsvcs/ImplRepo_Service/Locator_Options.h
@@ -94,6 +94,8 @@ public:
/// during indirect invocations, if this interval has elapsed.
ACE_Time_Value ping_interval (void) const;
+ bool unregister_if_address_reused (void) const;
+
private:
/// Parses and pulls out arguments for the ImR
int parse_args (int &argc, ACE_TCHAR *argv[]);
@@ -142,6 +144,10 @@ private:
/// The persistent XML file name.
ACE_TString persist_file_name_;
+
+ /// Should check the server address and remove previous server if
+ /// the address is reused.
+ bool unregister_if_address_reused_;
};
#endif
diff --git a/TAO/orbsvcs/ImplRepo_Service/Locator_Repository.cpp b/TAO/orbsvcs/ImplRepo_Service/Locator_Repository.cpp
index d847a6a3fdf..6092c74f041 100644
--- a/TAO/orbsvcs/ImplRepo_Service/Locator_Repository.cpp
+++ b/TAO/orbsvcs/ImplRepo_Service/Locator_Repository.cpp
@@ -22,6 +22,7 @@ static const ACE_TCHAR* ACTIVATOR = ACE_TEXT("Activator");
static const ACE_TCHAR* SERVERS_ROOT_KEY = ACE_TEXT("Servers");
static const ACE_TCHAR* ACTIVATORS_ROOT_KEY = ACE_TEXT("Activators");
static const ACE_TCHAR* TOKEN = ACE_TEXT("Token");
+static const ACE_TCHAR* SERVER_ID = ACE_TEXT("ServerId");
#if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_REGISTRY)
static const char* WIN32_REG_KEY = "Software\\TAO\\ImplementationRepository";
@@ -75,7 +76,7 @@ static void loadServersAsBinary(ACE_Configuration& config, Locator_Repository::S
ACE_TString name;
while (config.enumerate_sections (root, index, name) == 0)
{
- ACE_CString cmdline, dir, envstr, partial_ior, ior, aname;
+ ACE_CString server_id, cmdline, dir, envstr, partial_ior, ior, aname;
u_int amodeint = ImplementationRepository::MANUAL;
u_int start_limit;
@@ -85,6 +86,7 @@ static void loadServersAsBinary(ACE_Configuration& config, Locator_Repository::S
config.open_section (root, name.c_str (), 0, key);
// Ignore any missing values. Server name is enough on its own.
+ config.get_string_value (key, SERVER_ID, server_id);
config.get_string_value (key, ACTIVATOR, aname);
config.get_string_value (key, STARTUP_COMMAND, cmdline);
config.get_string_value (key, WORKING_DIR, dir);
@@ -100,7 +102,7 @@ static void loadServersAsBinary(ACE_Configuration& config, Locator_Repository::S
ImplementationRepository::EnvironmentList env_vars =
ImR_Utils::parseEnvList (envstr);
- Server_Info_Ptr info (new Server_Info(name, aname, cmdline,
+ Server_Info_Ptr info (new Server_Info(server_id, name, aname, cmdline,
env_vars, dir, amode, start_limit, partial_ior, ior));
map.bind (name, info);
index++;
@@ -135,10 +137,10 @@ public:
: repo_ (repo)
{
}
- virtual void next_server (const ACE_CString& name,
- const ACE_CString& aname, const ACE_CString& cmdline,
- const Locator_XMLHandler::EnvList& envlst, const ACE_CString& dir,
- const ACE_CString& amodestr, int start_limit,
+ virtual void next_server (const ACE_CString& server_id,
+ const ACE_CString& name, const ACE_CString& aname,
+ const ACE_CString& cmdline, const Locator_XMLHandler::EnvList& envlst,
+ const ACE_CString& dir, const ACE_CString& amodestr, int start_limit,
const ACE_CString& partial_ior, const ACE_CString& ior)
{
ImplementationRepository::ActivationMode amode =
@@ -149,7 +151,7 @@ public:
int limit = start_limit < 1 ? 1 : start_limit;
- Server_Info_Ptr si (new Server_Info (name, aname, cmdline,
+ Server_Info_Ptr si (new Server_Info (server_id, name, aname, cmdline,
env_vars, dir, amode, limit, partial_ior, ior));
this->repo_.servers ().bind (name, si);
@@ -224,6 +226,7 @@ static void saveAsXML (const ACE_CString& fname, Locator_Repository& repo)
{
Server_Info_Ptr& info = sientry->int_id_;
+ ACE_CString server_id = ACEXML_escape_string (info->server_id);
ACE_CString name = ACEXML_escape_string (info->name);
ACE_CString activator = ACEXML_escape_string (info->activator);
ACE_CString cmdline = ACEXML_escape_string (info->cmdline);
@@ -232,6 +235,7 @@ static void saveAsXML (const ACE_CString& fname, Locator_Repository& repo)
ACE_CString ior = ACEXML_escape_string (info->ior);
ACE_OS::fprintf (fp,"\t<%s", Locator_XMLHandler::SERVER_INFO_TAG);
+ ACE_OS::fprintf (fp," server_id=\"%s\"", server_id.c_str ());
ACE_OS::fprintf (fp," name=\"%s\"", name.c_str ());
ACE_OS::fprintf (fp," activator=\"%s\"", activator.c_str ());
ACE_OS::fprintf (fp," command_line=\"%s\"", cmdline.c_str ());
@@ -276,6 +280,7 @@ static void saveAsXML (const ACE_CString& fname, Locator_Repository& repo)
Locator_Repository::Locator_Repository ()
: rmode_ (Options::REPO_NONE)
, config_ (0)
+, debug_ (0)
{
}
@@ -284,6 +289,7 @@ Locator_Repository::init(const Options& opts)
{
this->rmode_ = opts.repository_mode ();
this->fname_ = opts.persist_file_name ();
+ this->debug_ = opts.debug ();
int err = 0;
switch (this->rmode_)
@@ -348,8 +354,69 @@ Locator_Repository::init(const Options& opts)
return err;
}
+
+int
+Locator_Repository::unregister_if_address_reused (
+ const ACE_CString& server_id,
+ const ACE_CString& name,
+ const char* partial_ior)
+{
+ if (this->debug_ > 0)
+ {
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t)ImR: checking reuse address ")
+ ACE_TEXT ("for server \"%s %s\" ior \"%s\"\n"),
+ server_id.c_str(), name.c_str (), partial_ior));
+ }
+
+ ACE_Vector<ACE_CString> srvs;
+
+ Locator_Repository::SIMap::ENTRY* sientry = 0;
+ Locator_Repository::SIMap::ITERATOR siit (servers ());
+ for (; siit.next (sientry); siit.advance() )
+ {
+ Server_Info_Ptr& info = sientry->int_id_;
+
+ if (this->debug_)
+ {
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t)ImR: iterating - registered server")
+ ACE_TEXT ("\"%s %s\" ior \"%s\"\n"), info->server_id.c_str(),
+ info->name.c_str (), info->partial_ior.c_str ()));
+ }
+
+ if (info->partial_ior == partial_ior
+ && name != info->name
+ && info->server_id != server_id)
+ {
+ if (this->debug_)
+ {
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t)ImR: reuse address %s so remove")
+ ACE_TEXT ("server %s \n"), info->partial_ior.c_str (), info->name.c_str ()));
+ }
+ if (! info->name.empty ())
+ {
+ srvs.push_back (info->name);
+ }
+ }
+ }
+
+ int err = 0;
+ for (size_t i = 0; i < srvs.size (); ++i)
+ {
+
+ if (this->remove_server (srvs[i]) != 0)
+ {
+ err = -1;
+ }
+ }
+
+ return err;
+}
+
+
+
int
-Locator_Repository::add_server (const ACE_CString& name,
+Locator_Repository::add_server (const ACE_CString& server_id,
+ const ACE_CString& name,
const ACE_CString& aname,
const ACE_CString& startup_command,
const ImplementationRepository::EnvironmentList& env_vars,
@@ -361,7 +428,7 @@ Locator_Repository::add_server (const ACE_CString& name,
ImplementationRepository::ServerObject_ptr svrobj)
{
int limit = start_limit < 1 ? 1 : start_limit;
- Server_Info_Ptr info(new Server_Info (name, aname, startup_command,
+ Server_Info_Ptr info(new Server_Info (server_id, name, aname, startup_command,
env_vars, working_dir, activation, limit, partial_ior, ior, svrobj));
int err = servers ().bind (name, info);
@@ -416,6 +483,7 @@ Locator_Repository::update_server (const Server_Info& info)
ACE_CString envstr = ImR_Utils::envListToString(info.env_vars);
+ cfg.set_string_value (key, SERVER_ID, info.server_id.c_str ());
cfg.set_string_value (key, ACTIVATOR, info.activator.c_str ());
cfg.set_string_value (key, STARTUP_COMMAND, info.cmdline.c_str ());
cfg.set_string_value (key, WORKING_DIR, info.dir.c_str ());
diff --git a/TAO/orbsvcs/ImplRepo_Service/Locator_Repository.h b/TAO/orbsvcs/ImplRepo_Service/Locator_Repository.h
index 2ef50b5753a..302df853cc8 100644
--- a/TAO/orbsvcs/ImplRepo_Service/Locator_Repository.h
+++ b/TAO/orbsvcs/ImplRepo_Service/Locator_Repository.h
@@ -54,8 +54,13 @@ public:
/// Initializes the Server Repository
int init (const Options& opts);
+ int unregister_if_address_reused (const ACE_CString& server_id,
+ const ACE_CString& name,
+ const char* partial_ior);
+
/// Add a new server to the Repository
- int add_server (const ACE_CString& name,
+ int add_server (const ACE_CString& server_id,
+ const ACE_CString& name,
const ACE_CString& aname,
const ACE_CString& startup_command,
const ImplementationRepository::EnvironmentList& environment_vars,
@@ -108,6 +113,8 @@ private:
ACE_Auto_Ptr<ACE_Configuration> config_;
// XML requires the file name
ACE_CString fname_;
+
+ unsigned int debug_;
};
diff --git a/TAO/orbsvcs/ImplRepo_Service/Locator_XMLHandler.cpp b/TAO/orbsvcs/ImplRepo_Service/Locator_XMLHandler.cpp
index 087ff256dfa..55757e8c97f 100644
--- a/TAO/orbsvcs/ImplRepo_Service/Locator_XMLHandler.cpp
+++ b/TAO/orbsvcs/ImplRepo_Service/Locator_XMLHandler.cpp
@@ -28,18 +28,19 @@ Locator_XMLHandler::startElement (const ACEXML_Char*,
this->server_name_ = ACE_TEXT("");
this->env_vars_.clear();
- if (attrs != 0 && attrs->getLength () == 8)
+ if (attrs != 0 && attrs->getLength () == 9)
{
- this->server_name_ = attrs->getValue ((size_t)0);
- this->activator_name_ = attrs->getValue ((size_t)1);
- this->command_line_ = attrs->getValue ((size_t)2);
- this->working_dir_ = attrs->getValue ((size_t)3);
- this->activation_ = attrs->getValue ((size_t)4);
+ this->server_id_ = attrs->getValue ((size_t)0);
+ this->server_name_ = attrs->getValue ((size_t)1);
+ this->activator_name_ = attrs->getValue ((size_t)2);
+ this->command_line_ = attrs->getValue ((size_t)3);
+ this->working_dir_ = attrs->getValue ((size_t)4);
+ this->activation_ = attrs->getValue ((size_t)5);
this->env_vars_.clear ();
- int limit = ACE_OS::atoi (attrs->getValue ((size_t)5));
+ int limit = ACE_OS::atoi (attrs->getValue ((size_t)6));
this->start_limit_ = limit;
- this->partial_ior_ = attrs->getValue ((size_t)6);
- this->server_object_ior_ = attrs->getValue ((size_t)7);
+ this->partial_ior_ = attrs->getValue ((size_t)7);
+ this->server_object_ior_ = attrs->getValue ((size_t)8);
}
}
else if (ACE_OS::strcasecmp (qName, ACTIVATOR_INFO_TAG) == 0)
@@ -74,7 +75,8 @@ Locator_XMLHandler::endElement (const ACEXML_Char*,
if (ACE_OS::strcasecmp (qName, SERVER_INFO_TAG) == 0
&& this->server_name_.length () > 0)
{
- this->callback_.next_server (this->server_name_,
+ this->callback_.next_server (
+ this->server_id_, this->server_name_,
this->activator_name_, this->command_line_,
this->env_vars_, this->working_dir_, this->activation_,
this->start_limit_, this->partial_ior_, this->server_object_ior_);
diff --git a/TAO/orbsvcs/ImplRepo_Service/Locator_XMLHandler.h b/TAO/orbsvcs/ImplRepo_Service/Locator_XMLHandler.h
index 25d13752827..5ab9d4bbc65 100644
--- a/TAO/orbsvcs/ImplRepo_Service/Locator_XMLHandler.h
+++ b/TAO/orbsvcs/ImplRepo_Service/Locator_XMLHandler.h
@@ -45,11 +45,12 @@ public:
struct Callback {
virtual ~Callback() {}
- virtual void next_server (const ACE_CString& server_name,
- const ACE_CString& aname, const ACE_CString& startup_cmd,
- const EnvList& env_vars, const ACE_CString& working_dir,
- const ACE_CString& actmode, int start_limit,
- const ACE_CString& partial_ior, const ACE_CString& ior) = 0;
+ virtual void next_server (const ACE_CString& server_id,
+ const ACE_CString& server_name, const ACE_CString& aname,
+ const ACE_CString& startup_cmd, const EnvList& env_vars,
+ const ACE_CString& working_dir, const ACE_CString& actmode,
+ int start_limit, const ACE_CString& partial_ior,
+ const ACE_CString& ior) = 0;
virtual void next_activator (const ACE_CString& activator_name,
long token,
@@ -72,6 +73,7 @@ public:
// callback on completion of an element
Callback& callback_;
+ ACE_CString server_id_;
ACE_TString server_name_;
ACE_TString activator_name_;
ACE_TString command_line_;
diff --git a/TAO/orbsvcs/ImplRepo_Service/Server_Info.cpp b/TAO/orbsvcs/ImplRepo_Service/Server_Info.cpp
index ed15f71c699..94a37c57b05 100644
--- a/TAO/orbsvcs/ImplRepo_Service/Server_Info.cpp
+++ b/TAO/orbsvcs/ImplRepo_Service/Server_Info.cpp
@@ -3,6 +3,7 @@
Server_Info::Server_Info
(
+ const ACE_CString& serverId,
const ACE_CString& server_name,
const ACE_CString& aname,
const ACE_CString& cmdline,
@@ -14,7 +15,8 @@ Server_Info::Server_Info
const ACE_CString& server_ior,
ImplementationRepository::ServerObject_ptr svrobj
)
- : name (server_name)
+ : server_id (serverId)
+ , name (server_name)
, activator (aname)
, cmdline( cmdline)
, env_vars (env)
diff --git a/TAO/orbsvcs/ImplRepo_Service/Server_Info.h b/TAO/orbsvcs/ImplRepo_Service/Server_Info.h
index 4e3bcd06d66..12403532beb 100644
--- a/TAO/orbsvcs/ImplRepo_Service/Server_Info.h
+++ b/TAO/orbsvcs/ImplRepo_Service/Server_Info.h
@@ -28,7 +28,8 @@
*/
struct Server_Info
{
- Server_Info (const ACE_CString& server_name,
+ Server_Info (const ACE_CString& serverId,
+ const ACE_CString& name,
const ACE_CString& aname,
const ACE_CString& cmdline,
const ImplementationRepository::EnvironmentList& env,
@@ -46,7 +47,9 @@ struct Server_Info
void reset();
/// The name of the server.
+ ACE_CString server_id;
ACE_CString name;
+
/// The name of the activator in which this server runs
ACE_CString activator;
/// The command line startup command (program and arguments).
diff --git a/TAO/orbsvcs/tests/ImplRepo/ReconnectServer/ReconnectServer.mpc b/TAO/orbsvcs/tests/ImplRepo/ReconnectServer/ReconnectServer.mpc
new file mode 100755
index 00000000000..e5c946e4951
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/ReconnectServer/ReconnectServer.mpc
@@ -0,0 +1,49 @@
+// $Id$
+//
+// Really the server is the only one that needs to avoid minimum_corba and
+// the lot. But there's no sense in building anything if you can't build
+// the server.
+
+project(*idl): taoidldefaults, avoids_minimum_corba, avoids_corba_e_compact, avoids_corba_e_micro {
+ custom_only = 1
+ IDL_Files {
+ test.idl
+ }
+}
+
+project(*serverA): taoserver, imr_client, avoids_minimum_corba, avoids_corba_e_compact, avoids_corba_e_micro {
+ exename = serverA
+ after += *idl
+ IDL_Files {
+ }
+ Source_Files {
+ testC.cpp
+ testS.cpp
+ serverA.cpp
+ test_i.cpp
+ }
+}
+
+project(*serverB): taoserver, imr_client, avoids_minimum_corba, avoids_corba_e_compact, avoids_corba_e_micro {
+ exename = serverB
+ after += *idl
+ IDL_Files {
+ }
+ Source_Files {
+ testC.cpp
+ testS.cpp
+ serverB.cpp
+ test_i.cpp
+ }
+}
+
+project(*client): taoserver, avoids_minimum_corba, avoids_corba_e_compact, avoids_corba_e_micro {
+ exename = client
+ after += *idl
+ IDL_Files {
+ }
+ Source_Files {
+ testC.cpp
+ client.cpp
+ }
+}
diff --git a/TAO/orbsvcs/tests/ImplRepo/ReconnectServer/client.cpp b/TAO/orbsvcs/tests/ImplRepo/ReconnectServer/client.cpp
new file mode 100755
index 00000000000..3b64fbddf4a
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/ReconnectServer/client.cpp
@@ -0,0 +1,164 @@
+#include "testS.h"
+#include "tao/AnyTypeCode/Any.h"
+#include "ace/Get_Opt.h"
+#include <ace/Task.h>
+#include <ace/OS.h>
+
+
+const ACE_TCHAR *ior_input_file = "file://serverA.ior";
+int test_duration_sec = 15;
+
+class Client_Task : public ACE_Task_Base
+{
+ public:
+ Client_Task (Test::Time_ptr obj)
+ : test_ (Test::Time::_duplicate (obj)),
+ communication_failed_ (false),
+ reconnected_ (false),
+ caught_object_not_exist_ (false)
+ {}
+
+ virtual int svc (void)
+ {
+ ACE_Time_Value start = ACE_OS::gettimeofday ();
+ ACE_Time_Value elapsed;
+ int i = 0;
+ while (elapsed < ACE_Time_Value (test_duration_sec))
+ {
+ try
+ {
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t)Request %d\n"), i ));
+ test_->current_time();
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t)Done request %d\n"), i ));
+ if (communication_failed_)
+ {
+ communication_failed_ = false;
+ reconnected_ = true;
+ }
+ ACE_OS::sleep (1);
+ }
+ catch (const CORBA::OBJECT_NOT_EXIST &)
+ {
+ ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t)caught OBJECT_NOT_EXIST exception for request %d\n"), i ));
+ caught_object_not_exist_ = false;
+ ACE_OS::sleep (1);
+ break;
+ }
+ catch (const CORBA::Exception & /*ex*/)
+ {
+ //ex._tao_print_exception ("Exception caught:");
+ communication_failed_ = true;
+ ACE_OS::sleep (1);
+ }
+ ++i;
+ elapsed = ACE_OS::gettimeofday () - start;
+ }
+
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t)Client thread exit \n")));
+ return 0;
+ }
+
+ bool test_passed () const
+ {
+ return ! communication_failed_ && reconnected_ && ! caught_object_not_exist_;
+ }
+
+ private:
+
+ Test::Time_var test_;
+ bool communication_failed_;
+ bool reconnected_;
+ bool caught_object_not_exist_;
+};
+
+
+int
+parse_args (int argc, ACE_TCHAR* argv[])
+{
+ ACE_Get_Opt get_opts (argc, argv, "i:t:");
+ int c;
+
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'i':
+ ior_input_file = get_opts.opt_arg ();
+ break;
+ case 't':
+ test_duration_sec = ACE_OS::atoi (get_opts.opt_arg ());
+ break;
+ case '?':
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "usage: %s "
+ "-i <iorfile> -t <test_duration>"
+ "\n",
+ argv [0]),
+ -1);
+ }
+ // Indicates sucessful parsing of the command line
+ return 0;
+};
+
+
+int
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
+{
+ try
+ {
+ CORBA::ORB_var orb = CORBA::ORB_init (argc, argv);
+
+ if (parse_args (argc, argv) != 0)
+ {
+ return 1;
+ }
+
+ CORBA::Object_var object = orb->resolve_initial_references ("RootPOA");
+ PortableServer::POA_var rootPOA = PortableServer::POA::_narrow (object.in ());
+
+ PortableServer::POAManager_var poa_manager = rootPOA->the_POAManager ();
+ poa_manager->activate ();
+
+ object = orb->string_to_object(ior_input_file);
+
+ Test::Time_var test = Test::Time::_narrow(object.in ());
+
+ if (CORBA::is_nil(test.in ()))
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%P|%t) Object reference is nil \n"),
+ 1);
+ }
+
+ Client_Task task (test.in ());
+ task.activate (THR_NEW_LWP | THR_JOINABLE, 1, 1);
+
+ ACE_Time_Value tv(test_duration_sec);
+ orb->run (&tv);
+
+ task.wait ();
+
+ // Destroy the POA, waiting until the destruction terminates
+ rootPOA->destroy (1, 1);
+ orb->destroy ();
+
+ if (task.test_passed ())
+ {
+ ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t)Client test passed \n")));
+ }
+ else
+ {
+ ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("(%P|%t)Client test failed.\n")), 1);
+ }
+ }
+ catch (const CORBA::Exception &ex)
+ {
+ ex._tao_print_exception ("Exception caught by client:");
+ return 1;
+ }
+
+ return 0;
+}
+
+
diff --git a/TAO/orbsvcs/tests/ImplRepo/ReconnectServer/run_test.pl b/TAO/orbsvcs/tests/ImplRepo/ReconnectServer/run_test.pl
new file mode 100755
index 00000000000..f3a2ac8c079
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/ReconnectServer/run_test.pl
@@ -0,0 +1,151 @@
+eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
+ & eval 'exec perl -S $0 $argv:q'
+ if 0;
+
+# $Id$
+# -*- perl -*-
+
+###############################################################################
+
+use strict;
+use Sys::Hostname;
+use lib "$ENV{ACE_ROOT}/bin";
+use PerlACE::Run_Test;
+
+my $imr_locator_ior = PerlACE::LocalFile ("imr_locator.ior");
+my $protocol = "iiop";
+my $host = hostname();
+my $port = PerlACE::uniqueid () + 10001;
+my $imr_endpoint = "-ORBEndpoint " . "$protocol" . "://:" . $port;
+my $imr_db = PerlACE::LocalFile ("imr.db");
+# -ORBDebugLevel 10 -ORBVerboseLogging 1 -ORBLogFile imr.log
+my $imr_locator_args = "$imr_endpoint -UnregisterIfAddressReused -d 1 -o $imr_locator_ior -p $imr_db";
+my $IMR_LOCATOR = new PerlACE::Process ("../../../ImplRepo_Service/ImplRepo_Service", $imr_locator_args);
+my $TAO_IMR = new PerlACE::Process("$ENV{ACE_ROOT}/bin/tao_imr");
+my $svr_port_base = PerlACE::uniqueid () + 9000;
+my $svr_a_id = "AAA";
+my $svr_b_id = "BBB";
+my $svr_a_ior = PerlACE::LocalFile ("A.ior");
+my $svr_b_ior = PerlACE::LocalFile ("B.ior");
+my $client_duration = 30;
+my $svr_endpoint = "-ORBEndpoint " . "$protocol" . "://:" . "$svr_port_base/portspan=20";
+my $imr_initref = "-ORBInitRef ImplRepoService=file://$imr_locator_ior";
+my $svr_a_args = "$svr_endpoint $imr_initref -ORBServerId $svr_a_id -ORBUseIMR 1 -o $svr_a_ior";
+my $svr_b_args = "$svr_endpoint $imr_initref -ORBServerId $svr_b_id -ORBUseIMR 1 -o $svr_b_ior";
+my $cli_args = "-ORBForwardInvocationOnObjectNotExist 1 -i file://$svr_a_ior -t $client_duration";
+
+my $SVR_A = new PerlACE::Process ("serverA", $svr_a_args);
+my $SVR_B = new PerlACE::Process ("serverB", $svr_b_args);
+my $CLI = new PerlACE::Process ("client", $cli_args);
+my $delay = 3;
+
+# Make sure the files are gone, so we can wait on them.
+unlink $svr_a_ior;
+unlink $svr_b_ior;
+unlink $imr_db;
+unlink $imr_locator_ior;
+
+my $status = 0;
+print STDERR $IMR_LOCATOR->CommandLine () . "\n";
+$IMR_LOCATOR->Spawn ();
+
+if (PerlACE::waitforfile_timed ($imr_locator_ior, 10) == -1) {
+ print STDERR "ERROR: cannot find $imr_locator_ior\n";
+ $IMR_LOCATOR->Kill ();
+ $status = 1;
+}
+
+sleep (2);
+print STDERR "=== start server A: " . $SVR_A->CommandLine () . "\n";
+$SVR_A->Spawn ();
+
+if (PerlACE::waitforfile_timed ($svr_a_ior, 10) == -1) {
+ print STDERR "ERROR: cannot find $svr_a_ior\n";
+ $IMR_LOCATOR->Kill ();
+ $SVR_A->Kill ();
+ $status = 1;
+}
+
+print STDERR "=== start server B: " . $SVR_B->CommandLine () . "\n";
+$SVR_B->Spawn ();
+
+if (PerlACE::waitforfile_timed ($svr_b_ior, 10) == -1) {
+ print STDERR "ERROR: cannot find $svr_b_ior\n";
+ $IMR_LOCATOR->Kill ();
+ $SVR_A->Kill ();
+ $SVR_B->Kill ();
+ $status = 1;
+}
+
+print STDERR "=== start client: " . $CLI->CommandLine () . "\n";
+my $client = $CLI->Spawn ();
+
+if ($client != 0) {
+ print STDERR "ERROR: client returned $client\n";
+ $IMR_LOCATOR->Kill ();
+ $SVR_A->Kill ();
+ $SVR_B->Kill ();
+ $status = 1;
+}
+
+sleep (5);
+
+print STDERR "=== kill server A\n";
+my $server = $SVR_A->TerminateWaitKill (5);
+
+if ($server != 0) {
+ print STDERR "ERROR: server A returned $server\n";
+ $status = 1;
+}
+
+print STDERR "=== kill server B\n";
+$server = $SVR_B->TerminateWaitKill (5);
+
+if ($server != 0) {
+ print STDERR "ERROR: server B returned $server\n";
+ $status = 1;
+}
+
+sleep (5);
+unlink $svr_a_ior;
+unlink $svr_b_ior;
+
+print STDERR "=== restart server B\n";
+$svr_b_args = $svr_b_args . " -l $delay";
+# Run -ORBDebugLevel 10 to see server raise OBJECT_NOT_EXIST exception.
+$SVR_B = new PerlACE::Process ("serverB", $svr_b_args);
+$SVR_B->Spawn ();
+if (PerlACE::waitforfile_timed ($svr_b_ior, 10) == -1) {
+ print STDERR "ERROR: cannot find $svr_b_ior\n";
+ $IMR_LOCATOR->Kill ();
+ $SVR_B->Kill ();
+ $CLI->Kill ();
+ $status = 1;
+}
+
+sleep ($delay * 2);
+
+print STDERR "=== restart server A\n";
+$SVR_A->Spawn ();
+if (PerlACE::waitforfile_timed ($svr_a_ior, 10) == -1) {
+ print STDERR "ERROR: cannot find $svr_a_ior\n";
+ $IMR_LOCATOR->Kill ();
+ $SVR_A->Kill ();
+ $SVR_B->Kill ();
+ $CLI->Kill ();
+ $status = 1;
+}
+
+$CLI->WaitKill ($client_duration);
+
+$IMR_LOCATOR->Kill();
+$SVR_A->Kill();
+$SVR_B->Kill();
+
+# Make sure the files are gone, so we can wait on them.
+unlink $svr_a_ior;
+unlink $svr_b_ior;
+unlink $imr_db;
+unlink $imr_locator_ior;
+
+exit $status;
diff --git a/TAO/orbsvcs/tests/ImplRepo/ReconnectServer/serverA.cpp b/TAO/orbsvcs/tests/ImplRepo/ReconnectServer/serverA.cpp
new file mode 100755
index 00000000000..eff5140b8b1
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/ReconnectServer/serverA.cpp
@@ -0,0 +1,127 @@
+#include "test_i.h"
+#include "tao/ImR_Client/ImR_Client.h"
+#include <ace/Task.h>
+#include <ace/Get_Opt.h>
+
+const ACE_TCHAR * ior_output_file = ACE_TEXT ("serverA.ior");
+
+int
+parse_args (int argc, ACE_TCHAR *argv[])
+{
+ ACE_Get_Opt get_opts (argc, argv, "o:");
+ int c;
+
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'o':
+ ior_output_file = get_opts.opt_arg ();
+ break;
+ case '?':
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "usage: %s "
+ "-o <iorfile>"
+ "\n",
+ argv [0]),
+ -1);
+ }
+
+ return 0;
+};
+
+int
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
+{
+ try
+ {
+ CORBA::ORB_var orb = CORBA::ORB_init (argc, argv);
+ if (parse_args (argc, argv) != 0)
+ {
+ return 1;
+ }
+
+ CORBA::Object_var object =
+ orb->resolve_initial_references ("RootPOA");
+ PortableServer::POA_var rootPOA =
+ PortableServer::POA::_narrow (object.in ());
+ PortableServer::POAManager_var poa_manager =
+ rootPOA->the_POAManager ();
+
+ CORBA::PolicyList policies (5);
+ policies.length (5);
+
+ // Lifespan policy
+ policies[0] =
+ rootPOA->create_lifespan_policy (PortableServer::PERSISTENT);
+
+ // Servant Retention Policy
+ policies[1] =
+ rootPOA->create_servant_retention_policy (PortableServer::RETAIN );
+
+ // ID Assignment Policy
+ policies[2] =
+ rootPOA->create_id_assignment_policy (PortableServer::USER_ID );
+
+ // Request Processing Policy
+ policies[3] =
+ rootPOA->create_request_processing_policy (PortableServer::USE_ACTIVE_OBJECT_MAP_ONLY );
+
+ // Threading policy
+ policies[4] =
+ rootPOA->create_thread_policy (PortableServer::ORB_CTRL_MODEL);
+
+ PortableServer::POA_var poa_a = rootPOA->create_POA ("poaA",
+ poa_manager.in (),
+ policies
+ );
+ PortableServer::POA_var poa_c = rootPOA->create_POA ("poaC",
+ poa_manager.in (),
+ policies
+ );
+
+ for (CORBA::ULong i = 0;
+ i < policies.length ();
+ ++i)
+ {
+ CORBA::Policy_ptr policy = policies[i];
+ policy->destroy ();
+ }
+
+ Test_Time_i* time = new Test_Time_i();
+
+ PortableServer::ObjectId_var oid =
+ PortableServer::string_to_ObjectId ("Server_A");
+ poa_a->activate_object_with_id (oid.in (), time);
+ CORBA::Object_var time_obj = poa_a->id_to_reference(oid.in());
+ CORBA::String_var ior =
+ orb->object_to_string (time_obj.in ());
+
+ poa_manager->activate ();
+
+ // Output the IOR to the <ior_output_file>
+ FILE *output_file= ACE_OS::fopen (ior_output_file, "w");
+ if (output_file == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Cannot open output file for writing IOR: %s",
+ ior_output_file),
+ 1);
+ ACE_OS::fprintf (output_file, "%s", ior.in ());
+ ACE_OS::fclose (output_file);
+
+ orb->run ();
+
+ rootPOA->destroy (1, 1);
+ orb->destroy ();
+ }
+ catch (const CORBA::Exception &ex)
+ {
+ ex._tao_print_exception ("Exception caught by serverA:");
+ return 1;
+ }
+
+ return 0;
+}
+
+
diff --git a/TAO/orbsvcs/tests/ImplRepo/ReconnectServer/serverB.cpp b/TAO/orbsvcs/tests/ImplRepo/ReconnectServer/serverB.cpp
new file mode 100755
index 00000000000..fd4f207447f
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/ReconnectServer/serverB.cpp
@@ -0,0 +1,134 @@
+#include "test_i.h"
+#include "tao/ImR_Client/ImR_Client.h"
+#include <ace/Task.h>
+#include <ace/Get_Opt.h>
+#include <ace/OS.h>
+
+const ACE_TCHAR * ior_output_file = ACE_TEXT ("serverB.ior");
+// delay between resolving RootPOA init ref and create_POA.
+int delay = 0;
+
+int
+parse_args (int argc, ACE_TCHAR *argv[])
+{
+ ACE_Get_Opt get_opts (argc, argv, "o:l:");
+ int c;
+
+
+ while ((c = get_opts ()) != -1)
+ switch (c)
+ {
+ case 'o':
+ ior_output_file = get_opts.opt_arg ();
+ break;
+ case 'l':
+ delay = ACE_OS::atoi (get_opts.opt_arg ());
+ break;
+ case '?':
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "usage: %s "
+ "-o <iorfile> -l <delay>"
+ "\n",
+ argv [0]),
+ -1);
+ }
+
+ return 0;
+};
+
+int
+ACE_TMAIN(int argc, ACE_TCHAR *argv[])
+{
+ try
+ {
+ CORBA::ORB_var orb = CORBA::ORB_init (argc, argv);
+ if (parse_args (argc, argv) != 0)
+ {
+ return 1;
+ }
+
+ CORBA::Object_var object =
+ orb->resolve_initial_references ("RootPOA");
+ PortableServer::POA_var rootPOA =
+ PortableServer::POA::_narrow (object.in ());
+ PortableServer::POAManager_var poa_manager =
+ rootPOA->the_POAManager ();
+
+ CORBA::PolicyList policies (5);
+ policies.length (5);
+
+ // Lifespan policy
+ policies[0] =
+ rootPOA->create_lifespan_policy (PortableServer::PERSISTENT);
+
+ // Servant Retention Policy
+ policies[1] =
+ rootPOA->create_servant_retention_policy (PortableServer::RETAIN );
+
+ // ID Assignment Policy
+ policies[2] =
+ rootPOA->create_id_assignment_policy (PortableServer::USER_ID );
+
+ // Request Processing Policy
+ policies[3] =
+ rootPOA->create_request_processing_policy (PortableServer::USE_ACTIVE_OBJECT_MAP_ONLY );
+
+ // Threading policy
+ policies[4] =
+ rootPOA->create_thread_policy (PortableServer::ORB_CTRL_MODEL);
+
+ if (delay > 0)
+ {
+ ACE_OS::sleep (delay);
+ }
+
+ PortableServer::POA_var poa_a = rootPOA->create_POA ("poaB",
+ poa_manager.in (),
+ policies
+ );
+
+ for (CORBA::ULong i = 0;
+ i < policies.length ();
+ ++i)
+ {
+ CORBA::Policy_ptr policy = policies[i];
+ policy->destroy ();
+ }
+
+ Test_Dummy_i* dummy = new Test_Dummy_i();
+
+ PortableServer::ObjectId_var oid =
+ PortableServer::string_to_ObjectId ("Server_B");
+ poa_a->activate_object_with_id (oid.in (), dummy);
+ CORBA::Object_var dummy_obj = poa_a->id_to_reference(oid.in());
+ CORBA::String_var ior =
+ orb->object_to_string (dummy_obj.in ());
+
+ poa_manager->activate ();
+
+ // Output the IOR to the <ior_output_file>
+ FILE *output_file= ACE_OS::fopen (ior_output_file, "w");
+ if (output_file == 0)
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "Cannot open output file for writing IOR: %s",
+ ior_output_file),
+ 1);
+ ACE_OS::fprintf (output_file, "%s", ior.in ());
+ ACE_OS::fclose (output_file);
+
+ orb->run ();
+
+ rootPOA->destroy (1, 1);
+ orb->destroy ();
+ }
+ catch (const CORBA::Exception &ex)
+ {
+ ex._tao_print_exception ("Exception caught by serverB:");
+ return 1;
+ }
+
+ return 0;
+}
+
+
diff --git a/TAO/orbsvcs/tests/ImplRepo/ReconnectServer/test.idl b/TAO/orbsvcs/tests/ImplRepo/ReconnectServer/test.idl
new file mode 100755
index 00000000000..b29892067a6
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/ReconnectServer/test.idl
@@ -0,0 +1,14 @@
+module Test
+{
+ interface Dummy
+ {
+ string getMessage();
+ };
+
+ interface Time
+ {
+ long current_time ();
+ oneway void shutdown ();
+ };
+
+};
diff --git a/TAO/orbsvcs/tests/ImplRepo/ReconnectServer/test_i.cpp b/TAO/orbsvcs/tests/ImplRepo/ReconnectServer/test_i.cpp
new file mode 100755
index 00000000000..703d319472b
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/ReconnectServer/test_i.cpp
@@ -0,0 +1,59 @@
+#include "test_i.h"
+#include "ace/OS_NS_time.h"
+
+
+// Implementation skeleton constructor
+Test_Dummy_i::Test_Dummy_i (void)
+{
+}
+
+// Implementation skeleton destructor
+Test_Dummy_i::~Test_Dummy_i (void)
+{
+}
+
+char * Test_Dummy_i::getMessage (
+ void
+ )
+ throw (
+ ::CORBA::SystemException
+ )
+{
+ // Add your implementation here
+ return CORBA::string_dup("Test::Dummy---->Hello World");
+}
+
+Test_Time_i::Test_Time_i (void)
+{
+}
+
+// Implementation skeleton destructor
+Test_Time_i::~Test_Time_i (void)
+{
+}
+
+::CORBA::Long Test_Time_i::current_time (
+ void
+ )
+ throw (
+ ::CORBA::SystemException
+ )
+{
+ ACE_DEBUG ((LM_DEBUG, "(%P|%t)Test_Time_i::current_time called\n"));
+ return CORBA::Long (ACE_OS::time (0));
+}
+
+void Test_Time_i::shutdown (
+ void
+ )
+ throw (
+ ::CORBA::SystemException
+ )
+{
+ ACE_DEBUG ((LM_DEBUG,
+ "%s\n",
+ "Time_i is shutting down"));
+
+}
+
+
diff --git a/TAO/orbsvcs/tests/ImplRepo/ReconnectServer/test_i.h b/TAO/orbsvcs/tests/ImplRepo/ReconnectServer/test_i.h
new file mode 100755
index 00000000000..165c90becf9
--- /dev/null
+++ b/TAO/orbsvcs/tests/ImplRepo/ReconnectServer/test_i.h
@@ -0,0 +1,56 @@
+#ifndef IMR_SWITCHSERVER_H
+#define IMR_SWITCHSERVER_H
+
+#include "testS.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+#pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+
+class Test_Dummy_i
+ : public virtual POA_Test::Dummy
+{
+public:
+ // Constructor
+ Test_Dummy_i (void);
+
+ // Destructor
+ virtual ~Test_Dummy_i (void);
+
+ virtual char * getMessage (void)
+ throw (
+ ::CORBA::SystemException
+ );
+};
+
+class Test_Time_i
+ : public virtual POA_Test::Time
+{
+public:
+ // Constructor
+ Test_Time_i (void);
+
+ // Destructor
+ virtual ~Test_Time_i (void);
+
+ virtual
+ ::CORBA::Long current_time (
+ void
+ )
+ throw (
+ ::CORBA::SystemException
+ );
+
+ virtual
+ void shutdown (
+ void
+ )
+ throw (
+ ::CORBA::SystemException
+ );
+};
+
+
+#endif /* IMR_SWITCHSERVER_H */
+
diff --git a/TAO/tao/ImR_Client/ImR_Client.cpp b/TAO/tao/ImR_Client/ImR_Client.cpp
index 084e493427e..0d1335792ff 100644
--- a/TAO/tao/ImR_Client/ImR_Client.cpp
+++ b/TAO/tao/ImR_Client/ImR_Client.cpp
@@ -122,7 +122,18 @@ namespace TAO
TAO::Portable_Server::Non_Servant_Upcall non_servant_upcall (*poa);
ACE_UNUSED_ARG (non_servant_upcall);
- imr_locator->server_is_running (poa->name().c_str (),
+ ACE_CString serverId = poa->orb_core ().server_id ();
+ ACE_CString name;
+ if (serverId.empty ())
+ {
+ name = poa->name();
+ }
+ else
+ {
+ name = serverId + ":" + poa->name();
+ }
+
+ imr_locator->server_is_running (name.c_str (),
partial_ior.c_str(),
svr.in());
}
diff --git a/TAO/tao/ORB_Core.cpp b/TAO/tao/ORB_Core.cpp
index 3b7089d28aa..a55af94ca97 100644
--- a/TAO/tao/ORB_Core.cpp
+++ b/TAO/tao/ORB_Core.cpp
@@ -1072,7 +1072,17 @@ TAO_ORB_Core::init (int &argc, char *argv[] )
arg_shifter.consume_arg ();
}
+ else if (0 != (current_arg = arg_shifter.get_the_parameter
+ (ACE_TEXT("-ORBForwardInvocationOnObjectNotExist"))))
+ {
+ int forward = ACE_OS::atoi (current_arg);
+ if (forward)
+ this->orb_params_.forward_invocation_on_object_not_exist (true);
+ else
+ this->orb_params_.forward_invocation_on_object_not_exist (false);
+ arg_shifter.consume_arg ();
+ }
////////////////////////////////////////////////////////////////
// catch any unknown -ORB args //
////////////////////////////////////////////////////////////////
diff --git a/TAO/tao/Synch_Invocation.cpp b/TAO/tao/Synch_Invocation.cpp
index e0ad08a0a55..55330d06043 100644
--- a/TAO/tao/Synch_Invocation.cpp
+++ b/TAO/tao/Synch_Invocation.cpp
@@ -538,6 +538,10 @@ namespace TAO
throw ::CORBA::MARSHAL (0, CORBA::COMPLETED_MAYBE);
}
+ bool forward_on_object_not_exist
+ = ACE_OS_String::strcmp (type_id.in (), "IDL:omg.org/CORBA/OBJECT_NOT_EXIST:1.0") == 0 ?
+ this->stub ()->orb_core ()->orb_params ()->forward_invocation_on_object_not_exist() : false;
+
// Special handling for non-fatal system exceptions.
//
// Note that we are careful to retain "at most once" semantics.
@@ -548,7 +552,8 @@ namespace TAO
ACE_OS_String::strcmp (type_id.in (),
"IDL:omg.org/CORBA/NO_RESPONSE:1.0") == 0 ||
ACE_OS_String::strcmp (type_id.in (),
- "IDL:omg.org/CORBA/COMM_FAILURE:1.0") == 0) &&
+ "IDL:omg.org/CORBA/COMM_FAILURE:1.0") == 0 ||
+ forward_on_object_not_exist) &&
(CORBA::CompletionStatus) completion != CORBA::COMPLETED_YES)
{
{
diff --git a/TAO/tao/params.cpp b/TAO/tao/params.cpp
index f3a299b9f84..7008353587a 100644
--- a/TAO/tao/params.cpp
+++ b/TAO/tao/params.cpp
@@ -61,6 +61,7 @@ TAO_ORB_Parameters::TAO_ORB_Parameters (void)
"TAO_PortableServer",
"_make_TAO_Object_Adapter_Factory",
""))
+ , forward_invocation_on_object_not_exist_ (false)
, collocation_resolver_name_ ("Default_Collocation_Resolver")
{
for (int i = 0; i != TAO_NO_OF_MCAST_SERVICES; ++i)
diff --git a/TAO/tao/params.h b/TAO/tao/params.h
index e9425d7789e..636988d3763 100644
--- a/TAO/tao/params.h
+++ b/TAO/tao/params.h
@@ -252,6 +252,9 @@ public:
void collocation_resolver_name (const char *s);
const char *collocation_resolver_name (void) const;
+ void forward_invocation_on_object_not_exist (bool opt);
+ bool forward_invocation_on_object_not_exist (void) const;
+
private:
// Each "endpoint" is of the form:
//
@@ -462,6 +465,13 @@ private:
*/
ACE_TString poa_factory_directive_;
+
+ /**
+ * Do we need forward invocation to next avaiable profile upon
+ * OBJECT_NOT_EXIST exception?
+ */
+ bool forward_invocation_on_object_not_exist_;
+
/**
* Name of the collocation resolver that needs to be instantiated.
* The default value is "Default_Collocation_Resolver". If
diff --git a/TAO/tao/params.inl b/TAO/tao/params.inl
index 7dde930b7f8..35bb921d258 100644
--- a/TAO/tao/params.inl
+++ b/TAO/tao/params.inl
@@ -352,4 +352,17 @@ TAO_ORB_Parameters::collocation_resolver_name (void) const
return this->collocation_resolver_name_.c_str ();
}
+ACE_INLINE bool
+TAO_ORB_Parameters::forward_invocation_on_object_not_exist (void) const
+{
+ return this->forward_invocation_on_object_not_exist_;
+}
+
+ACE_INLINE void
+TAO_ORB_Parameters::forward_invocation_on_object_not_exist (bool x)
+{
+ this->forward_invocation_on_object_not_exist_ = x;
+}
+
+
TAO_END_VERSIONED_NAMESPACE_DECL