diff options
author | Benoit Foucher <benoit@zeroc.com> | 2018-02-16 12:36:36 +0100 |
---|---|---|
committer | Benoit Foucher <benoit@zeroc.com> | 2018-02-16 12:36:36 +0100 |
commit | 1d9509c347547b2d36d6fa3ff667927836d72245 (patch) | |
tree | df6cc4ac9d1e2742ae8d9bf36a4f7927e7f970c1 | |
parent | Allow to create NuGet packages with single platform/configuration (diff) | |
download | ice-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
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)) |