diff options
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/slice/IceGrid/Admin.ice | 112 | ||||
-rw-r--r-- | cpp/src/IceGrid/AdminI.cpp | 66 | ||||
-rw-r--r-- | cpp/src/IceGrid/AdminI.h | 3 | ||||
-rw-r--r-- | cpp/src/IceGrid/Database.cpp | 2 | ||||
-rw-r--r-- | cpp/src/IceGrid/Parser.cpp | 7 | ||||
-rw-r--r-- | cpp/test/IceGrid/deployer/AllTests.cpp | 172 |
6 files changed, 331 insertions, 31 deletions
diff --git a/cpp/slice/IceGrid/Admin.ice b/cpp/slice/IceGrid/Admin.ice index 55663ab7cf0..c6bf295bf2c 100644 --- a/cpp/slice/IceGrid/Admin.ice +++ b/cpp/slice/IceGrid/Admin.ice @@ -452,6 +452,79 @@ class ApplicationDescriptor string comment; }; +struct ApplicationUpdateDescriptor +{ + /** + * + * The name of the application to update. + * + **/ + string name; + + /** + * + * The variables to update. + * + **/ + StringStringDict variables; + + /** + * + * The variables to remove. + * + **/ + Ice::StringSeq removeVariables; + + /** + * + * The server templates to update. + * + **/ + TemplateDescriptorDict serverTemplates; + + /** + * + * The ids of the server template to remove. + * + **/ + Ice::StringSeq removeServerTemplates; + + /** + * + * The service templates to update. + * + **/ + TemplateDescriptorDict serviceTemplates; + + /** + * + * The ids of the service tempate to remove. + * + **/ + Ice::StringSeq removeServiceTemplates; + + /** + * + * The application nodes to update. + * + **/ + NodeDescriptorSeq nodes; + + /** + * + * The server instances to update. + * + **/ + InstanceDescriptorSeq servers; + + /** + * + * The name of the server instances to remove. + * + **/ + Ice::StringSeq removeServers; +}; + /** * * The server activation mode. @@ -554,16 +627,35 @@ interface Admin /** * - * Update an application. An application is a set of servers. + * Synchronize a deployed application with the given application + * descriptor. * * @param descriptor The application descriptor. * - * @throws DeploymentException Raised if application deployment failed. + * @throws DeploymentException Raised if application deployment + * failed. * * @see removeApplication * **/ - void updateApplication(ApplicationDescriptor descriptor) + void syncApplication(ApplicationDescriptor descriptor) + throws DeploymentException, ApplicationNotExistException; + + /** + * + * Update a deployed application with the given update application + * descriptor. + * + * @param descriptor The update descriptor. + * + * @throws DeploymentException Raised if application deployment + * failed. + * + * @see syncApplication + * @see removeApplication + * + **/ + void updateApplication(ApplicationUpdateDescriptor descriptor) throws DeploymentException, ApplicationNotExistException; /** @@ -619,20 +711,6 @@ interface Admin nonmutating ApplicationDescriptor getApplicationDescriptor(string name) throws ApplicationNotExistException; - /** - * - * Add the server(s) from the given application descriptor. - * - * @param descriptor The application deployment descriptor. - * - * @throws DeploymentException Raised if server deployment failed. - * - * @see removeServer - * @see updateServer - * - **/ - void addServer(ApplicationDescriptor application) - throws DeploymentException, ServerExistsException; /** * diff --git a/cpp/src/IceGrid/AdminI.cpp b/cpp/src/IceGrid/AdminI.cpp index 9f6252c15cb..63acd4643f2 100644 --- a/cpp/src/IceGrid/AdminI.cpp +++ b/cpp/src/IceGrid/AdminI.cpp @@ -11,6 +11,7 @@ #include <IceGrid/AdminI.h> #include <IceGrid/RegistryI.h> #include <IceGrid/Database.h> +#include <IceGrid/Util.h> #include <IceGrid/DescriptorHelper.h> #include <Ice/LoggerUtil.h> #include <Ice/TraceUtil.h> @@ -40,12 +41,75 @@ AdminI::addApplication(const ApplicationDescriptorPtr& descriptor, const Current } void -AdminI::updateApplication(const ApplicationDescriptorPtr& descriptor, const Current&) +AdminI::syncApplication(const ApplicationDescriptorPtr& descriptor, const Current&) { _database->updateApplicationDescriptor(descriptor); } void +AdminI::updateApplication(const ApplicationUpdateDescriptor& descriptor, const Current&) +{ + ApplicationDescriptorPtr oldApp = _database->getApplicationDescriptor(descriptor.name); + + ApplicationDescriptorPtr newApp = new ApplicationDescriptor(); + newApp->name = oldApp->name; + newApp->comment = oldApp->comment; + newApp->targets = oldApp->targets; + newApp->variables = descriptor.variables; + newApp->variables.insert(oldApp->variables.begin(), oldApp->variables.end()); + StringSeq::const_iterator p; + for(p = descriptor.removeVariables.begin(); p != descriptor.removeVariables.end(); ++p) + { + newApp->variables.erase(*p); + } + + newApp->serverTemplates = descriptor.serverTemplates; + newApp->serverTemplates.insert(oldApp->serverTemplates.begin(), oldApp->serverTemplates.end()); + for(p = descriptor.removeServerTemplates.begin(); p != descriptor.removeServerTemplates.end(); ++p) + { + newApp->serverTemplates.erase(*p); + } + + newApp->serviceTemplates = descriptor.serviceTemplates; + newApp->serviceTemplates.insert(oldApp->serviceTemplates.begin(), oldApp->serviceTemplates.end()); + for(p = descriptor.removeServiceTemplates.begin(); p != descriptor.removeServiceTemplates.end(); ++p) + { + newApp->serviceTemplates.erase(*p); + } + + newApp->servers = descriptor.servers; + set<string> remove(descriptor.removeServers.begin(), descriptor.removeServers.end()); + set<string> updated; + for_each(newApp->servers.begin(), newApp->servers.end(), AddServerName(updated)); + for(InstanceDescriptorSeq::const_iterator q = oldApp->servers.begin(); q != oldApp->servers.end(); ++q) + { + if(updated.find(q->descriptor->name) == updated.end() && remove.find(q->descriptor->name) == remove.end()) + { + newApp->servers.push_back(*q); + } + } + + newApp->nodes = descriptor.nodes; + for(NodeDescriptorSeq::const_iterator q = oldApp->nodes.begin(); q != oldApp->nodes.end(); ++q) + { + NodeDescriptorSeq::const_iterator r; + for(r = descriptor.nodes.begin(); r != descriptor.nodes.end(); ++r) + { + if(q->name == r->name) + { + break; + } + } + if(r == descriptor.nodes.end()) + { + newApp->nodes.push_back(*q); + } + } + + _database->updateApplicationDescriptor(newApp); +} + +void AdminI::removeApplication(const string& name, const Current&) { _database->removeApplicationDescriptor(name); diff --git a/cpp/src/IceGrid/AdminI.h b/cpp/src/IceGrid/AdminI.h index 16f412b8d44..b2320cfbb74 100644 --- a/cpp/src/IceGrid/AdminI.h +++ b/cpp/src/IceGrid/AdminI.h @@ -26,7 +26,8 @@ public: virtual ~AdminI(); virtual void addApplication(const ApplicationDescriptorPtr&, const Ice::Current&); - virtual void updateApplication(const ApplicationDescriptorPtr&, const Ice::Current&); + virtual void syncApplication(const ApplicationDescriptorPtr&, const Ice::Current&); + virtual void updateApplication(const ApplicationUpdateDescriptor&, const Ice::Current&); virtual void removeApplication(const std::string&, const Ice::Current&); virtual ApplicationDescriptorPtr getApplicationDescriptor(const ::std::string&, const Ice::Current&) const; virtual void instantiateServer(const std::string&, const std::string&, const std::string&, const StringStringDict&, diff --git a/cpp/src/IceGrid/Database.cpp b/cpp/src/IceGrid/Database.cpp index 58580a3bd0b..dbd3c058a65 100644 --- a/cpp/src/IceGrid/Database.cpp +++ b/cpp/src/IceGrid/Database.cpp @@ -403,7 +403,7 @@ Database::updateApplicationDescriptor(const ApplicationDescriptorPtr& newDesc) if(_traceLevels->application > 0) { Ice::Trace out(_traceLevels->logger, _traceLevels->applicationCat); - out << "updated application `" << newDesc->name << "'"; + out << "synced application `" << newDesc->name << "'"; } for_each(entries.begin(), entries.end(), IceUtil::voidMemFun(&Database::ServerEntry::sync)); diff --git a/cpp/src/IceGrid/Parser.cpp b/cpp/src/IceGrid/Parser.cpp index 2d4feb1d44c..114569ebd2b 100644 --- a/cpp/src/IceGrid/Parser.cpp +++ b/cpp/src/IceGrid/Parser.cpp @@ -857,7 +857,7 @@ Parser::updateApplication(const list<string>& args) } } - _admin->updateApplication(DescriptorParser::parseDescriptor(descriptor, targets, vars, _communicator)); + _admin->syncApplication(DescriptorParser::parseDescriptor(descriptor, targets, vars, _communicator)); } catch(const IceXML::ParserException& ex) { @@ -1135,7 +1135,10 @@ Parser::addServer(const list<string>& args) } } - _admin->addServer(DescriptorParser::parseDescriptor(descriptor, targets, vars, _communicator)); + // + // TODO + // + //_admin->addServer(DescriptorParser::parseDescriptor(descriptor, targets, vars, _communicator)); } catch(const DeploymentException& ex) { diff --git a/cpp/test/IceGrid/deployer/AllTests.cpp b/cpp/test/IceGrid/deployer/AllTests.cpp index 519623497fa..c596a5d3160 100644 --- a/cpp/test/IceGrid/deployer/AllTests.cpp +++ b/cpp/test/IceGrid/deployer/AllTests.cpp @@ -17,6 +17,7 @@ using namespace std; using namespace Test; +using namespace IceGrid; struct ProxyIdentityEqual : public std::binary_function<Ice::ObjectPrx,string,bool> { @@ -33,7 +34,7 @@ public: void allCommonTests(const Ice::CommunicatorPtr& communicator) { - IceGrid::AdminPrx admin = IceGrid::AdminPrx::checkedCast(communicator->stringToProxy("IceGrid/Admin")); + AdminPrx admin = AdminPrx::checkedCast(communicator->stringToProxy("IceGrid/Admin")); test(admin); cout << "test server registration... " << flush; @@ -54,7 +55,7 @@ allCommonTests(const Ice::CommunicatorPtr& communicator) test(find(adapterIds.begin(), adapterIds.end(), "IceBox2Service2Adapter") != adapterIds.end()); cout << "ok" << endl; - IceGrid::QueryPrx query = IceGrid::QueryPrx::checkedCast(communicator->stringToProxy("IceGrid/Query")); + QueryPrx query = QueryPrx::checkedCast(communicator->stringToProxy("IceGrid/Query")); test(query); cout << "testing object registration... " << flush; @@ -78,7 +79,7 @@ allCommonTests(const Ice::CommunicatorPtr& communicator) { Ice::ObjectPrx obj = query->findObjectByType("::Foo"); } - catch(const IceGrid::ObjectNotExistException&) + catch(const ObjectNotExistException&) { } @@ -152,9 +153,6 @@ allTests(const Ice::CommunicatorPtr& communicator, bool withTemplates) test(obj->getProperty("Service2.DebugProperty") == ""); test(obj->getProperty("Service1.DebugProperty") == ""); - IceGrid::AdminPrx admin = IceGrid::AdminPrx::checkedCast(communicator->stringToProxy("IceGrid/Admin")); - test(admin); - cout << "ok" << endl; cout << "testing server options... " << flush; @@ -164,6 +162,163 @@ allTests(const Ice::CommunicatorPtr& communicator, bool withTemplates) test(obj->getProperty("Test.Test1") == "0"); cout << "ok" << endl; + + cout << "testing application update..." << flush; + AdminPrx admin = AdminPrx::checkedCast(communicator->stringToProxy("IceGrid/Admin")); + test(admin); + + admin->stopServer("Server1"); + admin->stopServer("Server2"); + admin->stopServer("IceBox1"); + admin->stopServer("IceBox2"); + + // + // Update the application + // + ApplicationDescriptorPtr application = admin->getApplicationDescriptor("test"); + + InstanceDescriptorSeq::iterator svr1; + InstanceDescriptor server1; + InstanceDescriptor server2; + InstanceDescriptor icebox1; + InstanceDescriptor icebox2; + + for(InstanceDescriptorSeq::iterator p = application->servers.begin(); p != application->servers.end(); ++p) + { + if(p->descriptor->name == "Server1") + { + svr1 = p; + server1 = *p; + } + else if(p->descriptor->name == "Server2") + { + server2 = *p; + ServerDescriptorPtr server = ServerDescriptorPtr::dynamicCast(p->descriptor); + assert(server); + for(PropertyDescriptorSeq::iterator r = server->properties.begin(); r != server->properties.end(); ++r) + { + if(r->name == "Type") + { + r->value = "ServerUpdated"; + } + } + } + else if(p->descriptor->name == "IceBox1") + { + icebox1 = *p; + icebox1.descriptor = ComponentDescriptorPtr::dynamicCast(icebox1.descriptor->ice_clone()); + IceBoxDescriptorPtr iceBox = IceBoxDescriptorPtr::dynamicCast(p->descriptor); + assert(iceBox); + for(InstanceDescriptorSeq::iterator r = iceBox->services.begin(); r != iceBox->services.end(); ++r) + { + if(r->descriptor->name == "Service1") + { + iceBox->services.erase(r); + break; + } + } + } + else if(p->descriptor->name == "IceBox2") + { + icebox2 = *p; + icebox2.descriptor = ComponentDescriptorPtr::dynamicCast(icebox2.descriptor->ice_clone()); + IceBoxDescriptorPtr iceBox = IceBoxDescriptorPtr::dynamicCast(p->descriptor); + assert(iceBox); + for(InstanceDescriptorSeq::iterator r = iceBox->services.begin(); r != iceBox->services.end(); ++r) + { + if(r->descriptor->name == "Service2") + { + assert(!r->descriptor->dbEnvs.empty()); + r->descriptor = ComponentDescriptorPtr::dynamicCast(r->descriptor->ice_clone()); + r->descriptor->dbEnvs.clear(); + } + } + } + } + + application->servers.erase(svr1); + + try + { + admin->syncApplication(application); + } + catch(const Ice::LocalException&) + { + test(false); + } + + try + { + admin->startServer("Server1"); // Ensure Server1 was removed. + test(false); + } + catch(const ServerNotExistException&) + { + } + + obj = TestIntfPrx::checkedCast(communicator->stringToProxy("Server2@Server2.Server")); + test(obj->getProperty("Type") == "ServerUpdated"); // Ensure Server2 configuration was updated. + + try + { + // + // Ensure the service 1 of the IceBox1 server is gone. + // + obj = TestIntfPrx::checkedCast(communicator->stringToProxy("IceBox1-Service1@IceBox1.Service1.Service1")); + } + catch(const Ice::NotRegisteredException&) + { + } + + // + // Make sure the database environment of Service2 of IceBox2 was removed. + // + obj = TestIntfPrx::checkedCast(communicator->stringToProxy("IceBox1-Service2@IceBox1Service2Adapter")); + test(!obj->getProperty("Freeze.DbEnv.Service2.DbHome").empty()); + + obj = TestIntfPrx::checkedCast(communicator->stringToProxy("IceBox2-Service2@IceBox2Service2Adapter")); + test(obj->getProperty("Freeze.DbEnv.Service2.DbHome").empty()); + + // + // Make sure the IceBox server is totally started before to shut it down. + // + communicator->stringToProxy("IceBox2/ServiceManager@IceBox2.IceBox.ServiceManager")->ice_ping(); + + admin->stopServer("Server2"); + admin->stopServer("IceBox1"); + admin->stopServer("IceBox2"); + + ApplicationUpdateDescriptor update; + update.name = "test"; + update.servers.push_back(server1); + update.removeServers.push_back(server2.descriptor->name); + update.servers.push_back(icebox1); + update.servers.push_back(icebox2); + + admin->updateApplication(update); + + admin->startServer("Server1"); // Ensure Server1 is back. + try + { + admin->startServer("Server2"); // Ensure Server2 was removed. + test(false); + } + catch(const ServerNotExistException&) + { + } + + // + // Ensure the service 1 of the IceBox1 server is back. + // + obj = TestIntfPrx::checkedCast(communicator->stringToProxy("IceBox1-Service1@IceBox1.Service1.Service1")); + + // + // Make sure the database environment of Service2 of IceBox2 is back. + // + obj = TestIntfPrx::checkedCast(communicator->stringToProxy("IceBox2-Service2@IceBox2Service2Adapter")); + test(!obj->getProperty("Freeze.DbEnv.Service2.DbHome").empty()); + + cout << "ok" << endl; } void @@ -171,14 +326,13 @@ allTestsWithTarget(const Ice::CommunicatorPtr& communicator) { allCommonTests(communicator); - IceGrid::AdminPrx admin = IceGrid::AdminPrx::checkedCast( - communicator->stringToProxy("IceGrid/Admin")); + AdminPrx admin = AdminPrx::checkedCast(communicator->stringToProxy("IceGrid/Admin")); test(admin); cout << "pinging server objects... " << flush; TestIntfPrx obj; - admin->setServerActivation("Server1", IceGrid::Manual); + admin->setServerActivation("Server1", Manual); try { obj = TestIntfPrx::checkedCast(communicator->stringToProxy("Server1@Server1.Server")); |