diff options
Diffstat (limited to 'cpp/src/IceGrid/Client.cpp')
-rw-r--r-- | cpp/src/IceGrid/Client.cpp | 247 |
1 files changed, 237 insertions, 10 deletions
diff --git a/cpp/src/IceGrid/Client.cpp b/cpp/src/IceGrid/Client.cpp index ed91c31f728..191d5749a88 100644 --- a/cpp/src/IceGrid/Client.cpp +++ b/cpp/src/IceGrid/Client.cpp @@ -21,6 +21,7 @@ #include <IceGrid/FileParserI.h> #include <IceGrid/Registry.h> #include <IceGrid/Locator.h> +#include <IceGrid/Discovery.h> #include <Glacier2/Router.h> #include <fstream> @@ -63,6 +64,74 @@ public: Init init; +class LookupReplyI : public LookupReply, private IceUtil::Monitor<IceUtil::Mutex> +{ +public: + + virtual void + foundLocator(const IceGrid::LocatorPrx& locator, const Ice::Current&) + { + Lock sync(*this); + for(vector<IceGrid::LocatorPrx>::iterator p = _locators.begin(); p != _locators.end(); ++p) + { + if((*p)->ice_getIdentity() == locator->ice_getIdentity()) + { + Ice::EndpointSeq newEndpoints = (*p)->ice_getEndpoints(); + Ice::EndpointSeq endpts = locator->ice_getEndpoints(); + for(Ice::EndpointSeq::const_iterator r = endpts.begin(); r != endpts.end(); ++r) + { + // + // Only add unknown endpoints + // + bool found = false; + for(Ice::EndpointSeq::const_iterator q = newEndpoints.begin(); q != newEndpoints.end(); ++q) + { + if(*r == *q) + { + found = true; + break; + } + } + if(!found) + { + newEndpoints.push_back(*r); + } + } + *p = (*p)->ice_endpoints(newEndpoints); + return; + } + } + _locators.push_back(locator); + notify(); + } + + vector<IceGrid::LocatorPrx> + getLocators() + { + Lock sync(*this); + return _locators; + } + + bool + waitForLocator() + { + Lock sync(*this); + while(_locators.empty()) + { + if(!timedWait(IceUtil::Time::milliSeconds(300))) + { + return false; + } + } + return true; + } + +private: + + vector<IceGrid::LocatorPrx> _locators; +}; +typedef IceUtil::Handle<LookupReplyI> LookupReplyIPtr; + } class SessionKeepAliveThread : public IceUtil::Thread, public IceUtil::Monitor<IceUtil::Mutex> @@ -211,6 +280,9 @@ Client::usage() "-e COMMANDS Execute COMMANDS.\n" "-d, --debug Print debug messages.\n" "-s, --server Start icegridadmin as a server (to parse XML files).\n" + "-i, --instanceName Connect to the registry with the given instance name.\n" + "-H, --host Connect to the registry at the given host.\n" + "-P, --port Connect to the registry running on the given port.\n" "-u, --username Login with the given username.\n" "-p, --password Login with the given password.\n" "-S, --ssl Authenticate through SSL.\n" @@ -229,6 +301,7 @@ Client::main(StringSeq& args) _appName = args[0]; InitializationData id; id.properties = createProperties(args); + id.properties->setProperty("Ice.Warn.Endpoints", "0"); _communicator = initialize(id); { @@ -332,6 +405,9 @@ Client::run(StringSeq& originalArgs) opts.addOpt("h", "help"); opts.addOpt("v", "version"); opts.addOpt("e", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat); + opts.addOpt("i", "instanceName", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::NoRepeat); + opts.addOpt("H", "host", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::NoRepeat); + opts.addOpt("P", "port", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::NoRepeat); opts.addOpt("u", "username", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::NoRepeat); opts.addOpt("p", "password", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::NoRepeat); opts.addOpt("S", "ssl"); @@ -407,6 +483,29 @@ Client::run(StringSeq& originalArgs) password = opts.optArg("password"); } + string host = communicator()->getProperties()->getProperty("IceGridAdmin.Host"); + if(!opts.optArg("host").empty()) + { + host = opts.optArg("host"); + } + + string instanceName = communicator()->getProperties()->getProperty("IceGridAdmin.InstaceName"); + if(!opts.optArg("instanceName").empty()) + { + instanceName = opts.optArg("instanceName"); + } + + int port = communicator()->getProperties()->getPropertyAsInt("IceGridAdmin.Port"); + if(!opts.optArg("port").empty()) + { + istringstream is(opts.optArg("port")); + if(!(is >> port)) + { + cerr << _appName << ": given port number is not a numeric value" << endl; + return EXIT_FAILURE; + } + } + PropertiesPtr properties = communicator()->getProperties(); string replica = properties->getProperty("IceGridAdmin.Replica"); if(!opts.optArg("replica").empty()) @@ -422,6 +521,141 @@ Client::run(StringSeq& originalArgs) { int sessionTimeout; int acmTimeout = 0; + if(!communicator()->getDefaultLocator() && !communicator()->getDefaultRouter()) + { + if(!host.empty()) + { + const int timeout = 3000; // 3s connection timeout. + ostringstream os; + os << "IceGridDiscovery/Lookup" << (ssl ? " -s" : ""); + os << ":tcp -h \"" << host << "\" -p " << (port == 0 ? 4061 : port) << " -t " << timeout; + os << ":ssl -h \"" << host << "\" -p " << (port == 0 ? 4063 : port) << " -t " << timeout; + LookupPrx lookup = LookupPrx::uncheckedCast(communicator()->stringToProxy(os.str())); + try + { + communicator()->setDefaultLocator(lookup->getLocator()); + } + catch(const Ice::LocalException&) + { + // Ignore. + } + if(!instanceName.empty() && + communicator()->getDefaultLocator()->ice_getIdentity().category != instanceName) + { + cerr << _appName << ": registry running on `" << host << "' uses a different instance name:\n"; + cerr << communicator()->getDefaultLocator()->ice_getIdentity().category << endl; + return EXIT_FAILURE; + } + } + else + { + bool ipv4 = properties->getPropertyAsIntWithDefault("Ice.IPv4", 1) > 0; + string address; + if(ipv4) + { + address = properties->getPropertyWithDefault("IceGridAdmin.Discovery.Address", "239.255.0.1"); + } + else + { + address = properties->getPropertyWithDefault("IceGridAdmin.Discovery.Address", "ff15::1"); + } + + string interface = properties->getProperty("IceGridAdmin.Discovery.Interface"); + + string lookupEndpoints = properties->getProperty("IceGridAdmin.Discovery.Lookup"); + if(lookupEndpoints.empty()) + { + ostringstream os; + os << "udp -h \"" << address << "\" -p " << (port == 0 ? 4061 : port); + if(!interface.empty()) + { + os << " --interface \"" << interface << "\""; + } + lookupEndpoints = os.str(); + } + + ObjectPrx prx = communicator()->stringToProxy("IceGridDiscovery/Lookup -d:" + lookupEndpoints); + LookupPrx lookupPrx = LookupPrx::uncheckedCast(prx->ice_collocationOptimized(false)); + + if(properties->getProperty("IceGridAdmin.Discovery.Reply.Endpoints").empty()) + { + ostringstream os; + os << "udp"; + if(!interface.empty()) + { + os << " -h \"" << interface << "\""; + } + properties->setProperty("IceGridAdmin.Discovery.Reply.Endpoints", os.str()); + } + + Ice::ObjectAdapterPtr adapter = communicator()->createObjectAdapter("IceGridAdmin.Discovery.Reply"); + adapter->activate(); + LookupReplyIPtr reply = new LookupReplyI(); + LookupReplyPrx replyPrx = LookupReplyPrx::uncheckedCast(adapter->addWithUUID(reply)->ice_datagram()); + int retryCount = 3; // Send several findLocator queries. + try + { + while(--retryCount >= 0) + { + lookupPrx->findLocator(instanceName, replyPrx); + if(instanceName.empty()) + { + IceUtil::ThreadControl::sleep(IceUtil::Time::milliSeconds(300)); + } + else if(reply->waitForLocator()) + { + break; + } + } + } + catch(const Ice::LocalException& ex) + { + cerr << _appName << ": registry discovery failed:\n" << ex << endl; + return EXIT_FAILURE; + } + adapter->destroy(); + + vector<IceGrid::LocatorPrx> locators = reply->getLocators(); + if(locators.size() > 1) + { + cout << "found " << locators.size() << " IceGrid locators:" << endl; + unsigned int num = 0; + for(vector<IceGrid::LocatorPrx>::const_iterator p = locators.begin(); p != locators.end(); ++p) + { + cout << ++num << ": proxy = `" << *p << "'" <<endl; + } + + num = 0; + while(num == 0 && cin.good()) + { + cout << "please enter the locator number to use: " << flush; + string line; + getline(cin, line); + if(!cin.good() || line.empty()) + { + return EXIT_FAILURE; + } + line = IceUtilInternal::trim(line); + + istringstream is(line); + is >> num; + if(num > locators.size()) + { + num = 0; + } + } + + assert(num <= locators.size()); + communicator()->setDefaultLocator(locators[num - 1]); + } + else if(locators.size() == 1) + { + cout << "using discovered locator:\nproxy = `" << locators[0] << "'" << endl; + communicator()->setDefaultLocator(locators[0]); + } + } + } + if(communicator()->getDefaultRouter()) { try @@ -476,11 +710,8 @@ Client::run(StringSeq& originalArgs) } session = AdminSessionPrx::uncheckedCast(router->createSession(id, password)); - // Zero the password string. - for(string::iterator p = password.begin(); p != password.end(); ++p) - { - *p = '\0'; - } + fill(password.begin(), password.end(), '\0'); // Zero the password string. + if(!session) { cerr << _appName @@ -631,11 +862,7 @@ Client::run(StringSeq& originalArgs) } session = registry->createAdminSession(id, password); - // Zero the password string. - for(string::iterator p = password.begin(); p != password.end(); ++p) - { - *p = '\0'; - } + fill(password.begin(), password.end(), '\0'); // Zero the password string. } sessionTimeout = registry->getSessionTimeout(); |