summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cpp/config/Make.rules12
-rw-r--r--cpp/msbuild/ice.test.sln4
-rw-r--r--cpp/src/IceDiscovery/LocatorI.cpp16
-rw-r--r--cpp/src/IceDiscovery/LookupI.cpp322
-rw-r--r--cpp/src/IceDiscovery/LookupI.h173
-rw-r--r--cpp/src/IceLocatorDiscovery/PluginI.cpp204
-rw-r--r--cpp/test/IceDiscovery/simple/AllTests.cpp49
-rw-r--r--cpp/test/IceGrid/simple/AllTests.cpp119
-rw-r--r--cpp/test/IceGrid/simple/Server.cpp2
-rw-r--r--csharp/src/Ice/Network.cs2
-rw-r--r--csharp/src/IceDiscovery/LookupI.cs194
-rw-r--r--csharp/src/IceLocatorDiscovery/PluginI.cs105
-rw-r--r--csharp/test/IceDiscovery/simple/AllTests.cs49
-rw-r--r--csharp/test/IceGrid/simple/AllTests.cs58
-rw-r--r--java-compat/src/IceDiscovery/src/main/java/IceDiscovery/LookupI.java197
-rw-r--r--java-compat/src/IceLocatorDiscovery/src/main/java/IceLocatorDiscovery/PluginI.java129
-rw-r--r--java-compat/test/src/main/java/test/IceDiscovery/simple/AllTests.java50
-rw-r--r--java-compat/test/src/main/java/test/IceGrid/simple/AllTests.java58
-rw-r--r--java/src/IceDiscovery/src/main/java/com/zeroc/IceDiscovery/LookupI.java175
-rw-r--r--java/src/IceLocatorDiscovery/src/main/java/com/zeroc/IceLocatorDiscovery/PluginI.java113
-rw-r--r--java/test/src/main/java/test/IceDiscovery/simple/AllTests.java49
-rw-r--r--java/test/src/main/java/test/IceGrid/simple/AllTests.java58
-rw-r--r--scripts/IceGridUtil.py3
-rw-r--r--scripts/Util.py27
-rw-r--r--scripts/tests/IceDiscovery/simple.py8
-rw-r--r--scripts/tests/IceGrid/simple.py14
26 files changed, 1558 insertions, 632 deletions
diff --git a/cpp/config/Make.rules b/cpp/config/Make.rules
index 6e9a1ce9b20..14767faed0c 100644
--- a/cpp/config/Make.rules
+++ b/cpp/config/Make.rules
@@ -51,7 +51,13 @@ shared_excludes = IceUtil Slice
# Build only few components with the static configuration (core and stubs)
#
static_components = $(coreandstub_components)
-static_projects = test/Common test/Ice/% test/IceSSL/% test/IceDiscovery/simple test/IceGrid/simple
+static_projects = test/Common \
+ test/Ice/% \
+ test/IceSSL/% \
+ test/IceDiscovery/simple \
+ test/Glacier2/application \
+ test/IceGrid/simple
+
static_excludes = test/Ice/library test/Ice/plugin
#
@@ -65,7 +71,9 @@ cpp11_projects = test/Common \
test/Ice/% \
test/IceSSL/% \
test/IceDiscovery/% \
- test/IceBox/%
+ test/IceBox/% \
+ test/Glacier2/application \
+ test/IceGrid/simple
cpp11_excludes = IcePatch2 \
test/Ice/gc
diff --git a/cpp/msbuild/ice.test.sln b/cpp/msbuild/ice.test.sln
index f022f3c4e37..91969a1a3d4 100644
--- a/cpp/msbuild/ice.test.sln
+++ b/cpp/msbuild/ice.test.sln
@@ -3788,8 +3788,10 @@ Global
{16EED45E-8D20-40EF-BB30-9DDD5A11B352}.Release|x64.ActiveCfg = Release|x64
{16EED45E-8D20-40EF-BB30-9DDD5A11B352}.Release|x64.Build.0 = Release|x64
{2B721A85-96F1-4B92-BB31-1BCEF6ACFC8E}.Cpp11-Debug|Win32.ActiveCfg = Cpp11-Debug|Win32
+ {2B721A85-96F1-4B92-BB31-1BCEF6ACFC8E}.Cpp11-Debug|Win32.Build.0 = Cpp11-Debug|Win32
{2B721A85-96F1-4B92-BB31-1BCEF6ACFC8E}.Cpp11-Debug|x64.ActiveCfg = Cpp11-Debug|x64
{2B721A85-96F1-4B92-BB31-1BCEF6ACFC8E}.Cpp11-Release|Win32.ActiveCfg = Cpp11-Release|Win32
+ {2B721A85-96F1-4B92-BB31-1BCEF6ACFC8E}.Cpp11-Release|Win32.Build.0 = Cpp11-Release|Win32
{2B721A85-96F1-4B92-BB31-1BCEF6ACFC8E}.Cpp11-Release|x64.ActiveCfg = Cpp11-Release|x64
{2B721A85-96F1-4B92-BB31-1BCEF6ACFC8E}.Debug|Win32.ActiveCfg = Debug|Win32
{2B721A85-96F1-4B92-BB31-1BCEF6ACFC8E}.Debug|Win32.Build.0 = Debug|Win32
@@ -3800,8 +3802,10 @@ Global
{2B721A85-96F1-4B92-BB31-1BCEF6ACFC8E}.Release|x64.ActiveCfg = Release|x64
{2B721A85-96F1-4B92-BB31-1BCEF6ACFC8E}.Release|x64.Build.0 = Release|x64
{C5606B09-9FB7-4337-A490-2024CDCE4036}.Cpp11-Debug|Win32.ActiveCfg = Cpp11-Debug|Win32
+ {C5606B09-9FB7-4337-A490-2024CDCE4036}.Cpp11-Debug|Win32.Build.0 = Cpp11-Debug|Win32
{C5606B09-9FB7-4337-A490-2024CDCE4036}.Cpp11-Debug|x64.ActiveCfg = Cpp11-Debug|x64
{C5606B09-9FB7-4337-A490-2024CDCE4036}.Cpp11-Release|Win32.ActiveCfg = Cpp11-Release|Win32
+ {C5606B09-9FB7-4337-A490-2024CDCE4036}.Cpp11-Release|Win32.Build.0 = Cpp11-Release|Win32
{C5606B09-9FB7-4337-A490-2024CDCE4036}.Cpp11-Release|x64.ActiveCfg = Cpp11-Release|x64
{C5606B09-9FB7-4337-A490-2024CDCE4036}.Debug|Win32.ActiveCfg = Debug|Win32
{C5606B09-9FB7-4337-A490-2024CDCE4036}.Debug|Win32.Build.0 = Debug|Win32
diff --git a/cpp/src/IceDiscovery/LocatorI.cpp b/cpp/src/IceDiscovery/LocatorI.cpp
index 6998007fa14..99e1cdc4fa6 100644
--- a/cpp/src/IceDiscovery/LocatorI.cpp
+++ b/cpp/src/IceDiscovery/LocatorI.cpp
@@ -229,20 +229,20 @@ LocatorI::LocatorI(const LookupIPtr& lookup, const LocatorRegistryPrxPtr& regist
#ifdef ICE_CPP11_MAPPING
void
LocatorI::findObjectByIdAsync(Ice::Identity id,
- function<void(const shared_ptr<ObjectPrx>&)> response,
- function<void(exception_ptr)>,
- const Ice::Current&) const
+ function<void(const shared_ptr<ObjectPrx>&)> response,
+ function<void(exception_ptr)> ex,
+ const Ice::Current&) const
{
- _lookup->findObject(response, id);
+ _lookup->findObject(make_pair(response, ex), id);
}
void
LocatorI::findAdapterByIdAsync(string adapterId,
- function<void(const shared_ptr<ObjectPrx>&)> response,
- function<void(exception_ptr)>,
- const Ice::Current&) const
+ function<void(const shared_ptr<ObjectPrx>&)> response,
+ function<void(exception_ptr)> ex,
+ const Ice::Current&) const
{
- _lookup->findAdapter(response, adapterId);
+ _lookup->findAdapter(make_pair(response, ex), adapterId);
}
#else
void
diff --git a/cpp/src/IceDiscovery/LookupI.cpp b/cpp/src/IceDiscovery/LookupI.cpp
index 76fb6525f03..ae560cbacfd 100644
--- a/cpp/src/IceDiscovery/LookupI.cpp
+++ b/cpp/src/IceDiscovery/LookupI.cpp
@@ -12,6 +12,7 @@
#include <Ice/Communicator.h>
#include <Ice/LocalException.h>
#include <Ice/Initialize.h>
+#include <Ice/LoggerUtil.h>
#include <IceDiscovery/LookupI.h>
#include <iterator>
@@ -21,21 +22,112 @@ using namespace Ice;
using namespace IceDiscovery;
#ifndef ICE_CPP11_MAPPING
-IceDiscovery::Request::Request(const LookupIPtr& lookup, int retryCount) : _lookup(lookup), _nRetry(retryCount)
+namespace
+{
+
+class AdapterCallbackI : public IceUtil::Shared
+{
+public:
+
+ AdapterCallbackI(const LookupIPtr& lookup, const AdapterRequestPtr& request) : _lookup(lookup), _request(request)
+ {
+ }
+
+ void
+ completed(const Ice::AsyncResultPtr& result)
+ {
+ try
+ {
+ result->throwLocalException();
+ }
+ catch(const Ice::LocalException& ex)
+ {
+ _lookup->adapterRequestException(_request, ex);
+ }
+ }
+
+private:
+
+ LookupIPtr _lookup;
+ AdapterRequestPtr _request;
+};
+
+class ObjectCallbackI : public IceUtil::Shared
+{
+public:
+
+ ObjectCallbackI(const LookupIPtr& lookup, const ObjectRequestPtr& request) : _lookup(lookup), _request(request)
+ {
+ }
+
+ void
+ completed(const Ice::AsyncResultPtr& result)
+ {
+ try
+ {
+ result->throwLocalException();
+ }
+ catch(const Ice::LocalException& ex)
+ {
+ _lookup->objectRequestException(_request, ex);
+ }
+ }
+
+private:
+
+ LookupIPtr _lookup;
+ ObjectRequestPtr _request;
+};
+
+}
+#endif
+
+IceDiscovery::Request::Request(const LookupIPtr& lookup, int retryCount) :
+ _lookup(lookup), _retryCount(retryCount), _lookupCount(0), _failureCount(0)
{
}
bool
IceDiscovery::Request::retry()
{
- return --_nRetry >= 0;
+ return --_retryCount >= 0;
+}
+
+void
+IceDiscovery::Request::invoke(const string& domainId, const vector<pair<LookupPrxPtr, LookupReplyPrxPtr> >& lookups)
+{
+ _lookupCount = lookups.size();
+ _failureCount = 0;
+ for(vector<pair<LookupPrxPtr, LookupReplyPrxPtr> >::const_iterator p = lookups.begin(); p != lookups.end(); ++p)
+ {
+ invokeWithLookup(domainId, p->first, p->second);
+ }
+}
+
+bool
+IceDiscovery::Request::exception()
+{
+ //
+ // If all the invocations on all the lookup proxies failed, report it to the locator.
+ //
+ if(++_failureCount == _lookupCount)
+ {
+ finished(0);
+ return true;
+ }
+ return false;
+}
+
+AdapterRequest::AdapterRequest(const LookupIPtr& lookup, const std::string& adapterId, int retryCount) :
+ RequestT<std::string, AdapterCB>(lookup, adapterId, retryCount),
+ _start(IceUtil::Time::now())
+{
}
-#endif
bool
AdapterRequest::retry()
{
- return _proxies.empty() && --_nRetry >= 0;
+ return _proxies.empty() && --_retryCount >= 0;
}
bool
@@ -61,20 +153,12 @@ AdapterRequest::finished(const ObjectPrxPtr& proxy)
{
if(proxy || _proxies.empty())
{
-#ifdef ICE_CPP11_MAPPING
- Request<string>::finished(proxy);
-#else
- RequestT<string, AMD_Locator_findAdapterByIdPtr>::finished(proxy);
-#endif
+ RequestT<string, AdapterCB>::finished(proxy);
return;
}
else if(_proxies.size() == 1)
{
-#ifdef ICE_CPP11_MAPPING
- Request<string>::finished(_proxies[0]);
-#else
- RequestT<string, AMD_Locator_findAdapterByIdPtr>::finished(_proxies[0]);
-#endif
+ RequestT<string, AdapterCB>::finished(_proxies[0]);
return;
}
@@ -89,10 +173,28 @@ AdapterRequest::finished(const ObjectPrxPtr& proxy)
Ice::EndpointSeq endpts = (*p)->ice_getEndpoints();
copy(endpts.begin(), endpts.end(), back_inserter(endpoints));
}
+ RequestT<string, AdapterCB>::finished(prx->ice_endpoints(endpoints));
+}
+
+void
+AdapterRequest::invokeWithLookup(const string& domainId, const LookupPrxPtr& lookup, const LookupReplyPrxPtr& lookupReply)
+{
#ifdef ICE_CPP11_MAPPING
- Request<string>::finished(prx->ice_endpoints(endpoints));
+ auto self = ICE_SHARED_FROM_THIS;
+ lookup->findAdapterByIdAsync(domainId, _id, lookupReply, nullptr, [self](exception_ptr ex)
+ {
+ try
+ {
+ rethrow_exception(ex);
+ }
+ catch(const Ice::LocalException& ex)
+ {
+ self->_lookup->adapterRequestException(self, ex);
+ }
+ });
#else
- RequestT<string, AMD_Locator_findAdapterByIdPtr>::finished(prx->ice_endpoints(endpoints));
+ lookup->begin_findAdapterById(domainId, _id, lookupReply, newCallback(new AdapterCallbackI(_lookup, this),
+ &AdapterCallbackI::completed));
#endif
}
@@ -102,6 +204,11 @@ AdapterRequest::runTimerTask()
_lookup->adapterRequestTimedOut(ICE_SHARED_FROM_THIS);
}
+ObjectRequest::ObjectRequest(const LookupIPtr& lookup, const Ice::Identity& id, int retryCount) :
+ RequestT<Ice::Identity, ObjectCB>(lookup, id, retryCount)
+{
+}
+
void
ObjectRequest::response(const Ice::ObjectPrxPtr& proxy)
{
@@ -109,6 +216,29 @@ ObjectRequest::response(const Ice::ObjectPrxPtr& proxy)
}
void
+ObjectRequest::invokeWithLookup(const string& domainId, const LookupPrxPtr& lookup, const LookupReplyPrxPtr& lookupReply)
+{
+#ifdef ICE_CPP11_MAPPING
+ auto self = ICE_SHARED_FROM_THIS;
+ lookup->findObjectByIdAsync(domainId, _id, lookupReply, nullptr, [self](exception_ptr ex)
+ {
+ try
+ {
+ rethrow_exception(ex);
+ }
+ catch(const Ice::LocalException& ex)
+ {
+ self->_lookup->objectRequestException(self, ex);
+ }
+ });
+#else
+ lookup->begin_findObjectById(domainId, _id, lookupReply, newCallback(new ObjectCallbackI(_lookup, this),
+ &ObjectCallbackI::completed));
+
+#endif
+}
+
+void
ObjectRequest::runTimerTask()
{
_lookup->objectRequestTimedOut(ICE_SHARED_FROM_THIS);
@@ -116,29 +246,14 @@ ObjectRequest::runTimerTask()
LookupI::LookupI(const LocatorRegistryIPtr& registry, const LookupPrxPtr& lookup, const Ice::PropertiesPtr& properties) :
_registry(registry),
+ _lookup(lookup),
_timeout(IceUtil::Time::milliSeconds(properties->getPropertyAsIntWithDefault("IceDiscovery.Timeout", 300))),
_retryCount(properties->getPropertyAsIntWithDefault("IceDiscovery.RetryCount", 3)),
_latencyMultiplier(properties->getPropertyAsIntWithDefault("IceDiscovery.LatencyMultiplier", 1)),
_domainId(properties->getProperty("IceDiscovery.DomainId")),
- _timer(IceInternal::getInstanceTimer(lookup->ice_getCommunicator()))
+ _timer(IceInternal::getInstanceTimer(lookup->ice_getCommunicator())),
+ _warnOnce(true)
{
-#ifndef ICE_CPP11_MAPPING
- __setNoDelete(true);
-#endif
- try
- {
- // Ensure we can establish a connection to the multicast proxy
- lookup->ice_getConnection();
- }
- catch(const Ice::LocalException& ex)
- {
- ostringstream os;
- os << "IceDiscovery is unable to establish a multicast connection:\n";
- os << "proxy = " << lookup << '\n';
- os << ex;
- throw Ice::PluginInitializationException(__FILE__, __LINE__, os.str());
- }
-
//
// Create one lookup proxy per endpoint from the given proxy. We want to send a multicast
// datagram on each endpoint.
@@ -146,22 +261,11 @@ LookupI::LookupI(const LocatorRegistryIPtr& registry, const LookupPrxPtr& lookup
EndpointSeq endpoints = lookup->ice_getEndpoints();
for(vector<EndpointPtr>::const_iterator p = endpoints.begin(); p != endpoints.end(); ++p)
{
- try
- {
- EndpointSeq single;
- single.push_back(*p);
- LookupPrxPtr l = lookup->ice_endpoints(single);
- l->ice_getConnection();
- _lookup.push_back(make_pair(l, LookupReplyPrxPtr()));
- }
- catch(const Ice::LocalException&)
- {
- }
+ EndpointSeq single;
+ single.push_back(*p);
+ _lookups.push_back(make_pair(lookup->ice_endpoints(single), LookupReplyPrxPtr()));
}
- assert(!_lookup.empty());
-#ifndef ICE_CPP11_MAPPING
- __setNoDelete(false);
-#endif
+ assert(!_lookups.empty());
}
LookupI::~LookupI()
@@ -177,6 +281,7 @@ LookupI::destroy()
p->second->finished(0);
_timer->cancel(p->second);
}
+ _objectRequests.clear();
for(map<string, AdapterRequestPtr>::const_iterator p = _adapterRequests.begin(); p != _adapterRequests.end(); ++p)
{
@@ -192,7 +297,7 @@ LookupI::setLookupReply(const LookupReplyPrxPtr& lookupReply)
//
// Use a lookup reply proxy whose adress matches the interface used to send multicast datagrams.
//
- for(vector<pair<LookupPrxPtr, LookupReplyPrxPtr> >::iterator p = _lookup.begin(); p != _lookup.end(); ++p)
+ for(vector<pair<LookupPrxPtr, LookupReplyPrxPtr> >::iterator p = _lookups.begin(); p != _lookups.end(); ++p)
{
UDPEndpointInfoPtr info = ICE_DYNAMIC_CAST(UDPEndpointInfo, p->first->ice_getEndpoints()[0]->getInfo());
if(info && !info->mcastInterface.empty())
@@ -218,13 +323,8 @@ LookupI::setLookupReply(const LookupReplyPrxPtr& lookupReply)
}
void
-#ifdef ICE_CPP11_MAPPING
-LookupI::findObjectById(string domainId, Ice::Identity id, shared_ptr<IceDiscovery::LookupReplyPrx> reply,
+LookupI::findObjectById(ICE_IN(string) domainId, ICE_IN(Ice::Identity) id, ICE_IN(LookupReplyPrxPtr) reply,
const Ice::Current&)
-#else
-LookupI::findObjectById(const string& domainId, const Ice::Identity& id, const IceDiscovery::LookupReplyPrx& reply,
- const Ice::Current&)
-#endif
{
if(domainId != _domainId)
{
@@ -253,13 +353,8 @@ LookupI::findObjectById(const string& domainId, const Ice::Identity& id, const I
}
void
-#ifdef ICE_CPP11_MAPPING
-LookupI::findAdapterById(string domainId, string adapterId, shared_ptr<IceDiscovery::LookupReplyPrx> reply,
- const Ice::Current&)
-#else
-LookupI::findAdapterById(const string& domainId, const string& adapterId, const IceDiscovery::LookupReplyPrxPtr& reply,
+LookupI::findAdapterById(ICE_IN(string) domainId, ICE_IN(string) adapterId, ICE_IN(LookupReplyPrxPtr) reply,
const Ice::Current&)
-#endif
{
if(domainId != _domainId)
{
@@ -289,11 +384,7 @@ LookupI::findAdapterById(const string& domainId, const string& adapterId, const
}
void
-#ifdef ICE_CPP11_MAPPING
-LookupI::findObject(function<void(const shared_ptr<Ice::ObjectPrx>&)> cb, const Ice::Identity& id)
-#else
-LookupI::findObject(const Ice::AMD_Locator_findObjectByIdPtr& cb, const Ice::Identity& id)
-#endif
+LookupI::findObject(const ObjectCB& cb, const Ice::Identity& id)
{
Lock sync(*this);
map<Ice::Identity, ObjectRequestPtr>::iterator p = _objectRequests.find(id);
@@ -309,15 +400,7 @@ LookupI::findObject(const Ice::AMD_Locator_findObjectByIdPtr& cb, const Ice::Ide
{
try
{
- for(vector<pair<LookupPrxPtr, LookupReplyPrxPtr> >::const_iterator l = _lookup.begin(); l != _lookup.end();
- ++l)
- {
-#ifdef ICE_CPP11_MAPPING
- l->first->findObjectByIdAsync(_domainId, id, l->second);
-#else
- l->first->begin_findObjectById(_domainId, id, l->second);
-#endif
- }
+ p->second->invoke(_domainId, _lookups);
_timer->schedule(p->second, _timeout);
}
catch(const Ice::LocalException&)
@@ -329,11 +412,7 @@ LookupI::findObject(const Ice::AMD_Locator_findObjectByIdPtr& cb, const Ice::Ide
}
void
-#ifdef ICE_CPP11_MAPPING
-LookupI::findAdapter(function<void(const shared_ptr<Ice::ObjectPrx>&)> cb, const std::string& adapterId)
-#else
-LookupI::findAdapter(const Ice::AMD_Locator_findAdapterByIdPtr& cb, const std::string& adapterId)
-#endif
+LookupI::findAdapter(const AdapterCB& cb, const std::string& adapterId)
{
Lock sync(*this);
map<string, AdapterRequestPtr>::iterator p = _adapterRequests.find(adapterId);
@@ -349,15 +428,7 @@ LookupI::findAdapter(const Ice::AMD_Locator_findAdapterByIdPtr& cb, const std::s
{
try
{
- for(vector<pair<LookupPrxPtr, LookupReplyPrxPtr> >::const_iterator l = _lookup.begin(); l != _lookup.end();
- ++l)
- {
-#ifdef ICE_CPP11_MAPPING
- l->first->findAdapterByIdAsync(_domainId, adapterId, l->second);
-#else
- l->first->begin_findAdapterById(_domainId, adapterId, l->second);
-#endif
- }
+ p->second->invoke(_domainId, _lookups);
_timer->schedule(p->second, _timeout);
}
catch(const Ice::LocalException&)
@@ -414,16 +485,8 @@ LookupI::objectRequestTimedOut(const ObjectRequestPtr& request)
{
try
{
- for(vector<pair<LookupPrxPtr, LookupReplyPrxPtr> >::const_iterator l = _lookup.begin(); l != _lookup.end();
- ++l)
- {
-#ifdef ICE_CPP11_MAPPING
- l->first->findObjectByIdAsync(_domainId, request->getId(), l->second);
-#else
- l->first->begin_findObjectById(_domainId, request->getId(), l->second);
-#endif
- }
- _timer->schedule(p->second, _timeout);
+ request->invoke(_domainId, _lookups);
+ _timer->schedule(request, _timeout);
return;
}
catch(const Ice::LocalException&)
@@ -437,6 +500,29 @@ LookupI::objectRequestTimedOut(const ObjectRequestPtr& request)
}
void
+LookupI::adapterRequestException(const AdapterRequestPtr& request, const LocalException& ex)
+{
+ Lock sync(*this);
+ map<string, AdapterRequestPtr>::iterator p = _adapterRequests.find(request->getId());
+ if(p == _adapterRequests.end() || p->second.get() != request.get())
+ {
+ return;
+ }
+
+ if(request->exception())
+ {
+ if(_warnOnce)
+ {
+ Warning warn(_lookup->ice_getCommunicator()->getLogger());
+ warn << "failed to lookup adapter `" << p->first << "' with lookup proxy `" << _lookup << "':\n" << ex;
+ _warnOnce = false;
+ }
+ _timer->cancel(request);
+ _adapterRequests.erase(p);
+ }
+}
+
+void
LookupI::adapterRequestTimedOut(const AdapterRequestPtr& request)
{
Lock sync(*this);
@@ -450,16 +536,8 @@ LookupI::adapterRequestTimedOut(const AdapterRequestPtr& request)
{
try
{
- for(vector<pair<LookupPrxPtr, LookupReplyPrxPtr> >::const_iterator l = _lookup.begin(); l != _lookup.end();
- ++l)
- {
-#ifdef ICE_CPP11_MAPPING
- l->first->findAdapterByIdAsync(_domainId, request->getId(), l->second);
-#else
- l->first->begin_findAdapterById(_domainId, request->getId(), l->second);
-#endif
- }
- _timer->schedule(p->second, _timeout);
+ request->invoke(_domainId, _lookups);
+ _timer->schedule(request, _timeout);
return;
}
catch(const Ice::LocalException&)
@@ -472,6 +550,30 @@ LookupI::adapterRequestTimedOut(const AdapterRequestPtr& request)
_timer->cancel(request);
}
+void
+LookupI::objectRequestException(const ObjectRequestPtr& request, const LocalException& ex)
+{
+ Lock sync(*this);
+ map<Ice::Identity, ObjectRequestPtr>::iterator p = _objectRequests.find(request->getId());
+ if(p == _objectRequests.end() || p->second.get() != request.get())
+ {
+ return;
+ }
+
+ if(request->exception())
+ {
+ if(_warnOnce)
+ {
+ Warning warn(_lookup->ice_getCommunicator()->getLogger());
+ string id = _lookup->ice_getCommunicator()->identityToString(p->first);
+ warn << "failed to lookup object `" << id << "' with lookup proxy `" << _lookup << "':\n" << ex;
+ _warnOnce = false;
+ }
+ _timer->cancel(request);
+ _objectRequests.erase(p);
+ }
+}
+
LookupReplyI::LookupReplyI(const LookupIPtr& lookup) : _lookup(lookup)
{
}
diff --git a/cpp/src/IceDiscovery/LookupI.h b/cpp/src/IceDiscovery/LookupI.h
index 46f582d6118..af9d40ea1e6 100644
--- a/cpp/src/IceDiscovery/LookupI.h
+++ b/cpp/src/IceDiscovery/LookupI.h
@@ -21,95 +21,6 @@ namespace IceDiscovery
class LookupI;
-#ifdef ICE_CPP11_MAPPING
-
-template<class T> class Request : public IceUtil::TimerTask
-{
-public:
-
- Request(std::shared_ptr<LookupI> lookup, const T& id, int retryCount) :
- _lookup(lookup),
- _id(id),
- _nRetry(retryCount)
- {
- }
-
- T getId() const
- {
- return _id;
- }
-
- virtual bool retry()
- {
- return --_nRetry >= 0;
- }
-
- bool addCallback(std::function<void(const std::shared_ptr<::Ice::ObjectPrx>&)> cb)
- {
- _callbacks.push_back(cb);
- return _callbacks.size() == 1;
- }
-
- virtual void finished(const Ice::ObjectPrxPtr& proxy)
- {
- for(auto cb : _callbacks)
- {
- cb(proxy);
- }
- _callbacks.clear();
- }
-
-protected:
-
- LookupIPtr _lookup;
- const T _id;
- int _nRetry;
- std::vector<std::function<void(const std::shared_ptr<::Ice::ObjectPrx>&)>> _callbacks;
-};
-
-class ObjectRequest : public Request<Ice::Identity>, public std::enable_shared_from_this<ObjectRequest>
-{
-public:
-
- ObjectRequest(const std::shared_ptr<LookupI>& lookup, const Ice::Identity& id, int retryCount) :
- Request<Ice::Identity>(lookup, id, retryCount)
- {
- }
-
- void response(const std::shared_ptr<Ice::ObjectPrx>&);
-
-private:
-
- virtual void runTimerTask();
-};
-typedef std::shared_ptr<ObjectRequest> ObjectRequestPtr;
-
-class AdapterRequest : public Request<std::string>, public std::enable_shared_from_this<AdapterRequest>
-{
-public:
-
- AdapterRequest(std::shared_ptr<LookupI> lookup, const std::string& adapterId, int retryCount) :
- Request<std::string>(lookup, adapterId, retryCount),
- _start(IceUtil::Time::now())
- {
- }
-
- bool response(const std::shared_ptr<Ice::ObjectPrx>&, bool);
-
- virtual bool retry();
- virtual void finished(const std::shared_ptr<Ice::ObjectPrx>&);
-
-private:
-
- virtual void runTimerTask();
- std::vector<Ice::ObjectPrxPtr> _proxies;
- IceUtil::Time _start;
- IceUtil::Time _latency;
-};
-typedef std::shared_ptr<AdapterRequest> AdapterRequestPtr;
-
-#else
-
class Request : public IceUtil::TimerTask
{
public:
@@ -117,18 +28,27 @@ public:
Request(const LookupIPtr&, int);
virtual bool retry();
+ void invoke(const std::string&, const std::vector<std::pair<LookupPrxPtr, LookupReplyPrxPtr> >&);
+ bool exception();
+
+ virtual void finished(const Ice::ObjectPrxPtr&) = 0;
protected:
+ virtual void invokeWithLookup(const std::string&, const LookupPrxPtr&, const LookupReplyPrxPtr&) = 0;
+
LookupIPtr _lookup;
- int _nRetry;
+ int _retryCount;
+ int _lookupCount;
+ int _failureCount;
};
+ICE_DEFINE_PTR(RequestPtr, Request);
template<class T, class CB> class RequestT : public Request
{
public:
- RequestT(LookupI* lookup, T id, int retryCount) : Request(lookup, retryCount), _id(id)
+ RequestT(const LookupIPtr& lookup, T id, int retryCount) : Request(lookup, retryCount), _id(id)
{
}
@@ -137,7 +57,7 @@ public:
return _id;
}
- bool addCallback(CB cb)
+ bool addCallback(const CB& cb)
{
_callbacks.push_back(cb);
return _callbacks.size() == 1;
@@ -147,7 +67,11 @@ public:
{
for(typename std::vector<CB>::const_iterator p = _callbacks.begin(); p != _callbacks.end(); ++p)
{
+#ifdef ICE_CPP11_MAPPING
+ p->first(proxy);
+#else
(*p)->ice_response(proxy);
+#endif
}
_callbacks.clear();
}
@@ -158,32 +82,42 @@ protected:
std::vector<CB> _callbacks;
};
-class ObjectRequest : public RequestT<Ice::Identity, Ice::AMD_Locator_findObjectByIdPtr>
+#ifdef ICE_CPP11_MAPPING
+typedef std::pair<std::function<void(const std::shared_ptr<::Ice::ObjectPrx>&)>,
+ std::function<void(std::exception_ptr)>> ObjectCB;
+typedef std::pair<std::function<void(const std::shared_ptr<::Ice::ObjectPrx>&)>,
+ std::function<void(std::exception_ptr)>> AdapterCB;
+#else
+typedef Ice::AMD_Locator_findObjectByIdPtr ObjectCB;
+typedef Ice::AMD_Locator_findAdapterByIdPtr AdapterCB;
+#endif
+
+class ObjectRequest : public RequestT<Ice::Identity, ObjectCB>
+#ifdef ICE_CPP11_MAPPING
+ , public std::enable_shared_from_this<ObjectRequest>
+#endif
{
public:
- ObjectRequest(LookupI* lookup, const Ice::Identity& id, int retryCount) :
- RequestT<Ice::Identity, Ice::AMD_Locator_findObjectByIdPtr>(lookup, id, retryCount)
- {
- }
+ ObjectRequest(const LookupIPtr&, const Ice::Identity&, int);
void response(const Ice::ObjectPrxPtr&);
private:
+ virtual void invokeWithLookup(const std::string&, const LookupPrxPtr&, const LookupReplyPrxPtr&);
virtual void runTimerTask();
};
-typedef IceUtil::Handle<ObjectRequest> ObjectRequestPtr;
+ICE_DEFINE_PTR(ObjectRequestPtr, ObjectRequest);
-class AdapterRequest : public RequestT<std::string, Ice::AMD_Locator_findAdapterByIdPtr>
+class AdapterRequest : public RequestT<std::string, AdapterCB>
+#ifdef ICE_CPP11_MAPPING
+ , public std::enable_shared_from_this<AdapterRequest>
+#endif
{
public:
- AdapterRequest(LookupI* lookup, const std::string& adapterId, int retryCount) :
- RequestT<std::string, Ice::AMD_Locator_findAdapterByIdPtr>(lookup, adapterId, retryCount),
- _start(IceUtil::Time::now())
- {
- }
+ AdapterRequest(const LookupIPtr&, const std::string&, int);
bool response(const Ice::ObjectPrxPtr&, bool);
@@ -192,14 +126,14 @@ public:
private:
+ virtual void invokeWithLookup(const std::string&, const LookupPrxPtr&, const LookupReplyPrxPtr&);
virtual void runTimerTask();
+
std::vector<Ice::ObjectPrxPtr> _proxies;
IceUtil::Time _start;
IceUtil::Time _latency;
};
-typedef IceUtil::Handle<AdapterRequest> AdapterRequestPtr;
-
-#endif
+ICE_DEFINE_PTR(AdapterRequestPtr, AdapterRequest);
class LookupI : public Lookup,
private IceUtil::Mutex
@@ -216,29 +150,20 @@ public:
void setLookupReply(const LookupReplyPrxPtr&);
-#ifdef ICE_CPP11_MAPPING
- virtual void findObjectById(std::string,
- Ice::Identity,
- ::std::shared_ptr<IceDiscovery::LookupReplyPrx>,
+ virtual void findObjectById(ICE_IN(std::string), ICE_IN(Ice::Identity), ICE_IN(IceDiscovery::LookupReplyPrxPtr),
const Ice::Current&);
- virtual void findAdapterById(std::string, std::string, ::std::shared_ptr<IceDiscovery::LookupReplyPrx>,
+ virtual void findAdapterById(ICE_IN(std::string), ICE_IN(std::string), ICE_IN(IceDiscovery::LookupReplyPrxPtr),
const Ice::Current&);
- void findObject(std::function<void(const std::shared_ptr<Ice::ObjectPrx>&)>, const Ice::Identity&);
- void findAdapter(std::function<void(const std::shared_ptr<Ice::ObjectPrx>&)>, const std::string&);
-#else
- virtual void findObjectById(const std::string&, const Ice::Identity&, const IceDiscovery::LookupReplyPrx&,
- const Ice::Current&);
- virtual void findAdapterById(const std::string&, const std::string&, const IceDiscovery::LookupReplyPrx&,
- const Ice::Current&);
- void findObject(const Ice::AMD_Locator_findObjectByIdPtr&, const Ice::Identity&);
- void findAdapter(const Ice::AMD_Locator_findAdapterByIdPtr&, const std::string&);
-#endif
+ void findObject(const ObjectCB&, const Ice::Identity&);
+ void findAdapter(const AdapterCB&, const std::string&);
void foundObject(const Ice::Identity&, const Ice::ObjectPrxPtr&);
void foundAdapter(const std::string&, const Ice::ObjectPrxPtr&, bool);
void adapterRequestTimedOut(const AdapterRequestPtr&);
+ void adapterRequestException(const AdapterRequestPtr&, const Ice::LocalException&);
void objectRequestTimedOut(const ObjectRequestPtr&);
+ void objectRequestException(const ObjectRequestPtr&, const Ice::LocalException&);
const IceUtil::TimerPtr&
timer()
@@ -255,7 +180,8 @@ public:
private:
LocatorRegistryIPtr _registry;
- std::vector<std::pair<LookupPrxPtr, LookupReplyPrxPtr> > _lookup;
+ LookupPrxPtr _lookup;
+ std::vector<std::pair<LookupPrxPtr, LookupReplyPrxPtr> > _lookups;
const IceUtil::Time _timeout;
const int _retryCount;
const int _latencyMultiplier;
@@ -263,6 +189,7 @@ private:
IceUtil::TimerPtr _timer;
Ice::ObjectPrxPtr _wellKnownProxy;
+ bool _warnOnce;
std::map<Ice::Identity, ObjectRequestPtr> _objectRequests;
std::map<std::string, AdapterRequestPtr> _adapterRequests;
diff --git a/cpp/src/IceLocatorDiscovery/PluginI.cpp b/cpp/src/IceLocatorDiscovery/PluginI.cpp
index ee01719fd72..112147f8978 100644
--- a/cpp/src/IceLocatorDiscovery/PluginI.cpp
+++ b/cpp/src/IceLocatorDiscovery/PluginI.cpp
@@ -10,6 +10,7 @@
#include <IceUtil/IceUtil.h>
#include <Ice/Ice.h>
#include <Ice/Network.h> // For getInterfacesForMulticast
+#include <Ice/LoggerUtil.h>
#include <IceLocatorDiscovery/Plugin.h>
#include <IceLocatorDiscovery/IceLocatorDiscovery.h>
@@ -22,6 +23,14 @@ namespace
class LocatorI; // Forward declaration
+#ifdef ICE_CPP11_MAPPING
+typedef std::pair<function<void(bool, const pair<const Ice::Byte*, const Ice::Byte*>&)>,
+ function<void(exception_ptr)>> AMDCallback;
+#else
+typedef Ice::AMD_Object_ice_invokePtr AMDCallback;
+#endif
+
+
class Request :
#ifdef ICE_CPP11_MAPPING
public std::enable_shared_from_this<Request>
@@ -31,35 +40,18 @@ class Request :
{
public:
-#ifdef ICE_CPP11_MAPPING
- Request(LocatorI* locator,
- const string& operation,
- Ice::OperationMode mode,
- const pair<const Ice::Byte*, const Ice::Byte*>& inParams,
- const Ice::Context& ctx,
- function<void(bool, const pair<const Ice::Byte*, const Ice::Byte*>&)> responseCB,
- function<void(exception_ptr)> exceptionCB) :
- _locator(locator),
- _operation(operation),
- _mode(mode),
- _context(ctx),
- _inParams(inParams.first, inParams.second),
- _responseCB(move(responseCB)),
- _exceptionCB(move(exceptionCB))
-#else
Request(LocatorI* locator,
const string& operation,
Ice::OperationMode mode,
const pair<const Ice::Byte*, const Ice::Byte*>& inParams,
const Ice::Context& ctx,
- const Ice::AMD_Object_ice_invokePtr& amdCB) :
+ const AMDCallback& amdCB) :
_locator(locator),
_operation(operation),
_mode(mode),
_context(ctx),
_inParams(inParams.first, inParams.second),
_amdCB(amdCB)
-#endif
{
}
@@ -74,12 +66,10 @@ protected:
const Ice::OperationMode _mode;
const Ice::Context _context;
const Ice::ByteSeq _inParams;
+ AMDCallback _amdCB;
#ifdef ICE_CPP11_MAPPING
- function<void(bool, const pair<const Ice::Byte*, const Ice::Byte*>&)> _responseCB;
- function<void(exception_ptr)> _exceptionCB;
exception_ptr _exception;
#else
- const Ice::AMD_Object_ice_invokePtr _amdCB;
IceInternal::UniquePtr<Ice::Exception> _exception;
#endif
@@ -114,11 +104,14 @@ public:
vector<Ice::LocatorPrxPtr> getLocators(const string&, const IceUtil::Time&);
+ void exception(const Ice::LocalException&);
+
private:
virtual void runTimerTask();
- vector<pair<LookupPrxPtr, LookupReplyPrxPtr> > _lookup;
+ LookupPrxPtr _lookup;
+ vector<pair<LookupPrxPtr, LookupReplyPrxPtr> > _lookups;
const IceUtil::Time _timeout;
const int _retryCount;
const IceUtil::Time _retryDelay;
@@ -132,6 +125,8 @@ private:
IceUtil::Time _nextRetry;
int _pendingRetryCount;
+ int _failureCount;
+ bool _warnOnce;
vector<RequestPtr> _pendingRequests;
};
ICE_DEFINE_PTR(LocatorIPtr, LocatorI);
@@ -229,6 +224,36 @@ private:
Ice::LocatorPrxPtr _defaultLocator;
};
+#ifndef ICE_CPP11_MAPPING
+
+class CallbackI : public IceUtil::Shared
+{
+public:
+
+ CallbackI(const LocatorIPtr& locator) : _locator(locator)
+ {
+ }
+
+ void
+ completed(const Ice::AsyncResultPtr& result)
+ {
+ try
+ {
+ result->throwLocalException();
+ }
+ catch(const Ice::LocalException& ex)
+ {
+ _locator->exception(ex);
+ }
+ }
+
+private:
+
+ LocatorIPtr _locator;
+};
+
+#endif
+
}
//
@@ -417,7 +442,7 @@ Request::invoke(const Ice::LocatorPrxPtr& l)
else
{
assert(_exception); // Don't retry if the proxy didn't change
- _exceptionCB(_exception);
+ _amdCB.second(_exception);
}
#else
@@ -447,7 +472,7 @@ void
Request::response(bool ok, const pair<const Ice::Byte*, const Ice::Byte*>& outParams)
{
#ifdef ICE_CPP11_MAPPING
- _responseCB(ok, outParams);
+ _amdCB.first(ok, outParams);
#else
_amdCB->ice_response(ok, outParams);
#endif
@@ -463,11 +488,11 @@ Request::exception(const Ice::Exception& ex)
}
catch(const Ice::RequestFailedException&)
{
- _exceptionCB(current_exception());
+ _amdCB.second(current_exception());
}
catch(const Ice::UnknownException&)
{
- _exceptionCB(current_exception());
+ _amdCB.second(current_exception());
}
catch(const Ice::NoEndpointException&)
{
@@ -477,7 +502,7 @@ Request::exception(const Ice::Exception& ex)
}
catch(...)
{
- _exceptionCB(current_exception());
+ _amdCB.second(current_exception());
}
}
catch(const Ice::CommunicatorDestroyedException&)
@@ -488,7 +513,7 @@ Request::exception(const Ice::Exception& ex)
}
catch(...)
{
- _exceptionCB(current_exception());
+ _amdCB.second(current_exception());
}
}
catch(const Ice::ObjectAdapterDeactivatedException&)
@@ -499,7 +524,7 @@ Request::exception(const Ice::Exception& ex)
}
catch(...)
{
- _exceptionCB(current_exception());
+ _amdCB.second(current_exception());
}
}
catch(const Ice::Exception&)
@@ -545,6 +570,7 @@ LocatorI::LocatorI(const string& name,
const Ice::PropertiesPtr& p,
const string& instanceName,
const Ice::LocatorPrxPtr& voidLocator) :
+ _lookup(lookup),
_timeout(IceUtil::Time::milliSeconds(p->getPropertyAsIntWithDefault(name + ".Timeout", 300))),
_retryCount(p->getPropertyAsIntWithDefault(name + ".RetryCount", 3)),
_retryDelay(IceUtil::Time::milliSeconds(p->getPropertyAsIntWithDefault(name + ".RetryDelay", 2000))),
@@ -553,25 +579,10 @@ LocatorI::LocatorI(const string& name,
_warned(false),
_locator(lookup->ice_getCommunicator()->getDefaultLocator()),
_voidLocator(voidLocator),
- _pendingRetryCount(0)
+ _pendingRetryCount(0),
+ _failureCount(0),
+ _warnOnce(true)
{
-#ifndef ICE_CPP11_MAPPING
- __setNoDelete(true);
-#endif
- try
- {
- // Ensure we can establish a connection to the multicast proxy
- lookup->ice_getConnection();
- }
- catch(const Ice::LocalException& ex)
- {
- ostringstream os;
- os << "IceLocatorDiscovery is unable to establish a multicast connection:\n";
- os << "proxy = " << lookup << '\n';
- os << ex;
- throw Ice::PluginInitializationException(__FILE__, __LINE__, os.str());
- }
-
//
// Create one lookup proxy per endpoint from the given proxy. We want to send a multicast
// datagram on each endpoint.
@@ -579,22 +590,11 @@ LocatorI::LocatorI(const string& name,
Ice::EndpointSeq endpoints = lookup->ice_getEndpoints();
for(vector<Ice::EndpointPtr>::const_iterator p = endpoints.begin(); p != endpoints.end(); ++p)
{
- try
- {
- Ice::EndpointSeq single;
- single.push_back(*p);
- LookupPrxPtr l = lookup->ice_endpoints(single);
- l->ice_getConnection();
- _lookup.push_back(make_pair(l, LookupReplyPrxPtr()));
- }
- catch(const Ice::LocalException&)
- {
- }
+ Ice::EndpointSeq single;
+ single.push_back(*p);
+ _lookups.push_back(make_pair(lookup->ice_endpoints(single), LookupReplyPrxPtr()));
}
- assert(!_lookup.empty());
-#ifndef ICE_CPP11_MAPPING
- __setNoDelete(false);
-#endif
+ assert(!_lookups.empty());
}
void
@@ -603,7 +603,7 @@ LocatorI::setLookupReply(const LookupReplyPrxPtr& lookupReply)
//
// Use a lookup reply proxy whose adress matches the interface used to send multicast datagrams.
//
- for(vector<pair<LookupPrxPtr, LookupReplyPrxPtr> >::iterator p = _lookup.begin(); p != _lookup.end(); ++p)
+ for(vector<pair<LookupPrxPtr, LookupReplyPrxPtr> >::iterator p = _lookups.begin(); p != _lookups.end(); ++p)
{
Ice::UDPEndpointInfoPtr info = ICE_DYNAMIC_CAST(Ice::UDPEndpointInfo, p->first->ice_getEndpoints()[0]->getInfo());
if(info && !info->mcastInterface.empty())
@@ -636,7 +636,7 @@ LocatorI::ice_invokeAsync(pair<const Ice::Byte*, const Ice::Byte*> inParams,
const Ice::Current& current)
{
invoke(nullptr, make_shared<Request>(this, current.operation, current.mode, inParams, current.ctx,
- move(responseCB), move(exceptionCB)));
+ make_pair(move(responseCB), move(exceptionCB))));
}
#else
void
@@ -811,16 +811,29 @@ LocatorI::invoke(const Ice::LocatorPrxPtr& locator, const RequestPtr& request)
if(_pendingRetryCount == 0) // No request in progress
{
+ _failureCount = 0;
_pendingRetryCount = _retryCount;
try
{
- for(vector<pair<LookupPrxPtr, LookupReplyPrxPtr> >::const_iterator l = _lookup.begin();
- l != _lookup.end(); ++l)
+ for(vector<pair<LookupPrxPtr, LookupReplyPrxPtr> >::const_iterator l = _lookups.begin();
+ l != _lookups.end(); ++l)
{
#ifdef ICE_CPP11_MAPPING
- l->first->findLocatorAsync(_instanceName, l->second); // Send multicast request.
+ auto self = shared_from_this();
+ l->first->findLocatorAsync(_instanceName, l->second, nullptr, [self](exception_ptr ex)
+ {
+ try
+ {
+ rethrow_exception(ex);
+ }
+ catch(const Ice::LocalException& e)
+ {
+ self->exception(e);
+ }
+ });
#else
- l->first->begin_findLocator(_instanceName, l->second); // Send multicast request.
+ l->first->begin_findLocator(_instanceName, l->second, Ice::newCallback(new CallbackI(this),
+ &CallbackI::completed));
#endif
}
_timer->schedule(ICE_SHARED_FROM_THIS, _timeout);
@@ -839,6 +852,40 @@ LocatorI::invoke(const Ice::LocatorPrxPtr& locator, const RequestPtr& request)
}
void
+LocatorI::exception(const Ice::LocalException& ex)
+{
+ Lock sync(*this);
+ if(++_failureCount == _lookups.size() && _pendingRetryCount > 0)
+ {
+ //
+ // All the lookup calls failed, cancel the timer and propagate the error to the requests.
+ //
+ _timer->cancel(ICE_SHARED_FROM_THIS);
+ _pendingRetryCount = 0;
+
+ if(_warnOnce)
+ {
+ Ice::Warning warn(_lookup->ice_getCommunicator()->getLogger());
+ warn << "failed to lookup locator with lookup proxy `" << _lookup << "':\n" << ex;
+ _warnOnce = false;
+ }
+
+ if(_pendingRequests.empty())
+ {
+ notify();
+ }
+ else
+ {
+ for(vector<RequestPtr>::const_iterator p = _pendingRequests.begin(); p != _pendingRequests.end(); ++p)
+ {
+ (*p)->invoke(_voidLocator);
+ }
+ _pendingRequests.clear();
+ }
+ }
+}
+
+void
LocatorI::runTimerTask()
{
Lock sync(*this);
@@ -846,13 +893,26 @@ LocatorI::runTimerTask()
{
try
{
- for(vector<pair<LookupPrxPtr, LookupReplyPrxPtr> >::const_iterator l = _lookup.begin();
- l != _lookup.end(); ++l)
+ _failureCount = 0;
+ for(vector<pair<LookupPrxPtr, LookupReplyPrxPtr> >::const_iterator l = _lookups.begin();
+ l != _lookups.end(); ++l)
{
#ifdef ICE_CPP11_MAPPING
- l->first->findLocatorAsync(_instanceName, l->second); // Send multicast request.
+ auto self = shared_from_this();
+ l->first->findLocatorAsync(_instanceName, l->second, nullptr, [self](exception_ptr ex)
+ {
+ try
+ {
+ rethrow_exception(ex);
+ }
+ catch(const Ice::LocalException& e)
+ {
+ self->exception(e);
+ }
+ });
#else
- l->first->begin_findLocator(_instanceName, l->second); // Send multicast request.
+ l->first->begin_findLocator(_instanceName, l->second, Ice::newCallback(new CallbackI(this),
+ &CallbackI::completed));
#endif
}
_timer->schedule(ICE_SHARED_FROM_THIS, _timeout);
diff --git a/cpp/test/IceDiscovery/simple/AllTests.cpp b/cpp/test/IceDiscovery/simple/AllTests.cpp
index 6eb9913954f..cb2df00069e 100644
--- a/cpp/test/IceDiscovery/simple/AllTests.cpp
+++ b/cpp/test/IceDiscovery/simple/AllTests.cpp
@@ -197,6 +197,55 @@ allTests(const CommunicatorPtr& communicator, int num)
}
cout << "ok" << endl;
+ cout << "testing invalid lookup endpoints... " << flush;
+ {
+ string multicast;
+ if(communicator->getProperties()->getProperty("Ice.IPv6") == "1")
+ {
+ multicast = "\"ff15::1\"";
+ }
+ else
+ {
+ multicast = "239.255.0.1";
+ }
+
+ {
+
+ Ice::InitializationData initData;
+ initData.properties = communicator->getProperties()->clone();
+ initData.properties->setProperty("IceDiscovery.Lookup", "udp -h " + multicast + " --interface unknown");
+ Ice::CommunicatorPtr com = Ice::initialize(initData);
+ test(com->getDefaultLocator());
+ try
+ {
+ com->stringToProxy("controller0@control0")->ice_ping();
+ test(false);
+ }
+ catch(const Ice::LocalException&)
+ {
+ }
+ com->destroy();
+ }
+ {
+ Ice::InitializationData initData;
+ initData.properties = communicator->getProperties()->clone();
+ string intf = initData.properties->getProperty("IceDiscovery.Interface");
+ if(!intf.empty())
+ {
+ intf = " --interface \"" + intf + "\"";
+ }
+ string port = initData.properties->getProperty("IceDiscovery.Port");
+ initData.properties->setProperty("IceDiscovery.Lookup",
+ "udp -h " + multicast + " --interface unknown:" +
+ "udp -h " + multicast + " -p " + port + intf);
+ Ice::CommunicatorPtr com = Ice::initialize(initData);
+ test(com->getDefaultLocator());
+ com->stringToProxy("controller0@control0")->ice_ping();
+ com->destroy();
+ }
+ }
+ cout << "ok" << endl;
+
cout << "shutting down... " << flush;
for(vector<ControllerPrxPtr>::const_iterator p = proxies.begin(); p != proxies.end(); ++p)
{
diff --git a/cpp/test/IceGrid/simple/AllTests.cpp b/cpp/test/IceGrid/simple/AllTests.cpp
index 29f1e84974d..125216db7a9 100644
--- a/cpp/test/IceGrid/simple/AllTests.cpp
+++ b/cpp/test/IceGrid/simple/AllTests.cpp
@@ -20,19 +20,19 @@ void
allTests(const Ice::CommunicatorPtr& communicator)
{
cout << "testing stringToProxy... " << flush;
- Ice::ObjectPrx base = communicator->stringToProxy("test @ TestAdapter");
+ Ice::ObjectPrxPtr base = communicator->stringToProxy("test @ TestAdapter");
test(base);
cout << "ok" << endl;
cout << "testing IceGrid.Locator is present... " << flush;
- IceGrid::LocatorPrx locator = IceGrid::LocatorPrx::uncheckedCast(base);
+ IceGrid::LocatorPrxPtr locator = ICE_UNCHECKED_CAST(IceGrid::LocatorPrx, base);
test(locator);
cout << "ok" << endl;
cout << "testing checked cast... " << flush;
- TestIntfPrx obj = TestIntfPrx::checkedCast(base);
+ TestIntfPrxPtr obj = ICE_CHECKED_CAST(TestIntfPrx, base);
test(obj);
- test(obj == base);
+ test(Ice::targetEqualTo(obj, base));
cout << "ok" << endl;
cout << "pinging server... " << flush;
@@ -43,7 +43,7 @@ allTests(const Ice::CommunicatorPtr& communicator)
Ice::Identity finderId;
finderId.category = "Ice";
finderId.name = "LocatorFinder";
- Ice::LocatorFinderPrx finder = Ice::LocatorFinderPrx::checkedCast(
+ Ice::LocatorFinderPrxPtr finder = ICE_CHECKED_CAST(Ice::LocatorFinderPrx,
communicator->getDefaultLocator()->ice_identity(finderId));
test(finder->getLocator());
cout << "ok" << endl;
@@ -54,11 +54,11 @@ allTests(const Ice::CommunicatorPtr& communicator)
cout << "testing discovery... " << flush;
{
// Add test well-known object
- IceGrid::RegistryPrx registry = IceGrid::RegistryPrx::checkedCast(
+ IceGrid::RegistryPrxPtr registry = ICE_CHECKED_CAST(IceGrid::RegistryPrx,
communicator->stringToProxy(communicator->getDefaultLocator()->ice_getIdentity().category + "/Registry"));
test(registry);
- IceGrid::AdminSessionPrx session = registry->createAdminSession("foo", "bar");
+ IceGrid::AdminSessionPrxPtr session = registry->createAdminSession("foo", "bar");
session->getAdmin()->addObjectWithType(base, "::Test");
session->destroy();
@@ -71,11 +71,6 @@ allTests(const Ice::CommunicatorPtr& communicator)
initData.properties->setProperty("Ice.Default.Locator", "");
initData.properties->setProperty("Ice.Plugin.IceLocatorDiscovery",
"IceLocatorDiscovery:createIceLocatorDiscovery");
- {
- ostringstream port;
- port << getTestPort(initData.properties, 99);
- initData.properties->setProperty("IceLocatorDiscovery.Port", port.str());
- }
initData.properties->setProperty("AdapterForDiscoveryTest.AdapterId", "discoveryAdapter");
initData.properties->setProperty("AdapterForDiscoveryTest.Endpoints", "default");
@@ -85,9 +80,9 @@ allTests(const Ice::CommunicatorPtr& communicator)
com->stringToProxy("test @ TestAdapter")->ice_ping();
com->stringToProxy("test")->ice_ping();
test(com->getDefaultLocator()->getRegistry());
- test(IceGrid::LocatorPrx::checkedCast(com->getDefaultLocator()));
- test(IceGrid::LocatorPrx::uncheckedCast(com->getDefaultLocator())->getLocalRegistry());
- test(IceGrid::LocatorPrx::uncheckedCast(com->getDefaultLocator())->getLocalQuery());
+ test(ICE_CHECKED_CAST(IceGrid::LocatorPrx, com->getDefaultLocator()));
+ test(ICE_UNCHECKED_CAST(IceGrid::LocatorPrx, com->getDefaultLocator())->getLocalRegistry());
+ test(ICE_UNCHECKED_CAST(IceGrid::LocatorPrx, com->getDefaultLocator())->getLocalQuery());
Ice::ObjectAdapterPtr adapter = com->createObjectAdapter("AdapterForDiscoveryTest");
adapter->activate();
@@ -126,10 +121,10 @@ allTests(const Ice::CommunicatorPtr& communicator)
{
}
test(!com->getDefaultLocator()->getRegistry());
- test(!IceGrid::LocatorPrx::checkedCast(com->getDefaultLocator()));
+ test(!ICE_CHECKED_CAST(IceGrid::LocatorPrx, com->getDefaultLocator()));
try
{
- test(IceGrid::LocatorPrx::uncheckedCast(com->getDefaultLocator())->getLocalQuery());
+ test(ICE_UNCHECKED_CAST(IceGrid::LocatorPrx, com->getDefaultLocator())->getLocalQuery());
}
catch(const Ice::OperationNotExistException&)
{
@@ -140,6 +135,66 @@ allTests(const Ice::CommunicatorPtr& communicator)
adapter->deactivate();
com->destroy();
+
+ string multicast;
+ if(communicator->getProperties()->getProperty("Ice.IPv6") == "1")
+ {
+ multicast = "\"ff15::1\"";
+ }
+ else
+ {
+ multicast = "239.255.0.1";
+ }
+
+ //
+ // Test invalid lookup endpoints
+ //
+ initData.properties = communicator->getProperties()->clone();
+ initData.properties->setProperty("Ice.Default.Locator", "");
+ initData.properties->setProperty("Ice.Plugin.IceLocatorDiscovery",
+ "IceLocatorDiscovery:createIceLocatorDiscovery");
+ initData.properties->setProperty("IceLocatorDiscovery.Lookup",
+ "udp -h " + multicast + " --interface unknown");
+ com = Ice::initialize(initData);
+ test(com->getDefaultLocator());
+ try
+ {
+ com->stringToProxy("test @ TestAdapter")->ice_ping();
+ test(false);
+ }
+ catch(const Ice::NoEndpointException&)
+ {
+ }
+ com->destroy();
+
+
+ initData.properties = communicator->getProperties()->clone();
+ initData.properties->setProperty("Ice.Default.Locator", "");
+ initData.properties->setProperty("Ice.Plugin.IceLocatorDiscovery",
+ "IceLocatorDiscovery:createIceLocatorDiscovery");
+ {
+ string intf = initData.properties->getProperty("IceLocatorDiscovery.Interface");
+ if(!intf.empty())
+ {
+ intf = " --interface \"" + intf + "\"";
+ }
+ ostringstream port;
+ port << getTestPort(initData.properties, 99);
+ initData.properties->setProperty("IceLocatorDiscovery.Lookup",
+ "udp -h " + multicast + " --interface unknown:" +
+ "udp -h " + multicast + " -p " + port.str() + intf);
+ }
+ com = Ice::initialize(initData);
+ test(com->getDefaultLocator());
+ try
+ {
+ com->stringToProxy("test @ TestAdapter")->ice_ping();
+ }
+ catch(const Ice::NoEndpointException&)
+ {
+ test(false);
+ }
+ com->destroy();
}
cout << "ok" << endl;
}
@@ -157,19 +212,19 @@ void
allTestsWithDeploy(const Ice::CommunicatorPtr& communicator)
{
cout << "testing stringToProxy... " << flush;
- Ice::ObjectPrx base = communicator->stringToProxy("test @ TestAdapter");
+ Ice::ObjectPrxPtr base = communicator->stringToProxy("test @ TestAdapter");
test(base);
- Ice::ObjectPrx base2 = communicator->stringToProxy("test");
+ Ice::ObjectPrxPtr base2 = communicator->stringToProxy("test");
test(base2);
cout << "ok" << endl;
cout << "testing checked cast... " << flush;
- TestIntfPrx obj = TestIntfPrx::checkedCast(base);
+ TestIntfPrxPtr obj = ICE_CHECKED_CAST(TestIntfPrx, base);
test(obj);
- test(obj == base);
- TestIntfPrx obj2 = TestIntfPrx::checkedCast(base2);
+ test(Ice::targetEqualTo(obj, base));
+ TestIntfPrxPtr obj2 = ICE_CHECKED_CAST(TestIntfPrx, base2);
test(obj2);
- test(obj2 == base2);
+ test(Ice::targetEqualTo(obj2, base2));
cout << "ok" << endl;
cout << "pinging server... " << flush;
@@ -178,9 +233,9 @@ allTestsWithDeploy(const Ice::CommunicatorPtr& communicator)
cout << "ok" << endl;
cout << "testing encoding versioning... " << flush;
- Ice::ObjectPrx base10 = communicator->stringToProxy("test10 @ TestAdapter10");
+ Ice::ObjectPrxPtr base10 = communicator->stringToProxy("test10 @ TestAdapter10");
test(base10);
- Ice::ObjectPrx base102 = communicator->stringToProxy("test10");
+ Ice::ObjectPrxPtr base102 = communicator->stringToProxy("test10");
test(base102);
try
{
@@ -230,15 +285,15 @@ allTestsWithDeploy(const Ice::CommunicatorPtr& communicator)
}
cout << "ok" << endl;
- IceGrid::RegistryPrx registry = IceGrid::RegistryPrx::checkedCast(
+ IceGrid::RegistryPrxPtr registry = ICE_CHECKED_CAST(IceGrid::RegistryPrx,
communicator->stringToProxy(communicator->getDefaultLocator()->ice_getIdentity().category + "/Registry"));
test(registry);
- IceGrid::AdminSessionPrx session = registry->createAdminSession("foo", "bar");
+ IceGrid::AdminSessionPrxPtr session = registry->createAdminSession("foo", "bar");
session->ice_getConnection()->setACM(registry->getACMTimeout(), IceUtil::None, Ice::ICE_ENUM(ACMHeartbeat, HeartbeatAlways));
- IceGrid::AdminPrx admin = session->getAdmin();
+ IceGrid::AdminPrxPtr admin = session->getAdmin();
test(admin);
admin->enableServer("server", false);
@@ -247,7 +302,7 @@ allTestsWithDeploy(const Ice::CommunicatorPtr& communicator)
cout << "testing whether server is still reachable... " << flush;
try
{
- obj = TestIntfPrx::checkedCast(base);
+ obj = ICE_CHECKED_CAST(TestIntfPrx, base);
test(false);
}
catch(const Ice::NoEndpointException&)
@@ -255,7 +310,7 @@ allTestsWithDeploy(const Ice::CommunicatorPtr& communicator)
}
try
{
- obj2 = TestIntfPrx::checkedCast(base2);
+ obj2 = ICE_CHECKED_CAST(TestIntfPrx, base2);
test(false);
}
catch(const Ice::NoEndpointException&)
@@ -266,7 +321,7 @@ allTestsWithDeploy(const Ice::CommunicatorPtr& communicator)
try
{
- obj = TestIntfPrx::checkedCast(base);
+ obj = ICE_CHECKED_CAST(TestIntfPrx, base);
}
catch(const Ice::NoEndpointException&)
{
@@ -274,7 +329,7 @@ allTestsWithDeploy(const Ice::CommunicatorPtr& communicator)
}
try
{
- obj2 = TestIntfPrx::checkedCast(base2);
+ obj2 = ICE_CHECKED_CAST(TestIntfPrx, base2);
}
catch(const Ice::NoEndpointException&)
{
diff --git a/cpp/test/IceGrid/simple/Server.cpp b/cpp/test/IceGrid/simple/Server.cpp
index 57f57c582f9..c252fae2b7e 100644
--- a/cpp/test/IceGrid/simple/Server.cpp
+++ b/cpp/test/IceGrid/simple/Server.cpp
@@ -28,7 +28,7 @@ Server::run(int argc, char* argv[])
Ice::stringSeqToArgs(args, argc, argv);
Ice::ObjectAdapterPtr adapter = communicator()->createObjectAdapter("TestAdapter");
- Ice::ObjectPtr object = new TestI();
+ Ice::ObjectPtr object = ICE_MAKE_SHARED(TestI);
string id = communicator()->getProperties()->getPropertyWithDefault("Identity", "test");
adapter->add(object, Ice::stringToIdentity(id));
diff --git a/csharp/src/Ice/Network.cs b/csharp/src/Ice/Network.cs
index 7606f6f4a98..08ffc80a77b 100644
--- a/csharp/src/Ice/Network.cs
+++ b/csharp/src/Ice/Network.cs
@@ -445,7 +445,7 @@ namespace IceInternal
socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.MulticastInterface, ifaceIndex);
}
}
- catch(SocketException ex)
+ catch(Exception ex)
{
closeSocketNoThrow(socket);
throw new Ice.SocketException(ex);
diff --git a/csharp/src/IceDiscovery/LookupI.cs b/csharp/src/IceDiscovery/LookupI.cs
index 9c4abb2d8a1..1912505f2da 100644
--- a/csharp/src/IceDiscovery/LookupI.cs
+++ b/csharp/src/IceDiscovery/LookupI.cs
@@ -15,12 +15,12 @@ namespace IceDiscovery
using System.Text;
using System.Diagnostics;
- class Request<T>
+ abstract class Request<T>
{
protected Request(LookupI lookup, T id, int retryCount)
{
lookup_ = lookup;
- nRetry_ = retryCount;
+ retryCount_ = retryCount;
_id = id;
}
@@ -37,14 +37,40 @@ namespace IceDiscovery
public virtual bool retry()
{
- return --nRetry_ >= 0;
+ return --retryCount_ >= 0;
}
+ public void invoke(String domainId, Dictionary<LookupPrx, LookupReplyPrx> lookups)
+ {
+ _lookupCount = lookups.Count;
+ _failureCount = 0;
+ foreach(var entry in lookups)
+ {
+ invokeWithLookup(domainId, entry.Key, entry.Value);
+ }
+ }
+
+ public bool exception()
+ {
+ if(++_failureCount == _lookupCount)
+ {
+ finished(null);
+ return true;
+ }
+ return false;
+ }
+
+ abstract public void finished(Ice.ObjectPrx proxy);
+
+ abstract protected void invokeWithLookup(string domainId, LookupPrx lookup, LookupReplyPrx lookupReply);
+
protected LookupI lookup_;
- protected int nRetry_;
+ protected int retryCount_;
+ protected int _lookupCount;
+ protected int _failureCount;
protected List<TaskCompletionSource<Ice.ObjectPrx>> callbacks_ = new List<TaskCompletionSource<Ice.ObjectPrx>>();
- private T _id;
+ protected T _id;
};
class AdapterRequest : Request<string>, IceInternal.TimerTask
@@ -56,7 +82,7 @@ namespace IceDiscovery
public override bool retry()
{
- return _proxies.Count == 0 && --nRetry_ >= 0;
+ return _proxies.Count == 0 && --retryCount_ >= 0;
}
public bool response(Ice.ObjectPrx proxy, bool isReplicaGroup)
@@ -80,7 +106,7 @@ namespace IceDiscovery
return true;
}
- public void finished(Ice.ObjectPrx proxy)
+ public override void finished(Ice.ObjectPrx proxy)
{
if(proxy != null || _proxies.Count == 0)
{
@@ -111,6 +137,20 @@ namespace IceDiscovery
lookup_.adapterRequestTimedOut(this);
}
+ protected override void invokeWithLookup(string domainId, LookupPrx lookup, LookupReplyPrx lookupReply)
+ {
+ lookup.findAdapterByIdAsync(domainId, _id, lookupReply).ContinueWith(task => {
+ try
+ {
+ task.Wait();
+ }
+ catch(AggregateException ex)
+ {
+ lookup_.adapterRequestException(this, ex.InnerException);
+ }
+ });
+ }
+
private void sendResponse(Ice.ObjectPrx proxy)
{
foreach(var cb in callbacks_)
@@ -136,7 +176,7 @@ namespace IceDiscovery
finished(proxy);
}
- public void finished(Ice.ObjectPrx proxy)
+ public override void finished(Ice.ObjectPrx proxy)
{
foreach(var cb in callbacks_)
{
@@ -149,6 +189,20 @@ namespace IceDiscovery
{
lookup_.objectRequestTimedOut(this);
}
+
+ protected override void invokeWithLookup(string domainId, LookupPrx lookup, LookupReplyPrx lookupReply)
+ {
+ lookup.findObjectByIdAsync(domainId, _id, lookupReply).ContinueWith(task => {
+ try
+ {
+ task.Wait();
+ }
+ catch(AggregateException ex)
+ {
+ lookup_.objectRequestException(this, ex.InnerException);
+ }
+ });
+ }
};
class LookupI : LookupDisp_
@@ -156,27 +210,13 @@ namespace IceDiscovery
public LookupI(LocatorRegistryI registry, LookupPrx lookup, Ice.Properties properties)
{
_registry = registry;
+ _lookup = lookup;
_timeout = properties.getPropertyAsIntWithDefault("IceDiscovery.Timeout", 300);
_retryCount = properties.getPropertyAsIntWithDefault("IceDiscovery.RetryCount", 3);
_latencyMultiplier = properties.getPropertyAsIntWithDefault("IceDiscovery.LatencyMultiplier", 1);
_domainId = properties.getProperty("IceDiscovery.DomainId");
_timer = IceInternal.Util.getInstance(lookup.ice_getCommunicator()).timer();
- try
- {
- lookup.ice_getConnection();
- }
- catch(Ice.LocalException ex)
- {
- StringBuilder b = new StringBuilder();
- b.Append("IceDiscovery is unable to establish a multicast connection:\n");
- b.Append("proxy = ");
- b.Append(lookup.ToString());
- b.Append('\n');
- b.Append(ex.ToString());
- throw new Ice.PluginInitializationException(b.ToString());
- }
-
//
// Create one lookup proxy per endpoint from the given proxy. We want to send a multicast
// datagram on each endpoint.
@@ -184,19 +224,10 @@ namespace IceDiscovery
var single = new Ice.Endpoint[1];
foreach(var endpt in lookup.ice_getEndpoints())
{
- try
- {
- single[0] = endpt;
- LookupPrx l = (LookupPrx)lookup.ice_endpoints(single);
- l.ice_getConnection();
- _lookup[(LookupPrx)lookup.ice_endpoints(single)] = null;
- }
- catch(Ice.LocalException)
- {
- // Ignore
- }
+ single[0] = endpt;
+ _lookups[(LookupPrx)lookup.ice_endpoints(single)] = null;
}
- Debug.Assert(_lookup.Count > 0);
+ Debug.Assert(_lookups.Count > 0);
}
public void setLookupReply(LookupReplyPrx lookupReply)
@@ -205,7 +236,7 @@ namespace IceDiscovery
// Use a lookup reply proxy whose adress matches the interface used to send multicast datagrams.
//
var single = new Ice.Endpoint[1];
- foreach(var key in new List<LookupPrx>(_lookup.Keys))
+ foreach(var key in new List<LookupPrx>(_lookups.Keys))
{
var info = (Ice.UDPEndpointInfo)key.ice_getEndpoints()[0].getInfo();
if(info.mcastInterface.Length > 0)
@@ -216,15 +247,15 @@ namespace IceDiscovery
if(r is Ice.IPEndpointInfo && ((Ice.IPEndpointInfo)r).host.Equals(info.mcastInterface))
{
single[0] = q;
- _lookup[key] = (LookupReplyPrx)lookupReply.ice_endpoints(single);
+ _lookups[key] = (LookupReplyPrx)lookupReply.ice_endpoints(single);
}
}
}
- if(_lookup[key] == null)
+ if(_lookups[key] == null)
{
// Fallback: just use the given lookup reply proxy if no matching endpoint found.
- _lookup[key] = lookupReply;
+ _lookups[key] = lookupReply;
}
}
}
@@ -296,10 +327,7 @@ namespace IceDiscovery
{
try
{
- foreach(var l in _lookup)
- {
- l.Key.findObjectByIdAsync(_domainId, id, l.Value);
- }
+ request.invoke(_domainId, _lookups);
_timer.schedule(request, _timeout);
}
catch(Ice.LocalException)
@@ -328,10 +356,7 @@ namespace IceDiscovery
{
try
{
- foreach(var l in _lookup)
- {
- l.Key.findAdapterByIdAsync(_domainId, adapterId, l.Value);
- }
+ request.invoke(_domainId, _lookups);
_timer.schedule(request, _timeout);
}
catch(Ice.LocalException)
@@ -391,10 +416,7 @@ namespace IceDiscovery
{
try
{
- foreach(var l in _lookup)
- {
- l.Key.findObjectByIdAsync(_domainId, request.getId(), l.Value);
- }
+ request.invoke(_domainId, _lookups);
_timer.schedule(request, _timeout);
return;
}
@@ -409,6 +431,36 @@ namespace IceDiscovery
}
}
+ internal void objectRequestException(ObjectRequest request, Exception ex)
+ {
+ lock(this)
+ {
+ ObjectRequest r;
+ if(!_objectRequests.TryGetValue(request.getId(), out r) || r != request)
+ {
+ return;
+ }
+
+ if(request.exception())
+ {
+ if(_warnOnce)
+ {
+ StringBuilder s = new StringBuilder();
+ s.Append("failed to lookup object `");
+ s.Append(_lookup.ice_getCommunicator().identityToString(request.getId()));
+ s.Append("' with lookup proxy `");
+ s.Append(_lookup);
+ s.Append("':\n");
+ s.Append(ex.ToString());
+ _lookup.ice_getCommunicator().getLogger().warning(s.ToString());
+ _warnOnce = false;
+ }
+ _timer.cancel(request);
+ _objectRequests.Remove(request.getId());
+ }
+ }
+ }
+
internal void adapterRequestTimedOut(AdapterRequest request)
{
lock(this)
@@ -423,10 +475,7 @@ namespace IceDiscovery
{
try
{
- foreach(var l in _lookup)
- {
- l.Key.findAdapterByIdAsync(_domainId, request.getId(), l.Value);
- }
+ request.invoke(_domainId, _lookups);
_timer.schedule(request, _timeout);
return;
}
@@ -441,6 +490,36 @@ namespace IceDiscovery
}
}
+ internal void adapterRequestException(AdapterRequest request, Exception ex)
+ {
+ lock(this)
+ {
+ AdapterRequest r;
+ if(!_adapterRequests.TryGetValue(request.getId(), out r) || r != request)
+ {
+ return;
+ }
+
+ if(request.exception())
+ {
+ if(_warnOnce)
+ {
+ StringBuilder s = new StringBuilder();
+ s.Append("failed to lookup adapter `");
+ s.Append(request.getId());
+ s.Append("' with lookup proxy `");
+ s.Append(_lookup);
+ s.Append("':\n");
+ s.Append(ex.ToString());
+ _lookup.ice_getCommunicator().getLogger().warning(s.ToString());
+ _warnOnce = false;
+ }
+ _timer.cancel(request);
+ _adapterRequests.Remove(request.getId());
+ }
+ }
+ }
+
internal IceInternal.Timer timer()
{
return _timer;
@@ -452,14 +531,15 @@ namespace IceDiscovery
}
private LocatorRegistryI _registry;
- private Dictionary<LookupPrx, LookupReplyPrx> _lookup = new Dictionary<LookupPrx, LookupReplyPrx>();
+ private LookupPrx _lookup;
+ private Dictionary<LookupPrx, LookupReplyPrx> _lookups = new Dictionary<LookupPrx, LookupReplyPrx>();
private readonly int _timeout;
private readonly int _retryCount;
private readonly int _latencyMultiplier;
private readonly string _domainId;
private IceInternal.Timer _timer;
-
+ private bool _warnOnce = true;
private Dictionary<Ice.Identity, ObjectRequest> _objectRequests = new Dictionary<Ice.Identity, ObjectRequest>();
private Dictionary<string, AdapterRequest> _adapterRequests = new Dictionary<string, AdapterRequest>();
};
diff --git a/csharp/src/IceLocatorDiscovery/PluginI.cs b/csharp/src/IceLocatorDiscovery/PluginI.cs
index 2a55fe8d4cc..0a91aec1c41 100644
--- a/csharp/src/IceLocatorDiscovery/PluginI.cs
+++ b/csharp/src/IceLocatorDiscovery/PluginI.cs
@@ -142,6 +142,7 @@ namespace IceLocatorDiscovery
LocatorI(string name, LookupPrx lookup, Ice.Properties properties, string instanceName,
Ice.LocatorPrx voidLocator)
{
+ _lookup = lookup;
_timeout = properties.getPropertyAsIntWithDefault(name + ".Timeout", 300);
_retryCount = properties.getPropertyAsIntWithDefault(name + ".RetryCount", 3);
_retryDelay = properties.getPropertyAsIntWithDefault(name + ".RetryDelay", 2000);
@@ -151,21 +152,8 @@ namespace IceLocatorDiscovery
_locator = lookup.ice_getCommunicator().getDefaultLocator();
_voidLocator = voidLocator;
_pendingRetryCount = 0;
-
- try
- {
- lookup.ice_getConnection();
- }
- catch(Ice.LocalException ex)
- {
- StringBuilder b = new StringBuilder();
- b.Append("IceLocatorDiscovery is unable to establish a multicast connection:\n");
- b.Append("proxy = ");
- b.Append(lookup.ToString());
- b.Append('\n');
- b.Append(ex.ToString());
- throw new Ice.PluginInitializationException(b.ToString());
- }
+ _failureCount = 0;
+ _warnOnce = true;
//
// Create one lookup proxy per endpoint from the given proxy. We want to send a multicast
@@ -174,19 +162,10 @@ namespace IceLocatorDiscovery
var single = new Ice.Endpoint[1];
foreach(var endpt in lookup.ice_getEndpoints())
{
- try
- {
- single[0] = endpt;
- LookupPrx l = (LookupPrx)lookup.ice_endpoints(single);
- l.ice_getConnection();
- _lookup[(LookupPrx)lookup.ice_endpoints(single)] = null;
- }
- catch(Ice.LocalException)
- {
- // Ignore
- }
+ single[0] = endpt;
+ _lookups[(LookupPrx)lookup.ice_endpoints(single)] = null;
}
- Debug.Assert(_lookup.Count > 0);
+ Debug.Assert(_lookups.Count > 0);
}
public void
@@ -196,7 +175,7 @@ namespace IceLocatorDiscovery
// Use a lookup reply proxy whose adress matches the interface used to send multicast datagrams.
//
var single = new Ice.Endpoint[1];
- foreach(var key in new List<LookupPrx>(_lookup.Keys))
+ foreach(var key in new List<LookupPrx>(_lookups.Keys))
{
var info = (Ice.UDPEndpointInfo)key.ice_getEndpoints()[0].getInfo();
if(info.mcastInterface.Length > 0)
@@ -207,15 +186,15 @@ namespace IceLocatorDiscovery
if(r is Ice.IPEndpointInfo && ((Ice.IPEndpointInfo)r).host.Equals(info.mcastInterface))
{
single[0] = q;
- _lookup[key] = (LookupReplyPrx)lookupReply.ice_endpoints(single);
+ _lookups[key] = (LookupReplyPrx)lookupReply.ice_endpoints(single);
}
}
}
- if(_lookup[key] == null)
+ if(_lookups[key] == null)
{
// Fallback: just use the given lookup reply proxy if no matching endpoint found.
- _lookup[key] = lookupReply;
+ _lookups[key] = lookupReply;
}
}
}
@@ -406,11 +385,21 @@ namespace IceLocatorDiscovery
if(_pendingRetryCount == 0) // No request in progress
{
_pendingRetryCount = _retryCount;
+ _failureCount = 0;
try
{
- foreach(var l in _lookup)
+ foreach(var l in _lookups)
{
- l.Key.findLocatorAsync(_instanceName, l.Value); // Send multicast request.
+ l.Key.findLocatorAsync(_instanceName, l.Value).ContinueWith(t => {
+ try
+ {
+ t.Wait();
+ }
+ catch(AggregateException ex)
+ {
+ exception(ex.InnerException);
+ }
+ }); // Send multicast request.
}
_timer.schedule(this, _timeout);
}
@@ -428,8 +417,47 @@ namespace IceLocatorDiscovery
}
}
- public void
- runTimerTask()
+ void exception(Exception ex)
+ {
+ lock(this)
+ {
+ if(++_failureCount == _lookups.Count && _pendingRetryCount > 0)
+ {
+ //
+ // All the lookup calls failed, cancel the timer and propagate the error to the requests.
+ //
+ _timer.cancel(this);
+
+ _pendingRetryCount = 0;
+
+ if(_warnOnce)
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.Append("failed to lookup locator with lookup proxy `");
+ builder.Append(_lookup);
+ builder.Append("':\n");
+ builder.Append(ex);
+ _lookup.ice_getCommunicator().getLogger().warning(builder.ToString());
+ _warnOnce = false;
+ }
+
+ if(_pendingRequests.Count == 0)
+ {
+ Monitor.Pulse(this);
+ }
+ else
+ {
+ foreach(Request req in _pendingRequests)
+ {
+ req.invoke(_voidLocator);
+ }
+ _pendingRequests.Clear();
+ }
+ }
+ }
+ }
+
+ public void runTimerTask()
{
lock(this)
{
@@ -437,7 +465,7 @@ namespace IceLocatorDiscovery
{
try
{
- foreach(var l in _lookup)
+ foreach(var l in _lookups)
{
l.Key.findLocatorAsync(_instanceName, l.Value); // Send multicast request
}
@@ -459,7 +487,8 @@ namespace IceLocatorDiscovery
}
}
- private Dictionary<LookupPrx, LookupReplyPrx> _lookup = new Dictionary<LookupPrx, LookupReplyPrx>();
+ private LookupPrx _lookup;
+ private Dictionary<LookupPrx, LookupReplyPrx> _lookups = new Dictionary<LookupPrx, LookupReplyPrx>();
private int _timeout;
private IceInternal.Timer _timer;
private int _retryCount;
@@ -472,6 +501,8 @@ namespace IceLocatorDiscovery
private Dictionary<string, Ice.LocatorPrx> _locators = new Dictionary<string, Ice.LocatorPrx>();
private int _pendingRetryCount;
+ private int _failureCount;
+ private bool _warnOnce = true;
private List<Request> _pendingRequests = new List<Request>();
private long _nextRetry;
};
diff --git a/csharp/test/IceDiscovery/simple/AllTests.cs b/csharp/test/IceDiscovery/simple/AllTests.cs
index 24060e86db3..dc8d867993f 100644
--- a/csharp/test/IceDiscovery/simple/AllTests.cs
+++ b/csharp/test/IceDiscovery/simple/AllTests.cs
@@ -198,6 +198,55 @@ public class AllTests : TestCommon.AllTests
}
WriteLine("ok");
+ Write("testing invalid lookup endpoints... ");
+ Flush();
+ {
+ String multicast;
+ if(communicator.getProperties().getProperty("Ice.IPv6").Equals("1"))
+ {
+ multicast = "\"ff15::1\"";
+ }
+ else
+ {
+ multicast = "239.255.0.1";
+ }
+
+ {
+ Ice.InitializationData initData = new Ice.InitializationData();
+ initData.properties = communicator.getProperties().ice_clone_();
+ initData.properties.setProperty("IceDiscovery.Lookup", "udp -h " + multicast + " --interface unknown");
+ Ice.Communicator comm = Ice.Util.initialize(initData);
+ test(comm.getDefaultLocator() != null);
+ try
+ {
+ comm.stringToProxy("controller0@control0").ice_ping();
+ test(false);
+ }
+ catch(Ice.LocalException)
+ {
+ }
+ comm.destroy();
+ }
+ {
+ Ice.InitializationData initData = new Ice.InitializationData();
+ initData.properties = communicator.getProperties().ice_clone_();
+ string intf = initData.properties.getProperty("IceDiscovery.Interface");
+ if(!intf.Equals(""))
+ {
+ intf = " --interface \"" + intf + "\"";
+ }
+ string port = initData.properties.getProperty("IceDiscovery.Port");
+ initData.properties.setProperty("IceDiscovery.Lookup",
+ "udp -h " + multicast + " --interface unknown:" +
+ "udp -h " + multicast + " -p " + port + intf);
+ Ice.Communicator comm = Ice.Util.initialize(initData);
+ test(comm.getDefaultLocator() != null);
+ comm.stringToProxy("controller0@control0").ice_ping();
+ comm.destroy();
+ }
+ }
+ WriteLine("ok");
+
Write("shutting down... ");
Flush();
foreach(ControllerPrx prx in proxies)
diff --git a/csharp/test/IceGrid/simple/AllTests.cs b/csharp/test/IceGrid/simple/AllTests.cs
index 4e618c9cde8..e002bb1c331 100644
--- a/csharp/test/IceGrid/simple/AllTests.cs
+++ b/csharp/test/IceGrid/simple/AllTests.cs
@@ -131,6 +131,64 @@ public class AllTests : TestCommon.AllTests
adapter.deactivate();
com.destroy();
+
+ string multicast;
+ if(communicator.getProperties().getProperty("Ice.IPv6").Equals("1"))
+ {
+ multicast = "\"ff15::1\"";
+ }
+ else
+ {
+ multicast = "239.255.0.1";
+ }
+
+ //
+ // Test invalid lookup endpoints
+ //
+ initData.properties = communicator.getProperties().ice_clone_();
+ initData.properties.setProperty("Ice.Default.Locator", "");
+ initData.properties.setProperty("Ice.Plugin.IceLocatorDiscovery",
+ "IceLocatorDiscovery:IceLocatorDiscovery.PluginFactory");
+ initData.properties.setProperty("IceLocatorDiscovery.Lookup",
+ "udp -h " + multicast + " --interface unknown");
+ com = Ice.Util.initialize(initData);
+ test(com.getDefaultLocator() != null);
+ try
+ {
+ com.stringToProxy("test @ TestAdapter").ice_ping();
+ test(false);
+ }
+ catch(Ice.NoEndpointException)
+ {
+ }
+ com.destroy();
+
+ initData.properties = communicator.getProperties().ice_clone_();
+ initData.properties.setProperty("Ice.Default.Locator", "");
+ initData.properties.setProperty("Ice.Plugin.IceLocatorDiscovery",
+ "IceLocatorDiscovery:IceLocatorDiscovery.PluginFactory");
+ {
+ string intf = initData.properties.getProperty("IceLocatorDiscovery.Interface");
+ if(!intf.Equals(""))
+ {
+ intf = " --interface \"" + intf + "\"";
+ }
+ string port = app.getTestPort(99).ToString();
+ initData.properties.setProperty("IceLocatorDiscovery.Lookup",
+ "udp -h " + multicast + " --interface unknown:" +
+ "udp -h " + multicast + " -p " + port + intf);
+ }
+ com = Ice.Util.initialize(initData);
+ test(com.getDefaultLocator() != null);
+ try
+ {
+ com.stringToProxy("test @ TestAdapter").ice_ping();
+ }
+ catch(Ice.NoEndpointException)
+ {
+ test(false);
+ }
+ com.destroy();
}
Console.Out.WriteLine("ok");
diff --git a/java-compat/src/IceDiscovery/src/main/java/IceDiscovery/LookupI.java b/java-compat/src/IceDiscovery/src/main/java/IceDiscovery/LookupI.java
index ca6407aff70..e5a35ee7bfd 100644
--- a/java-compat/src/IceDiscovery/src/main/java/IceDiscovery/LookupI.java
+++ b/java-compat/src/IceDiscovery/src/main/java/IceDiscovery/LookupI.java
@@ -21,7 +21,7 @@ class LookupI extends _LookupDisp
Request(T id, int retryCount)
{
_id = id;
- _nRetry = retryCount;
+ _retryCount = retryCount;
}
T
@@ -40,7 +40,29 @@ class LookupI extends _LookupDisp
boolean
retry()
{
- return --_nRetry >= 0;
+ return --_retryCount >= 0;
+ }
+
+ void
+ invoke(String domainId, Map<LookupPrx, LookupReplyPrx> lookups)
+ {
+ _lookupCount = lookups.size();
+ _failureCount = 0;
+ for(Map.Entry<LookupPrx, LookupReplyPrx> entry : lookups.entrySet())
+ {
+ invokeWithLookup(domainId, entry.getKey(), entry.getValue());
+ }
+ }
+
+ boolean
+ exception()
+ {
+ if(++_failureCount == _lookupCount)
+ {
+ finished(null);
+ return true;
+ }
+ return false;
}
void
@@ -57,9 +79,15 @@ class LookupI extends _LookupDisp
_future = null;
}
- protected int _nRetry;
+ abstract void finished(Ice.ObjectPrx proxy);
+
+ abstract protected void invokeWithLookup(String domainId, LookupPrx lookup, LookupReplyPrx lookupReply);
+
+ protected int _retryCount;
+ protected int _lookupCount;
+ protected int _failureCount;
protected List<AmdCB> _callbacks = new ArrayList<AmdCB>();
- private T _id;
+ protected T _id;
protected java.util.concurrent.Future<?> _future;
};
@@ -76,7 +104,7 @@ class LookupI extends _LookupDisp
boolean
retry()
{
- return _proxies.size() == 0 && --_nRetry >= 0;
+ return _proxies.size() == 0 && --_retryCount >= 0;
}
boolean
@@ -101,6 +129,7 @@ class LookupI extends _LookupDisp
return true;
}
+ @Override
void
finished(Ice.ObjectPrx proxy)
{
@@ -135,6 +164,28 @@ class LookupI extends _LookupDisp
adapterRequestTimedOut(this);
}
+ @Override
+ protected void
+ invokeWithLookup(String domainId, LookupPrx lookup, LookupReplyPrx lookupReply)
+ {
+ lookup.begin_findAdapterById(domainId, _id, lookupReply, new Ice.Callback()
+ {
+ @Override
+ public void
+ completed(Ice.AsyncResult r)
+ {
+ try
+ {
+ r.throwLocalException();
+ }
+ catch(Ice.LocalException ex)
+ {
+ adapterRequestException(AdapterRequest.this, ex);
+ }
+ }
+ });
+ }
+
private void
sendResponse(Ice.ObjectPrx proxy)
{
@@ -163,6 +214,7 @@ class LookupI extends _LookupDisp
finished(proxy);
}
+ @Override
void
finished(Ice.ObjectPrx proxy)
{
@@ -179,32 +231,40 @@ class LookupI extends _LookupDisp
{
objectRequestTimedOut(this);
}
+
+ @Override
+ protected void
+ invokeWithLookup(String domainId, LookupPrx lookup, LookupReplyPrx lookupReply)
+ {
+ lookup.begin_findObjectById(domainId, _id, lookupReply, new Ice.Callback()
+ {
+ @Override
+ public void
+ completed(Ice.AsyncResult r)
+ {
+ try
+ {
+ r.throwLocalException();
+ }
+ catch(Ice.LocalException ex)
+ {
+ objectRequestException(ObjectRequest.this, ex);
+ }
+ }
+ });
+ }
};
public LookupI(LocatorRegistryI registry, LookupPrx lookup, Ice.Properties properties)
{
_registry = registry;
+ _lookup = lookup;
_timeout = properties.getPropertyAsIntWithDefault("IceDiscovery.Timeout", 300);
_retryCount = properties.getPropertyAsIntWithDefault("IceDiscovery.RetryCount", 3);
_latencyMultiplier = properties.getPropertyAsIntWithDefault("IceDiscovery.LatencyMultiplier", 1);
_domainId = properties.getProperty("IceDiscovery.DomainId");
_timer = IceInternal.Util.getInstance(lookup.ice_getCommunicator()).timer();
- try
- {
- lookup.ice_getConnection();
- }
- catch(Ice.LocalException ex)
- {
- StringBuilder b = new StringBuilder();
- b.append("IceDiscovery is unable to establish a multicast connection:\n");
- b.append("proxy = ");
- b.append(lookup.toString());
- b.append('\n');
- b.append(ex.toString());
- throw new Ice.PluginInitializationException(b.toString());
- }
-
//
// Create one lookup proxy per endpoint from the given proxy. We want to send a multicast
// datagram on each endpoint.
@@ -212,18 +272,10 @@ class LookupI extends _LookupDisp
Ice.Endpoint[] single = new Ice.Endpoint[1];
for(Ice.Endpoint endpt : lookup.ice_getEndpoints())
{
- try
- {
- single[0] = endpt;
- LookupPrx l = (LookupPrx)lookup.ice_endpoints(single);
- l.ice_getConnection();
- _lookup.put(l, null);
- }
- catch(Ice.LocalException ex)
- {
- }
+ single[0] = endpt;
+ _lookups.put((LookupPrx)lookup.ice_endpoints(single), null);
}
- assert(!_lookup.isEmpty());
+ assert(!_lookups.isEmpty());
}
void
@@ -233,7 +285,7 @@ class LookupI extends _LookupDisp
// Use a lookup reply proxy whose adress matches the interface used to send multicast datagrams.
//
Ice.Endpoint[] single = new Ice.Endpoint[1];
- for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookup.entrySet())
+ for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookups.entrySet())
{
Ice.UDPEndpointInfo info = (Ice.UDPEndpointInfo)entry.getKey().ice_getEndpoints()[0].getInfo();
if(!info.mcastInterface.isEmpty())
@@ -324,10 +376,7 @@ class LookupI extends _LookupDisp
{
try
{
- for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookup.entrySet())
- {
- entry.getKey().begin_findObjectById(_domainId, id, entry.getValue());
- }
+ request.invoke(_domainId, _lookups);
request.scheduleTimer(_timeout);
}
catch(Ice.LocalException ex)
@@ -352,10 +401,7 @@ class LookupI extends _LookupDisp
{
try
{
- for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookup.entrySet())
- {
- entry.getKey().begin_findAdapterById(_domainId, adapterId, entry.getValue());
- }
+ request.invoke(_domainId, _lookups);
request.scheduleTimer(_timeout);
}
catch(Ice.LocalException ex)
@@ -409,10 +455,7 @@ class LookupI extends _LookupDisp
{
try
{
- for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookup.entrySet())
- {
- entry.getKey().begin_findObjectById(_domainId, request.getId(), entry.getValue());
- }
+ request.invoke(_domainId, _lookups);
request.scheduleTimer(_timeout);
return;
}
@@ -426,6 +469,34 @@ class LookupI extends _LookupDisp
}
synchronized void
+ objectRequestException(ObjectRequest request, Ice.LocalException ex)
+ {
+ ObjectRequest r = _objectRequests.get(request.getId());
+ if(r == null || r != request)
+ {
+ return;
+ }
+
+ if(request.exception())
+ {
+ if(_warnOnce)
+ {
+ StringBuilder s = new StringBuilder();
+ s.append("failed to lookup object `");
+ s.append(_lookup.ice_getCommunicator().identityToString(request.getId()));
+ s.append("' with lookup proxy `");
+ s.append(_lookup);
+ s.append("':\n");
+ s.append(ex.toString());
+ _lookup.ice_getCommunicator().getLogger().warning(s.toString());
+ _warnOnce = false;
+ }
+ request.cancelTimer();
+ _objectRequests.remove(request.getId());
+ }
+ }
+
+ synchronized void
adapterRequestTimedOut(AdapterRequest request)
{
AdapterRequest r = _adapterRequests.get(request.getId());
@@ -438,10 +509,7 @@ class LookupI extends _LookupDisp
{
try
{
- for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookup.entrySet())
- {
- entry.getKey().begin_findAdapterById(_domainId, request.getId(), entry.getValue());
- }
+ request.invoke(_domainId, _lookups);
request.scheduleTimer(_timeout);
return;
}
@@ -454,14 +522,43 @@ class LookupI extends _LookupDisp
_adapterRequests.remove(request.getId());
}
+ synchronized void
+ adapterRequestException(AdapterRequest request, Ice.LocalException ex)
+ {
+ AdapterRequest r = _adapterRequests.get(request.getId());
+ if(r == null || r != request)
+ {
+ return;
+ }
+
+ if(request.exception())
+ {
+ if(_warnOnce)
+ {
+ StringBuilder s = new StringBuilder();
+ s.append("failed to lookup adapter `");
+ s.append(request.getId());
+ s.append("' with lookup proxy `");
+ s.append(_lookup);
+ s.append("':\n");
+ s.append(ex.toString());
+ _lookup.ice_getCommunicator().getLogger().warning(s.toString());
+ _warnOnce = false;
+ }
+ request.cancelTimer();
+ _adapterRequests.remove(request.getId());
+ }
+ }
+
private LocatorRegistryI _registry;
- private java.util.Map<LookupPrx, LookupReplyPrx> _lookup = new java.util.HashMap<>();
+ private LookupPrx _lookup;
+ private java.util.Map<LookupPrx, LookupReplyPrx> _lookups = new java.util.HashMap<>();
private final int _timeout;
private final int _retryCount;
private final int _latencyMultiplier;
private final String _domainId;
-
private final java.util.concurrent.ScheduledExecutorService _timer;
+ private boolean _warnOnce = true;
private Map<Ice.Identity, ObjectRequest> _objectRequests = new HashMap<Ice.Identity, ObjectRequest>();
private Map<String, AdapterRequest> _adapterRequests = new HashMap<String, AdapterRequest>();
diff --git a/java-compat/src/IceLocatorDiscovery/src/main/java/IceLocatorDiscovery/PluginI.java b/java-compat/src/IceLocatorDiscovery/src/main/java/IceLocatorDiscovery/PluginI.java
index 2b49d63747d..571a840c975 100644
--- a/java-compat/src/IceLocatorDiscovery/src/main/java/IceLocatorDiscovery/PluginI.java
+++ b/java-compat/src/IceLocatorDiscovery/src/main/java/IceLocatorDiscovery/PluginI.java
@@ -145,6 +145,7 @@ class PluginI implements Plugin
LocatorI(String name, LookupPrx lookup, Ice.Properties properties, String instanceName,
Ice.LocatorPrx voidLocator)
{
+ _lookup = lookup;
_timeout = properties.getPropertyAsIntWithDefault(name + ".Timeout", 300);
_retryCount = properties.getPropertyAsIntWithDefault(name + ".RetryCount", 3);
_retryDelay = properties.getPropertyAsIntWithDefault(name + ".RetryDelay", 2000);
@@ -154,21 +155,8 @@ class PluginI implements Plugin
_locator = lookup.ice_getCommunicator().getDefaultLocator();
_voidLocator = voidLocator;
_pendingRetryCount = 0;
-
- try
- {
- lookup.ice_getConnection();
- }
- catch(Ice.LocalException ex)
- {
- StringBuilder b = new StringBuilder();
- b.append("IceDiscovery is unable to establish a multicast connection:\n");
- b.append("proxy = ");
- b.append(lookup.toString());
- b.append('\n');
- b.append(ex.toString());
- throw new Ice.PluginInitializationException(b.toString());
- }
+ _failureCount = 0;
+ _warnOnce = true;
//
// Create one lookup proxy per endpoint from the given proxy. We want to send a multicast
@@ -177,18 +165,10 @@ class PluginI implements Plugin
Ice.Endpoint[] single = new Ice.Endpoint[1];
for(Ice.Endpoint endpt : lookup.ice_getEndpoints())
{
- try
- {
- single[0] = endpt;
- LookupPrx l = (LookupPrx)lookup.ice_endpoints(single);
- l.ice_getConnection();
- _lookup.put(l, null);
- }
- catch(Ice.LocalException ex)
- {
- }
+ single[0] = endpt;
+ _lookups.put((LookupPrx)lookup.ice_endpoints(single), null);
}
- assert(!_lookup.isEmpty());
+ assert(!_lookups.isEmpty());
}
public void
@@ -198,7 +178,7 @@ class PluginI implements Plugin
// Use a lookup reply proxy whose adress matches the interface used to send multicast datagrams.
//
Ice.Endpoint[] single = new Ice.Endpoint[1];
- for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookup.entrySet())
+ for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookups.entrySet())
{
Ice.UDPEndpointInfo info = (Ice.UDPEndpointInfo)entry.getKey().ice_getEndpoints()[0].getInfo();
if(!info.mcastInterface.isEmpty())
@@ -401,11 +381,26 @@ class PluginI implements Plugin
if(_pendingRetryCount == 0) // No request in progress
{
_pendingRetryCount = _retryCount;
+ _failureCount = 0;
try
{
- for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookup.entrySet())
+ for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookups.entrySet())
{
- entry.getKey().begin_findLocator(_instanceName, entry.getValue()); // Send multicast request
+ entry.getKey().begin_findLocator(_instanceName, entry.getValue(), new Ice.Callback() {
+ @Override
+ public void
+ completed(Ice.AsyncResult r)
+ {
+ try
+ {
+ r.throwLocalException();
+ }
+ catch(Ice.LocalException ex)
+ {
+ exception(ex);
+ }
+ }
+ }); // Send multicast request
}
_future = _timer.schedule(_retryTask, _timeout, java.util.concurrent.TimeUnit.MILLISECONDS);
}
@@ -422,6 +417,45 @@ class PluginI implements Plugin
}
}
+ synchronized void
+ exception(Ice.LocalException ex)
+ {
+ if(++_failureCount == _lookups.size() && _pendingRetryCount > 0)
+ {
+ //
+ // All the lookup calls failed, cancel the timer and propagate the error to the requests.
+ //
+ _future.cancel(false);
+ _future = null;
+
+ _pendingRetryCount = 0;
+
+ if(_warnOnce)
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.append("failed to lookup locator with lookup proxy `");
+ builder.append(_lookup);
+ builder.append("':\n");
+ builder.append(ex);
+ _lookup.ice_getCommunicator().getLogger().warning(builder.toString());
+ _warnOnce = false;
+ }
+
+ if(_pendingRequests.isEmpty())
+ {
+ notify();
+ }
+ else
+ {
+ for(Request req : _pendingRequests)
+ {
+ req.invoke(_voidLocator);
+ }
+ _pendingRequests.clear();
+ }
+ }
+ }
+
private Runnable _retryTask = new Runnable()
{
@Override
@@ -433,9 +467,24 @@ class PluginI implements Plugin
{
try
{
- for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookup.entrySet())
+ _failureCount = 0;
+ for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookups.entrySet())
{
- entry.getKey().begin_findLocator(_instanceName, entry.getValue()); // Send multicast request
+ entry.getKey().begin_findLocator(_instanceName, entry.getValue(), new Ice.Callback() {
+ @Override
+ public void
+ completed(Ice.AsyncResult r)
+ {
+ try
+ {
+ r.throwLocalException();
+ }
+ catch(Ice.LocalException ex)
+ {
+ exception(ex);
+ }
+ }
+ }); // Send multicast request
}
_future = _timer.schedule(_retryTask, _timeout, java.util.concurrent.TimeUnit.MILLISECONDS);
return;
@@ -446,18 +495,26 @@ class PluginI implements Plugin
_pendingRetryCount = 0;
}
- for(Request req : _pendingRequests)
+ if(_pendingRequests.isEmpty())
{
- req.invoke(_voidLocator);
+ notify();
+ }
+ else
+ {
+ for(Request req : _pendingRequests)
+ {
+ req.invoke(_voidLocator);
+ }
+ _pendingRequests.clear();
}
- _pendingRequests.clear();
_nextRetry = IceInternal.Time.currentMonotonicTimeMillis() + _retryDelay;
}
}
};
- private final java.util.Map<LookupPrx, LookupReplyPrx> _lookup = new java.util.HashMap<>();
+ private final LookupPrx _lookup;
+ private final java.util.Map<LookupPrx, LookupReplyPrx> _lookups = new java.util.HashMap<>();
private final int _timeout;
private java.util.concurrent.Future<?> _future;
private final java.util.concurrent.ScheduledExecutorService _timer;
@@ -471,6 +528,8 @@ class PluginI implements Plugin
private Map<String, Ice.LocatorPrx> _locators = new java.util.HashMap<>();
private int _pendingRetryCount;
+ private int _failureCount;
+ private boolean _warnOnce;
private List<Request> _pendingRequests = new ArrayList<Request>();
private long _nextRetry;
};
diff --git a/java-compat/test/src/main/java/test/IceDiscovery/simple/AllTests.java b/java-compat/test/src/main/java/test/IceDiscovery/simple/AllTests.java
index 09a90399143..8dbe01b7d1e 100644
--- a/java-compat/test/src/main/java/test/IceDiscovery/simple/AllTests.java
+++ b/java-compat/test/src/main/java/test/IceDiscovery/simple/AllTests.java
@@ -212,6 +212,56 @@ public class AllTests
}
System.out.println("ok");
+ System.out.print("testing invalid lookup endpoints... ");
+ System.out.flush();
+ {
+ String multicast;
+ if(communicator.getProperties().getProperty("Ice.IPv6").equals("1"))
+ {
+ multicast = "\"ff15::1\"";
+ }
+ else
+ {
+ multicast = "239.255.0.1";
+ }
+
+ {
+
+ Ice.InitializationData initData = new Ice.InitializationData();
+ initData.properties = communicator.getProperties()._clone();
+ initData.properties.setProperty("IceDiscovery.Lookup", "udp -h " + multicast + " --interface unknown");
+ Ice.Communicator com = Ice.Util.initialize(initData);
+ test(com.getDefaultLocator() != null);
+ try
+ {
+ com.stringToProxy("controller0@control0").ice_ping();
+ test(false);
+ }
+ catch(Ice.LocalException ex)
+ {
+ }
+ com.destroy();
+ }
+ {
+ Ice.InitializationData initData = new Ice.InitializationData();
+ initData.properties = communicator.getProperties()._clone();
+ String intf = initData.properties.getProperty("IceDiscovery.Interface");
+ if(!intf.isEmpty())
+ {
+ intf = " --interface \"" + intf + "\"";
+ }
+ String port = initData.properties.getProperty("IceDiscovery.Port");
+ initData.properties.setProperty("IceDiscovery.Lookup",
+ "udp -h " + multicast + " --interface unknown:" +
+ "udp -h " + multicast + " -p " + port + intf);
+ Ice.Communicator com = Ice.Util.initialize(initData);
+ test(com.getDefaultLocator() != null);
+ com.stringToProxy("controller0@control0").ice_ping();
+ com.destroy();
+ }
+ }
+ System.out.println("ok");
+
System.out.print("shutting down... ");
System.out.flush();
for(ControllerPrx prx : proxies)
diff --git a/java-compat/test/src/main/java/test/IceGrid/simple/AllTests.java b/java-compat/test/src/main/java/test/IceGrid/simple/AllTests.java
index 95b173016e5..fd547cc6dc2 100644
--- a/java-compat/test/src/main/java/test/IceGrid/simple/AllTests.java
+++ b/java-compat/test/src/main/java/test/IceGrid/simple/AllTests.java
@@ -147,6 +147,64 @@ public class AllTests
adapter.deactivate();
com.destroy();
+
+ String multicast;
+ if(communicator.getProperties().getProperty("Ice.IPv6").equals("1"))
+ {
+ multicast = "\"ff15::1\"";
+ }
+ else
+ {
+ multicast = "239.255.0.1";
+ }
+
+ //
+ // Test invalid lookup endpoints
+ //
+ initData.properties = communicator.getProperties()._clone();
+ initData.properties.setProperty("Ice.Default.Locator", "");
+ initData.properties.setProperty("Ice.Plugin.IceLocatorDiscovery",
+ "IceLocatorDiscovery.PluginFactory");
+ initData.properties.setProperty("IceLocatorDiscovery.Lookup",
+ "udp -h " + multicast + " --interface unknown");
+ com = Ice.Util.initialize(initData);
+ test(com.getDefaultLocator() != null);
+ try
+ {
+ com.stringToProxy("test @ TestAdapter").ice_ping();
+ test(false);
+ }
+ catch(Ice.NoEndpointException ex)
+ {
+ }
+ com.destroy();
+
+ initData.properties = communicator.getProperties()._clone();
+ initData.properties.setProperty("Ice.Default.Locator", "");
+ initData.properties.setProperty("Ice.Plugin.IceLocatorDiscovery",
+ "IceLocatorDiscovery.PluginFactory");
+ {
+ String intf = initData.properties.getProperty("IceLocatorDiscovery.Interface");
+ if(!intf.isEmpty())
+ {
+ intf = " --interface \"" + intf + "\"";
+ }
+ String port = Integer.toString(app.getTestPort(99));
+ initData.properties.setProperty("IceLocatorDiscovery.Lookup",
+ "udp -h " + multicast + " --interface unknown:" +
+ "udp -h " + multicast + " -p " + port + intf);
+ }
+ com = Ice.Util.initialize(initData);
+ test(com.getDefaultLocator() != null);
+ try
+ {
+ com.stringToProxy("test @ TestAdapter").ice_ping();
+ }
+ catch(Ice.NoEndpointException ex)
+ {
+ test(false);
+ }
+ com.destroy();
}
out.println("ok");
diff --git a/java/src/IceDiscovery/src/main/java/com/zeroc/IceDiscovery/LookupI.java b/java/src/IceDiscovery/src/main/java/com/zeroc/IceDiscovery/LookupI.java
index ac99857d3ae..0de78d3215b 100644
--- a/java/src/IceDiscovery/src/main/java/com/zeroc/IceDiscovery/LookupI.java
+++ b/java/src/IceDiscovery/src/main/java/com/zeroc/IceDiscovery/LookupI.java
@@ -22,7 +22,7 @@ class LookupI implements Lookup
Request(T id, int retryCount)
{
_id = id;
- _nRetry = retryCount;
+ _retryCount = retryCount;
}
T getId()
@@ -38,7 +38,27 @@ class LookupI implements Lookup
boolean retry()
{
- return --_nRetry >= 0;
+ return --_retryCount >= 0;
+ }
+
+ void invoke(String domainId, Map<LookupPrx, LookupReplyPrx> lookups)
+ {
+ _lookupCount = lookups.size();
+ _failureCount = 0;
+ for(Map.Entry<LookupPrx, LookupReplyPrx> entry : lookups.entrySet())
+ {
+ invokeWithLookup(domainId, entry.getKey(), entry.getValue());
+ }
+ }
+
+ boolean exception()
+ {
+ if(++_failureCount == _lookupCount)
+ {
+ finished(null);
+ return true;
+ }
+ return false;
}
void scheduleTimer(long timeout)
@@ -53,9 +73,15 @@ class LookupI implements Lookup
_future = null;
}
- protected int _nRetry;
+ abstract void finished(com.zeroc.Ice.ObjectPrx proxy);
+
+ abstract protected void invokeWithLookup(String domainId, LookupPrx lookup, LookupReplyPrx lookupReply);
+
+ protected int _retryCount;
+ protected int _lookupCount;
+ protected int _failureCount;
protected List<CompletableFuture<Ret>> _futures = new ArrayList<>();
- private T _id;
+ protected T _id;
protected java.util.concurrent.Future<?> _future;
}
@@ -71,7 +97,7 @@ class LookupI implements Lookup
@Override
boolean retry()
{
- return _proxies.size() == 0 && --_nRetry >= 0;
+ return _proxies.size() == 0 && --_retryCount >= 0;
}
boolean response(com.zeroc.Ice.ObjectPrx proxy, boolean isReplicaGroup)
@@ -95,6 +121,7 @@ class LookupI implements Lookup
return true;
}
+ @Override
void finished(com.zeroc.Ice.ObjectPrx proxy)
{
if(proxy != null || _proxies.isEmpty())
@@ -127,6 +154,17 @@ class LookupI implements Lookup
adapterRequestTimedOut(this);
}
+ @Override
+ protected void invokeWithLookup(String domainId, LookupPrx lookup, LookupReplyPrx lookupReply)
+ {
+ lookup.findAdapterByIdAsync(domainId, _id, lookupReply).whenComplete((v, ex) -> {
+ if(ex != null)
+ {
+ adapterRequestException(AdapterRequest.this, ex);
+ }
+ });
+ }
+
private void sendResponse(com.zeroc.Ice.ObjectPrx proxy)
{
for(CompletableFuture<com.zeroc.Ice.ObjectPrx> f : _futures)
@@ -153,6 +191,7 @@ class LookupI implements Lookup
finished(proxy);
}
+ @Override
void finished(com.zeroc.Ice.ObjectPrx proxy)
{
for(CompletableFuture<com.zeroc.Ice.ObjectPrx> f : _futures)
@@ -167,51 +206,36 @@ class LookupI implements Lookup
{
objectRequestTimedOut(this);
}
+
+ @Override
+ protected void invokeWithLookup(String domainId, LookupPrx lookup, LookupReplyPrx lookupReply)
+ {
+ lookup.findObjectByIdAsync(domainId, _id, lookupReply).whenComplete((v, ex) -> {
+ if(ex != null)
+ {
+ objectRequestException(ObjectRequest.this, ex);
+ }
+ });
+ }
}
public LookupI(LocatorRegistryI registry, LookupPrx lookup, com.zeroc.Ice.Properties properties)
{
_registry = registry;
+ _lookup = lookup;
_timeout = properties.getPropertyAsIntWithDefault("IceDiscovery.Timeout", 300);
_retryCount = properties.getPropertyAsIntWithDefault("IceDiscovery.RetryCount", 3);
_latencyMultiplier = properties.getPropertyAsIntWithDefault("IceDiscovery.LatencyMultiplier", 1);
_domainId = properties.getProperty("IceDiscovery.DomainId");
_timer = com.zeroc.IceInternal.Util.getInstance(lookup.ice_getCommunicator()).timer();
- try
- {
- lookup.ice_getConnection();
- }
- catch(com.zeroc.Ice.LocalException ex)
- {
- StringBuilder b = new StringBuilder();
- b.append("IceDiscovery is unable to establish a multicast connection:\n");
- b.append("proxy = ");
- b.append(lookup.toString());
- b.append('\n');
- b.append(ex.toString());
- throw new com.zeroc.Ice.PluginInitializationException(b.toString());
- }
-
- //
- // Create one lookup proxy per endpoint from the given proxy. We want to send a multicast
- // datagram on each endpoint.
- //
com.zeroc.Ice.Endpoint[] single = new com.zeroc.Ice.Endpoint[1];
for(com.zeroc.Ice.Endpoint endpt : lookup.ice_getEndpoints())
{
- try
- {
- single[0] = endpt;
- LookupPrx l = (LookupPrx)lookup.ice_endpoints(single);
- l.ice_getConnection();
- _lookup.put(l, null);
- }
- catch(com.zeroc.Ice.LocalException ex)
- {
- }
+ single[0] = endpt;
+ _lookups.put((LookupPrx)lookup.ice_endpoints(single), null);
}
- assert(!_lookup.isEmpty());
+ assert(!_lookups.isEmpty());
}
void setLookupReply(LookupReplyPrx lookupReply)
@@ -220,7 +244,7 @@ class LookupI implements Lookup
// Use a lookup reply proxy whose adress matches the interface used to send multicast datagrams.
//
com.zeroc.Ice.Endpoint[] single = new com.zeroc.Ice.Endpoint[1];
- for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookup.entrySet())
+ for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookups.entrySet())
{
com.zeroc.Ice.UDPEndpointInfo info =
(com.zeroc.Ice.UDPEndpointInfo)entry.getKey().ice_getEndpoints()[0].getInfo();
@@ -311,10 +335,7 @@ class LookupI implements Lookup
{
try
{
- for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookup.entrySet())
- {
- entry.getKey().findObjectByIdAsync(_domainId, id, entry.getValue());
- }
+ request.invoke(_domainId, _lookups);
request.scheduleTimer(_timeout);
}
catch(com.zeroc.Ice.LocalException ex)
@@ -338,10 +359,7 @@ class LookupI implements Lookup
{
try
{
- for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookup.entrySet())
- {
- entry.getKey().findAdapterByIdAsync(_domainId, adapterId, entry.getValue());
- }
+ request.invoke(_domainId, _lookups);
request.scheduleTimer(_timeout);
}
catch(com.zeroc.Ice.LocalException ex)
@@ -392,10 +410,7 @@ class LookupI implements Lookup
{
try
{
- for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookup.entrySet())
- {
- entry.getKey().findObjectByIdAsync(_domainId, request.getId(), entry.getValue());
- }
+ request.invoke(_domainId, _lookups);
request.scheduleTimer(_timeout);
return;
}
@@ -408,6 +423,34 @@ class LookupI implements Lookup
_objectRequests.remove(request.getId());
}
+
+ synchronized void objectRequestException(ObjectRequest request, Throwable ex)
+ {
+ ObjectRequest r = _objectRequests.get(request.getId());
+ if(r == null || r != request)
+ {
+ return;
+ }
+
+ if(request.exception())
+ {
+ if(_warnOnce)
+ {
+ StringBuilder s = new StringBuilder();
+ s.append("failed to lookup object `");
+ s.append(_lookup.ice_getCommunicator().identityToString(request.getId()));
+ s.append("' with lookup proxy `");
+ s.append(_lookup);
+ s.append("':\n");
+ s.append(ex.toString());
+ _lookup.ice_getCommunicator().getLogger().warning(s.toString());
+ _warnOnce = false;
+ }
+ request.cancelTimer();
+ _objectRequests.remove(request.getId());
+ }
+ }
+
synchronized void adapterRequestTimedOut(AdapterRequest request)
{
AdapterRequest r = _adapterRequests.get(request.getId());
@@ -420,10 +463,7 @@ class LookupI implements Lookup
{
try
{
- for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookup.entrySet())
- {
- entry.getKey().findAdapterByIdAsync(_domainId, request.getId(), entry.getValue());
- }
+ request.invoke(_domainId, _lookups);
request.scheduleTimer(_timeout);
return;
}
@@ -436,14 +476,43 @@ class LookupI implements Lookup
_adapterRequests.remove(request.getId());
}
+ synchronized void adapterRequestException(AdapterRequest request, Throwable ex)
+ {
+ AdapterRequest r = _adapterRequests.get(request.getId());
+ if(r == null || r != request)
+ {
+ return;
+ }
+
+ if(request.exception())
+ {
+ if(_warnOnce)
+ {
+ StringBuilder s = new StringBuilder();
+ s.append("failed to lookup adapter `");
+ s.append(request.getId());
+ s.append("' with lookup proxy `");
+ s.append(_lookup);
+ s.append("':\n");
+ s.append(ex.toString());
+ _lookup.ice_getCommunicator().getLogger().warning(s.toString());
+ _warnOnce = false;
+ }
+ request.cancelTimer();
+ _adapterRequests.remove(request.getId());
+ }
+ }
+
private LocatorRegistryI _registry;
- private java.util.Map<LookupPrx, LookupReplyPrx> _lookup = new java.util.HashMap<>();
+ private LookupPrx _lookup;
+ private java.util.Map<LookupPrx, LookupReplyPrx> _lookups = new java.util.HashMap<>();
private final int _timeout;
private final int _retryCount;
private final int _latencyMultiplier;
private final String _domainId;
private final java.util.concurrent.ScheduledExecutorService _timer;
+ private boolean _warnOnce = true;
private Map<com.zeroc.Ice.Identity, ObjectRequest> _objectRequests = new HashMap<>();
private Map<String, AdapterRequest> _adapterRequests = new HashMap<>();
diff --git a/java/src/IceLocatorDiscovery/src/main/java/com/zeroc/IceLocatorDiscovery/PluginI.java b/java/src/IceLocatorDiscovery/src/main/java/com/zeroc/IceLocatorDiscovery/PluginI.java
index 61dd6f7cca1..4001913fc2e 100644
--- a/java/src/IceLocatorDiscovery/src/main/java/com/zeroc/IceLocatorDiscovery/PluginI.java
+++ b/java/src/IceLocatorDiscovery/src/main/java/com/zeroc/IceLocatorDiscovery/PluginI.java
@@ -141,6 +141,7 @@ class PluginI implements Plugin
LocatorI(String name, LookupPrx lookup, com.zeroc.Ice.Properties properties, String instanceName,
com.zeroc.Ice.LocatorPrx voidLocator)
{
+ _lookup = lookup;
_timeout = properties.getPropertyAsIntWithDefault(name + ".Timeout", 300);
_retryCount = properties.getPropertyAsIntWithDefault(name + ".RetryCount", 3);
_retryDelay = properties.getPropertyAsIntWithDefault(name + ".RetryDelay", 2000);
@@ -150,21 +151,8 @@ class PluginI implements Plugin
_locator = lookup.ice_getCommunicator().getDefaultLocator();
_voidLocator = voidLocator;
_pendingRetryCount = 0;
-
- try
- {
- lookup.ice_getConnection();
- }
- catch(com.zeroc.Ice.LocalException ex)
- {
- StringBuilder b = new StringBuilder();
- b.append("IceDiscovery is unable to establish a multicast connection:\n");
- b.append("proxy = ");
- b.append(lookup.toString());
- b.append('\n');
- b.append(ex.toString());
- throw new com.zeroc.Ice.PluginInitializationException(b.toString());
- }
+ _failureCount = 0;
+ _warnOnce = true;
//
// Create one lookup proxy per endpoint from the given proxy. We want to send a multicast
@@ -173,18 +161,10 @@ class PluginI implements Plugin
com.zeroc.Ice.Endpoint[] single = new com.zeroc.Ice.Endpoint[1];
for(com.zeroc.Ice.Endpoint endpt : lookup.ice_getEndpoints())
{
- try
- {
- single[0] = endpt;
- LookupPrx l = (LookupPrx)lookup.ice_endpoints(single);
- l.ice_getConnection();
- _lookup.put(l, null);
- }
- catch(com.zeroc.Ice.LocalException ex)
- {
- }
+ single[0] = endpt;
+ _lookups.put((LookupPrx)lookup.ice_endpoints(single), null);
}
- assert(!_lookup.isEmpty());
+ assert(!_lookups.isEmpty());
}
public void setLookupReply(LookupReplyPrx lookupReply)
@@ -193,7 +173,7 @@ class PluginI implements Plugin
// Use a lookup reply proxy whose adress matches the interface used to send multicast datagrams.
//
com.zeroc.Ice.Endpoint[] single = new com.zeroc.Ice.Endpoint[1];
- for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookup.entrySet())
+ for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookups.entrySet())
{
com.zeroc.Ice.UDPEndpointInfo info =
(com.zeroc.Ice.UDPEndpointInfo)entry.getKey().ice_getEndpoints()[0].getInfo();
@@ -228,8 +208,7 @@ class PluginI implements Plugin
return f;
}
- public List<com.zeroc.Ice.LocatorPrx>
- getLocators(String instanceName, int waitTime)
+ public List<com.zeroc.Ice.LocatorPrx> getLocators(String instanceName, int waitTime)
{
//
// Clear locators from previous search.
@@ -398,12 +377,18 @@ class PluginI implements Plugin
if(_pendingRetryCount == 0) // No request in progress
{
+ _failureCount = 0;
_pendingRetryCount = _retryCount;
try
{
- for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookup.entrySet())
+ for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookups.entrySet())
{
- entry.getKey().findLocatorAsync(_instanceName, entry.getValue()); // Send multicast request.
+ entry.getKey().findLocatorAsync(_instanceName, entry.getValue()).whenComplete((v, ex) -> {
+ if(ex != null)
+ {
+ exception(ex);
+ }
+ }); // Send multicast request.
}
_future = _timer.schedule(_retryTask, _timeout, java.util.concurrent.TimeUnit.MILLISECONDS);
}
@@ -420,6 +405,44 @@ class PluginI implements Plugin
}
}
+ synchronized void exception(Throwable ex)
+ {
+ if(++_failureCount == _lookups.size() && _pendingRetryCount > 0)
+ {
+ //
+ // All the lookup calls failed, cancel the timer and propagate the error to the requests.
+ //
+ _future.cancel(false);
+ _future = null;
+
+ _pendingRetryCount = 0;
+
+ if(_warnOnce)
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.append("failed to lookup locator with lookup proxy `");
+ builder.append(_lookup);
+ builder.append("':\n");
+ builder.append(ex);
+ _lookup.ice_getCommunicator().getLogger().warning(builder.toString());
+ _warnOnce = false;
+ }
+
+ if(_pendingRequests.isEmpty())
+ {
+ notify();
+ }
+ else
+ {
+ for(Request req : _pendingRequests)
+ {
+ req.invoke(_voidLocator);
+ }
+ _pendingRequests.clear();
+ }
+ }
+ }
+
private Runnable _retryTask = new Runnable()
{
@Override
@@ -431,9 +454,15 @@ class PluginI implements Plugin
{
try
{
- for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookup.entrySet())
+ _failureCount = 0;
+ for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookups.entrySet())
{
- entry.getKey().findLocatorAsync(_instanceName, entry.getValue()); // Send multicast request
+ entry.getKey().findLocatorAsync(_instanceName, entry.getValue()).whenComplete((v, ex) -> {
+ if(ex != null)
+ {
+ exception(ex);
+ }
+ }); // Send multicast request.
}
_future = _timer.schedule(_retryTask, _timeout, java.util.concurrent.TimeUnit.MILLISECONDS);
return;
@@ -444,18 +473,26 @@ class PluginI implements Plugin
_pendingRetryCount = 0;
}
- for(Request req : _pendingRequests)
+ if(_pendingRequests.isEmpty())
{
- req.invoke(_voidLocator);
+ notify();
+ }
+ else
+ {
+ for(Request req : _pendingRequests)
+ {
+ req.invoke(_voidLocator);
+ }
+ _pendingRequests.clear();
}
- _pendingRequests.clear();
_nextRetry = com.zeroc.IceInternal.Time.currentMonotonicTimeMillis() + _retryDelay;
}
}
};
- private final Map<LookupPrx, LookupReplyPrx> _lookup = new java.util.HashMap<>();
+ private final LookupPrx _lookup;
+ private final Map<LookupPrx, LookupReplyPrx> _lookups = new java.util.HashMap<>();
private final int _timeout;
private java.util.concurrent.Future<?> _future;
private final java.util.concurrent.ScheduledExecutorService _timer;
@@ -469,6 +506,8 @@ class PluginI implements Plugin
private Map<String, com.zeroc.Ice.LocatorPrx> _locators = new HashMap<>();
private int _pendingRetryCount;
+ private int _failureCount;
+ private boolean _warnOnce;
private List<Request> _pendingRequests = new ArrayList<>();
private long _nextRetry;
}
diff --git a/java/test/src/main/java/test/IceDiscovery/simple/AllTests.java b/java/test/src/main/java/test/IceDiscovery/simple/AllTests.java
index 820a6ad0bd9..f43e44dd761 100644
--- a/java/test/src/main/java/test/IceDiscovery/simple/AllTests.java
+++ b/java/test/src/main/java/test/IceDiscovery/simple/AllTests.java
@@ -209,6 +209,55 @@ public class AllTests
}
System.out.println("ok");
+ System.out.print("testing invalid lookup endpoints... ");
+ System.out.flush();
+ {
+ String multicast;
+ if(communicator.getProperties().getProperty("Ice.IPv6").equals("1"))
+ {
+ multicast = "\"ff15::1\"";
+ }
+ else
+ {
+ multicast = "239.255.0.1";
+ }
+
+ {
+ com.zeroc.Ice.InitializationData initData = new com.zeroc.Ice.InitializationData();
+ initData.properties = communicator.getProperties()._clone();
+ initData.properties.setProperty("IceDiscovery.Lookup", "udp -h " + multicast + " --interface unknown");
+ com.zeroc.Ice.Communicator comm = com.zeroc.Ice.Util.initialize(initData);
+ test(comm.getDefaultLocator() != null);
+ try
+ {
+ comm.stringToProxy("controller0@control0").ice_ping();
+ test(false);
+ }
+ catch(com.zeroc.Ice.LocalException ex)
+ {
+ }
+ comm.destroy();
+ }
+ {
+ com.zeroc.Ice.InitializationData initData = new com.zeroc.Ice.InitializationData();
+ initData.properties = communicator.getProperties()._clone();
+ String intf = initData.properties.getProperty("IceDiscovery.Interface");
+ if(!intf.isEmpty())
+ {
+ intf = " --interface \"" + intf + "\"";
+ }
+ String port = initData.properties.getProperty("IceDiscovery.Port");
+ initData.properties.setProperty("IceDiscovery.Lookup",
+ "udp -h " + multicast + " --interface unknown:" +
+ "udp -h " + multicast + " -p " + port + intf);
+ com.zeroc.Ice.Communicator comm = com.zeroc.Ice.Util.initialize(initData);
+ test(comm.getDefaultLocator() != null);
+ comm.stringToProxy("controller0@control0").ice_ping();
+ comm.destroy();
+ }
+ }
+ System.out.println("ok");
+
System.out.print("shutting down... ");
System.out.flush();
for(ControllerPrx prx : proxies)
diff --git a/java/test/src/main/java/test/IceGrid/simple/AllTests.java b/java/test/src/main/java/test/IceGrid/simple/AllTests.java
index 1c9e28cccc2..4e3fb2335b2 100644
--- a/java/test/src/main/java/test/IceGrid/simple/AllTests.java
+++ b/java/test/src/main/java/test/IceGrid/simple/AllTests.java
@@ -144,6 +144,64 @@ public class AllTests
adapter.deactivate();
comm.destroy();
+
+ String multicast;
+ if(communicator.getProperties().getProperty("Ice.IPv6").equals("1"))
+ {
+ multicast = "\"ff15::1\"";
+ }
+ else
+ {
+ multicast = "239.255.0.1";
+ }
+
+ //
+ // Test invalid lookup endpoints
+ //
+ initData.properties = communicator.getProperties()._clone();
+ initData.properties.setProperty("Ice.Default.Locator", "");
+ initData.properties.setProperty("Ice.Plugin.IceLocatorDiscovery",
+ "com.zeroc.IceLocatorDiscovery.PluginFactory");
+ initData.properties.setProperty("IceLocatorDiscovery.Lookup",
+ "udp -h " + multicast + " --interface unknown");
+ comm = com.zeroc.Ice.Util.initialize(initData);
+ test(comm.getDefaultLocator() != null);
+ try
+ {
+ comm.stringToProxy("test @ TestAdapter").ice_ping();
+ test(false);
+ }
+ catch(com.zeroc.Ice.NoEndpointException ex)
+ {
+ }
+ comm.destroy();
+
+ initData.properties = communicator.getProperties()._clone();
+ initData.properties.setProperty("Ice.Default.Locator", "");
+ initData.properties.setProperty("Ice.Plugin.IceLocatorDiscovery",
+ "com.zeroc.IceLocatorDiscovery.PluginFactory");
+ {
+ String intf = initData.properties.getProperty("IceLocatorDiscovery.Interface");
+ if(!intf.isEmpty())
+ {
+ intf = " --interface \"" + intf + "\"";
+ }
+ String port = Integer.toString(app.getTestPort(99));
+ initData.properties.setProperty("IceLocatorDiscovery.Lookup",
+ "udp -h " + multicast + " --interface unknown:" +
+ "udp -h " + multicast + " -p " + port + intf);
+ }
+ comm = com.zeroc.Ice.Util.initialize(initData);
+ test(comm.getDefaultLocator() != null);
+ try
+ {
+ comm.stringToProxy("test @ TestAdapter").ice_ping();
+ }
+ catch(com.zeroc.Ice.NoEndpointException ex)
+ {
+ test(false);
+ }
+ comm.destroy();
}
out.println("ok");
diff --git a/scripts/IceGridUtil.py b/scripts/IceGridUtil.py
index 2e9ec2b8129..c981b63eaae 100644
--- a/scripts/IceGridUtil.py
+++ b/scripts/IceGridUtil.py
@@ -136,8 +136,6 @@ class IceGridRegistry(ProcessFromBinDir, Server):
pass
def getProps(self, current):
- # NOTE: we use the loopback interface for multicast with IPv6 to prevent failures
- # on some machines which don't really have an IPv6 interface configured.
props = {
'IceGrid.InstanceName' : 'TestIceGrid',
'IceGrid.Registry.PermissionsVerifier' : 'TestIceGrid/NullPermissionsVerifier',
@@ -148,6 +146,7 @@ class IceGridRegistry(ProcessFromBinDir, Server):
'IceGrid.Registry.Internal.Endpoints' : 'default',
'IceGrid.Registry.Client.Endpoints' : self.getEndpoints(current),
'IceGrid.Registry.Discovery.Port' : current.driver.getTestPort(99),
+ "IceGrid.Registry.Discovery.Interface": "::1" if current.config.ipv6 else "127.0.0.1",
'IceGrid.Registry.SessionManager.Endpoints' : 'default',
'IceGrid.Registry.AdminSessionManager.Endpoints' : 'default',
'IceGrid.Registry.SessionTimeout' : 60,
diff --git a/scripts/Util.py b/scripts/Util.py
index d1150fa32cd..479aa590586 100644
--- a/scripts/Util.py
+++ b/scripts/Util.py
@@ -82,7 +82,7 @@ class Platform:
def getFilters(self, config):
if config.buildConfig in ["static", "cpp11-static"]:
- return (["Ice/.*", "IceSSL/configuration", "IceDiscovery/simple", "IceGrid/simple"],
+ return (["Ice/.*", "IceSSL/configuration", "IceDiscovery/simple", "IceGrid/simple", "Glacier2/application"],
["Ice/library", "Ice/plugin"])
return ([], [])
@@ -2496,10 +2496,15 @@ class CppMapping(Mapping):
return False
# No C++11 tests for IceStorm, IceGrid, etc
- parent = re.match(r'^([\w]*).*', current.testcase.getTestSuite().getId()).group(1)
- if self.cpp11 and not parent in ["IceUtil", "Slice", "Ice", "IceSSL", "IceDiscovery", "IceBox"]:
- return False
-
+ if self.cpp11:
+ testId = current.testcase.getTestSuite().getId()
+ parent = re.match(r'^([\w]*).*', testId).group(1)
+ if parent in ["IceStorm"]:
+ return False
+ elif parent in ["IceGrid"] and testId not in ["IceGrid/simple"]:
+ return False
+ elif parent in ["Glacier2"] and testId not in ["Glacier2/application"]:
+ return False
return True
def getNugetPackage(self, compiler, version):
@@ -2538,7 +2543,8 @@ class CppMapping(Mapping):
return {
"IceSSL" : "IceSSLOpenSSL:createIceSSLOpenSSL" if current.config.openssl else "IceSSL:createIceSSL",
"IceBT" : "IceBT:createIceBT",
- "IceDiscovery" : "IceDiscovery:createIceDiscovery"
+ "IceDiscovery" : "IceDiscovery:createIceDiscovery",
+ "IceLocatorDiscovery" : "IceLocatorDiscovery:createIceLocatorDiscovery"
}[plugin]
def getEnv(self, process, current):
@@ -2607,7 +2613,8 @@ class JavaMapping(Mapping):
return {
"IceSSL" : "com.zeroc.IceSSL.PluginFactory",
"IceBT" : "com.zeroc.IceBT.PluginFactory",
- "IceDiscovery" : "com.zeroc.IceDiscovery.PluginFactory"
+ "IceDiscovery" : "com.zeroc.IceDiscovery.PluginFactory",
+ "IceLocatorDiscovery" : "com.zeroc.IceLocatorDiscovery.PluginFactory"
}[plugin]
def getEnv(self, process, current):
@@ -2635,7 +2642,8 @@ class JavaCompatMapping(JavaMapping):
return {
"IceSSL" : "IceSSL.PluginFactory",
"IceBT" : "IceBT.PluginFactory",
- "IceDiscovery" : "IceDiscovery.PluginFactory"
+ "IceDiscovery" : "IceDiscovery.PluginFactory",
+ "IceLocatorDiscovery" : "IceLocatorDiscovery.PluginFactory"
}[plugin]
def getDefaultExe(self, processType, config=None):
@@ -2675,7 +2683,8 @@ class CSharpMapping(Mapping):
"lib" if current.driver.useIceBinDist(self) else "Assemblies")
return {
"IceSSL" : plugindir + "/IceSSL.dll:IceSSL.PluginFactory",
- "IceDiscovery" : plugindir + "/IceDiscovery.dll:IceDiscovery.PluginFactory"
+ "IceDiscovery" : plugindir + "/IceDiscovery.dll:IceDiscovery.PluginFactory",
+ "IceLocatorDiscovery" : plugindir + "/IceLocatorDiscovery.dll:IceLocatorDiscovery.PluginFactory"
}[plugin]
def getEnv(self, process, current):
diff --git a/scripts/tests/IceDiscovery/simple.py b/scripts/tests/IceDiscovery/simple.py
index ef6f8163553..4eab32122e4 100644
--- a/scripts/tests/IceDiscovery/simple.py
+++ b/scripts/tests/IceDiscovery/simple.py
@@ -11,12 +11,16 @@
props = lambda process, current: {
"IceDiscovery.Timeout": 50,
"IceDiscovery.RetryCount": 5,
- "IceDiscovery.Interface": "" if isinstance(platform, Linux) else "::1" if current.config.ipv6 else "127.0.0.1",
+ "IceDiscovery.Interface": "::1" if current.config.ipv6 else "127.0.0.1",
"IceDiscovery.Port": current.driver.getTestPort(10),
"Ice.Plugin.IceDiscovery": current.getPluginEntryPoint("IceDiscovery", process)
}
+# Filter-out the warning about invalid lookup proxy
+outfilters = [ lambda x: re.sub("-! .* warning: .*failed to lookup adapter.*\n", "", x),
+ lambda x: re.sub("^ .*\n", "", x) ]
+
TestSuite(__name__, [
- ClientServerTestCase(client=Client(args=[3], props=props),
+ ClientServerTestCase(client=Client(args=[3], props=props, outfilters=outfilters),
servers=[Server(args=[i], readyCount=4, props=props) for i in range(0, 3)])
], multihost=False)
diff --git a/scripts/tests/IceGrid/simple.py b/scripts/tests/IceGrid/simple.py
index 30110ee5197..dc87a4a7f62 100644
--- a/scripts/tests/IceGrid/simple.py
+++ b/scripts/tests/IceGrid/simple.py
@@ -17,11 +17,23 @@ registryProps = {
"IceGrid.Registry.DynamicRegistration" : 1
}
+clientProps = lambda process, current: {
+ "IceLocatorDiscovery.Timeout": 50,
+ "IceLocatorDiscovery.RetryCount": 5,
+ "IceLocatorDiscovery.Interface": "::1" if current.config.ipv6 else "127.0.0.1",
+ "IceLocatorDiscovery.Port": current.driver.getTestPort(99),
+}
+
+# Filter-out the warning about invalid lookup proxy
+outfilters = [ lambda x: re.sub("-! .* warning: .*failed to lookup locator.*\n", "", x),
+ lambda x: re.sub("^ .*\n", "", x) ]
+
TestSuite(__name__, [
IceGridTestCase("without deployment", application=None,
icegridregistry=[IceGridRegistryMaster(props=registryProps),
IceGridRegistrySlave(1, props=registryProps),
IceGridRegistrySlave(2, props=registryProps)],
- client=ClientServerTestCase(client=IceGridClient(), server=IceGridServer(props=serverProps))),
+ client=ClientServerTestCase(client=IceGridClient(props=clientProps, outfilters=outfilters),
+ server=IceGridServer(props=serverProps))),
IceGridTestCase("with deployment", client=IceGridClient(args=["--with-deploy"]))
], multihost=False)