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 
00031 
00037 #include "OW_config.h"
00038 #include "OW_ProviderAgentEnvironment.hpp"
00039 #include "OW_ProviderAgentProviderEnvironment.hpp"
00040 #include "OW_ProviderAgentCIMOMHandle.hpp"
00041 #include "OW_ProviderAgent.hpp"
00042 #include "OW_CppInstanceProviderIFC.hpp"
00043 #include "OW_CppSecondaryInstanceProviderIFC.hpp"
00044 #include "OW_CppMethodProviderIFC.hpp"
00045 #include "OW_CppAssociatorProviderIFC.hpp"
00046 #include "OW_MethodProviderInfo.hpp"
00047 #include "OW_RequestHandlerIFC.hpp"
00048 #include "OW_ConfigException.hpp"
00049 #include "OW_Assertion.hpp"
00050 #include "OW_CIMInstance.hpp"
00051 #include "OW_RWLocker.hpp"
00052 #include "OW_Mutex.hpp"
00053 #include "OW_NullLogger.hpp"
00054 #include "OW_ClientCIMOMHandle.hpp"
00055 #include "OW_HTTPServer.hpp"
00056 #include "OW_Thread.hpp"
00057 
00058 #include <algorithm> 
00059 
00060 namespace OW_NAMESPACE
00061 {
00062 namespace
00063 {
00064 
00065 const String COMPONENT_NAME("ow.provideragent");
00066 
00067 class PALockerNone : public ProviderAgentLockerIFC
00068 {
00069 public:
00070    PALockerNone() {}
00071    virtual ~PALockerNone() {}
00072    virtual void doGetReadLock() {}
00073    virtual void doGetWriteLock() {}
00074    virtual void doReleaseReadLock() {}
00075    virtual void doReleaseWriteLock() {}
00076 private:
00077    
00078    PALockerNone(const PALockerNone&);
00079    PALockerNone& operator=(const PALockerNone&);
00080 };
00081 
00082 class PALockerSWMR : public ProviderAgentLockerIFC
00083 {
00084 public:
00085    PALockerSWMR(UInt32 timeout)
00086       : m_timeout(timeout)
00087    {
00088    }
00089    virtual ~PALockerSWMR() {}
00090    virtual void doGetReadLock()
00091    {
00092       m_rwlocker.getReadLock(m_timeout);
00093    }
00094    virtual void doGetWriteLock()
00095    {
00096       m_rwlocker.getWriteLock(m_timeout);
00097    }
00098    virtual void doReleaseReadLock()
00099    {
00100       m_rwlocker.releaseReadLock();
00101    }
00102    virtual void doReleaseWriteLock()
00103    {
00104       m_rwlocker.releaseWriteLock();
00105    }
00106 private:
00107    
00108    PALockerSWMR(const PALockerSWMR&);
00109    PALockerSWMR& operator=(const PALockerSWMR&);
00110 
00111    RWLocker m_rwlocker;
00112    UInt32 m_timeout;
00113 };
00114 
00115 class PALockerSingleThreaded : public ProviderAgentLockerIFC
00116 {
00117 public:
00118    PALockerSingleThreaded() {}
00119    virtual ~PALockerSingleThreaded() {}
00120    virtual void doGetReadLock()
00121    {
00122       m_mutex.acquire();
00123    }
00124    virtual void doGetWriteLock()
00125    {
00126       m_mutex.acquire();
00127    }
00128    virtual void doReleaseReadLock()
00129    {
00130       m_mutex.release();
00131    }
00132    virtual void doReleaseWriteLock()
00133    {
00134       m_mutex.release();
00135    }
00136 private:
00137    
00138    PALockerSingleThreaded(const PALockerSingleThreaded&);
00139    PALockerSingleThreaded& operator=(const PALockerSingleThreaded&);
00140 
00141    Mutex m_mutex;
00142 };
00143 
00144 }
00145 
00146 
00147 ProviderAgentEnvironment::ProviderAgentEnvironment(const ConfigFile::ConfigMap& configMap,
00148       const Array<CppProviderBaseIFCRef>& providers,
00149       const Array<CIMClass>& cimClasses,
00150       const AuthenticatorIFCRef& authenticator,
00151       const Array<RequestHandlerIFCRef>& requestHandlers,
00152       const LoggerRef& logger,
00153       const String& callbackURL,
00154       const Reference<Array<SelectablePair_t> >& selectables,
00155       const ProviderAgentLockerIFCRef& locker)
00156    : m_configItems(configMap)
00157    , m_authenticator(authenticator)
00158    , m_logger(logger ? logger : LoggerRef(new NullLogger))
00159    , m_callbackURL(callbackURL)
00160    , m_requestHandlers(requestHandlers)
00161    , m_selectables(selectables)
00162    , m_locker(locker)
00163    , m_classRetrieval(E_DONT_RETRIEVE_CLASSES)
00164    , m_connectionPool(5)
00165    , m_useConnectionCredentials(E_DONT_USE_CONNECTION_CREDENTIALS)
00166 {
00167    m_cimClasses.setMaxCacheSize(cimClasses.size() + 100); 
00168    for (Array<CIMClass>::const_iterator iter = cimClasses.begin();
00169         iter < cimClasses.end(); ++iter)
00170    {
00171       String key = iter->getName();
00172       key.toLowerCase();
00173       m_cimClasses.addToCache(*iter, key);
00174    }
00175 
00176    for (Array<CppProviderBaseIFCRef>::const_iterator iter = providers.begin();
00177         iter < providers.end(); ++iter)
00178    {
00179       CppProviderBaseIFCRef prov = *iter;
00180 
00181       OperationContext oc;
00182       ProviderEnvironmentIFCRef pe(new ProviderAgentProviderEnvironment(
00183          m_logger, m_configItems, oc, m_callbackURL, m_connectionPool, E_DONT_USE_CONNECTION_CREDENTIALS));
00184       prov->initialize(pe);
00185       CppMethodProviderIFC* methodProv = prov->getMethodProvider();
00186       if (methodProv)
00187       {
00188          MethodProviderInfo info;
00189          methodProv->getMethodProviderInfo(info);
00190          MethodProviderInfo::ClassInfoArray cia = info.getClassInfo();
00191          for (MethodProviderInfo::ClassInfoArray::const_iterator citer  = cia.begin();
00192               citer < cia.end(); ++citer)
00193          {
00194             const MethodProviderInfo::ClassInfo& ci = *citer;
00195             String className = ci.className;
00196             StringArray namespaces = ci.namespaces;
00197             StringArray methods = ci.methods;
00198             if (namespaces.size() == 0)
00199             {
00200                namespaces.push_back("");
00201             }
00202             for (StringArray::const_iterator nsiter = namespaces.begin();
00203                  nsiter < namespaces.end(); ++nsiter)
00204             {
00205                for (StringArray::const_iterator miter = methods.begin();
00206                     miter < methods.end(); ++miter)
00207                {
00208                   String key = *nsiter + ":" + className + ":" + *miter;
00209                   key.toLowerCase();
00210                   m_methodProvs[key] = *iter;
00211                }
00212             }
00213          }
00214          m_methodProvs["*"] = *iter;
00215       }
00216 #ifndef OW_DISABLE_ASSOCIATION_TRAVERSAL
00217       CppAssociatorProviderIFC* assocProv = prov->getAssociatorProvider();
00218       if (assocProv)
00219       {
00220          AssociatorProviderInfo api;
00221          assocProv->getAssociatorProviderInfo(api);
00222          AssociatorProviderInfo::ClassInfoArray cia = api.getClassInfo();
00223          for (AssociatorProviderInfo::ClassInfoArray::const_iterator citer = cia.begin();
00224               citer < cia.end(); ++citer)
00225          {
00226             const AssociatorProviderInfo::ClassInfo& ci = *citer;
00227             String className = ci.className;
00228             StringArray namespaces = ci.namespaces;
00229             if (namespaces.size() == 0)
00230             {
00231                namespaces.push_back(String(""));
00232             }
00233             for (StringArray::const_iterator nsiter = namespaces.begin();
00234                  nsiter < namespaces.end(); ++nsiter)
00235             {
00236                String key = *nsiter + ":" + className;
00237                key.toLowerCase();
00238                m_assocProvs[key] = *iter;
00239             }
00240          }
00241          m_assocProvs["*"] = *iter;
00242       }
00243 #endif
00244       CppInstanceProviderIFC* instProv = prov->getInstanceProvider();
00245       if (instProv)
00246       {
00247          InstanceProviderInfo ipi;
00248          instProv->getInstanceProviderInfo(ipi);
00249          InstanceProviderInfo::ClassInfoArray cia = ipi.getClassInfo();
00250          for (InstanceProviderInfo::ClassInfoArray::const_iterator citer = cia.begin();
00251               citer < cia.end(); ++citer)
00252          {
00253             const InstanceProviderInfo::ClassInfo& ci = *citer;
00254             String className = ci.className;
00255             StringArray namespaces = ci.namespaces;
00256             if (namespaces.size() == 0)
00257             {
00258                namespaces.push_back(String(""));
00259             }
00260             for (StringArray::const_iterator nsiter = namespaces.begin();
00261                  nsiter < namespaces.end(); ++nsiter)
00262             {
00263                String key = *nsiter + ":" + className;
00264                key.toLowerCase();
00265                m_instProvs[key] = *iter;
00266             }
00267          }
00268          m_instProvs["*"] = *iter;
00269       }
00270       CppSecondaryInstanceProviderIFC* secInstProv = prov->getSecondaryInstanceProvider();
00271       if (secInstProv)
00272       {
00273          SecondaryInstanceProviderInfo ipi;
00274          secInstProv->getSecondaryInstanceProviderInfo(ipi);
00275          SecondaryInstanceProviderInfo::ClassInfoArray cia = ipi.getClassInfo();
00276          for (SecondaryInstanceProviderInfo::ClassInfoArray::const_iterator citer = cia.begin();
00277               citer < cia.end(); ++citer)
00278          {
00279             const SecondaryInstanceProviderInfo::ClassInfo& ci = *citer;
00280             String className = ci.className;
00281             StringArray namespaces = ci.namespaces;
00282             if (namespaces.size() == 0)
00283             {
00284                namespaces.push_back(String(""));
00285             }
00286             for (StringArray::const_iterator nsiter = namespaces.begin();
00287                  nsiter < namespaces.end(); ++nsiter)
00288             {
00289                String key = *nsiter + ":" + className;
00290                key.toLowerCase();
00291                m_secondaryInstProvs[key] = *iter;
00292             }
00293          }
00294          m_secondaryInstProvs["*"] = *iter;
00295       }
00296    }
00297 
00298    
00299    if (!m_locker)
00300    {
00301       String confItem = getConfigItem(ProviderAgent::LockingType_opt, "none");
00302       confItem.toLowerCase();
00303       if (confItem == ProviderAgent::LockingTypeNone)
00304       {
00305          m_locker = new PALockerNone;
00306       }
00307       else if (confItem == ProviderAgent::LockingTypeSWMR)
00308       {
00309          confItem = getConfigItem(ProviderAgent::LockingTimeout_opt, "300");
00310          UInt32 lockingTimeout(300);
00311          try
00312          {
00313             lockingTimeout = confItem.toUInt32();
00314          }
00315          catch (StringConversionException&)
00316          {
00317             OW_THROW(ConfigException, "invalid locking timeout");
00318          }
00319          m_locker = new PALockerSWMR(lockingTimeout);
00320       }
00321       else if (confItem == ProviderAgent::LockingTypeSingleThreaded)
00322       {
00323          m_locker = new PALockerSingleThreaded();
00324       }
00325       else
00326       {
00327          OW_THROW(ConfigException, "unknown locking type");
00328       }
00329    }
00330 
00331    String confItem = getConfigItem(ProviderAgent::DynamicClassRetrieval_opt, "false");
00332    confItem.toLowerCase();
00333    if (confItem == "true")
00334    {
00335       m_classRetrieval = E_RETRIEVE_CLASSES;
00336    }
00337    else
00338    {
00339       m_classRetrieval = E_DONT_RETRIEVE_CLASSES;
00340    }
00341 
00342    confItem = getConfigItem(ProviderAgent::UseConnectionCredentials_opt, "false");
00343    confItem.toLowerCase();
00344    if (confItem == "true")
00345    {
00346       m_useConnectionCredentials = E_USE_CONNECTION_CREDENTIALS;
00347    }
00348    else
00349    {
00350       m_useConnectionCredentials = E_DONT_USE_CONNECTION_CREDENTIALS;
00351    }
00352    if (m_authenticator)
00353    {
00354       m_authenticator->init(this); 
00355    }
00356 }
00357 
00359 ProviderAgentEnvironment::~ProviderAgentEnvironment() {}
00360 
00361 
00363 bool
00364 ProviderAgentEnvironment::authenticate(String &userName,
00365       const String &info, String &details, OperationContext& context) const
00366 {
00367    return m_authenticator->authenticate(userName, info, details, context);
00368 }
00369 
00371 void
00372 ProviderAgentEnvironment::addSelectable(const SelectableIFCRef& obj,
00373       const SelectableCallbackIFCRef& cb)
00374 {
00375    m_selectables->push_back(std::make_pair(obj, cb));
00376 }
00377 
00379 void
00380 ProviderAgentEnvironment::removeSelectable(const SelectableIFCRef& obj)
00381 {
00382    m_selectables->erase(std::remove_if (m_selectables->begin(), m_selectables->end(),
00383       selectableFinder(obj)), m_selectables->end());
00384 }
00386 String
00387 ProviderAgentEnvironment::getConfigItem(const String &name, const String& defRetVal) const
00388 {
00389    return ConfigFile::getConfigItem(m_configItems, name, defRetVal);
00390 }
00392 StringArray
00393 ProviderAgentEnvironment::getMultiConfigItem(const String &itemName, 
00394    const StringArray& defRetVal, const char* tokenizeSeparator) const
00395 {
00396    return ConfigFile::getMultiConfigItem(m_configItems, itemName, defRetVal, tokenizeSeparator);
00397 }
00399 void
00400 ProviderAgentEnvironment::setConfigItem(const String& item, const String& value,
00401                               EOverwritePreviousFlag overwritePrevious)
00402 {
00403    ConfigFile::setConfigItem(m_configItems, item, value, 
00404       overwritePrevious == E_OVERWRITE_PREVIOUS ? ConfigFile::E_OVERWRITE_PREVIOUS : ConfigFile::E_PRESERVE_PREVIOUS);
00405 }
00406    
00408 RequestHandlerIFCRef
00409 ProviderAgentEnvironment::getRequestHandler(const String& ct) const
00410 {
00411    for (Array<RequestHandlerIFCRef>::const_iterator iter = m_requestHandlers.begin();
00412         iter != m_requestHandlers.end(); ++iter)
00413    {
00414       StringArray sa = (*iter)->getSupportedContentTypes();
00415       if (std::find(sa.begin(), sa.end(), ct) != sa.end())
00416       {
00417          RequestHandlerIFCRef ref = RequestHandlerIFCRef(iter->getLibRef(),
00418             (*iter)->clone());
00419          ref->setEnvironment(ServiceEnvironmentIFCRef(const_cast<ProviderAgentEnvironment *>(this)));
00420          return ref;
00421       }
00422    }
00423    return RequestHandlerIFCRef(SharedLibraryRef(0), 0);  
00424 }
00426 CIMOMHandleIFCRef
00427 ProviderAgentEnvironment::getCIMOMHandle(OperationContext& context,
00428       EBypassProvidersFlag bypassProviders,
00429       ELockingFlag locking) const
00430 {
00431    ProviderEnvironmentIFCRef pe(new ProviderAgentProviderEnvironment(
00432       m_logger, m_configItems, context, m_callbackURL, m_connectionPool, m_useConnectionCredentials));
00433    return CIMOMHandleIFCRef(new ProviderAgentCIMOMHandle(
00434       m_assocProvs, m_instProvs, m_secondaryInstProvs, m_methodProvs,
00435       m_cimClasses, pe, m_classRetrieval, m_locker));
00436 }
00438 LoggerRef
00439 ProviderAgentEnvironment::getLogger() const
00440 {
00441    return getLogger(COMPONENT_NAME);
00442 }
00443 
00445 LoggerRef
00446 ProviderAgentEnvironment::getLogger(const String& componentName) const
00447 {
00448    LoggerRef rv(m_logger->clone());
00449    rv->setDefaultComponent(componentName);
00450    return rv;
00451 }
00452 
00453 } 
00454