summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenoit Foucher <benoit@zeroc.com>2005-04-01 15:42:10 +0000
committerBenoit Foucher <benoit@zeroc.com>2005-04-01 15:42:10 +0000
commitf496752b90c2d5c9099b7dbca383bd30820a6ebd (patch)
treedaba3e307aea127eccb2b1c50fe9353f18f1ca05
parentObjectNotExistException is now retried. (diff)
downloadice-f496752b90c2d5c9099b7dbca383bd30820a6ebd.tar.bz2
ice-f496752b90c2d5c9099b7dbca383bd30820a6ebd.tar.xz
ice-f496752b90c2d5c9099b7dbca383bd30820a6ebd.zip
Copied IcePack code to IceGrid.
-rw-r--r--cpp/slice/IceGrid/Admin.ice951
-rw-r--r--cpp/slice/IceGrid/Exception.ice107
-rw-r--r--cpp/slice/IceGrid/Query.ice84
-rw-r--r--cpp/src/IceGrid/Activator.cpp1259
-rw-r--r--cpp/src/IceGrid/Activator.h89
-rw-r--r--cpp/src/IceGrid/AdapterFactory.cpp110
-rw-r--r--cpp/src/IceGrid/AdapterFactory.h52
-rw-r--r--cpp/src/IceGrid/AdapterI.cpp55
-rw-r--r--cpp/src/IceGrid/AdapterI.h42
-rw-r--r--cpp/src/IceGrid/AdapterRegistryI.cpp144
-rw-r--r--cpp/src/IceGrid/AdapterRegistryI.h48
-rw-r--r--cpp/src/IceGrid/AdminI.cpp1530
-rw-r--r--cpp/src/IceGrid/AdminI.h83
-rw-r--r--cpp/src/IceGrid/ApplicationRegistryI.cpp157
-rw-r--r--cpp/src/IceGrid/ApplicationRegistryI.h52
-rw-r--r--cpp/src/IceGrid/DescriptorParser.cpp821
-rw-r--r--cpp/src/IceGrid/DescriptorParser.h34
-rw-r--r--cpp/src/IceGrid/DescriptorUtil.cpp216
-rw-r--r--cpp/src/IceGrid/DescriptorUtil.h22
-rw-r--r--cpp/src/IceGrid/DescriptorVisitor.cpp176
-rw-r--r--cpp/src/IceGrid/DescriptorVisitor.h147
-rw-r--r--cpp/src/IceGrid/GPL.h303
-rw-r--r--cpp/src/IceGrid/Grammar.y271
-rw-r--r--cpp/src/IceGrid/IceGridNode.cpp598
-rw-r--r--cpp/src/IceGrid/IceGridRegistry.cpp156
-rw-r--r--cpp/src/IceGrid/Internal.ice703
-rw-r--r--cpp/src/IceGrid/LocatorI.cpp336
-rw-r--r--cpp/src/IceGrid/LocatorI.h53
-rw-r--r--cpp/src/IceGrid/LocatorRegistryI.cpp188
-rw-r--r--cpp/src/IceGrid/LocatorRegistryI.h44
-rw-r--r--cpp/src/IceGrid/Makefile164
-rw-r--r--cpp/src/IceGrid/NodeI.cpp92
-rw-r--r--cpp/src/IceGrid/NodeI.h52
-rw-r--r--cpp/src/IceGrid/NodeRegistryI.cpp219
-rw-r--r--cpp/src/IceGrid/NodeRegistryI.h53
-rw-r--r--cpp/src/IceGrid/ObjectRegistryI.cpp228
-rw-r--r--cpp/src/IceGrid/ObjectRegistryI.h55
-rw-r--r--cpp/src/IceGrid/QueryI.cpp45
-rw-r--r--cpp/src/IceGrid/QueryI.h37
-rw-r--r--cpp/src/IceGrid/Registry.cpp326
-rw-r--r--cpp/src/IceGrid/Registry.h35
-rw-r--r--cpp/src/IceGrid/Scanner.l368
-rw-r--r--cpp/src/IceGrid/ServerAdapterI.cpp213
-rw-r--r--cpp/src/IceGrid/ServerAdapterI.h51
-rw-r--r--cpp/src/IceGrid/ServerDeployerI.cpp131
-rw-r--r--cpp/src/IceGrid/ServerDeployerI.h40
-rw-r--r--cpp/src/IceGrid/ServerFactory.cpp384
-rw-r--r--cpp/src/IceGrid/ServerFactory.h72
-rw-r--r--cpp/src/IceGrid/ServerI.cpp807
-rw-r--r--cpp/src/IceGrid/ServerI.h80
-rw-r--r--cpp/src/IceGrid/ServerRegistryI.cpp182
-rw-r--r--cpp/src/IceGrid/ServerRegistryI.h52
-rw-r--r--cpp/src/IceGrid/TraceLevels.cpp50
-rw-r--r--cpp/src/IceGrid/TraceLevels.h58
-rw-r--r--cpp/src/IceGrid/WaitQueue.cpp204
-rw-r--r--cpp/src/IceGrid/WaitQueue.h67
-rwxr-xr-xcpp/src/IceGrid/dummy1.ice3
-rwxr-xr-xcpp/src/IceGrid/dummy2.ice3
-rwxr-xr-xcpp/src/IceGrid/dummy3.ice3
-rwxr-xr-xcpp/src/IceGrid/dummy4.ice3
-rwxr-xr-xcpp/src/IceGrid/dummy5.ice3
-rw-r--r--cpp/src/IceGrid/icegrid.dsp270
-rw-r--r--cpp/src/IceGrid/icegridC.dsp224
-rwxr-xr-xcpp/src/IceGrid/icegridnode.dsp579
-rwxr-xr-xcpp/src/IceGrid/icegridregistry.dsp430
65 files changed, 14406 insertions, 8 deletions
diff --git a/cpp/slice/IceGrid/Admin.ice b/cpp/slice/IceGrid/Admin.ice
new file mode 100644
index 00000000000..c63f3f62fd0
--- /dev/null
+++ b/cpp/slice/IceGrid/Admin.ice
@@ -0,0 +1,951 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 ICE_GRID_ADMIN_ICE
+#define ICE_GRID_ADMIN_ICE
+
+#include <Ice/Identity.ice>
+#include <Ice/BuiltinSequences.ice>
+#include <Ice/SliceChecksumDict.ice>
+#include <IceGrid/Exception.ice>
+
+module IceGrid
+{
+
+/**
+ *
+ * The server activation mode.
+ *
+ **/
+enum ServerActivation
+{
+ /**
+ *
+ * The server is activated on demand if a client requests one of
+ * the server's adapter endpoints and the server is not already
+ * running.
+ *
+ **/
+ OnDemand,
+
+ /**
+ *
+ * The server is activated manually through the administrative
+ * interface.
+ *
+ **/
+ Manual
+};
+
+/**
+ *
+ * An &Ice; object descriptor.
+ *
+ **/
+struct ObjectDescriptor
+{
+ /**
+ *
+ * The object proxy.
+ *
+ **/
+ Object* proxy;
+
+ /**
+ *
+ * The object type.
+ *
+ **/
+ string type;
+
+ /**
+ *
+ * The object adapter id.
+ *
+ **/
+ string adapterId;
+};
+
+/**
+ *
+ * A sequence of object descriptors.
+ *
+ **/
+sequence<ObjectDescriptor> ObjectDescriptorSeq;
+
+/**
+ *
+ * An &Ice; object adapter descriptor.
+ *
+ **/
+struct AdapterDescriptor
+{
+ /**
+ *
+ * The object adapter name.
+ *
+ **/
+ string name;
+
+ /**
+ *
+ * The object adapter id.
+ *
+ **/
+ string id;
+
+ /**
+ *
+ * The object adapter endpoints.
+ *
+ **/
+ string endpoints;
+
+ /**
+ *
+ * Flag to specify if the object adapter will register a process object.
+ *
+ **/
+ bool registerProcess;
+
+ /**
+ *
+ * The object descriptor associated to this object adapter descriptor.
+ *
+ **/
+ ObjectDescriptorSeq objects;
+};
+
+/**
+ *
+ * A sequence of adapter descriptors.
+ *
+ **/
+sequence<AdapterDescriptor> AdapterDescriptorSeq;
+
+/**
+ *
+ * A configuration property descriptor.
+ *
+ **/
+struct PropertyDescriptor
+{
+ /**
+ *
+ * The name of the property.
+ *
+ **/
+ string name;
+
+ /**
+ *
+ * The value of the property.
+ *
+ **/
+ string value;
+};
+
+/**
+ *
+ * A sequence of property descriptors.
+ *
+ **/
+sequence<PropertyDescriptor> PropertyDescriptorSeq;
+
+/**
+ *
+ * A &Freeze; database environment descriptor.
+ *
+ **/
+struct DbEnvDescriptor
+{
+ /**
+ *
+ * The name of the database environment.
+ *
+ **/
+ string name;
+
+ /**
+ *
+ * The home of the database environment (i.e.: the directory where the database file
+ * will be stored).
+ *
+ **/
+ string dbHome;
+
+ /**
+ *
+ * The configuration properties of the database environment.
+ *
+ **/
+ PropertyDescriptorSeq properties;
+};
+
+/**
+ *
+ * A sequence of database environment descriptors.
+ *
+ **/
+sequence<DbEnvDescriptor> DbEnvDescriptorSeq;
+
+/**
+ *
+ * A component descriptor. A component is either an &Ice; server or
+ * an &IceBox; service.
+ *
+ **/
+class ComponentDescriptor
+{
+ /**
+ *
+ * The component nane.
+ *
+ **/
+ string name;
+
+ /**
+ *
+ * The component object adapters.
+ *
+ **/
+ AdapterDescriptorSeq adapters;
+
+ /**
+ *
+ * The component configuration properties.
+ *
+ **/
+ PropertyDescriptorSeq properties;
+
+ /**
+ *
+ * The component database environments.
+ *
+ **/
+ DbEnvDescriptorSeq dbEnvs;
+
+ /**
+ *
+ * Some comments on the component.
+ *
+ **/
+ string comment;
+};
+
+/**
+ *
+ * An &Ice; server descriptor.
+ *
+ **/
+class ServerDescriptor extends ComponentDescriptor
+{
+ /**
+ *
+ * The path of the server executable.
+ *
+ **/
+ string exe;
+
+ /**
+ *
+ * The path to the server working directory.
+ *
+ **/
+ string pwd;
+
+ /**
+ *
+ * The &IceGrid node on which the server is deployed.
+ *
+ **/
+ string node;
+
+ /**
+ *
+ * The name of the application this server belongs to.
+ *
+ **/
+ string application;
+
+ /**
+ *
+ * The command line options to pass to the server executable.
+ *
+ **/
+ Ice::StringSeq options;
+
+ /**
+ *
+ * The server environment variables.
+ *
+ **/
+ Ice::StringSeq envs;
+
+ /**
+ *
+ * The server initial activation mode.
+ *
+ **/
+ ServerActivation activation;
+};
+
+/**
+ *
+ * A sequence of server descriptors.
+ *
+ **/
+sequence<ServerDescriptor> ServerDescriptorSeq;
+
+/**
+ *
+ * A Java &Ice; server descriptor.
+ *
+ **/
+class JavaServerDescriptor extends ServerDescriptor
+{
+ /**
+ *
+ * The name of the Java class containing the main function.
+ *
+ **/
+ string className;
+
+ /**
+ *
+ * The command line options to pass to the JVM.
+ *
+ **/
+ Ice::StringSeq jvmOptions;
+};
+
+/**
+ *
+ * An &IceBox; service descriptor.
+ *
+ **/
+class ServiceDescriptor extends ComponentDescriptor
+{
+ /**
+ *
+ * The entry point of the &IceBox; service.
+ *
+ **/
+ string entry;
+};
+
+/**
+ *
+ * A sequence of service descriptors.
+ *
+ **/
+sequence<ServiceDescriptor> ServiceDescriptorSeq;
+
+/**
+ *
+ * A C++ &IceBox; server descriptor.
+ *
+ **/
+class CppIceBoxDescriptor extends ServerDescriptor
+{
+ /**
+ *
+ * The &IceBox; C++ services.
+ *
+ **/
+ ServiceDescriptorSeq services;
+
+ /**
+ *
+ * The endpoints of the &IceBox; service manager interface.
+ *
+ **/
+ string endpoints;
+};
+
+/**
+ *
+ * A Java &IceBox; server descriptor.
+ *
+ **/
+class JavaIceBoxDescriptor extends JavaServerDescriptor
+{
+ /**
+ *
+ * The &IceBox; Java services.
+ *
+ **/
+ ServiceDescriptorSeq services;
+
+ /**
+ *
+ * The endpoints of the &IceBox; service manager interface.
+ *
+ **/
+ string endpoints;
+};
+
+/**
+ *
+ * An application descriptor.
+ *
+ **/
+class ApplicationDescriptor
+{
+ /**
+ *
+ * The application name.
+ *
+ **/
+ string name;
+
+ /**
+ *
+ * The application servers.
+ *
+ **/
+ ServerDescriptorSeq servers;
+
+ /**
+ *
+ * Some comments on the application.
+ *
+ **/
+ string comment;
+};
+
+/**
+ *
+ * An enumeration representing the state of the server.
+ *
+ **/
+enum ServerState
+{
+ /**
+ *
+ * The server is not running.
+ *
+ **/
+ Inactive,
+
+ /**
+ *
+ * The server is being activated and will change to the active
+ * state if the server fork succeeded or to the Inactive state if
+ * it failed.
+ *
+ **/
+ Activating,
+
+ /**
+ *
+ * The server is running.
+ *
+ **/
+ Active,
+
+ /**
+ *
+ * The server is being deactivated.
+ *
+ **/
+ Deactivating,
+
+ /**
+ *
+ * The server is being destroyed.
+ *
+ **/
+ Destroying,
+
+ /**
+ *
+ * The server is destroyed.
+ *
+ **/
+ Destroyed
+};
+
+/**
+ *
+ * The &IceGrid; administrative interface. <warning><para>Allowing
+ * access to this interface is a security risk! Please see the
+ * &IceGrid; documentation for further information.</para></warning>
+ *
+ **/
+interface Admin
+{
+ /**
+ *
+ * Add an application to &IceGrid;. An application is a set of servers.
+ *
+ * @param descriptor The application descriptor.
+ *
+ * @throws DeploymentException Raised if application deployment failed.
+ *
+ * @see removeApplication
+ *
+ **/
+ void addApplication(ApplicationDescriptor descriptor)
+ throws DeploymentException;
+
+ /**
+ *
+ * Update an application. An application is a set of servers.
+ *
+ * @param descriptor The application descriptor.
+ *
+ * @throws DeploymentException Raised if application deployment failed.
+ *
+ * @see removeApplication
+ *
+ **/
+ void updateApplication(ApplicationDescriptor descriptor)
+ throws DeploymentException;
+
+ /**
+ *
+ * Get all the &IceGrid; applications currently registered.
+ *
+ * @return The application names.
+ *
+ **/
+ nonmutating Ice::StringSeq getAllApplicationNames();
+
+ /**
+ *
+ * Remove an application from &IceGrid;.
+ *
+ * @param name The application name.
+ *
+ * @see addApplication
+ *
+ **/
+ void removeApplication(string name)
+ throws ApplicationNotExistException;
+
+ /**
+ *
+ * Get an application descriptor.
+ *
+ * @param name The application name.
+ *
+ * @throws ApplicationNotExistException Raised if the application doesn't exist.
+ *
+ * @returns The application descriptor.
+ *
+ **/
+ nonmutating ApplicationDescriptor getApplicationDescriptor(string name)
+ throws ApplicationNotExistException;
+
+ /**
+ *
+ * Add a server to an &IceGrid; node.
+ *
+ * @param descriptor The server deployment descriptor.
+ *
+ * @throws DeploymentException Raised if server deployment failed.
+ *
+ * @see removeServer
+ * @see updateServer
+ *
+ **/
+ void addServer(ServerDescriptor server)
+ throws DeploymentException;
+
+ /**
+ *
+ * Update a server.
+ *
+ * @param descriptor The server deployment descriptor.
+ *
+ * @throws DeploymentException Raised if server deployment failed.
+ *
+ * @throws ServerNotExistException Raised if the server doesn't exist.
+ *
+ * @see addServer
+ * @see removeServer
+ *
+ **/
+ void updateServer(ServerDescriptor server)
+ throws ServerNotExistException, DeploymentException;
+
+ /**
+ *
+ * Remove a server from an &IceGrid; node.
+ *
+ * @param name The server name.
+ *
+ * @throws ServerNotExistException Raised if the server doesn't exist.
+ *
+ * @see addServer
+ * @see updateServer
+ *
+ **/
+ void removeServer(string name)
+ throws ServerNotExistException, DeploymentException;
+
+ /**
+ *
+ * Get a server descriptor.
+ *
+ * @param name The server name.
+ *
+ * @throws ServerNotExistException Raised if the server doesn't exist.
+ *
+ * @returns The server descriptor.
+ *
+ **/
+ nonmutating ServerDescriptor getServerDescriptor(string name)
+ throws ServerNotExistException;
+
+ /**
+ *
+ * Get a server's state.
+ *
+ * @param name The name of the server.
+ *
+ * @return The server state.
+ *
+ * @throws ServerNotExistException Raised if the server is not
+ * found.
+ *
+ * @throws NodeUnreachableException Raised if the node could not be
+ * reached.
+ *
+ * @see getServerPid
+ * @see getAllServerNames
+ *
+ **/
+ nonmutating ServerState getServerState(string name)
+ throws ServerNotExistException, NodeUnreachableException;
+
+ /**
+ *
+ * Get a server's system process id. The process id is operating
+ * system dependent.
+ *
+ * @param name The name of the server.
+ *
+ * @return The server process id.
+ *
+ * @throws ServerNotExistException Raised if the server is not
+ * found.
+ *
+ * @throws NodeUnreachableException Raised if the node could not be
+ * reached.
+ *
+ * @see getServerState
+ * @see getAllServerNames
+ *
+ **/
+ nonmutating int getServerPid(string name)
+ throws ServerNotExistException, NodeUnreachableException;
+
+ /**
+ *
+ * Get the server's activation mode.
+ *
+ * @param name The name of the server.
+ *
+ * @return The server activation mode.
+ *
+ * @throws ServerNotExistException Raised if the server is not
+ * found.
+ *
+ * @throws NodeUnreachableException Raised if the node could not be
+ * reached.
+ *
+ * @see getServerState
+ * @see getAllServerNames
+ *
+ **/
+ nonmutating ServerActivation getServerActivation(string name)
+ throws ServerNotExistException, NodeUnreachableException;
+
+ /**
+ *
+ * Set the server's activation mode.
+ *
+ * @param name The name of the server.
+ *
+ * @return The server activation mode.
+ *
+ * @throws ServerNotExistException Raised if the server is not
+ * found.
+ *
+ * @throws NodeUnreachableException Raised if the node could not be
+ * reached.
+ *
+ * @see getServerState
+ * @see getAllServerNames
+ *
+ **/
+ void setServerActivation(string name, ServerActivation mode)
+ throws ServerNotExistException, NodeUnreachableException;
+
+ /**
+ *
+ * Start a server.
+ *
+ * @param name The name of the server.
+ *
+ * @return True if the server was successfully started, false
+ * otherwise.
+ *
+ * @throws ServerNotExistException Raised if the server is not
+ * found.
+ *
+ * @throws NodeUnreachableException Raised if the node could not be
+ * reached.
+ *
+ **/
+ bool startServer(string name)
+ throws ServerNotExistException, NodeUnreachableException;
+
+ /**
+ *
+ * Stop a server.
+ *
+ * @param name The name of the server.
+ *
+ * @throws ServerNotExistException Raised if the server is not
+ * found.
+ *
+ * @throws NodeUnreachableException Raised if the node could not be
+ * reached.
+ *
+ **/
+ void stopServer(string name)
+ throws ServerNotExistException, NodeUnreachableException;
+
+
+ /**
+ *
+ * Send signal to a server.
+ *
+ * @param name The name of the server.
+ *
+ * @param signal The signal, for example SIGTERM or 15.
+ *
+ * @throws ServerNotExistException Raised if the server is not
+ * found.
+ *
+ * @throws NodeUnreachableException Raised if the node could not be
+ * reached.
+ *
+ * @throws BadSignalException Raised if the signal is not recognized
+ * by the target server.
+ *
+ **/
+ void sendSignal(string name, string signal)
+ throws ServerNotExistException, NodeUnreachableException, BadSignalException;
+
+ /**
+ *
+ * Write message on server stdout or stderr
+ *
+ * @param name The name of the server.
+ *
+ * @param message The message.
+ *
+ * @param fd 1 for stdout, 2 for stderr.
+ *
+ * @throws ServerNotExistException Raised if the server is not
+ * found.
+ *
+ * @throws NodeUnreachableException Raised if the node could not be
+ * reached.
+ *
+ **/
+ void writeMessage(string name, string message, int fd)
+ throws ServerNotExistException, NodeUnreachableException;
+
+ /**
+ *
+ * Get all the server names registered with &IceGrid;.
+ *
+ * @return The server names.
+ *
+ * @see getServerState
+ *
+ **/
+ nonmutating Ice::StringSeq getAllServerNames();
+
+ /**
+ *
+ * Get the list of endpoints for an adapter.
+ *
+ * @param id The adapter id.
+ *
+ * @return The stringified adapter endpoints.
+ *
+ * @throws AdapterNotExistException Raised if the adapter is not
+ * found.
+ *
+ **/
+ nonmutating string getAdapterEndpoints(string id)
+ throws AdapterNotExistException, NodeUnreachableException;
+
+ /**
+ *
+ * Get all the adapter ids registered with &IceGrid;.
+ *
+ * @return The adapter ids.
+ *
+ **/
+ nonmutating Ice::StringSeq getAllAdapterIds();
+
+ /**
+ *
+ * Add an object to the object registry. &IceGrid; will get the
+ * object type by calling [ice_id] on the given proxy. The object
+ * must be reachable.
+ *
+ * @param obj The object to be added to the registry.
+ *
+ * @throws ObjectExistsException Raised if the object is already
+ * registered.
+ *
+ **/
+ void addObject(Object* obj)
+ throws ObjectExistsException, DeploymentException;
+
+ /**
+ *
+ * Add an object to the object registry and explicitly specify
+ * its type.
+ *
+ * @param obj The object to be added to the registry.
+ *
+ * @param type The object type.
+ *
+ * @throws ObjectExistsException Raised if the object is already
+ * registered.
+ *
+ **/
+ void addObjectWithType(Object* obj, string type)
+ throws ObjectExistsException;
+
+ /**
+ *
+ * Remove an object from the object registry.
+ *
+ * @param id The identity of the object to be removed from the
+ * registry.
+ *
+ * @throws ObjectNotExistException Raised if the object cannot be
+ * found.
+ *
+ **/
+ void removeObject(Ice::Identity id)
+ throws ObjectNotExistException;
+
+ /**
+ *
+ * Get the object descriptor if the object with the given
+ * identity.
+ *
+ * @param id The identity of the object.
+ *
+ * @return The object descriptor.
+ *
+ * @throws ObjectNotExistExcpetion Raised if the object cannot be
+ * found.
+ *
+ **/
+ nonmutating ObjectDescriptor getObjectDescriptor(Ice::Identity id)
+ throws ObjectNotExistException;
+
+ /**
+ *
+ * Get the descriptors of all registered objects whose stringified
+ * identities match the given expression.
+ *
+ * @param expr The expression to match against the stringified
+ * identities of registered objects. The expression may contain
+ * a trailing wildcard (<literal>*</literal>) character.
+ *
+ * @return All the object descriptors with a stringified identity
+ * matching the given expression.
+ *
+ **/
+ nonmutating ObjectDescriptorSeq getAllObjectDescriptors(string expr);
+
+ /**
+ *
+ * Ping an &IceGrid; node to see if it is active.
+ *
+ * @param name The node name.
+ *
+ * @return true if the node ping succeeded, false otherwise.
+ *
+ **/
+ nonmutating bool pingNode(string name)
+ throws NodeNotExistException;
+
+ /**
+ *
+ * Shutdown an &IceGrid; node.
+ *
+ * @param name The node name.
+ *
+ **/
+ idempotent void shutdownNode(string name)
+ throws NodeNotExistException, NodeUnreachableException;
+
+ /**
+ *
+ * Remove the given node and associated servers from the &IceGrid; registry.
+ *
+ * @param name The node name.
+ *
+ **/
+ idempotent void removeNode(string name)
+ throws NodeNotExistException;
+
+ /**
+ *
+ * Get the hostname of this node.
+ *
+ * @param name The node name.
+ *
+ **/
+ nonmutating string getNodeHostname(string name)
+ throws NodeNotExistException, NodeUnreachableException;
+
+ /**
+ *
+ * Get all the &IceGrid; nodes currently registered.
+ *
+ * @return The node names.
+ *
+ **/
+ nonmutating Ice::StringSeq getAllNodeNames();
+
+ /**
+ *
+ * Shut down the &IceGrid; registry.
+ *
+ **/
+ idempotent void shutdown();
+
+ /**
+ *
+ * Returns the checksums for the IceGrid Slice definitions.
+ *
+ * @return A dictionary mapping Slice type ids to their checksums.
+ *
+ **/
+ nonmutating Ice::SliceChecksumDict getSliceChecksums();
+};
+
+};
+
+#endif
diff --git a/cpp/slice/IceGrid/Exception.ice b/cpp/slice/IceGrid/Exception.ice
new file mode 100644
index 00000000000..8cd7ef4663c
--- /dev/null
+++ b/cpp/slice/IceGrid/Exception.ice
@@ -0,0 +1,107 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 ICE_GRID_EXCEPTION_ICE
+#define ICE_GRID_EXCEPTION_ICE
+
+module IceGrid
+{
+
+/**
+ *
+ * This exception is raised if an adapter does not exist.
+ *
+ **/
+exception AdapterNotExistException
+{
+};
+
+/**
+ *
+ * This exception is raised if a server does not exist.
+ *
+ **/
+exception ServerNotExistException
+{
+};
+
+/**
+ *
+ * This exception is raised if an application does not exist.
+ *
+ **/
+exception ApplicationNotExistException
+{
+};
+
+/**
+ *
+ * This exception is raised if an object already exists.
+ *
+ **/
+exception ObjectExistsException
+{
+};
+
+/**
+ *
+ * This exception is raised if an object does not exist.
+ *
+ **/
+exception ObjectNotExistException
+{
+};
+
+/**
+ *
+ * This exception is raised if a node does not exist.
+ *
+ **/
+exception NodeNotExistException
+{
+};
+
+/**
+ *
+ * A generic exception base for all kinds of deployment error
+ * exception.
+ *
+ **/
+exception DeploymentException
+{
+ /**
+ *
+ * The reason for the failure.
+ *
+ **/
+ string reason;
+};
+
+/**
+ *
+ * This exception is raised if a node could not be reached.
+ *
+ **/
+exception NodeUnreachableException
+{
+};
+
+/**
+ *
+ * This exception is raised if an unknown signal was sent to
+ * to a server.
+ *
+ **/
+exception BadSignalException
+{
+};
+
+};
+
+#endif
diff --git a/cpp/slice/IceGrid/Query.ice b/cpp/slice/IceGrid/Query.ice
new file mode 100644
index 00000000000..c29c6612e22
--- /dev/null
+++ b/cpp/slice/IceGrid/Query.ice
@@ -0,0 +1,84 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 ICE_GRID_QUERY_ICE
+#define ICE_GRID_QUERY_ICE
+
+#include <Ice/Identity.ice>
+#include <Ice/BuiltinSequences.ice>
+
+#include <IceGrid/Exception.ice>
+
+/**
+ *
+ * &IceGrid; is a server activation and deployment tool. &IceGrid;,
+ * simplifies the complex task of deploying applications in a
+ * heterogenous computer network.
+ *
+ **/
+module IceGrid
+{
+
+/**
+ *
+ * The &IceGrid; query interface. This interface is accessible to
+ * &Ice; clients who wish to lookup objects.
+ *
+ **/
+interface Query
+{
+ /**
+ *
+ * Find an object by identity.
+ *
+ * @param id The identity.
+ *
+ * @return The proxy.
+ *
+ * @throws ObjectNotExistException Raised if no objects can be
+ * found.
+ *
+ **/
+ nonmutating Object* findObjectById(Ice::Identity id)
+ throws ObjectNotExistException;
+
+ /**
+ *
+ * Find an object by type.
+ *
+ * @param type The object type.
+ *
+ * @return The proxy.
+ *
+ * @throws ObjectNotExistException Raised if no objects can be
+ * found.
+ *
+ **/
+ nonmutating Object* findObjectByType(string type)
+ throws ObjectNotExistException;
+
+ /**
+ *
+ * Find all the objects with the given type.
+ *
+ * @param type The object type.
+ *
+ * @return The proxies.
+ *
+ * @throws ObjectNotExistException Raised if no objects can be
+ * found.
+ *
+ **/
+ nonmutating Ice::ObjectProxySeq findAllObjectsWithType(string type)
+ throws ObjectNotExistException;
+};
+
+};
+
+#endif
diff --git a/cpp/src/IceGrid/Activator.cpp b/cpp/src/IceGrid/Activator.cpp
new file mode 100644
index 00000000000..b01cbe326b1
--- /dev/null
+++ b/cpp/src/IceGrid/Activator.cpp
@@ -0,0 +1,1259 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 <IceGrid/Activator.h>
+#include <IceGrid/Admin.h>
+#include <IceGrid/Internal.h>
+#include <IceGrid/TraceLevels.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <signal.h>
+#include <fcntl.h>
+
+
+using namespace std;
+using namespace Ice;
+using namespace IceGrid;
+
+namespace IceGrid
+{
+
+class TerminationListenerThread : public IceUtil::Thread
+{
+public:
+
+ TerminationListenerThread(Activator& activator) :
+ _activator(activator)
+ {
+ }
+
+ virtual
+ void run()
+ {
+ _activator.runTerminationListener();
+ }
+
+private:
+
+ Activator& _activator;
+};
+
+}
+
+#define ICE_STRING(X) #X
+
+namespace
+{
+
+#ifndef _WIN32
+//
+// Helper function for async-signal safe error reporting
+//
+void
+reportChildError(int err, int fd, const char* cannot, const char* name)
+{
+ //
+ // Send any errors to the parent process, using the write
+ // end of the pipe.
+ //
+ char msg[500];
+ strcpy(msg, cannot);
+ strcat(msg, " `");
+ strcat(msg, name);
+ strcat(msg, "': ");
+ strcat(msg, strerror(err));
+ write(fd, msg, strlen(msg));
+ close(fd);
+
+ //
+ // _exit instead of exit to avoid interferences with the parent
+ // process.
+ //
+ _exit(EXIT_FAILURE);
+}
+
+#endif
+
+#ifndef _WIN32
+string
+signalToString(int signal)
+{
+ switch(signal)
+ {
+ case SIGHUP:
+ {
+ return ICE_STRING(SIGHUP);
+ }
+ case SIGINT:
+ {
+ return ICE_STRING(SIGINT);
+ }
+ case SIGQUIT:
+ {
+ return ICE_STRING(SIGQUIT);
+ }
+ case SIGILL:
+ {
+ return ICE_STRING(SIGILL);
+ }
+ case SIGTRAP:
+ {
+ return ICE_STRING(SIGTRAP);
+ }
+ case SIGABRT:
+ {
+ return ICE_STRING(SIGABRT);
+ }
+ case SIGBUS:
+ {
+ return ICE_STRING(SIGBUS);
+ }
+ case SIGFPE:
+ {
+ return ICE_STRING(SIGFPE);
+ }
+ case SIGKILL:
+ {
+ return ICE_STRING(SIGKILL);
+ }
+ case SIGUSR1:
+ {
+ return ICE_STRING(SIGUSR1);
+ }
+ case SIGSEGV:
+ {
+ return ICE_STRING(SIGSEGV);
+ }
+ case SIGPIPE:
+ {
+ return ICE_STRING(SIGPIPE);
+ }
+ case SIGALRM:
+ {
+ return ICE_STRING(SIGALRM);
+ }
+ case SIGTERM:
+ {
+ return ICE_STRING(SIGTERM);
+ }
+ default:
+ {
+ ostringstream os;
+ os << "signal " << signal;
+ return os.str();
+ }
+ }
+#endif
+}
+
+int
+stringToSignal(const string& str)
+{
+#ifdef _WIN32
+ throw BadSignalException();
+#else
+
+ if(str == ICE_STRING(SIGHUP))
+ {
+ return SIGHUP;
+ }
+ else if(str == ICE_STRING(SIGINT))
+ {
+ return SIGINT;
+ }
+ else if(str == ICE_STRING(SIGQUIT))
+ {
+ return SIGQUIT;
+ }
+ else if(str == ICE_STRING(SIGILL))
+ {
+ return SIGILL;
+ }
+ else if(str == ICE_STRING(SIGTRAP))
+ {
+ return SIGTRAP;
+ }
+ else if(str == ICE_STRING(SIGABRT))
+ {
+ return SIGABRT;
+ }
+ else if(str == ICE_STRING(SIGBUS))
+ {
+ return SIGBUS;
+ }
+ else if(str == ICE_STRING(SIGFPE))
+ {
+ return SIGFPE;
+ }
+ else if(str == ICE_STRING(SIGKILL))
+ {
+ return SIGKILL;
+ }
+ else if(str == ICE_STRING(SIGUSR1))
+ {
+ return SIGUSR1;
+ }
+ else if(str == ICE_STRING(SIGSEGV))
+ {
+ return SIGSEGV;
+ }
+ else if(str == ICE_STRING(SIGUSR2))
+ {
+ return SIGUSR2;
+ }
+ else if(str == ICE_STRING(SIGPIPE))
+ {
+ return SIGPIPE;
+ }
+ else if(str == ICE_STRING(SIGALRM))
+ {
+ return SIGALRM;
+ }
+ else if(str == ICE_STRING(SIGTERM))
+ {
+ return SIGTERM;
+ }
+ else
+ {
+ if(str != "")
+ {
+ char* end;
+ long int signal = strtol(str.c_str(), &end, 10);
+ if(*end == '\0' && signal > 0 && signal < 64)
+ {
+ return static_cast<int>(signal);
+ }
+ }
+ throw BadSignalException();
+ }
+}
+#endif
+
+}
+
+Activator::Activator(const TraceLevelsPtr& traceLevels, const PropertiesPtr& properties) :
+ _traceLevels(traceLevels),
+ _properties(properties),
+ _deactivating(false)
+{
+#ifdef _WIN32
+ _hIntr = CreateEvent(
+ NULL, // Security attributes
+ TRUE, // Manual reset
+ FALSE, // Initial state is nonsignaled
+ NULL // Unnamed
+ );
+
+ if(_hIntr == NULL)
+ {
+ SyscallException ex(__FILE__, __LINE__);
+ ex.error = getSystemErrno();
+ throw ex;
+ }
+#else
+ int fds[2];
+ if(pipe(fds) != 0)
+ {
+ SyscallException ex(__FILE__, __LINE__);
+ ex.error = getSystemErrno();
+ throw ex;
+ }
+ _fdIntrRead = fds[0];
+ _fdIntrWrite = fds[1];
+ int flags = fcntl(_fdIntrRead, F_GETFL);
+ flags |= O_NONBLOCK;
+ fcntl(_fdIntrRead, F_SETFL, flags);
+#endif
+
+ _outputDir = _properties->getProperty("IceGrid.Node.Output");
+ _redirectErrToOut = (_properties->getPropertyAsInt("IceGrid.Node.RedirectErrToOut") > 0);
+
+ //
+ // Parse the properties override property.
+ //
+ string props = _properties->getProperty("IceGrid.Node.PropertiesOverride");
+ if(!props.empty())
+ {
+ string::size_type end = 0;
+ while(end != string::npos)
+ {
+ const string delim = " \t\r\n";
+
+ string::size_type beg = props.find_first_not_of(delim, end);
+ if(beg == string::npos)
+ {
+ break;
+ }
+
+ end = props.find_first_of(delim, beg);
+ string arg;
+ if(end == string::npos)
+ {
+ arg = props.substr(beg);
+ }
+ else
+ {
+ arg = props.substr(beg, end - beg);
+ }
+ if(arg.find("--") != 0)
+ {
+ arg = "--" + arg;
+ }
+ _propertiesOverride.push_back(arg);
+ }
+ }
+}
+
+Activator::~Activator()
+{
+ assert(!_thread);
+
+#ifdef _WIN32
+ if(_hIntr != NULL)
+ {
+ CloseHandle(_hIntr);
+ }
+#else
+ close(_fdIntrRead);
+ close(_fdIntrWrite);
+#endif
+}
+
+bool
+Activator::activate(const string& name,
+ const string& exePath,
+ const string& pwdPath,
+ const Ice::StringSeq& options,
+ const Ice::StringSeq& envs,
+ const ServerPrx& server)
+{
+ IceUtil::Monitor< IceUtil::Mutex>::Lock sync(*this);
+
+ if(_deactivating)
+ {
+ return false;
+ }
+
+ string path = exePath;
+ if(path.empty())
+ {
+ return false;
+ }
+
+ string pwd = pwdPath;
+
+#ifdef _WIN32
+ //
+ // Get the absolute pathname of the executable.
+ //
+ char absbuf[_MAX_PATH];
+ char* filePart;
+ if(SearchPath(NULL, path.c_str(), ".exe", _MAX_PATH, absbuf, &filePart) == 0)
+ {
+ Error out(_traceLevels->logger);
+ out << "cannot convert `" << path << "' into an absolute path";
+ return false;
+ }
+ path = absbuf;
+
+ //
+ // Get the absolute pathname of the working directory.
+ //
+ if(!pwd.empty())
+ {
+ if(_fullpath(absbuf, pwd.c_str(), _MAX_PATH) == NULL)
+ {
+ Error out(_traceLevels->logger);
+ out << "cannot convert `" << pwd << "' into an absolute path";
+ return false;
+ }
+ pwd = absbuf;
+ }
+#else
+ //
+ // Normalize the pathname a bit.
+ //
+ {
+ string::size_type pos;
+ while((pos = path.find("//")) != string::npos)
+ {
+ path.erase(pos, 1);
+ }
+ while((pos = path.find("/./")) != string::npos)
+ {
+ path.erase(pos, 2);
+ }
+ }
+
+ //
+ // Normalize the path to the working directory.
+ //
+ if(!pwd.empty())
+ {
+ string::size_type pos;
+ while((pos = pwd.find("//")) != string::npos)
+ {
+ pwd.erase(pos, 1);
+ }
+ while((pos = pwd.find("/./")) != string::npos)
+ {
+ pwd.erase(pos, 2);
+ }
+ }
+#endif
+
+ //
+ // Setup arguments.
+ //
+ StringSeq args;
+ args.push_back(path);
+ args.insert(args.end(), options.begin(), options.end());
+ args.insert(args.end(), _propertiesOverride.begin(), _propertiesOverride.end());
+ args.push_back("--Ice.Default.Locator=" + _properties->getProperty("Ice.Default.Locator"));
+ args.push_back("--Ice.ServerId=" + name);
+
+ if(_outputDir.size() > 0)
+ {
+ string outFile = _outputDir + "/" + name + ".out";
+ string errFile = _redirectErrToOut ? outFile : _outputDir + "/" + name + ".err";
+ args.push_back("--Ice.StdOut=" + outFile);
+ args.push_back("--Ice.StdErr=" + errFile);
+ }
+
+
+ if(_traceLevels->activator > 1)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->activatorCat);
+ out << "activating server `" << name << "'";
+ if(_traceLevels->activator > 2)
+ {
+ out << "\n";
+ out << "path = " << path << "\n";
+ out << "pwd = " << pwd << "\n";
+ out << "args = ";
+
+ StringSeq::const_iterator p = args.begin();
+ ++p;
+ for(StringSeq::const_iterator q = p; q != args.end(); ++q)
+ {
+ out << " " << *q;
+ }
+ }
+ }
+
+ //
+ // Activate and create.
+ //
+#ifdef _WIN32
+ //
+ // Compose command line.
+ //
+ string cmd;
+ StringSeq::const_iterator p;
+ for(p = args.begin(); p != args.end(); ++p)
+ {
+ if(p != args.begin())
+ {
+ cmd.push_back(' ');
+ }
+ //
+ // Enclose arguments containing spaces in double quotes.
+ //
+ if((*p).find(' ') != string::npos)
+ {
+ cmd.push_back('"');
+ cmd.append(*p);
+ cmd.push_back('"');
+ }
+ else
+ {
+ cmd.append(*p);
+ }
+ }
+
+ const char* dir;
+ if(!pwd.empty())
+ {
+ dir = pwd.c_str();
+ }
+ else
+ {
+ dir = NULL;
+ }
+
+ //
+ // Make a copy of the command line.
+ //
+ char* cmdbuf = strdup(cmd.c_str());
+
+ //
+ // Create the environment block for the child process. We start with the environment
+ // of this process, and then merge environment variables from the server description.
+ //
+ const char* env = NULL;
+ string envbuf;
+ if(!envs.empty())
+ {
+ map<string, string> envMap;
+ LPVOID parentEnv = GetEnvironmentStrings();
+ const char* var = reinterpret_cast<const char*>(parentEnv);
+ if(*var == '=')
+ {
+ //
+ // The environment block may start with some information about the
+ // current drive and working directory. This is indicated by a leading
+ // '=' character, so we skip to the first '\0' byte.
+ //
+ while(*var)
+ var++;
+ var++;
+ }
+ while(*var)
+ {
+ string s(var);
+ string::size_type pos = s.find('=');
+ if(pos != string::npos)
+ {
+ envMap.insert(map<string, string>::value_type(s.substr(0, pos), s.substr(pos + 1)));
+ }
+ var += s.size();
+ var++; // Skip the '\0' byte
+ }
+ FreeEnvironmentStrings(static_cast<char*>(parentEnv));
+ for(p = envs.begin(); p != envs.end(); ++p)
+ {
+ string s = *p;
+ string::size_type pos = s.find('=');
+ if(pos != string::npos)
+ {
+ envMap.insert(map<string, string>::value_type(s.substr(0, pos), s.substr(pos + 1)));
+ }
+ }
+ for(map<string, string>::const_iterator q = envMap.begin(); q != envMap.end(); ++q)
+ {
+ envbuf.append(q->first);
+ envbuf.push_back('=');
+ envbuf.append(q->second);
+ envbuf.push_back('\0');
+ }
+ envbuf.push_back('\0');
+ env = envbuf.c_str();
+ }
+
+ Process process;
+
+ STARTUPINFO si;
+ ZeroMemory(&si, sizeof(si));
+ si.cb = sizeof(si);
+
+ PROCESS_INFORMATION pi;
+ ZeroMemory(&pi, sizeof(pi));
+
+ BOOL b = CreateProcess(
+ NULL, // Executable
+ cmdbuf, // Command line
+ NULL, // Process attributes
+ NULL, // Thread attributes
+ FALSE, // Do NOT inherit handles
+ CREATE_NEW_PROCESS_GROUP, // Process creation flags
+ (LPVOID)env, // Process environment
+ dir, // Current directory
+ &si, // Startup info
+ &pi // Process info
+ );
+
+ free(cmdbuf);
+
+ if(!b)
+ {
+ SyscallException ex(__FILE__, __LINE__);
+ ex.error = getSystemErrno();
+ throw ex;
+ }
+
+ //
+ // Caller is responsible for closing handles in PROCESS_INFORMATION. We don't need to
+ // keep the thread handle, so we close it now. The process handle will be closed later.
+ //
+ CloseHandle(pi.hThread);
+
+
+ process.pid = pi.dwProcessId;
+ process.hnd = pi.hProcess;
+ process.server = server;
+ _processes.insert(make_pair(name, process));
+
+ setInterrupt();
+
+ if(_traceLevels->activator > 0)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->activatorCat);
+ out << "activated server `" << name << "' (pid = " << pi.dwProcessId << ")";
+ }
+#else
+ int fds[2];
+ if(pipe(fds) != 0)
+ {
+ SyscallException ex(__FILE__, __LINE__);
+ ex.error = getSystemErrno();
+ throw ex;
+ }
+
+ //
+ // Convert to standard argc/argv.
+ //
+ int argc = static_cast<int>(args.size());
+ char** argv = static_cast<char**>(malloc((argc + 1) * sizeof(char*)));
+ int i = 0;
+ for(StringSeq::const_iterator p = args.begin(); p != args.end(); ++p, ++i)
+ {
+ assert(i < argc);
+ argv[i] = strdup(p->c_str());
+ }
+ assert(i == argc);
+ argv[argc] = 0;
+
+ int envCount = static_cast<int>(envs.size());
+ char** envArray = new char*[envCount];
+ i = 0;
+ for(StringSeq::const_iterator q = envs.begin(); q != envs.end(); ++q)
+ {
+ envArray[i++] = strdup(q->c_str());
+ }
+
+ //
+ // Current directory
+ //
+ const char* pwdCStr = pwd.c_str();
+
+
+ pid_t pid = fork();
+ if(pid == -1)
+ {
+ SyscallException ex(__FILE__, __LINE__);
+ ex.error = getSystemErrno();
+ throw ex;
+ }
+
+ if(pid == 0) // Child process.
+ {
+ //
+ // Until exec, we can only use async-signal safe functions
+ //
+
+#ifdef __linux
+ //
+ // Create a process group for this child, to be able to send
+ // a signal to all the thread-processes with killpg
+ //
+ setpgrp();
+#endif
+
+ //
+ // Close all file descriptors, except for standard input,
+ // standard output, standard error, and the write side
+ // of the newly created pipe.
+ //
+ int maxFd = static_cast<int>(sysconf(_SC_OPEN_MAX));
+ for(int fd = 3; fd < maxFd; ++fd)
+ {
+ if(fd != fds[1])
+ {
+ close(fd);
+ }
+ }
+
+ for(i = 0; i < envCount; i++)
+ {
+ if(putenv(envArray[i]) != 0)
+ {
+ reportChildError(errno, fds[1], "cannot set environment variable", envArray[i]);
+ }
+ }
+ //
+ // Each env is leaked on purpose ... see man putenv().
+ //
+ delete[] envArray;
+
+ //
+ // Change working directory.
+ //
+ if(strlen(pwdCStr) != 0)
+ {
+ if(chdir(pwdCStr) == -1)
+ {
+ reportChildError(errno, fds[1], "cannot change working directory to", pwdCStr);
+ }
+ }
+
+ if(execvp(argv[0], argv) == -1)
+ {
+ reportChildError(errno, fds[1], "cannot execute", argv[0]);
+ }
+ }
+ else // Parent process.
+ {
+ close(fds[1]);
+
+ for(i = 0; argv[i]; i++)
+ {
+ free(argv[i]);
+ }
+ free(argv);
+
+ for(i = 0; i < envCount; ++i)
+ {
+ free(envArray[i]);
+ }
+ delete[] envArray;
+
+ Process process;
+ process.pid = pid;
+ process.pipeFd = fds[0];
+ process.server = server;
+ _processes.insert(make_pair(name, process));
+
+ int flags = fcntl(process.pipeFd, F_GETFL);
+ flags |= O_NONBLOCK;
+ fcntl(process.pipeFd, F_SETFL, flags);
+
+ setInterrupt();
+
+ if(_traceLevels->activator > 0)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->activatorCat);
+ out << "activated server `" << name << "' (pid = " << pid << ")";
+ }
+ }
+#endif
+
+ return true;
+}
+
+void
+Activator::deactivate(const string& name, const Ice::ProcessPrx& process)
+{
+#ifdef _WIN32
+ Ice::Int pid = getServerPid(name);
+ if(pid == 0)
+ {
+ //
+ // Server is already deactivated.
+ //
+ return;
+ }
+#endif
+
+ //
+ // Try to shut down the server gracefully using the process proxy.
+ //
+ if(process)
+ {
+ if(_traceLevels->activator > 1)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->activatorCat);
+ out << "deactivating `" << name << "' using process proxy";
+ }
+ try
+ {
+ process->shutdown();
+ return;
+ }
+ catch(const Ice::LocalException& ex)
+ {
+ Ice::Warning out(_traceLevels->logger);
+ out << "exception occurred while deactivating `" << name << "' using process proxy:\n" << ex;
+ }
+ }
+
+ if(_traceLevels->activator > 1)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->activatorCat);
+ out << "no process proxy, deactivating `" << name << "' using signal";
+ }
+
+#ifdef _WIN32
+ //
+ // Generate a Ctrl+Break event on the child.
+ //
+ if(GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, pid))
+ {
+ if(_traceLevels->activator > 1)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->activatorCat);
+ out << "sent Ctrl+Break to server `" << name << "' (pid = " << pid << ")";
+ }
+ }
+ else
+ {
+ SyscallException ex(__FILE__, __LINE__);
+ ex.error = getSystemErrno();
+ throw ex;
+ }
+#else
+ //
+ // Send a SIGTERM to the process.
+ //
+ sendSignal(name, SIGTERM);
+
+#endif
+}
+
+void
+Activator::kill(const string& name)
+{
+#ifdef _WIN32
+ Ice::Int pid = getServerPid(name);
+ if(pid == 0)
+ {
+ //
+ // Server is already deactivated.
+ //
+ return;
+ }
+
+ HANDLE hnd = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
+ if(hnd == NULL)
+ {
+ SyscallException ex(__FILE__, __LINE__);
+ ex.error = getSystemErrno();
+ throw ex;
+ }
+
+ BOOL b = TerminateProcess(hnd, 1);
+
+ CloseHandle(hnd);
+
+ if(!b)
+ {
+ SyscallException ex(__FILE__, __LINE__);
+ ex.error = getSystemErrno();
+ throw ex;
+ }
+
+ if(_traceLevels->activator > 1)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->activatorCat);
+ out << "terminating server `" << name << "' (pid = " << pid << ")";
+ }
+
+#else
+ sendSignal(name, SIGKILL);
+#endif
+}
+
+
+void
+Activator::sendSignal(const string& name, const string& signal)
+{
+ sendSignal(name, stringToSignal(signal));
+}
+void
+Activator::sendSignal(const string& name, int signal)
+{
+#ifdef _WIN32
+ //
+ // TODO: Win32 implementation?
+ //
+ throw BadSignalException();
+
+#else
+ Ice::Int pid = getServerPid(name);
+ if(pid == 0)
+ {
+ //
+ // Server is already deactivated.
+ //
+ return;
+ }
+
+#ifdef __linux
+ // Use process groups on Linux instead of processes
+ int ret = ::killpg(static_cast<pid_t>(pid), signal);
+#else
+ int ret = ::kill(static_cast<pid_t>(pid), signal);
+#endif
+ if(ret != 0 && getSystemErrno() != ESRCH)
+ {
+ SyscallException ex(__FILE__, __LINE__);
+ ex.error = getSystemErrno();
+ throw ex;
+ }
+
+ if(_traceLevels->activator > 1)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->activatorCat);
+ out << "sent " << signalToString(signal) << " to server `" << name << "' (pid = " << pid << ")";
+ }
+#endif
+}
+
+Ice::Int
+Activator::getServerPid(const string& name)
+{
+ IceUtil::Monitor< IceUtil::Mutex>::Lock sync(*this);
+
+ map<string, Process>::const_iterator p = _processes.find(name);
+ if(p == _processes.end())
+ {
+ return 0;
+ }
+
+ return static_cast<Ice::Int>(p->second.pid);
+}
+
+void
+Activator::start()
+{
+ //
+ // Create and start the termination listener thread.
+ //
+ _thread = new TerminationListenerThread(*this);
+ _thread->start();
+}
+
+void
+Activator::waitForShutdown()
+{
+ IceUtil::Monitor< IceUtil::Mutex>::Lock sync(*this);
+ while(!_deactivating)
+ {
+ wait();
+ }
+}
+
+void
+Activator::shutdown()
+{
+ IceUtil::Monitor< IceUtil::Mutex>::Lock sync(*this);
+ //
+ // Deactivation has been initiated. Set _deactivating to true to
+ // prevent activation of new processes. This will also cause the
+ // termination listener thread to stop when there are no more
+ // active processes.
+ //
+ _deactivating = true;
+ setInterrupt();
+ notifyAll();
+}
+
+void
+Activator::destroy()
+{
+ {
+ IceUtil::Monitor< IceUtil::Mutex>::Lock sync(*this);
+ assert(_deactivating);
+ }
+
+ //
+ // Deactivate all the processes.
+ //
+ deactivateAll();
+
+ //
+ // Join the termination listener thread. This thread terminates
+ // when there's no more processes and when _deactivating is set to
+ // true.
+ //
+ _thread->getThreadControl().join();
+ _thread = 0;
+}
+
+void
+Activator::runTerminationListener()
+{
+ try
+ {
+ terminationListener();
+ }
+ catch(const Exception& ex)
+ {
+ Error out(_traceLevels->logger);
+ out << "exception in process termination listener:\n" << ex;
+ }
+ catch(...)
+ {
+ Error out(_traceLevels->logger);
+ out << "unknown exception in process termination listener";
+ }
+}
+
+void
+Activator::deactivateAll()
+{
+ //
+ // Stop all active processes.
+ //
+ map<string, Process> processes;
+ {
+ IceUtil::Monitor< IceUtil::Mutex>::Lock sync(*this);
+ processes = _processes;
+ }
+
+ for(map<string, Process>::iterator p = processes.begin(); p != processes.end(); ++p)
+ {
+ //
+ // Stop the server. The listener thread should detect the
+ // process deactivation and remove it from the activator's
+ // list of active processes.
+ //
+ try
+ {
+ p->second.server->stop();
+ }
+ catch(const ObjectNotExistException&)
+ {
+ //
+ // Expected if the server was in the process of being destroyed.
+ //
+ }
+ }
+}
+
+void
+Activator::terminationListener()
+{
+#ifdef _WIN32
+ while(true)
+ {
+ vector<HANDLE> handles;
+
+ //
+ // Lock while we collect the process handles.
+ //
+ {
+ IceUtil::Monitor< IceUtil::Mutex>::Lock sync(*this);
+
+ for(map<string, Process>::iterator p = _processes.begin(); p != _processes.end(); ++p)
+ {
+ handles.push_back(p->second.hnd);
+ }
+ }
+
+ handles.push_back(_hIntr);
+
+ //
+ // Wait for a child to terminate, or the interrupt event to be signaled.
+ //
+ DWORD ret = WaitForMultipleObjects(handles.size(), &handles[0], FALSE, INFINITE);
+ if(ret == WAIT_FAILED)
+ {
+ SyscallException ex(__FILE__, __LINE__);
+ ex.error = getSystemErrno();
+ throw ex;
+ }
+
+ vector<HANDLE>::size_type pos = ret - WAIT_OBJECT_0;
+ assert(pos < handles.size());
+ HANDLE hnd = handles[pos];
+
+ IceUtil::Monitor< IceUtil::Mutex>::Lock sync(*this);
+
+ if(hnd == _hIntr)
+ {
+ clearInterrupt();
+ }
+ else
+ {
+ for(map<string, Process>::iterator p = _processes.begin(); p != _processes.end(); ++p)
+ {
+ if(p->second.hnd == hnd)
+ {
+ if(_traceLevels->activator > 0)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->activatorCat);
+ out << "detected termination of server `" << p->first << "'";
+ }
+
+ try
+ {
+ p->second.server->terminated();
+ }
+ catch(const Ice::LocalException& ex)
+ {
+ Ice::Warning out(_traceLevels->logger);
+ out << "unexpected exception raised by server `" << p->first << "' termination:\n" << ex;
+ }
+
+ CloseHandle(hnd);
+ _processes.erase(p);
+ break;
+ }
+ }
+ }
+
+ if(_deactivating && _processes.empty())
+ {
+ return;
+ }
+ }
+#else
+ while(true)
+ {
+ fd_set fdSet;
+ int maxFd = _fdIntrRead;
+ FD_ZERO(&fdSet);
+ FD_SET(_fdIntrRead, &fdSet);
+
+ {
+ IceUtil::Monitor< IceUtil::Mutex>::Lock sync(*this);
+
+ for(map<string, Process>::iterator p = _processes.begin(); p != _processes.end(); ++p)
+ {
+ int fd = p->second.pipeFd;
+ FD_SET(fd, &fdSet);
+ if(maxFd < fd)
+ {
+ maxFd = fd;
+ }
+ }
+ }
+
+ repeatSelect:
+ int ret = ::select(maxFd + 1, &fdSet, 0, 0, 0);
+ assert(ret != 0);
+
+ if(ret == -1)
+ {
+#ifdef EPROTO
+ if(errno == EINTR || errno == EPROTO)
+ {
+ goto repeatSelect;
+ }
+#else
+ if(errno == EINTR)
+ {
+ goto repeatSelect;
+ }
+#endif
+
+ SyscallException ex(__FILE__, __LINE__);
+ ex.error = getSystemErrno();
+ throw ex;
+ }
+
+ {
+ IceUtil::Monitor< IceUtil::Mutex>::Lock sync(*this);
+
+ if(FD_ISSET(_fdIntrRead, &fdSet))
+ {
+ clearInterrupt();
+
+ if(_deactivating && _processes.empty())
+ {
+ return;
+ }
+ }
+
+ map<string, Process>::iterator p = _processes.begin();
+ while(p != _processes.end())
+ {
+ int fd = p->second.pipeFd;
+ if(!FD_ISSET(fd, &fdSet))
+ {
+ ++p;
+ continue;
+ }
+
+ char s[16];
+ ssize_t rs;
+ string message;
+
+ //
+ // Read the message over the pipe.
+ //
+ while((rs = read(fd, &s, 16)) > 0)
+ {
+ message.append(s, rs);
+ }
+
+ if(rs == -1)
+ {
+ if(errno != EAGAIN || message.empty())
+ {
+ SyscallException ex(__FILE__, __LINE__);
+ ex.error = getSystemErrno();
+ throw ex;
+ }
+
+ ++p;
+ }
+ else if(rs == 0)
+ {
+ //
+ // If the pipe was closed, the process has terminated.
+ //
+
+ if(_traceLevels->activator > 0)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->activatorCat);
+ out << "detected termination of server `" << p->first << "'";
+ }
+
+ try
+ {
+ p->second.server->terminated();
+ }
+ catch(const Ice::LocalException& ex)
+ {
+ Ice::Warning out(_traceLevels->logger);
+ out << "unexpected exception raised by server `" << p->first << "' termination:\n" << ex;
+ }
+
+ close(p->second.pipeFd);
+ _processes.erase(p++);
+
+ //
+ // We are deactivating and there's no more active processes. We can now
+ // end this loop
+ //
+ if(_deactivating && _processes.empty())
+ {
+ return;
+ }
+ }
+
+ //
+ // Log the received message.
+ //
+ if(!message.empty())
+ {
+ Error out(_traceLevels->logger);
+ out << message;
+ }
+ }
+ }
+ }
+#endif
+}
+
+void
+Activator::clearInterrupt()
+{
+#ifdef _WIN32
+ ResetEvent(_hIntr);
+#else
+ char c;
+ while(read(_fdIntrRead, &c, 1) == 1)
+ ;
+#endif
+}
+
+void
+Activator::setInterrupt()
+{
+#ifdef _WIN32
+ SetEvent(_hIntr);
+#else
+ char c = 0;
+ write(_fdIntrWrite, &c, 1);
+#endif
+}
diff --git a/cpp/src/IceGrid/Activator.h b/cpp/src/IceGrid/Activator.h
new file mode 100644
index 00000000000..3a7bbcd59f6
--- /dev/null
+++ b/cpp/src/IceGrid/Activator.h
@@ -0,0 +1,89 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 ICE_GRID_ACTIVATOR_H
+#define ICE_GRID_ACTIVATOR_H
+
+#include <IceUtil/Thread.h>
+#include <IceGrid/Internal.h>
+
+namespace IceGrid
+{
+
+class TraceLevels;
+typedef IceUtil::Handle<TraceLevels> TraceLevelsPtr;
+
+class Activator : public IceUtil::Monitor< IceUtil::Mutex>, public IceUtil::Shared
+{
+public:
+
+ Activator(const TraceLevelsPtr&, const Ice::PropertiesPtr&);
+ virtual ~Activator();
+
+ virtual bool activate(const std::string&, const std::string&, const std::string&, const Ice::StringSeq&,
+ const Ice::StringSeq&, const ServerPrx&);
+ virtual void deactivate(const std::string&, const Ice::ProcessPrx&);
+ virtual void kill(const std::string&);
+ virtual void sendSignal(const std::string&, const std::string&);
+
+ virtual Ice::Int getServerPid(const std::string&);
+
+ virtual void start();
+ virtual void waitForShutdown();
+ virtual void shutdown();
+ virtual void destroy();
+
+
+ void sendSignal(const std::string&, int);
+ void runTerminationListener();
+
+private:
+
+ void deactivateAll();
+
+ void terminationListener();
+ void clearInterrupt();
+ void setInterrupt();
+
+ struct Process
+ {
+#ifdef _WIN32
+ DWORD pid;
+ HANDLE hnd;
+#else
+ pid_t pid;
+ int pipeFd;
+#endif
+ ServerPrx server;
+ };
+
+ TraceLevelsPtr _traceLevels;
+ Ice::PropertiesPtr _properties;
+ std::map<std::string, Process> _processes;
+ bool _deactivating;
+
+#ifdef _WIN32
+ HANDLE _hIntr;
+#else
+ int _fdIntrRead;
+ int _fdIntrWrite;
+#endif
+
+ std::vector<std::string> _propertiesOverride;
+
+ std::string _outputDir;
+ bool _redirectErrToOut;
+
+ IceUtil::ThreadPtr _thread;
+};
+typedef IceUtil::Handle<Activator> ActivatorPtr;
+
+}
+
+#endif
diff --git a/cpp/src/IceGrid/AdapterFactory.cpp b/cpp/src/IceGrid/AdapterFactory.cpp
new file mode 100644
index 00000000000..739a3ceb5e1
--- /dev/null
+++ b/cpp/src/IceGrid/AdapterFactory.cpp
@@ -0,0 +1,110 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 <IceUtil/UUID.h>
+#include <Freeze/Evictor.h>
+#include <Freeze/Initialize.h>
+#include <IceGrid/AdapterFactory.h>
+#include <IceGrid/AdapterI.h>
+#include <IceGrid/TraceLevels.h>
+
+using namespace std;
+using namespace IceGrid;
+
+IceGrid::AdapterFactory::AdapterFactory(const Ice::ObjectAdapterPtr& adapter,
+ const TraceLevelsPtr& traceLevels,
+ const string& envName) :
+ _adapter(adapter),
+ _traceLevels(traceLevels)
+{
+ Ice::PropertiesPtr properties = _adapter->getCommunicator()->getProperties();
+
+ //
+ // Create and install the freeze evictor for standalone adapter objects.
+ //
+ properties->setProperty("Freeze.Evictor." + envName + ".adapter.SaveSizeTrigger", "1");
+ _evictor = Freeze::createEvictor(_adapter, envName, "adapter");
+ _evictor->setSize(1000);
+
+ //
+ // Install the server object factory.
+ //
+ _adapter->getCommunicator()->addObjectFactory(this, "::IceGrid::StandaloneAdapter");
+
+ //
+ // Install the evictors.
+ //
+ _adapter->addServantLocator(_evictor, "IceGridStandaloneAdapter");
+}
+
+//
+// Ice::ObjectFactory::create method implementation
+//
+Ice::ObjectPtr
+IceGrid::AdapterFactory::create(const string& type)
+{
+ if(type == "::IceGrid::StandaloneAdapter")
+ {
+ return new StandaloneAdapterI(this);
+ }
+ else
+ {
+ assert(false);
+ return 0; // Keep the compiler happy.
+ }
+}
+
+//
+// Ice::ObjectFactory::destroy method implementation
+//
+void
+IceGrid::AdapterFactory::destroy()
+{
+ _adapter = 0;
+ _evictor = 0;
+ _traceLevels = 0;
+}
+
+//
+// Create a new adapter servant with the given name and add
+// it the evictor database.
+//
+AdapterPrx
+IceGrid::AdapterFactory::createStandaloneAdapter(const string& name)
+{
+ StandaloneAdapterPtr adapterI = new StandaloneAdapterI(this);
+
+ Ice::Identity id;
+ id.category = "IceGridStandaloneAdapter";
+ id.name = name + "-" + IceUtil::generateUUID();
+
+ _evictor->add(adapterI, id);
+
+ return AdapterPrx::uncheckedCast(_adapter->createProxy(id));
+}
+
+void
+IceGrid::AdapterFactory::destroy(const Ice::Identity& id)
+{
+ try
+ {
+ _evictor->remove(id);
+ }
+ catch(const Freeze::DatabaseException& ex)
+ {
+ ostringstream os;
+ os << "couldn't destroy standalone adapter:\n" << ex;
+ _traceLevels->logger->warning(os.str());
+ }
+ catch(const Freeze::EvictorDeactivatedException&)
+ {
+ assert(false);
+ }
+}
diff --git a/cpp/src/IceGrid/AdapterFactory.h b/cpp/src/IceGrid/AdapterFactory.h
new file mode 100644
index 00000000000..85af7b72a4f
--- /dev/null
+++ b/cpp/src/IceGrid/AdapterFactory.h
@@ -0,0 +1,52 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 ICE_GRID_ADAPTER_FACTORY_H
+#define ICE_GRID_ADAPTER_FACTORY_H
+
+#include <IceGrid/Internal.h>
+#include <Freeze/EvictorF.h>
+
+namespace IceGrid
+{
+
+class TraceLevels;
+typedef IceUtil::Handle<TraceLevels> TraceLevelsPtr;
+
+class AdapterFactory : public Ice::ObjectFactory
+{
+public:
+
+ AdapterFactory(const Ice::ObjectAdapterPtr&, const TraceLevelsPtr&, const std::string&);
+
+ //
+ // Ice::ObjectFactory method implementation.
+ //
+ virtual Ice::ObjectPtr create(const std::string&);
+ virtual void destroy();
+
+ AdapterPrx createStandaloneAdapter(const std::string& name);
+
+private:
+
+ friend class StandaloneAdapterI;
+
+ void destroy(const Ice::Identity&);
+
+ Ice::ObjectAdapterPtr _adapter;
+ TraceLevelsPtr _traceLevels;
+
+ Freeze::EvictorPtr _evictor;
+};
+
+typedef ::IceUtil::Handle< AdapterFactory> AdapterFactoryPtr;
+
+}
+
+#endif
diff --git a/cpp/src/IceGrid/AdapterI.cpp b/cpp/src/IceGrid/AdapterI.cpp
new file mode 100644
index 00000000000..c588c2846f1
--- /dev/null
+++ b/cpp/src/IceGrid/AdapterI.cpp
@@ -0,0 +1,55 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 <IceGrid/AdapterI.h>
+#include <IceGrid/AdapterFactory.h>
+#include <IceGrid/TraceLevels.h>
+
+using namespace std;
+using namespace IceGrid;
+
+StandaloneAdapterI::StandaloneAdapterI(const AdapterFactoryPtr& factory) :
+ _factory(factory)
+{
+}
+
+StandaloneAdapterI::StandaloneAdapterI()
+{
+}
+
+void
+StandaloneAdapterI::activate_async(const AMD_Adapter_activatePtr& cb, const Ice::Current&)
+{
+ IceUtil::Mutex::Lock sync(*this);
+ cb->ice_response(proxy);
+}
+
+Ice::ObjectPrx
+StandaloneAdapterI::getDirectProxy(const Ice::Current&) const
+{
+ IceUtil::Mutex::Lock sync(*this);
+ return proxy;
+}
+
+void
+StandaloneAdapterI::setDirectProxy(const Ice::ObjectPrx& prx, const Ice::Current&)
+{
+ IceUtil::Mutex::Lock sync(*this);
+ proxy = prx;
+}
+
+void
+StandaloneAdapterI::destroy(const Ice::Current& current)
+{
+ if(_factory)
+ {
+ _factory->destroy(current.id);
+ }
+}
diff --git a/cpp/src/IceGrid/AdapterI.h b/cpp/src/IceGrid/AdapterI.h
new file mode 100644
index 00000000000..621013613a5
--- /dev/null
+++ b/cpp/src/IceGrid/AdapterI.h
@@ -0,0 +1,42 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 ICE_GRID_ADAPTER_I_H
+#define ICE_GRID_ADAPTER_I_H
+
+#include <IceUtil/Mutex.h>
+#include <IceGrid/Internal.h>
+#include <IceUtil/AbstractMutex.h>
+
+namespace IceGrid
+{
+
+class AdapterFactory;
+typedef IceUtil::Handle<AdapterFactory> AdapterFactoryPtr;
+
+class StandaloneAdapterI : public StandaloneAdapter, public IceUtil::AbstractMutexI<IceUtil::Mutex>
+{
+public:
+
+ StandaloneAdapterI(const AdapterFactoryPtr&);
+ StandaloneAdapterI();
+
+ virtual void activate_async(const AMD_Adapter_activatePtr&, const Ice::Current&);
+ virtual Ice::ObjectPrx getDirectProxy(const Ice::Current&) const;
+ virtual void setDirectProxy(const ::Ice::ObjectPrx&, const ::Ice::Current&);
+ virtual void destroy(const ::Ice::Current&);
+
+private:
+
+ AdapterFactoryPtr _factory;
+};
+
+}
+
+#endif
diff --git a/cpp/src/IceGrid/AdapterRegistryI.cpp b/cpp/src/IceGrid/AdapterRegistryI.cpp
new file mode 100644
index 00000000000..1eaca9cef4c
--- /dev/null
+++ b/cpp/src/IceGrid/AdapterRegistryI.cpp
@@ -0,0 +1,144 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 <IceGrid/AdapterRegistryI.h>
+#include <IceGrid/TraceLevels.h>
+#include <Freeze/Initialize.h>
+
+using namespace std;
+using namespace IceGrid;
+
+const string AdapterRegistryI::_dbName = "adapterregistry";
+
+AdapterRegistryI::AdapterRegistryI(const Ice::CommunicatorPtr& communicator,
+ const string& envName,
+ const TraceLevelsPtr& traceLevels) :
+ _connectionCache(Freeze::createConnection(communicator, envName)),
+ _dictCache(_connectionCache, _dbName),
+ _traceLevels(traceLevels),
+ _envName(envName),
+ _communicator(communicator)
+{
+}
+
+void
+AdapterRegistryI::add(const string& id, const AdapterPrx& adapter, const Ice::Current& current)
+{
+ while(true)
+ {
+ AdapterPrx oldAdapter;
+ try
+ {
+ oldAdapter = findById(id, current);
+ oldAdapter->ice_ping();
+ throw AdapterExistsException();
+ }
+ catch(const AdapterNotExistException&)
+ {
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ }
+ catch(const Ice::LocalException&)
+ {
+ throw AdapterExistsException();
+ }
+
+ Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName);
+ StringObjectProxyDict dict(connection, _dbName);
+
+ StringObjectProxyDict::iterator p = dict.find(id);
+ if(p != dict.end())
+ {
+ if(oldAdapter && oldAdapter != p->second)
+ {
+ continue;
+ }
+
+ p.set(adapter);
+
+ if(_traceLevels->adapterRegistry > 0)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->adapterRegistryCat);
+ out << "updated adapter `" << id << "'";
+ }
+ }
+ else
+ {
+ dict.put(pair<const string, const Ice::ObjectPrx>(id, adapter));
+
+ if(_traceLevels->adapterRegistry > 0)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->adapterRegistryCat);
+ out << "added adapter `" << id << "'";
+ }
+ }
+
+ break;
+ }
+}
+
+AdapterPrx
+AdapterRegistryI::remove(const string& id, const AdapterPrx& orig, const Ice::Current&)
+{
+ Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName);
+ StringObjectProxyDict dict(connection, _dbName);
+
+ StringObjectProxyDict::iterator p = dict.find(id);
+ if(p == dict.end())
+ {
+ throw AdapterNotExistException();
+ }
+
+ AdapterPrx adapter = AdapterPrx::uncheckedCast(p->second);
+ if(orig != 0 && orig != adapter) // Only remove if the adapter is equal to the provided proxy (if not null)
+ {
+ return 0;
+ }
+ dict.erase(p);
+
+ if(_traceLevels->adapterRegistry > 0)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->adapterRegistryCat);
+ out << "removed adapter `" << id << "'";
+ }
+
+ return adapter;
+}
+
+AdapterPrx
+AdapterRegistryI::findById(const string& id, const Ice::Current&)
+{
+ Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName);
+ StringObjectProxyDict dict(connection, _dbName);
+
+ StringObjectProxyDict::iterator p = dict.find(id);
+ if(p != dict.end())
+ {
+ return AdapterPrx::uncheckedCast(p->second);
+ }
+ throw AdapterNotExistException();
+}
+
+Ice::StringSeq
+AdapterRegistryI::getAll(const Ice::Current&) const
+{
+ Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName);
+ StringObjectProxyDict dict(connection, _dbName);
+
+ Ice::StringSeq ids;
+ ids.reserve(dict.size());
+
+ for(StringObjectProxyDict::iterator p = dict.begin(); p != dict.end(); ++p)
+ {
+ ids.push_back(p->first);
+ }
+
+ return ids;
+}
diff --git a/cpp/src/IceGrid/AdapterRegistryI.h b/cpp/src/IceGrid/AdapterRegistryI.h
new file mode 100644
index 00000000000..b89b0d954c7
--- /dev/null
+++ b/cpp/src/IceGrid/AdapterRegistryI.h
@@ -0,0 +1,48 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 ICE_GRID_ADAPTER_REGISTRY_I_H
+#define ICE_GRID_ADAPTER_REGISTRY_I_H
+
+#include <IceGrid/Internal.h>
+#include <IceGrid/StringObjectProxyDict.h>
+
+namespace IceGrid
+{
+
+class TraceLevels;
+typedef IceUtil::Handle<TraceLevels> TraceLevelsPtr;
+
+class AdapterRegistryI : public AdapterRegistry
+{
+public:
+
+ AdapterRegistryI(const Ice::CommunicatorPtr&, const std::string&, const TraceLevelsPtr&);
+
+ virtual void add(const std::string&, const AdapterPrx&, const ::Ice::Current&);
+ virtual AdapterPrx remove(const std::string&, const AdapterPrx&, const ::Ice::Current&);
+
+ virtual AdapterPrx findById(const ::std::string&, const ::Ice::Current&);
+ virtual Ice::StringSeq getAll(const ::Ice::Current&) const;
+
+private:
+
+ static const std::string _dbName;
+
+ Freeze::ConnectionPtr _connectionCache;
+ StringObjectProxyDict _dictCache;
+ TraceLevelsPtr _traceLevels;
+ const std::string _envName;
+ const Ice::CommunicatorPtr _communicator;
+
+};
+
+}
+
+#endif
diff --git a/cpp/src/IceGrid/AdminI.cpp b/cpp/src/IceGrid/AdminI.cpp
new file mode 100644
index 00000000000..3e32bcedb1f
--- /dev/null
+++ b/cpp/src/IceGrid/AdminI.cpp
@@ -0,0 +1,1530 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 <IceGrid/AdminI.h>
+#include <IceGrid/DescriptorVisitor.h>
+#include <IceGrid/DescriptorUtil.h>
+#include <IceGrid/Registry.h>
+#include <Ice/LoggerUtil.h>
+#include <Ice/TraceUtil.h>
+#include <Ice/SliceChecksums.h>
+
+using namespace std;
+using namespace Ice;
+using namespace IceGrid;
+
+namespace IceGrid
+{
+
+class Deployer : public DescriptorVisitor
+{
+public:
+
+ Deployer(const NodeRegistryPtr&,
+ const ApplicationRegistryPtr&,
+ const ServerRegistryPtr&,
+ const AdapterRegistryPtr&,
+ const ObjectRegistryPtr&,
+ const Ice::LoggerPtr&);
+
+ Deployer(const Deployer&);
+
+protected:
+
+ friend class Cleaner;
+
+ void exception(const string&);
+ void exception(const string&, const Ice::LocalException&);
+
+ const NodeRegistryPtr _nodeRegistry;
+ const ApplicationRegistryPtr _applicationRegistry;
+ const ServerRegistryPtr _serverRegistry;
+ const AdapterRegistryPtr _adapterRegistry;
+ const ObjectRegistryPtr _objectRegistry;
+ const Ice::LoggerPtr _logger;
+};
+
+class Cleaner : public DescriptorVisitor
+{
+public:
+
+ Cleaner(const NodeRegistryPtr&,
+ const ApplicationRegistryPtr&,
+ const ServerRegistryPtr&,
+ const AdapterRegistryPtr&,
+ const ObjectRegistryPtr&,
+ const Ice::LoggerPtr&);
+
+ Cleaner(const Deployer&);
+ Cleaner(const Cleaner&);
+
+protected:
+
+ void exception(const string&);
+ void exception(const string&, const Ice::LocalException&);
+
+ const NodeRegistryPtr _nodeRegistry;
+ const ApplicationRegistryPtr _applicationRegistry;
+ const ServerRegistryPtr _serverRegistry;
+ const AdapterRegistryPtr _adapterRegistry;
+ const ObjectRegistryPtr _objectRegistry;
+ const Ice::LoggerPtr _logger;
+};
+
+class ApplicationDeployer : public Deployer
+{
+public:
+
+ ApplicationDeployer(const NodeRegistryPtr&,
+ const ApplicationRegistryPtr&,
+ const ServerRegistryPtr&,
+ const AdapterRegistryPtr&,
+ const ObjectRegistryPtr&,
+ const Ice::LoggerPtr&);
+
+ ApplicationDeployer(const Deployer&);
+
+ void deploy(const ApplicationDescriptorPtr&);
+
+private:
+
+ virtual bool visitApplicationStart(const ApplicationWrapper&, const ApplicationDescriptorPtr&);
+ virtual bool visitServerStart(const ServerWrapper&, const ServerDescriptorPtr&);
+
+ ApplicationDescriptorPtr _deployed;
+};
+
+class ServerDeployer : public Deployer
+{
+public:
+
+ ServerDeployer(const NodeRegistryPtr&,
+ const ApplicationRegistryPtr&,
+ const ServerRegistryPtr&,
+ const AdapterRegistryPtr&,
+ const ObjectRegistryPtr&,
+ const Ice::LoggerPtr&);
+
+ ServerDeployer(const Deployer&);
+
+ void deploy(const ServerDescriptorPtr&, const string& = string());
+
+private:
+
+ virtual bool visitServerStart(const ServerWrapper&, const ServerDescriptorPtr&);
+ virtual void visitServerEnd(const ServerWrapper&, const ServerDescriptorPtr&);
+ virtual bool visitServiceStart(const ServiceWrapper&, const ServiceDescriptorPtr&);
+ virtual void visitDbEnv(const DbEnvWrapper&, const DbEnvDescriptor&);
+ virtual bool visitAdapterStart(const AdapterWrapper&, const AdapterDescriptor&);
+ virtual void visitObject(const ObjectWrapper&, const ObjectDescriptor&);
+
+ ServerDescriptorPtr _deployed;
+
+ string _currentNodeName;
+ NodePrx _currentNode;
+ ServerPrx _currentServer;
+ PropertyDescriptorSeq _currentProperties;
+ string _backup;
+};
+
+class ApplicationCleaner : public Cleaner
+{
+public:
+
+ ApplicationCleaner(const NodeRegistryPtr&,
+ const ApplicationRegistryPtr&,
+ const ServerRegistryPtr&,
+ const AdapterRegistryPtr&,
+ const ObjectRegistryPtr&,
+ const Ice::LoggerPtr&);
+
+ ApplicationCleaner(const Deployer&);
+
+ void clean(const ApplicationDescriptorPtr&);
+
+private:
+
+ virtual void visitApplicationEnd(const ApplicationWrapper&, const ApplicationDescriptorPtr&);
+ virtual bool visitServerStart(const ServerWrapper&, const ServerDescriptorPtr&);
+};
+
+class ServerCleaner : public Cleaner
+{
+public:
+
+ ServerCleaner(const NodeRegistryPtr&,
+ const ApplicationRegistryPtr&,
+ const ServerRegistryPtr&,
+ const AdapterRegistryPtr&,
+ const ObjectRegistryPtr&,
+ const Ice::LoggerPtr&);
+
+ ServerCleaner(const Deployer&);
+ ServerCleaner(const Cleaner&);
+
+ void clean(const ServerDescriptorPtr&, const string& = string());
+
+private:
+
+ virtual bool visitServerStart(const ServerWrapper&, const ServerDescriptorPtr&);
+ virtual void visitServerEnd(const ServerWrapper&, const ServerDescriptorPtr&);
+ virtual bool visitServiceStart(const ServiceWrapper&, const ServiceDescriptorPtr&);
+ virtual bool visitAdapterStart(const AdapterWrapper&, const AdapterDescriptor&);
+ virtual void visitDbEnv(const DbEnvWrapper&, const DbEnvDescriptor&);
+ virtual void visitObject(const ObjectWrapper&, const ObjectDescriptor&);
+
+ string _currentNodeName;
+ ServerPrx _currentServer;
+ string _backup;
+};
+
+class ApplicationUpdater : public Deployer
+{
+public:
+
+ ApplicationUpdater(const NodeRegistryPtr&,
+ const ApplicationRegistryPtr&,
+ const ServerRegistryPtr&,
+ const AdapterRegistryPtr&,
+ const ObjectRegistryPtr&,
+ const Ice::LoggerPtr&);
+
+ ApplicationUpdater(const Deployer&);
+
+ void update(const ApplicationDescriptorPtr&);
+
+private:
+
+ virtual bool visitApplicationStart(const ApplicationWrapper&, const ApplicationDescriptorPtr&);
+ virtual void visitApplicationEnd(const ApplicationWrapper&, const ApplicationDescriptorPtr&);
+ virtual bool visitServerStart(const ServerWrapper&, const ServerDescriptorPtr&);
+
+ ApplicationDescriptorPtr _deployed;
+ ApplicationDescriptorPtr _added;
+ ApplicationDescriptorPtr _removed;
+ map<string, pair<string, string> > _backup;
+};
+
+}
+
+Deployer::Deployer(const NodeRegistryPtr& nodeRegistry,
+ const ApplicationRegistryPtr& applicationRegistry,
+ const ServerRegistryPtr& serverRegistry,
+ const AdapterRegistryPtr& adapterRegistry,
+ const ObjectRegistryPtr& objectRegistry,
+ const Ice::LoggerPtr& logger) :
+ _nodeRegistry(nodeRegistry),
+ _applicationRegistry(applicationRegistry),
+ _serverRegistry(serverRegistry),
+ _adapterRegistry(adapterRegistry),
+ _objectRegistry(objectRegistry),
+ _logger(logger)
+{
+}
+
+Deployer::Deployer(const Deployer& deployer) :
+ _nodeRegistry(deployer._nodeRegistry),
+ _applicationRegistry(deployer._applicationRegistry),
+ _serverRegistry(deployer._serverRegistry),
+ _adapterRegistry(deployer._adapterRegistry),
+ _objectRegistry(deployer._objectRegistry),
+ _logger(deployer._logger)
+{
+}
+
+void
+Deployer::exception(const string& msg)
+{
+ DeploymentException ex;
+ ex.reason = msg;
+ throw ex;
+}
+
+void
+Deployer::exception(const string& msg, const Ice::LocalException& ex)
+{
+ ostringstream os;
+ os << msg << "\nException: " << ex;
+ DeploymentException e;
+ e.reason = os.str();
+ throw e;
+}
+
+Cleaner::Cleaner(const NodeRegistryPtr& nodeRegistry,
+ const ApplicationRegistryPtr& applicationRegistry,
+ const ServerRegistryPtr& serverRegistry,
+ const AdapterRegistryPtr& adapterRegistry,
+ const ObjectRegistryPtr& objectRegistry,
+ const Ice::LoggerPtr& logger) :
+ _nodeRegistry(nodeRegistry),
+ _applicationRegistry(applicationRegistry),
+ _serverRegistry(serverRegistry),
+ _adapterRegistry(adapterRegistry),
+ _objectRegistry(objectRegistry),
+ _logger(logger)
+{
+}
+
+Cleaner::Cleaner(const Deployer& deployer) :
+ _nodeRegistry(deployer._nodeRegistry),
+ _applicationRegistry(deployer._applicationRegistry),
+ _serverRegistry(deployer._serverRegistry),
+ _adapterRegistry(deployer._adapterRegistry),
+ _objectRegistry(deployer._objectRegistry),
+ _logger(deployer._logger)
+{
+}
+
+Cleaner::Cleaner(const Cleaner& cleaner) :
+ _nodeRegistry(cleaner._nodeRegistry),
+ _applicationRegistry(cleaner._applicationRegistry),
+ _serverRegistry(cleaner._serverRegistry),
+ _adapterRegistry(cleaner._adapterRegistry),
+ _objectRegistry(cleaner._objectRegistry),
+ _logger(cleaner._logger)
+{
+}
+
+void
+Cleaner::exception(const string& msg)
+{
+ Ice::Warning out(_logger);
+ out << msg;
+}
+
+void
+Cleaner::exception(const string& msg, const Ice::LocalException& ex)
+{
+ Ice::Warning out(_logger);
+ out << msg << "\nException: " << ex;
+}
+
+ApplicationDeployer::ApplicationDeployer(const NodeRegistryPtr& nodeRegistry,
+ const ApplicationRegistryPtr& applicationRegistry,
+ const ServerRegistryPtr& serverRegistry,
+ const AdapterRegistryPtr& adapterRegistry,
+ const ObjectRegistryPtr& objectRegistry,
+ const Ice::LoggerPtr& logger) :
+ Deployer(nodeRegistry, applicationRegistry, serverRegistry, adapterRegistry, objectRegistry, logger)
+{
+}
+
+ApplicationDeployer::ApplicationDeployer(const Deployer& deployer) :
+ Deployer(deployer)
+{
+}
+
+void
+ApplicationDeployer::deploy(const ApplicationDescriptorPtr& descriptor)
+{
+ try
+ {
+ ApplicationWrapper(descriptor).visit(*this);
+ }
+ catch(const DeploymentException&)
+ {
+ if(_deployed)
+ {
+ ApplicationCleaner cleaner(*this);
+ cleaner.clean(_deployed);
+ }
+ throw;
+ }
+}
+
+bool
+ApplicationDeployer::visitApplicationStart(const ApplicationWrapper&, const ApplicationDescriptorPtr& application)
+{
+ try
+ {
+ _applicationRegistry->add(application->name);
+ _deployed = new ApplicationDescriptor();
+ _deployed->name = application->name;
+ }
+ catch(const ApplicationExistsException&)
+ {
+ exception("application `" + application->name + "' already exists");
+ }
+ return true;
+}
+
+bool
+ApplicationDeployer::visitServerStart(const ServerWrapper&, const ServerDescriptorPtr& server)
+{
+ ServerDeployer deployer(*this);
+ deployer.deploy(server);
+ _deployed->servers.push_back(server);
+ return false;
+}
+
+ApplicationUpdater::ApplicationUpdater(const NodeRegistryPtr& nodeRegistry,
+ const ApplicationRegistryPtr& applicationRegistry,
+ const ServerRegistryPtr& serverRegistry,
+ const AdapterRegistryPtr& adapterRegistry,
+ const ObjectRegistryPtr& objectRegistry,
+ const Ice::LoggerPtr& logger) :
+ Deployer(nodeRegistry, applicationRegistry, serverRegistry, adapterRegistry, objectRegistry, logger)
+{
+}
+
+ApplicationUpdater::ApplicationUpdater(const Deployer& deployer) :
+ Deployer(deployer)
+{
+}
+
+void
+ApplicationUpdater::update(const ApplicationDescriptorPtr& descriptor)
+{
+ try
+ {
+ ApplicationWrapper(descriptor).visit(*this);
+ }
+ catch(const DeploymentException&)
+ {
+ if(_added)
+ {
+ for(ServerDescriptorSeq::const_iterator p = _added->servers.begin(); p != _added->servers.end(); ++p)
+ {
+ //
+ // If there's a backup directory for this server and it's on the same node we pass
+ // the backup directory to backup the databases.
+ //
+ if(_backup[(*p)->name].first == (*p)->node)
+ {
+ ServerCleaner(*this).clean(*p, _backup[(*p)->name].second);
+ }
+ else
+ {
+ ServerCleaner(*this).clean(*p);
+ }
+ }
+ }
+ if(_removed)
+ {
+ for(ServerDescriptorSeq::const_iterator p = _removed->servers.begin(); p != _removed->servers.end(); ++p)
+ {
+ try
+ {
+ ServerDeployer(*this).deploy(*p, _backup[(*p)->name].second);
+ }
+ catch(DeploymentException& ex)
+ {
+ cerr << "failed to add back updated server:\n" << ex << endl;
+ }
+ }
+ }
+ throw;
+ }
+
+ //
+ // Destroy all the temporary backup directories.
+ //
+ for(map<string, pair<string, string> >::const_iterator p = _backup.begin(); p != _backup.end(); ++p)
+ {
+ if(!p->second.first.empty())
+ {
+ _nodeRegistry->findByName(p->second.first)->destroyTmpDir(p->second.second);
+ }
+ }
+}
+
+bool
+ApplicationUpdater::visitApplicationStart(const ApplicationWrapper&, const ApplicationDescriptorPtr& application)
+{
+ try
+ {
+ _deployed = _applicationRegistry->getDescriptor(application->name);
+ _added = new ApplicationDescriptor();
+ _removed = new ApplicationDescriptor();
+ }
+ catch(const ApplicationNotExistException&)
+ {
+ exception("application `" + application->name + "' doesn't exists");
+ }
+ return true;
+}
+
+void
+ApplicationUpdater::visitApplicationEnd(const ApplicationWrapper&, const ApplicationDescriptorPtr& application)
+{
+ //
+ // Remove servers which don't exist anymore.
+ //
+ for(ServerDescriptorSeq::const_iterator p = _deployed->servers.begin(); p != _deployed->servers.end(); ++p)
+ {
+ bool found = false;
+ for(ServerDescriptorSeq::const_iterator q = application->servers.begin(); q != application->servers.end(); ++q)
+ {
+ if((*p)->name == (*q)->name)
+ {
+ found = true;
+ break;
+ }
+ }
+ if(!found)
+ {
+ ServerCleaner(*this).clean(*p);
+ }
+ }
+}
+
+bool
+ApplicationUpdater::visitServerStart(const ServerWrapper&, const ServerDescriptorPtr& server)
+{
+ for(ServerDescriptorSeq::const_iterator p = _deployed->servers.begin(); p != _deployed->servers.end(); ++p)
+ {
+ if((*p)->name == server->name)
+ {
+ if(equal(*p, server))
+ {
+ //
+ // Nothing to do, the descriptors are the same.
+ //
+ return false;
+ }
+
+ _backup[server->name].second = _nodeRegistry->findByName((*p)->node)->createTmpDir();
+ _backup[server->name].first = (*p)->node;
+
+ ServerCleaner(*this).clean(*p, _backup[server->name].second);
+ _removed->servers.push_back(*p);
+
+ if(server->node == ((*p)->node))
+ {
+ ServerDeployer(*this).deploy(server, _backup[server->name].second);
+ }
+ else
+ {
+ ServerDeployer(*this).deploy(server);
+ }
+
+ _added->servers.push_back(server);
+ return false;
+ }
+ }
+
+ ServerDeployer(*this).deploy(server, _backup[server->name].second);
+ _added->servers.push_back(server);
+ return false;
+}
+
+ServerDeployer::ServerDeployer(const NodeRegistryPtr& nodeRegistry,
+ const ApplicationRegistryPtr& applicationRegistry,
+ const ServerRegistryPtr& serverRegistry,
+ const AdapterRegistryPtr& adapterRegistry,
+ const ObjectRegistryPtr& objectRegistry,
+ const Ice::LoggerPtr& logger) :
+ Deployer(nodeRegistry, applicationRegistry, serverRegistry, adapterRegistry, objectRegistry, logger)
+{
+}
+
+ServerDeployer::ServerDeployer(const Deployer& deployer) :
+ Deployer(deployer)
+{
+}
+
+void
+ServerDeployer::deploy(const ServerDescriptorPtr& descriptor, const string& backup)
+{
+ _backup = backup;
+ try
+ {
+ ServerWrapper(descriptor).visit(*this);
+ }
+ catch(const DeploymentException&)
+ {
+ if(_deployed)
+ {
+ ServerCleaner cleaner(*this);
+ cleaner.clean(_deployed);
+ }
+ throw;
+ }
+
+}
+
+bool
+ServerDeployer::visitServerStart(const ServerWrapper&, const ServerDescriptorPtr& server)
+{
+ try
+ {
+ try
+ {
+ _currentNodeName = server->node;
+ _currentNode = _nodeRegistry->findByName(server->node);
+ _currentServer = _currentNode->createServer(server->name, server);
+ _currentProperties.clear();
+ PropertyDescriptor prop;
+ prop.name = "# Server configuration";
+ _currentProperties.push_back(prop);
+ prop.name = "Ice.ProgramName";
+ prop.value = server->name;
+ _currentProperties.push_back(prop);
+ copy(server->properties.begin(), server->properties.end(), back_inserter(_currentProperties));
+ _serverRegistry->add(server->name, _currentServer, server);
+
+ if(JavaIceBoxDescriptorPtr::dynamicCast(server))
+ {
+ _deployed = new JavaIceBoxDescriptor();
+ }
+ else if(CppIceBoxDescriptorPtr::dynamicCast(server))
+ {
+ _deployed = new CppIceBoxDescriptor();
+ }
+ else if(JavaServerDescriptorPtr::dynamicCast(server))
+ {
+ _deployed = new JavaServerDescriptor();
+ }
+ else
+ {
+ _deployed = new ServerDescriptor();
+ }
+ _deployed->node = server->node;
+ _deployed->name = server->name;
+
+ if(!server->application.empty())
+ {
+ _applicationRegistry->registerServer(server->application, server->name);
+ _deployed->application = server->application;
+ }
+ }
+ catch(const ServerExistsException&)
+ {
+ _currentServer->destroy();
+ _currentServer = 0;
+ exception("server `" + server->name + "' already exists");
+ }
+ catch(const ApplicationNotExistException&)
+ {
+ exception("application `" + server->application + "' doesn't exist");
+ }
+ catch(const NodeNotExistException&)
+ {
+ exception("couldn't find node `" + server->node + "'");
+ }
+
+ _currentServer->setActivationMode(server->activation);
+ _currentServer->setExePath(server->exe);
+ _currentServer->setPwd(server->pwd);
+ _currentServer->setEnvs(server->envs);
+ }
+ catch(const Ice::LocalException& ex)
+ {
+ exception("couldn't contact node `" + server->node + "'", ex);
+ }
+
+ return true;
+}
+
+void
+ServerDeployer::visitServerEnd(const ServerWrapper&, const ServerDescriptorPtr& server)
+{
+ assert(_currentServer);
+
+ try
+ {
+ Ice::StringSeq options;
+
+ JavaServerDescriptorPtr javaDesc = JavaServerDescriptorPtr::dynamicCast(server);
+ if(javaDesc)
+ {
+ copy(javaDesc->jvmOptions.begin(), javaDesc->jvmOptions.end(), back_inserter(options));
+ options.push_back("-ea");
+ options.push_back(javaDesc->className);
+ copy(javaDesc->options.begin(), javaDesc->options.end(), back_inserter(options));
+ }
+ else
+ {
+ options = server->options;
+ }
+
+ CppIceBoxDescriptorPtr cppIceBox = CppIceBoxDescriptorPtr::dynamicCast(server);
+ JavaIceBoxDescriptorPtr javaIceBox = JavaIceBoxDescriptorPtr::dynamicCast(server);
+
+ const ServiceDescriptorSeq& services =
+ cppIceBox ? cppIceBox->services : (javaIceBox ? javaIceBox->services : ServiceDescriptorSeq());
+
+ if(!services.empty())
+ {
+ PropertyDescriptor prop;
+ prop.name = "IceBox.LoadOrder";
+ for(ServiceDescriptorSeq::const_iterator p = services.begin(); p != services.end(); ++p)
+ {
+ prop.value += (*p)->name + " ";
+ }
+ _currentProperties.push_back(prop);
+ }
+
+ if(!_currentProperties.empty())
+ {
+ string path = _currentServer->addConfigFile("config", _currentProperties);
+ options.push_back("--Ice.Config=" + path);
+
+ _deployed->properties = _currentProperties;
+ }
+
+ _currentServer->setOptions(options);
+ }
+ catch(const Ice::LocalException& ex)
+ {
+ exception("couldn't contact node `" + _currentNodeName + "'", ex);
+ }
+}
+
+bool
+ServerDeployer::visitServiceStart(const ServiceWrapper&, const ServiceDescriptorPtr& service)
+{
+ assert(_currentServer);
+
+ try
+ {
+ string path = _currentServer->addConfigFile("config_" + service->name, service->properties);
+
+ ServiceDescriptorPtr svc = new ServiceDescriptor();
+ svc->name = service->name;
+ svc->properties = service->properties;
+ if(JavaIceBoxDescriptorPtr::dynamicCast(_deployed))
+ {
+ JavaIceBoxDescriptorPtr::dynamicCast(_deployed)->services.push_back(svc);
+ }
+ else
+ {
+ CppIceBoxDescriptorPtr::dynamicCast(_deployed)->services.push_back(svc);
+ }
+
+ PropertyDescriptor prop;
+ _currentProperties.push_back(prop);
+ prop.name = "#";
+ _currentProperties.push_back(prop);
+ prop.name = "# Service " + service->name;
+ _currentProperties.push_back(prop);
+ prop.name = "#";
+ _currentProperties.push_back(prop);
+ prop.name = "IceBox.Service." + service->name;
+ prop.value = service->entry + " --Ice.Config=" + path;
+ _currentProperties.push_back(prop);
+ }
+ catch(const Ice::LocalException& ex)
+ {
+ exception("couldn't contact node `" + _currentNodeName + "'", ex);
+ }
+
+ return true;
+}
+
+void
+ServerDeployer::visitDbEnv(const DbEnvWrapper&, const DbEnvDescriptor& dbEnv)
+{
+ assert(_currentServer);
+
+ try
+ {
+ string path = _currentServer->addDbEnv(dbEnv, _backup);
+ _deployed->dbEnvs.push_back(dbEnv);
+
+ PropertyDescriptor prop;
+ _currentProperties.push_back(prop);
+ prop.name = "# DbEnv " + dbEnv.name;
+ _currentProperties.push_back(prop);
+ prop.name = "Freeze.DbEnv." + dbEnv.name + ".DbHome";
+ prop.value = path;
+ _currentProperties.push_back(prop);
+ }
+ catch(const Ice::LocalException& ex)
+ {
+ exception("couldn't contact node `" + _currentNodeName + "'", ex);
+ }
+}
+
+bool
+ServerDeployer::visitAdapterStart(const AdapterWrapper&, const AdapterDescriptor& adapter)
+{
+ assert(_currentServer);
+
+ ServerAdapterPrx serverAdapter;
+ try
+ {
+ serverAdapter = _currentNode->createServerAdapter(_currentServer, adapter.id);
+ _adapterRegistry->add(adapter.id, serverAdapter);
+ _currentServer->addAdapter(serverAdapter, adapter.registerProcess);
+
+ AdapterDescriptor adpt;
+ adpt.id = adapter.id;
+ adpt.name = adapter.name;
+ adpt.endpoints = adapter.endpoints;
+ adpt.registerProcess = adapter.registerProcess;
+ _deployed->adapters.push_back(adpt);
+
+ PropertyDescriptor prop;
+ _currentProperties.push_back(prop);
+ prop.name = "# Adapter " + adapter.name;
+ _currentProperties.push_back(prop);
+ prop.name = adapter.name + ".Endpoints";
+ prop.value = adapter.endpoints;
+ _currentProperties.push_back(prop);
+ prop.name = adapter.name + ".AdapterId";
+ prop.value = adapter.id;
+ _currentProperties.push_back(prop);
+ if(adapter.registerProcess)
+ {
+ prop.name = adapter.name + ".RegisterProcess";
+ prop.value = "1";
+ _currentProperties.push_back(prop);
+ }
+ }
+ catch(const AdapterExistsException&)
+ {
+ serverAdapter->destroy();
+ exception("adapter `" + adapter.id + "' already exists");
+ }
+ catch(const Ice::LocalException& ex)
+ {
+ exception("couldn't contact node `" + _currentNodeName + "'", ex);
+ }
+
+ return true;
+}
+
+void
+ServerDeployer::visitObject(const ObjectWrapper&, const ObjectDescriptor& object)
+{
+ assert(_currentServer);
+
+ try
+ {
+ _objectRegistry->add(object);
+ _deployed->adapters.back().objects.push_back(object);
+ }
+ catch(const ObjectExistsException&)
+ {
+ exception("object `" + Ice::identityToString(object.proxy->ice_getIdentity()) + "' already exists");
+ }
+}
+
+ApplicationCleaner::ApplicationCleaner(const NodeRegistryPtr& nodeRegistry,
+ const ApplicationRegistryPtr& applicationRegistry,
+ const ServerRegistryPtr& serverRegistry,
+ const AdapterRegistryPtr& adapterRegistry,
+ const ObjectRegistryPtr& objectRegistry,
+ const Ice::LoggerPtr& logger) :
+ Cleaner(nodeRegistry, applicationRegistry, serverRegistry, adapterRegistry, objectRegistry, logger)
+{
+}
+
+ApplicationCleaner::ApplicationCleaner(const Deployer& deployer) :
+ Cleaner(deployer)
+{
+}
+
+void
+ApplicationCleaner::clean(const ApplicationDescriptorPtr& descriptor)
+{
+ ApplicationWrapper(descriptor).visit(*this);
+}
+
+void
+ApplicationCleaner::visitApplicationEnd(const ApplicationWrapper&, const ApplicationDescriptorPtr& application)
+{
+ try
+ {
+ _applicationRegistry->remove(application->name);
+ }
+ catch(const ApplicationNotExistException&)
+ {
+ exception("application `" + application->name + " doesn't exist");
+ }
+}
+
+bool
+ApplicationCleaner::visitServerStart(const ServerWrapper&, const ServerDescriptorPtr& server)
+{
+ ServerCleaner cleaner(*this);
+ cleaner.clean(server);
+ return false;
+}
+
+ServerCleaner::ServerCleaner(const NodeRegistryPtr& nodeRegistry,
+ const ApplicationRegistryPtr& applicationRegistry,
+ const ServerRegistryPtr& serverRegistry,
+ const AdapterRegistryPtr& adapterRegistry,
+ const ObjectRegistryPtr& objectRegistry,
+ const Ice::LoggerPtr& logger) :
+ Cleaner(nodeRegistry, applicationRegistry, serverRegistry, adapterRegistry, objectRegistry, logger)
+{
+}
+
+ServerCleaner::ServerCleaner(const Deployer& deployer) :
+ Cleaner(deployer)
+{
+}
+
+ServerCleaner::ServerCleaner(const Cleaner& cleaner) :
+ Cleaner(cleaner)
+{
+}
+
+void
+ServerCleaner::clean(const ServerDescriptorPtr& descriptor, const string& backup)
+{
+ _backup = backup;
+ ServerWrapper(descriptor).visit(*this);
+}
+
+bool
+ServerCleaner::visitServerStart(const ServerWrapper&, const ServerDescriptorPtr& server)
+{
+ _currentNodeName = server->node;
+
+ try
+ {
+ _currentServer = _serverRegistry->findByName(server->name);
+ _currentServer->setActivationMode(Manual);
+ _currentServer->stop();
+ }
+ catch(const ServerNotExistException&)
+ {
+ exception("server `" + server->name + "' doesn't exist");
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ _currentServer = 0;
+ }
+ catch(const Ice::LocalException& ex)
+ {
+ exception("couldn't contact node `" + server->node + "'", ex);
+ }
+
+ try
+ {
+ _serverRegistry->remove(server->name);
+ }
+ catch(const ServerNotExistException&)
+ {
+ exception("server `" + server->name + "' doesn't exist");
+ }
+
+ try
+ {
+ if(!server->application.empty())
+ {
+ _applicationRegistry->unregisterServer(server->application, server->name);
+ }
+ }
+ catch(const ApplicationNotExistException&)
+ {
+ exception("application `" + server->application + "' doesn't exist");
+ }
+
+ return true;
+}
+
+void
+ServerCleaner::visitServerEnd(const ServerWrapper&, const ServerDescriptorPtr& server)
+{
+ if(_currentServer)
+ {
+ try
+ {
+ _currentServer->removeConfigFile("config");
+ _currentServer->destroy();
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ }
+ catch(const Ice::LocalException& ex)
+ {
+ exception("couldn't contact node `" + _currentNodeName + "'", ex);
+ }
+ }
+}
+
+bool
+ServerCleaner::visitServiceStart(const ServiceWrapper&, const ServiceDescriptorPtr& service)
+{
+ if(!_currentServer)
+ {
+ return true;
+ }
+
+ try
+ {
+ _currentServer->removeConfigFile("config_" + service->name);
+ }
+ catch(const Ice::LocalException& ex)
+ {
+ exception("couldn't contact node `" + _currentNodeName + "'", ex);
+ }
+
+ return true;
+}
+
+bool
+ServerCleaner::visitAdapterStart(const AdapterWrapper&, const AdapterDescriptor& adapter)
+{
+ AdapterPrx adpt;
+ try
+ {
+ adpt = _adapterRegistry->remove(adapter.id, 0);
+ adpt->destroy();
+ }
+ catch(const AdapterNotExistException&)
+ {
+ exception("adapter `" + adapter.id + "' doesn't exist");
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ }
+ catch(const Ice::LocalException& ex)
+ {
+ exception("couldn't contact node `" + _currentNodeName + "'", ex);
+ }
+
+ if(_currentServer)
+ {
+ try
+ {
+ _currentServer->removeAdapter(ServerAdapterPrx::uncheckedCast(adpt));
+ }
+ catch(const Ice::LocalException& ex)
+ {
+ exception("couldn't contact node `" + _currentNodeName + "'", ex);
+ }
+ }
+
+ return true;
+}
+
+void
+ServerCleaner::visitDbEnv(const DbEnvWrapper&, const DbEnvDescriptor& dbEnv)
+{
+ if(_currentServer)
+ {
+ try
+ {
+ _currentServer->removeDbEnv(dbEnv, _backup);
+ }
+ catch(const Ice::LocalException& ex)
+ {
+ exception("couldn't contact node `" + _currentNodeName + "'", ex);
+ }
+ }
+}
+
+void
+ServerCleaner::visitObject(const ObjectWrapper&, const ObjectDescriptor& object)
+{
+ try
+ {
+ _objectRegistry->remove(object.proxy->ice_getIdentity());
+ }
+ catch(const ObjectNotExistException&)
+ {
+ exception("object `" + Ice::identityToString(object.proxy->ice_getIdentity()) + "' doesn't exist");
+ }
+}
+
+AdminI::AdminI(const CommunicatorPtr& communicator,
+ const NodeRegistryPtr& nodeRegistry,
+ const ApplicationRegistryPtr& applicationRegistry,
+ const ServerRegistryPtr& serverRegistry,
+ const AdapterRegistryPtr& adapterRegistry,
+ const ObjectRegistryPtr& objectRegistry,
+ const RegistryPtr& registry) :
+ _communicator(communicator),
+ _nodeRegistry(nodeRegistry),
+ _applicationRegistry(applicationRegistry),
+ _serverRegistry(serverRegistry),
+ _adapterRegistry(adapterRegistry),
+ _objectRegistry(objectRegistry),
+ _registry(registry)
+{
+}
+
+AdminI::~AdminI()
+{
+}
+
+void
+AdminI::addApplication(const ApplicationDescriptorPtr& descriptor, const Current&)
+{
+ ApplicationDeployer(_nodeRegistry,
+ _applicationRegistry,
+ _serverRegistry,
+ _adapterRegistry,
+ _objectRegistry,
+ _communicator->getLogger()).deploy(descriptor);
+}
+
+void
+AdminI::updateApplication(const ApplicationDescriptorPtr& descriptor, const Current&)
+{
+ ApplicationUpdater(_nodeRegistry,
+ _applicationRegistry,
+ _serverRegistry,
+ _adapterRegistry,
+ _objectRegistry,
+ _communicator->getLogger()).update(descriptor);
+}
+
+void
+AdminI::removeApplication(const string& name, const Current&)
+{
+ ApplicationCleaner(_nodeRegistry,
+ _applicationRegistry,
+ _serverRegistry,
+ _adapterRegistry,
+ _objectRegistry,
+ _communicator->getLogger()).clean(_applicationRegistry->getDescriptor(name));
+}
+
+ApplicationDescriptorPtr
+AdminI::getApplicationDescriptor(const string& name, const Current&) const
+{
+ return _applicationRegistry->getDescriptor(name);
+}
+
+Ice::StringSeq
+AdminI::getAllApplicationNames(const Current&) const
+{
+ return _applicationRegistry->getAll();
+}
+
+void
+AdminI::addServer(const ServerDescriptorPtr& server, const Current&)
+{
+ if(!server->application.empty())
+ {
+ DeploymentException ex;
+ ex.reason = "You need to update the descriptor of the application `" + server->application + "'" +
+ "to add this server.";
+ throw ex;
+ }
+
+ ServerDeployer(_nodeRegistry,
+ _applicationRegistry,
+ _serverRegistry,
+ _adapterRegistry,
+ _objectRegistry,
+ _communicator->getLogger()).deploy(server);
+}
+
+void
+AdminI::updateServer(const ServerDescriptorPtr& server, const Current&)
+{
+ ServerDescriptorPtr orig = _serverRegistry->getDescriptor(server->name);
+ if(!orig->application.empty())
+ {
+ DeploymentException ex;
+ ex.reason = "You need to update the descriptor of the application `" + orig->application + "'" +
+ "to add this server.";
+ throw ex;
+ }
+
+ if(!equal(orig, server))
+ {
+ string dir = _nodeRegistry->findByName(orig->node)->createTmpDir();
+
+ ServerCleaner(_nodeRegistry,
+ _applicationRegistry,
+ _serverRegistry,
+ _adapterRegistry,
+ _objectRegistry,
+ _communicator->getLogger()).clean(orig, dir);
+
+ try
+ {
+ if(server->node == orig->node)
+ {
+ ServerDeployer(_nodeRegistry,
+ _applicationRegistry,
+ _serverRegistry,
+ _adapterRegistry,
+ _objectRegistry,
+ _communicator->getLogger()).deploy(server, dir);
+ }
+ else
+ {
+ ServerDeployer(_nodeRegistry,
+ _applicationRegistry,
+ _serverRegistry,
+ _adapterRegistry,
+ _objectRegistry,
+ _communicator->getLogger()).deploy(server);
+ }
+ }
+ catch(const DeploymentException&)
+ {
+ try
+ {
+ ServerDeployer(_nodeRegistry,
+ _applicationRegistry,
+ _serverRegistry,
+ _adapterRegistry,
+ _objectRegistry,
+ _communicator->getLogger()).deploy(orig, dir);
+ }
+ catch(DeploymentException& ex)
+ {
+ DeploymentException e;
+ e.reason = "Failed to update and rollback original application: " + ex.reason;
+ throw e;
+ }
+ }
+
+ _nodeRegistry->findByName(orig->node)->destroyTmpDir(dir);
+ }
+}
+
+void
+AdminI::removeServer(const string& name, const Current&)
+{
+ ServerDescriptorPtr server = _serverRegistry->getDescriptor(name);
+ if(!server->application.empty())
+ {
+ DeploymentException ex;
+ ex.reason = "You need to update the descriptor of the application `" + server->application + "'" +
+ " to remove this server.";
+ throw ex;
+ }
+
+ ServerCleaner(_nodeRegistry,
+ _applicationRegistry,
+ _serverRegistry,
+ _adapterRegistry,
+ _objectRegistry,
+ _communicator->getLogger()).clean(server);
+}
+
+ServerDescriptorPtr
+AdminI::getServerDescriptor(const string& name, const Current&) const
+{
+ return _serverRegistry->getDescriptor(name);
+}
+
+ServerState
+AdminI::getServerState(const string& name, const Current&) const
+{
+ ServerPrx server = _serverRegistry->findByName(name);
+ try
+ {
+ return server->getState();
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ throw ServerNotExistException();
+ }
+ catch(const Ice::LocalException&)
+ {
+ throw NodeUnreachableException();
+ }
+}
+
+Ice::Int
+AdminI::getServerPid(const string& name, const Current&) const
+{
+ ServerPrx server = _serverRegistry->findByName(name);
+ try
+ {
+ return server->getPid();
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ throw ServerNotExistException();
+ }
+ catch(const Ice::LocalException&)
+ {
+ throw NodeUnreachableException();
+ }
+}
+
+bool
+AdminI::startServer(const string& name, const Current&)
+{
+ ServerPrx server = _serverRegistry->findByName(name);
+ try
+ {
+ return server->start(Manual);
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ throw ServerNotExistException();
+ }
+ catch(const Ice::LocalException&)
+ {
+ throw NodeUnreachableException();
+ }
+}
+
+void
+AdminI::stopServer(const string& name, const Current&)
+{
+ ServerPrx server = _serverRegistry->findByName(name);
+ try
+ {
+ server->stop();
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ throw ServerNotExistException();
+ }
+ catch(const Ice::LocalException&)
+ {
+ throw NodeUnreachableException();
+ }
+}
+
+void
+AdminI::sendSignal(const string& name, const string& signal, const Current&)
+{
+ ServerPrx server = _serverRegistry->findByName(name);
+ try
+ {
+ server->sendSignal(signal);
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ throw ServerNotExistException();
+ }
+ catch(const Ice::LocalException&)
+ {
+ throw NodeUnreachableException();
+ }
+}
+
+void
+AdminI::writeMessage(const string& name, const string& message, Int fd, const Current&)
+{
+ ServerPrx server = _serverRegistry->findByName(name);
+ try
+ {
+ server->writeMessage(message, fd);
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ throw ServerNotExistException();
+ }
+ catch(const Ice::LocalException&)
+ {
+ throw NodeUnreachableException();
+ }
+}
+
+
+StringSeq
+AdminI::getAllServerNames(const Current&) const
+{
+ return _serverRegistry->getAll();
+}
+
+ServerActivation
+AdminI::getServerActivation(const ::std::string& name, const Ice::Current&) const
+{
+ ServerPrx server = _serverRegistry->findByName(name);
+ try
+ {
+ return server->getActivationMode();
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ throw ServerNotExistException();
+ }
+ catch(const Ice::LocalException&)
+ {
+ throw NodeUnreachableException();
+ }
+}
+
+void
+AdminI::setServerActivation(const ::std::string& name, ServerActivation mode, const Ice::Current&)
+{
+ ServerPrx server = _serverRegistry->findByName(name);
+ try
+ {
+ server->setActivationMode(mode);
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ throw ServerNotExistException();
+ }
+ catch(const Ice::LocalException&)
+ {
+ throw NodeUnreachableException();
+ }
+}
+
+string
+AdminI::getAdapterEndpoints(const string& id, const Current&) const
+{
+ AdapterPrx adapter = _adapterRegistry->findById(id);
+ try
+ {
+ return _communicator->proxyToString(adapter->getDirectProxy());
+ }
+ catch(AdapterNotActiveException&)
+ {
+ return "";
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ throw AdapterNotExistException();
+ }
+ catch(const Ice::LocalException&)
+ {
+ throw NodeUnreachableException();
+ }
+}
+
+StringSeq
+AdminI::getAllAdapterIds(const Current&) const
+{
+ return _adapterRegistry->getAll();
+}
+
+void
+AdminI::addObject(const Ice::ObjectPrx& proxy, const ::Ice::Current& current)
+{
+ ObjectDescriptor desc;
+ desc.proxy = proxy;
+
+ try
+ {
+ addObjectWithType(proxy, proxy->ice_id(), current);
+ }
+ catch(const Ice::LocalException&)
+ {
+ DeploymentException ex;
+ ex.reason = "Couldn't invoke on the object to get its interface.";
+ throw ex;
+ }
+}
+
+void
+AdminI::addObjectWithType(const Ice::ObjectPrx& proxy, const string& type, const ::Ice::Current&)
+{
+ ObjectDescriptor desc;
+ desc.proxy = proxy;
+ desc.type = type;
+ _objectRegistry->add(desc);
+}
+
+void
+AdminI::removeObject(const Ice::Identity& id, const Ice::Current&)
+{
+ _objectRegistry->remove(id);
+}
+
+ObjectDescriptor
+AdminI::getObjectDescriptor(const Ice::Identity& id, const Ice::Current&) const
+{
+ return _objectRegistry->getObjectDescriptor(id);
+}
+
+ObjectDescriptorSeq
+AdminI::getAllObjectDescriptors(const string& expression, const Ice::Current&) const
+{
+ return _objectRegistry->findAll(expression);
+}
+
+bool
+AdminI::pingNode(const string& name, const Current&) const
+{
+ NodePrx node = _nodeRegistry->findByName(name);
+ try
+ {
+ node->ice_ping();
+ return true;
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ throw NodeNotExistException();
+ }
+ catch(const Ice::LocalException&)
+ {
+ return false;
+ }
+}
+
+void
+AdminI::shutdownNode(const string& name, const Current&)
+{
+ NodePrx node = _nodeRegistry->findByName(name);
+ try
+ {
+ node->shutdown();
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ throw NodeNotExistException();
+ }
+ catch(const Ice::LocalException&)
+ {
+ throw NodeUnreachableException();
+ }
+}
+
+void
+AdminI::removeNode(const string& name, const Current&)
+{
+ //
+ // Remove the node servers.
+ //
+ ServerDescriptorSeq servers = _serverRegistry->getAllDescriptorsOnNode(name);
+ for(ServerDescriptorSeq::const_iterator p = servers.begin(); p != servers.end(); ++p)
+ {
+ ServerCleaner(_nodeRegistry,
+ _applicationRegistry,
+ _serverRegistry,
+ _adapterRegistry,
+ _objectRegistry,
+ _communicator->getLogger()).clean(*p);
+ }
+
+ //
+ // Remove the node.
+ //
+ _nodeRegistry->remove(name);
+}
+
+string
+AdminI::getNodeHostname(const string& name, const Current&) const
+{
+ NodePrx node = _nodeRegistry->findByName(name);
+ try
+ {
+ return node->getHostname();
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ throw NodeNotExistException();
+ }
+ catch(const Ice::LocalException&)
+ {
+ throw NodeUnreachableException();
+ }
+}
+
+
+StringSeq
+AdminI::getAllNodeNames(const Current&) const
+{
+ return _nodeRegistry->getAll();
+}
+
+void
+AdminI::shutdown(const Current&)
+{
+ _registry->shutdown();
+}
+
+SliceChecksumDict
+AdminI::getSliceChecksums(const Current&) const
+{
+ return sliceChecksums();
+}
diff --git a/cpp/src/IceGrid/AdminI.h b/cpp/src/IceGrid/AdminI.h
new file mode 100644
index 00000000000..d0cd6e13cfd
--- /dev/null
+++ b/cpp/src/IceGrid/AdminI.h
@@ -0,0 +1,83 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 ICE_GRID_ADMIN_I_H
+#define ICE_GRID_ADMIN_I_H
+
+#include <IceGrid/Internal.h>
+
+namespace IceGrid
+{
+
+class Registry;
+typedef IceUtil::Handle<Registry> RegistryPtr;
+
+class AdminI : public Admin, public IceUtil::Mutex
+{
+public:
+
+ AdminI(const Ice::CommunicatorPtr&, const NodeRegistryPtr&, const ApplicationRegistryPtr&,
+ const ServerRegistryPtr&, const AdapterRegistryPtr&, const ObjectRegistryPtr&,
+ const RegistryPtr&);
+ virtual ~AdminI();
+
+ virtual void addApplication(const ApplicationDescriptorPtr&, const Ice::Current&);
+ virtual void updateApplication(const ApplicationDescriptorPtr&, const Ice::Current&);
+ virtual void removeApplication(const std::string&, const Ice::Current&);
+ virtual ApplicationDescriptorPtr getApplicationDescriptor(const ::std::string&, const Ice::Current&) const;
+ virtual Ice::StringSeq getAllApplicationNames(const Ice::Current&) const;
+
+ virtual void addServer(const ServerDescriptorPtr&, const Ice::Current&);
+ virtual void updateServer(const ServerDescriptorPtr&, const Ice::Current&);
+ virtual void removeServer(const ::std::string&, const Ice::Current&);
+ virtual ServerDescriptorPtr getServerDescriptor(const ::std::string&, const Ice::Current&) const;
+
+ virtual ServerState getServerState(const ::std::string&, const Ice::Current&) const;
+ virtual Ice::Int getServerPid(const ::std::string&, const Ice::Current&) const;
+ virtual bool startServer(const ::std::string&, const Ice::Current&);
+ virtual void stopServer(const ::std::string&, const Ice::Current&);
+ virtual void sendSignal(const ::std::string&, const ::std::string&, const Ice::Current&);
+ virtual void writeMessage(const ::std::string&, const ::std::string&, Ice::Int, const Ice::Current&);
+ virtual Ice::StringSeq getAllServerNames(const Ice::Current&) const;
+ virtual ServerActivation getServerActivation(const ::std::string&, const Ice::Current&) const;
+ virtual void setServerActivation(const ::std::string&, ServerActivation, const Ice::Current&);
+
+ virtual ::std::string getAdapterEndpoints(const ::std::string&, const ::Ice::Current&) const;
+ virtual Ice::StringSeq getAllAdapterIds(const ::Ice::Current&) const;
+
+ virtual void addObject(const ::Ice::ObjectPrx&, const ::Ice::Current&);
+ virtual void addObjectWithType(const ::Ice::ObjectPrx&, const ::std::string&, const ::Ice::Current&);
+ virtual void removeObject(const ::Ice::Identity&, const ::Ice::Current&);
+ virtual ObjectDescriptor getObjectDescriptor(const Ice::Identity&, const ::Ice::Current&) const;
+ virtual ObjectDescriptorSeq getAllObjectDescriptors(const std::string&, const ::Ice::Current&) const;
+
+ virtual bool pingNode(const std::string&, const Ice::Current&) const;
+ virtual void shutdownNode(const std::string&, const Ice::Current&);
+ virtual void removeNode(const std::string&, const Ice::Current&);
+ virtual std::string getNodeHostname(const std::string&, const Ice::Current&) const;
+ virtual Ice::StringSeq getAllNodeNames(const ::Ice::Current&) const;
+
+ virtual void shutdown(const Ice::Current&);
+
+ virtual Ice::SliceChecksumDict getSliceChecksums(const Ice::Current&) const;
+
+private:
+
+ Ice::CommunicatorPtr _communicator;
+ NodeRegistryPtr _nodeRegistry;
+ ApplicationRegistryPtr _applicationRegistry;
+ ServerRegistryPtr _serverRegistry;
+ AdapterRegistryPtr _adapterRegistry;
+ ObjectRegistryPtr _objectRegistry;
+ RegistryPtr _registry;
+};
+
+}
+
+#endif
diff --git a/cpp/src/IceGrid/ApplicationRegistryI.cpp b/cpp/src/IceGrid/ApplicationRegistryI.cpp
new file mode 100644
index 00000000000..54792222548
--- /dev/null
+++ b/cpp/src/IceGrid/ApplicationRegistryI.cpp
@@ -0,0 +1,157 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 <IceGrid/ApplicationRegistryI.h>
+#include <IceGrid/TraceLevels.h>
+#include <Freeze/Initialize.h>
+
+using namespace std;
+using namespace IceGrid;
+
+const string ApplicationRegistryI::_dbName = "applicationregistry";
+
+ApplicationRegistryI::ApplicationRegistryI(const Ice::CommunicatorPtr& communicator,
+ const ServerRegistryPtr& serverRegistry,
+ const string& envName,
+ const TraceLevelsPtr& traceLevels) :
+ _serverRegistry(serverRegistry),
+ _connectionCache(Freeze::createConnection(communicator, envName)),
+ _dictCache(_connectionCache, _dbName),
+ _traceLevels(traceLevels),
+ _envName(envName),
+ _communicator(communicator)
+{
+}
+
+void
+ApplicationRegistryI::add(const string& name, const Ice::Current&)
+{
+ Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName);
+ StringStringSeqDict dict(connection, _dbName);
+
+ StringStringSeqDict::iterator p = dict.find(name);
+ if(p != dict.end())
+ {
+ throw ApplicationExistsException();
+ }
+
+ dict.put(pair<const string, const Ice::StringSeq>(name, Ice::StringSeq()));
+
+ if(_traceLevels->applicationRegistry > 0)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->applicationRegistryCat);
+ out << "added application `" << name << "'";
+ }
+}
+
+void
+ApplicationRegistryI::remove(const string& name, const Ice::Current&)
+{
+ Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName);
+ StringStringSeqDict dict(connection, _dbName);
+
+ StringStringSeqDict::iterator p = dict.find(name);
+ if(p == dict.end())
+ {
+ throw ApplicationNotExistException();
+ }
+
+ dict.erase(p);
+
+ if(_traceLevels->applicationRegistry > 0)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->applicationRegistryCat);
+ out << "removed application `" << name << "'";
+ }
+}
+
+void
+ApplicationRegistryI::registerServer(const string& application, const string& name, const Ice::Current&)
+{
+ Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName);
+ StringStringSeqDict dict(connection, _dbName);
+
+ StringStringSeqDict::iterator p = dict.find(application);
+ if(p == dict.end())
+ {
+ throw ApplicationNotExistException();
+ }
+
+ Ice::StringSeq servers = p->second;
+ servers.push_back(name);
+ p.set(servers);
+}
+
+void
+ApplicationRegistryI::unregisterServer(const string& application, const string& name, const Ice::Current&)
+{
+ Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName);
+ StringStringSeqDict dict(connection, _dbName);
+
+ StringStringSeqDict::iterator p = dict.find(application);
+ if(p == dict.end())
+ {
+ throw ApplicationNotExistException();
+ }
+
+ Ice::StringSeq servers = p->second;
+ for(Ice::StringSeq::iterator q = servers.begin(); q != servers.end(); ++q)
+ {
+ if(*q == name)
+ {
+ servers.erase(q);
+ break;
+ }
+ }
+ p.set(servers);
+}
+
+ApplicationDescriptorPtr
+ApplicationRegistryI::getDescriptor(const string& name, const Ice::Current&)
+{
+ Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName);
+ StringStringSeqDict dict(connection, _dbName);
+
+ StringStringSeqDict::iterator p = dict.find(name);
+ if(p == dict.end())
+ {
+ throw ApplicationNotExistException();
+ }
+
+ ApplicationDescriptorPtr descriptor = new ApplicationDescriptor();
+ descriptor->name = name;
+ for(Ice::StringSeq::const_iterator q = p->second.begin(); q != p->second.end(); ++q)
+ {
+ try
+ {
+ descriptor->servers.push_back(_serverRegistry->getDescriptor(*q));
+ }
+ catch(ServerNotExistException&)
+ {
+ }
+ }
+ return descriptor;
+}
+
+Ice::StringSeq
+ApplicationRegistryI::getAll(const Ice::Current&) const
+{
+ Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName);
+ StringStringSeqDict dict(connection, _dbName);
+
+ Ice::StringSeq names;
+ names.reserve(dict.size());
+
+ for(StringStringSeqDict::const_iterator p = dict.begin(); p != dict.end(); ++p)
+ {
+ names.push_back(p->first);
+ }
+
+ return names;
+}
diff --git a/cpp/src/IceGrid/ApplicationRegistryI.h b/cpp/src/IceGrid/ApplicationRegistryI.h
new file mode 100644
index 00000000000..fbe5efe3b93
--- /dev/null
+++ b/cpp/src/IceGrid/ApplicationRegistryI.h
@@ -0,0 +1,52 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 ICE_GRID_APPLICATION_REGISTRY_I_H
+#define ICE_GRID_APPLICATION_REGISTRY_I_H
+
+#include <IceGrid/Internal.h>
+#include <IceGrid/StringStringSeqDict.h>
+
+namespace IceGrid
+{
+
+class TraceLevels;
+typedef IceUtil::Handle<TraceLevels> TraceLevelsPtr;
+
+class ApplicationRegistryI : public ApplicationRegistry
+{
+public:
+
+ ApplicationRegistryI(const Ice::CommunicatorPtr&, const ServerRegistryPtr&, const std::string&,
+ const TraceLevelsPtr&);
+
+ virtual void add(const std::string&, const ::Ice::Current&);
+ virtual void remove(const std::string&, const ::Ice::Current&);
+
+ virtual void registerServer(const std::string&, const std::string&, const Ice::Current&);
+ virtual void unregisterServer(const std::string&, const std::string&, const Ice::Current&);
+
+ virtual ApplicationDescriptorPtr getDescriptor(const ::std::string&, const Ice::Current&);
+ virtual Ice::StringSeq getAll(const ::Ice::Current&) const;
+
+private:
+
+ static const std::string _dbName;
+
+ ServerRegistryPtr _serverRegistry;
+ Freeze::ConnectionPtr _connectionCache;
+ StringStringSeqDict _dictCache;
+ TraceLevelsPtr _traceLevels;
+ const std::string _envName;
+ const Ice::CommunicatorPtr _communicator;
+};
+
+}
+
+#endif
diff --git a/cpp/src/IceGrid/DescriptorParser.cpp b/cpp/src/IceGrid/DescriptorParser.cpp
new file mode 100644
index 00000000000..ea175e8f467
--- /dev/null
+++ b/cpp/src/IceGrid/DescriptorParser.cpp
@@ -0,0 +1,821 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 <IceXML/Parser.h>
+#include <IceGrid/Admin.h>
+#include <IceGrid/DescriptorParser.h>
+
+#include <stack>
+#include <fstream>
+
+using namespace std;
+using namespace Ice;
+using namespace IceGrid;
+
+namespace IceGrid
+{
+
+class DescriptorHandler : public IceXML::Handler
+{
+public:
+
+ DescriptorHandler(const string&);
+
+ void setCommunicator(const Ice::CommunicatorPtr&);
+ void setVariables(const std::map<std::string, std::string>&);
+ void setTargets(const std::vector<std::string>&);
+
+ virtual void startElement(const string&, const IceXML::Attributes&, int, int);
+ virtual void endElement(const string&, int, int);
+ virtual void characters(const string&, int, int);
+ virtual void error(const string&, int, int);
+
+ const ApplicationDescriptorPtr& getApplicationDescriptor() const;
+ const ServerDescriptorPtr& getServerDescriptor() const;
+
+private:
+
+ std::string getAttributeValue(const IceXML::Attributes&, const std::string&) const;
+ std::string getAttributeValueWithDefault(const IceXML::Attributes&, const std::string&, const std::string&) const;
+ bool isCurrentTargetDeployable() const;
+ std::string substitute(const std::string&) const;
+ std::string elementValue() const;
+ std::vector<std::string> getTargets(const std::string&) const;
+ void error(const string&) const;
+
+ const std::string& getVariable(const std::string&) const;
+ bool hasVariable(const std::string&) const;
+ bool isTargetDeployable(const std::string&) const;
+
+ Ice::CommunicatorPtr _communicator;
+ string _filename;
+ std::vector<std::string> _targets;
+ std::vector< std::map<std::string, std::string> > _variables;
+ std::stack<std::string> _elements;
+ int _targetCounter;
+ bool _isCurrentTargetDeployable;
+ int _line;
+ int _column;
+
+ ApplicationDescriptorPtr _currentApplication;
+ ServerDescriptorPtr _currentServer;
+ ServiceDescriptorPtr _currentService;
+ ComponentDescriptorPtr _currentComponent;
+ AdapterDescriptor _currentAdapter;
+ DbEnvDescriptor _currentDbEnv;
+
+ bool _isTopLevel;
+ bool _inProperties;
+ bool _inAdapters;
+};
+
+}
+
+DescriptorHandler::DescriptorHandler(const string& filename) :
+ _filename(filename),
+ _isCurrentTargetDeployable(true),
+ _isTopLevel(true),
+ _inProperties(false),
+ _inAdapters(false)
+{
+ _variables.push_back(map<string, string>());
+}
+
+void
+DescriptorHandler::setCommunicator(const Ice::CommunicatorPtr& communicator)
+{
+ _communicator = communicator;
+}
+
+void
+DescriptorHandler::setVariables(const std::map<std::string, std::string>& variables)
+{
+ _variables.clear();
+ _variables.push_back(variables);
+}
+
+void
+DescriptorHandler::setTargets(const vector<string>& targets)
+{
+ _targets = targets;
+}
+
+void
+DescriptorHandler::startElement(const string& name, const IceXML::Attributes& attrs, int line, int column)
+{
+ _line = line;
+ _column = column;
+
+ if(name == "icegrid")
+ {
+ if(!_isTopLevel)
+ {
+ error("element <icegrid> is a top level element");
+ }
+ _isTopLevel = false;
+ }
+ else if(_isTopLevel)
+ {
+ error("only the <icegrid> element is allowed at the top-level");
+ }
+ else if(name == "target")
+ {
+ if(!_isCurrentTargetDeployable)
+ {
+ ++_targetCounter;
+ }
+ else
+ {
+ _isCurrentTargetDeployable = isTargetDeployable(getAttributeValue(attrs, "name"));
+ _targetCounter = 1;
+ return;
+ }
+ }
+ else if(!isCurrentTargetDeployable())
+ {
+ //
+ // We don't bother to parse the elements if the elements are enclosed in a target element
+ // which won't be deployed.
+ //
+ return;
+ }
+ else if(name == "include")
+ {
+ _variables.push_back(map<string, string>());
+
+ string file;
+ string targets;
+
+ for(IceXML::Attributes::const_iterator p = attrs.begin(); p != attrs.end(); ++p)
+ {
+ if(p->first == "descriptor")
+ {
+ file = substitute(p->second);
+ }
+ else if(p->first == "targets")
+ {
+ targets = substitute(p->second);
+ }
+ else
+ {
+ string v = substitute(p->second);
+ _variables.back()[p->first] = v;
+ }
+ }
+
+ if(file.empty())
+ {
+ error("attribute `descriptor' is mandatory in element <include>");
+ }
+
+ if(file[0] != '/')
+ {
+ string::size_type end = _filename.find_last_of('/');
+ if(end != string::npos)
+ {
+ file = _filename.substr(0, end) + "/" + file;
+ }
+ }
+
+ string oldFileName = _filename;
+ vector<string> oldTargets = _targets;
+ _isTopLevel = true;
+ _filename = file;
+ _targets = getTargets(targets);
+
+ IceXML::Parser::parse(file, *this);
+
+ _variables.pop_back();
+ _filename = oldFileName;
+ _targets = oldTargets;
+ }
+ else if(name == "application")
+ {
+ if(_currentApplication)
+ {
+ error("only one <application> element is allowed");
+ }
+ _currentApplication = new ApplicationDescriptor();
+ _currentApplication->name = getAttributeValue(attrs, "name");
+ _variables.back()["application"] = _currentApplication->name;
+ }
+ else if(name == "node")
+ {
+ _variables.back()["node"] = getAttributeValue(attrs, "name");
+ }
+ else if(name == "server")
+ {
+ if(!hasVariable("node"))
+ {
+ error("the <server> element can only be a child of a <node> element");
+ }
+
+ string kind = getAttributeValue(attrs, "kind");
+ if(kind == "cpp" || kind == "cs")
+ {
+ _currentServer = new ServerDescriptor();
+ _currentServer->exe = getAttributeValue(attrs, "exe");
+ }
+ else if(kind == "java")
+ {
+ JavaServerDescriptorPtr descriptor = new JavaServerDescriptor();
+ _currentServer = descriptor;
+ _currentServer->exe = getAttributeValueWithDefault(attrs, "exe", "java");
+ descriptor->className = getAttributeValue(attrs, "classname");
+ }
+ else if(kind == "cpp-icebox")
+ {
+ _currentServer = new CppIceBoxDescriptor();
+ _currentServer->exe = getAttributeValueWithDefault(attrs, "exe", "icebox");
+ }
+ else if(kind == "java-icebox")
+ {
+ JavaIceBoxDescriptorPtr descriptor = new JavaIceBoxDescriptor();
+ _currentServer = descriptor;
+ _currentServer->exe = getAttributeValueWithDefault(attrs, "exe", "java");
+ descriptor->className = getAttributeValueWithDefault(attrs, "classname", "IceBox.Server");
+ }
+
+ _currentServer->name = getAttributeValue(attrs, "name");
+ _currentServer->node = getVariable("node");
+ _currentServer->pwd = getAttributeValueWithDefault(attrs, "pwd", "");
+ _currentServer->activation =
+ getAttributeValueWithDefault(attrs, "activation", "manual") == "on-demand" ? OnDemand : Manual;
+
+ if(_currentApplication)
+ {
+ _currentServer->application = _currentApplication->name;
+ }
+
+ if(kind == "cpp-icebox" || kind == "java-icebox")
+ {
+ CppIceBoxDescriptorPtr cppIceBox = CppIceBoxDescriptorPtr::dynamicCast(_currentServer);
+ if(cppIceBox)
+ {
+ cppIceBox->endpoints = getAttributeValue(attrs, "endpoints");
+ }
+ JavaIceBoxDescriptorPtr javaIceBox = JavaIceBoxDescriptorPtr::dynamicCast(_currentServer);
+ if(javaIceBox)
+ {
+ javaIceBox->endpoints = getAttributeValue(attrs, "endpoints");
+ }
+
+ PropertyDescriptor prop;
+ prop.name = "IceBox.ServiceManager.Identity";
+ prop.value = _currentServer->name + "/ServiceManager";
+ _currentServer->properties.push_back(prop);
+
+ AdapterDescriptor adapter;
+ adapter.name = "IceBox.ServiceManager";
+ adapter.endpoints = getAttributeValue(attrs, "endpoints");
+ adapter.id = _currentServer->name + "." + adapter.name;
+ adapter.registerProcess = true;
+ _currentServer->adapters.push_back(adapter);
+ }
+
+ _currentComponent = _currentServer;
+ _variables.back()["server"] = _currentServer->name;
+ }
+ else if(name == "service")
+ {
+ if(!CppIceBoxDescriptorPtr::dynamicCast(_currentServer) &&
+ !JavaIceBoxDescriptorPtr::dynamicCast(_currentServer))
+ {
+ error("element <service> can only be a child of an IceBox <server> element");
+ }
+
+ _currentService = new ServiceDescriptor();
+ _currentService->name = getAttributeValue(attrs, "name");
+ _currentService->entry = getAttributeValue(attrs, "entry");
+
+ _currentComponent = _currentService;
+ _variables.back()["service"] = _currentService->name;
+ }
+ else if(name == "variable")
+ {
+ _variables.back()[getAttributeValue(attrs, "name")] = getAttributeValueWithDefault(attrs, "value", "");
+ }
+ else if(name == "properties")
+ {
+ if(!_currentComponent)
+ {
+ error("the <properties> element can only be a child of a <server> or <service> element");
+ }
+
+ _inProperties = true;
+ }
+ else if(name == "property")
+ {
+ if(!_inProperties)
+ {
+ error("the <property> element can only be a child of a <properties> element");
+ }
+
+ PropertyDescriptor prop;
+ prop.name = getAttributeValue(attrs, "name");
+ prop.value = getAttributeValueWithDefault(attrs, "value", "");
+ _currentComponent->properties.push_back(prop);
+ }
+ else if(name == "adapters")
+ {
+ if(!_currentComponent)
+ {
+ error("the <adapters> element can only be a child of a <server> or <service> element");
+ }
+
+ _inAdapters = true;
+ }
+ else if(name == "adapter")
+ {
+ if(!_inAdapters)
+ {
+ error("the <adapter> element can only be a child of an <adapters> element");
+ }
+
+ _currentAdapter.name = getAttributeValue(attrs, "name");
+ _currentAdapter.id = getAttributeValueWithDefault(attrs, "id", "");
+ if(_currentAdapter.id.empty())
+ {
+ string service = getVariable("service");
+ const string fqn = getVariable("server") + (service.empty() ? "" : ".") + service;
+ _currentAdapter.id = fqn + "." + _currentAdapter.name;
+ }
+ _currentAdapter.endpoints = getAttributeValue(attrs, "endpoints");
+ _currentAdapter.registerProcess = getAttributeValueWithDefault(attrs, "register", "false") == "true";
+ }
+ else if(name == "object")
+ {
+ if(_currentAdapter.name.empty())
+ {
+ error("the <object> element can only be a child of an <adapter> element");
+ }
+
+ ObjectDescriptor object;
+ object.type = getAttributeValueWithDefault(attrs, "type", "");
+ object.proxy = _communicator->stringToProxy(getAttributeValue(attrs, "identity") + "@" + _currentAdapter.id);
+ object.adapterId = _currentAdapter.id;
+ _currentAdapter.objects.push_back(object);
+ }
+ else if(name == "dbenv")
+ {
+ if(!_currentComponent)
+ {
+ error("the <dbenv> element can only be a child of a <server> or <service> element");
+ }
+
+ _currentDbEnv.name = getAttributeValue(attrs, "name");
+
+ DbEnvDescriptorSeq::iterator p;
+ for(p = _currentComponent->dbEnvs.begin(); p != _currentComponent->dbEnvs.end(); ++p)
+ {
+ //
+ // We are re-opening the dbenv element to define more properties.
+ //
+ if(p->name == _currentDbEnv.name)
+ {
+ break;
+ }
+ }
+
+ if(p != _currentComponent->dbEnvs.end())
+ {
+ //
+ // Remove the previously defined dbenv, we'll add it back again when
+ // the dbenv element end tag is reached.
+ //
+ _currentDbEnv = *p;
+ _currentComponent->dbEnvs.erase(p);
+ }
+
+ if(_currentDbEnv.dbHome.empty())
+ {
+ _currentDbEnv.dbHome = getAttributeValueWithDefault(attrs, "home", "");
+ }
+ }
+ else if(name == "dbproperty")
+ {
+ if(_currentDbEnv.name.empty())
+ {
+ error("the <dbproperty> element can only be a child of a <dbenv> element");
+ }
+
+ PropertyDescriptor prop;
+ prop.name = getAttributeValue(attrs, "name");
+ prop.value = getAttributeValueWithDefault(attrs, "value", "");
+ _currentDbEnv.properties.push_back(prop);
+ }
+
+ _elements.push("");
+}
+
+void
+DescriptorHandler::endElement(const string& name, int line, int column)
+{
+ _line = line;
+ _column = column;
+
+ if(name == "target")
+ {
+ if(!_isCurrentTargetDeployable && --_targetCounter == 0)
+ {
+ _isCurrentTargetDeployable = true;
+ _targetCounter = 0;
+ }
+ return;
+ }
+ else if(!isCurrentTargetDeployable())
+ {
+ //
+ // We don't bother to parse the elements if the elements are enclosed in a target element
+ // which won't be deployed.
+ //
+ return;
+ }
+ else if(name == "application")
+ {
+ _variables.back()["application"] = "";
+ }
+ else if(name == "node")
+ {
+ _variables.back()["node"] = "";
+ }
+ else if(name == "server")
+ {
+ if(_currentApplication)
+ {
+ _currentApplication->servers.push_back(_currentServer);
+ _currentServer = 0;
+ }
+ _currentComponent = 0;
+ _variables.back()["server"] = "";
+ }
+ else if(name == "service")
+ {
+ CppIceBoxDescriptorPtr cppIceBox = CppIceBoxDescriptorPtr::dynamicCast(_currentServer);
+ if(cppIceBox)
+ {
+ cppIceBox->services.push_back(_currentService);
+ }
+ JavaIceBoxDescriptorPtr javaIceBox = JavaIceBoxDescriptorPtr::dynamicCast(_currentServer);
+ if(javaIceBox)
+ {
+ javaIceBox->services.push_back(_currentService);
+ }
+ _currentService = 0;
+ _currentComponent = _currentServer;
+ _variables.back()["service"] = "";
+ }
+ else if(name == "comment")
+ {
+ if(_currentComponent)
+ {
+ _currentComponent->comment = elementValue();
+ }
+ else if(_currentApplication)
+ {
+ _currentApplication->comment = elementValue();
+ }
+ }
+ else if(name == "option")
+ {
+ if(!_currentServer)
+ {
+ error("element <option> can only be the child of a <server> element");
+ }
+ _currentServer->options.push_back(elementValue());
+ }
+ else if(name == "env")
+ {
+ if(!_currentServer)
+ {
+ error("element <env> can only be the child of a <server> element");
+ }
+ _currentServer->envs.push_back(elementValue());
+ }
+ else if(name == "jvm-option")
+ {
+ JavaServerDescriptorPtr descriptor = JavaServerDescriptorPtr::dynamicCast(_currentServer);
+ if(!descriptor)
+ {
+ error("element <jvm-option> can only be the child of a Java <server> element");
+ }
+ descriptor->jvmOptions.push_back(elementValue());
+ }
+ else if(name == "properties")
+ {
+ _inProperties = false;
+ }
+ else if(name == "adapters")
+ {
+ _inAdapters = false;
+ }
+ else if(name == "adapter")
+ {
+ _currentComponent->adapters.push_back(_currentAdapter);
+ _currentAdapter = AdapterDescriptor();
+ }
+ else if(name == "dbenv")
+ {
+ _currentComponent->dbEnvs.push_back(_currentDbEnv);
+ _currentDbEnv = DbEnvDescriptor();
+ }
+
+ _elements.pop();
+}
+
+void
+DescriptorHandler::characters(const string& chars, int, int)
+{
+ _elements.top().assign(chars);
+}
+
+void
+DescriptorHandler::error(const string& msg, int line, int column)
+{
+ ostringstream os;
+ os << "error in <" << _filename << "> descriptor, line " << line << ", column " << column << ":\n" << msg;
+ throw IceXML::ParserException(__FILE__, __LINE__, os.str());
+}
+
+const ApplicationDescriptorPtr&
+DescriptorHandler::getApplicationDescriptor() const
+{
+ if(!_currentApplication)
+ {
+ error("no application descriptor defined in this file");
+ }
+ return _currentApplication;
+}
+
+const ServerDescriptorPtr&
+DescriptorHandler::getServerDescriptor() const
+{
+ if(!_currentServer)
+ {
+ error("no server descriptor defined in this file");
+ }
+ return _currentServer;
+}
+
+string
+DescriptorHandler::getAttributeValue(const IceXML::Attributes& attrs, const string& name) const
+{
+ IceXML::Attributes::const_iterator p = attrs.find(name);
+ if(p == attrs.end())
+ {
+ error("missing attribute '" + name + "'");
+ }
+ string v = substitute(p->second);
+ if(v.empty())
+ {
+ error("attribute '" + name + "' is empty");
+ }
+ return v;
+}
+
+string
+DescriptorHandler::getAttributeValueWithDefault(const IceXML::Attributes& attrs,
+ const string& name,
+ const string& def) const
+{
+ IceXML::Attributes::const_iterator p = attrs.find(name);
+ if(p == attrs.end())
+ {
+ return substitute(def);
+ }
+ else
+ {
+ return substitute(p->second);
+ }
+}
+
+bool
+DescriptorHandler::isCurrentTargetDeployable() const
+{
+ return _isCurrentTargetDeployable;
+}
+
+vector<string>
+DescriptorHandler::getTargets(const string& targets) const
+{
+ vector<string> result;
+
+ if(!targets.empty())
+ {
+ const string delim = " \t\n\r";
+
+ string::size_type beg = 0;
+ string::size_type end = 0;
+ do
+ {
+ end = targets.find_first_of(delim, end);
+ if(end == string::npos)
+ {
+ end = targets.size();
+ }
+
+ result.push_back(targets.substr(beg, end - beg));
+ beg = ++end;
+ }
+ while(end < targets.size());
+ }
+
+ copy(_targets.begin(), _targets.end(), back_inserter(result));
+
+ return result;
+}
+
+void
+DescriptorHandler::error(const string& msg) const
+{
+ ostringstream os;
+ os << "error in <" << _filename << "> descriptor, line " << _line << ", column " << _column << ":\n" << msg;
+ throw IceXML::ParserException(__FILE__, __LINE__, os.str());
+}
+
+const string&
+DescriptorHandler::getVariable(const string& name) const
+{
+ static const string empty;
+
+ vector< map< string, string> >::const_reverse_iterator p = _variables.rbegin();
+ while(p != _variables.rend())
+ {
+ map<string, string>::const_iterator q = p->find(name);
+ if(q != p->end())
+ {
+ return q->second;
+ }
+ ++p;
+ }
+ return empty;
+}
+
+string
+DescriptorHandler::substitute(const string& v) const
+{
+ string value(v);
+ string::size_type beg = 0;
+ string::size_type end = 0;
+
+ while((beg = value.find("${", beg)) != string::npos)
+ {
+ end = value.find("}", beg);
+
+ if(end == string::npos)
+ {
+ error("malformed variable name in the '" + value + "' value");
+ }
+
+ string name = value.substr(beg + 2, end - beg - 2);
+ if(!hasVariable(name))
+ {
+ error("unknown variable `" + name + "'");
+ }
+ else
+ {
+ value.replace(beg, end - beg + 1, getVariable(name));
+ }
+ }
+
+ return value;
+}
+
+string
+DescriptorHandler::elementValue() const
+{
+ return substitute(_elements.top());
+}
+
+bool
+DescriptorHandler::hasVariable(const string& name) const
+{
+ vector< map< string, string> >::const_reverse_iterator p = _variables.rbegin();
+ while(p != _variables.rend())
+ {
+ map<string, string>::const_iterator q = p->find(name);
+ if(q != p->end())
+ {
+ return true;
+ }
+ ++p;
+ }
+ return false;
+}
+
+bool
+DescriptorHandler::isTargetDeployable(const string& target) const
+{
+ string application = getVariable("application");
+ string node = getVariable("node");
+ string server = getVariable("server");
+ string service = getVariable("service");
+
+ //
+ // Compute the current fully qualified name of the component.
+ //
+ string fqn;
+ if(!application.empty())
+ {
+ fqn = application;
+ if(!node.empty())
+ {
+ fqn += "." + node;
+ }
+ }
+ else
+ {
+ if(!node.empty())
+ {
+ fqn = node;
+ }
+ }
+ if(!server.empty())
+ {
+ assert(!node.empty());
+ fqn += "." + server;
+ }
+ if(!service.empty())
+ {
+ assert(!server.empty());
+ fqn += "." + service;
+ }
+
+ //
+ // Go through the list of supplied targets and see if we can match one with the current component + target.
+ //
+ for(vector<string>::const_iterator p = _targets.begin(); p != _targets.end(); ++p)
+ {
+ if((*p) == target)
+ {
+ //
+ // A supplied target without any component prefix is matching the target.
+ //
+ return true;
+ }
+ else
+ {
+ string componentTarget;
+ string::size_type end = 0;
+ while(end != string::npos)
+ {
+ //
+ // Add the first component name from the component fully qualified name to the
+ // target and see if matches.
+ //
+ end = fqn.find('.', end);
+ if(end == string::npos)
+ {
+ componentTarget = fqn + "." + target;
+ }
+ else
+ {
+ componentTarget = fqn.substr(0, end) + "." + target;
+ ++end;
+ }
+
+ if((*p) == componentTarget)
+ {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+ApplicationDescriptorPtr
+DescriptorParser::parseApplicationDescriptor(const string& descriptor,
+ const Ice::StringSeq& targets,
+ const map<string, string>& variables,
+ const Ice::CommunicatorPtr& communicator)
+{
+ DescriptorHandler handler(descriptor);
+ handler.setCommunicator(communicator);
+ handler.setTargets(targets);
+ handler.setVariables(variables);
+ IceXML::Parser::parse(descriptor, handler);
+ return handler.getApplicationDescriptor();
+}
+
+ServerDescriptorPtr
+DescriptorParser::parseServerDescriptor(const string& descriptor,
+ const Ice::StringSeq& targets,
+ const map<string, string>& variables,
+ const Ice::CommunicatorPtr& communicator)
+{
+ DescriptorHandler handler(descriptor);
+ handler.setCommunicator(communicator);
+ handler.setTargets(targets);
+ handler.setVariables(variables);
+ IceXML::Parser::parse(descriptor, handler);
+ return handler.getServerDescriptor();
+}
diff --git a/cpp/src/IceGrid/DescriptorParser.h b/cpp/src/IceGrid/DescriptorParser.h
new file mode 100644
index 00000000000..e448abf2aa2
--- /dev/null
+++ b/cpp/src/IceGrid/DescriptorParser.h
@@ -0,0 +1,34 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 ICEPACK_DESCRIPTOR_PARSER_H
+#define ICEPACK_DESCRIPTOR_PARSER_H
+
+namespace IceGrid
+{
+
+class DescriptorParser
+{
+public:
+
+ static ApplicationDescriptorPtr parseApplicationDescriptor(const std::string&,
+ const Ice::StringSeq&,
+ const std::map<std::string, std::string>&,
+ const Ice::CommunicatorPtr&);
+
+ static ServerDescriptorPtr parseServerDescriptor(const std::string&,
+ const Ice::StringSeq&,
+ const std::map<std::string, std::string>&,
+ const Ice::CommunicatorPtr&);
+
+};
+
+}
+
+#endif
diff --git a/cpp/src/IceGrid/DescriptorUtil.cpp b/cpp/src/IceGrid/DescriptorUtil.cpp
new file mode 100644
index 00000000000..fda7d194534
--- /dev/null
+++ b/cpp/src/IceGrid/DescriptorUtil.cpp
@@ -0,0 +1,216 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 <IceGrid/DescriptorUtil.h>
+
+using namespace std;
+
+namespace IceGrid
+{
+
+bool equal(const ServiceDescriptorPtr&, const ServiceDescriptorPtr&);
+
+}
+
+bool
+IceGrid::equal(const ServiceDescriptorPtr& lhs, const ServiceDescriptorPtr& rhs)
+{
+ if(lhs->ice_id() != rhs->ice_id())
+ {
+ return false;
+ }
+
+ if(lhs->name != rhs->name)
+ {
+ return false;
+ }
+
+ if(lhs->comment != rhs->comment)
+ {
+ return false;
+ }
+
+ if(lhs->entry != rhs->entry)
+ {
+ return false;
+ }
+
+ if(set<AdapterDescriptor>(lhs->adapters.begin(), lhs->adapters.end()) !=
+ set<AdapterDescriptor>(rhs->adapters.begin(), rhs->adapters.end()))
+ {
+ return false;
+ }
+
+ if(set<PropertyDescriptor>(lhs->properties.begin(), lhs->properties.end()) !=
+ set<PropertyDescriptor>(rhs->properties.begin(), rhs->properties.end()))
+ {
+ return false;
+ }
+
+ if(set<DbEnvDescriptor>(lhs->dbEnvs.begin(), lhs->dbEnvs.end()) !=
+ set<DbEnvDescriptor>(rhs->dbEnvs.begin(), rhs->dbEnvs.end()))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool
+IceGrid::equal(const ServerDescriptorPtr& lhs, const ServerDescriptorPtr& rhs)
+{
+ if(lhs->ice_id() != rhs->ice_id())
+ {
+ return false;
+ }
+
+ if(lhs->name != rhs->name)
+ {
+ return false;
+ }
+
+ if(lhs->comment != rhs->comment)
+ {
+ return false;
+ }
+
+ if(lhs->exe != rhs->exe)
+ {
+ return false;
+ }
+
+ if(lhs->pwd != rhs->pwd)
+ {
+ return false;
+ }
+
+ if(lhs->node != rhs->node)
+ {
+ return false;
+ }
+
+ if(lhs->application != rhs->application)
+ {
+ return false;
+ }
+
+ if(set<AdapterDescriptor>(lhs->adapters.begin(), lhs->adapters.end()) !=
+ set<AdapterDescriptor>(rhs->adapters.begin(), rhs->adapters.end()))
+ {
+ return false;
+ }
+
+ if(set<PropertyDescriptor>(lhs->properties.begin(), lhs->properties.end()) !=
+ set<PropertyDescriptor>(rhs->properties.begin(), rhs->properties.end()))
+ {
+ return false;
+ }
+
+ if(set<DbEnvDescriptor>(lhs->dbEnvs.begin(), lhs->dbEnvs.end()) !=
+ set<DbEnvDescriptor>(rhs->dbEnvs.begin(), rhs->dbEnvs.end()))
+ {
+ return false;
+ }
+
+ if(set<string>(lhs->options.begin(), lhs->options.end()) != set<string>(rhs->options.begin(), rhs->options.end()))
+ {
+ return false;
+ }
+
+ if(set<string>(lhs->envs.begin(), lhs->envs.end()) != set<string>(rhs->envs.begin(), rhs->envs.end()))
+ {
+ return false;
+ }
+
+ //
+ // TODO: perhaps if would be better to define an equal operation on the Slice class?
+ //
+ ServiceDescriptorSeq slhs;
+ ServiceDescriptorSeq srhs;
+
+ if(JavaServerDescriptorPtr::dynamicCast(lhs))
+ {
+ JavaServerDescriptorPtr jlhs = JavaServerDescriptorPtr::dynamicCast(lhs);
+ JavaServerDescriptorPtr jrhs = JavaServerDescriptorPtr::dynamicCast(rhs);
+
+ if(jlhs->className != jrhs->className)
+ {
+ return false;
+ }
+
+ if(set<string>(jlhs->jvmOptions.begin(), jlhs->jvmOptions.end()) !=
+ set<string>(jrhs->jvmOptions.begin(), jrhs->jvmOptions.end()))
+ {
+ return false;
+ }
+
+ if(JavaIceBoxDescriptorPtr::dynamicCast(lhs))
+ {
+ JavaIceBoxDescriptorPtr ilhs = JavaIceBoxDescriptorPtr::dynamicCast(lhs);
+ JavaIceBoxDescriptorPtr irhs = JavaIceBoxDescriptorPtr::dynamicCast(rhs);
+
+ if(ilhs->endpoints != irhs->endpoints)
+ {
+ return false;
+ }
+
+ if(ilhs->services.size() != irhs->services.size())
+ {
+ return false;
+ }
+
+ slhs = ilhs->services;
+ srhs = irhs->services;
+ }
+ }
+ else if(CppIceBoxDescriptorPtr::dynamicCast(lhs))
+ {
+ CppIceBoxDescriptorPtr ilhs = CppIceBoxDescriptorPtr::dynamicCast(lhs);
+ CppIceBoxDescriptorPtr irhs = CppIceBoxDescriptorPtr::dynamicCast(rhs);
+
+ if(ilhs->endpoints != irhs->endpoints)
+ {
+ return false;
+ }
+
+ if(ilhs->services.size() != irhs->services.size())
+ {
+ return false;
+ }
+
+ slhs = ilhs->services;
+ srhs = irhs->services;
+ }
+
+ if(!slhs.empty())
+ {
+ for(ServiceDescriptorSeq::const_iterator p = slhs.begin(); p != slhs.end(); ++p)
+ {
+ bool found = false;
+ for(ServiceDescriptorSeq::const_iterator q = srhs.begin(); q != srhs.end(); ++q)
+ {
+ if((*p)->name == (*q)->name)
+ {
+ if(!equal(*p, *q))
+ {
+ return false;
+ }
+ found = true;
+ break;
+ }
+ }
+ if(!found)
+ {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
diff --git a/cpp/src/IceGrid/DescriptorUtil.h b/cpp/src/IceGrid/DescriptorUtil.h
new file mode 100644
index 00000000000..97f3c3986eb
--- /dev/null
+++ b/cpp/src/IceGrid/DescriptorUtil.h
@@ -0,0 +1,22 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 ICEPACK_DESCRIPTOR_UTIL_H
+#define ICEPACK_DESCRIPTOR_UTIL_H
+
+#include <IceGrid/Admin.h>
+
+namespace IceGrid
+{
+
+bool equal(const ServerDescriptorPtr&, const ServerDescriptorPtr&);
+
+}
+
+#endif
diff --git a/cpp/src/IceGrid/DescriptorVisitor.cpp b/cpp/src/IceGrid/DescriptorVisitor.cpp
new file mode 100644
index 00000000000..e70690f1058
--- /dev/null
+++ b/cpp/src/IceGrid/DescriptorVisitor.cpp
@@ -0,0 +1,176 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 <IceGrid/Admin.h>
+#include <IceGrid/DescriptorVisitor.h>
+
+using namespace std;
+using namespace Ice;
+using namespace IceGrid;
+
+ApplicationWrapper::ApplicationWrapper(const ApplicationDescriptorPtr& descriptor) : _descriptor(descriptor)
+{
+}
+
+void
+ApplicationWrapper::visit(DescriptorVisitor& visitor)
+{
+ if(visitor.visitApplicationStart(*this, _descriptor))
+ {
+ for(ServerDescriptorSeq::const_iterator p = _descriptor->servers.begin(); p != _descriptor->servers.end(); ++p)
+ {
+ ServerWrapper(*p).visit(visitor);
+ }
+ visitor.visitApplicationEnd(*this, _descriptor);
+ }
+}
+
+const ApplicationDescriptorPtr&
+ApplicationWrapper::getDescriptor() const
+{
+ return _descriptor;
+}
+
+ComponentWrapper::ComponentWrapper(const ComponentDescriptorPtr& descriptor) : _descriptor(descriptor)
+{
+}
+
+void
+ComponentWrapper::visit(DescriptorVisitor& visitor)
+{
+ for(AdapterDescriptorSeq::const_iterator p = _descriptor->adapters.begin(); p != _descriptor->adapters.end(); ++p)
+ {
+ AdapterWrapper(*this, *p).visit(visitor);
+ }
+
+ for(DbEnvDescriptorSeq::const_iterator q = _descriptor->dbEnvs.begin(); q != _descriptor->dbEnvs.end(); ++q)
+ {
+ DbEnvWrapper(*this, *q).visit(visitor);
+ }
+}
+
+ServerWrapper::ServerWrapper(const ServerDescriptorPtr& descriptor) :
+ ComponentWrapper(descriptor),
+ _descriptor(descriptor)
+{
+}
+
+void
+ServerWrapper::visit(DescriptorVisitor& visitor)
+{
+ if(visitor.visitServerStart(*this, _descriptor))
+ {
+ ComponentWrapper::visit(visitor);
+
+ CppIceBoxDescriptorPtr cppIceBox = CppIceBoxDescriptorPtr::dynamicCast(_descriptor);
+ JavaIceBoxDescriptorPtr javaIceBox = JavaIceBoxDescriptorPtr::dynamicCast(_descriptor);
+
+ const ServiceDescriptorSeq& services =
+ cppIceBox ? cppIceBox->services : (javaIceBox ? javaIceBox->services : ServiceDescriptorSeq());
+
+ for(ServiceDescriptorSeq::const_iterator p = services.begin(); p != services.end(); ++p)
+ {
+ ServiceWrapper(*this, *p).visit(visitor);
+ }
+ visitor.visitServerEnd(*this, _descriptor);
+ }
+}
+
+const ServerDescriptorPtr&
+ServerWrapper::getDescriptor() const
+{
+ return _descriptor;
+}
+
+ServiceWrapper::ServiceWrapper(const ServerWrapper& server, const ServiceDescriptorPtr& descriptor) :
+ ComponentWrapper(descriptor),
+ _server(server),
+ _descriptor(descriptor)
+{
+}
+
+void
+ServiceWrapper::visit(DescriptorVisitor& visitor)
+{
+ if(visitor.visitServiceStart(*this, _descriptor))
+ {
+ ComponentWrapper::visit(visitor);
+ visitor.visitServiceEnd(*this, _descriptor);
+ }
+}
+
+const ServiceDescriptorPtr&
+ServiceWrapper::getDescriptor() const
+{
+ return _descriptor;
+}
+
+DbEnvWrapper::DbEnvWrapper(const ComponentWrapper& component, const DbEnvDescriptor& descriptor) :
+ _component(component),
+ _descriptor(descriptor)
+{
+}
+
+void
+DbEnvWrapper::visit(DescriptorVisitor& visitor)
+{
+ visitor.visitDbEnv(*this, _descriptor);
+}
+
+const DbEnvDescriptor&
+DbEnvWrapper::getDescriptor() const
+{
+ return _descriptor;
+}
+
+AdapterWrapper::AdapterWrapper(const ComponentWrapper& component, const AdapterDescriptor& descriptor) :
+ _component(component),
+ _descriptor(descriptor)
+{
+}
+
+void
+AdapterWrapper::visit(DescriptorVisitor& visitor)
+{
+ if(visitor.visitAdapterStart(*this, _descriptor))
+ {
+ for(ObjectDescriptorSeq::const_iterator p = _descriptor.objects.begin(); p != _descriptor.objects.end(); ++p)
+ {
+ ObjectWrapper(*this, *p).visit(visitor);
+ }
+ visitor.visitAdapterEnd(*this, _descriptor);
+ }
+}
+
+const AdapterDescriptor&
+AdapterWrapper::getDescriptor() const
+{
+ return _descriptor;
+}
+
+ObjectWrapper::ObjectWrapper(const AdapterWrapper& adapter, const ObjectDescriptor& descriptor):
+ _adapter(adapter),
+ _descriptor(descriptor)
+{
+}
+
+void
+ObjectWrapper::visit(DescriptorVisitor& visitor)
+{
+ visitor.visitObject(*this, _descriptor);
+}
+
+const ObjectDescriptor&
+ObjectWrapper::getDescriptor() const
+{
+ return _descriptor;
+}
+
+
diff --git a/cpp/src/IceGrid/DescriptorVisitor.h b/cpp/src/IceGrid/DescriptorVisitor.h
new file mode 100644
index 00000000000..90b6c93021b
--- /dev/null
+++ b/cpp/src/IceGrid/DescriptorVisitor.h
@@ -0,0 +1,147 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 ICEPACK_DESCRIPTOR_VISITOR_H
+#define ICEPACK_DESCRIPTOR_VISITOR_H
+
+namespace IceGrid
+{
+
+class ApplicationWrapper;
+class ServerWrapper;
+class ServiceWrapper;
+class AdapterWrapper;
+class ObjectWrapper;
+class DbEnvWrapper;
+
+class DescriptorVisitor
+{
+public:
+
+ virtual ~DescriptorVisitor() { }
+
+ virtual bool visitApplicationStart(const ApplicationWrapper&, const ApplicationDescriptorPtr&) { return true; }
+ virtual void visitApplicationEnd(const ApplicationWrapper&, const ApplicationDescriptorPtr&) { }
+ virtual bool visitServerStart(const ServerWrapper&, const ServerDescriptorPtr&) { return true; }
+ virtual void visitServerEnd(const ServerWrapper&, const ServerDescriptorPtr&) { }
+ virtual bool visitServiceStart(const ServiceWrapper&, const ServiceDescriptorPtr&) { return true; }
+ virtual void visitServiceEnd(const ServiceWrapper&, const ServiceDescriptorPtr&) { }
+ virtual bool visitAdapterStart(const AdapterWrapper&, const AdapterDescriptor&) { return true; }
+ virtual void visitAdapterEnd(const AdapterWrapper&, const AdapterDescriptor&) { }
+ virtual void visitDbEnv(const DbEnvWrapper&, const DbEnvDescriptor&) { }
+ virtual void visitObject(const ObjectWrapper&, const ObjectDescriptor&) { }
+};
+
+class ApplicationWrapper
+{
+public:
+
+ ApplicationWrapper(const ApplicationDescriptorPtr&);
+
+ void visit(DescriptorVisitor&);
+ const ApplicationDescriptorPtr& getDescriptor() const;
+
+private:
+
+ const ApplicationDescriptorPtr _descriptor;
+};
+
+class ComponentWrapper
+{
+public:
+
+ ComponentWrapper(const ComponentDescriptorPtr&);
+
+ void visit(DescriptorVisitor&);
+
+private:
+
+ ComponentDescriptorPtr _descriptor;
+
+};
+
+class ServerWrapper : public ComponentWrapper
+{
+public:
+
+ ServerWrapper(const ServerDescriptorPtr&);
+
+ void visit(DescriptorVisitor&);
+ const ServerDescriptorPtr& getDescriptor() const;
+
+private:
+
+ ServerDescriptorPtr _descriptor;
+};
+
+class ServiceWrapper : public ComponentWrapper
+{
+public:
+
+ ServiceWrapper(const ServerWrapper&, const ServiceDescriptorPtr&);
+
+ void visit(DescriptorVisitor&);
+ const ServiceDescriptorPtr& getDescriptor() const;
+
+private:
+
+ const ServerWrapper& _server;
+ ServiceDescriptorPtr _descriptor;
+};
+
+class DbEnvWrapper
+{
+public:
+
+ DbEnvWrapper(const ComponentWrapper&, const DbEnvDescriptor&);
+
+ void visit(DescriptorVisitor&);
+ const DbEnvDescriptor& getDescriptor() const;
+
+private:
+
+ const ComponentWrapper& _component;
+ const DbEnvDescriptor& _descriptor;
+};
+
+class AdapterWrapper
+{
+public:
+
+ AdapterWrapper(const ComponentWrapper&, const AdapterDescriptor&);
+
+ void visit(DescriptorVisitor&);
+ const AdapterDescriptor& getDescriptor() const;
+
+private:
+
+ const ComponentWrapper& _component;
+ const AdapterDescriptor& _descriptor;
+};
+
+class ObjectWrapper
+{
+public:
+
+ ObjectWrapper(const AdapterWrapper&, const ObjectDescriptor&);
+
+ void visit(DescriptorVisitor&);
+ const ObjectDescriptor& getDescriptor() const;
+
+private:
+
+ const AdapterWrapper& _adapter;
+ const ObjectDescriptor& _descriptor;
+};
+
+}
+
+#endif
+
+
diff --git a/cpp/src/IceGrid/GPL.h b/cpp/src/IceGrid/GPL.h
new file mode 100644
index 00000000000..6468c3c1324
--- /dev/null
+++ b/cpp/src/IceGrid/GPL.h
@@ -0,0 +1,303 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 ICE_GPL_H
+#define ICE_GPL_H
+
+static const char* gplBanner =
+"This copy of Ice is free software. You are welcome to change it and/or\n"
+"distribute copies under certain conditions. Type \"show copying\" to see\n"
+"these conditions.\n"
+"There is absolutely no warranty for Ice. Type \"show warranty\" for details.\n";
+
+static const char* gplCopying =
+" GNU GENERAL PUBLIC LICENSE\n"
+" Version 2, June 1991\n"
+"\n"
+" Copyright (C) 1989, 1991 Free Software Foundation, Inc.\n"
+" 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n"
+" Everyone is permitted to copy and distribute verbatim copies\n"
+" of this license document, but changing it is not allowed.\n"
+"\n"
+" Preamble\n"
+"\n"
+" The licenses for most software are designed to take away your\n"
+"freedom to share and change it. By contrast, the GNU General Public\n"
+"License is intended to guarantee your freedom to share and change free\n"
+"software--to make sure the software is free for all its users. This\n"
+"General Public License applies to most of the Free Software\n"
+"Foundation's software and to any other program whose authors commit to\n"
+"using it. (Some other Free Software Foundation software is covered by\n"
+"the GNU Library General Public License instead.) You can apply it to\n"
+"your programs, too.\n"
+"\n"
+" When we speak of free software, we are referring to freedom, not\n"
+"price. Our General Public Licenses are designed to make sure that you\n"
+"have the freedom to distribute copies of free software (and charge for\n"
+"this service if you wish), that you receive source code or can get it\n"
+"if you want it, that you can change the software or use pieces of it\n"
+"in new free programs; and that you know you can do these things.\n"
+"\n"
+" To protect your rights, we need to make restrictions that forbid\n"
+"anyone to deny you these rights or to ask you to surrender the rights.\n"
+"These restrictions translate to certain responsibilities for you if you\n"
+"distribute copies of the software, or if you modify it.\n"
+"\n"
+" For example, if you distribute copies of such a program, whether\n"
+"gratis or for a fee, you must give the recipients all the rights that\n"
+"you have. You must make sure that they, too, receive or can get the\n"
+"source code. And you must show them these terms so they know their\n"
+"rights.\n"
+"\n"
+" We protect your rights with two steps: (1) copyright the software, and\n"
+"(2) offer you this license which gives you legal permission to copy,\n"
+"distribute and/or modify the software.\n"
+"\n"
+" Also, for each author's protection and ours, we want to make certain\n"
+"that everyone understands that there is no warranty for this free\n"
+"software. If the software is modified by someone else and passed on, we\n"
+"want its recipients to know that what they have is not the original, so\n"
+"that any problems introduced by others will not reflect on the original\n"
+"authors' reputations.\n"
+"\n"
+" Finally, any free program is threatened constantly by software\n"
+"patents. We wish to avoid the danger that redistributors of a free\n"
+"program will individually obtain patent licenses, in effect making the\n"
+"program proprietary. To prevent this, we have made it clear that any\n"
+"patent must be licensed for everyone's free use or not licensed at all.\n"
+"\n"
+" The precise terms and conditions for copying, distribution and\n"
+"modification follow.\n"
+"\n"
+" GNU GENERAL PUBLIC LICENSE\n"
+" TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n"
+"\n"
+" 0. This License applies to any program or other work which contains\n"
+"a notice placed by the copyright holder saying it may be distributed\n"
+"under the terms of this General Public License. The \"Program\", below,\n"
+"refers to any such program or work, and a \"work based on the Program\"\n"
+"means either the Program or any derivative work under copyright law:\n"
+"that is to say, a work containing the Program or a portion of it,\n"
+"either verbatim or with modifications and/or translated into another\n"
+"language. (Hereinafter, translation is included without limitation in\n"
+"the term \"modification\".) Each licensee is addressed as \"you\".\n"
+"\n"
+"Activities other than copying, distribution and modification are not\n"
+"covered by this License; they are outside its scope. The act of\n"
+"running the Program is not restricted, and the output from the Program\n"
+"is covered only if its contents constitute a work based on the\n"
+"Program (independent of having been made by running the Program).\n"
+"Whether that is true depends on what the Program does.\n"
+"\n"
+" 1. You may copy and distribute verbatim copies of the Program's\n"
+"source code as you receive it, in any medium, provided that you\n"
+"conspicuously and appropriately publish on each copy an appropriate\n"
+"copyright notice and disclaimer of warranty; keep intact all the\n"
+"notices that refer to this License and to the absence of any warranty;\n"
+"and give any other recipients of the Program a copy of this License\n"
+"along with the Program.\n"
+"\n"
+"You may charge a fee for the physical act of transferring a copy, and\n"
+"you may at your option offer warranty protection in exchange for a fee.\n"
+"\n"
+" 2. You may modify your copy or copies of the Program or any portion\n"
+"of it, thus forming a work based on the Program, and copy and\n"
+"distribute such modifications or work under the terms of Section 1\n"
+"above, provided that you also meet all of these conditions:\n"
+"\n"
+" a) You must cause the modified files to carry prominent notices\n"
+" stating that you changed the files and the date of any change.\n"
+"\n"
+" b) You must cause any work that you distribute or publish, that in\n"
+" whole or in part contains or is derived from the Program or any\n"
+" part thereof, to be licensed as a whole at no charge to all third\n"
+" parties under the terms of this License.\n"
+"\n"
+" c) If the modified program normally reads commands interactively\n"
+" when run, you must cause it, when started running for such\n"
+" interactive use in the most ordinary way, to print or display an\n"
+" announcement including an appropriate copyright notice and a\n"
+" notice that there is no warranty (or else, saying that you provide\n"
+" a warranty) and that users may redistribute the program under\n"
+" these conditions, and telling the user how to view a copy of this\n"
+" License. (Exception: if the Program itself is interactive but\n"
+" does not normally print such an announcement, your work based on\n"
+" the Program is not required to print an announcement.)\n"
+"\n"
+"These requirements apply to the modified work as a whole. If\n"
+"identifiable sections of that work are not derived from the Program,\n"
+"and can be reasonably considered independent and separate works in\n"
+"themselves, then this License, and its terms, do not apply to those\n"
+"sections when you distribute them as separate works. But when you\n"
+"distribute the same sections as part of a whole which is a work based\n"
+"on the Program, the distribution of the whole must be on the terms of\n"
+"this License, whose permissions for other licensees extend to the\n"
+"entire whole, and thus to each and every part regardless of who wrote it.\n"
+"\n"
+"Thus, it is not the intent of this section to claim rights or contest\n"
+"your rights to work written entirely by you; rather, the intent is to\n"
+"exercise the right to control the distribution of derivative or\n"
+"collective works based on the Program.\n"
+"\n"
+"In addition, mere aggregation of another work not based on the Program\n"
+"with the Program (or with a work based on the Program) on a volume of\n"
+"a storage or distribution medium does not bring the other work under\n"
+"the scope of this License.\n"
+"\n"
+" 3. You may copy and distribute the Program (or a work based on it,\n"
+"under Section 2) in object code or executable form under the terms of\n"
+"Sections 1 and 2 above provided that you also do one of the following:\n"
+"\n"
+" a) Accompany it with the complete corresponding machine-readable\n"
+" source code, which must be distributed under the terms of Sections\n"
+" 1 and 2 above on a medium customarily used for software interchange; or,\n"
+"\n"
+" b) Accompany it with a written offer, valid for at least three\n"
+" years, to give any third party, for a charge no more than your\n"
+" cost of physically performing source distribution, a complete\n"
+" machine-readable copy of the corresponding source code, to be\n"
+" distributed under the terms of Sections 1 and 2 above on a medium\n"
+" customarily used for software interchange; or,\n"
+"\n"
+" c) Accompany it with the information you received as to the offer\n"
+" to distribute corresponding source code. (This alternative is\n"
+" allowed only for noncommercial distribution and only if you\n"
+" received the program in object code or executable form with such\n"
+" an offer, in accord with Subsection b above.)\n"
+"\n"
+"The source code for a work means the preferred form of the work for\n"
+"making modifications to it. For an executable work, complete source\n"
+"code means all the source code for all modules it contains, plus any\n"
+"associated interface definition files, plus the scripts used to\n"
+"control compilation and installation of the executable. However, as a\n"
+"special exception, the source code distributed need not include\n"
+"anything that is normally distributed (in either source or binary\n"
+"form) with the major components (compiler, kernel, and so on) of the\n"
+"operating system on which the executable runs, unless that component\n"
+"itself accompanies the executable.\n"
+"\n"
+"If distribution of executable or object code is made by offering\n"
+"access to copy from a designated place, then offering equivalent\n"
+"access to copy the source code from the same place counts as\n"
+"distribution of the source code, even though third parties are not\n"
+"compelled to copy the source along with the object code.\n"
+"\n"
+" 4. You may not copy, modify, sublicense, or distribute the Program\n"
+"except as expressly provided under this License. Any attempt\n"
+"otherwise to copy, modify, sublicense or distribute the Program is\n"
+"void, and will automatically terminate your rights under this License.\n"
+"However, parties who have received copies, or rights, from you under\n"
+"this License will not have their licenses terminated so long as such\n"
+"parties remain in full compliance.\n"
+"\n"
+" 5. You are not required to accept this License, since you have not\n"
+"signed it. However, nothing else grants you permission to modify or\n"
+"distribute the Program or its derivative works. These actions are\n"
+"prohibited by law if you do not accept this License. Therefore, by\n"
+"modifying or distributing the Program (or any work based on the\n"
+"Program), you indicate your acceptance of this License to do so, and\n"
+"all its terms and conditions for copying, distributing or modifying\n"
+"the Program or works based on it.\n"
+"\n"
+" 6. Each time you redistribute the Program (or any work based on the\n"
+"Program), the recipient automatically receives a license from the\n"
+"original licensor to copy, distribute or modify the Program subject to\n"
+"these terms and conditions. You may not impose any further\n"
+"restrictions on the recipients' exercise of the rights granted herein.\n"
+"You are not responsible for enforcing compliance by third parties to\n"
+"this License.\n"
+"\n"
+" 7. If, as a consequence of a court judgment or allegation of patent\n"
+"infringement or for any other reason (not limited to patent issues),\n"
+"conditions are imposed on you (whether by court order, agreement or\n"
+"otherwise) that contradict the conditions of this License, they do not\n"
+"excuse you from the conditions of this License. If you cannot\n"
+"distribute so as to satisfy simultaneously your obligations under this\n"
+"License and any other pertinent obligations, then as a consequence you\n"
+"may not distribute the Program at all. For example, if a patent\n"
+"license would not permit royalty-free redistribution of the Program by\n"
+"all those who receive copies directly or indirectly through you, then\n"
+"the only way you could satisfy both it and this License would be to\n"
+"refrain entirely from distribution of the Program.\n"
+"\n"
+"If any portion of this section is held invalid or unenforceable under\n"
+"any particular circumstance, the balance of the section is intended to\n"
+"apply and the section as a whole is intended to apply in other\n"
+"circumstances.\n"
+"\n"
+"It is not the purpose of this section to induce you to infringe any\n"
+"patents or other property right claims or to contest validity of any\n"
+"such claims; this section has the sole purpose of protecting the\n"
+"integrity of the free software distribution system, which is\n"
+"implemented by public license practices. Many people have made\n"
+"generous contributions to the wide range of software distributed\n"
+"through that system in reliance on consistent application of that\n"
+"system; it is up to the author/donor to decide if he or she is willing\n"
+"to distribute software through any other system and a licensee cannot\n"
+"impose that choice.\n"
+"\n"
+"This section is intended to make thoroughly clear what is believed to\n"
+"be a consequence of the rest of this License.\n"
+"\n"
+" 8. If the distribution and/or use of the Program is restricted in\n"
+"certain countries either by patents or by copyrighted interfaces, the\n"
+"original copyright holder who places the Program under this License\n"
+"may add an explicit geographical distribution limitation excluding\n"
+"those countries, so that distribution is permitted only in or among\n"
+"countries not thus excluded. In such case, this License incorporates\n"
+"the limitation as if written in the body of this License.\n"
+"\n"
+" 9. The Free Software Foundation may publish revised and/or new versions\n"
+"of the General Public License from time to time. Such new versions will\n"
+"be similar in spirit to the present version, but may differ in detail to\n"
+"address new problems or concerns.\n"
+"\n"
+"Each version is given a distinguishing version number. If the Program\n"
+"specifies a version number of this License which applies to it and \"any\n"
+"later version\", you have the option of following the terms and conditions\n"
+"either of that version or of any later version published by the Free\n"
+"Software Foundation. If the Program does not specify a version number of\n"
+"this License, you may choose any version ever published by the Free Software\n"
+"Foundation.\n"
+"\n"
+" 10. If you wish to incorporate parts of the Program into other free\n"
+"programs whose distribution conditions are different, write to the author\n"
+"to ask for permission. For software which is copyrighted by the Free\n"
+"Software Foundation, write to the Free Software Foundation; we sometimes\n"
+"make exceptions for this. Our decision will be guided by the two goals\n"
+"of preserving the free status of all derivatives of our free software and\n"
+"of promoting the sharing and reuse of software generally.\n"
+"\n";
+
+
+static const char* gplWarranty =
+" NO WARRANTY\n"
+"\n"
+" 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\n"
+"FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN\n"
+"OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\n"
+"PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\n"
+"OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n"
+"MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS\n"
+"TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE\n"
+"PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\n"
+"REPAIR OR CORRECTION.\n"
+"\n"
+" 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\n"
+"WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\n"
+"REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\n"
+"INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\n"
+"OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\n"
+"TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\n"
+"YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\n"
+"PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\n"
+"POSSIBILITY OF SUCH DAMAGES.\n"
+"\n";
+
+#endif
diff --git a/cpp/src/IceGrid/Grammar.y b/cpp/src/IceGrid/Grammar.y
new file mode 100644
index 00000000000..cf4e8465db5
--- /dev/null
+++ b/cpp/src/IceGrid/Grammar.y
@@ -0,0 +1,271 @@
+%{
+
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 <IceGrid/Parser.h>
+
+#ifdef _WIN32
+// I get these warnings from some bison versions:
+// warning C4102: 'yyoverflowlab' : unreferenced label
+# pragma warning( disable : 4102 )
+// warning C4065: switch statement contains 'default' but no 'case' labels
+# pragma warning( disable : 4065 )
+#endif
+
+using namespace std;
+using namespace Ice;
+using namespace IceGrid;
+
+void
+yyerror(const char* s)
+{
+ parser->error(s);
+}
+
+%}
+
+%pure_parser
+
+%token ICE_GRID_HELP
+%token ICE_GRID_EXIT
+%token ICE_GRID_APPLICATION
+%token ICE_GRID_NODE
+%token ICE_GRID_SERVER
+%token ICE_GRID_ADAPTER
+%token ICE_GRID_PING
+%token ICE_GRID_ADD
+%token ICE_GRID_REMOVE
+%token ICE_GRID_LIST
+%token ICE_GRID_SHUTDOWN
+%token ICE_GRID_STRING
+%token ICE_GRID_START
+%token ICE_GRID_STOP
+%token ICE_GRID_SIGNAL
+%token ICE_GRID_STDOUT
+%token ICE_GRID_STDERR
+%token ICE_GRID_DESCRIBE
+%token ICE_GRID_STATE
+%token ICE_GRID_PID
+%token ICE_GRID_ENDPOINTS
+%token ICE_GRID_ACTIVATION
+%token ICE_GRID_OBJECT
+%token ICE_GRID_FIND
+%token ICE_GRID_SHOW
+%token ICE_GRID_COPYING
+%token ICE_GRID_WARRANTY
+%token ICE_GRID_DIFF
+%token ICE_GRID_UPDATE
+
+%%
+
+// ----------------------------------------------------------------------
+start
+// ----------------------------------------------------------------------
+: commands
+{
+}
+|
+{
+}
+;
+
+// ----------------------------------------------------------------------
+commands
+// ----------------------------------------------------------------------
+: commands command
+{
+}
+| command
+{
+}
+;
+
+// ----------------------------------------------------------------------
+command
+// ----------------------------------------------------------------------
+: ICE_GRID_HELP ';'
+{
+ parser->usage();
+}
+| ICE_GRID_EXIT ';'
+{
+ return 0;
+}
+| ICE_GRID_APPLICATION ICE_GRID_ADD strings ';'
+{
+ parser->addApplication($3);
+}
+| ICE_GRID_APPLICATION ICE_GRID_REMOVE strings ';'
+{
+ parser->removeApplication($3);
+}
+| ICE_GRID_APPLICATION ICE_GRID_DIFF strings ';'
+{
+ parser->diffApplication($3);
+}
+| ICE_GRID_APPLICATION ICE_GRID_UPDATE strings ';'
+{
+ parser->updateApplication($3);
+}
+| ICE_GRID_APPLICATION ICE_GRID_DESCRIBE strings ';'
+{
+ parser->describeApplication($3);
+}
+| ICE_GRID_APPLICATION ICE_GRID_LIST ';'
+{
+ parser->listAllApplications();
+}
+| ICE_GRID_NODE ICE_GRID_PING strings ';'
+{
+ parser->pingNode($3);
+}
+| ICE_GRID_NODE ICE_GRID_SHUTDOWN strings ';'
+{
+ parser->shutdownNode($3);
+}
+| ICE_GRID_NODE ICE_GRID_REMOVE strings ';'
+{
+ parser->removeNode($3);
+}
+| ICE_GRID_NODE ICE_GRID_LIST ';'
+{
+ parser->listAllNodes();
+}
+| ICE_GRID_SERVER ICE_GRID_ADD strings ';'
+{
+ parser->addServer($3);
+}
+| ICE_GRID_SERVER ICE_GRID_UPDATE strings ';'
+{
+ parser->updateServer($3);
+}
+| ICE_GRID_SERVER ICE_GRID_DESCRIBE strings ';'
+{
+ parser->describeServer($3);
+}
+| ICE_GRID_SERVER ICE_GRID_START strings ';'
+{
+ parser->startServer($3);
+}
+| ICE_GRID_SERVER ICE_GRID_STOP strings ';'
+{
+ parser->stopServer($3);
+}
+| ICE_GRID_SERVER ICE_GRID_SIGNAL strings ';'
+{
+ parser->signalServer($3);
+}
+| ICE_GRID_SERVER ICE_GRID_STDOUT strings ';'
+{
+ parser->writeMessage($3, 1);
+}
+| ICE_GRID_SERVER ICE_GRID_STDERR strings ';'
+{
+ parser->writeMessage($3, 2);
+}
+| ICE_GRID_SERVER ICE_GRID_STATE strings ';'
+{
+ parser->stateServer($3);
+}
+| ICE_GRID_SERVER ICE_GRID_PID strings ';'
+{
+ parser->pidServer($3);
+}
+| ICE_GRID_SERVER ICE_GRID_ACTIVATION strings ';'
+{
+ parser->activationServer($3);
+}
+| ICE_GRID_SERVER ICE_GRID_REMOVE strings ';'
+{
+ parser->removeServer($3);
+}
+| ICE_GRID_SERVER ICE_GRID_LIST ';'
+{
+ parser->listAllServers();
+}
+| ICE_GRID_ADAPTER ICE_GRID_ENDPOINTS strings ';'
+{
+ parser->endpointsAdapter($3);
+}
+| ICE_GRID_ADAPTER ICE_GRID_LIST ';'
+{
+ parser->listAllAdapters();
+}
+| ICE_GRID_OBJECT ICE_GRID_ADD strings ';'
+{
+ parser->addObject($3);
+}
+| ICE_GRID_OBJECT ICE_GRID_REMOVE strings ';'
+{
+ parser->removeObject($3);
+}
+| ICE_GRID_OBJECT ICE_GRID_FIND strings ';'
+{
+ parser->findObject($3);
+}
+| ICE_GRID_OBJECT ICE_GRID_LIST optional_strings ';'
+{
+ parser->listObject($3);
+}
+| ICE_GRID_OBJECT ICE_GRID_DESCRIBE optional_strings ';'
+{
+ parser->describeObject($3);
+}
+| ICE_GRID_SHUTDOWN ';'
+{
+ parser->shutdown();
+}
+| ICE_GRID_SHOW ICE_GRID_COPYING ';'
+{
+ parser->showCopying();
+}
+| ICE_GRID_SHOW ICE_GRID_WARRANTY ';'
+{
+ parser->showWarranty();
+}
+| error ';'
+{
+ yyerrok;
+}
+| ';'
+{
+}
+;
+
+// ----------------------------------------------------------------------
+strings
+// ----------------------------------------------------------------------
+: ICE_GRID_STRING strings
+{
+ $$ = $2;
+ $$.push_front($1.front());
+}
+| ICE_GRID_STRING
+{
+ $$ = $1;
+}
+;
+
+// ----------------------------------------------------------------------
+optional_strings
+// ----------------------------------------------------------------------
+: ICE_GRID_STRING optional_strings
+{
+ $$ = $2;
+ $$.push_front($1.front());
+}
+|
+{
+ $$ = YYSTYPE()
+}
+;
+
+%%
diff --git a/cpp/src/IceGrid/IceGridNode.cpp b/cpp/src/IceGrid/IceGridNode.cpp
new file mode 100644
index 00000000000..81e500b1bb2
--- /dev/null
+++ b/cpp/src/IceGrid/IceGridNode.cpp
@@ -0,0 +1,598 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 <IceUtil/UUID.h>
+#include <Ice/Ice.h>
+#include <Ice/Service.h>
+#include <IceGrid/Activator.h>
+#include <IceGrid/WaitQueue.h>
+#include <IceGrid/Registry.h>
+#include <IceGrid/ServerFactory.h>
+#include <IceGrid/AdapterFactory.h>
+#include <IceGrid/AdapterI.h>
+#include <IceGrid/NodeI.h>
+#include <IceGrid/TraceLevels.h>
+#include <IceGrid/DescriptorParser.h>
+
+#ifdef _WIN32
+# include <direct.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+# define S_ISDIR(mode) ((mode) & _S_IFDIR)
+# define S_ISREG(mode) ((mode) & _S_IFREG)
+#else
+# include <csignal>
+# include <signal.h>
+# include <sys/wait.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <unistd.h>
+#endif
+
+using namespace std;
+using namespace Ice;
+using namespace IceGrid;
+
+namespace IceGrid
+{
+
+class NodeService : public Service
+{
+public:
+
+ NodeService();
+
+ virtual bool shutdown();
+
+protected:
+
+ virtual bool start(int, char*[]);
+ virtual void waitForShutdown();
+ virtual bool stop();
+ virtual CommunicatorPtr initializeCommunicator(int&, char*[]);
+
+private:
+
+ void usage(const std::string&);
+
+ ActivatorPtr _activator;
+ WaitQueuePtr _waitQueue;
+ RegistryPtr _registry;
+};
+
+class CollocatedRegistry : public Registry
+{
+public:
+
+ CollocatedRegistry(const Ice::CommunicatorPtr&, const ActivatorPtr&);
+ virtual void shutdown();
+
+private:
+
+ ActivatorPtr _activator;
+};
+
+} // End of namespace IceGrid
+
+#ifndef _WIN32
+extern "C"
+{
+
+static void
+childHandler(int)
+{
+ //
+ // Call wait to de-allocate any resources allocated for the child
+ // process and avoid zombie processes. See man wait or waitpid for
+ // more information.
+ //
+ int olderrno = errno;
+
+ pid_t pid;
+ do
+ {
+ pid = waitpid(-1, 0, WNOHANG);
+ }
+ while(pid > 0);
+
+ assert(pid != -1 || errno == ECHILD);
+
+ errno = olderrno;
+}
+
+}
+#endif
+
+CollocatedRegistry::CollocatedRegistry(const Ice::CommunicatorPtr& communicator, const ActivatorPtr& activator) :
+ Registry(communicator),
+ _activator(activator)
+{
+}
+
+void
+CollocatedRegistry::shutdown()
+{
+ _activator->shutdown();
+}
+
+NodeService::NodeService()
+{
+}
+
+bool
+NodeService::shutdown()
+{
+ assert(_activator);
+ _activator->shutdown();
+ return true;
+}
+
+bool
+NodeService::start(int argc, char* argv[])
+{
+#ifndef _WIN32
+ //
+ // This application forks, so we need a signal handler for child termination.
+ //
+ struct sigaction action;
+ action.sa_handler = childHandler;
+ sigemptyset(&action.sa_mask);
+ sigaddset(&action.sa_mask, SIGCHLD);
+ action.sa_flags = 0;
+ sigaction(SIGCHLD, &action, 0);
+#endif
+
+ bool nowarn = false;
+ bool checkdb = false;
+ string descriptor;
+ vector<string> targets;
+ for(int i = 1; i < argc; ++i)
+ {
+ if(strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0)
+ {
+ usage(argv[0]);
+ return false;
+ }
+ else if(strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0)
+ {
+ print(ICE_STRING_VERSION);
+ return false;
+ }
+ else if(strcmp(argv[i], "--nowarn") == 0)
+ {
+ nowarn = true;
+ }
+ else if(strcmp(argv[i], "--deploy") == 0)
+ {
+ if(i + 1 >= argc)
+ {
+ error("missing descriptor argument for option `" + string(argv[i]) + "'");
+ usage(argv[0]);
+ return false;
+ }
+
+ descriptor = argv[++i];
+
+ while(i + 1 < argc && argv[++i][0] != '-')
+ {
+ targets.push_back(argv[i]);
+ }
+ }
+ else if(strcmp(argv[i], "--checkdb") == 0)
+ {
+ checkdb = true;
+ }
+ }
+
+ PropertiesPtr properties = communicator()->getProperties();
+
+ //
+ // Disable server idle time. Otherwise, the adapter would be
+ // shutdown prematurely and the deactivation would fail.
+ // Deactivation of the node relies on the object adapter
+ // to be active since it needs to terminate servers.
+ //
+ // TODO: implement Ice.ServerIdleTime in the activator
+ // termination listener instead?
+ //
+ properties->setProperty("Ice.ServerIdleTime", "0");
+ if(properties->getPropertyAsIntWithDefault("Ice.ThreadPool.Server.Size", 5) <= 5)
+ {
+ properties->setProperty("Ice.ThreadPool.Server.Size", "5");
+ }
+
+ //
+ // Create the activator.
+ //
+ TraceLevelsPtr traceLevels = new TraceLevels(properties, communicator()->getLogger());
+ _activator = new Activator(traceLevels, properties);
+
+ //
+ // Collocate the IceGrid registry if we need to.
+ //
+ if(properties->getPropertyAsInt("IceGrid.Node.CollocateRegistry") > 0)
+ {
+ //
+ // The node needs a different thread pool.
+ //
+ if(properties->getPropertyAsInt("IceGrid.Node.ThreadPool.Size") == 0)
+ {
+ int size = properties->getPropertyAsInt("Ice.ThreadPool.Server.Size");
+
+ ostringstream os1;
+ os1 << static_cast<int>(size / 3);
+ properties->setProperty("IceGrid.Node.ThreadPool.Size", os1.str());
+
+ ostringstream os2;
+ os2 << size - static_cast<int>(size / 3);
+ properties->setProperty("Ice.ThreadPool.Server.Size", os2.str());
+ }
+
+ _registry = new CollocatedRegistry(communicator(), _activator);
+ if(!_registry->start(nowarn))
+ {
+ return false;
+ }
+
+ //
+ // Set the Ice.Default.Locator property to point to the
+ // collocated locator (this property is passed by the
+ // activator to each activated server).
+ //
+ string locatorPrx = "IceGrid/Locator:" + properties->getProperty("IceGrid.Registry.Client.Endpoints");
+ properties->setProperty("Ice.Default.Locator", locatorPrx);
+ }
+ else if(properties->getProperty("Ice.Default.Locator").empty())
+ {
+ error("property `Ice.Default.Locator' is not set");
+ return false;
+ }
+
+ //
+ // Initialize the database environment (first setup the directory structure if needed).
+ //
+ string dataPath = properties->getProperty("IceGrid.Node.Data");
+ string dbPath;
+ if(dataPath.empty())
+ {
+ error("property `IceGrid.Node.Data' is not set");
+ return false;
+ }
+ else
+ {
+#ifdef _WIN32
+ struct _stat filestat;
+ if(::_stat(dataPath.c_str(), &filestat) != 0 || !S_ISDIR(filestat.st_mode))
+ {
+ ostringstream os;
+ SyscallException ex(__FILE__, __LINE__);
+ ex.error = getSystemErrno();
+ os << ex;
+ error("property `IceGrid.Node.Data' is set to an invalid path:\n" + os.str());
+ return false;
+ }
+#else
+ struct stat filestat;
+ if(::stat(dataPath.c_str(), &filestat) != 0 || !S_ISDIR(filestat.st_mode))
+ {
+ ostringstream os;
+ SyscallException ex(__FILE__, __LINE__);
+ ex.error = getSystemErrno();
+ os << ex;
+ error("property `IceGrid.Node.Data' is set to an invalid path:\n" + os.str());
+ return false;
+ }
+#endif
+
+ //
+ // Creates subdirectories db and servers in the IceGrid.Node.Data directory if they don't already exist.
+ //
+ if(dataPath[dataPath.length() - 1] != '/')
+ {
+ dataPath += "/";
+ }
+
+ dbPath = dataPath + "db";
+ string serversPath = dataPath + "servers";
+ string tmpPath = dataPath + "tmp";
+
+#ifdef _WIN32
+ if(::_stat(dbPath.c_str(), &filestat) != 0)
+ {
+ _mkdir(dbPath.c_str());
+ }
+ if(::_stat(serversPath.c_str(), &filestat) != 0)
+ {
+ _mkdir(serversPath.c_str());
+ }
+ if(::_stat(tmpPath.c_str(), &filestat) != 0)
+ {
+ _mkdir(tmpPath.c_str());
+ }
+#else
+ if(::stat(dbPath.c_str(), &filestat) != 0)
+ {
+ mkdir(dbPath.c_str(), 0755);
+ }
+ if(::stat(serversPath.c_str(), &filestat) != 0)
+ {
+ mkdir(serversPath.c_str(), 0755);
+ }
+ if(::stat(tmpPath.c_str(), &filestat) != 0)
+ {
+ mkdir(tmpPath.c_str(), 0755);
+ }
+#endif
+ }
+
+ //
+ // Check that required properties are set and valid.
+ //
+ if(properties->getProperty("IceGrid.Node.Endpoints").empty())
+ {
+ error("property `IceGrid.Node.Endpoints' is not set");
+ return false;
+ }
+
+ string name = properties->getProperty("IceGrid.Node.Name");
+ if(name.empty())
+ {
+ char host[1024 + 1];
+ if(gethostname(host, 1024) != 0)
+ {
+ syserror("property `IceGrid.Node.Name' is not set and couldn't get the hostname:");
+ return false;
+ }
+ else if(!nowarn)
+ {
+ warning("property `IceGrid.Node.Name' is not set, using hostname: " + string(host));
+ }
+ properties->setProperty("IceGrid.Node.Name", string(host));
+ }
+
+ //
+ // Setup the Freeze database environment home directory. The name of the database
+ // environment for the IceGrid node is the name of the node.
+ //
+ properties->setProperty("Freeze.DbEnv." + name + ".DbHome", dbPath);
+
+ //
+ // Set the adapter id for this node and create the node object adapter.
+ //
+ properties->setProperty("IceGrid.Node.AdapterId", "IceGrid.Node." + name);
+ ObjectAdapterPtr adapter = communicator()->createObjectAdapter("IceGrid.Node");
+
+ //
+ // Create the wait queue.
+ //
+ _waitQueue = new WaitQueue();
+ _waitQueue->start();
+
+ //
+ // Create the server factory. The server factory creates persistent objects
+ // for the server and server adapter. It also takes care of installing the
+ // evictors and object factories necessary to store these objects.
+ //
+ ServerFactoryPtr serverFactory = new ServerFactory(adapter, traceLevels, name, _activator, _waitQueue);
+ NodePtr node = new NodeI(_activator, name, serverFactory, communicator(), properties);
+ Identity id = stringToIdentity(IceUtil::generateUUID());
+ adapter->add(node, id);
+ NodePrx nodeProxy = NodePrx::uncheckedCast(adapter->createDirectProxy(id));
+
+ //
+ // Register this node with the node registry.
+ //
+ try
+ {
+ ObjectPrx nodeRegistry = communicator()->stringToProxy("IceGrid/NodeRegistry@IceGrid.Registry.Internal");
+ NodeRegistryPrx::uncheckedCast(nodeRegistry)->add(name, nodeProxy);
+ }
+ catch(const NodeActiveException&)
+ {
+ error("a node with the same name is already registered and active");
+ return false;
+ }
+ catch(const LocalException&)
+ {
+ error("couldn't contact the IceGrid registry");
+ return false;
+ }
+
+ //
+ // Check the consistency of the databases.
+ //
+ if(checkdb)
+ {
+ serverFactory->checkConsistency();
+ }
+
+ //
+ // Start the activator.
+ //
+ _activator->start();
+
+ //
+ // We are ready to go! Activate the object adapter. NOTE: we don't want the activate call to
+ // set the direct proxy of the object adapter with the locator registry. This was already
+ // taken care of by the node registry. Furthermore, this wouldn't work anyway because the
+ // locator registry proxy would have collocation optimization enabled.
+ //
+ adapter->setLocator(0);
+ adapter->activate();
+ adapter->setLocator(communicator()->getDefaultLocator());
+
+ //
+ // Deploy application if a descriptor is passed as a command-line option.
+ //
+ if(!descriptor.empty())
+ {
+ AdminPrx admin;
+ try
+ {
+ admin = AdminPrx::checkedCast(communicator()->stringToProxy("IceGrid/Admin"));
+ }
+ catch(const LocalException& ex)
+ {
+ ostringstream ostr;
+ ostr << "couldn't contact IceGrid admin interface to deploy application `" << descriptor << "':" << endl
+ << ex;
+ warning(ostr.str());
+ }
+
+ if(admin)
+ {
+ try
+ {
+ map<string, string> vars;
+ admin->addApplication(
+ DescriptorParser::parseApplicationDescriptor(descriptor, targets, vars, communicator()));
+ }
+ catch(const DeploymentException& ex)
+ {
+ ostringstream ostr;
+ ostr << "failed to deploy application `" << descriptor << "':" << endl << ex << ": " << ex.reason;
+ warning(ostr.str());
+ }
+ catch(const LocalException& ex)
+ {
+ ostringstream ostr;
+ ostr << "failed to deploy application `" << descriptor << "':" << endl << ex;
+ warning(ostr.str());
+ }
+ }
+ }
+
+ string bundleName = properties->getProperty("IceGrid.Node.PrintServersReady");
+ if(!bundleName.empty())
+ {
+ print(bundleName + " ready");
+ }
+
+ return true;
+}
+
+void
+NodeService::waitForShutdown()
+{
+ //
+ // Wait for the activator shutdown. Once the run method returns
+ // all the servers have been deactivated.
+ //
+ enableInterrupt();
+ _activator->waitForShutdown();
+ disableInterrupt();
+}
+
+bool
+NodeService::stop()
+{
+ try
+ {
+ _activator->destroy();
+ }
+ catch(...)
+ {
+ }
+
+ //
+ // The wait queue must be destroyed after the activator and before
+ // the communicator is shutdown.
+ //
+ try
+ {
+ _waitQueue->destroy();
+ }
+ catch(...)
+ {
+ }
+
+ //
+ // We can now safely shutdown the communicator.
+ //
+ try
+ {
+ communicator()->shutdown();
+ communicator()->waitForShutdown();
+ }
+ catch(...)
+ {
+ }
+
+ _activator = 0;
+
+ return true;
+}
+
+CommunicatorPtr
+NodeService::initializeCommunicator(int& argc, char* argv[])
+{
+ PropertiesPtr defaultProperties = getDefaultProperties(argc, argv);
+
+ //
+ // Make sure that IceGridNode doesn't use thread-per-connection.
+ //
+ defaultProperties->setProperty("Ice.ThreadPerConnection", "");
+
+ return Service::initializeCommunicator(argc, argv);
+}
+
+void
+NodeService::usage(const string& appName)
+{
+ string options =
+ "Options:\n"
+ "-h, --help Show this message.\n"
+ "-v, --version Display the Ice version.\n"
+ "--nowarn Don't print any security warnings.\n"
+ "\n"
+ "--deploy DESCRIPTOR [TARGET1 [TARGET2 ...]]\n"
+ " Deploy descriptor in file DESCRIPTOR, with\n"
+ " optional targets.\n"
+ "--checkdb Do a consistency check of the node database.";
+#ifdef _WIN32
+ if(checkSystem())
+ {
+ options.append(
+ "\n"
+ "\n"
+ "--service NAME Run as the Windows service NAME.\n"
+ "\n"
+ "--install NAME [--display DISP] [--executable EXEC] [args]\n"
+ " Install as Windows service NAME. If DISP is\n"
+ " provided, use it as the display name,\n"
+ " otherwise NAME is used. If EXEC is provided,\n"
+ " use it as the service executable, otherwise\n"
+ " this executable is used. Any additional\n"
+ " arguments are passed unchanged to the\n"
+ " service at startup.\n"
+ "--uninstall NAME Uninstall Windows service NAME.\n"
+ "--start NAME [args] Start Windows service NAME. Any additional\n"
+ " arguments are passed unchanged to the\n"
+ " service.\n"
+ "--stop NAME Stop Windows service NAME."
+ );
+ }
+#else
+ options.append(
+ "\n"
+ "\n"
+ "--daemon Run as a daemon.\n"
+ "--noclose Do not close open file descriptors.\n"
+ "--nochdir Do not change the current working directory."
+ );
+#endif
+ print("Usage: " + appName + " [options]\n" + options);
+}
+
+int
+main(int argc, char* argv[])
+{
+ NodeService svc;
+ return svc.main(argc, argv);
+}
diff --git a/cpp/src/IceGrid/IceGridRegistry.cpp b/cpp/src/IceGrid/IceGridRegistry.cpp
new file mode 100644
index 00000000000..bcc320a213f
--- /dev/null
+++ b/cpp/src/IceGrid/IceGridRegistry.cpp
@@ -0,0 +1,156 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 <IceUtil/Options.h>
+#include <Ice/Ice.h>
+#include <Ice/Service.h>
+#include <IceGrid/Registry.h>
+
+using namespace std;
+using namespace Ice;
+using namespace IceGrid;
+
+namespace IceGrid
+{
+
+class RegistryService : public Service
+{
+public:
+
+ RegistryService();
+
+protected:
+
+ virtual bool start(int, char*[]);
+ virtual CommunicatorPtr initializeCommunicator(int&, char*[]);
+
+private:
+
+ void usage(const std::string&);
+
+ RegistryPtr _registry;
+};
+
+} // End of namespace IceGrid
+
+RegistryService::RegistryService()
+{
+}
+
+bool
+RegistryService::start(int argc, char* argv[])
+{
+ bool nowarn;
+
+ IceUtil::Options opts;
+ opts.addOpt("h", "help");
+ opts.addOpt("v", "version");
+ opts.addOpt("", "nowarn");
+
+ vector<string> args;
+ try
+ {
+ args = opts.parse(argc, argv);
+ }
+ catch(const IceUtil::Options::BadOpt& e)
+ {
+ error(e.reason);
+ usage(argv[0]);
+ return false;
+ }
+
+ if(opts.isSet("h") || opts.isSet("help"))
+ {
+ usage(argv[0]);
+ return false;
+ }
+ if(opts.isSet("v") || opts.isSet("version"))
+ {
+ print(ICE_STRING_VERSION);
+ return false;
+ }
+ nowarn = opts.isSet("nowarn");
+
+ if(!args.empty())
+ {
+ usage(argv[0]);
+ return false;
+ }
+
+ _registry = new Registry(communicator());
+ if(!_registry->start(nowarn))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+CommunicatorPtr
+RegistryService::initializeCommunicator(int& argc, char* argv[])
+{
+ PropertiesPtr defaultProperties = getDefaultProperties(argc, argv);
+
+ //
+ // Make sure that IceGridRegistry doesn't use thread-per-connection.
+ //
+ defaultProperties->setProperty("Ice.ThreadPerConnection", "");
+
+ return Service::initializeCommunicator(argc, argv);
+}
+
+void
+RegistryService::usage(const string& appName)
+{
+ string options =
+ "Options:\n"
+ "-h, --help Show this message.\n"
+ "-v, --version Display the Ice version.\n"
+ "--nowarn Don't print any security warnings.";
+#ifdef _WIN32
+ if(checkSystem())
+ {
+ options.append(
+ "\n"
+ "\n"
+ "--service NAME Run as the Windows service NAME.\n"
+ "\n"
+ "--install NAME [--display DISP] [--executable EXEC] [args]\n"
+ " Install as Windows service NAME. If DISP is\n"
+ " provided, use it as the display name,\n"
+ " otherwise NAME is used. If EXEC is provided,\n"
+ " use it as the service executable, otherwise\n"
+ " this executable is used. Any additional\n"
+ " arguments are passed unchanged to the\n"
+ " service at startup.\n"
+ "--uninstall NAME Uninstall Windows service NAME.\n"
+ "--start NAME [args] Start Windows service NAME. Any additional\n"
+ " arguments are passed unchanged to the\n"
+ " service.\n"
+ "--stop NAME Stop Windows service NAME."
+ );
+ }
+#else
+ options.append(
+ "\n"
+ "\n"
+ "--daemon Run as a daemon.\n"
+ "--noclose Do not close open file descriptors.\n"
+ "--nochdir Do not change the current working directory."
+ );
+#endif
+ print("Usage: " + appName + " [options]\n" + options);
+}
+
+int
+main(int argc, char* argv[])
+{
+ RegistryService svc;
+ return svc.main(argc, argv);
+}
diff --git a/cpp/src/IceGrid/Internal.ice b/cpp/src/IceGrid/Internal.ice
new file mode 100644
index 00000000000..4fb73b5c473
--- /dev/null
+++ b/cpp/src/IceGrid/Internal.ice
@@ -0,0 +1,703 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 ICE_GRID_INTERNAL_ICE
+#define ICE_GRID_INTERNAL_ICE
+
+#include <Ice/Identity.ice>
+#include <Ice/BuiltinSequences.ice>
+#include <Ice/ProcessF.ice>
+#include <IceGrid/Admin.ice>
+
+module IceGrid
+{
+
+/**
+ *
+ * The object registry interface.
+ *
+ **/
+interface ObjectRegistry
+{
+ /**
+ *
+ * Add an object to the registry.
+ *
+ **/
+ void add(ObjectDescriptor desc)
+ throws ObjectExistsException;
+
+ /**
+ *
+ * Remove an object from the registry.
+ *
+ **/
+ void remove(Ice::Identity id)
+ throws ObjectNotExistException;
+
+ /**
+ *
+ * Find an object by identity and returns its description.
+ *
+ **/
+ nonmutating ObjectDescriptor getObjectDescriptor(Ice::Identity id)
+ throws ObjectNotExistException;
+
+ /**
+ *
+ * Find an object by identity and return its proxy.
+ *
+ **/
+ nonmutating Object* findById(Ice::Identity id)
+ throws ObjectNotExistException;
+
+ /**
+ *
+ * Find an object by type and return its proxy.
+ *
+ **/
+ nonmutating Object* findByType(string type);
+
+ /**
+ *
+ * Find all the objects with the given type.
+ *
+ **/
+ nonmutating Ice::ObjectProxySeq findAllWithType(string type);
+
+ /**
+ *
+ * Find all the objects matching the given expression.
+ *
+ **/
+ nonmutating ObjectDescriptorSeq findAll(string expression);
+};
+
+/**
+ *
+ * This exception is raised if an adapter is active.
+ *
+ **/
+exception AdapterActiveException
+{
+};
+
+exception AdapterNotActiveException
+{
+ /** True if the adapter can be activated on demand. */
+ bool activatable;
+
+ /** How long to wait for the adapter to become active. */
+ int timeout;
+};
+
+interface Adapter
+{
+ /**
+ *
+ * Activate this adapter. If this adapter can be activated, this
+ * will activate the adapter and return the direct proxy of the
+ * adapter once it's active. If this adapter can be activated on
+ * demand, this will return 0 if the adapter is inactive or the
+ * adapter direct proxy it's active.
+ *
+ **/
+ ["ami", "amd"] Object* activate();
+
+ /**
+ *
+ * Get the adapter direct proxy. The adapter direct proxy is a
+ * proxy created with the object adapter. The proxy contains the
+ * last known adapter endpoints.
+ *
+ * @return A direct proxy containing the last known adapter
+ * endpoints if the adapter is already active.
+ *
+ **/
+ ["ami"] nonmutating Object* getDirectProxy()
+ throws AdapterNotActiveException;
+
+ /**
+ *
+ * Set the direct proxy for this adapter.
+ *
+ * @param The direct proxy. The direct proxy should be created
+ * with the object adapter and should contain the object adapter
+ * endpoints.
+ *
+ * @throws AdapterActiveException The adapter is already
+ * active. It's not possible to override the direct proxy of an
+ * active adapter.
+ *
+ **/
+ ["ami"] void setDirectProxy(Object* proxy)
+ throws AdapterActiveException;
+
+ /**
+ *
+ * Destroy the adapter.
+ *
+ **/
+ void destroy();
+};
+
+/**
+ *
+ * This exception is raised if an adapter with the same name already
+ * exists.
+ *
+ **/
+exception AdapterExistsException
+{
+};
+
+/**
+ *
+ * The adapter registry interface.
+ *
+ **/
+interface AdapterRegistry
+{
+ /**
+ *
+ * Add an adapter to the registry.
+ *
+ **/
+ void add(string id, Adapter* adpt)
+ throws AdapterExistsException;
+
+ /**
+ *
+ * Remove an adapter from the registry. If the given adapter proxy is not null, the adapter will
+ * be removed from the registry only if the proxy matches.
+ *
+ **/
+ Adapter* remove(string id, Adapter* adpt)
+ throws AdapterNotExistException;
+
+ /**
+ *
+ * Find an adapter and return its proxy.
+ *
+ **/
+ Adapter* findById(string id)
+ throws AdapterNotExistException;
+
+ /**
+ *
+ * Get all adapter ids.
+ *
+ **/
+ nonmutating Ice::StringSeq getAll();
+};
+
+/**
+ *
+ * A standalone adapter doesn't provide on demand activation. It just
+ * store the adapter endpoints in the proxy attribute.
+ *
+ **/
+class StandaloneAdapter implements Adapter
+{
+ /**
+ *
+ * The adapter direct proxy.
+ *
+ **/
+ Object* proxy;
+};
+
+class Server;
+
+/**
+ *
+ * This class implements the [Adapter] interface and provides on
+ * demand server activation when the adapter endpoints are requested
+ * through the [getDirectProxy] method.
+ *
+ **/
+class ServerAdapter implements Adapter
+{
+ /**
+ *
+ * Returns the adaper id.
+ *
+ **/
+ string getId();
+
+ /**
+ *
+ * The adapter server.
+ *
+ **/
+ Server* svr;
+
+ /**
+ *
+ * The adapter id.
+ *
+ **/
+ string id;
+};
+
+/**
+ *
+ * A sequence of server adapter proxies.
+ *
+ **/
+dictionary<Ice::Identity, ServerAdapter*> ServerAdapterPrxDict;
+
+class Server
+{
+ /**
+ *
+ * Start the server.
+ *
+ * @param mode The activation mode requested, start returns false
+ * if the activation mode requested is not compatible with the
+ * server activation mode. For example if mode is Automatic and
+ * the server activation mode is Manual the start will return
+ * false.
+ *
+ * @return True if the server was successfully started, false
+ * otherwise.
+ *
+ **/
+ bool start(ServerActivation mode);
+
+ /**
+ *
+ * Stop the server. This methods returns only when the server is
+ * deactivated. If the server doesn't stop after a configurable
+ * amount of time, it will be killed.
+ *
+ **/
+ void stop();
+
+ /**
+ *
+ * Send signal to the server
+ *
+ **/
+ void sendSignal(string signal)
+ throws BadSignalException;
+
+ /**
+ *
+ * Write message on servers' stdout or stderr.
+ *
+ **/
+ void writeMessage(string message, int fd);
+
+ /**
+ *
+ * Destroy the server. This method destroys the server and
+ * eventually deactivates if it's still active.
+ *
+ **/
+ void destroy();
+
+ /**
+ *
+ * This method is called by the activator when it detects that the
+ * server has terminated.
+ *
+ **/
+ void terminated();
+
+ /**
+ *
+ * Return the server state.
+ *
+ * @return The server state.
+ *
+ * @see ServerState
+ *
+ **/
+ ServerState getState();
+
+ /**
+ *
+ * Get the server pid. Note that the value returned by this method
+ * is system dependant. On Unix operating systems, it's the pid
+ * value returned by the fork() system call and converted to an
+ * integer.
+ *
+ **/
+ int getPid();
+
+ /**
+ *
+ * Get the descriptor used to deploy this server.
+ *
+ **/
+ ServerDescriptor getDescriptor();
+
+ /**
+ *
+ * Set the server activation mode.
+ *
+ **/
+ void setActivationMode(ServerActivation mode);
+
+ /**
+ *
+ * Get the server activation mode.
+ *
+ **/
+ ServerActivation getActivationMode();
+
+ /**
+ *
+ * Set the process proxy.
+ *
+ **/
+ ["ami"] void setProcess(Ice::Process* proc);
+
+ /**
+ *
+ * Set the server executable path.
+ *
+ **/
+ void setExePath(string name);
+
+ /**
+ *
+ * Set the path of the server working directory.
+ *
+ **/
+ void setPwd(string path);
+
+ /**
+ *
+ * Set the server environment variables.
+ *
+ **/
+ void setEnvs(Ice::StringSeq envs);
+
+ /**
+ *
+ * Set the server command line options.
+ *
+ **/
+ void setOptions(Ice::StringSeq options);
+
+ /**
+ *
+ * Add an adapter to this server.
+ *
+ **/
+ void addAdapter(ServerAdapter* adapter, bool registerProcess)
+ throws DeploymentException;
+
+ /**
+ *
+ * Remove an adapter from this server.
+ *
+ **/
+ void removeAdapter(ServerAdapter* adapter);
+
+ /**
+ *
+ * Add a configuration file.
+ *
+ **/
+ string addConfigFile(string name, PropertyDescriptorSeq properties)
+ throws DeploymentException;
+
+ /**
+ *
+ * Remove a configuration file.
+ *
+ **/
+ void removeConfigFile(string name);
+
+ /**
+ *
+ * Add a database environment.
+ *
+ **/
+ string addDbEnv(DbEnvDescriptor dbEnv, string path)
+ throws DeploymentException;
+
+ /**
+ *
+ * Remove a database environment.
+ *
+ **/
+ void removeDbEnv(DbEnvDescriptor dbEnv, string path);
+
+ /** The server name. */
+ string name;
+
+ /** The path of the server executable. */
+ string exePath;
+
+ /** The server environment variables. */
+ Ice::StringSeq envs;
+
+ /** The server command line options. */
+ Ice::StringSeq options;
+
+ /** The path to the server working directory. */
+ string pwd;
+
+ /** The server adapter proxies. */
+ ServerAdapterPrxDict adapters;
+
+ /** The server activation mode. */
+ ServerActivation activation;
+
+ /** True if an adapter is configured to register a process object. */
+ bool processRegistered;
+
+ /** The descriptor used to deploy this server. */
+ ServerDescriptor descriptor;
+};
+
+/**
+ *
+ * This exception is raised if a server with the same name already
+ * exists.
+ *
+ **/
+exception ServerExistsException
+{
+};
+
+interface ServerRegistry
+{
+ /**
+ *
+ * Add a server to the registry.
+ *
+ **/
+ void add(string name, Server* svr, ServerDescriptor descriptor)
+ throws ServerExistsException;
+
+ /**
+ *
+ * Remove a server from the registry.
+ *
+ **/
+ Server* remove(string name)
+ throws ServerNotExistException;
+
+ /**
+ *
+ * Find a server.
+ *
+ * @param name Name of the server.
+ *
+ * @return Server proxy.
+ *
+ **/
+ Server* findByName(string name)
+ throws ServerNotExistException;
+
+ /**
+ *
+ * Get a server descriptor.
+ *
+ **/
+ ServerDescriptor getDescriptor(string name)
+ throws ServerNotExistException;
+
+ /**
+ *
+ * Get all the server names.
+ *
+ **/
+ nonmutating Ice::StringSeq getAll();
+
+ /**
+ *
+ * Get all the server descriptors for servers deployed on the given node.
+ *
+ **/
+ nonmutating ServerDescriptorSeq getAllDescriptorsOnNode(string node);
+};
+
+/**
+ *
+ * This exception is raised if a server with the same name already
+ * exists.
+ *
+ **/
+exception ApplicationExistsException
+{
+};
+
+interface ApplicationRegistry
+{
+ /**
+ *
+ * Add an application to the registry.
+ *
+ **/
+ void add(string name)
+ throws ApplicationExistsException;
+
+ /**
+ *
+ * Remove an application from the registry.
+ *
+ **/
+ void remove(string name)
+ throws ApplicationNotExistException;
+
+ /**
+ *
+ * Register a server with the given application.
+ *
+ **/
+ void registerServer(string application, string name)
+ throws ApplicationNotExistException;
+
+ /**
+ *
+ * Unregister a server from the given application.
+ *
+ **/
+ void unregisterServer(string application, string name)
+ throws ApplicationNotExistException;
+
+ /**
+ *
+ * Get an application descriptor.
+ *
+ **/
+ ApplicationDescriptor getDescriptor(string name)
+ throws ApplicationNotExistException;
+
+ /**
+ *
+ * Get all the application names.
+ *
+ **/
+ nonmutating Ice::StringSeq getAll();
+};
+
+interface Node
+{
+ /**
+ *
+ * Create a new server on this node.
+ *
+ * @param The name of the server.
+ *
+ * @param The descriptor of the server.
+ *
+ **/
+ nonmutating Server* createServer(string name, ServerDescriptor desc)
+ throws DeploymentException;
+
+ /**
+ *
+ * Create a new adapter of a given server on this node.
+ *
+ * @param server The server associted to the adapter.
+ *
+ * @param id The id of the adapter.
+ *
+ **/
+ nonmutating ServerAdapter* createServerAdapter(Server* srv, string id);
+
+ /**
+ *
+ * Create a temporary directory.
+ *
+ **/
+ nonmutating string createTmpDir();
+
+ /**
+ *
+ * Destroy a temporary directory.
+ *
+ **/
+ nonmutating void destroyTmpDir(string path);
+
+ /**
+ *
+ * Get the node name.
+ *
+ **/
+ nonmutating string getName();
+
+ /**
+ *
+ * Get the node hostname.
+ *
+ **/
+ nonmutating string getHostname();
+
+ /**
+ *
+ * Shutdown the node.
+ *
+ **/
+ nonmutating void shutdown();
+};
+
+/**
+ *
+ * This exception is raised if a node is already registered and
+ * active.
+ *
+ **/
+exception NodeActiveException
+{
+};
+
+interface NodeRegistry
+{
+ /**
+ *
+ * Add a node to the registry. If a node with the same name is
+ * already registered, [add] will overide the previous node only
+ * if it's not active.
+ *
+ * @throws NodeActiveException Raised if the node is already
+ * registered and currently active.
+ *
+ **/
+ void add(string name, Node* nd)
+ throws NodeActiveException;
+
+ /**
+ *
+ * Remove a node from the registry.
+ *
+ **/
+ void remove(string name)
+ throws NodeNotExistException;
+
+ /**
+ *
+ * Find a node.
+ *
+ * @param name Name of the node.
+ *
+ * @return Node proxy or a null proxy if the node is not found.
+ *
+ **/
+ Node* findByName(string name)
+ throws NodeNotExistException;
+
+ /**
+ *
+ * Get all the node names.
+ *
+ **/
+ nonmutating Ice::StringSeq getAll();
+};
+
+};
+
+#endif
diff --git a/cpp/src/IceGrid/LocatorI.cpp b/cpp/src/IceGrid/LocatorI.cpp
new file mode 100644
index 00000000000..27a8b7c1403
--- /dev/null
+++ b/cpp/src/IceGrid/LocatorI.cpp
@@ -0,0 +1,336 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 <IceGrid/LocatorI.h>
+
+using namespace std;
+using namespace IceGrid;
+
+namespace IceGrid
+{
+
+//
+// Callback from asynchronous call to adapter->getDirectProxy() invoked in LocatorI::findAdapterById_async().
+//
+class AMI_Adapter_getDirectProxyI : public AMI_Adapter_getDirectProxy
+{
+public:
+
+ AMI_Adapter_getDirectProxyI(const LocatorIPtr& locator, const string& id, const AdapterPrx& adapter) :
+ _locator(locator), _id(id), _adapter(adapter)
+ {
+ }
+
+ virtual void ice_response(const ::Ice::ObjectPrx& obj)
+ {
+ assert(obj);
+ _locator->getDirectProxyCallback(_adapter->ice_getIdentity(), obj);
+ }
+
+ virtual void ice_exception(const ::Ice::Exception& ex)
+ {
+ _locator->getDirectProxyException(_adapter, _id, ex);
+ }
+
+private:
+
+ const LocatorIPtr _locator;
+ const string _id;
+ const AdapterPrx _adapter;
+};
+
+class AMI_Adapter_activateI : public AMI_Adapter_activate
+{
+public:
+
+ AMI_Adapter_activateI(const LocatorIPtr& locator, const string& id, const AdapterPrx& adapter) :
+ _locator(locator), _id(id), _adapter(adapter)
+ {
+ }
+
+ virtual void ice_response(const ::Ice::ObjectPrx& obj)
+ {
+ _locator->getDirectProxyCallback(_adapter->ice_getIdentity(), obj);
+ }
+
+ virtual void ice_exception(const ::Ice::Exception& ex)
+ {
+ _locator->getDirectProxyException(_adapter, _id, ex);
+ }
+
+private:
+
+ const LocatorIPtr _locator;
+ const string _id;
+ const AdapterPrx _adapter;
+};
+
+//
+// Callback from asynchrnous call to LocatorI::findAdapterById_async() invoked in LocatorI::findObjectById_async().
+//
+class AMD_Locator_findAdapterByIdI : public Ice::AMD_Locator_findAdapterById
+{
+public:
+
+ AMD_Locator_findAdapterByIdI(const Ice::AMD_Locator_findObjectByIdPtr& cb, const Ice::ObjectPrx& obj) :
+ _cb(cb),
+ _obj(obj)
+ {
+ }
+
+ virtual void ice_response(const ::Ice::ObjectPrx& obj)
+ {
+ //
+ // If the adapter dummy direct proxy is not null, return a
+ // proxy containing the identity we were looking for and the
+ // endpoints of the adapter.
+ //
+ // If null, return the proxy registered with the object
+ // registry.
+ //
+ if(obj)
+ {
+ _cb->ice_response(obj->ice_newIdentity(_obj->ice_getIdentity()));
+ }
+ else
+ {
+ _cb->ice_response(_obj);
+ }
+ }
+
+ virtual void ice_exception(const ::Ice::Exception& ex)
+ {
+ try
+ {
+ ex.ice_throw();
+ }
+ catch(Ice::AdapterNotFoundException&)
+ {
+ //
+ // We couldn't find the adapter, we ignore and return the
+ // original proxy containing the adapter id.
+ //
+ _cb->ice_response(_obj);
+ return;
+ }
+ catch(const Ice::Exception& ex)
+ {
+ //
+ // Rethrow unexpected exception.
+ //
+ _cb->ice_exception(ex);
+ return;
+ }
+
+ assert(false);
+ }
+
+ virtual void ice_exception(const std::exception& ex)
+ {
+ _cb->ice_exception(ex);
+ }
+
+ virtual void ice_exception()
+ {
+ _cb->ice_exception();
+ }
+
+private:
+
+ const Ice::AMD_Locator_findObjectByIdPtr _cb;
+ const Ice::ObjectPrx _obj;
+};
+
+}
+
+LocatorI::LocatorI(const AdapterRegistryPtr& adapterRegistry,
+ const ObjectRegistryPtr& objectRegistry,
+ const Ice::LocatorRegistryPrx& locatorRegistry) :
+ _adapterRegistry(adapterRegistry),
+ _objectRegistry(objectRegistry),
+ _locatorRegistry(locatorRegistry)
+{
+}
+
+//
+// Find an object by identity. The object is searched in the object
+// registry.
+//
+void
+LocatorI::findObjectById_async(const Ice::AMD_Locator_findObjectByIdPtr& cb,
+ const Ice::Identity& id,
+ const Ice::Current& current) const
+{
+ ObjectDescriptor obj;
+ try
+ {
+ obj = _objectRegistry->getObjectDescriptor(id);
+ }
+ catch(const ObjectNotExistException&)
+ {
+ throw Ice::ObjectNotFoundException();
+ }
+
+ //
+ // OPTIMIZATION: If the object is registered with an adapter id, try to get the adapter direct
+ // proxy (which might caused the server activation). This will avoid the client to lookup for
+ // the adapter id endpoints.
+ //
+ if(!obj.adapterId.empty())
+ {
+ Ice::AMD_Locator_findAdapterByIdPtr amiCB = new AMD_Locator_findAdapterByIdI(cb, obj.proxy);
+ findAdapterById_async(amiCB, obj.adapterId, current);
+ }
+ else
+ {
+ cb->ice_response(obj.proxy);
+ }
+}
+
+//
+// Find an adapter by identity. The object is searched in the adapter
+// registry. If found, we try to get its direct proxy.
+//
+void
+LocatorI::findAdapterById_async(const Ice::AMD_Locator_findAdapterByIdPtr& cb,
+ const string& id,
+ const Ice::Current&) const
+{
+ AdapterPrx adapter;
+ try
+ {
+ adapter = AdapterPrx::uncheckedCast(_adapterRegistry->findById(id)->ice_collocationOptimization(false));
+ }
+ catch(const AdapterNotExistException&)
+ {
+ throw Ice::AdapterNotFoundException();
+ }
+
+ LocatorIPtr self = const_cast<LocatorI*>(this);
+ if(self->getDirectProxyRequest(cb, adapter))
+ {
+ try
+ {
+ AMI_Adapter_getDirectProxyPtr amiCB = new AMI_Adapter_getDirectProxyI(self, id, adapter);
+ adapter->getDirectProxy_async(amiCB);
+ }
+ catch(const Ice::LocalException& ex)
+ {
+ self->getDirectProxyException(adapter, id, ex);
+ }
+ }
+}
+
+Ice::LocatorRegistryPrx
+LocatorI::getRegistry(const Ice::Current&) const
+{
+ return _locatorRegistry;
+}
+
+bool
+LocatorI::getDirectProxyRequest(const Ice::AMD_Locator_findAdapterByIdPtr& cb, const AdapterPrx& adapter)
+{
+ Lock sync(*this);
+
+ //
+ // Check if there's already pending requests for this adapter. If that's the case,
+ // we just add this one to the queue. If not, we add it to the queue and initiate
+ // a call on the adapter to get its direct proxy.
+ //
+ PendingRequestsMap::iterator p;
+ p = _pendingRequests.insert(make_pair(adapter->ice_getIdentity(), PendingRequests())).first;
+ p->second.push_back(cb);
+ return p->second.size() == 1;
+}
+
+void
+LocatorI::getDirectProxyException(const AdapterPrx& adapter, const string& id, const Ice::Exception& ex)
+{
+ Lock sync(*this);
+
+ PendingRequestsMap::iterator p = _pendingRequests.find(adapter->ice_getIdentity());
+ assert(p != _pendingRequests.end());
+ try
+ {
+ ex.ice_throw();
+ }
+ catch(const AdapterNotActiveException& ex)
+ {
+ if(ex.activatable)
+ {
+ //
+ // Activate the adapter if it can be activated on demand. NOTE: we use the timeout
+ // provided in the exception to activate the adapter. The timeout correspond to the
+ // wait time configured for the server.
+ //
+ try
+ {
+ AMI_Adapter_activatePtr amiCB = new AMI_Adapter_activateI(this, id, adapter);
+ AdapterPrx::uncheckedCast(adapter->ice_timeout(ex.timeout))->activate_async(amiCB);
+ }
+ catch(const Ice::LocalException& ex)
+ {
+ getDirectProxyException(adapter, id, ex);
+ }
+ return;
+ }
+ else
+ {
+ for(PendingRequests::const_iterator q = p->second.begin(); q != p->second.end(); ++q)
+ {
+ (*q)->ice_response(0);
+ }
+ }
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ //
+ // Expected if the adapter is destroyed, if that's the case, we remove it from the adapter registry.
+ //
+ try
+ {
+ _adapterRegistry->remove(id, adapter);
+ }
+ catch(const AdapterNotExistException&)
+ {
+ }
+
+ for(PendingRequests::const_iterator q = p->second.begin(); q != p->second.end(); ++q)
+ {
+ (*q)->ice_exception(Ice::AdapterNotFoundException());
+ }
+ }
+ catch(const Ice::LocalException&)
+ {
+ for(PendingRequests::const_iterator q = p->second.begin(); q != p->second.end(); ++q)
+ {
+ (*q)->ice_response(0);
+ }
+ }
+ catch(const Ice::Exception&)
+ {
+ assert(false);
+ }
+ _pendingRequests.erase(p);
+}
+
+void
+LocatorI::getDirectProxyCallback(const Ice::Identity& adapterId, const Ice::ObjectPrx& proxy)
+{
+ Lock sync(*this);
+
+ PendingRequestsMap::iterator p = _pendingRequests.find(adapterId);
+ assert(p != _pendingRequests.end());
+ for(PendingRequests::const_iterator q = p->second.begin(); q != p->second.end(); ++q)
+ {
+ (*q)->ice_response(proxy);
+ }
+ _pendingRequests.erase(p);
+}
diff --git a/cpp/src/IceGrid/LocatorI.h b/cpp/src/IceGrid/LocatorI.h
new file mode 100644
index 00000000000..d79740871c3
--- /dev/null
+++ b/cpp/src/IceGrid/LocatorI.h
@@ -0,0 +1,53 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 ICE_GRID_LOCATOR_I_H
+#define ICE_GRID_LOCATOR_I_H
+
+#include <IceGrid/Internal.h>
+#include <Ice/Locator.h>
+
+namespace IceGrid
+{
+
+class LocatorI : public Ice::Locator, public IceUtil::Mutex
+{
+public:
+
+ LocatorI(const AdapterRegistryPtr&, const ObjectRegistryPtr&, const ::Ice::LocatorRegistryPrx&);
+
+ virtual void findObjectById_async(const ::Ice::AMD_Locator_findObjectByIdPtr&, const ::Ice::Identity&,
+ const ::Ice::Current&) const;
+
+ virtual void findAdapterById_async(const ::Ice::AMD_Locator_findAdapterByIdPtr&, const ::std::string&,
+ const ::Ice::Current&) const;
+
+ virtual ::Ice::LocatorRegistryPrx getRegistry(const ::Ice::Current&) const;
+
+ bool getDirectProxyRequest(const ::Ice::AMD_Locator_findAdapterByIdPtr&, const AdapterPrx&);
+ void getDirectProxyException(const AdapterPrx&, const std::string&, const Ice::Exception&);
+ void getDirectProxyCallback(const Ice::Identity&, const Ice::ObjectPrx&);
+
+protected:
+
+ const AdapterRegistryPtr _adapterRegistry;
+ const ObjectRegistryPtr _objectRegistry;
+ const Ice::LocatorRegistryPrx _locatorRegistry;
+
+ typedef std::vector<Ice::AMD_Locator_findAdapterByIdPtr> PendingRequests;
+ typedef std::map<Ice::Identity, PendingRequests> PendingRequestsMap;
+
+ PendingRequestsMap _pendingRequests;
+};
+
+typedef IceUtil::Handle<LocatorI> LocatorIPtr;
+
+}
+
+#endif
diff --git a/cpp/src/IceGrid/LocatorRegistryI.cpp b/cpp/src/IceGrid/LocatorRegistryI.cpp
new file mode 100644
index 00000000000..b6e02518035
--- /dev/null
+++ b/cpp/src/IceGrid/LocatorRegistryI.cpp
@@ -0,0 +1,188 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 <IceGrid/LocatorRegistryI.h>
+#include <IceGrid/AdapterFactory.h>
+
+using namespace std;
+using namespace IceGrid;
+
+class AMI_Adapter_setDirectProxyI : public AMI_Adapter_setDirectProxy
+{
+public:
+
+ AMI_Adapter_setDirectProxyI(const Ice::AMD_LocatorRegistry_setAdapterDirectProxyPtr& cb) : _cb(cb)
+ {
+ }
+
+ virtual void ice_response()
+ {
+ _cb->ice_response();
+ }
+
+ virtual void ice_exception(const ::Ice::Exception& ex)
+ {
+ try
+ {
+ ex.ice_throw();
+ }
+ catch(const AdapterActiveException&)
+ {
+ _cb->ice_exception(Ice::AdapterAlreadyActiveException());
+ return;
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ _cb->ice_exception(Ice::AdapterNotFoundException()); // Expected if the adapter was destroyed.
+ return;
+ }
+ catch(const Ice::LocalException&)
+ {
+ _cb->ice_response();
+ return;
+ }
+
+ assert(false);
+ }
+
+private:
+
+ Ice::AMD_LocatorRegistry_setAdapterDirectProxyPtr _cb;
+};
+
+class AMI_Server_setProcessI : public AMI_Server_setProcess
+{
+public:
+
+ AMI_Server_setProcessI(const Ice::AMD_LocatorRegistry_setServerProcessProxyPtr& cb) : _cb(cb)
+ {
+ }
+
+ virtual void ice_response()
+ {
+ _cb->ice_response();
+ }
+
+ virtual void ice_exception(const ::Ice::Exception& ex)
+ {
+ try
+ {
+ ex.ice_throw();
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ _cb->ice_exception(Ice::ServerNotFoundException()); // Expected if the adapter was destroyed.
+ return;
+ }
+ catch(const Ice::LocalException&)
+ {
+ _cb->ice_response();
+ return;
+ }
+
+ assert(false);
+ }
+
+private:
+
+ Ice::AMD_LocatorRegistry_setServerProcessProxyPtr _cb;
+};
+
+LocatorRegistryI::LocatorRegistryI(const AdapterRegistryPtr& adapterRegistry,
+ const ServerRegistryPtr& serverRegistry,
+ const AdapterFactoryPtr& adapterFactory,
+ bool dynamicRegistration) :
+ _adapterRegistry(adapterRegistry),
+ _serverRegistry(serverRegistry),
+ _adapterFactory(adapterFactory),
+ _dynamicRegistration(dynamicRegistration)
+{
+}
+
+void
+LocatorRegistryI::setAdapterDirectProxy_async(const Ice::AMD_LocatorRegistry_setAdapterDirectProxyPtr& cb,
+ const string& id,
+ const Ice::ObjectPrx& proxy,
+ const Ice::Current&)
+{
+ while(true)
+ {
+ try
+ {
+ //
+ // Get the adapter from the registry and set its direct proxy.
+ //
+ AMI_Adapter_setDirectProxyPtr amiCB = new AMI_Adapter_setDirectProxyI(cb);
+ _adapterRegistry->findById(id)->setDirectProxy_async(amiCB, proxy);
+ return;
+ }
+ catch(const AdapterNotExistException&)
+ {
+ }
+ catch(const Ice::LocalException&)
+ {
+ cb->ice_response();
+ return;
+ }
+
+ if(_dynamicRegistration)
+ {
+ //
+ // Create a new standalone adapter. The adapter will be persistent. It's the responsability of
+ // the user to cleanup adapter entries which were dynamically added from the registry.
+ //
+ AdapterPrx adapter = _adapterFactory->createStandaloneAdapter(id);
+ try
+ {
+ _adapterRegistry->add(id, adapter);
+ }
+ catch(const AdapterExistsException&)
+ {
+ adapter->destroy();
+ }
+ }
+ else
+ {
+ throw Ice::AdapterNotFoundException();
+ }
+ }
+}
+
+void
+LocatorRegistryI::setServerProcessProxy_async(const Ice::AMD_LocatorRegistry_setServerProcessProxyPtr& cb,
+ const string& name,
+ const Ice::ProcessPrx& proxy,
+ const Ice::Current&)
+{
+ try
+ {
+ //
+ // Get the server from the registry and set its process proxy.
+ //
+ AMI_Server_setProcessPtr amiCB = new AMI_Server_setProcessI(cb);
+ _serverRegistry->findByName(name)->setProcess_async(amiCB, proxy);
+ return;
+ }
+ catch(const ServerNotExistException&)
+ {
+ }
+ catch(const Ice::LocalException&)
+ {
+ //
+ // TODO: We couldn't contact the server object. This is possibly because the IceGrid node is down and
+ // the server is started manually for example. We should probably throw here to prevent the server
+ // from starting?
+ //
+ cb->ice_response();
+ return;
+ }
+
+ throw Ice::ServerNotFoundException();
+}
diff --git a/cpp/src/IceGrid/LocatorRegistryI.h b/cpp/src/IceGrid/LocatorRegistryI.h
new file mode 100644
index 00000000000..21ff4b28339
--- /dev/null
+++ b/cpp/src/IceGrid/LocatorRegistryI.h
@@ -0,0 +1,44 @@
+
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 ICE_GRID_LOCATOR_REGISTRY_I_H
+#define ICE_GRID_LOCATOR_REGISTRY_I_H
+
+#include <IceGrid/Internal.h>
+#include <Ice/Locator.h>
+
+namespace IceGrid
+{
+
+class AdapterFactory;
+typedef IceUtil::Handle<AdapterFactory> AdapterFactoryPtr;
+
+class LocatorRegistryI : public Ice::LocatorRegistry
+{
+public:
+
+ LocatorRegistryI(const AdapterRegistryPtr&, const ServerRegistryPtr&, const AdapterFactoryPtr&, bool);
+
+ virtual void setAdapterDirectProxy_async(const Ice::AMD_LocatorRegistry_setAdapterDirectProxyPtr&,
+ const ::std::string&, const ::Ice::ObjectPrx&, const ::Ice::Current&);
+ virtual void setServerProcessProxy_async(const Ice::AMD_LocatorRegistry_setServerProcessProxyPtr&,
+ const ::std::string&, const ::Ice::ProcessPrx&, const ::Ice::Current&);
+
+private:
+
+ const AdapterRegistryPtr _adapterRegistry;
+ const ServerRegistryPtr _serverRegistry;
+ const AdapterFactoryPtr _adapterFactory;
+ const bool _dynamicRegistration;
+};
+
+}
+
+#endif
diff --git a/cpp/src/IceGrid/Makefile b/cpp/src/IceGrid/Makefile
index 1b041513be4..924e40addd8 100644
--- a/cpp/src/IceGrid/Makefile
+++ b/cpp/src/IceGrid/Makefile
@@ -9,32 +9,119 @@
top_srcdir = ../..
+LIBFILENAME = $(call mklibfilename,IceGrid,$(VERSION))
+SONAME = $(call mksoname,IceGrid,$(SOVERSION))
+LIBNAME = $(call mklibname,IceGrid)
+
PERFLIBFILENAME = $(call mklibfilename,IcePerf,$(VERSION))
PERFSONAME = $(call mksoname,IcePerf,$(SOVERSION))
PERFLIBNAME = $(call mklibname,IcePerf)
+ADMIN = $(top_srcdir)/bin/icegridadmin
+NODE_SERVER = $(top_srcdir)/bin/icegridnode
+REGISTRY_SERVER = $(top_srcdir)/bin/icegridregistry
+
+LIBTARGETS = $(call mklibtargets,$(libdir)/$(LIBFILENAME),$(libdir)/$(SONAME),$(libdir)/$(LIBNAME))
+PERFLIBTARGETS = $(call mklibtargets,$(libdir)/$(PERFLIBFILENAME),$(libdir)/$(PERFSONAME),$(libdir)/$(PERFLIBNAME))
+TARGETS = $(PERFLIBTARGETS) $(LIBTARGETS) $(NODE_SERVER) $(REGISTRY_SERVER) $(ADMIN)
-LIBTARGETS = $(call mklibtargets,$(libdir)/$(PERFLIBFILENAME),$(libdir)/$(PERFSONAME),$(libdir)/$(PERFLIBNAME))
-TARGETS = $(LIBTARGETS)
+LIB_OBJS = Admin.o \
+ Query.o \
+ Exception.o
PERFLIB_OBJS = PerfTypes.o \
PerfLinux.o
-SRCS = $(PERFLIB_OBJS:.o=.cpp)
-
-SLICE_SRCS = $(SDIR)/PerfTypes.ice
+ADMIN_OBJS = Grammar.o \
+ Scanner.o \
+ Parser.o \
+ DescriptorVisitor.o \
+ DescriptorParser.o \
+ DescriptorUtil.o \
+ Client.o
+
+COMMON_OBJS = Internal.o \
+ TraceLevels.o
+
+NODE_OBJS = NodeI.o \
+ ServerFactory.o \
+ ServerI.o \
+ ServerAdapterI.o \
+ Activator.o \
+ WaitQueue.o \
+ DescriptorParser.o
+
+REGISTRY_OBJS = Registry.o \
+ ObjectRegistryI.o \
+ AdapterRegistryI.o \
+ ServerRegistryI.o \
+ NodeRegistryI.o \
+ ApplicationRegistryI.o \
+ StringObjectProxyDict.o \
+ StringObjectProxySeqDict.o \
+ StringServerDescriptorDict.o \
+ StringStringSeqDict.o \
+ IdentityObjectDescDict.o \
+ LocatorI.o \
+ LocatorRegistryI.o \
+ AdapterFactory.o \
+ AdapterI.o \
+ AdminI.o \
+ DescriptorVisitor.o \
+ DescriptorUtil.o \
+ QueryI.o
+
+NODE_SVR_OBJS = $(COMMON_OBJS) \
+ $(NODE_OBJS) \
+ $(REGISTRY_OBJS) \
+ IceGridNode.o
+
+REGISTRY_SVR_OBJS = \
+ $(COMMON_OBJS) \
+ $(REGISTRY_OBJS) \
+ IceGridRegistry.o
+
+SRCS = $(LIB_OBJS:.o=.cpp) \
+ $(PERFLIB_OBJS:.o=.cpp) \
+ $(ADMIN_OBJS:.o=.cpp) \
+ $(COMMON_OBJS:.o=.cpp) \
+ $(NODE_OBJS:.o=.cpp) \
+ $(REGISTRY_OBJS:.o=.cpp) \
+ IceGridNode.cpp \
+ IceGridRegistry.cpp
+
+SLICE_SRCS = $(SDIR)/PerfTypes.ice \
+ $(SDIR)/Admin.ice \
+ $(SDIR)/Exception.ice \
+ $(SDIR)/Query.ice \
+ Internal.ice
HDIR = $(includedir)/IceGrid
LOCAL_HDIR = ../IceGrid
SDIR = $(slicedir)/IceGrid
LOCAL_SDIR = ../IceGrid
+SLICE2FREEZECMD = $(SLICE2FREEZE) --ice --include-dir IceGrid $(ICECPPFLAGS)
+
include $(top_srcdir)/config/Make.rules
-CPPFLAGS := $(CPPFLAGS) -DICE_PERF_API_EXPORTS
-SLICE2CPPFLAGS := --ice --include-dir IceGrid --dll-export ICE_PERF_API $(SLICE2CPPFLAGS)
+CPPFLAGS := $(CPPFLAGS) -I.. -DICE_GRID_API_EXPORTS $(READLINE_FLAGS)
+ICECPPFLAGS := $(ICECPPFLAGS) -I..
+SLICE2CPPFLAGS := --checksum --ice --include-dir IceGrid --dll-export ICE_GRID_API $(SLICE2CPPFLAGS)
LINKWITH := -lIce -lIceUtil
+$(libdir)/$(LIBFILENAME): $(LIB_OBJS)
+ rm -f $@
+ $(call mkshlib,$@,$(SONAME),$(LIB_OBJS),$(LINKWITH))
+
+$(libdir)/$(SONAME): $(libdir)/$(LIBFILENAME)
+ rm -f $@
+ ln -s $(LIBFILENAME) $@
+
+$(libdir)/$(LIBNAME): $(libdir)/$(SONAME)
+ rm -f $@
+ ln -s $(SONAME) $@
+
$(libdir)/$(PERFLIBFILENAME): $(PERFLIB_OBJS)
rm -f $@
$(call mkshlib,$@,$(PERFSONAME),$(PERFLIB_OBJS),$(LINKWITH))
@@ -47,12 +134,73 @@ $(libdir)/$(PERFLIBNAME): $(libdir)/$(SONAME)
rm -f $@
ln -s $(PERFSONAME) $@
+$(ADMIN): $(ADMIN_OBJS) $(LIBTARGETS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) -o $@ $(ADMIN_OBJS) -lIceXML -lIceGrid $(LIBS) $(READLINE_LIBS) $(EXPAT_LIBS)
+
+$(REGISTRY_SERVER): $(REGISTRY_SVR_OBJS) $(LIBTARGETS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) -o $@ $(REGISTRY_SVR_OBJS) -lIceGrid -lFreeze -lIceXML $(LIBS) $(DB_LIBS)
+
+$(NODE_SERVER): $(NODE_SVR_OBJS) $(LIBTARGETS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) -o $@ $(NODE_SVR_OBJS) -lIceGrid -lFreeze -lIceXML $(LIBS) $(DB_LIBS)
+
$(LOCAL_HDIR)/%.h %.cpp: $(SDIR)/%.ice $(SLICE2CPP)
rm -f $(HDIR)/$(*F).h $(*F).cpp
$(SLICE2CPP) $(SLICE2CPPFLAGS) $(SDIR)/$(*F).ice
+$(LOCAL_HDIR)/StringObjectProxyDict.h StringObjectProxyDict.cpp: $(SLICE2FREEZE)
+ rm -f StringObjectProxyDict.h StringObjectProxyDict.cpp
+ $(SLICE2FREEZECMD) --dict IceGrid::StringObjectProxyDict,string,Object* \
+ StringObjectProxyDict ../../slice/Ice/BuiltinSequences.ice
+
+clean::
+ rm -f StringObjectProxyDict.h StringObjectProxyDict.cpp
+
+$(LOCAL_HDIR)/StringStringSeqDict.h StringStringSeqDict.cpp: $(SLICE2FREEZE)
+ rm -f StringStringSeqDict.h StringStringSeqDict.cpp
+ $(SLICE2FREEZECMD) --dict IceGrid::StringStringSeqDict,string,Ice::StringSeq \
+ StringStringSeqDict ../../slice/Ice/BuiltinSequences.ice
+
+clean::
+ rm -f StringStringSeqDict.h StringStringSeqDict.cpp
+
+$(LOCAL_HDIR)/StringServerDescriptorDict.h StringServerDescriptorDict.cpp: $(SLICE2FREEZE)
+ rm -f StringServerDescriptorDict.h StringServerDescriptorDict.cpp
+ $(SLICE2FREEZECMD) --dict IceGrid::StringServerDescriptorDict,string,IcePacK::ServerDescriptor \
+ StringServerDescriptorDict ../../slice/IceGrid/Admin.ice
+
+clean::
+ rm -f StringServerDescriptorDict.h StringServerDescriptorDict.cpp
+
+$(LOCAL_HDIR)/IdentityObjectDescDict.h IdentityObjectDescDict.cpp: $(SLICE2FREEZE)
+ rm -f IdentityObjectDescDict.h IdentityObjectDescDict.cpp
+ $(SLICE2FREEZECMD) --dict IceGrid::IdentityObjectDescDict,Ice::Identity,IceGrid::ObjectDescriptor \
+ IdentityObjectDescDict ../../slice/Ice/Identity.ice $(LOCAL_SDIR)/Internal.ice
+
+clean::
+ rm -f IdentityObjectDescDict.h IdentityObjectDescDict.cpp
+
+$(LOCAL_HDIR)/StringObjectProxySeqDict.h StringObjectProxySeqDict.cpp: $(SLICE2FREEZE)
+ rm -f StringObjectProxySeqDict.h StringObjectProxySeqDict.cpp
+ $(SLICE2FREEZECMD) --dict IceGrid::StringObjectProxySeqDict,string,Ice::ObjectProxySeq \
+ StringObjectProxySeqDict $(slicedir)/Ice/BuiltinSequences.ice
+
+clean::
+ rm -f StringObjectProxySeqDict.h StringObjectProxySeqDict.cpp
+
+# Needed for make -jn to work.
+#../IceGrid/Grammar.y: Grammar.h
+
+clean::
+# rm -f Grammar.cpp Grammar.h
+# rm -f Scanner.cpp
install:: all
- $(call installlib,$(install_libdir),$(libdir),$(PERFLIBFILENAME),$(PERFSONAME),$(PERFLIBNAME))
+ $(call installlib,$(install_libdir),$(libdir),$(LIBFILENAME),$(SONAME),$(LIBNAME))
+ $(INSTALL_PROGRAM) $(ADMIN) $(install_bindir)
+ $(INSTALL_PROGRAM) $(NODE_SERVER) $(install_bindir)
+ $(INSTALL_PROGRAM) $(REGISTRY_SERVER) $(install_bindir)
include .depend
diff --git a/cpp/src/IceGrid/NodeI.cpp b/cpp/src/IceGrid/NodeI.cpp
new file mode 100644
index 00000000000..f14c1d40167
--- /dev/null
+++ b/cpp/src/IceGrid/NodeI.cpp
@@ -0,0 +1,92 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 <IceUtil/UUID.h>
+#include <Ice/Ice.h>
+#include <IceGrid/NodeI.h>
+#include <IceGrid/Activator.h>
+#include <IceGrid/ServerFactory.h>
+
+//
+// Just to get the hostname
+//
+#include <Ice/ProtocolPluginFacade.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef _WIN32
+# include <direct.h>
+#endif
+
+using namespace std;
+using namespace IceGrid;
+
+NodeI::NodeI(const ActivatorPtr& activator,
+ const string& name,
+ const ServerFactoryPtr& factory,
+ const Ice::CommunicatorPtr& communicator,
+ const Ice::PropertiesPtr& properties) :
+ _activator(activator),
+ _name(name),
+ _hostname(IceInternal::getProtocolPluginFacade(communicator)->getDefaultHost()),
+ _factory(factory)
+{
+ _tmpDir = properties->getProperty("IceGrid.Node.Data");
+ _tmpDir = _tmpDir + (_tmpDir[_tmpDir.length() - 1] == '/' ? "" : "/") + "tmp/";
+}
+
+ServerPrx
+NodeI::createServer(const string& name, const ServerDescriptorPtr& desc, const ::Ice::Current&) const
+{
+ return _factory->createServer(name, desc);
+}
+
+ServerAdapterPrx
+NodeI::createServerAdapter(const ServerPrx& server, const string& id, const ::Ice::Current&) const
+{
+ return _factory->createServerAdapter(id, server);
+}
+
+string
+NodeI::createTmpDir(const Ice::Current&) const
+{
+ string dir = _tmpDir + IceUtil::generateUUID();
+#ifdef _WIN32
+ _mkdir(dir.c_str());
+#else
+ mkdir(dir.c_str(), 0755);
+#endif
+ return dir;
+}
+
+void
+NodeI::destroyTmpDir(const string& path, const Ice::Current&) const
+{
+ rmdir(path.c_str());
+}
+
+std::string
+NodeI::getName(const Ice::Current&) const
+{
+ return _name;
+}
+
+std::string
+NodeI::getHostname(const Ice::Current&) const
+{
+ return _hostname;
+}
+
+void
+NodeI::shutdown(const Ice::Current&) const
+{
+ _activator->shutdown();
+}
+
diff --git a/cpp/src/IceGrid/NodeI.h b/cpp/src/IceGrid/NodeI.h
new file mode 100644
index 00000000000..d3eedf607df
--- /dev/null
+++ b/cpp/src/IceGrid/NodeI.h
@@ -0,0 +1,52 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 ICE_GRID_NODE_I_H
+#define ICE_GRID_NODE_I_H
+
+#include <IceGrid/Internal.h>
+
+namespace IceGrid
+{
+
+class Activator;
+typedef IceUtil::Handle<Activator> ActivatorPtr;
+
+class ServerFactory;
+typedef IceUtil::Handle<ServerFactory> ServerFactoryPtr;
+
+class NodeI : public Node
+{
+public:
+
+ NodeI(const ActivatorPtr&, const std::string&, const ServerFactoryPtr&,
+ const Ice::CommunicatorPtr&, const Ice::PropertiesPtr&);
+
+ virtual ServerPrx createServer(const std::string&, const ServerDescriptorPtr&, const Ice::Current&) const;
+ virtual ServerAdapterPrx createServerAdapter(const ServerPrx&, const std::string&, const Ice::Current&) const;
+
+ virtual std::string createTmpDir(const Ice::Current&) const;
+ virtual void destroyTmpDir(const std::string&, const Ice::Current&) const;
+
+ virtual std::string getName(const Ice::Current&) const;
+ virtual std::string getHostname(const Ice::Current&) const;
+ virtual void shutdown(const Ice::Current&) const;
+
+private:
+
+ const ActivatorPtr _activator;
+ const std::string _name;
+ const std::string _hostname;
+ const ServerFactoryPtr _factory;
+ std::string _tmpDir;
+};
+
+}
+
+#endif
diff --git a/cpp/src/IceGrid/NodeRegistryI.cpp b/cpp/src/IceGrid/NodeRegistryI.cpp
new file mode 100644
index 00000000000..3703d5428bc
--- /dev/null
+++ b/cpp/src/IceGrid/NodeRegistryI.cpp
@@ -0,0 +1,219 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 <IceGrid/NodeRegistryI.h>
+#include <IceGrid/AdapterFactory.h>
+#include <IceGrid/TraceLevels.h>
+#include <Freeze/Initialize.h>
+
+using namespace std;
+using namespace IceGrid;
+
+const string NodeRegistryI::_dbName = "noderegistry";
+
+NodeRegistryI::NodeRegistryI(const Ice::CommunicatorPtr& communicator,
+ const string& envName,
+ const AdapterRegistryPtr& adapterRegistry,
+ const AdapterFactoryPtr& adapterFactory,
+ const TraceLevelsPtr& traceLevels) :
+ _connectionCache(Freeze::createConnection(communicator, envName)),
+ _dictCache(_connectionCache, _dbName),
+ _adapterRegistry(adapterRegistry),
+ _adapterFactory(adapterFactory),
+ _traceLevels(traceLevels),
+ _envName(envName),
+ _communicator(communicator)
+{
+ for(StringObjectProxyDict::iterator p = _dictCache.begin(); p != _dictCache.end(); ++p)
+ {
+ NodePrx node = NodePrx::uncheckedCast(p->second);
+ try
+ {
+ node->ice_ping();
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ remove(p->first);
+ }
+ catch(const Ice::LocalException&)
+ {
+ }
+ }
+}
+
+void
+NodeRegistryI::add(const string& name, const NodePrx& node, const Ice::Current& current)
+{
+ while(true)
+ {
+ NodePrx oldNode;
+ try
+ {
+ oldNode = findByName(name, current);
+ oldNode->ice_ping();
+ throw NodeActiveException();
+ }
+ catch(const NodeNotExistException&)
+ {
+ }
+ catch(const Ice::LocalException&)
+ {
+ }
+
+ IceUtil::Mutex::Lock sync(*this);
+
+ Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName);
+ StringObjectProxyDict dict(connection, _dbName);
+
+ StringObjectProxyDict::iterator p = dict.find(name);
+ if(p != dict.end())
+ {
+ if(oldNode && oldNode != p->second)
+ {
+ continue;
+ }
+
+ p.set(node);
+
+ if(_traceLevels->nodeRegistry > 0)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->nodeRegistryCat);
+ out << "updated node `" << name << "' proxy";
+ }
+ }
+ else
+ {
+ dict.put(pair<const string, const Ice::ObjectPrx>(name, node));
+
+ if(_traceLevels->nodeRegistry > 0)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->nodeRegistryCat);
+ out << "added node `" << name << "'";
+ }
+ }
+
+ break;
+ }
+
+ //
+ // Set the direct proxy of the node object adapter.
+ //
+ while(true)
+ {
+ try
+ {
+ //
+ // TODO: ensure this adapter has been created by the adapter factory. It's possible that an
+ // adapter has been created with the same name. In such a case, the best is probably to
+ // prevent the node registration by throwing an appropriate exception. The user would then
+ // need to remove the adapter from the adapter registry to be able to run the node.
+ //
+
+ AdapterPrx adapter = _adapterRegistry->findById("IceGrid.Node." + name);
+ adapter->setDirectProxy(node);
+ return;
+ }
+ catch(const AdapterNotExistException&)
+ {
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ }
+
+ //
+ // Create and register the node adapter.
+ //
+ AdapterPrx adapter = _adapterFactory->createStandaloneAdapter("IceGridNodeAdapter." + name);
+ try
+ {
+ _adapterRegistry->add("IceGrid.Node." + name, adapter);
+ }
+ catch(const AdapterExistsException&)
+ {
+ adapter->destroy();
+ }
+ }
+}
+
+void
+NodeRegistryI::remove(const string& name, const Ice::Current&)
+{
+ IceUtil::Mutex::Lock sync(*this);
+
+ Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName);
+ StringObjectProxyDict dict(connection, _dbName);
+
+ StringObjectProxyDict::iterator p = dict.find(name);
+ if(p == dict.end())
+ {
+ throw NodeNotExistException();
+ }
+
+ dict.erase(p);
+
+ if(_traceLevels->nodeRegistry > 0)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->nodeRegistryCat);
+ out << "removed node `" << name << "'";
+ }
+
+ //
+ // Remove the adapter from the adapter registry.
+ //
+ try
+ {
+ AdapterPrx adapter = _adapterRegistry->findById("IceGrid.Node." + name);
+ adapter->destroy();
+ _adapterRegistry->remove("IceGrid.Node." + name, 0);
+ }
+ catch(const AdapterNotExistException&)
+ {
+ }
+}
+
+NodePrx
+NodeRegistryI::findByName(const string& name, const Ice::Current&)
+{
+ Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName);
+ StringObjectProxyDict dict(connection, _dbName);
+
+ StringObjectProxyDict::iterator p = dict.find(name);
+ if(p != dict.end())
+ {
+ try
+ {
+ return NodePrx::checkedCast(p->second);
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ }
+ catch(const Ice::LocalException&)
+ {
+ return NodePrx::uncheckedCast(p->second);
+ }
+ }
+ throw NodeNotExistException();
+}
+
+Ice::StringSeq
+NodeRegistryI::getAll(const Ice::Current&) const
+{
+ Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName);
+ StringObjectProxyDict dict(connection, _dbName);
+
+ Ice::StringSeq names;
+ names.reserve(dict.size());
+
+ for(StringObjectProxyDict::iterator p = dict.begin(); p != dict.end(); ++p)
+ {
+ names.push_back(p->first);
+ }
+
+ return names;
+}
diff --git a/cpp/src/IceGrid/NodeRegistryI.h b/cpp/src/IceGrid/NodeRegistryI.h
new file mode 100644
index 00000000000..35df3a630a7
--- /dev/null
+++ b/cpp/src/IceGrid/NodeRegistryI.h
@@ -0,0 +1,53 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 ICE_GRID_NODE_REGISTRY_I_H
+#define ICE_GRID_NODE_REGISTRY_I_H
+
+#include <IceGrid/Internal.h>
+#include <IceGrid/StringObjectProxyDict.h>
+
+namespace IceGrid
+{
+
+class AdapterFactory;
+typedef IceUtil::Handle<AdapterFactory> AdapterFactoryPtr;
+
+class TraceLevels;
+typedef IceUtil::Handle<TraceLevels> TraceLevelsPtr;
+
+class NodeRegistryI : public NodeRegistry, public IceUtil::Mutex
+{
+public:
+
+ NodeRegistryI(const Ice::CommunicatorPtr&, const std::string&, const AdapterRegistryPtr&,
+ const AdapterFactoryPtr&, const TraceLevelsPtr&);
+
+ virtual void add(const std::string&, const NodePrx&, const ::Ice::Current&);
+ virtual void remove(const std::string&, const ::Ice::Current& = Ice::Current());
+
+ virtual NodePrx findByName(const ::std::string&, const ::Ice::Current&);
+ virtual Ice::StringSeq getAll(const ::Ice::Current&) const;
+
+private:
+
+ static const std::string _dbName;
+
+ Freeze::ConnectionPtr _connectionCache;
+ StringObjectProxyDict _dictCache;
+ AdapterRegistryPtr _adapterRegistry;
+ AdapterFactoryPtr _adapterFactory;
+ TraceLevelsPtr _traceLevels;
+ const std::string _envName;
+ const Ice::CommunicatorPtr _communicator;
+};
+
+}
+
+#endif
diff --git a/cpp/src/IceGrid/ObjectRegistryI.cpp b/cpp/src/IceGrid/ObjectRegistryI.cpp
new file mode 100644
index 00000000000..12d18a43a8a
--- /dev/null
+++ b/cpp/src/IceGrid/ObjectRegistryI.cpp
@@ -0,0 +1,228 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 <IceUtil/StringUtil.h>
+#include <Ice/IdentityUtil.h>
+#include <IceGrid/ObjectRegistryI.h>
+#include <IceGrid/TraceLevels.h>
+#include <Freeze/Initialize.h>
+
+using namespace std;
+using namespace IceGrid;
+
+const string ObjectRegistryI::_objectsDbName = "objectregistry";
+const string ObjectRegistryI::_typesDbName = "objectregistry-types";
+
+ObjectRegistryI::ObjectRegistryI(const Ice::CommunicatorPtr& communicator,
+ const string& envName,
+ const TraceLevelsPtr& traceLevels) :
+ _connectionCache(Freeze::createConnection(communicator, envName)),
+ _objectsCache(_connectionCache, _objectsDbName, true),
+ _typesCache(_connectionCache, _typesDbName, true),
+ _traceLevels(traceLevels),
+ _envName(envName),
+ _communicator(communicator)
+{
+}
+
+void
+ObjectRegistryI::add(const ObjectDescriptor& obj, const Ice::Current&)
+{
+ IceUtil::Mutex::Lock sync(*this);
+
+ Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName);
+ IdentityObjectDescDict objects(connection, _objectsDbName);
+ StringObjectProxySeqDict types(connection, _typesDbName);
+
+ Ice::Identity id = obj.proxy->ice_getIdentity();
+
+ IdentityObjectDescDict::iterator p = objects.find(id);
+ if(p != objects.end())
+ {
+ throw ObjectExistsException();
+ }
+
+ //
+ // Add the object to the object dictionary.
+ //
+ objects.put(pair<const Ice::Identity, const ObjectDescriptor>(id, obj));
+
+ //
+ // Add the object to the interface dictionary.
+ //
+ if(!obj.type.empty())
+ {
+ Ice::ObjectProxySeq seq;
+
+ StringObjectProxySeqDict::iterator q = types.find(obj.type);
+ if(q != types.end())
+ {
+ seq = q->second;
+ }
+
+ seq.push_back(obj.proxy);
+
+ if(q == types.end())
+ {
+ types.put(pair<const string, const Ice::ObjectProxySeq>(obj.type, seq));
+ }
+ else
+ {
+ q.set(seq);
+ }
+ }
+
+ if(_traceLevels->objectRegistry > 0)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->objectRegistryCat);
+ out << "added object `" << Ice::identityToString(id) << "'";
+ }
+}
+
+void
+ObjectRegistryI::remove(const Ice::Identity& id, const Ice::Current&)
+{
+ IceUtil::Mutex::Lock sync(*this);
+
+ Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName);
+ IdentityObjectDescDict objects(connection, _objectsDbName);
+ StringObjectProxySeqDict types(connection, _typesDbName);
+
+ IdentityObjectDescDict::iterator p = objects.find(id);
+ if(p == objects.end())
+ {
+ throw ObjectNotExistException();
+ }
+
+ ObjectDescriptor obj = p->second;
+
+ if(!obj.type.empty())
+ {
+ //
+ // Remove the object from the interface dictionary.
+ //
+ StringObjectProxySeqDict::iterator q = types.find(obj.type);
+ assert(q != types.end());
+
+ Ice::ObjectProxySeq seq = q->second;
+
+ Ice::ObjectProxySeq::iterator r;
+ for(r = seq.begin(); r != seq.end(); ++r)
+ {
+ if((*r)->ice_getIdentity() == id)
+ {
+ break;
+ }
+ }
+
+ assert(r != seq.end());
+ seq.erase(r);
+
+ if(seq.size() == 0)
+ {
+ types.erase(q);
+ }
+ else
+ {
+ q.set(seq);
+ }
+ }
+
+ //
+ // Remove the object from the object dictionary.
+ //
+ objects.erase(p);
+
+ if(_traceLevels->objectRegistry > 0)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->objectRegistryCat);
+ out << "removed object `" << id << "'";
+ }
+}
+
+ObjectDescriptor
+ObjectRegistryI::getObjectDescriptor(const Ice::Identity& id, const Ice::Current&) const
+{
+ Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName);
+ IdentityObjectDescDict objects(connection, _objectsDbName);
+
+
+ IdentityObjectDescDict::iterator p = objects.find(id);
+ if(p == objects.end())
+ {
+ throw ObjectNotExistException();
+ }
+
+ return p->second;
+}
+
+Ice::ObjectPrx
+ObjectRegistryI::findById(const Ice::Identity& id, const Ice::Current&) const
+{
+ Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName);
+ IdentityObjectDescDict objects(connection, _objectsDbName);
+
+ IdentityObjectDescDict::iterator p = objects.find(id);
+ if(p == objects.end())
+ {
+ throw ObjectNotExistException();
+ }
+
+ return p->second.proxy;
+}
+
+Ice::ObjectPrx
+ObjectRegistryI::findByType(const string& type, const Ice::Current&) const
+{
+ Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName);
+ StringObjectProxySeqDict types(connection, _typesDbName);
+
+ StringObjectProxySeqDict::iterator p = types.find(type);
+ if(p == types.end())
+ {
+ throw ObjectNotExistException();
+ }
+
+ int r = rand() % int(p->second.size());
+ return p->second[r];
+}
+
+Ice::ObjectProxySeq
+ObjectRegistryI::findAllWithType(const string& type, const Ice::Current&) const
+{
+ Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName);
+ StringObjectProxySeqDict types(connection, _typesDbName);
+
+ StringObjectProxySeqDict::iterator p = types.find(type);
+ if(p == types.end())
+ {
+ throw ObjectNotExistException();
+ }
+
+ return p->second;
+}
+
+ObjectDescriptorSeq
+ObjectRegistryI::findAll(const string& expression, const Ice::Current&) const
+{
+ Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName);
+ IdentityObjectDescDict objects(connection, _objectsDbName);
+
+ ObjectDescriptorSeq result;
+ for(IdentityObjectDescDict::const_iterator p = objects.begin(); p != objects.end(); ++p)
+ {
+ if(expression.empty() ||
+ IceUtil::match(Ice::identityToString(p->second.proxy->ice_getIdentity()), expression, true))
+ {
+ result.push_back(p->second);
+ }
+ }
+ return result;
+}
+
diff --git a/cpp/src/IceGrid/ObjectRegistryI.h b/cpp/src/IceGrid/ObjectRegistryI.h
new file mode 100644
index 00000000000..bf4408fd7fc
--- /dev/null
+++ b/cpp/src/IceGrid/ObjectRegistryI.h
@@ -0,0 +1,55 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 ICE_GRID_OBJECT_REGISTRY_I_H
+#define ICE_GRID_OBJECT_REGISTRY_I_H
+
+#include <IceGrid/Internal.h>
+#include <IceGrid/IdentityObjectDescDict.h>
+#include <IceGrid/StringObjectProxySeqDict.h>
+#include <Freeze/ConnectionF.h>
+
+namespace IceGrid
+{
+
+class TraceLevels;
+typedef IceUtil::Handle<TraceLevels> TraceLevelsPtr;
+
+class ObjectRegistryI : public ObjectRegistry, public IceUtil::Mutex
+{
+public:
+
+ ObjectRegistryI(const Ice::CommunicatorPtr& communicator, const std::string&, const TraceLevelsPtr& traceLevels);
+
+ virtual void add(const IceGrid::ObjectDescriptor&, const ::Ice::Current&);
+ virtual void remove(const Ice::Identity&, const ::Ice::Current&);
+
+ virtual ObjectDescriptor getObjectDescriptor(const Ice::Identity&, const ::Ice::Current&) const;
+
+ virtual Ice::ObjectPrx findById(const ::Ice::Identity&, const ::Ice::Current&) const;
+ virtual Ice::ObjectPrx findByType(const std::string&, const ::Ice::Current&) const;
+ virtual Ice::ObjectProxySeq findAllWithType(const std::string&, const ::Ice::Current&) const;
+ virtual ObjectDescriptorSeq findAll(const std::string&, const ::Ice::Current&) const;
+
+private:
+
+ static const std::string _objectsDbName;
+ static const std::string _typesDbName;
+
+ Freeze::ConnectionPtr _connectionCache;
+ IdentityObjectDescDict _objectsCache;
+ StringObjectProxySeqDict _typesCache;
+ const TraceLevelsPtr _traceLevels;
+ const std::string _envName;
+ const Ice::CommunicatorPtr _communicator;
+};
+
+}
+
+#endif
diff --git a/cpp/src/IceGrid/QueryI.cpp b/cpp/src/IceGrid/QueryI.cpp
new file mode 100644
index 00000000000..bd24e80205f
--- /dev/null
+++ b/cpp/src/IceGrid/QueryI.cpp
@@ -0,0 +1,45 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 <IceGrid/Internal.h>
+#include <IceGrid/QueryI.h>
+
+using namespace std;
+using namespace Ice;
+using namespace IceGrid;
+
+QueryI::QueryI(const CommunicatorPtr& communicator, const ObjectRegistryPtr& objectRegistry) :
+ _communicator(communicator),
+ _objectRegistry(objectRegistry)
+{
+}
+
+QueryI::~QueryI()
+{
+}
+
+Ice::ObjectPrx
+QueryI::findObjectById(const Ice::Identity& id, const Ice::Current&) const
+{
+ return _objectRegistry->findById(id);
+}
+
+Ice::ObjectPrx
+QueryI::findObjectByType(const string& type, const Ice::Current&) const
+{
+ return _objectRegistry->findByType(type);
+}
+
+Ice::ObjectProxySeq
+QueryI::findAllObjectsWithType(const string& type, const Ice::Current&) const
+{
+ return _objectRegistry->findAllWithType(type);
+}
+
+
diff --git a/cpp/src/IceGrid/QueryI.h b/cpp/src/IceGrid/QueryI.h
new file mode 100644
index 00000000000..bb7d30d4cb2
--- /dev/null
+++ b/cpp/src/IceGrid/QueryI.h
@@ -0,0 +1,37 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 ICE_GRID_QUERY_I_H
+#define ICE_GRID_QUERY_I_H
+
+#include <IceGrid/Query.h>
+
+namespace IceGrid
+{
+
+class QueryI : public Query, public IceUtil::Mutex
+{
+public:
+
+ QueryI(const Ice::CommunicatorPtr&, const ObjectRegistryPtr&);
+ virtual ~QueryI();
+
+ virtual ::Ice::ObjectPrx findObjectById(const ::Ice::Identity&, const ::Ice::Current&) const;
+ virtual ::Ice::ObjectPrx findObjectByType(const ::std::string&, const ::Ice::Current&) const;
+ virtual ::Ice::ObjectProxySeq findAllObjectsWithType(const ::std::string&, const ::Ice::Current&) const;
+
+private:
+
+ Ice::CommunicatorPtr _communicator;
+ ObjectRegistryPtr _objectRegistry;
+};
+
+}
+
+#endif
diff --git a/cpp/src/IceGrid/Registry.cpp b/cpp/src/IceGrid/Registry.cpp
new file mode 100644
index 00000000000..1dd9a2c5ea4
--- /dev/null
+++ b/cpp/src/IceGrid/Registry.cpp
@@ -0,0 +1,326 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 <IceUtil/UUID.h>
+#include <Ice/Ice.h>
+#include <Freeze/Freeze.h>
+
+#include <IceGrid/Registry.h>
+#include <IceGrid/AdapterI.h>
+#include <IceGrid/AdapterFactory.h>
+#include <IceGrid/ApplicationRegistryI.h>
+#include <IceGrid/ServerRegistryI.h>
+#include <IceGrid/AdapterRegistryI.h>
+#include <IceGrid/ObjectRegistryI.h>
+#include <IceGrid/NodeRegistryI.h>
+#include <IceGrid/LocatorI.h>
+#include <IceGrid/LocatorRegistryI.h>
+#include <IceGrid/AdminI.h>
+#include <IceGrid/QueryI.h>
+#include <IceGrid/TraceLevels.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef _WIN32
+# include <direct.h>
+# define S_ISDIR(mode) ((mode) & _S_IFDIR)
+# define S_ISREG(mode) ((mode) & _S_IFREG)
+#else
+# include <unistd.h>
+#endif
+
+using namespace std;
+using namespace Ice;
+using namespace IceGrid;
+
+string
+intToString(int v)
+{
+ ostringstream os;
+ os << v;
+ return os.str();
+}
+
+Registry::Registry(const CommunicatorPtr& communicator) :
+ _communicator(communicator)
+{
+}
+
+Registry::~Registry()
+{
+}
+
+bool
+Registry::start(bool nowarn)
+{
+ assert(_communicator);
+ PropertiesPtr properties = _communicator->getProperties();
+
+ //
+ // Initialize the database environment.
+ //
+ string dbPath = properties->getProperty("IceGrid.Registry.Data");
+ if(dbPath.empty())
+ {
+ Error out(_communicator->getLogger());
+ out << "property `IceGrid.Registry.Data' is not set";
+ return false;
+ }
+ else
+ {
+ struct stat filestat;
+ if(stat(dbPath.c_str(), &filestat) != 0 || !S_ISDIR(filestat.st_mode))
+ {
+ Error out(_communicator->getLogger());
+ SyscallException ex(__FILE__, __LINE__);
+ ex.error = getSystemErrno();
+ out << "property `IceGrid.Registry.Data' is set to an invalid path:\n" << ex;
+ return false;
+ }
+ }
+
+ //
+ // Check that required properties are set and valid.
+ //
+ if(properties->getProperty("IceGrid.Registry.Client.Endpoints").empty())
+ {
+ Error out(_communicator->getLogger());
+ out << "property `IceGrid.Registry.Client.Endpoints' is not set";
+ return false;
+ }
+
+ if(properties->getProperty("IceGrid.Registry.Server.Endpoints").empty())
+ {
+ Error out(_communicator->getLogger());
+ out << "property `IceGrid.Registry.Server.Endpoints' is not set";
+ return false;
+ }
+
+ if(properties->getProperty("IceGrid.Registry.Internal.Endpoints").empty())
+ {
+ Error out(_communicator->getLogger());
+ out << "property `IceGrid.Registry.Internal.Endpoints' is not set";
+ return false;
+ }
+
+ if(!properties->getProperty("IceGrid.Registry.Admin.Endpoints").empty())
+ {
+ if(!nowarn)
+ {
+ Warning out(_communicator->getLogger());
+ out << "administrative endpoints `IceGrid.Registry.Admin.Endpoints' enabled";
+ }
+ }
+
+ properties->setProperty("Ice.PrintProcessId", "0");
+ properties->setProperty("Ice.Warn.Leaks", "0");
+ properties->setProperty("Ice.ServerIdleTime", "0");
+ properties->setProperty("IceGrid.Registry.Client.AdapterId", "");
+ properties->setProperty("IceGrid.Registry.Server.AdapterId", "");
+ properties->setProperty("IceGrid.Registry.Admin.AdapterId", "");
+ properties->setProperty("IceGrid.Registry.Internal.AdapterId", "IceGrid.Registry.Internal");
+
+ //
+ // Setup thread pool size for each thread pool.
+ //
+ int nThreadPool = 0;
+ if(properties->getPropertyAsInt("IceGrid.Registry.Client.ThreadPool.Size") == 0 &&
+ properties->getPropertyAsInt("IceGrid.Registry.Client.ThreadPool.SizeMax") == 0)
+ {
+ ++nThreadPool;
+ }
+ if(properties->getPropertyAsInt("IceGrid.Registry.Server.ThreadPool.Size") == 0 &&
+ properties->getPropertyAsInt("IceGrid.Registry.Server.ThreadPool.SizeMax") == 0)
+ {
+ ++nThreadPool;
+ }
+ if(properties->getPropertyAsInt("IceGrid.Registry.Admin.ThreadPool.Size") == 0 &&
+ properties->getPropertyAsInt("IceGrid.Registry.Admin.ThreadPool.SizeMax") == 0)
+ {
+ ++nThreadPool;
+ }
+
+ int size = properties->getPropertyAsIntWithDefault("Ice.ThreadPool.Server.Size", 10);
+ if(size < nThreadPool)
+ {
+ size = nThreadPool;
+ }
+ int sizeMax = properties->getPropertyAsIntWithDefault("Ice.ThreadPool.Server.SizeMax", size * 10);
+ if(sizeMax < size)
+ {
+ sizeMax = size;
+ }
+ int sizeWarn = properties->getPropertyAsIntWithDefault("Ice.ThreadPool.Server.SizeWarn", sizeMax * 80 / 100);
+
+ if(properties->getPropertyAsInt("IceGrid.Registry.Client.ThreadPool.Size") == 0 &&
+ properties->getPropertyAsInt("IceGrid.Registry.Client.ThreadPool.SizeMax") == 0)
+ {
+ properties->setProperty("IceGrid.Registry.Client.ThreadPool.Size", intToString(size / nThreadPool));
+ properties->setProperty("IceGrid.Registry.Client.ThreadPool.SizeMax", intToString(sizeMax / nThreadPool));
+ properties->setProperty("IceGrid.Registry.Client.ThreadPool.SizeWarn", intToString(sizeWarn / nThreadPool));
+ }
+ if(properties->getPropertyAsInt("IceGrid.Registry.Server.ThreadPool.Size") == 0 &&
+ properties->getPropertyAsInt("IceGrid.Registry.Server.ThreadPool.SizeMax") == 0)
+ {
+ properties->setProperty("IceGrid.Registry.Server.ThreadPool.Size", intToString(size / nThreadPool));
+ properties->setProperty("IceGrid.Registry.Server.ThreadPool.SizeMax", intToString(sizeMax / nThreadPool));
+ properties->setProperty("IceGrid.Registry.Server.ThreadPool.SizeWarn", intToString(sizeWarn / nThreadPool));
+ }
+ if(properties->getPropertyAsInt("IceGrid.Registry.Admin.ThreadPool.Size") == 0 &&
+ properties->getPropertyAsInt("IceGrid.Registry.Admin.ThreadPool.SizeMax") == 0)
+ {
+ properties->setProperty("IceGrid.Registry.Admin.ThreadPool.Size", intToString(size / nThreadPool));
+ properties->setProperty("IceGrid.Registry.Admin.ThreadPool.SizeMax", intToString(sizeMax / nThreadPool));
+ properties->setProperty("IceGrid.Registry.Admin.ThreadPool.SizeWarn", intToString(sizeWarn / nThreadPool));
+ }
+
+ int clientSize = properties->getPropertyAsInt("IceGrid.Registry.Client.ThreadPool.Size") * 2;
+ int serverSize = properties->getPropertyAsInt("IceGrid.Registry.Server.ThreadPool.Size") * 2;
+ properties->setProperty("IceGrid.Registry.Internal.ThreadPool.Size", intToString(clientSize + serverSize));
+
+ int clientSizeMax = properties->getPropertyAsInt("IceGrid.Registry.Client.ThreadPool.SizeMax") * 2;
+ if(clientSizeMax < clientSize)
+ {
+ clientSizeMax = clientSize;
+ }
+ int serverSizeMax = properties->getPropertyAsInt("IceGrid.Registry.Server.ThreadPool.SizeMax") * 2;
+ if(serverSizeMax < serverSize)
+ {
+ serverSizeMax = serverSize;
+ }
+ properties->setProperty("IceGrid.Registry.Internal.ThreadPool.SizeMax",
+ intToString(clientSizeMax + serverSizeMax));
+
+ int clientSizeWarn = properties->getPropertyAsIntWithDefault("IceGrid.Registry.Client.ThreadPool.SizeWarn",
+ clientSizeMax * 80 / 100) * 2;
+ int serverSizeWarn = properties->getPropertyAsIntWithDefault("IceGrid.Registry.Server.ThreadPool.SizeWarn",
+ serverSizeMax * 80 / 100) * 2;
+ properties->setProperty("IceGrid.Registry.Internal.ThreadPool.SizeWarn",
+ intToString(clientSizeWarn + serverSizeWarn));
+
+ TraceLevelsPtr traceLevels = new TraceLevels(properties, _communicator->getLogger());
+
+ _communicator->setDefaultLocator(0);
+
+ //
+ // Create the object adapters.
+ //
+ ObjectAdapterPtr serverAdapter = _communicator->createObjectAdapter("IceGrid.Registry.Server");
+ ObjectAdapterPtr clientAdapter = _communicator->createObjectAdapter("IceGrid.Registry.Client");
+ ObjectAdapterPtr adminAdapter = _communicator->createObjectAdapter("IceGrid.Registry.Admin");
+ ObjectAdapterPtr registryAdapter = _communicator->createObjectAdapter("IceGrid.Registry.Internal");
+
+ //
+ // Create the internal registries (node, server, adapter, object).
+ //
+ const string envName = "Registry";
+ properties->setProperty("Freeze.DbEnv.Registry.DbHome", dbPath);
+ AdapterFactoryPtr adapterFactory = new AdapterFactory(registryAdapter, traceLevels, envName);
+ ObjectRegistryPtr objectRegistry = new ObjectRegistryI(_communicator, envName, traceLevels);
+ AdapterRegistryPtr adapterRegistry = new AdapterRegistryI(_communicator, envName, traceLevels);
+ ServerRegistryPtr serverRegistry = new ServerRegistryI(_communicator, envName, traceLevels);
+ ApplicationRegistryPtr appReg = new ApplicationRegistryI(_communicator, serverRegistry, envName, traceLevels);
+ NodeRegistryPtr nodeReg = new NodeRegistryI(_communicator, envName, adapterRegistry, adapterFactory, traceLevels);
+
+ registryAdapter->add(objectRegistry, stringToIdentity("IceGrid/ObjectRegistry"));
+ registryAdapter->add(adapterRegistry, stringToIdentity("IceGrid/AdapterRegistry"));
+ registryAdapter->add(serverRegistry, stringToIdentity("IceGrid/ServerRegistry"));
+ registryAdapter->add(appReg, stringToIdentity("IceGrid/ApplicationRegistry"));
+ registryAdapter->add(nodeReg, stringToIdentity("IceGrid/NodeRegistry"));
+
+ //
+ // Create the locator registry and locator interfaces.
+ //
+ bool dynamicReg = properties->getPropertyAsInt("IceGrid.Registry.DynamicRegistration") > 0;
+ ObjectPtr locatorRegistry = new LocatorRegistryI(adapterRegistry, serverRegistry, adapterFactory, dynamicReg);
+ ObjectPrx obj = serverAdapter->add(locatorRegistry, stringToIdentity("IceGrid/" + IceUtil::generateUUID()));
+ LocatorRegistryPrx locatorRegistryPrx = LocatorRegistryPrx::uncheckedCast(obj->ice_collocationOptimization(false));
+ ObjectPtr locator = new LocatorI(adapterRegistry, objectRegistry, locatorRegistryPrx);
+ clientAdapter->add(locator, stringToIdentity("IceGrid/Locator"));
+
+ //
+ // Create the query interface and register it with the object registry.
+ //
+ QueryPtr query = new QueryI(_communicator, objectRegistry);
+ clientAdapter->add(query, stringToIdentity("IceGrid/Query"));
+ ObjectPrx queryPrx = clientAdapter->createDirectProxy(stringToIdentity("IceGrid/Query"));
+ try
+ {
+ objectRegistry->remove(queryPrx->ice_getIdentity());
+ }
+ catch(const ObjectNotExistException&)
+ {
+ }
+ IceGrid::ObjectDescriptor desc;
+ desc.proxy = queryPrx;
+ desc.type = "::IceGrid::Query";
+ objectRegistry->add(desc);
+
+ //
+ // Create the admin interface and register it with the object registry.
+ //
+ ObjectPtr admin = new AdminI(_communicator, nodeReg, appReg, serverRegistry, adapterRegistry, objectRegistry,
+ this);
+ adminAdapter->add(admin, stringToIdentity("IceGrid/Admin"));
+ ObjectPrx adminPrx = adminAdapter->createDirectProxy(stringToIdentity("IceGrid/Admin"));
+ try
+ {
+ objectRegistry->remove(adminPrx->ice_getIdentity());
+ }
+ catch(const ObjectNotExistException&)
+ {
+ }
+ desc.proxy = adminPrx;
+ desc.type = "::IceGrid::Admin";
+ objectRegistry->add(desc);
+
+ //
+ // Register the IceGrid.Registry.Internal adapter with the adapter registry.
+ //
+ try
+ {
+ adapterRegistry->remove("IceGrid.Registry.Internal", 0);
+ }
+ catch(const AdapterNotExistException&)
+ {
+ }
+ obj = registryAdapter->addWithUUID(new StandaloneAdapterI());
+ registryAdapter->activate();
+ AdapterPrx adapter = AdapterPrx::uncheckedCast(registryAdapter->createDirectProxy(obj->ice_getIdentity()));
+ adapterRegistry->add("IceGrid.Registry.Internal", adapter);
+ adapter->setDirectProxy(adapter);
+
+ //
+ // Setup a internal locator to be used by the IceGrid registry itself. This locator is
+ // registered with the registry object adapter which is using an independant threadpool.
+ //
+ locator = new LocatorI(adapterRegistry, objectRegistry, locatorRegistryPrx);
+ registryAdapter->add(locator, stringToIdentity("IceGrid/Locator"));
+ obj = registryAdapter->createDirectProxy(stringToIdentity("IceGrid/Locator"));
+ _communicator->setDefaultLocator(LocatorPrx::uncheckedCast(obj->ice_collocationOptimization(false)));
+
+ //
+ // We are ready to go!
+ //
+ serverAdapter->activate();
+ clientAdapter->activate();
+ if(adminAdapter)
+ {
+ adminAdapter->activate();
+ }
+
+ return true;
+}
+
+void
+Registry::shutdown()
+{
+ _communicator->shutdown();
+}
diff --git a/cpp/src/IceGrid/Registry.h b/cpp/src/IceGrid/Registry.h
new file mode 100644
index 00000000000..93f7633bf8c
--- /dev/null
+++ b/cpp/src/IceGrid/Registry.h
@@ -0,0 +1,35 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 ICE_GRID_REGISTRY_H
+#define ICE_GRID_REGISTRY_H
+
+namespace IceGrid
+{
+
+class Registry : public IceUtil::Shared
+{
+public:
+
+ Registry(const Ice::CommunicatorPtr&);
+ ~Registry();
+
+ bool start(bool);
+
+ virtual void shutdown();
+
+private:
+
+ Ice::CommunicatorPtr _communicator;
+};
+typedef IceUtil::Handle<Registry> RegistryPtr;
+
+}
+
+#endif
diff --git a/cpp/src/IceGrid/Scanner.l b/cpp/src/IceGrid/Scanner.l
new file mode 100644
index 00000000000..8cb8498b6a1
--- /dev/null
+++ b/cpp/src/IceGrid/Scanner.l
@@ -0,0 +1,368 @@
+%{
+
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 <IceGrid/Parser.h>
+#include <IceGrid/Grammar.h>
+
+#ifdef _WIN32
+// I get these warnings from some flex versions:
+// warning C4003: not enough actual parameters for macro 'yywrap'
+# pragma warning( disable : 4003 )
+#endif
+
+using namespace std;
+using namespace Ice;
+using namespace IceGrid;
+
+#define YY_INPUT(buf, result, maxSize) parser->getInput(buf, result, maxSize)
+
+%}
+
+WS [ \t\v\f\r]
+NL [\n]
+
+%option noyywrap
+
+%%
+
+^"#"[[:blank:]]*[[:digit:]]+[[:blank:]]*$ {
+ parser->scanPosition(yytext);
+}
+
+^"#"[[:blank:]]*[[:digit:]]+[[:blank:]]+"\""[^\"]*"\"".*$ {
+ parser->scanPosition(yytext);
+}
+
+^"#"[[:blank:]]*"line"[[:blank:]]+[[:digit:]]+[[:blank:]]*$ {
+ parser->scanPosition(yytext);
+}
+
+^"#"[[:blank:]]*"line"[[:blank:]]+[[:digit:]]+[[:blank:]]+"\""[^\"]*"\"".*$ {
+ parser->scanPosition(yytext);
+}
+
+"//" {
+ // C++-style comment
+ int c;
+ do
+ {
+ c = yyinput();
+ if(c == '\n')
+ {
+ parser->nextLine();
+ }
+ }
+ while(c != '\n' && c != EOF);
+}
+
+"/*" {
+ // C-style comment
+ while(true)
+ {
+ int c = yyinput();
+ if(c == '\n')
+ {
+ parser->nextLine();
+ }
+ else if(c == '*')
+ {
+ int next = yyinput();
+ if(next == '/')
+ {
+ break;
+ }
+ else
+ {
+ unput(next);
+ }
+ }
+ else if(c == EOF)
+ {
+ parser->warning("EOF in comment");
+ break;
+ }
+ }
+}
+
+"help" {
+ return ICE_GRID_HELP;
+}
+
+"quit"|"exit" {
+ return ICE_GRID_EXIT;
+}
+
+"application" {
+ return ICE_GRID_APPLICATION;
+}
+
+"server" {
+ return ICE_GRID_SERVER;
+}
+
+"adapter" {
+ return ICE_GRID_ADAPTER;
+}
+
+"add" {
+ return ICE_GRID_ADD;
+}
+
+"remove" {
+ return ICE_GRID_REMOVE;
+}
+
+"list" {
+ return ICE_GRID_LIST;
+}
+
+"shutdown" {
+ return ICE_GRID_SHUTDOWN;
+}
+
+"describe" {
+ return ICE_GRID_DESCRIBE;
+}
+
+"state" {
+ return ICE_GRID_STATE;
+}
+
+"pid" {
+ return ICE_GRID_PID;
+}
+
+"endpoints" {
+ return ICE_GRID_ENDPOINTS;
+}
+
+"start" {
+ return ICE_GRID_START;
+}
+
+"stop" {
+ return ICE_GRID_STOP;
+}
+
+"signal" {
+ return ICE_GRID_SIGNAL;
+}
+
+"stdout" {
+ return ICE_GRID_STDOUT;
+}
+
+"stderr" {
+ return ICE_GRID_STDERR;
+}
+
+"node" {
+ return ICE_GRID_NODE;
+}
+
+"ping" {
+ return ICE_GRID_PING;
+}
+
+"activation" {
+ return ICE_GRID_ACTIVATION;
+}
+
+"object" {
+ return ICE_GRID_OBJECT;
+}
+
+"find" {
+ return ICE_GRID_FIND;
+}
+
+"show" {
+ return ICE_GRID_SHOW;
+}
+
+"copying" {
+ return ICE_GRID_COPYING;
+}
+
+"warranty" {
+ return ICE_GRID_WARRANTY;
+}
+
+"diff" {
+ return ICE_GRID_DIFF;
+}
+
+"update" {
+ return ICE_GRID_UPDATE;
+}
+
+{WS}*(\\{WS}*{NL})? {
+ size_t len = strlen(yytext);
+ for(size_t i = 0; i < len; ++i)
+ {
+ if(yytext[i] == '\\')
+ {
+ parser->continueLine();
+ }
+ else if(yytext[i] == '\n')
+ {
+ parser->nextLine();
+ }
+ }
+}
+
+{NL}|; {
+ size_t len = strlen(yytext);
+ for(size_t i = 0; i < len; ++i)
+ {
+ if(yytext[i] == '\n')
+ {
+ parser->nextLine();
+ }
+ }
+ return ';';
+}
+
+\" {
+ // "..."-type strings
+ string s;
+ while(true)
+ {
+ char c = static_cast<char>(yyinput());
+ if(c == '"')
+ {
+ break;
+ }
+ else if(c == EOF)
+ {
+ parser->warning("EOF in string");
+ break;
+ }
+ else if(c == '\n')
+ {
+ s += c;
+ parser->nextLine();
+ }
+ else if(c == '\\')
+ {
+ char next = static_cast<char>(yyinput());
+ switch(next)
+ {
+ case '\\':
+ case '"':
+ {
+ s += next;
+ break;
+ }
+
+ case 'n':
+ {
+ s += '\n';
+ break;
+ }
+
+ case 'r':
+ {
+ s += '\r';
+ break;
+ }
+
+ case 't':
+ {
+ s += '\t';
+ break;
+ }
+
+ case 'v':
+ {
+ s += '\v';
+ break;
+ }
+
+ case 'f':
+ {
+ s += '\f';
+ break;
+ }
+
+ default:
+ {
+ s += c;
+ unput(next);
+ }
+ }
+ }
+ else
+ {
+ s += c;
+ }
+ }
+ yylvalp->clear();
+ yylvalp->push_back(s);
+ return ICE_GRID_STRING;
+}
+
+\' {
+ // '...'-type strings
+ string s;
+ while(true)
+ {
+ char c = static_cast<char>(yyinput());
+ if(c == '\'')
+ {
+ break;
+ }
+ else if(c == EOF)
+ {
+ parser->warning("EOF in string");
+ break;
+ }
+ else if(c == '\n')
+ {
+ s += c;
+ parser->nextLine();
+ }
+ else
+ {
+ s += c;
+ }
+ }
+ yylvalp->clear();
+ yylvalp->push_back(s);
+ return ICE_GRID_STRING;
+}
+
+. {
+ // Simple strings
+ string s;
+ s += yytext[0];
+ while(true)
+ {
+ char c = static_cast<char>(yyinput());
+ if(c == EOF)
+ {
+ break;
+ }
+ else if(isspace(c) || c == ';')
+ {
+ unput(c);
+ break;
+ }
+
+ s += c;
+ }
+ yylvalp->clear();
+ yylvalp->push_back(s);
+ return ICE_GRID_STRING;
+}
+
+%%
diff --git a/cpp/src/IceGrid/ServerAdapterI.cpp b/cpp/src/IceGrid/ServerAdapterI.cpp
new file mode 100644
index 00000000000..e2e03268fc9
--- /dev/null
+++ b/cpp/src/IceGrid/ServerAdapterI.cpp
@@ -0,0 +1,213 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 <IceGrid/ServerAdapterI.h>
+#include <IceGrid/ServerFactory.h>
+#include <IceGrid/TraceLevels.h>
+#include <IceGrid/WaitQueue.h>
+
+using namespace std;
+using namespace IceGrid;
+
+namespace IceGrid
+{
+
+class WaitForAdapterActivation : public WaitItem
+{
+public:
+
+ WaitForAdapterActivation(const ServerAdapterPtr& adapter,
+ const TraceLevelsPtr traceLevels,
+ const AMD_Adapter_activatePtr& cb) :
+ WaitItem(adapter),
+ _adapter(adapter),
+ _traceLevels(traceLevels),
+ _cb(cb)
+ {
+ }
+
+ virtual void execute()
+ {
+ try
+ {
+ _cb->ice_response(_adapter->getDirectProxy());
+ }
+ catch(const AdapterNotActiveException&)
+ {
+ _cb->ice_response(0);
+ }
+ catch(const Ice::LocalException&)
+ {
+ _cb->ice_response(0);
+ }
+ }
+
+ virtual void expired(bool destroyed)
+ {
+ if(_traceLevels->adapter > 1)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->adapterCat);
+ out << "server adapter `" << _adapter->id << "' activation timed out";
+ }
+ _cb->ice_response(0);
+ }
+
+private:
+
+ const ServerAdapterPtr _adapter;
+ const TraceLevelsPtr _traceLevels;
+ const AMD_Adapter_activatePtr _cb;
+};
+
+}
+
+ServerAdapterI::ServerAdapterI(const ServerFactoryPtr& factory, const TraceLevelsPtr& traceLevels,
+ Ice::Int waitTime) :
+ _factory(factory),
+ _traceLevels(traceLevels),
+ _waitTime(IceUtil::Time::seconds(waitTime))
+{
+}
+
+ServerAdapterI::~ServerAdapterI()
+{
+}
+
+string
+ServerAdapterI::getId(const Ice::Current&)
+{
+ return id;
+}
+
+void
+ServerAdapterI::activate_async(const AMD_Adapter_activatePtr& cb, const Ice::Current& current)
+{
+ {
+ Lock sync(*this);
+ if(_proxy)
+ {
+ //
+ // Return the adapter direct proxy.
+ //
+ cb->ice_response(_proxy);
+ return;
+ }
+
+ if(_traceLevels->adapter > 2)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->adapterCat);
+ out << "waiting for activation of server adapter `" << id << "'";
+ }
+
+ _factory->getWaitQueue()->add(new WaitForAdapterActivation(this, _traceLevels, cb), _waitTime);
+ }
+
+ //
+ // Try to start the server. Note that we start the server outside
+ // the synchronization block since start() can block and callback
+ // on this adapter (when the server is deactivating for example).
+ //
+ try
+ {
+ if(svr->start(OnDemand))
+ {
+ return;
+ }
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ //
+ // The server associated to this adapter doesn't exist anymore. Somehow the database is
+ // inconsistent if this happens. The best thing to do is to destroy the adapter and throw
+ // an ObjectNotExist exception.
+ //
+ destroy(current);
+ }
+
+ //
+ // The server couldn't be activated, trace and return the current adapter proxy.
+ //
+ if(_traceLevels->adapter > 1)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->adapterCat);
+ out << "server adapter `" << id << "' activation failed, couldn't start the server";
+ }
+
+ _factory->getWaitQueue()->notifyAllWaitingOn(this);
+}
+
+Ice::ObjectPrx
+ServerAdapterI::getDirectProxy(const Ice::Current& current) const
+{
+ Lock sync(*this);
+
+ //
+ // Return the adapter direct proxy if it's set. Otherwise, throw. The caller can eventually
+ // activate the adapter if it's activatable.
+ //
+ if(_proxy)
+ {
+ return _proxy;
+ }
+ else
+ {
+ AdapterNotActiveException ex;
+ ServerState state = svr->getState();
+ ex.activatable = svr->getActivationMode() == OnDemand || state == Activating || state == Active;
+ ex.timeout = static_cast<int>(_waitTime.toMilliSeconds());
+ throw ex;
+ }
+}
+
+void
+ServerAdapterI::setDirectProxy(const Ice::ObjectPrx& prx, const Ice::Current& current)
+{
+ Lock sync(*this);
+
+ //
+ // If the adapter proxy is not null the given proxy can only be null. We don't allow to overide an
+ // existing proxy by another non null proxy if the server is active.
+ //
+ if(prx && _proxy)
+ {
+ if(svr->getState() == Active)
+ {
+ throw AdapterActiveException();
+ }
+ }
+
+ //
+ // Prevent eviction of an active adapter object.
+ //
+ if(prx && !_proxy)
+ {
+ _factory->getServerAdapterEvictor()->keep(current.id);
+ }
+ else if(!prx && _proxy)
+ {
+ _factory->getServerAdapterEvictor()->release(current.id);
+ }
+
+ _proxy = prx;
+
+ if(_traceLevels->adapter > 1)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->adapterCat);
+ out << "server adapter `" << id << "' " << (_proxy ? "activated" : "deactivated");
+ }
+
+ _factory->getWaitQueue()->notifyAllWaitingOn(this);
+}
+
+void
+ServerAdapterI::destroy(const Ice::Current& current)
+{
+ _factory->destroy(this, current.id);
+}
diff --git a/cpp/src/IceGrid/ServerAdapterI.h b/cpp/src/IceGrid/ServerAdapterI.h
new file mode 100644
index 00000000000..c7b7eb57cf1
--- /dev/null
+++ b/cpp/src/IceGrid/ServerAdapterI.h
@@ -0,0 +1,51 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 ICE_GRID_SERVER_ADAPTER_I_H
+#define ICE_GRID_SERVER_ADAPTER_I_H
+
+#include <IceUtil/Mutex.h>
+#include <IceGrid/Internal.h>
+#include <IceUtil/AbstractMutex.h>
+
+namespace IceGrid
+{
+
+class TraceLevels;
+typedef IceUtil::Handle<TraceLevels> TraceLevelsPtr;
+
+class ServerFactory;
+typedef IceUtil::Handle<ServerFactory> ServerFactoryPtr;
+
+class ServerAdapterI : public ServerAdapter, public IceUtil::AbstractMutexI<IceUtil::Mutex>
+{
+public:
+
+ ServerAdapterI(const ServerFactoryPtr&, const TraceLevelsPtr&, Ice::Int waitTime);
+ virtual ~ServerAdapterI();
+
+ virtual std::string getId(const Ice::Current&);
+
+ virtual void activate_async(const AMD_Adapter_activatePtr& cb, const Ice::Current&);
+ virtual Ice::ObjectPrx getDirectProxy(const Ice::Current&) const;
+ virtual void setDirectProxy(const ::Ice::ObjectPrx&, const ::Ice::Current&);
+ virtual void destroy(const ::Ice::Current&);
+
+private:
+
+ ServerFactoryPtr _factory;
+ TraceLevelsPtr _traceLevels;
+ IceUtil::Time _waitTime;
+
+ Ice::ObjectPrx _proxy;
+};
+
+}
+
+#endif
diff --git a/cpp/src/IceGrid/ServerDeployerI.cpp b/cpp/src/IceGrid/ServerDeployerI.cpp
new file mode 100644
index 00000000000..b0948575e5d
--- /dev/null
+++ b/cpp/src/IceGrid/ServerDeployerI.cpp
@@ -0,0 +1,131 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 <IceGrid/ServerDeployerI.h>
+#include <IceGrid/ServerFactory.h>
+#include <IceGrid/ServerBuilder.h>
+#include <IceGrid/TraceLevels.h>
+
+using namespace std;
+using namespace IceGrid;
+
+ServerDeployerI::ServerDeployerI(const NodeInfoPtr& nodeInfo) :
+ _nodeInfo(nodeInfo)
+{
+}
+
+ServerDeployerI::~ServerDeployerI()
+{
+}
+
+void
+ServerDeployerI::add(const string& name, const string& descriptor, const string& binPath,
+ const string& libPath, const Ice::StringSeq& targets, const Ice::Current&)
+{
+ //
+ // Setup required variables.
+ //
+ map<string, string> variables;
+ variables["parent"] = _nodeInfo->getNode()->getName();
+ variables["name"] = name;
+ variables["fqn"] = _nodeInfo->getNode()->getName() + "." + name;
+ variables["binpath"] = binPath;
+ variables["libpath"] = libPath;
+
+ string dataDir = _nodeInfo->getCommunicator()->getProperties()->getProperty("IceGrid.Node.Data");
+ variables["datadir"] = dataDir + (dataDir[dataDir.length() - 1] == '/' ? "" : "/") + "servers/" + name;
+
+ ServerBuilder builder(_nodeInfo, variables, targets);
+
+ //
+ // Parse the server deployment descriptors.
+ //
+ builder.parse(descriptor);
+
+ //
+ // Execute the builder tasks.
+ //
+ builder.execute();
+}
+
+void
+ServerDeployerI::remove(const string& name, const Ice::Current&)
+{
+ ServerRegistryPrx registry = _nodeInfo->getServerRegistry();
+
+ //
+ // Component path is used to identify the component. For example:
+ // node1.server1.service3
+ //
+ string componentPath = _nodeInfo->getNode()->getName() + "." + name;
+
+ ServerPrx server;
+ try
+ {
+ server = registry->findByName(name);
+ }
+ catch(const ServerNotExistException&)
+ {
+ ServerDeploymentException ex;
+ ex.server = name;
+ ex.reason = "server doesn't exist";
+ ex.component = componentPath;
+ throw ex;
+ }
+
+
+ ServerDescription desc;
+ try
+ {
+ desc = server->getServerDescription();
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ ServerDeploymentException ex;
+ ex.server = name;
+ ex.reason = "server doesn't exist";
+ ex.component = componentPath;
+ throw ex;
+ }
+
+ //
+ // Ensure the server is from this node.
+ //
+ if(desc.node != _nodeInfo->getNode()->getName())
+ {
+ ServerDeploymentException ex;
+ ex.server = name;
+ ex.reason = "server is not managed by this node";
+ ex.component = componentPath;
+ throw ex;
+ }
+
+ map<string, string> variables;
+ variables["parent"] = _nodeInfo->getNode()->getName();
+ variables["name"] = name;
+ variables["fqn"] = _nodeInfo->getNode()->getName() + "." + name;
+ variables["binpath"] = desc.path;
+ variables["libpath"] = "";
+
+ string dataDir = _nodeInfo->getCommunicator()->getProperties()->getProperty("IceGrid.Node.Data");
+ variables["datadir"] = dataDir + (dataDir[dataDir.length() - 1] == '/' ? "" : "/") + "servers/" + name;
+
+ ServerBuilder builder(_nodeInfo, variables, desc.targets);
+
+ //
+ // Parse the server deployment descriptors.
+ //
+ builder.parse(desc.descriptor);
+
+ //
+ // Execute the builder tasks.
+ //
+ builder.undo();
+}
diff --git a/cpp/src/IceGrid/ServerDeployerI.h b/cpp/src/IceGrid/ServerDeployerI.h
new file mode 100644
index 00000000000..a718514ac33
--- /dev/null
+++ b/cpp/src/IceGrid/ServerDeployerI.h
@@ -0,0 +1,40 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 ICE_GRID_SERVER_DEPLOYER_I_H
+#define ICE_GRID_SERVER_DEPLOYER_I_H
+
+#include <IceGrid/Internal.h>
+#include <IceGrid/NodeInfo.h>
+
+namespace IceGrid
+{
+
+
+class ServerDeployerI : public ServerDeployer, public IceUtil::Mutex
+{
+public:
+
+ ServerDeployerI(const NodeInfoPtr&);
+ virtual ~ServerDeployerI();
+
+ virtual void add(const ::std::string&, const ::std::string&, const ::std::string&, const ::std::string&,
+ const ::Ice::StringSeq&, const ::Ice::Current& = ::Ice::Current());
+
+ virtual void remove(const ::std::string&, const ::Ice::Current& = ::Ice::Current());
+
+private:
+
+ NodeInfoPtr _nodeInfo;
+
+};
+
+}
+
+#endif
diff --git a/cpp/src/IceGrid/ServerFactory.cpp b/cpp/src/IceGrid/ServerFactory.cpp
new file mode 100644
index 00000000000..eb5e10e1a34
--- /dev/null
+++ b/cpp/src/IceGrid/ServerFactory.cpp
@@ -0,0 +1,384 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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.
+//
+// **********************************************************************
+
+#ifdef __sun
+#define _POSIX_PTHREAD_SEMANTICS
+#endif
+
+#include <Ice/Ice.h>
+#include <IceUtil/UUID.h>
+#include <Freeze/Evictor.h>
+#include <Freeze/Initialize.h>
+#include <IceGrid/ServerFactory.h>
+#include <IceGrid/ServerI.h>
+#include <IceGrid/ServerAdapterI.h>
+#include <IceGrid/TraceLevels.h>
+#include <IceGrid/DescriptorVisitor.h>
+
+#include <map>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef _WIN32
+# include <direct.h>
+#else
+# include <unistd.h>
+# include <dirent.h>
+#endif
+
+using namespace std;
+using namespace IceGrid;
+
+namespace IceGrid
+{
+
+class NodeServerCleaner : public DescriptorVisitor
+{
+public:
+
+ void clean(const ServerPrx&, const ServerDescriptorPtr&);
+
+private:
+
+ virtual void visitServerEnd(const ServerWrapper&, const ServerDescriptorPtr&);
+ virtual bool visitServiceStart(const ServiceWrapper&, const ServiceDescriptorPtr&);
+ virtual void visitDbEnv(const DbEnvWrapper&, const DbEnvDescriptor&);
+
+ ServerPrx _currentServer;
+};
+
+};
+
+void
+NodeServerCleaner::clean(const ServerPrx& server, const ServerDescriptorPtr& descriptor)
+{
+ _currentServer = server;
+ ServerWrapper(descriptor).visit(*this);
+}
+
+void
+NodeServerCleaner::visitServerEnd(const ServerWrapper&, const ServerDescriptorPtr& server)
+{
+ _currentServer->removeConfigFile("config");
+ _currentServer->destroy();
+}
+
+bool
+NodeServerCleaner::visitServiceStart(const ServiceWrapper&, const ServiceDescriptorPtr& service)
+{
+ _currentServer->removeConfigFile("config_" + service->name);
+ return true;
+}
+
+void
+NodeServerCleaner::visitDbEnv(const DbEnvWrapper&, const DbEnvDescriptor& dbEnv)
+{
+ _currentServer->removeDbEnv(dbEnv, "");
+}
+
+ServerFactory::ServerFactory(const Ice::ObjectAdapterPtr& adapter,
+ const TraceLevelsPtr& traceLevels,
+ const string& envName,
+ const ActivatorPtr& activator,
+ const WaitQueuePtr& waitQueue) :
+ _adapter(adapter),
+ _traceLevels(traceLevels),
+ _activator(activator),
+ _waitQueue(waitQueue)
+{
+ Ice::PropertiesPtr properties = _adapter->getCommunicator()->getProperties();
+ _waitTime = properties->getPropertyAsIntWithDefault("IceGrid.Node.WaitTime", 60);
+
+ _serversDir = properties->getProperty("IceGrid.Node.Data");
+ _serversDir = _serversDir + (_serversDir[_serversDir.length() - 1] == '/' ? "" : "/") + "servers/";
+
+ //
+ // Create and install the freeze evictor for server objects.
+ //
+ properties->setProperty("Freeze.Evictor." + envName + ".servers.SaveSizeTrigger", "1");
+ _serverEvictor = Freeze::createEvictor(_adapter, envName, "servers", 0);
+ _serverEvictor->setSize(10000);
+
+ //
+ // Create and install the freeze evictor for server adapter objects.
+ //
+ properties->setProperty("Freeze.Evictor." + envName + ".serveradapters.SaveSizeTrigger", "1");
+ _serverAdapterEvictor = Freeze::createEvictor(_adapter, envName, "serveradapters", 0);
+ _serverAdapterEvictor->setSize(10000);
+
+ //
+ // Install the server object factory.
+ //
+ _adapter->getCommunicator()->addObjectFactory(this, "::IceGrid::Server");
+ _adapter->getCommunicator()->addObjectFactory(this, "::IceGrid::ServerAdapter");
+
+ //
+ // Install the evictors.
+ //
+ _adapter->addServantLocator(_serverEvictor, "IceGridServer");
+ _adapter->addServantLocator(_serverAdapterEvictor, "IceGridServerAdapter");
+}
+
+//
+// Ice::ObjectFactory::create method implementation
+//
+Ice::ObjectPtr
+ServerFactory::create(const string& type)
+{
+ if(type == "::IceGrid::Server")
+ {
+ return new ServerI(this, _traceLevels, _activator, _waitTime, _serversDir);
+ }
+ else if(type == "::IceGrid::ServerAdapter")
+ {
+ return new ServerAdapterI(this, _traceLevels, _waitTime);
+ }
+ else
+ {
+ assert(false);
+ return 0; // Keep the compiler happy.
+ }
+}
+
+//
+// Ice::ObjectFactory::destroy method implementation
+//
+void
+ServerFactory::destroy()
+{
+ _adapter = 0;
+ _serverEvictor = 0;
+ _serverAdapterEvictor = 0;
+ _traceLevels = 0;
+ _activator = 0;
+}
+
+void
+ServerFactory::checkConsistency()
+{
+ try
+ {
+ Ice::CommunicatorPtr communicator = _adapter->getCommunicator();
+
+ //
+ // Make sure that all the servers in this node server database are registered with the
+ // IceGrid server registry. If a server isn't registered with the registry, we remove
+ // it from the node and also delete any resources associated with it (config files,
+ // db envs, ...).
+ //
+ ServerRegistryPrx serverRegistry = ServerRegistryPrx::checkedCast(
+ communicator->stringToProxy("IceGrid/ServerRegistry@IceGrid.Registry.Internal"));
+
+ Freeze::EvictorIteratorPtr p = _serverEvictor->getIterator("", 50);
+ while(p->hasNext())
+ {
+ ServerPrx server = ServerPrx::uncheckedCast(_adapter->createProxy(p->next()));
+ ServerDescriptorPtr descriptor = server->getDescriptor();
+ try
+ {
+ if(Ice::proxyIdentityEqual(serverRegistry->findByName(descriptor->name), server))
+ {
+ continue;
+ }
+ }
+ catch(const ServerNotExistException&)
+ {
+ }
+
+ NodeServerCleaner().clean(server, descriptor);
+ }
+
+ //
+ // Make sure all the adapters in this node adapter database are registered with the
+ // IceGrid adapter registry. If an adapter isn't registered with the registry, we
+ // remove it from this node.
+ //
+ AdapterRegistryPrx adapterRegistry = AdapterRegistryPrx::checkedCast(
+ communicator->stringToProxy("IceGrid/AdapterRegistry@IceGrid.Registry.Internal"));
+
+ p = _serverAdapterEvictor->getIterator("", 50);
+ while(p->hasNext())
+ {
+ ServerAdapterPrx adapter = ServerAdapterPrx::uncheckedCast(_adapter->createProxy(p->next()));
+ try
+ {
+ if(Ice::proxyIdentityEqual(adapterRegistry->findById(adapter->getId()), adapter))
+ {
+ continue;
+ }
+ }
+ catch(const AdapterNotExistException&)
+ {
+ }
+
+ adapter->destroy();
+ }
+ }
+ catch(const Ice::LocalException& ex)
+ {
+ ostringstream os;
+ os << "couldn't contact the IceGrid registry for the consistency check:\n" << ex;
+ _traceLevels->logger->warning(os.str());
+ return;
+ }
+
+}
+
+//
+// Create a new server servant and new server adapter servants from
+// the given description.
+//
+ServerPrx
+ServerFactory::createServer(const string& name, const ServerDescriptorPtr& desc)
+{
+ //
+ // Create the server object.
+ //
+ ServerPtr serverI = new ServerI(this, _traceLevels, _activator, _waitTime, _serversDir);
+
+ serverI->name = name;
+ serverI->activation = Manual;
+ serverI->processRegistered = false;
+ serverI->descriptor = desc;
+
+ string path = _serversDir + name;
+#ifdef _WIN32
+ if(_mkdir(path.c_str()) != 0)
+#else
+ if(mkdir(path.c_str(), 0755) != 0)
+#endif
+ {
+ DeploymentException ex;
+ ex.reason = "couldn't create directory " + path + ": " + strerror(getSystemErrno());
+ throw ex;
+ }
+
+#ifdef _WIN32
+ _mkdir(string(path + "/config").c_str());
+ _mkdir(string(path + "/dbs").c_str());
+#else
+ mkdir(string(path + "/config").c_str(), 0755);
+ mkdir(string(path + "/dbs").c_str(), 0755);
+#endif
+
+ Ice::Identity id;
+ id.category = "IceGridServer";
+ id.name = name + "-" + IceUtil::generateUUID();
+
+ _serverEvictor->add(serverI, id);
+
+ if(_traceLevels->server > 0)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->serverCat);
+ out << "created server `" << name << "'";
+ }
+
+ return ServerPrx::uncheckedCast(_adapter->createProxy(id));
+}
+
+//
+// Create a new server adapter servant with the given name and server
+// and add it the evictor database.
+//
+ServerAdapterPrx
+ServerFactory::createServerAdapter(const string& adapterId, const ServerPrx& server)
+{
+ ServerAdapterPtr adapterI = new ServerAdapterI(this, _traceLevels, _waitTime);
+ adapterI->id = adapterId;
+ adapterI->svr = server;
+
+ Ice::Identity id;
+ id.category = "IceGridServerAdapter";
+ id.name = adapterId + "-" + IceUtil::generateUUID();
+
+ _serverAdapterEvictor->add(adapterI, id);
+
+ if(_traceLevels->adapter > 0)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->adapterCat);
+ out << "created server adapter `" << adapterId << "'";
+ }
+
+ return ServerAdapterPrx::uncheckedCast(_adapter->createProxy(id));
+}
+
+const WaitQueuePtr&
+ServerFactory::getWaitQueue() const
+{
+ return _waitQueue;
+}
+
+const Freeze::EvictorPtr&
+ServerFactory::getServerEvictor() const
+{
+ return _serverEvictor;
+}
+
+const Freeze::EvictorPtr&
+ServerFactory::getServerAdapterEvictor() const
+{
+ return _serverAdapterEvictor;
+}
+
+void
+ServerFactory::destroy(const ServerPtr& server, const Ice::Identity& ident)
+{
+ try
+ {
+ _serverEvictor->remove(ident);
+
+ if(_traceLevels->server > 0)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->serverCat);
+ out << "destroyed server `" << server->name << "'";
+ }
+ }
+ catch(const Freeze::DatabaseException& ex)
+ {
+ ostringstream os;
+ os << "couldn't destroy server `" << server->name << "':\n" << ex;
+ _traceLevels->logger->warning(os.str());
+ }
+ catch(const Freeze::EvictorDeactivatedException&)
+ {
+ assert(false);
+ }
+
+ string path = _serversDir + server->name;
+ rmdir(string(path + "/config").c_str());
+ rmdir(string(path + "/dbs").c_str());
+ rmdir(path.c_str());
+}
+
+void
+ServerFactory::destroy(const ServerAdapterPtr& adapter, const Ice::Identity& ident)
+{
+ try
+ {
+ _serverAdapterEvictor->remove(ident);
+
+ if(_traceLevels->adapter > 0)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->adapterCat);
+ out << "destroyed server adapter `" << adapter->id << "'";
+ }
+ }
+ catch(const Freeze::DatabaseException& ex)
+ {
+ ostringstream os;
+ os << "couldn't destroy server adapter `" << adapter->id << "':\n" << ex;
+ _traceLevels->logger->warning(os.str());
+ }
+ catch(const Freeze::EvictorDeactivatedException&)
+ {
+ assert(false);
+ }
+}
+
diff --git a/cpp/src/IceGrid/ServerFactory.h b/cpp/src/IceGrid/ServerFactory.h
new file mode 100644
index 00000000000..b19697a3dc0
--- /dev/null
+++ b/cpp/src/IceGrid/ServerFactory.h
@@ -0,0 +1,72 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 ICE_GRID_SERVER_FACTORY_H
+#define ICE_GRID_SERVER_FACTORY_H
+
+#include <IceGrid/Internal.h>
+#include <IceGrid/Activator.h>
+#include <IceGrid/WaitQueue.h>
+#include <Freeze/Evictor.h>
+
+namespace IceGrid
+{
+
+class TraceLevels;
+typedef IceUtil::Handle<TraceLevels> TraceLevelsPtr;
+
+class ServerFactory : public Ice::ObjectFactory
+{
+public:
+
+ ServerFactory(const Ice::ObjectAdapterPtr&,
+ const TraceLevelsPtr&,
+ const std::string&,
+ const ActivatorPtr&,
+ const WaitQueuePtr&);
+
+ //
+ // Ice::ObjectFactory method implementation.
+ //
+ virtual Ice::ObjectPtr create(const std::string&);
+ virtual void destroy();
+
+ void checkConsistency();
+
+ ServerPrx createServer(const std::string&, const ServerDescriptorPtr&);
+ ServerAdapterPrx createServerAdapter(const std::string& name, const ServerPrx& server);
+
+ const WaitQueuePtr& getWaitQueue() const;
+ const Freeze::EvictorPtr& getServerEvictor() const;
+ const Freeze::EvictorPtr& getServerAdapterEvictor() const;
+
+private:
+
+ friend class ServerI;
+ friend class ServerAdapterI;
+
+ void destroy(const ServerPtr&, const Ice::Identity&);
+ void destroy(const ServerAdapterPtr&, const Ice::Identity&);
+
+ Ice::ObjectAdapterPtr _adapter;
+ TraceLevelsPtr _traceLevels;
+ ActivatorPtr _activator;
+ WaitQueuePtr _waitQueue;
+
+ Freeze::EvictorPtr _serverEvictor;
+ Freeze::EvictorPtr _serverAdapterEvictor;
+ Ice::Int _waitTime;
+ std::string _serversDir;
+};
+
+typedef ::IceUtil::Handle< ServerFactory> ServerFactoryPtr;
+
+}
+
+#endif
diff --git a/cpp/src/IceGrid/ServerI.cpp b/cpp/src/IceGrid/ServerI.cpp
new file mode 100644
index 00000000000..3d97d2a0302
--- /dev/null
+++ b/cpp/src/IceGrid/ServerI.cpp
@@ -0,0 +1,807 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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.
+//
+// **********************************************************************
+
+#ifdef __sun
+#define _POSIX_PTHREAD_SEMANTICS
+#endif
+
+#include <IceUtil/UUID.h>
+#include <Ice/Ice.h>
+#include <IceGrid/ServerI.h>
+#include <IceGrid/ServerFactory.h>
+#include <IceGrid/TraceLevels.h>
+#include <IceGrid/Activator.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef _WIN32
+# include <direct.h>
+#else
+# include <unistd.h>
+# include <dirent.h>
+#endif
+
+#include <fstream>
+
+using namespace std;
+using namespace IceGrid;
+
+ServerI::ServerI(const ServerFactoryPtr& factory,
+ const TraceLevelsPtr& traceLevels,
+ const ActivatorPtr& activator,
+ Ice::Int waitTime,
+ const string& serversDir) :
+ _factory(factory),
+ _traceLevels(traceLevels),
+ _activator(activator),
+ _waitTime(waitTime),
+ _serversDir(serversDir),
+ _state(Inactive)
+{
+ assert(_activator);
+}
+
+ServerI::~ServerI()
+{
+}
+
+bool
+ServerI::start(ServerActivation act, const Ice::Current& current)
+{
+ string exe;
+ string wd;
+ Ice::StringSeq opts;
+ Ice::StringSeq evs;
+
+ while(true)
+ {
+ Lock sync(*this);
+ switch(_state)
+ {
+ case Inactive:
+ {
+ if(act < activation)
+ {
+ return false;
+ }
+
+ _state = Activating;
+
+ //
+ // Prevent eviction of the server object once it's not anymore in the inactive state.
+ //
+ _factory->getServerEvictor()->keep(current.id);
+
+ break;
+ }
+ case Activating:
+ case Deactivating:
+ {
+ wait(); // TODO: Timeout?
+ continue;
+ }
+ case Active:
+ {
+ return true; // Raise an exception instead?
+ }
+ case Destroying:
+ case Destroyed:
+ {
+ Ice::ObjectNotExistException ex(__FILE__,__LINE__);
+ ex.id = current.id;
+ throw ex;
+ }
+ }
+
+ if(_traceLevels->server > 2)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->serverCat);
+ out << "changed server `" << name << "' state to `Activating'";
+ }
+ assert(_state == Activating);
+
+ exe = exePath;
+ wd = pwd;
+ opts = options;
+ evs = envs;
+ break;
+ }
+
+ try
+ {
+ ServerPrx self = ServerPrx::uncheckedCast(current.adapter->createProxy(current.id));
+ bool active = _activator->activate(name, exe, wd, opts, evs, self);
+ setState(active ? Active : Inactive, current);
+ return active;
+ }
+ catch(const Ice::SyscallException& ex)
+ {
+ Ice::Warning out(_traceLevels->logger);
+ out << "activation failed for server `" << name << "':\n";
+ out << ex;
+
+ setState(Inactive, current);
+ return false;
+ }
+}
+
+void
+ServerI::stop(const Ice::Current& current)
+{
+ while(true)
+ {
+ Lock sync(*this);
+ switch(_state)
+ {
+ case Inactive:
+ {
+ return;
+ }
+ case Activating:
+ case Deactivating:
+ {
+ wait(); // TODO: Timeout?
+ continue;
+ }
+ case Active:
+ {
+ _state = Deactivating;
+ break;
+ }
+ case Destroying:
+ case Destroyed:
+ {
+ Ice::ObjectNotExistException ex(__FILE__,__LINE__);
+ ex.id = current.id;
+ throw ex;
+ }
+ }
+
+ if(_traceLevels->server > 2)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->serverCat);
+ out << "changed server `" << name << "' state to `Deactivating'";
+ }
+ assert(_state == Deactivating);
+ break;
+ }
+
+ stopInternal(current);
+}
+
+void
+ServerI::sendSignal(const string& signal, const Ice::Current& current)
+{
+ _activator->sendSignal(name, signal);
+}
+
+void
+ServerI::writeMessage(const string& message, Ice::Int fd, const Ice::Current& current)
+{
+ IceUtil::Monitor< ::IceUtil::Mutex>::Lock sync(*this);
+ if(_process != 0)
+ {
+ try
+ {
+ _process->writeMessage(message, fd);
+ }
+ catch(const Ice::LocalException&)
+ {
+ }
+ }
+}
+
+void
+ServerI::destroy(const Ice::Current& current)
+{
+ bool stop = false;
+
+ while(true)
+ {
+ Lock sync(*this);
+ switch(_state)
+ {
+ case Inactive:
+ {
+ _state = Destroyed;
+ break;
+ }
+ case Active:
+ {
+ stop = true;
+ _state = Destroying;
+ break;
+ }
+ case Activating:
+ case Deactivating:
+ {
+ wait(); // TODO: Timeout?
+ continue;
+ }
+ case Destroying:
+ case Destroyed:
+ {
+ Ice::ObjectNotExistException ex(__FILE__,__LINE__);
+ ex.id = current.id;
+ throw ex;
+ }
+ }
+
+ assert(_state == Destroyed || _state == Destroying);
+
+ if(_traceLevels->server > 2)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->serverCat);
+ out << "changed server `" << name << "' state to `";
+ out << (_state == Destroyed ? "Destroyed" : "Destroying") << "'";
+ }
+ break;
+ }
+
+ if(stop)
+ {
+ stopInternal(current);
+ }
+
+
+ _factory->destroy(this, current.id);
+}
+
+void
+ServerI::terminated(const Ice::Current& current)
+{
+ ServerState newState = Inactive; // Initialize to keep the compiler happy.
+ ServerAdapterPrxDict adpts;
+ while(true)
+ {
+ Lock sync(*this);
+ switch(_state)
+ {
+ case Inactive:
+ {
+ assert(false);
+ }
+ case Activating:
+ {
+ wait(); // TODO: Timeout?
+ continue;
+ }
+ case Active:
+ {
+ _state = Deactivating;
+ if(_traceLevels->server > 2)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->serverCat);
+ out << "changed server `" << name << "' state to `Deactivating'";
+ }
+ newState = Inactive;
+ break;
+ }
+ case Deactivating:
+ {
+ //
+ // Deactivation was initiated by the stop method.
+ //
+ newState = Inactive;
+ break;
+ }
+ case Destroying:
+ {
+ //
+ // Deactivation was initiated by the destroy method.
+ //
+ newState = Destroyed;
+ break;
+ }
+ case Destroyed:
+ {
+ assert(false);
+ }
+ }
+
+ assert(_state == Deactivating || _state == Destroying);
+ adpts = adapters;
+
+ //
+ // Clear the process proxy.
+ //
+ _process = 0;
+ break;
+ }
+
+ if(newState != Destroyed)
+ {
+ //
+ // The server has terminated, set its adapter direct proxies to
+ // null to cause the server re-activation if one of its adapter
+ // direct proxy is requested.
+ //
+ for(ServerAdapterPrxDict::iterator p = adpts.begin(); p != adpts.end(); ++p)
+ {
+ try
+ {
+ p->second->setDirectProxy(0);
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ }
+ }
+ }
+
+ setState(newState, current);
+}
+
+ServerState
+ServerI::getState(const Ice::Current&)
+{
+ Lock sync(*this);
+ return _state;
+}
+
+Ice::Int
+ServerI::getPid(const Ice::Current& current)
+{
+ return _activator->getServerPid(name);
+}
+
+void
+ServerI::setActivationMode(ServerActivation mode, const ::Ice::Current&)
+{
+ Lock sync(*this);
+ activation = mode;
+}
+
+ServerActivation
+ServerI::getActivationMode(const ::Ice::Current&)
+{
+ Lock sync(*this);
+ return activation;
+}
+
+ServerDescriptorPtr
+ServerI::getDescriptor(const Ice::Current&)
+{
+ Lock sync(*this);
+ return descriptor;
+}
+
+void
+ServerI::setExePath(const string& path, const ::Ice::Current&)
+{
+ Lock sync(*this);
+ exePath = path;
+}
+
+void
+ServerI::setPwd(const string& path,const ::Ice::Current&)
+{
+ Lock sync(*this);
+ pwd = path;
+}
+
+void
+ServerI::setEnvs(const Ice::StringSeq& s, const ::Ice::Current&)
+{
+ Lock sync(*this);
+ envs = s;
+}
+
+void
+ServerI::setOptions(const Ice::StringSeq& opts, const ::Ice::Current&)
+{
+ Lock sync(*this);
+ options = opts;
+}
+
+void
+ServerI::addAdapter(const ServerAdapterPrx& adapter, bool registerProcess, const ::Ice::Current&)
+{
+ Lock sync(*this);
+ ServerAdapterPrxDict::const_iterator p = adapters.find(adapter->ice_getIdentity());
+ if(p != adapters.end())
+ {
+ DeploymentException ex;
+ ex.reason = "failed to add adapter because it already exists";
+ throw ex;
+ }
+ adapters[adapter->ice_getIdentity()] = adapter;
+ processRegistered |= registerProcess;
+}
+
+void
+ServerI::removeAdapter(const ServerAdapterPrx& adapter, const ::Ice::Current&)
+{
+ Lock sync(*this);
+ adapters.erase(adapter->ice_getIdentity());
+}
+
+string
+ServerI::addConfigFile(const string& n, const PropertyDescriptorSeq& properties, const ::Ice::Current&)
+{
+ string file = _serversDir + name + "/config/" + n;
+
+ ofstream configfile;
+ configfile.open(file.c_str(), ios::out);
+ if(!configfile)
+ {
+ DeploymentException ex;
+ ex.reason = "couldn't create configuration file: " + file;
+ throw ex;
+ }
+
+ for(PropertyDescriptorSeq::const_iterator p = properties.begin(); p != properties.end(); ++p)
+ {
+ configfile << p->name;
+ if(!p->value.empty())
+ {
+ configfile << "=" << p->value;
+ }
+ configfile << endl;
+ }
+ configfile.close();
+
+ return file;
+}
+
+void
+ServerI::removeConfigFile(const string& n, const ::Ice::Current&)
+{
+ string file = _serversDir + name + "/config/" + n;
+ if(unlink(file.c_str()) != 0)
+ {
+ Ice::Warning out(_traceLevels->logger);
+ out << "couldn't remove configuration file: " + file + ": " + strerror(getSystemErrno());
+ }
+}
+
+string
+ServerI::addDbEnv(const DbEnvDescriptor& dbEnv, const string& path, const ::Ice::Current&)
+{
+ string dir;
+ if(dbEnv.dbHome.empty())
+ {
+ dir = _serversDir + name + "/dbs/" + dbEnv.name;
+ }
+ else
+ {
+ dir = dbEnv.dbHome;
+ }
+
+ //
+ // If no db home directory is specified for this db env, we provide one.
+ //
+ if(dbEnv.dbHome.empty())
+ {
+ //
+ // First, we try to move the given backup if specified, if not successful, we just
+ // create the database environment directory.
+ //
+ if(path.empty() || rename((path + "/" + dbEnv.name).c_str(), dir.c_str()) != 0)
+ {
+ //
+ // Create the database environment directory.
+ //
+#ifdef _WIN32
+ if(_mkdir(dir.c_str()) != 0)
+#else
+ if(mkdir(dir.c_str(), 0755) != 0)
+#endif
+ {
+ DeploymentException ex;
+ ex.reason = "couldn't create directory " + dir + ": " + strerror(getSystemErrno());
+ throw ex;
+ }
+ }
+ }
+
+ string file = dir + "/DB_CONFIG";
+ ofstream configfile;
+ configfile.open(file.c_str(), ios::out);
+ if(!configfile)
+ {
+ rmdir(dir.c_str());
+
+ DeploymentException ex;
+ ex.reason = "couldn't create configuration file: " + file;
+ throw ex;
+ }
+
+ for(PropertyDescriptorSeq::const_iterator p = dbEnv.properties.begin(); p != dbEnv.properties.end(); ++p)
+ {
+ if(!p->name.empty())
+ {
+ configfile << p->name;
+ if(!p->value.empty())
+ {
+ configfile << " " << p->value;
+ }
+ configfile << endl;
+ }
+ }
+ configfile.close();
+
+ return dir;
+}
+
+void
+ServerI::removeDbEnv(const DbEnvDescriptor& dbEnv, const string& moveTo, const ::Ice::Current&)
+{
+ string path;
+ if(dbEnv.dbHome.empty())
+ {
+ path = _serversDir + name + "/dbs/" + dbEnv.name;
+ }
+ else
+ {
+ path = dbEnv.dbHome;
+ }
+
+ if(unlink((path + "/DB_CONFIG").c_str()) != 0)
+ {
+ Ice::Warning out(_traceLevels->logger);
+ out << "couldn't remove file: " + path + "/DB_CONFIG: " + strerror(getSystemErrno());
+ }
+
+ //
+ // If no db home directory was specified for this db env, we provided one. We need to cleanup
+ // this directory now.
+ //
+ if(dbEnv.dbHome.empty())
+ {
+ if(!moveTo.empty())
+ {
+ //
+ // Move the database environment directory to the given directory.
+ //
+ if(rename(path.c_str(), (moveTo + "/" + dbEnv.name).c_str()) != 0)
+ {
+ Ice::Warning out(_traceLevels->logger);
+ out << "couldn't rename directory " + path + " to " + moveTo + "/" + dbEnv.name + ": " +
+ strerror(getSystemErrno());
+ }
+ }
+ else
+ {
+ //
+ // Delete the database environment directory.
+ //
+ Ice::StringSeq files;
+
+#ifdef _WIN32
+ string pattern = path + "/*";
+ WIN32_FIND_DATA data;
+ HANDLE hnd = FindFirstFile(pattern.c_str(), &data);
+ if(hnd == INVALID_HANDLE_VALUE)
+ {
+ // TODO: log a warning, throw an exception?
+ return;
+ }
+
+ do
+ {
+ if((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
+ {
+ files.push_back(path + "/" + data.cFileName);
+ }
+ }
+ while(FindNextFile(hnd, &data));
+
+ FindClose(hnd);
+#else
+
+ DIR* dir = opendir(path.c_str());
+ if(dir == 0)
+ {
+ // TODO: log a warning, throw an exception?
+ return;
+ }
+
+ // TODO: make the allocation/deallocation exception-safe
+ struct dirent* entry = static_cast<struct dirent*>(malloc(pathconf(path.c_str(), _PC_NAME_MAX) + 1));
+
+ while(readdir_r(dir, entry, &entry) == 0 && entry != 0)
+ {
+ string name = path + "/" + entry->d_name;
+ struct stat buf;
+
+ if(::stat(name.c_str(), &buf) != 0)
+ {
+ if(errno != ENOENT)
+ {
+ //
+ // TODO: log error
+ //
+ }
+ }
+ else if(S_ISREG(buf.st_mode))
+ {
+ files.push_back(name);
+ }
+ }
+
+ free(entry);
+ closedir(dir);
+#endif
+
+ for(Ice::StringSeq::iterator p = files.begin(); p != files.end(); ++p)
+ {
+ if(unlink(p->c_str()) != 0)
+ {
+ //
+ // TODO: log error
+ //
+ }
+ }
+
+ if(rmdir(path.c_str()) != 0)
+ {
+ Ice::Warning out(_traceLevels->logger);
+ out << "couldn't remove directory: " + path + ": " + strerror(getSystemErrno());
+ }
+ }
+ }
+}
+
+void
+ServerI::setProcess(const ::Ice::ProcessPrx& proc, const ::Ice::Current&)
+{
+ IceUtil::Monitor< ::IceUtil::Mutex>::Lock sync(*this);
+ _process = proc;
+ notifyAll();
+}
+
+void
+ServerI::stopInternal(const Ice::Current& current)
+{
+ Ice::ProcessPrx process;
+ {
+ IceUtil::Monitor< ::IceUtil::Mutex>::Lock sync(*this);
+ if(!_process && processRegistered)
+ {
+ while(!_process)
+ {
+ if(_state == Inactive || _state == Destroyed)
+ {
+ //
+ // State changed to inactive or destroyed, the server
+ // has been correctly deactivated, we can return.
+ //
+ return;
+ }
+
+ //
+ // Wait for the process to be set.
+ //
+ wait(); // TODO: timeout?
+ }
+ }
+ process = _process;
+ }
+
+ try
+ {
+ //
+ // Deactivate the server.
+ //
+ _activator->deactivate(name, process);
+
+ //
+ // Wait for the server to be inactive (the activator monitors
+ // the process and should notify us when it detects the
+ // process termination by calling the terminated() method).
+ //
+ Lock sync(*this);
+
+#ifndef NDEBUG
+ ServerState oldState = _state;
+#endif
+
+ while(true)
+ {
+ if(_state == Inactive || _state == Destroyed)
+ {
+ //
+ // State changed to inactive or destroyed, the server
+ // has been correctly deactivated, we can return.
+ //
+ return;
+ }
+
+ //
+ // Wait for a notification.
+ //
+ bool notify = timedWait(IceUtil::Time::seconds(_waitTime));
+ if(!notify)
+ {
+ assert(oldState == _state);
+ break;
+ }
+ }
+
+ if(_traceLevels->server > 1)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->serverCat);
+ out << "graceful server shutdown timed out, killing server `" << name << "'";
+ }
+ }
+ catch(const Ice::Exception& ex)
+ {
+ Ice::Warning out(_traceLevels->logger);
+ out << "graceful server shutdown failed, killing server `" << name << "':\n";
+ out << ex;
+ }
+
+
+ //
+ // The server is still not inactive, kill it.
+ //
+ try
+ {
+ _activator->kill(name);
+ }
+ catch(const Ice::SyscallException& ex)
+ {
+ Ice::Warning out(_traceLevels->logger);
+ out << "deactivation failed for server `" << name << "':\n";
+ out << ex;
+
+ setState(Active, current);
+ }
+}
+
+void
+ServerI::setState(ServerState st, const Ice::Current& current)
+{
+ Lock sync(*this);
+
+ //
+ // Allow eviction of an inactive server object.
+ //
+ if(_state != Inactive && st == Inactive)
+ {
+ _factory->getServerEvictor()->release(current.id);
+ }
+
+ _state = st;
+
+ if(_traceLevels->server > 1)
+ {
+ if(_state == Active)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->serverCat);
+ out << "changed server `" << name << "' state to `Active'";
+ }
+ else if(_state == Inactive)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->serverCat);
+ out << "changed server `" << name << "' state to `Inactive'";
+ }
+ else if(_state == Destroyed)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->serverCat);
+ out << "changed server `" << name << "' state to `Destroyed'";
+ }
+ else if(_traceLevels->server > 2)
+ {
+ if(_state == Activating)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->serverCat);
+ out << "changed server `" << name << "' state to `Activating'";
+ }
+ else if(_state == Deactivating)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->serverCat);
+ out << "changed server `" << name << "' state to `Deactivating'";
+ }
+ }
+ }
+
+ notifyAll();
+}
diff --git a/cpp/src/IceGrid/ServerI.h b/cpp/src/IceGrid/ServerI.h
new file mode 100644
index 00000000000..43ca029d32f
--- /dev/null
+++ b/cpp/src/IceGrid/ServerI.h
@@ -0,0 +1,80 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 ICE_GRID_SERVER_I_H
+#define ICE_GRID_SERVER_I_H
+
+#include <IceUtil/Mutex.h>
+#include <Freeze/EvictorF.h>
+#include <IceGrid/Activator.h>
+#include <IceUtil/AbstractMutex.h>
+
+#include <IceGrid/Internal.h>
+
+namespace IceGrid
+{
+
+class TraceLevels;
+typedef IceUtil::Handle<TraceLevels> TraceLevelsPtr;
+
+class ServerFactory;
+typedef IceUtil::Handle<ServerFactory> ServerFactoryPtr;
+
+class ServerI : public Server, public IceUtil::AbstractMutexI<IceUtil::Monitor<IceUtil::Mutex> >
+{
+public:
+
+ ServerI(const ServerFactoryPtr&, const TraceLevelsPtr&, const ActivatorPtr&, Ice::Int waitTime,const std::string&);
+ virtual ~ServerI();
+
+ virtual bool start(ServerActivation, const ::Ice::Current&);
+ virtual void stop(const ::Ice::Current&);
+ virtual void sendSignal(const std::string&, const ::Ice::Current&);
+ virtual void writeMessage(const std::string&, Ice::Int, const ::Ice::Current&);
+ virtual void destroy(const ::Ice::Current&);
+ virtual void terminated(const ::Ice::Current&);
+
+ virtual ServerState getState(const ::Ice::Current&);
+ virtual Ice::Int getPid(const ::Ice::Current&);
+
+ virtual void setActivationMode(ServerActivation, const ::Ice::Current&);
+ virtual ServerActivation getActivationMode(const ::Ice::Current&);
+ virtual ServerDescriptorPtr getDescriptor(const ::Ice::Current&);
+ virtual void setProcess(const ::Ice::ProcessPrx&, const ::Ice::Current&);
+
+ void setExePath(const std::string&, const ::Ice::Current&);
+ void setPwd(const std::string&, const ::Ice::Current&);
+ void setEnvs(const Ice::StringSeq&, const ::Ice::Current&);
+ void setOptions(const Ice::StringSeq&, const ::Ice::Current&);
+ void addAdapter(const ServerAdapterPrx&, bool, const ::Ice::Current&);
+ void removeAdapter(const ServerAdapterPrx&, const ::Ice::Current&);
+ std::string addConfigFile(const std::string&, const PropertyDescriptorSeq&, const ::Ice::Current&);
+ void removeConfigFile(const std::string&, const ::Ice::Current&);
+ std::string addDbEnv(const DbEnvDescriptor&, const std::string&, const ::Ice::Current&);
+ void removeDbEnv(const DbEnvDescriptor&, const std::string&, const ::Ice::Current&);
+
+private:
+
+ void stopInternal(const Ice::Current&);
+ void setState(ServerState, const Ice::Current&);
+
+ ServerFactoryPtr _factory;
+ TraceLevelsPtr _traceLevels;
+ ActivatorPtr _activator;
+ ::Ice::Int _waitTime;
+ std::string _serversDir;
+
+ ServerState _state;
+
+ ::Ice::ProcessPrx _process;
+};
+
+}
+
+#endif
diff --git a/cpp/src/IceGrid/ServerRegistryI.cpp b/cpp/src/IceGrid/ServerRegistryI.cpp
new file mode 100644
index 00000000000..fdb87302485
--- /dev/null
+++ b/cpp/src/IceGrid/ServerRegistryI.cpp
@@ -0,0 +1,182 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 <IceGrid/ServerRegistryI.h>
+#include <IceGrid/TraceLevels.h>
+#include <Freeze/Initialize.h>
+
+using namespace std;
+using namespace IceGrid;
+
+const string ServerRegistryI::_dbName = "serverregistry";
+const string ServerRegistryI::_dbDescriptorName = "serverdescriptors";
+
+ServerRegistryI::ServerRegistryI(const Ice::CommunicatorPtr& communicator, const string& envName,
+ const TraceLevelsPtr& traceLevels) :
+ _connectionCache(Freeze::createConnection(communicator, envName)),
+ _dictCache(_connectionCache, _dbName),
+ _dictDescriptorCache(_connectionCache, _dbDescriptorName),
+ _traceLevels(traceLevels),
+ _envName(envName),
+ _communicator(communicator)
+{
+}
+
+void
+ServerRegistryI::add(const string& name,
+ const ServerPrx& server,
+ const ServerDescriptorPtr& descriptor,
+ const Ice::Current& current)
+{
+ while(true)
+ {
+ ServerPrx oldServer;
+ try
+ {
+ oldServer = findByName(name, current);
+ oldServer->ice_ping();
+ throw ServerExistsException();
+ }
+ catch(const ServerNotExistException&)
+ {
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ }
+ catch(const Ice::LocalException&)
+ {
+ throw ServerExistsException();
+ }
+
+ Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName);
+ StringObjectProxyDict dict(connection, _dbName);
+ StringServerDescriptorDict dictDescriptor(connection, _dbDescriptorName);
+
+ StringObjectProxyDict::iterator p = dict.find(name);
+ if(p != dict.end())
+ {
+ if(oldServer && oldServer != p->second)
+ {
+ continue;
+ }
+ }
+
+ dict.put(pair<const string, const Ice::ObjectPrx>(name, server));
+ dictDescriptor.put(pair<const string, const ServerDescriptorPtr>(name, descriptor));
+
+ if(_traceLevels->serverRegistry > 0)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->serverRegistryCat);
+ out << "added server `" << name << "'";
+ }
+
+ break;
+ }
+}
+
+ServerPrx
+ServerRegistryI::remove(const string& name, const Ice::Current&)
+{
+ Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName);
+ StringObjectProxyDict dict(connection, _dbName);
+ StringServerDescriptorDict dictDescriptor(connection, _dbDescriptorName);
+
+ StringObjectProxyDict::iterator p = dict.find(name);
+ if(p == dict.end())
+ {
+ throw ServerNotExistException();
+ }
+
+ ServerPrx server = ServerPrx::uncheckedCast(p->second);
+ dict.erase(p);
+ dictDescriptor.erase(name);
+
+ if(_traceLevels->serverRegistry > 0)
+ {
+ Ice::Trace out(_traceLevels->logger, _traceLevels->serverRegistryCat);
+ out << "removed server `" << name << "'";
+ }
+
+ return server;
+}
+
+ServerPrx
+ServerRegistryI::findByName(const string& name, const Ice::Current&)
+{
+ Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName);
+ StringObjectProxyDict dict(connection, _dbName);
+
+ StringObjectProxyDict::iterator p = dict.find(name);
+ if(p != dict.end())
+ {
+ try
+ {
+ return ServerPrx::checkedCast(p->second);
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ dict.erase(p);
+ }
+ catch(const Ice::LocalException&)
+ {
+ return ServerPrx::uncheckedCast(p->second);
+ }
+ }
+ throw ServerNotExistException();
+}
+
+ServerDescriptorPtr
+ServerRegistryI::getDescriptor(const string& name, const Ice::Current&)
+{
+ Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName);
+ StringServerDescriptorDict dictDescriptor(connection, _dbDescriptorName);
+
+ StringServerDescriptorDict::iterator p = dictDescriptor.find(name);
+ if(p == dictDescriptor.end())
+ {
+ throw ServerNotExistException();
+ }
+ return p->second;
+}
+
+Ice::StringSeq
+ServerRegistryI::getAll(const Ice::Current&) const
+{
+ Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName);
+ StringObjectProxyDict dict(connection, _dbName);
+
+ Ice::StringSeq names;
+ names.reserve(dict.size());
+
+ for(StringObjectProxyDict::iterator p = dict.begin(); p != dict.end(); ++p)
+ {
+ names.push_back(p->first);
+ }
+
+ return names;
+}
+
+ServerDescriptorSeq
+ServerRegistryI::getAllDescriptorsOnNode(const string& node, const Ice::Current&) const
+{
+ Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName);
+ StringServerDescriptorDict dict(connection, _dbDescriptorName);
+
+ ServerDescriptorSeq descriptors;
+
+ for(StringServerDescriptorDict::iterator p = dict.begin(); p != dict.end(); ++p)
+ {
+ if(p->second->node == node)
+ {
+ descriptors.push_back(p->second);
+ }
+ }
+
+ return descriptors;
+}
diff --git a/cpp/src/IceGrid/ServerRegistryI.h b/cpp/src/IceGrid/ServerRegistryI.h
new file mode 100644
index 00000000000..dc285145d57
--- /dev/null
+++ b/cpp/src/IceGrid/ServerRegistryI.h
@@ -0,0 +1,52 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 ICE_GRID_SERVER_REGISTRY_I_H
+#define ICE_GRID_SERVER_REGISTRY_I_H
+
+#include <IceGrid/Internal.h>
+#include <IceGrid/StringObjectProxyDict.h>
+#include <IceGrid/StringServerDescriptorDict.h>
+
+namespace IceGrid
+{
+
+class TraceLevels;
+typedef IceUtil::Handle<TraceLevels> TraceLevelsPtr;
+
+class ServerRegistryI : public ServerRegistry
+{
+public:
+
+ ServerRegistryI(const Ice::CommunicatorPtr&, const std::string&, const TraceLevelsPtr&);
+
+ virtual void add(const std::string&, const ServerPrx&, const ServerDescriptorPtr&, const ::Ice::Current&);
+ virtual ServerPrx remove(const std::string&, const ::Ice::Current&);
+
+ virtual ServerPrx findByName(const ::std::string&, const ::Ice::Current&);
+ virtual ServerDescriptorPtr getDescriptor(const ::std::string&, const Ice::Current&);
+ virtual Ice::StringSeq getAll(const ::Ice::Current&) const;
+ virtual ServerDescriptorSeq getAllDescriptorsOnNode(const std::string&, const ::Ice::Current&) const;
+
+private:
+
+ static const std::string _dbName;
+ static const std::string _dbDescriptorName;
+
+ Freeze::ConnectionPtr _connectionCache;
+ StringObjectProxyDict _dictCache;
+ StringServerDescriptorDict _dictDescriptorCache;
+ TraceLevelsPtr _traceLevels;
+ const std::string _envName;
+ const Ice::CommunicatorPtr _communicator;
+};
+
+}
+
+#endif
diff --git a/cpp/src/IceGrid/TraceLevels.cpp b/cpp/src/IceGrid/TraceLevels.cpp
new file mode 100644
index 00000000000..d2a4c6944c0
--- /dev/null
+++ b/cpp/src/IceGrid/TraceLevels.cpp
@@ -0,0 +1,50 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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/Properties.h>
+#include <IceGrid/TraceLevels.h>
+
+using namespace std;
+using namespace IceGrid;
+
+TraceLevels::TraceLevels(const Ice::PropertiesPtr& properties, const Ice::LoggerPtr& theLogger) :
+ server(0),
+ serverCat("Server"),
+ adapter(0),
+ adapterCat("Adapter"),
+ activator(0),
+ activatorCat("Activator"),
+ applicationRegistry(0),
+ applicationRegistryCat("ApplicationRegistry"),
+ serverRegistry(0),
+ serverRegistryCat("ServerRegistry"),
+ adapterRegistry(0),
+ adapterRegistryCat("AdapterRegistry"),
+ objectRegistry(0),
+ objectRegistryCat("ObjectRegistry"),
+ nodeRegistry(0),
+ nodeRegistryCat("NodeRegistry"),
+ logger(theLogger)
+{
+ const string nodeKeyBase = "IceGrid.Node.Trace.";
+ const_cast<int&>(server) = properties->getPropertyAsInt(nodeKeyBase + serverCat);
+ const_cast<int&>(adapter) = properties->getPropertyAsInt(nodeKeyBase + adapterCat);
+ const_cast<int&>(activator) = properties->getPropertyAsInt(nodeKeyBase + activatorCat);
+
+ const string registryKeyBase = "IceGrid.Registry.Trace.";
+ const_cast<int&>(applicationRegistry) = properties->getPropertyAsInt(registryKeyBase + applicationRegistryCat);
+ const_cast<int&>(serverRegistry) = properties->getPropertyAsInt(registryKeyBase + serverRegistryCat);
+ const_cast<int&>(adapterRegistry) = properties->getPropertyAsInt(registryKeyBase + adapterRegistryCat);
+ const_cast<int&>(objectRegistry) = properties->getPropertyAsInt(registryKeyBase + objectRegistryCat);
+ const_cast<int&>(nodeRegistry) = properties->getPropertyAsInt(registryKeyBase + nodeRegistryCat);
+}
+
+TraceLevels::~TraceLevels()
+{
+}
diff --git a/cpp/src/IceGrid/TraceLevels.h b/cpp/src/IceGrid/TraceLevels.h
new file mode 100644
index 00000000000..c67692bd281
--- /dev/null
+++ b/cpp/src/IceGrid/TraceLevels.h
@@ -0,0 +1,58 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 ICE_GRID_TRACE_LEVELS_H
+#define ICE_GRID_TRACE_LEVELS_H
+
+#include <IceUtil/Shared.h>
+#include <Ice/PropertiesF.h>
+#include <Ice/LoggerF.h>
+
+namespace IceGrid
+{
+
+class TraceLevels : public ::IceUtil::Shared
+{
+public:
+
+ TraceLevels(const ::Ice::PropertiesPtr&, const Ice::LoggerPtr&);
+ virtual ~TraceLevels();
+
+ const int server;
+ const char* serverCat;
+
+ const int adapter;
+ const char* adapterCat;
+
+ const int activator;
+ const char* activatorCat;
+
+ const int applicationRegistry;
+ const char* applicationRegistryCat;
+
+ const int serverRegistry;
+ const char* serverRegistryCat;
+
+ const int adapterRegistry;
+ const char* adapterRegistryCat;
+
+ const int objectRegistry;
+ const char* objectRegistryCat;
+
+ const int nodeRegistry;
+ const char* nodeRegistryCat;
+
+ const Ice::LoggerPtr logger;
+};
+
+typedef IceUtil::Handle<TraceLevels> TraceLevelsPtr;
+
+} // End namespace IceGrid
+
+#endif
diff --git a/cpp/src/IceGrid/WaitQueue.cpp b/cpp/src/IceGrid/WaitQueue.cpp
new file mode 100644
index 00000000000..9a4f3eb1a0c
--- /dev/null
+++ b/cpp/src/IceGrid/WaitQueue.cpp
@@ -0,0 +1,204 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 <IceGrid/WaitQueue.h>
+
+using namespace std;
+using namespace IceGrid;
+
+WaitItem::WaitItem(const Ice::ObjectPtr& object) :
+ _object(object)
+{
+}
+
+WaitItem::~WaitItem()
+{
+}
+
+const IceUtil::Time&
+WaitItem:: getExpirationTime()
+{
+ return _expiration;
+}
+
+void
+WaitItem::setExpirationTime(const IceUtil::Time& time)
+{
+ _expiration = time;
+}
+
+WaitQueue::WaitQueue() : _destroyed(false)
+{
+}
+
+void
+WaitQueue::run()
+{
+ Lock sync(*this);
+
+ while(true)
+ {
+ if(_waitQueue.empty() && _workQueue.empty() && !_destroyed)
+ {
+ wait();
+ }
+
+ if(!_workQueue.empty())
+ {
+ //
+ // Execute all the work queue items.
+ //
+ for(list<WaitItemPtr>::iterator p = _workQueue.begin(); p != _workQueue.end(); ++p)
+ {
+ try
+ {
+ if(_destroyed)
+ {
+ (*p)->expired(true);
+ }
+ else
+ {
+ (*p)->execute();
+ }
+ }
+ catch(...)
+ {
+ }
+ }
+ _workQueue.clear();
+ }
+
+ if(_destroyed)
+ {
+ break;
+ }
+
+ if(!_waitQueue.empty())
+ {
+ //
+ // Notify expired items.
+ //
+ while(!_waitQueue.empty())
+ {
+ WaitItemPtr item = _waitQueue.front();
+
+ if(item->getExpirationTime() <= IceUtil::Time::now())
+ {
+ try
+ {
+ item->expired(false);
+ }
+ catch(...)
+ {
+ }
+ _waitQueue.pop_front();
+ }
+ else
+ {
+ //
+ // Wait until the next item expire or a notification. Note: in any case we
+ // get out of this loop to get a chance to execute the work queue.
+ //
+ timedWait(item->getExpirationTime() - IceUtil::Time::now());
+ break;
+ }
+ }
+ }
+ }
+
+ assert(_workQueue.empty());
+
+ if(!_waitQueue.empty())
+ {
+ for(list<WaitItemPtr>::iterator p = _waitQueue.begin(); p != _waitQueue.end(); ++p)
+ {
+ (*p)->expired(true);
+ }
+ }
+}
+
+void
+WaitQueue::destroy()
+{
+ {
+ Lock sync(*this);
+ _destroyed = true;
+ notify();
+ }
+
+ getThreadControl().join();
+}
+
+void
+WaitQueue::add(const WaitItemPtr& item, const IceUtil::Time& wait)
+{
+ Lock sync(*this);
+
+ //
+ // We'll have to notify the thread if it's sleeping for good.
+ //
+ bool notifyThread = _workQueue.empty() && _waitQueue.empty();
+
+ if(wait == IceUtil::Time::seconds(0))
+ {
+ item->setExpirationTime(IceUtil::Time::now());
+ _workQueue.push_back(item);
+ }
+ else
+ {
+ IceUtil::Time expire = IceUtil::Time::now() + wait;
+ item->setExpirationTime(expire);
+
+ list<WaitItemPtr>::iterator p = _waitQueue.begin();
+ while(p != _waitQueue.end())
+ {
+ if((*p)->getExpirationTime() >= expire)
+ {
+ break;
+ }
+ ++p;
+ }
+ _waitQueue.insert(p, item);
+ }
+
+ if(notifyThread)
+ {
+ notify();
+ }
+}
+
+void
+WaitQueue::notifyAllWaitingOn(const Ice::ObjectPtr& object)
+{
+ Lock sync(*this);
+
+ //
+ // TODO: OPTIMIZATION: Use a map with the object as a key.
+ //
+
+ list<WaitItemPtr>::iterator p = _waitQueue.begin();
+ while(p != _waitQueue.end())
+ {
+ if((*p)->isWaitingOn(object))
+ {
+ _workQueue.push_back(*p);
+ p = _waitQueue.erase(p);
+ }
+ else
+ {
+ ++p;
+ }
+ }
+
+ if(!_workQueue.empty())
+ {
+ notify();
+ }
+}
diff --git a/cpp/src/IceGrid/WaitQueue.h b/cpp/src/IceGrid/WaitQueue.h
new file mode 100644
index 00000000000..f463c8051c2
--- /dev/null
+++ b/cpp/src/IceGrid/WaitQueue.h
@@ -0,0 +1,67 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 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 ICE_GRID_WAIT_QUEUE_H
+#define ICE_GRID_WAIT_QUEUE_H
+
+#include <IceUtil/Thread.h>
+
+#include <list>
+
+namespace IceGrid
+{
+
+class WaitItem : public ::IceUtil::SimpleShared
+{
+public:
+
+ WaitItem(const Ice::ObjectPtr&);
+ virtual ~WaitItem();
+
+ virtual void execute() = 0;
+ virtual void expired(bool) = 0;
+
+ bool isWaitingOn(const Ice::ObjectPtr& obj) { return obj == _object; }
+
+ const IceUtil::Time& getExpirationTime();
+ void setExpirationTime(const IceUtil::Time&);
+
+private:
+
+ Ice::ObjectPtr _object;
+ IceUtil::Time _expiration;
+};
+
+typedef IceUtil::Handle<WaitItem> WaitItemPtr;
+
+class WaitQueue : public IceUtil::Thread, public IceUtil::Monitor< IceUtil::Mutex>
+{
+public:
+
+ WaitQueue();
+
+ virtual void run();
+ void destroy();
+
+ void add(const WaitItemPtr&, const IceUtil::Time&);
+
+ void notifyAllWaitingOn(const Ice::ObjectPtr&);
+
+private:
+
+ std::list<WaitItemPtr> _waitQueue;
+ std::list<WaitItemPtr> _workQueue;
+ bool _destroyed;
+};
+
+typedef IceUtil::Handle<WaitQueue> WaitQueuePtr;
+
+}
+
+#endif
diff --git a/cpp/src/IceGrid/dummy1.ice b/cpp/src/IceGrid/dummy1.ice
new file mode 100755
index 00000000000..5b12cf78938
--- /dev/null
+++ b/cpp/src/IceGrid/dummy1.ice
@@ -0,0 +1,3 @@
+//
+// This file is necessary to compile IdentityObjectDescDict under msdev.
+//
diff --git a/cpp/src/IceGrid/dummy2.ice b/cpp/src/IceGrid/dummy2.ice
new file mode 100755
index 00000000000..2e6d4088952
--- /dev/null
+++ b/cpp/src/IceGrid/dummy2.ice
@@ -0,0 +1,3 @@
+//
+// This file is necessary to compile StringObjectProxyDict under msdev.
+//
diff --git a/cpp/src/IceGrid/dummy3.ice b/cpp/src/IceGrid/dummy3.ice
new file mode 100755
index 00000000000..46a7ad0cb73
--- /dev/null
+++ b/cpp/src/IceGrid/dummy3.ice
@@ -0,0 +1,3 @@
+//
+// This file is necessary to compile StringObjectProxySeqDict under msdev.
+//
diff --git a/cpp/src/IceGrid/dummy4.ice b/cpp/src/IceGrid/dummy4.ice
new file mode 100755
index 00000000000..c6622a8c14d
--- /dev/null
+++ b/cpp/src/IceGrid/dummy4.ice
@@ -0,0 +1,3 @@
+//
+// This file is necessary to compile StringStringSeqDict under msdev.
+//
diff --git a/cpp/src/IceGrid/dummy5.ice b/cpp/src/IceGrid/dummy5.ice
new file mode 100755
index 00000000000..90fb6893379
--- /dev/null
+++ b/cpp/src/IceGrid/dummy5.ice
@@ -0,0 +1,3 @@
+//
+// This file is necessary to compile StringServerDescriptorDict under msdev.
+//
diff --git a/cpp/src/IceGrid/icegrid.dsp b/cpp/src/IceGrid/icegrid.dsp
new file mode 100644
index 00000000000..085438c8931
--- /dev/null
+++ b/cpp/src/IceGrid/icegrid.dsp
@@ -0,0 +1,270 @@
+# Microsoft Developer Studio Project File - Name="icegrid" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=icegrid - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "icegrid.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "icegrid.mak" CFG="icegrid - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "icegrid - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "icegrid - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "icegrid - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBRARY_EXPORTS" /Yu"stdafx.h" /FD /c
+# ADD CPP /nologo /MD /W3 /WX /GR /GX /O2 /I ".." /I "../../include" /D "_USRDLL" /D "ICE_GRID_API_EXPORTS" /D "NDEBUG" /D "_CONSOLE" /FD /c
+# SUBTRACT CPP /Fr /YX
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 /nologo /dll /incremental:yes /machine:I386 /out:"Release/icegrid21.dll" /implib:"Release/icegrid.lib"
+# SUBTRACT LINK32 /pdb:none /debug /nodefaultlib
+# Begin Special Build Tool
+OutDir=.\Release
+SOURCE="$(InputPath)"
+PostBuild_Cmds=copy $(OutDir)\icegrid.lib ..\..\lib copy $(OutDir)\icegrid21.dll ..\..\bin
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "icegrid - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBRARY_EXPORTS" /Yu"stdafx.h" /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /WX /Gm /GR /GX /Zi /Od /I ".." /I "../../include" /D "_USRDLL" /D "ICE_GRID_API_EXPORTS" /D "_DEBUG" /D "_CONSOLE" /FD /GZ /c
+# SUBTRACT CPP /Fr /YX
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386
+# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Debug/icegrid21d.dll" /implib:"Debug/icegridd.lib"
+# SUBTRACT LINK32 /pdb:none /incremental:no /nodefaultlib
+# Begin Special Build Tool
+OutDir=.\Debug
+SOURCE="$(InputPath)"
+PostBuild_Cmds=copy $(OutDir)\icegridd.lib ..\..\lib copy $(OutDir)\icegrid21d.pdb ..\..\bin copy $(OutDir)\icegrid21d.dll ..\..\bin
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "icegrid - Win32 Release"
+# Name "icegrid - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\Admin.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Exception.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Query.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=..\..\include\icegrid\Admin.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\icegrid\Exception.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\icegrid\Query.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=..\..\slice\icegrid\Admin.ice
+
+!IF "$(CFG)" == "icegrid - Win32 Release"
+
+USERDEP__ADMIN="..\..\bin\slice2cpp.exe" "..\..\lib\slice.lib"
+# Begin Custom Build
+InputPath=..\..\slice\icegrid\Admin.ice
+
+BuildCmds= \
+ ..\..\bin\slice2cpp.exe --ice --checksum --dll-export ICE_GRID_API --include-dir icegrid -I../../slice ../../slice/IceGrid/Admin.ice \
+ move Admin.h ..\..\include\icegrid \
+
+
+"..\..\include\icegrid\Admin.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"Admin.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "icegrid - Win32 Debug"
+
+USERDEP__ADMIN="..\..\bin\slice2cpp.exe" "..\..\lib\sliced.lib"
+# Begin Custom Build
+InputPath=..\..\slice\icegrid\Admin.ice
+
+BuildCmds= \
+ ..\..\bin\slice2cpp.exe --ice --checksum --dll-export ICE_GRID_API --include-dir icegrid -I../../slice ../../slice/IceGrid/Admin.ice \
+ move Admin.h ..\..\include\icegrid \
+
+
+"..\..\include\icegrid\Admin.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"Admin.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\slice\icegrid\Exception.ice
+
+!IF "$(CFG)" == "icegrid - Win32 Release"
+
+USERDEP__EXCEP="..\..\bin\slice2cpp.exe" "..\..\lib\slice.lib"
+# Begin Custom Build
+InputPath=..\..\slice\icegrid\Exception.ice
+
+BuildCmds= \
+ ..\..\bin\slice2cpp.exe --ice --checksum --dll-export ICE_GRID_API --include-dir icegrid -I../../slice ../../slice/IceGrid/Exception.ice \
+ move Exception.h ..\..\include\icegrid \
+
+
+"..\..\include\icegrid\Exception.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"Exception.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "icegrid - Win32 Debug"
+
+USERDEP__EXCEP="..\..\bin\slice2cpp.exe" "..\..\lib\sliced.lib"
+# Begin Custom Build
+InputPath=..\..\slice\icegrid\Exception.ice
+
+BuildCmds= \
+ ..\..\bin\slice2cpp.exe --ice --checksum --dll-export ICE_GRID_API --include-dir icegrid -I../../slice ../../slice/IceGrid/Exception.ice \
+ move Exception.h ..\..\include\icegrid \
+
+
+"..\..\include\icegrid\Exception.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"Exception.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\slice\icegrid\Query.ice
+
+!IF "$(CFG)" == "icegrid - Win32 Release"
+
+USERDEP__QUERY="..\..\bin\slice2cpp.exe" "..\..\lib\slice.lib"
+# Begin Custom Build
+InputPath=..\..\slice\icegrid\Query.ice
+
+BuildCmds= \
+ ..\..\bin\slice2cpp.exe --ice --checksum --dll-export ICE_GRID_API --include-dir icegrid -I../../slice ../../slice/IceGrid/Query.ice \
+ move Query.h ..\..\include\icegrid \
+
+
+"..\..\include\icegrid\Query.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"Query.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "icegrid - Win32 Debug"
+
+USERDEP__QUERY="..\..\bin\slice2cpp.exe" "..\..\lib\sliced.lib"
+# Begin Custom Build
+InputPath=..\..\slice\icegrid\Query.ice
+
+BuildCmds= \
+ ..\..\bin\slice2cpp.exe --ice --checksum --dll-export ICE_GRID_API --include-dir icegrid -I../../slice ../../slice/IceGrid/Query.ice \
+ move Query.h ..\..\include\icegrid \
+
+
+"..\..\include\icegrid\Query.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"Query.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/cpp/src/IceGrid/icegridC.dsp b/cpp/src/IceGrid/icegridC.dsp
new file mode 100644
index 00000000000..5c04c18896e
--- /dev/null
+++ b/cpp/src/IceGrid/icegridC.dsp
@@ -0,0 +1,224 @@
+# Microsoft Developer Studio Project File - Name="icegridC" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=icegridC - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "icegridC.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "icegridC.mak" CFG="icegridC - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "icegridC - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "icegridC - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "icegridC - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /WX /GR /GX /O2 /I ".." /I "../../include" /I "dummyinclude" /D "NDEBUG" /D "_CONSOLE" /FD /c
+# SUBTRACT CPP /Fr /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 setargv.obj /nologo /subsystem:console /incremental:yes /machine:I386 /out:"Release/icegridadmin.exe" /libpath:"../../../lib"
+# SUBTRACT LINK32 /debug /nodefaultlib
+# Begin Special Build Tool
+OutDir=.\Release
+TargetName=icegridadmin
+SOURCE="$(InputPath)"
+PostBuild_Cmds=copy $(OutDir)\$(TargetName).exe ..\..\bin
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "icegridC - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /WX /Gm /GR /GX /Zi /Od /I ".." /I "../../include" /I "dummyinclude" /D "_DEBUG" /D "_CONSOLE" /FD /GZ /c
+# SUBTRACT CPP /Fr /YX
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 setargv.obj /nologo /subsystem:console /debug /machine:I386 /out:"Debug/icegridadmin.exe" /pdbtype:sept /libpath:"../../../lib"
+# SUBTRACT LINK32 /incremental:no /nodefaultlib
+# Begin Special Build Tool
+OutDir=.\Debug
+TargetName=icegridadmin
+SOURCE="$(InputPath)"
+PostBuild_Cmds=copy $(OutDir)\$(TargetName).exe ..\..\bin
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "icegridC - Win32 Release"
+# Name "icegridC - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\Client.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\DescriptorParser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\DescriptorUtil.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\DescriptorVisitor.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Grammar.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Parser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Scanner.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\Grammar.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Parser.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=.\Grammar.y
+
+!IF "$(CFG)" == "icegridC - Win32 Release"
+
+# Begin Custom Build
+InputPath=.\Grammar.y
+
+BuildCmds= \
+ bison -dvt Grammar.y \
+ move Grammar.tab.c Grammar.cpp \
+ move Grammar.tab.h Grammar.h \
+
+
+"Grammar.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"Grammar.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "icegridC - Win32 Debug"
+
+# Begin Custom Build
+InputPath=.\Grammar.y
+
+BuildCmds= \
+ bison -dvt Grammar.y \
+ move Grammar.tab.c Grammar.cpp \
+ move Grammar.tab.h Grammar.h \
+
+
+"Grammar.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"Grammar.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\Scanner.l
+
+!IF "$(CFG)" == "icegridC - Win32 Release"
+
+# Begin Custom Build
+InputPath=.\Scanner.l
+
+"Scanner.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ flex Scanner.l
+ echo #include "IceUtil/Config.h" > Scanner.cpp
+ type lex.yy.c >> Scanner.cpp
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "icegridC - Win32 Debug"
+
+# Begin Custom Build
+InputPath=.\Scanner.l
+
+"Scanner.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ flex Scanner.l
+ echo #include "IceUtil/Config.h" > Scanner.cpp
+ type lex.yy.c >> Scanner.cpp
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/cpp/src/IceGrid/icegridnode.dsp b/cpp/src/IceGrid/icegridnode.dsp
new file mode 100755
index 00000000000..0779e56d153
--- /dev/null
+++ b/cpp/src/IceGrid/icegridnode.dsp
@@ -0,0 +1,579 @@
+# Microsoft Developer Studio Project File - Name="icegridnode" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=icegridnode - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "icegridnode.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "icegridnode.mak" CFG="icegridnode - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "icegridnode - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "icegridnode - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "icegridnode - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /WX /GR /GX /O2 /I ".." /I "../../include" /I "dummyinclude" /D "NDEBUG" /D "_CONSOLE" /FD /c
+# SUBTRACT CPP /Fr /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 ws2_32.lib setargv.obj /nologo /subsystem:console /incremental:yes /machine:I386 /libpath:"../../../lib"
+# SUBTRACT LINK32 /debug /nodefaultlib
+# Begin Special Build Tool
+OutDir=.\Release
+TargetName=icegridnode
+SOURCE="$(InputPath)"
+PostBuild_Cmds=copy $(OutDir)\$(TargetName).exe ..\..\bin
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "icegridnode - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /WX /Gm /GR /GX /Zi /Od /I ".." /I "../../include" /I "dummyinclude" /D "_DEBUG" /D "_CONSOLE" /FD /GZ /c
+# SUBTRACT CPP /Fr /YX
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ws2_32.lib setargv.obj /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"../../../lib"
+# SUBTRACT LINK32 /incremental:no /nodefaultlib
+# Begin Special Build Tool
+OutDir=.\Debug
+TargetName=icegridnode
+SOURCE="$(InputPath)"
+PostBuild_Cmds=copy $(OutDir)\$(TargetName).exe ..\..\bin
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "icegridnode - Win32 Release"
+# Name "icegridnode - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\Activator.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\AdapterFactory.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\AdapterI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\AdapterRegistryI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\AdminI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ApplicationRegistryI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\DescriptorParser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\DescriptorUtil.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\DescriptorVisitor.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\icegridnode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\IdentityObjectDescDict.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Internal.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LocatorI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LocatorRegistryI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\NodeI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\NodeRegistryI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ObjectRegistryI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\QueryI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Registry.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ServerAdapterI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ServerFactory.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ServerI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ServerRegistryI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\StringObjectProxyDict.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\StringObjectProxySeqDict.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\StringServerDescriptorDict.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\StringStringSeqDict.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\TraceLevels.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\WaitQueue.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\Activator.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ActivatorI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\AdapterFactory.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\AdapterI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\AdapterRegistryI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\AdminI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ApplicationBuilder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ComponentBuilder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\IdentityObjectDescDict.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Internal.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LocatorI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LocatorRegistryI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NodeI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NodeInfo.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NodeRegistryI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ObjectRegistryI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\QueryI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Registry.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ServerAdapterI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ServerBuilder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ServerDeployerI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ServerFactory.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ServerI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ServerRegistryI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ServiceBuilder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\StringObjectProxyDict.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\StringObjectProxySeqDict.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\TraceLevels.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\WaitQueue.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=.\dummy1.ice
+
+!IF "$(CFG)" == "icegridnode - Win32 Release"
+
+USERDEP__DUMMY="..\..\bin\slice2freeze.exe" "..\..\lib\slice.lib"
+# Begin Custom Build
+InputPath=.\dummy1.ice
+
+BuildCmds= \
+ ..\..\bin\slice2freeze.exe --ice --include-dir IceGrid -I../../slice -I.. --dict IceGrid::IdentityObjectDescDict,Ice::Identity,IceGrid::ObjectDescriptor IdentityObjectDescDict ../../slice/Ice/Identity.ice ../IceGrid/Internal.ice
+
+"IdentityObjectDescDict.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"IdentityObjectDescDict.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "icegridnode - Win32 Debug"
+
+USERDEP__DUMMY="..\..\bin\slice2freeze.exe" "..\..\lib\sliced.lib"
+# Begin Custom Build
+InputPath=.\dummy1.ice
+
+BuildCmds= \
+ ..\..\bin\slice2freeze.exe --ice --include-dir IceGrid -I../../slice -I.. --dict IceGrid::IdentityObjectDescDict,Ice::Identity,IceGrid::ObjectDescriptor IdentityObjectDescDict ../../slice/Ice/Identity.ice ../IceGrid/Internal.ice
+
+"IdentityObjectDescDict.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"IdentityObjectDescDict.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\dummy2.ice
+
+!IF "$(CFG)" == "icegridnode - Win32 Release"
+
+# Begin Custom Build
+InputPath=.\dummy2.ice
+
+BuildCmds= \
+ ..\..\bin\slice2freeze.exe --include-dir IceGrid --dict "IceGrid::StringObjectProxyDict,string,Object*" StringObjectProxyDict
+
+"StringObjectProxyDict.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"StringObjectProxyDict.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "icegridnode - Win32 Debug"
+
+USERDEP__DUMMY2="..\..\bin\slice2freeze.exe" "..\..\lib\sliced.lib"
+# Begin Custom Build
+InputPath=.\dummy2.ice
+
+BuildCmds= \
+ ..\..\bin\slice2freeze.exe --include-dir IceGrid --dict "IceGrid::StringObjectProxyDict,string,Object*" StringObjectProxyDict
+
+"StringObjectProxyDict.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"StringObjectProxyDict.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\dummy3.ice
+
+!IF "$(CFG)" == "icegridnode - Win32 Release"
+
+USERDEP__DUMMY3="..\..\bin\slice2freeze.exe" "..\..\lib\slice.lib"
+# Begin Custom Build
+InputPath=.\dummy3.ice
+
+BuildCmds= \
+ ..\..\bin\slice2freeze.exe --ice --include-dir IceGrid -I../../slice --dict IceGrid::StringObjectProxySeqDict,string,Ice::ObjectProxySeq StringObjectProxySeqDict ../../slice/Ice/BuiltinSequences.ice
+
+"StringObjectProxySeqDict.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"StringObjectProxySeqDict.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "icegridnode - Win32 Debug"
+
+USERDEP__DUMMY3="..\..\bin\slice2freeze.exe" "..\..\lib\sliced.lib"
+# Begin Custom Build
+InputPath=.\dummy3.ice
+
+BuildCmds= \
+ ..\..\bin\slice2freeze.exe --ice --include-dir IceGrid -I../../slice --dict IceGrid::StringObjectProxySeqDict,string,Ice::ObjectProxySeq StringObjectProxySeqDict ../../slice/Ice/BuiltinSequences.ice
+
+"StringObjectProxySeqDict.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"StringObjectProxySeqDict.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\dummy4.ice
+
+!IF "$(CFG)" == "icegridnode - Win32 Release"
+
+USERDEP__DUMMY4="..\..\bin\slice2freeze.exe" "..\..\lib\slice.lib"
+# Begin Custom Build
+InputPath=.\dummy4.ice
+
+BuildCmds= \
+ ..\..\bin\slice2freeze.exe --ice --include-dir IceGrid -I../../slice --dict IceGrid::StringStringSeqDict,string,Ice::StringSeq StringStringSeqDict ../../slice/Ice/BuiltinSequences.ice
+
+"StringStringSeqDict.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"StringStringSeqDict.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "icegridnode - Win32 Debug"
+
+USERDEP__DUMMY4="..\..\bin\slice2freeze.exe" "..\..\lib\sliced.lib"
+# Begin Custom Build
+InputPath=.\dummy4.ice
+
+BuildCmds= \
+ ..\..\bin\slice2freeze.exe --ice --include-dir IceGrid -I../../slice --dict IceGrid::StringStringSeqDict,string,Ice::StringSeq StringStringSeqDict ../../slice/Ice/BuiltinSequences.ice
+
+"StringStringSeqDict.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"StringStringSeqDict.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\dummy5.ice
+
+!IF "$(CFG)" == "icegridnode - Win32 Release"
+
+USERDEP__DUMMY5="..\..\bin\slice2freeze.exe" "..\..\lib\slice.lib"
+# Begin Custom Build
+InputPath=.\dummy5.ice
+
+BuildCmds= \
+ ..\..\bin\slice2freeze.exe --ice --include-dir IceGrid -I../../slice --dict IceGrid::StringServerDescriptorDict,string,IceGrid::ServerDescriptor StringServerDescriptorDict ../../slice/IceGrid/Admin.ice
+
+"StringServerDescriptorDict.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"StringServerDescriptorDict.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "icegridnode - Win32 Debug"
+
+USERDEP__DUMMY5="..\..\bin\slice2freeze.exe" "..\..\lib\sliced.lib"
+# Begin Custom Build
+InputPath=.\dummy5.ice
+
+BuildCmds= \
+ ..\..\bin\slice2freeze.exe --ice --include-dir IceGrid -I../../slice --dict IceGrid::StringServerDescriptorDict,string,IceGrid::ServerDescriptor StringServerDescriptorDict ../../slice/IceGrid/Admin.ice
+
+"StringServerDescriptorDict.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"StringServerDescriptorDict.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\Internal.ice
+
+!IF "$(CFG)" == "icegridnode - Win32 Release"
+
+USERDEP__INTER="..\..\bin\slice2cpp.exe" "..\..\lib\slice.lib"
+# Begin Custom Build
+InputPath=.\Internal.ice
+
+BuildCmds= \
+ ..\..\bin\slice2cpp.exe --ice --include-dir IceGrid -I../../slice Internal.ice
+
+"Internal.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"Internal.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "icegridnode - Win32 Debug"
+
+USERDEP__INTER="..\..\bin\slice2cpp.exe" "..\..\lib\sliced.lib"
+# Begin Custom Build
+InputPath=.\Internal.ice
+
+BuildCmds= \
+ ..\..\bin\slice2cpp.exe --ice --include-dir IceGrid -I../../slice Internal.ice
+
+"Internal.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"Internal.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/cpp/src/IceGrid/icegridregistry.dsp b/cpp/src/IceGrid/icegridregistry.dsp
new file mode 100755
index 00000000000..86dd7dc03b7
--- /dev/null
+++ b/cpp/src/IceGrid/icegridregistry.dsp
@@ -0,0 +1,430 @@
+# Microsoft Developer Studio Project File - Name="icegridregistry" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=icegridregistry - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "icegridRegistry.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "icegridRegistry.mak" CFG="icegridregistry - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "icegridregistry - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "icegridregistry - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "icegridregistry - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /WX /GR /GX /O2 /I ".." /I "../../include" /I "dummyinclude" /D "NDEBUG" /D "_CONSOLE" /FD /c
+# SUBTRACT CPP /Fr /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 setargv.obj /nologo /subsystem:console /incremental:yes /machine:I386 /libpath:"../../../lib"
+# SUBTRACT LINK32 /debug /nodefaultlib
+# Begin Special Build Tool
+OutDir=.\Release
+TargetName=icegridRegistry
+SOURCE="$(InputPath)"
+PostBuild_Cmds=copy $(OutDir)\$(TargetName).exe ..\..\bin
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "icegridregistry - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /WX /Gm /GR /GX /Zi /Od /I ".." /I "../../include" /I "dummyinclude" /D "_DEBUG" /D "_CONSOLE" /FD /GZ /c
+# SUBTRACT CPP /Fr /YX
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 setargv.obj /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"../../../lib"
+# SUBTRACT LINK32 /incremental:no /nodefaultlib
+# Begin Special Build Tool
+OutDir=.\Debug
+TargetName=icegridRegistry
+SOURCE="$(InputPath)"
+PostBuild_Cmds=copy $(OutDir)\$(TargetName).exe ..\..\bin
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "icegridregistry - Win32 Release"
+# Name "icegridregistry - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\AdapterFactory.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\AdapterI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\AdapterRegistryI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\AdminI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ApplicationRegistryI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\DescriptorUtil.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\DescriptorVisitor.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\icegridregistry.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\IdentityObjectDescDict.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Internal.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LocatorI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LocatorRegistryI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\NodeRegistryI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ObjectRegistryI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\QueryI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Registry.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ServerRegistryI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\StringObjectProxyDict.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\StringObjectProxySeqDict.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\StringServerDescriptorDict.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\StringStringSeqDict.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\TraceLevels.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\AdapterFactory.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\AdapterI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\AdapterRegistryI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\AdminI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ApplicationBuilder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ComponentBuilder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\IdentityObjectDescDict.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Internal.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LocatorI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LocatorRegistryI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NodeRegistryI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ObjectRegistryI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\QueryI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Registry.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ServerRegistryI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\StringObjectProxyDict.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\StringObjectProxySeqDict.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\TraceLevels.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=.\dummy1.ice
+
+!IF "$(CFG)" == "icegridregistry - Win32 Release"
+
+USERDEP__DUMMY="..\..\bin\slice2freeze.exe" "..\..\lib\slice.lib"
+# Begin Custom Build
+InputPath=.\dummy1.ice
+
+BuildCmds= \
+ ..\..\bin\slice2freeze.exe --ice --include-dir IceGrid -I../../slice -I.. --dict IceGrid::IdentityObjectDescDict,Ice::Identity,IceGrid::ObjectDescriptor IdentityObjectDescDict ../../slice/Ice/Identity.ice ../IceGrid/Internal.ice
+
+"IdentityObjectDescDict.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"IdentityObjectDescDict.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "icegridregistry - Win32 Debug"
+
+USERDEP__DUMMY="..\..\bin\slice2freeze.exe" "..\..\lib\sliced.lib"
+# Begin Custom Build
+InputPath=.\dummy1.ice
+
+BuildCmds= \
+ ..\..\bin\slice2freeze.exe --ice --include-dir IceGrid -I../../slice -I.. --dict IceGrid::IdentityObjectDescDict,Ice::Identity,IceGrid::ObjectDescriptor IdentityObjectDescDict ../../slice/Ice/Identity.ice ../IceGrid/Internal.ice
+
+"IdentityObjectDescDict.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"IdentityObjectDescDict.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\dummy2.ice
+
+!IF "$(CFG)" == "icegridregistry - Win32 Release"
+
+USERDEP__DUMMY2="..\..\bin\slice2freeze.exe" "..\..\lib\slice.lib"
+# Begin Custom Build
+InputPath=.\dummy2.ice
+
+BuildCmds= \
+ ..\..\bin\slice2freeze.exe --include-dir IceGrid --dict "IceGrid::StringObjectProxyDict,string,Object*" StringObjectProxyDict
+
+"StringObjectProxyDict.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"StringObjectProxyDict.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "icegridregistry - Win32 Debug"
+
+USERDEP__DUMMY2="..\..\bin\slice2freeze.exe" "..\..\lib\sliced.lib"
+# Begin Custom Build
+InputPath=.\dummy2.ice
+
+BuildCmds= \
+ ..\..\bin\slice2freeze.exe --include-dir IceGrid --dict "IceGrid::StringObjectProxyDict,string,Object*" StringObjectProxyDict
+
+"StringObjectProxyDict.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"StringObjectProxyDict.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\dummy3.ice
+
+!IF "$(CFG)" == "icegridregistry - Win32 Release"
+
+USERDEP__DUMMY3="..\..\bin\slice2freeze.exe" "..\..\lib\slice.lib"
+# Begin Custom Build
+InputPath=.\dummy3.ice
+
+BuildCmds= \
+ ..\..\bin\slice2freeze.exe --ice --include-dir IceGrid -I../../slice --dict IceGrid::StringObjectProxySeqDict,string,Ice::ObjectProxySeq StringObjectProxySeqDict ../../slice/Ice/BuiltinSequences.ice
+
+"StringObjectProxySeqDict.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"StringObjectProxySeqDict.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "icegridregistry - Win32 Debug"
+
+USERDEP__DUMMY3="..\..\bin\slice2freeze.exe" "..\..\lib\sliced.lib"
+# Begin Custom Build
+InputPath=.\dummy3.ice
+
+BuildCmds= \
+ ..\..\bin\slice2freeze.exe --ice --include-dir IceGrid -I../../slice --dict IceGrid::StringObjectProxySeqDict,string,Ice::ObjectProxySeq StringObjectProxySeqDict ../../slice/Ice/BuiltinSequences.ice
+
+"StringObjectProxySeqDict.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"StringObjectProxySeqDict.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\Internal.ice
+
+!IF "$(CFG)" == "icegridregistry - Win32 Release"
+
+USERDEP__INTER="..\..\bin\slice2cpp.exe" "..\..\lib\slice.lib"
+# Begin Custom Build
+InputPath=.\Internal.ice
+
+BuildCmds= \
+ ..\..\bin\slice2cpp.exe --ice --include-dir IceGrid -I../../slice -I.. Internal.ice
+
+".\Internal.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"Internal.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "icegridregistry - Win32 Debug"
+
+USERDEP__INTER="..\..\bin\slice2cpp.exe" "..\..\lib\sliced.lib"
+# Begin Custom Build
+InputPath=.\Internal.ice
+
+BuildCmds= \
+ ..\..\bin\slice2cpp.exe --ice --include-dir IceGrid -I../../slice -I.. Internal.ice
+
+".\Internal.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"Internal.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# End Group
+# End Target
+# End Project