summaryrefslogtreecommitdiff
path: root/cpp/src/IceGrid/Client.cpp
diff options
context:
space:
mode:
authorBenoit Foucher <benoit@zeroc.com>2014-07-10 14:16:59 +0200
committerBenoit Foucher <benoit@zeroc.com>2014-07-10 14:16:59 +0200
commit9962c1c90ddb9a0986bb98f84f2d97685203fce0 (patch)
treefef7973a98850f43f7118f65b8e8b8586286d987 /cpp/src/IceGrid/Client.cpp
parentFix background test. (diff)
downloadice-9962c1c90ddb9a0986bb98f84f2d97685203fce0.tar.bz2
ice-9962c1c90ddb9a0986bb98f84f2d97685203fce0.tar.xz
ice-9962c1c90ddb9a0986bb98f84f2d97685203fce0.zip
ICE-4612: first cut of the IceGrid discovery plugin and APIs
Diffstat (limited to 'cpp/src/IceGrid/Client.cpp')
-rw-r--r--cpp/src/IceGrid/Client.cpp247
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();