/******************************************************************************* * e.S.O. - ACS project * * "@(#) $Id: maciContainerImpl.cpp,v 1.150 2012/10/15 13:50:00 bjeram Exp $" * * who when what * -------- --------- ---------------------------------------------- * msekoran 2003-05-22 turned into multi-threaded server * bjeram 2002-11-26 removed ccsInit/Exit from xxThread * msekoran 2002-09-23 full multi-threaded support * msekoran 2002-09-17 new CDB * bjeram 2002-08-30 copy comand line options be4 DB initalization (for new CDB) * bjeram 2002-06-27 Waiting for m_handle in get_object * bgustafs 2002-04-15 corrected shutdown action * jib/blo 2002-04-02 get_object method added. * msekoran 2002-03-03 ACSError::init() added. * bgustafs 2002-02-08 changed task name of VxWorks task * msekoran 2002-02-07 Even move improoved desctruction. * msekoran 2002-02-02 Improoved desctruction. * gchiozzi 2002-01-30 Added ccsInit to initThread and ccsExit to doneThread * msekoran 2001-12-25 cleaned, reconnect, IFR resolving * msekoran 2001-12-24 initialization added * msekoran 2001-09-21 Fixed IFR handling, autogenerated IFR ORBInitRef and ORBEndpoint * msekoran 2001-09-10 Added additional ORB endpoint initialization checking. * almamgr 2001-07-23 Added getManager() method and init of m_manager in constructor * almamgr 2001-07-19 Moved here include of maciLibraryManager.h and maciServantManager.h * msekoran 2001/05/19 redesigned * msekoran 2001/02/21 created */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef MAKE_VXWORKS #include #endif /* #ifdef MAKE_VXWORKS #include #endif */ #include #include #include #include #include #include #include /// @todo Alarm System is not yet supported for VxWorks #ifndef MAKE_VXWORKS #include #endif using namespace maci; using namespace cdb; // static public vars ContainerImpl * ContainerImpl::m_container = 0; LoggingProxy * ContainerImpl::m_loggerProxy = 0; LibraryManager * ContainerImpl::m_dllmgr = 0; int ContainerImpl::m_logLevelRefresh = CDB_LOG_LEVEL; int ContainerImpl::m_logLevelConfigure = CDB_LOG_LEVEL; CORBA::ULong ContainerImpl::m_invocationTimeout = 15000; // in milliseconds; 15s // ************************************************************************ class ActivationMethod : public ACE_Method_Request, public Logging::Loggable { public: ActivationMethod ( ContainerImpl* container, maci::Handle h, maci::ExecutionId execution_id, const char * name, const char * exe, const char * type, maci::CBComponentInfo_ptr cb, const ACS::CBDescIn& descIn) : Logging::Loggable("Container-ActivationMethod"), container_(container), h_(h), execution_id_(execution_id), name_(name), exe_(exe), type_(type), cb_(maci::CBComponentInfo::_duplicate(cb)), descOut_() { ACS_TRACE ("maci::ActivationMethod::ActivationMethod"); descOut_.id_tag = descIn.id_tag; } virtual int call (void) { ACS_TRACE ("maci::ActivationMethod::call"); char buf[256]; ACE_OS::snprintf(buf, 256, "Async. activation of component %s with descOut.id_tag = %d has started.", name_.c_str(), descOut_.id_tag); ACS_DEBUG_PARAM ("maci::ActivationMethod::call", "%s", buf); maci::ComponentInfo_var componentInfo; ACSErr::Completion completion = ACSErrTypeOK::ACSErrOKCompletion(); try { componentInfo = container_->activate_component(h_, execution_id_, name_.c_str(), exe_.c_str(), type_.c_str()); } catch (maciErrType::CannotActivateComponentEx &_ex) { maciErrType::CannotActivateComponentExImpl exImpl(_ex); completion = maciErrType::CannotActivateComponentCompletion(exImpl, __FILE__, __LINE__, "maci::ActivationMethod::call"); } catch (ACSErr::ACSbaseExImpl &_ex) { completion = maciErrType::CannotActivateComponentCompletion(_ex, __FILE__, __LINE__, "maci::ActivationMethod::call"); } catch (...) { ACSErrTypeCommon::UnexpectedExceptionExImpl uex(__FILE__, __LINE__, "maci::ActivationMethod::call"); completion = maciErrType::CannotActivateComponentCompletion(uex, __FILE__, __LINE__, "maci::ActivationMethod::call"); } // in case of an error, we need to create valid ComponentInfo if (!componentInfo.ptr()) { componentInfo = new maci::ComponentInfo(); componentInfo->h = h_; componentInfo->reference = CORBA::Object::_nil(); componentInfo->name = CORBA::string_dup(name_.c_str()); componentInfo->type = CORBA::string_dup(type_.c_str()); componentInfo->code = CORBA::string_dup(exe_.c_str()); componentInfo->container_name = CORBA::string_dup("unspecified"); componentInfo->container = 0; componentInfo->access = 0; componentInfo->interfaces.length(0); } const int tries = 3; int tryNo = 0; while (true) { tryNo++; try { ACS_DEBUG_PARAM ("maci::ActivationMethod::call", "Calling maci::CBComponentInfo::done with descOut.id_tag = %d.", descOut_.id_tag); cb_->done(*componentInfo, completion, descOut_); ACS_DEBUG_PARAM ("maci::ActivationMethod::call", "Call to maci::CBComponentInfo::done with descOut.id_tag = %d completed.", descOut_.id_tag); } catch( CORBA::SystemException &_ex ) { ACSErrTypeCommon::CORBAProblemExImpl corbaProblemEx(__FILE__, __LINE__, "maci::ActivationMethod::call"); corbaProblemEx.setMinor(_ex.minor()); corbaProblemEx.setCompletionStatus(_ex.completed()); corbaProblemEx.setInfo(_ex._info().c_str()); maciErrType::CannotReleaseComponentExImpl ex(corbaProblemEx, __FILE__, __LINE__, "maci::ActivationMethod::call"); corbaProblemEx.log(); // retry in case of COMM_FAILURE or TIMEOUT if (tryNo < tries && (ACE_OS::strstr(_ex._info().c_str(), "IDL:omg.org/CORBA/COMM_FAILURE:1.0") || ACE_OS::strstr(_ex._info().c_str(), "IDL:omg.org/CORBA/TIMEOUT:1.0") || ACE_OS::strstr(_ex._info().c_str(), "IDL:omg.org/CORBA/TRANSIENT:1.0")) ) { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ActivationMethod::call", (LM_WARNING, "Call to maci::CBComponentInfo::done for component %s with descOut.id_tag = %d failed with %s, retrying...", name_.c_str(), descOut_.id_tag, _ex._rep_id())); // sleep for a second ACE_OS::sleep(1); continue; } ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ActivationMethod::call", (LM_WARNING, "Call to maci::CBComponentInfo::done for component %s with descOut.id_tag = %d failed with %s, deactivating the component.", name_.c_str(), descOut_.id_tag, _ex._rep_id())); try { container_->deactivate_component(h_); } catch (maciErrType::CannotDeactivateComponentEx &ex) { maciErrType::CannotDeactivateComponentExImpl lex(ex, __FILE__, __LINE__, "maci::ActivationMethod::call"); lex.log(); } catch (maciErrType::ComponentDeactivationUncleanEx &ex) { maciErrType::ComponentDeactivationUncleanExImpl lex(ex, __FILE__, __LINE__, "maci::ActivationMethod::call"); lex.log(); } catch (maciErrType::ComponentDeactivationFailedEx &ex) { maciErrType::ComponentDeactivationFailedExImpl lex(ex, __FILE__, __LINE__, "maci::ActivationMethod::call"); lex.log(); } } catch(...) { ACSErrTypeCommon::UnknownExImpl uex(__FILE__, __LINE__, "maci::ActivationMethod::call"); uex.log(); } break; } return 0; } private: ContainerImpl* container_; maci::Handle h_; maci::ExecutionId execution_id_; ACE_CString name_; ACE_CString exe_; ACE_CString type_; maci::CBComponentInfo_var cb_; ACS::CBDescOut descOut_; };//class ActivationMethod class ExitMethod : public ACE_Method_Request { public: virtual int call (void) { // Cause exit. return -1; } };//class ExitMethod MethodRequestThreadPool::MethodRequestThreadPool (int n_threads) : Logging::Loggable("Container-MethodRequestThreadPool"), m_threads(n_threads) { ACS_TRACE ("maci::MethodRequestThreadPool::MethodRequestThreadPool"); this->activate (THR_NEW_LWP|THR_JOINABLE|THR_INHERIT_SCHED, n_threads); } int MethodRequestThreadPool::svc (void) { LoggingProxy *logger = maci::ContainerImpl::getLoggerProxy(); if (logger!=0) { char *contName = ContainerImpl::getContainer()->name(); // in some threads the logging will be initialized two times what is not harmful LoggingProxy::init(logger); LoggingProxy::ProcessName(contName); CORBA::string_free(contName); } ACS_TRACE ("maci::MethodRequestThreadPool::svc"); while (1) { // Dequeue the next method object auto_ptr request (this->activation_queue_.dequeue ()); // Invoke the method request. if (request->call () == -1) break; } return 0; } int MethodRequestThreadPool::enqueue (ACE_Method_Request *request) { ACS_TRACE ("maci::MethodRequestThreadPool::enqueue"); return this->activation_queue_.enqueue (request); } void MethodRequestThreadPool::shutdown() { for (int i = 0; i < m_threads; i++) this->enqueue (new ExitMethod ()); // might do better implementation while (!this->activation_queue_.is_empty()) { ACE_OS::sleep(1); } } // ************************************************************************ ContainerImpl::ContainerImpl() : m_manager(maci::Manager::_nil()), m_handle(0), m_status(0), m_shutdown(false), m_argc(0), m_shutdownAction(0), m_hasIFR(false), m_recovery(true), m_shutdownDone(m_shutdownMutex), m_shutdownDoneSignaled(false), m_serverThreads(5), m_dynamicContainer(false), m_containerServices(0), m_logger(0), m_executionId(0), m_startTime(::getTimeStamp()), //logging stuff cacheSize(5U), minCachePriority(0), maxCachePriority (LM_MAX_PRIORITY), flushPeriodSeconds(10), maxLogsPerSecond(-1), m_methodRequestThreadPool(0) { orb = CORBA::ORB::_nil(); poaManager = PortableServer::POAManager::_nil(); poaRoot = poaContainer = poaPersistent = poaTransient = PortableServer::POA::_nil(); m_pid_file_name = 0; m_manager_ref = 0; m_container_name = 0; m_servant_mgr = 0; m_database = 0; m_argv = 0; // initialize ACE logger instance ACE_TCHAR hostname[33]; ACE_OS::hostname (hostname, sizeof(hostname)); ACE_Log_Msg::instance()->local_host(hostname); // initialize default log levels m_defaultLogLevels.minLogLevel = 2; m_defaultLogLevels.minLogLevelLocal = 2; m_defaultLogLevels.useDefault = true; // singleton check if (m_container) { // since ContainerImpl is a singleton, refuse to create another instance // exception aware compiler is required throw CORBA::IMP_LIMIT(); } else m_container = this; } // ************************************************************************ ContainerImpl::~ContainerImpl() { #ifndef MAKE_VXWORKS if (m_logThrottleAlarm_p!=NULL && m_loggerProxy!=NULL) { m_loggerProxy->setAlarmSender(m_logThrottleAlarm_p); delete m_logThrottleAlarm_p; } #endif if (getLogger() != 0) // we have to check if logger is there. .... { // ....It can happened that Container is just created w/o using init method where the logger is "created" ACS_TRACE("maci::ContainerImpl::~ContainerImpl"); } m_container = 0; if (m_methodRequestThreadPool) delete m_methodRequestThreadPool; if (m_dllmgr){ m_dllmgr->closeAllLibraries(); delete m_dllmgr; m_dllmgr = 0; } if (m_containerServices) delete m_containerServices; if (ContainerImpl::getLoggerProxy()) { ContainerImpl::getLoggerProxy()->flush(); ContainerImpl::getLoggerProxy()->done(); }//if if (m_argv) { for (int i=0; iresolve_initial_references("RootPOA"); poaRoot = PortableServer::POA::_narrow(objRootPOA.in()); if (CORBA::is_nil(poaRoot.ptr())) return false; // Get the manager of the root POA to apply to the child POAs. /*PortableServer::POAManager_var*/ poaManager = poaRoot->the_POAManager(); // // Prepare policies our POAs will be using. // PortableServer::IdAssignmentPolicy_var user_id_policy = poaRoot->create_id_assignment_policy(PortableServer::USER_ID); PortableServer::LifespanPolicy_var persistent_policy = poaRoot->create_lifespan_policy(PortableServer::PERSISTENT); PortableServer::RequestProcessingPolicy_var user_servant_manager_policy = poaRoot->create_request_processing_policy (PortableServer::USE_SERVANT_MANAGER); PortableServer::ServantRetentionPolicy_var servant_retention_policy = poaRoot->create_servant_retention_policy (PortableServer::RETAIN); // // Container (using persistent servant-manager) POA // CORBA::PolicyList policies; poaTransient = poaRoot->create_POA("TransientPOA", poaManager.in(), policies); if (CORBA::is_nil(poaTransient.ptr())) { return false; } policies.length(4); policies[0] = PortableServer::LifespanPolicy::_duplicate(persistent_policy.in()); policies[1] = PortableServer::IdAssignmentPolicy::_duplicate(user_id_policy.in()); policies[2] = PortableServer::ServantRetentionPolicy::_duplicate(servant_retention_policy.in()); policies[3] = PortableServer::RequestProcessingPolicy::_duplicate(user_servant_manager_policy.in()); poaContainer = poaRoot->create_POA("ServantManagerPOA", poaManager.in(), policies); if (CORBA::is_nil(poaContainer.ptr())) return false; ACS_NEW_RETURN(m_servant_mgr, MACIServantManager(), false); PortableServer::ServantActivator_var servant_activator = m_servant_mgr; poaContainer->set_servant_manager(servant_activator.in()); // // Persistent POA // policies.length(3); poaPersistent = poaRoot->create_POA("PersistentPOA", poaManager.in(), policies); if (CORBA::is_nil(poaPersistent.ptr())) return false; // We're done using the policies. user_id_policy->destroy(); persistent_policy->destroy(); user_servant_manager_policy->destroy(); servant_retention_policy->destroy(); if (ContainerImpl::m_invocationTimeout) { // // Set time-out for all invocations // CORBA::Object_var current_object = orb->resolve_initial_references ("ORBPolicyManager"); // ORB policy // orb->resolve_initial_references ("PolicyCurrent"); // Current thread policy CORBA::PolicyManager_var policy_current = CORBA::PolicyManager::_narrow (current_object.in ()); // CORBA::PolicyCurrent_var policy_current = // CORBA::PolicyCurrent::_narrow (current_object.in ()); TimeBase::TimeT timeout = ContainerImpl::m_invocationTimeout; timeout *= 10000; // convert to ns CORBA::Any any_object; any_object <<= timeout; policies.length (1); policies[0] = orb->create_policy (Messaging::RELATIVE_RT_TIMEOUT_POLICY_TYPE, any_object ); policy_current->set_policy_overrides (policies, CORBA::SET_OVERRIDE); policies[0]->destroy (); } // POA Manager can start processing incoming requests. poaManager->activate(); } catch (CORBA::BAD_PARAM &badex) { if (badex.minor() == CORBA::SystemException::_tao_minor_code (TAO_ACCEPTOR_REGISTRY_OPEN_LOCATION_CODE, EINVAL)) { ACS_LOG(0, "maci::ContainerImpl::initalizeCORBA", (LM_INFO, "Failed to bind to specified endpoint - wrong ORB endpoint specification or port already used.")); ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::initalizeCORBA", (LM_ERROR, "Failed to bind to specified endpoint - wrong ORB endpoint specification or port already used.")); } badex._tao_print_exception( "maci::ContainerImpl::initalizeCORBA"); return false; } catch( CORBA::Exception &ex ) { ex._tao_print_exception( "maci::ContainerImpl::initalizeCORBA"); return false; } catch(...) { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::Container::initializeCORBA", (LM_ERROR, "Unexpected exception caught while initializing CORBA")); return false; } return true; } // ************************************************************************ bool ContainerImpl::doneCORBA() { ACS_TRACE("maci::ContainerImpl::doneCORBA"); try { if(poaRoot.ptr() != PortableServer::POA::_nil()) { // destroy(etherealize_objects, wait_for_completion) // this also destroys other POAs poaRoot->destroy(1, 1); } if(orb.ptr() != CORBA::ORB::_nil()) { orb->destroy(); } } catch( CORBA::Exception &ex ) { ex._tao_print_exception("maci::ContainerImpl::doneCORBA) Unexpected exception occured while destroying CORBA"); } catch(...) { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::Container::doneCORBA", (LM_ERROR, "Unexpected exception caught while destroying CORBA")); } return true; } // ************************************************************************ int ContainerImpl::parseArgs (int argc, char *argv[]) { //ACS_TRACE("maci::ContainerImpl::parseArgs"); // use trick to handle extra container name parameter // so that get_opts() will work ACE_Get_Opt get_opts (argc, &argv[1], "dDrnp:m:b:"); bool usageAlreadyShown = false; int c; while ((c = get_opts ()) != -1) switch (c) { // used by CDB DAL access -d //case 'd': // debug flag. //TAO_debug_level++; //break; case 'd': // -d case 'D': // -DA[L|O]<...> options break; case 'b': // -d ACS_INSTANCE select break; case 'r': // recovery switch this->m_recovery = true; ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::parseArgs", (LM_INFO, "Recovery mode enabled via command line.")); break; case 'n': // recovery switch this->m_recovery = false; ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::parseArgs", (LM_INFO, "Recovery mode disabled via command line.")); break; #ifndef ACS_HAS_WIN32 case 'p': this->m_pid_file_name = get_opts.optarg; break; #endif case 'm': this->m_manager_ref = get_opts.optarg; break; case '?': default: if (!usageAlreadyShown) { showUsage(argc, argv); usageAlreadyShown=true; } } return 0; } // ************************************************************************ void ContainerImpl::showUsage(int argc, char *argv[]) { ACE_UNUSED_ARG(argc); ACE_OS::printf("Usage: %s \n\t(e.g. %s Container)\n", argv[0], argv[0]); ACE_OS::printf ("Options:\n" "\t-d \tuse given DAL reference\n" "\t-DALReference \tuse given DAL reference\n" "\t-r\t\t\trun Container in recovery mode (default)\n" "\t-n\t\t\trun Container in non-recovery mode\n" "\t-m \tuse given Manager reference\n" #ifndef ACS_HAS_WIN32 "\t-p \twrite process id to file\n" #endif "\n"); } // ************************************************************************ bool ContainerImpl::init(int argc, char *argv[]) { //ACS_TRACE("maci::ContainerImpl::init"); Logging::Logger::setConfigureLoggerFunction(ContainerImpl::configureLogger); try { ACE_OS::printf("%s\n", ::maci::Container::ContainerStatusStartupBeginMsg); // At least one command-line argument is expected: the name of the // Container. It must be the first argument in the command-line. if (argc<2 || argv[1][0]=='-') { showUsage(argc, argv); ACS_CHECK_LOGGER; m_logger = getNamedLogger("Undefined"); return false; } m_container_name = argv[1]; ACS_CHECK_LOGGER; m_logger = getNamedLogger(m_container_name); // here we set container global logger std::string containerGlobalLoggerName=m_container_name; containerGlobalLoggerName+="-GL"; Logging::Logger::setGlobalLogger(getNamedLogger(containerGlobalLoggerName)); // here we set container static logger std::string containerStaticLoggerName=m_container_name; containerStaticLoggerName+="-Static"; Logging::Logger::setStaticLogger(getNamedLogger(containerStaticLoggerName)); // store command line options // preallocate 512 chars ACE_CString strCmdLn(size_t(512)); for (int i=argc-1; i>=0; i--) strCmdLn = ACE_CString(argv[i])+ " " + strCmdLn; // if there is not command line parameters for DAL, query manager... maci::Manager_var manager; CORBA::ORB_var cdbORB; CDB::DAL_var cdbDAL; if (strCmdLn.find("-d") == ACE_CString::npos && strCmdLn.find("-DALReference") == ACE_CString::npos) { try { ACS_DEBUG("maci::ContainerImpl::init", "Retrieving CDB reference from Manager using bootstrap ORB"); // Creates local copy of command line arguments, making sure // that no ORBEndpoint option is used for this bootstrap ORB. // In this way a free port is automatically selected. ACE_ARGV cdbBootstrapArgv; for (int i=0; iget_service(0, "CDB", true); if (!CORBA::is_nil(cdb.in())) { cdbDAL = CDB::DAL::_narrow(cdb.in()); DALaccess::forceDAL(cdbDAL.in()); } } } catch( CORBA::Exception &ex ) { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::init", (LM_DEBUG, "Failed to retrieve CDB referece.")); } } // // create and initialize DB // m_dbPrefix = ACE_CString(":Appl_data:MACI:Containers:")+m_container_name; m_dbRootPrefix = ":Appl_data:MACI"; m_database = getDatabase(argc, argv, cdbORB.in()); if (!m_database || !m_database->isInitialized()) { ACS_SHORT_LOG((LM_INFO, "Unable to open database")); // No logger initialized yet // ACS_LOG(LM_RUNTIME_CONTEXT, "maci::Container::init", (LM_ERROR, "Unable to open database")); return false; } // // create and initialize logger // Field fld; CORBA::ULong ul; if (!m_dynamicContainer && m_database->GetField(m_dbPrefix, "LoggingConfig/dispatchPacketSize", fld)) { if (fld.GetULong(ul)) cacheSize = ul; } // check if container configuration else { ACS_SHORT_LOG((LM_INFO, "Configuration information for container '%s' not available.", m_container_name)); m_dynamicContainer = true; } if (!m_dynamicContainer && m_database->GetField(m_dbPrefix, "LoggingConfig/minLogLevel", fld)) { if (fld.GetULong(ul)) minCachePriority = ul; } if (!m_dynamicContainer && m_database->GetField(m_dbPrefix, "LoggingConfig/immediateDispatchLevel", fld)) { if (fld.GetULong(ul)) maxCachePriority = ul; } if (!m_dynamicContainer && m_database->GetField(m_dbPrefix, "LoggingConfig/flushPeriodSeconds", fld)) { if (fld.GetULong(ul)) flushPeriodSeconds = static_cast(ul); } int maxLogsPerSecond = -1; if (!m_dynamicContainer && m_database->GetField(m_dbPrefix, "LoggingConfig/maxLogsPerSecond", fld)) { ::CORBA::Long l; if (fld.GetLong(l)) maxLogsPerSecond = static_cast(l); } m_loggerProxy = new LoggingProxy(cacheSize, minCachePriority, maxCachePriority, 0, 0, flushPeriodSeconds, maxLogsPerSecond); if (!m_loggerProxy) ACS_SHORT_LOG((LM_WARNING, "Unable to create logging system. Using 'stdout'...")); m_logLevelRefresh = CDB_LOG_LEVEL; int envStdioPriority = -1; int envCentralizePriority = -1; char *acsSTDIO = getenv("ACS_LOG_STDOUT"); if (acsSTDIO && *acsSTDIO) { envStdioPriority = atoi(acsSTDIO); } if (envStdioPriority >= 0 && envStdioPriority <=11 ) m_defaultLogLevels.minLogLevelLocal = envStdioPriority; char *acsCentralizeLogger = getenv("ACS_LOG_CENTRAL"); if (acsCentralizeLogger && *acsCentralizeLogger) { envCentralizePriority = atoi(acsCentralizeLogger); } if(envCentralizePriority >= 0 && envCentralizePriority <=11 ) m_defaultLogLevels.minLogLevel = envCentralizePriority; if (m_dynamicContainer) { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::Container::init", (LM_INFO, "Starting as dynamic container.")); } else { // setup loggers refresh_logging_config(); } m_logLevelRefresh = CDB_REFRESH_LOG_LEVEL; // // setup DLL manager // ACS_NEW_RETURN(m_dllmgr, LibraryManager, false); // // "fix" command line // // get command line options from the local database. // @TODO Now that Container.CommandLine is gone, we need to read this data from Container.DeployInfo.Flags ! // ACE_CString strCmdLnDB(""); // if (!m_dynamicContainer && m_database->GetField(m_dbPrefix, "CommandLine", fld)) // fld.GetString(strCmdLnDB); // // strCmdLn += strCmdLnDB; ACE_OS::printf("%s\n", ::maci::Container::ContainerStatusORBInitBeginMsg); //get the default C++ Container port std::ostringstream containerOutput; containerOutput << std::setw(4) << std::setfill('0') << (ACSPorts::getBasePort()*100 + 3000 + 50) << std::ends; // enable ORBDottedDecimalAddresses option if (strCmdLn.find("-ORBDottedDecimalAddresses")==ACE_CString::npos) strCmdLn += " -ORBDottedDecimalAddresses 1"; // add defaut Container's endpoint if no other specified if (strCmdLn.find("-ORBEndpoint")==ACE_CString::npos) { const char* hostname = ACSPorts::getIP(); strCmdLn += " -ORBEndpoint iiop://"; strCmdLn += hostname; strCmdLn += ":"; strCmdLn += containerOutput.str().c_str(); } // add local IFR address if no other specified if (strCmdLn.find("-ORBInitRef InterfaceRepository")==ACE_CString::npos) { ACE_CString managerHostname = MACIHelper::getManagerHostname(argc, argv); if (managerHostname.length()>0) { strCmdLn += " -ORBInitRef InterfaceRepository=corbaloc::"; strCmdLn += managerHostname; strCmdLn += ":"; strCmdLn += ACSPorts::getIRPort().c_str(); strCmdLn += "/InterfaceRepository"; } } // split command line string to array int targc = m_argc; ACE_OS::string_to_argv((ACE_TCHAR*)strCmdLn.c_str(), targc, m_argv); m_fullargc = m_argc = targc; // initialize here (now m_argv is initialized) initThread("main"); m_logLevelConfigure = CDB_LOG_LEVEL; configureLogger(m_container_name); configureLogger(containerGlobalLoggerName); configureLogger(containerStaticLoggerName); m_logLevelConfigure = DYNAMIC_LOG_LEVEL; ACS_DEBUG_PARAM("maci::ContainerImpl::init", "Generated CommandLine: %s", strCmdLn.c_str()); // Manager cmd-ln reference m_manager_ref = 0; // PID file name m_pid_file_name = 0; if (!m_dynamicContainer && m_database->GetField(m_dbPrefix, "ServerThreads", fld)) { if (fld.GetULong(ul) && ul > 0) m_serverThreads = (int)ul; } // read invocationTimeout if (!m_dynamicContainer && m_database->GetField(m_dbPrefix, "Timeout", fld)) { CORBA::Double timeoutInS; fld.GetDouble(timeoutInS); //Convert to milliseconds timeoutInS = timeoutInS * static_cast(1000.0); m_invocationTimeout = static_cast(timeoutInS); } // read recovery default (mode) if (!m_dynamicContainer && m_database->GetField(m_dbPrefix, "Recovery", fld)) { ACE_CString bVal(""); if (fld.GetString(bVal)) { m_recovery = (ACE_OS::strcmp(bVal.c_str(), "true") == 0 ? true : false); } } // read DALtype ACE_CString dbType = "DAL"; if (!m_dynamicContainer && m_database->GetField(m_dbPrefix, "DALtype", fld)) fld.GetString(dbType); destroyDatabase( m_database ); m_database = 0; if (!CORBA::is_nil(cdbORB.in())) { ACS_DEBUG("maci::ContainerImpl::init", "Destroy bootstrap ORB"); cdbORB->destroy(); } // // Initialize CORBA. // if(!initializeCORBA(m_argc, m_argv)) { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::init", (LM_INFO, "Failed to initialize the ORB.")); return false; } ACE_OS::printf("%s\n", ::maci::Container::ContainerStatusORBInitEndMsg); // // Initialize and configure database access. // m_database = getDatabase(m_argc, m_argv, orb.in(), dbType.c_str()); if (!m_database || !m_database->isInitialized()) { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::init", (LM_INFO, "Failed to initialize the DB.")); return false; } // // Initialize ACSError. // if (!ACSError::init (orb.in())) { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::init", (LM_INFO, "Failed to initialize ACSError.")); return false; } // // Initialize acsQoS. // if (!acsQoS::init (orb.in())) { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::init", (LM_INFO, "Failed to initialize acsQoS.")); return false; } /// @todo AlarmSystem is not supported for VxWorks #ifndef MAKE_VXWORKS // Initialize the alarm system factory try { ACSAlarmSystemInterfaceFactory::init(getManager()); } catch(ACSErr::ACSbaseExImpl &ex) { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::init", (LM_ERROR, "Failed to initialize AlarmSystem factory.")); ex.log(); return false; } catch(...) { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::init", (LM_ERROR, "Failed to initialize AlarmSystem factory.")); return false; }//try-catch #endif // parse args for opts parseArgs(m_argc, m_argv); // show recovery mode if (m_recovery) { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::Container::init", (LM_INFO, "Recovery enabled.")); } else { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::Container::init", (LM_INFO, "Recovery disabled.")); } // // Get the path in which to look for DLLs from environment // ATTENTION: this does not work on HP, where the variable is called SHLIB_PATH // #ifdef ACS_HAS_WIN32 ACE_CString strDLLPath(ACE_OS::getenv ("PATH")); #else ACE_CString strDLLPath(ACE_OS::getenv ("LD_LIBRARY_PATH")); #endif m_dllmgr->setSearchPath(strDLLPath.c_str()); ACS_DEBUG_PARAM("maci::ContainerImpl::init", "Using DLL path: %s", strDLLPath.c_str()); m_methodRequestThreadPool = new MethodRequestThreadPool(5); // // activate the Container as a CORBA object. // CORBA::Object_var obj = activateCORBAObject(this, m_container_name); /* PortableServer::ObjectId_var id = PortableServer::string_to_ObjectId(m_container_name); poaPersistent->activate_object_with_id(id.in(), this); CORBA::Object_var obj = poaPersistent->servant_to_reference(this); */ if (CORBA::is_nil(obj.in())) return false; m_container_ref = maci::Container::_narrow(obj.in()); if (CORBA::is_nil(m_container_ref.ptr())) { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::init", (LM_INFO, "Failed to narrow Container.")); return false; } ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::init", (LM_INFO, "Container '%s' activated.", m_container_name)); // // load DLLs specified in Autoload // // loading BACI is required by default (to initialize CDB access) // this is not very clean solution StringArray * ary = 0; bool deleteArray = false; if (!m_dynamicContainer && m_database->GetField(m_dbPrefix, "Autoload", fld)) { ary = fld.GetStringArray(); } else { ary = new StringArray(); deleteArray = true; ary->push_back("baci"); } for(StringArray::const_iterator iter = ary->begin(); (iter != ary->end()) && (iter->length() > 0); ++iter) { int dll_handle; ACS_DEBUG_PARAM("maci::ContainerImpl::init", "Autoloading '%s'", iter->c_str()); if ((dll_handle=loadDLL(iter->c_str()))==0) { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::init", (LM_ERROR, "Failed to autoload '%s'", iter->c_str())); } else { m_dllmgr->setupCORBAinDLL(dll_handle, orb.in(), poaManager.in(), poaRoot.in(), poaPersistent.in(), poaTransient.in()); m_dllmgr->initThreadsInDLL(dll_handle, initThread, doneThread); } } if (deleteArray) { delete ary; ary = 0; } ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::init", (LM_INFO, "Container '%s' initialized successfuly", m_container_name)); // // write PID (option) // #ifndef ACS_HAS_WIN32 // write pid to the file if (m_pid_file_name) { FILE * pidf = ACE_OS::fopen (m_pid_file_name, "w"); if (pidf) { ACE_OS::fprintf (pidf, "%ld\n", static_cast(ACE_OS::getpid ())); ACE_OS::fclose (pidf); } } #endif return true; } catch( CORBA::Exception &ex ) { ex._tao_print_exception("maci::ContainerImpl::init"); ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::init", (LM_ERROR, "CORBA exception caught")); ACS_LOG(0, "maci::ContainerImpl::init", (LM_INFO, "CORBA exception caught")); } return false; } // ************************************************************************ bool ContainerImpl::connect() { if (m_shutdown) return false; /// /// IFR presence check /// unsigned long useIFR = 0; Field fld; //CORBA::ULong ul; if (!m_dynamicContainer && m_database->GetField(m_dbPrefix, "UseIFR", fld)) { ACE_CString bVal(""); if (fld.GetString(bVal)) { useIFR = ((ACE_OS::strcmp(bVal.c_str(), "true") == 0) || (ACE_OS::strcmp(bVal.c_str(), "1") == 0) ? 1 : 0); } } if (useIFR) { /// Get && provide IFR connection status. /// Only this method should be used, because CORBA::Object::_get_interface() uses it. try { CORBA::Object_var obj = orb->resolve_initial_references ("InterfaceRepository" ); if (!CORBA::is_nil (obj.in ())) { CORBA::Repository_var repo = CORBA::Repository::_narrow (obj.in ()); if (!CORBA::is_nil (repo.in ())) { m_hasIFR = true; ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::init", (LM_INFO, "Connected to the InterfaceRepository.")); } else { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::init", (LM_INFO, "Failed to connect to the InterfaceRepository.")); } } else { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::init", (LM_INFO, "Failed to connect to the InterfaceRepository.")); } } catch( CORBA::Exception &ex ) { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::init", (LM_INFO, "Failed to connect to the InterfaceRepository.")); ex._tao_print_exception( "maci::ContainerImpl::init"); } } else { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::init", (LM_INFO, "Usage of an InterfaceRepository disabled.")); } ACE_OS::printf("%s\n", ::maci::Container::ContainerStatusMgrInitBeginMsg); ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::init", (LM_INFO, "Connecting to the Manager...")); m_manager = resolveManager(-1); // 4 ever if (CORBA::is_nil(m_manager.ptr())) { ACS_LOG(0, "maci::ContainerImpl::init", (LM_INFO, "Failed to connect to the Manager.")); ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::init", (LM_ERROR, "Failed to connect to the Manager.")); return false; } ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::init", (LM_INFO, "Connected to the Manager.")); //now that we have a reference to manager, we can be certain that the CORBA Naming Service //is available. in as such, we can initialize the archiving system. ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::init", (LM_INFO, "Connecting to the Archiving Channel.")); //get the naming service reference from manager CORBA::Object_var nc_obj = m_manager->get_service(m_handle, "NameService", true); ACE_ASSERT(!CORBA::is_nil(nc_obj.in())); CosNaming::NamingContext_var nc = CosNaming::NamingContext::_narrow(nc_obj.in()); ACE_ASSERT(!CORBA::is_nil(nc.in())); //initialize the archiving supplier singleton using the naming service reference. ArchiveSupplierSingleton::Instance().init(nc.in()); ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::init", (LM_INFO, "Connecting to the Centralized Logger...")); if (m_loggerProxy) { ACE_CString centralizedLogger("Log"); // default if (!m_dynamicContainer && m_database->GetField(m_dbPrefix, "LoggingConfig/centralizedLogger", fld)) fld.GetString(centralizedLogger); try { // get centralized logger CORBA::Object_var log_obj = m_manager->get_service(m_handle, centralizedLogger.c_str(), true); if (log_obj.ptr() != CORBA::Object::_nil()) { Logging::AcsLogService_var logger = Logging::AcsLogService::_narrow(log_obj.in()); if (logger.ptr() != Logging::AcsLogService::_nil()) { m_loggerProxy->setCentralizedLogger(logger.in()); #ifndef MAKE_VXWORKS //Log4cpp remote logging initialization char * log4cpp_disabled = getenv("ACS_DISABLE_LOG4CPP"); if (log4cpp_disabled == NULL) LOGGER_FACTORY->enableRemoteAppender(cacheSize, flushPeriodSeconds, logger, NULL, maxLogsPerSecond); #endif ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::init", (LM_INFO, "Connected to the Centralized Logger.")); } else { ACS_LOG(0, "maci::ContainerImpl::init", (LM_INFO, "Failed to connect to the Centralized Logger.")); ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::init", (LM_ERROR, "Failed to connect to the Centralized Logger.")); } } else { ACS_LOG(0, "maci::ContainerImpl::init", (LM_INFO, "Failed to connect to the Centralized Logger.")); ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::init", (LM_ERROR, "Failed to connect to the Centralized Logger.")); } } catch( CORBA::Exception &ex ) { ACS_LOG(0, "maci::ContainerImpl::init", (LM_INFO, "Failed to connect to the Centralized Logger.")); ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::init", (LM_ERROR, "Failed to connect to the Centralized Logger.")); ex._tao_print_exception("maci::ContainerImpl::init"); } // set namingContext to the logger (to enable CL reconnections). try { CORBA::Object_var nc_obj = m_manager->get_service(m_handle, "NameService", true); if (nc_obj.ptr() != CORBA::Object::_nil()) { CosNaming::NamingContext_var nc = CosNaming::NamingContext::_narrow(nc_obj.in()); if (nc.ptr() != CosNaming::NamingContext::_nil()) { m_loggerProxy->setNamingContext(nc.in()); ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::init", (LM_INFO, "Set Naming Context to Logger.")); } else { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::init", (LM_ERROR, "Unable to set Naming Context to Logger.")); } } else { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::init", (LM_ERROR, "Unable to set Naming Context to Logger.")); } } catch( CORBA::Exception &ex ) { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::init", (LM_ERROR, "Unable to set Naming Context to Logger.")); ex._tao_print_exception("maci::ContainerImpl::init"); } } ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::init", (LM_INFO, "Logging into the Manager...")); int loginAttempts = -1; // inf maci::ClientInfo_var info = 0; while (loginAttempts!=0 && !m_shutdown) { try { info = m_manager->login(m_container_ref.in()); // everything is OK loginAttempts = 0; } catch( CORBA::Exception &ex ) { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::init", (LM_ERROR, "Failed to login to the Manager.")); //ACS_LOG(0, "maci::ContainerImpl::init", (LM_INFO, "Failed to login to the Manager.")); ex._tao_print_exception("maci::ContainerImpl::init"); //return false; if (loginAttempts!=0 && !m_shutdown) { if (loginAttempts!=-1) loginAttempts--; if (loginAttempts>0) ACE_OS::sleep(10-loginAttempts); // sleep else ACE_OS::sleep(10); } } } if (info.ptr()==0) { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::init", (LM_ERROR, "Failed to login to the Manager.")); return false; } m_handle = info->h; //Creating container services (container handle) ACE_CString ctrName(m_container_name); ACE_CString unusedType(""); m_containerServices = instantiateContainerServices(m_handle,ctrName,unusedType,poaContainer.in()); ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::init", (LM_INFO, "Logged into the Manager.")); ACE_OS::printf("%s\n", ::maci::Container::ContainerStatusMgrInitEndMsg); ACE_OS::printf("%s\n", ::maci::Container::ContainerStatusStartupEndMsg); #ifndef MAKE_VXWORKS // Init the sending of alarms in the LoggingProxy m_logThrottleAlarm_p = new LogThrottleAlarmImpl(m_containerServices,m_container_name); m_loggerProxy->setAlarmSender(m_logThrottleAlarm_p); #endif return true; } // ************************************************************************ bool ContainerImpl::run() { ACS_TRACE("maci::ContainerImpl::run"); ACS_LOG(LM_RUNTIME_CONTEXT, "ContainerImpl::run", (LM_INFO, "Container running...")); if (orb.ptr() != CORBA::ORB::_nil()) { // constrcut CORBA ORB request handler task ORBTask task (orb.in(), m_loggerProxy); // activate task, i.e. spawn threads and handle requests if (task.activate (THR_NEW_LWP | THR_JOINABLE, m_serverThreads) == 0) // wait until CORBA ORB is shutdown or destroyed task.thr_mgr()->wait (); else { // failed to spawn threads ACS_LOG(LM_RUNTIME_CONTEXT, "ContainerImpl::run", (LM_INFO, "Failed to activate CORBA ORB request handler threads...")); return false; } } ACS_LOG(LM_RUNTIME_CONTEXT, "ContainerImpl::run", (LM_INFO, "Container stopping...")); // Are we shutting down via ContainerImpl::shutdown() method // wait here until ContainerImpl::shutdown() method is finished if (m_shutdown) { // "strange" thing, if server is killed using 'killall SIGTERM maciContainer' it causes a call of signal handle, // but if CTRL-C is pressed all threads receive signal (including CORBA ORB main thread) and CORBA::run() method terminates // this makes the main program to terminate before shutdown is done // wait for done signal if (!m_shutdownDoneSignaled) m_shutdownDone.wait(); DALaccess::exitFunction(); } ACS_DEBUG("ContainerImpl::run", "Leaving ContainerImpl::run() method."); return true; } // ************************************************************************ bool ContainerImpl::done() { //ACS_TRACE("maci::ContainerImpl::done"); doneCORBA(); acsQoS::done(); if(m_dllmgr) { m_dllmgr->unload("baci"); // baci has to be unloaded earlier because of DLLClose } if (m_database) { destroyDatabase(m_database); m_database = 0; } ACSError::done(); return true; } // ************************************************************************ maci::Manager_ptr ContainerImpl::resolveManager(int nSecTimeout) { ACS_TRACE("maci::ContainerImpl::resolveManager"); Field fld; ULong retries = 10; if (!m_dynamicContainer && m_database->GetField(m_dbPrefix, "ManagerRetry", fld)) fld.GetULong(retries); return MACIHelper::resolveManager(orb.in(), m_argc, m_argv, retries, nSecTimeout); } // ************************************************************************ void ContainerImpl::logout () { ACS_TRACE("maci::ContainerImpl::logout"); if (!CORBA::is_nil(m_manager.ptr()) && m_handle!=0) { try { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::logout", (LM_INFO, "Logging out from the Manager.")); m_manager->logout(m_handle); m_handle = 0; m_manager = maci::Manager::_nil(); ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::logout", (LM_INFO, "Logged out from the Manager.")); } catch( CORBA::Exception &ex ) { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::logout", (LM_INFO, "Failed to log out from the Manager.")); ex._tao_print_exception("maci::ContainerImpl::logout) CORBA Exception occured."); } } } // ************************************************************************ int ContainerImpl::loadDLL(const char * name) { ACS_TRACE("maci::ContainerImpl::loadDLL"); if (!m_dllmgr) return 0; // passing while Container's command line int h = m_dllmgr->load(name, m_argc, m_argv); return h; } // ************************************************************************ CORBA::Object_ptr ContainerImpl::activateCORBAObject(PortableServer::Servant srvnt, const char * name) { ACS_TRACE("maci::ContainerImpl::activateCORBAObject"); if (!name) return CORBA::Object::_nil(); try { PortableServer::ObjectId_var id = PortableServer::string_to_ObjectId(name); poaContainer->activate_object_with_id(id.in(), srvnt); CORBA::Object_var obj = poaContainer->servant_to_reference(srvnt); return obj._retn(); } catch( CORBA::Exception &ex ) { return CORBA::Object::_nil(); } return CORBA::Object::_nil(); } // ************************************************************************ void ContainerImpl::etherealizeComponent(const char * id, PortableServer::Servant servant) { bool errorStatus=false; // if etherealizing container if (servant==this) return; ACS_TRACE("maci::ContainerImpl::etherealizeComponent"); ACS_DEBUG_PARAM("maci::ContainerImpl::etherealizeComponent", "Etherealizing '%s'", id); try{ // remove reference (POA will now destroy servant - so dtor will be called) ACS_STOP_WATCH("ContainerImpl::etherealizeComponent - _remove_ref() => destroy servant", 10.0/*s*/); servant->_remove_ref(); } catch(ACSErr::ACSbaseExImpl &ex) { maciErrType::ComponentDeletionExImpl dex(ex, __FILE__, __LINE__, "ContainerImpl::etherealizeComponent"); dex.setCURL(id); dex.setReason("problem in servant's DTOR?. Please check component's DTOR!"); dex.log(LM_CRITICAL); errorStatus = true; } catch( CORBA::SystemException &ex ) { ACSErrTypeCommon::CORBAProblemExImpl corbaProblemEx(__FILE__, __LINE__, "ContainerImpl::etherealizeComponent"); corbaProblemEx.setMinor(ex.minor()); corbaProblemEx.setCompletionStatus(ex.completed()); corbaProblemEx.setInfo(ex._info().c_str()); maciErrType::ComponentDeletionExImpl dex(corbaProblemEx, __FILE__, __LINE__, "ContainerImpl::etherealizeComponent"); dex.setCURL(id); dex.setReason("problem in servant's DTOR?. Please check component's DTOR!"); dex.log(LM_CRITICAL); errorStatus = true; } catch(std::exception &ex) { ACSErrTypeCommon::StdExceptionExImpl stdex(__FILE__, __LINE__, "ContainerImpl::etherealizeComponent"); stdex.setWhat(ex.what()); maciErrType::ComponentDeletionExImpl dex(stdex, __FILE__, __LINE__, "ContainerImpl::etherealizeComponent"); dex.setCURL(id); dex.setReason("problem in servant's DTOR?. Please check component's DTOR!"); dex.log(LM_CRITICAL); errorStatus = true; } catch (...) { ACSErrTypeCommon::UnexpectedExceptionExImpl uex(__FILE__, __LINE__, "ContainerImpl::etherealizeComponent"); maciErrType::ComponentDeletionExImpl dex(uex, __FILE__, __LINE__, "ContainerImpl::etherealizeComponent"); dex.setCURL(id); dex.setReason("problem in servant's DTOR?. Please check component's DTOR!"); dex.log(LM_CRITICAL); errorStatus = true; }//try-catch // // after it is destroyed, unlock library // // this is only needed it this is not the only point of calling ACE_Guard guard(m_activeComponents.mutex()); COMPONENT_HASH_MAP_ENTRY *entry; for (COMPONENT_HASH_MAP_ITER hash_iter (m_activeComponents); (hash_iter.next (entry) != 0); hash_iter.advance ()) if (ACE_OS::strcmp(id, entry->int_id_.info.name.in())==0) { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::etherealizeComponent", (LM_INFO, "Component '%s' etherealized.", entry->int_id_.info.name.in())); if (errorStatus) { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::etherealizeComponent", (LM_WARNING, "Although there was problem to etherealized (dtor) component '%s' going to TRY to unload the library what can have an unpredicted result.", entry->int_id_.info.name.in())); ContainerImpl::getLoggerProxy()->flush(); }//if m_dllmgr->unlock(entry->int_id_.lib); m_activeComponentList.remove(entry->int_id_.info.h); m_activeComponents.unbind(entry); break; //return; }//if if (errorStatus) { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::etherealizeComponent", (LM_WARNING, "There was problem to etherealized (dtor) a component, so we are going to TRY to shutdown the container. This operation has unpredictable result!")); ContainerImpl::getLoggerProxy()->flush(); shutdown(-2); } } // ************************************************************************ bool ContainerImpl::deactivateCORBAObject(CORBA::Object_ptr obj) { ACS_TRACE("maci::ContainerImpl::deactivateCORBAObject"); try { PortableServer::ObjectId_var id = poaContainer->reference_to_id(obj); poaContainer->deactivate_object(id.in()); return true; } catch( CORBA::SystemException &ex ) { ACSErrTypeCommon::CORBAProblemExImpl corbaProblemEx(__FILE__, __LINE__, "ContainerImpl::deactivateCORBAObject"); corbaProblemEx.setMinor(ex.minor()); corbaProblemEx.setCompletionStatus(ex.completed()); corbaProblemEx.setInfo(ex._info().c_str()); maciErrType::CannotDeactivateComponentExImpl dex(corbaProblemEx, __FILE__, __LINE__, "ContainerImpl::deactivateCORBAObject"); dex.log(LM_ERROR); } catch( CORBA::Exception &ex ) { ACSErrTypeCommon::CORBAProblemExImpl corbaProblemEx(__FILE__, __LINE__, "ContainerImpl::deactivateCORBAObject"); corbaProblemEx.setInfo(ex._info().c_str()); maciErrType::CannotDeactivateComponentExImpl dex(corbaProblemEx, __FILE__, __LINE__, "ContainerImpl::deactivateCORBAObject"); dex.log(LM_ERROR); } catch(...) { ACSErrTypeCommon::UnexpectedExceptionExImpl uex(__FILE__, __LINE__, "ContainerImpl::deactivateCORBAObject"); maciErrType::CannotDeactivateComponentExImpl dex(uex, __FILE__, __LINE__, "ContainerImpl::deactivateCORBAObject"); dex.log(LM_ERROR); }//try-catch return false; } // ************************************************************************ bool ContainerImpl::deactivateCORBAObject(PortableServer::Servant srvnt) { ACS_TRACE("maci::ContainerImpl::deactivateCORBAObject (maci::Handle, PortableServer::Servant)"); try { PortableServer::ObjectId_var id = poaContainer->servant_to_id(srvnt); poaContainer->deactivate_object(id.in()); return true; } catch( CORBA::SystemException &ex ) { ACSErrTypeCommon::CORBAProblemExImpl corbaProblemEx(__FILE__, __LINE__, "ContainerImpl::deactivateCORBAObject(servant)"); corbaProblemEx.setMinor(ex.minor()); corbaProblemEx.setCompletionStatus(ex.completed()); corbaProblemEx.setInfo(ex._info().c_str()); maciErrType::CannotDeactivateComponentExImpl dex(corbaProblemEx, __FILE__, __LINE__, "ContainerImpl::deactivateCORBAObject(servant)"); dex.log(LM_ERROR); } catch( CORBA::Exception &ex ) { ACSErrTypeCommon::CORBAProblemExImpl corbaProblemEx(__FILE__, __LINE__, "ContainerImpl::deactivateCORBAObject(servant)"); corbaProblemEx.setInfo(ex._info().c_str()); maciErrType::CannotDeactivateComponentExImpl dex(corbaProblemEx, __FILE__, __LINE__, "ContainerImpl::deactivateCORBAObject(servant)"); dex.log(LM_ERROR); } catch(...) { ACSErrTypeCommon::UnexpectedExceptionExImpl uex(__FILE__, __LINE__, "ContainerImpl::deactivateCORBAObject(servant)"); maciErrType::CannotDeactivateComponentExImpl dex(uex, __FILE__, __LINE__, "ContainerImpl::deactivateCORBAObject(servant)"); dex.log(LM_ERROR); }//try-catch return false; } // ************************************************************************ void ContainerImpl::initThread(const char * threadName) { char *contName = getContainer()->name(); ACS_CHECK_LOGGER; getNamedLogger(threadName)->log(Logging::BaseLog::LM_TRACE, Logging::BaseLog::FIELD_UNAVAILABLE, __FILE__, __LINE__, "maci::ContainerImpl::initThread"); if (m_loggerProxy) LoggingProxy::init(m_loggerProxy); LoggingProxy::ProcessName(contName); LoggingProxy::ThreadName(threadName); LoggingProxy::Flags(LM_SOURCE_INFO | LM_RUNTIME_CONTEXT); if (threadName && ACE_OS::strlen(threadName)) { getNamedLogger(threadName)->log(Logging::BaseLog::LM_DEBUG, std::string("Thread name: '") + threadName + "'", __FILE__, __LINE__, "maci::ContainerImpl::initThread"); } CORBA::string_free(contName); }//ContainerImpl::initThread // ************************************************************************ void ContainerImpl::doneThread() { ACS_CHECK_LOGGER; getNamedLogger(LoggingProxy::ThreadName())->log(Logging::BaseLog::LM_TRACE, Logging::BaseLog::FIELD_UNAVAILABLE, __FILE__, __LINE__, "maci::ContainerImpl::doneThread"); // LoggingProxy::done(); } /**************************************************************************/ /* -----------------------------------------------------------------------*/ /* ------------------------ [ CORBA interface ] --------------------------*/ /* -----------------------------------------------------------------------*/ /**************************************************************************/ ::maci::Handle ContainerImpl::get_handle () { ACS_TRACE("maci::ContainerImpl::get_handle"); return m_handle; } maci::ComponentInfo * ContainerImpl::activate_component ( maci::Handle h, maci::ExecutionId execution_id, const char * name, const char * exe, const char * type ) { ACE_UNUSED_ARG(execution_id); ACS_TRACE("maci::ContainerImpl::activate_component"); ContainerComponentInfo info; // here we create a dummy exception just because we do not have default ctor for it, // but then latter we may assign a real exception in case of an error and throw it maciErrType::CannotActivateComponentExImpl ex( __FILE__, __LINE__, "maci::ContainerImpl::activate_component"); bool throwException = false; // indicate if we have to throw an exception, // because there is a problem to throw an exception in catch statement if you unload a library which contains the caught exception if (m_shutdown) { maciErrType::CannotActivateComponentExImpl ex(__FILE__, __LINE__, "maci::ContainerImpl::activate_component"); ex.setCURL(name); ex.setComponentCode(exe); ex.setComponentType(type); ex.log(LM_DEBUG); throw ex.getCannotActivateComponentEx(); }//if // !!! there is a possibility of allowing creating two same components // but this won't happen since CORBA deny activation info.info.h = h; info.lib = 0; info.info.reference = CORBA::Object::_nil(); info.info.name = CORBA::string_dup(name); info.info.type = CORBA::string_dup(type); info.info.code = CORBA::string_dup(exe); info.info.container_name = CORBA::string_dup(m_container_name); info.info.container = m_handle; info.info.access = 0; info.info.interfaces.length(0); ContainerComponentInfo currentInfo; if (m_activeComponents.find(h, currentInfo)!=-1) { if (CORBA::is_nil(currentInfo.info.reference.in())) { char re[255]; sprintf(re, "Component with handle %u is marked to be deactivated, but is still waiting for POA to etherealizate it...", h); maciErrType::CannotActivateComponentExImpl ex(__FILE__, __LINE__, "maci::ContainerImpl::activate_component"); ex.setCURL(name); ex.setDetailedReason(re); ex.setComponentCode(exe); ex.setComponentType(type); ex.log(LM_DEBUG); throw ex.getCannotActivateComponentEx(); } else { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::activate_component", (LM_WARNING, "component with handle %u (%s) already activated", h, name)); if (ACE_OS::strcmp(currentInfo.info.name, name) == 0 && ACE_OS::strcmp(currentInfo.info.type, type) == 0) { // already activated, just copy info maci::ComponentInfo_var infoc = new maci::ComponentInfo(); *(infoc.ptr()) = currentInfo.info; return infoc._retn(); } else // this should never happen, Manager should know the state of Containers // here I could search if component is already activated with different handle and propose that one... // however this means that Manager is now aware of this handle (it thinks it is free), so this makes // component with this handle unusable... { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::activate_component", (LM_WARNING, "Activated component with handle %u (%s) has different name or type that existant! Releasing that component and replacing it with the new one...", h, name)); deactivate_component(h); } } } else { // no such component with that id, but maybe there is already component with the same name // this should also never happen ACE_Guard guard(m_activeComponents.mutex()); COMPONENT_HASH_MAP_ENTRY *entry; for (COMPONENT_HASH_MAP_ITER hash_iter (m_activeComponents); (hash_iter.next (entry) != 0); hash_iter.advance ()) if (ACE_OS::strcmp(name, entry->int_id_.info.name.in())==0 && ACE_OS::strcmp(type, entry->int_id_.info.type.in())==0) { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::activate_component", (LM_WARNING, "Activated component with specified %s name and type %s already exists! Fixing handle...", name, type)); if (CORBA::is_nil(entry->int_id_.info.reference.in())) { char re[255]; sprintf(re, "Component with handle %u is marked to be deactivated, but is still waiting for POA to etherealizate it...", h); maciErrType::CannotActivateComponentExImpl ex(__FILE__, __LINE__, "maci::ContainerImpl::activate_component"); ex.setCURL(name); ex.setDetailedReason(re); ex.setComponentCode(exe); ex.setComponentType(type); ex.log(LM_DEBUG); throw ex.getCannotActivateComponentEx(); } /* // fix handle m_activeComponents.unbind(entry->int_id_.info.h, info); info.info.h = h; m_activeComponents.bind(h, info); */ // do not fix handle, pass existing handle to the Manager and let it to fix it (if possible) maci::ComponentInfo_var infoc = new maci::ComponentInfo(); // *(infoc.ptr()) = info.info; *(infoc.ptr()) = entry->int_id_.info; return infoc._retn(); } }//if-else int libHandle = 0; // load the executable ACE_Time_Value start_time = ACE_OS::gettimeofday(); if((libHandle = loadDLL(exe)) == 0) { ACSErrTypeCommon::CannotLoadExImpl lex(__FILE__, __LINE__, "maci::ContainerImpl::activate_component"); lex.setObjectName(exe); maciErrType::CannotActivateComponentExImpl ex(lex, __FILE__, __LINE__, "maci::ContainerImpl::activate_component"); ex.setCURL(name); ex.setComponentCode(exe); ex.setComponentType(type); ex.log(LM_DEBUG); throw ex.getCannotActivateComponentEx(); }//if ACE_Time_Value elapsed_time = ACE_OS::gettimeofday() - start_time; AcsContainerLog::LOG_CompAct_Loading_OK loadingLog(__FILE__, __LINE__, "maci::ContainerImpl::activate_component"); loadingLog.setCompName(name); loadingLog.setTimeMillis(elapsed_time.sec()*1000 + elapsed_time.usec()/1000); loadingLog.log(); // get entry point of the component DLL. ConstructComponentFunc ConstructComponent = (ConstructComponentFunc)m_dllmgr->getSymbol(libHandle, "ConstructComponent"); if (ConstructComponent == 0) { char re[100]; sprintf (re, "ConstructComponent in library %s", exe); ACSErrTypeCommon::NotImplementedExImpl nex(__FILE__, __LINE__, "maci::ContainerImpl::activate_component"); nex.setFeature(re); maciErrType::CannotActivateComponentExImpl ex(nex, __FILE__, __LINE__, "maci::ContainerImpl::activate_component"); ex.setCURL(name); ex.setComponentCode(exe); ex.setComponentType(type); ex.log(LM_DEBUG); m_dllmgr->unlock(libHandle); throw ex.getCannotActivateComponentEx(); }//if // Build the ContainerServices that has to be passed to the constructor of the // component // The component stores the ContainerServices using a loki smart pointer // so it is the component that deletes the ContainerServices when the smart // pointer is destroyed ACE_CString cmpName(name); ACE_CString cmpType(type); ContainerServices* acsCS = instantiateContainerServices(h,cmpName,cmpType,poaContainer.in()); if (acsCS==NULL) { ACSErrTypeCommon::NullPointerExImpl nullEx(__FILE__, __LINE__, "maci::ContainerImpl::activate_component"); nullEx.setVariable("acsCS(ContainerServices)"); maciErrType::CannotActivateComponentExImpl ex(nullEx, __FILE__, __LINE__, "maci::ContainerImpl::activate_component"); ex.setCURL(name); ex.setComponentCode(exe); ex.setComponentType(type); ex.log(LM_DEBUG); m_dllmgr->unlock(libHandle); throw ex.getCannotActivateComponentEx(); }//if // construct the component PortableServer::Servant servant=0; try { start_time = ACE_OS::gettimeofday(); servant = ConstructComponent(h, name, type, acsCS); elapsed_time = ACE_OS::gettimeofday() - start_time; AcsContainerLog::LOG_CompAct_Instance_OK instantiationLog(__FILE__, __LINE__, "maci::ContainerImpl::activate_component"); instantiationLog.setCompName(name); instantiationLog.setTimeMillis(elapsed_time.sec()*1000 + elapsed_time.usec()/1000); instantiationLog.log(); } catch (ACSErr::ACSbaseExImpl &_ex) { ex = maciErrType::CannotActivateComponentExImpl(_ex, __FILE__, __LINE__, "maci::ContainerImpl::activate_component"); throwException = true; // if we unload here the library we might got a seg fault // because the caught exception was defined in the same library so we have to throw the exception outside } catch (...) { ACSErrTypeCommon::UnexpectedExceptionExImpl uex(__FILE__, __LINE__, "maci::ContainerImpl::activate_component"); ex = maciErrType::CannotActivateComponentExImpl(uex, __FILE__, __LINE__, "maci::ContainerImpl::activate_component"); throwException = true; // if we unload here the library we might got a seg fault // because the caught exception was defined in the same library so we have to throw the exception outside }//try-catch if (throwException) { ex.setCURL(name); ex.setComponentCode(exe); ex.setComponentType(type); ex.log(LM_DEBUG); servant = 0; m_dllmgr->unlock(libHandle); throw ex.getCannotActivateComponentEx(); }//if // @todo this can be removed since there should not happend in case of an error if(servant == 0) { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::activate_component", (LM_WARNING, "The constructor of a component should not return 0, but an exception in case of an error ! Please change the code!")); ACSErrTypeCommon::NullPointerExImpl nullEx(__FILE__, __LINE__, "maci::ContainerImpl::activate_component"); nullEx.setVariable("servant"); maciErrType::CannotActivateComponentExImpl ex(nullEx, __FILE__, __LINE__, "maci::ContainerImpl::activate_component"); ex.setCURL(name); ex.setComponentCode(exe); ex.setComponentType(type); ex.log(LM_DEBUG); m_dllmgr->unlock(libHandle); throw ex.getCannotActivateComponentEx(); }//if start_time = ACE_OS::gettimeofday(); info.lib = libHandle; info.info.reference = activateCORBAObject(servant, name); elapsed_time = ACE_OS::gettimeofday() - start_time; AcsContainerLog::LOG_CompAct_Corba_OK corbaActivationLog(__FILE__, __LINE__, "maci::ContainerImpl::activate_component"); corbaActivationLog.setCompName(name); corbaActivationLog.setTimeMillis(elapsed_time.sec()*1000 + elapsed_time.usec()/1000); corbaActivationLog.log(); // in case of an error if(CORBA::is_nil(info.info.reference.in())) { maciErrType::CannotActivateComponentExImpl ex(__FILE__, __LINE__, "maci::ContainerImpl::activate_component"); ex.setCURL(name); ex.setComponentCode(exe); ex.setComponentType(type); ex.setDetailedReason("activateCORBAObject() failed"); ex.log(LM_DEBUG); // destroy delete servant; m_dllmgr->unlock(libHandle); throw ex.getCannotActivateComponentEx(); } // remove reference to servant, so that only POA nows owns it servant->_remove_ref(); // even though the component is now an activated Corba object already, // it won't be called yet since the maciManager will only pass around // access information after we've returned from this activate_component method. // Therefore it's not too late to call initialize and execute, which are // guaranteed to be called before incoming functional calls must be expected. // At the moment we have to call these two methods one after the other; // if the Manager supports new calling semantics, we could separate the two // as described in ComponentLifecycle if (acscomponent::ACSComponentImpl *tempComp = dynamic_cast(servant)) { try { // first we have to check if we are in the right state if (tempComp->componentState() != ACS::COMPSTATE_NEW) { acsErrTypeLifeCycle::WrongInitialStateExImpl ex(__FILE__, __LINE__, "maci::ContainerImpl::activate_component"); ex.setComponentName(name); throw ex; // this exception will be caught few lines lower }//if start_time = ACE_OS::gettimeofday(); ComponentStateManager *csm = tempComp->getContainerServices()->getComponentStateManager(); csm->setState(ACS::COMPSTATE_INITIALIZING); tempComp->__initialize(); csm->setState(ACS::COMPSTATE_INITIALIZED); csm->setState(ACS::COMPSTATE_OPERATIONAL); tempComp->__execute(); elapsed_time = ACE_OS::gettimeofday() - start_time; AcsContainerLog::LOG_CompAct_Init_OK initLog(__FILE__, __LINE__, "maci::ContainerImpl::activate_component"); initLog.setCompName(name); initLog.setTimeMillis(elapsed_time.sec()*1000 + elapsed_time.usec()/1000); initLog.log(); } catch (ACSErr::ACSbaseExImpl &_ex) { ex = maciErrType::CannotActivateComponentExImpl(_ex, __FILE__, __LINE__, "maci::ContainerImpl::activate_component"); throwException = true; // if we unload here the library we might got a seg fault // because the caught exception was defined in the same library so we have to throw the exception outside } catch (...) { ACSErrTypeCommon::UnexpectedExceptionExImpl uex(__FILE__, __LINE__, "maci::ContainerImpl::activate_component"); ex = maciErrType::CannotActivateComponentExImpl(uex, __FILE__, __LINE__, "maci::ContainerImpl::activate_component"); throwException = true; // if we unload here the library we might got a seg fault // because the caught exception was defined in the same library so we have to throw the exception outside }//try-catch if (throwException) { ex.setCURL(name); ex.setComponentCode(exe); ex.setComponentType(type); ex.log(LM_DEBUG); deactivateCORBAObject(servant); /// @todo should be here called unlock library ? m_dllmgr->unlock(libHandle); throw ex.getCannotActivateComponentEx(); }//if } // We allow also compoennts not implementing the acscomponent::ACSComponentImpl // interface. // In this case there is no life cycle handling // Warning: This might change in the future! else { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::activate_component", (LM_INFO, "Component '%s' does not implement acscomponent::ACSComponentImpl", name)); } /// try to query IFR, if it is not available then /// return "IDL:omg.org/CORBA/Object:1.0" try { CORBA::InterfaceDef_var ifdef = CORBA::InterfaceDef::_nil(); if (m_hasIFR) { ifdef = servant->_get_interface (); }//if if (m_hasIFR && !CORBA::is_nil(ifdef.in()) ) { CORBA::InterfaceDef::FullInterfaceDescription_var desc = ifdef->describe_interface(); info.info.interfaces.length(desc->base_interfaces.length()+1); CORBA::ULong i=0; for(; i < desc->base_interfaces.length(); i++) info.info.interfaces[i] = CORBA::string_dup(desc->base_interfaces[i].in()); info.info.interfaces[i] = CORBA::string_dup(desc->id.in()); } else { info.info.interfaces.length(1); info.info.interfaces[0] = CORBA::string_dup("IDL:omg.org/CORBA/Object:1.0"); }//if-else } catch( CORBA::SystemException &_ex ) { ACSErrTypeCommon::CORBAProblemExImpl corbaProblemEx(__FILE__, __LINE__, "ContainerImpl::activate_component"); corbaProblemEx.setMinor(_ex.minor()); corbaProblemEx.setCompletionStatus(_ex.completed()); corbaProblemEx.setInfo(_ex._info().c_str()); corbaProblemEx.log(LM_WARNING); // @todo: I do not know if here we have to throw an exception ? info.info.interfaces.length(1); info.info.interfaces[0] = CORBA::string_dup("IDL:omg.org/CORBA/Object:1.0"); } if (m_activeComponents.bind(h, info)==-1) { // failed to bind char re[100]; sprintf(re, "Failed to bind the component with handle %d to HashMap!", h); // deactivate & destroy info.info.reference = CORBA::Object::_nil(); maciErrType::CannotActivateComponentExImpl ex(__FILE__, __LINE__, "maci::ContainerImpl::activate_component"); ex.setCURL(name); ex.setDetailedReason(re); ex.setComponentCode(exe); ex.setComponentType(type); ex.log(LM_DEBUG); deactivateCORBAObject(servant); m_dllmgr->unlock(libHandle); // @todo unlock library ? // @todo: Warning: memory leak here?! No lifecycle methods called here (and container services cleanup) // also servant->_remove_ref(); should be called here?! throw ex.getCannotActivateComponentEx(); } m_activeComponentList.insert(h); ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::activate_component", (LM_INFO, "Component '%s' activated.", name)); maci::ComponentInfo_var infoCpy = new maci::ComponentInfo(); *(infoCpy.ptr()) = info.info; return infoCpy._retn(); }//activate_component void ContainerImpl::activate_component_async(maci::Handle h, maci::ExecutionId id, const char* name, const char* exe, const char* type, maci::CBComponentInfo_ptr ci, const ACS::CBDescIn& descIn) { m_methodRequestThreadPool->enqueue(new ActivationMethod (this, h, id, name, exe, type, ci, descIn)); } // ************************************************************************ void ContainerImpl::deactivate_component(maci::Handle h ) { ACS_TRACE("maci::ContainerImpl::deactivate_component"); // deactivation has to be allowed during shutdown... //maci::stringSeq compNames; //compNames.length(h.length()); // int idxCompNames = 0; ContainerComponentInfo info; if (m_activeComponents.find(h, info) != -1 && !CORBA::is_nil(info.info.reference.in())) { ACS_LOG( LM_RUNTIME_CONTEXT, "maci::ContainerImpl::deactivate_component", (LM_DEBUG, "Deactivating component with handle %d (%s of type %s)", h, info.info.name.in(), info.info.type.in())); maciErrType::ComponentCleanUpExImpl *cleanEx = NULL; CORBA::Object_ptr ref = CORBA::Object::_duplicate( info.info.reference.in()); info.info.reference = CORBA::Object::_nil(); m_activeComponents.rebind(h, info); // update // Before really deactivating the component, // we call the cleanUp() ComponentLifecycle termination method // This gives the component time to cleanup itself, performin any needed // CORBA activity before deactivation. // This cannot be done in the destructor, since the destructor // is called by the POA after having "disconnected" the Component // from CORBA. PortableServer::Servant servant = poaContainer->reference_to_servant( ref); if (acscomponent::ACSComponentImpl *tempComp = dynamic_cast(servant)) { ACS_LOG( LM_RUNTIME_CONTEXT, "maci::ContainerImpl::deactivate_component", (LM_DEBUG, "Component '%s': calling cleanUp Lifecycle .", info.info.name.in())); tempComp->getContainerServices()->getComponentStateManager()->setState( ACS::COMPSTATE_DESTROYING); try { ACS_STOP_WATCH("ContainerImpl::deactivate_component - __cleanUp()", 10.0/*s*/); tempComp->__cleanUp(); } catch (ACSErr::ACSbaseExImpl &ex) { cleanEx = new maciErrType::ComponentCleanUpExImpl(ex.getErrorTrace(), __FILE__, __LINE__, __PRETTY_FUNCTION__); cleanEx->log(LM_WARNING); } catch (...) { cleanEx = new maciErrType::ComponentCleanUpExImpl(__FILE__, __LINE__, __PRETTY_FUNCTION__); cleanEx->addData("Reason", "Unknown Exception"); cleanEx->log(LM_WARNING); } if (tempComp->getContainerServices()) { tempComp->getContainerServices()->getComponentStateManager()->setState( ACS::COMPSTATE_DEFUNCT); } // The containerServices is deleted by the component (it stores the // ContainerServices into a smart pointer } try{ servant->_remove_ref(); // Do not forget to signal we are not using the servant any more ACS_LOG( LM_RUNTIME_CONTEXT, "maci::ContainerImpl::deactivate_component", (LM_DEBUG, "Component '%s' reference set to nil.", info.info.name.in())); // Real deactivation. // This will also cause the call of the destructor // for the component if (!deactivateCORBAObject(ref)) { ACS_LOG( LM_RUNTIME_CONTEXT, "maci::ContainerImpl::deactivate_component", (LM_ERROR, "Failed to deactivate component with handle %d (%s of type %s)", h, info.info.name.in(), info.info.type.in())); }//if CORBA::release(ref); ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::deactivate_component", (LM_INFO, "Component '%s' deactivated.", info.info.name.in())); }catch(...) { maciErrType::CannotDeactivateComponentExImpl dex(__FILE__, __LINE__, "ContainerImpl::deactivate_component"); dex.log(LM_ERROR); } //compNames[idxCompNames++] = info.info.name; if (cleanEx != NULL) { maciErrType::ComponentCleanUpEx ex = cleanEx->getComponentCleanUpEx(); delete cleanEx; throw ex; } } //compNames.length(idxCompNames); //components_unavailable(compNames); } // ************************************************************************ CORBA::Object_ptr ContainerImpl::restart_component(maci::Handle h) { if (m_shutdown) { throw CORBA::NO_RESOURCES(); return 0; } throw CORBA::NO_IMPLEMENT(); return 0; } // ************************************************************************ maci::ComponentInfoSeq * ContainerImpl::get_component_info ( const maci::HandleSeq & h ) { ACS_TRACE("maci::ContainerImpl:::get_component_info"); if (m_shutdown) { throw CORBA::NO_RESOURCES (); return 0; } maci::ComponentInfoSeq_var seq; CORBA::ULong len = 0; //If the list of handles is empty, information about all components hosted by the container is returned. CORBA::ULong listLen = h.length(); if( listLen == 0 ) { listLen = m_activeComponents.current_size(); seq = new maci::ComponentInfoSeq(listLen); if(seq==0){ errno = ENOMEM; throw CORBA::NO_RESOURCES(); } // ACE_NEW_THROW_EX(seq, maci::ComponentInfoSeq(listLen), CORBA::NO_RESOURCES()); seq->length(listLen); COMPONENT_HASH_MAP_ENTRY *entry; for (COMPONENT_HASH_MAP_ITER hash_iter (m_activeComponents); (hash_iter.next (entry) != 0); hash_iter.advance ()) { seq[len++]=entry->int_id_.info; } return seq._retn(); } seq = new maci::ComponentInfoSeq(listLen); if( seq==0 ) { errno = ENOMEM; throw CORBA::NO_RESOURCES(); } // ACE_NEW_THROW_EX(seq, maci::ComponentInfoSeq(h.length()), CORBA::NO_RESOURCES()); ContainerComponentInfo info; for (CORBA::ULong i = 0; ilength(len); return seq._retn(); } // ************************************************************************ /** * Bits 8 thru 15 of this parameter denote the action, which can be one of: * 0 - reload the container (not implemented; partital implementation - init() method is not called, only connect() - acts like reconnect) * 1 - reboot the computer (not implemented) * 2 - exit the container (done) **/ void ContainerImpl::shutdown ( CORBA::ULong action ) { ACS_TRACE("maci::ContainerImpl::shutdown"); if (m_shutdown) return; else m_shutdown=true; setStatus(action & 0xFF); setShutdownAction((action & 0xFF00) >> 8); logout(); m_methodRequestThreadPool->shutdown(); // // cleanup components // // use manager's component shutdown order // @TODO: Error handling is missing here. // we should catch exceptions. if (m_componentShutdownOrder.length()) { // NOTE: m_componentShutdownOrder is in sync since cannot be changed if container is in shutdown state for (CORBA::ULong i = 0; i < m_componentShutdownOrder.length(); i++) deactivate_component(m_componentShutdownOrder[i]); } // cleanup the rest ACE_Guard guard(m_activeComponents.mutex()); maci::HandleSeq_var handles = new maci::HandleSeq(m_activeComponents.current_size()); handles->length(m_activeComponents.current_size()); /* CORBA::ULong pos = 0; COMPONENT_HASH_MAP_ENTRY *entry; for (COMPONENT_HASH_MAP_ITER iter(m_activeComponents); iter.next(entry) != 0; iter.advance()) handles[pos++] = entry->int_id_.info.h; */ // get reverse deactivation order of components CORBA::ULong pos = m_activeComponents.current_size()-1; for (COMPONENT_LIST::CONST_ITERATOR iter(m_activeComponentList); !iter.done(); iter.advance()) handles[pos--] = *iter; guard.release(); ACS_DEBUG_PARAM("maci::ContainerImpl::shutdown", "%d components left unactivated (using reverse activation order).", handles->length()); // @TODO: Error handling is missing here. // we should catch exceptions. if (handles->length()) { for (CORBA::ULong i = 0; i < handles->length(); i++) deactivate_component(handles[i]); } // This was the orginal code trying to deactivate. /* ACE_Guard guard(m_mutex); maci::HandleSeq_var handles = new maci::HandleSeq(m_activeComponents.current_size()); handles->length(m_activeComponents.current_size()); CORBA::ULong pos = 0; COMPONENT_HASH_MAP_ENTRY *entry; for (COMPONENT_HASH_MAP_ITER iter(m_activeComponents); iter.next(entry) != 0; iter.advance()) handles[pos++] = entry->int_id_.info.h; guard.release(); ACS_DEBUG_PARAM("maci::ContainerImpl::shutdown", "%d components left unactivated.", handles->length()); if (handles->length()) { try { deactivate_components(handles.in()); } catch( CORBA::Exception &ex ) { ex._tao_print_exception("maci::ContainerImpl::shutdown"); } } */ /* ACS_DEBUG("maci::ContainerImpl::shutdown", "Shutting down Container POA"); try { if (poaContainer.ptr() != PortableServer::POA::_nil()) { // destroy(etherealize_objects, wait_for_completion) // If the wait_for_completion parameter is TRUE, the destroy // operation will return only after all requests in process have // completed and all invocations of etherealize have // completed. Otherwise, the destroy operation returns after // destroying the POAs. // If wait_for_completion is TRUE and the current thread is // in an invocation context dispatched from some POA // belonging to the same ORB as this POA, the BAD_INV_ORDER // system exception with standard minor code 3 is raised and // POA destruction does not occur. // system exception, ID 'IDL:omg.org/CORBA/BAD_INV_ORDER:1.0' // OMG minor code (3), described as 'Operation would deadlock.', completed = NO // this also destroys other POAs poaContainer->destroy(1, 1/); poaContainer = PortableServer::POA::_nil(); } } catch( CORBA::Exception &ex ) { ex._tao_print_exception("maci::ContainerImpl::shutdown"); } */ ArchiveSupplierSingleton::Instance().done(); #ifndef MAKE_VXWORKS ACSAlarmSystemInterfaceFactory::done(); #endif // flush until we still have ORB // and disable remote logging if (m_loggerProxy) { m_loggerProxy->flush(); m_loggerProxy->setCentralizedLogger(Logging::AcsLogService::_nil()); } ACS_DEBUG("maci::ContainerImpl::shutdown", "Shutting down ORB"); try { // false - avoid deadlock; true would try to wait for all requests // to complete before returning, but because we are calling it from within // a request, we would be blocking it from orb->shutdown(false); } catch( CORBA::Exception &ex ) { ex._tao_print_exception("maci::ContainerImpl::shutdown"); } m_shutdownDoneSignaled = true; m_shutdownDone.signal(); ACS_DEBUG("maci::ContainerImpl::shutdown", "Done"); } // ************************************************************************ void ContainerImpl::disconnect () { ACS_TRACE("maci::ContainerImpl::disconnect"); ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::disconnect", (LM_INFO, "Disconnect notification received.")); if (!m_shutdown && (m_handle || m_manager.ptr()!=maci::Manager::_nil())) { // just logout logout(); // forget manager ref. and handle anyway m_handle = 0; m_manager = maci::Manager::_nil(); // now manager must refresh my state when it is restated m_recovery = true; // sleep for a few seconds before reconnect ACE_OS::sleep(3); if (!connect()) shutdown(CONTAINER_EXIT); } } // ************************************************************************ maci::AuthenticationData* ContainerImpl::authenticate ( maci::ExecutionId execution_id, const char * question ) { ACE_UNUSED_ARG(question); ACS_TRACE("maci::ContainerImpl:::authenticate"); maci::AuthenticationData_var data = new AuthenticationData(); data->answer = CORBA::string_dup(""); data->client_type = maci::CONTAINER_TYPE; data->impl_lang = maci::CPP; data->recover = m_recovery; data->timestamp = m_startTime; if (m_executionId == 0) m_executionId = execution_id; data->execution_id = m_executionId; return data._retn(); } // ************************************************************************ char * ContainerImpl::name () { return CORBA::string_dup(m_container_name); } // ************************************************************************ void ContainerImpl::message ( CORBA::Short type, const char * message ) { ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::message", (LM_INFO, "Message from manager received. Type: %d. Message: %s", type, message)); } // ************************************************************************ void ContainerImpl::taggedmessage ( CORBA::Short type, CORBA::Short tag, const char * message ) { if (tag == ::maci::Client::MSGID_AUTOLOAD_START) { ACE_OS::printf("%s\n", ::maci::Container::ContainerStatusCompAutoloadBeginMsg); } ACS_LOG(LM_RUNTIME_CONTEXT, "maci::ContainerImpl::taggedmessage", (LM_INFO, "Message from manager received. Type: %d. Tag: %d. Message: %s", type, tag, message)); if (tag == ::maci::Client::MSGID_AUTOLOAD_END) { ACE_OS::printf("%s\n", ::maci::Container::ContainerStatusCompAutoloadEndMsg); ACE_OS::printf("%s\n", ::maci::Container::ContainerStatusReadyMsg); ACE_OS::fflush(stdout); } } // ************************************************************************ void ContainerImpl::components_available ( const maci::ComponentInfoSeq & cobs ) { ACS_SHORT_LOG((LM_DEBUG, "Informing Components Available")); ACE_CString_Vector compNames; for(CORBA::ULong i = 0; ireference_to_servant(ref); if (acscomponent::ACSComponentImpl *tempComp = dynamic_cast(servant)){ tempComp->getContainerServices()->fireComponentsAvailable(compNames); } } } } // ************************************************************************ void ContainerImpl::set_component_shutdown_order ( const maci::HandleSeq & h ) { ACS_TRACE("maci::ContainerImpl::set_component_shutdown_order"); if (m_shutdown) return; // copy list m_componentShutdownOrder = h; } // ************************************************************************ void ContainerImpl::components_unavailable ( const maci::stringSeq & cob_names ) { ACS_SHORT_LOG((LM_DEBUG, "Informing Components Unavailable")); ACE_CString_Vector compNames; for(CORBA::ULong i = 0; ireference_to_servant(ref); if (acscomponent::ACSComponentImpl *tempComp = dynamic_cast(servant)){ tempComp->getContainerServices()->fireComponentsUnavailable(compNames); } } } } // ************************************************************************ void ContainerImpl::releaseComponent(const char *name) { m_manager->release_component(m_handle, name); } // ************************************************************************ CORBA::Object_ptr ContainerImpl::get_object(const char *name, const char *domain, bool activate ) { /** * Check if is null */ if(!name) { ACS_SHORT_LOG((LM_DEBUG, "Name parameter is null.")); return CORBA::Object::_nil(); } /** * Get reference of component object */ /** * First creates the CURL, if not already a CURL, * and query the Manager for the component */ const char* curl_str = "curl://"; ACE_CString curl = ""; if(strncmp(name, curl_str, strlen(curl_str)) != 0 ) { curl += curl_str; if (domain) curl += domain; curl += ACE_CString("/"); } curl += name; ACS_SHORT_LOG((LM_DEBUG, "Getting component: '%s'. Creating it...", curl.c_str())); // wait that m_handle become !=0 while (m_handle==0) { ACS_SHORT_LOG((LM_DEBUG, "Waiting for m_handle")); ACE_OS::sleep(1); } try { CORBA::Object_var obj = m_manager->get_service(m_handle, curl.c_str(), activate); if (CORBA::is_nil(obj.in())) { ACS_SHORT_LOG((LM_DEBUG, "Failed to create '%s'", curl.c_str())); return 0; } return obj._retn(); } catch( CORBA::Exception &ex ) { ex._tao_print_exception("maci::ContainerImpl::get_object"); return CORBA::Object::_nil(); } catch(...) { return CORBA::Object::_nil(); } return CORBA::Object::_nil(); } // ************************************************************************ CORBA::Boolean ContainerImpl::ping ( ) { return true; } // ************************************************************************ ContainerServices* ContainerImpl::instantiateContainerServices( maci::Handle h, ACE_CString& name, ACE_CString& type, PortableServer::POA_ptr poa) { #ifndef MAKE_VXWORKS return new MACIContainerServices(h,name,type,poa,getAlarmSourceThread()); #else return new MACIContainerServices(h,name,type,poa); #endif } /************************************************************************/ /** * Logging configurable methods */ Logging::LoggingConfigurable::LogLevels ContainerImpl::get_default_logLevels() { ACS_TRACE("maci::ContainerImpl::get_default_logLevels"); return m_defaultLogLevels; } void ContainerImpl::set_default_logLevels(const Logging::LoggingConfigurable::LogLevels& logLevels) { ACS_TRACE("maci::ContainerImpl::set_default_logLevels"); Logging::Logger::getGlobalLogger()->setLevels( static_cast(LogLevelDefinition::getACELogPriority(logLevels.minLogLevel)), static_cast(LogLevelDefinition::getACELogPriority(logLevels.minLogLevelLocal)), DYNAMIC_LOG_LEVEL); m_defaultLogLevels = logLevels; m_defaultLogLevels.useDefault = true; }//ContainerImpl::set_default_logLevels Logging::stringSeq* ContainerImpl::get_logger_names() { ACS_TRACE("maci::ContainerImpl::get_logger_names"); std::list names = Logging::Logger::getGlobalLogger()->getLoggerNames(); Logging::stringSeq_var namesSeq = new Logging::stringSeq(); namesSeq->length(names.size() + m_logLevels.size()); CORBA::ULong i = 0; // add live logs std::list::iterator pos; for (pos = names.begin(); pos != names.end(); pos++) { namesSeq[i++] = CORBA::string_dup(pos->c_str()); } // add logs from configuration, but hide non-existant std::map::iterator iter; for (iter = m_logLevels.begin(); iter != m_logLevels.end(); iter++) if (find(names.begin(), names.end(), iter->first) == names.end()) if (Logging::Logger::getGlobalLogger()->exists(iter->first)) { namesSeq[i++] = CORBA::string_dup(iter->first.c_str()); } namesSeq->length(i); return namesSeq._retn(); } /* * @throw maciErrType::LoggerDoesNotExistEx */ Logging::LoggingConfigurable::LogLevels ContainerImpl::get_logLevels(const char* loggerName) { ACS_TRACE("maci::ContainerImpl::get_logLevels"); if(! Logging::Logger::getGlobalLogger()->exists(loggerName)){ Logging::LoggerDoesNotExistEx ex(loggerName); throw ex; } if (m_logLevels.find(loggerName) != m_logLevels.end()) return m_logLevels[loggerName]; else return m_defaultLogLevels; } /* * @throw maciErrType::LoggerDoesNotExistEx */ void ContainerImpl::set_logLevels(const char* loggerName, const Logging::LoggingConfigurable::LogLevels& logLevels) { ACS_TRACE("maci::ContainerImpl::set_logLevels"); if (!Logging::Logger::getGlobalLogger()->exists(loggerName)) { Logging::LoggerDoesNotExistEx ex(loggerName); throw ex; } m_logLevels[loggerName] = logLevels; if (logLevels.useDefault){ Logging::Logger::getGlobalLogger()->setLevels(loggerName, static_cast(LogLevelDefinition::getACELogPriority(m_defaultLogLevels.minLogLevel)), static_cast(LogLevelDefinition::getACELogPriority(m_defaultLogLevels.minLogLevelLocal)), DYNAMIC_LOG_LEVEL); }else{ Logging::Logger::getGlobalLogger()->setLevels(loggerName, static_cast(LogLevelDefinition::getACELogPriority(logLevels.minLogLevel)), static_cast(LogLevelDefinition::getACELogPriority(logLevels.minLogLevelLocal)), DYNAMIC_LOG_LEVEL); } } void ContainerImpl::refresh_logging_config() { ACS_TRACE("maci::ContainerImpl::refresh_logging_config"); if (m_dynamicContainer) return; Field fld; // m_defaultLogLevels.minLogLevel int envStdioPriority = -1; int envCentralizePriority = -1; char *acsSTDIO = getenv("ACS_LOG_STDOUT"); if (acsSTDIO && *acsSTDIO) { envStdioPriority = atoi(acsSTDIO); } char *acsCentralizeLogger = getenv("ACS_LOG_CENTRAL"); if (acsCentralizeLogger && *acsCentralizeLogger) { envCentralizePriority = atoi(acsCentralizeLogger); } cdb::ULong ul; if (m_logLevelRefresh == CDB_LOG_LEVEL && envCentralizePriority >= 0 && envCentralizePriority <=11) m_defaultLogLevels.minLogLevel = envCentralizePriority; else if (m_database->GetField(m_dbPrefix, "LoggingConfig/minLogLevel", fld)) { if (fld.GetULong(ul)) m_defaultLogLevels.minLogLevel = ul; } // m_defaultLogLevels.minLogLevelLocal if (m_logLevelRefresh == CDB_LOG_LEVEL && envStdioPriority >= 0 && envStdioPriority <=11) m_defaultLogLevels.minLogLevelLocal = envStdioPriority; else if (m_database->GetField(m_dbPrefix, "LoggingConfig/minLogLevelLocal", fld)) { if (fld.GetULong(ul)) m_defaultLogLevels.minLogLevelLocal = ul; } // set default logger levels Logging::Logger::getGlobalLogger()->setLevels( static_cast(LogLevelDefinition::getACELogPriority(m_defaultLogLevels.minLogLevel)), static_cast(LogLevelDefinition::getACELogPriority(m_defaultLogLevels.minLogLevelLocal)), m_logLevelRefresh); // other loggers config if (m_database->GetField(m_dbPrefix.c_str(), "LoggingConfig", fld)) { cdb::StringArray loggers; if (fld.GetStringArray(loggers)) { cdb::StringArray::iterator iter; for (iter = loggers.begin(); iter != loggers.end(); iter++) { // C++ CDB impl reutrns also attriburtes, we do not want if (*iter == "centralizedLogger" || *iter == "dispatchPacketSize" || *iter == "flushPeriodSeconds" || *iter == "immediateDispatchLevel" || *iter == "maxLogQueueSize" || *iter == "minLogLevel" || *iter == "minLogLevelLocal"|| *iter == "maxLogsPerSecond" ) continue; // load loadLoggerConfiguration(iter->c_str()); int oldLogLevelConfigure = m_logLevelConfigure; // ... and configure configureLogger(iter->c_str()); m_logLevelConfigure = oldLogLevelConfigure; } } } } void ContainerImpl::configureLogger(const std::string& loggerName) { #ifndef MAKE_VXWORKS //Log4cpp Log creation char * log4cpp_disabled = getenv("ACS_DISABLE_LOG4CPP"); if (log4cpp_disabled == NULL) LOGGER_FACTORY->getLogger(loggerName); #endif Logging::LoggingConfigurable::LogLevels logLevels; if (getContainer()->m_logLevels.find(loggerName) != getContainer()->m_logLevels.end()) logLevels = getContainer()->m_logLevels[loggerName]; else logLevels = getContainer()->m_defaultLogLevels; if (logLevels.useDefault){ Logging::Logger::getGlobalLogger()->setLevels(loggerName, static_cast(LogLevelDefinition::getACELogPriority(getContainer()->m_defaultLogLevels.minLogLevel)), static_cast(LogLevelDefinition::getACELogPriority(getContainer()->m_defaultLogLevels.minLogLevelLocal)), m_logLevelConfigure); #ifndef MAKE_VXWORKS //Log4cpp: set levels if (log4cpp_disabled == NULL) LOGGER_FACTORY->setLogLevels(loggerName, logging::convertPriority(getContainer()->m_defaultLogLevels.minLogLevel), logging::convertPriority(getContainer()->m_defaultLogLevels.minLogLevelLocal)); #endif }else{ Logging::Logger::getGlobalLogger()->setLevels(loggerName, static_cast(LogLevelDefinition::getACELogPriority(logLevels.minLogLevel)), static_cast(LogLevelDefinition::getACELogPriority(logLevels.minLogLevelLocal)), m_logLevelConfigure); #ifndef MAKE_VXWORKS //Log4cpp: set levels if (log4cpp_disabled == NULL) LOGGER_FACTORY->setLogLevels(loggerName, logging::convertPriority(logLevels.minLogLevel), logging::convertPriority(logLevels.minLogLevelLocal)); #endif } } void ContainerImpl::loadLoggerConfiguration(const std::string& loggerName) { bool failed = false; Logging::LoggingConfigurable::LogLevels logLevels; logLevels.useDefault = false; Field fld; // minLogLevel cdb::ULong ul; if (m_database->GetField(m_dbPrefix, ACE_CString("LoggingConfig/") + loggerName.c_str() + "/minLogLevel", fld)) { if (fld.GetULong(ul)) logLevels.minLogLevel = ul; else failed = true; } else failed = true; // minLogLevelLocal if (!failed && m_database->GetField(m_dbPrefix, ACE_CString("LoggingConfig/") + loggerName.c_str() + "/minLogLevelLocal", fld)) { if (fld.GetULong(ul)) logLevels.minLogLevelLocal = ul; else failed = true; } else failed = true; // store or remove old if (failed) m_logLevels.erase(loggerName); else m_logLevels[loggerName] = logLevels; } Logging::ACSLogStatistics::logStatsInformationSeq* ContainerImpl::get_statistics_logger_configuration() { ACS_TRACE("maci::ContainerImpl::get_statistics_logger_configuration"); Logging::ACSLogStatistics::logStatsInformationSeq_var statsInfoSeq = new Logging::ACSLogStatistics::logStatsInformationSeq(); statsInfoSeq->length(ACE_Singleton::instance()->loggers_m.size() ); CORBA::ULong i = 0; Logging::Logger::LoggerList::iterator pos; for (pos = ACE_Singleton::instance()->loggers_m.begin(); pos != ACE_Singleton::instance()->loggers_m.end(); pos++) { statsInfoSeq[i].statsId = CORBA::string_dup((*pos)->stats.getStatisticsIdentification().c_str()); statsInfoSeq[i].loggerName = CORBA::string_dup((*pos)->getName().c_str()); statsInfoSeq[i].statsStatus = (*pos)->stats.getDisableStatistics(); statsInfoSeq[i].statsPeriodConfiguration = (*pos)->stats.getStatisticsCalculationPeriod(); statsInfoSeq[i].statsGranularityConfiguration = (*pos)->stats.getStatisticsGranularity(); i++; } statsInfoSeq->length(i); return statsInfoSeq._retn(); } /* * @throw maciErrType::LoggerDoesNotExistEx */ Logging::ACSLogStatistics::LogStatsInformation* ContainerImpl::get_statistics_logger_configuration_byname(const char* logger_name) { ACS_TRACE("maci::ContainerImpl::get_statistics_logger_configuration_byname"); if(! Logging::Logger::getGlobalLogger()->exists(logger_name)) { Logging::LoggerDoesNotExistEx ex(logger_name); throw ex; } Logging::ACSLogStatistics::LogStatsInformation_var statsInfo = new Logging::ACSLogStatistics::LogStatsInformation(); Logging::Logger::LoggerList::iterator pos; for (pos = ACE_Singleton::instance()->loggers_m.begin(); pos != ACE_Singleton::instance()->loggers_m.end(); pos++) if ((*pos)->getName() == logger_name) { statsInfo->statsId = CORBA::string_dup((*pos)->stats.getStatisticsIdentification().c_str()); statsInfo->loggerName = CORBA::string_dup(logger_name); statsInfo->statsStatus = (*pos)->stats.getDisableStatistics(); statsInfo->statsPeriodConfiguration = (*pos)->stats.getStatisticsCalculationPeriod(); statsInfo->statsGranularityConfiguration = (*pos)->stats.getStatisticsGranularity(); } return statsInfo._retn(); } /* * @throw maciErrType::LoggerDoesNotExistEx */ void ContainerImpl::set_statistics_logger_configuration_byname(const char* logger_name, const Logging::ACSLogStatistics::LogStatsInformation& statsInformation) { ACS_TRACE("maci::ContainerImpl::set_statistics_logger_configuration_byname"); if(! Logging::Logger::getGlobalLogger()->exists(logger_name)) { Logging::LoggerDoesNotExistEx ex(logger_name); throw ex; } Logging::Logger::LoggerList::iterator pos; for (pos = ACE_Singleton::instance()->loggers_m.begin(); pos != ACE_Singleton::instance()->loggers_m.end(); pos++) if ((*pos)->getName() == logger_name) { (*pos)->stats.configureStatistics(std::string(statsInformation.statsId), statsInformation.statsStatus, statsInformation.statsPeriodConfiguration, statsInformation.statsGranularityConfiguration); } return; }