summaryrefslogtreecommitdiff
path: root/cpp/src/IceGrid/ServerFactory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/IceGrid/ServerFactory.cpp')
-rw-r--r--cpp/src/IceGrid/ServerFactory.cpp384
1 files changed, 384 insertions, 0 deletions
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);
+ }
+}
+