summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config/PropertyNames.xml1
-rwxr-xr-xcpp/src/Ice/Network.cpp10
-rwxr-xr-xcpp/src/Ice/Network.h2
-rw-r--r--cpp/src/Ice/PropertyNames.cpp39
-rw-r--r--cpp/src/Ice/PropertyNames.h2
-rwxr-xr-xcpp/src/Ice/UdpTransceiver.cpp2
-rw-r--r--cpp/src/IceDiscovery/LookupI.cpp222
-rw-r--r--cpp/src/IceDiscovery/LookupI.h3
-rw-r--r--cpp/src/IceDiscovery/PluginI.cpp64
-rw-r--r--cpp/src/IceGrid/Client.cpp158
-rw-r--r--cpp/src/IceGrid/Makefile.mk5
-rw-r--r--cpp/src/IceGrid/msbuild/icegridadmin/icegridadmin.vcxproj41
-rw-r--r--cpp/src/IceGrid/msbuild/icegridadmin/icegridadmin.vcxproj.filters27
-rw-r--r--cpp/src/IceLocatorDiscovery/Plugin.h52
-rw-r--r--cpp/src/IceLocatorDiscovery/PluginI.cpp419
-rw-r--r--cpp/src/IceLocatorDiscovery/PluginI.h36
-rw-r--r--cpp/test/IceGrid/simple/AllTests.cpp6
-rw-r--r--csharp/src/Ice/Network.cs10
-rw-r--r--csharp/src/Ice/PropertyNames.cs39
-rw-r--r--csharp/src/Ice/UdpTransceiver.cs8
-rw-r--r--csharp/src/IceDiscovery/LookupI.cs89
-rw-r--r--csharp/src/IceDiscovery/PluginI.cs48
-rw-r--r--csharp/src/IceLocatorDiscovery/PluginI.cs295
-rw-r--r--java-compat/src/Ice/src/main/java/IceInternal/Network.java9
-rw-r--r--java-compat/src/Ice/src/main/java/IceInternal/PropertyNames.java39
-rw-r--r--java-compat/src/Ice/src/main/java/IceInternal/UdpMulticastClientTransceiver.java3
-rw-r--r--java-compat/src/Ice/src/main/java/IceInternal/UdpMulticastServerTransceiver.java3
-rw-r--r--java-compat/src/Ice/src/main/java/IceInternal/UdpTransceiver.java2
-rw-r--r--java-compat/src/IceDiscovery/src/main/java/IceDiscovery/LookupI.java86
-rw-r--r--java-compat/src/IceDiscovery/src/main/java/IceDiscovery/PluginI.java50
-rw-r--r--java-compat/src/IceLocatorDiscovery/src/main/java/IceLocatorDiscovery/Plugin.java17
-rw-r--r--java-compat/src/IceLocatorDiscovery/src/main/java/IceLocatorDiscovery/PluginFactory.java2
-rw-r--r--java-compat/src/IceLocatorDiscovery/src/main/java/IceLocatorDiscovery/PluginI.java278
-rw-r--r--java-compat/test/src/main/java/test/IceGrid/simple/AllTests.java5
-rw-r--r--java/src/Ice/src/main/java/com/zeroc/IceInternal/Network.java9
-rw-r--r--java/src/Ice/src/main/java/com/zeroc/IceInternal/PropertyNames.java39
-rw-r--r--java/src/Ice/src/main/java/com/zeroc/IceInternal/UdpMulticastClientTransceiver.java3
-rw-r--r--java/src/Ice/src/main/java/com/zeroc/IceInternal/UdpMulticastServerTransceiver.java3
-rw-r--r--java/src/Ice/src/main/java/com/zeroc/IceInternal/UdpTransceiver.java2
-rw-r--r--java/src/IceDiscovery/src/main/java/com/zeroc/IceDiscovery/LookupI.java88
-rw-r--r--java/src/IceDiscovery/src/main/java/com/zeroc/IceDiscovery/PluginI.java52
-rw-r--r--java/src/IceGridGUI/src/main/java/com/zeroc/IceGridGUI/SessionKeeper.java301
-rw-r--r--java/src/IceLocatorDiscovery/src/main/java/com/zeroc/IceLocatorDiscovery/Plugin.java17
-rw-r--r--java/src/IceLocatorDiscovery/src/main/java/com/zeroc/IceLocatorDiscovery/PluginFactory.java2
-rw-r--r--java/src/IceLocatorDiscovery/src/main/java/com/zeroc/IceLocatorDiscovery/PluginI.java279
-rw-r--r--java/test/src/main/java/test/IceGrid/simple/AllTests.java5
-rw-r--r--js/src/Ice/PropertyNames.js2
-rwxr-xr-xscripts/Expect.py4
-rw-r--r--scripts/IceGridUtil.py4
-rw-r--r--scripts/Util.py5
-rw-r--r--scripts/tests/IceDiscovery/simple.py1
-rw-r--r--slice/IceLocatorDiscovery/IceLocatorDiscovery.ice2
52 files changed, 1720 insertions, 1170 deletions
diff --git a/config/PropertyNames.xml b/config/PropertyNames.xml
index f0461a5fe1b..c12367fc58e 100644
--- a/config/PropertyNames.xml
+++ b/config/PropertyNames.xml
@@ -471,6 +471,7 @@ generated from the section label.
<property name="Discovery.Interface" />
<property name="Discovery.Lookup" />
<property name="Discovery.Reply" class="objectadapter" />
+ <property name="Discovery.Locator" class="objectadapter" />
<property name="Trace.Observers" />
<property name="Trace.SaveToRegistry" />
</section>
diff --git a/cpp/src/Ice/Network.cpp b/cpp/src/Ice/Network.cpp
index 05abc9528f9..b98ea329429 100755
--- a/cpp/src/Ice/Network.cpp
+++ b/cpp/src/Ice/Network.cpp
@@ -1664,9 +1664,8 @@ IceInternal::getHostsForEndpointExpand(const string& host, ProtocolSupport proto
}
vector<string>
-IceInternal::getInterfacesForMulticast(const string& intf, const Address& mcastAddr)
+IceInternal::getInterfacesForMulticast(const string& intf, ProtocolSupport protocolSupport)
{
- ProtocolSupport protocolSupport = getProtocolSupport(mcastAddr);
vector<string> interfaces = getHostsForEndpointExpand(intf, protocolSupport, true);
if(interfaces.empty())
{
@@ -1700,9 +1699,8 @@ IceInternal::getHostsForEndpointExpand(const string& host, ProtocolSupport proto
}
vector<string>
-IceInternal::getInterfacesForMulticast(const string& intf, const Address& mcastAddr)
+IceInternal::getInterfacesForMulticast(const string& intf, ProtocolSupport protocolSupport)
{
- ProtocolSupport protocolSupport = getProtocolSupport(mcastAddr);
vector<string> interfaces;
bool ipv4Wildcard = false;
if(isWildcard(intf, protocolSupport, ipv4Wildcard))
@@ -2069,7 +2067,7 @@ IceInternal::getRecvBufferSize(SOCKET fd)
void
IceInternal::setMcastGroup(SOCKET fd, const Address& group, const string& intf)
{
- vector<string> interfaces = getInterfacesForMulticast(intf, group);
+ vector<string> interfaces = getInterfacesForMulticast(intf, getProtocolSupport(group));
set<int> indexes;
for(vector<string>::const_iterator p = interfaces.begin(); p != interfaces.end(); ++p)
{
@@ -3068,7 +3066,7 @@ IceInternal::isIpAddress(const string& name)
#else
in_addr addr;
in6_addr addr6;
-
+
return inet_pton(AF_INET, name.c_str(), &addr) > 0 || inet_pton(AF_INET6, name.c_str(), &addr6) > 0;
#endif
} \ No newline at end of file
diff --git a/cpp/src/Ice/Network.h b/cpp/src/Ice/Network.h
index df07941f73d..38ae134437f 100755
--- a/cpp/src/Ice/Network.h
+++ b/cpp/src/Ice/Network.h
@@ -284,7 +284,7 @@ ICE_API std::string addressesToString(const Address&, const Address&, bool);
ICE_API bool isAddressValid(const Address&);
ICE_API std::vector<std::string> getHostsForEndpointExpand(const std::string&, ProtocolSupport, bool);
-ICE_API std::vector<std::string> getInterfacesForMulticast(const std::string&, const Address&);
+ICE_API std::vector<std::string> getInterfacesForMulticast(const std::string&, ProtocolSupport);
ICE_API std::string inetAddrToString(const Address&);
ICE_API int getPort(const Address&);
diff --git a/cpp/src/Ice/PropertyNames.cpp b/cpp/src/Ice/PropertyNames.cpp
index e78121014d3..02ee0f7ac2c 100644
--- a/cpp/src/Ice/PropertyNames.cpp
+++ b/cpp/src/Ice/PropertyNames.cpp
@@ -6,7 +6,7 @@
// ICE_LICENSE file included in this distribution.
//
// **********************************************************************
-// Generated by makeprops.py from file ..\config\PropertyNames.xml, Fri Feb 24 18:49:18 2017
+// Generated by makeprops.py from file ./config/PropertyNames.xml, Tue Feb 28 15:01:12 2017
// IMPORTANT: Do not edit this file -- any edits made here will be lost!
@@ -520,6 +520,43 @@ const IceInternal::Property IceGridAdminPropsData[] =
IceInternal::Property("IceGridAdmin.Discovery.Reply.ThreadPool.ThreadIdleTime", false, 0),
IceInternal::Property("IceGridAdmin.Discovery.Reply.ThreadPool.ThreadPriority", false, 0),
IceInternal::Property("IceGridAdmin.Discovery.Reply.MessageSizeMax", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.ACM.Timeout", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.ACM.Heartbeat", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.ACM.Close", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.ACM", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.AdapterId", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.Endpoints", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.Locator.EndpointSelection", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.Locator.ConnectionCached", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.Locator.PreferSecure", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.Locator.LocatorCacheTimeout", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.Locator.InvocationTimeout", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.Locator.Locator", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.Locator.Router", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.Locator.CollocationOptimized", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.Locator.Context.*", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.Locator", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.PublishedEndpoints", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.ReplicaGroupId", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.Router.EndpointSelection", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.Router.ConnectionCached", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.Router.PreferSecure", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.Router.LocatorCacheTimeout", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.Router.InvocationTimeout", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.Router.Locator", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.Router.Router", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.Router.CollocationOptimized", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.Router.Context.*", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.Router", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.ProxyOptions", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.ThreadPool.Size", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.ThreadPool.SizeMax", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.ThreadPool.SizeWarn", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.ThreadPool.StackSize", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.ThreadPool.Serialize", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.ThreadPool.ThreadIdleTime", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.ThreadPool.ThreadPriority", false, 0),
+ IceInternal::Property("IceGridAdmin.Discovery.Locator.MessageSizeMax", false, 0),
IceInternal::Property("IceGridAdmin.Trace.Observers", false, 0),
IceInternal::Property("IceGridAdmin.Trace.SaveToRegistry", false, 0),
};
diff --git a/cpp/src/Ice/PropertyNames.h b/cpp/src/Ice/PropertyNames.h
index 3479ab66c1e..171fa1bed8c 100644
--- a/cpp/src/Ice/PropertyNames.h
+++ b/cpp/src/Ice/PropertyNames.h
@@ -6,7 +6,7 @@
// ICE_LICENSE file included in this distribution.
//
// **********************************************************************
-// Generated by makeprops.py from file ..\config\PropertyNames.xml, Fri Feb 24 18:49:18 2017
+// Generated by makeprops.py from file ./config/PropertyNames.xml, Tue Feb 28 15:01:12 2017
// IMPORTANT: Do not edit this file -- any edits made here will be lost!
diff --git a/cpp/src/Ice/UdpTransceiver.cpp b/cpp/src/Ice/UdpTransceiver.cpp
index 0eeba8690e2..bcb78ed2373 100755
--- a/cpp/src/Ice/UdpTransceiver.cpp
+++ b/cpp/src/Ice/UdpTransceiver.cpp
@@ -774,7 +774,7 @@ IceInternal::UdpTransceiver::toDetailedString() const
vector<string> intfs;
if(isAddressValid(_mcastAddr))
{
- intfs = getInterfacesForMulticast(_mcastInterface, _mcastAddr);
+ intfs = getInterfacesForMulticast(_mcastInterface, getProtocolSupport(_mcastAddr));
}
else
{
diff --git a/cpp/src/IceDiscovery/LookupI.cpp b/cpp/src/IceDiscovery/LookupI.cpp
index 0f554e397d8..76fb6525f03 100644
--- a/cpp/src/IceDiscovery/LookupI.cpp
+++ b/cpp/src/IceDiscovery/LookupI.cpp
@@ -56,24 +56,31 @@ AdapterRequest::response(const Ice::ObjectPrxPtr& proxy, bool isReplicaGroup)
return true;
}
-#ifdef ICE_CPP11_MAPPING
void
-AdapterRequest::finished(const Ice::ObjectPrxPtr& proxy)
+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
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
return;
}
EndpointSeq endpoints;
- shared_ptr<ObjectPrx> prx;
- for(vector<shared_ptr<ObjectPrx>>::const_iterator p = _proxies.begin(); p != _proxies.end(); ++p)
+ ObjectPrxPtr prx;
+ for(vector<ObjectPrxPtr>::const_iterator p = _proxies.begin(); p != _proxies.end(); ++p)
{
if(!prx)
{
@@ -82,37 +89,12 @@ AdapterRequest::finished(const Ice::ObjectPrxPtr& proxy)
Ice::EndpointSeq endpts = (*p)->ice_getEndpoints();
copy(endpts.begin(), endpts.end(), back_inserter(endpoints));
}
+#ifdef ICE_CPP11_MAPPING
Request<string>::finished(prx->ice_endpoints(endpoints));
-}
#else
-void
-AdapterRequest::finished(const Ice::ObjectPrxPtr& proxy)
-{
- if(proxy || _proxies.empty())
- {
- RequestT<std::string, Ice::AMD_Locator_findAdapterByIdPtr>::finished(proxy);
- return;
- }
- else if(_proxies.size() == 1)
- {
- RequestT<std::string, Ice::AMD_Locator_findAdapterByIdPtr>::finished(_proxies[0]);
- return;
- }
-
- Ice::EndpointSeq endpoints;
- Ice::ObjectPrxPtr prx;
- for(vector<Ice::ObjectPrxPtr>::const_iterator p = _proxies.begin(); p != _proxies.end(); ++p)
- {
- if(!prx)
- {
- prx = *p;
- }
- Ice::EndpointSeq endpts = (*p)->ice_getEndpoints();
- copy(endpts.begin(), endpts.end(), back_inserter(endpoints));
- }
- RequestT<std::string, Ice::AMD_Locator_findAdapterByIdPtr>::finished(prx->ice_endpoints(endpoints));
-}
+ RequestT<string, AMD_Locator_findAdapterByIdPtr>::finished(prx->ice_endpoints(endpoints));
#endif
+}
void
AdapterRequest::runTimerTask()
@@ -134,13 +116,52 @@ 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()))
{
+#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.
+ //
+ 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&)
+ {
+ }
+ }
+ assert(!_lookup.empty());
+#ifndef ICE_CPP11_MAPPING
+ __setNoDelete(false);
+#endif
}
LookupI::~LookupI()
@@ -168,7 +189,32 @@ LookupI::destroy()
void
LookupI::setLookupReply(const LookupReplyPrxPtr& lookupReply)
{
- _lookupReply = 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)
+ {
+ UDPEndpointInfoPtr info = ICE_DYNAMIC_CAST(UDPEndpointInfo, p->first->ice_getEndpoints()[0]->getInfo());
+ if(info && !info->mcastInterface.empty())
+ {
+ EndpointSeq endpts = lookupReply->ice_getEndpoints();
+ for(EndpointSeq::const_iterator q = endpts.begin(); q != endpts.end(); ++q)
+ {
+ IPEndpointInfoPtr r = ICE_DYNAMIC_CAST(IPEndpointInfo, (*q)->getInfo());
+ if(r && r->host == info->mcastInterface)
+ {
+ EndpointSeq single;
+ single.push_back(*q);
+ p->second = lookupReply->ice_endpoints(single);
+ }
+ }
+ }
+
+ if(!p->second)
+ {
+ p->second = lookupReply; // Fallback: just use the given lookup reply proxy if no matching endpoint found.
+ }
+ }
}
void
@@ -242,107 +288,85 @@ LookupI::findAdapterById(const string& domainId, const string& adapterId, const
}
}
-#ifdef ICE_CPP11_MAPPING
void
-LookupI::findObject(function<void(const shared_ptr<Ice::ObjectPrx>&)> response, const Ice::Identity& id)
-{
- Lock sync(*this);
- map<Ice::Identity, ObjectRequestPtr>::iterator p = _objectRequests.find(id);
- if(p == _objectRequests.end())
- {
- p = _objectRequests.insert(make_pair(id, make_shared<ObjectRequest>(shared_from_this(), id, _retryCount))).first;
- }
-
- if(p->second->addCallback(response))
- {
- try
- {
- _lookup->findObjectByIdAsync(_domainId, id, _lookupReply);
- _timer->schedule(p->second, _timeout);
- }
- catch(const Ice::LocalException&)
- {
- p->second->finished(nullptr);
- _objectRequests.erase(p);
- }
- }
-}
-
-void
-LookupI::findAdapter(function<void(const shared_ptr<Ice::ObjectPrx>&)> response, const std::string& adapterId)
-{
- Lock sync(*this);
- map<string, AdapterRequestPtr>::iterator p = _adapterRequests.find(adapterId);
- if(p == _adapterRequests.end())
- {
- p = _adapterRequests.insert(make_pair(adapterId, make_shared<AdapterRequest>(shared_from_this(), adapterId, _retryCount))).first;
- }
-
- if(p->second->addCallback(response))
- {
- try
- {
- _lookup->findAdapterByIdAsync(_domainId, adapterId, _lookupReply);
- _timer->schedule(p->second, _timeout);
- }
- catch(const Ice::LocalException&)
- {
- p->second->finished(0);
- _adapterRequests.erase(p);
- }
- }
-}
+#ifdef ICE_CPP11_MAPPING
+LookupI::findObject(function<void(const shared_ptr<Ice::ObjectPrx>&)> cb, const Ice::Identity& id)
#else
-void
LookupI::findObject(const Ice::AMD_Locator_findObjectByIdPtr& cb, const Ice::Identity& id)
+#endif
{
Lock sync(*this);
map<Ice::Identity, ObjectRequestPtr>::iterator p = _objectRequests.find(id);
if(p == _objectRequests.end())
{
- p = _objectRequests.insert(make_pair(id, new ObjectRequest(this, id, _retryCount))).first;
+ p = _objectRequests.insert(make_pair(id, ICE_MAKE_SHARED(ObjectRequest,
+ ICE_SHARED_FROM_THIS,
+ id,
+ _retryCount))).first;
}
if(p->second->addCallback(cb))
{
try
{
- _lookup->begin_findObjectById(_domainId, id, _lookupReply);
+ 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
+ }
_timer->schedule(p->second, _timeout);
}
catch(const Ice::LocalException&)
{
- p->second->finished(0);
+ p->second->finished(ICE_NULLPTR);
_objectRequests.erase(p);
}
}
}
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
{
Lock sync(*this);
map<string, AdapterRequestPtr>::iterator p = _adapterRequests.find(adapterId);
if(p == _adapterRequests.end())
{
- p = _adapterRequests.insert(make_pair(adapterId, new AdapterRequest(this, adapterId, _retryCount))).first;
+ p = _adapterRequests.insert(make_pair(adapterId, ICE_MAKE_SHARED(AdapterRequest,
+ ICE_SHARED_FROM_THIS,
+ adapterId,
+ _retryCount))).first;
}
if(p->second->addCallback(cb))
{
try
{
- _lookup->begin_findAdapterById(_domainId, adapterId, _lookupReply);
+ 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
+ }
_timer->schedule(p->second, _timeout);
}
catch(const Ice::LocalException&)
{
- p->second->finished(0);
+ p->second->finished(ICE_NULLPTR);
_adapterRequests.erase(p);
}
}
}
-#endif
void
LookupI::foundObject(const Ice::Identity& id, const Ice::ObjectPrxPtr& proxy)
@@ -390,11 +414,15 @@ LookupI::objectRequestTimedOut(const ObjectRequestPtr& request)
{
try
{
+ for(vector<pair<LookupPrxPtr, LookupReplyPrxPtr> >::const_iterator l = _lookup.begin(); l != _lookup.end();
+ ++l)
+ {
#ifdef ICE_CPP11_MAPPING
- _lookup->findObjectByIdAsync(_domainId, request->getId(), _lookupReply);
+ l->first->findObjectByIdAsync(_domainId, request->getId(), l->second);
#else
- _lookup->begin_findObjectById(_domainId, request->getId(), _lookupReply);
+ l->first->begin_findObjectById(_domainId, request->getId(), l->second);
#endif
+ }
_timer->schedule(p->second, _timeout);
return;
}
@@ -422,11 +450,15 @@ LookupI::adapterRequestTimedOut(const AdapterRequestPtr& request)
{
try
{
+ for(vector<pair<LookupPrxPtr, LookupReplyPrxPtr> >::const_iterator l = _lookup.begin(); l != _lookup.end();
+ ++l)
+ {
#ifdef ICE_CPP11_MAPPING
- _lookup->findAdapterByIdAsync(_domainId, request->getId(), _lookupReply);
+ l->first->findAdapterByIdAsync(_domainId, request->getId(), l->second);
#else
- _lookup->begin_findAdapterById(_domainId, request->getId(), _lookupReply);
+ l->first->begin_findAdapterById(_domainId, request->getId(), l->second);
#endif
+ }
_timer->schedule(p->second, _timeout);
return;
}
diff --git a/cpp/src/IceDiscovery/LookupI.h b/cpp/src/IceDiscovery/LookupI.h
index fed98927913..46f582d6118 100644
--- a/cpp/src/IceDiscovery/LookupI.h
+++ b/cpp/src/IceDiscovery/LookupI.h
@@ -255,8 +255,7 @@ public:
private:
LocatorRegistryIPtr _registry;
- const LookupPrxPtr _lookup;
- LookupReplyPrxPtr _lookupReply;
+ std::vector<std::pair<LookupPrxPtr, LookupReplyPrxPtr> > _lookup;
const IceUtil::Time _timeout;
const int _retryCount;
const int _latencyMultiplier;
diff --git a/cpp/src/IceDiscovery/PluginI.cpp b/cpp/src/IceDiscovery/PluginI.cpp
index 2275459c04f..fa6e65bc5b2 100644
--- a/cpp/src/IceDiscovery/PluginI.cpp
+++ b/cpp/src/IceDiscovery/PluginI.cpp
@@ -9,6 +9,7 @@
#include <IceUtil/IceUtil.h>
#include <Ice/Ice.h>
+#include <Ice/Network.h> // For getInterfacesForMulticast
#include <IceDiscovery/PluginI.h>
#include <IceDiscovery/LocatorI.h>
@@ -87,16 +88,33 @@ PluginI::initialize()
}
properties->setProperty("IceDiscovery.Multicast.Endpoints", os.str());
}
- if(properties->getProperty("IceDiscovery.Reply.Endpoints").empty())
+
+ string lookupEndpoints = properties->getProperty("IceDiscovery.Lookup");
+ if(lookupEndpoints.empty())
{
- ostringstream os;
- os << "udp";
- if(!intf.empty())
+ //
+ // If no lookup endpoints are specified, we get all the network interfaces and create
+ // an endpoint for each of them. We'll send UDP multicast packages on each interface.
+ //
+ IceInternal::ProtocolSupport protocol = ipv4 && !preferIPv6 ? IceInternal::EnableIPv4 : IceInternal::EnableIPv6;
+ vector<string> interfaces = IceInternal::getInterfacesForMulticast(intf, protocol);
+ ostringstream lookup;
+ for(vector<string>::const_iterator p = interfaces.begin(); p != interfaces.end(); ++p)
{
- os << " -h \"" << intf << "\"";
+ if(p != interfaces.begin())
+ {
+ lookup << ":";
+ }
+ lookup << "udp -h \"" << address << "\" -p " << port << " --interface \"" << *p << "\"";
}
- properties->setProperty("IceDiscovery.Reply.Endpoints", os.str());
+ lookupEndpoints = lookup.str();
}
+
+ if(properties->getProperty("IceDiscovery.Reply.Endpoints").empty())
+ {
+ properties->setProperty("IceDiscovery.Reply.Endpoints", "udp -h " + (intf.empty() ? "*" : "\"" + intf + "\""));
+ }
+
if(properties->getProperty("IceDiscovery.Locator.Endpoints").empty())
{
properties->setProperty("IceDiscovery.Locator.AdapterId", Ice::generateUUID());
@@ -113,42 +131,8 @@ PluginI::initialize()
Ice::LocatorRegistryPrxPtr locatorRegistryPrx =
ICE_UNCHECKED_CAST(Ice::LocatorRegistryPrx, _locatorAdapter->addWithUUID(locatorRegistry));
- string lookupEndpoints = properties->getProperty("IceDiscovery.Lookup");
- if(lookupEndpoints.empty())
- {
- ostringstream os;
- os << "udp -h \"" << address << "\" -p " << port;
- if(!intf.empty())
- {
- os << " --interface \"" << intf << "\"";
- }
- lookupEndpoints = os.str();
- }
-
Ice::ObjectPrxPtr lookupPrx = _communicator->stringToProxy("IceDiscovery/Lookup -d:" + lookupEndpoints);
lookupPrx = lookupPrx->ice_collocationOptimized(false); // No collocation optimization for the multicast proxy!
- try
- {
- // Ensure we can establish a connection to the multicast proxy
- // but don't block.
-#ifdef ICE_CPP11_MAPPING
- lookupPrx->ice_getConnection();
-#else
- Ice::AsyncResultPtr result = lookupPrx->begin_ice_getConnection();
- if(result->sentSynchronously())
- {
- lookupPrx->end_ice_getConnection(result);
- }
-#endif
- }
- catch(const Ice::LocalException& ex)
- {
- ostringstream os;
- os << "IceDiscovery is unable to establish a multicast connection:\n";
- os << "proxy = " << lookupPrx << '\n';
- os << ex;
- throw Ice::PluginInitializationException(__FILE__, __LINE__, os.str());
- }
//
// Add lookup and lookup reply Ice objects
diff --git a/cpp/src/IceGrid/Client.cpp b/cpp/src/IceGrid/Client.cpp
index 35721f3cf74..3473bdb72ca 100644
--- a/cpp/src/IceGrid/Client.cpp
+++ b/cpp/src/IceGrid/Client.cpp
@@ -21,7 +21,7 @@
#include <IceGrid/Parser.h>
#include <IceGrid/FileParserI.h>
#include <IceGrid/Registry.h>
-#include <IceGrid/IceLocatorDiscovery.h>
+#include <IceLocatorDiscovery/Plugin.h>
#include <Glacier2/Router.h>
#include <fstream>
@@ -68,74 +68,6 @@ public:
Init init;
-class LookupReplyI : public LookupReply, private IceUtil::Monitor<IceUtil::Mutex>
-{
-public:
-
- virtual void
- foundLocator(const Ice::LocatorPrx& locator, const Ice::Current&)
- {
- Lock sync(*this);
- for(vector<Ice::LocatorPrx>::iterator p = _locators.begin(); p != _locators.end(); ++p)
- {
- if((*p)->ice_getIdentity() == locator->ice_getIdentity())
- {
- Ice::EndpointSeq newEndpoints = (*p)->ice_getEndpoints();
- Ice::EndpointSeq endpts = locator->ice_getEndpoints();
- for(Ice::EndpointSeq::const_iterator r = endpts.begin(); r != endpts.end(); ++r)
- {
- //
- // Only add unknown endpoints
- //
- bool found = false;
- for(Ice::EndpointSeq::const_iterator q = newEndpoints.begin(); q != newEndpoints.end(); ++q)
- {
- if(*r == *q)
- {
- found = true;
- break;
- }
- }
- if(!found)
- {
- newEndpoints.push_back(*r);
- }
- }
- *p = (*p)->ice_endpoints(newEndpoints);
- return;
- }
- }
- _locators.push_back(locator);
- notify();
- }
-
- vector<Ice::LocatorPrx>
- getLocators()
- {
- Lock sync(*this);
- return _locators;
- }
-
- bool
- waitForLocator()
- {
- Lock sync(*this);
- while(_locators.empty())
- {
- if(!timedWait(IceUtil::Time::milliSeconds(300)))
- {
- return false;
- }
- }
- return true;
- }
-
-private:
-
- vector<Ice::LocatorPrx> _locators;
-};
-typedef IceUtil::Handle<LookupReplyI> LookupReplyIPtr;
-
}
class SessionKeepAliveThread : public IceUtil::Thread, public IceUtil::Monitor<IceUtil::Mutex>
@@ -297,6 +229,8 @@ Client::usage()
;
}
+extern "C" ICE_LOCATOR_DISCOVERY_API Ice::Plugin*
+createIceLocatorDiscovery(const Ice::CommunicatorPtr&, const string&, const Ice::StringSeq&);
int
Client::main(StringSeq& args)
@@ -539,74 +473,17 @@ Client::run(StringSeq& originalArgs)
}
else
{
- bool ipv4 = properties->getPropertyAsIntWithDefault("Ice.IPv4", 1) > 0;
- string address;
- bool preferIPv6 = properties->getPropertyAsInt("Ice.PreferIPv6Address") > 0;
- if(ipv4 && !preferIPv6)
- {
- address = properties->getPropertyWithDefault("IceGridAdmin.Discovery.Address", "239.255.0.1");
- }
- else
- {
- address = properties->getPropertyWithDefault("IceGridAdmin.Discovery.Address", "ff15::1");
- }
-
- string interface = properties->getProperty("IceGridAdmin.Discovery.Interface");
-
- string lookupEndpoints = properties->getProperty("IceGridAdmin.Discovery.Lookup");
- if(lookupEndpoints.empty())
- {
- ostringstream os;
- os << "udp -h \"" << address << "\" -p " << (port == 0 ? 4061 : port);
- if(!interface.empty())
- {
- os << " --interface \"" << interface << "\"";
- }
- lookupEndpoints = os.str();
- }
-
- ObjectPrx prx = communicator()->stringToProxy("IceLocatorDiscovery/Lookup -d:" + lookupEndpoints);
- LookupPrx lookupPrx = LookupPrx::uncheckedCast(prx->ice_collocationOptimized(false));
-
- if(properties->getProperty("IceGridAdmin.Discovery.Reply.Endpoints").empty())
- {
- ostringstream os;
- os << "udp";
- if(!interface.empty())
- {
- os << " -h \"" << interface << "\"";
- }
- properties->setProperty("IceGridAdmin.Discovery.Reply.Endpoints", os.str());
- }
-
- Ice::ObjectAdapterPtr adapter = communicator()->createObjectAdapter("IceGridAdmin.Discovery.Reply");
- adapter->activate();
- LookupReplyIPtr reply = new LookupReplyI();
- LookupReplyPrx replyPrx = LookupReplyPrx::uncheckedCast(adapter->addWithUUID(reply)->ice_datagram());
- int retryCount = 3; // Send several findLocator queries.
- try
- {
- while(--retryCount >= 0)
- {
- lookupPrx->findLocator(instanceName, replyPrx);
- if(instanceName.empty())
- {
- IceUtil::ThreadControl::sleep(IceUtil::Time::milliSeconds(300));
- }
- else if(reply->waitForLocator())
- {
- break;
- }
- }
- }
- catch(const Ice::LocalException& ex)
- {
- consoleErr << _appName << ": registry discovery failed:\n" << ex << endl;
- return EXIT_FAILURE;
- }
- adapter->destroy();
+ //
+ // NOTE: we don't configure the plugin with the Ice communicator on initialization
+ // because it would install a default locator. Instead, we create the plugin here
+ // to lookup for locator proxies. We destroy the plugin, once we have selected a
+ // locator.
+ //
+ Ice::PluginPtr p = createIceLocatorDiscovery(communicator(), "IceGridAdmin.Discovery", Ice::StringSeq());
+ IceLocatorDiscovery::PluginPtr plugin = IceLocatorDiscovery::PluginPtr::dynamicCast(p);
+ plugin->initialize();
- vector<Ice::LocatorPrx> locators = reply->getLocators();
+ vector<Ice::LocatorPrx> locators = plugin->getLocators(instanceName, IceUtil::Time::milliSeconds(300));
if(locators.size() > 1)
{
consoleOut << "found " << locators.size() << " Ice locators:" << endl;
@@ -644,6 +521,15 @@ Client::run(StringSeq& originalArgs)
consoleOut << "using discovered locator:\nproxy = `" << locators[0] << "'" << endl;
communicator()->setDefaultLocator(locators[0]);
}
+ else
+ {
+ communicator()->setDefaultLocator(0);
+ }
+
+ //
+ // Destroy the plugin, we no longer need it.
+ //
+ plugin->destroy();
}
}
diff --git a/cpp/src/IceGrid/Makefile.mk b/cpp/src/IceGrid/Makefile.mk
index 4e14f08b10b..c3ab9e190a2 100644
--- a/cpp/src/IceGrid/Makefile.mk
+++ b/cpp/src/IceGrid/Makefile.mk
@@ -78,9 +78,8 @@ icegridregistry_sources := $(addprefix $(currentdir)/,$(local_registry_srcs) I
icegridregistry_dependencies := IceBox IceStormService IceStorm IceXML IceSSL IcePatch2 IceDB $(local_dependencies)
icegridregistry_cppflags := $(if $(lmdb_includedir),-I$(lmdb_includedir))
-icegridadmin_dependencies := IcePatch2 IceBox IceXML
-icegridadmin_sources := $(slicedir)/IceLocatorDiscovery/IceLocatorDiscovery.ice \
- $(addprefix $(currentdir)/,$(local_admin_srcs))
+icegridadmin_dependencies := IcePatch2 IceBox IceXML IceLocatorDiscovery
+icegridadmin_sources := $(addprefix $(currentdir)/,$(local_admin_srcs))
projects += $(project)
diff --git a/cpp/src/IceGrid/msbuild/icegridadmin/icegridadmin.vcxproj b/cpp/src/IceGrid/msbuild/icegridadmin/icegridadmin.vcxproj
index bbc62f79b1c..65ef495834a 100644
--- a/cpp/src/IceGrid/msbuild/icegridadmin/icegridadmin.vcxproj
+++ b/cpp/src/IceGrid/msbuild/icegridadmin/icegridadmin.vcxproj
@@ -105,41 +105,21 @@
<ClCompile Include="..\..\Parser.cpp" />
<ClCompile Include="..\..\Scanner.cpp" />
<ClCompile Include="..\..\Util.cpp" />
- <ClCompile Include="Win32\Debug\IceLocatorDiscovery.cpp">
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
- </ClCompile>
<ClCompile Include="Win32\Debug\Internal.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
- <ClCompile Include="Win32\Release\IceLocatorDiscovery.cpp">
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
- </ClCompile>
<ClCompile Include="Win32\Release\Internal.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
- <ClCompile Include="x64\Debug\IceLocatorDiscovery.cpp">
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
- </ClCompile>
<ClCompile Include="x64\Debug\Internal.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
- <ClCompile Include="x64\Release\IceLocatorDiscovery.cpp">
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
- </ClCompile>
<ClCompile Include="x64\Release\Internal.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
@@ -147,45 +127,24 @@
</ClCompile>
</ItemGroup>
<ItemGroup>
- <IceBuilder Include="..\..\..\..\..\slice\IceLocatorDiscovery\IceLocatorDiscovery.ice" />
<IceBuilder Include="..\..\Internal.ice" />
</ItemGroup>
<ItemGroup>
- <ClInclude Include="Win32\Debug\IceGrid\IceLocatorDiscovery.h">
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
- </ClInclude>
<ClInclude Include="Win32\Debug\IceGrid\Internal.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClInclude>
- <ClInclude Include="Win32\Release\IceGrid\IceLocatorDiscovery.h">
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
- </ClInclude>
<ClInclude Include="Win32\Release\IceGrid\Internal.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClInclude>
- <ClInclude Include="x64\Debug\IceGrid\IceLocatorDiscovery.h">
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
- </ClInclude>
<ClInclude Include="x64\Debug\IceGrid\Internal.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClInclude>
- <ClInclude Include="x64\Release\IceGrid\IceLocatorDiscovery.h">
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
- <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
- </ClInclude>
<ClInclude Include="x64\Release\IceGrid\Internal.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
diff --git a/cpp/src/IceGrid/msbuild/icegridadmin/icegridadmin.vcxproj.filters b/cpp/src/IceGrid/msbuild/icegridadmin/icegridadmin.vcxproj.filters
index fc0cc2249bc..d63f7b210fc 100644
--- a/cpp/src/IceGrid/msbuild/icegridadmin/icegridadmin.vcxproj.filters
+++ b/cpp/src/IceGrid/msbuild/icegridadmin/icegridadmin.vcxproj.filters
@@ -82,61 +82,34 @@
<ClCompile Include="..\..\Util.cpp">
<Filter>Source Files</Filter>
</ClCompile>
- <ClCompile Include="Win32\Debug\IceLocatorDiscovery.cpp">
- <Filter>Source Files\Win32\Debug</Filter>
- </ClCompile>
<ClCompile Include="Win32\Debug\Internal.cpp">
<Filter>Source Files\Win32\Debug</Filter>
</ClCompile>
- <ClCompile Include="x64\Debug\IceLocatorDiscovery.cpp">
- <Filter>Source Files\x64\Debug</Filter>
- </ClCompile>
<ClCompile Include="x64\Debug\Internal.cpp">
<Filter>Source Files\x64\Debug</Filter>
</ClCompile>
- <ClCompile Include="Win32\Release\IceLocatorDiscovery.cpp">
- <Filter>Source Files\Win32\Release</Filter>
- </ClCompile>
<ClCompile Include="Win32\Release\Internal.cpp">
<Filter>Source Files\Win32\Release</Filter>
</ClCompile>
- <ClCompile Include="x64\Release\IceLocatorDiscovery.cpp">
- <Filter>Source Files\x64\Release</Filter>
- </ClCompile>
<ClCompile Include="x64\Release\Internal.cpp">
<Filter>Source Files\x64\Release</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
- <IceBuilder Include="..\..\..\..\..\slice\IceLocatorDiscovery\IceLocatorDiscovery.ice">
- <Filter>Slice Files</Filter>
- </IceBuilder>
<IceBuilder Include="..\..\Internal.ice">
<Filter>Slice Files</Filter>
</IceBuilder>
</ItemGroup>
<ItemGroup>
- <ClInclude Include="Win32\Debug\IceGrid\IceLocatorDiscovery.h">
- <Filter>Header Files\Win32\Debug</Filter>
- </ClInclude>
<ClInclude Include="Win32\Debug\IceGrid\Internal.h">
<Filter>Header Files\Win32\Debug</Filter>
</ClInclude>
- <ClInclude Include="x64\Debug\IceGrid\IceLocatorDiscovery.h">
- <Filter>Header Files\x64\Debug</Filter>
- </ClInclude>
<ClInclude Include="x64\Debug\IceGrid\Internal.h">
<Filter>Header Files\x64\Debug</Filter>
</ClInclude>
- <ClInclude Include="Win32\Release\IceGrid\IceLocatorDiscovery.h">
- <Filter>Header Files\Win32\Release</Filter>
- </ClInclude>
<ClInclude Include="Win32\Release\IceGrid\Internal.h">
<Filter>Header Files\Win32\Release</Filter>
</ClInclude>
- <ClInclude Include="x64\Release\IceGrid\IceLocatorDiscovery.h">
- <Filter>Header Files\x64\Release</Filter>
- </ClInclude>
<ClInclude Include="x64\Release\IceGrid\Internal.h">
<Filter>Header Files\x64\Release</Filter>
</ClInclude>
diff --git a/cpp/src/IceLocatorDiscovery/Plugin.h b/cpp/src/IceLocatorDiscovery/Plugin.h
new file mode 100644
index 00000000000..f9e02b1166a
--- /dev/null
+++ b/cpp/src/IceLocatorDiscovery/Plugin.h
@@ -0,0 +1,52 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef LOCATOR_DISCOVERY_PLUGIN_I_H
+#define LOCATOR_DISCOVERY_PLUGIN_I_H
+
+#include <Ice/Config.h>
+#include <Ice/Plugin.h>
+#include <Ice/Locator.h>
+#include <IceUtil/Time.h>
+
+//
+// Automatically link IceLocatorDiscovery[D|++11|++11D].lib with Visual C++
+//
+#if !defined(ICE_BUILDING_ICE_LOCATOR_DISCOVERY) && defined(ICE_LOCATOR_DISCOVERY_API_EXPORTS)
+# define ICE_BUILDING_ICE_LOCATOR_DISCOVERY
+#endif
+
+#if defined(_MSC_VER) && !defined(ICE_BUILDING_ICE_LOCATOR_DISCOVERY)
+# pragma comment(lib, ICE_LIBNAME("IceLocatorDiscovery"))
+#endif
+
+#ifndef ICE_LOCATOR_DISCOVERY_API
+# if defined(ICE_STATIC_LIBS)
+# define ICE_LOCATOR_DISCOVERY_API /**/
+# elif defined(ICE_LOCATOR_DISCOVERY_API_EXPORTS)
+# define ICE_LOCATOR_DISCOVERY_API ICE_DECLSPEC_EXPORT
+# else
+# define ICE_LOCATOR_DISCOVERY_API ICE_DECLSPEC_IMPORT
+# endif
+#endif
+
+namespace IceLocatorDiscovery
+{
+
+class ICE_LOCATOR_DISCOVERY_API Plugin : public Ice::Plugin
+{
+public:
+
+ virtual std::vector<Ice::LocatorPrxPtr> getLocators(const std::string&, const IceUtil::Time&) const = 0;
+};
+ICE_DEFINE_PTR(PluginPtr, Plugin);
+
+};
+
+#endif
diff --git a/cpp/src/IceLocatorDiscovery/PluginI.cpp b/cpp/src/IceLocatorDiscovery/PluginI.cpp
index d68d4eacf34..7948fa13870 100644
--- a/cpp/src/IceLocatorDiscovery/PluginI.cpp
+++ b/cpp/src/IceLocatorDiscovery/PluginI.cpp
@@ -9,50 +9,14 @@
#include <IceUtil/IceUtil.h>
#include <Ice/Ice.h>
+#include <Ice/Network.h> // For getInterfacesForMulticast
-#include <IceLocatorDiscovery/PluginI.h>
+#include <IceLocatorDiscovery/Plugin.h>
#include <IceLocatorDiscovery/IceLocatorDiscovery.h>
using namespace std;
using namespace IceLocatorDiscovery;
-#ifndef ICE_LOCATOR_DISCOVERY_API
-# ifdef ICE_LOCATOR_DISCOVERY_API_EXPORTS
-# define ICE_LOCATOR_DISCOVERY_API ICE_DECLSPEC_EXPORT
-# else
-# define ICE_LOCATOR_DISCOVERY_API /**/
-# endif
-#endif
-
-//
-// Plugin factory function.
-//
-extern "C" ICE_LOCATOR_DISCOVERY_API Ice::Plugin*
-createIceLocatorDiscovery(const Ice::CommunicatorPtr& communicator, const string&, const Ice::StringSeq&)
-{
- return new PluginI(communicator);
-}
-
-namespace Ice
-{
-
-ICE_LOCATOR_DISCOVERY_API void
-registerIceLocatorDiscovery(bool loadOnInitialize)
-{
- Ice::registerPluginFactory("IceLocatorDiscovery", createIceLocatorDiscovery, loadOnInitialize);
-}
-
-}
-
-//
-// Objective-C function to allow Objective-C programs to register plugin.
-//
-extern "C" ICE_LOCATOR_DISCOVERY_API void
-ICEregisterIceLocatorDiscovery(bool loadOnInitialize)
-{
- Ice::registerIceLocatorDiscovery(loadOnInitialize);
-}
-
namespace
{
@@ -136,7 +100,7 @@ class LocatorI : public Ice::BlobjectArrayAsync,
{
public:
- LocatorI(const LookupPrxPtr&, const Ice::PropertiesPtr&, const string&, const Ice::LocatorPrxPtr&);
+ LocatorI(const string&, const LookupPrxPtr&, const Ice::PropertiesPtr&, const string&, const Ice::LocatorPrxPtr&);
void setLookupReply(const LookupReplyPrxPtr&);
#ifdef ICE_CPP11_MAPPING
@@ -152,11 +116,13 @@ public:
void foundLocator(const Ice::LocatorPrxPtr&);
void invoke(const Ice::LocatorPrxPtr&, const RequestPtr&);
+ vector<Ice::LocatorPrxPtr> getLocators(const string&, const IceUtil::Time&);
+
private:
virtual void runTimerTask();
- const LookupPrxPtr _lookup;
+ vector<pair<LookupPrxPtr, LookupReplyPrxPtr> > _lookup;
const IceUtil::Time _timeout;
const int _retryCount;
const IceUtil::Time _retryDelay;
@@ -164,8 +130,8 @@ private:
string _instanceName;
bool _warned;
- LookupReplyPrxPtr _lookupReply;
Ice::LocatorPrxPtr _locator;
+ map<string, Ice::LocatorPrxPtr> _locators;
Ice::LocatorPrxPtr _voidLocator;
IceUtil::Time _nextRetry;
@@ -246,9 +212,58 @@ public:
}
};
+class PluginI : public Plugin
+{
+public:
+
+ PluginI(const std::string&, const Ice::CommunicatorPtr&);
+
+ virtual void initialize();
+ virtual void destroy();
+ virtual vector<Ice::LocatorPrxPtr> getLocators(const string&, const IceUtil::Time&) const;
+
+private:
+
+ const string _name;
+ const Ice::CommunicatorPtr _communicator;
+ Ice::ObjectAdapterPtr _locatorAdapter;
+ Ice::ObjectAdapterPtr _replyAdapter;
+ LocatorIPtr _locator;
+};
+
+}
+
+//
+// Plugin factory function.
+//
+extern "C" ICE_LOCATOR_DISCOVERY_API Ice::Plugin*
+createIceLocatorDiscovery(const Ice::CommunicatorPtr& communicator, const string& name, const Ice::StringSeq&)
+{
+ return new PluginI(name, communicator);
+}
+
+namespace Ice
+{
+
+ICE_LOCATOR_DISCOVERY_API void
+registerIceLocatorDiscovery(bool loadOnInitialize)
+{
+ Ice::registerPluginFactory("IceLocatorDiscovery", createIceLocatorDiscovery, loadOnInitialize);
+}
+
}
-PluginI::PluginI(const Ice::CommunicatorPtr& communicator) : _communicator(communicator)
+//
+// Objective-C function to allow Objective-C programs to register plugin.
+//
+extern "C" ICE_LOCATOR_DISCOVERY_API void
+ICEregisterIceLocatorDiscovery(bool loadOnInitialize)
+{
+ Ice::registerIceLocatorDiscovery(loadOnInitialize);
+}
+
+PluginI::PluginI(const string& name, const Ice::CommunicatorPtr& communicator) :
+ _name(name), _communicator(communicator)
{
}
@@ -262,109 +277,80 @@ PluginI::initialize()
string address;
if(ipv4 && !preferIPv6)
{
- address = properties->getPropertyWithDefault("IceLocatorDiscovery.Address", "239.255.0.1");
+ address = properties->getPropertyWithDefault(_name + ".Address", "239.255.0.1");
}
else
{
- address = properties->getPropertyWithDefault("IceLocatorDiscovery.Address", "ff15::1");
+ address = properties->getPropertyWithDefault(_name + ".Address", "ff15::1");
}
- int port = properties->getPropertyAsIntWithDefault("IceLocatorDiscovery.Port", 4061);
- string intf = properties->getProperty("IceLocatorDiscovery.Interface");
+ int port = properties->getPropertyAsIntWithDefault(_name + ".Port", 4061);
+ string intf = properties->getProperty(_name + ".Interface");
- if(properties->getProperty("IceLocatorDiscovery.Reply.Endpoints").empty())
+ string lookupEndpoints = properties->getProperty(_name + ".Lookup");
+ if(lookupEndpoints.empty())
{
- ostringstream os;
- os << "udp";
- if(!intf.empty())
+ //
+ // If no lookup endpoints are specified, we get all the network interfaces and create
+ // an endpoint for each of them. We'll send UDP multicast packages on each interface.
+ //
+ IceInternal::ProtocolSupport protocol = ipv4 && !preferIPv6 ? IceInternal::EnableIPv4 : IceInternal::EnableIPv6;
+ vector<string> interfaces = IceInternal::getInterfacesForMulticast(intf, protocol);
+ ostringstream lookup;
+ for(vector<string>::const_iterator p = interfaces.begin(); p != interfaces.end(); ++p)
{
- os << " -h \"" << intf << "\"";
+ if(p != interfaces.begin())
+ {
+ lookup << ":";
+ }
+ lookup << "udp -h \"" << address << "\" -p " << port << " --interface \"" << *p << "\"";
}
- properties->setProperty("IceLocatorDiscovery.Reply.Endpoints", os.str());
+ lookupEndpoints = lookup.str();
+ }
+
+ if(properties->getProperty(_name + ".Reply.Endpoints").empty())
+ {
+ properties->setProperty(_name + ".Reply.Endpoints", "udp -h " + (intf.empty() ? "*" : "\"" + intf + "\""));
}
- if(properties->getProperty("IceLocatorDiscovery.Locator.Endpoints").empty())
+
+ if(properties->getProperty(_name + ".Locator.Endpoints").empty())
{
- properties->setProperty("IceLocatorDiscovery.Locator.AdapterId", Ice::generateUUID()); // Collocated adapter
+ properties->setProperty(_name + ".Locator.AdapterId", Ice::generateUUID()); // Collocated adapter
}
- _replyAdapter = _communicator->createObjectAdapter("IceLocatorDiscovery.Reply");
- _locatorAdapter = _communicator->createObjectAdapter("IceLocatorDiscovery.Locator");
+ _replyAdapter = _communicator->createObjectAdapter(_name + ".Reply");
+ _locatorAdapter = _communicator->createObjectAdapter(_name + ".Locator");
// We don't want those adapters to be registered with the locator so clear their locator.
_replyAdapter->setLocator(0);
_locatorAdapter->setLocator(0);
- string lookupEndpoints = properties->getProperty("IceLocatorDiscovery.Lookup");
- if(lookupEndpoints.empty())
- {
- ostringstream os;
- os << "udp -h \"" << address << "\" -p " << port;
- if(!intf.empty())
- {
- os << " --interface \"" << intf << "\"";
- }
- lookupEndpoints = os.str();
- }
-
Ice::ObjectPrxPtr lookupPrx = _communicator->stringToProxy("IceLocatorDiscovery/Lookup -d:" + lookupEndpoints);
lookupPrx = lookupPrx->ice_collocationOptimized(false); // No collocation optimization for the multicast proxy!
- try
- {
- // Ensure we can establish a connection to the multicast proxy
- // but don't block.
-#ifdef ICE_CPP11_MAPPING
- promise<bool> sent;
- promise<void> completed;
-
- lookupPrx->ice_getConnectionAsync(
- [&](shared_ptr<Ice::Connection>)
- {
- completed.set_value();
- },
- [&](exception_ptr ex)
- {
- completed.set_exception(ex);
- },
- [&](bool sentSynchronously)
- {
- sent.set_value(sentSynchronously);
- });
- if(sent.get_future().get())
- {
- completed.get_future().get();
- }
-#else
- Ice::AsyncResultPtr result = lookupPrx->begin_ice_getConnection();
- if(result->sentSynchronously())
- {
- lookupPrx->end_ice_getConnection(result);
- }
-#endif
- }
- catch(const Ice::LocalException& ex)
- {
- ostringstream os;
- os << "IceLocatorDiscovery is unable to establish a multicast connection:\n";
- os << "proxy = " << lookupPrx << '\n';
- os << ex;
- throw Ice::PluginInitializationException(__FILE__, __LINE__, os.str());
- }
- Ice::LocatorPrxPtr voidLocator = ICE_UNCHECKED_CAST(Ice::LocatorPrx, _locatorAdapter->addWithUUID(ICE_MAKE_SHARED(VoidLocatorI)));
+ Ice::LocatorPrxPtr voidLocator = ICE_UNCHECKED_CAST(Ice::LocatorPrx,
+ _locatorAdapter->addWithUUID(ICE_MAKE_SHARED(VoidLocatorI)));
- string instanceName = properties->getProperty("IceLocatorDiscovery.InstanceName");
+ string instanceName = properties->getProperty(_name + ".InstanceName");
Ice::Identity id;
id.name = "Locator";
id.category = !instanceName.empty() ? instanceName : Ice::generateUUID();
- LocatorIPtr locator = ICE_MAKE_SHARED(LocatorI, ICE_UNCHECKED_CAST(LookupPrx, lookupPrx), properties, instanceName, voidLocator);
- _communicator->setDefaultLocator(ICE_UNCHECKED_CAST(Ice::LocatorPrx, _locatorAdapter->add(locator, id)));
+ _locator = ICE_MAKE_SHARED(LocatorI, _name, ICE_UNCHECKED_CAST(LookupPrx, lookupPrx), properties, instanceName,
+ voidLocator);
+ _communicator->setDefaultLocator(ICE_UNCHECKED_CAST(Ice::LocatorPrx, _locatorAdapter->add(_locator, id)));
- Ice::ObjectPrxPtr lookupReply = _replyAdapter->addWithUUID(ICE_MAKE_SHARED(LookupReplyI, locator))->ice_datagram();
- locator->setLookupReply(ICE_UNCHECKED_CAST(LookupReplyPrx, lookupReply));
+ Ice::ObjectPrxPtr lookupReply = _replyAdapter->addWithUUID(ICE_MAKE_SHARED(LookupReplyI, _locator))->ice_datagram();
+ _locator->setLookupReply(ICE_UNCHECKED_CAST(LookupReplyPrx, lookupReply));
_replyAdapter->activate();
_locatorAdapter->activate();
}
+vector<Ice::LocatorPrxPtr>
+PluginI::getLocators(const string& instanceName, const IceUtil::Time& waitTime) const
+{
+ return _locator->getLocators(instanceName, waitTime);
+}
+
void
PluginI::destroy()
{
@@ -545,14 +531,14 @@ Request::exception(const Ice::Exception& ex)
#endif
}
-LocatorI::LocatorI(const LookupPrxPtr& lookup,
+LocatorI::LocatorI(const string& name,
+ const LookupPrxPtr& lookup,
const Ice::PropertiesPtr& p,
const string& instanceName,
const Ice::LocatorPrxPtr& voidLocator) :
- _lookup(lookup),
- _timeout(IceUtil::Time::milliSeconds(p->getPropertyAsIntWithDefault("IceLocatorDiscovery.Timeout", 300))),
- _retryCount(p->getPropertyAsIntWithDefault("IceLocatorDiscovery.RetryCount", 3)),
- _retryDelay(IceUtil::Time::milliSeconds(p->getPropertyAsIntWithDefault("IceLocatorDiscovery.RetryDelay", 2000))),
+ _timeout(IceUtil::Time::milliSeconds(p->getPropertyAsIntWithDefault(name + ".Timeout", 300))),
+ _retryCount(p->getPropertyAsIntWithDefault(name + ".RetryCount", 3)),
+ _retryDelay(IceUtil::Time::milliSeconds(p->getPropertyAsIntWithDefault(name + ".RetryDelay", 2000))),
_timer(IceInternal::getInstanceTimer(lookup->ice_getCommunicator())),
_instanceName(instanceName),
_warned(false),
@@ -560,12 +546,77 @@ LocatorI::LocatorI(const LookupPrxPtr& lookup,
_voidLocator(voidLocator),
_pendingRetryCount(0)
{
+#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.
+ //
+ 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&)
+ {
+ }
+ }
+ assert(!_lookup.empty());
+#ifndef ICE_CPP11_MAPPING
+ __setNoDelete(false);
+#endif
}
void
LocatorI::setLookupReply(const LookupReplyPrxPtr& lookupReply)
{
- _lookupReply = 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)
+ {
+ Ice::UDPEndpointInfoPtr info = ICE_DYNAMIC_CAST(Ice::UDPEndpointInfo, p->first->ice_getEndpoints()[0]->getInfo());
+ if(info && !info->mcastInterface.empty())
+ {
+ Ice::EndpointSeq endpts = lookupReply->ice_getEndpoints();
+ for(Ice::EndpointSeq::const_iterator q = endpts.begin(); q != endpts.end(); ++q)
+ {
+ Ice::IPEndpointInfoPtr r = ICE_DYNAMIC_CAST(Ice::IPEndpointInfo, (*q)->getInfo());
+ if(r && r->host == info->mcastInterface)
+ {
+ Ice::EndpointSeq single;
+ single.push_back(*q);
+ p->second = lookupReply->ice_endpoints(single);
+ }
+ }
+ }
+
+ if(!p->second)
+ {
+ p->second = lookupReply; // Fallback: just use the given lookup reply proxy if no matching endpoint found.
+ }
+ }
}
#ifdef ICE_CPP11_MAPPING
@@ -588,6 +639,50 @@ LocatorI::ice_invoke_async(const Ice::AMD_Object_ice_invokePtr& amdCB,
}
#endif
+vector<Ice::LocatorPrxPtr>
+LocatorI::getLocators(const string& instanceName, const IceUtil::Time& waitTime)
+{
+ //
+ // Clear locators from previous search
+ //
+ {
+ Lock sync(*this);
+ _locators.clear();
+ }
+
+ //
+ // Find a locator
+ //
+ invoke(ICE_NULLPTR, ICE_NULLPTR);
+
+ //
+ // Wait for responses
+ //
+ if(instanceName.empty())
+ {
+ IceUtil::ThreadControl::sleep(waitTime);
+ }
+ else
+ {
+ Lock sync(*this);
+ while(_locators.find(instanceName) == _locators.end() && _pendingRetryCount > 0)
+ {
+ timedWait(waitTime);
+ }
+ }
+
+ //
+ // Return found locators
+ //
+ Lock sync(*this);
+ vector<Ice::LocatorPrxPtr> locators;
+ for(map<string, Ice::LocatorPrxPtr>::const_iterator p = _locators.begin(); p != _locators.end(); ++p)
+ {
+ locators.push_back(p->second);
+ }
+ return locators;
+}
+
void
LocatorI::foundLocator(const Ice::LocatorPrxPtr& locator)
{
@@ -601,7 +696,8 @@ LocatorI::foundLocator(const Ice::LocatorPrxPtr& locator)
// If we already have a locator assigned, ensure the given locator
// has the same identity, otherwise ignore it.
//
- if(_locator && locator->ice_getIdentity().category != _locator->ice_getIdentity().category)
+ if(!_pendingRequests.empty() &&
+ _locator && locator->ice_getIdentity().category != _locator->ice_getIdentity().category)
{
if(!_warned)
{
@@ -624,13 +720,14 @@ LocatorI::foundLocator(const Ice::LocatorPrxPtr& locator)
_pendingRetryCount = 0;
}
- if(_locator)
+ Ice::LocatorPrxPtr l = _pendingRequests.empty() ? _locators[locator->ice_getIdentity().category] : _locator;
+ if(l)
{
//
// We found another locator replica, append its endpoints to the
// current locator proxy endpoints.
//
- Ice::EndpointSeq newEndpoints = _locator->ice_getEndpoints();
+ Ice::EndpointSeq newEndpoints = l->ice_getEndpoints();
Ice::EndpointSeq endpts = locator->ice_getEndpoints();
for(Ice::EndpointSeq::const_iterator p = endpts.begin(); p != endpts.end(); ++p)
{
@@ -651,25 +748,35 @@ LocatorI::foundLocator(const Ice::LocatorPrxPtr& locator)
newEndpoints.push_back(*p);
}
}
- _locator = _locator->ice_endpoints(newEndpoints);
+ l = l->ice_endpoints(newEndpoints);
+ }
+ else
+ {
+ l = locator;
+ }
+
+ if(_pendingRequests.empty())
+ {
+ _locators[locator->ice_getIdentity().category] = l;
+ notify();
}
else
{
- _locator = locator;
+ _locator = l;
if(_instanceName.empty())
{
_instanceName = _locator->ice_getIdentity().category; // Stick to the first discovered locator.
}
- }
- //
- // Send pending requests if any.
- //
- for(vector<RequestPtr>::const_iterator p = _pendingRequests.begin(); p != _pendingRequests.end(); ++p)
- {
- (*p)->invoke(_locator);
+ //
+ // Send pending requests if any.
+ //
+ for(vector<RequestPtr>::const_iterator p = _pendingRequests.begin(); p != _pendingRequests.end(); ++p)
+ {
+ (*p)->invoke(_locator);
+ }
+ _pendingRequests.clear();
}
- _pendingRequests.clear();
}
void
@@ -678,28 +785,41 @@ LocatorI::invoke(const Ice::LocatorPrxPtr& locator, const RequestPtr& request)
Lock sync(*this);
if(_locator && _locator != locator)
{
- request->invoke(_locator);
+ if(request)
+ {
+ request->invoke(_locator);
+ }
}
else if(IceUtil::Time::now() < _nextRetry)
{
- request->invoke(_voidLocator); // Don't retry to find a locator before the retry delay expires
+ if(request)
+ {
+ request->invoke(_voidLocator); // Don't retry to find a locator before the retry delay expires
+ }
}
else
{
_locator = 0;
- _pendingRequests.push_back(request);
+ if(request)
+ {
+ _pendingRequests.push_back(request);
+ }
if(_pendingRetryCount == 0) // No request in progress
{
_pendingRetryCount = _retryCount;
try
{
+ for(vector<pair<LookupPrxPtr, LookupReplyPrxPtr> >::const_iterator l = _lookup.begin();
+ l != _lookup.end(); ++l)
+ {
#ifdef ICE_CPP11_MAPPING
- _lookup->findLocatorAsync(_instanceName, _lookupReply); // Send multicast request.
+ l->first->findLocatorAsync(_instanceName, l->second); // Send multicast request.
#else
- _lookup->begin_findLocator(_instanceName, _lookupReply); // Send multicast request.
+ l->first->begin_findLocator(_instanceName, l->second); // Send multicast request.
#endif
+ }
_timer->schedule(ICE_SHARED_FROM_THIS, _timeout);
}
catch(const Ice::LocalException&)
@@ -723,11 +843,15 @@ LocatorI::runTimerTask()
{
try
{
+ for(vector<pair<LookupPrxPtr, LookupReplyPrxPtr> >::const_iterator l = _lookup.begin();
+ l != _lookup.end(); ++l)
+ {
#ifdef ICE_CPP11_MAPPING
- _lookup->findLocatorAsync(_instanceName, _lookupReply); // Send multicast request.
+ l->first->findLocatorAsync(_instanceName, l->second); // Send multicast request.
#else
- _lookup->begin_findLocator(_instanceName, _lookupReply); // Send multicast request.
+ l->first->begin_findLocator(_instanceName, l->second); // Send multicast request.
#endif
+ }
_timer->schedule(ICE_SHARED_FROM_THIS, _timeout);
return;
}
@@ -737,11 +861,18 @@ LocatorI::runTimerTask()
_pendingRetryCount = 0;
}
- for(vector<RequestPtr>::const_iterator p = _pendingRequests.begin(); p != _pendingRequests.end(); ++p)
+ if(_pendingRequests.empty())
+ {
+ notify();
+ }
+ else
{
- (*p)->invoke(_voidLocator); // Send pending requests on void locator.
+ for(vector<RequestPtr>::const_iterator p = _pendingRequests.begin(); p != _pendingRequests.end(); ++p)
+ {
+ (*p)->invoke(_voidLocator); // Send pending requests on void locator.
+ }
+ _pendingRequests.clear();
}
- _pendingRequests.clear();
_nextRetry = IceUtil::Time::now() + _retryDelay; // Only retry when the retry delay expires
}
diff --git a/cpp/src/IceLocatorDiscovery/PluginI.h b/cpp/src/IceLocatorDiscovery/PluginI.h
deleted file mode 100644
index c87b6a9b438..00000000000
--- a/cpp/src/IceLocatorDiscovery/PluginI.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// **********************************************************************
-//
-// Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
-//
-// This copy of Ice is licensed to you under the terms described in the
-// ICE_LICENSE file included in this distribution.
-//
-// **********************************************************************
-
-#ifndef LOCATOR_DISCOVERY_PLUGIN_I_H
-#define LOCATOR_DISCOVERY_PLUGIN_I_H
-
-#include <Ice/Plugin.h>
-
-namespace IceLocatorDiscovery
-{
-
-class PluginI : public Ice::Plugin
-{
-public:
-
- PluginI(const Ice::CommunicatorPtr&);
-
- virtual void initialize();
- virtual void destroy();
-
-private:
-
- const Ice::CommunicatorPtr _communicator;
- Ice::ObjectAdapterPtr _locatorAdapter;
- Ice::ObjectAdapterPtr _replyAdapter;
-};
-
-};
-
-#endif
diff --git a/cpp/test/IceGrid/simple/AllTests.cpp b/cpp/test/IceGrid/simple/AllTests.cpp
index 67c4b41b1f5..fdfbf76ca7a 100644
--- a/cpp/test/IceGrid/simple/AllTests.cpp
+++ b/cpp/test/IceGrid/simple/AllTests.cpp
@@ -71,12 +71,6 @@ allTests(const Ice::CommunicatorPtr& communicator)
initData.properties->setProperty("Ice.Default.Locator", "");
initData.properties->setProperty("Ice.Plugin.IceLocatorDiscovery",
"IceLocatorDiscovery:createIceLocatorDiscovery");
-#ifdef __APPLE__
- if(initData.properties->getPropertyAsInt("Ice.PreferIPv6Address") > 0)
- {
- initData.properties->setProperty("IceLocatorDiscovery.Interface", "::1");
- }
-#endif
{
ostringstream port;
port << getTestPort(initData.properties, 99);
diff --git a/csharp/src/Ice/Network.cs b/csharp/src/Ice/Network.cs
index d9172aa086c..babefa65710 100644
--- a/csharp/src/Ice/Network.cs
+++ b/csharp/src/Ice/Network.cs
@@ -457,7 +457,7 @@ namespace IceInternal
try
{
var indexes = new HashSet<int>();
- foreach(string intf in getInterfacesForMulticast(iface, group))
+ foreach(string intf in getInterfacesForMulticast(iface, getProtocolSupport(group)))
{
int index = getInterfaceIndex(intf, group.AddressFamily);
if(!indexes.Contains(index))
@@ -687,6 +687,11 @@ namespace IceInternal
setBlock(fd, fd.Blocking);
}
+ public static int getProtocolSupport(IPAddress addr)
+ {
+ return addr.AddressFamily == AddressFamily.InterNetwork ? EnableIPv4 : EnableIPv6;
+ }
+
public static EndPoint getAddressForServer(string host, int port, int protocol, bool preferIPv6)
{
if(host.Length == 0)
@@ -951,11 +956,10 @@ namespace IceInternal
return hosts;
}
- public static List<string> getInterfacesForMulticast(string intf, IPAddress group)
+ public static List<string> getInterfacesForMulticast(string intf, int protocol)
{
List<string> interfaces = new List<string>();
bool ipv4Wildcard = false;
- int protocol = group.AddressFamily == AddressFamily.InterNetwork ? EnableIPv4 : EnableIPv6;
if(isWildcard(intf, out ipv4Wildcard))
{
IPAddress[] addrs = getLocalAddresses(ipv4Wildcard ? EnableIPv4 : protocol, true);
diff --git a/csharp/src/Ice/PropertyNames.cs b/csharp/src/Ice/PropertyNames.cs
index 5cfc6aaaab6..b5fa1fec421 100644
--- a/csharp/src/Ice/PropertyNames.cs
+++ b/csharp/src/Ice/PropertyNames.cs
@@ -6,7 +6,7 @@
// ICE_LICENSE file included in this distribution.
//
// **********************************************************************
-// Generated by makeprops.py from file ..\config\PropertyNames.xml, Fri Feb 24 18:49:18 2017
+// Generated by makeprops.py from file ./config/PropertyNames.xml, Tue Feb 28 15:01:12 2017
// IMPORTANT: Do not edit this file -- any edits made here will be lost!
@@ -504,6 +504,43 @@ namespace IceInternal
new Property(@"^IceGridAdmin\.Discovery\.Reply\.ThreadPool\.ThreadIdleTime$", false, null),
new Property(@"^IceGridAdmin\.Discovery\.Reply\.ThreadPool\.ThreadPriority$", false, null),
new Property(@"^IceGridAdmin\.Discovery\.Reply\.MessageSizeMax$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.ACM\.Timeout$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.ACM\.Heartbeat$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.ACM\.Close$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.ACM$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.AdapterId$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.Endpoints$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.Locator\.EndpointSelection$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.Locator\.ConnectionCached$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.Locator\.PreferSecure$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.Locator\.LocatorCacheTimeout$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.Locator\.InvocationTimeout$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.Locator\.Locator$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.Locator\.Router$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.Locator\.CollocationOptimized$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.Locator\.Context\.[^\s]+$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.Locator$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.PublishedEndpoints$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.ReplicaGroupId$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.Router\.EndpointSelection$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.Router\.ConnectionCached$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.Router\.PreferSecure$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.Router\.LocatorCacheTimeout$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.Router\.InvocationTimeout$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.Router\.Locator$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.Router\.Router$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.Router\.CollocationOptimized$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.Router\.Context\.[^\s]+$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.Router$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.ProxyOptions$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.ThreadPool\.Size$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.ThreadPool\.SizeMax$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.ThreadPool\.SizeWarn$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.ThreadPool\.StackSize$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.ThreadPool\.Serialize$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.ThreadPool\.ThreadIdleTime$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.ThreadPool\.ThreadPriority$", false, null),
+ new Property(@"^IceGridAdmin\.Discovery\.Locator\.MessageSizeMax$", false, null),
new Property(@"^IceGridAdmin\.Trace\.Observers$", false, null),
new Property(@"^IceGridAdmin\.Trace\.SaveToRegistry$", false, null),
null
diff --git a/csharp/src/Ice/UdpTransceiver.cs b/csharp/src/Ice/UdpTransceiver.cs
index 0b469bba3ac..897ca80a9a6 100644
--- a/csharp/src/Ice/UdpTransceiver.cs
+++ b/csharp/src/Ice/UdpTransceiver.cs
@@ -586,11 +586,10 @@ namespace IceInternal
info.remotePort = Network.endpointPort(remoteEndpoint);
}
}
+ info.rcvSize = Network.getRecvBufferSize(_fd);
+ info.sndSize = Network.getSendBufferSize(_fd);
}
- info.rcvSize = Network.getRecvBufferSize(_fd);
- info.sndSize = Network.getSendBufferSize(_fd);
-
if(_mcastAddr != null)
{
info.mcastAddress = Network.endpointAddressToString(_mcastAddr);
@@ -660,7 +659,8 @@ namespace IceInternal
}
else
{
- intfs = Network.getInterfacesForMulticast(_mcastInterface, _mcastAddr.Address);
+ intfs = Network.getInterfacesForMulticast(_mcastInterface,
+ Network.getProtocolSupport(_mcastAddr.Address));
}
if(intfs.Count != 0)
{
diff --git a/csharp/src/IceDiscovery/LookupI.cs b/csharp/src/IceDiscovery/LookupI.cs
index ee1775bb444..14dfbdd9f36 100644
--- a/csharp/src/IceDiscovery/LookupI.cs
+++ b/csharp/src/IceDiscovery/LookupI.cs
@@ -12,6 +12,8 @@ namespace IceDiscovery
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
+ using System.Text;
+ using System.Diagnostics;
class Request<T>
{
@@ -154,17 +156,77 @@ 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.
+ //
+ 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
+ }
+ }
+ Debug.Assert(_lookup.Count > 0);
}
public void setLookupReply(LookupReplyPrx lookupReply)
{
- _lookupReply = lookupReply;
+ //
+ // 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))
+ {
+ var info = (Ice.UDPEndpointInfo)key.ice_getEndpoints()[0].getInfo();
+ if(info.mcastInterface.Length > 0)
+ {
+ foreach(var q in lookupReply.ice_getEndpoints())
+ {
+ var r = q.getInfo();
+ if(r is Ice.IPEndpointInfo && ((Ice.IPEndpointInfo)r).host.Equals(info.mcastInterface))
+ {
+ single[0] = q;
+ _lookup[key] = (LookupReplyPrx)lookupReply.ice_endpoints(single);
+ }
+ }
+ }
+
+ if(_lookup[key] == null)
+ {
+ // Fallback: just use the given lookup reply proxy if no matching endpoint found.
+ _lookup[key] = lookupReply;
+ }
+ }
}
public override void findObjectById(string domainId, Ice.Identity id, LookupReplyPrx reply,
@@ -234,7 +296,10 @@ namespace IceDiscovery
{
try
{
- _lookup.findObjectByIdAsync(_domainId, id, _lookupReply);
+ foreach(var l in _lookup)
+ {
+ l.Key.findObjectByIdAsync(_domainId, id, l.Value);
+ }
_timer.schedule(request, _timeout);
}
catch(Ice.LocalException)
@@ -263,7 +328,10 @@ namespace IceDiscovery
{
try
{
- _lookup.findAdapterByIdAsync(_domainId, adapterId, _lookupReply);
+ foreach(var l in _lookup)
+ {
+ l.Key.findAdapterByIdAsync(_domainId, adapterId, l.Value);
+ }
_timer.schedule(request, _timeout);
}
catch(Ice.LocalException)
@@ -323,7 +391,10 @@ namespace IceDiscovery
{
try
{
- _lookup.findObjectByIdAsync(_domainId, request.getId(), _lookupReply);
+ foreach(var l in _lookup)
+ {
+ l.Key.findObjectByIdAsync(_domainId, request.getId(), l.Value);
+ }
_timer.schedule(request, _timeout);
return;
}
@@ -352,7 +423,10 @@ namespace IceDiscovery
{
try
{
- _lookup.findAdapterByIdAsync(_domainId, request.getId(), _lookupReply);
+ foreach(var l in _lookup)
+ {
+ l.Key.findAdapterByIdAsync(_domainId, request.getId(), l.Value);
+ }
_timer.schedule(request, _timeout);
return;
}
@@ -378,8 +452,7 @@ namespace IceDiscovery
}
private LocatorRegistryI _registry;
- private readonly LookupPrx _lookup;
- private LookupReplyPrx _lookupReply;
+ private Dictionary<LookupPrx, LookupReplyPrx> _lookup = new Dictionary<LookupPrx, LookupReplyPrx>();
private readonly int _timeout;
private readonly int _retryCount;
private readonly int _latencyMultiplier;
diff --git a/csharp/src/IceDiscovery/PluginI.cs b/csharp/src/IceDiscovery/PluginI.cs
index 5883dabeaf5..f633d3a7f2d 100644
--- a/csharp/src/IceDiscovery/PluginI.cs
+++ b/csharp/src/IceDiscovery/PluginI.cs
@@ -57,16 +57,28 @@ namespace IceDiscovery
}
properties.setProperty("IceDiscovery.Multicast.Endpoints", s.ToString());
}
- if(properties.getProperty("IceDiscovery.Reply.Endpoints").Length == 0)
+
+ string lookupEndpoints = properties.getProperty("IceDiscovery.Lookup");
+ if(lookupEndpoints.Length == 0)
{
- StringBuilder s = new StringBuilder();
- s.Append("udp");
- if(intf.Length != 0)
+ int protocol = ipv4 && !preferIPv6 ? IceInternal.Network.EnableIPv4 : IceInternal.Network.EnableIPv6;
+ var interfaces = IceInternal.Network.getInterfacesForMulticast(intf, protocol);
+ foreach(string p in interfaces)
{
- s.Append(" -h \"").Append(intf).Append("\"");
+ if(p != interfaces[0])
+ {
+ lookupEndpoints += ":";
+ }
+ lookupEndpoints += "udp -h \"" + address + "\" -p " + port + " --interface \"" + p + "\"";
}
- properties.setProperty("IceDiscovery.Reply.Endpoints", s.ToString());
}
+
+ if(properties.getProperty("IceDiscovery.Reply.Endpoints").Length == 0)
+ {
+ properties.setProperty("IceDiscovery.Reply.Endpoints",
+ "udp -h " + (intf.Length == 0 ? "*" : "\"" + intf + "\""));
+ }
+
if(properties.getProperty("IceDiscovery.Locator.Endpoints").Length == 0)
{
properties.setProperty("IceDiscovery.Locator.AdapterId", Guid.NewGuid().ToString());
@@ -83,32 +95,8 @@ namespace IceDiscovery
Ice.LocatorRegistryPrx locatorRegistryPrx = Ice.LocatorRegistryPrxHelper.uncheckedCast(
_locatorAdapter.addWithUUID(locatorRegistry));
- string lookupEndpoints = properties.getProperty("IceDiscovery.Lookup");
- if(lookupEndpoints.Length == 0)
- {
- lookupEndpoints = "udp -h \"" + address + "\" -p " + port;
- if(intf.Length > 0)
- {
- lookupEndpoints += " --interface \"" + intf + "\"";
- }
- }
-
Ice.ObjectPrx lookupPrx = _communicator.stringToProxy("IceDiscovery/Lookup -d:" + lookupEndpoints);
lookupPrx = lookupPrx.ice_collocationOptimized(false);
- try
- {
- lookupPrx.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(lookupPrx.ToString());
- b.Append('\n');
- b.Append(ex.ToString());
- throw new Ice.PluginInitializationException(b.ToString());
- }
//
// Add lookup and lookup reply Ice objects
diff --git a/csharp/src/IceLocatorDiscovery/PluginI.cs b/csharp/src/IceLocatorDiscovery/PluginI.cs
index 7e728d4b2e8..a3a32cb3c7f 100644
--- a/csharp/src/IceLocatorDiscovery/PluginI.cs
+++ b/csharp/src/IceLocatorDiscovery/PluginI.cs
@@ -12,17 +12,24 @@ namespace IceLocatorDiscovery
using System;
using System.Collections.Generic;
using System.Diagnostics;
+ using System.Threading;
using System.Threading.Tasks;
+ using System.Text;
public sealed class PluginFactory : Ice.PluginFactory
{
public Ice.Plugin
create(Ice.Communicator communicator, string name, string[] args)
{
- return new PluginI(communicator);
+ return new PluginI(name, communicator);
}
}
+ public interface Plugin : Ice.Plugin
+ {
+ List<Ice.LocatorPrx> getLocators(string instanceName, int waitTime);
+ }
+
internal class Request : TaskCompletionSource<Ice.Object_Ice_invokeResult>
{
public Request(LocatorI locator,
@@ -132,24 +139,85 @@ namespace IceLocatorDiscovery
internal class LocatorI : Ice.BlobjectAsync, IceInternal.TimerTask
{
public
- LocatorI(LookupPrx lookup, Ice.Properties properties, string instanceName, Ice.LocatorPrx voidLocator)
+ LocatorI(string name, LookupPrx lookup, Ice.Properties properties, string instanceName,
+ Ice.LocatorPrx voidLocator)
{
- _lookup = lookup;
- _timeout = properties.getPropertyAsIntWithDefault("IceLocatorDiscovery.Timeout", 300);
- _retryCount = properties.getPropertyAsIntWithDefault("IceLocatorDiscovery.RetryCount", 3);
- _retryDelay = properties.getPropertyAsIntWithDefault("IceLocatorDiscovery.RetryDelay", 2000);
+ _timeout = properties.getPropertyAsIntWithDefault(name + ".Timeout", 300);
+ _retryCount = properties.getPropertyAsIntWithDefault(name + ".RetryCount", 3);
+ _retryDelay = properties.getPropertyAsIntWithDefault(name + ".RetryDelay", 2000);
_timer = IceInternal.Util.getInstance(lookup.ice_getCommunicator()).timer();
_instanceName = instanceName;
_warned = false;
_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());
+ }
+
+ //
+ // Create one lookup proxy per endpoint from the given proxy. We want to send a multicast
+ // datagram on each endpoint.
+ //
+ 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
+ }
+ }
+ Debug.Assert(_lookup.Count > 0);
}
public void
setLookupReply(LookupReplyPrx lookupReply)
{
- _lookupReply = lookupReply;
+ //
+ // 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))
+ {
+ var info = (Ice.UDPEndpointInfo)key.ice_getEndpoints()[0].getInfo();
+ if(info.mcastInterface.Length > 0)
+ {
+ foreach(var q in lookupReply.ice_getEndpoints())
+ {
+ var r = q.getInfo();
+ if(r is Ice.IPEndpointInfo && ((Ice.IPEndpointInfo)r).host.Equals(info.mcastInterface))
+ {
+ single[0] = q;
+ _lookup[key] = (LookupReplyPrx)lookupReply.ice_endpoints(single);
+ }
+ }
+ }
+
+ if(_lookup[key] == null)
+ {
+ // Fallback: just use the given lookup reply proxy if no matching endpoint found.
+ _lookup[key] = lookupReply;
+ }
+ }
}
public override Task<Ice.Object_Ice_invokeResult>
@@ -163,6 +231,49 @@ namespace IceLocatorDiscovery
}
}
+ public List<Ice.LocatorPrx>
+ getLocators(String instanceName, int waitTime)
+ {
+ //
+ // Clear locators from previous search.
+ //
+ lock(this)
+ {
+ _locators.Clear();
+ }
+
+ //
+ // Find a locator
+ //
+ invoke(null, null);
+
+ //
+ // Wait for responses
+ //
+ if(instanceName.Length == 0)
+ {
+ Thread.Sleep(waitTime);
+ }
+ else
+ {
+ lock(this)
+ {
+ while(!_locators.ContainsKey(instanceName) && _pendingRetryCount > 0)
+ {
+ Monitor.Wait(this, waitTime);
+ }
+ }
+ }
+
+ //
+ // Return found locators
+ //
+ lock(this)
+ {
+ return new List<Ice.LocatorPrx>(_locators.Values);
+ }
+ }
+
public void
foundLocator(Ice.LocatorPrx locator)
{
@@ -178,7 +289,8 @@ namespace IceLocatorDiscovery
// If we already have a locator assigned, ensure the given locator
// has the same identity, otherwise ignore it.
//
- if(_locator != null && !locator.ice_getIdentity().category.Equals(_locator.ice_getIdentity().category))
+ if(_pendingRequests.Count > 0 &&
+ _locator != null && !locator.ice_getIdentity().category.Equals(_locator.ice_getIdentity().category))
{
if(!_warned)
{
@@ -202,13 +314,22 @@ namespace IceLocatorDiscovery
_pendingRetryCount = 0;
}
- if(_locator != null)
+ Ice.LocatorPrx l = null;
+ if(_pendingRequests.Count == 0)
+ {
+ _locators.TryGetValue(locator.ice_getIdentity().category, out _locator);
+ }
+ else
+ {
+ l = _locator;
+ }
+ if(l != null)
{
//
// We found another locator replica, append its endpoints to the
// current locator proxy endpoints.
//
- List<Ice.Endpoint> newEndpoints = new List<Ice.Endpoint>(_locator.ice_getEndpoints());
+ List<Ice.Endpoint> newEndpoints = new List<Ice.Endpoint>(l.ice_getEndpoints());
foreach(Ice.Endpoint p in locator.ice_getEndpoints())
{
//
@@ -228,25 +349,35 @@ namespace IceLocatorDiscovery
newEndpoints.Add(p);
}
}
- _locator = (Ice.LocatorPrx) _locator.ice_endpoints(newEndpoints.ToArray());
+ l = (Ice.LocatorPrx)l.ice_endpoints(newEndpoints.ToArray());
}
else
{
- _locator = locator;
+ l = locator;
+ }
+
+ if(_pendingRequests.Count == 0)
+ {
+ _locators[locator.ice_getIdentity().category] = l;
+ Monitor.Pulse(this);
+ }
+ else
+ {
+ _locator = l;
if(_instanceName.Length == 0)
{
_instanceName = _locator.ice_getIdentity().category; // Stick to the first locator
}
- }
- //
- // Send pending requests if any.
- //
- foreach(Request req in _pendingRequests)
- {
- req.invoke(_locator);
+ //
+ // Send pending requests if any.
+ //
+ foreach(Request req in _pendingRequests)
+ {
+ req.invoke(_locator);
+ }
+ _pendingRequests.Clear();
}
- _pendingRequests.Clear();
}
}
@@ -257,24 +388,36 @@ namespace IceLocatorDiscovery
{
if(_locator != null && _locator != locator)
{
- request.invoke(_locator);
+ if(request != null)
+ {
+ request.invoke(_locator);
+ }
}
else if(IceInternal.Time.currentMonotonicTimeMillis() < _nextRetry)
{
- request.invoke(_voidLocator); // Don't retry to find a locator before the retry delay expires
+ if(request != null)
+ {
+ request.invoke(_voidLocator); // Don't retry to find a locator before the retry delay expires
+ }
}
else
{
_locator = null;
- _pendingRequests.Add(request);
+ if(request != null)
+ {
+ _pendingRequests.Add(request);
+ }
if(_pendingRetryCount == 0) // No request in progress
{
_pendingRetryCount = _retryCount;
try
{
- _lookup.findLocatorAsync(_instanceName, _lookupReply); // Send multicast request.
+ foreach(var l in _lookup)
+ {
+ l.Key.findLocatorAsync(_instanceName, l.Value); // Send multicast request.
+ }
_timer.schedule(this, _timeout);
}
catch(Ice.LocalException)
@@ -300,7 +443,10 @@ namespace IceLocatorDiscovery
{
try
{
- _lookup.findLocatorAsync(_instanceName, _lookupReply); // Send multicast request
+ foreach(var l in _lookup)
+ {
+ l.Key.findLocatorAsync(_instanceName, l.Value); // Send multicast request
+ }
_timer.schedule(this, _timeout);
return;
}
@@ -319,7 +465,7 @@ namespace IceLocatorDiscovery
}
}
- private LookupPrx _lookup;
+ private Dictionary<LookupPrx, LookupReplyPrx> _lookup = new Dictionary<LookupPrx, LookupReplyPrx>();
private int _timeout;
private IceInternal.Timer _timer;
private int _retryCount;
@@ -327,9 +473,9 @@ namespace IceLocatorDiscovery
private string _instanceName;
private bool _warned;
- private LookupReplyPrx _lookupReply;
private Ice.LocatorPrx _locator;
private Ice.LocatorPrx _voidLocator;
+ private Dictionary<string, Ice.LocatorPrx> _locators = new Dictionary<string, Ice.LocatorPrx>();
private int _pendingRetryCount;
private List<Request> _pendingRequests = new List<Request>();
@@ -352,11 +498,12 @@ namespace IceLocatorDiscovery
private LocatorI _locator;
}
- class PluginI : Ice.Plugin
+ internal class PluginI : Ice.Plugin
{
public
- PluginI(Ice.Communicator communicator)
+ PluginI(string name, Ice.Communicator communicator)
{
+ _name = name;
_communicator = communicator;
}
@@ -370,85 +517,63 @@ namespace IceLocatorDiscovery
string address;
if(ipv4 && !preferIPv6)
{
- address = properties.getPropertyWithDefault("IceLocatorDiscovery.Address", "239.255.0.1");
+ address = properties.getPropertyWithDefault(_name + ".Address", "239.255.0.1");
}
else
{
- address = properties.getPropertyWithDefault("IceLocatorDiscovery.Address", "ff15::1");
+ address = properties.getPropertyWithDefault(_name + ".Address", "ff15::1");
}
- int port = properties.getPropertyAsIntWithDefault("IceLocatorDiscovery.Port", 4061);
- string intf = properties.getProperty("IceLocatorDiscovery.Interface");
+ int port = properties.getPropertyAsIntWithDefault(_name + ".Port", 4061);
+ string intf = properties.getProperty(_name + ".Interface");
- if(properties.getProperty("IceLocatorDiscovery.Reply.Endpoints").Length == 0)
+ string lookupEndpoints = properties.getProperty(_name + ".Lookup");
+ if(lookupEndpoints.Length == 0)
{
- System.Text.StringBuilder s = new System.Text.StringBuilder();
- s.Append("udp");
- if(intf.Length > 0)
+ int protocol = ipv4 && !preferIPv6 ? IceInternal.Network.EnableIPv4 : IceInternal.Network.EnableIPv6;
+ var interfaces = IceInternal.Network.getInterfacesForMulticast(intf, protocol);
+ foreach(string p in interfaces)
{
- s.Append(" -h \"");
- s.Append(intf);
- s.Append("\"");
+ if(p != interfaces[0])
+ {
+ lookupEndpoints += ":";
+ }
+ lookupEndpoints += "udp -h \"" + address + "\" -p " + port + " --interface \"" + p + "\"";
}
- properties.setProperty("IceLocatorDiscovery.Reply.Endpoints", s.ToString());
}
- if(properties.getProperty("IceLocatorDiscovery.Locator.Endpoints").Length == 0)
+
+ if(properties.getProperty(_name + ".Reply.Endpoints").Length == 0)
{
- properties.setProperty("IceLocatorDiscovery.Locator.AdapterId", Guid.NewGuid().ToString());
+ properties.setProperty(_name + ".Reply.Endpoints",
+ "udp -h " + (intf.Length == 0 ? "*" : "\"" + intf + "\""));
}
- _replyAdapter = _communicator.createObjectAdapter("IceLocatorDiscovery.Reply");
- _locatorAdapter = _communicator.createObjectAdapter("IceLocatorDiscovery.Locator");
+ if(properties.getProperty(_name + ".Locator.Endpoints").Length == 0)
+ {
+ properties.setProperty(_name + ".Locator.AdapterId", Guid.NewGuid().ToString());
+ }
+
+ _replyAdapter = _communicator.createObjectAdapter(_name + ".Reply");
+ _locatorAdapter = _communicator.createObjectAdapter(_name + ".Locator");
// We don't want those adapters to be registered with the locator so clear their locator.
_replyAdapter.setLocator(null);
_locatorAdapter.setLocator(null);
- string lookupEndpoints = properties.getProperty("IceLocatorDiscovery.Lookup");
- if(lookupEndpoints.Length == 0)
- {
- System.Text.StringBuilder s = new System.Text.StringBuilder();
- s.Append("udp -h \"");
- s.Append(address);
- s.Append("\" -p ");
- s.Append(port);
- if(intf.Length > 0)
- {
- s.Append(" --interface \"");
- s.Append(intf);
- s.Append("\"");
- }
- lookupEndpoints = s.ToString();
- }
-
Ice.ObjectPrx lookupPrx = _communicator.stringToProxy("IceLocatorDiscovery/Lookup -d:" + lookupEndpoints);
lookupPrx = lookupPrx.ice_collocationOptimized(false); // No colloc optimization for the multicast proxy!
- try
- {
- lookupPrx.ice_getConnection(); // Ensure we can establish a connection to the multicast proxy
- }
- catch (Ice.LocalException ex)
- {
- System.Text.StringBuilder s = new System.Text.StringBuilder();
- s.Append("IceLocatorDiscovery is unable to establish a multicast connection:\n");
- s.Append("proxy = ");
- s.Append(lookupPrx.ToString());
- s.Append("\n");
- s.Append(ex);
- throw new Ice.PluginInitializationException(s.ToString());
- }
Ice.LocatorPrx voidLo = Ice.LocatorPrxHelper.uncheckedCast(_locatorAdapter.addWithUUID(new VoidLocatorI()));
- string instanceName = properties.getProperty("IceLocatorDiscovery.InstanceName");
+ string instanceName = properties.getProperty(_name + ".InstanceName");
Ice.Identity id = new Ice.Identity();
id.name = "Locator";
id.category = instanceName.Length > 0 ? instanceName : Guid.NewGuid().ToString();
- LocatorI locator = new LocatorI(LookupPrxHelper.uncheckedCast(lookupPrx), properties, instanceName, voidLo);
- _communicator.setDefaultLocator(Ice.LocatorPrxHelper.uncheckedCast(_locatorAdapter.addWithUUID(locator)));
+ _locator = new LocatorI(_name, LookupPrxHelper.uncheckedCast(lookupPrx), properties, instanceName, voidLo);
+ _communicator.setDefaultLocator(Ice.LocatorPrxHelper.uncheckedCast(_locatorAdapter.addWithUUID(_locator)));
- Ice.ObjectPrx lookupReply = _replyAdapter.addWithUUID(new LookupReplyI(locator)).ice_datagram();
- locator.setLookupReply(LookupReplyPrxHelper.uncheckedCast(lookupReply));
+ Ice.ObjectPrx lookupReply = _replyAdapter.addWithUUID(new LookupReplyI(_locator)).ice_datagram();
+ _locator.setLookupReply(LookupReplyPrxHelper.uncheckedCast(lookupReply));
_replyAdapter.activate();
_locatorAdapter.activate();
@@ -461,8 +586,16 @@ namespace IceLocatorDiscovery
_locatorAdapter.destroy();
}
+ List<Ice.LocatorPrx>
+ getLocators(string instanceName, int waitTime)
+ {
+ return _locator.getLocators(instanceName, waitTime);
+ }
+
+ private string _name;
private Ice.Communicator _communicator;
private Ice.ObjectAdapter _locatorAdapter;
private Ice.ObjectAdapter _replyAdapter;
+ private LocatorI _locator;
}
}
diff --git a/java-compat/src/Ice/src/main/java/IceInternal/Network.java b/java-compat/src/Ice/src/main/java/IceInternal/Network.java
index 6e22f1484ec..14c50c52e40 100644
--- a/java-compat/src/Ice/src/main/java/IceInternal/Network.java
+++ b/java-compat/src/Ice/src/main/java/IceInternal/Network.java
@@ -298,7 +298,7 @@ public final class Network
try
{
java.util.Set<java.net.NetworkInterface> interfaces = new java.util.HashSet<>();
- for(String address : getInterfacesForMulticast(intf, group))
+ for(String address : getInterfacesForMulticast(intf, getProtocolSupport(group)))
{
java.net.NetworkInterface intf2 = getInterface(address);
if(!interfaces.contains(intf2))
@@ -320,7 +320,7 @@ public final class Network
try
{
java.util.Set<java.net.NetworkInterface> interfaces = new java.util.HashSet<>();
- for(String address : getInterfacesForMulticast(intf, group))
+ for(String address : getInterfacesForMulticast(intf, getProtocolSupport(group)))
{
java.net.NetworkInterface intf2 = getInterface(address);
if(!interfaces.contains(intf2))
@@ -1076,10 +1076,9 @@ public final class Network
return hosts;
}
- public static java.util.ArrayList<String>
- getInterfacesForMulticast(String intf, java.net.InetSocketAddress mcastAddr)
+ public static java.util.List<String>
+ getInterfacesForMulticast(String intf, int protocolSupport)
{
- int protocolSupport = getProtocolSupport(mcastAddr);
java.util.ArrayList<String> interfaces = new java.util.ArrayList<>();
if(isWildcard(intf))
{
diff --git a/java-compat/src/Ice/src/main/java/IceInternal/PropertyNames.java b/java-compat/src/Ice/src/main/java/IceInternal/PropertyNames.java
index e925bf7d217..1b2db0f1030 100644
--- a/java-compat/src/Ice/src/main/java/IceInternal/PropertyNames.java
+++ b/java-compat/src/Ice/src/main/java/IceInternal/PropertyNames.java
@@ -6,7 +6,7 @@
// ICE_LICENSE file included in this distribution.
//
// **********************************************************************
-// Generated by makeprops.py from file ..\config\PropertyNames.xml, Fri Feb 24 18:49:18 2017
+// Generated by makeprops.py from file ./config/PropertyNames.xml, Tue Feb 28 15:01:12 2017
// IMPORTANT: Do not edit this file -- any edits made here will be lost!
@@ -504,6 +504,43 @@ public final class PropertyNames
new Property("IceGridAdmin\\.Discovery\\.Reply\\.ThreadPool\\.ThreadIdleTime", false, null),
new Property("IceGridAdmin\\.Discovery\\.Reply\\.ThreadPool\\.ThreadPriority", false, null),
new Property("IceGridAdmin\\.Discovery\\.Reply\\.MessageSizeMax", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.ACM\\.Timeout", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.ACM\\.Heartbeat", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.ACM\\.Close", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.ACM", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.AdapterId", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Endpoints", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Locator\\.EndpointSelection", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Locator\\.ConnectionCached", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Locator\\.PreferSecure", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Locator\\.LocatorCacheTimeout", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Locator\\.InvocationTimeout", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Locator\\.Locator", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Locator\\.Router", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Locator\\.CollocationOptimized", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Locator\\.Context\\.[^\\s]+", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Locator", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.PublishedEndpoints", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.ReplicaGroupId", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Router\\.EndpointSelection", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Router\\.ConnectionCached", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Router\\.PreferSecure", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Router\\.LocatorCacheTimeout", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Router\\.InvocationTimeout", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Router\\.Locator", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Router\\.Router", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Router\\.CollocationOptimized", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Router\\.Context\\.[^\\s]+", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Router", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.ProxyOptions", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.ThreadPool\\.Size", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.ThreadPool\\.SizeMax", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.ThreadPool\\.SizeWarn", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.ThreadPool\\.StackSize", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.ThreadPool\\.Serialize", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.ThreadPool\\.ThreadIdleTime", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.ThreadPool\\.ThreadPriority", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.MessageSizeMax", false, null),
new Property("IceGridAdmin\\.Trace\\.Observers", false, null),
new Property("IceGridAdmin\\.Trace\\.SaveToRegistry", false, null),
null
diff --git a/java-compat/src/Ice/src/main/java/IceInternal/UdpMulticastClientTransceiver.java b/java-compat/src/Ice/src/main/java/IceInternal/UdpMulticastClientTransceiver.java
index d92f362395d..ce5da6173ff 100644
--- a/java-compat/src/Ice/src/main/java/IceInternal/UdpMulticastClientTransceiver.java
+++ b/java-compat/src/Ice/src/main/java/IceInternal/UdpMulticastClientTransceiver.java
@@ -161,7 +161,8 @@ final class UdpMulticastClientTransceiver implements Transceiver
public String toDetailedString()
{
StringBuilder s = new StringBuilder(toString());
- java.util.List<String> intfs = Network.getInterfacesForMulticast(_mcastInterface, _addr);
+ java.util.List<String> intfs = Network.getInterfacesForMulticast(_mcastInterface,
+ Network.getProtocolSupport(_addr));
if(!intfs.isEmpty())
{
s.append("\nlocal interfaces = ");
diff --git a/java-compat/src/Ice/src/main/java/IceInternal/UdpMulticastServerTransceiver.java b/java-compat/src/Ice/src/main/java/IceInternal/UdpMulticastServerTransceiver.java
index e6d44880908..4ae7b4c08a3 100644
--- a/java-compat/src/Ice/src/main/java/IceInternal/UdpMulticastServerTransceiver.java
+++ b/java-compat/src/Ice/src/main/java/IceInternal/UdpMulticastServerTransceiver.java
@@ -169,7 +169,8 @@ final class UdpMulticastServerTransceiver implements Transceiver
public String toDetailedString()
{
StringBuilder s = new StringBuilder(toString());
- java.util.List<String> intfs = Network.getInterfacesForMulticast(_mcastInterface, _addr);
+ java.util.List<String> intfs = Network.getInterfacesForMulticast(_mcastInterface,
+ Network.getProtocolSupport(_addr));
if(!intfs.isEmpty())
{
s.append("\nlocal interfaces = ");
diff --git a/java-compat/src/Ice/src/main/java/IceInternal/UdpTransceiver.java b/java-compat/src/Ice/src/main/java/IceInternal/UdpTransceiver.java
index 9c8261732e0..288af7da40d 100644
--- a/java-compat/src/Ice/src/main/java/IceInternal/UdpTransceiver.java
+++ b/java-compat/src/Ice/src/main/java/IceInternal/UdpTransceiver.java
@@ -290,7 +290,7 @@ final class UdpTransceiver implements Transceiver
}
else
{
- intfs = Network.getInterfacesForMulticast(_mcastInterface, _mcastAddr);
+ intfs = Network.getInterfacesForMulticast(_mcastInterface, Network.getProtocolSupport(_mcastAddr));
}
if(!intfs.isEmpty())
{
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 7f805891f56..fcf1f3acf23 100644
--- a/java-compat/src/IceDiscovery/src/main/java/IceDiscovery/LookupI.java
+++ b/java-compat/src/IceDiscovery/src/main/java/IceDiscovery/LookupI.java
@@ -184,18 +184,77 @@ class LookupI extends _LookupDisp
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.
+ //
+ 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)
+ {
+ }
+ }
+ assert(!_lookup.isEmpty());
}
void
setLookupReply(LookupReplyPrx lookupReply)
{
- _lookupReply = lookupReply;
+ //
+ // 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())
+ {
+ Ice.UDPEndpointInfo info = (Ice.UDPEndpointInfo)entry.getKey().ice_getEndpoints()[0].getInfo();
+ if(!info.mcastInterface.isEmpty())
+ {
+ for(Ice.Endpoint q : lookupReply.ice_getEndpoints())
+ {
+ Ice.EndpointInfo r = q.getInfo();
+ if(r instanceof Ice.IPEndpointInfo && ((Ice.IPEndpointInfo)r).host.equals(info.mcastInterface))
+ {
+ single[0] = q;
+ entry.setValue((LookupReplyPrx)lookupReply.ice_endpoints(single));
+ }
+ }
+ }
+
+ if(entry.getValue() == null)
+ {
+ // Fallback: just use the given lookup reply proxy if no matching endpoint found.
+ entry.setValue(lookupReply);
+ }
+ }
}
@Override
@@ -265,7 +324,10 @@ class LookupI extends _LookupDisp
{
try
{
- _lookup.begin_findObjectById(_domainId, id, _lookupReply);
+ for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookup.entrySet())
+ {
+ entry.getKey().begin_findObjectById(_domainId, id, entry.getValue());
+ }
request.scheduleTimer(_timeout);
}
catch(Ice.LocalException ex)
@@ -290,7 +352,10 @@ class LookupI extends _LookupDisp
{
try
{
- _lookup.begin_findAdapterById(_domainId, adapterId, _lookupReply);
+ for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookup.entrySet())
+ {
+ entry.getKey().begin_findAdapterById(_domainId, adapterId, entry.getValue());
+ }
request.scheduleTimer(_timeout);
}
catch(Ice.LocalException ex)
@@ -344,7 +409,10 @@ class LookupI extends _LookupDisp
{
try
{
- _lookup.begin_findObjectById(_domainId, request.getId(), _lookupReply);
+ for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookup.entrySet())
+ {
+ entry.getKey().begin_findObjectById(_domainId, request.getId(), entry.getValue());
+ }
request.scheduleTimer(_timeout);
return;
}
@@ -370,7 +438,10 @@ class LookupI extends _LookupDisp
{
try
{
- _lookup.begin_findAdapterById(_domainId, request.getId(), _lookupReply);
+ for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookup.entrySet())
+ {
+ entry.getKey().begin_findAdapterById(_domainId, request.getId(), entry.getValue());
+ }
request.scheduleTimer(_timeout);
return;
}
@@ -384,8 +455,7 @@ class LookupI extends _LookupDisp
}
private LocatorRegistryI _registry;
- private final LookupPrx _lookup;
- private LookupReplyPrx _lookupReply;
+ private java.util.Map<LookupPrx, LookupReplyPrx> _lookup = new java.util.HashMap<>();
private final int _timeout;
private final int _retryCount;
private final int _latencyMultiplier;
diff --git a/java-compat/src/IceDiscovery/src/main/java/IceDiscovery/PluginI.java b/java-compat/src/IceDiscovery/src/main/java/IceDiscovery/PluginI.java
index bc36a6cc7f6..1e2074a65a2 100644
--- a/java-compat/src/IceDiscovery/src/main/java/IceDiscovery/PluginI.java
+++ b/java-compat/src/IceDiscovery/src/main/java/IceDiscovery/PluginI.java
@@ -47,16 +47,28 @@ public class PluginI implements Ice.Plugin
}
properties.setProperty("IceDiscovery.Multicast.Endpoints", s.toString());
}
- if(properties.getProperty("IceDiscovery.Reply.Endpoints").isEmpty())
+
+ String lookupEndpoints = properties.getProperty("IceDiscovery.Lookup");
+ if(lookupEndpoints.isEmpty())
{
- StringBuilder s = new StringBuilder();
- s.append("udp");
- if(!intf.isEmpty())
+ int protocol = ipv4 && !preferIPv6 ? IceInternal.Network.EnableIPv4 : IceInternal.Network.EnableIPv6;
+ java.util.List<String> interfaces = IceInternal.Network.getInterfacesForMulticast(intf, protocol);
+ for(String p : interfaces)
{
- s.append(" -h \"").append(intf).append("\"");
+ if(p != interfaces.get(0))
+ {
+ lookupEndpoints += ":";
+ }
+ lookupEndpoints += "udp -h \"" + address + "\" -p " + port + " --interface \"" + p + "\"";
}
- properties.setProperty("IceDiscovery.Reply.Endpoints", s.toString());
}
+
+ if(properties.getProperty("IceDiscovery.Reply.Endpoints").isEmpty())
+ {
+ properties.setProperty("IceDiscovery.Reply.Endpoints",
+ "udp -h " + (intf.isEmpty() ? "*" : "\"" + intf + "\""));
+ }
+
if(properties.getProperty("IceDiscovery.Locator.Endpoints").isEmpty())
{
properties.setProperty("IceDiscovery.Locator.AdapterId", java.util.UUID.randomUUID().toString());
@@ -73,34 +85,8 @@ public class PluginI implements Ice.Plugin
Ice.LocatorRegistryPrx locatorRegistryPrx = Ice.LocatorRegistryPrxHelper.uncheckedCast(
_locatorAdapter.addWithUUID(locatorRegistry));
- String lookupEndpoints = properties.getProperty("IceDiscovery.Lookup");
- if(lookupEndpoints.isEmpty())
- {
- StringBuilder s = new StringBuilder();
- s.append("udp -h \"").append(address).append("\" -p ").append(port);
- if(!intf.isEmpty())
- {
- s.append(" --interface \"").append(intf).append("\"");
- }
- lookupEndpoints = s.toString();
- }
-
Ice.ObjectPrx lookupPrx = _communicator.stringToProxy("IceDiscovery/Lookup -d:" + lookupEndpoints);
lookupPrx = lookupPrx.ice_collocationOptimized(false); // No collocation optimization for the multicast proxy!
- try
- {
- lookupPrx.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(lookupPrx.toString());
- b.append('\n');
- b.append(ex.toString());
- throw new Ice.PluginInitializationException(b.toString());
- }
//
// Add lookup and lookup reply Ice objects
diff --git a/java-compat/src/IceLocatorDiscovery/src/main/java/IceLocatorDiscovery/Plugin.java b/java-compat/src/IceLocatorDiscovery/src/main/java/IceLocatorDiscovery/Plugin.java
new file mode 100644
index 00000000000..a7fbd1eaf0f
--- /dev/null
+++ b/java-compat/src/IceLocatorDiscovery/src/main/java/IceLocatorDiscovery/Plugin.java
@@ -0,0 +1,17 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+package IceLocatorDiscovery;
+
+import java.util.List;
+
+interface Plugin extends Ice.Plugin
+{
+ List<Ice.LocatorPrx> getLocators(String instanceName, int waitTime);
+}
diff --git a/java-compat/src/IceLocatorDiscovery/src/main/java/IceLocatorDiscovery/PluginFactory.java b/java-compat/src/IceLocatorDiscovery/src/main/java/IceLocatorDiscovery/PluginFactory.java
index 9701f75571a..38ec505eb76 100644
--- a/java-compat/src/IceLocatorDiscovery/src/main/java/IceLocatorDiscovery/PluginFactory.java
+++ b/java-compat/src/IceLocatorDiscovery/src/main/java/IceLocatorDiscovery/PluginFactory.java
@@ -15,6 +15,6 @@ public class PluginFactory implements Ice.PluginFactory
public Ice.Plugin
create(Ice.Communicator communicator, String name, String[] args)
{
- return new PluginI(communicator);
+ return new PluginI(name, communicator);
}
}
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 d95ea460ad5..c93137b7bee 100644
--- a/java-compat/src/IceLocatorDiscovery/src/main/java/IceLocatorDiscovery/PluginI.java
+++ b/java-compat/src/IceLocatorDiscovery/src/main/java/IceLocatorDiscovery/PluginI.java
@@ -12,8 +12,9 @@ package IceLocatorDiscovery;
import java.util.List;
import java.util.Arrays;
import java.util.ArrayList;
+import java.util.Map;
-class PluginI implements Ice.Plugin
+class PluginI implements Plugin
{
private static class Request
{
@@ -141,24 +142,84 @@ class PluginI implements Ice.Plugin
private static class LocatorI extends Ice.BlobjectAsync
{
- LocatorI(LookupPrx lookup, Ice.Properties properties, String instanceName, Ice.LocatorPrx voidLocator)
+ LocatorI(String name, LookupPrx lookup, Ice.Properties properties, String instanceName,
+ Ice.LocatorPrx voidLocator)
{
- _lookup = lookup;
- _timeout = properties.getPropertyAsIntWithDefault("IceLocatorDiscovery.Timeout", 300);
- _retryCount = properties.getPropertyAsIntWithDefault("IceLocatorDiscovery.RetryCount", 3);
- _retryDelay = properties.getPropertyAsIntWithDefault("IceLocatorDiscovery.RetryDelay", 2000);
+ _timeout = properties.getPropertyAsIntWithDefault(name + ".Timeout", 300);
+ _retryCount = properties.getPropertyAsIntWithDefault(name + ".RetryCount", 3);
+ _retryDelay = properties.getPropertyAsIntWithDefault(name + ".RetryDelay", 2000);
_timer = IceInternal.Util.getInstance(lookup.ice_getCommunicator()).timer();
_instanceName = instanceName;
_warned = false;
_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());
+ }
+
+ //
+ // Create one lookup proxy per endpoint from the given proxy. We want to send a multicast
+ // datagram on each endpoint.
+ //
+ 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)
+ {
+ }
+ }
+ assert(!_lookup.isEmpty());
}
public void
setLookupReply(LookupReplyPrx lookupReply)
{
- _lookupReply = lookupReply;
+ //
+ // 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())
+ {
+ Ice.UDPEndpointInfo info = (Ice.UDPEndpointInfo)entry.getKey().ice_getEndpoints()[0].getInfo();
+ if(!info.mcastInterface.isEmpty())
+ {
+ for(Ice.Endpoint q : lookupReply.ice_getEndpoints())
+ {
+ Ice.EndpointInfo r = q.getInfo();
+ if(r instanceof Ice.IPEndpointInfo && ((Ice.IPEndpointInfo)r).host.equals(info.mcastInterface))
+ {
+ single[0] = q;
+ entry.setValue((LookupReplyPrx)lookupReply.ice_endpoints(single));
+ }
+ }
+ }
+
+ if(entry.getValue() == null)
+ {
+ // Fallback: just use the given lookup reply proxy if no matching endpoint found.
+ entry.setValue(lookupReply);
+ }
+ }
}
@Override
@@ -168,6 +229,56 @@ class PluginI implements Ice.Plugin
invoke(null, new Request(this, current.operation, current.mode, inParams, current.ctx, amdCB));
}
+ public List<Ice.LocatorPrx>
+ getLocators(String instanceName, int waitTime)
+ {
+ //
+ // Clear locators from previous search.
+ //
+ synchronized(this)
+ {
+ _locators.clear();
+ }
+
+ //
+ // Find a locator
+ //
+ invoke(null, null);
+
+ //
+ // Wait for responses
+ //
+ try
+ {
+ if(instanceName.isEmpty())
+ {
+ Thread.sleep(waitTime);
+ }
+ else
+ {
+ synchronized(this)
+ {
+ while(!_locators.containsKey(instanceName) && _pendingRetryCount > 0)
+ {
+ wait(waitTime);
+ }
+ }
+ }
+ }
+ catch(java.lang.InterruptedException ex)
+ {
+ throw new Ice.OperationInterruptedException();
+ }
+
+ //
+ // Return found locators
+ //
+ synchronized(this)
+ {
+ return new ArrayList<>(_locators.values());
+ }
+ }
+
public synchronized void
foundLocator(Ice.LocatorPrx locator)
{
@@ -181,7 +292,8 @@ class PluginI implements Ice.Plugin
// If we already have a locator assigned, ensure the given locator
// has the same identity, otherwise ignore it.
//
- if(_locator != null && !locator.ice_getIdentity().category.equals(_locator.ice_getIdentity().category))
+ if(!_pendingRequests.isEmpty() &&
+ _locator != null && !locator.ice_getIdentity().category.equals(_locator.ice_getIdentity().category))
{
if(!_warned)
{
@@ -206,14 +318,15 @@ class PluginI implements Ice.Plugin
_pendingRetryCount = 0;
}
- if(_locator != null)
+ Ice.LocatorPrx l =
+ _pendingRequests.isEmpty() ? _locators.get(locator.ice_getIdentity().category) : _locator;
+ if(l != null)
{
//
// We found another locator replica, append its endpoints to the
// current locator proxy endpoints.
//
- List<Ice.Endpoint> newEndpoints = new ArrayList<Ice.Endpoint>(
- Arrays.asList(_locator.ice_getEndpoints()));
+ List<Ice.Endpoint> newEndpoints = new ArrayList<Ice.Endpoint>(Arrays.asList(l.ice_getEndpoints()));
for(Ice.Endpoint p : locator.ice_getEndpoints())
{
//
@@ -234,26 +347,35 @@ class PluginI implements Ice.Plugin
}
}
- _locator = (Ice.LocatorPrx)_locator.ice_endpoints(
- newEndpoints.toArray(new Ice.Endpoint[newEndpoints.size()]));
+ l = (Ice.LocatorPrx)l.ice_endpoints(newEndpoints.toArray(new Ice.Endpoint[newEndpoints.size()]));
+ }
+ else
+ {
+ l = locator;
+ }
+
+ if(_pendingRequests.isEmpty())
+ {
+ _locators.put(locator.ice_getIdentity().category, l);
+ notify();
}
else
{
- _locator = locator;
+ _locator = l;
if(_instanceName.isEmpty())
{
_instanceName = _locator.ice_getIdentity().category; // Stick to the first locator
}
- }
- //
- // Send pending requests if any.
- //
- for(Request req : _pendingRequests)
- {
- req.invoke(_locator);
+ //
+ // Send pending requests if any.
+ //
+ for(Request req : _pendingRequests)
+ {
+ req.invoke(_locator);
+ }
+ _pendingRequests.clear();
}
- _pendingRequests.clear();
}
public synchronized void
@@ -261,24 +383,36 @@ class PluginI implements Ice.Plugin
{
if(_locator != null && _locator != locator)
{
- request.invoke(_locator);
+ if(request != null)
+ {
+ request.invoke(_locator);
+ }
}
else if(IceInternal.Time.currentMonotonicTimeMillis() < _nextRetry)
{
- request.invoke(_voidLocator); // Don't retry to find a locator before the retry delay expires
+ if(request != null)
+ {
+ request.invoke(_voidLocator); // Don't retry to find a locator before the retry delay expires
+ }
}
else
{
_locator = null;
- _pendingRequests.add(request);
+ if(request != null)
+ {
+ _pendingRequests.add(request);
+ }
if(_pendingRetryCount == 0) // No request in progress
{
_pendingRetryCount = _retryCount;
try
{
- _lookup.begin_findLocator(_instanceName, _lookupReply); // Send multicast request.
+ for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookup.entrySet())
+ {
+ entry.getKey().begin_findLocator(_instanceName, entry.getValue()); // Send multicast request
+ }
_future = _timer.schedule(_retryTask, _timeout, java.util.concurrent.TimeUnit.MILLISECONDS);
}
catch(Ice.LocalException ex)
@@ -305,7 +439,10 @@ class PluginI implements Ice.Plugin
{
try
{
- _lookup.begin_findLocator(_instanceName, _lookupReply); // Send multicast request.
+ for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookup.entrySet())
+ {
+ entry.getKey().begin_findLocator(_instanceName, entry.getValue()); // Send multicast request
+ }
_future = _timer.schedule(_retryTask, _timeout, java.util.concurrent.TimeUnit.MILLISECONDS);
return;
}
@@ -326,7 +463,7 @@ class PluginI implements Ice.Plugin
}
};
- private final LookupPrx _lookup;
+ private final java.util.Map<LookupPrx, LookupReplyPrx> _lookup = new java.util.HashMap<>();
private final int _timeout;
private java.util.concurrent.Future<?> _future;
private final java.util.concurrent.ScheduledExecutorService _timer;
@@ -335,9 +472,9 @@ class PluginI implements Ice.Plugin
private String _instanceName;
private boolean _warned;
- private LookupReplyPrx _lookupReply;
private Ice.LocatorPrx _locator;
private Ice.LocatorPrx _voidLocator;
+ private Map<String, Ice.LocatorPrx> _locators = new java.util.HashMap<>();
private int _pendingRetryCount;
private List<Request> _pendingRequests = new ArrayList<Request>();
@@ -362,8 +499,9 @@ class PluginI implements Ice.Plugin
};
public
- PluginI(Ice.Communicator communicator)
+ PluginI(String name, Ice.Communicator communicator)
{
+ _name = name;
_communicator = communicator;
}
@@ -378,74 +516,61 @@ class PluginI implements Ice.Plugin
String address;
if(ipv4 && !preferIPv6)
{
- address = properties.getPropertyWithDefault("IceLocatorDiscovery.Address", "239.255.0.1");
+ address = properties.getPropertyWithDefault(_name + ".Address", "239.255.0.1");
}
else
{
- address = properties.getPropertyWithDefault("IceLocatorDiscovery.Address", "ff15::1");
+ address = properties.getPropertyWithDefault(_name + ".Address", "ff15::1");
}
- int port = properties.getPropertyAsIntWithDefault("IceLocatorDiscovery.Port", 4061);
- String intf = properties.getProperty("IceLocatorDiscovery.Interface");
+ int port = properties.getPropertyAsIntWithDefault(_name + ".Port", 4061);
+ String intf = properties.getProperty(_name + ".Interface");
- if(properties.getProperty("IceLocatorDiscovery.Reply.Endpoints").isEmpty())
+ String lookupEndpoints = properties.getProperty(_name + ".Lookup");
+ if(lookupEndpoints.isEmpty())
{
- StringBuilder s = new StringBuilder();
- s.append("udp");
- if(!intf.isEmpty())
+ int protocol = ipv4 && !preferIPv6 ? IceInternal.Network.EnableIPv4 : IceInternal.Network.EnableIPv6;
+ java.util.List<String> interfaces = IceInternal.Network.getInterfacesForMulticast(intf, protocol);
+ for(String p : interfaces)
{
- s.append(" -h \"").append(intf).append("\"");
+ if(p != interfaces.get(0))
+ {
+ lookupEndpoints += ":";
+ }
+ lookupEndpoints += "udp -h \"" + address + "\" -p " + port + " --interface \"" + p + "\"";
}
- properties.setProperty("IceLocatorDiscovery.Reply.Endpoints", s.toString());
}
- if(properties.getProperty("IceLocatorDiscovery.Locator.Endpoints").isEmpty())
+
+ if(properties.getProperty(_name + ".Reply.Endpoints").isEmpty())
+ {
+ properties.setProperty(_name + ".Reply.Endpoints", "udp -h " + (intf.isEmpty() ? "*" : "\"" + intf + "\""));
+ }
+
+ if(properties.getProperty(_name + ".Locator.Endpoints").isEmpty())
{
- properties.setProperty("IceLocatorDiscovery.Locator.AdapterId", java.util.UUID.randomUUID().toString());
+ properties.setProperty(_name + ".Locator.AdapterId", java.util.UUID.randomUUID().toString());
}
- _replyAdapter = _communicator.createObjectAdapter("IceLocatorDiscovery.Reply");
- _locatorAdapter = _communicator.createObjectAdapter("IceLocatorDiscovery.Locator");
+ _replyAdapter = _communicator.createObjectAdapter(_name + ".Reply");
+ _locatorAdapter = _communicator.createObjectAdapter(_name + ".Locator");
// We don't want those adapters to be registered with the locator so clear their locator.
_replyAdapter.setLocator(null);
_locatorAdapter.setLocator(null);
- String lookupEndpoints = properties.getProperty("IceLocatorDiscovery.Lookup");
- if(lookupEndpoints.isEmpty())
- {
- StringBuilder s = new StringBuilder();
- s.append("udp -h \"").append(address).append("\" -p ").append(port);
- if(!intf.isEmpty())
- {
- s.append(" --interface \"").append(intf).append("\"");
- }
- lookupEndpoints = s.toString();
- }
-
Ice.ObjectPrx lookupPrx = _communicator.stringToProxy("IceLocatorDiscovery/Lookup -d:" + lookupEndpoints);
lookupPrx = lookupPrx.ice_collocationOptimized(false); // No collocation optimization for the multicast proxy!
- try
- {
- lookupPrx.ice_getConnection(); // Ensure we can establish a connection to the multicast proxy
- }
- catch(Ice.LocalException ex)
- {
- StringBuilder s = new StringBuilder();
- s.append("IceLocatorDiscovery is unable to establish a multicast connection:\n");
- s.append("proxy = ").append(lookupPrx.toString()).append("\n").append(ex);
- throw new Ice.PluginInitializationException(s.toString());
- }
Ice.LocatorPrx voidLoc = Ice.LocatorPrxHelper.uncheckedCast(_locatorAdapter.addWithUUID(new VoidLocatorI()));
- String instanceName = properties.getProperty("IceLocatorDiscovery.InstanceName");
+ String instanceName = properties.getProperty(_name + ".InstanceName");
Ice.Identity id = new Ice.Identity();
id.name = "Locator";
id.category = !instanceName.isEmpty() ? instanceName : java.util.UUID.randomUUID().toString();
- LocatorI locator = new LocatorI(LookupPrxHelper.uncheckedCast(lookupPrx), properties, instanceName, voidLoc);
- _communicator.setDefaultLocator(Ice.LocatorPrxHelper.uncheckedCast(_locatorAdapter.addWithUUID(locator)));
+ _locator = new LocatorI(_name, LookupPrxHelper.uncheckedCast(lookupPrx), properties, instanceName, voidLoc);
+ _communicator.setDefaultLocator(Ice.LocatorPrxHelper.uncheckedCast(_locatorAdapter.addWithUUID(_locator)));
- Ice.ObjectPrx lookupReply = _replyAdapter.addWithUUID(new LookupReplyI(locator)).ice_datagram();
- locator.setLookupReply(LookupReplyPrxHelper.uncheckedCast(lookupReply));
+ Ice.ObjectPrx lookupReply = _replyAdapter.addWithUUID(new LookupReplyI(_locator)).ice_datagram();
+ _locator.setLookupReply(LookupReplyPrxHelper.uncheckedCast(lookupReply));
_replyAdapter.activate();
_locatorAdapter.activate();
@@ -459,7 +584,16 @@ class PluginI implements Ice.Plugin
_locatorAdapter.destroy();
}
+ @Override
+ public List<Ice.LocatorPrx>
+ getLocators(String instanceName, int waitTime)
+ {
+ return _locator.getLocators(instanceName, waitTime);
+ }
+
+ private String _name;
private Ice.Communicator _communicator;
private Ice.ObjectAdapter _locatorAdapter;
private Ice.ObjectAdapter _replyAdapter;
+ private LocatorI _locator;
}
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 79dcf805dd0..95b173016e5 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
@@ -91,11 +91,6 @@ public class AllTests
initData.properties.setProperty("Ice.Default.Locator", "");
initData.properties.setProperty("Ice.Plugin.IceLocatorDiscovery",
"IceLocatorDiscovery:IceLocatorDiscovery.PluginFactory");
- if(System.getProperty("os.name").contains("OS X") &&
- initData.properties.getPropertyAsInt("Ice.PreferIPv6Address") > 0)
- {
- initData.properties.setProperty("IceLocatorDiscovery.Interface", "::1");
- }
initData.properties.setProperty("IceLocatorDiscovery.Port", Integer.toString(app.getTestPort(99)));
initData.properties.setProperty("AdapterForDiscoveryTest.AdapterId", "discoveryAdapter");
initData.properties.setProperty("AdapterForDiscoveryTest.Endpoints", "default");
diff --git a/java/src/Ice/src/main/java/com/zeroc/IceInternal/Network.java b/java/src/Ice/src/main/java/com/zeroc/IceInternal/Network.java
index 7e29515406d..cb56f0bb9e1 100644
--- a/java/src/Ice/src/main/java/com/zeroc/IceInternal/Network.java
+++ b/java/src/Ice/src/main/java/com/zeroc/IceInternal/Network.java
@@ -303,7 +303,7 @@ public final class Network
try
{
java.util.Set<java.net.NetworkInterface> interfaces = new java.util.HashSet<>();
- for(String address : getInterfacesForMulticast(intf, group))
+ for(String address : getInterfacesForMulticast(intf, getProtocolSupport(group)))
{
java.net.NetworkInterface intf2 = getInterface(address);
if(!interfaces.contains(intf2))
@@ -325,7 +325,7 @@ public final class Network
try
{
java.util.Set<java.net.NetworkInterface> interfaces = new java.util.HashSet<>();
- for(String address : getInterfacesForMulticast(intf, group))
+ for(String address : getInterfacesForMulticast(intf, getProtocolSupport(group)))
{
java.net.NetworkInterface intf2 = getInterface(address);
if(!interfaces.contains(intf2))
@@ -1081,10 +1081,9 @@ public final class Network
return hosts;
}
- public static java.util.ArrayList<String>
- getInterfacesForMulticast(String intf, java.net.InetSocketAddress mcastAddr)
+ public static java.util.List<String>
+ getInterfacesForMulticast(String intf, int protocolSupport)
{
- int protocolSupport = getProtocolSupport(mcastAddr);
java.util.ArrayList<String> interfaces = new java.util.ArrayList<>();
if(isWildcard(intf))
{
diff --git a/java/src/Ice/src/main/java/com/zeroc/IceInternal/PropertyNames.java b/java/src/Ice/src/main/java/com/zeroc/IceInternal/PropertyNames.java
index 6d1273b8793..eb3319e9b46 100644
--- a/java/src/Ice/src/main/java/com/zeroc/IceInternal/PropertyNames.java
+++ b/java/src/Ice/src/main/java/com/zeroc/IceInternal/PropertyNames.java
@@ -6,7 +6,7 @@
// ICE_LICENSE file included in this distribution.
//
// **********************************************************************
-// Generated by makeprops.py from file ..\config\PropertyNames.xml, Fri Feb 24 18:49:18 2017
+// Generated by makeprops.py from file ./config/PropertyNames.xml, Tue Feb 28 15:01:12 2017
// IMPORTANT: Do not edit this file -- any edits made here will be lost!
@@ -504,6 +504,43 @@ public final class PropertyNames
new Property("IceGridAdmin\\.Discovery\\.Reply\\.ThreadPool\\.ThreadIdleTime", false, null),
new Property("IceGridAdmin\\.Discovery\\.Reply\\.ThreadPool\\.ThreadPriority", false, null),
new Property("IceGridAdmin\\.Discovery\\.Reply\\.MessageSizeMax", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.ACM\\.Timeout", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.ACM\\.Heartbeat", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.ACM\\.Close", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.ACM", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.AdapterId", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Endpoints", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Locator\\.EndpointSelection", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Locator\\.ConnectionCached", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Locator\\.PreferSecure", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Locator\\.LocatorCacheTimeout", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Locator\\.InvocationTimeout", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Locator\\.Locator", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Locator\\.Router", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Locator\\.CollocationOptimized", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Locator\\.Context\\.[^\\s]+", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Locator", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.PublishedEndpoints", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.ReplicaGroupId", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Router\\.EndpointSelection", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Router\\.ConnectionCached", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Router\\.PreferSecure", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Router\\.LocatorCacheTimeout", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Router\\.InvocationTimeout", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Router\\.Locator", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Router\\.Router", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Router\\.CollocationOptimized", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Router\\.Context\\.[^\\s]+", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.Router", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.ProxyOptions", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.ThreadPool\\.Size", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.ThreadPool\\.SizeMax", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.ThreadPool\\.SizeWarn", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.ThreadPool\\.StackSize", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.ThreadPool\\.Serialize", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.ThreadPool\\.ThreadIdleTime", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.ThreadPool\\.ThreadPriority", false, null),
+ new Property("IceGridAdmin\\.Discovery\\.Locator\\.MessageSizeMax", false, null),
new Property("IceGridAdmin\\.Trace\\.Observers", false, null),
new Property("IceGridAdmin\\.Trace\\.SaveToRegistry", false, null),
null
diff --git a/java/src/Ice/src/main/java/com/zeroc/IceInternal/UdpMulticastClientTransceiver.java b/java/src/Ice/src/main/java/com/zeroc/IceInternal/UdpMulticastClientTransceiver.java
index e3edc69d4b5..2390cea50a1 100644
--- a/java/src/Ice/src/main/java/com/zeroc/IceInternal/UdpMulticastClientTransceiver.java
+++ b/java/src/Ice/src/main/java/com/zeroc/IceInternal/UdpMulticastClientTransceiver.java
@@ -161,7 +161,8 @@ final class UdpMulticastClientTransceiver implements Transceiver
public String toDetailedString()
{
StringBuilder s = new StringBuilder(toString());
- java.util.List<String> intfs = Network.getInterfacesForMulticast(_mcastInterface, _addr);
+ java.util.List<String> intfs = Network.getInterfacesForMulticast(_mcastInterface,
+ Network.getProtocolSupport(_addr));
if(!intfs.isEmpty())
{
s.append("\nlocal interfaces = ");
diff --git a/java/src/Ice/src/main/java/com/zeroc/IceInternal/UdpMulticastServerTransceiver.java b/java/src/Ice/src/main/java/com/zeroc/IceInternal/UdpMulticastServerTransceiver.java
index 8c7b462e89e..bfcc1c11060 100644
--- a/java/src/Ice/src/main/java/com/zeroc/IceInternal/UdpMulticastServerTransceiver.java
+++ b/java/src/Ice/src/main/java/com/zeroc/IceInternal/UdpMulticastServerTransceiver.java
@@ -169,7 +169,8 @@ final class UdpMulticastServerTransceiver implements Transceiver
public String toDetailedString()
{
StringBuilder s = new StringBuilder(toString());
- java.util.List<String> intfs = Network.getInterfacesForMulticast(_mcastInterface, _addr);
+ java.util.List<String> intfs = Network.getInterfacesForMulticast(_mcastInterface,
+ Network.getProtocolSupport(_addr));
if(!intfs.isEmpty())
{
s.append("\nlocal interfaces = ");
diff --git a/java/src/Ice/src/main/java/com/zeroc/IceInternal/UdpTransceiver.java b/java/src/Ice/src/main/java/com/zeroc/IceInternal/UdpTransceiver.java
index 491e6c0b7ee..8f6d5683251 100644
--- a/java/src/Ice/src/main/java/com/zeroc/IceInternal/UdpTransceiver.java
+++ b/java/src/Ice/src/main/java/com/zeroc/IceInternal/UdpTransceiver.java
@@ -290,7 +290,7 @@ final class UdpTransceiver implements Transceiver
}
else
{
- intfs = Network.getInterfacesForMulticast(_mcastInterface, _mcastAddr);
+ intfs = Network.getInterfacesForMulticast(_mcastInterface, Network.getProtocolSupport(_mcastAddr));
}
if(!intfs.isEmpty())
{
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 5e3910d4aef..ac99857d3ae 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
@@ -172,17 +172,78 @@ class LookupI implements Lookup
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)
+ {
+ }
+ }
+ assert(!_lookup.isEmpty());
}
void setLookupReply(LookupReplyPrx lookupReply)
{
- _lookupReply = lookupReply;
+ //
+ // 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())
+ {
+ com.zeroc.Ice.UDPEndpointInfo info =
+ (com.zeroc.Ice.UDPEndpointInfo)entry.getKey().ice_getEndpoints()[0].getInfo();
+ if(!info.mcastInterface.isEmpty())
+ {
+ for(com.zeroc.Ice.Endpoint q : lookupReply.ice_getEndpoints())
+ {
+ com.zeroc.Ice.EndpointInfo r = q.getInfo();
+ if(r instanceof com.zeroc.Ice.IPEndpointInfo &&
+ ((com.zeroc.Ice.IPEndpointInfo)r).host.equals(info.mcastInterface))
+ {
+ single[0] = q;
+ entry.setValue((LookupReplyPrx)lookupReply.ice_endpoints(single));
+ }
+ }
+ }
+
+ if(entry.getValue() == null)
+ {
+ // Fallback: just use the given lookup reply proxy if no matching endpoint found.
+ entry.setValue(lookupReply);
+ }
+ }
}
@Override
@@ -250,7 +311,10 @@ class LookupI implements Lookup
{
try
{
- _lookup.findObjectByIdAsync(_domainId, id, _lookupReply);
+ for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookup.entrySet())
+ {
+ entry.getKey().findObjectByIdAsync(_domainId, id, entry.getValue());
+ }
request.scheduleTimer(_timeout);
}
catch(com.zeroc.Ice.LocalException ex)
@@ -274,7 +338,10 @@ class LookupI implements Lookup
{
try
{
- _lookup.findAdapterByIdAsync(_domainId, adapterId, _lookupReply);
+ for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookup.entrySet())
+ {
+ entry.getKey().findAdapterByIdAsync(_domainId, adapterId, entry.getValue());
+ }
request.scheduleTimer(_timeout);
}
catch(com.zeroc.Ice.LocalException ex)
@@ -325,7 +392,10 @@ class LookupI implements Lookup
{
try
{
- _lookup.findObjectByIdAsync(_domainId, request.getId(), _lookupReply);
+ for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookup.entrySet())
+ {
+ entry.getKey().findObjectByIdAsync(_domainId, request.getId(), entry.getValue());
+ }
request.scheduleTimer(_timeout);
return;
}
@@ -350,7 +420,10 @@ class LookupI implements Lookup
{
try
{
- _lookup.findAdapterByIdAsync(_domainId, request.getId(), _lookupReply);
+ for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookup.entrySet())
+ {
+ entry.getKey().findAdapterByIdAsync(_domainId, request.getId(), entry.getValue());
+ }
request.scheduleTimer(_timeout);
return;
}
@@ -364,8 +437,7 @@ class LookupI implements Lookup
}
private LocatorRegistryI _registry;
- private final LookupPrx _lookup;
- private LookupReplyPrx _lookupReply;
+ private java.util.Map<LookupPrx, LookupReplyPrx> _lookup = new java.util.HashMap<>();
private final int _timeout;
private final int _retryCount;
private final int _latencyMultiplier;
diff --git a/java/src/IceDiscovery/src/main/java/com/zeroc/IceDiscovery/PluginI.java b/java/src/IceDiscovery/src/main/java/com/zeroc/IceDiscovery/PluginI.java
index 9b52edf963b..46bed9f0ee8 100644
--- a/java/src/IceDiscovery/src/main/java/com/zeroc/IceDiscovery/PluginI.java
+++ b/java/src/IceDiscovery/src/main/java/com/zeroc/IceDiscovery/PluginI.java
@@ -9,6 +9,8 @@
package com.zeroc.IceDiscovery;
+import com.zeroc.IceInternal.Network;
+
public class PluginI implements com.zeroc.Ice.Plugin
{
public PluginI(com.zeroc.Ice.Communicator communicator)
@@ -45,16 +47,28 @@ public class PluginI implements com.zeroc.Ice.Plugin
}
properties.setProperty("IceDiscovery.Multicast.Endpoints", s.toString());
}
- if(properties.getProperty("IceDiscovery.Reply.Endpoints").isEmpty())
+
+ String lookupEndpoints = properties.getProperty("IceDiscovery.Lookup");
+ if(lookupEndpoints.isEmpty())
{
- StringBuilder s = new StringBuilder();
- s.append("udp");
- if(!intf.isEmpty())
+ int protocol = ipv4 && !preferIPv6 ? Network.EnableIPv4 : Network.EnableIPv6;
+ java.util.List<String> interfaces = Network.getInterfacesForMulticast(intf, protocol);
+ for(String p : interfaces)
{
- s.append(" -h \"").append(intf).append("\"");
+ if(p != interfaces.get(0))
+ {
+ lookupEndpoints += ":";
+ }
+ lookupEndpoints += "udp -h \"" + address + "\" -p " + port + " --interface \"" + p + "\"";
}
- properties.setProperty("IceDiscovery.Reply.Endpoints", s.toString());
}
+
+ if(properties.getProperty("IceDiscovery.Reply.Endpoints").isEmpty())
+ {
+ properties.setProperty("IceDiscovery.Reply.Endpoints",
+ "udp -h " + (intf.isEmpty() ? "*" : "\"" + intf + "\""));
+ }
+
if(properties.getProperty("IceDiscovery.Locator.Endpoints").isEmpty())
{
properties.setProperty("IceDiscovery.Locator.AdapterId", java.util.UUID.randomUUID().toString());
@@ -71,34 +85,8 @@ public class PluginI implements com.zeroc.Ice.Plugin
com.zeroc.Ice.LocatorRegistryPrx locatorRegistryPrx = com.zeroc.Ice.LocatorRegistryPrx.uncheckedCast(
_locatorAdapter.addWithUUID(locatorRegistry));
- String lookupEndpoints = properties.getProperty("IceDiscovery.Lookup");
- if(lookupEndpoints.isEmpty())
- {
- StringBuilder s = new StringBuilder();
- s.append("udp -h \"").append(address).append("\" -p ").append(port);
- if(!intf.isEmpty())
- {
- s.append(" --interface \"").append(intf).append("\"");
- }
- lookupEndpoints = s.toString();
- }
-
com.zeroc.Ice.ObjectPrx lookupPrx = _communicator.stringToProxy("IceDiscovery/Lookup -d:" + lookupEndpoints);
lookupPrx = lookupPrx.ice_collocationOptimized(false); // No collocation optimization for the multicast proxy!
- try
- {
- lookupPrx.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(lookupPrx.toString());
- b.append('\n');
- b.append(ex.toString());
- throw new com.zeroc.Ice.PluginInitializationException(b.toString());
- }
//
// Add lookup and lookup reply Ice objects
diff --git a/java/src/IceGridGUI/src/main/java/com/zeroc/IceGridGUI/SessionKeeper.java b/java/src/IceGridGUI/src/main/java/com/zeroc/IceGridGUI/SessionKeeper.java
index a12122ea4cf..9aeb8315872 100644
--- a/java/src/IceGridGUI/src/main/java/com/zeroc/IceGridGUI/SessionKeeper.java
+++ b/java/src/IceGridGUI/src/main/java/com/zeroc/IceGridGUI/SessionKeeper.java
@@ -62,9 +62,8 @@ import javax.naming.ldap.Rdn;
import java.net.NetworkInterface;
import java.net.InetAddress;
-import com.zeroc.IceLocatorDiscovery.LookupPrx;
-import com.zeroc.IceLocatorDiscovery.LookupReplyPrx;
-import com.zeroc.IceLocatorDiscovery.LookupReply;
+import com.zeroc.IceLocatorDiscovery.Plugin;
+import com.zeroc.IceLocatorDiscovery.PluginFactory;
import com.zeroc.IceGrid.*;
@@ -1075,175 +1074,67 @@ public class SessionKeeper
_nextButton.requestFocusInWindow();
}
- public void destroyDiscoveryAdapter()
- {
- synchronized(SessionKeeper.this)
- {
- if(_discoveryAdapter != null)
- {
- SwingUtilities.invokeLater(() ->
- {
- if(_directDiscoveryEndpointModel.size() > 0)
- {
- _discoveryStatus.setText("");
- }
- else
- {
- _discoveryStatus.setText("No registries found");
- }
- });
- _discoveryAdapter.destroy();
- _discoveryAdapter = null;
- }
- }
- }
-
- public void refreshDiscoveryEndpoints()
+ public void refreshDiscoveryLocators()
{
final com.zeroc.Ice.Communicator communicator = _coordinator.getCommunicator();
- if(_discoveryLookupReply == null)
- {
- _discoveryLookupReply = new LookupReply()
- {
- @Override
- public void foundLocator(final com.zeroc.Ice.LocatorPrx locator, com.zeroc.Ice.Current curr)
- {
- SwingUtilities.invokeLater(() ->
- {
- if(_directDiscoveryEndpointModel.indexOf(locator) == -1)
- {
- _directDiscoveryEndpointModel.addElement(locator);
- }
-
- if(_directDiscoveryEndpointModel.size() > 0 &&
- _directDiscoveryEndpointList.getSelectedIndex() == -1)
- {
- _directDiscoveryEndpointList.setSelectedIndex(0);
- }
- });
- }
- };
- }
-
_discoveryStatus.setText("Searching for registries...");
-
- //
- // If there isn't any search in progress clear the endpoint list.
- //
- synchronized(SessionKeeper.this)
- {
- if(_discoveryAdapter == null)
- {
- _directDiscoveryEndpointModel.clear();
- }
- }
-
- final com.zeroc.Ice.Properties properties = communicator.getProperties();
- final String intf = _discoveryInterfaces.getSelectedItem().toString();
-
- String lookupEndpoints = properties.getProperty("IceGridAdmin.Discovery.Lookup");
- String address;
- if(properties.getPropertyAsIntWithDefault("Ice.IPv4", 1) > 0 &&
- properties.getPropertyAsInt("Ice.PreferIPv6Address") <= 0)
- {
- address = "239.255.0.1";
- }
- else
- {
- address = "ff15::1";
- }
- if(lookupEndpoints.isEmpty())
- {
- StringBuilder s = new StringBuilder();
- s.append("udp -h \"");
- s.append(properties.getPropertyWithDefault("IceGridAdmin.Discovery.Address", address));
- s.append("\" -p ");
- s.append(4061);
- if(!intf.isEmpty())
- {
- s.append(" --interface \"").append(intf).append("\"");
- }
- lookupEndpoints = s.toString();
- }
-
try
{
- final LookupPrx lookupPrx = LookupPrx.uncheckedCast(
- communicator.stringToProxy("IceLocatorDiscovery/Lookup -d:" +
- lookupEndpoints).ice_collocationOptimized(false).ice_router(null));
-
new Thread(() ->
{
synchronized(SessionKeeper.this)
{
- //
- // If search is in progress when refresh is hit, cancel the
- // finish task we will schedule a new one with this new
- // search.
- //
- if(_discoveryFinishTask != null)
- {
- _discoveryFinishTask.cancel();
- }
-
- if(properties.getProperty("IceGridAdmin.Discovery.Reply.Endpoints").isEmpty())
+ try
{
- StringBuilder s = new StringBuilder();
- s.append("udp");
- if(!intf.isEmpty())
+ if(_discoveryPlugin == null)
{
- s.append(" -h \"").append(intf).append("\"");
+ PluginFactory f = new PluginFactory();
+ _discoveryPlugin = (Plugin)f.create(communicator, "IceGridAdmin.Discovery", null);
+ _discoveryPlugin.initialize();
}
- properties.setProperty("IceGridAdmin.Discovery.Reply.Endpoints", s.toString());
- }
- try
- {
- if(_discoveryAdapter == null)
+ final List<com.zeroc.Ice.LocatorPrx> locators = _discoveryPlugin.getLocators("", 1000);
+ SwingUtilities.invokeLater(() ->
{
- _discoveryAdapter = communicator.createObjectAdapter(
- "IceGridAdmin.Discovery.Reply");
- _discoveryAdapter.activate();
- _discoveryReplyPrx = LookupReplyPrx.uncheckedCast(
- _discoveryAdapter.addWithUUID(_discoveryLookupReply).ice_datagram());
- }
+ _directDiscoveryLocatorModel.clear();
+ for(com.zeroc.Ice.LocatorPrx locator : locators)
+ {
+ _directDiscoveryLocatorModel.addElement(locator);
+ }
+ if(_directDiscoveryLocatorModel.size() > 0 &&
+ _directDiscoveryLocatorList.getSelectedIndex() == -1)
+ {
+ _directDiscoveryLocatorList.setSelectedIndex(0);
+ }
- lookupPrx.findLocator("", _discoveryReplyPrx);
+ if(_directDiscoveryLocatorModel.size() > 0)
+ {
+ _discoveryStatus.setText("");
+ }
+ else
+ {
+ _discoveryStatus.setText("No registries found");
+ }
+ });
}
catch(final com.zeroc.Ice.LocalException ex)
{
- ex.printStackTrace();
- destroyDiscoveryAdapter();
SwingUtilities.invokeLater(() ->
{
+ _discoveryStatus.setText("No registries found");
JOptionPane.showMessageDialog(ConnectionWizardDialog.this,
ex.toString(),
- "Error while looking up locator endpoints",
+ "Error while looking up registries",
JOptionPane.ERROR_MESSAGE);
});
}
-
- //
- // We schedule a timer task to destroy the discovery adapter after 2
- // seconds, the user doesn't need to wait, discovered proxies are
- // added as they are found.
- //
- _discoveryFinishTask = new java.util.TimerTask()
- {
- @Override
- public void run()
- {
- destroyDiscoveryAdapter();
- }
- };
- new java.util.Timer().schedule(_discoveryFinishTask, 2000);
}
}).start();
}
catch(com.zeroc.Ice.LocalException ex)
{
JOptionPane.showMessageDialog(ConnectionWizardDialog.this, ex.toString(),
- "Error while looking up locator endpoints", JOptionPane.ERROR_MESSAGE);
+ "Error while looking up registries", JOptionPane.ERROR_MESSAGE);
}
}
@@ -1298,69 +1189,11 @@ public class SessionKeeper
builder.append(new JLabel("Connect to an IceGrid registry through a Glacier2 router."));
_cardPanel.add(builder.getPanel(), WizardStep.ConnectionTypeStep.toString());
}
-
- JPanel discoveryInterface;
- {
- FormLayout layout = new FormLayout("pref, 2dlu, pref:grow", "pref");
- DefaultFormBuilder builder = new DefaultFormBuilder(layout);
- _discoveryInterfaces = new JComboBox();
-
- builder.append("Discovery Interface:", _discoveryInterfaces);
-
- List<String> addresses = new ArrayList<String>();
- try
- {
- Enumeration<NetworkInterface> p = NetworkInterface.getNetworkInterfaces();
-
- while(p != null && p.hasMoreElements())
- {
- NetworkInterface intf = p.nextElement();
- if(intf.isUp())
- {
- Enumeration<InetAddress> q = intf.getInetAddresses();
- while(q != null && q.hasMoreElements())
- {
- InetAddress address = q.nextElement();
- if(!address.isAnyLocalAddress())
- {
- addresses.add(address.getHostAddress());
- }
- }
- }
- }
- }
- catch(java.net.SocketException ex)
- {
- JOptionPane.showMessageDialog(ConnectionWizardDialog.this,
- ex.toString(),
- "Error retrieving network interfaces",
- JOptionPane.ERROR_MESSAGE);
- }
-
- final com.zeroc.Ice.Properties properties = _coordinator.getCommunicator().getProperties();
- String selected = properties.getPropertyWithDefault("IceGridAdmin.Discovery.Interface", "127.0.0.1");
- if(!addresses.contains(selected))
- {
- addresses.add(selected);
- }
-
- _discoveryInterfaces.setModel(new DefaultComboBoxModel(addresses.toArray()));
- _discoveryInterfaces.setSelectedItem(selected);
- _discoveryInterfaces.addActionListener(new ActionListener ()
- {
- @Override
- public void actionPerformed(ActionEvent e)
- {
- refreshDiscoveryEndpoints();
- }
- });
- discoveryInterface = builder.getPanel();
- }
- // Direct Discovery Endpoint List
+ // Direct Discovery Locator List
{
- _directDiscoveryEndpointModel = new DefaultListModel<>();
- _directDiscoveryEndpointList = new JList(_directDiscoveryEndpointModel)
+ _directDiscoveryLocatorModel = new DefaultListModel<>();
+ _directDiscoveryLocatorList = new JList(_directDiscoveryLocatorModel)
{
@Override
public String getToolTipText(MouseEvent evt)
@@ -1378,9 +1211,9 @@ public class SessionKeeper
return null;
}
};
- _directDiscoveryEndpointList.setVisibleRowCount(7);
- _directDiscoveryEndpointList.setFixedCellWidth(500);
- _directDiscoveryEndpointList.addMouseListener(
+ _directDiscoveryLocatorList.setVisibleRowCount(7);
+ _directDiscoveryLocatorList.setFixedCellWidth(500);
+ _directDiscoveryLocatorList.addMouseListener(
new MouseAdapter()
{
@Override
@@ -1388,8 +1221,8 @@ public class SessionKeeper
{
if(e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1)
{
- Object obj = _directDiscoveryEndpointModel.getElementAt(
- _directDiscoveryEndpointList.locationToIndex(e.getPoint()));
+ Object obj = _directDiscoveryLocatorModel.getElementAt(
+ _directDiscoveryLocatorList.locationToIndex(e.getPoint()));
if(obj != null && obj instanceof com.zeroc.Ice.LocatorPrx)
{
_nextButton.doClick(0);
@@ -1397,9 +1230,9 @@ public class SessionKeeper
}
}
});
-
- _directDiscoveryEndpointList.addListSelectionListener(new ListSelectionListener()
+
+ _directDiscoveryLocatorList.addListSelectionListener(new ListSelectionListener()
{
@Override
public void valueChanged(ListSelectionEvent event)
@@ -1409,20 +1242,20 @@ public class SessionKeeper
});
ButtonGroup group = new ButtonGroup();
- _directDiscoveryDiscoveredEndpoint = new JRadioButton(new AbstractAction("Discovered Endpoints")
+ _directDiscoveryDiscoveredLocators = new JRadioButton(new AbstractAction("Discovered Registries")
{
@Override
public void actionPerformed(ActionEvent e)
{
- _directDiscoveryEndpointList.setEnabled(true);
+ _directDiscoveryLocatorList.setEnabled(true);
_discoveryStatus.setEnabled(true);
_discoveryRefresh.setEnabled(true);
validatePanel();
- refreshDiscoveryEndpoints();
+ refreshDiscoveryLocators();
}
});
- _directDiscoveryDiscoveredEndpoint.setSelected(true);
- group.add(_directDiscoveryDiscoveredEndpoint);
+ _directDiscoveryDiscoveredLocators.setSelected(true);
+ group.add(_directDiscoveryDiscoveredLocators);
JPanel discoveryStatus;
{
@@ -1435,7 +1268,7 @@ public class SessionKeeper
@Override
public void actionPerformed(ActionEvent e)
{
- refreshDiscoveryEndpoints();
+ refreshDiscoveryLocators();
}
});
@@ -1449,8 +1282,7 @@ public class SessionKeeper
@Override
public void actionPerformed(ActionEvent e)
{
- destroyDiscoveryAdapter();
- _directDiscoveryEndpointList.setEnabled(false);
+ _directDiscoveryLocatorList.setEnabled(false);
_discoveryStatus.setEnabled(false);
_discoveryRefresh.setEnabled(false);
validatePanel();
@@ -1463,9 +1295,8 @@ public class SessionKeeper
DefaultFormBuilder builder = new DefaultFormBuilder(layout);
builder.border(Borders.DIALOG);
builder.rowGroupingEnabled(false);
- builder.append(_directDiscoveryDiscoveredEndpoint);
- builder.append(discoveryInterface);
- builder.append(createStrippedScrollPane(_directDiscoveryEndpointList));
+ builder.append(_directDiscoveryDiscoveredLocators);
+ builder.append(createStrippedScrollPane(_directDiscoveryLocatorList));
builder.append(discoveryStatus);
builder.append(_directDiscoveryManualEndpoint);
_cardPanel.add(builder.getPanel(), WizardStep.DirectDiscoveryChooseStep.toString());
@@ -2170,9 +2001,9 @@ public class SessionKeeper
{
_cardLayout.show(_cardPanel, WizardStep.DirectDiscoveryChooseStep.toString());
_wizardSteps.push(WizardStep.DirectDiscoveryChooseStep);
- if(_directDiscoveryDiscoveredEndpoint.isSelected())
+ if(_directDiscoveryDiscoveredLocators.isSelected())
{
- refreshDiscoveryEndpoints();
+ refreshDiscoveryLocators();
}
break;
}
@@ -2186,9 +2017,9 @@ public class SessionKeeper
}
else
{
- com.zeroc.Ice.LocatorPrx locator = _directDiscoveryEndpointList.getSelectedValue();
+ com.zeroc.Ice.LocatorPrx locator = _directDiscoveryLocatorList.getSelectedValue();
_directInstanceName.setText(locator.ice_getIdentity().category);
-
+
String endpoints = null;
for(com.zeroc.Ice.Endpoint endpoint : locator.ice_getEndpoints())
{
@@ -2496,7 +2327,8 @@ public class SessionKeeper
@Override
public void actionPerformed(ActionEvent e)
{
- destroyDiscoveryAdapter();
+ _discoveryPlugin.destroy();
+ _discoveryPlugin = null;
ConnectionInfo inf = getConfiguration();
if(inf == null)
@@ -2670,7 +2502,8 @@ public class SessionKeeper
@Override
public void actionPerformed(ActionEvent e)
{
- destroyDiscoveryAdapter();
+ _discoveryPlugin.destroy();
+ _discoveryPlugin = null;
dispose();
}
};
@@ -2707,7 +2540,7 @@ public class SessionKeeper
}
else
{
- _directDiscoveryEndpointList.requestFocusInWindow();
+ _directDiscoveryLocatorList.requestFocusInWindow();
}
break;
}
@@ -2851,7 +2684,7 @@ public class SessionKeeper
}
else
{
- validated = _directDiscoveryEndpointList.getSelectedValue() != null;
+ validated = _directDiscoveryLocatorList.getSelectedValue() != null;
}
break;
}
@@ -3247,17 +3080,13 @@ public class SessionKeeper
private JCheckBox _directConnectToMaster;
// Direct Discovery Endpoints
- private JComboBox _discoveryInterfaces;
- private JList<com.zeroc.Ice.LocatorPrx> _directDiscoveryEndpointList;
- private DefaultListModel<com.zeroc.Ice.LocatorPrx> _directDiscoveryEndpointModel;
- private JRadioButton _directDiscoveryDiscoveredEndpoint;
+ private JList<com.zeroc.Ice.LocatorPrx> _directDiscoveryLocatorList;
+ private DefaultListModel<com.zeroc.Ice.LocatorPrx> _directDiscoveryLocatorModel;
+ private JRadioButton _directDiscoveryDiscoveredLocators;
private JLabel _discoveryStatus;
private JButton _discoveryRefresh;
- private java.util.TimerTask _discoveryFinishTask;
- private com.zeroc.Ice.ObjectAdapter _discoveryAdapter;
- private LookupReplyPrx _discoveryReplyPrx;
- private LookupReply _discoveryLookupReply;
+ private Plugin _discoveryPlugin;
private JRadioButton _directDiscoveryManualEndpoint;
// Direct Endpoints panel components
diff --git a/java/src/IceLocatorDiscovery/src/main/java/com/zeroc/IceLocatorDiscovery/Plugin.java b/java/src/IceLocatorDiscovery/src/main/java/com/zeroc/IceLocatorDiscovery/Plugin.java
new file mode 100644
index 00000000000..b050046aab7
--- /dev/null
+++ b/java/src/IceLocatorDiscovery/src/main/java/com/zeroc/IceLocatorDiscovery/Plugin.java
@@ -0,0 +1,17 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2017 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+package com.zeroc.IceLocatorDiscovery;
+
+import java.util.List;
+
+public interface Plugin extends com.zeroc.Ice.Plugin
+{
+ List<com.zeroc.Ice.LocatorPrx> getLocators(String instanceName, int waitTime);
+}
diff --git a/java/src/IceLocatorDiscovery/src/main/java/com/zeroc/IceLocatorDiscovery/PluginFactory.java b/java/src/IceLocatorDiscovery/src/main/java/com/zeroc/IceLocatorDiscovery/PluginFactory.java
index 6c6b82f4fac..cec8ddf78b3 100644
--- a/java/src/IceLocatorDiscovery/src/main/java/com/zeroc/IceLocatorDiscovery/PluginFactory.java
+++ b/java/src/IceLocatorDiscovery/src/main/java/com/zeroc/IceLocatorDiscovery/PluginFactory.java
@@ -14,6 +14,6 @@ public class PluginFactory implements com.zeroc.Ice.PluginFactory
@Override
public com.zeroc.Ice.Plugin create(com.zeroc.Ice.Communicator communicator, String name, String[] args)
{
- return new PluginI(communicator);
+ return new PluginI(name, communicator);
}
}
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 5cdf0d781ff..3a50fd6c79b 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
@@ -9,13 +9,16 @@
package com.zeroc.IceLocatorDiscovery;
+import com.zeroc.IceInternal.Network;
import java.util.List;
import java.util.Arrays;
import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
-class PluginI implements com.zeroc.Ice.Plugin
+class PluginI implements Plugin
{
private static class Request
{
@@ -135,24 +138,85 @@ class PluginI implements com.zeroc.Ice.Plugin
private static class LocatorI implements com.zeroc.Ice.BlobjectAsync
{
- LocatorI(LookupPrx lookup, com.zeroc.Ice.Properties properties, String instanceName,
+ LocatorI(String name, LookupPrx lookup, com.zeroc.Ice.Properties properties, String instanceName,
com.zeroc.Ice.LocatorPrx voidLocator)
{
- _lookup = lookup;
- _timeout = properties.getPropertyAsIntWithDefault("IceLocatorDiscovery.Timeout", 300);
- _retryCount = properties.getPropertyAsIntWithDefault("IceLocatorDiscovery.RetryCount", 3);
- _retryDelay = properties.getPropertyAsIntWithDefault("IceLocatorDiscovery.RetryDelay", 2000);
+ _timeout = properties.getPropertyAsIntWithDefault(name + ".Timeout", 300);
+ _retryCount = properties.getPropertyAsIntWithDefault(name + ".RetryCount", 3);
+ _retryDelay = properties.getPropertyAsIntWithDefault(name + ".RetryDelay", 2000);
_timer = com.zeroc.IceInternal.Util.getInstance(lookup.ice_getCommunicator()).timer();
_instanceName = instanceName;
_warned = false;
_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());
+ }
+
+ //
+ // 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)
+ {
+ }
+ }
+ assert(!_lookup.isEmpty());
}
public void setLookupReply(LookupReplyPrx lookupReply)
{
- _lookupReply = lookupReply;
+ //
+ // 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())
+ {
+ com.zeroc.Ice.UDPEndpointInfo info =
+ (com.zeroc.Ice.UDPEndpointInfo)entry.getKey().ice_getEndpoints()[0].getInfo();
+ if(!info.mcastInterface.isEmpty())
+ {
+ for(com.zeroc.Ice.Endpoint q : lookupReply.ice_getEndpoints())
+ {
+ com.zeroc.Ice.EndpointInfo r = q.getInfo();
+ if(r instanceof com.zeroc.Ice.IPEndpointInfo &&
+ ((com.zeroc.Ice.IPEndpointInfo)r).host.equals(info.mcastInterface))
+ {
+ single[0] = q;
+ entry.setValue((LookupReplyPrx)lookupReply.ice_endpoints(single));
+ }
+ }
+ }
+
+ if(entry.getValue() == null)
+ {
+ // Fallback: just use the given lookup reply proxy if no matching endpoint found.
+ entry.setValue(lookupReply);
+ }
+ }
}
@Override
@@ -164,6 +228,56 @@ class PluginI implements com.zeroc.Ice.Plugin
return f;
}
+ public List<com.zeroc.Ice.LocatorPrx>
+ getLocators(String instanceName, int waitTime)
+ {
+ //
+ // Clear locators from previous search.
+ //
+ synchronized(this)
+ {
+ _locators.clear();
+ }
+
+ //
+ // Find a locator
+ //
+ invoke(null, null);
+
+ //
+ // Wait for responses
+ //
+ try
+ {
+ if(instanceName.isEmpty())
+ {
+ Thread.sleep(waitTime);
+ }
+ else
+ {
+ synchronized(this)
+ {
+ while(!_locators.containsKey(instanceName) && _pendingRetryCount > 0)
+ {
+ wait(waitTime);
+ }
+ }
+ }
+ }
+ catch(java.lang.InterruptedException ex)
+ {
+ throw new com.zeroc.Ice.OperationInterruptedException();
+ }
+
+ //
+ // Return found locators
+ //
+ synchronized(this)
+ {
+ return new ArrayList<>(_locators.values());
+ }
+ }
+
public synchronized void foundLocator(com.zeroc.Ice.LocatorPrx locator)
{
if(locator == null ||
@@ -176,7 +290,8 @@ class PluginI implements com.zeroc.Ice.Plugin
// If we already have a locator assigned, ensure the given locator
// has the same identity, otherwise ignore it.
//
- if(_locator != null && !locator.ice_getIdentity().category.equals(_locator.ice_getIdentity().category))
+ if(!_pendingRequests.isEmpty() &&
+ _locator != null && !locator.ice_getIdentity().category.equals(_locator.ice_getIdentity().category))
{
if(!_warned)
{
@@ -201,14 +316,15 @@ class PluginI implements com.zeroc.Ice.Plugin
_pendingRetryCount = 0;
}
- if(_locator != null)
+ com.zeroc.Ice.LocatorPrx l =
+ _pendingRequests.isEmpty() ? _locators.get(locator.ice_getIdentity().category) : _locator;
+ if(l != null)
{
//
// We found another locator replica, append its endpoints to the
// current locator proxy endpoints.
//
- List<com.zeroc.Ice.Endpoint> newEndpoints = new ArrayList<>(
- Arrays.asList(_locator.ice_getEndpoints()));
+ List<com.zeroc.Ice.Endpoint> newEndpoints = new ArrayList<>(Arrays.asList(l.ice_getEndpoints()));
for(com.zeroc.Ice.Endpoint p : locator.ice_getEndpoints())
{
//
@@ -229,50 +345,72 @@ class PluginI implements com.zeroc.Ice.Plugin
}
}
- _locator = (com.zeroc.Ice.LocatorPrx)_locator.ice_endpoints(
+ l = (com.zeroc.Ice.LocatorPrx)l.ice_endpoints(
newEndpoints.toArray(new com.zeroc.Ice.Endpoint[newEndpoints.size()]));
}
else
{
- _locator = locator;
+ l = locator;
+ }
+
+ if(_pendingRequests.isEmpty())
+ {
+ _locators.put(locator.ice_getIdentity().category, l);
+ notify();
+ }
+ else
+ {
+ _locator = l;
if(_instanceName.isEmpty())
{
_instanceName = _locator.ice_getIdentity().category; // Stick to the first locator
}
- }
- //
- // Send pending requests if any.
- //
- for(Request req : _pendingRequests)
- {
- req.invoke(_locator);
+ //
+ // Send pending requests if any.
+ //
+ for(Request req : _pendingRequests)
+ {
+ req.invoke(_locator);
+ }
+ _pendingRequests.clear();
}
- _pendingRequests.clear();
}
public synchronized void invoke(com.zeroc.Ice.LocatorPrx locator, Request request)
{
if(_locator != null && _locator != locator)
{
- request.invoke(_locator);
+ if(request != null)
+ {
+ request.invoke(_locator);
+ }
}
else if(com.zeroc.IceInternal.Time.currentMonotonicTimeMillis() < _nextRetry)
{
- request.invoke(_voidLocator); // Don't retry to find a locator before the retry delay expires
+ if(request != null)
+ {
+ request.invoke(_voidLocator); // Don't retry to find a locator before the retry delay expires
+ }
}
else
{
_locator = null;
- _pendingRequests.add(request);
+ if(request != null)
+ {
+ _pendingRequests.add(request);
+ }
if(_pendingRetryCount == 0) // No request in progress
{
_pendingRetryCount = _retryCount;
try
{
- _lookup.findLocatorAsync(_instanceName, _lookupReply); // Send multicast request.
+ for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookup.entrySet())
+ {
+ entry.getKey().findLocatorAsync(_instanceName, entry.getValue()); // Send multicast request.
+ }
_future = _timer.schedule(_retryTask, _timeout, java.util.concurrent.TimeUnit.MILLISECONDS);
}
catch(com.zeroc.Ice.LocalException ex)
@@ -299,7 +437,10 @@ class PluginI implements com.zeroc.Ice.Plugin
{
try
{
- _lookup.findLocatorAsync(_instanceName, _lookupReply); // Send multicast request.
+ for(Map.Entry<LookupPrx, LookupReplyPrx> entry : _lookup.entrySet())
+ {
+ entry.getKey().findLocatorAsync(_instanceName, entry.getValue()); // Send multicast request
+ }
_future = _timer.schedule(_retryTask, _timeout, java.util.concurrent.TimeUnit.MILLISECONDS);
return;
}
@@ -320,7 +461,7 @@ class PluginI implements com.zeroc.Ice.Plugin
}
};
- private final LookupPrx _lookup;
+ private final Map<LookupPrx, LookupReplyPrx> _lookup = new java.util.HashMap<>();
private final int _timeout;
private java.util.concurrent.Future<?> _future;
private final java.util.concurrent.ScheduledExecutorService _timer;
@@ -329,9 +470,9 @@ class PluginI implements com.zeroc.Ice.Plugin
private String _instanceName;
private boolean _warned;
- private LookupReplyPrx _lookupReply;
private com.zeroc.Ice.LocatorPrx _locator;
private com.zeroc.Ice.LocatorPrx _voidLocator;
+ private Map<String, com.zeroc.Ice.LocatorPrx> _locators = new HashMap<>();
private int _pendingRetryCount;
private List<Request> _pendingRequests = new ArrayList<>();
@@ -354,8 +495,9 @@ class PluginI implements com.zeroc.Ice.Plugin
private final LocatorI _locator;
}
- public PluginI(com.zeroc.Ice.Communicator communicator)
+ public PluginI(String name, com.zeroc.Ice.Communicator communicator)
{
+ _name = name;
_communicator = communicator;
}
@@ -369,76 +511,63 @@ class PluginI implements com.zeroc.Ice.Plugin
String address;
if(ipv4 && !preferIPv6)
{
- address = properties.getPropertyWithDefault("IceLocatorDiscovery.Address", "239.255.0.1");
+ address = properties.getPropertyWithDefault(_name + ".Address", "239.255.0.1");
}
else
{
- address = properties.getPropertyWithDefault("IceLocatorDiscovery.Address", "ff15::1");
+ address = properties.getPropertyWithDefault(_name + ".Address", "ff15::1");
}
- int port = properties.getPropertyAsIntWithDefault("IceLocatorDiscovery.Port", 4061);
- String intf = properties.getProperty("IceLocatorDiscovery.Interface");
+ int port = properties.getPropertyAsIntWithDefault(_name + ".Port", 4061);
+ String intf = properties.getProperty(_name + ".Interface");
- if(properties.getProperty("IceLocatorDiscovery.Reply.Endpoints").isEmpty())
+ String lookupEndpoints = properties.getProperty(_name + ".Lookup");
+ if(lookupEndpoints.isEmpty())
{
- StringBuilder s = new StringBuilder();
- s.append("udp");
- if(!intf.isEmpty())
+ int protocol = ipv4 && !preferIPv6 ? Network.EnableIPv4 : Network.EnableIPv6;
+ java.util.List<String> interfaces = Network.getInterfacesForMulticast(intf, protocol);
+ for(String p : interfaces)
{
- s.append(" -h \"").append(intf).append("\"");
+ if(p != interfaces.get(0))
+ {
+ lookupEndpoints += ":";
+ }
+ lookupEndpoints += "udp -h \"" + address + "\" -p " + port + " --interface \"" + p + "\"";
}
- properties.setProperty("IceLocatorDiscovery.Reply.Endpoints", s.toString());
}
- if(properties.getProperty("IceLocatorDiscovery.Locator.Endpoints").isEmpty())
+
+ if(properties.getProperty(_name + ".Reply.Endpoints").isEmpty())
+ {
+ properties.setProperty(_name + ".Reply.Endpoints", "udp -h " + (intf.isEmpty() ? "*" : "\"" + intf + "\""));
+ }
+
+ if(properties.getProperty(_name + ".Locator.Endpoints").isEmpty())
{
- properties.setProperty("IceLocatorDiscovery.Locator.AdapterId", java.util.UUID.randomUUID().toString());
+ properties.setProperty(_name + ".Locator.AdapterId", java.util.UUID.randomUUID().toString());
}
- _replyAdapter = _communicator.createObjectAdapter("IceLocatorDiscovery.Reply");
- _locatorAdapter = _communicator.createObjectAdapter("IceLocatorDiscovery.Locator");
+ _replyAdapter = _communicator.createObjectAdapter(_name + ".Reply");
+ _locatorAdapter = _communicator.createObjectAdapter(_name + ".Locator");
// We don't want those adapters to be registered with the locator so clear their locator.
_replyAdapter.setLocator(null);
_locatorAdapter.setLocator(null);
- String lookupEndpoints = properties.getProperty("IceLocatorDiscovery.Lookup");
- if(lookupEndpoints.isEmpty())
- {
- StringBuilder s = new StringBuilder();
- s.append("udp -h \"").append(address).append("\" -p ").append(port);
- if(!intf.isEmpty())
- {
- s.append(" --interface \"").append(intf).append("\"");
- }
- lookupEndpoints = s.toString();
- }
-
com.zeroc.Ice.ObjectPrx lookupPrx =
_communicator.stringToProxy("IceLocatorDiscovery/Lookup -d:" + lookupEndpoints);
lookupPrx = lookupPrx.ice_collocationOptimized(false); // No collocation optimization for the multicast proxy!
- try
- {
- lookupPrx.ice_getConnection(); // Ensure we can establish a connection to the multicast proxy
- }
- catch(com.zeroc.Ice.LocalException ex)
- {
- StringBuilder s = new StringBuilder();
- s.append("IceLocatorDiscovery is unable to establish a multicast connection:\n");
- s.append("proxy = ").append(lookupPrx.toString()).append("\n").append(ex);
- throw new com.zeroc.Ice.PluginInitializationException(s.toString());
- }
com.zeroc.Ice.LocatorPrx voidLoc =
com.zeroc.Ice.LocatorPrx.uncheckedCast(_locatorAdapter.addWithUUID(new VoidLocatorI()));
- String instanceName = properties.getProperty("IceLocatorDiscovery.InstanceName");
+ String instanceName = properties.getProperty(_name + ".InstanceName");
com.zeroc.Ice.Identity id = new com.zeroc.Ice.Identity();
id.name = "Locator";
id.category = !instanceName.isEmpty() ? instanceName : java.util.UUID.randomUUID().toString();
- LocatorI locator = new LocatorI(LookupPrx.uncheckedCast(lookupPrx), properties, instanceName, voidLoc);
- _communicator.setDefaultLocator(com.zeroc.Ice.LocatorPrx.uncheckedCast(_locatorAdapter.addWithUUID(locator)));
+ _locator = new LocatorI(_name, LookupPrx.uncheckedCast(lookupPrx), properties, instanceName, voidLoc);
+ _communicator.setDefaultLocator(com.zeroc.Ice.LocatorPrx.uncheckedCast(_locatorAdapter.addWithUUID(_locator)));
- com.zeroc.Ice.ObjectPrx lookupReply = _replyAdapter.addWithUUID(new LookupReplyI(locator)).ice_datagram();
- locator.setLookupReply(LookupReplyPrx.uncheckedCast(lookupReply));
+ com.zeroc.Ice.ObjectPrx lookupReply = _replyAdapter.addWithUUID(new LookupReplyI(_locator)).ice_datagram();
+ _locator.setLookupReply(LookupReplyPrx.uncheckedCast(lookupReply));
_replyAdapter.activate();
_locatorAdapter.activate();
@@ -451,7 +580,15 @@ class PluginI implements com.zeroc.Ice.Plugin
_locatorAdapter.destroy();
}
+ public List<com.zeroc.Ice.LocatorPrx>
+ getLocators(String instanceName, int waitTime)
+ {
+ return _locator.getLocators(instanceName, waitTime);
+ }
+
+ private String _name;
private com.zeroc.Ice.Communicator _communicator;
private com.zeroc.Ice.ObjectAdapter _locatorAdapter;
private com.zeroc.Ice.ObjectAdapter _replyAdapter;
+ private LocatorI _locator;
}
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 f5f8cb46f8c..1c9e28cccc2 100644
--- a/java/test/src/main/java/test/IceGrid/simple/AllTests.java
+++ b/java/test/src/main/java/test/IceGrid/simple/AllTests.java
@@ -88,11 +88,6 @@ public class AllTests
initData.properties.setProperty("Ice.Default.Locator", "");
initData.properties.setProperty("Ice.Plugin.IceLocatorDiscovery",
"IceLocatorDiscovery:com.zeroc.IceLocatorDiscovery.PluginFactory");
- if(System.getProperty("os.name").contains("OS X") &&
- initData.properties.getPropertyAsInt("Ice.PreferIPv6Address") > 0)
- {
- initData.properties.setProperty("IceLocatorDiscovery.Interface", "::1");
- }
initData.properties.setProperty("IceLocatorDiscovery.Port", Integer.toString(app.getTestPort(99)));
initData.properties.setProperty("AdapterForDiscoveryTest.AdapterId", "discoveryAdapter");
initData.properties.setProperty("AdapterForDiscoveryTest.Endpoints", "default");
diff --git a/js/src/Ice/PropertyNames.js b/js/src/Ice/PropertyNames.js
index 9aa03b29979..835a981434d 100644
--- a/js/src/Ice/PropertyNames.js
+++ b/js/src/Ice/PropertyNames.js
@@ -6,7 +6,7 @@
// ICE_LICENSE file included in this distribution.
//
// **********************************************************************
-// Generated by makeprops.py from file ..\config\PropertyNames.xml, Fri Feb 24 18:49:18 2017
+// Generated by makeprops.py from file ./config/PropertyNames.xml, Tue Feb 28 15:01:12 2017
// IMPORTANT: Do not edit this file -- any edits made here will be lost!
diff --git a/scripts/Expect.py b/scripts/Expect.py
index aacaf80258e..a3bf1962724 100755
--- a/scripts/Expect.py
+++ b/scripts/Expect.py
@@ -655,7 +655,7 @@ class Expect (object):
raise RuntimeError("unexpected exit status: expected: %d, got %d\n" % (expected, result))
self.wait(timeout)
- if self.mapping == "java":
+ if self.mapping in ["java", "java-compat"]:
if self.killed is not None:
if win32:
test(self.exitstatus, -self.killed)
@@ -674,6 +674,6 @@ class Expect (object):
def hasInterruptSupport(self):
"""Return True if the application gracefully terminated, False otherwise."""
- if win32 and self.mapping == "java":
+ if win32 and self.mapping in ["java", "java-compat"]:
return False
return True
diff --git a/scripts/IceGridUtil.py b/scripts/IceGridUtil.py
index a60de105794..296d92a8e56 100644
--- a/scripts/IceGridUtil.py
+++ b/scripts/IceGridUtil.py
@@ -158,10 +158,6 @@ class IceGridRegistry(ProcessFromBinDir, Server):
'IceGrid.Registry.DefaultTemplates' :
'"' + os.path.abspath(os.path.join(toplevel, "cpp", "config", "templates.xml")) + '"'
}
-
- if current.config.ipv6 and not isinstance(platform, Linux):
- props['IceGrid.Registry.Discovery.Interface'] = '::1'
-
return props
def getEndpoints(self, current):
diff --git a/scripts/Util.py b/scripts/Util.py
index 4df40f78e0e..3b968a2c553 100644
--- a/scripts/Util.py
+++ b/scripts/Util.py
@@ -2071,7 +2071,6 @@ class BrowserProcessController(RemoteProcessController):
def __init__(self, current):
RemoteProcessController.__init__(self, current, "ws -h 127.0.0.1 -p 15002:wss -h 127.0.0.1 -p 15003")
self.httpServer = None
- self.safariDriver = None
try:
from selenium import webdriver
if not hasattr(webdriver, current.config.browser):
@@ -2136,10 +2135,6 @@ class BrowserProcessController(RemoteProcessController):
self.httpServer.terminate()
self.httpServer = None
- if self.safariDriver:
- self.safariDriver.terminate()
- self.safariDriver = None
-
try:
self.driver.quit()
except:
diff --git a/scripts/tests/IceDiscovery/simple.py b/scripts/tests/IceDiscovery/simple.py
index d04aea87985..40c8a00b2a0 100644
--- a/scripts/tests/IceDiscovery/simple.py
+++ b/scripts/tests/IceDiscovery/simple.py
@@ -17,7 +17,6 @@
props = lambda process, current: {
"IceDiscovery.Timeout": 50,
"IceDiscovery.RetryCount": 5,
- "IceDiscovery.Interface": '::1' if current.config.ipv6 and not isinstance(platform, Linux) else "",
"Ice.Plugin.IceDiscovery": current.getPluginEntryPoint("IceDiscovery", process)
}
diff --git a/slice/IceLocatorDiscovery/IceLocatorDiscovery.ice b/slice/IceLocatorDiscovery/IceLocatorDiscovery.ice
index b0c0db983e7..68eb3c31c45 100644
--- a/slice/IceLocatorDiscovery/IceLocatorDiscovery.ice
+++ b/slice/IceLocatorDiscovery/IceLocatorDiscovery.ice
@@ -8,7 +8,7 @@
// **********************************************************************
#pragma once
-[["ice-prefix", "cpp:header-ext:h", "objc:header-dir:objc"]]
+[["ice-prefix", "cpp:dll-export:ICE_LOCATOR_DISCOVERY_API", "cpp:header-ext:h", "objc:header-dir:objc"]]
#include <Ice/Locator.ice>