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