summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
authorBenoit Foucher <benoit@zeroc.com>2002-07-22 18:27:40 +0000
committerBenoit Foucher <benoit@zeroc.com>2002-07-22 18:27:40 +0000
commitf8ad6db815b1584bd55b8e56c2e8d1bd5cc66279 (patch)
tree394a626cf81c18d96d8c3efa9da325133080ff14 /cpp/src
parentFixed null dereference caused by silly typo in exception action. (diff)
downloadice-f8ad6db815b1584bd55b8e56c2e8d1bd5cc66279.tar.bz2
ice-f8ad6db815b1584bd55b8e56c2e8d1bd5cc66279.tar.xz
ice-f8ad6db815b1584bd55b8e56c2e8d1bd5cc66279.zip
Initial IcePack deployment implementation.
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/IcePack/ActivatorI.cpp15
-rw-r--r--cpp/src/IcePack/ActivatorI.h3
-rw-r--r--cpp/src/IcePack/AdminI.cpp5
-rw-r--r--cpp/src/IcePack/AdminI.h3
-rw-r--r--cpp/src/IcePack/ComponentDeployer.cpp496
-rw-r--r--cpp/src/IcePack/ComponentDeployer.h121
-rw-r--r--cpp/src/IcePack/Makefile9
-rw-r--r--cpp/src/IcePack/Parser.cpp17
-rw-r--r--cpp/src/IcePack/Server.cpp27
-rw-r--r--cpp/src/IcePack/ServerDeployer.cpp354
-rw-r--r--cpp/src/IcePack/ServerDeployer.h63
-rw-r--r--cpp/src/IcePack/ServerManager.ice11
-rw-r--r--cpp/src/IcePack/ServerManagerI.cpp94
-rw-r--r--cpp/src/IcePack/ServerManagerI.h14
-rw-r--r--cpp/src/IcePack/ServiceDeployer.cpp139
-rw-r--r--cpp/src/IcePack/ServiceDeployer.h51
16 files changed, 1322 insertions, 100 deletions
diff --git a/cpp/src/IcePack/ActivatorI.cpp b/cpp/src/IcePack/ActivatorI.cpp
index 0260d459550..dd11db49854 100644
--- a/cpp/src/IcePack/ActivatorI.cpp
+++ b/cpp/src/IcePack/ActivatorI.cpp
@@ -22,10 +22,9 @@ using namespace std;
using namespace Ice;
using namespace IcePack;
-IcePack::ActivatorI::ActivatorI(const CommunicatorPtr& communicator, const vector<string>& defaultArgs) :
+IcePack::ActivatorI::ActivatorI(const CommunicatorPtr& communicator) :
_communicator(communicator),
- _destroy(false),
- _defaultArgs(defaultArgs)
+ _destroy(false)
{
int fds[2];
if(pipe(fds) != 0)
@@ -212,7 +211,7 @@ IcePack::ActivatorI::activate(const ServerPrx& server, const ::Ice::Current&)
//
// Compute arguments.
//
- int argc = desc.args.size() + _defaultArgs.size() + 3;
+ int argc = desc.args.size() + 2;
char** argv = static_cast<char**>(malloc(argc * sizeof(char*)));
argv[0] = strdup(path.c_str());
unsigned int i = 0;
@@ -221,14 +220,6 @@ IcePack::ActivatorI::activate(const ServerPrx& server, const ::Ice::Current&)
{
argv[i + 1] = strdup(q->c_str());
}
- for(q = _defaultArgs.begin(); q != _defaultArgs.end(); ++q, ++i)
- {
- argv[i + 1] = strdup(q->c_str());
- }
-
- string serverName = "--Ice.ProgramName=" + desc.name;
- argv[argc - 2] = strdup(serverName.c_str());
-
argv[argc - 1] = 0;
if(execvp(argv[0], argv) == -1)
diff --git a/cpp/src/IcePack/ActivatorI.h b/cpp/src/IcePack/ActivatorI.h
index 892b2bf3a60..bc5064d02c2 100644
--- a/cpp/src/IcePack/ActivatorI.h
+++ b/cpp/src/IcePack/ActivatorI.h
@@ -22,7 +22,7 @@ class ActivatorI : public Activator, public IceUtil::Thread, public IceUtil::Mut
{
public:
- ActivatorI(const Ice::CommunicatorPtr&, const std::vector<std::string>&);
+ ActivatorI(const Ice::CommunicatorPtr&);
virtual ~ActivatorI();
virtual void run();
@@ -48,7 +48,6 @@ private:
bool _destroy;
int _fdIntrRead;
int _fdIntrWrite;
- std::vector<std::string> _defaultArgs;
};
typedef IceUtil::Handle<ActivatorI> ActivatorIPtr;
diff --git a/cpp/src/IcePack/AdminI.cpp b/cpp/src/IcePack/AdminI.cpp
index 6892e30ab5f..7a47b2f9985 100644
--- a/cpp/src/IcePack/AdminI.cpp
+++ b/cpp/src/IcePack/AdminI.cpp
@@ -26,9 +26,10 @@ IcePack::AdminI::AdminI(const CommunicatorPtr& communicator, const ServerManager
}
void
-IcePack::AdminI::addServer(const ServerDescription& desc, const Current&)
+IcePack::AdminI::addServer(const string& name, const string& path, const string& ldpath, const string& descriptor,
+ const Current&)
{
- _serverManager->create(desc);
+ _serverManager->create(name, path, ldpath, descriptor);
}
ServerDescription
diff --git a/cpp/src/IcePack/AdminI.h b/cpp/src/IcePack/AdminI.h
index 8cef398e1ca..972be3afde4 100644
--- a/cpp/src/IcePack/AdminI.h
+++ b/cpp/src/IcePack/AdminI.h
@@ -24,7 +24,8 @@ public:
AdminI(const Ice::CommunicatorPtr&, const ServerManagerPrx&, const AdapterManagerPrx&);
- virtual void addServer(const ServerDescription&, const Ice::Current&);
+ virtual void addServer(const std::string&, const std::string&, const std::string&, const std::string&,
+ const Ice::Current&);
virtual ServerDescription getServerDescription(const ::std::string&, const Ice::Current&);
virtual ServerState getServerState(const ::std::string&, const Ice::Current&);
virtual bool startServer(const ::std::string&, const Ice::Current&);
diff --git a/cpp/src/IcePack/ComponentDeployer.cpp b/cpp/src/IcePack/ComponentDeployer.cpp
new file mode 100644
index 00000000000..ca429de68de
--- /dev/null
+++ b/cpp/src/IcePack/ComponentDeployer.cpp
@@ -0,0 +1,496 @@
+// **********************************************************************
+//
+// Copyright (c) 2001
+// Mutable Realms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <Ice/Ice.h>
+
+#include <IcePack/ComponentDeployer.h>
+#include <IcePack/Admin.h>
+
+#include <Yellow/Yellow.h>
+
+#include <parsers/SAXParser.hpp>
+#include <sax/HandlerBase.hpp>
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <stack>
+#include <iterator>
+#include <fstream>
+
+using namespace std;
+using namespace IcePack;
+
+void IcePack::incRef(Task* p) { p->__incRef(); }
+void IcePack::decRef(Task* p) { p->__decRef(); }
+
+namespace IcePack
+{
+
+static string
+toString(const XMLCh* ch)
+{
+ char* t = XMLString::transcode(ch);
+ string s(t);
+ delete[] t;
+ return s;
+}
+
+//
+// Create a directory.
+//
+class CreateDirectory : public Task
+{
+public:
+
+ CreateDirectory(const string& name)
+ : _name(name)
+ {
+ }
+
+ virtual void
+ deploy()
+ {
+ if(mkdir(_name.c_str(), 0755) != 0)
+ {
+ cerr << "Can't create directory: " << _name << endl;
+
+ Ice::SystemException ex(__FILE__, __LINE__);
+ ex.error = getSystemErrno();
+ throw ex;
+ }
+ }
+
+ virtual void
+ undeploy()
+ {
+ if(rmdir(_name.c_str()) != 0)
+ {
+ cerr << "Can't remove directory: " << _name << endl;
+
+ Ice::SystemException ex(__FILE__, __LINE__);
+ ex.error = getSystemErrno();
+ throw ex;
+ }
+ }
+
+private:
+
+ string _name;
+};
+
+//
+// Generate a configuration file from a property set.
+//
+class GenerateConfiguration : public Task
+{
+ class WriteConfigProperty : public unary_function<Ice::PropertyDict::value_type, string>
+ {
+ public:
+ string
+ operator()(const Ice::PropertyDict::value_type& p) const
+ {
+ return p.first + "=" + p.second;
+ }
+ };
+
+public:
+
+ GenerateConfiguration(const string& file, const Ice::PropertiesPtr& properties) :
+ _file(file),
+ _properties(properties)
+ {
+ }
+
+ virtual void
+ deploy()
+ {
+ ofstream configfile;
+ configfile.open(_file.c_str(), ios::out);
+ if(!configfile)
+ {
+ cerr << "Can't create configuration file: " << _file << endl;
+ Ice::SystemException ex(__FILE__, __LINE__);
+ throw ex;
+ }
+
+ Ice::PropertyDict props = _properties->getPropertiesForPrefix("");
+ transform(props.begin(), props.end(), ostream_iterator<string>(configfile,"\n"), WriteConfigProperty());
+ configfile.close();
+ }
+
+ virtual void
+ undeploy()
+ {
+ if(unlink(_file.c_str()) != 0)
+ {
+ cerr << "Can't remove configuration file: " << _file << endl;
+
+ Ice::SystemException ex(__FILE__, __LINE__);
+ ex.error = getSystemErrno();
+ throw ex;
+ }
+ }
+
+private:
+
+ string _file;
+ Ice::PropertiesPtr _properties;
+};
+
+//
+// Register an offer with the yellow page service.
+//
+class RegisterOffer : public Task
+{
+public:
+
+ RegisterOffer(const Yellow::AdminPrx& admin, const string& offer, const Ice::ObjectPrx& proxy) :
+ _admin(admin),
+ _offer(offer),
+ _proxy(proxy)
+ {
+ }
+
+ virtual void
+ deploy()
+ {
+ _admin->add(_offer, _proxy);
+ }
+
+ virtual void
+ undeploy()
+ {
+ try
+ {
+ _admin->remove(_offer, _proxy);
+ }
+ catch(const Yellow::NoSuchOfferException&)
+ {
+ //
+ // TODO: The offer doesn't exist anymore so no need to
+ // worry about removing it. We should print a warning
+ // though.
+ //
+ }
+ }
+
+private:
+
+ Yellow::AdminPrx _admin;
+ string _offer;
+ Ice::ObjectPrx _proxy;
+};
+
+}
+
+IcePack::ComponentErrorHandler::ComponentErrorHandler(ComponentDeployer& deployer) :
+ _deployer(deployer)
+{
+}
+
+void
+IcePack::ComponentErrorHandler::warning(const SAXParseException& exception)
+{
+ string s = toString(exception.getMessage());
+ cerr << "warning: " << s << endl;
+}
+
+void
+IcePack::ComponentErrorHandler::error(const SAXParseException& exception)
+{
+ string s = toString(exception.getMessage());
+ cerr << "error: " << s << endl;
+}
+
+void
+IcePack::ComponentErrorHandler::fatalError(const SAXParseException& exception)
+{
+ string s = toString(exception.getMessage());
+ cerr << "fatal:" << s << endl;
+}
+
+void
+IcePack::ComponentErrorHandler::resetErrors()
+{
+}
+
+IcePack::ComponentDeployHandler::ComponentDeployHandler(ComponentDeployer& deployer) :
+ _deployer(deployer)
+{
+}
+
+void
+IcePack::ComponentDeployHandler::characters(const XMLCh *const chars, const unsigned int length)
+{
+ _elements.top().assign(toString(chars));
+}
+
+void
+IcePack::ComponentDeployHandler::startElement(const XMLCh *const name, AttributeList &attrs)
+{
+ _elements.push("");
+
+ string str = toString(name);
+
+ if(str == "property")
+ {
+ _deployer.addProperty(getAttributeValue(attrs, "name"), getAttributeValue(attrs, "value"));
+ }
+}
+
+void
+IcePack::ComponentDeployHandler::endElement(const XMLCh *const name)
+{
+ _elements.pop();
+}
+
+string
+IcePack::ComponentDeployHandler::getAttributeValue(const AttributeList& attrs, const string& name) const
+{
+ XMLCh* n = XMLString::transcode(name.c_str());
+ const XMLCh* value = attrs.getValue(n);
+ delete[] n;
+
+ if(value == 0)
+ {
+ cerr << "Missing attribute '" << name << "'" << endl;
+ return "";
+ }
+
+ return toString(value);
+}
+
+string
+IcePack::ComponentDeployHandler::getAttributeValueWithDefault(const AttributeList& attrs, const string& name,
+ const string& def) const
+{
+ XMLCh* n = XMLString::transcode(name.c_str());
+ const XMLCh* value = attrs.getValue(n);
+ delete[] n;
+
+ if(value == 0)
+ {
+ return def;
+ }
+ else
+ {
+ return toString(value);
+ }
+}
+
+string
+IcePack::ComponentDeployHandler::toString(const XMLCh* ch) const
+{
+ return IcePack::toString(ch);
+}
+
+string
+IcePack::ComponentDeployHandler::elementValue() const
+{
+ return _elements.top();
+}
+
+IcePack::ComponentDeployer::ComponentDeployer(const Ice::CommunicatorPtr& communicator) :
+ _communicator(communicator),
+ _properties(Ice::createProperties())
+{
+ _variables["datadir"] = _communicator->getProperties()->getProperty("IcePack.Data");
+ assert(!_variables["datadir"].empty());
+
+ try
+ {
+ _yellowAdmin = Yellow::AdminPrx::checkedCast(
+ _communicator->stringToProxy(_communicator->getProperties()->getProperty("IcePack.Yellow.Admin")));
+ }
+ catch(Ice::LocalException&)
+ {
+ }
+}
+
+void
+IcePack::ComponentDeployer::parse(const string& xmlFile, ComponentDeployHandler& handler)
+{
+ _error = 0;
+
+ SAXParser* parser = new SAXParser;
+ parser->setValidationScheme(SAXParser::Val_Never);
+
+ try
+ {
+ ComponentErrorHandler err(*this);
+ parser->setDocumentHandler(&handler);
+ parser->setErrorHandler(&err);
+ parser->parse(xmlFile.c_str());
+ }
+ catch(const XMLException& e)
+ {
+ cerr << "XMLException: " << toString(e.getMessage()) << endl;
+ }
+ int rc = parser->getErrorCount();
+ delete parser;
+
+ if(_error > 0 || rc > 0)
+ {
+ throw DeploymentException();
+ }
+}
+
+void
+IcePack::ComponentDeployer::deploy()
+{
+ vector<TaskPtr>::iterator p;
+ for(p = _tasks.begin(); p != _tasks.end(); p++)
+ {
+ try
+ {
+ (*p)->deploy();
+ }
+ catch(const DeploymentException& ex)
+ {
+ cerr << "Deploy: " << ex << endl;
+ undeployFrom(p);
+ throw;
+ }
+ catch(const Ice::SystemException& ex)
+ {
+ cerr << "Deploy: " << ex << endl;
+ undeployFrom(p);
+ throw DeploymentException();;
+ }
+ }
+}
+
+void
+IcePack::ComponentDeployer::undeploy()
+{
+ for(vector<TaskPtr>::reverse_iterator p = _tasks.rbegin(); p != _tasks.rend(); p++)
+ {
+ try
+ {
+ (*p)->undeploy();
+ }
+ catch(const DeploymentException& ex)
+ {
+ //
+ // TODO: we probably need to log the failure to execute
+ // this task so that the use can take necessary steps to
+ // ensure it's correctly undeployed.
+ //
+ cerr << "Undeploy: " << ex << endl;
+ }
+ catch(const Ice::SystemException& ex)
+ {
+ cerr << "Undeploy: " << ex << endl;
+ }
+ }
+}
+
+void
+IcePack::ComponentDeployer::createDirectory(const string& name)
+{
+ string path = _variables["datadir"] + substitute(name.empty() || name[0] == '/' ? name : "/" + name);
+ _tasks.push_back(new CreateDirectory(path));
+}
+
+void
+IcePack::ComponentDeployer::createConfigFile(const string& name)
+{
+ assert(!name.empty());
+ _configFile = _variables["datadir"] + substitute(name[0] == '/' ? name : "/" + name);
+ _tasks.push_back(new GenerateConfiguration(_configFile, _properties));
+}
+
+void
+IcePack::ComponentDeployer::addProperty(const string& name, const string& value)
+{
+ _properties->setProperty(substitute(name), substitute(value));
+}
+
+void
+IcePack::ComponentDeployer::addOffer(const string& offer, const string& proxy)
+{
+ if(!_yellowAdmin)
+ {
+ cerr << "Yellow admin not set, can't register the offer '" << offer << "'" << endl;
+ _error++;
+ return;
+ }
+
+ Ice::ObjectPrx object = _communicator->stringToProxy(proxy);
+ if(!object)
+ {
+ cerr << "Invalid proxy: " << proxy << endl;
+ _error++;
+ return;
+ }
+
+ _tasks.push_back(new RegisterOffer(_yellowAdmin, offer, object));
+}
+
+//
+// Substitute variables with their values.
+//
+string
+IcePack::ComponentDeployer::substitute(const string& v) const
+{
+ string value(v);
+ string::size_type beg;
+ string::size_type end = 0;
+
+ while((beg = value.find("${")) != string::npos)
+ {
+ end = value.find("}", beg);
+
+ if(end == string::npos)
+ {
+ cerr << "Malformed variable name in : " << value << endl;
+ break; // Throw instead?
+ }
+
+
+ string name = value.substr(beg + 2, end - beg - 2);
+ map<string, string>::const_iterator p = _variables.find(name);
+ if(p == _variables.end())
+ {
+ cerr << "Unknown variable: " << name << endl;
+ break; // Throw instead?
+ }
+
+ value.replace(beg, end - beg + 1, p->second);
+ }
+
+ return value;
+}
+
+void
+IcePack::ComponentDeployer::undeployFrom(vector<TaskPtr>::iterator p)
+{
+ if(p != _tasks.begin())
+ {
+ for(vector<TaskPtr>::reverse_iterator q(p); q != _tasks.rend(); q++)
+ {
+ try
+ {
+ (*q)->undeploy();
+ }
+ catch(DeploymentException& ex)
+ {
+ cerr << "Undeploy: " << ex << endl;
+ }
+ catch(Ice::SystemException& ex)
+ {
+ cerr << "Undeploy: " << ex << endl;
+ }
+ }
+ }
+}
+
diff --git a/cpp/src/IcePack/ComponentDeployer.h b/cpp/src/IcePack/ComponentDeployer.h
new file mode 100644
index 00000000000..df9c9b1c689
--- /dev/null
+++ b/cpp/src/IcePack/ComponentDeployer.h
@@ -0,0 +1,121 @@
+// **********************************************************************
+//
+// Copyright (c) 2001
+// Mutable Realms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef ICE_PACK_COMPONENT_DEPLOYER_H
+#define ICE_PACK_COMPONENT_DEPLOYER_H
+
+#include <IceUtil/Shared.h>
+#include <Yellow/Yellow.h>
+#include <sax/HandlerBase.hpp>
+
+#include <map>
+#include <vector>
+#include <stack>
+
+namespace IcePack
+{
+
+class Task : public ::IceUtil::SimpleShared
+{
+public:
+ virtual void deploy() = 0;
+ virtual void undeploy() = 0;
+};
+
+typedef ::IceInternal::Handle< ::IcePack::Task> TaskPtr;
+
+void incRef(::IcePack::Task*);
+void decRef(::IcePack::Task*);
+
+class ComponentDeployer;
+
+class ComponentErrorHandler : public ErrorHandler
+{
+public:
+
+ ComponentErrorHandler(ComponentDeployer&);
+
+ void warning(const SAXParseException& exception);
+ void error(const SAXParseException& exception);
+ void fatalError(const SAXParseException& exception);
+ void resetErrors();
+
+private:
+
+ ComponentDeployer& _deployer;
+
+};
+
+class ComponentDeployHandler : public DocumentHandler
+{
+public:
+
+ ComponentDeployHandler(ComponentDeployer&);
+
+ virtual void characters(const XMLCh *const, const unsigned int);
+ virtual void startElement(const XMLCh *const, AttributeList &);
+ virtual void endElement(const XMLCh *const);
+
+ virtual void ignorableWhitespace(const XMLCh *const, const unsigned int) { }
+ virtual void processingInstruction(const XMLCh *const, const XMLCh *const) { }
+ virtual void resetDocument() { }
+ virtual void setDocumentLocator(const Locator *const) { }
+ virtual void startDocument() { }
+ virtual void endDocument() { }
+
+protected:
+
+ std::string getAttributeValue(const AttributeList&, const std::string&) const;
+ std::string getAttributeValueWithDefault(const AttributeList&, const std::string&, const std::string&) const;
+
+ std::string toString(const XMLCh *const) const;
+ std::string elementValue() const;
+
+private:
+
+ std::stack<std::string> _elements;
+
+ ComponentDeployer& _deployer;
+};
+
+class ComponentDeployer : public Task
+{
+public:
+
+ ComponentDeployer(const Ice::CommunicatorPtr&);
+
+ virtual void deploy();
+ virtual void undeploy();
+
+ void parse(const std::string&, ComponentDeployHandler&);
+ std::string substitute(const std::string&) const;
+
+ void createDirectory(const std::string&);
+ void createConfigFile(const std::string&);
+ void addProperty(const std::string&, const std::string&);
+ void addOffer(const std::string&, const std::string&);
+
+protected:
+
+ void undeployFrom(std::vector<TaskPtr>::iterator);
+
+ Ice::CommunicatorPtr _communicator;
+ Yellow::AdminPrx _yellowAdmin;
+
+ Ice::PropertiesPtr _properties;
+ std::map<std::string, std::string> _variables;
+ std::vector<TaskPtr> _tasks;
+ std::string _configFile;
+ int _error;
+};
+
+}
+
+#endif
diff --git a/cpp/src/IcePack/Makefile b/cpp/src/IcePack/Makefile
index e3052af2946..94a62e37be0 100644
--- a/cpp/src/IcePack/Makefile
+++ b/cpp/src/IcePack/Makefile
@@ -34,6 +34,9 @@ COBJS = Grammar.o \
SOBJS = Server.o \
AdapterManagerI.o \
ServerManagerI.o \
+ ComponentDeployer.o \
+ ServerDeployer.o \
+ ServiceDeployer.o \
LocatorI.o \
LocatorRegistryI.o \
AdminI.o \
@@ -50,7 +53,7 @@ SLICECMD = $(SLICE2CPP) --include-dir IcePack --dll-export ICE_PACK_API -I$(slic
include $(top_srcdir)/config/Make.rules
-CPPFLAGS := -I.. $(CPPFLAGS)
+CPPFLAGS := -I.. $(CPPFLAGS) $(XERCESC_FLAGS)
$(VERSIONED_NAME): $(OBJS)
rm -f $@
@@ -62,11 +65,11 @@ $(NAME): $(VERSIONED_NAME)
$(CLIENT): $(COBJS)
rm -f $@
- $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $(COBJS) -lIcePack $(LIBS) -lreadline -lcurses
+ $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $(COBJS) -lYellow -lIcePack $(LIBS) -lreadline -lcurses
$(SERVER): $(SOBJS)
rm -f $@
- $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $(SOBJS) -lIcePack $(LIBS)
+ $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $(SOBJS) -lYellow -lIcePack $(XERCESC_LIBS) $(LIBS)
Grammar.cpp Grammar.h: Grammar.y
bison -dvt Grammar.y
diff --git a/cpp/src/IcePack/Parser.cpp b/cpp/src/IcePack/Parser.cpp
index 859fd1005cc..ee5cc1ac515 100644
--- a/cpp/src/IcePack/Parser.cpp
+++ b/cpp/src/IcePack/Parser.cpp
@@ -70,21 +70,14 @@ IcePack::Parser::addServer(const list<string>& args, const std::list<std::string
try
{
- ServerDescription desc;
list<string>::const_iterator p = args.begin();
-
- desc.name = *p++;
- desc.path = *p++;
- if(p != args.end())
- {
- desc.pwd = *p++;
- }
-
- copy(adapters.begin(), adapters.end(), back_inserter(desc.adapters));
- copy(options.begin(), options.end(), back_inserter(desc.args));
+ string name = *p++;
+ string path = *p++;
+ string ldpath = *p++;
+ string descriptor = *p++;
- _admin->addServer(desc);
+ _admin->addServer(name, path, ldpath, descriptor);
}
catch(const Exception& ex)
diff --git a/cpp/src/IcePack/Server.cpp b/cpp/src/IcePack/Server.cpp
index 194de82b309..d47775a688f 100644
--- a/cpp/src/IcePack/Server.cpp
+++ b/cpp/src/IcePack/Server.cpp
@@ -19,6 +19,7 @@
# include <signal.h>
# include <sys/wait.h>
#endif
+#include <util/PlatformUtils.hpp>
using namespace std;
using namespace Ice;
@@ -56,8 +57,22 @@ main(int argc, char* argv[])
sigaction(SIGCHLD, &action, 0);
#endif
+ try
+ {
+ XMLPlatformUtils::Initialize();
+ }
+ catch(const XMLException& e)
+ {
+ cout << e.getMessage() << endl;
+ return EXIT_FAILURE;
+ }
+
::Server app;
- return app.main(argc, argv);
+ int rc = app.main(argc, argv);
+
+ XMLPlatformUtils::Terminate();
+
+ return rc;
}
void
@@ -133,6 +148,8 @@ int
string locatorRegistryId = properties->getPropertyWithDefault("IcePack.LocatorRegistry.Identity",
"IcePack/locatorregistry");
string adminId = properties->getPropertyWithDefault("IcePack.Admin.Identity", "IcePack/admin");
+
+ communicator()->getProperties()->setProperty("Ice.Default.Locator", locatorId + ":" + locatorEndpoints);
//
// Register the server manager and adapter manager with an
@@ -151,14 +168,8 @@ int
ActivatorPrx activatorProxy;
#ifndef _WIN32
- //
- // Setup default arguments which will be passed to each activated
- // process. Then, create and start the activator.
- //
- Args defaultArgs;
- defaultArgs.push_back("--Ice.Default.Locator=" + locatorId + ":" + locatorEndpoints);
- ActivatorIPtr activator = new ActivatorI(communicator(), defaultArgs);
+ ActivatorIPtr activator = new ActivatorI(communicator());
activator->start();
activatorProxy = ActivatorPrx::uncheckedCast(internalAdapter->add(activator,
stringToIdentity("IcePack/activator")));
diff --git a/cpp/src/IcePack/ServerDeployer.cpp b/cpp/src/IcePack/ServerDeployer.cpp
new file mode 100644
index 00000000000..d3b7b1dd9b1
--- /dev/null
+++ b/cpp/src/IcePack/ServerDeployer.cpp
@@ -0,0 +1,354 @@
+// **********************************************************************
+//
+// Copyright (c) 2001
+// Mutable Realms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <Ice/Ice.h>
+#include <IcePack/ServerDeployer.h>
+#include <IcePack/ServiceDeployer.h>
+#include <IcePack/AdapterManager.h>
+#include <IcePack/ServerManager.h>
+
+using namespace std;
+using namespace IcePack;
+
+namespace IcePack
+{
+
+//
+// Adapter registration task.
+//
+class AddAdapterTask : public Task
+{
+public:
+
+ AddAdapterTask(const AdapterManagerPrx& manager, const ServerPtr& server, const AdapterDescription& desc) :
+ _manager(manager),
+ _server(server),
+ _desc(desc)
+ {
+ }
+
+ virtual void
+ deploy()
+ {
+ try
+ {
+ AdapterPrx adapter = _manager->create(_desc);
+
+ _server->_description.adapters.push_back(_desc.name);
+ _server->_adapters.push_back(adapter);
+ }
+ catch(const AdapterExistsException&)
+ {
+ throw DeploymentException();
+ }
+ }
+
+ virtual void
+ undeploy()
+ {
+ _manager->remove(_desc.name);
+
+ //
+ // NOTE: We don't need to remove the adapter from the
+ // server. The undo occured because a problem during the
+ // server deployment so the server will be removed anyway.
+ //
+ }
+
+private:
+
+ AdapterManagerPrx _manager;
+ ServerPtr _server;
+ AdapterDescription _desc;
+};
+
+//
+// Server deployer handler.
+//
+class ServerDeployHandler : public ComponentDeployHandler
+{
+public:
+
+ ServerDeployHandler(ServerDeployer&);
+
+ virtual void startElement(const XMLCh *const name, AttributeList &attrs);
+ virtual void endElement(const XMLCh *const name);
+ virtual void startDocument();
+
+private:
+
+ ServerDeployer& _deployer;
+};
+
+}
+
+IcePack::ServerDeployHandler::ServerDeployHandler(ServerDeployer& deployer) :
+ ComponentDeployHandler(deployer),
+ _deployer(deployer)
+{
+}
+
+void
+IcePack::ServerDeployHandler::startDocument()
+{
+ //
+ // Create top level directory and configuration directory.
+ //
+ _deployer.createDirectory("");
+ _deployer.createDirectory("/config");
+}
+
+void
+IcePack::ServerDeployHandler::startElement(const XMLCh *const name, AttributeList &attrs)
+{
+ ComponentDeployHandler::startElement(name, attrs);
+
+ string str = toString(name);
+
+ if(str == "server")
+ {
+ string kind = getAttributeValue(attrs, "kind");
+ if(kind == "cpp")
+ {
+ _deployer.setKind(ServerDeployer::CppServer);
+ }
+ else if(kind == "java")
+ {
+ _deployer.setKind(ServerDeployer::JavaServer);
+ }
+ else if(kind == "cpp-icebox")
+ {
+ _deployer.setKind(ServerDeployer::CppIceBox);
+ }
+ else if(kind == "java-icebox")
+ {
+ _deployer.setKind(ServerDeployer::JavaIceBox);
+ }
+
+ _deployer.createConfigFile("/config/config_server");
+ }
+ else if(str == "service")
+ {
+ string name = getAttributeValue(attrs, "name");
+ string descriptor = getAttributeValue(attrs, "descriptor");
+ _deployer.addService(name, descriptor);
+ }
+ else if(str == "adapter")
+ {
+ _deployer.addAdapter(getAttributeValue(attrs, "name"));
+ }
+}
+
+void
+IcePack::ServerDeployHandler::endElement(const XMLCh *const name)
+{
+ string str = toString(name);
+
+ if(str == "classname")
+ {
+ _deployer.setClassName(elementValue());
+ }
+ else if(str == "pwd")
+ {
+ _deployer.setWorkingDirectory(elementValue());
+ }
+
+ ComponentDeployHandler::endElement(name);
+}
+
+IcePack::ServerDeployer::ServerDeployer(const Ice::CommunicatorPtr& communicator,
+ const ServerPtr& server,
+ const ServerPrx& serverProxy) :
+ ComponentDeployer(communicator),
+ _server(server),
+ _serverProxy(serverProxy)
+{
+ _variables["name"] = _server->_description.name;
+ _variables["datadir"] += "/" + _variables["name"];
+}
+
+void
+IcePack::ServerDeployer::setAdapterManager(const AdapterManagerPrx& manager)
+{
+ _adapterManager = manager;
+}
+
+void
+IcePack::ServerDeployer::parse()
+{
+ ServerDeployHandler handler(*this);
+
+ ComponentDeployer::parse(_server->_description.descriptor, handler);
+
+ //
+ // Once everything is parsed, we can perform some final setup
+ // before the deployment starts.
+ //
+ Ice::PropertiesPtr props = _communicator->getProperties();
+ _properties->setProperty("Ice.ProgramName", _variables["name"]);
+ _properties->setProperty("Ice.Default.Locator", props->getProperty("Ice.Default.Locator"));
+ _properties->setProperty("Yellow.Query", props->getProperty("IcePack.Yellow.Query"));
+
+ if(_kind == JavaServer)
+ {
+ if(!_server->_description.libraryPath.empty())
+ {
+ _javaOptions.push_back("-classpath");
+ _javaOptions.push_back(_server->_description.libraryPath);
+ _javaOptions.push_back("-ea");
+ }
+ _javaOptions.push_back(_className);
+
+ for(vector<string>::reverse_iterator p = _javaOptions.rbegin(); p != _javaOptions.rend(); ++p)
+ {
+ _server->_description.args.insert(_server->_description.args.begin(), *p);
+ }
+ }
+
+ _server->_description.args.push_back("--Ice.Config=" + _configFile);
+}
+
+void
+IcePack::ServerDeployer::setClassName(const string& name)
+{
+ if(_kind != JavaServer)
+ {
+ cerr << "Class name element only allowed for Java servers." << endl;
+ _error++;
+ return;
+ }
+
+ if(name == "")
+ {
+ cerr << "Empty path." << endl;
+ _error++;
+ return;
+ }
+
+ _className = name;
+}
+
+void
+IcePack::ServerDeployer::setWorkingDirectory(const string& pwd)
+{
+ if(pwd == "")
+ {
+ cerr << "Empty working directory." << endl;
+ _error++;
+ return;
+ }
+
+ _server->_description.pwd = substitute(pwd);
+}
+
+void
+IcePack::ServerDeployer::addAdapter(const string& name)
+{
+ if(!_adapterManager)
+ {
+ cerr << "Adapter manager not set, can't register the adapter '" << name << "'" << endl;
+ _error++;
+ return;
+ }
+
+ AdapterDescription desc;
+ desc.name = substitute(name);
+ desc.server = _serverProxy;
+ if(desc.name == "")
+ {
+ cerr << "Empty adapter name." << endl;
+ _error++;
+ return;
+ }
+
+ _tasks.push_back(new AddAdapterTask(_adapterManager, _server, desc));
+}
+
+void
+IcePack::ServerDeployer::addService(const string& name, const string& descriptor)
+{
+ if(_kind != CppIceBox && _kind != JavaIceBox)
+ {
+ cerr << "Service elements are only allowed for Java or C++ IceBox servers." << endl;
+ _error++;
+ return;
+ }
+
+ std::map<std::string, std::string> variables = _variables;
+ variables["name"] = name;
+
+ ServiceDeployer* task = new ServiceDeployer(_communicator, *this, variables);
+ try
+ {
+ task->parse(descriptor);
+ }
+ catch(const DeploymentException&)
+ {
+ cerr << "Failed to parse the service '" << name << "' descriptor" << endl;
+ delete task;
+ _error++;
+ }
+
+ _tasks.push_back(task);
+}
+
+void
+IcePack::ServerDeployer::addOption(const string& option)
+{
+ _server->_description.args.push_back(substitute(option));
+}
+
+void
+IcePack::ServerDeployer::addJavaOption(const string& option)
+{
+ _javaOptions.push_back(substitute(option));
+}
+
+void
+IcePack::ServerDeployer::setKind(ServerDeployer::ServerKind kind)
+{
+ switch(kind)
+ {
+ case CppServer:
+ if(_server->_description.path.empty())
+ {
+ cerr << "C++ server path is not specified" << endl;
+ _error++;
+ break;
+ }
+
+ case JavaServer:
+ if(_server->_description.path.empty())
+ {
+ _server->_description.path = "java";
+ }
+ break;
+
+ case JavaIceBox:
+ if(_server->_description.path.empty())
+ {
+ _server->_description.path = "java";
+ }
+ addProperty("IceBox.Name", "${name}");
+ addAdapter("${name}.ServiceManagerAdapter");
+ break;
+
+ case CppIceBox:
+ if(_server->_description.path.empty())
+ {
+ _server->_description.path = "icebox";
+ }
+ addProperty("IceBox.Name", "${name}");
+ addAdapter("${name}.ServiceManagerAdapter");
+ break;
+ }
+
+ _kind = kind;
+}
diff --git a/cpp/src/IcePack/ServerDeployer.h b/cpp/src/IcePack/ServerDeployer.h
new file mode 100644
index 00000000000..3e93a4b720a
--- /dev/null
+++ b/cpp/src/IcePack/ServerDeployer.h
@@ -0,0 +1,63 @@
+// **********************************************************************
+//
+// Copyright (c) 2001
+// Mutable Realms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+
+#ifndef ICE_PACK_SERVER_DEPLOYER_H
+#define ICE_PACK_SERVER_DEPLOYER_H
+
+#include <IceUtil/Shared.h>
+#include <IcePack/ComponentDeployer.h>
+#include <IcePack/ServerManagerF.h>
+#include <IcePack/AdapterManagerF.h>
+
+namespace IcePack
+{
+
+class ServerDeployer : public ComponentDeployer
+{
+public:
+ enum ServerKind
+ {
+ CppIceBox,
+ JavaIceBox,
+ CppServer,
+ JavaServer
+ };
+
+ ServerDeployer(const Ice::CommunicatorPtr&, const ServerPtr&, const ServerPrx&);
+
+ void setAdapterManager(const AdapterManagerPrx&);
+
+ virtual void parse();
+
+ void setClassName(const std::string&);
+ void setWorkingDirectory(const std::string&);
+ void addAdapter(const std::string&);
+ void addService(const std::string&, const std::string&);
+ void addOption(const std::string&);
+ void addJavaOption(const std::string&);
+ void setKind(ServerKind);
+
+private:
+
+ AdapterManagerPrx _adapterManager;
+
+ ServerKind _kind;
+
+ ServerPtr _server;
+ ServerPrx _serverProxy;
+
+ std::string _className;
+ std::vector<std::string> _javaOptions;
+};
+
+}
+
+#endif
diff --git a/cpp/src/IcePack/ServerManager.ice b/cpp/src/IcePack/ServerManager.ice
index 190d59baec0..3a3db9e9981 100644
--- a/cpp/src/IcePack/ServerManager.ice
+++ b/cpp/src/IcePack/ServerManager.ice
@@ -54,6 +54,13 @@ class Server
ServerState getState();
/**
+ *
+ * Set the server state.
+ *
+ **/
+ void setState(ServerState state);
+
+ /**
*
* The description of this server.
*
@@ -82,8 +89,8 @@ class ServerManager
* Create a server.
*
**/
- Server* create(ServerDescription description)
- throws ServerExistsException, AdapterExistsException;
+ Server* create(string name, string path, string libpath, string descriptor)
+ throws DeploymentException, ServerExistsException;
/**
*
diff --git a/cpp/src/IcePack/ServerManagerI.cpp b/cpp/src/IcePack/ServerManagerI.cpp
index dff51a37fd3..a9ec5b768c4 100644
--- a/cpp/src/IcePack/ServerManagerI.cpp
+++ b/cpp/src/IcePack/ServerManagerI.cpp
@@ -14,11 +14,15 @@
#include <IcePack/ServerManagerI.h>
#include <IcePack/AdapterManager.h>
#include <IcePack/Activator.h>
+#include <IcePack/ServerDeployer.h>
using namespace std;
using namespace Ice;
using namespace IcePack;
+namespace IcePack
+{
+
class ServerNameToServer
{
public:
@@ -42,6 +46,8 @@ private:
ObjectAdapterPtr _adapter;
};
+}
+
IcePack::ServerI::ServerI(const ObjectAdapterPtr& adapter, const ActivatorPrx& activator) :
_adapter(adapter),
_activator(activator)
@@ -137,7 +143,7 @@ IcePack::ServerI::getState(const Current&)
}
void
-IcePack::ServerI::setState(ServerState state)
+IcePack::ServerI::setState(ServerState state, const Current&)
{
IceUtil::Monitor< ::IceUtil::Mutex>::Lock sync(*this);
@@ -163,18 +169,15 @@ IcePack::ServerManagerI::~ServerManagerI()
}
ServerPrx
-IcePack::ServerManagerI::create(const ServerDescription& description, const Current&)
+IcePack::ServerManagerI::create(const string& name, const string& path, const string& libraryPath,
+ const string& descriptor, const Current&)
{
IceUtil::Mutex::Lock sync(*this);
- ServerPrx server = ServerNameToServer(_adapter)(description.name);
+ ServerPrx server = ServerNameToServer(_adapter)(name);
try
{
server->ice_ping();
-
- //
- // The server already exists.
- //
throw ServerExistsException();
}
catch (const ObjectNotExistException&)
@@ -182,63 +185,46 @@ IcePack::ServerManagerI::create(const ServerDescription& description, const Curr
}
//
- // Create the server. Set its state to Activating so that we can
+ // Creates the server. Set its state to Activating so that we can
// safelly register the adapters without any race conditions. If a
// request comes in for an adapter we've just registerd, the
// server won't be started as long as we are not in the Inactive
// state.
//
- ServerI* serverI = new ServerI(_adapter, _activator);
- ServerPtr s = serverI;
- serverI->_description = description;
+ // TODO: the server isn't fully initialized here. Is this really
+ // valid to add the servant to the object adapter? If not, how do
+ // we handle the race condition because of registered adapters
+ // having a proxy on the server?
+ //
+ ServerPtr serverI = new ServerI(_adapter, _activator);
+ serverI->_description.name = name;
+ serverI->_description.path = path;
+ serverI->_description.libraryPath = libraryPath;
+ serverI->_description.descriptor = descriptor;
serverI->_state = Activating;
+ server = ServerPrx::uncheckedCast(_adapter->add(serverI, server->ice_getIdentity()));
//
- // The server object might receives requests as soon as it returns
- // from this call. This is the reason why we've created the server
- // in the activating state -- to block any attempts to activate
- // the server. The server state is set to inactive once it's fully
- // created.
+ // Deploy the server.
//
- server = ServerPrx::uncheckedCast(_adapter->add(serverI, server->ice_getIdentity()));
-
try
{
- //
- // Register the server adapters to enabled automatic
- // activation. If an adapter already exists, rollback the
- // server creation and throw an exception.
- //
- for(AdapterNames::const_iterator p = description.adapters.begin(); p != description.adapters.end(); ++p)
- {
- AdapterDescription desc;
- desc.name = (*p);
- desc.server = server;
- serverI->_adapters.push_back(_adapterManager->create(desc));
- }
+ ServerDeployer deployer(_adapter->getCommunicator(), serverI, server);
+ deployer.setAdapterManager(_adapterManager);
+
+ deployer.parse();
+ deployer.deploy();
}
- catch (const AdapterExistsException&)
+ catch(const DeploymentException&)
{
- //
- // The adapter is already registered with a server, remove the
- // server.
- //
_adapter->remove(server->ice_getIdentity());
serverI->setState(Destroyed);
throw;
}
- //
- // Set the server state as inactive. At this point the server can
- // be automatically started if a request for one of its adapter
- // comes in.
- //
serverI->setState(Inactive);
- //
- // Add this server name to our server names internal list.
- //
- _serverNames.insert(description.name);
+ _serverNames.insert(name);
return server;
}
@@ -254,7 +240,7 @@ IcePack::ServerManagerI::findByName(const string& name, const Current&)
server->ice_ping();
return server;
}
- catch (const ObjectNotExistException&)
+ catch(const ObjectNotExistException&)
{
return 0;
}
@@ -270,7 +256,7 @@ IcePack::ServerManagerI::remove(const string& name, const Current&)
{
server->ice_ping();
}
- catch (const ObjectNotExistException&)
+ catch(const ObjectNotExistException&)
{
throw ServerNotExistException();
}
@@ -278,17 +264,23 @@ IcePack::ServerManagerI::remove(const string& name, const Current&)
//
// Mark the server as destroyed.
//
- ServerI* serverI = dynamic_cast<ServerI*>(_adapter->proxyToServant(server).get());
+ ServerPtr serverI = ServerPtr::dynamicCast(_adapter->proxyToServant(server).get());
assert(serverI);
serverI->setState(Destroyed);
//
- // Remove server adapters.
+ // Undeploy the server.
//
- ServerDescription description = serverI->_description;
- for(AdapterNames::iterator p = description.adapters.begin(); p != description.adapters.end(); ++p)
+ try
+ {
+ ServerDeployer deployer(_adapter->getCommunicator(), serverI, server);
+ deployer.setAdapterManager(_adapterManager);
+
+ deployer.parse();
+ deployer.undeploy();
+ }
+ catch(const DeploymentException& ex)
{
- _adapterManager->remove(*p);
}
_adapter->remove(server->ice_getIdentity());
diff --git a/cpp/src/IcePack/ServerManagerI.h b/cpp/src/IcePack/ServerManagerI.h
index 8e1190f4e14..b5262e05634 100644
--- a/cpp/src/IcePack/ServerManagerI.h
+++ b/cpp/src/IcePack/ServerManagerI.h
@@ -26,12 +26,11 @@ public:
ServerI(const ::Ice::ObjectAdapterPtr&, const ActivatorPrx&);
virtual ~ServerI();
- virtual ServerDescription getServerDescription(const ::Ice::Current&);
- virtual bool start(const ::Ice::Current&);
- virtual void terminationCallback(const ::Ice::Current&);
- virtual ServerState getState(const ::Ice::Current&);
-
- void setState(ServerState);
+ virtual ServerDescription getServerDescription(const ::Ice::Current& = ::Ice::Current());
+ virtual bool start(const ::Ice::Current& = ::Ice::Current());
+ virtual void terminationCallback(const ::Ice::Current& = ::Ice::Current());
+ virtual ServerState getState(const ::Ice::Current& = ::Ice::Current());
+ virtual void setState(ServerState, const ::Ice::Current& = ::Ice::Current());
private:
@@ -47,7 +46,8 @@ public:
ServerManagerI(const Ice::ObjectAdapterPtr&, const AdapterManagerPrx&, const ActivatorPrx&);
virtual ~ServerManagerI();
- virtual ServerPrx create(const ServerDescription&, const ::Ice::Current&);
+ virtual ServerPrx create(const std::string&, const std::string&, const std::string&, const std::string&,
+ const ::Ice::Current&);
virtual ServerPrx findByName(const ::std::string&, const ::Ice::Current&);
virtual void remove(const ::std::string&, const ::Ice::Current&);
virtual ServerNames getAll(const ::Ice::Current&);
diff --git a/cpp/src/IcePack/ServiceDeployer.cpp b/cpp/src/IcePack/ServiceDeployer.cpp
new file mode 100644
index 00000000000..5c70c9391a8
--- /dev/null
+++ b/cpp/src/IcePack/ServiceDeployer.cpp
@@ -0,0 +1,139 @@
+// **********************************************************************
+//
+// Copyright (c) 2001
+// Mutable Realms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <Ice/Ice.h>
+#include <IcePack/ServiceDeployer.h>
+#include <IcePack/ServerDeployer.h>
+
+using namespace std;
+using namespace IcePack;
+
+namespace IcePack
+{
+
+class ServiceDeployHandler : public ComponentDeployHandler
+{
+public:
+
+ ServiceDeployHandler(ServiceDeployer&);
+
+ virtual void startElement(const XMLCh *const name, AttributeList &attrs);
+ virtual void endElement(const XMLCh *const name);
+ virtual void startDocument();
+
+private:
+
+ ServiceDeployer& _deployer;
+};
+
+}
+
+IcePack::ServiceDeployHandler::ServiceDeployHandler(ServiceDeployer& deployer) :
+ ComponentDeployHandler(deployer),
+ _deployer(deployer)
+{
+}
+
+void
+IcePack::ServiceDeployHandler::startDocument()
+{
+}
+
+void
+IcePack::ServiceDeployHandler::startElement(const XMLCh *const name, AttributeList &attrs)
+{
+ ComponentDeployHandler::startElement(name, attrs);
+
+ string str = toString(name);
+
+ if(str == "service")
+ {
+ string kind = getAttributeValue(attrs, "kind");
+ if(kind == "standard")
+ {
+ _deployer.setKind(ServiceDeployer::Standard);
+ }
+ else if(kind == "freeze")
+ {
+ _deployer.setKind(ServiceDeployer::Freeze);
+ _deployer.setDBEnv(getAttributeValueWithDefault(attrs, "dbenv", "${name}"));
+ }
+
+ _deployer.setEntryPoint(getAttributeValueWithDefault(attrs, "library", "${name}"),
+ getAttributeValueWithDefault(attrs, "entry", "create"));
+
+ _deployer.createConfigFile("/config/config_${name}");
+ }
+ else if(str == "adapter")
+ {
+ _deployer.getServerDeployer().addAdapter(getAttributeValue(attrs, "name"));
+ }
+}
+
+void
+IcePack::ServiceDeployHandler::endElement(const XMLCh *const name)
+{
+ string str = toString(name);
+
+ ComponentDeployHandler::endElement(name);
+}
+
+IcePack::ServiceDeployer::ServiceDeployer(const Ice::CommunicatorPtr& communicator,
+ ServerDeployer& serverDeployer,
+ const map<string, string>& variables) :
+ ComponentDeployer(communicator),
+ _serverDeployer(serverDeployer)
+{
+ _variables = variables;
+}
+
+void
+IcePack::ServiceDeployer::parse(const string& descriptor)
+{
+ ServiceDeployHandler handler(*this);
+
+ ComponentDeployer::parse(descriptor, handler);
+}
+
+ServerDeployer&
+IcePack::ServiceDeployer::getServerDeployer() const
+{
+ return _serverDeployer;
+}
+
+void
+IcePack::ServiceDeployer::setKind(ServiceKind kind)
+{
+ _kind = kind;
+}
+
+void
+IcePack::ServiceDeployer::setEntryPoint(const string& library, const string& entry)
+{
+ assert(!_configFile.empty());
+ _serverDeployer.addProperty("IceBox.Service.${name}", library + ":" + entry + " --Ice.Config=" + _configFile);
+}
+
+void
+IcePack::ServiceDeployer::setDBEnv(const string& dir)
+{
+ assert(!dir.empty());
+
+ if(_kind != Freeze)
+ {
+ cerr << "Dabase environment is only allowed for Freeze services." << endl;
+ _error++;
+ return;
+ }
+
+ createDirectory("/dbs" + (dir[0] == '/' ? dir : "/" + dir));
+ addProperty("IceBox.DBEnvName.${name}", "${datadir}/dbs" + (dir[0] == '/' ? dir : "/" + dir));
+}
+
diff --git a/cpp/src/IcePack/ServiceDeployer.h b/cpp/src/IcePack/ServiceDeployer.h
new file mode 100644
index 00000000000..6a645ca3416
--- /dev/null
+++ b/cpp/src/IcePack/ServiceDeployer.h
@@ -0,0 +1,51 @@
+// **********************************************************************
+//
+// Copyright (c) 2001
+// Mutable Realms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#ifndef ICE_PACK_SERVICE_DEPLOYER_H
+#define ICE_PACK_SERVICE_DEPLOYER_H
+
+#include <IceUtil/Shared.h>
+#include <IcePack/ComponentDeployer.h>
+
+
+namespace IcePack
+{
+class ServerDeployer;
+
+class ServiceDeployer : public ComponentDeployer
+{
+public:
+
+ enum ServiceKind
+ {
+ Standard,
+ Freeze
+ };
+
+ ServiceDeployer(const Ice::CommunicatorPtr&, ServerDeployer&, const std::map<std::string, std::string>&);
+
+ void parse(const std::string&);
+
+ ServerDeployer& getServerDeployer() const;
+
+ void setKind(ServiceKind);
+ void setEntryPoint(const std::string&, const std::string&);
+ void setDBEnv(const std::string&);
+
+private:
+
+ ServerDeployer& _serverDeployer;
+
+ ServiceKind _kind;
+};
+
+}
+
+#endif