diff options
author | Dwayne Boone <dwayne@zeroc.com> | 2009-03-26 11:34:24 -0230 |
---|---|---|
committer | Dwayne Boone <dwayne@zeroc.com> | 2009-03-26 11:34:24 -0230 |
commit | 0de45cd71fa21bcb20b8a3f754ff20cdf329ff23 (patch) | |
tree | 06c0fd3304362d39a56df0a234e90b3f84687edc | |
parent | More fixes to FixUtil.py (diff) | |
download | ice-0de45cd71fa21bcb20b8a3f754ff20cdf329ff23.tar.bz2 ice-0de45cd71fa21bcb20b8a3f754ff20cdf329ff23.tar.xz ice-0de45cd71fa21bcb20b8a3f754ff20cdf329ff23.zip |
Bug 2511 - add default servants
49 files changed, 1847 insertions, 7 deletions
@@ -32,6 +32,15 @@ General Changes These entries apply to all relevant language mappings unless otherwise noted. +- Added the following operations to the ObjectAdapter API: + + - addDefaultServant + - removeDefaultServant + - findDefaultServant + +These methods allow you to use default servants with Ice. Please refer +to the manual file for more information. + - Using the --depend option with Slice compilers that support it no longer outputs dependency info even if the Slice file itself contains errors. diff --git a/cpp/allTests.py b/cpp/allTests.py index 257a63c9da1..005db4d6f32 100755 --- a/cpp/allTests.py +++ b/cpp/allTests.py @@ -56,6 +56,7 @@ tests = [ ("Ice/interceptor", ["core"]), ("Ice/stringConverter", ["core"]), ("Ice/udp", ["core"]), + ("Ice/defaultServant", ["core"]), ("IceSSL/configuration", ["once", "novalgrind"]), # valgrind doesn't work well with openssl ("IceBox/configuration", ["core", "noipv6"]), ("Freeze/dbmap", ["once"]), diff --git a/cpp/src/Ice/ObjectAdapterI.cpp b/cpp/src/Ice/ObjectAdapterI.cpp index 897ef753181..22832b15ac0 100644 --- a/cpp/src/Ice/ObjectAdapterI.cpp +++ b/cpp/src/Ice/ObjectAdapterI.cpp @@ -407,6 +407,16 @@ Ice::ObjectAdapterI::addFacetWithUUID(const ObjectPtr& object, const string& fac return addFacet(object, ident, facet); } +void +Ice::ObjectAdapterI::addDefaultServant(const ObjectPtr& servant, const string& category) +{ + IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this); + + checkForDeactivation(); + + _servantManager->addDefaultServant(servant, category); +} + ObjectPtr Ice::ObjectAdapterI::remove(const Identity& ident) { @@ -436,6 +446,16 @@ Ice::ObjectAdapterI::removeAllFacets(const Identity& ident) } ObjectPtr +Ice::ObjectAdapterI::removeDefaultServant(const string& category) +{ + IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this); + + checkForDeactivation(); + + return _servantManager->removeDefaultServant(category); +} + +ObjectPtr Ice::ObjectAdapterI::find(const Identity& ident) const { return findFacet(ident, ""); @@ -474,6 +494,16 @@ Ice::ObjectAdapterI::findByProxy(const ObjectPrx& proxy) const return findFacet(ref->getIdentity(), ref->getFacet()); } +ObjectPtr +Ice::ObjectAdapterI::findDefaultServant(const string& category) const +{ + IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this); + + checkForDeactivation(); + + return _servantManager->findDefaultServant(category); +} + void Ice::ObjectAdapterI::addServantLocator(const ServantLocatorPtr& locator, const string& prefix) { diff --git a/cpp/src/Ice/ObjectAdapterI.h b/cpp/src/Ice/ObjectAdapterI.h index 58b2830e13f..5985dac062a 100644 --- a/cpp/src/Ice/ObjectAdapterI.h +++ b/cpp/src/Ice/ObjectAdapterI.h @@ -56,13 +56,17 @@ public: virtual ObjectPrx addFacet(const ObjectPtr&, const Identity&, const std::string&); virtual ObjectPrx addWithUUID(const ObjectPtr&); virtual ObjectPrx addFacetWithUUID(const ObjectPtr&, const std::string&); + virtual void addDefaultServant(const ObjectPtr&, const std::string&); virtual ObjectPtr remove(const Identity&); virtual ObjectPtr removeFacet(const Identity&, const std::string&); virtual FacetMap removeAllFacets(const Identity&); + virtual ObjectPtr removeDefaultServant(const std::string&); virtual ObjectPtr find(const Identity&) const; virtual ObjectPtr findFacet(const Identity&, const std::string&) const; virtual FacetMap findAllFacets(const Identity&) const; virtual ObjectPtr findByProxy(const ObjectPrx&) const; + virtual ObjectPtr findDefaultServant(const std::string&) const; + virtual void addServantLocator(const ServantLocatorPtr&, const std::string&); virtual ServantLocatorPtr findServantLocator(const std::string&) const; diff --git a/cpp/src/Ice/ServantManager.cpp b/cpp/src/Ice/ServantManager.cpp index 743f0bdb6b9..6562896ae0a 100644 --- a/cpp/src/Ice/ServantManager.cpp +++ b/cpp/src/Ice/ServantManager.cpp @@ -58,6 +58,25 @@ IceInternal::ServantManager::addServant(const ObjectPtr& object, const Identity& p->second.insert(pair<const string, ObjectPtr>(facet, object)); } +void +IceInternal::ServantManager::addDefaultServant(const ObjectPtr& object, const string& category) +{ + IceUtil::Mutex::Lock sync(*this); + + assert(_instance); // Must not be called after destruction. + + DefaultServantMap::iterator p = _defaultServantMap.find(category); + if(p != _defaultServantMap.end()) + { + AlreadyRegisteredException ex(__FILE__, __LINE__); + ex.kindOfObject = "default servant"; + ex.id = category; + throw ex; + } + + _defaultServantMap.insert(pair<const string, ObjectPtr>(category, object)); +} + ObjectPtr IceInternal::ServantManager::removeServant(const Identity& ident, const string& facet) { @@ -110,6 +129,35 @@ IceInternal::ServantManager::removeServant(const Identity& ident, const string& return servant; } +ObjectPtr +IceInternal::ServantManager::removeDefaultServant(const string& category) +{ + // + // We return the removed servant to avoid releasing the last reference count + // with *this locked. We don't want to run user code, such as the servant + // destructor, with an internal Ice mutex locked. + // + ObjectPtr servant = 0; + + IceUtil::Mutex::Lock sync(*this); + + assert(_instance); // Must not be called after destruction. + + DefaultServantMap::iterator p = _defaultServantMap.find(category); + if(p == _defaultServantMap.end()) + { + NotRegisteredException ex(__FILE__, __LINE__); + ex.kindOfObject = "default servant"; + ex.id = category; + throw ex; + } + + servant = p->second; + _defaultServantMap.erase(p); + + return servant; +} + FacetMap IceInternal::ServantManager::removeAllFacets(const Identity& ident) { @@ -172,7 +220,23 @@ IceInternal::ServantManager::findServant(const Identity& ident, const string& fa if(p == servantMapMap.end() || (q = p->second.find(facet)) == p->second.end()) { - return 0; + DefaultServantMap::const_iterator p = _defaultServantMap.find(ident.category); + if(p == _defaultServantMap.end()) + { + p = _defaultServantMap.find(""); + if(p == _defaultServantMap.end()) + { + return 0; + } + else + { + return p->second; + } + } + else + { + return p->second; + } } else { @@ -181,6 +245,22 @@ IceInternal::ServantManager::findServant(const Identity& ident, const string& fa } } +ObjectPtr +IceInternal::ServantManager::findDefaultServant(const string& category) const +{ + IceUtil::Mutex::Lock sync(*this); + + DefaultServantMap::const_iterator p = _defaultServantMap.find(category); + if(p == _defaultServantMap.end()) + { + return 0; + } + else + { + return p->second; + } +} + FacetMap IceInternal::ServantManager::findAllFacets(const Identity& ident) const { diff --git a/cpp/src/Ice/ServantManager.h b/cpp/src/Ice/ServantManager.h index a06d050fa71..2cb1134e2e9 100644 --- a/cpp/src/Ice/ServantManager.h +++ b/cpp/src/Ice/ServantManager.h @@ -33,9 +33,12 @@ class ServantManager : public IceUtil::Shared, public IceUtil::Mutex public: void addServant(const Ice::ObjectPtr&, const Ice::Identity&, const std::string&); + void addDefaultServant(const Ice::ObjectPtr&, const std::string&); Ice::ObjectPtr removeServant(const Ice::Identity&, const std::string&); + Ice::ObjectPtr removeDefaultServant(const std::string&); Ice::FacetMap removeAllFacets(const Ice::Identity&); Ice::ObjectPtr findServant(const Ice::Identity&, const std::string&) const; + Ice::ObjectPtr findDefaultServant(const std::string&) const; Ice::FacetMap findAllFacets(const Ice::Identity&) const; bool hasServant(const Ice::Identity&) const; @@ -54,10 +57,13 @@ private: const std::string _adapterName; typedef std::map<Ice::Identity, Ice::FacetMap> ServantMapMap; + typedef std::map<std::string, Ice::ObjectPtr> DefaultServantMap; ServantMapMap _servantMapMap; mutable ServantMapMap::iterator _servantMapMapHint; + DefaultServantMap _defaultServantMap; + std::map<std::string, Ice::ServantLocatorPtr> _locatorMap; mutable std::map<std::string, Ice::ServantLocatorPtr>::iterator _locatorMapHint; }; diff --git a/cpp/test/Ice/Makefile b/cpp/test/Ice/Makefile index f344aa259de..9eb14928c79 100644 --- a/cpp/test/Ice/Makefile +++ b/cpp/test/Ice/Makefile @@ -33,7 +33,8 @@ SUBDIRS = proxy \ interceptor \ stringConverter \ background \ - udp + udp \ + defaultServant $(EVERYTHING):: @for subdir in $(SUBDIRS); \ diff --git a/cpp/test/Ice/Makefile.mak b/cpp/test/Ice/Makefile.mak index 58f3c8aabac..728a96f3873 100644 --- a/cpp/test/Ice/Makefile.mak +++ b/cpp/test/Ice/Makefile.mak @@ -33,7 +33,8 @@ SUBDIRS = proxy \ interceptor \
stringConverter \
background \
- udp
+ udp \
+ defaultServant
$(EVERYTHING)::
@for %i in ( $(SUBDIRS) ) do \
diff --git a/cpp/test/Ice/defaultServant/.depend b/cpp/test/Ice/defaultServant/.depend new file mode 100644 index 00000000000..e2f6cf95eff --- /dev/null +++ b/cpp/test/Ice/defaultServant/.depend @@ -0,0 +1,3 @@ +Test$(OBJEXT): Test.cpp ./Test.h $(includedir)/Ice/LocalObjectF.h $(includedir)/IceUtil/Shared.h $(includedir)/IceUtil/Config.h $(includedir)/Ice/Handle.h $(includedir)/IceUtil/Handle.h $(includedir)/IceUtil/Exception.h $(includedir)/Ice/Config.h $(includedir)/Ice/ProxyHandle.h $(includedir)/Ice/ProxyF.h $(includedir)/Ice/ObjectF.h $(includedir)/Ice/GCCountMap.h $(includedir)/Ice/GCShared.h $(includedir)/Ice/Exception.h $(includedir)/Ice/LocalObject.h $(includedir)/Ice/Proxy.h $(includedir)/IceUtil/Mutex.h $(includedir)/IceUtil/Lock.h $(includedir)/IceUtil/ThreadException.h $(includedir)/IceUtil/Time.h $(includedir)/Ice/ProxyFactoryF.h $(includedir)/Ice/ConnectionIF.h $(includedir)/Ice/RequestHandlerF.h $(includedir)/Ice/EndpointIF.h $(includedir)/Ice/Endpoint.h $(includedir)/Ice/UndefSysMacros.h $(includedir)/Ice/ObjectAdapterF.h $(includedir)/Ice/ReferenceF.h $(includedir)/Ice/OutgoingAsyncF.h $(includedir)/Ice/Current.h $(includedir)/Ice/ConnectionF.h $(includedir)/Ice/Identity.h $(includedir)/Ice/StreamF.h $(includedir)/Ice/CommunicatorF.h $(includedir)/Ice/Object.h $(includedir)/Ice/IncomingAsyncF.h $(includedir)/Ice/Outgoing.h $(includedir)/IceUtil/Monitor.h $(includedir)/IceUtil/Cond.h $(includedir)/Ice/InstanceF.h $(includedir)/Ice/BasicStream.h $(includedir)/Ice/ObjectFactoryF.h $(includedir)/Ice/Buffer.h $(includedir)/Ice/Protocol.h $(includedir)/Ice/StringConverter.h $(includedir)/Ice/Plugin.h $(includedir)/Ice/LoggerF.h $(includedir)/IceUtil/Unicode.h $(includedir)/Ice/Incoming.h $(includedir)/Ice/ServantLocatorF.h $(includedir)/Ice/ServantManagerF.h $(includedir)/Ice/Direct.h $(includedir)/Ice/LocalException.h $(includedir)/Ice/BuiltinSequences.h $(includedir)/Ice/ObjectFactory.h $(includedir)/IceUtil/Iterator.h $(includedir)/IceUtil/ScopedArray.h +Test.cpp: Test.ice +Test.ice: $(SLICE2CPP) $(SLICEPARSERLIB) diff --git a/cpp/test/Ice/defaultServant/.gitignore b/cpp/test/Ice/defaultServant/.gitignore new file mode 100644 index 00000000000..505a9066685 --- /dev/null +++ b/cpp/test/Ice/defaultServant/.gitignore @@ -0,0 +1,6 @@ +// Generated by makegitignore.py + +// IMPORTANT: Do not edit this file -- any edits made here will be lost! +client +Test.cpp +Test.h diff --git a/cpp/test/Ice/defaultServant/AllTests.cpp b/cpp/test/Ice/defaultServant/AllTests.cpp new file mode 100644 index 00000000000..0ff1da9a5a8 --- /dev/null +++ b/cpp/test/Ice/defaultServant/AllTests.cpp @@ -0,0 +1,158 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 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. +// +// ********************************************************************** + +#include <Ice/Ice.h> +#include <TestCommon.h> +#include <TestI.h> + +using namespace std; +using namespace Test; + +void +allTests(const Ice::CommunicatorPtr& communicator) +{ + Ice::ObjectAdapterPtr oa = communicator->createObjectAdapterWithEndpoints("MyOA", "tcp -h localhost"); + oa->activate(); + + Ice::ObjectPtr servant = new MyObjectI(); + + // + // Register default servant with category "foo" + // + oa->addDefaultServant(servant, "foo"); + + // + // Start test + // + cout << "testing single category... " << flush; + + Ice::ObjectPtr r = oa->findDefaultServant("foo"); + test(r == servant); + + r = oa->findDefaultServant("bar"); + test(r == 0); + + Ice::Identity identity; + identity.category = "foo"; + + string names[] = { "foo", "bar", "x", "y", "abcdefg" }; + + for(int idx = 0; idx < 5; ++idx) + { + identity.name = names[idx]; + MyObjectPrx prx = MyObjectPrx::uncheckedCast(oa->createProxy(identity)); + prx->ice_ping(); + test(prx->getName() == names[idx]); + } + + identity.name = "ObjectNotExist"; + MyObjectPrx prx = MyObjectPrx::uncheckedCast(oa->createProxy(identity)); + try + { + prx->ice_ping(); + test(false); + } + catch(const Ice::ObjectNotExistException&) + { + // Expected + } + + try + { + prx->getName(); + test(false); + } + catch(const Ice::ObjectNotExistException&) + { + // Expected + } + + identity.name = "FacetNotExist"; + prx = MyObjectPrx::uncheckedCast(oa->createProxy(identity)); + try + { + prx->ice_ping(); + test(false); + } + catch(const Ice::FacetNotExistException&) + { + // Expected + } + + try + { + prx->getName(); + test(false); + } + catch(const Ice::FacetNotExistException&) + { + // Expected + } + + identity.category = "bar"; + for(int idx = 0; idx < 5; idx++) + { + identity.name = names[idx]; + prx = MyObjectPrx::uncheckedCast(oa->createProxy(identity)); + + try + { + prx->ice_ping(); + test(false); + } + catch(const Ice::ObjectNotExistException&) + { + // Expected + } + + try + { + prx->getName(); + test(false); + } + catch(const Ice::ObjectNotExistException&) + { + // Expected + } + } + + oa->removeDefaultServant("foo"); + identity.category = "foo"; + prx = MyObjectPrx::uncheckedCast(oa->createProxy(identity)); + try + { + prx->ice_ping(); + } + catch(const Ice::ObjectNotExistException&) + { + // Expected + } + + cout << "ok" << endl; + + cout << "testing default category... " << flush; + + oa->addDefaultServant(servant, ""); + + r = oa->findDefaultServant("bar"); + test(r == 0); + + r = oa->findDefaultServant(""); + test(r == servant); + + for(int idx = 0; idx < 5; ++idx) + { + identity.name = names[idx]; + prx = MyObjectPrx::uncheckedCast(oa->createProxy(identity)); + prx->ice_ping(); + test(prx->getName() == names[idx]); + } + + cout << "ok" << endl; +} diff --git a/cpp/test/Ice/defaultServant/Client.cpp b/cpp/test/Ice/defaultServant/Client.cpp new file mode 100644 index 00000000000..0b5ffe9cca6 --- /dev/null +++ b/cpp/test/Ice/defaultServant/Client.cpp @@ -0,0 +1,57 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 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. +// +// ********************************************************************** + +#include <Ice/Ice.h> +#include <TestCommon.h> +#include <Test.h> + +using namespace std; +using namespace Test; + +int +run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator) +{ + void allTests(const Ice::CommunicatorPtr&); + allTests(communicator); + + return EXIT_SUCCESS; +} + +int +main(int argc, char* argv[]) +{ + int status; + Ice::CommunicatorPtr communicator; + + try + { + communicator = Ice::initialize(argc, argv); + status = run(argc, argv, communicator); + } + catch(const Ice::Exception& ex) + { + cerr << ex << endl; + status = EXIT_FAILURE; + } + + if(communicator) + { + try + { + communicator->destroy(); + } + catch(const Ice::Exception& ex) + { + cerr << ex << endl; + status = EXIT_FAILURE; + } + } + + return status; +} diff --git a/cpp/test/Ice/defaultServant/Makefile b/cpp/test/Ice/defaultServant/Makefile new file mode 100644 index 00000000000..928ecf67c5d --- /dev/null +++ b/cpp/test/Ice/defaultServant/Makefile @@ -0,0 +1,33 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2009 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. +# +# ********************************************************************** + +top_srcdir = ../../.. + +CLIENT = client + +TARGETS = $(CLIENT) + +OBJS = Test.o \ + TestI.o \ + Client.o \ + AllTests.o + +SRCS = $(OBJS:.o=.cpp) + +SLICE_SRCS = Test.ice + +include $(top_srcdir)/config/Make.rules + +CPPFLAGS := -I. -I../../include $(CPPFLAGS) + +$(CLIENT): $(OBJS) + rm -f $@ + $(CXX) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) + +include .depend diff --git a/cpp/test/Ice/defaultServant/Makefile.mak b/cpp/test/Ice/defaultServant/Makefile.mak new file mode 100644 index 00000000000..65486d149cc --- /dev/null +++ b/cpp/test/Ice/defaultServant/Makefile.mak @@ -0,0 +1,39 @@ +# **********************************************************************
+#
+# Copyright (c) 2003-2009 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.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+CLIENT = client.exe
+
+TARGETS = $(CLIENT)
+
+COBJS = Test.obj \
+ TestI.obj \
+ Client.obj \
+ AllTests.obj
+
+SRCS = $(COBJS:.obj=.cpp)
+
+!include $(top_srcdir)/config/Make.rules.mak
+
+CPPFLAGS = -I. -I../../include $(CPPFLAGS) -DWIN32_LEAN_AND_MEAN
+
+!if "$(GENERATE_PDB)" == "yes"
+PDBFLAGS = /pdb:$(CLIENT:.exe=.pdb)
+!endif
+
+$(CLIENT): $(COBJS)
+ $(LINK) $(LD_EXEFLAGS) $(PDBFLAGS) $(SETARGV) $(COBJS) $(PREOUT)$@ $(PRELIBS)$(LIBS)
+ @if exist $@.manifest echo ^ ^ ^ Embedding manifest using $(MT) && \
+ $(MT) -nologo -manifest $@.manifest -outputresource:$@;#1 && del /q $@.manifest
+
+clean::
+ del /q Test.cpp Test.h
+
+!include .depend
diff --git a/cpp/test/Ice/defaultServant/Test.ice b/cpp/test/Ice/defaultServant/Test.ice new file mode 100644 index 00000000000..46398613058 --- /dev/null +++ b/cpp/test/Ice/defaultServant/Test.ice @@ -0,0 +1,23 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef TEST_ICE +#define TEST_ICE + +module Test +{ + +interface MyObject +{ + string getName(); +}; + +}; + +#endif diff --git a/cpp/test/Ice/defaultServant/TestI.cpp b/cpp/test/Ice/defaultServant/TestI.cpp new file mode 100644 index 00000000000..50d2f49fc1f --- /dev/null +++ b/cpp/test/Ice/defaultServant/TestI.cpp @@ -0,0 +1,45 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 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. +// +// ********************************************************************** + +#include <Ice/Ice.h> +#include <TestI.h> + +using namespace std; + +void +MyObjectI::ice_ping(const Ice::Current& current) const +{ + string name = current.id.name; + + if(name == "ObjectNotExist") + { + throw Ice::ObjectNotExistException(__FILE__, __LINE__); + } + else if(name == "FacetNotExist") + { + throw Ice::FacetNotExistException(__FILE__, __LINE__); + } +} + +std::string +MyObjectI::getName(const Ice::Current& current) +{ + string name = current.id.name; + + if(name == "ObjectNotExist") + { + throw Ice::ObjectNotExistException(__FILE__, __LINE__); + } + else if(name == "FacetNotExist") + { + throw Ice::FacetNotExistException(__FILE__, __LINE__); + } + + return name; +} diff --git a/cpp/test/Ice/defaultServant/TestI.h b/cpp/test/Ice/defaultServant/TestI.h new file mode 100644 index 00000000000..7731e95be90 --- /dev/null +++ b/cpp/test/Ice/defaultServant/TestI.h @@ -0,0 +1,23 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef TEST_I_H +#define TEST_I_H + +#include <Test.h> + +class MyObjectI : virtual public Test::MyObject +{ +public: + + virtual void ice_ping(const Ice::Current&) const; + virtual std::string getName(const Ice::Current&); +}; + +#endif diff --git a/cpp/test/Ice/defaultServant/run.py b/cpp/test/Ice/defaultServant/run.py new file mode 100755 index 00000000000..e2a84c8cd83 --- /dev/null +++ b/cpp/test/Ice/defaultServant/run.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2008 ZeroC, Inc. All rights reserved. +# +# This copy of Ice-E is licensed to you under the terms described in the +# ICEE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise "can't find toplevel directory!" +sys.path.append(os.path.join(path[0])) +from scripts import * + +client = os.path.join(os.getcwd(), "client") + +TestUtil.simpleTest(client) diff --git a/cs/allTests.py b/cs/allTests.py index df497955cae..40a6c445d36 100755 --- a/cs/allTests.py +++ b/cs/allTests.py @@ -49,6 +49,7 @@ tests = [ ("Ice/seqMapping", ["core"]), ("Ice/background", ["core"]), ("Ice/udp", ["core"]), + ("Ice/defaultServant", ["core"]), ("IceBox/configuration", ["core", "noipv6"]), ("Glacier2/router", ["service"]), ("IceGrid/simple", ["service"]), diff --git a/cs/src/Ice/ObjectAdapterI.cs b/cs/src/Ice/ObjectAdapterI.cs index 8ad2efeb684..b3480b5568b 100644 --- a/cs/src/Ice/ObjectAdapterI.cs +++ b/cs/src/Ice/ObjectAdapterI.cs @@ -400,6 +400,16 @@ namespace Ice return addFacet(obj, ident, facet); } + + public void addDefaultServant(Ice.Object servant, string category) + { + lock(this) + { + checkForDeactivation(); + + _servantManager.addDefaultServant(servant, category); + } + } public Ice.Object remove(Identity ident) { @@ -428,6 +438,16 @@ namespace Ice } } + public Ice.Object removeDefaultServant(string category) + { + lock(this) + { + checkForDeactivation(); + + return _servantManager.removeDefaultServant(category); + } + } + public Ice.Object find(Identity ident) { return findFacet(ident, ""); @@ -466,6 +486,16 @@ namespace Ice } } + public Ice.Object findDefaultServant(string category) + { + lock(this) + { + checkForDeactivation(); + + return _servantManager.findDefaultServant(category); + } + } + public void addServantLocator(ServantLocator locator, string prefix) { lock(this) diff --git a/cs/src/Ice/ServantManager.cs b/cs/src/Ice/ServantManager.cs index 9ae77ccb174..15539b195ea 100644 --- a/cs/src/Ice/ServantManager.cs +++ b/cs/src/Ice/ServantManager.cs @@ -50,6 +50,25 @@ public sealed class ServantManager m[facet] = servant; } } + + public void addDefaultServant(Ice.Object servant, string category) + { + lock(this) + { + Debug.Assert(instance_ != null); // Must not be called after destruction. + Ice.Object obj = null; + _defaultServantMap.TryGetValue(category, out obj); + if(obj != null) + { + Ice.AlreadyRegisteredException ex = new Ice.AlreadyRegisteredException(); + ex.kindOfObject = "default servant"; + ex.id = category; + throw ex; + } + + _defaultServantMap[category] = servant; + } + } public Ice.Object removeServant(Ice.Identity ident, string facet) { @@ -86,6 +105,27 @@ public sealed class ServantManager return obj; } } + + public Ice.Object removeDefaultServant(string category) + { + lock(this) + { + Debug.Assert(instance_ != null); // Must not be called after destruction. + + Ice.Object obj = null; + _defaultServantMap.TryGetValue(category, out obj); + if(obj == null) + { + Ice.NotRegisteredException ex = new Ice.NotRegisteredException(); + ex.kindOfObject = "default servant"; + ex.id = category; + throw ex; + } + + _defaultServantMap.Remove(category); + return obj; + } + } public Dictionary<string, Ice.Object> removeAllFacets(Ice.Identity ident) { @@ -128,7 +168,15 @@ public sealed class ServantManager Dictionary<string, Ice.Object> m; _servantMapMap.TryGetValue(ident, out m); Ice.Object obj = null; - if(m != null) + if(m == null) + { + _defaultServantMap.TryGetValue(ident.category, out obj); + if(obj == null) + { + _defaultServantMap.TryGetValue("", out obj); + } + } + else { m.TryGetValue(facet, out obj); } @@ -137,6 +185,18 @@ public sealed class ServantManager } } + public Ice.Object findDefaultServant(string category) + { + lock(this) + { + Debug.Assert(instance_ != null); // Must not be called after destruction. + + Ice.Object obj = null; + _defaultServantMap.TryGetValue(category, out obj); + return obj; + } + } + public Dictionary<string, Ice.Object> findAllFacets(Ice.Identity ident) { lock(this) @@ -279,6 +339,7 @@ public sealed class ServantManager private readonly string _adapterName; private Dictionary <Ice.Identity, Dictionary<string, Ice.Object>> _servantMapMap = new Dictionary<Ice.Identity, Dictionary<string, Ice.Object>>(); + private Dictionary <string, Ice.Object> _defaultServantMap = new Dictionary<string, Ice.Object>(); private Dictionary<string, Ice.ServantLocator> _locatorMap = new Dictionary<string, Ice.ServantLocator>(); } diff --git a/cs/test/Ice/Makefile b/cs/test/Ice/Makefile index 8d18f8d2e83..fa130830c16 100644 --- a/cs/test/Ice/Makefile +++ b/cs/test/Ice/Makefile @@ -33,7 +33,8 @@ SUBDIRS = application \ dictMapping \ seqMapping \ background \ - udp + udp \ + defaultServant $(EVERYTHING):: @for subdir in $(SUBDIRS); \ diff --git a/cs/test/Ice/Makefile.mak b/cs/test/Ice/Makefile.mak index 3632757730a..e205b1f5f67 100644 --- a/cs/test/Ice/Makefile.mak +++ b/cs/test/Ice/Makefile.mak @@ -33,7 +33,8 @@ SUBDIRS = application \ dictMapping \
seqMapping \
background \
- udp
+ udp \
+ defaultServant
$(EVERYTHING)::
@for %i in ( $(SUBDIRS) ) do \
diff --git a/cs/test/Ice/defaultServant/.depend b/cs/test/Ice/defaultServant/.depend new file mode 100644 index 00000000000..d07cfb3711e --- /dev/null +++ b/cs/test/Ice/defaultServant/.depend @@ -0,0 +1 @@ +Test.cs: ./Test.ice diff --git a/cs/test/Ice/defaultServant/AllTests.cs b/cs/test/Ice/defaultServant/AllTests.cs new file mode 100644 index 00000000000..2cb7727304b --- /dev/null +++ b/cs/test/Ice/defaultServant/AllTests.cs @@ -0,0 +1,167 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 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. +// +// ********************************************************************** + +using System; + +public class AllTests +{ + private static void test(bool b) + { + if(!b) + { + throw new System.Exception(); + } + } + + public static void + allTests(Ice.Communicator communicator) + { + Ice.ObjectAdapter oa = communicator.createObjectAdapterWithEndpoints("MyOA", "tcp -h localhost"); + oa.activate(); + + Ice.Object servant = new MyObjectI(); + + // + // Register default servant with category "foo" + // + oa.addDefaultServant(servant, "foo"); + + // + // Start test + // + Console.Out.Write("testing single category... "); + Console.Out.Flush(); + + Ice.Object r = oa.findDefaultServant("foo"); + test(r == servant); + + r = oa.findDefaultServant("bar"); + test(r == null); + + Ice.Identity identity = new Ice.Identity(); + identity.category = "foo"; + + string[] names = new string[] { "foo", "bar", "x", "y", "abcdefg" }; + + Test.MyObjectPrx prx = null; + for(int idx = 0; idx < 5; ++idx) + { + identity.name = names[idx]; + prx = Test.MyObjectPrxHelper.uncheckedCast(oa.createProxy(identity)); + prx.ice_ping(); + test(prx.getName() == names[idx]); + } + + identity.name = "ObjectNotExist"; + prx = Test.MyObjectPrxHelper.uncheckedCast(oa.createProxy(identity)); + try + { + prx.ice_ping(); + test(false); + } + catch(Ice.ObjectNotExistException) + { + // Expected + } + + try + { + prx.getName(); + test(false); + } + catch(Ice.ObjectNotExistException) + { + // Expected + } + + identity.name = "FacetNotExist"; + prx = Test.MyObjectPrxHelper.uncheckedCast(oa.createProxy(identity)); + try + { + prx.ice_ping(); + test(false); + } + catch(Ice.FacetNotExistException) + { + // Expected + } + + try + { + prx.getName(); + test(false); + } + catch(Ice.FacetNotExistException) + { + // Expected + } + + identity.category = "bar"; + for(int idx = 0; idx < 5; idx++) + { + identity.name = names[idx]; + prx = Test.MyObjectPrxHelper.uncheckedCast(oa.createProxy(identity)); + + try + { + prx.ice_ping(); + test(false); + } + catch(Ice.ObjectNotExistException) + { + // Expected + } + + try + { + prx.getName(); + test(false); + } + catch(Ice.ObjectNotExistException) + { + // Expected + } + } + + oa.removeDefaultServant("foo"); + identity.category = "foo"; + prx = Test.MyObjectPrxHelper.uncheckedCast(oa.createProxy(identity)); + try + { + prx.ice_ping(); + } + catch(Ice.ObjectNotExistException) + { + // Expected + } + + Console.Out.WriteLine("ok"); + + Console.Out.Write("testing default category... "); + Console.Out.Flush(); + + oa.addDefaultServant(servant, ""); + + r = oa.findDefaultServant("bar"); + test(r == null); + + r = oa.findDefaultServant(""); + test(r == servant); + + for(int idx = 0; idx < 5; ++idx) + { + identity.name = names[idx]; + prx = Test.MyObjectPrxHelper.uncheckedCast(oa.createProxy(identity)); + prx.ice_ping(); + test(prx.getName() == names[idx]); + } + + Console.Out.WriteLine("ok"); + } +} diff --git a/cs/test/Ice/defaultServant/Client.cs b/cs/test/Ice/defaultServant/Client.cs new file mode 100644 index 00000000000..da7f9a9b55b --- /dev/null +++ b/cs/test/Ice/defaultServant/Client.cs @@ -0,0 +1,66 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 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. +// +// ********************************************************************** + +using System; +using System.Diagnostics; +using System.Reflection; + +[assembly: CLSCompliant(true)] + +[assembly: AssemblyTitle("IceTest")] +[assembly: AssemblyDescription("Ice test")] +[assembly: AssemblyCompany("ZeroC, Inc.")] + +public class Client +{ + private static int run(string[] args, Ice.Communicator communicator) + { + AllTests.allTests(communicator); + + return 0; + } + + public static void Main(string[] args) + { + int status = 0; + Ice.Communicator communicator = null; + + Debug.Listeners.Add(new ConsoleTraceListener()); + + try + { + communicator = Ice.Util.initialize(ref args); + status = run(args, communicator); + } + catch(System.Exception ex) + { + Console.Error.WriteLine(ex); + status = 1; + } + + if(communicator != null) + { + try + { + communicator.destroy(); + } + catch(Ice.LocalException ex) + { + Console.Error.WriteLine(ex); + status = 1; + } + } + + if(status != 0) + { + System.Environment.Exit(status); + } + } +} + diff --git a/cs/test/Ice/defaultServant/Makefile b/cs/test/Ice/defaultServant/Makefile new file mode 100644 index 00000000000..2b5422bc2d0 --- /dev/null +++ b/cs/test/Ice/defaultServant/Makefile @@ -0,0 +1,32 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2009 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. +# +# ********************************************************************** + +top_srcdir = ../../.. + +TARGETS = client.exe + +C_SRCS = Client.cs \ + AllTests.cs \ + MyObjectI.cs + +SLICE_SRCS = $(SDIR)/Test.ice + +SDIR = . + +GDIR = generated + +include $(top_srcdir)/config/Make.rules.cs + +MCSFLAGS := $(MCSFLAGS) -target:exe + + +client.exe: $(C_SRCS) $(GEN_SRCS) + $(MCS) $(MCSFLAGS) -out:$@ $(call ref,Ice) $(subst /,$(DSEP),$^) + +include .depend diff --git a/cs/test/Ice/defaultServant/Makefile.mak b/cs/test/Ice/defaultServant/Makefile.mak new file mode 100644 index 00000000000..6d47f42df66 --- /dev/null +++ b/cs/test/Ice/defaultServant/Makefile.mak @@ -0,0 +1,32 @@ +# **********************************************************************
+#
+# Copyright (c) 2003-2009 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.
+#
+# **********************************************************************
+
+top_srcdir = ..\..\..
+
+TARGETS = client.exe
+TARGETS_CONFIG = $(TARGETS:.exe=.exe.config)
+
+C_SRCS = Client.cs \
+ AllTests.cs \
+ MyObjectI.cs
+
+GEN_SRCS = $(GDIR)\Test.cs
+
+SDIR = .
+
+GDIR = generated
+
+!include $(top_srcdir)\config\Make.rules.mak.cs
+
+MCSFLAGS = $(MCSFLAGS) -target:exe
+
+client.exe: $(C_SRCS) $(GEN_SRCS)
+ $(MCS) $(MCSFLAGS) -out:$@ -r:$(refdir)\Ice.dll $(C_SRCS) $(GEN_SRCS)
+
+!include .depend
diff --git a/cs/test/Ice/defaultServant/MyObjectI.cs b/cs/test/Ice/defaultServant/MyObjectI.cs new file mode 100644 index 00000000000..15ae0818935 --- /dev/null +++ b/cs/test/Ice/defaultServant/MyObjectI.cs @@ -0,0 +1,44 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 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. +// +// ********************************************************************** + + +public sealed class MyObjectI : Test.MyObjectDisp_ +{ + public override void + ice_ping(Ice.Current current) + { + string name = current.id.name; + + if(name == "ObjectNotExist") + { + throw new Ice.ObjectNotExistException(); + } + else if(name == "FacetNotExist") + { + throw new Ice.FacetNotExistException(); + } + } + + public override string + getName(Ice.Current current) + { + string name = current.id.name; + + if(name == "ObjectNotExist") + { + throw new Ice.ObjectNotExistException(); + } + else if(name == "FacetNotExist") + { + throw new Ice.FacetNotExistException(); + } + + return name; + } +} diff --git a/cs/test/Ice/defaultServant/Test.ice b/cs/test/Ice/defaultServant/Test.ice new file mode 100644 index 00000000000..46398613058 --- /dev/null +++ b/cs/test/Ice/defaultServant/Test.ice @@ -0,0 +1,23 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef TEST_ICE +#define TEST_ICE + +module Test +{ + +interface MyObject +{ + string getName(); +}; + +}; + +#endif diff --git a/cs/test/Ice/defaultServant/run.py b/cs/test/Ice/defaultServant/run.py new file mode 100755 index 00000000000..c37cd7dd820 --- /dev/null +++ b/cs/test/Ice/defaultServant/run.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2009 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. +# +# ********************************************************************** + +import os, sys, getopt + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise "can't find toplevel directory!" +sys.path.append(os.path.join(path[0])) +from scripts import * + +client = os.path.join(os.getcwd(), "client") + +print "starting client...", +clientProc = TestUtil.startClient(client, " --Ice.Warn.Dispatch=0", startReader = False) +print "ok" +clientProc.startReader() + +clientProc.waitTestSuccess() diff --git a/java/allTests.py b/java/allTests.py index 8c8825008fb..5db47603281 100755 --- a/java/allTests.py +++ b/java/allTests.py @@ -57,6 +57,7 @@ tests = [ ("Ice/interceptor", ["core"]), ("Ice/udp", ["core"]), ("Ice/serialize", ["core"]), + ("Ice/defaultServant", ["core"]), ("IceBox/configuration", ["core", "noipv6"]), ("Freeze/dbmap", ["once"]), ("Freeze/complex", ["once"]), diff --git a/java/build.xml b/java/build.xml index ab0474daa5c..b3b46f597ae 100644 --- a/java/build.xml +++ b/java/build.xml @@ -220,6 +220,9 @@ <fileset dir="test/Ice/binding"> <include name="Test.ice" /> </fileset> + <fileset dir="test/Ice/defaultServant"> + <include name="Test.ice" /> + </fileset> <fileset dir="test/Ice/exceptions"> <include name="Test.ice" /> <include name="TestAMD.ice" /> diff --git a/java/src/Ice/ObjectAdapterI.java b/java/src/Ice/ObjectAdapterI.java index 49f78794cc7..ba25b1b1173 100644 --- a/java/src/Ice/ObjectAdapterI.java +++ b/java/src/Ice/ObjectAdapterI.java @@ -423,6 +423,14 @@ public final class ObjectAdapterI implements ObjectAdapter return addFacet(object, ident, facet); } + public synchronized void + addDefaultServant(Ice.Object servant, String category) + { + checkForDeactivation(); + + _servantManager.addDefaultServant(servant, category); + } + public Ice.Object remove(Identity ident) { @@ -447,6 +455,14 @@ public final class ObjectAdapterI implements ObjectAdapter return _servantManager.removeAllFacets(ident); } + public synchronized Ice.Object + removeDefaultServant(String category) + { + checkForDeactivation(); + + return _servantManager.removeDefaultServant(category); + } + public Ice.Object find(Identity ident) { @@ -480,6 +496,14 @@ public final class ObjectAdapterI implements ObjectAdapter return findFacet(ref.getIdentity(), ref.getFacet()); } + public synchronized Ice.Object + findDefaultServant(String category) + { + checkForDeactivation(); + + return _servantManager.findDefaultServant(category); + } + public synchronized void addServantLocator(ServantLocator locator, String prefix) { diff --git a/java/src/IceInternal/ServantManager.java b/java/src/IceInternal/ServantManager.java index 83652e87882..7fe206c0d14 100644 --- a/java/src/IceInternal/ServantManager.java +++ b/java/src/IceInternal/ServantManager.java @@ -45,6 +45,23 @@ public final class ServantManager m.put(facet, servant); } + public synchronized void + addDefaultServant(Ice.Object servant, String category) + { + assert(_instance != null); // Must not be called after destruction + + Ice.Object obj = _defaultServantMap.get(category); + if(obj != null) + { + Ice.AlreadyRegisteredException ex = new Ice.AlreadyRegisteredException(); + ex.kindOfObject = "default servant"; + ex.id = category; + throw ex; + } + + _defaultServantMap.put(category, servant); + } + public synchronized Ice.Object removeServant(Ice.Identity ident, String facet) { @@ -76,6 +93,24 @@ public final class ServantManager return obj; } + public synchronized Ice.Object + removeDefaultServant(String category) + { + assert(_instance != null); // Must not be called after destruction. + + Ice.Object obj = _defaultServantMap.get(category); + if(obj == null) + { + Ice.NotRegisteredException ex = new Ice.NotRegisteredException(); + ex.kindOfObject = "default servant"; + ex.id = category; + throw ex; + } + + _defaultServantMap.remove(category); + return obj; + } + public synchronized java.util.Map<String, Ice.Object> removeAllFacets(Ice.Identity ident) { @@ -113,7 +148,15 @@ public final class ServantManager java.util.Map<String, Ice.Object> m = _servantMapMap.get(ident); Ice.Object obj = null; - if(m != null) + if(m == null) + { + obj = _defaultServantMap.get(ident.category); + if(obj == null) + { + obj = _defaultServantMap.get(""); + } + } + else { obj = m.get(facet); } @@ -121,6 +164,14 @@ public final class ServantManager return obj; } + public synchronized Ice.Object + findDefaultServant(String category) + { + assert(_instance != null); // Must not be called after destruction. + + return _defaultServantMap.get(category); + } + public synchronized java.util.Map<String, Ice.Object> findAllFacets(Ice.Identity ident) { @@ -253,5 +304,6 @@ public final class ServantManager final private String _adapterName; private java.util.Map<Ice.Identity, java.util.Map<String, Ice.Object> > _servantMapMap = new java.util.HashMap<Ice.Identity, java.util.Map<String, Ice.Object> >(); + private java.util.Map<String, Ice.Object> _defaultServantMap = new java.util.HashMap<String, Ice.Object>(); private java.util.Map<String, Ice.ServantLocator> _locatorMap = new java.util.HashMap<String, Ice.ServantLocator>(); } diff --git a/java/test/Ice/defaultServant/AllTests.java b/java/test/Ice/defaultServant/AllTests.java new file mode 100644 index 00000000000..efc0a105d07 --- /dev/null +++ b/java/test/Ice/defaultServant/AllTests.java @@ -0,0 +1,171 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +package test.Ice.defaultServant; +import java.io.PrintWriter; +import test.Ice.defaultServant.Test.MyObjectPrx; +import test.Ice.defaultServant.Test.MyObjectPrxHelper; + +public class AllTests +{ + private static void + test(boolean b) + { + if(!b) + { + throw new RuntimeException(); + } + } + + public static void + allTests(test.Util.Application app, PrintWriter out) + { + Ice.Communicator communicator = app.communicator(); + Ice.ObjectAdapter oa = communicator.createObjectAdapterWithEndpoints("MyOA", "tcp -h localhost"); + oa.activate(); + + Ice.Object servant = (Ice.Object)new MyObjectI(); + + // + // Register default servant with category "foo" + // + oa.addDefaultServant(servant, "foo"); + + // + // Start test + // + out.print("testing single category... "); + out.flush(); + + Ice.Object r = oa.findDefaultServant("foo"); + test(r == servant); + + r = oa.findDefaultServant("bar"); + test(r == null); + + Ice.Identity identity = new Ice.Identity(); + identity.category = "foo"; + + String names[] = { "foo", "bar", "x", "y", "abcdefg" }; + + for(int idx = 0; idx < 5; ++idx) + { + identity.name = names[idx]; + MyObjectPrx prx = MyObjectPrxHelper.uncheckedCast(oa.createProxy(identity)); + prx.ice_ping(); + test(prx.getName() == names[idx]); + } + + identity.name = "ObjectNotExist"; + MyObjectPrx prx = MyObjectPrxHelper.uncheckedCast(oa.createProxy(identity)); + try + { + prx.ice_ping(); + test(false); + } + catch(Ice.ObjectNotExistException ex) + { + // Expected + } + + try + { + prx.getName(); + test(false); + } + catch(Ice.ObjectNotExistException ex) + { + // Expected + } + + identity.name = "FacetNotExist"; + prx = MyObjectPrxHelper.uncheckedCast(oa.createProxy(identity)); + try + { + prx.ice_ping(); + test(false); + } + catch(Ice.FacetNotExistException ex) + { + // Expected + } + + try + { + prx.getName(); + test(false); + } + catch(Ice.FacetNotExistException ex) + { + // Expected + } + + identity.category = "bar"; + for(int idx = 0; idx < 5; idx++) + { + identity.name = names[idx]; + prx = MyObjectPrxHelper.uncheckedCast(oa.createProxy(identity)); + + try + { + prx.ice_ping(); + test(false); + } + catch(Ice.ObjectNotExistException ex) + { + // Expected + } + + try + { + prx.getName(); + test(false); + } + catch(Ice.ObjectNotExistException ex) + { + // Expected + } + } + + oa.removeDefaultServant("foo"); + identity.category = "foo"; + prx = MyObjectPrxHelper.uncheckedCast(oa.createProxy(identity)); + try + { + prx.ice_ping(); + } + catch(Ice.ObjectNotExistException ex) + { + // Expected + } + + out.println("ok"); + + out.print("testing default category... "); + out.flush(); + + oa.addDefaultServant(servant, ""); + + r = oa.findDefaultServant("bar"); + test(r == null); + + r = oa.findDefaultServant(""); + test(r == servant); + + for(int idx = 0; idx < 5; ++idx) + { + identity.name = names[idx]; + prx = MyObjectPrxHelper.uncheckedCast(oa.createProxy(identity)); + prx.ice_ping(); + test(prx.getName() == names[idx]); + } + + out.println("ok"); + } +} diff --git a/java/test/Ice/defaultServant/Client.java b/java/test/Ice/defaultServant/Client.java new file mode 100644 index 00000000000..51ccdabf237 --- /dev/null +++ b/java/test/Ice/defaultServant/Client.java @@ -0,0 +1,29 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +package test.Ice.defaultServant; + +public class Client extends test.Util.Application +{ + public int run(String[] args) + { + AllTests.allTests(this, getWriter()); + + return 0; + } + + public static void main(String[] args) + { + Client c = new Client(); + int status = c.main("Client", args); + + System.gc(); + System.exit(status); + } +} diff --git a/java/test/Ice/defaultServant/MyObjectI.java b/java/test/Ice/defaultServant/MyObjectI.java new file mode 100644 index 00000000000..553db4ad3e2 --- /dev/null +++ b/java/test/Ice/defaultServant/MyObjectI.java @@ -0,0 +1,46 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +package test.Ice.defaultServant; +import test.Ice.defaultServant.Test.*; + +public final class MyObjectI extends _MyObjectDisp +{ + public void + ice_ping(Ice.Current current) + { + String name = current.id.name; + + if(name == "ObjectNotExist") + { + throw new Ice.ObjectNotExistException(); + } + else if(name == "FacetNotExist") + { + throw new Ice.FacetNotExistException(); + } + } + + public String + getName(Ice.Current current) + { + String name = current.id.name; + + if(name == "ObjectNotExist") + { + throw new Ice.ObjectNotExistException(); + } + else if(name == "FacetNotExist") + { + throw new Ice.FacetNotExistException(); + } + + return name; + } +} diff --git a/java/test/Ice/defaultServant/Test.ice b/java/test/Ice/defaultServant/Test.ice new file mode 100644 index 00000000000..6020b9639b6 --- /dev/null +++ b/java/test/Ice/defaultServant/Test.ice @@ -0,0 +1,24 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef TEST_ICE +#define TEST_ICE + +[["java:package:test.Ice.defaultServant"]] +module Test +{ + +interface MyObject +{ + string getName(); +}; + +}; + +#endif diff --git a/java/test/Ice/defaultServant/run.py b/java/test/Ice/defaultServant/run.py new file mode 100755 index 00000000000..5053bafec30 --- /dev/null +++ b/java/test/Ice/defaultServant/run.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2009 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. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise "can't find toplevel directory!" +sys.path.append(os.path.join(path[0])) +from scripts import * + +print "starting client...", +clientProc = TestUtil.startClient("test.Ice.defaultServant.Client", "--Ice.Warn.Dispatch=0",startReader=False) +print "ok" +clientProc.startReader() + +clientProc.waitTestSuccess() diff --git a/py/allTests.py b/py/allTests.py index d7c78b41dd7..459dd846e59 100755 --- a/py/allTests.py +++ b/py/allTests.py @@ -43,6 +43,7 @@ tests = [ ("Ice/timeout", ["core"]), ("Ice/servantLocator", ["core"]), ("Ice/blobject", ["core"]) + ("Ice/defaultServant", ["core"]) ] if __name__ == "__main__": diff --git a/py/modules/IcePy/ObjectAdapter.cpp b/py/modules/IcePy/ObjectAdapter.cpp index efd8b2164b2..8a27457b428 100644 --- a/py/modules/IcePy/ObjectAdapter.cpp +++ b/py/modules/IcePy/ObjectAdapter.cpp @@ -790,6 +790,47 @@ adapterAddFacetWithUUID(ObjectAdapterObject* self, PyObject* args) extern "C" #endif static PyObject* +adapterAddDefaultServant(ObjectAdapterObject* self, PyObject* args) +{ + PyObject* objectType = lookupType("Ice.Object"); + PyObject* servant; + PyObject* categoryObj; + if(!PyArg_ParseTuple(args, STRCAST("O!O"), objectType, &servant, &categoryObj)) + { + return 0; + } + + ServantWrapperPtr wrapper= createServantWrapper(servant); + if(PyErr_Occurred()) + { + return 0; + } + + string category; + if(!getStringArg(categoryObj, "category", category)) + { + return 0; + } + + assert(self->adapter); + try + { + (*self->adapter)->addDefaultServant(wrapper, category); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* adapterRemove(ObjectAdapterObject* self, PyObject* args) { PyObject* identityType = lookupType("Ice.Identity"); @@ -932,6 +973,47 @@ adapterRemoveAllFacets(ObjectAdapterObject* self, PyObject* args) extern "C" #endif static PyObject* +adapterRemoveDefaultServant(ObjectAdapterObject* self, PyObject* args) +{ + PyObject* categoryObj; + if(!PyArg_ParseTuple(args, STRCAST("O"), &categoryObj)) + { + return 0; + } + + string category; + if(!getStringArg(categoryObj, "category", category)) + { + return 0; + } + + assert(self->adapter); + Ice::ObjectPtr obj; + try + { + obj = (*self->adapter)->removeDefaultServant(category); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + if(!obj) + { + Py_INCREF(Py_None); + return Py_None; + } + + ServantWrapperPtr wrapper = ServantWrapperPtr::dynamicCast(obj); + assert(wrapper); + return wrapper->getObject(); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* adapterFind(ObjectAdapterObject* self, PyObject* args) { PyObject* identityType = lookupType("Ice.Identity"); @@ -1112,6 +1194,47 @@ adapterFindByProxy(ObjectAdapterObject* self, PyObject* args) extern "C" #endif static PyObject* +adapterFindDefaultServant(ObjectAdapterObject* self, PyObject* args) +{ + PyObject* categoryObj; + if(!PyArg_ParseTuple(args, STRCAST("O"), &categoryObj)) + { + return 0; + } + + string category; + if(!getStringArg(categoryObj, "category", category)) + { + return 0; + } + + assert(self->adapter); + Ice::ObjectPtr obj; + try + { + obj = (*self->adapter)->findDefaultServant(category); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + if(!obj) + { + Py_INCREF(Py_None); + return Py_None; + } + + ServantWrapperPtr wrapper = ServantWrapperPtr::dynamicCast(obj); + assert(wrapper); + return wrapper->getObject(); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* adapterAddServantLocator(ObjectAdapterObject* self, PyObject* args) { PyObject* locatorType = lookupType("Ice.ServantLocator"); @@ -1369,12 +1492,16 @@ static PyMethodDef AdapterMethods[] = PyDoc_STR(STRCAST("addWithUUID(servant) -> Ice.ObjectPrx")) }, { STRCAST("addFacetWithUUID"), reinterpret_cast<PyCFunction>(adapterAddFacetWithUUID), METH_VARARGS, PyDoc_STR(STRCAST("addFacetWithUUID(servant, facet) -> Ice.ObjectPrx")) }, + { STRCAST("addDefaultServant"), reinterpret_cast<PyCFunction>(adapterAddDefaultServant), METH_VARARGS, + PyDoc_STR(STRCAST("addDefaultServant(servant, category) -> None")) }, { STRCAST("remove"), reinterpret_cast<PyCFunction>(adapterRemove), METH_VARARGS, PyDoc_STR(STRCAST("remove(identity) -> Ice.Object")) }, { STRCAST("removeFacet"), reinterpret_cast<PyCFunction>(adapterRemoveFacet), METH_VARARGS, PyDoc_STR(STRCAST("removeFacet(identity, facet) -> Ice.Object")) }, { STRCAST("removeAllFacets"), reinterpret_cast<PyCFunction>(adapterRemoveAllFacets), METH_VARARGS, PyDoc_STR(STRCAST("removeAllFacets(identity) -> dictionary")) }, + { STRCAST("removeDefaultServant"), reinterpret_cast<PyCFunction>(adapterRemoveDefaultServant), METH_VARARGS, + PyDoc_STR(STRCAST("removeDefaultServant(category) -> Ice.Object")) }, { STRCAST("find"), reinterpret_cast<PyCFunction>(adapterFind), METH_VARARGS, PyDoc_STR(STRCAST("find(identity) -> Ice.Object")) }, { STRCAST("findFacet"), reinterpret_cast<PyCFunction>(adapterFindFacet), METH_VARARGS, @@ -1383,6 +1510,8 @@ static PyMethodDef AdapterMethods[] = PyDoc_STR(STRCAST("findAllFacets(identity) -> dictionary")) }, { STRCAST("findByProxy"), reinterpret_cast<PyCFunction>(adapterFindByProxy), METH_VARARGS, PyDoc_STR(STRCAST("findByProxy(Ice.ObjectPrx) -> Ice.Object")) }, + { STRCAST("findDefaultServant"), reinterpret_cast<PyCFunction>(adapterFindDefaultServant), METH_VARARGS, + PyDoc_STR(STRCAST("findDefaultServant(category) -> Ice.Object")) }, { STRCAST("addServantLocator"), reinterpret_cast<PyCFunction>(adapterAddServantLocator), METH_VARARGS, PyDoc_STR(STRCAST("addServantLocator(Ice.ServantLocator, category) -> None")) }, { STRCAST("findServantLocator"), reinterpret_cast<PyCFunction>(adapterFindServantLocator), METH_VARARGS, diff --git a/py/python/Ice.py b/py/python/Ice.py index 9689dbabc88..3ebee8efd6e 100644 --- a/py/python/Ice.py +++ b/py/python/Ice.py @@ -399,6 +399,9 @@ class ObjectAdapterI(ObjectAdapter): def addFacetWithUUID(self, servant, facet): return self._impl.addFacetWIthUUID(servant, facet) + def addDefaultServant(self, servant, category): + self._impl.addDefaultServant(servant, category) + def remove(self, id): return self._impl.remove(id) @@ -408,6 +411,9 @@ class ObjectAdapterI(ObjectAdapter): def removeAllFacets(self, id): return self._impl.removeAllFacets(id) + def removeDefaultServant(self, category): + return self._impl.removeDefaultServant(category) + def find(self, id): return self._impl.find(id) @@ -420,6 +426,9 @@ class ObjectAdapterI(ObjectAdapter): def findByProxy(self, proxy): return self._impl.findByProxy(proxy) + def findDefaultServant(self, category): + return self._impl.findDefaultServant(category) + def addServantLocator(self, locator, category): self._impl.addServantLocator(locator, category) diff --git a/py/test/Ice/defaultServant/AllTests.py b/py/test/Ice/defaultServant/AllTests.py new file mode 100644 index 00000000000..421e3397e97 --- /dev/null +++ b/py/test/Ice/defaultServant/AllTests.py @@ -0,0 +1,124 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2009 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. +# +# ********************************************************************** + +import Ice, Test, MyObjectI + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +def allTests(communicator): + + oa = communicator.createObjectAdapterWithEndpoints("MyOA", "tcp -h localhost") + oa.activate() + + servant = MyObjectI.MyObjectI() + + # Register default servant with category "foo" + oa.addDefaultServant(servant, "foo") + + # Start test + print "testing single category... ", + + r = oa.findDefaultServant("foo") + test(r == servant) + + r = oa.findDefaultServant("bar") + test(r == None) + + identity = Ice.Identity() + identity.category = "foo" + + names = ( "foo", "bar", "x", "y", "abcdefg" ) + + for idx in range(0, 5): + identity.name = names[idx] + prx = Test.MyObjectPrx.uncheckedCast(oa.createProxy(identity)) + prx.ice_ping() + test(prx.getName() == names[idx]) + + identity.name = "ObjectNotExist" + prx = Test.MyObjectPrx.uncheckedCast(oa.createProxy(identity)) + try: + prx.ice_ping() + test(false) + except Ice.ObjectNotExistException: + # Expected + pass + + try: + prx.getName() + test(false) + except Ice.ObjectNotExistException: + # Expected + pass + + identity.name = "FacetNotExist" + prx = Test.MyObjectPrx.uncheckedCast(oa.createProxy(identity)) + try: + prx.ice_ping() + test(false) + except Ice.FacetNotExistException: + # Expected + pass + + try: + prx.getName() + test(false) + except Ice.FacetNotExistException: + # Expected + pass + + identity.category = "bar" + for idx in range(0, 5): + identity.name = names[idx] + prx = Test.MyObjectPrx.uncheckedCast(oa.createProxy(identity)) + + try: + prx.ice_ping() + test(false) + except Ice.ObjectNotExistException: + # Expected + pass + + try: + prx.getName() + test(false) + except Ice.ObjectNotExistException: + # Expected + pass + + oa.removeDefaultServant("foo") + identity.category = "foo" + prx = Test.MyObjectPrx.uncheckedCast(oa.createProxy(identity)) + try: + prx.ice_ping() + except Ice.ObjectNotExistException: + # Expected + pass + + print "ok" + + print "testing default category... ", + + oa.addDefaultServant(servant, "") + + r = oa.findDefaultServant("bar") + test(r == None) + + r = oa.findDefaultServant("") + test(r == servant) + + for idx in range(0, 5): + identity.name = names[idx] + prx = Test.MyObjectPrx.uncheckedCast(oa.createProxy(identity)) + prx.ice_ping() + test(prx.getName() == names[idx]) + + print "ok" diff --git a/py/test/Ice/defaultServant/Client.py b/py/test/Ice/defaultServant/Client.py new file mode 100755 index 00000000000..b806752c0ea --- /dev/null +++ b/py/test/Ice/defaultServant/Client.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2009 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. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice + +Ice.loadSlice('Test.ice') +import AllTests + +def run(args, communicator): + AllTests.allTests(communicator) + return True + +try: + communicator = Ice.initialize(sys.argv) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/py/test/Ice/defaultServant/MyObjectI.py b/py/test/Ice/defaultServant/MyObjectI.py new file mode 100644 index 00000000000..fcc6adb10b3 --- /dev/null +++ b/py/test/Ice/defaultServant/MyObjectI.py @@ -0,0 +1,29 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2009 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. +# +# ********************************************************************** + +import Ice, Test + +class MyObjectI(Test.MyObject): + def ice_ping(self, current=None): + name = current.id.name + + if name == "ObjectNotExist": + raise Ice.ObjectNotExistException() + elif name == "FacetNotExist": + raise Ice.FacetNotExistException() + + def getName(self, current=None): + name = current.id.name + + if name == "ObjectNotExist": + raise Ice.ObjectNotExistException() + elif name == "FacetNotExist": + raise Ice.FacetNotExistException() + + return name diff --git a/py/test/Ice/defaultServant/Test.ice b/py/test/Ice/defaultServant/Test.ice new file mode 100644 index 00000000000..46398613058 --- /dev/null +++ b/py/test/Ice/defaultServant/Test.ice @@ -0,0 +1,23 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef TEST_ICE +#define TEST_ICE + +module Test +{ + +interface MyObject +{ + string getName(); +}; + +}; + +#endif diff --git a/py/test/Ice/defaultServant/run.py b/py/test/Ice/defaultServant/run.py new file mode 100755 index 00000000000..4bafa789a82 --- /dev/null +++ b/py/test/Ice/defaultServant/run.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2009 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. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise "can't find toplevel directory!" +sys.path.append(os.path.join(path[0])) +from scripts import * + +print "starting client...", +clientProc = TestUtil.startClient("Client.py", startReader = False) +print "ok" +clientProc.startReader() + +clientProc.waitTestSuccess() diff --git a/slice/Ice/ObjectAdapter.ice b/slice/Ice/ObjectAdapter.ice index c1d48a151e2..6dd095851a5 100644 --- a/slice/Ice/ObjectAdapter.ice +++ b/slice/Ice/ObjectAdapter.ice @@ -264,6 +264,25 @@ local interface ObjectAdapter /** * + * Add a default servant to handle requests for specific + * category. Adding a default servant for a category for + * which a default servant locator is already registered + * throws [AlreadyRegisteredException]. + * + * @param servant The default servant. + * + * @param category The category for which the default + * servant is registered. An empty category means it will + * handle all categories. + * + * @see removeDefaultServant + * @see findDefaultServant + * + **/ + void addDefaultServant(Object servant, string category); + + /** + * * Remove a servant (that is, the default facet) from the * object adapter's Active Servant Map. * @@ -323,6 +342,22 @@ local interface ObjectAdapter /** * + * Remove the default servant for a specific category. Attempting + * to remove a default servant for a category that is not + * registered throws [NotRegisteredException]. + * + * @param category The category of the default servant to remove. + * + * @return The default servant. + * + * @see addDefaultServant + * @see findDefaultServant + * + **/ + Object removeDefaultServant(string category); + + /** + * * Look up a servant in this object adapter's Active Servant Map * by the identity of the Ice object it implements. * @@ -474,6 +509,21 @@ local interface ObjectAdapter /** * + * Find the default servant for a specific category. + * + * @param category The category of the default servant to find. + * + * @return The default servant or null if no default servant was + * registered for the category. + * + * @see addDefaultServant + * @see removeDefaultServant + * + **/ + ["cpp:const"] Object findDefaultServant(string category); + + /** + * * Create a proxy for the object with the given identity. If this * object adapter is configured with an adapter id, the return * value is an indirect proxy that refers to the adapter id. If |