16
16
#include <IceGrid/RegistryI.h>
17
17
#include <IceGrid/FileUserAccountMapperI.h>
18
18
#include <IceGrid/NodeI.h>
19
#include <IceGrid/NodeSessionManager.h>
19
20
#include <IceGrid/TraceLevels.h>
20
#include <IceGrid/DescriptorParser.h>
21
21
#ifdef __BCPLUSPLUS__
22
22
# include <IceGrid/ServerI.h>
23
23
# include <IceGrid/AdminSessionI.h>
24
24
# include <IceGrid/ReapThread.h>
25
25
# include <IceGrid/Database.h>
26
# include <IceGrid/WellKnownObjectsManager.h>
28
#include <IceGrid/DescriptorParser.h>
27
29
#include <IcePatch2/Util.h>
264
223
if(!nowarn && properties->getPropertyAsIntWithDefault("Ice.ThreadPool.Server.Size", 0) > 0)
266
Warning out(communicator()->getLogger());
267
out << "setting `Ice.ThreadPool.Server.Size' is not useful,\n";
268
out << "you should set individual adapter thread pools instead.";
225
Warning out(communicator()->getLogger());
226
out << "setting `Ice.ThreadPool.Server.Size' is not useful, ";
227
out << "you should set individual adapter thread pools instead.";
271
230
int size = properties->getPropertyAsIntWithDefault("IceGrid.Node.ThreadPool.Size", 0);
274
properties->setProperty("IceGrid.Node.ThreadPool.Size", "1");
233
properties->setProperty("IceGrid.Node.ThreadPool.Size", "1");
277
237
int sizeMax = properties->getPropertyAsIntWithDefault("IceGrid.Node.ThreadPool.SizeMax", 0);
287
properties->setProperty("IceGrid.Node.ThreadPool.SizeMax", os.str());
247
properties->setProperty("IceGrid.Node.ThreadPool.SizeMax", os.str());
250
size = properties->getPropertyAsIntWithDefault("Ice.ThreadPool.Client.Size", 0);
253
properties->setProperty("Ice.ThreadPool.Client.Size", "1");
256
sizeMax = properties->getPropertyAsIntWithDefault("Ice.ThreadPool.Client.SizeMax", 0);
269
properties->setProperty("Ice.ThreadPool.Client.SizeMax", os.str());
291
273
// Create the activator.
293
TraceLevelsPtr traceLevels = new TraceLevels(properties, communicator()->getLogger(), true);
294
_activator = new Activator(traceLevels, properties);
275
TraceLevelsPtr traceLevels = new TraceLevels(communicator(), "IceGrid.Node");
276
_activator = new Activator(traceLevels);
297
279
// Collocate the IceGrid registry if we need to.
308
// Set the Ice.Default.Locator property to point to the
309
// collocated locator (this property is passed by the
310
// activator to each activated server).
290
// Set the default locator property to point to the collocated
291
// locator (this property is passed by the activator to each
292
// activated server). The default locator is also needed by
293
// the node session manager.
312
const string instanceNameProperty = "IceGrid.InstanceName";
314
locatorId.category = properties->getPropertyWithDefault(instanceNameProperty, "IceGrid");
315
locatorId.name = "Locator";
316
string locatorPrx = "\"" + communicator()->identityToString(locatorId) + "\" :" +
317
properties->getProperty("IceGrid.Registry.Client.Endpoints");
318
properties->setProperty("Ice.Default.Locator", locatorPrx);
295
if(properties->getProperty("Ice.Default.Locator").empty())
298
locatorId.category = properties->getPropertyWithDefault("IceGrid.InstanceName", "IceGrid");
299
locatorId.name = "Locator";
300
string endpoints = properties->getProperty("IceGrid.Registry.Client.Endpoints");
301
string locatorPrx = "\"" + communicator()->identityToString(locatorId) + "\" :" + endpoints;
302
communicator()->setDefaultLocator(LocatorPrx::uncheckedCast(communicator()->stringToProxy(locatorPrx)));
303
properties->setProperty("Ice.Default.Locator", locatorPrx);
320
306
else if(properties->getProperty("Ice.Default.Locator").empty())
339
325
struct _stat filestat;
340
326
if(::_stat(dataPath.c_str(), &filestat) != 0 || !S_ISDIR(filestat.st_mode))
343
FileException ex(__FILE__, __LINE__);
345
ex.error = getSystemErrno();
329
FileException ex(__FILE__, __LINE__);
331
ex.error = getSystemErrno();
347
333
error("property `IceGrid.Node.Data' is set to an invalid path:\n" + os.str());
351
337
struct stat filestat;
352
338
if(::stat(dataPath.c_str(), &filestat) != 0 || !S_ISDIR(filestat.st_mode))
355
FileException ex(__FILE__, __LINE__);
357
ex.error = getSystemErrno();
341
FileException ex(__FILE__, __LINE__);
343
ex.error = getSystemErrno();
359
345
error("property `IceGrid.Node.Data' is set to an invalid path:\n" + os.str());
422
393
// Setup the user account mapper if configured.
424
string mapperProperty = properties->getProperty("IceGrid.Node.UserAccountMapper");
395
string mapperProperty = "IceGrid.Node.UserAccountMapper";
396
string mapperPropertyValue = properties->getProperty(mapperProperty);
425
397
UserAccountMapperPrx mapper;
426
if(!mapperProperty.empty())
398
if(!mapperPropertyValue.empty())
430
mapper = UserAccountMapperPrx::uncheckedCast(communicator()->stringToProxy(mapperProperty));
432
catch(const Ice::LocalException& ex)
435
os << "user account mapper `" << mapperProperty << "' is invalid:\n" << ex;
402
mapper = UserAccountMapperPrx::uncheckedCast(communicator()->propertyToProxy(mapperProperty));
404
catch(const Ice::LocalException& ex)
407
os << "user account mapper `" << mapperProperty << "' is invalid:\n" << ex;
442
string userAccountFileProperty = properties->getProperty("IceGrid.Node.UserAccounts");
443
if(!userAccountFileProperty.empty())
447
Ice::ObjectPrx object = _adapter->addWithUUID(new FileUserAccountMapperI(userAccountFileProperty));
448
object = object->ice_collocationOptimized(true);
449
mapper = UserAccountMapperPrx::uncheckedCast(object);
451
catch(const std::string& msg)
414
string userAccountFileProperty = properties->getProperty("IceGrid.Node.UserAccounts");
415
if(!userAccountFileProperty.empty())
419
Ice::ObjectPrx object = _adapter->addWithUUID(new FileUserAccountMapperI(userAccountFileProperty));
420
object = object->ice_collocationOptimized(true);
421
mapper = UserAccountMapperPrx::uncheckedCast(object);
423
catch(const std::string& msg)
463
435
_waitQueue->start();
438
// The IceGrid instance name.
440
const string instanceName = communicator()->getDefaultLocator()->ice_getIdentity().category;
466
443
// Create the server factory. The server factory creates persistent objects
467
444
// for the server and server adapter. It also takes care of installing the
468
445
// evictors and object factories necessary to store these objects.
470
Identity id = communicator()->stringToIdentity(IceUtil::generateUUID());
447
Identity id = communicator()->stringToIdentity(instanceName + "/Node-" + name);
471
448
NodePrx nodeProxy = NodePrx::uncheckedCast(_adapter->createProxy(id));
472
_node = new NodeI(_adapter, _activator, _waitQueue, traceLevels, nodeProxy, name, mapper);
449
_node = new NodeI(_adapter, _sessions, _activator, _waitQueue, traceLevels, nodeProxy, name, mapper);
473
450
_adapter->add(_node, nodeProxy->ice_getIdentity());
476
// Start the keep alive thread. By default we start the thread
477
// with a 5s timeout, then we'll use the registry node session
480
_keepAliveThread = new KeepAliveThread(_node, 5);
481
_keepAliveThread->start();
453
// Start the platform info thread if needed.
455
_node->getPlatformInfo().start();
458
// Create the node sessions with the registries.
460
_sessions.create(_node);
484
463
// Add a process servant to allow shutdown through the process
487
466
if(!properties->getProperty("Ice.ServerId").empty() && communicator()->getDefaultLocator())
491
ProcessPrx proxy = ProcessPrx::uncheckedCast(_adapter->addWithUUID(new ProcessI(_activator)));
492
LocatorRegistryPrx locatorRegistry = communicator()->getDefaultLocator()->getRegistry();
493
locatorRegistry->setServerProcessProxy(properties->getProperty("Ice.ServerId"), proxy);
495
catch(const ServerNotFoundException&)
498
catch(const LocalException&)
470
ProcessPrx proxy = ProcessPrx::uncheckedCast(_adapter->addWithUUID(new ProcessI(_activator)));
471
LocatorRegistryPrx locatorRegistry = communicator()->getDefaultLocator()->getRegistry();
472
locatorRegistry->setServerProcessProxy(properties->getProperty("Ice.ServerId"), proxy);
474
catch(const ServerNotFoundException&)
477
catch(const LocalException&)
511
490
_adapter->activate();
493
// Notify the node session manager that the node can start
494
// accepting incoming connections.
496
_sessions.activate();
498
string bundleName = properties->getProperty("IceGrid.Node.PrintServersReady");
499
if(!bundleName.empty() || !desc.empty())
502
if(!_sessions.waitForCreate())
505
// Create was interrupted, return true as if the service was
506
// correctly initiliazed to make sure it's properly stopped.
514
514
// Deploy application if a descriptor is passed as a command-line option.
516
516
if(!desc.empty())
521
const string instanceNameProperty = "IceGrid.InstanceName";
523
adminId.category = properties->getPropertyWithDefault(instanceNameProperty, "IceGrid");
524
adminId.name = "Admin";
525
admin = AdminPrx::checkedCast(
526
communicator()->stringToProxy("\"" + communicator()->identityToString(adminId) + "\""));
520
Ice::Identity registryId;
521
registryId.category = instanceName;
522
registryId.name = "Registry";
524
RegistryPrx registry = RegistryPrx::checkedCast(
525
communicator()->stringToProxy("\"" + communicator()->identityToString(registryId) + "\""));
528
throw "invalid registry";
532
// Use SSL if available.
536
registry = RegistryPrx::checkedCast(registry->ice_secure(true));
538
catch(const Ice::NoEndpointException&)
542
IceGrid::AdminSessionPrx session;
543
if(communicator()->getProperties()->getPropertyAsInt("IceGridAdmin.AuthenticateUsingSSL"))
545
session = registry->createAdminSessionFromSecureConnection();
549
string id = communicator()->getProperties()->getProperty("IceGridAdmin.Username");
550
string password = communicator()->getProperties()->getProperty("IceGridAdmin.Password");
553
cout << "user id: " << flush;
560
cout << "password: " << flush;
561
getline(cin, password);
562
password = trim(password);
565
session = registry->createAdminSession(id, password);
569
AdminPrx admin = session->getAdmin();
570
map<string, string> vars;
571
ApplicationDescriptor app = DescriptorParser::parseDescriptor(desc, targets, vars, communicator(), admin);
575
admin->syncApplication(app);
577
catch(const ApplicationNotExistException&)
579
admin->addApplication(app);
582
catch(const DeploymentException& ex)
585
ostr << "failed to deploy application `" << desc << "':\n" << ex << ": " << ex.reason;
588
catch(const AccessDeniedException& ex)
591
ostr << "failed to deploy application `" << desc << "':\n"
592
<< "registry database is locked by `" << ex.lockUserId << "'";
528
595
catch(const LocalException& ex)
530
597
ostringstream ostr;
531
ostr << "couldn't contact IceGrid admin interface to deploy application `" << desc << "':\n" << ex;
598
ostr << "failed to deploy application `" << desc << "':\n" << ex;
532
599
warning(ostr.str());
601
catch(const string& reason)
539
map<string, string> vars;
540
ApplicationDescriptor app;
541
app = DescriptorParser::parseDescriptor(desc, targets, vars, communicator(), admin);
544
admin->syncApplication(app);
546
catch(const ApplicationNotExistException&)
548
admin->addApplication(app);
551
catch(const DeploymentException& ex)
554
ostr << "failed to deploy application `" << desc << "':\n" << ex << ": " << ex.reason;
557
catch(const LocalException& ex)
560
ostr << "failed to deploy application `" << desc << "':\n" << ex;
604
ostr << "failed to deploy application `" << desc << "':\n" << reason;
566
string bundleName = properties->getProperty("IceGrid.Node.PrintServersReady");
567
609
if(!bundleName.empty())
570
// We wait for the node to be registered with the registry
571
// before to claim it's ready.
573
_node->waitForSession();
574
print(bundleName + " ready");
611
print(bundleName + " ready");
697
733
NodeService::usage(const string& appName)
701
"-h, --help Show this message.\n"
702
"-v, --version Display the Ice version.\n"
703
"--nowarn Don't print any security warnings.\n"
705
"--deploy DESCRIPTOR [TARGET1 [TARGET2 ...]]\n"
706
" Add or update descriptor in file DESCRIPTOR, with\n"
707
" optional targets.\n";
737
"-h, --help Show this message.\n"
738
"-v, --version Display the Ice version.\n"
739
"--nowarn Don't print any security warnings.\n"
741
"--deploy DESCRIPTOR [TARGET1 [TARGET2 ...]]\n"
742
" Add or update descriptor in file DESCRIPTOR, with\n"
743
" optional targets.\n";
709
745
if(checkSystem())
714
"--service NAME Run as the Windows service NAME.\n"
716
"--install NAME [--display DISP] [--executable EXEC] [args]\n"
717
" Install as Windows service NAME. If DISP is\n"
718
" provided, use it as the display name,\n"
719
" otherwise NAME is used. If EXEC is provided,\n"
720
" use it as the service executable, otherwise\n"
721
" this executable is used. Any additional\n"
722
" arguments are passed unchanged to the\n"
723
" service at startup.\n"
724
"--uninstall NAME Uninstall Windows service NAME.\n"
725
"--start NAME [args] Start Windows service NAME. Any additional\n"
726
" arguments are passed unchanged to the\n"
728
"--stop NAME Stop Windows service NAME."
750
"--service NAME Run as the Windows service NAME.\n"
752
"--install NAME [--display DISP] [--executable EXEC] [args]\n"
753
" Install as Windows service NAME. If DISP is\n"
754
" provided, use it as the display name,\n"
755
" otherwise NAME is used. If EXEC is provided,\n"
756
" use it as the service executable, otherwise\n"
757
" this executable is used. Any additional\n"
758
" arguments are passed unchanged to the\n"
759
" service at startup.\n"
760
"--uninstall NAME Uninstall Windows service NAME.\n"
761
"--start NAME [args] Start Windows service NAME. Any additional\n"
762
" arguments are passed unchanged to the\n"
764
"--stop NAME Stop Windows service NAME."
735
771
"--daemon Run as a daemon.\n"
736
772
"--noclose Do not close open file descriptors.\n"
737
"--nochdir Do not change the current working directory."
773
"--nochdir Do not change the current working directory.\n"
774
"--pidfile FILE Write process ID into FILE."
740
777
print("Usage: " + appName + " [options]\n" + options);
781
NodeService::trim(const string& s)
783
static const string delims = "\t\r\n ";
784
string::size_type last = s.find_last_not_of(delims);
785
if(last != string::npos)
787
return s.substr(s.find_first_not_of(delims), last+1);
744
793
main(int argc, char* argv[])