diff options
author | Benoit Foucher <benoit@zeroc.com> | 2002-07-22 18:27:40 +0000 |
---|---|---|
committer | Benoit Foucher <benoit@zeroc.com> | 2002-07-22 18:27:40 +0000 |
commit | f8ad6db815b1584bd55b8e56c2e8d1bd5cc66279 (patch) | |
tree | 394a626cf81c18d96d8c3efa9da325133080ff14 /cpp/src | |
parent | Fixed null dereference caused by silly typo in exception action. (diff) | |
download | ice-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.cpp | 15 | ||||
-rw-r--r-- | cpp/src/IcePack/ActivatorI.h | 3 | ||||
-rw-r--r-- | cpp/src/IcePack/AdminI.cpp | 5 | ||||
-rw-r--r-- | cpp/src/IcePack/AdminI.h | 3 | ||||
-rw-r--r-- | cpp/src/IcePack/ComponentDeployer.cpp | 496 | ||||
-rw-r--r-- | cpp/src/IcePack/ComponentDeployer.h | 121 | ||||
-rw-r--r-- | cpp/src/IcePack/Makefile | 9 | ||||
-rw-r--r-- | cpp/src/IcePack/Parser.cpp | 17 | ||||
-rw-r--r-- | cpp/src/IcePack/Server.cpp | 27 | ||||
-rw-r--r-- | cpp/src/IcePack/ServerDeployer.cpp | 354 | ||||
-rw-r--r-- | cpp/src/IcePack/ServerDeployer.h | 63 | ||||
-rw-r--r-- | cpp/src/IcePack/ServerManager.ice | 11 | ||||
-rw-r--r-- | cpp/src/IcePack/ServerManagerI.cpp | 94 | ||||
-rw-r--r-- | cpp/src/IcePack/ServerManagerI.h | 14 | ||||
-rw-r--r-- | cpp/src/IcePack/ServiceDeployer.cpp | 139 | ||||
-rw-r--r-- | cpp/src/IcePack/ServiceDeployer.h | 51 |
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 |