diff options
Diffstat (limited to 'cpp/src/IceGrid')
62 files changed, 13264 insertions, 8 deletions
diff --git a/cpp/src/IceGrid/Activator.cpp b/cpp/src/IceGrid/Activator.cpp new file mode 100644 index 00000000000..b01cbe326b1 --- /dev/null +++ b/cpp/src/IceGrid/Activator.cpp @@ -0,0 +1,1259 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <Ice/Ice.h> +#include <IceGrid/Activator.h> +#include <IceGrid/Admin.h> +#include <IceGrid/Internal.h> +#include <IceGrid/TraceLevels.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <signal.h> +#include <fcntl.h> + + +using namespace std; +using namespace Ice; +using namespace IceGrid; + +namespace IceGrid +{ + +class TerminationListenerThread : public IceUtil::Thread +{ +public: + + TerminationListenerThread(Activator& activator) : + _activator(activator) + { + } + + virtual + void run() + { + _activator.runTerminationListener(); + } + +private: + + Activator& _activator; +}; + +} + +#define ICE_STRING(X) #X + +namespace +{ + +#ifndef _WIN32 +// +// Helper function for async-signal safe error reporting +// +void +reportChildError(int err, int fd, const char* cannot, const char* name) +{ + // + // Send any errors to the parent process, using the write + // end of the pipe. + // + char msg[500]; + strcpy(msg, cannot); + strcat(msg, " `"); + strcat(msg, name); + strcat(msg, "': "); + strcat(msg, strerror(err)); + write(fd, msg, strlen(msg)); + close(fd); + + // + // _exit instead of exit to avoid interferences with the parent + // process. + // + _exit(EXIT_FAILURE); +} + +#endif + +#ifndef _WIN32 +string +signalToString(int signal) +{ + switch(signal) + { + case SIGHUP: + { + return ICE_STRING(SIGHUP); + } + case SIGINT: + { + return ICE_STRING(SIGINT); + } + case SIGQUIT: + { + return ICE_STRING(SIGQUIT); + } + case SIGILL: + { + return ICE_STRING(SIGILL); + } + case SIGTRAP: + { + return ICE_STRING(SIGTRAP); + } + case SIGABRT: + { + return ICE_STRING(SIGABRT); + } + case SIGBUS: + { + return ICE_STRING(SIGBUS); + } + case SIGFPE: + { + return ICE_STRING(SIGFPE); + } + case SIGKILL: + { + return ICE_STRING(SIGKILL); + } + case SIGUSR1: + { + return ICE_STRING(SIGUSR1); + } + case SIGSEGV: + { + return ICE_STRING(SIGSEGV); + } + case SIGPIPE: + { + return ICE_STRING(SIGPIPE); + } + case SIGALRM: + { + return ICE_STRING(SIGALRM); + } + case SIGTERM: + { + return ICE_STRING(SIGTERM); + } + default: + { + ostringstream os; + os << "signal " << signal; + return os.str(); + } + } +#endif +} + +int +stringToSignal(const string& str) +{ +#ifdef _WIN32 + throw BadSignalException(); +#else + + if(str == ICE_STRING(SIGHUP)) + { + return SIGHUP; + } + else if(str == ICE_STRING(SIGINT)) + { + return SIGINT; + } + else if(str == ICE_STRING(SIGQUIT)) + { + return SIGQUIT; + } + else if(str == ICE_STRING(SIGILL)) + { + return SIGILL; + } + else if(str == ICE_STRING(SIGTRAP)) + { + return SIGTRAP; + } + else if(str == ICE_STRING(SIGABRT)) + { + return SIGABRT; + } + else if(str == ICE_STRING(SIGBUS)) + { + return SIGBUS; + } + else if(str == ICE_STRING(SIGFPE)) + { + return SIGFPE; + } + else if(str == ICE_STRING(SIGKILL)) + { + return SIGKILL; + } + else if(str == ICE_STRING(SIGUSR1)) + { + return SIGUSR1; + } + else if(str == ICE_STRING(SIGSEGV)) + { + return SIGSEGV; + } + else if(str == ICE_STRING(SIGUSR2)) + { + return SIGUSR2; + } + else if(str == ICE_STRING(SIGPIPE)) + { + return SIGPIPE; + } + else if(str == ICE_STRING(SIGALRM)) + { + return SIGALRM; + } + else if(str == ICE_STRING(SIGTERM)) + { + return SIGTERM; + } + else + { + if(str != "") + { + char* end; + long int signal = strtol(str.c_str(), &end, 10); + if(*end == '\0' && signal > 0 && signal < 64) + { + return static_cast<int>(signal); + } + } + throw BadSignalException(); + } +} +#endif + +} + +Activator::Activator(const TraceLevelsPtr& traceLevels, const PropertiesPtr& properties) : + _traceLevels(traceLevels), + _properties(properties), + _deactivating(false) +{ +#ifdef _WIN32 + _hIntr = CreateEvent( + NULL, // Security attributes + TRUE, // Manual reset + FALSE, // Initial state is nonsignaled + NULL // Unnamed + ); + + if(_hIntr == NULL) + { + SyscallException ex(__FILE__, __LINE__); + ex.error = getSystemErrno(); + throw ex; + } +#else + int fds[2]; + if(pipe(fds) != 0) + { + SyscallException ex(__FILE__, __LINE__); + ex.error = getSystemErrno(); + throw ex; + } + _fdIntrRead = fds[0]; + _fdIntrWrite = fds[1]; + int flags = fcntl(_fdIntrRead, F_GETFL); + flags |= O_NONBLOCK; + fcntl(_fdIntrRead, F_SETFL, flags); +#endif + + _outputDir = _properties->getProperty("IceGrid.Node.Output"); + _redirectErrToOut = (_properties->getPropertyAsInt("IceGrid.Node.RedirectErrToOut") > 0); + + // + // Parse the properties override property. + // + string props = _properties->getProperty("IceGrid.Node.PropertiesOverride"); + if(!props.empty()) + { + string::size_type end = 0; + while(end != string::npos) + { + const string delim = " \t\r\n"; + + string::size_type beg = props.find_first_not_of(delim, end); + if(beg == string::npos) + { + break; + } + + end = props.find_first_of(delim, beg); + string arg; + if(end == string::npos) + { + arg = props.substr(beg); + } + else + { + arg = props.substr(beg, end - beg); + } + if(arg.find("--") != 0) + { + arg = "--" + arg; + } + _propertiesOverride.push_back(arg); + } + } +} + +Activator::~Activator() +{ + assert(!_thread); + +#ifdef _WIN32 + if(_hIntr != NULL) + { + CloseHandle(_hIntr); + } +#else + close(_fdIntrRead); + close(_fdIntrWrite); +#endif +} + +bool +Activator::activate(const string& name, + const string& exePath, + const string& pwdPath, + const Ice::StringSeq& options, + const Ice::StringSeq& envs, + const ServerPrx& server) +{ + IceUtil::Monitor< IceUtil::Mutex>::Lock sync(*this); + + if(_deactivating) + { + return false; + } + + string path = exePath; + if(path.empty()) + { + return false; + } + + string pwd = pwdPath; + +#ifdef _WIN32 + // + // Get the absolute pathname of the executable. + // + char absbuf[_MAX_PATH]; + char* filePart; + if(SearchPath(NULL, path.c_str(), ".exe", _MAX_PATH, absbuf, &filePart) == 0) + { + Error out(_traceLevels->logger); + out << "cannot convert `" << path << "' into an absolute path"; + return false; + } + path = absbuf; + + // + // Get the absolute pathname of the working directory. + // + if(!pwd.empty()) + { + if(_fullpath(absbuf, pwd.c_str(), _MAX_PATH) == NULL) + { + Error out(_traceLevels->logger); + out << "cannot convert `" << pwd << "' into an absolute path"; + return false; + } + pwd = absbuf; + } +#else + // + // Normalize the pathname a bit. + // + { + string::size_type pos; + while((pos = path.find("//")) != string::npos) + { + path.erase(pos, 1); + } + while((pos = path.find("/./")) != string::npos) + { + path.erase(pos, 2); + } + } + + // + // Normalize the path to the working directory. + // + if(!pwd.empty()) + { + string::size_type pos; + while((pos = pwd.find("//")) != string::npos) + { + pwd.erase(pos, 1); + } + while((pos = pwd.find("/./")) != string::npos) + { + pwd.erase(pos, 2); + } + } +#endif + + // + // Setup arguments. + // + StringSeq args; + args.push_back(path); + args.insert(args.end(), options.begin(), options.end()); + args.insert(args.end(), _propertiesOverride.begin(), _propertiesOverride.end()); + args.push_back("--Ice.Default.Locator=" + _properties->getProperty("Ice.Default.Locator")); + args.push_back("--Ice.ServerId=" + name); + + if(_outputDir.size() > 0) + { + string outFile = _outputDir + "/" + name + ".out"; + string errFile = _redirectErrToOut ? outFile : _outputDir + "/" + name + ".err"; + args.push_back("--Ice.StdOut=" + outFile); + args.push_back("--Ice.StdErr=" + errFile); + } + + + if(_traceLevels->activator > 1) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->activatorCat); + out << "activating server `" << name << "'"; + if(_traceLevels->activator > 2) + { + out << "\n"; + out << "path = " << path << "\n"; + out << "pwd = " << pwd << "\n"; + out << "args = "; + + StringSeq::const_iterator p = args.begin(); + ++p; + for(StringSeq::const_iterator q = p; q != args.end(); ++q) + { + out << " " << *q; + } + } + } + + // + // Activate and create. + // +#ifdef _WIN32 + // + // Compose command line. + // + string cmd; + StringSeq::const_iterator p; + for(p = args.begin(); p != args.end(); ++p) + { + if(p != args.begin()) + { + cmd.push_back(' '); + } + // + // Enclose arguments containing spaces in double quotes. + // + if((*p).find(' ') != string::npos) + { + cmd.push_back('"'); + cmd.append(*p); + cmd.push_back('"'); + } + else + { + cmd.append(*p); + } + } + + const char* dir; + if(!pwd.empty()) + { + dir = pwd.c_str(); + } + else + { + dir = NULL; + } + + // + // Make a copy of the command line. + // + char* cmdbuf = strdup(cmd.c_str()); + + // + // Create the environment block for the child process. We start with the environment + // of this process, and then merge environment variables from the server description. + // + const char* env = NULL; + string envbuf; + if(!envs.empty()) + { + map<string, string> envMap; + LPVOID parentEnv = GetEnvironmentStrings(); + const char* var = reinterpret_cast<const char*>(parentEnv); + if(*var == '=') + { + // + // The environment block may start with some information about the + // current drive and working directory. This is indicated by a leading + // '=' character, so we skip to the first '\0' byte. + // + while(*var) + var++; + var++; + } + while(*var) + { + string s(var); + string::size_type pos = s.find('='); + if(pos != string::npos) + { + envMap.insert(map<string, string>::value_type(s.substr(0, pos), s.substr(pos + 1))); + } + var += s.size(); + var++; // Skip the '\0' byte + } + FreeEnvironmentStrings(static_cast<char*>(parentEnv)); + for(p = envs.begin(); p != envs.end(); ++p) + { + string s = *p; + string::size_type pos = s.find('='); + if(pos != string::npos) + { + envMap.insert(map<string, string>::value_type(s.substr(0, pos), s.substr(pos + 1))); + } + } + for(map<string, string>::const_iterator q = envMap.begin(); q != envMap.end(); ++q) + { + envbuf.append(q->first); + envbuf.push_back('='); + envbuf.append(q->second); + envbuf.push_back('\0'); + } + envbuf.push_back('\0'); + env = envbuf.c_str(); + } + + Process process; + + STARTUPINFO si; + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + + PROCESS_INFORMATION pi; + ZeroMemory(&pi, sizeof(pi)); + + BOOL b = CreateProcess( + NULL, // Executable + cmdbuf, // Command line + NULL, // Process attributes + NULL, // Thread attributes + FALSE, // Do NOT inherit handles + CREATE_NEW_PROCESS_GROUP, // Process creation flags + (LPVOID)env, // Process environment + dir, // Current directory + &si, // Startup info + &pi // Process info + ); + + free(cmdbuf); + + if(!b) + { + SyscallException ex(__FILE__, __LINE__); + ex.error = getSystemErrno(); + throw ex; + } + + // + // Caller is responsible for closing handles in PROCESS_INFORMATION. We don't need to + // keep the thread handle, so we close it now. The process handle will be closed later. + // + CloseHandle(pi.hThread); + + + process.pid = pi.dwProcessId; + process.hnd = pi.hProcess; + process.server = server; + _processes.insert(make_pair(name, process)); + + setInterrupt(); + + if(_traceLevels->activator > 0) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->activatorCat); + out << "activated server `" << name << "' (pid = " << pi.dwProcessId << ")"; + } +#else + int fds[2]; + if(pipe(fds) != 0) + { + SyscallException ex(__FILE__, __LINE__); + ex.error = getSystemErrno(); + throw ex; + } + + // + // Convert to standard argc/argv. + // + int argc = static_cast<int>(args.size()); + char** argv = static_cast<char**>(malloc((argc + 1) * sizeof(char*))); + int i = 0; + for(StringSeq::const_iterator p = args.begin(); p != args.end(); ++p, ++i) + { + assert(i < argc); + argv[i] = strdup(p->c_str()); + } + assert(i == argc); + argv[argc] = 0; + + int envCount = static_cast<int>(envs.size()); + char** envArray = new char*[envCount]; + i = 0; + for(StringSeq::const_iterator q = envs.begin(); q != envs.end(); ++q) + { + envArray[i++] = strdup(q->c_str()); + } + + // + // Current directory + // + const char* pwdCStr = pwd.c_str(); + + + pid_t pid = fork(); + if(pid == -1) + { + SyscallException ex(__FILE__, __LINE__); + ex.error = getSystemErrno(); + throw ex; + } + + if(pid == 0) // Child process. + { + // + // Until exec, we can only use async-signal safe functions + // + +#ifdef __linux + // + // Create a process group for this child, to be able to send + // a signal to all the thread-processes with killpg + // + setpgrp(); +#endif + + // + // Close all file descriptors, except for standard input, + // standard output, standard error, and the write side + // of the newly created pipe. + // + int maxFd = static_cast<int>(sysconf(_SC_OPEN_MAX)); + for(int fd = 3; fd < maxFd; ++fd) + { + if(fd != fds[1]) + { + close(fd); + } + } + + for(i = 0; i < envCount; i++) + { + if(putenv(envArray[i]) != 0) + { + reportChildError(errno, fds[1], "cannot set environment variable", envArray[i]); + } + } + // + // Each env is leaked on purpose ... see man putenv(). + // + delete[] envArray; + + // + // Change working directory. + // + if(strlen(pwdCStr) != 0) + { + if(chdir(pwdCStr) == -1) + { + reportChildError(errno, fds[1], "cannot change working directory to", pwdCStr); + } + } + + if(execvp(argv[0], argv) == -1) + { + reportChildError(errno, fds[1], "cannot execute", argv[0]); + } + } + else // Parent process. + { + close(fds[1]); + + for(i = 0; argv[i]; i++) + { + free(argv[i]); + } + free(argv); + + for(i = 0; i < envCount; ++i) + { + free(envArray[i]); + } + delete[] envArray; + + Process process; + process.pid = pid; + process.pipeFd = fds[0]; + process.server = server; + _processes.insert(make_pair(name, process)); + + int flags = fcntl(process.pipeFd, F_GETFL); + flags |= O_NONBLOCK; + fcntl(process.pipeFd, F_SETFL, flags); + + setInterrupt(); + + if(_traceLevels->activator > 0) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->activatorCat); + out << "activated server `" << name << "' (pid = " << pid << ")"; + } + } +#endif + + return true; +} + +void +Activator::deactivate(const string& name, const Ice::ProcessPrx& process) +{ +#ifdef _WIN32 + Ice::Int pid = getServerPid(name); + if(pid == 0) + { + // + // Server is already deactivated. + // + return; + } +#endif + + // + // Try to shut down the server gracefully using the process proxy. + // + if(process) + { + if(_traceLevels->activator > 1) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->activatorCat); + out << "deactivating `" << name << "' using process proxy"; + } + try + { + process->shutdown(); + return; + } + catch(const Ice::LocalException& ex) + { + Ice::Warning out(_traceLevels->logger); + out << "exception occurred while deactivating `" << name << "' using process proxy:\n" << ex; + } + } + + if(_traceLevels->activator > 1) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->activatorCat); + out << "no process proxy, deactivating `" << name << "' using signal"; + } + +#ifdef _WIN32 + // + // Generate a Ctrl+Break event on the child. + // + if(GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, pid)) + { + if(_traceLevels->activator > 1) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->activatorCat); + out << "sent Ctrl+Break to server `" << name << "' (pid = " << pid << ")"; + } + } + else + { + SyscallException ex(__FILE__, __LINE__); + ex.error = getSystemErrno(); + throw ex; + } +#else + // + // Send a SIGTERM to the process. + // + sendSignal(name, SIGTERM); + +#endif +} + +void +Activator::kill(const string& name) +{ +#ifdef _WIN32 + Ice::Int pid = getServerPid(name); + if(pid == 0) + { + // + // Server is already deactivated. + // + return; + } + + HANDLE hnd = OpenProcess(PROCESS_TERMINATE, FALSE, pid); + if(hnd == NULL) + { + SyscallException ex(__FILE__, __LINE__); + ex.error = getSystemErrno(); + throw ex; + } + + BOOL b = TerminateProcess(hnd, 1); + + CloseHandle(hnd); + + if(!b) + { + SyscallException ex(__FILE__, __LINE__); + ex.error = getSystemErrno(); + throw ex; + } + + if(_traceLevels->activator > 1) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->activatorCat); + out << "terminating server `" << name << "' (pid = " << pid << ")"; + } + +#else + sendSignal(name, SIGKILL); +#endif +} + + +void +Activator::sendSignal(const string& name, const string& signal) +{ + sendSignal(name, stringToSignal(signal)); +} +void +Activator::sendSignal(const string& name, int signal) +{ +#ifdef _WIN32 + // + // TODO: Win32 implementation? + // + throw BadSignalException(); + +#else + Ice::Int pid = getServerPid(name); + if(pid == 0) + { + // + // Server is already deactivated. + // + return; + } + +#ifdef __linux + // Use process groups on Linux instead of processes + int ret = ::killpg(static_cast<pid_t>(pid), signal); +#else + int ret = ::kill(static_cast<pid_t>(pid), signal); +#endif + if(ret != 0 && getSystemErrno() != ESRCH) + { + SyscallException ex(__FILE__, __LINE__); + ex.error = getSystemErrno(); + throw ex; + } + + if(_traceLevels->activator > 1) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->activatorCat); + out << "sent " << signalToString(signal) << " to server `" << name << "' (pid = " << pid << ")"; + } +#endif +} + +Ice::Int +Activator::getServerPid(const string& name) +{ + IceUtil::Monitor< IceUtil::Mutex>::Lock sync(*this); + + map<string, Process>::const_iterator p = _processes.find(name); + if(p == _processes.end()) + { + return 0; + } + + return static_cast<Ice::Int>(p->second.pid); +} + +void +Activator::start() +{ + // + // Create and start the termination listener thread. + // + _thread = new TerminationListenerThread(*this); + _thread->start(); +} + +void +Activator::waitForShutdown() +{ + IceUtil::Monitor< IceUtil::Mutex>::Lock sync(*this); + while(!_deactivating) + { + wait(); + } +} + +void +Activator::shutdown() +{ + IceUtil::Monitor< IceUtil::Mutex>::Lock sync(*this); + // + // Deactivation has been initiated. Set _deactivating to true to + // prevent activation of new processes. This will also cause the + // termination listener thread to stop when there are no more + // active processes. + // + _deactivating = true; + setInterrupt(); + notifyAll(); +} + +void +Activator::destroy() +{ + { + IceUtil::Monitor< IceUtil::Mutex>::Lock sync(*this); + assert(_deactivating); + } + + // + // Deactivate all the processes. + // + deactivateAll(); + + // + // Join the termination listener thread. This thread terminates + // when there's no more processes and when _deactivating is set to + // true. + // + _thread->getThreadControl().join(); + _thread = 0; +} + +void +Activator::runTerminationListener() +{ + try + { + terminationListener(); + } + catch(const Exception& ex) + { + Error out(_traceLevels->logger); + out << "exception in process termination listener:\n" << ex; + } + catch(...) + { + Error out(_traceLevels->logger); + out << "unknown exception in process termination listener"; + } +} + +void +Activator::deactivateAll() +{ + // + // Stop all active processes. + // + map<string, Process> processes; + { + IceUtil::Monitor< IceUtil::Mutex>::Lock sync(*this); + processes = _processes; + } + + for(map<string, Process>::iterator p = processes.begin(); p != processes.end(); ++p) + { + // + // Stop the server. The listener thread should detect the + // process deactivation and remove it from the activator's + // list of active processes. + // + try + { + p->second.server->stop(); + } + catch(const ObjectNotExistException&) + { + // + // Expected if the server was in the process of being destroyed. + // + } + } +} + +void +Activator::terminationListener() +{ +#ifdef _WIN32 + while(true) + { + vector<HANDLE> handles; + + // + // Lock while we collect the process handles. + // + { + IceUtil::Monitor< IceUtil::Mutex>::Lock sync(*this); + + for(map<string, Process>::iterator p = _processes.begin(); p != _processes.end(); ++p) + { + handles.push_back(p->second.hnd); + } + } + + handles.push_back(_hIntr); + + // + // Wait for a child to terminate, or the interrupt event to be signaled. + // + DWORD ret = WaitForMultipleObjects(handles.size(), &handles[0], FALSE, INFINITE); + if(ret == WAIT_FAILED) + { + SyscallException ex(__FILE__, __LINE__); + ex.error = getSystemErrno(); + throw ex; + } + + vector<HANDLE>::size_type pos = ret - WAIT_OBJECT_0; + assert(pos < handles.size()); + HANDLE hnd = handles[pos]; + + IceUtil::Monitor< IceUtil::Mutex>::Lock sync(*this); + + if(hnd == _hIntr) + { + clearInterrupt(); + } + else + { + for(map<string, Process>::iterator p = _processes.begin(); p != _processes.end(); ++p) + { + if(p->second.hnd == hnd) + { + if(_traceLevels->activator > 0) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->activatorCat); + out << "detected termination of server `" << p->first << "'"; + } + + try + { + p->second.server->terminated(); + } + catch(const Ice::LocalException& ex) + { + Ice::Warning out(_traceLevels->logger); + out << "unexpected exception raised by server `" << p->first << "' termination:\n" << ex; + } + + CloseHandle(hnd); + _processes.erase(p); + break; + } + } + } + + if(_deactivating && _processes.empty()) + { + return; + } + } +#else + while(true) + { + fd_set fdSet; + int maxFd = _fdIntrRead; + FD_ZERO(&fdSet); + FD_SET(_fdIntrRead, &fdSet); + + { + IceUtil::Monitor< IceUtil::Mutex>::Lock sync(*this); + + for(map<string, Process>::iterator p = _processes.begin(); p != _processes.end(); ++p) + { + int fd = p->second.pipeFd; + FD_SET(fd, &fdSet); + if(maxFd < fd) + { + maxFd = fd; + } + } + } + + repeatSelect: + int ret = ::select(maxFd + 1, &fdSet, 0, 0, 0); + assert(ret != 0); + + if(ret == -1) + { +#ifdef EPROTO + if(errno == EINTR || errno == EPROTO) + { + goto repeatSelect; + } +#else + if(errno == EINTR) + { + goto repeatSelect; + } +#endif + + SyscallException ex(__FILE__, __LINE__); + ex.error = getSystemErrno(); + throw ex; + } + + { + IceUtil::Monitor< IceUtil::Mutex>::Lock sync(*this); + + if(FD_ISSET(_fdIntrRead, &fdSet)) + { + clearInterrupt(); + + if(_deactivating && _processes.empty()) + { + return; + } + } + + map<string, Process>::iterator p = _processes.begin(); + while(p != _processes.end()) + { + int fd = p->second.pipeFd; + if(!FD_ISSET(fd, &fdSet)) + { + ++p; + continue; + } + + char s[16]; + ssize_t rs; + string message; + + // + // Read the message over the pipe. + // + while((rs = read(fd, &s, 16)) > 0) + { + message.append(s, rs); + } + + if(rs == -1) + { + if(errno != EAGAIN || message.empty()) + { + SyscallException ex(__FILE__, __LINE__); + ex.error = getSystemErrno(); + throw ex; + } + + ++p; + } + else if(rs == 0) + { + // + // If the pipe was closed, the process has terminated. + // + + if(_traceLevels->activator > 0) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->activatorCat); + out << "detected termination of server `" << p->first << "'"; + } + + try + { + p->second.server->terminated(); + } + catch(const Ice::LocalException& ex) + { + Ice::Warning out(_traceLevels->logger); + out << "unexpected exception raised by server `" << p->first << "' termination:\n" << ex; + } + + close(p->second.pipeFd); + _processes.erase(p++); + + // + // We are deactivating and there's no more active processes. We can now + // end this loop + // + if(_deactivating && _processes.empty()) + { + return; + } + } + + // + // Log the received message. + // + if(!message.empty()) + { + Error out(_traceLevels->logger); + out << message; + } + } + } + } +#endif +} + +void +Activator::clearInterrupt() +{ +#ifdef _WIN32 + ResetEvent(_hIntr); +#else + char c; + while(read(_fdIntrRead, &c, 1) == 1) + ; +#endif +} + +void +Activator::setInterrupt() +{ +#ifdef _WIN32 + SetEvent(_hIntr); +#else + char c = 0; + write(_fdIntrWrite, &c, 1); +#endif +} diff --git a/cpp/src/IceGrid/Activator.h b/cpp/src/IceGrid/Activator.h new file mode 100644 index 00000000000..3a7bbcd59f6 --- /dev/null +++ b/cpp/src/IceGrid/Activator.h @@ -0,0 +1,89 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICE_GRID_ACTIVATOR_H +#define ICE_GRID_ACTIVATOR_H + +#include <IceUtil/Thread.h> +#include <IceGrid/Internal.h> + +namespace IceGrid +{ + +class TraceLevels; +typedef IceUtil::Handle<TraceLevels> TraceLevelsPtr; + +class Activator : public IceUtil::Monitor< IceUtil::Mutex>, public IceUtil::Shared +{ +public: + + Activator(const TraceLevelsPtr&, const Ice::PropertiesPtr&); + virtual ~Activator(); + + virtual bool activate(const std::string&, const std::string&, const std::string&, const Ice::StringSeq&, + const Ice::StringSeq&, const ServerPrx&); + virtual void deactivate(const std::string&, const Ice::ProcessPrx&); + virtual void kill(const std::string&); + virtual void sendSignal(const std::string&, const std::string&); + + virtual Ice::Int getServerPid(const std::string&); + + virtual void start(); + virtual void waitForShutdown(); + virtual void shutdown(); + virtual void destroy(); + + + void sendSignal(const std::string&, int); + void runTerminationListener(); + +private: + + void deactivateAll(); + + void terminationListener(); + void clearInterrupt(); + void setInterrupt(); + + struct Process + { +#ifdef _WIN32 + DWORD pid; + HANDLE hnd; +#else + pid_t pid; + int pipeFd; +#endif + ServerPrx server; + }; + + TraceLevelsPtr _traceLevels; + Ice::PropertiesPtr _properties; + std::map<std::string, Process> _processes; + bool _deactivating; + +#ifdef _WIN32 + HANDLE _hIntr; +#else + int _fdIntrRead; + int _fdIntrWrite; +#endif + + std::vector<std::string> _propertiesOverride; + + std::string _outputDir; + bool _redirectErrToOut; + + IceUtil::ThreadPtr _thread; +}; +typedef IceUtil::Handle<Activator> ActivatorPtr; + +} + +#endif diff --git a/cpp/src/IceGrid/AdapterFactory.cpp b/cpp/src/IceGrid/AdapterFactory.cpp new file mode 100644 index 00000000000..739a3ceb5e1 --- /dev/null +++ b/cpp/src/IceGrid/AdapterFactory.cpp @@ -0,0 +1,110 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <Ice/Ice.h> +#include <IceUtil/UUID.h> +#include <Freeze/Evictor.h> +#include <Freeze/Initialize.h> +#include <IceGrid/AdapterFactory.h> +#include <IceGrid/AdapterI.h> +#include <IceGrid/TraceLevels.h> + +using namespace std; +using namespace IceGrid; + +IceGrid::AdapterFactory::AdapterFactory(const Ice::ObjectAdapterPtr& adapter, + const TraceLevelsPtr& traceLevels, + const string& envName) : + _adapter(adapter), + _traceLevels(traceLevels) +{ + Ice::PropertiesPtr properties = _adapter->getCommunicator()->getProperties(); + + // + // Create and install the freeze evictor for standalone adapter objects. + // + properties->setProperty("Freeze.Evictor." + envName + ".adapter.SaveSizeTrigger", "1"); + _evictor = Freeze::createEvictor(_adapter, envName, "adapter"); + _evictor->setSize(1000); + + // + // Install the server object factory. + // + _adapter->getCommunicator()->addObjectFactory(this, "::IceGrid::StandaloneAdapter"); + + // + // Install the evictors. + // + _adapter->addServantLocator(_evictor, "IceGridStandaloneAdapter"); +} + +// +// Ice::ObjectFactory::create method implementation +// +Ice::ObjectPtr +IceGrid::AdapterFactory::create(const string& type) +{ + if(type == "::IceGrid::StandaloneAdapter") + { + return new StandaloneAdapterI(this); + } + else + { + assert(false); + return 0; // Keep the compiler happy. + } +} + +// +// Ice::ObjectFactory::destroy method implementation +// +void +IceGrid::AdapterFactory::destroy() +{ + _adapter = 0; + _evictor = 0; + _traceLevels = 0; +} + +// +// Create a new adapter servant with the given name and add +// it the evictor database. +// +AdapterPrx +IceGrid::AdapterFactory::createStandaloneAdapter(const string& name) +{ + StandaloneAdapterPtr adapterI = new StandaloneAdapterI(this); + + Ice::Identity id; + id.category = "IceGridStandaloneAdapter"; + id.name = name + "-" + IceUtil::generateUUID(); + + _evictor->add(adapterI, id); + + return AdapterPrx::uncheckedCast(_adapter->createProxy(id)); +} + +void +IceGrid::AdapterFactory::destroy(const Ice::Identity& id) +{ + try + { + _evictor->remove(id); + } + catch(const Freeze::DatabaseException& ex) + { + ostringstream os; + os << "couldn't destroy standalone adapter:\n" << ex; + _traceLevels->logger->warning(os.str()); + } + catch(const Freeze::EvictorDeactivatedException&) + { + assert(false); + } +} diff --git a/cpp/src/IceGrid/AdapterFactory.h b/cpp/src/IceGrid/AdapterFactory.h new file mode 100644 index 00000000000..85af7b72a4f --- /dev/null +++ b/cpp/src/IceGrid/AdapterFactory.h @@ -0,0 +1,52 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICE_GRID_ADAPTER_FACTORY_H +#define ICE_GRID_ADAPTER_FACTORY_H + +#include <IceGrid/Internal.h> +#include <Freeze/EvictorF.h> + +namespace IceGrid +{ + +class TraceLevels; +typedef IceUtil::Handle<TraceLevels> TraceLevelsPtr; + +class AdapterFactory : public Ice::ObjectFactory +{ +public: + + AdapterFactory(const Ice::ObjectAdapterPtr&, const TraceLevelsPtr&, const std::string&); + + // + // Ice::ObjectFactory method implementation. + // + virtual Ice::ObjectPtr create(const std::string&); + virtual void destroy(); + + AdapterPrx createStandaloneAdapter(const std::string& name); + +private: + + friend class StandaloneAdapterI; + + void destroy(const Ice::Identity&); + + Ice::ObjectAdapterPtr _adapter; + TraceLevelsPtr _traceLevels; + + Freeze::EvictorPtr _evictor; +}; + +typedef ::IceUtil::Handle< AdapterFactory> AdapterFactoryPtr; + +} + +#endif diff --git a/cpp/src/IceGrid/AdapterI.cpp b/cpp/src/IceGrid/AdapterI.cpp new file mode 100644 index 00000000000..c588c2846f1 --- /dev/null +++ b/cpp/src/IceGrid/AdapterI.cpp @@ -0,0 +1,55 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <Ice/Ice.h> +#include <IceGrid/AdapterI.h> +#include <IceGrid/AdapterFactory.h> +#include <IceGrid/TraceLevels.h> + +using namespace std; +using namespace IceGrid; + +StandaloneAdapterI::StandaloneAdapterI(const AdapterFactoryPtr& factory) : + _factory(factory) +{ +} + +StandaloneAdapterI::StandaloneAdapterI() +{ +} + +void +StandaloneAdapterI::activate_async(const AMD_Adapter_activatePtr& cb, const Ice::Current&) +{ + IceUtil::Mutex::Lock sync(*this); + cb->ice_response(proxy); +} + +Ice::ObjectPrx +StandaloneAdapterI::getDirectProxy(const Ice::Current&) const +{ + IceUtil::Mutex::Lock sync(*this); + return proxy; +} + +void +StandaloneAdapterI::setDirectProxy(const Ice::ObjectPrx& prx, const Ice::Current&) +{ + IceUtil::Mutex::Lock sync(*this); + proxy = prx; +} + +void +StandaloneAdapterI::destroy(const Ice::Current& current) +{ + if(_factory) + { + _factory->destroy(current.id); + } +} diff --git a/cpp/src/IceGrid/AdapterI.h b/cpp/src/IceGrid/AdapterI.h new file mode 100644 index 00000000000..621013613a5 --- /dev/null +++ b/cpp/src/IceGrid/AdapterI.h @@ -0,0 +1,42 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICE_GRID_ADAPTER_I_H +#define ICE_GRID_ADAPTER_I_H + +#include <IceUtil/Mutex.h> +#include <IceGrid/Internal.h> +#include <IceUtil/AbstractMutex.h> + +namespace IceGrid +{ + +class AdapterFactory; +typedef IceUtil::Handle<AdapterFactory> AdapterFactoryPtr; + +class StandaloneAdapterI : public StandaloneAdapter, public IceUtil::AbstractMutexI<IceUtil::Mutex> +{ +public: + + StandaloneAdapterI(const AdapterFactoryPtr&); + StandaloneAdapterI(); + + virtual void activate_async(const AMD_Adapter_activatePtr&, const Ice::Current&); + virtual Ice::ObjectPrx getDirectProxy(const Ice::Current&) const; + virtual void setDirectProxy(const ::Ice::ObjectPrx&, const ::Ice::Current&); + virtual void destroy(const ::Ice::Current&); + +private: + + AdapterFactoryPtr _factory; +}; + +} + +#endif diff --git a/cpp/src/IceGrid/AdapterRegistryI.cpp b/cpp/src/IceGrid/AdapterRegistryI.cpp new file mode 100644 index 00000000000..1eaca9cef4c --- /dev/null +++ b/cpp/src/IceGrid/AdapterRegistryI.cpp @@ -0,0 +1,144 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <IceGrid/AdapterRegistryI.h> +#include <IceGrid/TraceLevels.h> +#include <Freeze/Initialize.h> + +using namespace std; +using namespace IceGrid; + +const string AdapterRegistryI::_dbName = "adapterregistry"; + +AdapterRegistryI::AdapterRegistryI(const Ice::CommunicatorPtr& communicator, + const string& envName, + const TraceLevelsPtr& traceLevels) : + _connectionCache(Freeze::createConnection(communicator, envName)), + _dictCache(_connectionCache, _dbName), + _traceLevels(traceLevels), + _envName(envName), + _communicator(communicator) +{ +} + +void +AdapterRegistryI::add(const string& id, const AdapterPrx& adapter, const Ice::Current& current) +{ + while(true) + { + AdapterPrx oldAdapter; + try + { + oldAdapter = findById(id, current); + oldAdapter->ice_ping(); + throw AdapterExistsException(); + } + catch(const AdapterNotExistException&) + { + } + catch(const Ice::ObjectNotExistException&) + { + } + catch(const Ice::LocalException&) + { + throw AdapterExistsException(); + } + + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + StringObjectProxyDict dict(connection, _dbName); + + StringObjectProxyDict::iterator p = dict.find(id); + if(p != dict.end()) + { + if(oldAdapter && oldAdapter != p->second) + { + continue; + } + + p.set(adapter); + + if(_traceLevels->adapterRegistry > 0) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->adapterRegistryCat); + out << "updated adapter `" << id << "'"; + } + } + else + { + dict.put(pair<const string, const Ice::ObjectPrx>(id, adapter)); + + if(_traceLevels->adapterRegistry > 0) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->adapterRegistryCat); + out << "added adapter `" << id << "'"; + } + } + + break; + } +} + +AdapterPrx +AdapterRegistryI::remove(const string& id, const AdapterPrx& orig, const Ice::Current&) +{ + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + StringObjectProxyDict dict(connection, _dbName); + + StringObjectProxyDict::iterator p = dict.find(id); + if(p == dict.end()) + { + throw AdapterNotExistException(); + } + + AdapterPrx adapter = AdapterPrx::uncheckedCast(p->second); + if(orig != 0 && orig != adapter) // Only remove if the adapter is equal to the provided proxy (if not null) + { + return 0; + } + dict.erase(p); + + if(_traceLevels->adapterRegistry > 0) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->adapterRegistryCat); + out << "removed adapter `" << id << "'"; + } + + return adapter; +} + +AdapterPrx +AdapterRegistryI::findById(const string& id, const Ice::Current&) +{ + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + StringObjectProxyDict dict(connection, _dbName); + + StringObjectProxyDict::iterator p = dict.find(id); + if(p != dict.end()) + { + return AdapterPrx::uncheckedCast(p->second); + } + throw AdapterNotExistException(); +} + +Ice::StringSeq +AdapterRegistryI::getAll(const Ice::Current&) const +{ + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + StringObjectProxyDict dict(connection, _dbName); + + Ice::StringSeq ids; + ids.reserve(dict.size()); + + for(StringObjectProxyDict::iterator p = dict.begin(); p != dict.end(); ++p) + { + ids.push_back(p->first); + } + + return ids; +} diff --git a/cpp/src/IceGrid/AdapterRegistryI.h b/cpp/src/IceGrid/AdapterRegistryI.h new file mode 100644 index 00000000000..b89b0d954c7 --- /dev/null +++ b/cpp/src/IceGrid/AdapterRegistryI.h @@ -0,0 +1,48 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICE_GRID_ADAPTER_REGISTRY_I_H +#define ICE_GRID_ADAPTER_REGISTRY_I_H + +#include <IceGrid/Internal.h> +#include <IceGrid/StringObjectProxyDict.h> + +namespace IceGrid +{ + +class TraceLevels; +typedef IceUtil::Handle<TraceLevels> TraceLevelsPtr; + +class AdapterRegistryI : public AdapterRegistry +{ +public: + + AdapterRegistryI(const Ice::CommunicatorPtr&, const std::string&, const TraceLevelsPtr&); + + virtual void add(const std::string&, const AdapterPrx&, const ::Ice::Current&); + virtual AdapterPrx remove(const std::string&, const AdapterPrx&, const ::Ice::Current&); + + virtual AdapterPrx findById(const ::std::string&, const ::Ice::Current&); + virtual Ice::StringSeq getAll(const ::Ice::Current&) const; + +private: + + static const std::string _dbName; + + Freeze::ConnectionPtr _connectionCache; + StringObjectProxyDict _dictCache; + TraceLevelsPtr _traceLevels; + const std::string _envName; + const Ice::CommunicatorPtr _communicator; + +}; + +} + +#endif diff --git a/cpp/src/IceGrid/AdminI.cpp b/cpp/src/IceGrid/AdminI.cpp new file mode 100644 index 00000000000..3e32bcedb1f --- /dev/null +++ b/cpp/src/IceGrid/AdminI.cpp @@ -0,0 +1,1530 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <Ice/Ice.h> +#include <IceGrid/AdminI.h> +#include <IceGrid/DescriptorVisitor.h> +#include <IceGrid/DescriptorUtil.h> +#include <IceGrid/Registry.h> +#include <Ice/LoggerUtil.h> +#include <Ice/TraceUtil.h> +#include <Ice/SliceChecksums.h> + +using namespace std; +using namespace Ice; +using namespace IceGrid; + +namespace IceGrid +{ + +class Deployer : public DescriptorVisitor +{ +public: + + Deployer(const NodeRegistryPtr&, + const ApplicationRegistryPtr&, + const ServerRegistryPtr&, + const AdapterRegistryPtr&, + const ObjectRegistryPtr&, + const Ice::LoggerPtr&); + + Deployer(const Deployer&); + +protected: + + friend class Cleaner; + + void exception(const string&); + void exception(const string&, const Ice::LocalException&); + + const NodeRegistryPtr _nodeRegistry; + const ApplicationRegistryPtr _applicationRegistry; + const ServerRegistryPtr _serverRegistry; + const AdapterRegistryPtr _adapterRegistry; + const ObjectRegistryPtr _objectRegistry; + const Ice::LoggerPtr _logger; +}; + +class Cleaner : public DescriptorVisitor +{ +public: + + Cleaner(const NodeRegistryPtr&, + const ApplicationRegistryPtr&, + const ServerRegistryPtr&, + const AdapterRegistryPtr&, + const ObjectRegistryPtr&, + const Ice::LoggerPtr&); + + Cleaner(const Deployer&); + Cleaner(const Cleaner&); + +protected: + + void exception(const string&); + void exception(const string&, const Ice::LocalException&); + + const NodeRegistryPtr _nodeRegistry; + const ApplicationRegistryPtr _applicationRegistry; + const ServerRegistryPtr _serverRegistry; + const AdapterRegistryPtr _adapterRegistry; + const ObjectRegistryPtr _objectRegistry; + const Ice::LoggerPtr _logger; +}; + +class ApplicationDeployer : public Deployer +{ +public: + + ApplicationDeployer(const NodeRegistryPtr&, + const ApplicationRegistryPtr&, + const ServerRegistryPtr&, + const AdapterRegistryPtr&, + const ObjectRegistryPtr&, + const Ice::LoggerPtr&); + + ApplicationDeployer(const Deployer&); + + void deploy(const ApplicationDescriptorPtr&); + +private: + + virtual bool visitApplicationStart(const ApplicationWrapper&, const ApplicationDescriptorPtr&); + virtual bool visitServerStart(const ServerWrapper&, const ServerDescriptorPtr&); + + ApplicationDescriptorPtr _deployed; +}; + +class ServerDeployer : public Deployer +{ +public: + + ServerDeployer(const NodeRegistryPtr&, + const ApplicationRegistryPtr&, + const ServerRegistryPtr&, + const AdapterRegistryPtr&, + const ObjectRegistryPtr&, + const Ice::LoggerPtr&); + + ServerDeployer(const Deployer&); + + void deploy(const ServerDescriptorPtr&, const string& = string()); + +private: + + virtual bool visitServerStart(const ServerWrapper&, const ServerDescriptorPtr&); + virtual void visitServerEnd(const ServerWrapper&, const ServerDescriptorPtr&); + virtual bool visitServiceStart(const ServiceWrapper&, const ServiceDescriptorPtr&); + virtual void visitDbEnv(const DbEnvWrapper&, const DbEnvDescriptor&); + virtual bool visitAdapterStart(const AdapterWrapper&, const AdapterDescriptor&); + virtual void visitObject(const ObjectWrapper&, const ObjectDescriptor&); + + ServerDescriptorPtr _deployed; + + string _currentNodeName; + NodePrx _currentNode; + ServerPrx _currentServer; + PropertyDescriptorSeq _currentProperties; + string _backup; +}; + +class ApplicationCleaner : public Cleaner +{ +public: + + ApplicationCleaner(const NodeRegistryPtr&, + const ApplicationRegistryPtr&, + const ServerRegistryPtr&, + const AdapterRegistryPtr&, + const ObjectRegistryPtr&, + const Ice::LoggerPtr&); + + ApplicationCleaner(const Deployer&); + + void clean(const ApplicationDescriptorPtr&); + +private: + + virtual void visitApplicationEnd(const ApplicationWrapper&, const ApplicationDescriptorPtr&); + virtual bool visitServerStart(const ServerWrapper&, const ServerDescriptorPtr&); +}; + +class ServerCleaner : public Cleaner +{ +public: + + ServerCleaner(const NodeRegistryPtr&, + const ApplicationRegistryPtr&, + const ServerRegistryPtr&, + const AdapterRegistryPtr&, + const ObjectRegistryPtr&, + const Ice::LoggerPtr&); + + ServerCleaner(const Deployer&); + ServerCleaner(const Cleaner&); + + void clean(const ServerDescriptorPtr&, const string& = string()); + +private: + + virtual bool visitServerStart(const ServerWrapper&, const ServerDescriptorPtr&); + virtual void visitServerEnd(const ServerWrapper&, const ServerDescriptorPtr&); + virtual bool visitServiceStart(const ServiceWrapper&, const ServiceDescriptorPtr&); + virtual bool visitAdapterStart(const AdapterWrapper&, const AdapterDescriptor&); + virtual void visitDbEnv(const DbEnvWrapper&, const DbEnvDescriptor&); + virtual void visitObject(const ObjectWrapper&, const ObjectDescriptor&); + + string _currentNodeName; + ServerPrx _currentServer; + string _backup; +}; + +class ApplicationUpdater : public Deployer +{ +public: + + ApplicationUpdater(const NodeRegistryPtr&, + const ApplicationRegistryPtr&, + const ServerRegistryPtr&, + const AdapterRegistryPtr&, + const ObjectRegistryPtr&, + const Ice::LoggerPtr&); + + ApplicationUpdater(const Deployer&); + + void update(const ApplicationDescriptorPtr&); + +private: + + virtual bool visitApplicationStart(const ApplicationWrapper&, const ApplicationDescriptorPtr&); + virtual void visitApplicationEnd(const ApplicationWrapper&, const ApplicationDescriptorPtr&); + virtual bool visitServerStart(const ServerWrapper&, const ServerDescriptorPtr&); + + ApplicationDescriptorPtr _deployed; + ApplicationDescriptorPtr _added; + ApplicationDescriptorPtr _removed; + map<string, pair<string, string> > _backup; +}; + +} + +Deployer::Deployer(const NodeRegistryPtr& nodeRegistry, + const ApplicationRegistryPtr& applicationRegistry, + const ServerRegistryPtr& serverRegistry, + const AdapterRegistryPtr& adapterRegistry, + const ObjectRegistryPtr& objectRegistry, + const Ice::LoggerPtr& logger) : + _nodeRegistry(nodeRegistry), + _applicationRegistry(applicationRegistry), + _serverRegistry(serverRegistry), + _adapterRegistry(adapterRegistry), + _objectRegistry(objectRegistry), + _logger(logger) +{ +} + +Deployer::Deployer(const Deployer& deployer) : + _nodeRegistry(deployer._nodeRegistry), + _applicationRegistry(deployer._applicationRegistry), + _serverRegistry(deployer._serverRegistry), + _adapterRegistry(deployer._adapterRegistry), + _objectRegistry(deployer._objectRegistry), + _logger(deployer._logger) +{ +} + +void +Deployer::exception(const string& msg) +{ + DeploymentException ex; + ex.reason = msg; + throw ex; +} + +void +Deployer::exception(const string& msg, const Ice::LocalException& ex) +{ + ostringstream os; + os << msg << "\nException: " << ex; + DeploymentException e; + e.reason = os.str(); + throw e; +} + +Cleaner::Cleaner(const NodeRegistryPtr& nodeRegistry, + const ApplicationRegistryPtr& applicationRegistry, + const ServerRegistryPtr& serverRegistry, + const AdapterRegistryPtr& adapterRegistry, + const ObjectRegistryPtr& objectRegistry, + const Ice::LoggerPtr& logger) : + _nodeRegistry(nodeRegistry), + _applicationRegistry(applicationRegistry), + _serverRegistry(serverRegistry), + _adapterRegistry(adapterRegistry), + _objectRegistry(objectRegistry), + _logger(logger) +{ +} + +Cleaner::Cleaner(const Deployer& deployer) : + _nodeRegistry(deployer._nodeRegistry), + _applicationRegistry(deployer._applicationRegistry), + _serverRegistry(deployer._serverRegistry), + _adapterRegistry(deployer._adapterRegistry), + _objectRegistry(deployer._objectRegistry), + _logger(deployer._logger) +{ +} + +Cleaner::Cleaner(const Cleaner& cleaner) : + _nodeRegistry(cleaner._nodeRegistry), + _applicationRegistry(cleaner._applicationRegistry), + _serverRegistry(cleaner._serverRegistry), + _adapterRegistry(cleaner._adapterRegistry), + _objectRegistry(cleaner._objectRegistry), + _logger(cleaner._logger) +{ +} + +void +Cleaner::exception(const string& msg) +{ + Ice::Warning out(_logger); + out << msg; +} + +void +Cleaner::exception(const string& msg, const Ice::LocalException& ex) +{ + Ice::Warning out(_logger); + out << msg << "\nException: " << ex; +} + +ApplicationDeployer::ApplicationDeployer(const NodeRegistryPtr& nodeRegistry, + const ApplicationRegistryPtr& applicationRegistry, + const ServerRegistryPtr& serverRegistry, + const AdapterRegistryPtr& adapterRegistry, + const ObjectRegistryPtr& objectRegistry, + const Ice::LoggerPtr& logger) : + Deployer(nodeRegistry, applicationRegistry, serverRegistry, adapterRegistry, objectRegistry, logger) +{ +} + +ApplicationDeployer::ApplicationDeployer(const Deployer& deployer) : + Deployer(deployer) +{ +} + +void +ApplicationDeployer::deploy(const ApplicationDescriptorPtr& descriptor) +{ + try + { + ApplicationWrapper(descriptor).visit(*this); + } + catch(const DeploymentException&) + { + if(_deployed) + { + ApplicationCleaner cleaner(*this); + cleaner.clean(_deployed); + } + throw; + } +} + +bool +ApplicationDeployer::visitApplicationStart(const ApplicationWrapper&, const ApplicationDescriptorPtr& application) +{ + try + { + _applicationRegistry->add(application->name); + _deployed = new ApplicationDescriptor(); + _deployed->name = application->name; + } + catch(const ApplicationExistsException&) + { + exception("application `" + application->name + "' already exists"); + } + return true; +} + +bool +ApplicationDeployer::visitServerStart(const ServerWrapper&, const ServerDescriptorPtr& server) +{ + ServerDeployer deployer(*this); + deployer.deploy(server); + _deployed->servers.push_back(server); + return false; +} + +ApplicationUpdater::ApplicationUpdater(const NodeRegistryPtr& nodeRegistry, + const ApplicationRegistryPtr& applicationRegistry, + const ServerRegistryPtr& serverRegistry, + const AdapterRegistryPtr& adapterRegistry, + const ObjectRegistryPtr& objectRegistry, + const Ice::LoggerPtr& logger) : + Deployer(nodeRegistry, applicationRegistry, serverRegistry, adapterRegistry, objectRegistry, logger) +{ +} + +ApplicationUpdater::ApplicationUpdater(const Deployer& deployer) : + Deployer(deployer) +{ +} + +void +ApplicationUpdater::update(const ApplicationDescriptorPtr& descriptor) +{ + try + { + ApplicationWrapper(descriptor).visit(*this); + } + catch(const DeploymentException&) + { + if(_added) + { + for(ServerDescriptorSeq::const_iterator p = _added->servers.begin(); p != _added->servers.end(); ++p) + { + // + // If there's a backup directory for this server and it's on the same node we pass + // the backup directory to backup the databases. + // + if(_backup[(*p)->name].first == (*p)->node) + { + ServerCleaner(*this).clean(*p, _backup[(*p)->name].second); + } + else + { + ServerCleaner(*this).clean(*p); + } + } + } + if(_removed) + { + for(ServerDescriptorSeq::const_iterator p = _removed->servers.begin(); p != _removed->servers.end(); ++p) + { + try + { + ServerDeployer(*this).deploy(*p, _backup[(*p)->name].second); + } + catch(DeploymentException& ex) + { + cerr << "failed to add back updated server:\n" << ex << endl; + } + } + } + throw; + } + + // + // Destroy all the temporary backup directories. + // + for(map<string, pair<string, string> >::const_iterator p = _backup.begin(); p != _backup.end(); ++p) + { + if(!p->second.first.empty()) + { + _nodeRegistry->findByName(p->second.first)->destroyTmpDir(p->second.second); + } + } +} + +bool +ApplicationUpdater::visitApplicationStart(const ApplicationWrapper&, const ApplicationDescriptorPtr& application) +{ + try + { + _deployed = _applicationRegistry->getDescriptor(application->name); + _added = new ApplicationDescriptor(); + _removed = new ApplicationDescriptor(); + } + catch(const ApplicationNotExistException&) + { + exception("application `" + application->name + "' doesn't exists"); + } + return true; +} + +void +ApplicationUpdater::visitApplicationEnd(const ApplicationWrapper&, const ApplicationDescriptorPtr& application) +{ + // + // Remove servers which don't exist anymore. + // + for(ServerDescriptorSeq::const_iterator p = _deployed->servers.begin(); p != _deployed->servers.end(); ++p) + { + bool found = false; + for(ServerDescriptorSeq::const_iterator q = application->servers.begin(); q != application->servers.end(); ++q) + { + if((*p)->name == (*q)->name) + { + found = true; + break; + } + } + if(!found) + { + ServerCleaner(*this).clean(*p); + } + } +} + +bool +ApplicationUpdater::visitServerStart(const ServerWrapper&, const ServerDescriptorPtr& server) +{ + for(ServerDescriptorSeq::const_iterator p = _deployed->servers.begin(); p != _deployed->servers.end(); ++p) + { + if((*p)->name == server->name) + { + if(equal(*p, server)) + { + // + // Nothing to do, the descriptors are the same. + // + return false; + } + + _backup[server->name].second = _nodeRegistry->findByName((*p)->node)->createTmpDir(); + _backup[server->name].first = (*p)->node; + + ServerCleaner(*this).clean(*p, _backup[server->name].second); + _removed->servers.push_back(*p); + + if(server->node == ((*p)->node)) + { + ServerDeployer(*this).deploy(server, _backup[server->name].second); + } + else + { + ServerDeployer(*this).deploy(server); + } + + _added->servers.push_back(server); + return false; + } + } + + ServerDeployer(*this).deploy(server, _backup[server->name].second); + _added->servers.push_back(server); + return false; +} + +ServerDeployer::ServerDeployer(const NodeRegistryPtr& nodeRegistry, + const ApplicationRegistryPtr& applicationRegistry, + const ServerRegistryPtr& serverRegistry, + const AdapterRegistryPtr& adapterRegistry, + const ObjectRegistryPtr& objectRegistry, + const Ice::LoggerPtr& logger) : + Deployer(nodeRegistry, applicationRegistry, serverRegistry, adapterRegistry, objectRegistry, logger) +{ +} + +ServerDeployer::ServerDeployer(const Deployer& deployer) : + Deployer(deployer) +{ +} + +void +ServerDeployer::deploy(const ServerDescriptorPtr& descriptor, const string& backup) +{ + _backup = backup; + try + { + ServerWrapper(descriptor).visit(*this); + } + catch(const DeploymentException&) + { + if(_deployed) + { + ServerCleaner cleaner(*this); + cleaner.clean(_deployed); + } + throw; + } + +} + +bool +ServerDeployer::visitServerStart(const ServerWrapper&, const ServerDescriptorPtr& server) +{ + try + { + try + { + _currentNodeName = server->node; + _currentNode = _nodeRegistry->findByName(server->node); + _currentServer = _currentNode->createServer(server->name, server); + _currentProperties.clear(); + PropertyDescriptor prop; + prop.name = "# Server configuration"; + _currentProperties.push_back(prop); + prop.name = "Ice.ProgramName"; + prop.value = server->name; + _currentProperties.push_back(prop); + copy(server->properties.begin(), server->properties.end(), back_inserter(_currentProperties)); + _serverRegistry->add(server->name, _currentServer, server); + + if(JavaIceBoxDescriptorPtr::dynamicCast(server)) + { + _deployed = new JavaIceBoxDescriptor(); + } + else if(CppIceBoxDescriptorPtr::dynamicCast(server)) + { + _deployed = new CppIceBoxDescriptor(); + } + else if(JavaServerDescriptorPtr::dynamicCast(server)) + { + _deployed = new JavaServerDescriptor(); + } + else + { + _deployed = new ServerDescriptor(); + } + _deployed->node = server->node; + _deployed->name = server->name; + + if(!server->application.empty()) + { + _applicationRegistry->registerServer(server->application, server->name); + _deployed->application = server->application; + } + } + catch(const ServerExistsException&) + { + _currentServer->destroy(); + _currentServer = 0; + exception("server `" + server->name + "' already exists"); + } + catch(const ApplicationNotExistException&) + { + exception("application `" + server->application + "' doesn't exist"); + } + catch(const NodeNotExistException&) + { + exception("couldn't find node `" + server->node + "'"); + } + + _currentServer->setActivationMode(server->activation); + _currentServer->setExePath(server->exe); + _currentServer->setPwd(server->pwd); + _currentServer->setEnvs(server->envs); + } + catch(const Ice::LocalException& ex) + { + exception("couldn't contact node `" + server->node + "'", ex); + } + + return true; +} + +void +ServerDeployer::visitServerEnd(const ServerWrapper&, const ServerDescriptorPtr& server) +{ + assert(_currentServer); + + try + { + Ice::StringSeq options; + + JavaServerDescriptorPtr javaDesc = JavaServerDescriptorPtr::dynamicCast(server); + if(javaDesc) + { + copy(javaDesc->jvmOptions.begin(), javaDesc->jvmOptions.end(), back_inserter(options)); + options.push_back("-ea"); + options.push_back(javaDesc->className); + copy(javaDesc->options.begin(), javaDesc->options.end(), back_inserter(options)); + } + else + { + options = server->options; + } + + CppIceBoxDescriptorPtr cppIceBox = CppIceBoxDescriptorPtr::dynamicCast(server); + JavaIceBoxDescriptorPtr javaIceBox = JavaIceBoxDescriptorPtr::dynamicCast(server); + + const ServiceDescriptorSeq& services = + cppIceBox ? cppIceBox->services : (javaIceBox ? javaIceBox->services : ServiceDescriptorSeq()); + + if(!services.empty()) + { + PropertyDescriptor prop; + prop.name = "IceBox.LoadOrder"; + for(ServiceDescriptorSeq::const_iterator p = services.begin(); p != services.end(); ++p) + { + prop.value += (*p)->name + " "; + } + _currentProperties.push_back(prop); + } + + if(!_currentProperties.empty()) + { + string path = _currentServer->addConfigFile("config", _currentProperties); + options.push_back("--Ice.Config=" + path); + + _deployed->properties = _currentProperties; + } + + _currentServer->setOptions(options); + } + catch(const Ice::LocalException& ex) + { + exception("couldn't contact node `" + _currentNodeName + "'", ex); + } +} + +bool +ServerDeployer::visitServiceStart(const ServiceWrapper&, const ServiceDescriptorPtr& service) +{ + assert(_currentServer); + + try + { + string path = _currentServer->addConfigFile("config_" + service->name, service->properties); + + ServiceDescriptorPtr svc = new ServiceDescriptor(); + svc->name = service->name; + svc->properties = service->properties; + if(JavaIceBoxDescriptorPtr::dynamicCast(_deployed)) + { + JavaIceBoxDescriptorPtr::dynamicCast(_deployed)->services.push_back(svc); + } + else + { + CppIceBoxDescriptorPtr::dynamicCast(_deployed)->services.push_back(svc); + } + + PropertyDescriptor prop; + _currentProperties.push_back(prop); + prop.name = "#"; + _currentProperties.push_back(prop); + prop.name = "# Service " + service->name; + _currentProperties.push_back(prop); + prop.name = "#"; + _currentProperties.push_back(prop); + prop.name = "IceBox.Service." + service->name; + prop.value = service->entry + " --Ice.Config=" + path; + _currentProperties.push_back(prop); + } + catch(const Ice::LocalException& ex) + { + exception("couldn't contact node `" + _currentNodeName + "'", ex); + } + + return true; +} + +void +ServerDeployer::visitDbEnv(const DbEnvWrapper&, const DbEnvDescriptor& dbEnv) +{ + assert(_currentServer); + + try + { + string path = _currentServer->addDbEnv(dbEnv, _backup); + _deployed->dbEnvs.push_back(dbEnv); + + PropertyDescriptor prop; + _currentProperties.push_back(prop); + prop.name = "# DbEnv " + dbEnv.name; + _currentProperties.push_back(prop); + prop.name = "Freeze.DbEnv." + dbEnv.name + ".DbHome"; + prop.value = path; + _currentProperties.push_back(prop); + } + catch(const Ice::LocalException& ex) + { + exception("couldn't contact node `" + _currentNodeName + "'", ex); + } +} + +bool +ServerDeployer::visitAdapterStart(const AdapterWrapper&, const AdapterDescriptor& adapter) +{ + assert(_currentServer); + + ServerAdapterPrx serverAdapter; + try + { + serverAdapter = _currentNode->createServerAdapter(_currentServer, adapter.id); + _adapterRegistry->add(adapter.id, serverAdapter); + _currentServer->addAdapter(serverAdapter, adapter.registerProcess); + + AdapterDescriptor adpt; + adpt.id = adapter.id; + adpt.name = adapter.name; + adpt.endpoints = adapter.endpoints; + adpt.registerProcess = adapter.registerProcess; + _deployed->adapters.push_back(adpt); + + PropertyDescriptor prop; + _currentProperties.push_back(prop); + prop.name = "# Adapter " + adapter.name; + _currentProperties.push_back(prop); + prop.name = adapter.name + ".Endpoints"; + prop.value = adapter.endpoints; + _currentProperties.push_back(prop); + prop.name = adapter.name + ".AdapterId"; + prop.value = adapter.id; + _currentProperties.push_back(prop); + if(adapter.registerProcess) + { + prop.name = adapter.name + ".RegisterProcess"; + prop.value = "1"; + _currentProperties.push_back(prop); + } + } + catch(const AdapterExistsException&) + { + serverAdapter->destroy(); + exception("adapter `" + adapter.id + "' already exists"); + } + catch(const Ice::LocalException& ex) + { + exception("couldn't contact node `" + _currentNodeName + "'", ex); + } + + return true; +} + +void +ServerDeployer::visitObject(const ObjectWrapper&, const ObjectDescriptor& object) +{ + assert(_currentServer); + + try + { + _objectRegistry->add(object); + _deployed->adapters.back().objects.push_back(object); + } + catch(const ObjectExistsException&) + { + exception("object `" + Ice::identityToString(object.proxy->ice_getIdentity()) + "' already exists"); + } +} + +ApplicationCleaner::ApplicationCleaner(const NodeRegistryPtr& nodeRegistry, + const ApplicationRegistryPtr& applicationRegistry, + const ServerRegistryPtr& serverRegistry, + const AdapterRegistryPtr& adapterRegistry, + const ObjectRegistryPtr& objectRegistry, + const Ice::LoggerPtr& logger) : + Cleaner(nodeRegistry, applicationRegistry, serverRegistry, adapterRegistry, objectRegistry, logger) +{ +} + +ApplicationCleaner::ApplicationCleaner(const Deployer& deployer) : + Cleaner(deployer) +{ +} + +void +ApplicationCleaner::clean(const ApplicationDescriptorPtr& descriptor) +{ + ApplicationWrapper(descriptor).visit(*this); +} + +void +ApplicationCleaner::visitApplicationEnd(const ApplicationWrapper&, const ApplicationDescriptorPtr& application) +{ + try + { + _applicationRegistry->remove(application->name); + } + catch(const ApplicationNotExistException&) + { + exception("application `" + application->name + " doesn't exist"); + } +} + +bool +ApplicationCleaner::visitServerStart(const ServerWrapper&, const ServerDescriptorPtr& server) +{ + ServerCleaner cleaner(*this); + cleaner.clean(server); + return false; +} + +ServerCleaner::ServerCleaner(const NodeRegistryPtr& nodeRegistry, + const ApplicationRegistryPtr& applicationRegistry, + const ServerRegistryPtr& serverRegistry, + const AdapterRegistryPtr& adapterRegistry, + const ObjectRegistryPtr& objectRegistry, + const Ice::LoggerPtr& logger) : + Cleaner(nodeRegistry, applicationRegistry, serverRegistry, adapterRegistry, objectRegistry, logger) +{ +} + +ServerCleaner::ServerCleaner(const Deployer& deployer) : + Cleaner(deployer) +{ +} + +ServerCleaner::ServerCleaner(const Cleaner& cleaner) : + Cleaner(cleaner) +{ +} + +void +ServerCleaner::clean(const ServerDescriptorPtr& descriptor, const string& backup) +{ + _backup = backup; + ServerWrapper(descriptor).visit(*this); +} + +bool +ServerCleaner::visitServerStart(const ServerWrapper&, const ServerDescriptorPtr& server) +{ + _currentNodeName = server->node; + + try + { + _currentServer = _serverRegistry->findByName(server->name); + _currentServer->setActivationMode(Manual); + _currentServer->stop(); + } + catch(const ServerNotExistException&) + { + exception("server `" + server->name + "' doesn't exist"); + } + catch(const Ice::ObjectNotExistException&) + { + _currentServer = 0; + } + catch(const Ice::LocalException& ex) + { + exception("couldn't contact node `" + server->node + "'", ex); + } + + try + { + _serverRegistry->remove(server->name); + } + catch(const ServerNotExistException&) + { + exception("server `" + server->name + "' doesn't exist"); + } + + try + { + if(!server->application.empty()) + { + _applicationRegistry->unregisterServer(server->application, server->name); + } + } + catch(const ApplicationNotExistException&) + { + exception("application `" + server->application + "' doesn't exist"); + } + + return true; +} + +void +ServerCleaner::visitServerEnd(const ServerWrapper&, const ServerDescriptorPtr& server) +{ + if(_currentServer) + { + try + { + _currentServer->removeConfigFile("config"); + _currentServer->destroy(); + } + catch(const Ice::ObjectNotExistException&) + { + } + catch(const Ice::LocalException& ex) + { + exception("couldn't contact node `" + _currentNodeName + "'", ex); + } + } +} + +bool +ServerCleaner::visitServiceStart(const ServiceWrapper&, const ServiceDescriptorPtr& service) +{ + if(!_currentServer) + { + return true; + } + + try + { + _currentServer->removeConfigFile("config_" + service->name); + } + catch(const Ice::LocalException& ex) + { + exception("couldn't contact node `" + _currentNodeName + "'", ex); + } + + return true; +} + +bool +ServerCleaner::visitAdapterStart(const AdapterWrapper&, const AdapterDescriptor& adapter) +{ + AdapterPrx adpt; + try + { + adpt = _adapterRegistry->remove(adapter.id, 0); + adpt->destroy(); + } + catch(const AdapterNotExistException&) + { + exception("adapter `" + adapter.id + "' doesn't exist"); + } + catch(const Ice::ObjectNotExistException&) + { + } + catch(const Ice::LocalException& ex) + { + exception("couldn't contact node `" + _currentNodeName + "'", ex); + } + + if(_currentServer) + { + try + { + _currentServer->removeAdapter(ServerAdapterPrx::uncheckedCast(adpt)); + } + catch(const Ice::LocalException& ex) + { + exception("couldn't contact node `" + _currentNodeName + "'", ex); + } + } + + return true; +} + +void +ServerCleaner::visitDbEnv(const DbEnvWrapper&, const DbEnvDescriptor& dbEnv) +{ + if(_currentServer) + { + try + { + _currentServer->removeDbEnv(dbEnv, _backup); + } + catch(const Ice::LocalException& ex) + { + exception("couldn't contact node `" + _currentNodeName + "'", ex); + } + } +} + +void +ServerCleaner::visitObject(const ObjectWrapper&, const ObjectDescriptor& object) +{ + try + { + _objectRegistry->remove(object.proxy->ice_getIdentity()); + } + catch(const ObjectNotExistException&) + { + exception("object `" + Ice::identityToString(object.proxy->ice_getIdentity()) + "' doesn't exist"); + } +} + +AdminI::AdminI(const CommunicatorPtr& communicator, + const NodeRegistryPtr& nodeRegistry, + const ApplicationRegistryPtr& applicationRegistry, + const ServerRegistryPtr& serverRegistry, + const AdapterRegistryPtr& adapterRegistry, + const ObjectRegistryPtr& objectRegistry, + const RegistryPtr& registry) : + _communicator(communicator), + _nodeRegistry(nodeRegistry), + _applicationRegistry(applicationRegistry), + _serverRegistry(serverRegistry), + _adapterRegistry(adapterRegistry), + _objectRegistry(objectRegistry), + _registry(registry) +{ +} + +AdminI::~AdminI() +{ +} + +void +AdminI::addApplication(const ApplicationDescriptorPtr& descriptor, const Current&) +{ + ApplicationDeployer(_nodeRegistry, + _applicationRegistry, + _serverRegistry, + _adapterRegistry, + _objectRegistry, + _communicator->getLogger()).deploy(descriptor); +} + +void +AdminI::updateApplication(const ApplicationDescriptorPtr& descriptor, const Current&) +{ + ApplicationUpdater(_nodeRegistry, + _applicationRegistry, + _serverRegistry, + _adapterRegistry, + _objectRegistry, + _communicator->getLogger()).update(descriptor); +} + +void +AdminI::removeApplication(const string& name, const Current&) +{ + ApplicationCleaner(_nodeRegistry, + _applicationRegistry, + _serverRegistry, + _adapterRegistry, + _objectRegistry, + _communicator->getLogger()).clean(_applicationRegistry->getDescriptor(name)); +} + +ApplicationDescriptorPtr +AdminI::getApplicationDescriptor(const string& name, const Current&) const +{ + return _applicationRegistry->getDescriptor(name); +} + +Ice::StringSeq +AdminI::getAllApplicationNames(const Current&) const +{ + return _applicationRegistry->getAll(); +} + +void +AdminI::addServer(const ServerDescriptorPtr& server, const Current&) +{ + if(!server->application.empty()) + { + DeploymentException ex; + ex.reason = "You need to update the descriptor of the application `" + server->application + "'" + + "to add this server."; + throw ex; + } + + ServerDeployer(_nodeRegistry, + _applicationRegistry, + _serverRegistry, + _adapterRegistry, + _objectRegistry, + _communicator->getLogger()).deploy(server); +} + +void +AdminI::updateServer(const ServerDescriptorPtr& server, const Current&) +{ + ServerDescriptorPtr orig = _serverRegistry->getDescriptor(server->name); + if(!orig->application.empty()) + { + DeploymentException ex; + ex.reason = "You need to update the descriptor of the application `" + orig->application + "'" + + "to add this server."; + throw ex; + } + + if(!equal(orig, server)) + { + string dir = _nodeRegistry->findByName(orig->node)->createTmpDir(); + + ServerCleaner(_nodeRegistry, + _applicationRegistry, + _serverRegistry, + _adapterRegistry, + _objectRegistry, + _communicator->getLogger()).clean(orig, dir); + + try + { + if(server->node == orig->node) + { + ServerDeployer(_nodeRegistry, + _applicationRegistry, + _serverRegistry, + _adapterRegistry, + _objectRegistry, + _communicator->getLogger()).deploy(server, dir); + } + else + { + ServerDeployer(_nodeRegistry, + _applicationRegistry, + _serverRegistry, + _adapterRegistry, + _objectRegistry, + _communicator->getLogger()).deploy(server); + } + } + catch(const DeploymentException&) + { + try + { + ServerDeployer(_nodeRegistry, + _applicationRegistry, + _serverRegistry, + _adapterRegistry, + _objectRegistry, + _communicator->getLogger()).deploy(orig, dir); + } + catch(DeploymentException& ex) + { + DeploymentException e; + e.reason = "Failed to update and rollback original application: " + ex.reason; + throw e; + } + } + + _nodeRegistry->findByName(orig->node)->destroyTmpDir(dir); + } +} + +void +AdminI::removeServer(const string& name, const Current&) +{ + ServerDescriptorPtr server = _serverRegistry->getDescriptor(name); + if(!server->application.empty()) + { + DeploymentException ex; + ex.reason = "You need to update the descriptor of the application `" + server->application + "'" + + " to remove this server."; + throw ex; + } + + ServerCleaner(_nodeRegistry, + _applicationRegistry, + _serverRegistry, + _adapterRegistry, + _objectRegistry, + _communicator->getLogger()).clean(server); +} + +ServerDescriptorPtr +AdminI::getServerDescriptor(const string& name, const Current&) const +{ + return _serverRegistry->getDescriptor(name); +} + +ServerState +AdminI::getServerState(const string& name, const Current&) const +{ + ServerPrx server = _serverRegistry->findByName(name); + try + { + return server->getState(); + } + catch(const Ice::ObjectNotExistException&) + { + throw ServerNotExistException(); + } + catch(const Ice::LocalException&) + { + throw NodeUnreachableException(); + } +} + +Ice::Int +AdminI::getServerPid(const string& name, const Current&) const +{ + ServerPrx server = _serverRegistry->findByName(name); + try + { + return server->getPid(); + } + catch(const Ice::ObjectNotExistException&) + { + throw ServerNotExistException(); + } + catch(const Ice::LocalException&) + { + throw NodeUnreachableException(); + } +} + +bool +AdminI::startServer(const string& name, const Current&) +{ + ServerPrx server = _serverRegistry->findByName(name); + try + { + return server->start(Manual); + } + catch(const Ice::ObjectNotExistException&) + { + throw ServerNotExistException(); + } + catch(const Ice::LocalException&) + { + throw NodeUnreachableException(); + } +} + +void +AdminI::stopServer(const string& name, const Current&) +{ + ServerPrx server = _serverRegistry->findByName(name); + try + { + server->stop(); + } + catch(const Ice::ObjectNotExistException&) + { + throw ServerNotExistException(); + } + catch(const Ice::LocalException&) + { + throw NodeUnreachableException(); + } +} + +void +AdminI::sendSignal(const string& name, const string& signal, const Current&) +{ + ServerPrx server = _serverRegistry->findByName(name); + try + { + server->sendSignal(signal); + } + catch(const Ice::ObjectNotExistException&) + { + throw ServerNotExistException(); + } + catch(const Ice::LocalException&) + { + throw NodeUnreachableException(); + } +} + +void +AdminI::writeMessage(const string& name, const string& message, Int fd, const Current&) +{ + ServerPrx server = _serverRegistry->findByName(name); + try + { + server->writeMessage(message, fd); + } + catch(const Ice::ObjectNotExistException&) + { + throw ServerNotExistException(); + } + catch(const Ice::LocalException&) + { + throw NodeUnreachableException(); + } +} + + +StringSeq +AdminI::getAllServerNames(const Current&) const +{ + return _serverRegistry->getAll(); +} + +ServerActivation +AdminI::getServerActivation(const ::std::string& name, const Ice::Current&) const +{ + ServerPrx server = _serverRegistry->findByName(name); + try + { + return server->getActivationMode(); + } + catch(const Ice::ObjectNotExistException&) + { + throw ServerNotExistException(); + } + catch(const Ice::LocalException&) + { + throw NodeUnreachableException(); + } +} + +void +AdminI::setServerActivation(const ::std::string& name, ServerActivation mode, const Ice::Current&) +{ + ServerPrx server = _serverRegistry->findByName(name); + try + { + server->setActivationMode(mode); + } + catch(const Ice::ObjectNotExistException&) + { + throw ServerNotExistException(); + } + catch(const Ice::LocalException&) + { + throw NodeUnreachableException(); + } +} + +string +AdminI::getAdapterEndpoints(const string& id, const Current&) const +{ + AdapterPrx adapter = _adapterRegistry->findById(id); + try + { + return _communicator->proxyToString(adapter->getDirectProxy()); + } + catch(AdapterNotActiveException&) + { + return ""; + } + catch(const Ice::ObjectNotExistException&) + { + throw AdapterNotExistException(); + } + catch(const Ice::LocalException&) + { + throw NodeUnreachableException(); + } +} + +StringSeq +AdminI::getAllAdapterIds(const Current&) const +{ + return _adapterRegistry->getAll(); +} + +void +AdminI::addObject(const Ice::ObjectPrx& proxy, const ::Ice::Current& current) +{ + ObjectDescriptor desc; + desc.proxy = proxy; + + try + { + addObjectWithType(proxy, proxy->ice_id(), current); + } + catch(const Ice::LocalException&) + { + DeploymentException ex; + ex.reason = "Couldn't invoke on the object to get its interface."; + throw ex; + } +} + +void +AdminI::addObjectWithType(const Ice::ObjectPrx& proxy, const string& type, const ::Ice::Current&) +{ + ObjectDescriptor desc; + desc.proxy = proxy; + desc.type = type; + _objectRegistry->add(desc); +} + +void +AdminI::removeObject(const Ice::Identity& id, const Ice::Current&) +{ + _objectRegistry->remove(id); +} + +ObjectDescriptor +AdminI::getObjectDescriptor(const Ice::Identity& id, const Ice::Current&) const +{ + return _objectRegistry->getObjectDescriptor(id); +} + +ObjectDescriptorSeq +AdminI::getAllObjectDescriptors(const string& expression, const Ice::Current&) const +{ + return _objectRegistry->findAll(expression); +} + +bool +AdminI::pingNode(const string& name, const Current&) const +{ + NodePrx node = _nodeRegistry->findByName(name); + try + { + node->ice_ping(); + return true; + } + catch(const Ice::ObjectNotExistException&) + { + throw NodeNotExistException(); + } + catch(const Ice::LocalException&) + { + return false; + } +} + +void +AdminI::shutdownNode(const string& name, const Current&) +{ + NodePrx node = _nodeRegistry->findByName(name); + try + { + node->shutdown(); + } + catch(const Ice::ObjectNotExistException&) + { + throw NodeNotExistException(); + } + catch(const Ice::LocalException&) + { + throw NodeUnreachableException(); + } +} + +void +AdminI::removeNode(const string& name, const Current&) +{ + // + // Remove the node servers. + // + ServerDescriptorSeq servers = _serverRegistry->getAllDescriptorsOnNode(name); + for(ServerDescriptorSeq::const_iterator p = servers.begin(); p != servers.end(); ++p) + { + ServerCleaner(_nodeRegistry, + _applicationRegistry, + _serverRegistry, + _adapterRegistry, + _objectRegistry, + _communicator->getLogger()).clean(*p); + } + + // + // Remove the node. + // + _nodeRegistry->remove(name); +} + +string +AdminI::getNodeHostname(const string& name, const Current&) const +{ + NodePrx node = _nodeRegistry->findByName(name); + try + { + return node->getHostname(); + } + catch(const Ice::ObjectNotExistException&) + { + throw NodeNotExistException(); + } + catch(const Ice::LocalException&) + { + throw NodeUnreachableException(); + } +} + + +StringSeq +AdminI::getAllNodeNames(const Current&) const +{ + return _nodeRegistry->getAll(); +} + +void +AdminI::shutdown(const Current&) +{ + _registry->shutdown(); +} + +SliceChecksumDict +AdminI::getSliceChecksums(const Current&) const +{ + return sliceChecksums(); +} diff --git a/cpp/src/IceGrid/AdminI.h b/cpp/src/IceGrid/AdminI.h new file mode 100644 index 00000000000..d0cd6e13cfd --- /dev/null +++ b/cpp/src/IceGrid/AdminI.h @@ -0,0 +1,83 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICE_GRID_ADMIN_I_H +#define ICE_GRID_ADMIN_I_H + +#include <IceGrid/Internal.h> + +namespace IceGrid +{ + +class Registry; +typedef IceUtil::Handle<Registry> RegistryPtr; + +class AdminI : public Admin, public IceUtil::Mutex +{ +public: + + AdminI(const Ice::CommunicatorPtr&, const NodeRegistryPtr&, const ApplicationRegistryPtr&, + const ServerRegistryPtr&, const AdapterRegistryPtr&, const ObjectRegistryPtr&, + const RegistryPtr&); + virtual ~AdminI(); + + virtual void addApplication(const ApplicationDescriptorPtr&, const Ice::Current&); + virtual void updateApplication(const ApplicationDescriptorPtr&, const Ice::Current&); + virtual void removeApplication(const std::string&, const Ice::Current&); + virtual ApplicationDescriptorPtr getApplicationDescriptor(const ::std::string&, const Ice::Current&) const; + virtual Ice::StringSeq getAllApplicationNames(const Ice::Current&) const; + + virtual void addServer(const ServerDescriptorPtr&, const Ice::Current&); + virtual void updateServer(const ServerDescriptorPtr&, const Ice::Current&); + virtual void removeServer(const ::std::string&, const Ice::Current&); + virtual ServerDescriptorPtr getServerDescriptor(const ::std::string&, const Ice::Current&) const; + + virtual ServerState getServerState(const ::std::string&, const Ice::Current&) const; + virtual Ice::Int getServerPid(const ::std::string&, const Ice::Current&) const; + virtual bool startServer(const ::std::string&, const Ice::Current&); + virtual void stopServer(const ::std::string&, const Ice::Current&); + virtual void sendSignal(const ::std::string&, const ::std::string&, const Ice::Current&); + virtual void writeMessage(const ::std::string&, const ::std::string&, Ice::Int, const Ice::Current&); + virtual Ice::StringSeq getAllServerNames(const Ice::Current&) const; + virtual ServerActivation getServerActivation(const ::std::string&, const Ice::Current&) const; + virtual void setServerActivation(const ::std::string&, ServerActivation, const Ice::Current&); + + virtual ::std::string getAdapterEndpoints(const ::std::string&, const ::Ice::Current&) const; + virtual Ice::StringSeq getAllAdapterIds(const ::Ice::Current&) const; + + virtual void addObject(const ::Ice::ObjectPrx&, const ::Ice::Current&); + virtual void addObjectWithType(const ::Ice::ObjectPrx&, const ::std::string&, const ::Ice::Current&); + virtual void removeObject(const ::Ice::Identity&, const ::Ice::Current&); + virtual ObjectDescriptor getObjectDescriptor(const Ice::Identity&, const ::Ice::Current&) const; + virtual ObjectDescriptorSeq getAllObjectDescriptors(const std::string&, const ::Ice::Current&) const; + + virtual bool pingNode(const std::string&, const Ice::Current&) const; + virtual void shutdownNode(const std::string&, const Ice::Current&); + virtual void removeNode(const std::string&, const Ice::Current&); + virtual std::string getNodeHostname(const std::string&, const Ice::Current&) const; + virtual Ice::StringSeq getAllNodeNames(const ::Ice::Current&) const; + + virtual void shutdown(const Ice::Current&); + + virtual Ice::SliceChecksumDict getSliceChecksums(const Ice::Current&) const; + +private: + + Ice::CommunicatorPtr _communicator; + NodeRegistryPtr _nodeRegistry; + ApplicationRegistryPtr _applicationRegistry; + ServerRegistryPtr _serverRegistry; + AdapterRegistryPtr _adapterRegistry; + ObjectRegistryPtr _objectRegistry; + RegistryPtr _registry; +}; + +} + +#endif diff --git a/cpp/src/IceGrid/ApplicationRegistryI.cpp b/cpp/src/IceGrid/ApplicationRegistryI.cpp new file mode 100644 index 00000000000..54792222548 --- /dev/null +++ b/cpp/src/IceGrid/ApplicationRegistryI.cpp @@ -0,0 +1,157 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <IceGrid/ApplicationRegistryI.h> +#include <IceGrid/TraceLevels.h> +#include <Freeze/Initialize.h> + +using namespace std; +using namespace IceGrid; + +const string ApplicationRegistryI::_dbName = "applicationregistry"; + +ApplicationRegistryI::ApplicationRegistryI(const Ice::CommunicatorPtr& communicator, + const ServerRegistryPtr& serverRegistry, + const string& envName, + const TraceLevelsPtr& traceLevels) : + _serverRegistry(serverRegistry), + _connectionCache(Freeze::createConnection(communicator, envName)), + _dictCache(_connectionCache, _dbName), + _traceLevels(traceLevels), + _envName(envName), + _communicator(communicator) +{ +} + +void +ApplicationRegistryI::add(const string& name, const Ice::Current&) +{ + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + StringStringSeqDict dict(connection, _dbName); + + StringStringSeqDict::iterator p = dict.find(name); + if(p != dict.end()) + { + throw ApplicationExistsException(); + } + + dict.put(pair<const string, const Ice::StringSeq>(name, Ice::StringSeq())); + + if(_traceLevels->applicationRegistry > 0) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->applicationRegistryCat); + out << "added application `" << name << "'"; + } +} + +void +ApplicationRegistryI::remove(const string& name, const Ice::Current&) +{ + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + StringStringSeqDict dict(connection, _dbName); + + StringStringSeqDict::iterator p = dict.find(name); + if(p == dict.end()) + { + throw ApplicationNotExistException(); + } + + dict.erase(p); + + if(_traceLevels->applicationRegistry > 0) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->applicationRegistryCat); + out << "removed application `" << name << "'"; + } +} + +void +ApplicationRegistryI::registerServer(const string& application, const string& name, const Ice::Current&) +{ + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + StringStringSeqDict dict(connection, _dbName); + + StringStringSeqDict::iterator p = dict.find(application); + if(p == dict.end()) + { + throw ApplicationNotExistException(); + } + + Ice::StringSeq servers = p->second; + servers.push_back(name); + p.set(servers); +} + +void +ApplicationRegistryI::unregisterServer(const string& application, const string& name, const Ice::Current&) +{ + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + StringStringSeqDict dict(connection, _dbName); + + StringStringSeqDict::iterator p = dict.find(application); + if(p == dict.end()) + { + throw ApplicationNotExistException(); + } + + Ice::StringSeq servers = p->second; + for(Ice::StringSeq::iterator q = servers.begin(); q != servers.end(); ++q) + { + if(*q == name) + { + servers.erase(q); + break; + } + } + p.set(servers); +} + +ApplicationDescriptorPtr +ApplicationRegistryI::getDescriptor(const string& name, const Ice::Current&) +{ + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + StringStringSeqDict dict(connection, _dbName); + + StringStringSeqDict::iterator p = dict.find(name); + if(p == dict.end()) + { + throw ApplicationNotExistException(); + } + + ApplicationDescriptorPtr descriptor = new ApplicationDescriptor(); + descriptor->name = name; + for(Ice::StringSeq::const_iterator q = p->second.begin(); q != p->second.end(); ++q) + { + try + { + descriptor->servers.push_back(_serverRegistry->getDescriptor(*q)); + } + catch(ServerNotExistException&) + { + } + } + return descriptor; +} + +Ice::StringSeq +ApplicationRegistryI::getAll(const Ice::Current&) const +{ + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + StringStringSeqDict dict(connection, _dbName); + + Ice::StringSeq names; + names.reserve(dict.size()); + + for(StringStringSeqDict::const_iterator p = dict.begin(); p != dict.end(); ++p) + { + names.push_back(p->first); + } + + return names; +} diff --git a/cpp/src/IceGrid/ApplicationRegistryI.h b/cpp/src/IceGrid/ApplicationRegistryI.h new file mode 100644 index 00000000000..fbe5efe3b93 --- /dev/null +++ b/cpp/src/IceGrid/ApplicationRegistryI.h @@ -0,0 +1,52 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICE_GRID_APPLICATION_REGISTRY_I_H +#define ICE_GRID_APPLICATION_REGISTRY_I_H + +#include <IceGrid/Internal.h> +#include <IceGrid/StringStringSeqDict.h> + +namespace IceGrid +{ + +class TraceLevels; +typedef IceUtil::Handle<TraceLevels> TraceLevelsPtr; + +class ApplicationRegistryI : public ApplicationRegistry +{ +public: + + ApplicationRegistryI(const Ice::CommunicatorPtr&, const ServerRegistryPtr&, const std::string&, + const TraceLevelsPtr&); + + virtual void add(const std::string&, const ::Ice::Current&); + virtual void remove(const std::string&, const ::Ice::Current&); + + virtual void registerServer(const std::string&, const std::string&, const Ice::Current&); + virtual void unregisterServer(const std::string&, const std::string&, const Ice::Current&); + + virtual ApplicationDescriptorPtr getDescriptor(const ::std::string&, const Ice::Current&); + virtual Ice::StringSeq getAll(const ::Ice::Current&) const; + +private: + + static const std::string _dbName; + + ServerRegistryPtr _serverRegistry; + Freeze::ConnectionPtr _connectionCache; + StringStringSeqDict _dictCache; + TraceLevelsPtr _traceLevels; + const std::string _envName; + const Ice::CommunicatorPtr _communicator; +}; + +} + +#endif diff --git a/cpp/src/IceGrid/DescriptorParser.cpp b/cpp/src/IceGrid/DescriptorParser.cpp new file mode 100644 index 00000000000..ea175e8f467 --- /dev/null +++ b/cpp/src/IceGrid/DescriptorParser.cpp @@ -0,0 +1,821 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <Ice/Ice.h> +#include <IceXML/Parser.h> +#include <IceGrid/Admin.h> +#include <IceGrid/DescriptorParser.h> + +#include <stack> +#include <fstream> + +using namespace std; +using namespace Ice; +using namespace IceGrid; + +namespace IceGrid +{ + +class DescriptorHandler : public IceXML::Handler +{ +public: + + DescriptorHandler(const string&); + + void setCommunicator(const Ice::CommunicatorPtr&); + void setVariables(const std::map<std::string, std::string>&); + void setTargets(const std::vector<std::string>&); + + virtual void startElement(const string&, const IceXML::Attributes&, int, int); + virtual void endElement(const string&, int, int); + virtual void characters(const string&, int, int); + virtual void error(const string&, int, int); + + const ApplicationDescriptorPtr& getApplicationDescriptor() const; + const ServerDescriptorPtr& getServerDescriptor() const; + +private: + + std::string getAttributeValue(const IceXML::Attributes&, const std::string&) const; + std::string getAttributeValueWithDefault(const IceXML::Attributes&, const std::string&, const std::string&) const; + bool isCurrentTargetDeployable() const; + std::string substitute(const std::string&) const; + std::string elementValue() const; + std::vector<std::string> getTargets(const std::string&) const; + void error(const string&) const; + + const std::string& getVariable(const std::string&) const; + bool hasVariable(const std::string&) const; + bool isTargetDeployable(const std::string&) const; + + Ice::CommunicatorPtr _communicator; + string _filename; + std::vector<std::string> _targets; + std::vector< std::map<std::string, std::string> > _variables; + std::stack<std::string> _elements; + int _targetCounter; + bool _isCurrentTargetDeployable; + int _line; + int _column; + + ApplicationDescriptorPtr _currentApplication; + ServerDescriptorPtr _currentServer; + ServiceDescriptorPtr _currentService; + ComponentDescriptorPtr _currentComponent; + AdapterDescriptor _currentAdapter; + DbEnvDescriptor _currentDbEnv; + + bool _isTopLevel; + bool _inProperties; + bool _inAdapters; +}; + +} + +DescriptorHandler::DescriptorHandler(const string& filename) : + _filename(filename), + _isCurrentTargetDeployable(true), + _isTopLevel(true), + _inProperties(false), + _inAdapters(false) +{ + _variables.push_back(map<string, string>()); +} + +void +DescriptorHandler::setCommunicator(const Ice::CommunicatorPtr& communicator) +{ + _communicator = communicator; +} + +void +DescriptorHandler::setVariables(const std::map<std::string, std::string>& variables) +{ + _variables.clear(); + _variables.push_back(variables); +} + +void +DescriptorHandler::setTargets(const vector<string>& targets) +{ + _targets = targets; +} + +void +DescriptorHandler::startElement(const string& name, const IceXML::Attributes& attrs, int line, int column) +{ + _line = line; + _column = column; + + if(name == "icegrid") + { + if(!_isTopLevel) + { + error("element <icegrid> is a top level element"); + } + _isTopLevel = false; + } + else if(_isTopLevel) + { + error("only the <icegrid> element is allowed at the top-level"); + } + else if(name == "target") + { + if(!_isCurrentTargetDeployable) + { + ++_targetCounter; + } + else + { + _isCurrentTargetDeployable = isTargetDeployable(getAttributeValue(attrs, "name")); + _targetCounter = 1; + return; + } + } + else if(!isCurrentTargetDeployable()) + { + // + // We don't bother to parse the elements if the elements are enclosed in a target element + // which won't be deployed. + // + return; + } + else if(name == "include") + { + _variables.push_back(map<string, string>()); + + string file; + string targets; + + for(IceXML::Attributes::const_iterator p = attrs.begin(); p != attrs.end(); ++p) + { + if(p->first == "descriptor") + { + file = substitute(p->second); + } + else if(p->first == "targets") + { + targets = substitute(p->second); + } + else + { + string v = substitute(p->second); + _variables.back()[p->first] = v; + } + } + + if(file.empty()) + { + error("attribute `descriptor' is mandatory in element <include>"); + } + + if(file[0] != '/') + { + string::size_type end = _filename.find_last_of('/'); + if(end != string::npos) + { + file = _filename.substr(0, end) + "/" + file; + } + } + + string oldFileName = _filename; + vector<string> oldTargets = _targets; + _isTopLevel = true; + _filename = file; + _targets = getTargets(targets); + + IceXML::Parser::parse(file, *this); + + _variables.pop_back(); + _filename = oldFileName; + _targets = oldTargets; + } + else if(name == "application") + { + if(_currentApplication) + { + error("only one <application> element is allowed"); + } + _currentApplication = new ApplicationDescriptor(); + _currentApplication->name = getAttributeValue(attrs, "name"); + _variables.back()["application"] = _currentApplication->name; + } + else if(name == "node") + { + _variables.back()["node"] = getAttributeValue(attrs, "name"); + } + else if(name == "server") + { + if(!hasVariable("node")) + { + error("the <server> element can only be a child of a <node> element"); + } + + string kind = getAttributeValue(attrs, "kind"); + if(kind == "cpp" || kind == "cs") + { + _currentServer = new ServerDescriptor(); + _currentServer->exe = getAttributeValue(attrs, "exe"); + } + else if(kind == "java") + { + JavaServerDescriptorPtr descriptor = new JavaServerDescriptor(); + _currentServer = descriptor; + _currentServer->exe = getAttributeValueWithDefault(attrs, "exe", "java"); + descriptor->className = getAttributeValue(attrs, "classname"); + } + else if(kind == "cpp-icebox") + { + _currentServer = new CppIceBoxDescriptor(); + _currentServer->exe = getAttributeValueWithDefault(attrs, "exe", "icebox"); + } + else if(kind == "java-icebox") + { + JavaIceBoxDescriptorPtr descriptor = new JavaIceBoxDescriptor(); + _currentServer = descriptor; + _currentServer->exe = getAttributeValueWithDefault(attrs, "exe", "java"); + descriptor->className = getAttributeValueWithDefault(attrs, "classname", "IceBox.Server"); + } + + _currentServer->name = getAttributeValue(attrs, "name"); + _currentServer->node = getVariable("node"); + _currentServer->pwd = getAttributeValueWithDefault(attrs, "pwd", ""); + _currentServer->activation = + getAttributeValueWithDefault(attrs, "activation", "manual") == "on-demand" ? OnDemand : Manual; + + if(_currentApplication) + { + _currentServer->application = _currentApplication->name; + } + + if(kind == "cpp-icebox" || kind == "java-icebox") + { + CppIceBoxDescriptorPtr cppIceBox = CppIceBoxDescriptorPtr::dynamicCast(_currentServer); + if(cppIceBox) + { + cppIceBox->endpoints = getAttributeValue(attrs, "endpoints"); + } + JavaIceBoxDescriptorPtr javaIceBox = JavaIceBoxDescriptorPtr::dynamicCast(_currentServer); + if(javaIceBox) + { + javaIceBox->endpoints = getAttributeValue(attrs, "endpoints"); + } + + PropertyDescriptor prop; + prop.name = "IceBox.ServiceManager.Identity"; + prop.value = _currentServer->name + "/ServiceManager"; + _currentServer->properties.push_back(prop); + + AdapterDescriptor adapter; + adapter.name = "IceBox.ServiceManager"; + adapter.endpoints = getAttributeValue(attrs, "endpoints"); + adapter.id = _currentServer->name + "." + adapter.name; + adapter.registerProcess = true; + _currentServer->adapters.push_back(adapter); + } + + _currentComponent = _currentServer; + _variables.back()["server"] = _currentServer->name; + } + else if(name == "service") + { + if(!CppIceBoxDescriptorPtr::dynamicCast(_currentServer) && + !JavaIceBoxDescriptorPtr::dynamicCast(_currentServer)) + { + error("element <service> can only be a child of an IceBox <server> element"); + } + + _currentService = new ServiceDescriptor(); + _currentService->name = getAttributeValue(attrs, "name"); + _currentService->entry = getAttributeValue(attrs, "entry"); + + _currentComponent = _currentService; + _variables.back()["service"] = _currentService->name; + } + else if(name == "variable") + { + _variables.back()[getAttributeValue(attrs, "name")] = getAttributeValueWithDefault(attrs, "value", ""); + } + else if(name == "properties") + { + if(!_currentComponent) + { + error("the <properties> element can only be a child of a <server> or <service> element"); + } + + _inProperties = true; + } + else if(name == "property") + { + if(!_inProperties) + { + error("the <property> element can only be a child of a <properties> element"); + } + + PropertyDescriptor prop; + prop.name = getAttributeValue(attrs, "name"); + prop.value = getAttributeValueWithDefault(attrs, "value", ""); + _currentComponent->properties.push_back(prop); + } + else if(name == "adapters") + { + if(!_currentComponent) + { + error("the <adapters> element can only be a child of a <server> or <service> element"); + } + + _inAdapters = true; + } + else if(name == "adapter") + { + if(!_inAdapters) + { + error("the <adapter> element can only be a child of an <adapters> element"); + } + + _currentAdapter.name = getAttributeValue(attrs, "name"); + _currentAdapter.id = getAttributeValueWithDefault(attrs, "id", ""); + if(_currentAdapter.id.empty()) + { + string service = getVariable("service"); + const string fqn = getVariable("server") + (service.empty() ? "" : ".") + service; + _currentAdapter.id = fqn + "." + _currentAdapter.name; + } + _currentAdapter.endpoints = getAttributeValue(attrs, "endpoints"); + _currentAdapter.registerProcess = getAttributeValueWithDefault(attrs, "register", "false") == "true"; + } + else if(name == "object") + { + if(_currentAdapter.name.empty()) + { + error("the <object> element can only be a child of an <adapter> element"); + } + + ObjectDescriptor object; + object.type = getAttributeValueWithDefault(attrs, "type", ""); + object.proxy = _communicator->stringToProxy(getAttributeValue(attrs, "identity") + "@" + _currentAdapter.id); + object.adapterId = _currentAdapter.id; + _currentAdapter.objects.push_back(object); + } + else if(name == "dbenv") + { + if(!_currentComponent) + { + error("the <dbenv> element can only be a child of a <server> or <service> element"); + } + + _currentDbEnv.name = getAttributeValue(attrs, "name"); + + DbEnvDescriptorSeq::iterator p; + for(p = _currentComponent->dbEnvs.begin(); p != _currentComponent->dbEnvs.end(); ++p) + { + // + // We are re-opening the dbenv element to define more properties. + // + if(p->name == _currentDbEnv.name) + { + break; + } + } + + if(p != _currentComponent->dbEnvs.end()) + { + // + // Remove the previously defined dbenv, we'll add it back again when + // the dbenv element end tag is reached. + // + _currentDbEnv = *p; + _currentComponent->dbEnvs.erase(p); + } + + if(_currentDbEnv.dbHome.empty()) + { + _currentDbEnv.dbHome = getAttributeValueWithDefault(attrs, "home", ""); + } + } + else if(name == "dbproperty") + { + if(_currentDbEnv.name.empty()) + { + error("the <dbproperty> element can only be a child of a <dbenv> element"); + } + + PropertyDescriptor prop; + prop.name = getAttributeValue(attrs, "name"); + prop.value = getAttributeValueWithDefault(attrs, "value", ""); + _currentDbEnv.properties.push_back(prop); + } + + _elements.push(""); +} + +void +DescriptorHandler::endElement(const string& name, int line, int column) +{ + _line = line; + _column = column; + + if(name == "target") + { + if(!_isCurrentTargetDeployable && --_targetCounter == 0) + { + _isCurrentTargetDeployable = true; + _targetCounter = 0; + } + return; + } + else if(!isCurrentTargetDeployable()) + { + // + // We don't bother to parse the elements if the elements are enclosed in a target element + // which won't be deployed. + // + return; + } + else if(name == "application") + { + _variables.back()["application"] = ""; + } + else if(name == "node") + { + _variables.back()["node"] = ""; + } + else if(name == "server") + { + if(_currentApplication) + { + _currentApplication->servers.push_back(_currentServer); + _currentServer = 0; + } + _currentComponent = 0; + _variables.back()["server"] = ""; + } + else if(name == "service") + { + CppIceBoxDescriptorPtr cppIceBox = CppIceBoxDescriptorPtr::dynamicCast(_currentServer); + if(cppIceBox) + { + cppIceBox->services.push_back(_currentService); + } + JavaIceBoxDescriptorPtr javaIceBox = JavaIceBoxDescriptorPtr::dynamicCast(_currentServer); + if(javaIceBox) + { + javaIceBox->services.push_back(_currentService); + } + _currentService = 0; + _currentComponent = _currentServer; + _variables.back()["service"] = ""; + } + else if(name == "comment") + { + if(_currentComponent) + { + _currentComponent->comment = elementValue(); + } + else if(_currentApplication) + { + _currentApplication->comment = elementValue(); + } + } + else if(name == "option") + { + if(!_currentServer) + { + error("element <option> can only be the child of a <server> element"); + } + _currentServer->options.push_back(elementValue()); + } + else if(name == "env") + { + if(!_currentServer) + { + error("element <env> can only be the child of a <server> element"); + } + _currentServer->envs.push_back(elementValue()); + } + else if(name == "jvm-option") + { + JavaServerDescriptorPtr descriptor = JavaServerDescriptorPtr::dynamicCast(_currentServer); + if(!descriptor) + { + error("element <jvm-option> can only be the child of a Java <server> element"); + } + descriptor->jvmOptions.push_back(elementValue()); + } + else if(name == "properties") + { + _inProperties = false; + } + else if(name == "adapters") + { + _inAdapters = false; + } + else if(name == "adapter") + { + _currentComponent->adapters.push_back(_currentAdapter); + _currentAdapter = AdapterDescriptor(); + } + else if(name == "dbenv") + { + _currentComponent->dbEnvs.push_back(_currentDbEnv); + _currentDbEnv = DbEnvDescriptor(); + } + + _elements.pop(); +} + +void +DescriptorHandler::characters(const string& chars, int, int) +{ + _elements.top().assign(chars); +} + +void +DescriptorHandler::error(const string& msg, int line, int column) +{ + ostringstream os; + os << "error in <" << _filename << "> descriptor, line " << line << ", column " << column << ":\n" << msg; + throw IceXML::ParserException(__FILE__, __LINE__, os.str()); +} + +const ApplicationDescriptorPtr& +DescriptorHandler::getApplicationDescriptor() const +{ + if(!_currentApplication) + { + error("no application descriptor defined in this file"); + } + return _currentApplication; +} + +const ServerDescriptorPtr& +DescriptorHandler::getServerDescriptor() const +{ + if(!_currentServer) + { + error("no server descriptor defined in this file"); + } + return _currentServer; +} + +string +DescriptorHandler::getAttributeValue(const IceXML::Attributes& attrs, const string& name) const +{ + IceXML::Attributes::const_iterator p = attrs.find(name); + if(p == attrs.end()) + { + error("missing attribute '" + name + "'"); + } + string v = substitute(p->second); + if(v.empty()) + { + error("attribute '" + name + "' is empty"); + } + return v; +} + +string +DescriptorHandler::getAttributeValueWithDefault(const IceXML::Attributes& attrs, + const string& name, + const string& def) const +{ + IceXML::Attributes::const_iterator p = attrs.find(name); + if(p == attrs.end()) + { + return substitute(def); + } + else + { + return substitute(p->second); + } +} + +bool +DescriptorHandler::isCurrentTargetDeployable() const +{ + return _isCurrentTargetDeployable; +} + +vector<string> +DescriptorHandler::getTargets(const string& targets) const +{ + vector<string> result; + + if(!targets.empty()) + { + const string delim = " \t\n\r"; + + string::size_type beg = 0; + string::size_type end = 0; + do + { + end = targets.find_first_of(delim, end); + if(end == string::npos) + { + end = targets.size(); + } + + result.push_back(targets.substr(beg, end - beg)); + beg = ++end; + } + while(end < targets.size()); + } + + copy(_targets.begin(), _targets.end(), back_inserter(result)); + + return result; +} + +void +DescriptorHandler::error(const string& msg) const +{ + ostringstream os; + os << "error in <" << _filename << "> descriptor, line " << _line << ", column " << _column << ":\n" << msg; + throw IceXML::ParserException(__FILE__, __LINE__, os.str()); +} + +const string& +DescriptorHandler::getVariable(const string& name) const +{ + static const string empty; + + vector< map< string, string> >::const_reverse_iterator p = _variables.rbegin(); + while(p != _variables.rend()) + { + map<string, string>::const_iterator q = p->find(name); + if(q != p->end()) + { + return q->second; + } + ++p; + } + return empty; +} + +string +DescriptorHandler::substitute(const string& v) const +{ + string value(v); + string::size_type beg = 0; + string::size_type end = 0; + + while((beg = value.find("${", beg)) != string::npos) + { + end = value.find("}", beg); + + if(end == string::npos) + { + error("malformed variable name in the '" + value + "' value"); + } + + string name = value.substr(beg + 2, end - beg - 2); + if(!hasVariable(name)) + { + error("unknown variable `" + name + "'"); + } + else + { + value.replace(beg, end - beg + 1, getVariable(name)); + } + } + + return value; +} + +string +DescriptorHandler::elementValue() const +{ + return substitute(_elements.top()); +} + +bool +DescriptorHandler::hasVariable(const string& name) const +{ + vector< map< string, string> >::const_reverse_iterator p = _variables.rbegin(); + while(p != _variables.rend()) + { + map<string, string>::const_iterator q = p->find(name); + if(q != p->end()) + { + return true; + } + ++p; + } + return false; +} + +bool +DescriptorHandler::isTargetDeployable(const string& target) const +{ + string application = getVariable("application"); + string node = getVariable("node"); + string server = getVariable("server"); + string service = getVariable("service"); + + // + // Compute the current fully qualified name of the component. + // + string fqn; + if(!application.empty()) + { + fqn = application; + if(!node.empty()) + { + fqn += "." + node; + } + } + else + { + if(!node.empty()) + { + fqn = node; + } + } + if(!server.empty()) + { + assert(!node.empty()); + fqn += "." + server; + } + if(!service.empty()) + { + assert(!server.empty()); + fqn += "." + service; + } + + // + // Go through the list of supplied targets and see if we can match one with the current component + target. + // + for(vector<string>::const_iterator p = _targets.begin(); p != _targets.end(); ++p) + { + if((*p) == target) + { + // + // A supplied target without any component prefix is matching the target. + // + return true; + } + else + { + string componentTarget; + string::size_type end = 0; + while(end != string::npos) + { + // + // Add the first component name from the component fully qualified name to the + // target and see if matches. + // + end = fqn.find('.', end); + if(end == string::npos) + { + componentTarget = fqn + "." + target; + } + else + { + componentTarget = fqn.substr(0, end) + "." + target; + ++end; + } + + if((*p) == componentTarget) + { + return true; + } + } + } + } + + return false; +} + +ApplicationDescriptorPtr +DescriptorParser::parseApplicationDescriptor(const string& descriptor, + const Ice::StringSeq& targets, + const map<string, string>& variables, + const Ice::CommunicatorPtr& communicator) +{ + DescriptorHandler handler(descriptor); + handler.setCommunicator(communicator); + handler.setTargets(targets); + handler.setVariables(variables); + IceXML::Parser::parse(descriptor, handler); + return handler.getApplicationDescriptor(); +} + +ServerDescriptorPtr +DescriptorParser::parseServerDescriptor(const string& descriptor, + const Ice::StringSeq& targets, + const map<string, string>& variables, + const Ice::CommunicatorPtr& communicator) +{ + DescriptorHandler handler(descriptor); + handler.setCommunicator(communicator); + handler.setTargets(targets); + handler.setVariables(variables); + IceXML::Parser::parse(descriptor, handler); + return handler.getServerDescriptor(); +} diff --git a/cpp/src/IceGrid/DescriptorParser.h b/cpp/src/IceGrid/DescriptorParser.h new file mode 100644 index 00000000000..e448abf2aa2 --- /dev/null +++ b/cpp/src/IceGrid/DescriptorParser.h @@ -0,0 +1,34 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICEPACK_DESCRIPTOR_PARSER_H +#define ICEPACK_DESCRIPTOR_PARSER_H + +namespace IceGrid +{ + +class DescriptorParser +{ +public: + + static ApplicationDescriptorPtr parseApplicationDescriptor(const std::string&, + const Ice::StringSeq&, + const std::map<std::string, std::string>&, + const Ice::CommunicatorPtr&); + + static ServerDescriptorPtr parseServerDescriptor(const std::string&, + const Ice::StringSeq&, + const std::map<std::string, std::string>&, + const Ice::CommunicatorPtr&); + +}; + +} + +#endif diff --git a/cpp/src/IceGrid/DescriptorUtil.cpp b/cpp/src/IceGrid/DescriptorUtil.cpp new file mode 100644 index 00000000000..fda7d194534 --- /dev/null +++ b/cpp/src/IceGrid/DescriptorUtil.cpp @@ -0,0 +1,216 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <IceGrid/DescriptorUtil.h> + +using namespace std; + +namespace IceGrid +{ + +bool equal(const ServiceDescriptorPtr&, const ServiceDescriptorPtr&); + +} + +bool +IceGrid::equal(const ServiceDescriptorPtr& lhs, const ServiceDescriptorPtr& rhs) +{ + if(lhs->ice_id() != rhs->ice_id()) + { + return false; + } + + if(lhs->name != rhs->name) + { + return false; + } + + if(lhs->comment != rhs->comment) + { + return false; + } + + if(lhs->entry != rhs->entry) + { + return false; + } + + if(set<AdapterDescriptor>(lhs->adapters.begin(), lhs->adapters.end()) != + set<AdapterDescriptor>(rhs->adapters.begin(), rhs->adapters.end())) + { + return false; + } + + if(set<PropertyDescriptor>(lhs->properties.begin(), lhs->properties.end()) != + set<PropertyDescriptor>(rhs->properties.begin(), rhs->properties.end())) + { + return false; + } + + if(set<DbEnvDescriptor>(lhs->dbEnvs.begin(), lhs->dbEnvs.end()) != + set<DbEnvDescriptor>(rhs->dbEnvs.begin(), rhs->dbEnvs.end())) + { + return false; + } + + return true; +} + +bool +IceGrid::equal(const ServerDescriptorPtr& lhs, const ServerDescriptorPtr& rhs) +{ + if(lhs->ice_id() != rhs->ice_id()) + { + return false; + } + + if(lhs->name != rhs->name) + { + return false; + } + + if(lhs->comment != rhs->comment) + { + return false; + } + + if(lhs->exe != rhs->exe) + { + return false; + } + + if(lhs->pwd != rhs->pwd) + { + return false; + } + + if(lhs->node != rhs->node) + { + return false; + } + + if(lhs->application != rhs->application) + { + return false; + } + + if(set<AdapterDescriptor>(lhs->adapters.begin(), lhs->adapters.end()) != + set<AdapterDescriptor>(rhs->adapters.begin(), rhs->adapters.end())) + { + return false; + } + + if(set<PropertyDescriptor>(lhs->properties.begin(), lhs->properties.end()) != + set<PropertyDescriptor>(rhs->properties.begin(), rhs->properties.end())) + { + return false; + } + + if(set<DbEnvDescriptor>(lhs->dbEnvs.begin(), lhs->dbEnvs.end()) != + set<DbEnvDescriptor>(rhs->dbEnvs.begin(), rhs->dbEnvs.end())) + { + return false; + } + + if(set<string>(lhs->options.begin(), lhs->options.end()) != set<string>(rhs->options.begin(), rhs->options.end())) + { + return false; + } + + if(set<string>(lhs->envs.begin(), lhs->envs.end()) != set<string>(rhs->envs.begin(), rhs->envs.end())) + { + return false; + } + + // + // TODO: perhaps if would be better to define an equal operation on the Slice class? + // + ServiceDescriptorSeq slhs; + ServiceDescriptorSeq srhs; + + if(JavaServerDescriptorPtr::dynamicCast(lhs)) + { + JavaServerDescriptorPtr jlhs = JavaServerDescriptorPtr::dynamicCast(lhs); + JavaServerDescriptorPtr jrhs = JavaServerDescriptorPtr::dynamicCast(rhs); + + if(jlhs->className != jrhs->className) + { + return false; + } + + if(set<string>(jlhs->jvmOptions.begin(), jlhs->jvmOptions.end()) != + set<string>(jrhs->jvmOptions.begin(), jrhs->jvmOptions.end())) + { + return false; + } + + if(JavaIceBoxDescriptorPtr::dynamicCast(lhs)) + { + JavaIceBoxDescriptorPtr ilhs = JavaIceBoxDescriptorPtr::dynamicCast(lhs); + JavaIceBoxDescriptorPtr irhs = JavaIceBoxDescriptorPtr::dynamicCast(rhs); + + if(ilhs->endpoints != irhs->endpoints) + { + return false; + } + + if(ilhs->services.size() != irhs->services.size()) + { + return false; + } + + slhs = ilhs->services; + srhs = irhs->services; + } + } + else if(CppIceBoxDescriptorPtr::dynamicCast(lhs)) + { + CppIceBoxDescriptorPtr ilhs = CppIceBoxDescriptorPtr::dynamicCast(lhs); + CppIceBoxDescriptorPtr irhs = CppIceBoxDescriptorPtr::dynamicCast(rhs); + + if(ilhs->endpoints != irhs->endpoints) + { + return false; + } + + if(ilhs->services.size() != irhs->services.size()) + { + return false; + } + + slhs = ilhs->services; + srhs = irhs->services; + } + + if(!slhs.empty()) + { + for(ServiceDescriptorSeq::const_iterator p = slhs.begin(); p != slhs.end(); ++p) + { + bool found = false; + for(ServiceDescriptorSeq::const_iterator q = srhs.begin(); q != srhs.end(); ++q) + { + if((*p)->name == (*q)->name) + { + if(!equal(*p, *q)) + { + return false; + } + found = true; + break; + } + } + if(!found) + { + return false; + } + } + } + + return true; +} diff --git a/cpp/src/IceGrid/DescriptorUtil.h b/cpp/src/IceGrid/DescriptorUtil.h new file mode 100644 index 00000000000..97f3c3986eb --- /dev/null +++ b/cpp/src/IceGrid/DescriptorUtil.h @@ -0,0 +1,22 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICEPACK_DESCRIPTOR_UTIL_H +#define ICEPACK_DESCRIPTOR_UTIL_H + +#include <IceGrid/Admin.h> + +namespace IceGrid +{ + +bool equal(const ServerDescriptorPtr&, const ServerDescriptorPtr&); + +} + +#endif diff --git a/cpp/src/IceGrid/DescriptorVisitor.cpp b/cpp/src/IceGrid/DescriptorVisitor.cpp new file mode 100644 index 00000000000..e70690f1058 --- /dev/null +++ b/cpp/src/IceGrid/DescriptorVisitor.cpp @@ -0,0 +1,176 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <Ice/Ice.h> +#include <IceGrid/Admin.h> +#include <IceGrid/DescriptorVisitor.h> + +using namespace std; +using namespace Ice; +using namespace IceGrid; + +ApplicationWrapper::ApplicationWrapper(const ApplicationDescriptorPtr& descriptor) : _descriptor(descriptor) +{ +} + +void +ApplicationWrapper::visit(DescriptorVisitor& visitor) +{ + if(visitor.visitApplicationStart(*this, _descriptor)) + { + for(ServerDescriptorSeq::const_iterator p = _descriptor->servers.begin(); p != _descriptor->servers.end(); ++p) + { + ServerWrapper(*p).visit(visitor); + } + visitor.visitApplicationEnd(*this, _descriptor); + } +} + +const ApplicationDescriptorPtr& +ApplicationWrapper::getDescriptor() const +{ + return _descriptor; +} + +ComponentWrapper::ComponentWrapper(const ComponentDescriptorPtr& descriptor) : _descriptor(descriptor) +{ +} + +void +ComponentWrapper::visit(DescriptorVisitor& visitor) +{ + for(AdapterDescriptorSeq::const_iterator p = _descriptor->adapters.begin(); p != _descriptor->adapters.end(); ++p) + { + AdapterWrapper(*this, *p).visit(visitor); + } + + for(DbEnvDescriptorSeq::const_iterator q = _descriptor->dbEnvs.begin(); q != _descriptor->dbEnvs.end(); ++q) + { + DbEnvWrapper(*this, *q).visit(visitor); + } +} + +ServerWrapper::ServerWrapper(const ServerDescriptorPtr& descriptor) : + ComponentWrapper(descriptor), + _descriptor(descriptor) +{ +} + +void +ServerWrapper::visit(DescriptorVisitor& visitor) +{ + if(visitor.visitServerStart(*this, _descriptor)) + { + ComponentWrapper::visit(visitor); + + CppIceBoxDescriptorPtr cppIceBox = CppIceBoxDescriptorPtr::dynamicCast(_descriptor); + JavaIceBoxDescriptorPtr javaIceBox = JavaIceBoxDescriptorPtr::dynamicCast(_descriptor); + + const ServiceDescriptorSeq& services = + cppIceBox ? cppIceBox->services : (javaIceBox ? javaIceBox->services : ServiceDescriptorSeq()); + + for(ServiceDescriptorSeq::const_iterator p = services.begin(); p != services.end(); ++p) + { + ServiceWrapper(*this, *p).visit(visitor); + } + visitor.visitServerEnd(*this, _descriptor); + } +} + +const ServerDescriptorPtr& +ServerWrapper::getDescriptor() const +{ + return _descriptor; +} + +ServiceWrapper::ServiceWrapper(const ServerWrapper& server, const ServiceDescriptorPtr& descriptor) : + ComponentWrapper(descriptor), + _server(server), + _descriptor(descriptor) +{ +} + +void +ServiceWrapper::visit(DescriptorVisitor& visitor) +{ + if(visitor.visitServiceStart(*this, _descriptor)) + { + ComponentWrapper::visit(visitor); + visitor.visitServiceEnd(*this, _descriptor); + } +} + +const ServiceDescriptorPtr& +ServiceWrapper::getDescriptor() const +{ + return _descriptor; +} + +DbEnvWrapper::DbEnvWrapper(const ComponentWrapper& component, const DbEnvDescriptor& descriptor) : + _component(component), + _descriptor(descriptor) +{ +} + +void +DbEnvWrapper::visit(DescriptorVisitor& visitor) +{ + visitor.visitDbEnv(*this, _descriptor); +} + +const DbEnvDescriptor& +DbEnvWrapper::getDescriptor() const +{ + return _descriptor; +} + +AdapterWrapper::AdapterWrapper(const ComponentWrapper& component, const AdapterDescriptor& descriptor) : + _component(component), + _descriptor(descriptor) +{ +} + +void +AdapterWrapper::visit(DescriptorVisitor& visitor) +{ + if(visitor.visitAdapterStart(*this, _descriptor)) + { + for(ObjectDescriptorSeq::const_iterator p = _descriptor.objects.begin(); p != _descriptor.objects.end(); ++p) + { + ObjectWrapper(*this, *p).visit(visitor); + } + visitor.visitAdapterEnd(*this, _descriptor); + } +} + +const AdapterDescriptor& +AdapterWrapper::getDescriptor() const +{ + return _descriptor; +} + +ObjectWrapper::ObjectWrapper(const AdapterWrapper& adapter, const ObjectDescriptor& descriptor): + _adapter(adapter), + _descriptor(descriptor) +{ +} + +void +ObjectWrapper::visit(DescriptorVisitor& visitor) +{ + visitor.visitObject(*this, _descriptor); +} + +const ObjectDescriptor& +ObjectWrapper::getDescriptor() const +{ + return _descriptor; +} + + diff --git a/cpp/src/IceGrid/DescriptorVisitor.h b/cpp/src/IceGrid/DescriptorVisitor.h new file mode 100644 index 00000000000..90b6c93021b --- /dev/null +++ b/cpp/src/IceGrid/DescriptorVisitor.h @@ -0,0 +1,147 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICEPACK_DESCRIPTOR_VISITOR_H +#define ICEPACK_DESCRIPTOR_VISITOR_H + +namespace IceGrid +{ + +class ApplicationWrapper; +class ServerWrapper; +class ServiceWrapper; +class AdapterWrapper; +class ObjectWrapper; +class DbEnvWrapper; + +class DescriptorVisitor +{ +public: + + virtual ~DescriptorVisitor() { } + + virtual bool visitApplicationStart(const ApplicationWrapper&, const ApplicationDescriptorPtr&) { return true; } + virtual void visitApplicationEnd(const ApplicationWrapper&, const ApplicationDescriptorPtr&) { } + virtual bool visitServerStart(const ServerWrapper&, const ServerDescriptorPtr&) { return true; } + virtual void visitServerEnd(const ServerWrapper&, const ServerDescriptorPtr&) { } + virtual bool visitServiceStart(const ServiceWrapper&, const ServiceDescriptorPtr&) { return true; } + virtual void visitServiceEnd(const ServiceWrapper&, const ServiceDescriptorPtr&) { } + virtual bool visitAdapterStart(const AdapterWrapper&, const AdapterDescriptor&) { return true; } + virtual void visitAdapterEnd(const AdapterWrapper&, const AdapterDescriptor&) { } + virtual void visitDbEnv(const DbEnvWrapper&, const DbEnvDescriptor&) { } + virtual void visitObject(const ObjectWrapper&, const ObjectDescriptor&) { } +}; + +class ApplicationWrapper +{ +public: + + ApplicationWrapper(const ApplicationDescriptorPtr&); + + void visit(DescriptorVisitor&); + const ApplicationDescriptorPtr& getDescriptor() const; + +private: + + const ApplicationDescriptorPtr _descriptor; +}; + +class ComponentWrapper +{ +public: + + ComponentWrapper(const ComponentDescriptorPtr&); + + void visit(DescriptorVisitor&); + +private: + + ComponentDescriptorPtr _descriptor; + +}; + +class ServerWrapper : public ComponentWrapper +{ +public: + + ServerWrapper(const ServerDescriptorPtr&); + + void visit(DescriptorVisitor&); + const ServerDescriptorPtr& getDescriptor() const; + +private: + + ServerDescriptorPtr _descriptor; +}; + +class ServiceWrapper : public ComponentWrapper +{ +public: + + ServiceWrapper(const ServerWrapper&, const ServiceDescriptorPtr&); + + void visit(DescriptorVisitor&); + const ServiceDescriptorPtr& getDescriptor() const; + +private: + + const ServerWrapper& _server; + ServiceDescriptorPtr _descriptor; +}; + +class DbEnvWrapper +{ +public: + + DbEnvWrapper(const ComponentWrapper&, const DbEnvDescriptor&); + + void visit(DescriptorVisitor&); + const DbEnvDescriptor& getDescriptor() const; + +private: + + const ComponentWrapper& _component; + const DbEnvDescriptor& _descriptor; +}; + +class AdapterWrapper +{ +public: + + AdapterWrapper(const ComponentWrapper&, const AdapterDescriptor&); + + void visit(DescriptorVisitor&); + const AdapterDescriptor& getDescriptor() const; + +private: + + const ComponentWrapper& _component; + const AdapterDescriptor& _descriptor; +}; + +class ObjectWrapper +{ +public: + + ObjectWrapper(const AdapterWrapper&, const ObjectDescriptor&); + + void visit(DescriptorVisitor&); + const ObjectDescriptor& getDescriptor() const; + +private: + + const AdapterWrapper& _adapter; + const ObjectDescriptor& _descriptor; +}; + +} + +#endif + + diff --git a/cpp/src/IceGrid/GPL.h b/cpp/src/IceGrid/GPL.h new file mode 100644 index 00000000000..6468c3c1324 --- /dev/null +++ b/cpp/src/IceGrid/GPL.h @@ -0,0 +1,303 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICE_GPL_H +#define ICE_GPL_H + +static const char* gplBanner = +"This copy of Ice is free software. You are welcome to change it and/or\n" +"distribute copies under certain conditions. Type \"show copying\" to see\n" +"these conditions.\n" +"There is absolutely no warranty for Ice. Type \"show warranty\" for details.\n"; + +static const char* gplCopying = +" GNU GENERAL PUBLIC LICENSE\n" +" Version 2, June 1991\n" +"\n" +" Copyright (C) 1989, 1991 Free Software Foundation, Inc.\n" +" 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n" +" Everyone is permitted to copy and distribute verbatim copies\n" +" of this license document, but changing it is not allowed.\n" +"\n" +" Preamble\n" +"\n" +" The licenses for most software are designed to take away your\n" +"freedom to share and change it. By contrast, the GNU General Public\n" +"License is intended to guarantee your freedom to share and change free\n" +"software--to make sure the software is free for all its users. This\n" +"General Public License applies to most of the Free Software\n" +"Foundation's software and to any other program whose authors commit to\n" +"using it. (Some other Free Software Foundation software is covered by\n" +"the GNU Library General Public License instead.) You can apply it to\n" +"your programs, too.\n" +"\n" +" When we speak of free software, we are referring to freedom, not\n" +"price. Our General Public Licenses are designed to make sure that you\n" +"have the freedom to distribute copies of free software (and charge for\n" +"this service if you wish), that you receive source code or can get it\n" +"if you want it, that you can change the software or use pieces of it\n" +"in new free programs; and that you know you can do these things.\n" +"\n" +" To protect your rights, we need to make restrictions that forbid\n" +"anyone to deny you these rights or to ask you to surrender the rights.\n" +"These restrictions translate to certain responsibilities for you if you\n" +"distribute copies of the software, or if you modify it.\n" +"\n" +" For example, if you distribute copies of such a program, whether\n" +"gratis or for a fee, you must give the recipients all the rights that\n" +"you have. You must make sure that they, too, receive or can get the\n" +"source code. And you must show them these terms so they know their\n" +"rights.\n" +"\n" +" We protect your rights with two steps: (1) copyright the software, and\n" +"(2) offer you this license which gives you legal permission to copy,\n" +"distribute and/or modify the software.\n" +"\n" +" Also, for each author's protection and ours, we want to make certain\n" +"that everyone understands that there is no warranty for this free\n" +"software. If the software is modified by someone else and passed on, we\n" +"want its recipients to know that what they have is not the original, so\n" +"that any problems introduced by others will not reflect on the original\n" +"authors' reputations.\n" +"\n" +" Finally, any free program is threatened constantly by software\n" +"patents. We wish to avoid the danger that redistributors of a free\n" +"program will individually obtain patent licenses, in effect making the\n" +"program proprietary. To prevent this, we have made it clear that any\n" +"patent must be licensed for everyone's free use or not licensed at all.\n" +"\n" +" The precise terms and conditions for copying, distribution and\n" +"modification follow.\n" +"\n" +" GNU GENERAL PUBLIC LICENSE\n" +" TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n" +"\n" +" 0. This License applies to any program or other work which contains\n" +"a notice placed by the copyright holder saying it may be distributed\n" +"under the terms of this General Public License. The \"Program\", below,\n" +"refers to any such program or work, and a \"work based on the Program\"\n" +"means either the Program or any derivative work under copyright law:\n" +"that is to say, a work containing the Program or a portion of it,\n" +"either verbatim or with modifications and/or translated into another\n" +"language. (Hereinafter, translation is included without limitation in\n" +"the term \"modification\".) Each licensee is addressed as \"you\".\n" +"\n" +"Activities other than copying, distribution and modification are not\n" +"covered by this License; they are outside its scope. The act of\n" +"running the Program is not restricted, and the output from the Program\n" +"is covered only if its contents constitute a work based on the\n" +"Program (independent of having been made by running the Program).\n" +"Whether that is true depends on what the Program does.\n" +"\n" +" 1. You may copy and distribute verbatim copies of the Program's\n" +"source code as you receive it, in any medium, provided that you\n" +"conspicuously and appropriately publish on each copy an appropriate\n" +"copyright notice and disclaimer of warranty; keep intact all the\n" +"notices that refer to this License and to the absence of any warranty;\n" +"and give any other recipients of the Program a copy of this License\n" +"along with the Program.\n" +"\n" +"You may charge a fee for the physical act of transferring a copy, and\n" +"you may at your option offer warranty protection in exchange for a fee.\n" +"\n" +" 2. You may modify your copy or copies of the Program or any portion\n" +"of it, thus forming a work based on the Program, and copy and\n" +"distribute such modifications or work under the terms of Section 1\n" +"above, provided that you also meet all of these conditions:\n" +"\n" +" a) You must cause the modified files to carry prominent notices\n" +" stating that you changed the files and the date of any change.\n" +"\n" +" b) You must cause any work that you distribute or publish, that in\n" +" whole or in part contains or is derived from the Program or any\n" +" part thereof, to be licensed as a whole at no charge to all third\n" +" parties under the terms of this License.\n" +"\n" +" c) If the modified program normally reads commands interactively\n" +" when run, you must cause it, when started running for such\n" +" interactive use in the most ordinary way, to print or display an\n" +" announcement including an appropriate copyright notice and a\n" +" notice that there is no warranty (or else, saying that you provide\n" +" a warranty) and that users may redistribute the program under\n" +" these conditions, and telling the user how to view a copy of this\n" +" License. (Exception: if the Program itself is interactive but\n" +" does not normally print such an announcement, your work based on\n" +" the Program is not required to print an announcement.)\n" +"\n" +"These requirements apply to the modified work as a whole. If\n" +"identifiable sections of that work are not derived from the Program,\n" +"and can be reasonably considered independent and separate works in\n" +"themselves, then this License, and its terms, do not apply to those\n" +"sections when you distribute them as separate works. But when you\n" +"distribute the same sections as part of a whole which is a work based\n" +"on the Program, the distribution of the whole must be on the terms of\n" +"this License, whose permissions for other licensees extend to the\n" +"entire whole, and thus to each and every part regardless of who wrote it.\n" +"\n" +"Thus, it is not the intent of this section to claim rights or contest\n" +"your rights to work written entirely by you; rather, the intent is to\n" +"exercise the right to control the distribution of derivative or\n" +"collective works based on the Program.\n" +"\n" +"In addition, mere aggregation of another work not based on the Program\n" +"with the Program (or with a work based on the Program) on a volume of\n" +"a storage or distribution medium does not bring the other work under\n" +"the scope of this License.\n" +"\n" +" 3. You may copy and distribute the Program (or a work based on it,\n" +"under Section 2) in object code or executable form under the terms of\n" +"Sections 1 and 2 above provided that you also do one of the following:\n" +"\n" +" a) Accompany it with the complete corresponding machine-readable\n" +" source code, which must be distributed under the terms of Sections\n" +" 1 and 2 above on a medium customarily used for software interchange; or,\n" +"\n" +" b) Accompany it with a written offer, valid for at least three\n" +" years, to give any third party, for a charge no more than your\n" +" cost of physically performing source distribution, a complete\n" +" machine-readable copy of the corresponding source code, to be\n" +" distributed under the terms of Sections 1 and 2 above on a medium\n" +" customarily used for software interchange; or,\n" +"\n" +" c) Accompany it with the information you received as to the offer\n" +" to distribute corresponding source code. (This alternative is\n" +" allowed only for noncommercial distribution and only if you\n" +" received the program in object code or executable form with such\n" +" an offer, in accord with Subsection b above.)\n" +"\n" +"The source code for a work means the preferred form of the work for\n" +"making modifications to it. For an executable work, complete source\n" +"code means all the source code for all modules it contains, plus any\n" +"associated interface definition files, plus the scripts used to\n" +"control compilation and installation of the executable. However, as a\n" +"special exception, the source code distributed need not include\n" +"anything that is normally distributed (in either source or binary\n" +"form) with the major components (compiler, kernel, and so on) of the\n" +"operating system on which the executable runs, unless that component\n" +"itself accompanies the executable.\n" +"\n" +"If distribution of executable or object code is made by offering\n" +"access to copy from a designated place, then offering equivalent\n" +"access to copy the source code from the same place counts as\n" +"distribution of the source code, even though third parties are not\n" +"compelled to copy the source along with the object code.\n" +"\n" +" 4. You may not copy, modify, sublicense, or distribute the Program\n" +"except as expressly provided under this License. Any attempt\n" +"otherwise to copy, modify, sublicense or distribute the Program is\n" +"void, and will automatically terminate your rights under this License.\n" +"However, parties who have received copies, or rights, from you under\n" +"this License will not have their licenses terminated so long as such\n" +"parties remain in full compliance.\n" +"\n" +" 5. You are not required to accept this License, since you have not\n" +"signed it. However, nothing else grants you permission to modify or\n" +"distribute the Program or its derivative works. These actions are\n" +"prohibited by law if you do not accept this License. Therefore, by\n" +"modifying or distributing the Program (or any work based on the\n" +"Program), you indicate your acceptance of this License to do so, and\n" +"all its terms and conditions for copying, distributing or modifying\n" +"the Program or works based on it.\n" +"\n" +" 6. Each time you redistribute the Program (or any work based on the\n" +"Program), the recipient automatically receives a license from the\n" +"original licensor to copy, distribute or modify the Program subject to\n" +"these terms and conditions. You may not impose any further\n" +"restrictions on the recipients' exercise of the rights granted herein.\n" +"You are not responsible for enforcing compliance by third parties to\n" +"this License.\n" +"\n" +" 7. If, as a consequence of a court judgment or allegation of patent\n" +"infringement or for any other reason (not limited to patent issues),\n" +"conditions are imposed on you (whether by court order, agreement or\n" +"otherwise) that contradict the conditions of this License, they do not\n" +"excuse you from the conditions of this License. If you cannot\n" +"distribute so as to satisfy simultaneously your obligations under this\n" +"License and any other pertinent obligations, then as a consequence you\n" +"may not distribute the Program at all. For example, if a patent\n" +"license would not permit royalty-free redistribution of the Program by\n" +"all those who receive copies directly or indirectly through you, then\n" +"the only way you could satisfy both it and this License would be to\n" +"refrain entirely from distribution of the Program.\n" +"\n" +"If any portion of this section is held invalid or unenforceable under\n" +"any particular circumstance, the balance of the section is intended to\n" +"apply and the section as a whole is intended to apply in other\n" +"circumstances.\n" +"\n" +"It is not the purpose of this section to induce you to infringe any\n" +"patents or other property right claims or to contest validity of any\n" +"such claims; this section has the sole purpose of protecting the\n" +"integrity of the free software distribution system, which is\n" +"implemented by public license practices. Many people have made\n" +"generous contributions to the wide range of software distributed\n" +"through that system in reliance on consistent application of that\n" +"system; it is up to the author/donor to decide if he or she is willing\n" +"to distribute software through any other system and a licensee cannot\n" +"impose that choice.\n" +"\n" +"This section is intended to make thoroughly clear what is believed to\n" +"be a consequence of the rest of this License.\n" +"\n" +" 8. If the distribution and/or use of the Program is restricted in\n" +"certain countries either by patents or by copyrighted interfaces, the\n" +"original copyright holder who places the Program under this License\n" +"may add an explicit geographical distribution limitation excluding\n" +"those countries, so that distribution is permitted only in or among\n" +"countries not thus excluded. In such case, this License incorporates\n" +"the limitation as if written in the body of this License.\n" +"\n" +" 9. The Free Software Foundation may publish revised and/or new versions\n" +"of the General Public License from time to time. Such new versions will\n" +"be similar in spirit to the present version, but may differ in detail to\n" +"address new problems or concerns.\n" +"\n" +"Each version is given a distinguishing version number. If the Program\n" +"specifies a version number of this License which applies to it and \"any\n" +"later version\", you have the option of following the terms and conditions\n" +"either of that version or of any later version published by the Free\n" +"Software Foundation. If the Program does not specify a version number of\n" +"this License, you may choose any version ever published by the Free Software\n" +"Foundation.\n" +"\n" +" 10. If you wish to incorporate parts of the Program into other free\n" +"programs whose distribution conditions are different, write to the author\n" +"to ask for permission. For software which is copyrighted by the Free\n" +"Software Foundation, write to the Free Software Foundation; we sometimes\n" +"make exceptions for this. Our decision will be guided by the two goals\n" +"of preserving the free status of all derivatives of our free software and\n" +"of promoting the sharing and reuse of software generally.\n" +"\n"; + + +static const char* gplWarranty = +" NO WARRANTY\n" +"\n" +" 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\n" +"FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN\n" +"OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\n" +"PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\n" +"OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n" +"MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS\n" +"TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE\n" +"PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\n" +"REPAIR OR CORRECTION.\n" +"\n" +" 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\n" +"WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\n" +"REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\n" +"INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\n" +"OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\n" +"TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\n" +"YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\n" +"PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\n" +"POSSIBILITY OF SUCH DAMAGES.\n" +"\n"; + +#endif diff --git a/cpp/src/IceGrid/Grammar.y b/cpp/src/IceGrid/Grammar.y new file mode 100644 index 00000000000..cf4e8465db5 --- /dev/null +++ b/cpp/src/IceGrid/Grammar.y @@ -0,0 +1,271 @@ +%{ + +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <Ice/Ice.h> +#include <IceGrid/Parser.h> + +#ifdef _WIN32 +// I get these warnings from some bison versions: +// warning C4102: 'yyoverflowlab' : unreferenced label +# pragma warning( disable : 4102 ) +// warning C4065: switch statement contains 'default' but no 'case' labels +# pragma warning( disable : 4065 ) +#endif + +using namespace std; +using namespace Ice; +using namespace IceGrid; + +void +yyerror(const char* s) +{ + parser->error(s); +} + +%} + +%pure_parser + +%token ICE_GRID_HELP +%token ICE_GRID_EXIT +%token ICE_GRID_APPLICATION +%token ICE_GRID_NODE +%token ICE_GRID_SERVER +%token ICE_GRID_ADAPTER +%token ICE_GRID_PING +%token ICE_GRID_ADD +%token ICE_GRID_REMOVE +%token ICE_GRID_LIST +%token ICE_GRID_SHUTDOWN +%token ICE_GRID_STRING +%token ICE_GRID_START +%token ICE_GRID_STOP +%token ICE_GRID_SIGNAL +%token ICE_GRID_STDOUT +%token ICE_GRID_STDERR +%token ICE_GRID_DESCRIBE +%token ICE_GRID_STATE +%token ICE_GRID_PID +%token ICE_GRID_ENDPOINTS +%token ICE_GRID_ACTIVATION +%token ICE_GRID_OBJECT +%token ICE_GRID_FIND +%token ICE_GRID_SHOW +%token ICE_GRID_COPYING +%token ICE_GRID_WARRANTY +%token ICE_GRID_DIFF +%token ICE_GRID_UPDATE + +%% + +// ---------------------------------------------------------------------- +start +// ---------------------------------------------------------------------- +: commands +{ +} +| +{ +} +; + +// ---------------------------------------------------------------------- +commands +// ---------------------------------------------------------------------- +: commands command +{ +} +| command +{ +} +; + +// ---------------------------------------------------------------------- +command +// ---------------------------------------------------------------------- +: ICE_GRID_HELP ';' +{ + parser->usage(); +} +| ICE_GRID_EXIT ';' +{ + return 0; +} +| ICE_GRID_APPLICATION ICE_GRID_ADD strings ';' +{ + parser->addApplication($3); +} +| ICE_GRID_APPLICATION ICE_GRID_REMOVE strings ';' +{ + parser->removeApplication($3); +} +| ICE_GRID_APPLICATION ICE_GRID_DIFF strings ';' +{ + parser->diffApplication($3); +} +| ICE_GRID_APPLICATION ICE_GRID_UPDATE strings ';' +{ + parser->updateApplication($3); +} +| ICE_GRID_APPLICATION ICE_GRID_DESCRIBE strings ';' +{ + parser->describeApplication($3); +} +| ICE_GRID_APPLICATION ICE_GRID_LIST ';' +{ + parser->listAllApplications(); +} +| ICE_GRID_NODE ICE_GRID_PING strings ';' +{ + parser->pingNode($3); +} +| ICE_GRID_NODE ICE_GRID_SHUTDOWN strings ';' +{ + parser->shutdownNode($3); +} +| ICE_GRID_NODE ICE_GRID_REMOVE strings ';' +{ + parser->removeNode($3); +} +| ICE_GRID_NODE ICE_GRID_LIST ';' +{ + parser->listAllNodes(); +} +| ICE_GRID_SERVER ICE_GRID_ADD strings ';' +{ + parser->addServer($3); +} +| ICE_GRID_SERVER ICE_GRID_UPDATE strings ';' +{ + parser->updateServer($3); +} +| ICE_GRID_SERVER ICE_GRID_DESCRIBE strings ';' +{ + parser->describeServer($3); +} +| ICE_GRID_SERVER ICE_GRID_START strings ';' +{ + parser->startServer($3); +} +| ICE_GRID_SERVER ICE_GRID_STOP strings ';' +{ + parser->stopServer($3); +} +| ICE_GRID_SERVER ICE_GRID_SIGNAL strings ';' +{ + parser->signalServer($3); +} +| ICE_GRID_SERVER ICE_GRID_STDOUT strings ';' +{ + parser->writeMessage($3, 1); +} +| ICE_GRID_SERVER ICE_GRID_STDERR strings ';' +{ + parser->writeMessage($3, 2); +} +| ICE_GRID_SERVER ICE_GRID_STATE strings ';' +{ + parser->stateServer($3); +} +| ICE_GRID_SERVER ICE_GRID_PID strings ';' +{ + parser->pidServer($3); +} +| ICE_GRID_SERVER ICE_GRID_ACTIVATION strings ';' +{ + parser->activationServer($3); +} +| ICE_GRID_SERVER ICE_GRID_REMOVE strings ';' +{ + parser->removeServer($3); +} +| ICE_GRID_SERVER ICE_GRID_LIST ';' +{ + parser->listAllServers(); +} +| ICE_GRID_ADAPTER ICE_GRID_ENDPOINTS strings ';' +{ + parser->endpointsAdapter($3); +} +| ICE_GRID_ADAPTER ICE_GRID_LIST ';' +{ + parser->listAllAdapters(); +} +| ICE_GRID_OBJECT ICE_GRID_ADD strings ';' +{ + parser->addObject($3); +} +| ICE_GRID_OBJECT ICE_GRID_REMOVE strings ';' +{ + parser->removeObject($3); +} +| ICE_GRID_OBJECT ICE_GRID_FIND strings ';' +{ + parser->findObject($3); +} +| ICE_GRID_OBJECT ICE_GRID_LIST optional_strings ';' +{ + parser->listObject($3); +} +| ICE_GRID_OBJECT ICE_GRID_DESCRIBE optional_strings ';' +{ + parser->describeObject($3); +} +| ICE_GRID_SHUTDOWN ';' +{ + parser->shutdown(); +} +| ICE_GRID_SHOW ICE_GRID_COPYING ';' +{ + parser->showCopying(); +} +| ICE_GRID_SHOW ICE_GRID_WARRANTY ';' +{ + parser->showWarranty(); +} +| error ';' +{ + yyerrok; +} +| ';' +{ +} +; + +// ---------------------------------------------------------------------- +strings +// ---------------------------------------------------------------------- +: ICE_GRID_STRING strings +{ + $$ = $2; + $$.push_front($1.front()); +} +| ICE_GRID_STRING +{ + $$ = $1; +} +; + +// ---------------------------------------------------------------------- +optional_strings +// ---------------------------------------------------------------------- +: ICE_GRID_STRING optional_strings +{ + $$ = $2; + $$.push_front($1.front()); +} +| +{ + $$ = YYSTYPE() +} +; + +%% diff --git a/cpp/src/IceGrid/IceGridNode.cpp b/cpp/src/IceGrid/IceGridNode.cpp new file mode 100644 index 00000000000..81e500b1bb2 --- /dev/null +++ b/cpp/src/IceGrid/IceGridNode.cpp @@ -0,0 +1,598 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <IceUtil/UUID.h> +#include <Ice/Ice.h> +#include <Ice/Service.h> +#include <IceGrid/Activator.h> +#include <IceGrid/WaitQueue.h> +#include <IceGrid/Registry.h> +#include <IceGrid/ServerFactory.h> +#include <IceGrid/AdapterFactory.h> +#include <IceGrid/AdapterI.h> +#include <IceGrid/NodeI.h> +#include <IceGrid/TraceLevels.h> +#include <IceGrid/DescriptorParser.h> + +#ifdef _WIN32 +# include <direct.h> +# include <sys/types.h> +# include <sys/stat.h> +# define S_ISDIR(mode) ((mode) & _S_IFDIR) +# define S_ISREG(mode) ((mode) & _S_IFREG) +#else +# include <csignal> +# include <signal.h> +# include <sys/wait.h> +# include <sys/types.h> +# include <sys/stat.h> +# include <unistd.h> +#endif + +using namespace std; +using namespace Ice; +using namespace IceGrid; + +namespace IceGrid +{ + +class NodeService : public Service +{ +public: + + NodeService(); + + virtual bool shutdown(); + +protected: + + virtual bool start(int, char*[]); + virtual void waitForShutdown(); + virtual bool stop(); + virtual CommunicatorPtr initializeCommunicator(int&, char*[]); + +private: + + void usage(const std::string&); + + ActivatorPtr _activator; + WaitQueuePtr _waitQueue; + RegistryPtr _registry; +}; + +class CollocatedRegistry : public Registry +{ +public: + + CollocatedRegistry(const Ice::CommunicatorPtr&, const ActivatorPtr&); + virtual void shutdown(); + +private: + + ActivatorPtr _activator; +}; + +} // End of namespace IceGrid + +#ifndef _WIN32 +extern "C" +{ + +static void +childHandler(int) +{ + // + // Call wait to de-allocate any resources allocated for the child + // process and avoid zombie processes. See man wait or waitpid for + // more information. + // + int olderrno = errno; + + pid_t pid; + do + { + pid = waitpid(-1, 0, WNOHANG); + } + while(pid > 0); + + assert(pid != -1 || errno == ECHILD); + + errno = olderrno; +} + +} +#endif + +CollocatedRegistry::CollocatedRegistry(const Ice::CommunicatorPtr& communicator, const ActivatorPtr& activator) : + Registry(communicator), + _activator(activator) +{ +} + +void +CollocatedRegistry::shutdown() +{ + _activator->shutdown(); +} + +NodeService::NodeService() +{ +} + +bool +NodeService::shutdown() +{ + assert(_activator); + _activator->shutdown(); + return true; +} + +bool +NodeService::start(int argc, char* argv[]) +{ +#ifndef _WIN32 + // + // This application forks, so we need a signal handler for child termination. + // + struct sigaction action; + action.sa_handler = childHandler; + sigemptyset(&action.sa_mask); + sigaddset(&action.sa_mask, SIGCHLD); + action.sa_flags = 0; + sigaction(SIGCHLD, &action, 0); +#endif + + bool nowarn = false; + bool checkdb = false; + string descriptor; + vector<string> targets; + for(int i = 1; i < argc; ++i) + { + if(strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) + { + usage(argv[0]); + return false; + } + else if(strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0) + { + print(ICE_STRING_VERSION); + return false; + } + else if(strcmp(argv[i], "--nowarn") == 0) + { + nowarn = true; + } + else if(strcmp(argv[i], "--deploy") == 0) + { + if(i + 1 >= argc) + { + error("missing descriptor argument for option `" + string(argv[i]) + "'"); + usage(argv[0]); + return false; + } + + descriptor = argv[++i]; + + while(i + 1 < argc && argv[++i][0] != '-') + { + targets.push_back(argv[i]); + } + } + else if(strcmp(argv[i], "--checkdb") == 0) + { + checkdb = true; + } + } + + PropertiesPtr properties = communicator()->getProperties(); + + // + // Disable server idle time. Otherwise, the adapter would be + // shutdown prematurely and the deactivation would fail. + // Deactivation of the node relies on the object adapter + // to be active since it needs to terminate servers. + // + // TODO: implement Ice.ServerIdleTime in the activator + // termination listener instead? + // + properties->setProperty("Ice.ServerIdleTime", "0"); + if(properties->getPropertyAsIntWithDefault("Ice.ThreadPool.Server.Size", 5) <= 5) + { + properties->setProperty("Ice.ThreadPool.Server.Size", "5"); + } + + // + // Create the activator. + // + TraceLevelsPtr traceLevels = new TraceLevels(properties, communicator()->getLogger()); + _activator = new Activator(traceLevels, properties); + + // + // Collocate the IceGrid registry if we need to. + // + if(properties->getPropertyAsInt("IceGrid.Node.CollocateRegistry") > 0) + { + // + // The node needs a different thread pool. + // + if(properties->getPropertyAsInt("IceGrid.Node.ThreadPool.Size") == 0) + { + int size = properties->getPropertyAsInt("Ice.ThreadPool.Server.Size"); + + ostringstream os1; + os1 << static_cast<int>(size / 3); + properties->setProperty("IceGrid.Node.ThreadPool.Size", os1.str()); + + ostringstream os2; + os2 << size - static_cast<int>(size / 3); + properties->setProperty("Ice.ThreadPool.Server.Size", os2.str()); + } + + _registry = new CollocatedRegistry(communicator(), _activator); + if(!_registry->start(nowarn)) + { + return false; + } + + // + // Set the Ice.Default.Locator property to point to the + // collocated locator (this property is passed by the + // activator to each activated server). + // + string locatorPrx = "IceGrid/Locator:" + properties->getProperty("IceGrid.Registry.Client.Endpoints"); + properties->setProperty("Ice.Default.Locator", locatorPrx); + } + else if(properties->getProperty("Ice.Default.Locator").empty()) + { + error("property `Ice.Default.Locator' is not set"); + return false; + } + + // + // Initialize the database environment (first setup the directory structure if needed). + // + string dataPath = properties->getProperty("IceGrid.Node.Data"); + string dbPath; + if(dataPath.empty()) + { + error("property `IceGrid.Node.Data' is not set"); + return false; + } + else + { +#ifdef _WIN32 + struct _stat filestat; + if(::_stat(dataPath.c_str(), &filestat) != 0 || !S_ISDIR(filestat.st_mode)) + { + ostringstream os; + SyscallException ex(__FILE__, __LINE__); + ex.error = getSystemErrno(); + os << ex; + error("property `IceGrid.Node.Data' is set to an invalid path:\n" + os.str()); + return false; + } +#else + struct stat filestat; + if(::stat(dataPath.c_str(), &filestat) != 0 || !S_ISDIR(filestat.st_mode)) + { + ostringstream os; + SyscallException ex(__FILE__, __LINE__); + ex.error = getSystemErrno(); + os << ex; + error("property `IceGrid.Node.Data' is set to an invalid path:\n" + os.str()); + return false; + } +#endif + + // + // Creates subdirectories db and servers in the IceGrid.Node.Data directory if they don't already exist. + // + if(dataPath[dataPath.length() - 1] != '/') + { + dataPath += "/"; + } + + dbPath = dataPath + "db"; + string serversPath = dataPath + "servers"; + string tmpPath = dataPath + "tmp"; + +#ifdef _WIN32 + if(::_stat(dbPath.c_str(), &filestat) != 0) + { + _mkdir(dbPath.c_str()); + } + if(::_stat(serversPath.c_str(), &filestat) != 0) + { + _mkdir(serversPath.c_str()); + } + if(::_stat(tmpPath.c_str(), &filestat) != 0) + { + _mkdir(tmpPath.c_str()); + } +#else + if(::stat(dbPath.c_str(), &filestat) != 0) + { + mkdir(dbPath.c_str(), 0755); + } + if(::stat(serversPath.c_str(), &filestat) != 0) + { + mkdir(serversPath.c_str(), 0755); + } + if(::stat(tmpPath.c_str(), &filestat) != 0) + { + mkdir(tmpPath.c_str(), 0755); + } +#endif + } + + // + // Check that required properties are set and valid. + // + if(properties->getProperty("IceGrid.Node.Endpoints").empty()) + { + error("property `IceGrid.Node.Endpoints' is not set"); + return false; + } + + string name = properties->getProperty("IceGrid.Node.Name"); + if(name.empty()) + { + char host[1024 + 1]; + if(gethostname(host, 1024) != 0) + { + syserror("property `IceGrid.Node.Name' is not set and couldn't get the hostname:"); + return false; + } + else if(!nowarn) + { + warning("property `IceGrid.Node.Name' is not set, using hostname: " + string(host)); + } + properties->setProperty("IceGrid.Node.Name", string(host)); + } + + // + // Setup the Freeze database environment home directory. The name of the database + // environment for the IceGrid node is the name of the node. + // + properties->setProperty("Freeze.DbEnv." + name + ".DbHome", dbPath); + + // + // Set the adapter id for this node and create the node object adapter. + // + properties->setProperty("IceGrid.Node.AdapterId", "IceGrid.Node." + name); + ObjectAdapterPtr adapter = communicator()->createObjectAdapter("IceGrid.Node"); + + // + // Create the wait queue. + // + _waitQueue = new WaitQueue(); + _waitQueue->start(); + + // + // Create the server factory. The server factory creates persistent objects + // for the server and server adapter. It also takes care of installing the + // evictors and object factories necessary to store these objects. + // + ServerFactoryPtr serverFactory = new ServerFactory(adapter, traceLevels, name, _activator, _waitQueue); + NodePtr node = new NodeI(_activator, name, serverFactory, communicator(), properties); + Identity id = stringToIdentity(IceUtil::generateUUID()); + adapter->add(node, id); + NodePrx nodeProxy = NodePrx::uncheckedCast(adapter->createDirectProxy(id)); + + // + // Register this node with the node registry. + // + try + { + ObjectPrx nodeRegistry = communicator()->stringToProxy("IceGrid/NodeRegistry@IceGrid.Registry.Internal"); + NodeRegistryPrx::uncheckedCast(nodeRegistry)->add(name, nodeProxy); + } + catch(const NodeActiveException&) + { + error("a node with the same name is already registered and active"); + return false; + } + catch(const LocalException&) + { + error("couldn't contact the IceGrid registry"); + return false; + } + + // + // Check the consistency of the databases. + // + if(checkdb) + { + serverFactory->checkConsistency(); + } + + // + // Start the activator. + // + _activator->start(); + + // + // We are ready to go! Activate the object adapter. NOTE: we don't want the activate call to + // set the direct proxy of the object adapter with the locator registry. This was already + // taken care of by the node registry. Furthermore, this wouldn't work anyway because the + // locator registry proxy would have collocation optimization enabled. + // + adapter->setLocator(0); + adapter->activate(); + adapter->setLocator(communicator()->getDefaultLocator()); + + // + // Deploy application if a descriptor is passed as a command-line option. + // + if(!descriptor.empty()) + { + AdminPrx admin; + try + { + admin = AdminPrx::checkedCast(communicator()->stringToProxy("IceGrid/Admin")); + } + catch(const LocalException& ex) + { + ostringstream ostr; + ostr << "couldn't contact IceGrid admin interface to deploy application `" << descriptor << "':" << endl + << ex; + warning(ostr.str()); + } + + if(admin) + { + try + { + map<string, string> vars; + admin->addApplication( + DescriptorParser::parseApplicationDescriptor(descriptor, targets, vars, communicator())); + } + catch(const DeploymentException& ex) + { + ostringstream ostr; + ostr << "failed to deploy application `" << descriptor << "':" << endl << ex << ": " << ex.reason; + warning(ostr.str()); + } + catch(const LocalException& ex) + { + ostringstream ostr; + ostr << "failed to deploy application `" << descriptor << "':" << endl << ex; + warning(ostr.str()); + } + } + } + + string bundleName = properties->getProperty("IceGrid.Node.PrintServersReady"); + if(!bundleName.empty()) + { + print(bundleName + " ready"); + } + + return true; +} + +void +NodeService::waitForShutdown() +{ + // + // Wait for the activator shutdown. Once the run method returns + // all the servers have been deactivated. + // + enableInterrupt(); + _activator->waitForShutdown(); + disableInterrupt(); +} + +bool +NodeService::stop() +{ + try + { + _activator->destroy(); + } + catch(...) + { + } + + // + // The wait queue must be destroyed after the activator and before + // the communicator is shutdown. + // + try + { + _waitQueue->destroy(); + } + catch(...) + { + } + + // + // We can now safely shutdown the communicator. + // + try + { + communicator()->shutdown(); + communicator()->waitForShutdown(); + } + catch(...) + { + } + + _activator = 0; + + return true; +} + +CommunicatorPtr +NodeService::initializeCommunicator(int& argc, char* argv[]) +{ + PropertiesPtr defaultProperties = getDefaultProperties(argc, argv); + + // + // Make sure that IceGridNode doesn't use thread-per-connection. + // + defaultProperties->setProperty("Ice.ThreadPerConnection", ""); + + return Service::initializeCommunicator(argc, argv); +} + +void +NodeService::usage(const string& appName) +{ + string options = + "Options:\n" + "-h, --help Show this message.\n" + "-v, --version Display the Ice version.\n" + "--nowarn Don't print any security warnings.\n" + "\n" + "--deploy DESCRIPTOR [TARGET1 [TARGET2 ...]]\n" + " Deploy descriptor in file DESCRIPTOR, with\n" + " optional targets.\n" + "--checkdb Do a consistency check of the node database."; +#ifdef _WIN32 + if(checkSystem()) + { + options.append( + "\n" + "\n" + "--service NAME Run as the Windows service NAME.\n" + "\n" + "--install NAME [--display DISP] [--executable EXEC] [args]\n" + " Install as Windows service NAME. If DISP is\n" + " provided, use it as the display name,\n" + " otherwise NAME is used. If EXEC is provided,\n" + " use it as the service executable, otherwise\n" + " this executable is used. Any additional\n" + " arguments are passed unchanged to the\n" + " service at startup.\n" + "--uninstall NAME Uninstall Windows service NAME.\n" + "--start NAME [args] Start Windows service NAME. Any additional\n" + " arguments are passed unchanged to the\n" + " service.\n" + "--stop NAME Stop Windows service NAME." + ); + } +#else + options.append( + "\n" + "\n" + "--daemon Run as a daemon.\n" + "--noclose Do not close open file descriptors.\n" + "--nochdir Do not change the current working directory." + ); +#endif + print("Usage: " + appName + " [options]\n" + options); +} + +int +main(int argc, char* argv[]) +{ + NodeService svc; + return svc.main(argc, argv); +} diff --git a/cpp/src/IceGrid/IceGridRegistry.cpp b/cpp/src/IceGrid/IceGridRegistry.cpp new file mode 100644 index 00000000000..bcc320a213f --- /dev/null +++ b/cpp/src/IceGrid/IceGridRegistry.cpp @@ -0,0 +1,156 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <IceUtil/Options.h> +#include <Ice/Ice.h> +#include <Ice/Service.h> +#include <IceGrid/Registry.h> + +using namespace std; +using namespace Ice; +using namespace IceGrid; + +namespace IceGrid +{ + +class RegistryService : public Service +{ +public: + + RegistryService(); + +protected: + + virtual bool start(int, char*[]); + virtual CommunicatorPtr initializeCommunicator(int&, char*[]); + +private: + + void usage(const std::string&); + + RegistryPtr _registry; +}; + +} // End of namespace IceGrid + +RegistryService::RegistryService() +{ +} + +bool +RegistryService::start(int argc, char* argv[]) +{ + bool nowarn; + + IceUtil::Options opts; + opts.addOpt("h", "help"); + opts.addOpt("v", "version"); + opts.addOpt("", "nowarn"); + + vector<string> args; + try + { + args = opts.parse(argc, argv); + } + catch(const IceUtil::Options::BadOpt& e) + { + error(e.reason); + usage(argv[0]); + return false; + } + + if(opts.isSet("h") || opts.isSet("help")) + { + usage(argv[0]); + return false; + } + if(opts.isSet("v") || opts.isSet("version")) + { + print(ICE_STRING_VERSION); + return false; + } + nowarn = opts.isSet("nowarn"); + + if(!args.empty()) + { + usage(argv[0]); + return false; + } + + _registry = new Registry(communicator()); + if(!_registry->start(nowarn)) + { + return false; + } + + return true; +} + +CommunicatorPtr +RegistryService::initializeCommunicator(int& argc, char* argv[]) +{ + PropertiesPtr defaultProperties = getDefaultProperties(argc, argv); + + // + // Make sure that IceGridRegistry doesn't use thread-per-connection. + // + defaultProperties->setProperty("Ice.ThreadPerConnection", ""); + + return Service::initializeCommunicator(argc, argv); +} + +void +RegistryService::usage(const string& appName) +{ + string options = + "Options:\n" + "-h, --help Show this message.\n" + "-v, --version Display the Ice version.\n" + "--nowarn Don't print any security warnings."; +#ifdef _WIN32 + if(checkSystem()) + { + options.append( + "\n" + "\n" + "--service NAME Run as the Windows service NAME.\n" + "\n" + "--install NAME [--display DISP] [--executable EXEC] [args]\n" + " Install as Windows service NAME. If DISP is\n" + " provided, use it as the display name,\n" + " otherwise NAME is used. If EXEC is provided,\n" + " use it as the service executable, otherwise\n" + " this executable is used. Any additional\n" + " arguments are passed unchanged to the\n" + " service at startup.\n" + "--uninstall NAME Uninstall Windows service NAME.\n" + "--start NAME [args] Start Windows service NAME. Any additional\n" + " arguments are passed unchanged to the\n" + " service.\n" + "--stop NAME Stop Windows service NAME." + ); + } +#else + options.append( + "\n" + "\n" + "--daemon Run as a daemon.\n" + "--noclose Do not close open file descriptors.\n" + "--nochdir Do not change the current working directory." + ); +#endif + print("Usage: " + appName + " [options]\n" + options); +} + +int +main(int argc, char* argv[]) +{ + RegistryService svc; + return svc.main(argc, argv); +} diff --git a/cpp/src/IceGrid/Internal.ice b/cpp/src/IceGrid/Internal.ice new file mode 100644 index 00000000000..4fb73b5c473 --- /dev/null +++ b/cpp/src/IceGrid/Internal.ice @@ -0,0 +1,703 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICE_GRID_INTERNAL_ICE +#define ICE_GRID_INTERNAL_ICE + +#include <Ice/Identity.ice> +#include <Ice/BuiltinSequences.ice> +#include <Ice/ProcessF.ice> +#include <IceGrid/Admin.ice> + +module IceGrid +{ + +/** + * + * The object registry interface. + * + **/ +interface ObjectRegistry +{ + /** + * + * Add an object to the registry. + * + **/ + void add(ObjectDescriptor desc) + throws ObjectExistsException; + + /** + * + * Remove an object from the registry. + * + **/ + void remove(Ice::Identity id) + throws ObjectNotExistException; + + /** + * + * Find an object by identity and returns its description. + * + **/ + nonmutating ObjectDescriptor getObjectDescriptor(Ice::Identity id) + throws ObjectNotExistException; + + /** + * + * Find an object by identity and return its proxy. + * + **/ + nonmutating Object* findById(Ice::Identity id) + throws ObjectNotExistException; + + /** + * + * Find an object by type and return its proxy. + * + **/ + nonmutating Object* findByType(string type); + + /** + * + * Find all the objects with the given type. + * + **/ + nonmutating Ice::ObjectProxySeq findAllWithType(string type); + + /** + * + * Find all the objects matching the given expression. + * + **/ + nonmutating ObjectDescriptorSeq findAll(string expression); +}; + +/** + * + * This exception is raised if an adapter is active. + * + **/ +exception AdapterActiveException +{ +}; + +exception AdapterNotActiveException +{ + /** True if the adapter can be activated on demand. */ + bool activatable; + + /** How long to wait for the adapter to become active. */ + int timeout; +}; + +interface Adapter +{ + /** + * + * Activate this adapter. If this adapter can be activated, this + * will activate the adapter and return the direct proxy of the + * adapter once it's active. If this adapter can be activated on + * demand, this will return 0 if the adapter is inactive or the + * adapter direct proxy it's active. + * + **/ + ["ami", "amd"] Object* activate(); + + /** + * + * Get the adapter direct proxy. The adapter direct proxy is a + * proxy created with the object adapter. The proxy contains the + * last known adapter endpoints. + * + * @return A direct proxy containing the last known adapter + * endpoints if the adapter is already active. + * + **/ + ["ami"] nonmutating Object* getDirectProxy() + throws AdapterNotActiveException; + + /** + * + * Set the direct proxy for this adapter. + * + * @param The direct proxy. The direct proxy should be created + * with the object adapter and should contain the object adapter + * endpoints. + * + * @throws AdapterActiveException The adapter is already + * active. It's not possible to override the direct proxy of an + * active adapter. + * + **/ + ["ami"] void setDirectProxy(Object* proxy) + throws AdapterActiveException; + + /** + * + * Destroy the adapter. + * + **/ + void destroy(); +}; + +/** + * + * This exception is raised if an adapter with the same name already + * exists. + * + **/ +exception AdapterExistsException +{ +}; + +/** + * + * The adapter registry interface. + * + **/ +interface AdapterRegistry +{ + /** + * + * Add an adapter to the registry. + * + **/ + void add(string id, Adapter* adpt) + throws AdapterExistsException; + + /** + * + * Remove an adapter from the registry. If the given adapter proxy is not null, the adapter will + * be removed from the registry only if the proxy matches. + * + **/ + Adapter* remove(string id, Adapter* adpt) + throws AdapterNotExistException; + + /** + * + * Find an adapter and return its proxy. + * + **/ + Adapter* findById(string id) + throws AdapterNotExistException; + + /** + * + * Get all adapter ids. + * + **/ + nonmutating Ice::StringSeq getAll(); +}; + +/** + * + * A standalone adapter doesn't provide on demand activation. It just + * store the adapter endpoints in the proxy attribute. + * + **/ +class StandaloneAdapter implements Adapter +{ + /** + * + * The adapter direct proxy. + * + **/ + Object* proxy; +}; + +class Server; + +/** + * + * This class implements the [Adapter] interface and provides on + * demand server activation when the adapter endpoints are requested + * through the [getDirectProxy] method. + * + **/ +class ServerAdapter implements Adapter +{ + /** + * + * Returns the adaper id. + * + **/ + string getId(); + + /** + * + * The adapter server. + * + **/ + Server* svr; + + /** + * + * The adapter id. + * + **/ + string id; +}; + +/** + * + * A sequence of server adapter proxies. + * + **/ +dictionary<Ice::Identity, ServerAdapter*> ServerAdapterPrxDict; + +class Server +{ + /** + * + * Start the server. + * + * @param mode The activation mode requested, start returns false + * if the activation mode requested is not compatible with the + * server activation mode. For example if mode is Automatic and + * the server activation mode is Manual the start will return + * false. + * + * @return True if the server was successfully started, false + * otherwise. + * + **/ + bool start(ServerActivation mode); + + /** + * + * Stop the server. This methods returns only when the server is + * deactivated. If the server doesn't stop after a configurable + * amount of time, it will be killed. + * + **/ + void stop(); + + /** + * + * Send signal to the server + * + **/ + void sendSignal(string signal) + throws BadSignalException; + + /** + * + * Write message on servers' stdout or stderr. + * + **/ + void writeMessage(string message, int fd); + + /** + * + * Destroy the server. This method destroys the server and + * eventually deactivates if it's still active. + * + **/ + void destroy(); + + /** + * + * This method is called by the activator when it detects that the + * server has terminated. + * + **/ + void terminated(); + + /** + * + * Return the server state. + * + * @return The server state. + * + * @see ServerState + * + **/ + ServerState getState(); + + /** + * + * Get the server pid. Note that the value returned by this method + * is system dependant. On Unix operating systems, it's the pid + * value returned by the fork() system call and converted to an + * integer. + * + **/ + int getPid(); + + /** + * + * Get the descriptor used to deploy this server. + * + **/ + ServerDescriptor getDescriptor(); + + /** + * + * Set the server activation mode. + * + **/ + void setActivationMode(ServerActivation mode); + + /** + * + * Get the server activation mode. + * + **/ + ServerActivation getActivationMode(); + + /** + * + * Set the process proxy. + * + **/ + ["ami"] void setProcess(Ice::Process* proc); + + /** + * + * Set the server executable path. + * + **/ + void setExePath(string name); + + /** + * + * Set the path of the server working directory. + * + **/ + void setPwd(string path); + + /** + * + * Set the server environment variables. + * + **/ + void setEnvs(Ice::StringSeq envs); + + /** + * + * Set the server command line options. + * + **/ + void setOptions(Ice::StringSeq options); + + /** + * + * Add an adapter to this server. + * + **/ + void addAdapter(ServerAdapter* adapter, bool registerProcess) + throws DeploymentException; + + /** + * + * Remove an adapter from this server. + * + **/ + void removeAdapter(ServerAdapter* adapter); + + /** + * + * Add a configuration file. + * + **/ + string addConfigFile(string name, PropertyDescriptorSeq properties) + throws DeploymentException; + + /** + * + * Remove a configuration file. + * + **/ + void removeConfigFile(string name); + + /** + * + * Add a database environment. + * + **/ + string addDbEnv(DbEnvDescriptor dbEnv, string path) + throws DeploymentException; + + /** + * + * Remove a database environment. + * + **/ + void removeDbEnv(DbEnvDescriptor dbEnv, string path); + + /** The server name. */ + string name; + + /** The path of the server executable. */ + string exePath; + + /** The server environment variables. */ + Ice::StringSeq envs; + + /** The server command line options. */ + Ice::StringSeq options; + + /** The path to the server working directory. */ + string pwd; + + /** The server adapter proxies. */ + ServerAdapterPrxDict adapters; + + /** The server activation mode. */ + ServerActivation activation; + + /** True if an adapter is configured to register a process object. */ + bool processRegistered; + + /** The descriptor used to deploy this server. */ + ServerDescriptor descriptor; +}; + +/** + * + * This exception is raised if a server with the same name already + * exists. + * + **/ +exception ServerExistsException +{ +}; + +interface ServerRegistry +{ + /** + * + * Add a server to the registry. + * + **/ + void add(string name, Server* svr, ServerDescriptor descriptor) + throws ServerExistsException; + + /** + * + * Remove a server from the registry. + * + **/ + Server* remove(string name) + throws ServerNotExistException; + + /** + * + * Find a server. + * + * @param name Name of the server. + * + * @return Server proxy. + * + **/ + Server* findByName(string name) + throws ServerNotExistException; + + /** + * + * Get a server descriptor. + * + **/ + ServerDescriptor getDescriptor(string name) + throws ServerNotExistException; + + /** + * + * Get all the server names. + * + **/ + nonmutating Ice::StringSeq getAll(); + + /** + * + * Get all the server descriptors for servers deployed on the given node. + * + **/ + nonmutating ServerDescriptorSeq getAllDescriptorsOnNode(string node); +}; + +/** + * + * This exception is raised if a server with the same name already + * exists. + * + **/ +exception ApplicationExistsException +{ +}; + +interface ApplicationRegistry +{ + /** + * + * Add an application to the registry. + * + **/ + void add(string name) + throws ApplicationExistsException; + + /** + * + * Remove an application from the registry. + * + **/ + void remove(string name) + throws ApplicationNotExistException; + + /** + * + * Register a server with the given application. + * + **/ + void registerServer(string application, string name) + throws ApplicationNotExistException; + + /** + * + * Unregister a server from the given application. + * + **/ + void unregisterServer(string application, string name) + throws ApplicationNotExistException; + + /** + * + * Get an application descriptor. + * + **/ + ApplicationDescriptor getDescriptor(string name) + throws ApplicationNotExistException; + + /** + * + * Get all the application names. + * + **/ + nonmutating Ice::StringSeq getAll(); +}; + +interface Node +{ + /** + * + * Create a new server on this node. + * + * @param The name of the server. + * + * @param The descriptor of the server. + * + **/ + nonmutating Server* createServer(string name, ServerDescriptor desc) + throws DeploymentException; + + /** + * + * Create a new adapter of a given server on this node. + * + * @param server The server associted to the adapter. + * + * @param id The id of the adapter. + * + **/ + nonmutating ServerAdapter* createServerAdapter(Server* srv, string id); + + /** + * + * Create a temporary directory. + * + **/ + nonmutating string createTmpDir(); + + /** + * + * Destroy a temporary directory. + * + **/ + nonmutating void destroyTmpDir(string path); + + /** + * + * Get the node name. + * + **/ + nonmutating string getName(); + + /** + * + * Get the node hostname. + * + **/ + nonmutating string getHostname(); + + /** + * + * Shutdown the node. + * + **/ + nonmutating void shutdown(); +}; + +/** + * + * This exception is raised if a node is already registered and + * active. + * + **/ +exception NodeActiveException +{ +}; + +interface NodeRegistry +{ + /** + * + * Add a node to the registry. If a node with the same name is + * already registered, [add] will overide the previous node only + * if it's not active. + * + * @throws NodeActiveException Raised if the node is already + * registered and currently active. + * + **/ + void add(string name, Node* nd) + throws NodeActiveException; + + /** + * + * Remove a node from the registry. + * + **/ + void remove(string name) + throws NodeNotExistException; + + /** + * + * Find a node. + * + * @param name Name of the node. + * + * @return Node proxy or a null proxy if the node is not found. + * + **/ + Node* findByName(string name) + throws NodeNotExistException; + + /** + * + * Get all the node names. + * + **/ + nonmutating Ice::StringSeq getAll(); +}; + +}; + +#endif diff --git a/cpp/src/IceGrid/LocatorI.cpp b/cpp/src/IceGrid/LocatorI.cpp new file mode 100644 index 00000000000..27a8b7c1403 --- /dev/null +++ b/cpp/src/IceGrid/LocatorI.cpp @@ -0,0 +1,336 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <Ice/Ice.h> +#include <IceGrid/LocatorI.h> + +using namespace std; +using namespace IceGrid; + +namespace IceGrid +{ + +// +// Callback from asynchronous call to adapter->getDirectProxy() invoked in LocatorI::findAdapterById_async(). +// +class AMI_Adapter_getDirectProxyI : public AMI_Adapter_getDirectProxy +{ +public: + + AMI_Adapter_getDirectProxyI(const LocatorIPtr& locator, const string& id, const AdapterPrx& adapter) : + _locator(locator), _id(id), _adapter(adapter) + { + } + + virtual void ice_response(const ::Ice::ObjectPrx& obj) + { + assert(obj); + _locator->getDirectProxyCallback(_adapter->ice_getIdentity(), obj); + } + + virtual void ice_exception(const ::Ice::Exception& ex) + { + _locator->getDirectProxyException(_adapter, _id, ex); + } + +private: + + const LocatorIPtr _locator; + const string _id; + const AdapterPrx _adapter; +}; + +class AMI_Adapter_activateI : public AMI_Adapter_activate +{ +public: + + AMI_Adapter_activateI(const LocatorIPtr& locator, const string& id, const AdapterPrx& adapter) : + _locator(locator), _id(id), _adapter(adapter) + { + } + + virtual void ice_response(const ::Ice::ObjectPrx& obj) + { + _locator->getDirectProxyCallback(_adapter->ice_getIdentity(), obj); + } + + virtual void ice_exception(const ::Ice::Exception& ex) + { + _locator->getDirectProxyException(_adapter, _id, ex); + } + +private: + + const LocatorIPtr _locator; + const string _id; + const AdapterPrx _adapter; +}; + +// +// Callback from asynchrnous call to LocatorI::findAdapterById_async() invoked in LocatorI::findObjectById_async(). +// +class AMD_Locator_findAdapterByIdI : public Ice::AMD_Locator_findAdapterById +{ +public: + + AMD_Locator_findAdapterByIdI(const Ice::AMD_Locator_findObjectByIdPtr& cb, const Ice::ObjectPrx& obj) : + _cb(cb), + _obj(obj) + { + } + + virtual void ice_response(const ::Ice::ObjectPrx& obj) + { + // + // If the adapter dummy direct proxy is not null, return a + // proxy containing the identity we were looking for and the + // endpoints of the adapter. + // + // If null, return the proxy registered with the object + // registry. + // + if(obj) + { + _cb->ice_response(obj->ice_newIdentity(_obj->ice_getIdentity())); + } + else + { + _cb->ice_response(_obj); + } + } + + virtual void ice_exception(const ::Ice::Exception& ex) + { + try + { + ex.ice_throw(); + } + catch(Ice::AdapterNotFoundException&) + { + // + // We couldn't find the adapter, we ignore and return the + // original proxy containing the adapter id. + // + _cb->ice_response(_obj); + return; + } + catch(const Ice::Exception& ex) + { + // + // Rethrow unexpected exception. + // + _cb->ice_exception(ex); + return; + } + + assert(false); + } + + virtual void ice_exception(const std::exception& ex) + { + _cb->ice_exception(ex); + } + + virtual void ice_exception() + { + _cb->ice_exception(); + } + +private: + + const Ice::AMD_Locator_findObjectByIdPtr _cb; + const Ice::ObjectPrx _obj; +}; + +} + +LocatorI::LocatorI(const AdapterRegistryPtr& adapterRegistry, + const ObjectRegistryPtr& objectRegistry, + const Ice::LocatorRegistryPrx& locatorRegistry) : + _adapterRegistry(adapterRegistry), + _objectRegistry(objectRegistry), + _locatorRegistry(locatorRegistry) +{ +} + +// +// Find an object by identity. The object is searched in the object +// registry. +// +void +LocatorI::findObjectById_async(const Ice::AMD_Locator_findObjectByIdPtr& cb, + const Ice::Identity& id, + const Ice::Current& current) const +{ + ObjectDescriptor obj; + try + { + obj = _objectRegistry->getObjectDescriptor(id); + } + catch(const ObjectNotExistException&) + { + throw Ice::ObjectNotFoundException(); + } + + // + // OPTIMIZATION: If the object is registered with an adapter id, try to get the adapter direct + // proxy (which might caused the server activation). This will avoid the client to lookup for + // the adapter id endpoints. + // + if(!obj.adapterId.empty()) + { + Ice::AMD_Locator_findAdapterByIdPtr amiCB = new AMD_Locator_findAdapterByIdI(cb, obj.proxy); + findAdapterById_async(amiCB, obj.adapterId, current); + } + else + { + cb->ice_response(obj.proxy); + } +} + +// +// Find an adapter by identity. The object is searched in the adapter +// registry. If found, we try to get its direct proxy. +// +void +LocatorI::findAdapterById_async(const Ice::AMD_Locator_findAdapterByIdPtr& cb, + const string& id, + const Ice::Current&) const +{ + AdapterPrx adapter; + try + { + adapter = AdapterPrx::uncheckedCast(_adapterRegistry->findById(id)->ice_collocationOptimization(false)); + } + catch(const AdapterNotExistException&) + { + throw Ice::AdapterNotFoundException(); + } + + LocatorIPtr self = const_cast<LocatorI*>(this); + if(self->getDirectProxyRequest(cb, adapter)) + { + try + { + AMI_Adapter_getDirectProxyPtr amiCB = new AMI_Adapter_getDirectProxyI(self, id, adapter); + adapter->getDirectProxy_async(amiCB); + } + catch(const Ice::LocalException& ex) + { + self->getDirectProxyException(adapter, id, ex); + } + } +} + +Ice::LocatorRegistryPrx +LocatorI::getRegistry(const Ice::Current&) const +{ + return _locatorRegistry; +} + +bool +LocatorI::getDirectProxyRequest(const Ice::AMD_Locator_findAdapterByIdPtr& cb, const AdapterPrx& adapter) +{ + Lock sync(*this); + + // + // Check if there's already pending requests for this adapter. If that's the case, + // we just add this one to the queue. If not, we add it to the queue and initiate + // a call on the adapter to get its direct proxy. + // + PendingRequestsMap::iterator p; + p = _pendingRequests.insert(make_pair(adapter->ice_getIdentity(), PendingRequests())).first; + p->second.push_back(cb); + return p->second.size() == 1; +} + +void +LocatorI::getDirectProxyException(const AdapterPrx& adapter, const string& id, const Ice::Exception& ex) +{ + Lock sync(*this); + + PendingRequestsMap::iterator p = _pendingRequests.find(adapter->ice_getIdentity()); + assert(p != _pendingRequests.end()); + try + { + ex.ice_throw(); + } + catch(const AdapterNotActiveException& ex) + { + if(ex.activatable) + { + // + // Activate the adapter if it can be activated on demand. NOTE: we use the timeout + // provided in the exception to activate the adapter. The timeout correspond to the + // wait time configured for the server. + // + try + { + AMI_Adapter_activatePtr amiCB = new AMI_Adapter_activateI(this, id, adapter); + AdapterPrx::uncheckedCast(adapter->ice_timeout(ex.timeout))->activate_async(amiCB); + } + catch(const Ice::LocalException& ex) + { + getDirectProxyException(adapter, id, ex); + } + return; + } + else + { + for(PendingRequests::const_iterator q = p->second.begin(); q != p->second.end(); ++q) + { + (*q)->ice_response(0); + } + } + } + catch(const Ice::ObjectNotExistException&) + { + // + // Expected if the adapter is destroyed, if that's the case, we remove it from the adapter registry. + // + try + { + _adapterRegistry->remove(id, adapter); + } + catch(const AdapterNotExistException&) + { + } + + for(PendingRequests::const_iterator q = p->second.begin(); q != p->second.end(); ++q) + { + (*q)->ice_exception(Ice::AdapterNotFoundException()); + } + } + catch(const Ice::LocalException&) + { + for(PendingRequests::const_iterator q = p->second.begin(); q != p->second.end(); ++q) + { + (*q)->ice_response(0); + } + } + catch(const Ice::Exception&) + { + assert(false); + } + _pendingRequests.erase(p); +} + +void +LocatorI::getDirectProxyCallback(const Ice::Identity& adapterId, const Ice::ObjectPrx& proxy) +{ + Lock sync(*this); + + PendingRequestsMap::iterator p = _pendingRequests.find(adapterId); + assert(p != _pendingRequests.end()); + for(PendingRequests::const_iterator q = p->second.begin(); q != p->second.end(); ++q) + { + (*q)->ice_response(proxy); + } + _pendingRequests.erase(p); +} diff --git a/cpp/src/IceGrid/LocatorI.h b/cpp/src/IceGrid/LocatorI.h new file mode 100644 index 00000000000..d79740871c3 --- /dev/null +++ b/cpp/src/IceGrid/LocatorI.h @@ -0,0 +1,53 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICE_GRID_LOCATOR_I_H +#define ICE_GRID_LOCATOR_I_H + +#include <IceGrid/Internal.h> +#include <Ice/Locator.h> + +namespace IceGrid +{ + +class LocatorI : public Ice::Locator, public IceUtil::Mutex +{ +public: + + LocatorI(const AdapterRegistryPtr&, const ObjectRegistryPtr&, const ::Ice::LocatorRegistryPrx&); + + virtual void findObjectById_async(const ::Ice::AMD_Locator_findObjectByIdPtr&, const ::Ice::Identity&, + const ::Ice::Current&) const; + + virtual void findAdapterById_async(const ::Ice::AMD_Locator_findAdapterByIdPtr&, const ::std::string&, + const ::Ice::Current&) const; + + virtual ::Ice::LocatorRegistryPrx getRegistry(const ::Ice::Current&) const; + + bool getDirectProxyRequest(const ::Ice::AMD_Locator_findAdapterByIdPtr&, const AdapterPrx&); + void getDirectProxyException(const AdapterPrx&, const std::string&, const Ice::Exception&); + void getDirectProxyCallback(const Ice::Identity&, const Ice::ObjectPrx&); + +protected: + + const AdapterRegistryPtr _adapterRegistry; + const ObjectRegistryPtr _objectRegistry; + const Ice::LocatorRegistryPrx _locatorRegistry; + + typedef std::vector<Ice::AMD_Locator_findAdapterByIdPtr> PendingRequests; + typedef std::map<Ice::Identity, PendingRequests> PendingRequestsMap; + + PendingRequestsMap _pendingRequests; +}; + +typedef IceUtil::Handle<LocatorI> LocatorIPtr; + +} + +#endif diff --git a/cpp/src/IceGrid/LocatorRegistryI.cpp b/cpp/src/IceGrid/LocatorRegistryI.cpp new file mode 100644 index 00000000000..b6e02518035 --- /dev/null +++ b/cpp/src/IceGrid/LocatorRegistryI.cpp @@ -0,0 +1,188 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <Ice/Ice.h> +#include <IceGrid/LocatorRegistryI.h> +#include <IceGrid/AdapterFactory.h> + +using namespace std; +using namespace IceGrid; + +class AMI_Adapter_setDirectProxyI : public AMI_Adapter_setDirectProxy +{ +public: + + AMI_Adapter_setDirectProxyI(const Ice::AMD_LocatorRegistry_setAdapterDirectProxyPtr& cb) : _cb(cb) + { + } + + virtual void ice_response() + { + _cb->ice_response(); + } + + virtual void ice_exception(const ::Ice::Exception& ex) + { + try + { + ex.ice_throw(); + } + catch(const AdapterActiveException&) + { + _cb->ice_exception(Ice::AdapterAlreadyActiveException()); + return; + } + catch(const Ice::ObjectNotExistException&) + { + _cb->ice_exception(Ice::AdapterNotFoundException()); // Expected if the adapter was destroyed. + return; + } + catch(const Ice::LocalException&) + { + _cb->ice_response(); + return; + } + + assert(false); + } + +private: + + Ice::AMD_LocatorRegistry_setAdapterDirectProxyPtr _cb; +}; + +class AMI_Server_setProcessI : public AMI_Server_setProcess +{ +public: + + AMI_Server_setProcessI(const Ice::AMD_LocatorRegistry_setServerProcessProxyPtr& cb) : _cb(cb) + { + } + + virtual void ice_response() + { + _cb->ice_response(); + } + + virtual void ice_exception(const ::Ice::Exception& ex) + { + try + { + ex.ice_throw(); + } + catch(const Ice::ObjectNotExistException&) + { + _cb->ice_exception(Ice::ServerNotFoundException()); // Expected if the adapter was destroyed. + return; + } + catch(const Ice::LocalException&) + { + _cb->ice_response(); + return; + } + + assert(false); + } + +private: + + Ice::AMD_LocatorRegistry_setServerProcessProxyPtr _cb; +}; + +LocatorRegistryI::LocatorRegistryI(const AdapterRegistryPtr& adapterRegistry, + const ServerRegistryPtr& serverRegistry, + const AdapterFactoryPtr& adapterFactory, + bool dynamicRegistration) : + _adapterRegistry(adapterRegistry), + _serverRegistry(serverRegistry), + _adapterFactory(adapterFactory), + _dynamicRegistration(dynamicRegistration) +{ +} + +void +LocatorRegistryI::setAdapterDirectProxy_async(const Ice::AMD_LocatorRegistry_setAdapterDirectProxyPtr& cb, + const string& id, + const Ice::ObjectPrx& proxy, + const Ice::Current&) +{ + while(true) + { + try + { + // + // Get the adapter from the registry and set its direct proxy. + // + AMI_Adapter_setDirectProxyPtr amiCB = new AMI_Adapter_setDirectProxyI(cb); + _adapterRegistry->findById(id)->setDirectProxy_async(amiCB, proxy); + return; + } + catch(const AdapterNotExistException&) + { + } + catch(const Ice::LocalException&) + { + cb->ice_response(); + return; + } + + if(_dynamicRegistration) + { + // + // Create a new standalone adapter. The adapter will be persistent. It's the responsability of + // the user to cleanup adapter entries which were dynamically added from the registry. + // + AdapterPrx adapter = _adapterFactory->createStandaloneAdapter(id); + try + { + _adapterRegistry->add(id, adapter); + } + catch(const AdapterExistsException&) + { + adapter->destroy(); + } + } + else + { + throw Ice::AdapterNotFoundException(); + } + } +} + +void +LocatorRegistryI::setServerProcessProxy_async(const Ice::AMD_LocatorRegistry_setServerProcessProxyPtr& cb, + const string& name, + const Ice::ProcessPrx& proxy, + const Ice::Current&) +{ + try + { + // + // Get the server from the registry and set its process proxy. + // + AMI_Server_setProcessPtr amiCB = new AMI_Server_setProcessI(cb); + _serverRegistry->findByName(name)->setProcess_async(amiCB, proxy); + return; + } + catch(const ServerNotExistException&) + { + } + catch(const Ice::LocalException&) + { + // + // TODO: We couldn't contact the server object. This is possibly because the IceGrid node is down and + // the server is started manually for example. We should probably throw here to prevent the server + // from starting? + // + cb->ice_response(); + return; + } + + throw Ice::ServerNotFoundException(); +} diff --git a/cpp/src/IceGrid/LocatorRegistryI.h b/cpp/src/IceGrid/LocatorRegistryI.h new file mode 100644 index 00000000000..21ff4b28339 --- /dev/null +++ b/cpp/src/IceGrid/LocatorRegistryI.h @@ -0,0 +1,44 @@ + +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICE_GRID_LOCATOR_REGISTRY_I_H +#define ICE_GRID_LOCATOR_REGISTRY_I_H + +#include <IceGrid/Internal.h> +#include <Ice/Locator.h> + +namespace IceGrid +{ + +class AdapterFactory; +typedef IceUtil::Handle<AdapterFactory> AdapterFactoryPtr; + +class LocatorRegistryI : public Ice::LocatorRegistry +{ +public: + + LocatorRegistryI(const AdapterRegistryPtr&, const ServerRegistryPtr&, const AdapterFactoryPtr&, bool); + + virtual void setAdapterDirectProxy_async(const Ice::AMD_LocatorRegistry_setAdapterDirectProxyPtr&, + const ::std::string&, const ::Ice::ObjectPrx&, const ::Ice::Current&); + virtual void setServerProcessProxy_async(const Ice::AMD_LocatorRegistry_setServerProcessProxyPtr&, + const ::std::string&, const ::Ice::ProcessPrx&, const ::Ice::Current&); + +private: + + const AdapterRegistryPtr _adapterRegistry; + const ServerRegistryPtr _serverRegistry; + const AdapterFactoryPtr _adapterFactory; + const bool _dynamicRegistration; +}; + +} + +#endif diff --git a/cpp/src/IceGrid/Makefile b/cpp/src/IceGrid/Makefile index 1b041513be4..924e40addd8 100644 --- a/cpp/src/IceGrid/Makefile +++ b/cpp/src/IceGrid/Makefile @@ -9,32 +9,119 @@ top_srcdir = ../.. +LIBFILENAME = $(call mklibfilename,IceGrid,$(VERSION)) +SONAME = $(call mksoname,IceGrid,$(SOVERSION)) +LIBNAME = $(call mklibname,IceGrid) + PERFLIBFILENAME = $(call mklibfilename,IcePerf,$(VERSION)) PERFSONAME = $(call mksoname,IcePerf,$(SOVERSION)) PERFLIBNAME = $(call mklibname,IcePerf) +ADMIN = $(top_srcdir)/bin/icegridadmin +NODE_SERVER = $(top_srcdir)/bin/icegridnode +REGISTRY_SERVER = $(top_srcdir)/bin/icegridregistry + +LIBTARGETS = $(call mklibtargets,$(libdir)/$(LIBFILENAME),$(libdir)/$(SONAME),$(libdir)/$(LIBNAME)) +PERFLIBTARGETS = $(call mklibtargets,$(libdir)/$(PERFLIBFILENAME),$(libdir)/$(PERFSONAME),$(libdir)/$(PERFLIBNAME)) +TARGETS = $(PERFLIBTARGETS) $(LIBTARGETS) $(NODE_SERVER) $(REGISTRY_SERVER) $(ADMIN) -LIBTARGETS = $(call mklibtargets,$(libdir)/$(PERFLIBFILENAME),$(libdir)/$(PERFSONAME),$(libdir)/$(PERFLIBNAME)) -TARGETS = $(LIBTARGETS) +LIB_OBJS = Admin.o \ + Query.o \ + Exception.o PERFLIB_OBJS = PerfTypes.o \ PerfLinux.o -SRCS = $(PERFLIB_OBJS:.o=.cpp) - -SLICE_SRCS = $(SDIR)/PerfTypes.ice +ADMIN_OBJS = Grammar.o \ + Scanner.o \ + Parser.o \ + DescriptorVisitor.o \ + DescriptorParser.o \ + DescriptorUtil.o \ + Client.o + +COMMON_OBJS = Internal.o \ + TraceLevels.o + +NODE_OBJS = NodeI.o \ + ServerFactory.o \ + ServerI.o \ + ServerAdapterI.o \ + Activator.o \ + WaitQueue.o \ + DescriptorParser.o + +REGISTRY_OBJS = Registry.o \ + ObjectRegistryI.o \ + AdapterRegistryI.o \ + ServerRegistryI.o \ + NodeRegistryI.o \ + ApplicationRegistryI.o \ + StringObjectProxyDict.o \ + StringObjectProxySeqDict.o \ + StringServerDescriptorDict.o \ + StringStringSeqDict.o \ + IdentityObjectDescDict.o \ + LocatorI.o \ + LocatorRegistryI.o \ + AdapterFactory.o \ + AdapterI.o \ + AdminI.o \ + DescriptorVisitor.o \ + DescriptorUtil.o \ + QueryI.o + +NODE_SVR_OBJS = $(COMMON_OBJS) \ + $(NODE_OBJS) \ + $(REGISTRY_OBJS) \ + IceGridNode.o + +REGISTRY_SVR_OBJS = \ + $(COMMON_OBJS) \ + $(REGISTRY_OBJS) \ + IceGridRegistry.o + +SRCS = $(LIB_OBJS:.o=.cpp) \ + $(PERFLIB_OBJS:.o=.cpp) \ + $(ADMIN_OBJS:.o=.cpp) \ + $(COMMON_OBJS:.o=.cpp) \ + $(NODE_OBJS:.o=.cpp) \ + $(REGISTRY_OBJS:.o=.cpp) \ + IceGridNode.cpp \ + IceGridRegistry.cpp + +SLICE_SRCS = $(SDIR)/PerfTypes.ice \ + $(SDIR)/Admin.ice \ + $(SDIR)/Exception.ice \ + $(SDIR)/Query.ice \ + Internal.ice HDIR = $(includedir)/IceGrid LOCAL_HDIR = ../IceGrid SDIR = $(slicedir)/IceGrid LOCAL_SDIR = ../IceGrid +SLICE2FREEZECMD = $(SLICE2FREEZE) --ice --include-dir IceGrid $(ICECPPFLAGS) + include $(top_srcdir)/config/Make.rules -CPPFLAGS := $(CPPFLAGS) -DICE_PERF_API_EXPORTS -SLICE2CPPFLAGS := --ice --include-dir IceGrid --dll-export ICE_PERF_API $(SLICE2CPPFLAGS) +CPPFLAGS := $(CPPFLAGS) -I.. -DICE_GRID_API_EXPORTS $(READLINE_FLAGS) +ICECPPFLAGS := $(ICECPPFLAGS) -I.. +SLICE2CPPFLAGS := --checksum --ice --include-dir IceGrid --dll-export ICE_GRID_API $(SLICE2CPPFLAGS) LINKWITH := -lIce -lIceUtil +$(libdir)/$(LIBFILENAME): $(LIB_OBJS) + rm -f $@ + $(call mkshlib,$@,$(SONAME),$(LIB_OBJS),$(LINKWITH)) + +$(libdir)/$(SONAME): $(libdir)/$(LIBFILENAME) + rm -f $@ + ln -s $(LIBFILENAME) $@ + +$(libdir)/$(LIBNAME): $(libdir)/$(SONAME) + rm -f $@ + ln -s $(SONAME) $@ + $(libdir)/$(PERFLIBFILENAME): $(PERFLIB_OBJS) rm -f $@ $(call mkshlib,$@,$(PERFSONAME),$(PERFLIB_OBJS),$(LINKWITH)) @@ -47,12 +134,73 @@ $(libdir)/$(PERFLIBNAME): $(libdir)/$(SONAME) rm -f $@ ln -s $(PERFSONAME) $@ +$(ADMIN): $(ADMIN_OBJS) $(LIBTARGETS) + rm -f $@ + $(CXX) $(LDFLAGS) -o $@ $(ADMIN_OBJS) -lIceXML -lIceGrid $(LIBS) $(READLINE_LIBS) $(EXPAT_LIBS) + +$(REGISTRY_SERVER): $(REGISTRY_SVR_OBJS) $(LIBTARGETS) + rm -f $@ + $(CXX) $(LDFLAGS) -o $@ $(REGISTRY_SVR_OBJS) -lIceGrid -lFreeze -lIceXML $(LIBS) $(DB_LIBS) + +$(NODE_SERVER): $(NODE_SVR_OBJS) $(LIBTARGETS) + rm -f $@ + $(CXX) $(LDFLAGS) -o $@ $(NODE_SVR_OBJS) -lIceGrid -lFreeze -lIceXML $(LIBS) $(DB_LIBS) + $(LOCAL_HDIR)/%.h %.cpp: $(SDIR)/%.ice $(SLICE2CPP) rm -f $(HDIR)/$(*F).h $(*F).cpp $(SLICE2CPP) $(SLICE2CPPFLAGS) $(SDIR)/$(*F).ice +$(LOCAL_HDIR)/StringObjectProxyDict.h StringObjectProxyDict.cpp: $(SLICE2FREEZE) + rm -f StringObjectProxyDict.h StringObjectProxyDict.cpp + $(SLICE2FREEZECMD) --dict IceGrid::StringObjectProxyDict,string,Object* \ + StringObjectProxyDict ../../slice/Ice/BuiltinSequences.ice + +clean:: + rm -f StringObjectProxyDict.h StringObjectProxyDict.cpp + +$(LOCAL_HDIR)/StringStringSeqDict.h StringStringSeqDict.cpp: $(SLICE2FREEZE) + rm -f StringStringSeqDict.h StringStringSeqDict.cpp + $(SLICE2FREEZECMD) --dict IceGrid::StringStringSeqDict,string,Ice::StringSeq \ + StringStringSeqDict ../../slice/Ice/BuiltinSequences.ice + +clean:: + rm -f StringStringSeqDict.h StringStringSeqDict.cpp + +$(LOCAL_HDIR)/StringServerDescriptorDict.h StringServerDescriptorDict.cpp: $(SLICE2FREEZE) + rm -f StringServerDescriptorDict.h StringServerDescriptorDict.cpp + $(SLICE2FREEZECMD) --dict IceGrid::StringServerDescriptorDict,string,IcePacK::ServerDescriptor \ + StringServerDescriptorDict ../../slice/IceGrid/Admin.ice + +clean:: + rm -f StringServerDescriptorDict.h StringServerDescriptorDict.cpp + +$(LOCAL_HDIR)/IdentityObjectDescDict.h IdentityObjectDescDict.cpp: $(SLICE2FREEZE) + rm -f IdentityObjectDescDict.h IdentityObjectDescDict.cpp + $(SLICE2FREEZECMD) --dict IceGrid::IdentityObjectDescDict,Ice::Identity,IceGrid::ObjectDescriptor \ + IdentityObjectDescDict ../../slice/Ice/Identity.ice $(LOCAL_SDIR)/Internal.ice + +clean:: + rm -f IdentityObjectDescDict.h IdentityObjectDescDict.cpp + +$(LOCAL_HDIR)/StringObjectProxySeqDict.h StringObjectProxySeqDict.cpp: $(SLICE2FREEZE) + rm -f StringObjectProxySeqDict.h StringObjectProxySeqDict.cpp + $(SLICE2FREEZECMD) --dict IceGrid::StringObjectProxySeqDict,string,Ice::ObjectProxySeq \ + StringObjectProxySeqDict $(slicedir)/Ice/BuiltinSequences.ice + +clean:: + rm -f StringObjectProxySeqDict.h StringObjectProxySeqDict.cpp + +# Needed for make -jn to work. +#../IceGrid/Grammar.y: Grammar.h + +clean:: +# rm -f Grammar.cpp Grammar.h +# rm -f Scanner.cpp install:: all - $(call installlib,$(install_libdir),$(libdir),$(PERFLIBFILENAME),$(PERFSONAME),$(PERFLIBNAME)) + $(call installlib,$(install_libdir),$(libdir),$(LIBFILENAME),$(SONAME),$(LIBNAME)) + $(INSTALL_PROGRAM) $(ADMIN) $(install_bindir) + $(INSTALL_PROGRAM) $(NODE_SERVER) $(install_bindir) + $(INSTALL_PROGRAM) $(REGISTRY_SERVER) $(install_bindir) include .depend diff --git a/cpp/src/IceGrid/NodeI.cpp b/cpp/src/IceGrid/NodeI.cpp new file mode 100644 index 00000000000..f14c1d40167 --- /dev/null +++ b/cpp/src/IceGrid/NodeI.cpp @@ -0,0 +1,92 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <IceUtil/UUID.h> +#include <Ice/Ice.h> +#include <IceGrid/NodeI.h> +#include <IceGrid/Activator.h> +#include <IceGrid/ServerFactory.h> + +// +// Just to get the hostname +// +#include <Ice/ProtocolPluginFacade.h> + +#include <sys/types.h> +#include <sys/stat.h> + +#ifdef _WIN32 +# include <direct.h> +#endif + +using namespace std; +using namespace IceGrid; + +NodeI::NodeI(const ActivatorPtr& activator, + const string& name, + const ServerFactoryPtr& factory, + const Ice::CommunicatorPtr& communicator, + const Ice::PropertiesPtr& properties) : + _activator(activator), + _name(name), + _hostname(IceInternal::getProtocolPluginFacade(communicator)->getDefaultHost()), + _factory(factory) +{ + _tmpDir = properties->getProperty("IceGrid.Node.Data"); + _tmpDir = _tmpDir + (_tmpDir[_tmpDir.length() - 1] == '/' ? "" : "/") + "tmp/"; +} + +ServerPrx +NodeI::createServer(const string& name, const ServerDescriptorPtr& desc, const ::Ice::Current&) const +{ + return _factory->createServer(name, desc); +} + +ServerAdapterPrx +NodeI::createServerAdapter(const ServerPrx& server, const string& id, const ::Ice::Current&) const +{ + return _factory->createServerAdapter(id, server); +} + +string +NodeI::createTmpDir(const Ice::Current&) const +{ + string dir = _tmpDir + IceUtil::generateUUID(); +#ifdef _WIN32 + _mkdir(dir.c_str()); +#else + mkdir(dir.c_str(), 0755); +#endif + return dir; +} + +void +NodeI::destroyTmpDir(const string& path, const Ice::Current&) const +{ + rmdir(path.c_str()); +} + +std::string +NodeI::getName(const Ice::Current&) const +{ + return _name; +} + +std::string +NodeI::getHostname(const Ice::Current&) const +{ + return _hostname; +} + +void +NodeI::shutdown(const Ice::Current&) const +{ + _activator->shutdown(); +} + diff --git a/cpp/src/IceGrid/NodeI.h b/cpp/src/IceGrid/NodeI.h new file mode 100644 index 00000000000..d3eedf607df --- /dev/null +++ b/cpp/src/IceGrid/NodeI.h @@ -0,0 +1,52 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICE_GRID_NODE_I_H +#define ICE_GRID_NODE_I_H + +#include <IceGrid/Internal.h> + +namespace IceGrid +{ + +class Activator; +typedef IceUtil::Handle<Activator> ActivatorPtr; + +class ServerFactory; +typedef IceUtil::Handle<ServerFactory> ServerFactoryPtr; + +class NodeI : public Node +{ +public: + + NodeI(const ActivatorPtr&, const std::string&, const ServerFactoryPtr&, + const Ice::CommunicatorPtr&, const Ice::PropertiesPtr&); + + virtual ServerPrx createServer(const std::string&, const ServerDescriptorPtr&, const Ice::Current&) const; + virtual ServerAdapterPrx createServerAdapter(const ServerPrx&, const std::string&, const Ice::Current&) const; + + virtual std::string createTmpDir(const Ice::Current&) const; + virtual void destroyTmpDir(const std::string&, const Ice::Current&) const; + + virtual std::string getName(const Ice::Current&) const; + virtual std::string getHostname(const Ice::Current&) const; + virtual void shutdown(const Ice::Current&) const; + +private: + + const ActivatorPtr _activator; + const std::string _name; + const std::string _hostname; + const ServerFactoryPtr _factory; + std::string _tmpDir; +}; + +} + +#endif diff --git a/cpp/src/IceGrid/NodeRegistryI.cpp b/cpp/src/IceGrid/NodeRegistryI.cpp new file mode 100644 index 00000000000..3703d5428bc --- /dev/null +++ b/cpp/src/IceGrid/NodeRegistryI.cpp @@ -0,0 +1,219 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <IceGrid/NodeRegistryI.h> +#include <IceGrid/AdapterFactory.h> +#include <IceGrid/TraceLevels.h> +#include <Freeze/Initialize.h> + +using namespace std; +using namespace IceGrid; + +const string NodeRegistryI::_dbName = "noderegistry"; + +NodeRegistryI::NodeRegistryI(const Ice::CommunicatorPtr& communicator, + const string& envName, + const AdapterRegistryPtr& adapterRegistry, + const AdapterFactoryPtr& adapterFactory, + const TraceLevelsPtr& traceLevels) : + _connectionCache(Freeze::createConnection(communicator, envName)), + _dictCache(_connectionCache, _dbName), + _adapterRegistry(adapterRegistry), + _adapterFactory(adapterFactory), + _traceLevels(traceLevels), + _envName(envName), + _communicator(communicator) +{ + for(StringObjectProxyDict::iterator p = _dictCache.begin(); p != _dictCache.end(); ++p) + { + NodePrx node = NodePrx::uncheckedCast(p->second); + try + { + node->ice_ping(); + } + catch(const Ice::ObjectNotExistException&) + { + remove(p->first); + } + catch(const Ice::LocalException&) + { + } + } +} + +void +NodeRegistryI::add(const string& name, const NodePrx& node, const Ice::Current& current) +{ + while(true) + { + NodePrx oldNode; + try + { + oldNode = findByName(name, current); + oldNode->ice_ping(); + throw NodeActiveException(); + } + catch(const NodeNotExistException&) + { + } + catch(const Ice::LocalException&) + { + } + + IceUtil::Mutex::Lock sync(*this); + + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + StringObjectProxyDict dict(connection, _dbName); + + StringObjectProxyDict::iterator p = dict.find(name); + if(p != dict.end()) + { + if(oldNode && oldNode != p->second) + { + continue; + } + + p.set(node); + + if(_traceLevels->nodeRegistry > 0) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->nodeRegistryCat); + out << "updated node `" << name << "' proxy"; + } + } + else + { + dict.put(pair<const string, const Ice::ObjectPrx>(name, node)); + + if(_traceLevels->nodeRegistry > 0) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->nodeRegistryCat); + out << "added node `" << name << "'"; + } + } + + break; + } + + // + // Set the direct proxy of the node object adapter. + // + while(true) + { + try + { + // + // TODO: ensure this adapter has been created by the adapter factory. It's possible that an + // adapter has been created with the same name. In such a case, the best is probably to + // prevent the node registration by throwing an appropriate exception. The user would then + // need to remove the adapter from the adapter registry to be able to run the node. + // + + AdapterPrx adapter = _adapterRegistry->findById("IceGrid.Node." + name); + adapter->setDirectProxy(node); + return; + } + catch(const AdapterNotExistException&) + { + } + catch(const Ice::ObjectNotExistException&) + { + } + + // + // Create and register the node adapter. + // + AdapterPrx adapter = _adapterFactory->createStandaloneAdapter("IceGridNodeAdapter." + name); + try + { + _adapterRegistry->add("IceGrid.Node." + name, adapter); + } + catch(const AdapterExistsException&) + { + adapter->destroy(); + } + } +} + +void +NodeRegistryI::remove(const string& name, const Ice::Current&) +{ + IceUtil::Mutex::Lock sync(*this); + + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + StringObjectProxyDict dict(connection, _dbName); + + StringObjectProxyDict::iterator p = dict.find(name); + if(p == dict.end()) + { + throw NodeNotExistException(); + } + + dict.erase(p); + + if(_traceLevels->nodeRegistry > 0) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->nodeRegistryCat); + out << "removed node `" << name << "'"; + } + + // + // Remove the adapter from the adapter registry. + // + try + { + AdapterPrx adapter = _adapterRegistry->findById("IceGrid.Node." + name); + adapter->destroy(); + _adapterRegistry->remove("IceGrid.Node." + name, 0); + } + catch(const AdapterNotExistException&) + { + } +} + +NodePrx +NodeRegistryI::findByName(const string& name, const Ice::Current&) +{ + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + StringObjectProxyDict dict(connection, _dbName); + + StringObjectProxyDict::iterator p = dict.find(name); + if(p != dict.end()) + { + try + { + return NodePrx::checkedCast(p->second); + } + catch(const Ice::ObjectNotExistException&) + { + } + catch(const Ice::LocalException&) + { + return NodePrx::uncheckedCast(p->second); + } + } + throw NodeNotExistException(); +} + +Ice::StringSeq +NodeRegistryI::getAll(const Ice::Current&) const +{ + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + StringObjectProxyDict dict(connection, _dbName); + + Ice::StringSeq names; + names.reserve(dict.size()); + + for(StringObjectProxyDict::iterator p = dict.begin(); p != dict.end(); ++p) + { + names.push_back(p->first); + } + + return names; +} diff --git a/cpp/src/IceGrid/NodeRegistryI.h b/cpp/src/IceGrid/NodeRegistryI.h new file mode 100644 index 00000000000..35df3a630a7 --- /dev/null +++ b/cpp/src/IceGrid/NodeRegistryI.h @@ -0,0 +1,53 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICE_GRID_NODE_REGISTRY_I_H +#define ICE_GRID_NODE_REGISTRY_I_H + +#include <IceGrid/Internal.h> +#include <IceGrid/StringObjectProxyDict.h> + +namespace IceGrid +{ + +class AdapterFactory; +typedef IceUtil::Handle<AdapterFactory> AdapterFactoryPtr; + +class TraceLevels; +typedef IceUtil::Handle<TraceLevels> TraceLevelsPtr; + +class NodeRegistryI : public NodeRegistry, public IceUtil::Mutex +{ +public: + + NodeRegistryI(const Ice::CommunicatorPtr&, const std::string&, const AdapterRegistryPtr&, + const AdapterFactoryPtr&, const TraceLevelsPtr&); + + virtual void add(const std::string&, const NodePrx&, const ::Ice::Current&); + virtual void remove(const std::string&, const ::Ice::Current& = Ice::Current()); + + virtual NodePrx findByName(const ::std::string&, const ::Ice::Current&); + virtual Ice::StringSeq getAll(const ::Ice::Current&) const; + +private: + + static const std::string _dbName; + + Freeze::ConnectionPtr _connectionCache; + StringObjectProxyDict _dictCache; + AdapterRegistryPtr _adapterRegistry; + AdapterFactoryPtr _adapterFactory; + TraceLevelsPtr _traceLevels; + const std::string _envName; + const Ice::CommunicatorPtr _communicator; +}; + +} + +#endif diff --git a/cpp/src/IceGrid/ObjectRegistryI.cpp b/cpp/src/IceGrid/ObjectRegistryI.cpp new file mode 100644 index 00000000000..12d18a43a8a --- /dev/null +++ b/cpp/src/IceGrid/ObjectRegistryI.cpp @@ -0,0 +1,228 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <IceUtil/StringUtil.h> +#include <Ice/IdentityUtil.h> +#include <IceGrid/ObjectRegistryI.h> +#include <IceGrid/TraceLevels.h> +#include <Freeze/Initialize.h> + +using namespace std; +using namespace IceGrid; + +const string ObjectRegistryI::_objectsDbName = "objectregistry"; +const string ObjectRegistryI::_typesDbName = "objectregistry-types"; + +ObjectRegistryI::ObjectRegistryI(const Ice::CommunicatorPtr& communicator, + const string& envName, + const TraceLevelsPtr& traceLevels) : + _connectionCache(Freeze::createConnection(communicator, envName)), + _objectsCache(_connectionCache, _objectsDbName, true), + _typesCache(_connectionCache, _typesDbName, true), + _traceLevels(traceLevels), + _envName(envName), + _communicator(communicator) +{ +} + +void +ObjectRegistryI::add(const ObjectDescriptor& obj, const Ice::Current&) +{ + IceUtil::Mutex::Lock sync(*this); + + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + IdentityObjectDescDict objects(connection, _objectsDbName); + StringObjectProxySeqDict types(connection, _typesDbName); + + Ice::Identity id = obj.proxy->ice_getIdentity(); + + IdentityObjectDescDict::iterator p = objects.find(id); + if(p != objects.end()) + { + throw ObjectExistsException(); + } + + // + // Add the object to the object dictionary. + // + objects.put(pair<const Ice::Identity, const ObjectDescriptor>(id, obj)); + + // + // Add the object to the interface dictionary. + // + if(!obj.type.empty()) + { + Ice::ObjectProxySeq seq; + + StringObjectProxySeqDict::iterator q = types.find(obj.type); + if(q != types.end()) + { + seq = q->second; + } + + seq.push_back(obj.proxy); + + if(q == types.end()) + { + types.put(pair<const string, const Ice::ObjectProxySeq>(obj.type, seq)); + } + else + { + q.set(seq); + } + } + + if(_traceLevels->objectRegistry > 0) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->objectRegistryCat); + out << "added object `" << Ice::identityToString(id) << "'"; + } +} + +void +ObjectRegistryI::remove(const Ice::Identity& id, const Ice::Current&) +{ + IceUtil::Mutex::Lock sync(*this); + + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + IdentityObjectDescDict objects(connection, _objectsDbName); + StringObjectProxySeqDict types(connection, _typesDbName); + + IdentityObjectDescDict::iterator p = objects.find(id); + if(p == objects.end()) + { + throw ObjectNotExistException(); + } + + ObjectDescriptor obj = p->second; + + if(!obj.type.empty()) + { + // + // Remove the object from the interface dictionary. + // + StringObjectProxySeqDict::iterator q = types.find(obj.type); + assert(q != types.end()); + + Ice::ObjectProxySeq seq = q->second; + + Ice::ObjectProxySeq::iterator r; + for(r = seq.begin(); r != seq.end(); ++r) + { + if((*r)->ice_getIdentity() == id) + { + break; + } + } + + assert(r != seq.end()); + seq.erase(r); + + if(seq.size() == 0) + { + types.erase(q); + } + else + { + q.set(seq); + } + } + + // + // Remove the object from the object dictionary. + // + objects.erase(p); + + if(_traceLevels->objectRegistry > 0) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->objectRegistryCat); + out << "removed object `" << id << "'"; + } +} + +ObjectDescriptor +ObjectRegistryI::getObjectDescriptor(const Ice::Identity& id, const Ice::Current&) const +{ + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + IdentityObjectDescDict objects(connection, _objectsDbName); + + + IdentityObjectDescDict::iterator p = objects.find(id); + if(p == objects.end()) + { + throw ObjectNotExistException(); + } + + return p->second; +} + +Ice::ObjectPrx +ObjectRegistryI::findById(const Ice::Identity& id, const Ice::Current&) const +{ + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + IdentityObjectDescDict objects(connection, _objectsDbName); + + IdentityObjectDescDict::iterator p = objects.find(id); + if(p == objects.end()) + { + throw ObjectNotExistException(); + } + + return p->second.proxy; +} + +Ice::ObjectPrx +ObjectRegistryI::findByType(const string& type, const Ice::Current&) const +{ + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + StringObjectProxySeqDict types(connection, _typesDbName); + + StringObjectProxySeqDict::iterator p = types.find(type); + if(p == types.end()) + { + throw ObjectNotExistException(); + } + + int r = rand() % int(p->second.size()); + return p->second[r]; +} + +Ice::ObjectProxySeq +ObjectRegistryI::findAllWithType(const string& type, const Ice::Current&) const +{ + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + StringObjectProxySeqDict types(connection, _typesDbName); + + StringObjectProxySeqDict::iterator p = types.find(type); + if(p == types.end()) + { + throw ObjectNotExistException(); + } + + return p->second; +} + +ObjectDescriptorSeq +ObjectRegistryI::findAll(const string& expression, const Ice::Current&) const +{ + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + IdentityObjectDescDict objects(connection, _objectsDbName); + + ObjectDescriptorSeq result; + for(IdentityObjectDescDict::const_iterator p = objects.begin(); p != objects.end(); ++p) + { + if(expression.empty() || + IceUtil::match(Ice::identityToString(p->second.proxy->ice_getIdentity()), expression, true)) + { + result.push_back(p->second); + } + } + return result; +} + diff --git a/cpp/src/IceGrid/ObjectRegistryI.h b/cpp/src/IceGrid/ObjectRegistryI.h new file mode 100644 index 00000000000..bf4408fd7fc --- /dev/null +++ b/cpp/src/IceGrid/ObjectRegistryI.h @@ -0,0 +1,55 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICE_GRID_OBJECT_REGISTRY_I_H +#define ICE_GRID_OBJECT_REGISTRY_I_H + +#include <IceGrid/Internal.h> +#include <IceGrid/IdentityObjectDescDict.h> +#include <IceGrid/StringObjectProxySeqDict.h> +#include <Freeze/ConnectionF.h> + +namespace IceGrid +{ + +class TraceLevels; +typedef IceUtil::Handle<TraceLevels> TraceLevelsPtr; + +class ObjectRegistryI : public ObjectRegistry, public IceUtil::Mutex +{ +public: + + ObjectRegistryI(const Ice::CommunicatorPtr& communicator, const std::string&, const TraceLevelsPtr& traceLevels); + + virtual void add(const IceGrid::ObjectDescriptor&, const ::Ice::Current&); + virtual void remove(const Ice::Identity&, const ::Ice::Current&); + + virtual ObjectDescriptor getObjectDescriptor(const Ice::Identity&, const ::Ice::Current&) const; + + virtual Ice::ObjectPrx findById(const ::Ice::Identity&, const ::Ice::Current&) const; + virtual Ice::ObjectPrx findByType(const std::string&, const ::Ice::Current&) const; + virtual Ice::ObjectProxySeq findAllWithType(const std::string&, const ::Ice::Current&) const; + virtual ObjectDescriptorSeq findAll(const std::string&, const ::Ice::Current&) const; + +private: + + static const std::string _objectsDbName; + static const std::string _typesDbName; + + Freeze::ConnectionPtr _connectionCache; + IdentityObjectDescDict _objectsCache; + StringObjectProxySeqDict _typesCache; + const TraceLevelsPtr _traceLevels; + const std::string _envName; + const Ice::CommunicatorPtr _communicator; +}; + +} + +#endif diff --git a/cpp/src/IceGrid/QueryI.cpp b/cpp/src/IceGrid/QueryI.cpp new file mode 100644 index 00000000000..bd24e80205f --- /dev/null +++ b/cpp/src/IceGrid/QueryI.cpp @@ -0,0 +1,45 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <IceGrid/Internal.h> +#include <IceGrid/QueryI.h> + +using namespace std; +using namespace Ice; +using namespace IceGrid; + +QueryI::QueryI(const CommunicatorPtr& communicator, const ObjectRegistryPtr& objectRegistry) : + _communicator(communicator), + _objectRegistry(objectRegistry) +{ +} + +QueryI::~QueryI() +{ +} + +Ice::ObjectPrx +QueryI::findObjectById(const Ice::Identity& id, const Ice::Current&) const +{ + return _objectRegistry->findById(id); +} + +Ice::ObjectPrx +QueryI::findObjectByType(const string& type, const Ice::Current&) const +{ + return _objectRegistry->findByType(type); +} + +Ice::ObjectProxySeq +QueryI::findAllObjectsWithType(const string& type, const Ice::Current&) const +{ + return _objectRegistry->findAllWithType(type); +} + + diff --git a/cpp/src/IceGrid/QueryI.h b/cpp/src/IceGrid/QueryI.h new file mode 100644 index 00000000000..bb7d30d4cb2 --- /dev/null +++ b/cpp/src/IceGrid/QueryI.h @@ -0,0 +1,37 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICE_GRID_QUERY_I_H +#define ICE_GRID_QUERY_I_H + +#include <IceGrid/Query.h> + +namespace IceGrid +{ + +class QueryI : public Query, public IceUtil::Mutex +{ +public: + + QueryI(const Ice::CommunicatorPtr&, const ObjectRegistryPtr&); + virtual ~QueryI(); + + virtual ::Ice::ObjectPrx findObjectById(const ::Ice::Identity&, const ::Ice::Current&) const; + virtual ::Ice::ObjectPrx findObjectByType(const ::std::string&, const ::Ice::Current&) const; + virtual ::Ice::ObjectProxySeq findAllObjectsWithType(const ::std::string&, const ::Ice::Current&) const; + +private: + + Ice::CommunicatorPtr _communicator; + ObjectRegistryPtr _objectRegistry; +}; + +} + +#endif diff --git a/cpp/src/IceGrid/Registry.cpp b/cpp/src/IceGrid/Registry.cpp new file mode 100644 index 00000000000..1dd9a2c5ea4 --- /dev/null +++ b/cpp/src/IceGrid/Registry.cpp @@ -0,0 +1,326 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <IceUtil/UUID.h> +#include <Ice/Ice.h> +#include <Freeze/Freeze.h> + +#include <IceGrid/Registry.h> +#include <IceGrid/AdapterI.h> +#include <IceGrid/AdapterFactory.h> +#include <IceGrid/ApplicationRegistryI.h> +#include <IceGrid/ServerRegistryI.h> +#include <IceGrid/AdapterRegistryI.h> +#include <IceGrid/ObjectRegistryI.h> +#include <IceGrid/NodeRegistryI.h> +#include <IceGrid/LocatorI.h> +#include <IceGrid/LocatorRegistryI.h> +#include <IceGrid/AdminI.h> +#include <IceGrid/QueryI.h> +#include <IceGrid/TraceLevels.h> + +#include <sys/types.h> +#include <sys/stat.h> + +#ifdef _WIN32 +# include <direct.h> +# define S_ISDIR(mode) ((mode) & _S_IFDIR) +# define S_ISREG(mode) ((mode) & _S_IFREG) +#else +# include <unistd.h> +#endif + +using namespace std; +using namespace Ice; +using namespace IceGrid; + +string +intToString(int v) +{ + ostringstream os; + os << v; + return os.str(); +} + +Registry::Registry(const CommunicatorPtr& communicator) : + _communicator(communicator) +{ +} + +Registry::~Registry() +{ +} + +bool +Registry::start(bool nowarn) +{ + assert(_communicator); + PropertiesPtr properties = _communicator->getProperties(); + + // + // Initialize the database environment. + // + string dbPath = properties->getProperty("IceGrid.Registry.Data"); + if(dbPath.empty()) + { + Error out(_communicator->getLogger()); + out << "property `IceGrid.Registry.Data' is not set"; + return false; + } + else + { + struct stat filestat; + if(stat(dbPath.c_str(), &filestat) != 0 || !S_ISDIR(filestat.st_mode)) + { + Error out(_communicator->getLogger()); + SyscallException ex(__FILE__, __LINE__); + ex.error = getSystemErrno(); + out << "property `IceGrid.Registry.Data' is set to an invalid path:\n" << ex; + return false; + } + } + + // + // Check that required properties are set and valid. + // + if(properties->getProperty("IceGrid.Registry.Client.Endpoints").empty()) + { + Error out(_communicator->getLogger()); + out << "property `IceGrid.Registry.Client.Endpoints' is not set"; + return false; + } + + if(properties->getProperty("IceGrid.Registry.Server.Endpoints").empty()) + { + Error out(_communicator->getLogger()); + out << "property `IceGrid.Registry.Server.Endpoints' is not set"; + return false; + } + + if(properties->getProperty("IceGrid.Registry.Internal.Endpoints").empty()) + { + Error out(_communicator->getLogger()); + out << "property `IceGrid.Registry.Internal.Endpoints' is not set"; + return false; + } + + if(!properties->getProperty("IceGrid.Registry.Admin.Endpoints").empty()) + { + if(!nowarn) + { + Warning out(_communicator->getLogger()); + out << "administrative endpoints `IceGrid.Registry.Admin.Endpoints' enabled"; + } + } + + properties->setProperty("Ice.PrintProcessId", "0"); + properties->setProperty("Ice.Warn.Leaks", "0"); + properties->setProperty("Ice.ServerIdleTime", "0"); + properties->setProperty("IceGrid.Registry.Client.AdapterId", ""); + properties->setProperty("IceGrid.Registry.Server.AdapterId", ""); + properties->setProperty("IceGrid.Registry.Admin.AdapterId", ""); + properties->setProperty("IceGrid.Registry.Internal.AdapterId", "IceGrid.Registry.Internal"); + + // + // Setup thread pool size for each thread pool. + // + int nThreadPool = 0; + if(properties->getPropertyAsInt("IceGrid.Registry.Client.ThreadPool.Size") == 0 && + properties->getPropertyAsInt("IceGrid.Registry.Client.ThreadPool.SizeMax") == 0) + { + ++nThreadPool; + } + if(properties->getPropertyAsInt("IceGrid.Registry.Server.ThreadPool.Size") == 0 && + properties->getPropertyAsInt("IceGrid.Registry.Server.ThreadPool.SizeMax") == 0) + { + ++nThreadPool; + } + if(properties->getPropertyAsInt("IceGrid.Registry.Admin.ThreadPool.Size") == 0 && + properties->getPropertyAsInt("IceGrid.Registry.Admin.ThreadPool.SizeMax") == 0) + { + ++nThreadPool; + } + + int size = properties->getPropertyAsIntWithDefault("Ice.ThreadPool.Server.Size", 10); + if(size < nThreadPool) + { + size = nThreadPool; + } + int sizeMax = properties->getPropertyAsIntWithDefault("Ice.ThreadPool.Server.SizeMax", size * 10); + if(sizeMax < size) + { + sizeMax = size; + } + int sizeWarn = properties->getPropertyAsIntWithDefault("Ice.ThreadPool.Server.SizeWarn", sizeMax * 80 / 100); + + if(properties->getPropertyAsInt("IceGrid.Registry.Client.ThreadPool.Size") == 0 && + properties->getPropertyAsInt("IceGrid.Registry.Client.ThreadPool.SizeMax") == 0) + { + properties->setProperty("IceGrid.Registry.Client.ThreadPool.Size", intToString(size / nThreadPool)); + properties->setProperty("IceGrid.Registry.Client.ThreadPool.SizeMax", intToString(sizeMax / nThreadPool)); + properties->setProperty("IceGrid.Registry.Client.ThreadPool.SizeWarn", intToString(sizeWarn / nThreadPool)); + } + if(properties->getPropertyAsInt("IceGrid.Registry.Server.ThreadPool.Size") == 0 && + properties->getPropertyAsInt("IceGrid.Registry.Server.ThreadPool.SizeMax") == 0) + { + properties->setProperty("IceGrid.Registry.Server.ThreadPool.Size", intToString(size / nThreadPool)); + properties->setProperty("IceGrid.Registry.Server.ThreadPool.SizeMax", intToString(sizeMax / nThreadPool)); + properties->setProperty("IceGrid.Registry.Server.ThreadPool.SizeWarn", intToString(sizeWarn / nThreadPool)); + } + if(properties->getPropertyAsInt("IceGrid.Registry.Admin.ThreadPool.Size") == 0 && + properties->getPropertyAsInt("IceGrid.Registry.Admin.ThreadPool.SizeMax") == 0) + { + properties->setProperty("IceGrid.Registry.Admin.ThreadPool.Size", intToString(size / nThreadPool)); + properties->setProperty("IceGrid.Registry.Admin.ThreadPool.SizeMax", intToString(sizeMax / nThreadPool)); + properties->setProperty("IceGrid.Registry.Admin.ThreadPool.SizeWarn", intToString(sizeWarn / nThreadPool)); + } + + int clientSize = properties->getPropertyAsInt("IceGrid.Registry.Client.ThreadPool.Size") * 2; + int serverSize = properties->getPropertyAsInt("IceGrid.Registry.Server.ThreadPool.Size") * 2; + properties->setProperty("IceGrid.Registry.Internal.ThreadPool.Size", intToString(clientSize + serverSize)); + + int clientSizeMax = properties->getPropertyAsInt("IceGrid.Registry.Client.ThreadPool.SizeMax") * 2; + if(clientSizeMax < clientSize) + { + clientSizeMax = clientSize; + } + int serverSizeMax = properties->getPropertyAsInt("IceGrid.Registry.Server.ThreadPool.SizeMax") * 2; + if(serverSizeMax < serverSize) + { + serverSizeMax = serverSize; + } + properties->setProperty("IceGrid.Registry.Internal.ThreadPool.SizeMax", + intToString(clientSizeMax + serverSizeMax)); + + int clientSizeWarn = properties->getPropertyAsIntWithDefault("IceGrid.Registry.Client.ThreadPool.SizeWarn", + clientSizeMax * 80 / 100) * 2; + int serverSizeWarn = properties->getPropertyAsIntWithDefault("IceGrid.Registry.Server.ThreadPool.SizeWarn", + serverSizeMax * 80 / 100) * 2; + properties->setProperty("IceGrid.Registry.Internal.ThreadPool.SizeWarn", + intToString(clientSizeWarn + serverSizeWarn)); + + TraceLevelsPtr traceLevels = new TraceLevels(properties, _communicator->getLogger()); + + _communicator->setDefaultLocator(0); + + // + // Create the object adapters. + // + ObjectAdapterPtr serverAdapter = _communicator->createObjectAdapter("IceGrid.Registry.Server"); + ObjectAdapterPtr clientAdapter = _communicator->createObjectAdapter("IceGrid.Registry.Client"); + ObjectAdapterPtr adminAdapter = _communicator->createObjectAdapter("IceGrid.Registry.Admin"); + ObjectAdapterPtr registryAdapter = _communicator->createObjectAdapter("IceGrid.Registry.Internal"); + + // + // Create the internal registries (node, server, adapter, object). + // + const string envName = "Registry"; + properties->setProperty("Freeze.DbEnv.Registry.DbHome", dbPath); + AdapterFactoryPtr adapterFactory = new AdapterFactory(registryAdapter, traceLevels, envName); + ObjectRegistryPtr objectRegistry = new ObjectRegistryI(_communicator, envName, traceLevels); + AdapterRegistryPtr adapterRegistry = new AdapterRegistryI(_communicator, envName, traceLevels); + ServerRegistryPtr serverRegistry = new ServerRegistryI(_communicator, envName, traceLevels); + ApplicationRegistryPtr appReg = new ApplicationRegistryI(_communicator, serverRegistry, envName, traceLevels); + NodeRegistryPtr nodeReg = new NodeRegistryI(_communicator, envName, adapterRegistry, adapterFactory, traceLevels); + + registryAdapter->add(objectRegistry, stringToIdentity("IceGrid/ObjectRegistry")); + registryAdapter->add(adapterRegistry, stringToIdentity("IceGrid/AdapterRegistry")); + registryAdapter->add(serverRegistry, stringToIdentity("IceGrid/ServerRegistry")); + registryAdapter->add(appReg, stringToIdentity("IceGrid/ApplicationRegistry")); + registryAdapter->add(nodeReg, stringToIdentity("IceGrid/NodeRegistry")); + + // + // Create the locator registry and locator interfaces. + // + bool dynamicReg = properties->getPropertyAsInt("IceGrid.Registry.DynamicRegistration") > 0; + ObjectPtr locatorRegistry = new LocatorRegistryI(adapterRegistry, serverRegistry, adapterFactory, dynamicReg); + ObjectPrx obj = serverAdapter->add(locatorRegistry, stringToIdentity("IceGrid/" + IceUtil::generateUUID())); + LocatorRegistryPrx locatorRegistryPrx = LocatorRegistryPrx::uncheckedCast(obj->ice_collocationOptimization(false)); + ObjectPtr locator = new LocatorI(adapterRegistry, objectRegistry, locatorRegistryPrx); + clientAdapter->add(locator, stringToIdentity("IceGrid/Locator")); + + // + // Create the query interface and register it with the object registry. + // + QueryPtr query = new QueryI(_communicator, objectRegistry); + clientAdapter->add(query, stringToIdentity("IceGrid/Query")); + ObjectPrx queryPrx = clientAdapter->createDirectProxy(stringToIdentity("IceGrid/Query")); + try + { + objectRegistry->remove(queryPrx->ice_getIdentity()); + } + catch(const ObjectNotExistException&) + { + } + IceGrid::ObjectDescriptor desc; + desc.proxy = queryPrx; + desc.type = "::IceGrid::Query"; + objectRegistry->add(desc); + + // + // Create the admin interface and register it with the object registry. + // + ObjectPtr admin = new AdminI(_communicator, nodeReg, appReg, serverRegistry, adapterRegistry, objectRegistry, + this); + adminAdapter->add(admin, stringToIdentity("IceGrid/Admin")); + ObjectPrx adminPrx = adminAdapter->createDirectProxy(stringToIdentity("IceGrid/Admin")); + try + { + objectRegistry->remove(adminPrx->ice_getIdentity()); + } + catch(const ObjectNotExistException&) + { + } + desc.proxy = adminPrx; + desc.type = "::IceGrid::Admin"; + objectRegistry->add(desc); + + // + // Register the IceGrid.Registry.Internal adapter with the adapter registry. + // + try + { + adapterRegistry->remove("IceGrid.Registry.Internal", 0); + } + catch(const AdapterNotExistException&) + { + } + obj = registryAdapter->addWithUUID(new StandaloneAdapterI()); + registryAdapter->activate(); + AdapterPrx adapter = AdapterPrx::uncheckedCast(registryAdapter->createDirectProxy(obj->ice_getIdentity())); + adapterRegistry->add("IceGrid.Registry.Internal", adapter); + adapter->setDirectProxy(adapter); + + // + // Setup a internal locator to be used by the IceGrid registry itself. This locator is + // registered with the registry object adapter which is using an independant threadpool. + // + locator = new LocatorI(adapterRegistry, objectRegistry, locatorRegistryPrx); + registryAdapter->add(locator, stringToIdentity("IceGrid/Locator")); + obj = registryAdapter->createDirectProxy(stringToIdentity("IceGrid/Locator")); + _communicator->setDefaultLocator(LocatorPrx::uncheckedCast(obj->ice_collocationOptimization(false))); + + // + // We are ready to go! + // + serverAdapter->activate(); + clientAdapter->activate(); + if(adminAdapter) + { + adminAdapter->activate(); + } + + return true; +} + +void +Registry::shutdown() +{ + _communicator->shutdown(); +} diff --git a/cpp/src/IceGrid/Registry.h b/cpp/src/IceGrid/Registry.h new file mode 100644 index 00000000000..93f7633bf8c --- /dev/null +++ b/cpp/src/IceGrid/Registry.h @@ -0,0 +1,35 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICE_GRID_REGISTRY_H +#define ICE_GRID_REGISTRY_H + +namespace IceGrid +{ + +class Registry : public IceUtil::Shared +{ +public: + + Registry(const Ice::CommunicatorPtr&); + ~Registry(); + + bool start(bool); + + virtual void shutdown(); + +private: + + Ice::CommunicatorPtr _communicator; +}; +typedef IceUtil::Handle<Registry> RegistryPtr; + +} + +#endif diff --git a/cpp/src/IceGrid/Scanner.l b/cpp/src/IceGrid/Scanner.l new file mode 100644 index 00000000000..8cb8498b6a1 --- /dev/null +++ b/cpp/src/IceGrid/Scanner.l @@ -0,0 +1,368 @@ +%{ + +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <Ice/Ice.h> +#include <IceGrid/Parser.h> +#include <IceGrid/Grammar.h> + +#ifdef _WIN32 +// I get these warnings from some flex versions: +// warning C4003: not enough actual parameters for macro 'yywrap' +# pragma warning( disable : 4003 ) +#endif + +using namespace std; +using namespace Ice; +using namespace IceGrid; + +#define YY_INPUT(buf, result, maxSize) parser->getInput(buf, result, maxSize) + +%} + +WS [ \t\v\f\r] +NL [\n] + +%option noyywrap + +%% + +^"#"[[:blank:]]*[[:digit:]]+[[:blank:]]*$ { + parser->scanPosition(yytext); +} + +^"#"[[:blank:]]*[[:digit:]]+[[:blank:]]+"\""[^\"]*"\"".*$ { + parser->scanPosition(yytext); +} + +^"#"[[:blank:]]*"line"[[:blank:]]+[[:digit:]]+[[:blank:]]*$ { + parser->scanPosition(yytext); +} + +^"#"[[:blank:]]*"line"[[:blank:]]+[[:digit:]]+[[:blank:]]+"\""[^\"]*"\"".*$ { + parser->scanPosition(yytext); +} + +"//" { + // C++-style comment + int c; + do + { + c = yyinput(); + if(c == '\n') + { + parser->nextLine(); + } + } + while(c != '\n' && c != EOF); +} + +"/*" { + // C-style comment + while(true) + { + int c = yyinput(); + if(c == '\n') + { + parser->nextLine(); + } + else if(c == '*') + { + int next = yyinput(); + if(next == '/') + { + break; + } + else + { + unput(next); + } + } + else if(c == EOF) + { + parser->warning("EOF in comment"); + break; + } + } +} + +"help" { + return ICE_GRID_HELP; +} + +"quit"|"exit" { + return ICE_GRID_EXIT; +} + +"application" { + return ICE_GRID_APPLICATION; +} + +"server" { + return ICE_GRID_SERVER; +} + +"adapter" { + return ICE_GRID_ADAPTER; +} + +"add" { + return ICE_GRID_ADD; +} + +"remove" { + return ICE_GRID_REMOVE; +} + +"list" { + return ICE_GRID_LIST; +} + +"shutdown" { + return ICE_GRID_SHUTDOWN; +} + +"describe" { + return ICE_GRID_DESCRIBE; +} + +"state" { + return ICE_GRID_STATE; +} + +"pid" { + return ICE_GRID_PID; +} + +"endpoints" { + return ICE_GRID_ENDPOINTS; +} + +"start" { + return ICE_GRID_START; +} + +"stop" { + return ICE_GRID_STOP; +} + +"signal" { + return ICE_GRID_SIGNAL; +} + +"stdout" { + return ICE_GRID_STDOUT; +} + +"stderr" { + return ICE_GRID_STDERR; +} + +"node" { + return ICE_GRID_NODE; +} + +"ping" { + return ICE_GRID_PING; +} + +"activation" { + return ICE_GRID_ACTIVATION; +} + +"object" { + return ICE_GRID_OBJECT; +} + +"find" { + return ICE_GRID_FIND; +} + +"show" { + return ICE_GRID_SHOW; +} + +"copying" { + return ICE_GRID_COPYING; +} + +"warranty" { + return ICE_GRID_WARRANTY; +} + +"diff" { + return ICE_GRID_DIFF; +} + +"update" { + return ICE_GRID_UPDATE; +} + +{WS}*(\\{WS}*{NL})? { + size_t len = strlen(yytext); + for(size_t i = 0; i < len; ++i) + { + if(yytext[i] == '\\') + { + parser->continueLine(); + } + else if(yytext[i] == '\n') + { + parser->nextLine(); + } + } +} + +{NL}|; { + size_t len = strlen(yytext); + for(size_t i = 0; i < len; ++i) + { + if(yytext[i] == '\n') + { + parser->nextLine(); + } + } + return ';'; +} + +\" { + // "..."-type strings + string s; + while(true) + { + char c = static_cast<char>(yyinput()); + if(c == '"') + { + break; + } + else if(c == EOF) + { + parser->warning("EOF in string"); + break; + } + else if(c == '\n') + { + s += c; + parser->nextLine(); + } + else if(c == '\\') + { + char next = static_cast<char>(yyinput()); + switch(next) + { + case '\\': + case '"': + { + s += next; + break; + } + + case 'n': + { + s += '\n'; + break; + } + + case 'r': + { + s += '\r'; + break; + } + + case 't': + { + s += '\t'; + break; + } + + case 'v': + { + s += '\v'; + break; + } + + case 'f': + { + s += '\f'; + break; + } + + default: + { + s += c; + unput(next); + } + } + } + else + { + s += c; + } + } + yylvalp->clear(); + yylvalp->push_back(s); + return ICE_GRID_STRING; +} + +\' { + // '...'-type strings + string s; + while(true) + { + char c = static_cast<char>(yyinput()); + if(c == '\'') + { + break; + } + else if(c == EOF) + { + parser->warning("EOF in string"); + break; + } + else if(c == '\n') + { + s += c; + parser->nextLine(); + } + else + { + s += c; + } + } + yylvalp->clear(); + yylvalp->push_back(s); + return ICE_GRID_STRING; +} + +. { + // Simple strings + string s; + s += yytext[0]; + while(true) + { + char c = static_cast<char>(yyinput()); + if(c == EOF) + { + break; + } + else if(isspace(c) || c == ';') + { + unput(c); + break; + } + + s += c; + } + yylvalp->clear(); + yylvalp->push_back(s); + return ICE_GRID_STRING; +} + +%% diff --git a/cpp/src/IceGrid/ServerAdapterI.cpp b/cpp/src/IceGrid/ServerAdapterI.cpp new file mode 100644 index 00000000000..e2e03268fc9 --- /dev/null +++ b/cpp/src/IceGrid/ServerAdapterI.cpp @@ -0,0 +1,213 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <Ice/Ice.h> +#include <IceGrid/ServerAdapterI.h> +#include <IceGrid/ServerFactory.h> +#include <IceGrid/TraceLevels.h> +#include <IceGrid/WaitQueue.h> + +using namespace std; +using namespace IceGrid; + +namespace IceGrid +{ + +class WaitForAdapterActivation : public WaitItem +{ +public: + + WaitForAdapterActivation(const ServerAdapterPtr& adapter, + const TraceLevelsPtr traceLevels, + const AMD_Adapter_activatePtr& cb) : + WaitItem(adapter), + _adapter(adapter), + _traceLevels(traceLevels), + _cb(cb) + { + } + + virtual void execute() + { + try + { + _cb->ice_response(_adapter->getDirectProxy()); + } + catch(const AdapterNotActiveException&) + { + _cb->ice_response(0); + } + catch(const Ice::LocalException&) + { + _cb->ice_response(0); + } + } + + virtual void expired(bool destroyed) + { + if(_traceLevels->adapter > 1) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->adapterCat); + out << "server adapter `" << _adapter->id << "' activation timed out"; + } + _cb->ice_response(0); + } + +private: + + const ServerAdapterPtr _adapter; + const TraceLevelsPtr _traceLevels; + const AMD_Adapter_activatePtr _cb; +}; + +} + +ServerAdapterI::ServerAdapterI(const ServerFactoryPtr& factory, const TraceLevelsPtr& traceLevels, + Ice::Int waitTime) : + _factory(factory), + _traceLevels(traceLevels), + _waitTime(IceUtil::Time::seconds(waitTime)) +{ +} + +ServerAdapterI::~ServerAdapterI() +{ +} + +string +ServerAdapterI::getId(const Ice::Current&) +{ + return id; +} + +void +ServerAdapterI::activate_async(const AMD_Adapter_activatePtr& cb, const Ice::Current& current) +{ + { + Lock sync(*this); + if(_proxy) + { + // + // Return the adapter direct proxy. + // + cb->ice_response(_proxy); + return; + } + + if(_traceLevels->adapter > 2) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->adapterCat); + out << "waiting for activation of server adapter `" << id << "'"; + } + + _factory->getWaitQueue()->add(new WaitForAdapterActivation(this, _traceLevels, cb), _waitTime); + } + + // + // Try to start the server. Note that we start the server outside + // the synchronization block since start() can block and callback + // on this adapter (when the server is deactivating for example). + // + try + { + if(svr->start(OnDemand)) + { + return; + } + } + catch(const Ice::ObjectNotExistException&) + { + // + // The server associated to this adapter doesn't exist anymore. Somehow the database is + // inconsistent if this happens. The best thing to do is to destroy the adapter and throw + // an ObjectNotExist exception. + // + destroy(current); + } + + // + // The server couldn't be activated, trace and return the current adapter proxy. + // + if(_traceLevels->adapter > 1) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->adapterCat); + out << "server adapter `" << id << "' activation failed, couldn't start the server"; + } + + _factory->getWaitQueue()->notifyAllWaitingOn(this); +} + +Ice::ObjectPrx +ServerAdapterI::getDirectProxy(const Ice::Current& current) const +{ + Lock sync(*this); + + // + // Return the adapter direct proxy if it's set. Otherwise, throw. The caller can eventually + // activate the adapter if it's activatable. + // + if(_proxy) + { + return _proxy; + } + else + { + AdapterNotActiveException ex; + ServerState state = svr->getState(); + ex.activatable = svr->getActivationMode() == OnDemand || state == Activating || state == Active; + ex.timeout = static_cast<int>(_waitTime.toMilliSeconds()); + throw ex; + } +} + +void +ServerAdapterI::setDirectProxy(const Ice::ObjectPrx& prx, const Ice::Current& current) +{ + Lock sync(*this); + + // + // If the adapter proxy is not null the given proxy can only be null. We don't allow to overide an + // existing proxy by another non null proxy if the server is active. + // + if(prx && _proxy) + { + if(svr->getState() == Active) + { + throw AdapterActiveException(); + } + } + + // + // Prevent eviction of an active adapter object. + // + if(prx && !_proxy) + { + _factory->getServerAdapterEvictor()->keep(current.id); + } + else if(!prx && _proxy) + { + _factory->getServerAdapterEvictor()->release(current.id); + } + + _proxy = prx; + + if(_traceLevels->adapter > 1) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->adapterCat); + out << "server adapter `" << id << "' " << (_proxy ? "activated" : "deactivated"); + } + + _factory->getWaitQueue()->notifyAllWaitingOn(this); +} + +void +ServerAdapterI::destroy(const Ice::Current& current) +{ + _factory->destroy(this, current.id); +} diff --git a/cpp/src/IceGrid/ServerAdapterI.h b/cpp/src/IceGrid/ServerAdapterI.h new file mode 100644 index 00000000000..c7b7eb57cf1 --- /dev/null +++ b/cpp/src/IceGrid/ServerAdapterI.h @@ -0,0 +1,51 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICE_GRID_SERVER_ADAPTER_I_H +#define ICE_GRID_SERVER_ADAPTER_I_H + +#include <IceUtil/Mutex.h> +#include <IceGrid/Internal.h> +#include <IceUtil/AbstractMutex.h> + +namespace IceGrid +{ + +class TraceLevels; +typedef IceUtil::Handle<TraceLevels> TraceLevelsPtr; + +class ServerFactory; +typedef IceUtil::Handle<ServerFactory> ServerFactoryPtr; + +class ServerAdapterI : public ServerAdapter, public IceUtil::AbstractMutexI<IceUtil::Mutex> +{ +public: + + ServerAdapterI(const ServerFactoryPtr&, const TraceLevelsPtr&, Ice::Int waitTime); + virtual ~ServerAdapterI(); + + virtual std::string getId(const Ice::Current&); + + virtual void activate_async(const AMD_Adapter_activatePtr& cb, const Ice::Current&); + virtual Ice::ObjectPrx getDirectProxy(const Ice::Current&) const; + virtual void setDirectProxy(const ::Ice::ObjectPrx&, const ::Ice::Current&); + virtual void destroy(const ::Ice::Current&); + +private: + + ServerFactoryPtr _factory; + TraceLevelsPtr _traceLevels; + IceUtil::Time _waitTime; + + Ice::ObjectPrx _proxy; +}; + +} + +#endif diff --git a/cpp/src/IceGrid/ServerDeployerI.cpp b/cpp/src/IceGrid/ServerDeployerI.cpp new file mode 100644 index 00000000000..b0948575e5d --- /dev/null +++ b/cpp/src/IceGrid/ServerDeployerI.cpp @@ -0,0 +1,131 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <Ice/Ice.h> +#include <IceGrid/ServerDeployerI.h> +#include <IceGrid/ServerFactory.h> +#include <IceGrid/ServerBuilder.h> +#include <IceGrid/TraceLevels.h> + +using namespace std; +using namespace IceGrid; + +ServerDeployerI::ServerDeployerI(const NodeInfoPtr& nodeInfo) : + _nodeInfo(nodeInfo) +{ +} + +ServerDeployerI::~ServerDeployerI() +{ +} + +void +ServerDeployerI::add(const string& name, const string& descriptor, const string& binPath, + const string& libPath, const Ice::StringSeq& targets, const Ice::Current&) +{ + // + // Setup required variables. + // + map<string, string> variables; + variables["parent"] = _nodeInfo->getNode()->getName(); + variables["name"] = name; + variables["fqn"] = _nodeInfo->getNode()->getName() + "." + name; + variables["binpath"] = binPath; + variables["libpath"] = libPath; + + string dataDir = _nodeInfo->getCommunicator()->getProperties()->getProperty("IceGrid.Node.Data"); + variables["datadir"] = dataDir + (dataDir[dataDir.length() - 1] == '/' ? "" : "/") + "servers/" + name; + + ServerBuilder builder(_nodeInfo, variables, targets); + + // + // Parse the server deployment descriptors. + // + builder.parse(descriptor); + + // + // Execute the builder tasks. + // + builder.execute(); +} + +void +ServerDeployerI::remove(const string& name, const Ice::Current&) +{ + ServerRegistryPrx registry = _nodeInfo->getServerRegistry(); + + // + // Component path is used to identify the component. For example: + // node1.server1.service3 + // + string componentPath = _nodeInfo->getNode()->getName() + "." + name; + + ServerPrx server; + try + { + server = registry->findByName(name); + } + catch(const ServerNotExistException&) + { + ServerDeploymentException ex; + ex.server = name; + ex.reason = "server doesn't exist"; + ex.component = componentPath; + throw ex; + } + + + ServerDescription desc; + try + { + desc = server->getServerDescription(); + } + catch(const Ice::ObjectNotExistException&) + { + ServerDeploymentException ex; + ex.server = name; + ex.reason = "server doesn't exist"; + ex.component = componentPath; + throw ex; + } + + // + // Ensure the server is from this node. + // + if(desc.node != _nodeInfo->getNode()->getName()) + { + ServerDeploymentException ex; + ex.server = name; + ex.reason = "server is not managed by this node"; + ex.component = componentPath; + throw ex; + } + + map<string, string> variables; + variables["parent"] = _nodeInfo->getNode()->getName(); + variables["name"] = name; + variables["fqn"] = _nodeInfo->getNode()->getName() + "." + name; + variables["binpath"] = desc.path; + variables["libpath"] = ""; + + string dataDir = _nodeInfo->getCommunicator()->getProperties()->getProperty("IceGrid.Node.Data"); + variables["datadir"] = dataDir + (dataDir[dataDir.length() - 1] == '/' ? "" : "/") + "servers/" + name; + + ServerBuilder builder(_nodeInfo, variables, desc.targets); + + // + // Parse the server deployment descriptors. + // + builder.parse(desc.descriptor); + + // + // Execute the builder tasks. + // + builder.undo(); +} diff --git a/cpp/src/IceGrid/ServerDeployerI.h b/cpp/src/IceGrid/ServerDeployerI.h new file mode 100644 index 00000000000..a718514ac33 --- /dev/null +++ b/cpp/src/IceGrid/ServerDeployerI.h @@ -0,0 +1,40 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICE_GRID_SERVER_DEPLOYER_I_H +#define ICE_GRID_SERVER_DEPLOYER_I_H + +#include <IceGrid/Internal.h> +#include <IceGrid/NodeInfo.h> + +namespace IceGrid +{ + + +class ServerDeployerI : public ServerDeployer, public IceUtil::Mutex +{ +public: + + ServerDeployerI(const NodeInfoPtr&); + virtual ~ServerDeployerI(); + + virtual void add(const ::std::string&, const ::std::string&, const ::std::string&, const ::std::string&, + const ::Ice::StringSeq&, const ::Ice::Current& = ::Ice::Current()); + + virtual void remove(const ::std::string&, const ::Ice::Current& = ::Ice::Current()); + +private: + + NodeInfoPtr _nodeInfo; + +}; + +} + +#endif diff --git a/cpp/src/IceGrid/ServerFactory.cpp b/cpp/src/IceGrid/ServerFactory.cpp new file mode 100644 index 00000000000..eb5e10e1a34 --- /dev/null +++ b/cpp/src/IceGrid/ServerFactory.cpp @@ -0,0 +1,384 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifdef __sun +#define _POSIX_PTHREAD_SEMANTICS +#endif + +#include <Ice/Ice.h> +#include <IceUtil/UUID.h> +#include <Freeze/Evictor.h> +#include <Freeze/Initialize.h> +#include <IceGrid/ServerFactory.h> +#include <IceGrid/ServerI.h> +#include <IceGrid/ServerAdapterI.h> +#include <IceGrid/TraceLevels.h> +#include <IceGrid/DescriptorVisitor.h> + +#include <map> + +#include <sys/types.h> +#include <sys/stat.h> + +#ifdef _WIN32 +# include <direct.h> +#else +# include <unistd.h> +# include <dirent.h> +#endif + +using namespace std; +using namespace IceGrid; + +namespace IceGrid +{ + +class NodeServerCleaner : public DescriptorVisitor +{ +public: + + void clean(const ServerPrx&, const ServerDescriptorPtr&); + +private: + + virtual void visitServerEnd(const ServerWrapper&, const ServerDescriptorPtr&); + virtual bool visitServiceStart(const ServiceWrapper&, const ServiceDescriptorPtr&); + virtual void visitDbEnv(const DbEnvWrapper&, const DbEnvDescriptor&); + + ServerPrx _currentServer; +}; + +}; + +void +NodeServerCleaner::clean(const ServerPrx& server, const ServerDescriptorPtr& descriptor) +{ + _currentServer = server; + ServerWrapper(descriptor).visit(*this); +} + +void +NodeServerCleaner::visitServerEnd(const ServerWrapper&, const ServerDescriptorPtr& server) +{ + _currentServer->removeConfigFile("config"); + _currentServer->destroy(); +} + +bool +NodeServerCleaner::visitServiceStart(const ServiceWrapper&, const ServiceDescriptorPtr& service) +{ + _currentServer->removeConfigFile("config_" + service->name); + return true; +} + +void +NodeServerCleaner::visitDbEnv(const DbEnvWrapper&, const DbEnvDescriptor& dbEnv) +{ + _currentServer->removeDbEnv(dbEnv, ""); +} + +ServerFactory::ServerFactory(const Ice::ObjectAdapterPtr& adapter, + const TraceLevelsPtr& traceLevels, + const string& envName, + const ActivatorPtr& activator, + const WaitQueuePtr& waitQueue) : + _adapter(adapter), + _traceLevels(traceLevels), + _activator(activator), + _waitQueue(waitQueue) +{ + Ice::PropertiesPtr properties = _adapter->getCommunicator()->getProperties(); + _waitTime = properties->getPropertyAsIntWithDefault("IceGrid.Node.WaitTime", 60); + + _serversDir = properties->getProperty("IceGrid.Node.Data"); + _serversDir = _serversDir + (_serversDir[_serversDir.length() - 1] == '/' ? "" : "/") + "servers/"; + + // + // Create and install the freeze evictor for server objects. + // + properties->setProperty("Freeze.Evictor." + envName + ".servers.SaveSizeTrigger", "1"); + _serverEvictor = Freeze::createEvictor(_adapter, envName, "servers", 0); + _serverEvictor->setSize(10000); + + // + // Create and install the freeze evictor for server adapter objects. + // + properties->setProperty("Freeze.Evictor." + envName + ".serveradapters.SaveSizeTrigger", "1"); + _serverAdapterEvictor = Freeze::createEvictor(_adapter, envName, "serveradapters", 0); + _serverAdapterEvictor->setSize(10000); + + // + // Install the server object factory. + // + _adapter->getCommunicator()->addObjectFactory(this, "::IceGrid::Server"); + _adapter->getCommunicator()->addObjectFactory(this, "::IceGrid::ServerAdapter"); + + // + // Install the evictors. + // + _adapter->addServantLocator(_serverEvictor, "IceGridServer"); + _adapter->addServantLocator(_serverAdapterEvictor, "IceGridServerAdapter"); +} + +// +// Ice::ObjectFactory::create method implementation +// +Ice::ObjectPtr +ServerFactory::create(const string& type) +{ + if(type == "::IceGrid::Server") + { + return new ServerI(this, _traceLevels, _activator, _waitTime, _serversDir); + } + else if(type == "::IceGrid::ServerAdapter") + { + return new ServerAdapterI(this, _traceLevels, _waitTime); + } + else + { + assert(false); + return 0; // Keep the compiler happy. + } +} + +// +// Ice::ObjectFactory::destroy method implementation +// +void +ServerFactory::destroy() +{ + _adapter = 0; + _serverEvictor = 0; + _serverAdapterEvictor = 0; + _traceLevels = 0; + _activator = 0; +} + +void +ServerFactory::checkConsistency() +{ + try + { + Ice::CommunicatorPtr communicator = _adapter->getCommunicator(); + + // + // Make sure that all the servers in this node server database are registered with the + // IceGrid server registry. If a server isn't registered with the registry, we remove + // it from the node and also delete any resources associated with it (config files, + // db envs, ...). + // + ServerRegistryPrx serverRegistry = ServerRegistryPrx::checkedCast( + communicator->stringToProxy("IceGrid/ServerRegistry@IceGrid.Registry.Internal")); + + Freeze::EvictorIteratorPtr p = _serverEvictor->getIterator("", 50); + while(p->hasNext()) + { + ServerPrx server = ServerPrx::uncheckedCast(_adapter->createProxy(p->next())); + ServerDescriptorPtr descriptor = server->getDescriptor(); + try + { + if(Ice::proxyIdentityEqual(serverRegistry->findByName(descriptor->name), server)) + { + continue; + } + } + catch(const ServerNotExistException&) + { + } + + NodeServerCleaner().clean(server, descriptor); + } + + // + // Make sure all the adapters in this node adapter database are registered with the + // IceGrid adapter registry. If an adapter isn't registered with the registry, we + // remove it from this node. + // + AdapterRegistryPrx adapterRegistry = AdapterRegistryPrx::checkedCast( + communicator->stringToProxy("IceGrid/AdapterRegistry@IceGrid.Registry.Internal")); + + p = _serverAdapterEvictor->getIterator("", 50); + while(p->hasNext()) + { + ServerAdapterPrx adapter = ServerAdapterPrx::uncheckedCast(_adapter->createProxy(p->next())); + try + { + if(Ice::proxyIdentityEqual(adapterRegistry->findById(adapter->getId()), adapter)) + { + continue; + } + } + catch(const AdapterNotExistException&) + { + } + + adapter->destroy(); + } + } + catch(const Ice::LocalException& ex) + { + ostringstream os; + os << "couldn't contact the IceGrid registry for the consistency check:\n" << ex; + _traceLevels->logger->warning(os.str()); + return; + } + +} + +// +// Create a new server servant and new server adapter servants from +// the given description. +// +ServerPrx +ServerFactory::createServer(const string& name, const ServerDescriptorPtr& desc) +{ + // + // Create the server object. + // + ServerPtr serverI = new ServerI(this, _traceLevels, _activator, _waitTime, _serversDir); + + serverI->name = name; + serverI->activation = Manual; + serverI->processRegistered = false; + serverI->descriptor = desc; + + string path = _serversDir + name; +#ifdef _WIN32 + if(_mkdir(path.c_str()) != 0) +#else + if(mkdir(path.c_str(), 0755) != 0) +#endif + { + DeploymentException ex; + ex.reason = "couldn't create directory " + path + ": " + strerror(getSystemErrno()); + throw ex; + } + +#ifdef _WIN32 + _mkdir(string(path + "/config").c_str()); + _mkdir(string(path + "/dbs").c_str()); +#else + mkdir(string(path + "/config").c_str(), 0755); + mkdir(string(path + "/dbs").c_str(), 0755); +#endif + + Ice::Identity id; + id.category = "IceGridServer"; + id.name = name + "-" + IceUtil::generateUUID(); + + _serverEvictor->add(serverI, id); + + if(_traceLevels->server > 0) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->serverCat); + out << "created server `" << name << "'"; + } + + return ServerPrx::uncheckedCast(_adapter->createProxy(id)); +} + +// +// Create a new server adapter servant with the given name and server +// and add it the evictor database. +// +ServerAdapterPrx +ServerFactory::createServerAdapter(const string& adapterId, const ServerPrx& server) +{ + ServerAdapterPtr adapterI = new ServerAdapterI(this, _traceLevels, _waitTime); + adapterI->id = adapterId; + adapterI->svr = server; + + Ice::Identity id; + id.category = "IceGridServerAdapter"; + id.name = adapterId + "-" + IceUtil::generateUUID(); + + _serverAdapterEvictor->add(adapterI, id); + + if(_traceLevels->adapter > 0) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->adapterCat); + out << "created server adapter `" << adapterId << "'"; + } + + return ServerAdapterPrx::uncheckedCast(_adapter->createProxy(id)); +} + +const WaitQueuePtr& +ServerFactory::getWaitQueue() const +{ + return _waitQueue; +} + +const Freeze::EvictorPtr& +ServerFactory::getServerEvictor() const +{ + return _serverEvictor; +} + +const Freeze::EvictorPtr& +ServerFactory::getServerAdapterEvictor() const +{ + return _serverAdapterEvictor; +} + +void +ServerFactory::destroy(const ServerPtr& server, const Ice::Identity& ident) +{ + try + { + _serverEvictor->remove(ident); + + if(_traceLevels->server > 0) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->serverCat); + out << "destroyed server `" << server->name << "'"; + } + } + catch(const Freeze::DatabaseException& ex) + { + ostringstream os; + os << "couldn't destroy server `" << server->name << "':\n" << ex; + _traceLevels->logger->warning(os.str()); + } + catch(const Freeze::EvictorDeactivatedException&) + { + assert(false); + } + + string path = _serversDir + server->name; + rmdir(string(path + "/config").c_str()); + rmdir(string(path + "/dbs").c_str()); + rmdir(path.c_str()); +} + +void +ServerFactory::destroy(const ServerAdapterPtr& adapter, const Ice::Identity& ident) +{ + try + { + _serverAdapterEvictor->remove(ident); + + if(_traceLevels->adapter > 0) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->adapterCat); + out << "destroyed server adapter `" << adapter->id << "'"; + } + } + catch(const Freeze::DatabaseException& ex) + { + ostringstream os; + os << "couldn't destroy server adapter `" << adapter->id << "':\n" << ex; + _traceLevels->logger->warning(os.str()); + } + catch(const Freeze::EvictorDeactivatedException&) + { + assert(false); + } +} + diff --git a/cpp/src/IceGrid/ServerFactory.h b/cpp/src/IceGrid/ServerFactory.h new file mode 100644 index 00000000000..b19697a3dc0 --- /dev/null +++ b/cpp/src/IceGrid/ServerFactory.h @@ -0,0 +1,72 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICE_GRID_SERVER_FACTORY_H +#define ICE_GRID_SERVER_FACTORY_H + +#include <IceGrid/Internal.h> +#include <IceGrid/Activator.h> +#include <IceGrid/WaitQueue.h> +#include <Freeze/Evictor.h> + +namespace IceGrid +{ + +class TraceLevels; +typedef IceUtil::Handle<TraceLevels> TraceLevelsPtr; + +class ServerFactory : public Ice::ObjectFactory +{ +public: + + ServerFactory(const Ice::ObjectAdapterPtr&, + const TraceLevelsPtr&, + const std::string&, + const ActivatorPtr&, + const WaitQueuePtr&); + + // + // Ice::ObjectFactory method implementation. + // + virtual Ice::ObjectPtr create(const std::string&); + virtual void destroy(); + + void checkConsistency(); + + ServerPrx createServer(const std::string&, const ServerDescriptorPtr&); + ServerAdapterPrx createServerAdapter(const std::string& name, const ServerPrx& server); + + const WaitQueuePtr& getWaitQueue() const; + const Freeze::EvictorPtr& getServerEvictor() const; + const Freeze::EvictorPtr& getServerAdapterEvictor() const; + +private: + + friend class ServerI; + friend class ServerAdapterI; + + void destroy(const ServerPtr&, const Ice::Identity&); + void destroy(const ServerAdapterPtr&, const Ice::Identity&); + + Ice::ObjectAdapterPtr _adapter; + TraceLevelsPtr _traceLevels; + ActivatorPtr _activator; + WaitQueuePtr _waitQueue; + + Freeze::EvictorPtr _serverEvictor; + Freeze::EvictorPtr _serverAdapterEvictor; + Ice::Int _waitTime; + std::string _serversDir; +}; + +typedef ::IceUtil::Handle< ServerFactory> ServerFactoryPtr; + +} + +#endif diff --git a/cpp/src/IceGrid/ServerI.cpp b/cpp/src/IceGrid/ServerI.cpp new file mode 100644 index 00000000000..3d97d2a0302 --- /dev/null +++ b/cpp/src/IceGrid/ServerI.cpp @@ -0,0 +1,807 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifdef __sun +#define _POSIX_PTHREAD_SEMANTICS +#endif + +#include <IceUtil/UUID.h> +#include <Ice/Ice.h> +#include <IceGrid/ServerI.h> +#include <IceGrid/ServerFactory.h> +#include <IceGrid/TraceLevels.h> +#include <IceGrid/Activator.h> + +#include <sys/types.h> +#include <sys/stat.h> + +#ifdef _WIN32 +# include <direct.h> +#else +# include <unistd.h> +# include <dirent.h> +#endif + +#include <fstream> + +using namespace std; +using namespace IceGrid; + +ServerI::ServerI(const ServerFactoryPtr& factory, + const TraceLevelsPtr& traceLevels, + const ActivatorPtr& activator, + Ice::Int waitTime, + const string& serversDir) : + _factory(factory), + _traceLevels(traceLevels), + _activator(activator), + _waitTime(waitTime), + _serversDir(serversDir), + _state(Inactive) +{ + assert(_activator); +} + +ServerI::~ServerI() +{ +} + +bool +ServerI::start(ServerActivation act, const Ice::Current& current) +{ + string exe; + string wd; + Ice::StringSeq opts; + Ice::StringSeq evs; + + while(true) + { + Lock sync(*this); + switch(_state) + { + case Inactive: + { + if(act < activation) + { + return false; + } + + _state = Activating; + + // + // Prevent eviction of the server object once it's not anymore in the inactive state. + // + _factory->getServerEvictor()->keep(current.id); + + break; + } + case Activating: + case Deactivating: + { + wait(); // TODO: Timeout? + continue; + } + case Active: + { + return true; // Raise an exception instead? + } + case Destroying: + case Destroyed: + { + Ice::ObjectNotExistException ex(__FILE__,__LINE__); + ex.id = current.id; + throw ex; + } + } + + if(_traceLevels->server > 2) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->serverCat); + out << "changed server `" << name << "' state to `Activating'"; + } + assert(_state == Activating); + + exe = exePath; + wd = pwd; + opts = options; + evs = envs; + break; + } + + try + { + ServerPrx self = ServerPrx::uncheckedCast(current.adapter->createProxy(current.id)); + bool active = _activator->activate(name, exe, wd, opts, evs, self); + setState(active ? Active : Inactive, current); + return active; + } + catch(const Ice::SyscallException& ex) + { + Ice::Warning out(_traceLevels->logger); + out << "activation failed for server `" << name << "':\n"; + out << ex; + + setState(Inactive, current); + return false; + } +} + +void +ServerI::stop(const Ice::Current& current) +{ + while(true) + { + Lock sync(*this); + switch(_state) + { + case Inactive: + { + return; + } + case Activating: + case Deactivating: + { + wait(); // TODO: Timeout? + continue; + } + case Active: + { + _state = Deactivating; + break; + } + case Destroying: + case Destroyed: + { + Ice::ObjectNotExistException ex(__FILE__,__LINE__); + ex.id = current.id; + throw ex; + } + } + + if(_traceLevels->server > 2) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->serverCat); + out << "changed server `" << name << "' state to `Deactivating'"; + } + assert(_state == Deactivating); + break; + } + + stopInternal(current); +} + +void +ServerI::sendSignal(const string& signal, const Ice::Current& current) +{ + _activator->sendSignal(name, signal); +} + +void +ServerI::writeMessage(const string& message, Ice::Int fd, const Ice::Current& current) +{ + IceUtil::Monitor< ::IceUtil::Mutex>::Lock sync(*this); + if(_process != 0) + { + try + { + _process->writeMessage(message, fd); + } + catch(const Ice::LocalException&) + { + } + } +} + +void +ServerI::destroy(const Ice::Current& current) +{ + bool stop = false; + + while(true) + { + Lock sync(*this); + switch(_state) + { + case Inactive: + { + _state = Destroyed; + break; + } + case Active: + { + stop = true; + _state = Destroying; + break; + } + case Activating: + case Deactivating: + { + wait(); // TODO: Timeout? + continue; + } + case Destroying: + case Destroyed: + { + Ice::ObjectNotExistException ex(__FILE__,__LINE__); + ex.id = current.id; + throw ex; + } + } + + assert(_state == Destroyed || _state == Destroying); + + if(_traceLevels->server > 2) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->serverCat); + out << "changed server `" << name << "' state to `"; + out << (_state == Destroyed ? "Destroyed" : "Destroying") << "'"; + } + break; + } + + if(stop) + { + stopInternal(current); + } + + + _factory->destroy(this, current.id); +} + +void +ServerI::terminated(const Ice::Current& current) +{ + ServerState newState = Inactive; // Initialize to keep the compiler happy. + ServerAdapterPrxDict adpts; + while(true) + { + Lock sync(*this); + switch(_state) + { + case Inactive: + { + assert(false); + } + case Activating: + { + wait(); // TODO: Timeout? + continue; + } + case Active: + { + _state = Deactivating; + if(_traceLevels->server > 2) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->serverCat); + out << "changed server `" << name << "' state to `Deactivating'"; + } + newState = Inactive; + break; + } + case Deactivating: + { + // + // Deactivation was initiated by the stop method. + // + newState = Inactive; + break; + } + case Destroying: + { + // + // Deactivation was initiated by the destroy method. + // + newState = Destroyed; + break; + } + case Destroyed: + { + assert(false); + } + } + + assert(_state == Deactivating || _state == Destroying); + adpts = adapters; + + // + // Clear the process proxy. + // + _process = 0; + break; + } + + if(newState != Destroyed) + { + // + // The server has terminated, set its adapter direct proxies to + // null to cause the server re-activation if one of its adapter + // direct proxy is requested. + // + for(ServerAdapterPrxDict::iterator p = adpts.begin(); p != adpts.end(); ++p) + { + try + { + p->second->setDirectProxy(0); + } + catch(const Ice::ObjectNotExistException&) + { + } + } + } + + setState(newState, current); +} + +ServerState +ServerI::getState(const Ice::Current&) +{ + Lock sync(*this); + return _state; +} + +Ice::Int +ServerI::getPid(const Ice::Current& current) +{ + return _activator->getServerPid(name); +} + +void +ServerI::setActivationMode(ServerActivation mode, const ::Ice::Current&) +{ + Lock sync(*this); + activation = mode; +} + +ServerActivation +ServerI::getActivationMode(const ::Ice::Current&) +{ + Lock sync(*this); + return activation; +} + +ServerDescriptorPtr +ServerI::getDescriptor(const Ice::Current&) +{ + Lock sync(*this); + return descriptor; +} + +void +ServerI::setExePath(const string& path, const ::Ice::Current&) +{ + Lock sync(*this); + exePath = path; +} + +void +ServerI::setPwd(const string& path,const ::Ice::Current&) +{ + Lock sync(*this); + pwd = path; +} + +void +ServerI::setEnvs(const Ice::StringSeq& s, const ::Ice::Current&) +{ + Lock sync(*this); + envs = s; +} + +void +ServerI::setOptions(const Ice::StringSeq& opts, const ::Ice::Current&) +{ + Lock sync(*this); + options = opts; +} + +void +ServerI::addAdapter(const ServerAdapterPrx& adapter, bool registerProcess, const ::Ice::Current&) +{ + Lock sync(*this); + ServerAdapterPrxDict::const_iterator p = adapters.find(adapter->ice_getIdentity()); + if(p != adapters.end()) + { + DeploymentException ex; + ex.reason = "failed to add adapter because it already exists"; + throw ex; + } + adapters[adapter->ice_getIdentity()] = adapter; + processRegistered |= registerProcess; +} + +void +ServerI::removeAdapter(const ServerAdapterPrx& adapter, const ::Ice::Current&) +{ + Lock sync(*this); + adapters.erase(adapter->ice_getIdentity()); +} + +string +ServerI::addConfigFile(const string& n, const PropertyDescriptorSeq& properties, const ::Ice::Current&) +{ + string file = _serversDir + name + "/config/" + n; + + ofstream configfile; + configfile.open(file.c_str(), ios::out); + if(!configfile) + { + DeploymentException ex; + ex.reason = "couldn't create configuration file: " + file; + throw ex; + } + + for(PropertyDescriptorSeq::const_iterator p = properties.begin(); p != properties.end(); ++p) + { + configfile << p->name; + if(!p->value.empty()) + { + configfile << "=" << p->value; + } + configfile << endl; + } + configfile.close(); + + return file; +} + +void +ServerI::removeConfigFile(const string& n, const ::Ice::Current&) +{ + string file = _serversDir + name + "/config/" + n; + if(unlink(file.c_str()) != 0) + { + Ice::Warning out(_traceLevels->logger); + out << "couldn't remove configuration file: " + file + ": " + strerror(getSystemErrno()); + } +} + +string +ServerI::addDbEnv(const DbEnvDescriptor& dbEnv, const string& path, const ::Ice::Current&) +{ + string dir; + if(dbEnv.dbHome.empty()) + { + dir = _serversDir + name + "/dbs/" + dbEnv.name; + } + else + { + dir = dbEnv.dbHome; + } + + // + // If no db home directory is specified for this db env, we provide one. + // + if(dbEnv.dbHome.empty()) + { + // + // First, we try to move the given backup if specified, if not successful, we just + // create the database environment directory. + // + if(path.empty() || rename((path + "/" + dbEnv.name).c_str(), dir.c_str()) != 0) + { + // + // Create the database environment directory. + // +#ifdef _WIN32 + if(_mkdir(dir.c_str()) != 0) +#else + if(mkdir(dir.c_str(), 0755) != 0) +#endif + { + DeploymentException ex; + ex.reason = "couldn't create directory " + dir + ": " + strerror(getSystemErrno()); + throw ex; + } + } + } + + string file = dir + "/DB_CONFIG"; + ofstream configfile; + configfile.open(file.c_str(), ios::out); + if(!configfile) + { + rmdir(dir.c_str()); + + DeploymentException ex; + ex.reason = "couldn't create configuration file: " + file; + throw ex; + } + + for(PropertyDescriptorSeq::const_iterator p = dbEnv.properties.begin(); p != dbEnv.properties.end(); ++p) + { + if(!p->name.empty()) + { + configfile << p->name; + if(!p->value.empty()) + { + configfile << " " << p->value; + } + configfile << endl; + } + } + configfile.close(); + + return dir; +} + +void +ServerI::removeDbEnv(const DbEnvDescriptor& dbEnv, const string& moveTo, const ::Ice::Current&) +{ + string path; + if(dbEnv.dbHome.empty()) + { + path = _serversDir + name + "/dbs/" + dbEnv.name; + } + else + { + path = dbEnv.dbHome; + } + + if(unlink((path + "/DB_CONFIG").c_str()) != 0) + { + Ice::Warning out(_traceLevels->logger); + out << "couldn't remove file: " + path + "/DB_CONFIG: " + strerror(getSystemErrno()); + } + + // + // If no db home directory was specified for this db env, we provided one. We need to cleanup + // this directory now. + // + if(dbEnv.dbHome.empty()) + { + if(!moveTo.empty()) + { + // + // Move the database environment directory to the given directory. + // + if(rename(path.c_str(), (moveTo + "/" + dbEnv.name).c_str()) != 0) + { + Ice::Warning out(_traceLevels->logger); + out << "couldn't rename directory " + path + " to " + moveTo + "/" + dbEnv.name + ": " + + strerror(getSystemErrno()); + } + } + else + { + // + // Delete the database environment directory. + // + Ice::StringSeq files; + +#ifdef _WIN32 + string pattern = path + "/*"; + WIN32_FIND_DATA data; + HANDLE hnd = FindFirstFile(pattern.c_str(), &data); + if(hnd == INVALID_HANDLE_VALUE) + { + // TODO: log a warning, throw an exception? + return; + } + + do + { + if((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) + { + files.push_back(path + "/" + data.cFileName); + } + } + while(FindNextFile(hnd, &data)); + + FindClose(hnd); +#else + + DIR* dir = opendir(path.c_str()); + if(dir == 0) + { + // TODO: log a warning, throw an exception? + return; + } + + // TODO: make the allocation/deallocation exception-safe + struct dirent* entry = static_cast<struct dirent*>(malloc(pathconf(path.c_str(), _PC_NAME_MAX) + 1)); + + while(readdir_r(dir, entry, &entry) == 0 && entry != 0) + { + string name = path + "/" + entry->d_name; + struct stat buf; + + if(::stat(name.c_str(), &buf) != 0) + { + if(errno != ENOENT) + { + // + // TODO: log error + // + } + } + else if(S_ISREG(buf.st_mode)) + { + files.push_back(name); + } + } + + free(entry); + closedir(dir); +#endif + + for(Ice::StringSeq::iterator p = files.begin(); p != files.end(); ++p) + { + if(unlink(p->c_str()) != 0) + { + // + // TODO: log error + // + } + } + + if(rmdir(path.c_str()) != 0) + { + Ice::Warning out(_traceLevels->logger); + out << "couldn't remove directory: " + path + ": " + strerror(getSystemErrno()); + } + } + } +} + +void +ServerI::setProcess(const ::Ice::ProcessPrx& proc, const ::Ice::Current&) +{ + IceUtil::Monitor< ::IceUtil::Mutex>::Lock sync(*this); + _process = proc; + notifyAll(); +} + +void +ServerI::stopInternal(const Ice::Current& current) +{ + Ice::ProcessPrx process; + { + IceUtil::Monitor< ::IceUtil::Mutex>::Lock sync(*this); + if(!_process && processRegistered) + { + while(!_process) + { + if(_state == Inactive || _state == Destroyed) + { + // + // State changed to inactive or destroyed, the server + // has been correctly deactivated, we can return. + // + return; + } + + // + // Wait for the process to be set. + // + wait(); // TODO: timeout? + } + } + process = _process; + } + + try + { + // + // Deactivate the server. + // + _activator->deactivate(name, process); + + // + // Wait for the server to be inactive (the activator monitors + // the process and should notify us when it detects the + // process termination by calling the terminated() method). + // + Lock sync(*this); + +#ifndef NDEBUG + ServerState oldState = _state; +#endif + + while(true) + { + if(_state == Inactive || _state == Destroyed) + { + // + // State changed to inactive or destroyed, the server + // has been correctly deactivated, we can return. + // + return; + } + + // + // Wait for a notification. + // + bool notify = timedWait(IceUtil::Time::seconds(_waitTime)); + if(!notify) + { + assert(oldState == _state); + break; + } + } + + if(_traceLevels->server > 1) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->serverCat); + out << "graceful server shutdown timed out, killing server `" << name << "'"; + } + } + catch(const Ice::Exception& ex) + { + Ice::Warning out(_traceLevels->logger); + out << "graceful server shutdown failed, killing server `" << name << "':\n"; + out << ex; + } + + + // + // The server is still not inactive, kill it. + // + try + { + _activator->kill(name); + } + catch(const Ice::SyscallException& ex) + { + Ice::Warning out(_traceLevels->logger); + out << "deactivation failed for server `" << name << "':\n"; + out << ex; + + setState(Active, current); + } +} + +void +ServerI::setState(ServerState st, const Ice::Current& current) +{ + Lock sync(*this); + + // + // Allow eviction of an inactive server object. + // + if(_state != Inactive && st == Inactive) + { + _factory->getServerEvictor()->release(current.id); + } + + _state = st; + + if(_traceLevels->server > 1) + { + if(_state == Active) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->serverCat); + out << "changed server `" << name << "' state to `Active'"; + } + else if(_state == Inactive) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->serverCat); + out << "changed server `" << name << "' state to `Inactive'"; + } + else if(_state == Destroyed) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->serverCat); + out << "changed server `" << name << "' state to `Destroyed'"; + } + else if(_traceLevels->server > 2) + { + if(_state == Activating) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->serverCat); + out << "changed server `" << name << "' state to `Activating'"; + } + else if(_state == Deactivating) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->serverCat); + out << "changed server `" << name << "' state to `Deactivating'"; + } + } + } + + notifyAll(); +} diff --git a/cpp/src/IceGrid/ServerI.h b/cpp/src/IceGrid/ServerI.h new file mode 100644 index 00000000000..43ca029d32f --- /dev/null +++ b/cpp/src/IceGrid/ServerI.h @@ -0,0 +1,80 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICE_GRID_SERVER_I_H +#define ICE_GRID_SERVER_I_H + +#include <IceUtil/Mutex.h> +#include <Freeze/EvictorF.h> +#include <IceGrid/Activator.h> +#include <IceUtil/AbstractMutex.h> + +#include <IceGrid/Internal.h> + +namespace IceGrid +{ + +class TraceLevels; +typedef IceUtil::Handle<TraceLevels> TraceLevelsPtr; + +class ServerFactory; +typedef IceUtil::Handle<ServerFactory> ServerFactoryPtr; + +class ServerI : public Server, public IceUtil::AbstractMutexI<IceUtil::Monitor<IceUtil::Mutex> > +{ +public: + + ServerI(const ServerFactoryPtr&, const TraceLevelsPtr&, const ActivatorPtr&, Ice::Int waitTime,const std::string&); + virtual ~ServerI(); + + virtual bool start(ServerActivation, const ::Ice::Current&); + virtual void stop(const ::Ice::Current&); + virtual void sendSignal(const std::string&, const ::Ice::Current&); + virtual void writeMessage(const std::string&, Ice::Int, const ::Ice::Current&); + virtual void destroy(const ::Ice::Current&); + virtual void terminated(const ::Ice::Current&); + + virtual ServerState getState(const ::Ice::Current&); + virtual Ice::Int getPid(const ::Ice::Current&); + + virtual void setActivationMode(ServerActivation, const ::Ice::Current&); + virtual ServerActivation getActivationMode(const ::Ice::Current&); + virtual ServerDescriptorPtr getDescriptor(const ::Ice::Current&); + virtual void setProcess(const ::Ice::ProcessPrx&, const ::Ice::Current&); + + void setExePath(const std::string&, const ::Ice::Current&); + void setPwd(const std::string&, const ::Ice::Current&); + void setEnvs(const Ice::StringSeq&, const ::Ice::Current&); + void setOptions(const Ice::StringSeq&, const ::Ice::Current&); + void addAdapter(const ServerAdapterPrx&, bool, const ::Ice::Current&); + void removeAdapter(const ServerAdapterPrx&, const ::Ice::Current&); + std::string addConfigFile(const std::string&, const PropertyDescriptorSeq&, const ::Ice::Current&); + void removeConfigFile(const std::string&, const ::Ice::Current&); + std::string addDbEnv(const DbEnvDescriptor&, const std::string&, const ::Ice::Current&); + void removeDbEnv(const DbEnvDescriptor&, const std::string&, const ::Ice::Current&); + +private: + + void stopInternal(const Ice::Current&); + void setState(ServerState, const Ice::Current&); + + ServerFactoryPtr _factory; + TraceLevelsPtr _traceLevels; + ActivatorPtr _activator; + ::Ice::Int _waitTime; + std::string _serversDir; + + ServerState _state; + + ::Ice::ProcessPrx _process; +}; + +} + +#endif diff --git a/cpp/src/IceGrid/ServerRegistryI.cpp b/cpp/src/IceGrid/ServerRegistryI.cpp new file mode 100644 index 00000000000..fdb87302485 --- /dev/null +++ b/cpp/src/IceGrid/ServerRegistryI.cpp @@ -0,0 +1,182 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <IceGrid/ServerRegistryI.h> +#include <IceGrid/TraceLevels.h> +#include <Freeze/Initialize.h> + +using namespace std; +using namespace IceGrid; + +const string ServerRegistryI::_dbName = "serverregistry"; +const string ServerRegistryI::_dbDescriptorName = "serverdescriptors"; + +ServerRegistryI::ServerRegistryI(const Ice::CommunicatorPtr& communicator, const string& envName, + const TraceLevelsPtr& traceLevels) : + _connectionCache(Freeze::createConnection(communicator, envName)), + _dictCache(_connectionCache, _dbName), + _dictDescriptorCache(_connectionCache, _dbDescriptorName), + _traceLevels(traceLevels), + _envName(envName), + _communicator(communicator) +{ +} + +void +ServerRegistryI::add(const string& name, + const ServerPrx& server, + const ServerDescriptorPtr& descriptor, + const Ice::Current& current) +{ + while(true) + { + ServerPrx oldServer; + try + { + oldServer = findByName(name, current); + oldServer->ice_ping(); + throw ServerExistsException(); + } + catch(const ServerNotExistException&) + { + } + catch(const Ice::ObjectNotExistException&) + { + } + catch(const Ice::LocalException&) + { + throw ServerExistsException(); + } + + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + StringObjectProxyDict dict(connection, _dbName); + StringServerDescriptorDict dictDescriptor(connection, _dbDescriptorName); + + StringObjectProxyDict::iterator p = dict.find(name); + if(p != dict.end()) + { + if(oldServer && oldServer != p->second) + { + continue; + } + } + + dict.put(pair<const string, const Ice::ObjectPrx>(name, server)); + dictDescriptor.put(pair<const string, const ServerDescriptorPtr>(name, descriptor)); + + if(_traceLevels->serverRegistry > 0) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->serverRegistryCat); + out << "added server `" << name << "'"; + } + + break; + } +} + +ServerPrx +ServerRegistryI::remove(const string& name, const Ice::Current&) +{ + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + StringObjectProxyDict dict(connection, _dbName); + StringServerDescriptorDict dictDescriptor(connection, _dbDescriptorName); + + StringObjectProxyDict::iterator p = dict.find(name); + if(p == dict.end()) + { + throw ServerNotExistException(); + } + + ServerPrx server = ServerPrx::uncheckedCast(p->second); + dict.erase(p); + dictDescriptor.erase(name); + + if(_traceLevels->serverRegistry > 0) + { + Ice::Trace out(_traceLevels->logger, _traceLevels->serverRegistryCat); + out << "removed server `" << name << "'"; + } + + return server; +} + +ServerPrx +ServerRegistryI::findByName(const string& name, const Ice::Current&) +{ + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + StringObjectProxyDict dict(connection, _dbName); + + StringObjectProxyDict::iterator p = dict.find(name); + if(p != dict.end()) + { + try + { + return ServerPrx::checkedCast(p->second); + } + catch(const Ice::ObjectNotExistException&) + { + dict.erase(p); + } + catch(const Ice::LocalException&) + { + return ServerPrx::uncheckedCast(p->second); + } + } + throw ServerNotExistException(); +} + +ServerDescriptorPtr +ServerRegistryI::getDescriptor(const string& name, const Ice::Current&) +{ + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + StringServerDescriptorDict dictDescriptor(connection, _dbDescriptorName); + + StringServerDescriptorDict::iterator p = dictDescriptor.find(name); + if(p == dictDescriptor.end()) + { + throw ServerNotExistException(); + } + return p->second; +} + +Ice::StringSeq +ServerRegistryI::getAll(const Ice::Current&) const +{ + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + StringObjectProxyDict dict(connection, _dbName); + + Ice::StringSeq names; + names.reserve(dict.size()); + + for(StringObjectProxyDict::iterator p = dict.begin(); p != dict.end(); ++p) + { + names.push_back(p->first); + } + + return names; +} + +ServerDescriptorSeq +ServerRegistryI::getAllDescriptorsOnNode(const string& node, const Ice::Current&) const +{ + Freeze::ConnectionPtr connection = Freeze::createConnection(_communicator, _envName); + StringServerDescriptorDict dict(connection, _dbDescriptorName); + + ServerDescriptorSeq descriptors; + + for(StringServerDescriptorDict::iterator p = dict.begin(); p != dict.end(); ++p) + { + if(p->second->node == node) + { + descriptors.push_back(p->second); + } + } + + return descriptors; +} diff --git a/cpp/src/IceGrid/ServerRegistryI.h b/cpp/src/IceGrid/ServerRegistryI.h new file mode 100644 index 00000000000..dc285145d57 --- /dev/null +++ b/cpp/src/IceGrid/ServerRegistryI.h @@ -0,0 +1,52 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICE_GRID_SERVER_REGISTRY_I_H +#define ICE_GRID_SERVER_REGISTRY_I_H + +#include <IceGrid/Internal.h> +#include <IceGrid/StringObjectProxyDict.h> +#include <IceGrid/StringServerDescriptorDict.h> + +namespace IceGrid +{ + +class TraceLevels; +typedef IceUtil::Handle<TraceLevels> TraceLevelsPtr; + +class ServerRegistryI : public ServerRegistry +{ +public: + + ServerRegistryI(const Ice::CommunicatorPtr&, const std::string&, const TraceLevelsPtr&); + + virtual void add(const std::string&, const ServerPrx&, const ServerDescriptorPtr&, const ::Ice::Current&); + virtual ServerPrx remove(const std::string&, const ::Ice::Current&); + + virtual ServerPrx findByName(const ::std::string&, const ::Ice::Current&); + virtual ServerDescriptorPtr getDescriptor(const ::std::string&, const Ice::Current&); + virtual Ice::StringSeq getAll(const ::Ice::Current&) const; + virtual ServerDescriptorSeq getAllDescriptorsOnNode(const std::string&, const ::Ice::Current&) const; + +private: + + static const std::string _dbName; + static const std::string _dbDescriptorName; + + Freeze::ConnectionPtr _connectionCache; + StringObjectProxyDict _dictCache; + StringServerDescriptorDict _dictDescriptorCache; + TraceLevelsPtr _traceLevels; + const std::string _envName; + const Ice::CommunicatorPtr _communicator; +}; + +} + +#endif diff --git a/cpp/src/IceGrid/TraceLevels.cpp b/cpp/src/IceGrid/TraceLevels.cpp new file mode 100644 index 00000000000..d2a4c6944c0 --- /dev/null +++ b/cpp/src/IceGrid/TraceLevels.cpp @@ -0,0 +1,50 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <Ice/Properties.h> +#include <IceGrid/TraceLevels.h> + +using namespace std; +using namespace IceGrid; + +TraceLevels::TraceLevels(const Ice::PropertiesPtr& properties, const Ice::LoggerPtr& theLogger) : + server(0), + serverCat("Server"), + adapter(0), + adapterCat("Adapter"), + activator(0), + activatorCat("Activator"), + applicationRegistry(0), + applicationRegistryCat("ApplicationRegistry"), + serverRegistry(0), + serverRegistryCat("ServerRegistry"), + adapterRegistry(0), + adapterRegistryCat("AdapterRegistry"), + objectRegistry(0), + objectRegistryCat("ObjectRegistry"), + nodeRegistry(0), + nodeRegistryCat("NodeRegistry"), + logger(theLogger) +{ + const string nodeKeyBase = "IceGrid.Node.Trace."; + const_cast<int&>(server) = properties->getPropertyAsInt(nodeKeyBase + serverCat); + const_cast<int&>(adapter) = properties->getPropertyAsInt(nodeKeyBase + adapterCat); + const_cast<int&>(activator) = properties->getPropertyAsInt(nodeKeyBase + activatorCat); + + const string registryKeyBase = "IceGrid.Registry.Trace."; + const_cast<int&>(applicationRegistry) = properties->getPropertyAsInt(registryKeyBase + applicationRegistryCat); + const_cast<int&>(serverRegistry) = properties->getPropertyAsInt(registryKeyBase + serverRegistryCat); + const_cast<int&>(adapterRegistry) = properties->getPropertyAsInt(registryKeyBase + adapterRegistryCat); + const_cast<int&>(objectRegistry) = properties->getPropertyAsInt(registryKeyBase + objectRegistryCat); + const_cast<int&>(nodeRegistry) = properties->getPropertyAsInt(registryKeyBase + nodeRegistryCat); +} + +TraceLevels::~TraceLevels() +{ +} diff --git a/cpp/src/IceGrid/TraceLevels.h b/cpp/src/IceGrid/TraceLevels.h new file mode 100644 index 00000000000..c67692bd281 --- /dev/null +++ b/cpp/src/IceGrid/TraceLevels.h @@ -0,0 +1,58 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICE_GRID_TRACE_LEVELS_H +#define ICE_GRID_TRACE_LEVELS_H + +#include <IceUtil/Shared.h> +#include <Ice/PropertiesF.h> +#include <Ice/LoggerF.h> + +namespace IceGrid +{ + +class TraceLevels : public ::IceUtil::Shared +{ +public: + + TraceLevels(const ::Ice::PropertiesPtr&, const Ice::LoggerPtr&); + virtual ~TraceLevels(); + + const int server; + const char* serverCat; + + const int adapter; + const char* adapterCat; + + const int activator; + const char* activatorCat; + + const int applicationRegistry; + const char* applicationRegistryCat; + + const int serverRegistry; + const char* serverRegistryCat; + + const int adapterRegistry; + const char* adapterRegistryCat; + + const int objectRegistry; + const char* objectRegistryCat; + + const int nodeRegistry; + const char* nodeRegistryCat; + + const Ice::LoggerPtr logger; +}; + +typedef IceUtil::Handle<TraceLevels> TraceLevelsPtr; + +} // End namespace IceGrid + +#endif diff --git a/cpp/src/IceGrid/WaitQueue.cpp b/cpp/src/IceGrid/WaitQueue.cpp new file mode 100644 index 00000000000..9a4f3eb1a0c --- /dev/null +++ b/cpp/src/IceGrid/WaitQueue.cpp @@ -0,0 +1,204 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <Ice/Ice.h> +#include <IceGrid/WaitQueue.h> + +using namespace std; +using namespace IceGrid; + +WaitItem::WaitItem(const Ice::ObjectPtr& object) : + _object(object) +{ +} + +WaitItem::~WaitItem() +{ +} + +const IceUtil::Time& +WaitItem:: getExpirationTime() +{ + return _expiration; +} + +void +WaitItem::setExpirationTime(const IceUtil::Time& time) +{ + _expiration = time; +} + +WaitQueue::WaitQueue() : _destroyed(false) +{ +} + +void +WaitQueue::run() +{ + Lock sync(*this); + + while(true) + { + if(_waitQueue.empty() && _workQueue.empty() && !_destroyed) + { + wait(); + } + + if(!_workQueue.empty()) + { + // + // Execute all the work queue items. + // + for(list<WaitItemPtr>::iterator p = _workQueue.begin(); p != _workQueue.end(); ++p) + { + try + { + if(_destroyed) + { + (*p)->expired(true); + } + else + { + (*p)->execute(); + } + } + catch(...) + { + } + } + _workQueue.clear(); + } + + if(_destroyed) + { + break; + } + + if(!_waitQueue.empty()) + { + // + // Notify expired items. + // + while(!_waitQueue.empty()) + { + WaitItemPtr item = _waitQueue.front(); + + if(item->getExpirationTime() <= IceUtil::Time::now()) + { + try + { + item->expired(false); + } + catch(...) + { + } + _waitQueue.pop_front(); + } + else + { + // + // Wait until the next item expire or a notification. Note: in any case we + // get out of this loop to get a chance to execute the work queue. + // + timedWait(item->getExpirationTime() - IceUtil::Time::now()); + break; + } + } + } + } + + assert(_workQueue.empty()); + + if(!_waitQueue.empty()) + { + for(list<WaitItemPtr>::iterator p = _waitQueue.begin(); p != _waitQueue.end(); ++p) + { + (*p)->expired(true); + } + } +} + +void +WaitQueue::destroy() +{ + { + Lock sync(*this); + _destroyed = true; + notify(); + } + + getThreadControl().join(); +} + +void +WaitQueue::add(const WaitItemPtr& item, const IceUtil::Time& wait) +{ + Lock sync(*this); + + // + // We'll have to notify the thread if it's sleeping for good. + // + bool notifyThread = _workQueue.empty() && _waitQueue.empty(); + + if(wait == IceUtil::Time::seconds(0)) + { + item->setExpirationTime(IceUtil::Time::now()); + _workQueue.push_back(item); + } + else + { + IceUtil::Time expire = IceUtil::Time::now() + wait; + item->setExpirationTime(expire); + + list<WaitItemPtr>::iterator p = _waitQueue.begin(); + while(p != _waitQueue.end()) + { + if((*p)->getExpirationTime() >= expire) + { + break; + } + ++p; + } + _waitQueue.insert(p, item); + } + + if(notifyThread) + { + notify(); + } +} + +void +WaitQueue::notifyAllWaitingOn(const Ice::ObjectPtr& object) +{ + Lock sync(*this); + + // + // TODO: OPTIMIZATION: Use a map with the object as a key. + // + + list<WaitItemPtr>::iterator p = _waitQueue.begin(); + while(p != _waitQueue.end()) + { + if((*p)->isWaitingOn(object)) + { + _workQueue.push_back(*p); + p = _waitQueue.erase(p); + } + else + { + ++p; + } + } + + if(!_workQueue.empty()) + { + notify(); + } +} diff --git a/cpp/src/IceGrid/WaitQueue.h b/cpp/src/IceGrid/WaitQueue.h new file mode 100644 index 00000000000..f463c8051c2 --- /dev/null +++ b/cpp/src/IceGrid/WaitQueue.h @@ -0,0 +1,67 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICE_GRID_WAIT_QUEUE_H +#define ICE_GRID_WAIT_QUEUE_H + +#include <IceUtil/Thread.h> + +#include <list> + +namespace IceGrid +{ + +class WaitItem : public ::IceUtil::SimpleShared +{ +public: + + WaitItem(const Ice::ObjectPtr&); + virtual ~WaitItem(); + + virtual void execute() = 0; + virtual void expired(bool) = 0; + + bool isWaitingOn(const Ice::ObjectPtr& obj) { return obj == _object; } + + const IceUtil::Time& getExpirationTime(); + void setExpirationTime(const IceUtil::Time&); + +private: + + Ice::ObjectPtr _object; + IceUtil::Time _expiration; +}; + +typedef IceUtil::Handle<WaitItem> WaitItemPtr; + +class WaitQueue : public IceUtil::Thread, public IceUtil::Monitor< IceUtil::Mutex> +{ +public: + + WaitQueue(); + + virtual void run(); + void destroy(); + + void add(const WaitItemPtr&, const IceUtil::Time&); + + void notifyAllWaitingOn(const Ice::ObjectPtr&); + +private: + + std::list<WaitItemPtr> _waitQueue; + std::list<WaitItemPtr> _workQueue; + bool _destroyed; +}; + +typedef IceUtil::Handle<WaitQueue> WaitQueuePtr; + +} + +#endif diff --git a/cpp/src/IceGrid/dummy1.ice b/cpp/src/IceGrid/dummy1.ice new file mode 100755 index 00000000000..5b12cf78938 --- /dev/null +++ b/cpp/src/IceGrid/dummy1.ice @@ -0,0 +1,3 @@ +// +// This file is necessary to compile IdentityObjectDescDict under msdev. +// diff --git a/cpp/src/IceGrid/dummy2.ice b/cpp/src/IceGrid/dummy2.ice new file mode 100755 index 00000000000..2e6d4088952 --- /dev/null +++ b/cpp/src/IceGrid/dummy2.ice @@ -0,0 +1,3 @@ +// +// This file is necessary to compile StringObjectProxyDict under msdev. +// diff --git a/cpp/src/IceGrid/dummy3.ice b/cpp/src/IceGrid/dummy3.ice new file mode 100755 index 00000000000..46a7ad0cb73 --- /dev/null +++ b/cpp/src/IceGrid/dummy3.ice @@ -0,0 +1,3 @@ +// +// This file is necessary to compile StringObjectProxySeqDict under msdev. +// diff --git a/cpp/src/IceGrid/dummy4.ice b/cpp/src/IceGrid/dummy4.ice new file mode 100755 index 00000000000..c6622a8c14d --- /dev/null +++ b/cpp/src/IceGrid/dummy4.ice @@ -0,0 +1,3 @@ +// +// This file is necessary to compile StringStringSeqDict under msdev. +// diff --git a/cpp/src/IceGrid/dummy5.ice b/cpp/src/IceGrid/dummy5.ice new file mode 100755 index 00000000000..90fb6893379 --- /dev/null +++ b/cpp/src/IceGrid/dummy5.ice @@ -0,0 +1,3 @@ +// +// This file is necessary to compile StringServerDescriptorDict under msdev. +// diff --git a/cpp/src/IceGrid/icegrid.dsp b/cpp/src/IceGrid/icegrid.dsp new file mode 100644 index 00000000000..085438c8931 --- /dev/null +++ b/cpp/src/IceGrid/icegrid.dsp @@ -0,0 +1,270 @@ +# Microsoft Developer Studio Project File - Name="icegrid" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=icegrid - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "icegrid.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "icegrid.mak" CFG="icegrid - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "icegrid - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "icegrid - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "icegrid - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBRARY_EXPORTS" /Yu"stdafx.h" /FD /c
+# ADD CPP /nologo /MD /W3 /WX /GR /GX /O2 /I ".." /I "../../include" /D "_USRDLL" /D "ICE_GRID_API_EXPORTS" /D "NDEBUG" /D "_CONSOLE" /FD /c
+# SUBTRACT CPP /Fr /YX
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 /nologo /dll /incremental:yes /machine:I386 /out:"Release/icegrid21.dll" /implib:"Release/icegrid.lib"
+# SUBTRACT LINK32 /pdb:none /debug /nodefaultlib
+# Begin Special Build Tool
+OutDir=.\Release
+SOURCE="$(InputPath)"
+PostBuild_Cmds=copy $(OutDir)\icegrid.lib ..\..\lib copy $(OutDir)\icegrid21.dll ..\..\bin
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "icegrid - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBRARY_EXPORTS" /Yu"stdafx.h" /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /WX /Gm /GR /GX /Zi /Od /I ".." /I "../../include" /D "_USRDLL" /D "ICE_GRID_API_EXPORTS" /D "_DEBUG" /D "_CONSOLE" /FD /GZ /c
+# SUBTRACT CPP /Fr /YX
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386
+# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Debug/icegrid21d.dll" /implib:"Debug/icegridd.lib"
+# SUBTRACT LINK32 /pdb:none /incremental:no /nodefaultlib
+# Begin Special Build Tool
+OutDir=.\Debug
+SOURCE="$(InputPath)"
+PostBuild_Cmds=copy $(OutDir)\icegridd.lib ..\..\lib copy $(OutDir)\icegrid21d.pdb ..\..\bin copy $(OutDir)\icegrid21d.dll ..\..\bin
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "icegrid - Win32 Release"
+# Name "icegrid - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\Admin.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Exception.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Query.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=..\..\include\icegrid\Admin.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\icegrid\Exception.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\include\icegrid\Query.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=..\..\slice\icegrid\Admin.ice
+
+!IF "$(CFG)" == "icegrid - Win32 Release"
+
+USERDEP__ADMIN="..\..\bin\slice2cpp.exe" "..\..\lib\slice.lib"
+# Begin Custom Build
+InputPath=..\..\slice\icegrid\Admin.ice
+
+BuildCmds= \
+ ..\..\bin\slice2cpp.exe --ice --checksum --dll-export ICE_GRID_API --include-dir icegrid -I../../slice ../../slice/IceGrid/Admin.ice \
+ move Admin.h ..\..\include\icegrid \
+
+
+"..\..\include\icegrid\Admin.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"Admin.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "icegrid - Win32 Debug"
+
+USERDEP__ADMIN="..\..\bin\slice2cpp.exe" "..\..\lib\sliced.lib"
+# Begin Custom Build
+InputPath=..\..\slice\icegrid\Admin.ice
+
+BuildCmds= \
+ ..\..\bin\slice2cpp.exe --ice --checksum --dll-export ICE_GRID_API --include-dir icegrid -I../../slice ../../slice/IceGrid/Admin.ice \
+ move Admin.h ..\..\include\icegrid \
+
+
+"..\..\include\icegrid\Admin.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"Admin.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\slice\icegrid\Exception.ice
+
+!IF "$(CFG)" == "icegrid - Win32 Release"
+
+USERDEP__EXCEP="..\..\bin\slice2cpp.exe" "..\..\lib\slice.lib"
+# Begin Custom Build
+InputPath=..\..\slice\icegrid\Exception.ice
+
+BuildCmds= \
+ ..\..\bin\slice2cpp.exe --ice --checksum --dll-export ICE_GRID_API --include-dir icegrid -I../../slice ../../slice/IceGrid/Exception.ice \
+ move Exception.h ..\..\include\icegrid \
+
+
+"..\..\include\icegrid\Exception.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"Exception.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "icegrid - Win32 Debug"
+
+USERDEP__EXCEP="..\..\bin\slice2cpp.exe" "..\..\lib\sliced.lib"
+# Begin Custom Build
+InputPath=..\..\slice\icegrid\Exception.ice
+
+BuildCmds= \
+ ..\..\bin\slice2cpp.exe --ice --checksum --dll-export ICE_GRID_API --include-dir icegrid -I../../slice ../../slice/IceGrid/Exception.ice \
+ move Exception.h ..\..\include\icegrid \
+
+
+"..\..\include\icegrid\Exception.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"Exception.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\slice\icegrid\Query.ice
+
+!IF "$(CFG)" == "icegrid - Win32 Release"
+
+USERDEP__QUERY="..\..\bin\slice2cpp.exe" "..\..\lib\slice.lib"
+# Begin Custom Build
+InputPath=..\..\slice\icegrid\Query.ice
+
+BuildCmds= \
+ ..\..\bin\slice2cpp.exe --ice --checksum --dll-export ICE_GRID_API --include-dir icegrid -I../../slice ../../slice/IceGrid/Query.ice \
+ move Query.h ..\..\include\icegrid \
+
+
+"..\..\include\icegrid\Query.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"Query.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "icegrid - Win32 Debug"
+
+USERDEP__QUERY="..\..\bin\slice2cpp.exe" "..\..\lib\sliced.lib"
+# Begin Custom Build
+InputPath=..\..\slice\icegrid\Query.ice
+
+BuildCmds= \
+ ..\..\bin\slice2cpp.exe --ice --checksum --dll-export ICE_GRID_API --include-dir icegrid -I../../slice ../../slice/IceGrid/Query.ice \
+ move Query.h ..\..\include\icegrid \
+
+
+"..\..\include\icegrid\Query.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"Query.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/cpp/src/IceGrid/icegridC.dsp b/cpp/src/IceGrid/icegridC.dsp new file mode 100644 index 00000000000..5c04c18896e --- /dev/null +++ b/cpp/src/IceGrid/icegridC.dsp @@ -0,0 +1,224 @@ +# Microsoft Developer Studio Project File - Name="icegridC" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=icegridC - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "icegridC.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "icegridC.mak" CFG="icegridC - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "icegridC - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "icegridC - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "icegridC - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /WX /GR /GX /O2 /I ".." /I "../../include" /I "dummyinclude" /D "NDEBUG" /D "_CONSOLE" /FD /c
+# SUBTRACT CPP /Fr /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 setargv.obj /nologo /subsystem:console /incremental:yes /machine:I386 /out:"Release/icegridadmin.exe" /libpath:"../../../lib"
+# SUBTRACT LINK32 /debug /nodefaultlib
+# Begin Special Build Tool
+OutDir=.\Release
+TargetName=icegridadmin
+SOURCE="$(InputPath)"
+PostBuild_Cmds=copy $(OutDir)\$(TargetName).exe ..\..\bin
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "icegridC - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /WX /Gm /GR /GX /Zi /Od /I ".." /I "../../include" /I "dummyinclude" /D "_DEBUG" /D "_CONSOLE" /FD /GZ /c
+# SUBTRACT CPP /Fr /YX
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 setargv.obj /nologo /subsystem:console /debug /machine:I386 /out:"Debug/icegridadmin.exe" /pdbtype:sept /libpath:"../../../lib"
+# SUBTRACT LINK32 /incremental:no /nodefaultlib
+# Begin Special Build Tool
+OutDir=.\Debug
+TargetName=icegridadmin
+SOURCE="$(InputPath)"
+PostBuild_Cmds=copy $(OutDir)\$(TargetName).exe ..\..\bin
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "icegridC - Win32 Release"
+# Name "icegridC - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\Client.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\DescriptorParser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\DescriptorUtil.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\DescriptorVisitor.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Grammar.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Parser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Scanner.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\Grammar.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Parser.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=.\Grammar.y
+
+!IF "$(CFG)" == "icegridC - Win32 Release"
+
+# Begin Custom Build
+InputPath=.\Grammar.y
+
+BuildCmds= \
+ bison -dvt Grammar.y \
+ move Grammar.tab.c Grammar.cpp \
+ move Grammar.tab.h Grammar.h \
+
+
+"Grammar.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"Grammar.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "icegridC - Win32 Debug"
+
+# Begin Custom Build
+InputPath=.\Grammar.y
+
+BuildCmds= \
+ bison -dvt Grammar.y \
+ move Grammar.tab.c Grammar.cpp \
+ move Grammar.tab.h Grammar.h \
+
+
+"Grammar.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"Grammar.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\Scanner.l
+
+!IF "$(CFG)" == "icegridC - Win32 Release"
+
+# Begin Custom Build
+InputPath=.\Scanner.l
+
+"Scanner.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ flex Scanner.l
+ echo #include "IceUtil/Config.h" > Scanner.cpp
+ type lex.yy.c >> Scanner.cpp
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "icegridC - Win32 Debug"
+
+# Begin Custom Build
+InputPath=.\Scanner.l
+
+"Scanner.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ flex Scanner.l
+ echo #include "IceUtil/Config.h" > Scanner.cpp
+ type lex.yy.c >> Scanner.cpp
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/cpp/src/IceGrid/icegridnode.dsp b/cpp/src/IceGrid/icegridnode.dsp new file mode 100755 index 00000000000..0779e56d153 --- /dev/null +++ b/cpp/src/IceGrid/icegridnode.dsp @@ -0,0 +1,579 @@ +# Microsoft Developer Studio Project File - Name="icegridnode" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=icegridnode - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "icegridnode.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "icegridnode.mak" CFG="icegridnode - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "icegridnode - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "icegridnode - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "icegridnode - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /WX /GR /GX /O2 /I ".." /I "../../include" /I "dummyinclude" /D "NDEBUG" /D "_CONSOLE" /FD /c
+# SUBTRACT CPP /Fr /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 ws2_32.lib setargv.obj /nologo /subsystem:console /incremental:yes /machine:I386 /libpath:"../../../lib"
+# SUBTRACT LINK32 /debug /nodefaultlib
+# Begin Special Build Tool
+OutDir=.\Release
+TargetName=icegridnode
+SOURCE="$(InputPath)"
+PostBuild_Cmds=copy $(OutDir)\$(TargetName).exe ..\..\bin
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "icegridnode - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /WX /Gm /GR /GX /Zi /Od /I ".." /I "../../include" /I "dummyinclude" /D "_DEBUG" /D "_CONSOLE" /FD /GZ /c
+# SUBTRACT CPP /Fr /YX
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 ws2_32.lib setargv.obj /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"../../../lib"
+# SUBTRACT LINK32 /incremental:no /nodefaultlib
+# Begin Special Build Tool
+OutDir=.\Debug
+TargetName=icegridnode
+SOURCE="$(InputPath)"
+PostBuild_Cmds=copy $(OutDir)\$(TargetName).exe ..\..\bin
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "icegridnode - Win32 Release"
+# Name "icegridnode - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\Activator.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\AdapterFactory.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\AdapterI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\AdapterRegistryI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\AdminI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ApplicationRegistryI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\DescriptorParser.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\DescriptorUtil.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\DescriptorVisitor.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\icegridnode.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\IdentityObjectDescDict.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Internal.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LocatorI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LocatorRegistryI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\NodeI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\NodeRegistryI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ObjectRegistryI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\QueryI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Registry.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ServerAdapterI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ServerFactory.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ServerI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ServerRegistryI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\StringObjectProxyDict.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\StringObjectProxySeqDict.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\StringServerDescriptorDict.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\StringStringSeqDict.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\TraceLevels.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\WaitQueue.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\Activator.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ActivatorI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\AdapterFactory.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\AdapterI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\AdapterRegistryI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\AdminI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ApplicationBuilder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ComponentBuilder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\IdentityObjectDescDict.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Internal.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LocatorI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LocatorRegistryI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NodeI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NodeInfo.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NodeRegistryI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ObjectRegistryI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\QueryI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Registry.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ServerAdapterI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ServerBuilder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ServerDeployerI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ServerFactory.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ServerI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ServerRegistryI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ServiceBuilder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\StringObjectProxyDict.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\StringObjectProxySeqDict.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\TraceLevels.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\WaitQueue.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=.\dummy1.ice
+
+!IF "$(CFG)" == "icegridnode - Win32 Release"
+
+USERDEP__DUMMY="..\..\bin\slice2freeze.exe" "..\..\lib\slice.lib"
+# Begin Custom Build
+InputPath=.\dummy1.ice
+
+BuildCmds= \
+ ..\..\bin\slice2freeze.exe --ice --include-dir IceGrid -I../../slice -I.. --dict IceGrid::IdentityObjectDescDict,Ice::Identity,IceGrid::ObjectDescriptor IdentityObjectDescDict ../../slice/Ice/Identity.ice ../IceGrid/Internal.ice
+
+"IdentityObjectDescDict.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"IdentityObjectDescDict.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "icegridnode - Win32 Debug"
+
+USERDEP__DUMMY="..\..\bin\slice2freeze.exe" "..\..\lib\sliced.lib"
+# Begin Custom Build
+InputPath=.\dummy1.ice
+
+BuildCmds= \
+ ..\..\bin\slice2freeze.exe --ice --include-dir IceGrid -I../../slice -I.. --dict IceGrid::IdentityObjectDescDict,Ice::Identity,IceGrid::ObjectDescriptor IdentityObjectDescDict ../../slice/Ice/Identity.ice ../IceGrid/Internal.ice
+
+"IdentityObjectDescDict.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"IdentityObjectDescDict.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\dummy2.ice
+
+!IF "$(CFG)" == "icegridnode - Win32 Release"
+
+# Begin Custom Build
+InputPath=.\dummy2.ice
+
+BuildCmds= \
+ ..\..\bin\slice2freeze.exe --include-dir IceGrid --dict "IceGrid::StringObjectProxyDict,string,Object*" StringObjectProxyDict
+
+"StringObjectProxyDict.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"StringObjectProxyDict.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "icegridnode - Win32 Debug"
+
+USERDEP__DUMMY2="..\..\bin\slice2freeze.exe" "..\..\lib\sliced.lib"
+# Begin Custom Build
+InputPath=.\dummy2.ice
+
+BuildCmds= \
+ ..\..\bin\slice2freeze.exe --include-dir IceGrid --dict "IceGrid::StringObjectProxyDict,string,Object*" StringObjectProxyDict
+
+"StringObjectProxyDict.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"StringObjectProxyDict.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\dummy3.ice
+
+!IF "$(CFG)" == "icegridnode - Win32 Release"
+
+USERDEP__DUMMY3="..\..\bin\slice2freeze.exe" "..\..\lib\slice.lib"
+# Begin Custom Build
+InputPath=.\dummy3.ice
+
+BuildCmds= \
+ ..\..\bin\slice2freeze.exe --ice --include-dir IceGrid -I../../slice --dict IceGrid::StringObjectProxySeqDict,string,Ice::ObjectProxySeq StringObjectProxySeqDict ../../slice/Ice/BuiltinSequences.ice
+
+"StringObjectProxySeqDict.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"StringObjectProxySeqDict.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "icegridnode - Win32 Debug"
+
+USERDEP__DUMMY3="..\..\bin\slice2freeze.exe" "..\..\lib\sliced.lib"
+# Begin Custom Build
+InputPath=.\dummy3.ice
+
+BuildCmds= \
+ ..\..\bin\slice2freeze.exe --ice --include-dir IceGrid -I../../slice --dict IceGrid::StringObjectProxySeqDict,string,Ice::ObjectProxySeq StringObjectProxySeqDict ../../slice/Ice/BuiltinSequences.ice
+
+"StringObjectProxySeqDict.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"StringObjectProxySeqDict.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\dummy4.ice
+
+!IF "$(CFG)" == "icegridnode - Win32 Release"
+
+USERDEP__DUMMY4="..\..\bin\slice2freeze.exe" "..\..\lib\slice.lib"
+# Begin Custom Build
+InputPath=.\dummy4.ice
+
+BuildCmds= \
+ ..\..\bin\slice2freeze.exe --ice --include-dir IceGrid -I../../slice --dict IceGrid::StringStringSeqDict,string,Ice::StringSeq StringStringSeqDict ../../slice/Ice/BuiltinSequences.ice
+
+"StringStringSeqDict.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"StringStringSeqDict.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "icegridnode - Win32 Debug"
+
+USERDEP__DUMMY4="..\..\bin\slice2freeze.exe" "..\..\lib\sliced.lib"
+# Begin Custom Build
+InputPath=.\dummy4.ice
+
+BuildCmds= \
+ ..\..\bin\slice2freeze.exe --ice --include-dir IceGrid -I../../slice --dict IceGrid::StringStringSeqDict,string,Ice::StringSeq StringStringSeqDict ../../slice/Ice/BuiltinSequences.ice
+
+"StringStringSeqDict.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"StringStringSeqDict.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\dummy5.ice
+
+!IF "$(CFG)" == "icegridnode - Win32 Release"
+
+USERDEP__DUMMY5="..\..\bin\slice2freeze.exe" "..\..\lib\slice.lib"
+# Begin Custom Build
+InputPath=.\dummy5.ice
+
+BuildCmds= \
+ ..\..\bin\slice2freeze.exe --ice --include-dir IceGrid -I../../slice --dict IceGrid::StringServerDescriptorDict,string,IceGrid::ServerDescriptor StringServerDescriptorDict ../../slice/IceGrid/Admin.ice
+
+"StringServerDescriptorDict.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"StringServerDescriptorDict.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "icegridnode - Win32 Debug"
+
+USERDEP__DUMMY5="..\..\bin\slice2freeze.exe" "..\..\lib\sliced.lib"
+# Begin Custom Build
+InputPath=.\dummy5.ice
+
+BuildCmds= \
+ ..\..\bin\slice2freeze.exe --ice --include-dir IceGrid -I../../slice --dict IceGrid::StringServerDescriptorDict,string,IceGrid::ServerDescriptor StringServerDescriptorDict ../../slice/IceGrid/Admin.ice
+
+"StringServerDescriptorDict.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"StringServerDescriptorDict.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\Internal.ice
+
+!IF "$(CFG)" == "icegridnode - Win32 Release"
+
+USERDEP__INTER="..\..\bin\slice2cpp.exe" "..\..\lib\slice.lib"
+# Begin Custom Build
+InputPath=.\Internal.ice
+
+BuildCmds= \
+ ..\..\bin\slice2cpp.exe --ice --include-dir IceGrid -I../../slice Internal.ice
+
+"Internal.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"Internal.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "icegridnode - Win32 Debug"
+
+USERDEP__INTER="..\..\bin\slice2cpp.exe" "..\..\lib\sliced.lib"
+# Begin Custom Build
+InputPath=.\Internal.ice
+
+BuildCmds= \
+ ..\..\bin\slice2cpp.exe --ice --include-dir IceGrid -I../../slice Internal.ice
+
+"Internal.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"Internal.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/cpp/src/IceGrid/icegridregistry.dsp b/cpp/src/IceGrid/icegridregistry.dsp new file mode 100755 index 00000000000..86dd7dc03b7 --- /dev/null +++ b/cpp/src/IceGrid/icegridregistry.dsp @@ -0,0 +1,430 @@ +# Microsoft Developer Studio Project File - Name="icegridregistry" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=icegridregistry - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "icegridRegistry.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "icegridRegistry.mak" CFG="icegridregistry - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "icegridregistry - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "icegridregistry - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "icegridregistry - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /WX /GR /GX /O2 /I ".." /I "../../include" /I "dummyinclude" /D "NDEBUG" /D "_CONSOLE" /FD /c
+# SUBTRACT CPP /Fr /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 setargv.obj /nologo /subsystem:console /incremental:yes /machine:I386 /libpath:"../../../lib"
+# SUBTRACT LINK32 /debug /nodefaultlib
+# Begin Special Build Tool
+OutDir=.\Release
+TargetName=icegridRegistry
+SOURCE="$(InputPath)"
+PostBuild_Cmds=copy $(OutDir)\$(TargetName).exe ..\..\bin
+# End Special Build Tool
+
+!ELSEIF "$(CFG)" == "icegridregistry - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /WX /Gm /GR /GX /Zi /Od /I ".." /I "../../include" /I "dummyinclude" /D "_DEBUG" /D "_CONSOLE" /FD /GZ /c
+# SUBTRACT CPP /Fr /YX
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 setargv.obj /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"../../../lib"
+# SUBTRACT LINK32 /incremental:no /nodefaultlib
+# Begin Special Build Tool
+OutDir=.\Debug
+TargetName=icegridRegistry
+SOURCE="$(InputPath)"
+PostBuild_Cmds=copy $(OutDir)\$(TargetName).exe ..\..\bin
+# End Special Build Tool
+
+!ENDIF
+
+# Begin Target
+
+# Name "icegridregistry - Win32 Release"
+# Name "icegridregistry - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\AdapterFactory.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\AdapterI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\AdapterRegistryI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\AdminI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ApplicationRegistryI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\DescriptorUtil.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\DescriptorVisitor.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\icegridregistry.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\IdentityObjectDescDict.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Internal.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LocatorI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\LocatorRegistryI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\NodeRegistryI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ObjectRegistryI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\QueryI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\Registry.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ServerRegistryI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\StringObjectProxyDict.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\StringObjectProxySeqDict.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\StringServerDescriptorDict.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\StringStringSeqDict.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\TraceLevels.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\AdapterFactory.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\AdapterI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\AdapterRegistryI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\AdminI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ApplicationBuilder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ComponentBuilder.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\IdentityObjectDescDict.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Internal.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LocatorI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\LocatorRegistryI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\NodeRegistryI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ObjectRegistryI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\QueryI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Registry.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ServerRegistryI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\StringObjectProxyDict.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\StringObjectProxySeqDict.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\TraceLevels.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=.\dummy1.ice
+
+!IF "$(CFG)" == "icegridregistry - Win32 Release"
+
+USERDEP__DUMMY="..\..\bin\slice2freeze.exe" "..\..\lib\slice.lib"
+# Begin Custom Build
+InputPath=.\dummy1.ice
+
+BuildCmds= \
+ ..\..\bin\slice2freeze.exe --ice --include-dir IceGrid -I../../slice -I.. --dict IceGrid::IdentityObjectDescDict,Ice::Identity,IceGrid::ObjectDescriptor IdentityObjectDescDict ../../slice/Ice/Identity.ice ../IceGrid/Internal.ice
+
+"IdentityObjectDescDict.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"IdentityObjectDescDict.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "icegridregistry - Win32 Debug"
+
+USERDEP__DUMMY="..\..\bin\slice2freeze.exe" "..\..\lib\sliced.lib"
+# Begin Custom Build
+InputPath=.\dummy1.ice
+
+BuildCmds= \
+ ..\..\bin\slice2freeze.exe --ice --include-dir IceGrid -I../../slice -I.. --dict IceGrid::IdentityObjectDescDict,Ice::Identity,IceGrid::ObjectDescriptor IdentityObjectDescDict ../../slice/Ice/Identity.ice ../IceGrid/Internal.ice
+
+"IdentityObjectDescDict.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"IdentityObjectDescDict.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\dummy2.ice
+
+!IF "$(CFG)" == "icegridregistry - Win32 Release"
+
+USERDEP__DUMMY2="..\..\bin\slice2freeze.exe" "..\..\lib\slice.lib"
+# Begin Custom Build
+InputPath=.\dummy2.ice
+
+BuildCmds= \
+ ..\..\bin\slice2freeze.exe --include-dir IceGrid --dict "IceGrid::StringObjectProxyDict,string,Object*" StringObjectProxyDict
+
+"StringObjectProxyDict.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"StringObjectProxyDict.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "icegridregistry - Win32 Debug"
+
+USERDEP__DUMMY2="..\..\bin\slice2freeze.exe" "..\..\lib\sliced.lib"
+# Begin Custom Build
+InputPath=.\dummy2.ice
+
+BuildCmds= \
+ ..\..\bin\slice2freeze.exe --include-dir IceGrid --dict "IceGrid::StringObjectProxyDict,string,Object*" StringObjectProxyDict
+
+"StringObjectProxyDict.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"StringObjectProxyDict.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\dummy3.ice
+
+!IF "$(CFG)" == "icegridregistry - Win32 Release"
+
+USERDEP__DUMMY3="..\..\bin\slice2freeze.exe" "..\..\lib\slice.lib"
+# Begin Custom Build
+InputPath=.\dummy3.ice
+
+BuildCmds= \
+ ..\..\bin\slice2freeze.exe --ice --include-dir IceGrid -I../../slice --dict IceGrid::StringObjectProxySeqDict,string,Ice::ObjectProxySeq StringObjectProxySeqDict ../../slice/Ice/BuiltinSequences.ice
+
+"StringObjectProxySeqDict.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"StringObjectProxySeqDict.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "icegridregistry - Win32 Debug"
+
+USERDEP__DUMMY3="..\..\bin\slice2freeze.exe" "..\..\lib\sliced.lib"
+# Begin Custom Build
+InputPath=.\dummy3.ice
+
+BuildCmds= \
+ ..\..\bin\slice2freeze.exe --ice --include-dir IceGrid -I../../slice --dict IceGrid::StringObjectProxySeqDict,string,Ice::ObjectProxySeq StringObjectProxySeqDict ../../slice/Ice/BuiltinSequences.ice
+
+"StringObjectProxySeqDict.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"StringObjectProxySeqDict.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\Internal.ice
+
+!IF "$(CFG)" == "icegridregistry - Win32 Release"
+
+USERDEP__INTER="..\..\bin\slice2cpp.exe" "..\..\lib\slice.lib"
+# Begin Custom Build
+InputPath=.\Internal.ice
+
+BuildCmds= \
+ ..\..\bin\slice2cpp.exe --ice --include-dir IceGrid -I../../slice -I.. Internal.ice
+
+".\Internal.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"Internal.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "icegridregistry - Win32 Debug"
+
+USERDEP__INTER="..\..\bin\slice2cpp.exe" "..\..\lib\sliced.lib"
+# Begin Custom Build
+InputPath=.\Internal.ice
+
+BuildCmds= \
+ ..\..\bin\slice2cpp.exe --ice --include-dir IceGrid -I../../slice -I.. Internal.ice
+
+".\Internal.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+
+"Internal.cpp" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ $(BuildCmds)
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# End Group
+# End Target
+# End Project
|