void ServiceI::start( const string& name, const CommunicatorPtr& communicator, const StringSeq& /*args*/) { PropertiesPtr properties = communicator->getProperties(); validateProperties(name, properties, communicator->getLogger()); int id = properties->getPropertyAsIntWithDefault(name + ".NodeId", -1); // If we are using a replicated deployment and if the topic // manager thread pool max size is not set then ensure it is set // to some suitably high number. This ensures no deadlocks in the // replicated case due to call forwarding from replicas to // coordinators. if(id != -1 && properties->getProperty(name + ".TopicManager.ThreadPool.SizeMax").empty()) { properties->setProperty(name + ".TopicManager.ThreadPool.SizeMax", "100"); } Ice::ObjectAdapterPtr topicAdapter = communicator->createObjectAdapter(name + ".TopicManager"); Ice::ObjectAdapterPtr publishAdapter = communicator->createObjectAdapter(name + ".Publish"); // // We use the name of the service for the name of the database environment. // string instanceName = properties->getPropertyWithDefault(name + ".InstanceName", "IceStorm"); Identity topicManagerId; topicManagerId.category = instanceName; topicManagerId.name = "TopicManager"; if(properties->getPropertyAsIntWithDefault(name+ ".Transient", 0) > 0) { _instance = new Instance(instanceName, name, communicator, publishAdapter, topicAdapter, 0); try { TransientTopicManagerImplPtr manager = new TransientTopicManagerImpl(_instance); _managerProxy = TopicManagerPrx::uncheckedCast(topicAdapter->add(manager, topicManagerId)); } catch(const Ice::Exception& ex) { _instance = 0; LoggerOutputBase s; s << "exception while starting IceStorm service " << name << ":\n"; s << ex; IceBox::FailureException e(__FILE__, __LINE__); e.reason = s.str(); throw e; } topicAdapter->activate(); publishAdapter->activate(); return; } if(id == -1) // No replication. { _instance = new Instance(instanceName, name, communicator, publishAdapter, topicAdapter); try { _manager = new TopicManagerImpl(_instance); _managerProxy = TopicManagerPrx::uncheckedCast(topicAdapter->add(_manager->getServant(), topicManagerId)); } catch(const Ice::Exception& ex) { _instance = 0; LoggerOutputBase s; s << "exception while starting IceStorm service " << name << ":\n"; s << ex; IceBox::FailureException e(__FILE__, __LINE__); e.reason = s.str(); throw e; } } else { // Here we want to create a map of id -> election node // proxies. map<int, NodePrx> nodes; string topicManagerAdapterId = properties->getProperty(name + ".TopicManager.AdapterId"); // We support two possible deployments. The first is a manual // deployment, the second is IceGrid. // // Here we check for the manual deployment const string prefix = name + ".Nodes."; Ice::PropertyDict props = properties->getPropertiesForPrefix(prefix); if(!props.empty()) { for(Ice::PropertyDict::const_iterator p = props.begin(); p != props.end(); ++p) { int nodeid = atoi(p->first.substr(prefix.size()).c_str()); nodes[nodeid] = NodePrx::uncheckedCast(communicator->propertyToProxy(p->first)); } } else { // If adapter id's are defined for the topic manager or // node adapters then we consider this an IceGrid based // deployment. string nodeAdapterId = properties->getProperty(name + ".Node.AdapterId"); // Validate first that the adapter ids match for the node // and the topic manager otherwise some other deployment // is being used. const string suffix = ".TopicManager"; if(topicManagerAdapterId.empty() || nodeAdapterId.empty() || topicManagerAdapterId.replace( topicManagerAdapterId.find(suffix), suffix.size(), ".Node") != nodeAdapterId) { Ice::Error error(communicator->getLogger()); error << "deployment error: `" << topicManagerAdapterId << "' prefix does not match `" << nodeAdapterId << "'"; throw IceBox::FailureException(__FILE__, __LINE__, "IceGrid deployment is incorrect"); } // Determine the set of node id and node proxies. // // This is determined by locating all topic manager // replicas, and then working out the node for that // replica. // // We work out the node id by removing the instance // name. The node id must follow. // IceGrid::LocatorPrx locator = IceGrid::LocatorPrx::checkedCast(communicator->getDefaultLocator()); assert(locator); IceGrid::QueryPrx query = locator->getLocalQuery(); Ice::ObjectProxySeq replicas = query->findAllReplicas( communicator->stringToProxy(instanceName + "/TopicManager")); for(Ice::ObjectProxySeq::const_iterator p = replicas.begin(); p != replicas.end(); ++p) { string adapterid = (*p)->ice_getAdapterId(); // Replace TopicManager with the node endpoint. adapterid = adapterid.replace(adapterid.find(suffix), suffix.size(), ".Node"); // The adapter id must start with the instance name. if(adapterid.find(instanceName) != 0) { Ice::Error error(communicator->getLogger()); error << "deployment error: `" << adapterid << "' does not start with `" << instanceName << "'"; throw IceBox::FailureException(__FILE__, __LINE__, "IceGrid deployment is incorrect"); } // The node id follows. We find the first digit (the // start of the node id, and then the end of the // digits). string::size_type start = instanceName.size(); while(start < adapterid.size() && !IceUtilInternal::isDigit(adapterid[start])) { ++start; } string::size_type end = start; while(end < adapterid.size() && IceUtilInternal::isDigit(adapterid[end])) { ++end; } if(start == end) { // We must have at least one digit, otherwise there is // some sort of deployment error. Ice::Error error(communicator->getLogger()); error << "deployment error: node id does not follow instance name. instance name:" << instanceName << " adapter id: " << adapterid; throw IceBox::FailureException(__FILE__, __LINE__, "IceGrid deployment is incorrect"); } int nodeid = atoi(adapterid.substr(start, end-start).c_str()); ostringstream os; os << "node" << nodeid; Ice::Identity id; id.category = instanceName; id.name = os.str(); nodes[nodeid] = NodePrx::uncheckedCast((*p)->ice_adapterId(adapterid)->ice_identity(id)); } } if(nodes.size() < 3) { Ice::Error error(communicator->getLogger()); error << "Replication requires at least 3 Nodes"; throw IceBox::FailureException(__FILE__, __LINE__, "Replication requires at least 3 Nodes"); } try { // If the node thread pool size is not set then initialize // to the number of nodes + 1 and disable thread pool size // warnings. if(properties->getProperty(name + ".Node.ThreadPool.Size").empty()) { ostringstream os; os << nodes.size() + 1; properties->setProperty(name + ".Node.ThreadPool.Size", os.str()); properties->setProperty(name + ".Node.ThreadPool.SizeWarn", "0"); } if(properties->getProperty(name + ".Node.MessageSizeMax").empty()) { properties->setProperty(name + ".Node.MessageSizeMax", "0"); // No limit on data exchanged internally } Ice::ObjectAdapterPtr nodeAdapter = communicator->createObjectAdapter(name + ".Node"); _instance = new Instance(instanceName, name, communicator, publishAdapter, topicAdapter, nodeAdapter, nodes[id]); _instance->observers()->setMajority(static_cast<unsigned int>(nodes.size())/2); // Trace replication information. TraceLevelsPtr traceLevels = _instance->traceLevels(); if(traceLevels->election > 0) { Ice::Trace out(traceLevels->logger, traceLevels->electionCat); out << "I am node " << id << "\n"; for(map<int, NodePrx>::const_iterator p = nodes.begin(); p != nodes.end(); ++p) { out << "\tnode: " << p->first << " proxy: " << p->second->ice_toString() << "\n"; } } if(topicManagerAdapterId.empty()) { // We're not using an IceGrid deployment. Here we need // a proxy which is used to create proxies to the // replicas later. _managerProxy = TopicManagerPrx::uncheckedCast(topicAdapter->createProxy(topicManagerId)); } else { // If we're using IceGrid deployment we need to create // indirect proxies. _managerProxy = TopicManagerPrx::uncheckedCast(topicAdapter->createIndirectProxy(topicManagerId)); } _manager = new TopicManagerImpl(_instance); topicAdapter->add(_manager->getServant(), topicManagerId); ostringstream os; // The node object identity. os << "node" << id; Ice::Identity nodeid; nodeid.category = instanceName; nodeid.name = os.str(); NodeIPtr node = new NodeI(_instance, _manager, _managerProxy, id, nodes); _instance->setNode(node); nodeAdapter->add(node, nodeid); nodeAdapter->activate(); node->start(); } catch(const Ice::Exception& ex) { _instance = 0; LoggerOutputBase s; s << "exception while starting IceStorm service " << name << ":\n"; s << ex; IceBox::FailureException e(__FILE__, __LINE__); e.reason = s.str(); throw e; } } topicAdapter->add(new FinderI(TopicManagerPrx::uncheckedCast(topicAdapter->createProxy(topicManagerId))), communicator->stringToIdentity("IceStorm/Finder")); topicAdapter->activate(); publishAdapter->activate(); }
int PropsClient::run(int argc, char* argv[]) { if(argc > 1) { cerr << appName() << ": too many arguments" << endl; return EXIT_FAILURE; } PropsPrx props = PropsPrx::checkedCast(communicator()->propertyToProxy("Props.Proxy")); if(!props) { cerr << argv[0] << ": invalid proxy" << endl; return EXIT_FAILURE; } Ice::PropertiesAdminPrx admin = Ice::PropertiesAdminPrx::checkedCast(communicator()->propertyToProxy("Admin.Proxy")); Ice::PropertyDict batch1; batch1["Demo.Prop1"] = "1"; batch1["Demo.Prop2"] = "2"; batch1["Demo.Prop3"] = "3"; Ice::PropertyDict batch2; batch2["Demo.Prop1"] = "10"; batch2["Demo.Prop2"] = ""; // An empty value removes this property batch2["Demo.Prop3"] = "30"; show(admin); menu(); char c = 'x'; do { try { cout << "==> "; cin >> c; if(c == '1' || c == '2') { Ice::PropertyDict dict = c == '1' ? batch1 : batch2; cout << "Sending:" << endl; for(Ice::PropertyDict::iterator p = dict.begin(); p != dict.end(); ++p) { if(p->first.find("Demo") == 0) { cout << " " << p->first << "=" << p->second << endl; } } cout << endl; admin->setProperties(dict); cout << "Changes:" << endl; Ice::PropertyDict changes = props->getChanges(); if(changes.empty()) { cout << " None." << endl; } else { for(Ice::PropertyDict::iterator p = changes.begin(); p != changes.end(); ++p) { cout << " " << p->first; if(p->second.empty()) { cout << " was removed" << endl; } else { cout << " is now " << p->second << endl; } } } } else if(c == 'c') { show(admin); } else if(c == 's') { props->shutdown(); } else if(c == 'x') { // Nothing to do } else if(c == '?') { menu(); } else { cout << "unknown command `" << c << "'" << endl; menu(); } } catch(const Ice::Exception& ex) { cerr << ex << endl; } } while(cin.good() && c != 'x'); return EXIT_SUCCESS; }
void allTests(const Ice::CommunicatorPtr& communicator) { string ref = "DemoIceBox/admin:default -p 9996 -t 10000"; Ice::ObjectPrx admin = communicator->stringToProxy(ref); TestFacetPrx facet; cout << "testing custom facet... " << flush; { // // Test: Verify that the custom facet is present. // facet = Test::TestFacetPrx::checkedCast(admin, "TestFacet"); facet->ice_ping(); } cout << "ok" << endl; cout << "testing properties facet... " << flush; { Ice::PropertiesAdminPrx pa = Ice::PropertiesAdminPrx::checkedCast(admin, "IceBox.Service.TestService.Properties"); // // Test: PropertiesAdmin::getProperty() // test(pa->getProperty("Prop1") == "1"); test(pa->getProperty("Bogus") == ""); // // Test: PropertiesAdmin::getProperties() // Ice::PropertyDict pd = pa->getPropertiesForPrefix(""); test(pd.size() == 5); test(pd["Prop1"] == "1"); test(pd["Prop2"] == "2"); test(pd["Prop3"] == "3"); test(pd["Ice.Config"] == "config.service"); test(pd["Ice.ProgramName"] == "IceBox-TestService"); Ice::PropertyDict changes; // // Test: PropertiesAdmin::setProperties() // Ice::PropertyDict setProps; setProps["Prop1"] = "10"; // Changed setProps["Prop2"] = "20"; // Changed setProps["Prop3"] = ""; // Removed setProps["Prop4"] = "4"; // Added setProps["Prop5"] = "5"; // Added pa->setProperties(setProps); test(pa->getProperty("Prop1") == "10"); test(pa->getProperty("Prop2") == "20"); test(pa->getProperty("Prop3") == ""); test(pa->getProperty("Prop4") == "4"); test(pa->getProperty("Prop5") == "5"); changes = facet->getChanges(); test(changes.size() == 5); test(changes["Prop1"] == "10"); test(changes["Prop2"] == "20"); test(changes["Prop3"] == ""); test(changes["Prop4"] == "4"); test(changes["Prop5"] == "5"); pa->setProperties(setProps); changes = facet->getChanges(); test(changes.empty()); } cout << "ok" << endl; cout << "testing metrics admin facet... " << flush; { IceMX::MetricsAdminPrx ma = IceMX::MetricsAdminPrx::checkedCast(admin, "IceBox.Service.TestService.Metrics"); Ice::PropertiesAdminPrx pa = Ice::PropertiesAdminPrx::checkedCast(admin, "IceBox.Service.TestService.Properties"); Ice::StringSeq views; Ice::StringSeq disabledViews; views = ma->getMetricsViewNames(disabledViews); test(views.empty()); Ice::PropertyDict setProps; setProps["IceMX.Metrics.Debug.GroupBy"] = "id"; setProps["IceMX.Metrics.All.GroupBy"] = "none"; setProps["IceMX.Metrics.Parent.GroupBy"] = "parent"; pa->setProperties(setProps); pa->setProperties(Ice::PropertyDict()); views = ma->getMetricsViewNames(disabledViews); test(views.size() == 3); // Make sure that the IceBox communicator metrics admin is a separate instance. test(IceMX::MetricsAdminPrx::checkedCast(admin, "Metrics")->getMetricsViewNames(disabledViews).empty()); } cout << "ok" << endl; }