00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00036 #include "OW_config.h"
00037 #include "OW_CIMOMEnvironment.hpp"
00038 #include "OW_ConfigOpts.hpp"
00039 #include "OW_ConfigException.hpp"
00040 #include "OW_Format.hpp"
00041 #include "OW_FileSystem.hpp"
00042 #include "OW_SafeLibCreate.hpp"
00043 #include "OW_SelectEngine.hpp"
00044 #include "OW_CIMServer.hpp"
00045 #include "OW_CIMRepository.hpp"
00046 #include "OW_CIMInstance.hpp"
00047 #include "OW_CIMNameSpace.hpp"
00048 #include "OW_ServiceIFC.hpp"
00049 #include "OW_RequestHandlerIFC.hpp"
00050 #include "OW_IndicationServer.hpp"
00051 #include "OW_PollingManager.hpp"
00052 #include "OW_Assertion.hpp"
00053 #include "OW_AuthManager.hpp"
00054 #include "OW_LocalCIMOMHandle.hpp"
00055 #include "OW_WQLFilterRep.hpp"
00056 #include "OW_IndicationRepLayer.hpp"
00057 #include "OW_Platform.hpp"
00058 #include "OW_WQLIFC.hpp"
00059 #include "OW_SharedLibraryRepository.hpp"
00060 #include "OW_IndicationRepLayerMediator.hpp"
00061 #include "OW_OperationContext.hpp"
00062 #include "OW_Authorizer2IFC.hpp"
00063 #include "OW_ExceptionIds.hpp"
00064 #include "OW_CIMObjectPath.hpp"
00065 #include "OW_AuthorizerManager.hpp"
00066 #include "OW_AuthorizerIFC.hpp"
00067 #include "OW_Socket.hpp"
00068 #include "OW_LogAppender.hpp"
00069 #include "OW_AppenderLogger.hpp"
00070 #include "OW_CerrLogger.hpp"
00071 #include "OW_ProviderEnvironmentIFC.hpp"
00072 #include "OW_ProviderManager.hpp"
00073
00074 #include <iostream>
00075 #include <map>
00076 #include <set>
00077
00078 namespace OW_NAMESPACE
00079 {
00080
00081 OW_DECLARE_EXCEPTION(CIMOMEnvironment)
00082 OW_DEFINE_EXCEPTION_WITH_ID(CIMOMEnvironment)
00083
00084 using std::cerr;
00085 using std::endl;
00086
00087 namespace
00088 {
00089
00090 CIMOMEnvironmentRef theCimomEnvironment;
00091 }
00092
00093 CIMOMEnvironmentRef&
00094 CIMOMEnvironment::instance()
00095 {
00096 if (!theCimomEnvironment)
00097 {
00098 theCimomEnvironment = CIMOMEnvironmentRef(new CIMOMEnvironment);
00099 }
00100 return theCimomEnvironment;
00101 }
00102
00103 String CIMOMEnvironment::COMPONENT_NAME("ow.owcimomd");
00104
00105 namespace
00106 {
00107 class CIMOMProviderEnvironment : public ProviderEnvironmentIFC
00108 {
00109 public:
00110 CIMOMProviderEnvironment(CIMOMEnvironmentRef pCenv)
00111 : m_pCenv(pCenv)
00112 , m_context()
00113 {}
00114 virtual String getConfigItem(const String &name, const String& defRetVal="") const
00115 {
00116 return m_pCenv->getConfigItem(name, defRetVal);
00117 }
00118 virtual StringArray getMultiConfigItem(const String &itemName,
00119 const StringArray& defRetVal, const char* tokenizeSeparator) const
00120 {
00121 return m_pCenv->getMultiConfigItem(itemName, defRetVal, tokenizeSeparator);
00122 }
00123 virtual CIMOMHandleIFCRef getCIMOMHandle() const
00124 {
00125 OW_ASSERT("Cannot call CIMOMProviderEnvironment::getCIMOMHandle()" == 0);
00126 return CIMOMHandleIFCRef();
00127 }
00128
00129 virtual CIMOMHandleIFCRef getRepositoryCIMOMHandle() const
00130 {
00131 OW_ASSERT("Cannot call CIMOMProviderEnvironment::getRepositoryCIMOMHandle()" == 0);
00132 return CIMOMHandleIFCRef();
00133 }
00134
00135 virtual RepositoryIFCRef getRepository() const
00136 {
00137 return m_pCenv->getRepository();
00138 }
00139 virtual LoggerRef getLogger() const
00140 {
00141 return m_pCenv->getLogger();
00142 }
00143 virtual LoggerRef getLogger(const String& componentName) const
00144 {
00145 return m_pCenv->getLogger(componentName);
00146 }
00147 virtual String getUserName() const
00148 {
00149 return Platform::getCurrentUserName();
00150 }
00151 virtual OperationContext& getOperationContext()
00152 {
00153 return m_context;
00154 }
00155 virtual ProviderEnvironmentIFCRef clone() const
00156 {
00157 return ProviderEnvironmentIFCRef(new CIMOMProviderEnvironment(m_pCenv));
00158 }
00159 private:
00160 CIMOMEnvironmentRef m_pCenv;
00161 OperationContext m_context;
00162 };
00163 ProviderEnvironmentIFCRef createProvEnvRef(const CIMOMEnvironmentRef& pcenv)
00164 {
00165 return ProviderEnvironmentIFCRef(new CIMOMProviderEnvironment(pcenv));
00166 }
00167 }
00169
00170
00171 CIMOMEnvironment::CIMOMEnvironment()
00172 : m_Logger(new CerrLogger)
00173 , m_configItems(new ConfigMap)
00174 , m_indicationsDisabled(true)
00175 , m_indicationRepLayerDisabled(false)
00176 , m_state(E_STATE_INVALID)
00177 , m_indicationRepLayerMediatorRef(new IndicationRepLayerMediator)
00178 {
00179 }
00181 CIMOMEnvironment::~CIMOMEnvironment()
00182 {
00183 try
00184 {
00185 try
00186 {
00187 if (isLoaded(m_state))
00188 {
00189 shutdown();
00190 }
00191 }
00192 catch(Exception& e)
00193 {
00194 cerr << e << endl;
00195 }
00196 m_configItems = 0;
00197 m_state = E_STATE_INVALID;
00198 }
00199 catch (Exception& e)
00200 {
00201 OW_LOG_ERROR(m_Logger, Format("Caught exception in CIMOMEnvironment::~CIMOMEnvironment(): %1", e));
00202 }
00203 catch (...)
00204 {
00205
00206 }
00207 }
00209 void
00210 CIMOMEnvironment::init()
00211 {
00212
00213 _clearSelectables();
00214
00215
00216 _loadConfigItemsFromFile(getConfigItem(ConfigOpts::CONFIG_FILE_opt, OW_DEFAULT_CONFIG_FILE));
00217
00218
00219 _createLogger();
00220 }
00222 void
00223 CIMOMEnvironment::startServices()
00224 {
00225
00226
00227
00228
00229
00230
00231
00232
00233 Socket::createShutDownMechanism();
00234
00235
00236 OW_LOG_DEBUG(m_Logger, "CIMOMEnvironment loading services");
00237
00238 m_authorizerManager = new AuthorizerManager;
00239 m_services.push_back(ServiceIFCRef(SharedLibraryRef(), m_authorizerManager));
00240
00241 m_providerManager = new ProviderManager;
00242 m_providerManager->load(ProviderIFCLoader::createProviderIFCLoader(
00243 this), this);
00244 m_services.push_back(ServiceIFCRef(SharedLibraryRef(), m_providerManager));
00245
00246 m_cimRepository = new CIMRepository;
00247 m_services.push_back(ServiceIFCRef(SharedLibraryRef(), m_cimRepository));
00248
00249 m_cimServer = RepositoryIFCRef(new CIMServer(this,
00250 m_providerManager, m_cimRepository, m_authorizerManager));
00251 m_services.push_back(ServiceIFCRef(SharedLibraryRef(), m_cimServer));
00252
00253 _loadAuthorizer();
00254 _createAuthorizerManager();
00255 _createAuthManager();
00256 _loadRequestHandlers();
00257 _loadServices();
00258 if (!getConfigItem(ConfigOpts::HTTP_SERVER_SINGLE_THREAD_opt).equalsIgnoreCase("true"))
00259 {
00260 _createPollingManager();
00261 _createIndicationServer();
00262 }
00263
00264 OW_LOG_DEBUG(m_Logger, "CIMOMEnvironment finished loading services");
00265
00266 _sortServicesForDependencies();
00267
00268
00269
00270 OW_LOG_DEBUG(m_Logger, "CIMOMEnvironment initializing services");
00271
00272 {
00273 MutexLock l(m_stateGuard);
00274 m_state = E_STATE_INITIALIZING;
00275 }
00276
00277 for (size_t i = 0; i < m_services.size(); i++)
00278 {
00279 OW_LOG_DEBUG(m_Logger, Format("CIMOM initializing service: %1", m_services[i]->getName()));
00280 m_services[i]->init(this);
00281 }
00282 {
00283 MutexLock l(m_stateGuard);
00284 m_state = E_STATE_INITIALIZED;
00285 }
00286
00287 for (size_t i = 0; i < m_services.size(); i++)
00288 {
00289 OW_LOG_DEBUG(m_Logger, Format("CIMOM calling initialized() for service: %1", m_services[i]->getName()));
00290 m_services[i]->initialized();
00291 }
00292
00293 OW_LOG_DEBUG(m_Logger, "CIMOMEnvironment finished initializing services");
00294
00295
00296 OW_LOG_DEBUG(m_Logger, "CIMOMEnvironment starting services");
00297 {
00298 MutexLock l(m_stateGuard);
00299 m_state = E_STATE_STARTING;
00300 }
00301
00302 for (size_t i = 0; i < m_services.size(); i++)
00303 {
00304 OW_LOG_DEBUG(m_Logger, Format("CIMOM starting service: %1", m_services[i]->getName()));
00305 m_services[i]->start();
00306 }
00307 {
00308 MutexLock l(m_stateGuard);
00309 m_state = E_STATE_STARTED;
00310 }
00311
00312 for (size_t i = 0; i < m_services.size(); i++)
00313 {
00314 OW_LOG_DEBUG(m_Logger, Format("CIMOM calling started() for service: %1", m_services[i]->getName()));
00315 m_services[i]->started();
00316 }
00317
00318 OW_LOG_DEBUG(m_Logger, "CIMOMEnvironment finished starting services");
00319 }
00321 void
00322 CIMOMEnvironment::shutdown()
00323 {
00324
00325
00326 OW_LOG_DEBUG(m_Logger, "CIMOMEnvironment notifying services of shutdown");
00327
00328 for (int i = int(m_services.size())-1; i >= 0; i--)
00329 {
00330 try
00331 {
00332 OW_LOG_DEBUG(m_Logger, Format("CIMOMEnvironment notifying service: %1", m_services[i]->getName()));
00333 m_services[i]->shuttingDown();
00334 }
00335 catch (Exception& e)
00336 {
00337 OW_LOG_ERROR(m_Logger, Format("Caught exception while calling shuttingDown(): %1", e));
00338 }
00339 catch (...)
00340 {
00341 }
00342 }
00343
00344
00345 OW_LOG_DEBUG(m_Logger, "CIMOMEnvironment beginning shutdown process");
00346 {
00347 MutexLock l(m_stateGuard);
00348 m_state = E_STATE_SHUTTING_DOWN;
00349 }
00350
00351 OW_LOG_DEBUG(m_Logger, "CIMOMEnvironment shutting down sockets");
00352
00353 Socket::shutdownAllSockets();
00354
00355
00356 OW_LOG_DEBUG(m_Logger, "CIMOMEnvironment shutting down services");
00357
00358 for (int i = int(m_services.size())-1; i >= 0; i--)
00359 {
00360 try
00361 {
00362 OW_LOG_DEBUG(m_Logger, Format("CIMOMEnvironment shutting down service: %1", m_services[i]->getName()));
00363 m_services[i]->shutdown();
00364 }
00365 catch (Exception& e)
00366 {
00367 OW_LOG_ERROR(m_Logger, Format("Caught exception while calling shutdown(): %1", e));
00368 }
00369 catch (...)
00370 {
00371 }
00372 }
00373
00374 {
00375 MutexLock l(m_stateGuard);
00376 m_state = E_STATE_SHUTDOWN;
00377 }
00378
00379
00380
00381
00382 MutexLock ml(m_monitor);
00383
00384 OW_LOG_DEBUG(m_Logger, "CIMOMEnvironment unloading and deleting services");
00385
00386 m_pollingManager = 0;
00387
00388
00389 try
00390 {
00391 _clearSelectables();
00392 }
00393 catch (Exception& e)
00394 {
00395 OW_LOG_ERROR(m_Logger, Format("Caught exception while calling _clearSelectables(): %1", e));
00396 }
00397 catch(...)
00398 {
00399 }
00400
00401
00402
00403
00404 for (int i = int(m_services.size())-1; i >= 0; i--)
00405 {
00406 m_services[i].setNull();
00407 }
00408 m_services.clear();
00409
00410 m_reqHandlers.clear();
00411
00412 m_wqlLib = 0;
00413
00414 if (m_indicationServer)
00415 {
00416 m_indicationServer.setNull();
00417 m_indicationRepLayerLib = 0;
00418 }
00419
00420 m_authManager = 0;
00421
00422 m_cimServer = 0;
00423
00424 m_cimRepository = 0;
00425
00426 m_authorizerManager = 0;
00427
00428 m_providerManager = 0;
00429
00430 {
00431 MutexLock l(m_stateGuard);
00432 m_state = E_STATE_UNLOADED;
00433 }
00434
00435 OW_LOG_DEBUG(m_Logger, "CIMOMEnvironment has shut down");
00436 }
00438 ProviderManagerRef
00439 CIMOMEnvironment::getProviderManager() const
00440 {
00441 {
00442 MutexLock l(m_stateGuard);
00443 if (!isLoaded(m_state))
00444 {
00445 OW_THROW(CIMOMEnvironmentException, "CIMOMEnvironment::getProviderManager() called when state is not constructed");
00446 }
00447 }
00448 OW_ASSERT(m_providerManager);
00449 return m_providerManager;
00450 }
00452 void
00453 CIMOMEnvironment::_createAuthManager()
00454 {
00455 m_authManager = AuthManagerRef(new AuthManager);
00456 m_services.push_back(ServiceIFCRef(SharedLibraryRef(), m_authManager));
00457 }
00459 void
00460 CIMOMEnvironment::_createPollingManager()
00461 {
00462 m_pollingManager = PollingManagerRef(new PollingManager(m_providerManager));
00463 m_services.push_back(ServiceIFCRef(SharedLibraryRef(), m_pollingManager));
00464 }
00466 void
00467 CIMOMEnvironment::_createIndicationServer()
00468 {
00469
00470 m_indicationsDisabled = getConfigItem(
00471 ConfigOpts::DISABLE_INDICATIONS_opt, OW_DEFAULT_DISABLE_INDICATIONS).equalsIgnoreCase("true");
00472 if (!m_indicationsDisabled)
00473 {
00474
00475 String indicationLib = getConfigItem(ConfigOpts::OWLIBDIR_opt, OW_DEFAULT_OWLIBDIR);
00476 if (!indicationLib.endsWith(OW_FILENAME_SEPARATOR))
00477 {
00478 indicationLib += OW_FILENAME_SEPARATOR;
00479 }
00480 indicationLib += "libowindicationserver"OW_SHAREDLIB_EXTENSION;
00481 m_indicationServer = SafeLibCreate<IndicationServer>::loadAndCreateObject(
00482 indicationLib, "createIndicationServer", getLogger(COMPONENT_NAME));
00483 if (!m_indicationServer)
00484 {
00485
00486 OW_LOG_FATAL_ERROR(m_Logger, Format("CIMOM Failed to load indication server"
00487 " from library %1. Indication are currently DISABLED!",
00488 indicationLib));
00489 OW_THROW(CIMOMEnvironmentException, "Failed to load indication server");
00490 }
00491 m_services.push_back(m_indicationServer);
00492 }
00493 }
00495 void
00496 CIMOMEnvironment::_loadRequestHandlers()
00497 {
00498 m_reqHandlers.clear();
00499 int reqHandlerCount = 0;
00500 const StringArray libPaths = getMultiConfigItem(
00501 ConfigOpts::REQUEST_HANDLER_PATH_opt,
00502 String(OW_DEFAULT_REQUEST_HANDLER_PATH).tokenize(OW_PATHNAME_SEPARATOR),
00503 OW_PATHNAME_SEPARATOR);
00504 for (size_t i = 0; i < libPaths.size(); ++i)
00505 {
00506 String libPath(libPaths[i]);
00507 if (!libPath.endsWith(OW_FILENAME_SEPARATOR))
00508 {
00509 libPath += OW_FILENAME_SEPARATOR;
00510 }
00511 OW_LOG_INFO(m_Logger, Format("CIMOM loading request handlers from"
00512 " directory %1", libPath));
00513 StringArray dirEntries;
00514 if (!FileSystem::getDirectoryContents(libPath, dirEntries))
00515 {
00516 OW_LOG_FATAL_ERROR(m_Logger, Format("CIMOM failed getting the contents of the"
00517 " request handler directory: %1", libPath));
00518 OW_THROW(CIMOMEnvironmentException, "No RequestHandlers");
00519 }
00520 for (size_t i = 0; i < dirEntries.size(); i++)
00521 {
00522 if (!dirEntries[i].endsWith(OW_SHAREDLIB_EXTENSION))
00523 {
00524 continue;
00525 }
00526 #ifdef OW_DARWIN
00527 if (dirEntries[i].indexOf(OW_VERSION) != String::npos)
00528 {
00529 continue;
00530 }
00531 #endif // OW_DARWIN
00532 String libName = libPath;
00533 libName += dirEntries[i];
00534 RequestHandlerIFCRef rh =
00535 SafeLibCreate<RequestHandlerIFC>::loadAndCreateObject(
00536 libName, "createRequestHandler", getLogger(COMPONENT_NAME));
00537 if (rh)
00538 {
00539 ++reqHandlerCount;
00540 rh->setEnvironment(this);
00541 StringArray supportedContentTypes = rh->getSupportedContentTypes();
00542 OW_LOG_INFO(m_Logger, Format("CIMOM loaded request handler from file: %1",
00543 libName));
00544
00545 ReqHandlerDataRef rqData(new ReqHandlerData);
00546 rqData->filename = libName;
00547 rqData->rqIFCRef = rh;
00548 rqData->dt.setToCurrent();
00549 for (StringArray::const_iterator iter = supportedContentTypes.begin();
00550 iter != supportedContentTypes.end(); iter++)
00551 {
00552 MutexLock ml(m_reqHandlersLock);
00553 m_reqHandlers[(*iter)] = rqData;
00554 ml.release();
00555 OW_LOG_INFO(m_Logger, Format(
00556 "CIMOM associating Content-Type %1 with Request Handler %2",
00557 *iter, libName));
00558 }
00559 m_services.push_back(rh);
00560 }
00561 else
00562 {
00563 OW_LOG_FATAL_ERROR(m_Logger, Format("CIMOM failed to load request handler from file:"
00564 " %1", libName));
00565 OW_THROW(CIMOMEnvironmentException, "Invalid request handler");
00566 }
00567 }
00568 }
00569 OW_LOG_INFO(m_Logger, Format("CIMOM: Handling %1 Content-Types from %2 Request Handlers",
00570 m_reqHandlers.size(), reqHandlerCount));
00571 }
00573 void
00574 CIMOMEnvironment::_loadServices()
00575 {
00576 const StringArray libPaths = getMultiConfigItem(
00577 ConfigOpts::SERVICES_PATH_opt, String(OW_DEFAULT_SERVICES_PATH).tokenize(OW_PATHNAME_SEPARATOR), OW_PATHNAME_SEPARATOR);
00578 for (size_t i = 0; i < libPaths.size(); ++i)
00579 {
00580 String libPath(libPaths[i]);
00581 if (!libPath.endsWith(OW_FILENAME_SEPARATOR))
00582 {
00583 libPath += OW_FILENAME_SEPARATOR;
00584 }
00585 OW_LOG_INFO(m_Logger, Format("CIMOM loading services from directory %1",
00586 libPath));
00587 StringArray dirEntries;
00588 if (!FileSystem::getDirectoryContents(libPath, dirEntries))
00589 {
00590 OW_LOG_FATAL_ERROR(m_Logger, Format("CIMOM failed getting the contents of the"
00591 " services directory: %1", libPath));
00592 OW_THROW(CIMOMEnvironmentException, "No Services");
00593 }
00594 for (size_t i = 0; i < dirEntries.size(); i++)
00595 {
00596 if (!dirEntries[i].endsWith(OW_SHAREDLIB_EXTENSION))
00597 {
00598 continue;
00599 }
00600 #ifdef OW_DARWIN
00601 if (dirEntries[i].indexOf(OW_VERSION) != String::npos)
00602 {
00603 continue;
00604 }
00605 #endif // OW_DARWIN
00606 String libName = libPath;
00607 libName += dirEntries[i];
00608 ServiceIFCRef srv =
00609 SafeLibCreate<ServiceIFC>::loadAndCreateObject(libName,
00610 "createService", getLogger(COMPONENT_NAME));
00611 if (srv)
00612 {
00613 m_services.push_back(srv);
00614 OW_LOG_INFO(m_Logger, Format("CIMOM loaded service from file: %1", libName));
00615 }
00616 else
00617 {
00618 OW_LOG_FATAL_ERROR(m_Logger, Format("CIMOM failed to load service from library: %1",
00619 libName));
00620 OW_THROW(CIMOMEnvironmentException, "Invalid service");
00621 }
00622 }
00623 }
00624 OW_LOG_INFO(m_Logger, Format("CIMOM: Number of services loaded: %1",
00625 m_services.size()));
00626 }
00627
00629 namespace
00630 {
00631 LogAppender::ConfigMap getAppenderConfig(const ConfigFile::ConfigMap& configItems)
00632 {
00633 LogAppender::ConfigMap appenderConfig;
00634 for (ConfigFile::ConfigMap::const_iterator iter = configItems.begin(); iter != configItems.end(); ++iter)
00635 {
00636 if (iter->first.startsWith("log") && iter->second.size() > 0)
00637 {
00638 appenderConfig[iter->first] = iter->second.back().value;
00639 }
00640 }
00641 return appenderConfig;
00642 }
00643
00644 }
00646 void
00647 CIMOMEnvironment::_createLogger()
00648 {
00649 using namespace ConfigOpts;
00650 Array<LogAppenderRef> appenders;
00651
00652 StringArray additionalLogs = getMultiConfigItem(ADDITIONAL_LOGS_opt, StringArray(), " \t");
00653
00654
00655 bool debugFlag = getConfigItem(DEBUGFLAG_opt, OW_DEFAULT_DEBUGFLAG).equalsIgnoreCase("true");
00656 if ( debugFlag )
00657 {
00658
00659 additionalLogs.insert(additionalLogs.begin(), LOG_DEBUG_LOG_NAME);
00660 }
00661
00662 for (size_t i = 0; i < additionalLogs.size(); ++i)
00663 {
00664 const String& logName(additionalLogs[i]);
00665
00666 String logMainType = getConfigItem(Format(LOG_1_TYPE_opt, logName), OW_DEFAULT_LOG_1_TYPE);
00667 String logMainComponents = getConfigItem(Format(LOG_1_COMPONENTS_opt, logName), OW_DEFAULT_LOG_1_COMPONENTS);
00668 String logMainCategories = getConfigItem(Format(LOG_1_CATEGORIES_opt, logName));
00669 if (logMainCategories.empty())
00670 {
00671
00672 String logMainLevel = getConfigItem(Format(LOG_1_LEVEL_opt, logName), OW_DEFAULT_LOG_1_LEVEL);
00673 if (logMainLevel.equalsIgnoreCase(Logger::STR_DEBUG_CATEGORY))
00674 {
00675 logMainCategories = Logger::STR_DEBUG_CATEGORY + " " + Logger::STR_INFO_CATEGORY + " " + Logger::STR_ERROR_CATEGORY + " " + Logger::STR_FATAL_CATEGORY;
00676 }
00677 else if (logMainLevel.equalsIgnoreCase(Logger::STR_INFO_CATEGORY))
00678 {
00679 logMainCategories = Logger::STR_INFO_CATEGORY + " " + Logger::STR_ERROR_CATEGORY + " " + Logger::STR_FATAL_CATEGORY;
00680 }
00681 else if (logMainLevel.equalsIgnoreCase(Logger::STR_ERROR_CATEGORY))
00682 {
00683 logMainCategories = Logger::STR_ERROR_CATEGORY + " " + Logger::STR_FATAL_CATEGORY;
00684 }
00685 else if (logMainLevel.equalsIgnoreCase(Logger::STR_FATAL_CATEGORY))
00686 {
00687 logMainCategories = Logger::STR_FATAL_CATEGORY;
00688 }
00689 }
00690 String logMainFormat = getConfigItem(Format(LOG_1_FORMAT_opt, logName), OW_DEFAULT_LOG_1_FORMAT);
00691
00692 appenders.push_back(LogAppender::createLogAppender(logName, logMainComponents.tokenize(), logMainCategories.tokenize(),
00693 logMainFormat, logMainType, getAppenderConfig(*m_configItems)));
00694 }
00695
00696
00697
00698
00699 String logName(LOG_MAIN_LOG_NAME);
00700 String logMainType = getConfigItem(Format(LOG_1_TYPE_opt, logName));
00701 String logMainComponents = getConfigItem(Format(LOG_1_COMPONENTS_opt, logName), OW_DEFAULT_LOG_1_COMPONENTS);
00702 String logMainCategories = getConfigItem(Format(LOG_1_CATEGORIES_opt, logName));
00703 String logMainLevel = getConfigItem(Format(LOG_1_LEVEL_opt, logName));
00704 String logMainFormat = getConfigItem(Format(LOG_1_FORMAT_opt, logName), OW_DEFAULT_LOG_1_FORMAT);
00705
00706
00707 if (logMainType.empty())
00708 {
00709 String deprecatedLogLocation = getConfigItem(ConfigOpts::LOG_LOCATION_opt, OW_DEFAULT_LOG_LOCATION);
00710 if (deprecatedLogLocation.empty() || deprecatedLogLocation.equalsIgnoreCase("syslog"))
00711 {
00712 logMainType = "syslog";
00713 }
00714 else if (deprecatedLogLocation.equalsIgnoreCase("null"))
00715 {
00716 logMainType = "null";
00717 }
00718 else
00719 {
00720 logMainType = "file";
00721 setConfigItem(Format(LOG_1_LOCATION_opt, logName), deprecatedLogLocation);
00722 }
00723 }
00724
00725
00726 if (logMainCategories.empty() && logMainLevel.empty())
00727 {
00728 String deprecatedLogLevel = getConfigItem(ConfigOpts::LOG_LEVEL_opt);
00729 if (deprecatedLogLevel.empty())
00730 {
00731 logMainLevel = OW_DEFAULT_LOG_1_LEVEL;
00732 }
00733 else
00734 {
00735
00736 if (deprecatedLogLevel.equalsIgnoreCase("fatalerror"))
00737 {
00738 logMainLevel = Logger::STR_FATAL_CATEGORY;
00739 }
00740 else
00741 {
00742 deprecatedLogLevel.toUpperCase();
00743 logMainLevel = deprecatedLogLevel;
00744 }
00745 }
00746 }
00747
00748
00749 if (logMainCategories.empty())
00750 {
00751
00752 String logMainLevel = getConfigItem(Format(LOG_1_LEVEL_opt, logName), OW_DEFAULT_LOG_1_LEVEL);
00753 if (logMainLevel.equalsIgnoreCase(Logger::STR_DEBUG_CATEGORY))
00754 {
00755 logMainCategories = Logger::STR_DEBUG_CATEGORY + " " + Logger::STR_INFO_CATEGORY + " " + Logger::STR_ERROR_CATEGORY + " " + Logger::STR_FATAL_CATEGORY;
00756 }
00757 else if (logMainLevel.equalsIgnoreCase(Logger::STR_INFO_CATEGORY))
00758 {
00759 logMainCategories = Logger::STR_INFO_CATEGORY + " " + Logger::STR_ERROR_CATEGORY + " " + Logger::STR_FATAL_CATEGORY;
00760 }
00761 else if (logMainLevel.equalsIgnoreCase(Logger::STR_ERROR_CATEGORY))
00762 {
00763 logMainCategories = Logger::STR_ERROR_CATEGORY + " " + Logger::STR_FATAL_CATEGORY;
00764 }
00765 else if (logMainLevel.equalsIgnoreCase(Logger::STR_FATAL_CATEGORY))
00766 {
00767 logMainCategories = Logger::STR_FATAL_CATEGORY;
00768 }
00769 }
00770
00771 appenders.push_back(LogAppender::createLogAppender(logName, logMainComponents.tokenize(), logMainCategories.tokenize(),
00772 logMainFormat, logMainType, getAppenderConfig(*m_configItems)));
00773
00774
00775 m_Logger = new AppenderLogger(COMPONENT_NAME, appenders);
00776 }
00778 void
00779 CIMOMEnvironment::_loadConfigItemsFromFile(const String& filename)
00780 {
00781 OW_LOG_DEBUG(m_Logger, "\nUsing config file: " + filename);
00782 ConfigFile::loadConfigFile(filename, *m_configItems);
00783 StringArray configDirs = ConfigFile::getMultiConfigItem(*m_configItems,
00784 ConfigOpts::ADDITIONAL_CONFIG_FILES_DIRS_opt,
00785 String(OW_DEFAULT_ADDITIONAL_CONFIG_FILES_DIRS).tokenize(OW_PATHNAME_SEPARATOR),
00786 OW_PATHNAME_SEPARATOR);
00787 }
00789 bool
00790 CIMOMEnvironment::authenticate(String &userName, const String &info,
00791 String &details, OperationContext& context) const
00792 {
00793 {
00794 MutexLock l(m_stateGuard);
00795 if (!isInitialized(m_state))
00796 {
00797 return false;
00798 }
00799 }
00800 MutexLock ml(m_monitor);
00801 OW_ASSERT(m_authManager);
00802 return m_authManager->authenticate(userName, info, details, context);
00803 }
00805 String
00806 CIMOMEnvironment::getConfigItem(const String &name, const String& defRetVal) const
00807 {
00808 return ConfigFile::getConfigItem(*m_configItems, name, defRetVal);
00809 }
00810
00812 StringArray
00813 CIMOMEnvironment::getMultiConfigItem(const String &itemName,
00814 const StringArray& defRetVal, const char* tokenizeSeparator) const
00815 {
00816 return ConfigFile::getMultiConfigItem(*m_configItems, itemName, defRetVal, tokenizeSeparator);
00817 }
00818
00820 CIMOMHandleIFCRef
00821 CIMOMEnvironment::getWQLFilterCIMOMHandle(const CIMInstance& inst,
00822 OperationContext& context) const
00823 {
00824 {
00825 MutexLock l(m_stateGuard);
00826 if (!isLoaded(m_state))
00827 {
00828 OW_THROW(CIMOMEnvironmentException, "CIMOMEnvironment::getWQLFilterCIMOMHandle() called when state is not initialized");
00829 }
00830 }
00831 OW_ASSERT(m_cimServer);
00832 return CIMOMHandleIFCRef(new LocalCIMOMHandle(
00833 const_cast<CIMOMEnvironment *>(this),
00834 RepositoryIFCRef(new WQLFilterRep(inst, m_cimServer)), context));
00835 }
00836
00838 CIMOMHandleIFCRef
00839 CIMOMEnvironment::getCIMOMHandle(OperationContext& context,
00840 EBypassProvidersFlag bypassProviders,
00841 ELockingFlag locking) const
00842 {
00843 return getCIMOMHandle(context, E_SEND_INDICATIONS, bypassProviders, locking);
00844 }
00845
00847 CIMOMHandleIFCRef
00848 CIMOMEnvironment::getCIMOMHandle(OperationContext& context,
00849 ESendIndicationsFlag sendIndications,
00850 EBypassProvidersFlag bypassProviders,
00851 ELockingFlag locking) const
00852 {
00853 {
00854 MutexLock l(m_stateGuard);
00855 if (!isLoaded(m_state))
00856 {
00857 OW_THROW(CIMOMEnvironmentException, "CIMOMEnvironment::getCIMOMHandle() called when state is not loaded.");
00858 }
00859 }
00860 MutexLock ml(m_monitor);
00861 OW_ASSERT(m_cimServer);
00862
00863
00864
00865
00866 RepositoryIFCRef rref;
00867 if (bypassProviders == E_BYPASS_PROVIDERS)
00868 {
00869 rref = m_cimRepository;
00870 }
00871 else
00872 {
00873 rref = m_cimServer;
00874 }
00875
00876 if (sendIndications == E_SEND_INDICATIONS && m_indicationServer && !m_indicationsDisabled)
00877 {
00878 SharedLibraryRepositoryIFCRef irl = _getIndicationRepLayer(rref);
00879 if (irl)
00880 {
00881 rref = RepositoryIFCRef(new SharedLibraryRepository(irl));
00882 }
00883 }
00884 if (m_authorizer)
00885 {
00886 AuthorizerIFC* p = m_authorizer->clone();
00887 p->setSubRepositoryIFC(rref);
00888 rref = RepositoryIFCRef(new SharedLibraryRepository(SharedLibraryRepositoryIFCRef(m_authorizer.getLibRef(), RepositoryIFCRef(p))));
00889 }
00890
00891 return CIMOMHandleIFCRef(new LocalCIMOMHandle(const_cast<CIMOMEnvironment*>(this), rref,
00892 context, locking == E_LOCKING ? LocalCIMOMHandle::E_LOCKING : LocalCIMOMHandle::E_NO_LOCKING));
00893 }
00895 WQLIFCRef
00896 CIMOMEnvironment::getWQLRef() const
00897 {
00898 {
00899 MutexLock l(m_stateGuard);
00900 if (!isLoaded(m_state))
00901 {
00902 OW_THROW(CIMOMEnvironmentException, "CIMOMEnvironment::getWQLRef() called when state is not loaded");
00903 }
00904 }
00905 MutexLock ml(m_monitor);
00906 if (!m_wqlLib)
00907 {
00908 String libname = getConfigItem(ConfigOpts::WQL_LIB_opt, OW_DEFAULT_WQL_LIB);
00909 OW_LOG_DEBUG(m_Logger, Format("CIMOM loading wql library %1", libname));
00910 SharedLibraryLoaderRef sll =
00911 SharedLibraryLoader::createSharedLibraryLoader();
00912 m_wqlLib = sll->loadSharedLibrary(libname, m_Logger);
00913 if (!m_wqlLib)
00914 {
00915 OW_LOG_ERROR(m_Logger, Format("CIMOM Failed to load WQL Libary: %1", libname));
00916 return WQLIFCRef();
00917 }
00918 }
00919 return WQLIFCRef(m_wqlLib, SafeLibCreate<WQLIFC>::create(
00920 m_wqlLib, "createWQL", m_Logger));
00921 }
00923 SharedLibraryRepositoryIFCRef
00924 CIMOMEnvironment::_getIndicationRepLayer(const RepositoryIFCRef& rref) const
00925 {
00926 SharedLibraryRepositoryIFCRef retref;
00927 if (!m_indicationRepLayerDisabled)
00928 {
00929 MutexLock ml(m_indicationLock);
00930 if (!m_indicationRepLayerLib)
00931 {
00932 const String libPath = getConfigItem(ConfigOpts::OWLIBDIR_opt, OW_DEFAULT_OWLIBDIR) + OW_FILENAME_SEPARATOR;
00933 const String libBase = "libowindicationreplayer";
00934 String libname = libPath + libBase + OW_SHAREDLIB_EXTENSION;
00935 OW_LOG_DEBUG(m_Logger, Format("CIMOM loading indication libary %1",
00936 libname));
00937 SharedLibraryLoaderRef sll =
00938 SharedLibraryLoader::createSharedLibraryLoader();
00939
00940 if (!sll)
00941 {
00942 m_indicationRepLayerDisabled = true;
00943 OW_LOG_FATAL_ERROR(m_Logger, Format("CIMOM failed to create SharedLibraryLoader"
00944 " library %1", libname));
00945 return retref;
00946 }
00947 m_indicationRepLayerLib = sll->loadSharedLibrary(libname, m_Logger);
00948 if (!m_indicationRepLayerLib)
00949 {
00950 m_indicationRepLayerDisabled = true;
00951 OW_LOG_FATAL_ERROR(m_Logger, Format("CIMOM failed to load indication rep layer"
00952 " library %1", libname));
00953 return retref;
00954 }
00955 }
00956 IndicationRepLayer* pirep =
00957 SafeLibCreate<IndicationRepLayer>::create(
00958 m_indicationRepLayerLib, "createIndicationRepLayer", m_Logger);
00959 if (pirep)
00960 {
00961 retref = SharedLibraryRepositoryIFCRef(m_indicationRepLayerLib,
00962 RepositoryIFCRef(pirep));
00963 pirep->setCIMServer(rref);
00964 }
00965 else
00966 {
00967 m_indicationRepLayerDisabled = true;
00968 m_indicationRepLayerLib = 0;
00969 }
00970 }
00971 return retref;
00972 }
00973
00975 void
00976 CIMOMEnvironment::_loadAuthorizer()
00977 {
00978 OW_ASSERT(!m_authorizer);
00979 String libname = getConfigItem(ConfigOpts::AUTHORIZATION_LIB_opt);
00980
00981
00982 if (libname.empty())
00983 {
00984 return;
00985 }
00986
00987 OW_LOG_DEBUG(m_Logger, Format("CIMOM loading authorization libary %1",
00988 libname));
00989 SharedLibraryLoaderRef sll =
00990 SharedLibraryLoader::createSharedLibraryLoader();
00991 if (!sll)
00992 {
00993 String msg = Format("CIMOM failed to create SharedLibraryLoader."
00994 " library %1", libname);
00995 OW_LOG_FATAL_ERROR(m_Logger, msg);
00996 OW_THROW(CIMOMEnvironmentException, msg.c_str());
00997 }
00998 SharedLibraryRef authorizerLib = sll->loadSharedLibrary(libname, m_Logger);
00999 if (!authorizerLib)
01000 {
01001 String msg = Format("CIMOM failed to load authorization"
01002 " library %1", libname);
01003 OW_LOG_FATAL_ERROR(m_Logger, msg);
01004 OW_THROW(CIMOMEnvironmentException, msg.c_str());
01005 }
01006 AuthorizerIFC* p =
01007 SafeLibCreate<AuthorizerIFC>::create(
01008 authorizerLib, "createAuthorizer", m_Logger);
01009 if (!p)
01010 {
01011 String msg = Format("CIMOM failed to load authorization"
01012 " library %1", libname);
01013 OW_LOG_FATAL_ERROR(m_Logger, msg);
01014 OW_THROW(CIMOMEnvironmentException, msg.c_str());
01015 }
01016 m_authorizer = AuthorizerIFCRef(authorizerLib,
01017 AuthorizerIFCRef::element_type(p));
01018
01019 m_services.push_back(m_authorizer);
01020 }
01022 void
01023 CIMOMEnvironment::_createAuthorizerManager()
01024 {
01025
01026
01027
01028
01029 String libname = getConfigItem(ConfigOpts::AUTHORIZATION2_LIB_opt);
01030
01031
01032 if (libname.empty())
01033 {
01034 return;
01035 }
01036
01037 OW_LOG_DEBUG(m_Logger, Format("CIMOM loading authorization libary %1", libname));
01038
01039 SharedLibraryLoaderRef sll =
01040 SharedLibraryLoader::createSharedLibraryLoader();
01041 if (!sll)
01042 {
01043 String msg = Format("CIMOM failed to create SharedLibraryLoader."
01044 " library %1", libname);
01045 OW_LOG_FATAL_ERROR(m_Logger, msg);
01046 OW_THROW(CIMOMEnvironmentException, msg.c_str());
01047 }
01048 SharedLibraryRef authorizerLib = sll->loadSharedLibrary(libname, m_Logger);
01049 if (!authorizerLib)
01050 {
01051 String msg = Format("CIMOM failed to load authorization"
01052 " library %1", libname);
01053 OW_LOG_FATAL_ERROR(m_Logger, msg);
01054 OW_THROW(CIMOMEnvironmentException, msg.c_str());
01055 }
01056 Authorizer2IFC* p =
01057 SafeLibCreate<Authorizer2IFC>::create(
01058 authorizerLib, "createAuthorizer2", m_Logger);
01059 if (!p)
01060 {
01061 String msg = Format("CIMOM failed to load authorization"
01062 " library %1", libname);
01063 OW_LOG_FATAL_ERROR(m_Logger, msg);
01064 OW_THROW(CIMOMEnvironmentException, msg.c_str());
01065 }
01066
01067 m_authorizerManager->setAuthorizer(
01068 Authorizer2IFCRef(authorizerLib,Authorizer2IFCRef::element_type(p)));
01069 }
01071 RequestHandlerIFCRef
01072 CIMOMEnvironment::getRequestHandler(const String &id) const
01073 {
01074 RequestHandlerIFCRef ref;
01075 {
01076 MutexLock l(m_stateGuard);
01077 if (!isInitialized(m_state))
01078 {
01079 return ref;
01080 }
01081 }
01082 MutexLock ml(m_reqHandlersLock);
01083 ReqHandlerMap::iterator iter =
01084 m_reqHandlers.find(id);
01085 if (iter != m_reqHandlers.end())
01086 {
01087 if (!iter->second->rqIFCRef)
01088 {
01089 iter->second->rqIFCRef =
01090 SafeLibCreate<RequestHandlerIFC>::loadAndCreateObject(
01091 iter->second->filename, "createRequestHandler", getLogger(COMPONENT_NAME));
01092
01093
01094 m_services.push_back(iter->second->rqIFCRef);
01095 const_cast<CIMOMEnvironment*>(this)->_sortServicesForDependencies();
01096 }
01097 if (iter->second->rqIFCRef)
01098 {
01099 ref = RequestHandlerIFCRef(iter->second->rqIFCRef.getLibRef(),
01100 iter->second->rqIFCRef->clone());
01101 iter->second->dt.setToCurrent();
01102 ref->setEnvironment(const_cast<CIMOMEnvironment*>(this));
01103 OW_LOG_DEBUG(m_Logger, Format("Request Handler %1 handling request for content type %2",
01104 iter->second->filename, id));
01105 }
01106 else
01107 {
01108 OW_LOG_ERROR(m_Logger, Format(
01109 "Error loading request handler library %1 for content type %2",
01110 iter->second->filename, id));
01111 }
01112 }
01113 return ref;
01114 }
01116 void
01117 CIMOMEnvironment::unloadReqHandlers()
01118 {
01119
01120 Int32 ttl;
01121 try
01122 {
01123 ttl = getConfigItem(ConfigOpts::REQUEST_HANDLER_TTL_opt, OW_DEFAULT_REQUEST_HANDLER_TTL).toInt32();
01124 }
01125 catch (const StringConversionException&)
01126 {
01127 OW_LOG_ERROR(m_Logger, Format("Invalid value (%1) for %2 config item.",
01128 getConfigItem(ConfigOpts::REQUEST_HANDLER_TTL_opt, OW_DEFAULT_REQUEST_HANDLER_TTL),
01129 ConfigOpts::REQUEST_HANDLER_TTL_opt));
01130 }
01131 if (ttl < 0)
01132 {
01133 OW_LOG_DEBUG(m_Logger, "Non-Positive TTL for Request Handlers: OpenWBEM will not unload request handlers.");
01134 return;
01135 }
01136 DateTime dt;
01137 dt.setToCurrent();
01138 MutexLock ml(m_reqHandlersLock);
01139 for (ReqHandlerMap::iterator iter = m_reqHandlers.begin();
01140 iter != m_reqHandlers.end(); ++iter)
01141 {
01142 if (iter->second->rqIFCRef)
01143 {
01144 DateTime rqDT = iter->second->dt;
01145 rqDT.addMinutes(ttl);
01146 if (rqDT < dt)
01147 {
01148
01149 for (size_t i = 0; i < m_services.size(); ++i)
01150 {
01151 if (m_services[i].get() == iter->second->rqIFCRef.get())
01152 {
01153 m_services.remove(i);
01154 break;
01155 }
01156 }
01157 iter->second->rqIFCRef.setNull();
01158 OW_LOG_DEBUG(m_Logger, Format("Unloaded request handler lib %1 for content type %2",
01159 iter->second->filename, iter->first));
01160 }
01161 }
01162 }
01163 }
01165 LoggerRef
01166 CIMOMEnvironment::getLogger() const
01167 {
01168 OW_ASSERT(m_Logger);
01169 return m_Logger->clone();
01170 }
01172 LoggerRef
01173 CIMOMEnvironment::getLogger(const String& componentName) const
01174 {
01175 OW_ASSERT(m_Logger);
01176 LoggerRef rv(m_Logger->clone());
01177 rv->setDefaultComponent(componentName);
01178 return rv;
01179 }
01181 IndicationServerRef
01182 CIMOMEnvironment::getIndicationServer() const
01183 {
01184 return m_indicationServer;
01185 }
01187 PollingManagerRef
01188 CIMOMEnvironment::getPollingManager() const
01189 {
01190 return m_pollingManager;
01191 }
01193 void
01194 CIMOMEnvironment::clearConfigItems()
01195 {
01196 m_configItems->clear();
01197 }
01199 void
01200 CIMOMEnvironment::setConfigItem(const String &item,
01201 const String &value, EOverwritePreviousFlag overwritePrevious)
01202 {
01203 ConfigFile::setConfigItem(*m_configItems, item, value,
01204 overwritePrevious == E_OVERWRITE_PREVIOUS ? ConfigFile::E_OVERWRITE_PREVIOUS : ConfigFile::E_PRESERVE_PREVIOUS);
01205 }
01207 void
01208 CIMOMEnvironment::runSelectEngine() const
01209 {
01210 OW_ASSERT(m_selectables.size() == m_selectableCallbacks.size());
01211 SelectEngine engine;
01212
01213 engine.addSelectableObject(Platform::getSigSelectable(),
01214 SelectableCallbackIFCRef(new SelectEngineStopper(engine)));
01215
01216 for (size_t i = 0; i < m_selectables.size(); ++i)
01217 {
01218 engine.addSelectableObject(m_selectables[i], m_selectableCallbacks[i]);
01219 }
01220 engine.go();
01221 }
01223 void
01224 CIMOMEnvironment::_clearSelectables()
01225 {
01226 MutexLock ml(m_selectableLock);
01227 m_selectables.clear();
01228 m_selectableCallbacks.clear();
01229 }
01231 void
01232 CIMOMEnvironment::addSelectable(const SelectableIFCRef& obj,
01233 const SelectableCallbackIFCRef& cb)
01234 {
01235 MutexLock ml(m_selectableLock);
01236 m_selectables.push_back(obj);
01237 m_selectableCallbacks.push_back(cb);
01238 }
01240 void
01241 CIMOMEnvironment::removeSelectable(const SelectableIFCRef& obj)
01242 {
01243 MutexLock ml(m_selectableLock);
01244 for (size_t i = 0; i < m_selectables.size(); i++)
01245 {
01246 if (obj == m_selectables[i])
01247 {
01248 m_selectables.remove(i);
01249 m_selectableCallbacks.remove(i);
01250 --i;
01251 continue;
01252 }
01253 }
01254 }
01256 void
01257 CIMOMEnvironment::exportIndication(const CIMInstance& instance,
01258 const String& instNS)
01259 {
01260 OW_LOG_DEBUG(m_Logger, "CIMOMEnvironment::exportIndication");
01261 if (m_indicationServer && !m_indicationsDisabled)
01262 {
01263 OW_LOG_DEBUG(m_Logger, "CIMOMEnvironment::exportIndication - calling indication"
01264 " server");
01265 m_indicationServer->processIndication(instance, instNS);
01266 }
01267 }
01269 IndicationRepLayerMediatorRef
01270 CIMOMEnvironment::getIndicationRepLayerMediator() const
01271 {
01272 return m_indicationRepLayerMediatorRef;
01273 }
01275 RepositoryIFCRef
01276 CIMOMEnvironment::getRepository() const
01277 {
01278 return m_cimRepository;
01279 }
01281 AuthorizerManagerRef
01282 CIMOMEnvironment::getAuthorizerManager() const
01283 {
01284 return m_authorizerManager;
01285 }
01286
01288 void
01289 CIMOMEnvironment::unloadProviders()
01290 {
01291 m_providerManager->unloadProviders(createProvEnvRef(this));
01292 }
01293
01294 namespace
01295 {
01296
01298 struct Node
01299 {
01300 Node(const String& name_, size_t index_ = ~0)
01301 : name(name_)
01302 , index(index_)
01303 {}
01304
01305 String name;
01306 size_t index;
01307 };
01308
01310 bool operator!=(const Node& x, const Node& y)
01311 {
01312 return x.name != y.name;
01313 }
01314
01316 bool operator<(const Node& x, const Node& y)
01317 {
01318 return x.name < y.name;
01319 }
01320
01322 Node INVALID_NODE("", ~0);
01323
01325 class ServiceDependencyGraph
01326 {
01327 public:
01328
01329 bool addNode(const String& serviceName, size_t index);
01330
01331
01332 bool addDependency(const String& serviceName, const String& dependentServiceName);
01333 Node findIndependentNode() const;
01334 void removeNode(const String& serviceName);
01335 bool empty() const;
01336 Array<Node> getNodes() const;
01337
01338 private:
01339 typedef std::map<Node, std::set<String> > deps_t;
01340 deps_t m_deps;
01341 };
01342
01344 bool
01345 ServiceDependencyGraph::addNode(const String& serviceName, size_t index)
01346 {
01347 return m_deps.insert(std::make_pair(Node(serviceName, index), deps_t::mapped_type())).second;
01348 }
01349
01351 bool
01352 ServiceDependencyGraph::addDependency(const String& serviceName, const String& dependentServiceName)
01353 {
01354 return m_deps.find(serviceName)->second.insert(dependentServiceName).second;
01355 }
01356
01358 Node
01359 ServiceDependencyGraph::findIndependentNode() const
01360 {
01361 for (deps_t::const_iterator nodeiter(m_deps.begin()); nodeiter != m_deps.end(); ++nodeiter)
01362 {
01363 if (nodeiter->second.empty())
01364 {
01365 return nodeiter->first;
01366 }
01367 }
01368
01369
01370 return INVALID_NODE;
01371 }
01372
01374 void
01375 ServiceDependencyGraph::removeNode(const String& serviceName)
01376 {
01377
01378 for (deps_t::iterator nodeiter(m_deps.begin()); nodeiter != m_deps.end(); ++nodeiter)
01379 {
01380 nodeiter->second.erase(serviceName);
01381 }
01382 m_deps.erase(serviceName);
01383 }
01384
01386 bool
01387 ServiceDependencyGraph::empty() const
01388 {
01389 return m_deps.empty();
01390 }
01391
01393 Array<Node>
01394 ServiceDependencyGraph::getNodes() const
01395 {
01396 Array<Node> rv;
01397 rv.reserve(m_deps.size());
01398 for (deps_t::const_iterator nodeiter(m_deps.begin()); nodeiter != m_deps.end(); ++nodeiter)
01399 {
01400 rv.push_back(nodeiter->first);
01401 }
01402 return rv;
01403 }
01404
01405 }
01406
01408 void
01409 CIMOMEnvironment::_sortServicesForDependencies()
01410 {
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429 Array<ServiceIFCRef> sortedServices;
01430
01431
01432 ServiceDependencyGraph depGraph;
01433
01434 for (size_t i = 0; i < m_services.size(); ++i)
01435 {
01436 String name = m_services[i]->getName();
01437 if (name == "")
01438 {
01439
01440 sortedServices.push_back(m_services[i]);
01441 OW_LOG_DEBUG(m_Logger, "Found service with no name, adding to sortedServices");
01442 }
01443 else
01444 {
01445 OW_LOG_DEBUG(m_Logger, Format("Adding node for service %1", name));
01446 if (!depGraph.addNode(name, i))
01447 {
01448 OW_THROW(CIMOMEnvironmentException, Format("Invalid: 2 services with the same name: %1", name).c_str());
01449 }
01450
01451 }
01452 }
01453
01454
01455 for (size_t i = 0; i < m_services.size(); ++i)
01456 {
01457 String name = m_services[i]->getName();
01458 if (name != "")
01459 {
01460 StringArray deps(m_services[i]->getDependencies());
01461 for (size_t j = 0; j < deps.size(); ++j)
01462 {
01463 OW_LOG_DEBUG(m_Logger, Format("Adding dependency for service %1->%2", name, deps[j]));
01464 if (!depGraph.addDependency(name, deps[j]))
01465 {
01466 OW_THROW(CIMOMEnvironmentException, Format("Invalid: service %1 has duplicate dependencies: %2", name, deps[j]).c_str());
01467 }
01468 }
01469
01470
01471 StringArray dependentServices(m_services[i]->getDependentServices());
01472 for (size_t j = 0; j < dependentServices.size(); ++j)
01473 {
01474 OW_LOG_DEBUG(m_Logger, Format("Adding dependency for service %1->%2", dependentServices[j], name));
01475 if (!depGraph.addDependency(dependentServices[j], name))
01476 {
01477 OW_THROW(CIMOMEnvironmentException, Format("Invalid: service %1 has duplicate dependencies: %2", dependentServices[j], name).c_str());
01478 }
01479 }
01480 }
01481 }
01482
01483
01484 Node curNode = depGraph.findIndependentNode();
01485 while (curNode != INVALID_NODE)
01486 {
01487 OW_LOG_DEBUG(m_Logger, Format("Found service with satisfied dependencies: %1", curNode.name));
01488 sortedServices.push_back(m_services[curNode.index]);
01489 depGraph.removeNode(curNode.name);
01490 curNode = depGraph.findIndependentNode();
01491 }
01492
01493 if (!depGraph.empty())
01494 {
01495 OW_LOG_FATAL_ERROR(m_Logger, "Service dependency graph contains a cycle:");
01496 Array<Node> nodes(depGraph.getNodes());
01497 for (size_t i = 0; i < nodes.size(); ++i)
01498 {
01499 OW_LOG_FATAL_ERROR(m_Logger, Format("Service: %1", nodes[i].name));
01500 }
01501 OW_THROW(CIMOMEnvironmentException, "Service dependency graph contains a cycle");
01502 }
01503
01504 m_services = sortedServices;
01505 }
01506
01507 }
01508