summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenoit Foucher <benoit@zeroc.com>2018-02-16 12:36:36 +0100
committerBenoit Foucher <benoit@zeroc.com>2018-02-16 12:36:36 +0100
commit1d9509c347547b2d36d6fa3ff667927836d72245 (patch)
treedf6cc4ac9d1e2742ae8d9bf36a4f7927e7f970c1
parentAllow to create NuGet packages with single platform/configuration (diff)
downloadice-1d9509c347547b2d36d6fa3ff667927836d72245.tar.bz2
ice-1d9509c347547b2d36d6fa3ff667927836d72245.tar.xz
ice-1d9509c347547b2d36d6fa3ff667927836d72245.zip
Improved object adapter getPublishedEndpoints/refreshPublishedEndpoints method
to return the Ice router server endpoints if the adapter is associated with a router. setPublishedEndpoints now also raises an invalid argument exception for such adapters. Also fixed a rare deadlock that could occur on adapter creating if the router wasn't accessible. Fixes ICE-8675 and ICE-8650
-rw-r--r--CHANGELOG-3.7.md6
-rw-r--r--cpp/src/Ice/ConnectionFactory.cpp7
-rw-r--r--cpp/src/Ice/ObjectAdapterFactory.cpp70
-rw-r--r--cpp/src/Ice/ObjectAdapterI.cpp179
-rw-r--r--cpp/src/Ice/ObjectAdapterI.h3
-rw-r--r--cpp/src/Ice/RouterInfo.cpp32
-rw-r--r--cpp/src/Ice/RouterInfo.h2
-rw-r--r--cpp/test/Ice/adapterDeactivation/AllTests.cpp78
-rw-r--r--cpp/test/Ice/adapterDeactivation/ServantLocatorI.cpp60
-rw-r--r--cpp/test/Ice/adapterDeactivation/ServantLocatorI.h1
-rw-r--r--csharp/src/Ice/ConnectionFactory.cs8
-rw-r--r--csharp/src/Ice/ObjectAdapterFactory.cs59
-rw-r--r--csharp/src/Ice/ObjectAdapterI.cs226
-rw-r--r--csharp/src/Ice/RouterInfo.cs29
-rw-r--r--csharp/test/Ice/adapterDeactivation/AllTests.cs75
-rw-r--r--csharp/test/Ice/adapterDeactivation/ServantLocatorI.cs37
-rw-r--r--java-compat/gradle/wrapper/gradle-wrapper.properties4
-rw-r--r--java-compat/src/Ice/src/main/java/Ice/ObjectAdapterI.java214
-rw-r--r--java-compat/src/Ice/src/main/java/IceInternal/ObjectAdapterFactory.java66
-rw-r--r--java-compat/src/Ice/src/main/java/IceInternal/OutgoingConnectionFactory.java69
-rw-r--r--java-compat/src/Ice/src/main/java/IceInternal/RouterInfo.java27
-rw-r--r--java-compat/test/src/main/java/test/Ice/adapterDeactivation/AllTests.java76
-rw-r--r--java-compat/test/src/main/java/test/Ice/adapterDeactivation/ServantLocatorI.java35
-rw-r--r--java/src/Ice/src/main/java/com/zeroc/Ice/ObjectAdapterI.java210
-rw-r--r--java/src/Ice/src/main/java/com/zeroc/IceInternal/ObjectAdapterFactory.java68
-rw-r--r--java/src/Ice/src/main/java/com/zeroc/IceInternal/OutgoingConnectionFactory.java71
-rw-r--r--java/src/Ice/src/main/java/com/zeroc/IceInternal/RouterInfo.java27
-rw-r--r--java/test/src/main/java/test/Ice/adapterDeactivation/AllTests.java78
-rw-r--r--java/test/src/main/java/test/Ice/adapterDeactivation/ServantLocatorI.java34
-rw-r--r--js/gulpfile.js1
-rw-r--r--js/src/Ice/ObjectAdapterI.js232
-rw-r--r--js/src/Ice/RouterInfo.js30
-rw-r--r--js/test/Ice/adapterDeactivation/Client.js226
-rw-r--r--js/test/Ice/adapterDeactivation/Test.ice27
-rw-r--r--python/test/Ice/adapterDeactivation/AllTests.py79
-rw-r--r--python/test/Ice/adapterDeactivation/TestI.py25
-rw-r--r--scripts/Util.py3
37 files changed, 1644 insertions, 830 deletions
diff --git a/CHANGELOG-3.7.md b/CHANGELOG-3.7.md
index a848884a31e..b329f6650b0 100644
--- a/CHANGELOG-3.7.md
+++ b/CHANGELOG-3.7.md
@@ -27,6 +27,12 @@ These are the changes since Ice 3.7.0 included in this pre-release.
## General Changes
+- Improved `Ice::ObjectAdapter` `getPublishedEndpoints` and
+ `refreshPublishedEndpoints` methods to now return or refresh the Ice router
+ server endpoints if the adapter is associated with a router. Calling the
+ `setPublishedEndpoints` method on an adapter associated with a router also now
+ raises an invalid argument exception.
+
- Added tracing support for IceGrid and locator discovery. The IceGrid registry
supports the `IceGrid.Registry.Trace.Discovery` property and the
`IceLocatorDiscovery` plug-in supports `IceLocatorDiscovery.Trace.Lookup` to
diff --git a/cpp/src/Ice/ConnectionFactory.cpp b/cpp/src/Ice/ConnectionFactory.cpp
index 955c661bfb9..9652a253ff9 100644
--- a/cpp/src/Ice/ConnectionFactory.cpp
+++ b/cpp/src/Ice/ConnectionFactory.cpp
@@ -271,6 +271,10 @@ IceInternal::OutgoingConnectionFactory::create(const vector<EndpointIPtr>& endpt
void
IceInternal::OutgoingConnectionFactory::setRouterInfo(const RouterInfoPtr& routerInfo)
{
+ assert(routerInfo);
+ ObjectAdapterPtr adapter = routerInfo->getAdapter();
+ vector<EndpointIPtr> endpoints = routerInfo->getClientEndpoints(); // Must be called outside the synchronization
+
IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*this);
if(_destroyed)
@@ -278,7 +282,6 @@ IceInternal::OutgoingConnectionFactory::setRouterInfo(const RouterInfoPtr& route
throw CommunicatorDestroyedException(__FILE__, __LINE__);
}
- assert(routerInfo);
//
// Search for connections to the router's client proxy endpoints,
@@ -286,8 +289,6 @@ IceInternal::OutgoingConnectionFactory::setRouterInfo(const RouterInfoPtr& route
// callbacks from the router can be received over such
// connections.
//
- ObjectAdapterPtr adapter = routerInfo->getAdapter();
- vector<EndpointIPtr> endpoints = routerInfo->getClientEndpoints();
for(vector<EndpointIPtr>::const_iterator p = endpoints.begin(); p != endpoints.end(); ++p)
{
EndpointIPtr endpoint = *p;
diff --git a/cpp/src/Ice/ObjectAdapterFactory.cpp b/cpp/src/Ice/ObjectAdapterFactory.cpp
index 69fbc13aa2c..12de90e3212 100644
--- a/cpp/src/Ice/ObjectAdapterFactory.cpp
+++ b/cpp/src/Ice/ObjectAdapterFactory.cpp
@@ -41,8 +41,8 @@ IceInternal::ObjectAdapterFactory::shutdown()
adapters = _adapters;
- _instance = 0;
- _communicator = 0;
+ _instance = ICE_NULLPTR;
+ _communicator = ICE_NULLPTR;
notifyAll();
}
@@ -147,32 +147,66 @@ IceInternal::ObjectAdapterFactory::updateObservers(void (ObjectAdapterI::*fn)())
ObjectAdapterPtr
IceInternal::ObjectAdapterFactory::createObjectAdapter(const string& name, const RouterPrxPtr& router)
{
- IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
-
- if(!_instance)
+ ObjectAdapterIPtr adapter;
{
- throw CommunicatorDestroyedException(__FILE__, __LINE__);
+ IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
+
+ if(!_instance)
+ {
+ throw CommunicatorDestroyedException(__FILE__, __LINE__);
+ }
+
+ if(name.empty())
+ {
+ string uuid = Ice::generateUUID();
+ adapter = ICE_MAKE_SHARED(ObjectAdapterI, _instance, _communicator, ICE_SHARED_FROM_THIS, uuid, true);
+ }
+ else
+ {
+ if(_adapterNamesInUse.find(name) != _adapterNamesInUse.end())
+ {
+ throw AlreadyRegisteredException(__FILE__, __LINE__, "object adapter", name);
+ }
+ adapter = ICE_MAKE_SHARED(ObjectAdapterI, _instance, _communicator, ICE_SHARED_FROM_THIS, name, false);
+ _adapterNamesInUse.insert(name);
+ }
}
- ObjectAdapterIPtr adapter;
- if(name.empty())
+ //
+ // Must be called outside the synchronization since initialize can make client invocations
+ // on the router if it's set.
+ //
+ bool initialized = false;
+ try
{
- string uuid = Ice::generateUUID();
- adapter = ICE_MAKE_SHARED(ObjectAdapterI, _instance, _communicator, ICE_SHARED_FROM_THIS, uuid, true);
- adapter->initialize(ICE_NULLPTR);
+ adapter->initialize(router);
+ initialized = true;
+
+ IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
+ if(!_instance)
+ {
+ throw CommunicatorDestroyedException(__FILE__, __LINE__);
+ }
+ _adapters.push_back(adapter);
}
- else
+ catch(const Ice::CommunicatorDestroyedException&)
{
- if(_adapterNamesInUse.find(name) != _adapterNamesInUse.end())
+ if(initialized)
{
- throw AlreadyRegisteredException(__FILE__, __LINE__, "object adapter", name);
+ adapter->destroy();
}
- adapter = ICE_MAKE_SHARED(ObjectAdapterI, _instance, _communicator, ICE_SHARED_FROM_THIS, name, false);
- adapter->initialize(router);
- _adapterNamesInUse.insert(name);
+ throw;
+ }
+ catch(const std::exception&)
+ {
+ if(!name.empty())
+ {
+ IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
+ _adapterNamesInUse.erase(name);
+ }
+ throw;
}
- _adapters.push_back(adapter);
return adapter;
}
diff --git a/cpp/src/Ice/ObjectAdapterI.cpp b/cpp/src/Ice/ObjectAdapterI.cpp
index dd93e592c90..903ea04336e 100644
--- a/cpp/src/Ice/ObjectAdapterI.cpp
+++ b/cpp/src/Ice/ObjectAdapterI.cpp
@@ -415,7 +415,6 @@ Ice::ObjectAdapterI::destroy() ICE_NOEXCEPT
//
_instance = 0;
_threadPool = 0;
- _routerEndpoints.clear();
_routerInfo = 0;
_publishedEndpoints.clear();
_locatorInfo = 0;
@@ -677,7 +676,7 @@ Ice::ObjectAdapterI::refreshPublishedEndpoints()
checkForDeactivation();
oldPublishedEndpoints = _publishedEndpoints;
- _publishedEndpoints = parsePublishedEndpoints();
+ _publishedEndpoints = computePublishedEndpoints();
locatorInfo = _locatorInfo;
}
@@ -704,26 +703,31 @@ EndpointSeq
Ice::ObjectAdapterI::getPublishedEndpoints() const ICE_NOEXCEPT
{
IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
-
- EndpointSeq endpoints;
- copy(_publishedEndpoints.begin(), _publishedEndpoints.end(), back_inserter(endpoints));
- return endpoints;
+ return EndpointSeq(_publishedEndpoints.begin(), _publishedEndpoints.end());
}
void
Ice::ObjectAdapterI::setPublishedEndpoints(const EndpointSeq& newEndpoints)
{
- vector<EndpointIPtr> newPublishedEndpoints;
- transform(newEndpoints.begin(), newEndpoints.end(), back_inserter(newPublishedEndpoints), toEndpointI);
-
LocatorInfoPtr locatorInfo;
vector<EndpointIPtr> oldPublishedEndpoints;
{
IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
checkForDeactivation();
+ if(_routerInfo)
+ {
+ const string s("can't set published endpoints on object adapter associated with a router");
+ #ifdef ICE_CPP11_MAPPING
+ throw invalid_argument(s);
+ #else
+ throw IceUtil::IllegalArgumentException(__FILE__, __LINE__, s);
+ #endif
+ }
+
oldPublishedEndpoints = _publishedEndpoints;
- _publishedEndpoints = newPublishedEndpoints;
+ _publishedEndpoints.clear();
+ transform(newEndpoints.begin(), newEndpoints.end(), back_inserter(_publishedEndpoints), toEndpointI);
locatorInfo = _locatorInfo;
}
@@ -802,25 +806,6 @@ Ice::ObjectAdapterI::isLocal(const ObjectPrxPtr& proxy) const
}
}
}
-
- //
- // Proxies which have at least one endpoint in common with the
- // router's server proxy endpoints (if any), are also considered
- // local.
- //
- if(_routerInfo && _routerInfo->getRouter() == proxy->ice_getRouter())
- {
- for(vector<EndpointIPtr>::const_iterator p = endpoints.begin(); p != endpoints.end(); ++p)
- {
- for(vector<EndpointIPtr>::const_iterator r = _routerEndpoints.begin(); r != _routerEndpoints.end(); ++r)
- {
- if((*p)->equivalent(*r))
- {
- return true;
- }
- }
- }
- }
}
return false;
@@ -1060,42 +1045,29 @@ Ice::ObjectAdapterI::initialize(const RouterPrxPtr& router)
if(router)
{
_routerInfo = _instance->routerManager()->get(router);
- if(_routerInfo)
- {
- //
- // Make sure this router is not already registered with another adapter.
- //
- if(_routerInfo->getAdapter())
- {
- throw AlreadyRegisteredException(__FILE__, __LINE__,
- "object adapter with router",
- _communicator->identityToString(router->ice_getIdentity()));
- }
+ assert(_routerInfo);
- //
- // Add the router's server proxy endpoints to this object
- // adapter.
- //
- vector<EndpointIPtr> endpoints = _routerInfo->getServerEndpoints();
- copy(endpoints.begin(), endpoints.end(), back_inserter(_routerEndpoints));
- sort(_routerEndpoints.begin(), _routerEndpoints.end()); // Must be sorted.
- _routerEndpoints.erase(unique(_routerEndpoints.begin(), _routerEndpoints.end()),
- _routerEndpoints.end());
-
- //
- // Associate this object adapter with the router. This way,
- // new outgoing connections to the router's client proxy will
- // use this object adapter for callbacks.
- //
- _routerInfo->setAdapter(ICE_SHARED_FROM_THIS);
-
- //
- // Also modify all existing outgoing connections to the
- // router's client proxy to use this object adapter for
- // callbacks.
- //
- _instance->outgoingConnectionFactory()->setRouterInfo(_routerInfo);
+ //
+ // Make sure this router is not already registered with another adapter.
+ //
+ if(_routerInfo->getAdapter())
+ {
+ throw AlreadyRegisteredException(__FILE__, __LINE__,
+ "object adapter with router",
+ _communicator->identityToString(router->ice_getIdentity()));
}
+
+ //
+ // Associate this object adapter with the router. This way, new outgoing connections
+ // to the router's client proxy will use this object adapter for callbacks.
+ //
+ _routerInfo->setAdapter(ICE_SHARED_FROM_THIS);
+
+ //
+ // Also modify all existing outgoing connections to the router's client proxy to use
+ // this object adapter for callbacks.
+ //
+ _instance->outgoingConnectionFactory()->setRouterInfo(_routerInfo);
}
else
{
@@ -1129,13 +1101,13 @@ Ice::ObjectAdapterI::initialize(const RouterPrxPtr& router)
out << "created adapter `" << _name << "' without endpoints";
}
}
-
- //
- // Parse the published endpoints.
- //
- _publishedEndpoints = parsePublishedEndpoints();
}
+ //
+ // Compute the published endpoints.
+ //
+ _publishedEndpoints = computePublishedEndpoints();
+
if(!properties->getProperty(_name + ".Locator").empty())
{
setLocator(ICE_UNCHECKED_CAST(LocatorPrx, _instance->proxyFactory()->propertyToProxy(_name + ".Locator")));
@@ -1193,19 +1165,10 @@ Ice::ObjectAdapterI::newProxy(const Identity& ident, const string& facet) const
ObjectPrxPtr
Ice::ObjectAdapterI::newDirectProxy(const Identity& ident, const string& facet) const
{
- vector<EndpointIPtr> endpoints = _publishedEndpoints;
-
- //
- // Now we also add the endpoints of the router's server proxy, if
- // any. This way, object references created by this object adapter
- // will also point to the router's server proxy endpoints.
- //
- copy(_routerEndpoints.begin(), _routerEndpoints.end(), back_inserter(endpoints));
-
//
// Create a reference and return a proxy for this reference.
//
- ReferencePtr ref = _instance->referenceFactory()->create(ident, facet, _reference, endpoints);
+ ReferencePtr ref = _instance->referenceFactory()->create(ident, facet, _reference, _publishedEndpoints);
return _instance->proxyFactory()->referenceToProxy(ref);
}
@@ -1316,34 +1279,52 @@ Ice::ObjectAdapterI::parseEndpoints(const string& endpts, bool oaEndpoints) cons
}
std::vector<EndpointIPtr>
-ObjectAdapterI::parsePublishedEndpoints()
+ObjectAdapterI::computePublishedEndpoints()
{
- //
- // Parse published endpoints. If set, these are used in proxies
- // instead of the connection factory endpoints.
- //
- string endpts = _communicator->getProperties()->getProperty(_name + ".PublishedEndpoints");
- vector<EndpointIPtr> endpoints = parseEndpoints(endpts, false);
- if(endpoints.empty())
+ vector<EndpointIPtr> endpoints;
+ if(_routerInfo)
+ {
+ //
+ // Get the router's server proxy endpoints and use them as the published endpoints.
+ //
+ vector<EndpointIPtr> endps = _routerInfo->getServerEndpoints();
+ for(vector<EndpointIPtr>::const_iterator p = endps.begin(); p != endps.end(); ++p)
+ {
+ if(::find(endpoints.begin(), endpoints.end(), *p) == endpoints.end())
+ {
+ endpoints.push_back(*p);
+ }
+ }
+ }
+ else
{
//
- // If the PublishedEndpoints property isn't set, we compute the published enpdoints
- // from the OA endpoints, expanding any endpoints that may be listening on INADDR_ANY
- // to include actual addresses in the published endpoints.
+ // Parse published endpoints. If set, these are used in proxies
+ // instead of the connection factory endpoints.
//
- for(unsigned int i = 0; i < _incomingConnectionFactories.size(); ++i)
+ string endpts = _communicator->getProperties()->getProperty(_name + ".PublishedEndpoints");
+ endpoints = parseEndpoints(endpts, false);
+ if(endpoints.empty())
{
- vector<EndpointIPtr> endps = _incomingConnectionFactories[i]->endpoint()->expandIfWildcard();
- for(vector<EndpointIPtr>::const_iterator p = endps.begin(); p != endps.end(); ++p)
+ //
+ // If the PublishedEndpoints property isn't set, we compute the published enpdoints
+ // from the OA endpoints, expanding any endpoints that may be listening on INADDR_ANY
+ // to include actual addresses in the published endpoints.
+ //
+ for(unsigned int i = 0; i < _incomingConnectionFactories.size(); ++i)
{
- //
- // Check for duplicate endpoints, this might occur if an endpoint with a DNS name
- // expands to multiple addresses. In this case, multiple incoming connection
- // factories can point to the same published endpoint.
- //
- if(::find(endpoints.begin(), endpoints.end(), *p) == endpoints.end())
+ vector<EndpointIPtr> endps = _incomingConnectionFactories[i]->endpoint()->expandIfWildcard();
+ for(vector<EndpointIPtr>::const_iterator p = endps.begin(); p != endps.end(); ++p)
{
- endpoints.push_back(*p);
+ //
+ // Check for duplicate endpoints, this might occur if an endpoint with a DNS name
+ // expands to multiple addresses. In this case, multiple incoming connection
+ // factories can point to the same published endpoint.
+ //
+ if(::find(endpoints.begin(), endpoints.end(), *p) == endpoints.end())
+ {
+ endpoints.push_back(*p);
+ }
}
}
}
diff --git a/cpp/src/Ice/ObjectAdapterI.h b/cpp/src/Ice/ObjectAdapterI.h
index 08c2cee5658..3d4f9de3e63 100644
--- a/cpp/src/Ice/ObjectAdapterI.h
+++ b/cpp/src/Ice/ObjectAdapterI.h
@@ -120,7 +120,7 @@ private:
ObjectPrxPtr newIndirectProxy(const Identity&, const std::string&, const std::string&) const;
void checkForDeactivation() const;
std::vector<IceInternal::EndpointIPtr> parseEndpoints(const std::string&, bool) const;
- std::vector<IceInternal::EndpointIPtr> parsePublishedEndpoints();
+ std::vector<IceInternal::EndpointIPtr> computePublishedEndpoints();
void updateLocatorRegistry(const IceInternal::LocatorInfoPtr&, const Ice::ObjectPrxPtr&);
bool filterProperties(Ice::StringSeq&);
@@ -147,7 +147,6 @@ private:
const std::string _replicaGroupId;
IceInternal::ReferencePtr _reference;
std::vector<IceInternal::IncomingConnectionFactoryPtr> _incomingConnectionFactories;
- std::vector<IceInternal::EndpointIPtr> _routerEndpoints;
IceInternal::RouterInfoPtr _routerInfo;
std::vector<IceInternal::EndpointIPtr> _publishedEndpoints;
IceInternal::LocatorInfoPtr _locatorInfo;
diff --git a/cpp/src/Ice/RouterInfo.cpp b/cpp/src/Ice/RouterInfo.cpp
index 5ee23de0f13..18d56ccb201 100644
--- a/cpp/src/Ice/RouterInfo.cpp
+++ b/cpp/src/Ice/RouterInfo.cpp
@@ -120,7 +120,6 @@ IceInternal::RouterInfo::destroy()
IceUtil::Mutex::Lock sync(*this);
_clientEndpoints.clear();
- _serverEndpoints.clear();
_adapter = 0;
_identities.clear();
}
@@ -212,15 +211,13 @@ IceInternal::RouterInfo::getClientEndpoints(const GetClientEndpointsCallbackPtr&
vector<EndpointIPtr>
IceInternal::RouterInfo::getServerEndpoints()
{
+ Ice::ObjectPrxPtr serverProxy = _router->getServerProxy();
+ if(!serverProxy)
{
- IceUtil::Mutex::Lock sync(*this);
- if(!_serverEndpoints.empty())
- {
- return _serverEndpoints;
- }
+ throw NoEndpointException(__FILE__, __LINE__);
}
-
- return setServerEndpoints(_router->getServerProxy());
+ serverProxy = serverProxy->ice_router(0); // The server proxy cannot be routed.
+ return serverProxy->_getReference()->getEndpoints();
}
void
@@ -342,25 +339,6 @@ IceInternal::RouterInfo::setClientEndpoints(const Ice::ObjectPrxPtr& proxy, bool
return _clientEndpoints;
}
-vector<EndpointIPtr>
-IceInternal::RouterInfo::setServerEndpoints(const Ice::ObjectPrxPtr& /*serverProxy*/)
-{
- IceUtil::Mutex::Lock sync(*this);
- if(_serverEndpoints.empty()) // Lazy initialization.
- {
- ObjectPrxPtr serverProxy = _router->getServerProxy();
- if(!serverProxy)
- {
- throw NoEndpointException(__FILE__, __LINE__);
- }
-
- serverProxy = serverProxy->ice_router(0); // The server proxy cannot be routed.
-
- _serverEndpoints = serverProxy->_getReference()->getEndpoints();
- }
- return _serverEndpoints;
-}
-
void
IceInternal::RouterInfo::addAndEvictProxies(const Ice::ObjectPrxPtr& proxy, const Ice::ObjectProxySeq& evictedProxies)
{
diff --git a/cpp/src/Ice/RouterInfo.h b/cpp/src/Ice/RouterInfo.h
index f3e32b9a22c..ed13364642a 100644
--- a/cpp/src/Ice/RouterInfo.h
+++ b/cpp/src/Ice/RouterInfo.h
@@ -140,14 +140,12 @@ public:
// The following methods need to be public for access by AMI callbacks.
//
std::vector<EndpointIPtr> setClientEndpoints(const Ice::ObjectPrxPtr&, bool);
- std::vector<EndpointIPtr> setServerEndpoints(const Ice::ObjectPrxPtr&);
void addAndEvictProxies(const Ice::ObjectPrxPtr&, const Ice::ObjectProxySeq&);
private:
const Ice::RouterPrxPtr _router;
std::vector<EndpointIPtr> _clientEndpoints;
- std::vector<EndpointIPtr> _serverEndpoints;
bool _hasRoutingTable;
Ice::ObjectAdapterPtr _adapter;
std::set<Ice::Identity> _identities;
diff --git a/cpp/test/Ice/adapterDeactivation/AllTests.cpp b/cpp/test/Ice/adapterDeactivation/AllTests.cpp
index 6a0812f5c7b..4e4fb341477 100644
--- a/cpp/test/Ice/adapterDeactivation/AllTests.cpp
+++ b/cpp/test/Ice/adapterDeactivation/AllTests.cpp
@@ -85,6 +85,33 @@ allTests(const CommunicatorPtr& communicator)
cout << "ok" << endl;
}
+ cout << "testing object adapter published endpoints... " << flush;
+ {
+ communicator->getProperties()->setProperty("PAdapter.PublishedEndpoints", "tcp -h localhost -p 12345 -t 30000");
+ Ice::ObjectAdapterPtr adapter = communicator->createObjectAdapter("PAdapter");
+ test(adapter->getPublishedEndpoints().size() == 1);
+ Ice::EndpointPtr endpt = adapter->getPublishedEndpoints()[0];
+ test(endpt->toString() == "tcp -h localhost -p 12345 -t 30000");
+ Ice::ObjectPrxPtr prx =
+ communicator->stringToProxy("dummy:tcp -h localhost -p 12346 -t 20000:tcp -h localhost -p 12347 -t 10000");
+ adapter->setPublishedEndpoints(prx->ice_getEndpoints());
+ test(adapter->getPublishedEndpoints().size() == 2);
+ Ice::Identity id;
+ id.name = "dummy";
+ test(adapter->createProxy(id)->ice_getEndpoints() == prx->ice_getEndpoints());
+ test(adapter->getPublishedEndpoints() == prx->ice_getEndpoints());
+ adapter->refreshPublishedEndpoints();
+ test(adapter->getPublishedEndpoints().size() == 1);
+ test(adapter->getPublishedEndpoints()[0] == endpt);
+ communicator->getProperties()->setProperty("PAdapter.PublishedEndpoints", "tcp -h localhost -p 12345 -t 20000");
+ adapter->refreshPublishedEndpoints();
+ test(adapter->getPublishedEndpoints().size() == 1);
+ test(adapter->getPublishedEndpoints()[0]->toString() == "tcp -h localhost -p 12345 -t 20000");
+ adapter->destroy();
+ test(adapter->getPublishedEndpoints().empty());
+ }
+ cout << "ok" << endl;
+
if(obj->ice_getConnection())
{
cout << "testing object adapter with bi-dir connection... " << flush;
@@ -103,6 +130,57 @@ allTests(const CommunicatorPtr& communicator)
cout << "ok" << endl;
}
+ cout << "testing object adapter with router... " << flush;
+ {
+ Ice::Identity routerId;
+ routerId.name = "router";
+ Ice::RouterPrxPtr router = ICE_UNCHECKED_CAST(Ice::RouterPrx, base->ice_identity(routerId)->ice_connectionId("rc"));
+ Ice::ObjectAdapterPtr adapter = communicator->createObjectAdapterWithRouter("", router);
+ test(adapter->getPublishedEndpoints().size() == 1);
+ test(adapter->getPublishedEndpoints()[0]->toString() == "tcp -h localhost -p 23456 -t 30000");
+ adapter->refreshPublishedEndpoints();
+ test(adapter->getPublishedEndpoints().size() == 1);
+ test(adapter->getPublishedEndpoints()[0]->toString() == "tcp -h localhost -p 23457 -t 30000");
+ try
+ {
+ adapter->setPublishedEndpoints(router->ice_getEndpoints());
+ test(false);
+ }
+#if defined(ICE_CPP11_MAPPING)
+ catch(const invalid_argument&)
+#else
+ catch(const IceUtil::IllegalArgumentException&)
+#endif
+ {
+ // Expected.
+ }
+ adapter->destroy();
+
+ try
+ {
+ routerId.name = "test";
+ router = ICE_UNCHECKED_CAST(Ice::RouterPrx, base->ice_identity(routerId));
+ communicator->createObjectAdapterWithRouter("", router);
+ test(false);
+ }
+ catch(const Ice::OperationNotExistException&)
+ {
+ // Expected: the "test" object doesn't implement Ice::Router!
+ }
+
+ try
+ {
+ router = ICE_UNCHECKED_CAST(Ice::RouterPrx,
+ communicator->stringToProxy("test:" + getTestEndpoint(communicator, 1)));
+ communicator->createObjectAdapterWithRouter("", router);
+ test(false);
+ }
+ catch(const Ice::ConnectFailedException&)
+ {
+ }
+ }
+ cout << "ok" << endl;
+
cout << "deactivating object adapter in the server... " << flush;
obj->deactivate();
cout << "ok" << endl;
diff --git a/cpp/test/Ice/adapterDeactivation/ServantLocatorI.cpp b/cpp/test/Ice/adapterDeactivation/ServantLocatorI.cpp
index e2efa4f4b96..fdff00e4d14 100644
--- a/cpp/test/Ice/adapterDeactivation/ServantLocatorI.cpp
+++ b/cpp/test/Ice/adapterDeactivation/ServantLocatorI.cpp
@@ -15,8 +15,50 @@ using namespace std;
using namespace Ice;
using namespace Test;
-ServantLocatorI::ServantLocatorI() :
- _deactivated(false)
+
+namespace
+{
+
+class RouterI : public Ice::Router
+{
+public:
+
+ RouterI() : _nextPort(23456)
+ {
+ }
+
+ virtual Ice::ObjectPrxPtr
+ getClientProxy(IceUtil::Optional<bool>&, const Ice::Current&) const
+ {
+ return ICE_NULLPTR;
+ }
+
+ virtual Ice::ObjectPrxPtr
+ getServerProxy(const Ice::Current& c) const
+ {
+ ostringstream os;
+ os << "dummy:tcp -h localhost -p " << _nextPort++ << " -t 30000";
+ return c.adapter->getCommunicator()->stringToProxy(os.str());
+ }
+
+ virtual Ice::ObjectProxySeq
+#ifdef ICE_CPP11_MAPPING
+ addProxies(Ice::ObjectProxySeq, const Ice::Current&)
+#else
+ addProxies(const Ice::ObjectProxySeq&, const Ice::Current&)
+#endif
+ {
+ return Ice::ObjectProxySeq();
+ }
+
+private:
+
+ mutable int _nextPort;
+};
+
+}
+
+ServantLocatorI::ServantLocatorI() : _deactivated(false), _router(ICE_MAKE_SHARED(RouterI))
{
}
@@ -34,6 +76,11 @@ ServantLocatorI::locate(const Ice::Current& current, Ice::LocalObjectPtr& cookie
{
test(!_deactivated);
+ if(current.id.name == "router")
+ {
+ return _router;
+ }
+
test(current.id.category == "");
test(current.id.name == "test");
@@ -44,12 +91,17 @@ ServantLocatorI::locate(const Ice::Current& current, Ice::LocalObjectPtr& cookie
void
#ifdef ICE_CPP11_MAPPING
-ServantLocatorI::finished(const Ice::Current&, const Ice::ObjectPtr&, const std::shared_ptr<void>& cookie)
+ServantLocatorI::finished(const Ice::Current& current, const Ice::ObjectPtr&, const std::shared_ptr<void>& cookie)
#else
-ServantLocatorI::finished(const Ice::Current&, const Ice::ObjectPtr&, const Ice::LocalObjectPtr& cookie)
+ServantLocatorI::finished(const Ice::Current& current, const Ice::ObjectPtr&, const Ice::LocalObjectPtr& cookie)
#endif
{
test(!_deactivated);
+ if(current.id.name == "router")
+ {
+ return;
+ }
+
#ifdef ICE_CPP11_MAPPING
shared_ptr<CookieI> co = static_pointer_cast<CookieI>(cookie);
#else
diff --git a/cpp/test/Ice/adapterDeactivation/ServantLocatorI.h b/cpp/test/Ice/adapterDeactivation/ServantLocatorI.h
index ba84b778a3c..d77744f19cf 100644
--- a/cpp/test/Ice/adapterDeactivation/ServantLocatorI.h
+++ b/cpp/test/Ice/adapterDeactivation/ServantLocatorI.h
@@ -31,6 +31,7 @@ public:
public:
bool _deactivated;
+ Ice::ObjectPtr _router;
};
#endif
diff --git a/csharp/src/Ice/ConnectionFactory.cs b/csharp/src/Ice/ConnectionFactory.cs
index d70262228d6..091c0eae16a 100644
--- a/csharp/src/Ice/ConnectionFactory.cs
+++ b/csharp/src/Ice/ConnectionFactory.cs
@@ -183,6 +183,10 @@ namespace IceInternal
public void setRouterInfo(IceInternal.RouterInfo routerInfo)
{
+ Debug.Assert(routerInfo != null);
+ Ice.ObjectAdapter adapter = routerInfo.getAdapter();
+ EndpointI[] endpoints = routerInfo.getClientEndpoints(); // Must be called outside the synchronization
+
lock(this)
{
if(_destroyed)
@@ -190,17 +194,13 @@ namespace IceInternal
throw new Ice.CommunicatorDestroyedException();
}
- Debug.Assert(routerInfo != null);
-
//
// Search for connections to the router's client proxy
// endpoints, and update the object adapter for such
// connections, so that callbacks from the router can be
// received over such connections.
//
- Ice.ObjectAdapter adapter = routerInfo.getAdapter();
DefaultsAndOverrides defaultsAndOverrides = _instance.defaultsAndOverrides();
- EndpointI[] endpoints = routerInfo.getClientEndpoints();
for(int i = 0; i < endpoints.Length; i++)
{
EndpointI endpoint = endpoints[i];
diff --git a/csharp/src/Ice/ObjectAdapterFactory.cs b/csharp/src/Ice/ObjectAdapterFactory.cs
index 9992d9da8e2..394ee773f71 100644
--- a/csharp/src/Ice/ObjectAdapterFactory.cs
+++ b/csharp/src/Ice/ObjectAdapterFactory.cs
@@ -141,13 +141,7 @@ namespace IceInternal
throw new Ice.CommunicatorDestroyedException();
}
- Ice.ObjectAdapterI adapter = null;
- if(name.Length == 0)
- {
- string uuid = System.Guid.NewGuid().ToString();
- adapter = new Ice.ObjectAdapterI(_instance, _communicator, this, uuid, null, true);
- }
- else
+ if(name.Length > 0)
{
if(_adapterNamesInUse.Contains(name))
{
@@ -156,12 +150,57 @@ namespace IceInternal
ex.id = name;
throw ex;
}
- adapter = new Ice.ObjectAdapterI(_instance, _communicator, this, name, router, false);
_adapterNamesInUse.Add(name);
}
- _adapters.Add(adapter);
- return adapter;
}
+
+ //
+ // Must be called outside the synchronization since initialize can make client invocations
+ // on the router if it's set.
+ //
+ Ice.ObjectAdapterI adapter = null;
+ try
+ {
+ if(name.Length == 0)
+ {
+ string uuid = System.Guid.NewGuid().ToString();
+ adapter = new Ice.ObjectAdapterI(_instance, _communicator, this, uuid, null, true);
+ }
+ else
+ {
+ adapter = new Ice.ObjectAdapterI(_instance, _communicator, this, name, router, false);
+ }
+
+ lock(this)
+ {
+ if(_instance == null)
+ {
+ throw new Ice.CommunicatorDestroyedException();
+ }
+ _adapters.Add(adapter);
+ }
+ }
+ catch(Ice.CommunicatorDestroyedException ex)
+ {
+ if(adapter != null)
+ {
+ adapter.destroy();
+ }
+ throw ex;
+ }
+ catch(Ice.LocalException ex)
+ {
+ if(name.Length > 0)
+ {
+ lock(this)
+ {
+ _adapterNamesInUse.Remove(name);
+ }
+ }
+ throw ex;
+ }
+
+ return adapter;
}
public Ice.ObjectAdapter findObjectAdapter(Ice.ObjectPrx proxy)
diff --git a/csharp/src/Ice/ObjectAdapterI.cs b/csharp/src/Ice/ObjectAdapterI.cs
index 62000eaaeea..e18e210edbe 100644
--- a/csharp/src/Ice/ObjectAdapterI.cs
+++ b/csharp/src/Ice/ObjectAdapterI.cs
@@ -314,9 +314,8 @@ namespace Ice
//
_instance = null;
_threadPool = null;
- _routerEndpoints = null;
_routerInfo = null;
- _publishedEndpoints = null;
+ _publishedEndpoints = new EndpointI[0];
_locatorInfo = null;
_reference = null;
_objectAdapterFactory = null;
@@ -570,14 +569,14 @@ namespace Ice
public void refreshPublishedEndpoints()
{
LocatorInfo locatorInfo = null;
- List<EndpointI> oldPublishedEndpoints;
+ EndpointI[] oldPublishedEndpoints;
lock(this)
{
checkForDeactivation();
oldPublishedEndpoints = _publishedEndpoints;
- _publishedEndpoints = parsePublishedEndpoints();
+ _publishedEndpoints = computePublishedEndpoints();
locatorInfo = _locatorInfo;
}
@@ -605,29 +604,26 @@ namespace Ice
{
lock(this)
{
- return _publishedEndpoints.ToArray();
+ return (Endpoint[])_publishedEndpoints.Clone();
}
}
public void setPublishedEndpoints(Endpoint[] newEndpoints)
{
- List<EndpointI> newPublishedEndpoints = new List<EndpointI>(newEndpoints.Length);
-
- foreach(Endpoint e in newEndpoints)
- {
- newPublishedEndpoints.Add((EndpointI)e);
- }
-
LocatorInfo locatorInfo = null;
- List<EndpointI> oldPublishedEndpoints;
+ EndpointI[] oldPublishedEndpoints;
lock(this)
{
checkForDeactivation();
+ if(_routerInfo != null)
+ {
+ throw new ArgumentException(
+ "can't set published endpoints on object adapter associated with a router");
+ }
oldPublishedEndpoints = _publishedEndpoints;
- _publishedEndpoints = newPublishedEndpoints;
-
+ _publishedEndpoints = Array.ConvertAll(newEndpoints, endpt => (EndpointI)endpt);
locatorInfo = _locatorInfo;
}
@@ -704,26 +700,6 @@ namespace Ice
}
}
}
-
- //
- // Proxies which have at least one endpoint in common with the
- // router's server proxy endpoints (if any), are also considered
- // local.
- //
- if(_routerInfo != null && _routerInfo.getRouter().Equals(proxy.ice_getRouter()))
- {
- for(int i = 0; i < endpoints.Length; ++i)
- {
- foreach(EndpointI endpoint in _routerEndpoints)
- {
- if(endpoints[i].equivalent(endpoint))
- {
- return true;
- }
- }
- }
- }
-
return false;
}
}
@@ -863,8 +839,7 @@ namespace Ice
_servantManager = new ServantManager(instance, name);
_name = name;
_incomingConnectionFactories = new List<IncomingConnectionFactory>();
- _publishedEndpoints = new List<EndpointI>();
- _routerEndpoints = new List<EndpointI>();
+ _publishedEndpoints = new EndpointI[0];
_routerInfo = null;
_directCount = 0;
_noConfig = noConfig;
@@ -960,67 +935,37 @@ namespace Ice
if(router == null)
{
- router = RouterPrxHelper.uncheckedCast(
- _instance.proxyFactory().propertyToProxy(_name + ".Router"));
+ router = RouterPrxHelper.uncheckedCast(_instance.proxyFactory().propertyToProxy(_name + ".Router"));
}
if(router != null)
{
_routerInfo = _instance.routerManager().get(router);
- if(_routerInfo != null)
- {
- //
- // Make sure this router is not already registered with another adapter.
- //
- if(_routerInfo.getAdapter() != null)
- {
- AlreadyRegisteredException ex = new AlreadyRegisteredException();
- ex.kindOfObject = "object adapter with router";
- ex.id = Util.identityToString(router.ice_getIdentity(), _instance.toStringMode());
- throw ex;
- }
+ Debug.Assert(_routerInfo != null);
- //
- // Add the router's server proxy endpoints to this object
- // adapter.
- //
- EndpointI[] endpoints = _routerInfo.getServerEndpoints();
- for(int i = 0; i < endpoints.Length; ++i)
- {
- _routerEndpoints.Add(endpoints[i]);
- }
- _routerEndpoints.Sort(); // Must be sorted.
+ //
+ // Make sure this router is not already registered with another adapter.
+ //
+ if(_routerInfo.getAdapter() != null)
+ {
+ AlreadyRegisteredException ex = new AlreadyRegisteredException();
+ ex.kindOfObject = "object adapter with router";
+ ex.id = Util.identityToString(router.ice_getIdentity(), _instance.toStringMode());
+ throw ex;
+ }
- //
- // Remove duplicate endpoints, so we have a list of unique endpoints.
- //
- for(int i = 0; i < _routerEndpoints.Count-1;)
- {
- EndpointI e1 = _routerEndpoints[i];
- EndpointI e2 = _routerEndpoints[i + 1];
- if(e1.Equals(e2))
- {
- _routerEndpoints.RemoveAt(i);
- }
- else
- {
- ++i;
- }
- }
+ //
+ // Associate this object adapter with the router. This way,
+ // new outgoing connections to the router's client proxy will
+ // use this object adapter for callbacks.
+ //
+ _routerInfo.setAdapter(this);
- //
- // Associate this object adapter with the router. This way,
- // new outgoing connections to the router's client proxy will
- // use this object adapter for callbacks.
- //
- _routerInfo.setAdapter(this);
-
- //
- // Also modify all existing outgoing connections to the
- // router's client proxy to use this object adapter for
- // callbacks.
- //
- _instance.outgoingConnectionFactory().setRouterInfo(_routerInfo);
- }
+ //
+ // Also modify all existing outgoing connections to the
+ // router's client proxy to use this object adapter for
+ // callbacks.
+ //
+ _instance.outgoingConnectionFactory().setRouterInfo(_routerInfo);
}
else
{
@@ -1050,13 +995,13 @@ namespace Ice
"' without endpoints");
}
}
-
- //
- // Parse published endpoints.
- //
- _publishedEndpoints = parsePublishedEndpoints();
}
+ //
+ // Parse published endpoints.
+ //
+ _publishedEndpoints = computePublishedEndpoints();
+
if(properties.getProperty(_name + ".Locator").Length > 0)
{
setLocator(LocatorPrxHelper.uncheckedCast(
@@ -1092,33 +1037,10 @@ namespace Ice
private ObjectPrx newDirectProxy(Identity ident, string facet)
{
- EndpointI[] endpoints;
-
- //
- // Use the published endpoints, otherwise use the endpoints from all
- // incoming connection factories.
- //
- int sz = _publishedEndpoints.Count;
- endpoints = new EndpointI[sz + _routerEndpoints.Count];
- for(int i = 0; i < sz; ++i)
- {
- endpoints[i] = _publishedEndpoints[i];
- }
-
- //
- // Now we also add the endpoints of the router's server proxy, if
- // any. This way, object references created by this object adapter
- // will also point to the router's server proxy endpoints.
- //
- for(int i = 0; i < _routerEndpoints.Count; ++i)
- {
- endpoints[sz + i] = _routerEndpoints[i];
- }
-
//
// Create a reference and return a proxy for this reference.
//
- Reference reference = _instance.referenceFactory().create(ident, facet, _reference, endpoints);
+ Reference reference = _instance.referenceFactory().create(ident, facet, _reference, _publishedEndpoints);
return _instance.proxyFactory().referenceToProxy(reference);
}
@@ -1244,33 +1166,51 @@ namespace Ice
return endpoints;
}
- private List<EndpointI> parsePublishedEndpoints()
+ private EndpointI[] computePublishedEndpoints()
{
- //
- // Parse published endpoints. If set, these are used in proxies
- // instead of the connection factory endpoints.
- //
- string endpts = _instance.initializationData().properties.getProperty(_name + ".PublishedEndpoints");
- List<EndpointI> endpoints = parseEndpoints(endpts, false);
- if(endpoints.Count == 0)
+ List<EndpointI> endpoints;
+ if(_routerInfo != null)
{
//
- // If the PublishedEndpoints property isn't set, we compute the published enpdoints
- // from the OA endpoints, expanding any endpoints that may be listening on INADDR_ANY
- // to include actual addresses in the published endpoints.
+ // Get the router's server proxy endpoints and use them as the published endpoints.
//
- foreach(IncomingConnectionFactory factory in _incomingConnectionFactories)
+ endpoints = new List<EndpointI>();
+ foreach(EndpointI endpt in _routerInfo.getServerEndpoints())
{
- foreach(EndpointI endpt in factory.endpoint().expandIfWildcard())
+ if(!endpoints.Contains(endpt))
{
- //
- // Check for duplicate endpoints, this might occur if an endpoint with a DNS name
- // expands to multiple addresses. In this case, multiple incoming connection
- // factories can point to the same published endpoint.
- //
- if(!endpoints.Contains(endpt))
+ endpoints.Add(endpt);
+ }
+ }
+ }
+ else
+ {
+ //
+ // Parse published endpoints. If set, these are used in proxies
+ // instead of the connection factory endpoints.
+ //
+ string endpts = _instance.initializationData().properties.getProperty(_name + ".PublishedEndpoints");
+ endpoints = parseEndpoints(endpts, false);
+ if(endpoints.Count == 0)
+ {
+ //
+ // If the PublishedEndpoints property isn't set, we compute the published enpdoints
+ // from the OA endpoints, expanding any endpoints that may be listening on INADDR_ANY
+ // to include actual addresses in the published endpoints.
+ //
+ foreach(IncomingConnectionFactory factory in _incomingConnectionFactories)
+ {
+ foreach(EndpointI endpt in factory.endpoint().expandIfWildcard())
{
- endpoints.Add(endpt);
+ //
+ // Check for duplicate endpoints, this might occur if an endpoint with a DNS name
+ // expands to multiple addresses. In this case, multiple incoming connection
+ // factories can point to the same published endpoint.
+ //
+ if(!endpoints.Contains(endpt))
+ {
+ endpoints.Add(endpt);
+ }
}
}
}
@@ -1293,7 +1233,8 @@ namespace Ice
}
_instance.initializationData().logger.trace(_instance.traceLevels().networkCat, s.ToString());
}
- return endpoints;
+
+ return endpoints.ToArray();
}
private void updateLocatorRegistry(LocatorInfo locatorInfo, ObjectPrx proxy)
@@ -1512,9 +1453,8 @@ namespace Ice
private readonly string _replicaGroupId;
private Reference _reference;
private List<IncomingConnectionFactory> _incomingConnectionFactories;
- private List<EndpointI> _routerEndpoints;
private RouterInfo _routerInfo;
- private List<EndpointI> _publishedEndpoints;
+ private EndpointI[] _publishedEndpoints;
private LocatorInfo _locatorInfo;
private int _directCount; // The number of direct proxies dispatching on this object adapter.
private bool _noConfig;
diff --git a/csharp/src/Ice/RouterInfo.cs b/csharp/src/Ice/RouterInfo.cs
index e134c5834e2..4bc5c4e2a19 100644
--- a/csharp/src/Ice/RouterInfo.cs
+++ b/csharp/src/Ice/RouterInfo.cs
@@ -38,7 +38,6 @@ namespace IceInternal
lock(this)
{
_clientEndpoints = new EndpointI[0];
- _serverEndpoints = new EndpointI[0];
_adapter = null;
_identities.Clear();
}
@@ -116,16 +115,14 @@ namespace IceInternal
public EndpointI[] getServerEndpoints()
{
- lock(this)
+ Ice.ObjectPrx serverProxy = _router.getServerProxy();
+ if(serverProxy == null)
{
- if(_serverEndpoints != null) // Lazy initialization.
- {
- return _serverEndpoints;
- }
-
+ throw new Ice.NoEndpointException();
}
- return setServerEndpoints(_router.getServerProxy());
+ serverProxy = serverProxy.ice_router(null); // The server proxy cannot be routed.
+ return ((Ice.ObjectPrxHelperBase)serverProxy).iceReference().getEndpoints();
}
public void addProxy(Ice.ObjectPrx proxy)
@@ -239,21 +236,6 @@ namespace IceInternal
}
}
- private EndpointI[] setServerEndpoints(Ice.ObjectPrx serverProxy)
- {
- lock(this)
- {
- if(serverProxy == null)
- {
- throw new Ice.NoEndpointException();
- }
-
- serverProxy = serverProxy.ice_router(null); // The server proxy cannot be routed.
- _serverEndpoints = ((Ice.ObjectPrxHelperBase)serverProxy).iceReference().getEndpoints();
- return _serverEndpoints;
- }
- }
-
private void addAndEvictProxies(Ice.ObjectPrx proxy, Ice.ObjectPrx[] evictedProxies)
{
lock(this)
@@ -297,7 +279,6 @@ namespace IceInternal
private readonly Ice.RouterPrx _router;
private EndpointI[] _clientEndpoints;
- private EndpointI[] _serverEndpoints;
private Ice.ObjectAdapter _adapter;
private HashSet<Ice.Identity> _identities = new HashSet<Ice.Identity>();
private List<Ice.Identity> _evictedIdentities = new List<Ice.Identity>();
diff --git a/csharp/test/Ice/adapterDeactivation/AllTests.cs b/csharp/test/Ice/adapterDeactivation/AllTests.cs
index faddd07a441..c8677989db9 100644
--- a/csharp/test/Ice/adapterDeactivation/AllTests.cs
+++ b/csharp/test/Ice/adapterDeactivation/AllTests.cs
@@ -72,6 +72,34 @@ public class AllTests : TestCommon.AllTests
WriteLine("ok");
}
+ Write("testing object adapter published endpoints... ");
+ Flush();
+ {
+ communicator.getProperties().setProperty("PAdapter.PublishedEndpoints", "tcp -h localhost -p 12345 -t 30000");
+ Ice.ObjectAdapter adapter = communicator.createObjectAdapter("PAdapter");
+ test(adapter.getPublishedEndpoints().Length == 1);
+ Ice.Endpoint endpt = adapter.getPublishedEndpoints()[0];
+ test(endpt.ToString().Equals("tcp -h localhost -p 12345 -t 30000"));
+ Ice.ObjectPrx prx =
+ communicator.stringToProxy("dummy:tcp -h localhost -p 12346 -t 20000:tcp -h localhost -p 12347 -t 10000");
+ adapter.setPublishedEndpoints(prx.ice_getEndpoints());
+ test(adapter.getPublishedEndpoints().Length == 2);
+ Ice.Identity id = new Ice.Identity();
+ id.name = "dummy";
+ test(IceUtilInternal.Arrays.Equals(adapter.createProxy(id).ice_getEndpoints(), prx.ice_getEndpoints()));
+ test(IceUtilInternal.Arrays.Equals(adapter.getPublishedEndpoints(), prx.ice_getEndpoints()));
+ adapter.refreshPublishedEndpoints();
+ test(adapter.getPublishedEndpoints().Length == 1);
+ test(adapter.getPublishedEndpoints()[0].Equals(endpt));
+ communicator.getProperties().setProperty("PAdapter.PublishedEndpoints", "tcp -h localhost -p 12345 -t 20000");
+ adapter.refreshPublishedEndpoints();
+ test(adapter.getPublishedEndpoints().Length == 1);
+ test(adapter.getPublishedEndpoints()[0].ToString().Equals("tcp -h localhost -p 12345 -t 20000"));
+ adapter.destroy();
+ test(adapter.getPublishedEndpoints().Length == 0);
+ }
+ WriteLine("ok");
+
if(obj.ice_getConnection() != null)
{
Write("testing object adapter with bi-dir connection... ");
@@ -91,6 +119,53 @@ public class AllTests : TestCommon.AllTests
WriteLine("ok");
}
+ Write("testing object adapter with router... ");
+ Flush();
+ {
+ Ice.Identity routerId = new Ice.Identity();
+ routerId.name = "router";
+ Ice.RouterPrx router = Ice.RouterPrxHelper.uncheckedCast(@base.ice_identity(routerId).ice_connectionId("rc"));
+ Ice.ObjectAdapter adapter = communicator.createObjectAdapterWithRouter("", router);
+ test(adapter.getPublishedEndpoints().Length == 1);
+ test(adapter.getPublishedEndpoints()[0].ToString().Equals("tcp -h localhost -p 23456 -t 30000"));
+ adapter.refreshPublishedEndpoints();
+ test(adapter.getPublishedEndpoints().Length == 1);
+ test(adapter.getPublishedEndpoints()[0].ToString().Equals("tcp -h localhost -p 23457 -t 30000"));
+ try
+ {
+ adapter.setPublishedEndpoints(router.ice_getEndpoints());
+ test(false);
+ }
+ catch(ArgumentException)
+ {
+ // Expected.
+ }
+ adapter.destroy();
+
+ try
+ {
+ routerId.name = "test";
+ router = Ice.RouterPrxHelper.uncheckedCast(@base.ice_identity(routerId));
+ communicator.createObjectAdapterWithRouter("", router);
+ test(false);
+ }
+ catch(Ice.OperationNotExistException)
+ {
+ // Expected: the "test" object doesn't implement Ice::Router!
+ }
+
+ try
+ {
+ router = Ice.RouterPrxHelper.uncheckedCast(communicator.stringToProxy("test:" + app.getTestEndpoint(1)));
+ communicator.createObjectAdapterWithRouter("", router);
+ test(false);
+ }
+ catch(Ice.ConnectFailedException)
+ {
+ }
+ }
+ WriteLine("ok");
+
Write("deactivating object adapter in the server... ");
Flush();
obj.deactivate();
diff --git a/csharp/test/Ice/adapterDeactivation/ServantLocatorI.cs b/csharp/test/Ice/adapterDeactivation/ServantLocatorI.cs
index 54cd1d43aab..fb7ebb2820d 100644
--- a/csharp/test/Ice/adapterDeactivation/ServantLocatorI.cs
+++ b/csharp/test/Ice/adapterDeactivation/ServantLocatorI.cs
@@ -8,6 +8,31 @@
// **********************************************************************
using Test;
+using System.Text;
+
+public class RouterI : Ice.RouterDisp_
+{
+ public override Ice.ObjectPrx getClientProxy(out Ice.Optional<bool> hasRoutingTable, Ice.Current current)
+ {
+ hasRoutingTable = false;
+ return null;
+ }
+
+ public override Ice.ObjectPrx getServerProxy(Ice.Current current)
+ {
+ StringBuilder s = new StringBuilder("dummy:tcp -h localhost -p ");
+ s.Append(_nextPort++);
+ s.Append(" -t 30000");
+ return current.adapter.getCommunicator().stringToProxy(s.ToString());
+ }
+
+ public override Ice.ObjectPrx[] addProxies(Ice.ObjectPrx[] proxies, Ice.Current current)
+ {
+ return null;
+ }
+
+ private int _nextPort = 23456;
+}
public sealed class ServantLocatorI : Ice.ServantLocator
{
@@ -39,6 +64,12 @@ public sealed class ServantLocatorI : Ice.ServantLocator
test(!_deactivated);
}
+ if(current.id.name.Equals("router"))
+ {
+ cookie = null;
+ return _router;
+ }
+
test(current.id.category.Length == 0);
test(current.id.name.Equals("test"));
@@ -54,6 +85,11 @@ public sealed class ServantLocatorI : Ice.ServantLocator
test(!_deactivated);
}
+ if(current.id.name.Equals("router"))
+ {
+ return;
+ }
+
Cookie co = (Cookie) cookie;
test(co.message().Equals("blahblah"));
}
@@ -69,4 +105,5 @@ public sealed class ServantLocatorI : Ice.ServantLocator
}
private bool _deactivated;
+ static private RouterI _router = new RouterI();
}
diff --git a/java-compat/gradle/wrapper/gradle-wrapper.properties b/java-compat/gradle/wrapper/gradle-wrapper.properties
index 731147b9379..74bb77845e0 100644
--- a/java-compat/gradle/wrapper/gradle-wrapper.properties
+++ b/java-compat/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.2.1-bin.zip
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.2.1-bin.zip
diff --git a/java-compat/src/Ice/src/main/java/Ice/ObjectAdapterI.java b/java-compat/src/Ice/src/main/java/Ice/ObjectAdapterI.java
index 70ef1b56b6c..9a91d61d402 100644
--- a/java-compat/src/Ice/src/main/java/Ice/ObjectAdapterI.java
+++ b/java-compat/src/Ice/src/main/java/Ice/ObjectAdapterI.java
@@ -12,6 +12,7 @@ package Ice;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
+import java.util.Arrays;
import IceInternal.IncomingConnectionFactory;
@@ -377,9 +378,8 @@ public final class ObjectAdapterI implements ObjectAdapter
//
_instance = null;
_threadPool = null;
- _routerEndpoints = null;
_routerInfo = null;
- _publishedEndpoints = null;
+ _publishedEndpoints = new IceInternal.EndpointI[0];
_locatorInfo = null;
_reference = null;
_objectAdapterFactory = null;
@@ -614,7 +614,7 @@ public final class ObjectAdapterI implements ObjectAdapter
public synchronized Endpoint[]
getEndpoints()
{
- List<Endpoint> endpoints = new ArrayList<Endpoint>();
+ List<Endpoint> endpoints = new ArrayList<>();
for(IncomingConnectionFactory factory : _incomingConnectionFactories)
{
endpoints.add(factory.endpoint());
@@ -627,14 +627,14 @@ public final class ObjectAdapterI implements ObjectAdapter
refreshPublishedEndpoints()
{
IceInternal.LocatorInfo locatorInfo = null;
- List<IceInternal.EndpointI> oldPublishedEndpoints;
+ IceInternal.EndpointI[] oldPublishedEndpoints;
synchronized(this)
{
checkForDeactivation();
oldPublishedEndpoints = _publishedEndpoints;
- _publishedEndpoints = parsePublishedEndpoints();
+ _publishedEndpoints = computePublishedEndpoints();
locatorInfo = _locatorInfo;
}
@@ -662,27 +662,27 @@ public final class ObjectAdapterI implements ObjectAdapter
public synchronized Endpoint[]
getPublishedEndpoints()
{
- return _publishedEndpoints.toArray(new Endpoint[0]);
+ return Arrays.copyOf(_publishedEndpoints, _publishedEndpoints.length, Endpoint[].class);
}
@Override
public void
setPublishedEndpoints(Endpoint[] newEndpoints)
{
- List<IceInternal.EndpointI> newPublishedEndpoints = new ArrayList<>(newEndpoints.length);
- for(Endpoint e: newEndpoints)
- {
- newPublishedEndpoints.add((IceInternal.EndpointI)e);
- }
-
IceInternal.LocatorInfo locatorInfo = null;
- List<IceInternal.EndpointI> oldPublishedEndpoints;
+ IceInternal.EndpointI[] oldPublishedEndpoints;
synchronized(this)
{
checkForDeactivation();
+ if(_routerInfo != null)
+ {
+ throw new IllegalArgumentException(
+ "can't set published endpoints on object adapter associated with a router");
+ }
+
oldPublishedEndpoints = _publishedEndpoints;
- _publishedEndpoints = newPublishedEndpoints;
+ _publishedEndpoints = Arrays.copyOf(newEndpoints, newEndpoints.length, IceInternal.EndpointI[].class);
locatorInfo = _locatorInfo;
}
@@ -760,25 +760,6 @@ public final class ObjectAdapterI implements ObjectAdapter
}
}
}
-
- //
- // Proxies which have at least one endpoint in common with the
- // router's server proxy endpoints (if any), are also considered
- // local.
- //
- if(_routerInfo != null && _routerInfo.getRouter().equals(proxy.ice_getRouter()))
- {
- for(IceInternal.EndpointI endpoint : endpoints)
- {
- for(IceInternal.EndpointI p : _routerEndpoints)
- {
- if(endpoint.equivalent(p))
- {
- return true;
- }
- }
- }
- }
}
}
@@ -1019,61 +1000,31 @@ public final class ObjectAdapterI implements ObjectAdapter
if(router != null)
{
_routerInfo = _instance.routerManager().get(router);
- if(_routerInfo != null)
- {
- //
- // Make sure this router is not already registered with another adapter.
- //
- if(_routerInfo.getAdapter() != null)
- {
- throw new AlreadyRegisteredException("object adapter with router",
- Ice.Util.identityToString(router.ice_getIdentity(),
- _instance.toStringMode()));
- }
+ assert(_routerInfo != null);
- //
- // Add the router's server proxy endpoints to this object
- // adapter.
- //
- IceInternal.EndpointI[] endpoints = _routerInfo.getServerEndpoints();
- for(IceInternal.EndpointI endpoint : endpoints)
- {
- _routerEndpoints.add(endpoint);
- }
- java.util.Collections.sort(_routerEndpoints); // Must be sorted.
+ //
+ // Make sure this router is not already registered with another adapter.
+ //
+ if(_routerInfo.getAdapter() != null)
+ {
+ throw new AlreadyRegisteredException("object adapter with router",
+ Ice.Util.identityToString(router.ice_getIdentity(),
+ _instance.toStringMode()));
+ }
- //
- // Remove duplicate endpoints, so we have a list of unique
- // endpoints.
- //
- for(int i = 0; i < _routerEndpoints.size() - 1;)
- {
- IceInternal.EndpointI e1 = _routerEndpoints.get(i);
- IceInternal.EndpointI e2 = _routerEndpoints.get(i + 1);
- if(e1.equals(e2))
- {
- _routerEndpoints.remove(i);
- }
- else
- {
- ++i;
- }
- }
+ //
+ // Associate this object adapter with the router. This way,
+ // new outgoing connections to the router's client proxy will
+ // use this object adapter for callbacks.
+ //
+ _routerInfo.setAdapter(this);
- //
- // Associate this object adapter with the router. This way,
- // new outgoing connections to the router's client proxy will
- // use this object adapter for callbacks.
- //
- _routerInfo.setAdapter(this);
-
- //
- // Also modify all existing outgoing connections to the
- // router's client proxy to use this object adapter for
- // callbacks.
- //
- _instance.outgoingConnectionFactory().setRouterInfo(_routerInfo);
- }
+ //
+ // Also modify all existing outgoing connections to the
+ // router's client proxy to use this object adapter for
+ // callbacks.
+ //
+ _instance.outgoingConnectionFactory().setRouterInfo(_routerInfo);
}
else
{
@@ -1104,13 +1055,13 @@ public final class ObjectAdapterI implements ObjectAdapter
"created adapter `" + name + "' without endpoints");
}
}
-
- //
- // Parse the publsihed endpoints.
- //
- _publishedEndpoints = parsePublishedEndpoints();
}
+ //
+ // Compute the publsihed endpoints.
+ //
+ _publishedEndpoints = computePublishedEndpoints();
+
if(properties.getProperty(_name + ".Locator").length() > 0)
{
setLocator(LocatorPrxHelper.uncheckedCast(
@@ -1184,26 +1135,10 @@ public final class ObjectAdapterI implements ObjectAdapter
private ObjectPrx
newDirectProxy(Identity ident, String facet)
{
- IceInternal.EndpointI[] endpoints;
-
- int sz = _publishedEndpoints.size();
- endpoints = new IceInternal.EndpointI[sz + _routerEndpoints.size()];
- _publishedEndpoints.toArray(endpoints);
-
- //
- // Now we also add the endpoints of the router's server proxy, if
- // any. This way, object references created by this object adapter
- // will also point to the router's server proxy endpoints.
- //
- for(int i = 0; i < _routerEndpoints.size(); ++i)
- {
- endpoints[sz + i] = _routerEndpoints.get(i);
- }
-
//
// Create a reference and return a proxy for this reference.
//
- IceInternal.Reference ref = _instance.referenceFactory().create(ident, facet, _reference, endpoints);
+ IceInternal.Reference ref = _instance.referenceFactory().create(ident, facet, _reference, _publishedEndpoints);
return _instance.proxyFactory().referenceToProxy(ref);
}
@@ -1335,34 +1270,52 @@ public final class ObjectAdapterI implements ObjectAdapter
return endpoints;
}
- private List<IceInternal.EndpointI>
- parsePublishedEndpoints()
+ private IceInternal.EndpointI[]
+ computePublishedEndpoints()
{
- //
- // Parse published endpoints. If set, these are used in proxies
- // instead of the connection factory Endpoints.
- //
- String endpts = _instance.initializationData().properties.getProperty(_name + ".PublishedEndpoints");
- List<IceInternal.EndpointI> endpoints = parseEndpoints(endpts, false);
- if(endpoints.isEmpty())
+ List<IceInternal.EndpointI> endpoints;
+ if(_routerInfo != null)
{
//
- // If the PublishedEndpoints property isn't set, we compute the published enpdoints
- // from the OA endpoints, expanding any endpoints that may be listening on INADDR_ANY
- // to include actual addresses in the published endpoints.
+ // Get the router's server proxy endpoints and use them as the published endpoints.
//
- for(IncomingConnectionFactory factory : _incomingConnectionFactories)
+ endpoints = new ArrayList<>();
+ for(IceInternal.EndpointI endpt : _routerInfo.getServerEndpoints())
+ {
+ if(!endpoints.contains(endpt))
+ {
+ endpoints.add(endpt);
+ }
+ }
+ }
+ else
+ {
+ //
+ // Parse published endpoints. If set, these are used in proxies
+ // instead of the connection factory Endpoints.
+ //
+ String endpts = _instance.initializationData().properties.getProperty(_name + ".PublishedEndpoints");
+ endpoints = parseEndpoints(endpts, false);
+ if(endpoints.isEmpty())
{
- for(IceInternal.EndpointI endpt : factory.endpoint().expandIfWildcard())
+ //
+ // If the PublishedEndpoints property isn't set, we compute the published enpdoints
+ // from the OA endpoints, expanding any endpoints that may be listening on INADDR_ANY
+ // to include actual addresses in the published endpoints.
+ //
+ for(IncomingConnectionFactory factory : _incomingConnectionFactories)
{
- //
- // Check for duplicate endpoints, this might occur if an endpoint with a DNS name
- // expands to multiple addresses. In this case, multiple incoming connection
- // factories can point to the same published endpoint.
- //
- if(!endpoints.contains(endpt))
+ for(IceInternal.EndpointI endpt : factory.endpoint().expandIfWildcard())
{
- endpoints.add(endpt);
+ //
+ // Check for duplicate endpoints, this might occur if an endpoint with a DNS name
+ // expands to multiple addresses. In this case, multiple incoming connection
+ // factories can point to the same published endpoint.
+ //
+ if(!endpoints.contains(endpt))
+ {
+ endpoints.add(endpt);
+ }
}
}
}
@@ -1385,7 +1338,7 @@ public final class ObjectAdapterI implements ObjectAdapter
}
_instance.initializationData().logger.trace(_instance.traceLevels().networkCat, s.toString());
}
- return endpoints;
+ return endpoints.toArray(new IceInternal.EndpointI[endpoints.size()]);
}
private void
@@ -1617,9 +1570,8 @@ public final class ObjectAdapterI implements ObjectAdapter
final private String _replicaGroupId;
private IceInternal.Reference _reference;
private List<IncomingConnectionFactory> _incomingConnectionFactories = new ArrayList<IncomingConnectionFactory>();
- private List<IceInternal.EndpointI> _routerEndpoints = new ArrayList<IceInternal.EndpointI>();
private IceInternal.RouterInfo _routerInfo = null;
- private List<IceInternal.EndpointI> _publishedEndpoints = new ArrayList<IceInternal.EndpointI>();
+ private IceInternal.EndpointI[] _publishedEndpoints = new IceInternal.EndpointI[0];
private IceInternal.LocatorInfo _locatorInfo;
private int _directCount; // The number of direct proxies dispatching on this object adapter.
private boolean _noConfig;
diff --git a/java-compat/src/Ice/src/main/java/IceInternal/ObjectAdapterFactory.java b/java-compat/src/Ice/src/main/java/IceInternal/ObjectAdapterFactory.java
index ba2fe8e6604..2a34fbd3da3 100644
--- a/java-compat/src/Ice/src/main/java/IceInternal/ObjectAdapterFactory.java
+++ b/java-compat/src/Ice/src/main/java/IceInternal/ObjectAdapterFactory.java
@@ -140,7 +140,7 @@ public final class ObjectAdapterFactory
}
}
- public synchronized Ice.ObjectAdapter
+ public Ice.ObjectAdapter
createObjectAdapter(String name, Ice.RouterPrx router)
{
if(Thread.interrupted())
@@ -148,27 +148,69 @@ public final class ObjectAdapterFactory
throw new Ice.OperationInterruptedException();
}
- if(_instance == null)
+ synchronized(this)
{
- throw new Ice.CommunicatorDestroyedException();
+ if(_instance == null)
+ {
+ throw new Ice.CommunicatorDestroyedException();
+ }
+
+ if(!name.isEmpty())
+ {
+ if(_adapterNamesInUse.contains(name))
+ {
+ throw new Ice.AlreadyRegisteredException("object adapter", name);
+ }
+ _adapterNamesInUse.add(name);
+ }
}
+ //
+ // Must be called outside the synchronization since initialize can make client invocations
+ // on the router if it's set.
+ //
Ice.ObjectAdapterI adapter = null;
- if(name.length() == 0)
+ try
+ {
+ if(name.isEmpty())
+ {
+ String uuid = java.util.UUID.randomUUID().toString();
+ adapter = new Ice.ObjectAdapterI(_instance, _communicator, this, uuid, null, true);
+ }
+ else
+ {
+ adapter = new Ice.ObjectAdapterI(_instance, _communicator, this, name, router, false);
+ }
+
+ synchronized(this)
+ {
+ if(_instance == null)
+ {
+ throw new Ice.CommunicatorDestroyedException();
+ }
+ _adapters.add(adapter);
+ }
+ }
+ catch(Ice.CommunicatorDestroyedException ex)
{
- String uuid = java.util.UUID.randomUUID().toString();
- adapter = new Ice.ObjectAdapterI(_instance, _communicator, this, uuid, null, true);
+ if(adapter != null)
+ {
+ adapter.destroy();
+ }
+ throw ex;
}
- else
+ catch(Ice.LocalException ex)
{
- if(_adapterNamesInUse.contains(name))
+ if(!name.isEmpty())
{
- throw new Ice.AlreadyRegisteredException("object adapter", name);
+ synchronized(this)
+ {
+ _adapterNamesInUse.remove(name);
+ }
}
- adapter = new Ice.ObjectAdapterI(_instance, _communicator, this, name, router, false);
- _adapterNamesInUse.add(name);
+ throw ex;
}
- _adapters.add(adapter);
+
return adapter;
}
diff --git a/java-compat/src/Ice/src/main/java/IceInternal/OutgoingConnectionFactory.java b/java-compat/src/Ice/src/main/java/IceInternal/OutgoingConnectionFactory.java
index 5acbbfd4b23..2036900f139 100644
--- a/java-compat/src/Ice/src/main/java/IceInternal/OutgoingConnectionFactory.java
+++ b/java-compat/src/Ice/src/main/java/IceInternal/OutgoingConnectionFactory.java
@@ -225,52 +225,55 @@ public final class OutgoingConnectionFactory
}
}
- public synchronized void
+ public void
setRouterInfo(IceInternal.RouterInfo routerInfo)
{
- if(_destroyed)
- {
- throw new Ice.CommunicatorDestroyedException();
- }
-
assert(routerInfo != null);
-
- //
- // Search for connections to the router's client proxy
- // endpoints, and update the object adapter for such
- // connections, so that callbacks from the router can be
- // received over such connections.
- //
Ice.ObjectAdapter adapter = routerInfo.getAdapter();
- DefaultsAndOverrides defaultsAndOverrides = _instance.defaultsAndOverrides();
- for(EndpointI endpoint : routerInfo.getClientEndpoints())
+ EndpointI[] endpoints = routerInfo.getClientEndpoints(); // Must be called outside the synchronization
+ synchronized(this)
{
- //
- // Modify endpoints with overrides.
- //
- if(defaultsAndOverrides.overrideTimeout)
+ if(_destroyed)
{
- endpoint = endpoint.timeout(defaultsAndOverrides.overrideTimeoutValue);
+ throw new Ice.CommunicatorDestroyedException();
}
//
- // The Connection object does not take the compression flag of
- // endpoints into account, but instead gets the information
- // about whether messages should be compressed or not from
- // other sources. In order to allow connection sharing for
- // endpoints that differ in the value of the compression flag
- // only, we always set the compression flag to false here in
- // this connection factory.
+ // Search for connections to the router's client proxy
+ // endpoints, and update the object adapter for such
+ // connections, so that callbacks from the router can be
+ // received over such connections.
//
- endpoint = endpoint.compress(false);
-
- for(java.util.List<Ice.ConnectionI> connectionList : _connections.values())
+ DefaultsAndOverrides defaultsAndOverrides = _instance.defaultsAndOverrides();
+ for(EndpointI endpoint : endpoints)
{
- for(Ice.ConnectionI connection : connectionList)
+ //
+ // Modify endpoints with overrides.
+ //
+ if(defaultsAndOverrides.overrideTimeout)
{
- if(connection.endpoint() == endpoint)
+ endpoint = endpoint.timeout(defaultsAndOverrides.overrideTimeoutValue);
+ }
+
+ //
+ // The Connection object does not take the compression flag of
+ // endpoints into account, but instead gets the information
+ // about whether messages should be compressed or not from
+ // other sources. In order to allow connection sharing for
+ // endpoints that differ in the value of the compression flag
+ // only, we always set the compression flag to false here in
+ // this connection factory.
+ //
+ endpoint = endpoint.compress(false);
+
+ for(java.util.List<Ice.ConnectionI> connectionList : _connections.values())
+ {
+ for(Ice.ConnectionI connection : connectionList)
{
- connection.setAdapter(adapter);
+ if(connection.endpoint() == endpoint)
+ {
+ connection.setAdapter(adapter);
+ }
}
}
}
diff --git a/java-compat/src/Ice/src/main/java/IceInternal/RouterInfo.java b/java-compat/src/Ice/src/main/java/IceInternal/RouterInfo.java
index 5650c6ee69c..6e1c7e27fcc 100644
--- a/java-compat/src/Ice/src/main/java/IceInternal/RouterInfo.java
+++ b/java-compat/src/Ice/src/main/java/IceInternal/RouterInfo.java
@@ -34,7 +34,6 @@ public final class RouterInfo
destroy()
{
_clientEndpoints = new EndpointI[0];
- _serverEndpoints = new EndpointI[0];
_adapter = null;
_identities.clear();
}
@@ -125,15 +124,13 @@ public final class RouterInfo
public EndpointI[]
getServerEndpoints()
{
- synchronized(this)
+ Ice.ObjectPrx serverProxy = _router.getServerProxy();
+ if(serverProxy == null)
{
- if(_serverEndpoints != null) // Lazy initialization.
- {
- return _serverEndpoints;
- }
+ throw new Ice.NoEndpointException();
}
-
- return setServerEndpoints(_router.getServerProxy());
+ serverProxy = serverProxy.ice_router(null); // The server proxy cannot be routed.
+ return ((Ice.ObjectPrxHelperBase)serverProxy)._getReference().getEndpoints();
}
public boolean
@@ -227,19 +224,6 @@ public final class RouterInfo
return _clientEndpoints;
}
- private synchronized EndpointI[]
- setServerEndpoints(Ice.ObjectPrx serverProxy)
- {
- if(serverProxy == null)
- {
- throw new Ice.NoEndpointException();
- }
-
- serverProxy = serverProxy.ice_router(null); // The server proxy cannot be routed.
- _serverEndpoints = ((Ice.ObjectPrxHelperBase)serverProxy)._getReference().getEndpoints();
- return _serverEndpoints;
- }
-
private synchronized void
addAndEvictProxies(Ice.ObjectPrx proxy, Ice.ObjectPrx[] evictedProxies)
{
@@ -281,7 +265,6 @@ public final class RouterInfo
private final Ice.RouterPrx _router;
private EndpointI[] _clientEndpoints;
- private EndpointI[] _serverEndpoints;
private Ice.ObjectAdapter _adapter;
private java.util.Set<Ice.Identity> _identities = new java.util.HashSet<Ice.Identity>();
private java.util.List<Ice.Identity> _evictedIdentities = new java.util.ArrayList<Ice.Identity>();
diff --git a/java-compat/test/src/main/java/test/Ice/adapterDeactivation/AllTests.java b/java-compat/test/src/main/java/test/Ice/adapterDeactivation/AllTests.java
index 3b0ec713776..56caa122982 100644
--- a/java-compat/test/src/main/java/test/Ice/adapterDeactivation/AllTests.java
+++ b/java-compat/test/src/main/java/test/Ice/adapterDeactivation/AllTests.java
@@ -11,6 +11,7 @@ package test.Ice.adapterDeactivation;
import test.Ice.adapterDeactivation.Test.TestIntfPrx;
import test.Ice.adapterDeactivation.Test.TestIntfPrxHelper;
+import java.util.Arrays;
public class AllTests
{
@@ -85,6 +86,34 @@ public class AllTests
out.println("ok");
}
+ out.print("testing object adapter published endpoints... ");
+ out.flush();
+ {
+ communicator.getProperties().setProperty("PAdapter.PublishedEndpoints", "tcp -h localhost -p 12345 -t 30000");
+ Ice.ObjectAdapter adapter = communicator.createObjectAdapter("PAdapter");
+ test(adapter.getPublishedEndpoints().length == 1);
+ Ice.Endpoint endpt = adapter.getPublishedEndpoints()[0];
+ test(endpt.toString().equals("tcp -h localhost -p 12345 -t 30000"));
+ Ice.ObjectPrx prx =
+ communicator.stringToProxy("dummy:tcp -h localhost -p 12346 -t 20000:tcp -h localhost -p 12347 -t 10000");
+ adapter.setPublishedEndpoints(prx.ice_getEndpoints());
+ test(adapter.getPublishedEndpoints().length == 2);
+ Ice.Identity id = new Ice.Identity();
+ id.name = "dummy";
+ test(Arrays.equals(adapter.createProxy(id).ice_getEndpoints(), prx.ice_getEndpoints()));
+ test(Arrays.equals(adapter.getPublishedEndpoints(), prx.ice_getEndpoints()));
+ adapter.refreshPublishedEndpoints();
+ test(adapter.getPublishedEndpoints().length == 1);
+ test(adapter.getPublishedEndpoints()[0].equals(endpt));
+ communicator.getProperties().setProperty("PAdapter.PublishedEndpoints", "tcp -h localhost -p 12345 -t 20000");
+ adapter.refreshPublishedEndpoints();
+ test(adapter.getPublishedEndpoints().length == 1);
+ test(adapter.getPublishedEndpoints()[0].toString().equals("tcp -h localhost -p 12345 -t 20000"));
+ adapter.destroy();
+ test(adapter.getPublishedEndpoints().length == 0);
+ }
+ out.println("ok");
+
if(obj.ice_getConnection() != null)
{
out.print("testing object adapter with bi-dir connection... ");
@@ -104,6 +133,53 @@ public class AllTests
out.println("ok");
}
+ out.print("testing object adapter with router... ");
+ out.flush();
+ {
+ Ice.Identity routerId = new Ice.Identity();
+ routerId.name = "router";
+ Ice.RouterPrx router = Ice.RouterPrxHelper.uncheckedCast(base.ice_identity(routerId).ice_connectionId("rc"));
+ Ice.ObjectAdapter adapter = communicator.createObjectAdapterWithRouter("", router);
+ test(adapter.getPublishedEndpoints().length == 1);
+ test(adapter.getPublishedEndpoints()[0].toString().equals("tcp -h localhost -p 23456 -t 30000"));
+ adapter.refreshPublishedEndpoints();
+ test(adapter.getPublishedEndpoints().length == 1);
+ test(adapter.getPublishedEndpoints()[0].toString().equals("tcp -h localhost -p 23457 -t 30000"));
+ try
+ {
+ adapter.setPublishedEndpoints(router.ice_getEndpoints());
+ test(false);
+ }
+ catch(IllegalArgumentException ex)
+ {
+ // Expected.
+ }
+ adapter.destroy();
+
+ try
+ {
+ routerId.name = "test";
+ router = Ice.RouterPrxHelper.uncheckedCast(base.ice_identity(routerId));
+ communicator.createObjectAdapterWithRouter("", router);
+ test(false);
+ }
+ catch(Ice.OperationNotExistException ex)
+ {
+ // Expected: the "test" object doesn't implement Ice::Router!
+ }
+
+ try
+ {
+ router = Ice.RouterPrxHelper.uncheckedCast(communicator.stringToProxy("test:" + app.getTestEndpoint(1)));
+ communicator.createObjectAdapterWithRouter("", router);
+ test(false);
+ }
+ catch(Ice.ConnectFailedException ex)
+ {
+ }
+ }
+ out.println("ok");
+
out.print("deactivating object adapter in the server... ");
out.flush();
obj.deactivate();
diff --git a/java-compat/test/src/main/java/test/Ice/adapterDeactivation/ServantLocatorI.java b/java-compat/test/src/main/java/test/Ice/adapterDeactivation/ServantLocatorI.java
index 501bdab1581..dcd933d76fe 100644
--- a/java-compat/test/src/main/java/test/Ice/adapterDeactivation/ServantLocatorI.java
+++ b/java-compat/test/src/main/java/test/Ice/adapterDeactivation/ServantLocatorI.java
@@ -13,6 +13,30 @@ import test.Ice.adapterDeactivation.Test.Cookie;
public final class ServantLocatorI implements Ice.ServantLocator
{
+ final static class RouterI extends Ice._RouterDisp
+ {
+ public Ice.ObjectPrx getClientProxy(Ice.BooleanHolder hasRoutingTable, Ice.Current current)
+ {
+ hasRoutingTable.value = false;
+ return null;
+ }
+
+ public Ice.ObjectPrx getServerProxy(Ice.Current current)
+ {
+ StringBuilder s = new StringBuilder("dummy:tcp -h localhost -p ");
+ s.append(_nextPort++);
+ s.append(" -t 30000");
+ return current.adapter.getCommunicator().stringToProxy(s.toString());
+ }
+
+ public Ice.ObjectPrx[] addProxies(Ice.ObjectPrx[] proxies, Ice.Current current)
+ {
+ return null;
+ }
+
+ private int _nextPort = 23456;
+ }
+
public
ServantLocatorI()
{
@@ -44,6 +68,11 @@ public final class ServantLocatorI implements Ice.ServantLocator
test(!_deactivated);
}
+ if(current.id.name.equals("router"))
+ {
+ return _router;
+ }
+
test(current.id.category.length() == 0);
test(current.id.name.equals("test"));
@@ -60,6 +89,11 @@ public final class ServantLocatorI implements Ice.ServantLocator
test(!_deactivated);
}
+ if(current.id.name.equals("router"))
+ {
+ return;
+ }
+
Cookie co = (Cookie)cookie;
test(co.message().equals("blahblah"));
}
@@ -76,4 +110,5 @@ public final class ServantLocatorI implements Ice.ServantLocator
}
private boolean _deactivated;
+ static private Ice.Object _router = new RouterI();
}
diff --git a/java/src/Ice/src/main/java/com/zeroc/Ice/ObjectAdapterI.java b/java/src/Ice/src/main/java/com/zeroc/Ice/ObjectAdapterI.java
index 87017f4b929..b6d96727904 100644
--- a/java/src/Ice/src/main/java/com/zeroc/Ice/ObjectAdapterI.java
+++ b/java/src/Ice/src/main/java/com/zeroc/Ice/ObjectAdapterI.java
@@ -377,9 +377,8 @@ public final class ObjectAdapterI implements ObjectAdapter
//
_instance = null;
_threadPool = null;
- _routerEndpoints = null;
_routerInfo = null;
- _publishedEndpoints = null;
+ _publishedEndpoints = new EndpointI[0];
_locatorInfo = null;
_reference = null;
_objectAdapterFactory = null;
@@ -627,14 +626,14 @@ public final class ObjectAdapterI implements ObjectAdapter
refreshPublishedEndpoints()
{
com.zeroc.IceInternal.LocatorInfo locatorInfo = null;
- List<com.zeroc.IceInternal.EndpointI> oldPublishedEndpoints;
+ EndpointI[] oldPublishedEndpoints;
synchronized(this)
{
checkForDeactivation();
oldPublishedEndpoints = _publishedEndpoints;
- _publishedEndpoints = parsePublishedEndpoints();
+ _publishedEndpoints = computePublishedEndpoints();
locatorInfo = _locatorInfo;
}
@@ -662,27 +661,27 @@ public final class ObjectAdapterI implements ObjectAdapter
public synchronized Endpoint[]
getPublishedEndpoints()
{
- return _publishedEndpoints.toArray(new Endpoint[0]);
+ return java.util.Arrays.copyOf(_publishedEndpoints, _publishedEndpoints.length, Endpoint[].class);
}
@Override
public void
setPublishedEndpoints(Endpoint[] newEndpoints)
{
- List<com.zeroc.IceInternal.EndpointI> newPublishedEndpoints = new ArrayList<>(newEndpoints.length);
- for(Endpoint e: newEndpoints)
- {
- newPublishedEndpoints.add((com.zeroc.IceInternal.EndpointI)e);
- }
-
com.zeroc.IceInternal.LocatorInfo locatorInfo = null;
- List<com.zeroc.IceInternal.EndpointI> oldPublishedEndpoints;
+ EndpointI[] oldPublishedEndpoints;
synchronized(this)
{
checkForDeactivation();
+ if(_routerInfo != null)
+ {
+ throw new IllegalArgumentException(
+ "can't set published endpoints on object adapter associated with a router");
+ }
+
oldPublishedEndpoints = _publishedEndpoints;
- _publishedEndpoints = newPublishedEndpoints;
+ _publishedEndpoints = java.util.Arrays.copyOf(newEndpoints, newEndpoints.length, EndpointI[].class);
locatorInfo = _locatorInfo;
}
@@ -760,25 +759,6 @@ public final class ObjectAdapterI implements ObjectAdapter
}
}
}
-
- //
- // Proxies which have at least one endpoint in common with the
- // router's server proxy endpoints (if any), are also considered
- // local.
- //
- if(_routerInfo != null && _routerInfo.getRouter().equals(proxy.ice_getRouter()))
- {
- for(com.zeroc.IceInternal.EndpointI endpoint : endpoints)
- {
- for(com.zeroc.IceInternal.EndpointI p : _routerEndpoints)
- {
- if(endpoint.equivalent(p))
- {
- return true;
- }
- }
- }
- }
}
}
@@ -1021,60 +1001,30 @@ public final class ObjectAdapterI implements ObjectAdapter
if(router != null)
{
_routerInfo = _instance.routerManager().get(router);
- if(_routerInfo != null)
- {
- //
- // Make sure this router is not already registered with another adapter.
- //
- if(_routerInfo.getAdapter() != null)
- {
- throw new AlreadyRegisteredException("object adapter with router",
- _communicator.identityToString(router.ice_getIdentity()));
- }
+ assert(_routerInfo != null);
- //
- // Add the router's server proxy endpoints to this object
- // adapter.
- //
- com.zeroc.IceInternal.EndpointI[] endpoints = _routerInfo.getServerEndpoints();
- for(com.zeroc.IceInternal.EndpointI endpoint : endpoints)
- {
- _routerEndpoints.add(endpoint);
- }
- java.util.Collections.sort(_routerEndpoints); // Must be sorted.
+ //
+ // Make sure this router is not already registered with another adapter.
+ //
+ if(_routerInfo.getAdapter() != null)
+ {
+ throw new AlreadyRegisteredException("object adapter with router",
+ _communicator.identityToString(router.ice_getIdentity()));
+ }
- //
- // Remove duplicate endpoints, so we have a list of unique
- // endpoints.
- //
- for(int i = 0; i < _routerEndpoints.size() - 1;)
- {
- com.zeroc.IceInternal.EndpointI e1 = _routerEndpoints.get(i);
- com.zeroc.IceInternal.EndpointI e2 = _routerEndpoints.get(i + 1);
- if(e1.equals(e2))
- {
- _routerEndpoints.remove(i);
- }
- else
- {
- ++i;
- }
- }
+ //
+ // Associate this object adapter with the router. This way,
+ // new outgoing connections to the router's client proxy will
+ // use this object adapter for callbacks.
+ //
+ _routerInfo.setAdapter(this);
- //
- // Associate this object adapter with the router. This way,
- // new outgoing connections to the router's client proxy will
- // use this object adapter for callbacks.
- //
- _routerInfo.setAdapter(this);
-
- //
- // Also modify all existing outgoing connections to the
- // router's client proxy to use this object adapter for
- // callbacks.
- //
- _instance.outgoingConnectionFactory().setRouterInfo(_routerInfo);
- }
+ //
+ // Also modify all existing outgoing connections to the
+ // router's client proxy to use this object adapter for
+ // callbacks.
+ //
+ _instance.outgoingConnectionFactory().setRouterInfo(_routerInfo);
}
else
{
@@ -1105,13 +1055,13 @@ public final class ObjectAdapterI implements ObjectAdapter
"created adapter `" + name + "' without endpoints");
}
}
-
- //
- // Parse the publsihed endpoints.
- //
- _publishedEndpoints = parsePublishedEndpoints();
}
+ //
+ // Compute the publsihed endpoints.
+ //
+ _publishedEndpoints = computePublishedEndpoints();
+
if(properties.getProperty(_name + ".Locator").length() > 0)
{
setLocator(LocatorPrx.uncheckedCast(_instance.proxyFactory().propertyToProxy(_name + ".Locator")));
@@ -1184,26 +1134,11 @@ public final class ObjectAdapterI implements ObjectAdapter
private ObjectPrx
newDirectProxy(Identity ident, String facet)
{
- com.zeroc.IceInternal.EndpointI[] endpoints;
-
- int sz = _publishedEndpoints.size();
- endpoints = new com.zeroc.IceInternal.EndpointI[sz + _routerEndpoints.size()];
- _publishedEndpoints.toArray(endpoints);
-
- //
- // Now we also add the endpoints of the router's server proxy, if
- // any. This way, object references created by this object adapter
- // will also point to the router's server proxy endpoints.
- //
- for(int i = 0; i < _routerEndpoints.size(); ++i)
- {
- endpoints[sz + i] = _routerEndpoints.get(i);
- }
-
//
// Create a reference and return a proxy for this reference.
//
- com.zeroc.IceInternal.Reference ref = _instance.referenceFactory().create(ident, facet, _reference, endpoints);
+ com.zeroc.IceInternal.Reference ref = _instance.referenceFactory().create(ident, facet, _reference,
+ _publishedEndpoints);
return _instance.proxyFactory().referenceToProxy(ref);
}
@@ -1335,34 +1270,52 @@ public final class ObjectAdapterI implements ObjectAdapter
return endpoints;
}
- private List<com.zeroc.IceInternal.EndpointI>
- parsePublishedEndpoints()
+ private EndpointI[]
+ computePublishedEndpoints()
{
- //
- // Parse published endpoints. If set, these are used in proxies
- // instead of the connection factory Endpoints.
- //
- String endpts = _instance.initializationData().properties.getProperty(_name + ".PublishedEndpoints");
- List<com.zeroc.IceInternal.EndpointI> endpoints = parseEndpoints(endpts, false);
- if(endpoints.isEmpty())
+ List<EndpointI> endpoints;
+ if(_routerInfo != null)
{
//
- // If the PublishedEndpoints property isn't set, we compute the published enpdoints
- // from the OA endpoints, expanding any endpoints that may be listening on INADDR_ANY
- // to include actual addresses in the published endpoints.
+ // Get the router's server proxy endpoints and use them as the published endpoints.
//
- for(IncomingConnectionFactory factory : _incomingConnectionFactories)
+ endpoints = new ArrayList<>();
+ for(EndpointI endpt : _routerInfo.getServerEndpoints())
+ {
+ if(!endpoints.contains(endpt))
+ {
+ endpoints.add(endpt);
+ }
+ }
+ }
+ else
+ {
+ //
+ // Parse published endpoints. If set, these are used in proxies
+ // instead of the connection factory Endpoints.
+ //
+ String endpts = _instance.initializationData().properties.getProperty(_name + ".PublishedEndpoints");
+ endpoints = parseEndpoints(endpts, false);
+ if(endpoints.isEmpty())
{
- for(EndpointI endpt : factory.endpoint().expandIfWildcard())
+ //
+ // If the PublishedEndpoints property isn't set, we compute the published enpdoints
+ // from the OA endpoints, expanding any endpoints that may be listening on INADDR_ANY
+ // to include actual addresses in the published endpoints.
+ //
+ for(IncomingConnectionFactory factory : _incomingConnectionFactories)
{
- //
- // Check for duplicate endpoints, this might occur if an endpoint with a DNS name
- // expands to multiple addresses. In this case, multiple incoming connection
- // factories can point to the same published endpoint.
- //
- if(!endpoints.contains(endpt))
+ for(EndpointI endpt : factory.endpoint().expandIfWildcard())
{
- endpoints.add(endpt);
+ //
+ // Check for duplicate endpoints, this might occur if an endpoint with a DNS name
+ // expands to multiple addresses. In this case, multiple incoming connection
+ // factories can point to the same published endpoint.
+ //
+ if(!endpoints.contains(endpt))
+ {
+ endpoints.add(endpt);
+ }
}
}
}
@@ -1385,7 +1338,7 @@ public final class ObjectAdapterI implements ObjectAdapter
}
_instance.initializationData().logger.trace(_instance.traceLevels().networkCat, s.toString());
}
- return endpoints;
+ return endpoints.toArray(new EndpointI[endpoints.size()]);
}
private void
@@ -1617,9 +1570,8 @@ public final class ObjectAdapterI implements ObjectAdapter
final private String _replicaGroupId;
private com.zeroc.IceInternal.Reference _reference;
private List<IncomingConnectionFactory> _incomingConnectionFactories = new ArrayList<>();
- private List<com.zeroc.IceInternal.EndpointI> _routerEndpoints = new ArrayList<>();
private com.zeroc.IceInternal.RouterInfo _routerInfo = null;
- private List<com.zeroc.IceInternal.EndpointI> _publishedEndpoints = new ArrayList<>();
+ private EndpointI[] _publishedEndpoints = new EndpointI[0];
private com.zeroc.IceInternal.LocatorInfo _locatorInfo;
private int _directCount; // The number of direct proxies dispatching on this object adapter.
private boolean _noConfig;
diff --git a/java/src/Ice/src/main/java/com/zeroc/IceInternal/ObjectAdapterFactory.java b/java/src/Ice/src/main/java/com/zeroc/IceInternal/ObjectAdapterFactory.java
index 51b2753def0..a2fcb1cc2c1 100644
--- a/java/src/Ice/src/main/java/com/zeroc/IceInternal/ObjectAdapterFactory.java
+++ b/java/src/Ice/src/main/java/com/zeroc/IceInternal/ObjectAdapterFactory.java
@@ -143,7 +143,7 @@ public final class ObjectAdapterFactory
}
}
- public synchronized ObjectAdapter
+ public ObjectAdapter
createObjectAdapter(String name, com.zeroc.Ice.RouterPrx router)
{
if(Thread.interrupted())
@@ -151,27 +151,69 @@ public final class ObjectAdapterFactory
throw new com.zeroc.Ice.OperationInterruptedException();
}
- if(_instance == null)
+ synchronized(this)
{
- throw new com.zeroc.Ice.CommunicatorDestroyedException();
+ if(_instance == null)
+ {
+ throw new com.zeroc.Ice.CommunicatorDestroyedException();
+ }
+
+ if(!name.isEmpty())
+ {
+ if(_adapterNamesInUse.contains(name))
+ {
+ throw new com.zeroc.Ice.AlreadyRegisteredException("object adapter", name);
+ }
+ _adapterNamesInUse.add(name);
+ }
}
- ObjectAdapterI adapter = null;
- if(name.length() == 0)
+ //
+ // Must be called outside the synchronization since initialize can make client invocations
+ // on the router if it's set.
+ //
+ com.zeroc.Ice.ObjectAdapterI adapter = null;
+ try
+ {
+ if(name.isEmpty())
+ {
+ String uuid = java.util.UUID.randomUUID().toString();
+ adapter = new com.zeroc.Ice.ObjectAdapterI(_instance, _communicator, this, uuid, null, true);
+ }
+ else
+ {
+ adapter = new com.zeroc.Ice.ObjectAdapterI(_instance, _communicator, this, name, router, false);
+ }
+
+ synchronized(this)
+ {
+ if(_instance == null)
+ {
+ throw new com.zeroc.Ice.CommunicatorDestroyedException();
+ }
+ _adapters.add(adapter);
+ }
+ }
+ catch(com.zeroc.Ice.CommunicatorDestroyedException ex)
{
- String uuid = java.util.UUID.randomUUID().toString();
- adapter = new ObjectAdapterI(_instance, _communicator, this, uuid, null, true);
+ if(adapter != null)
+ {
+ adapter.destroy();
+ }
+ throw ex;
}
- else
+ catch(com.zeroc.Ice.LocalException ex)
{
- if(_adapterNamesInUse.contains(name))
+ if(!name.isEmpty())
{
- throw new com.zeroc.Ice.AlreadyRegisteredException("object adapter", name);
+ synchronized(this)
+ {
+ _adapterNamesInUse.remove(name);
+ }
}
- adapter = new ObjectAdapterI(_instance, _communicator, this, name, router, false);
- _adapterNamesInUse.add(name);
+ throw ex;
}
- _adapters.add(adapter);
+
return adapter;
}
diff --git a/java/src/Ice/src/main/java/com/zeroc/IceInternal/OutgoingConnectionFactory.java b/java/src/Ice/src/main/java/com/zeroc/IceInternal/OutgoingConnectionFactory.java
index dcafe13b5fa..4d6edec0efa 100644
--- a/java/src/Ice/src/main/java/com/zeroc/IceInternal/OutgoingConnectionFactory.java
+++ b/java/src/Ice/src/main/java/com/zeroc/IceInternal/OutgoingConnectionFactory.java
@@ -231,52 +231,57 @@ public final class OutgoingConnectionFactory
}
}
- public synchronized void
+ public void
setRouterInfo(RouterInfo routerInfo)
{
- if(_destroyed)
- {
- throw new com.zeroc.Ice.CommunicatorDestroyedException();
- }
-
assert(routerInfo != null);
-
- //
- // Search for connections to the router's client proxy
- // endpoints, and update the object adapter for such
- // connections, so that callbacks from the router can be
- // received over such connections.
- //
com.zeroc.Ice.ObjectAdapter adapter = routerInfo.getAdapter();
- DefaultsAndOverrides defaultsAndOverrides = _instance.defaultsAndOverrides();
- for(EndpointI endpoint : routerInfo.getClientEndpoints())
+ EndpointI[] endpoints = routerInfo.getClientEndpoints(); // Must be called outside the synchronization
+
+ synchronized(this)
{
- //
- // Modify endpoints with overrides.
- //
- if(defaultsAndOverrides.overrideTimeout)
+ if(_destroyed)
{
- endpoint = endpoint.timeout(defaultsAndOverrides.overrideTimeoutValue);
+ throw new com.zeroc.Ice.CommunicatorDestroyedException();
}
+ DefaultsAndOverrides defaultsAndOverrides = _instance.defaultsAndOverrides();
+
//
- // The Connection object does not take the compression flag of
- // endpoints into account, but instead gets the information
- // about whether messages should be compressed or not from
- // other sources. In order to allow connection sharing for
- // endpoints that differ in the value of the compression flag
- // only, we always set the compression flag to false here in
- // this connection factory.
+ // Search for connections to the router's client proxy
+ // endpoints, and update the object adapter for such
+ // connections, so that callbacks from the router can be
+ // received over such connections.
//
- endpoint = endpoint.compress(false);
-
- for(java.util.List<ConnectionI> connectionList : _connections.values())
+ for(EndpointI endpoint : endpoints)
{
- for(ConnectionI connection : connectionList)
+ //
+ // Modify endpoints with overrides.
+ //
+ if(defaultsAndOverrides.overrideTimeout)
+ {
+ endpoint = endpoint.timeout(defaultsAndOverrides.overrideTimeoutValue);
+ }
+
+ //
+ // The Connection object does not take the compression flag of
+ // endpoints into account, but instead gets the information
+ // about whether messages should be compressed or not from
+ // other sources. In order to allow connection sharing for
+ // endpoints that differ in the value of the compression flag
+ // only, we always set the compression flag to false here in
+ // this connection factory.
+ //
+ endpoint = endpoint.compress(false);
+
+ for(java.util.List<ConnectionI> connectionList : _connections.values())
{
- if(connection.endpoint() == endpoint)
+ for(ConnectionI connection : connectionList)
{
- connection.setAdapter(adapter);
+ if(connection.endpoint() == endpoint)
+ {
+ connection.setAdapter(adapter);
+ }
}
}
}
diff --git a/java/src/Ice/src/main/java/com/zeroc/IceInternal/RouterInfo.java b/java/src/Ice/src/main/java/com/zeroc/IceInternal/RouterInfo.java
index 14ffb9bdde9..96c4a71f1b5 100644
--- a/java/src/Ice/src/main/java/com/zeroc/IceInternal/RouterInfo.java
+++ b/java/src/Ice/src/main/java/com/zeroc/IceInternal/RouterInfo.java
@@ -34,7 +34,6 @@ public final class RouterInfo
destroy()
{
_clientEndpoints = new EndpointI[0];
- _serverEndpoints = new EndpointI[0];
_adapter = null;
_identities.clear();
}
@@ -125,15 +124,13 @@ public final class RouterInfo
public EndpointI[]
getServerEndpoints()
{
- synchronized(this)
+ com.zeroc.Ice.ObjectPrx serverProxy = _router.getServerProxy();
+ if(serverProxy == null)
{
- if(_serverEndpoints != null) // Lazy initialization.
- {
- return _serverEndpoints;
- }
+ throw new com.zeroc.Ice.NoEndpointException();
}
-
- return setServerEndpoints(_router.getServerProxy());
+ serverProxy = serverProxy.ice_router(null); // The server proxy cannot be routed.
+ return ((com.zeroc.Ice._ObjectPrxI)serverProxy)._getReference().getEndpoints();
}
public boolean
@@ -229,19 +226,6 @@ public final class RouterInfo
return _clientEndpoints;
}
- private synchronized EndpointI[]
- setServerEndpoints(com.zeroc.Ice.ObjectPrx serverProxy)
- {
- if(serverProxy == null)
- {
- throw new com.zeroc.Ice.NoEndpointException();
- }
-
- serverProxy = serverProxy.ice_router(null); // The server proxy cannot be routed.
- _serverEndpoints = ((com.zeroc.Ice._ObjectPrxI)serverProxy)._getReference().getEndpoints();
- return _serverEndpoints;
- }
-
private synchronized void
addAndEvictProxies(com.zeroc.Ice.ObjectPrx proxy, com.zeroc.Ice.ObjectPrx[] evictedProxies)
{
@@ -283,7 +267,6 @@ public final class RouterInfo
private final com.zeroc.Ice.RouterPrx _router;
private EndpointI[] _clientEndpoints;
- private EndpointI[] _serverEndpoints;
private com.zeroc.Ice.ObjectAdapter _adapter;
private java.util.Set<com.zeroc.Ice.Identity> _identities = new java.util.HashSet<>();
private java.util.List<com.zeroc.Ice.Identity> _evictedIdentities = new java.util.ArrayList<>();
diff --git a/java/test/src/main/java/test/Ice/adapterDeactivation/AllTests.java b/java/test/src/main/java/test/Ice/adapterDeactivation/AllTests.java
index e9899de11ca..afe415960e7 100644
--- a/java/test/src/main/java/test/Ice/adapterDeactivation/AllTests.java
+++ b/java/test/src/main/java/test/Ice/adapterDeactivation/AllTests.java
@@ -9,6 +9,7 @@
package test.Ice.adapterDeactivation;
+import java.util.Arrays;
import test.Ice.adapterDeactivation.Test.TestIntfPrx;
public class AllTests
@@ -82,6 +83,34 @@ public class AllTests
out.println("ok");
}
+ out.print("testing object adapter published endpoints... ");
+ out.flush();
+ {
+ communicator.getProperties().setProperty("PAdapter.PublishedEndpoints", "tcp -h localhost -p 12345 -t 30000");
+ com.zeroc.Ice.ObjectAdapter adapter = communicator.createObjectAdapter("PAdapter");
+ test(adapter.getPublishedEndpoints().length == 1);
+ com.zeroc.Ice.Endpoint endpt = adapter.getPublishedEndpoints()[0];
+ test(endpt.toString().equals("tcp -h localhost -p 12345 -t 30000"));
+ com.zeroc.Ice.ObjectPrx prx =
+ communicator.stringToProxy("dummy:tcp -h localhost -p 12346 -t 20000:tcp -h localhost -p 12347 -t 10000");
+ adapter.setPublishedEndpoints(prx.ice_getEndpoints());
+ test(adapter.getPublishedEndpoints().length == 2);
+ com.zeroc.Ice.Identity id = new com.zeroc.Ice.Identity();
+ id.name = "dummy";
+ test(Arrays.equals(adapter.createProxy(id).ice_getEndpoints(), prx.ice_getEndpoints()));
+ test(Arrays.equals(adapter.getPublishedEndpoints(), prx.ice_getEndpoints()));
+ adapter.refreshPublishedEndpoints();
+ test(adapter.getPublishedEndpoints().length == 1);
+ test(adapter.getPublishedEndpoints()[0].equals(endpt));
+ communicator.getProperties().setProperty("PAdapter.PublishedEndpoints", "tcp -h localhost -p 12345 -t 20000");
+ adapter.refreshPublishedEndpoints();
+ test(adapter.getPublishedEndpoints().length == 1);
+ test(adapter.getPublishedEndpoints()[0].toString().equals("tcp -h localhost -p 12345 -t 20000"));
+ adapter.destroy();
+ test(adapter.getPublishedEndpoints().length == 0);
+ }
+ out.println("ok");
+
if(obj.ice_getConnection() != null)
{
out.print("testing object adapter with bi-dir connection... ");
@@ -101,6 +130,55 @@ public class AllTests
out.println("ok");
}
+ out.print("testing object adapter with router... ");
+ out.flush();
+ {
+ com.zeroc.Ice.Identity routerId = new com.zeroc.Ice.Identity();
+ routerId.name = "router";
+ com.zeroc.Ice.RouterPrx router =
+ com.zeroc.Ice.RouterPrx.uncheckedCast(base.ice_identity(routerId).ice_connectionId("rc"));
+ com.zeroc.Ice.ObjectAdapter adapter = communicator.createObjectAdapterWithRouter("", router);
+ test(adapter.getPublishedEndpoints().length == 1);
+ test(adapter.getPublishedEndpoints()[0].toString().equals("tcp -h localhost -p 23456 -t 30000"));
+ adapter.refreshPublishedEndpoints();
+ test(adapter.getPublishedEndpoints().length == 1);
+ test(adapter.getPublishedEndpoints()[0].toString().equals("tcp -h localhost -p 23457 -t 30000"));
+ try
+ {
+ adapter.setPublishedEndpoints(router.ice_getEndpoints());
+ test(false);
+ }
+ catch(IllegalArgumentException ex)
+ {
+ // Expected.
+ }
+ adapter.destroy();
+
+ try
+ {
+ routerId.name = "test";
+ router = com.zeroc.Ice.RouterPrx.uncheckedCast(base.ice_identity(routerId));
+ communicator.createObjectAdapterWithRouter("", router);
+ test(false);
+ }
+ catch(com.zeroc.Ice.OperationNotExistException ex)
+ {
+ // Expected: the "test" object doesn't implement Ice::Router!
+ }
+
+ try
+ {
+ router =
+ com.zeroc.Ice.RouterPrx.uncheckedCast(communicator.stringToProxy("test:" + app.getTestEndpoint(1)));
+ communicator.createObjectAdapterWithRouter("", router);
+ test(false);
+ }
+ catch(com.zeroc.Ice.ConnectFailedException ex)
+ {
+ }
+ }
+ out.println("ok");
+
out.print("deactivating object adapter in the server... ");
out.flush();
obj.deactivate();
diff --git a/java/test/src/main/java/test/Ice/adapterDeactivation/ServantLocatorI.java b/java/test/src/main/java/test/Ice/adapterDeactivation/ServantLocatorI.java
index 7c13b721681..529082a7377 100644
--- a/java/test/src/main/java/test/Ice/adapterDeactivation/ServantLocatorI.java
+++ b/java/test/src/main/java/test/Ice/adapterDeactivation/ServantLocatorI.java
@@ -14,6 +14,29 @@ import com.zeroc.Ice.ServantLocator;
public final class ServantLocatorI implements ServantLocator
{
+ final static class RouterI implements com.zeroc.Ice.Router
+ {
+ public com.zeroc.Ice.Router.GetClientProxyResult getClientProxy(com.zeroc.Ice.Current current)
+ {
+ return new com.zeroc.Ice.Router.GetClientProxyResult();
+ }
+
+ public com.zeroc.Ice.ObjectPrx getServerProxy(com.zeroc.Ice.Current current)
+ {
+ StringBuilder s = new StringBuilder("dummy:tcp -h localhost -p ");
+ s.append(_nextPort++);
+ s.append(" -t 30000");
+ return current.adapter.getCommunicator().stringToProxy(s.toString());
+ }
+
+ public com.zeroc.Ice.ObjectPrx[] addProxies(com.zeroc.Ice.ObjectPrx[] proxies, com.zeroc.Ice.Current current)
+ {
+ return null;
+ }
+
+ private int _nextPort = 23456;
+ }
+
public ServantLocatorI()
{
_deactivated = false;
@@ -41,6 +64,11 @@ public final class ServantLocatorI implements ServantLocator
test(!_deactivated);
}
+ if(current.id.name.equals("router"))
+ {
+ return new ServantLocator.LocateResult(_router, null);
+ }
+
test(current.id.category.length() == 0);
test(current.id.name.equals("test"));
@@ -54,6 +82,11 @@ public final class ServantLocatorI implements ServantLocator
test(!_deactivated);
}
+ if(current.id.name.equals("router"))
+ {
+ return;
+ }
+
Cookie co = (Cookie)cookie;
test(co.message().equals("blahblah"));
}
@@ -69,4 +102,5 @@ public final class ServantLocatorI implements ServantLocator
}
private boolean _deactivated;
+ static private com.zeroc.Ice.Object _router = new RouterI();
}
diff --git a/js/gulpfile.js b/js/gulpfile.js
index 1fa8b04cf29..0e627d1b54e 100644
--- a/js/gulpfile.js
+++ b/js/gulpfile.js
@@ -83,6 +83,7 @@ function slice2js(options) {
//
var tests = [
"test/Ice/acm",
+ "test/Ice/adapterDeactivation",
"test/Ice/ami",
"test/Ice/binding",
"test/Ice/defaultValue",
diff --git a/js/src/Ice/ObjectAdapterI.js b/js/src/Ice/ObjectAdapterI.js
index 66d815bbe8e..3f2c94812cf 100644
--- a/js/src/Ice/ObjectAdapterI.js
+++ b/js/src/Ice/ObjectAdapterI.js
@@ -18,7 +18,8 @@ Ice._ModuleRegistry.require(module,
"../Ice/Router",
"../Ice/ServantManager",
"../Ice/StringUtil",
- "../Ice/UUID"
+ "../Ice/UUID",
+ "../Ice/ArrayUtil"
]);
const AsyncResultBase = Ice.AsyncResultBase;
@@ -27,6 +28,7 @@ const Identity = Ice.Identity;
const PropertyNames = Ice.PropertyNames;
const ServantManager = Ice.ServantManager;
const StringUtil = Ice.StringUtil;
+const ArrayUtil = Ice.ArrayUtil;
const _suffixes =
[
@@ -86,7 +88,7 @@ class ObjectAdapterI
this._objectAdapterFactory = objectAdapterFactory;
this._servantManager = new ServantManager(instance, name);
this._name = name;
- this._routerEndpoints = [];
+ this._publishedEndpoints = [];
this._routerInfo = null;
this._state = StateUninitialized;
this._noConfig = noConfig;
@@ -158,12 +160,12 @@ class ObjectAdapterI
try
{
-
if(router === null)
{
router = Ice.RouterPrx.uncheckedCast(
this._instance.proxyFactory().propertyToProxy(this._name + ".Router"));
}
+ let p;
if(router !== null)
{
this._routerInfo = this._instance.routerManager().find(router);
@@ -180,46 +182,18 @@ class ObjectAdapterI
}
//
- // Add the router's server proxy endpoints to this object
- // adapter.
+ // Associate this object adapter with the router. This way,
+ // new outgoing connections to the router's client proxy will
+ // use this object adapter for callbacks.
//
- this._routerInfo.getServerEndpoints().then(
- (endpoints) =>
- {
- endpoints.forEach(endpoint => this._routerEndpoints.push(endpoint));
- this._routerEndpoints.sort((e1, e2) => e1.compareTo(e2)); // Must be sorted.
-
- //
- // Remove duplicate endpoints, so we have a list of unique
- // endpoints.
- //
- for(let i = 0; i < this._routerEndpoints.length - 1;)
- {
- if(this._routerEndpoints[i].equals(this._routerEndpoints[i + 1]))
- {
- this._routerEndpoints.splice(i, 1);
- }
- else
- {
- ++i;
- }
- }
+ this._routerInfo.setAdapter(this);
- //
- // Associate this object adapter with the router. This way,
- // new outgoing connections to the router's client proxy will
- // use this object adapter for callbacks.
- //
- this._routerInfo.setAdapter(this);
-
- //
- // Also modify all existing outgoing connections to the
- // router's client proxy to use this object adapter for
- // callbacks.
- //
- return this._instance.outgoingConnectionFactory().setRouterInfo(this._routerInfo);
- }
- ).then(() => promise.resolve(this), promise.reject);
+ //
+ // Also modify all existing outgoing connections to the
+ // router's client proxy to use this object adapter for
+ // callbacks.
+ //
+ p = this._instance.outgoingConnectionFactory().setRouterInfo(this._routerInfo);
}
else
{
@@ -228,8 +202,19 @@ class ObjectAdapterI
{
throw new Ice.FeatureNotSupportedException("object adapter endpoints not supported");
}
- promise.resolve(this);
+ p = Ice.Promise.resolve();
}
+
+ p.then(() => this.computePublishedEndpoints()).then(endpoints =>
+ {
+ this._publishedEndpoints = endpoints;
+ promise.resolve(this);
+ },
+ ex =>
+ {
+ this.destroy();
+ promise.reject(ex);
+ });
}
catch(ex)
{
@@ -268,14 +253,11 @@ class ObjectAdapterI
deactivate()
{
- const promise = new AsyncResultBase(this._communicator, "deactivate", null, null, this);
if(this._state < StateDeactivated)
{
this._state = StateDeactivated;
this._instance.outgoingConnectionFactory().removeAdapter(this);
}
- promise.resolve();
- return promise;
}
waitForDeactivate()
@@ -290,19 +272,15 @@ class ObjectAdapterI
destroy()
{
- const promise = new AsyncResultBase(this._communicator, "destroy", null, null, this);
- const destroyInternal = () =>
+ this.deactivate();
+ if(this._state < StateDestroyed)
{
- if(this._state < StateDestroyed)
- {
- this._state = StateDestroyed;
- this._servantManager.destroy();
- this._objectAdapterFactory.removeObjectAdapter(this);
- }
- return promise.resolve();
- };
-
- return this._state < StateDeactivated ? this.deactivate().then(destroyInternal) : destroyInternal();
+ this._state = StateDestroyed;
+ this._servantManager.destroy();
+ this._objectAdapterFactory.removeObjectAdapter(this);
+ this._publishedEndpoints = [];
+ }
+ return new AsyncResultBase(this._communicator, "destroy", null, null, this).resolve();
}
add(object, ident)
@@ -452,17 +430,23 @@ class ObjectAdapterI
refreshPublishedEndpoints()
{
- throw new Ice.FeatureNotSupportedException("refreshPublishedEndpoints not supported");
+ this.checkForDeactivation();
+ return this.computePublishedEndpoints().then(endpoints => this._publishedEndpoints = endpoints);
}
getPublishedEndpoints()
{
- return [];
+ return ArrayUtil.clone(this._publishedEndpoints);
}
setPublishedEndpoints(newEndpoints)
{
- throw new Ice.FeatureNotSupportedException("setPublishedEndpoints not supported");
+ this.checkForDeactivation();
+ if(this._routerInfo !== null)
+ {
+ throw new Error("can't set published endpoints on object adapter associated with a router");
+ }
+ this._publishedEndpoints = ArrayUtil.clone(newEndpoints);
}
getServantManager()
@@ -495,8 +479,7 @@ class ObjectAdapterI
// Create a reference and return a proxy for this reference.
//
return this._instance.proxyFactory().referenceToProxy(
- this._instance.referenceFactory().create(ident, facet, this._reference,
- Array.from(this._routerEndpoints)));
+ this._instance.referenceFactory().create(ident, facet, this._reference, this._publishedEndpoints));
}
checkForDeactivation(promise)
@@ -541,6 +524,131 @@ class ObjectAdapterI
}
}
+ computePublishedEndpoints()
+ {
+ let p;
+ if(this._routerInfo !== null)
+ {
+ p = this._routerInfo.getServerEndpoints().then((endpts) =>
+ {
+ //
+ // Remove duplicate endpoints, so we have a list of unique endpoints.
+ //
+ let endpoints = [];
+ endpts.forEach(endpoint =>
+ {
+ if(endpoints.findIndex(value => endpoint.equals(value)) === -1)
+ {
+ endpoints.push(endpoint);
+ }
+ });
+ return endpoints;
+ });
+ }
+ else
+ {
+
+ //
+ // Parse published endpoints. If set, these are used in proxies
+ // instead of the connection factory Endpoints.
+ //
+ let endpoints = [];
+ let s = this._instance.initializationData().properties.getProperty(this._name + ".PublishedEndpoints");
+ const delim = " \t\n\r";
+
+ let end = 0;
+ let beg;
+ while(end < s.length)
+ {
+ beg = StringUtil.findFirstNotOf(s, delim, end);
+ if(beg === -1)
+ {
+ if(s != "")
+ {
+ throw new Ice.EndpointParseException("invalid empty object adapter endpoint");
+ }
+ break;
+ }
+
+ end = beg;
+ while(true)
+ {
+ end = s.indexOf(':', end);
+ if(end == -1)
+ {
+ end = s.length;
+ break;
+ }
+ else
+ {
+ let quoted = false;
+ let quote = beg;
+ while(true)
+ {
+ quote = s.indexOf("\"", quote);
+ if(quote == -1 || end < quote)
+ {
+ break;
+ }
+ else
+ {
+ quote = s.indexOf('\"', ++quote);
+ if(quote == -1)
+ {
+ break;
+ }
+ else if(end < quote)
+ {
+ quoted = true;
+ break;
+ }
+ ++quote;
+ }
+ }
+ if(!quoted)
+ {
+ break;
+ }
+ ++end;
+ }
+ }
+
+ let es = s.substring(beg, end);
+ let endp = this._instance.endpointFactoryManager().create(es, false);
+ if(endp == null)
+ {
+ throw new Ice.EndpointParseException("invalid object adapter endpoint `" + s + "'");
+ }
+ endpoints.push(endp);
+ }
+
+ p = Ice.Promise.resolve(endpoints);
+ }
+
+ return p.then((endpoints) =>
+ {
+ if(this._instance.traceLevels().network >= 1 && endpoints.length > 0)
+ {
+ let s = [];
+ s.push("published endpoints for object adapter `");
+ s.push(_name);
+ s.push("':\n");
+ let first = true;
+ endpoints.forEach(endpoint =>
+ {
+ if(!first)
+ {
+ s.push(":");
+ }
+ s.push(endpoint.toString());
+ first = false;
+ });
+ this._instance.initializationData().logger.trace(this._instance.traceLevels().networkCat, s.toString());
+ }
+ return endpoints;
+ });
+ }
+
filterProperties(unknownProps)
{
//
diff --git a/js/src/Ice/RouterInfo.js b/js/src/Ice/RouterInfo.js
index d5fc2d3509b..9264e9d0c7c 100644
--- a/js/src/Ice/RouterInfo.js
+++ b/js/src/Ice/RouterInfo.js
@@ -31,7 +31,6 @@ class RouterInfo
Debug.assert(this._router !== null);
this._clientEndpoints = null;
- this._serverEndpoints = null;
this._adapter = null;
this._identities = new HashMap(HashMap.compareEquals); // Set<Identity> = Map<Identity, 1>
this._evictedIdentities = [];
@@ -41,7 +40,6 @@ class RouterInfo
destroy()
{
this._clientEndpoints = [];
- this._serverEndpoints = [];
this._adapter = null;
this._identities.clear();
}
@@ -93,14 +91,14 @@ class RouterInfo
getServerEndpoints()
{
- if(this._serverEndpoints !== null) // Lazy initialization.
- {
- return Ice.Promise.resolve(this._serverEndpoints);
- }
- else
- {
- return this._router.getServerProxy().then(proxy => this.setServerEndpoints(proxy));
- }
+ return this._router.getServerProxy().then(serverProxy => {
+ if(serverProxy === null)
+ {
+ throw new Ice.NoEndpointException();
+ }
+ serverProxy = serverProxy.ice_router(null); // The server proxy cannot be routed.
+ return serverProxy._getReference().getEndpoints();
+ });
}
addProxy(proxy)
@@ -178,18 +176,6 @@ class RouterInfo
}
}
- setServerEndpoints(serverProxy)
- {
- if(serverProxy === null)
- {
- throw new Ice.NoEndpointException();
- }
-
- serverProxy = serverProxy.ice_router(null); // The server proxy cannot be routed.
- this._serverEndpoints = serverProxy._getReference().getEndpoints();
- return this._serverEndpoints;
- }
-
addAndEvictProxies(proxy, evictedProxies)
{
//
diff --git a/js/test/Ice/adapterDeactivation/Client.js b/js/test/Ice/adapterDeactivation/Client.js
new file mode 100644
index 00000000000..d6055cb0814
--- /dev/null
+++ b/js/test/Ice/adapterDeactivation/Client.js
@@ -0,0 +1,226 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2018 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.
+//
+// **********************************************************************
+
+(function(module, require, exports)
+{
+ const Ice = require("ice").Ice;
+ const IceSSL = require("ice").IceSSL;
+ const Test = require("Test").Test;
+
+ async function allTests(communicator, out)
+ {
+ class TestError extends Error
+ {
+ constructor(message)
+ {
+ super(message);
+ }
+ }
+
+ function test(value, ex)
+ {
+ if(!value)
+ {
+ let message = "test failed";
+ if(ex)
+ {
+ message += "\n" + ex.toString();
+ }
+ throw new TestError(message);
+ }
+ }
+
+ let defaultProtocol = communicator.getProperties().getPropertyWithDefault("Ice.Default.Protocol", "tcp");
+
+ out.write("testing stringToProxy... ");
+ const ref = "test:default -p 12010";
+ const base = communicator.stringToProxy(ref);
+ test(base != null);
+ out.writeLine("ok");
+
+ out.write("testing checked cast... ");
+ const obj = await Test.TestIntfPrx.checkedCast(base);
+ test(obj !== null);
+ test(obj.equals(base));
+ out.writeLine("ok");
+
+ {
+ out.write("creating/destroying/recreating object adapter... ");
+ communicator.getProperties().setProperty("TransientTestAdapter.AdapterId", "dummy");
+ let adapter = await communicator.createObjectAdapter("TransientTestAdapter");
+ try
+ {
+ await communicator.createObjectAdapterWithEndpoints("TransientTestAdapter");
+ test(false);
+ }
+ catch(ex)
+ {
+ test(ex instanceof Ice.AlreadyRegisteredException);
+ }
+ adapter.destroy();
+ //
+ // Use a different port than the first adapter to avoid an "address already in use" error.
+ //
+ adapter = await communicator.createObjectAdapterWithEndpoints("TransientTestAdapter");
+ adapter.destroy();
+ out.writeLine("ok");
+ }
+
+ out.write("creating/activating/deactivating object adapter in one operation... ");
+ await obj.transient();
+ out.writeLine("ok");
+
+ {
+ out.write("testing connection closure... ");
+ for(i = 0; i < 10; ++i)
+ {
+ let initData = new Ice.InitializationData();
+ initData.properties = communicator.getProperties().clone();
+ let comm = Ice.initialize(initData);
+ comm.stringToProxy("test:default -p 12010").ice_ping().catch(ex => {});
+ comm.destroy();
+ }
+ out.writeLine("ok");
+ }
+
+ out.write("testing object adapter published endpoints... ");
+ {
+ communicator.getProperties().setProperty("PAdapter.PublishedEndpoints", "tcp -h localhost -p 12345 -t 30000");
+ let adapter = await communicator.createObjectAdapter("PAdapter");
+ test(adapter.getPublishedEndpoints().length === 1);
+ let endpt = adapter.getPublishedEndpoints()[0];
+ test(endpt.toString() == "tcp -h localhost -p 12345 -t 30000");
+ let prx =
+ communicator.stringToProxy("dummy:tcp -h localhost -p 12346 -t 20000:tcp -h localhost -p 12347 -t 10000");
+ adapter.setPublishedEndpoints(prx.ice_getEndpoints());
+ test(adapter.getPublishedEndpoints().length === 2);
+ let id = new Ice.Identity();
+ id.name = "dummy";
+ test(Ice.ArrayUtil.equals(adapter.createProxy(id).ice_getEndpoints(), prx.ice_getEndpoints()));
+ test(Ice.ArrayUtil.equals(adapter.getPublishedEndpoints(), prx.ice_getEndpoints()));
+ await adapter.refreshPublishedEndpoints();
+ test(adapter.getPublishedEndpoints().length === 1);
+ test(adapter.getPublishedEndpoints()[0].equals(endpt));
+ communicator.getProperties().setProperty("PAdapter.PublishedEndpoints", "tcp -h localhost -p 12345 -t 20000");
+ await adapter.refreshPublishedEndpoints();
+ test(adapter.getPublishedEndpoints().length === 1);
+ test(adapter.getPublishedEndpoints()[0].toString() == "tcp -h localhost -p 12345 -t 20000");
+ await adapter.destroy();
+ test(adapter.getPublishedEndpoints().length === 0);
+ }
+ out.writeLine("ok");
+
+ test(obj.ice_getConnection() != null)
+ {
+ out.write("testing object adapter with bi-dir connection... ");
+ const adapter = await communicator.createObjectAdapter("");
+ (await obj.ice_getConnection()).setAdapter(adapter);
+ (await obj.ice_getConnection()).setAdapter(null);
+ adapter.deactivate();
+ try
+ {
+ (await obj.ice_getConnection()).setAdapter(adapter);
+ test(false);
+ }
+ catch(ex)
+ {
+ test(ex instanceof Ice.ObjectAdapterDeactivatedException);
+ }
+ out.writeLine("ok");
+ }
+
+ out.write("testing object adapter with router... ");
+ {
+ const routerId = new Ice.Identity();
+ routerId.name = "router";
+ let router = Ice.RouterPrx.uncheckedCast(base.ice_identity(routerId).ice_connectionId("rc"));
+ const adapter = await communicator.createObjectAdapterWithRouter("", router);
+ test(adapter.getPublishedEndpoints().length == 1);
+ test(adapter.getPublishedEndpoints()[0].toString() == "tcp -h localhost -p 23456 -t 30000");
+ await adapter.refreshPublishedEndpoints();
+ test(adapter.getPublishedEndpoints().length == 1);
+ test(adapter.getPublishedEndpoints()[0].toString() == "tcp -h localhost -p 23457 -t 30000");
+ try
+ {
+ adapter.setPublishedEndpoints(router.ice_getEndpoints());
+ test(false);
+ }
+ catch(ex)
+ {
+ // Expected.
+ test(ex instanceof Error);
+ }
+ adapter.destroy();
+
+ try
+ {
+ routerId.name = "test";
+ router = Ice.RouterPrx.uncheckedCast(base.ice_identity(routerId));
+ await communicator.createObjectAdapterWithRouter("", router);
+ test(false);
+ }
+ catch(ex)
+ {
+ // Expected: the "test" object doesn't implement Ice::Router!
+ test(ex instanceof Ice.OperationNotExistException);
+ }
+
+ try
+ {
+ router = Ice.RouterPrx.uncheckedCast(communicator.stringToProxy("router:default -p 12011"));
+ await communicator.createObjectAdapterWithRouter("", router);
+ test(false);
+ }
+ catch(ex)
+ {
+ test(ex instanceof Ice.ConnectFailedException);
+ }
+ }
+ out.writeLine("ok");
+
+ out.write("deactivating object adapter in the server... ");
+ await obj.deactivate();
+ out.writeLine("ok");
+
+ out.write("testing whether server is gone... ");
+ try
+ {
+ await obj.ice_timeout(100).ice_ping(); // Use timeout to speed up testing on Windows
+ throw new RuntimeException();
+ }
+ catch(ex)
+ {
+ test(ex instanceof Ice.LocalException);
+ out.writeLine("ok");
+ }
+ }
+
+ async function run(out, initData)
+ {
+ let communicator;
+ try
+ {
+ communicator = Ice.initialize(initData);
+ await allTests(communicator, out);
+ }
+ finally
+ {
+ if(communicator)
+ {
+ await communicator.destroy();
+ }
+ }
+ }
+
+ exports._test = run;
+ exports._runServer = true;
+}
+(typeof(global) !== "undefined" && typeof(global.process) !== "undefined" ? module : undefined,
+ typeof(global) !== "undefined" && typeof(global.process) !== "undefined" ? require : this.Ice._require,
+ typeof(global) !== "undefined" && typeof(global.process) !== "undefined" ? exports : this));
diff --git a/js/test/Ice/adapterDeactivation/Test.ice b/js/test/Ice/adapterDeactivation/Test.ice
new file mode 100644
index 00000000000..16b6ba44592
--- /dev/null
+++ b/js/test/Ice/adapterDeactivation/Test.ice
@@ -0,0 +1,27 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2018 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.
+//
+// **********************************************************************
+
+#pragma once
+
+module Test
+{
+
+interface TestIntf
+{
+ void transient();
+
+ void deactivate();
+}
+
+local class Cookie
+{
+ ["cpp:const"] string message();
+}
+
+}
diff --git a/python/test/Ice/adapterDeactivation/AllTests.py b/python/test/Ice/adapterDeactivation/AllTests.py
index f794d9faa97..fd59f96b472 100644
--- a/python/test/Ice/adapterDeactivation/AllTests.py
+++ b/python/test/Ice/adapterDeactivation/AllTests.py
@@ -46,20 +46,42 @@ def allTests(communicator):
obj.transient()
print("ok")
- sys.stdout.write("deactivating object adapter in the server... ")
+ sys.stdout.write("testing connection closure... ")
sys.stdout.flush()
- obj.deactivate()
+ for x in range(10):
+ initData = Ice.InitializationData()
+ initData.properties = communicator.getProperties().clone()
+ comm = Ice.initialize(initData)
+ comm.stringToProxy("test:default -p 12010").ice_pingAsync()
+ comm.destroy()
print("ok")
- sys.stdout.write("testing connection closure... ");
- sys.stdout.flush();
- for x in range(10):
- initData = Ice.InitializationData();
- initData.properties = communicator.getProperties().clone();
- comm = Ice.initialize(initData);
- comm.stringToProxy("test:default -p 12010").ice_pingAsync();
- comm.destroy();
- print("ok");
+ sys.stdout.write("testing object adapter published endpoints... ")
+ sys.stdout.flush()
+
+ communicator.getProperties().setProperty("PAdapter.PublishedEndpoints", "tcp -h localhost -p 12345 -t 30000")
+ adapter = communicator.createObjectAdapter("PAdapter")
+ test(len(adapter.getPublishedEndpoints()) == 1)
+ endpt = adapter.getPublishedEndpoints()[0];
+ test(str(endpt) == "tcp -h localhost -p 12345 -t 30000")
+ prx = communicator.stringToProxy("dummy:tcp -h localhost -p 12346 -t 20000:tcp -h localhost -p 12347 -t 10000")
+ adapter.setPublishedEndpoints(prx.ice_getEndpoints())
+ test(len(adapter.getPublishedEndpoints()) == 2)
+ ident = Ice.Identity()
+ ident.name = "dummy";
+ test(adapter.createProxy(ident).ice_getEndpoints() == prx.ice_getEndpoints())
+ test(adapter.getPublishedEndpoints() == prx.ice_getEndpoints())
+ adapter.refreshPublishedEndpoints()
+ test(len(adapter.getPublishedEndpoints()) == 1)
+ test(adapter.getPublishedEndpoints()[0] == endpt)
+ communicator.getProperties().setProperty("PAdapter.PublishedEndpoints", "tcp -h localhost -p 12345 -t 20000")
+ adapter.refreshPublishedEndpoints()
+ test(len(adapter.getPublishedEndpoints()) == 1)
+ test(str(adapter.getPublishedEndpoints()[0]) == "tcp -h localhost -p 12345 -t 20000")
+ adapter.destroy()
+ test(len(adapter.getPublishedEndpoints()) == 0)
+
+ print("ok")
if obj.ice_getConnection():
sys.stdout.write("testing object adapter with bi-dir connection... ")
@@ -75,6 +97,41 @@ def allTests(communicator):
pass
print("ok")
+
+ sys.stdout.write("testing object adapter with router... ")
+ sys.stdout.flush()
+ routerId = Ice.Identity()
+ routerId.name = "router";
+ router = Ice.RouterPrx.uncheckedCast(base.ice_identity(routerId).ice_connectionId("rc"))
+ adapter = communicator.createObjectAdapterWithRouter("", router)
+ test(len(adapter.getPublishedEndpoints()) == 1)
+ test(str(adapter.getPublishedEndpoints()[0]) == "tcp -h localhost -p 23456 -t 30000")
+ adapter.refreshPublishedEndpoints()
+ test(len(adapter.getPublishedEndpoints()) == 1)
+ test(str(adapter.getPublishedEndpoints()[0]) == "tcp -h localhost -p 23457 -t 30000")
+ try:
+ adapter.setPublishedEndpoints(router.ice_getEndpoints())
+ test(False)
+ except Exception, ex:
+ # Expected.
+ pass
+ adapter.destroy()
+
+ try:
+ routerId.name = "test";
+ router = Ice.RouterPrx.uncheckedCast(base.ice_identity(routerId))
+ communicator.createObjectAdapterWithRouter("", router)
+ test(False)
+ except Ice.OperationNotExistException:
+ # Expected: the "test" object doesn't implement Ice::Router!
+ pass
+ print("ok")
+
+ sys.stdout.write("deactivating object adapter in the server... ")
+ sys.stdout.flush()
+ obj.deactivate()
+ print("ok")
+
sys.stdout.write("testing whether server is gone... ")
sys.stdout.flush()
try:
diff --git a/python/test/Ice/adapterDeactivation/TestI.py b/python/test/Ice/adapterDeactivation/TestI.py
index fb3425e3bcc..b7e117844b6 100644
--- a/python/test/Ice/adapterDeactivation/TestI.py
+++ b/python/test/Ice/adapterDeactivation/TestI.py
@@ -25,13 +25,32 @@ class TestI(Test.TestIntf):
current.adapter.deactivate()
time.sleep(0.1)
+
+class RouterI(Ice.Router):
+
+ def __init__(self):
+ self._nextPort = 23456;
+
+ def getClientProxy(self, c):
+ return (None, False)
+
+ def getServerProxy(self, c):
+ port = self._nextPort
+ self._nextPort += 1
+ return c.adapter.getCommunicator().stringToProxy("dummy:tcp -h localhost -p {0} -t 30000".format(port))
+
+ def addProxies(self, proxies, c):
+ return []
+
class CookieI(Test.Cookie):
def message(self):
return 'blahblah'
class ServantLocatorI(Ice.ServantLocator):
+
def __init__(self):
self._deactivated = False
+ self._router = RouterI()
def __del__(self):
test(self._deactivated)
@@ -39,6 +58,9 @@ class ServantLocatorI(Ice.ServantLocator):
def locate(self, current):
test(not self._deactivated)
+ if current.id.name == 'router':
+ return (self._router, None)
+
test(current.id.category == '')
test(current.id.name == 'test')
@@ -47,6 +69,9 @@ class ServantLocatorI(Ice.ServantLocator):
def finished(self, current, servant, cookie):
test(not self._deactivated)
+ if current.id.name == 'router':
+ return
+
test(isinstance(cookie, Test.Cookie))
test(cookie.message() == 'blahblah')
diff --git a/scripts/Util.py b/scripts/Util.py
index 0a7239af471..92523c8e5d4 100644
--- a/scripts/Util.py
+++ b/scripts/Util.py
@@ -1910,8 +1910,7 @@ class LocalProcessController(ProcessController):
def teardown(self, current, success):
if self.traceFile:
if success or current.driver.isInterrupted():
-# os.remove(self.traceFile)
- pass
+ os.remove(self.traceFile)
else:
current.writeln("saved {0}".format(self.traceFile))