OW_ProviderAgentEnvironment.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2001-2004 Vintela, Inc. All rights reserved.
00003 * Copyright (C) 2004 Novell, Inc. All rights reserved.
00004 *
00005 * Redistribution and use in source and binary forms, with or without
00006 * modification, are permitted provided that the following conditions are met:
00007 *
00008 *  - Redistributions of source code must retain the above copyright notice,
00009 *    this list of conditions and the following disclaimer.
00010 *
00011 *  - Redistributions in binary form must reproduce the above copyright notice,
00012 *    this list of conditions and the following disclaimer in the documentation
00013 *    and/or other materials provided with the distribution.
00014 *
00015 *  - Neither the name of Vintela, Inc. nor the names of its
00016 *    contributors may be used to endorse or promote products derived from this
00017 *    software without specific prior written permission.
00018 *
00019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
00020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00021 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00022 * ARE DISCLAIMED. IN NO EVENT SHALL Vintela, Inc. OR THE CONTRIBUTORS
00023 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00024 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00025 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00026 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00027 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00028 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00029 * POSSIBILITY OF SUCH DAMAGE.
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> // for std::find
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    //non-copyable
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    //non-copyable
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    //non-copyable
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); // 100 extra just in case.
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    // if the caller didn't provide their own custom locker
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);  //TODO need to throw?
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 } // end namespace OW_NAMESPACE
00454 

Generated on Thu Feb 9 08:48:08 2006 for openwbem by  doxygen 1.4.6