OW_NPIProviderIFC.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2001-2004 Vintela, Inc. All rights reserved.
00003 *
00004 * Redistribution and use in source and binary forms, with or without
00005 * modification, are permitted provided that the following conditions are met:
00006 *
00007 *  - Redistributions of source code must retain the above copyright notice,
00008 *    this list of conditions and the following disclaimer.
00009 *
00010 *  - Redistributions in binary form must reproduce the above copyright notice,
00011 *    this list of conditions and the following disclaimer in the documentation
00012 *    and/or other materials provided with the distribution.
00013 *
00014 *  - Neither the name of Vintela, Inc. nor the names of its
00015 *    contributors may be used to endorse or promote products derived from this
00016 *    software without specific prior written permission.
00017 *
00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
00019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021 * ARE DISCLAIMED. IN NO EVENT SHALL Vintela, Inc. OR THE CONTRIBUTORS
00022 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00028 * POSSIBILITY OF SUCH DAMAGE.
00029 *******************************************************************************/
00030 #include "OW_config.h"
00031 #include "OW_NPIProviderIFC.hpp"
00032 #include "OW_SharedLibraryException.hpp"
00033 #include "OW_SharedLibraryLoader.hpp"
00034 #include "OW_Format.hpp"
00035 #include "OW_SignalScope.hpp"
00036 #include "OW_ConfigOpts.hpp"
00037 #include "OW_FileSystem.hpp"
00038 #include "OW_NoSuchProviderException.hpp"
00039 #include "OW_NPIInstanceProviderProxy.hpp"
00040 #include "OW_NPIMethodProviderProxy.hpp"
00041 #ifndef OW_DISABLE_ASSOCIATION_TRAVERSAL
00042 #include "OW_NPIAssociatorProviderProxy.hpp"
00043 #endif
00044 #include "OW_NPIPolledProviderProxy.hpp"
00045 #include "OW_NPIIndicationProviderProxy.hpp"
00046 
00047 namespace OW_NAMESPACE
00048 {
00049 
00050 //typedef NPIProviderBaseIFC* (*ProviderCreationFunc)();
00051 // the closest approximation of NPIProviderBaseIFCRef is NPIFTABLE
00052 typedef FTABLERef* (*ProviderCreationFunc)();
00053 typedef const char* (*versionFunc_t)();
00054 const char* const NPIProviderIFC::CREATIONFUNC = "createProvider";
00055 namespace
00056 {
00057    const String COMPONENT_NAME("ow.provider.npi.ifc");
00058 }
00059 
00061 NPIProviderIFC::NPIProviderIFC()
00062    : ProviderIFCBaseIFC()
00063    , m_provs()
00064    , m_guard()
00065    , m_noidProviders()
00066    , m_loadDone(false)
00067 {
00068 }
00070 NPIProviderIFC::~NPIProviderIFC()
00071 {
00072    try
00073    {
00074       ProviderMap::iterator it = m_provs.begin();
00075       //Reference<NPIenv> npiHandle(); // TODO: createEnv(...);
00076       while (it != m_provs.end())
00077       {
00078          it->second->fp_cleanup(0); // TODO: FIX this. m_npiHandle);
00079          it->second.setNull();
00080          it++;
00081       }
00082    
00083       m_provs.clear();
00084    
00085       for (size_t i = 0; i < m_noidProviders.size(); i++)
00086       {
00087          m_noidProviders[i]->fp_cleanup(0);
00088          m_noidProviders[i].setNull();
00089       }
00090    
00091       m_noidProviders.clear();
00092    }
00093    catch (...)
00094    {
00095       // don't let exceptions escape
00096    }
00097 }
00099 void
00100 NPIProviderIFC::doInit(const ProviderEnvironmentIFCRef&,
00101    InstanceProviderInfoArray&,
00102    SecondaryInstanceProviderInfoArray&,
00103 #ifndef OW_DISABLE_ASSOCIATION_TRAVERSAL
00104    AssociatorProviderInfoArray&,
00105 #endif
00106    MethodProviderInfoArray&,
00107    IndicationProviderInfoArray&)
00108 {
00109    return;
00110 }
00112 InstanceProviderIFCRef
00113 NPIProviderIFC::doGetInstanceProvider(const ProviderEnvironmentIFCRef& env,
00114    const char* provIdString)
00115 {
00116    FTABLERef pProv = getProvider(env, provIdString);
00117    if (pProv)
00118    {
00119       // if the createInstance pointer is set, then assume it's an instance
00120       // provider
00121       if (pProv->fp_createInstance)
00122       {
00123          OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME), Format("NPIProviderIFC found instance"
00124             " provider %1", provIdString));
00125          return InstanceProviderIFCRef(new NPIInstanceProviderProxy(
00126             pProv));
00127       }
00128       OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), Format("Provider %1 is not an instance provider",
00129          provIdString));
00130    }
00131    OW_THROW(NoSuchProviderException, provIdString);
00132 }
00134 IndicationExportProviderIFCRefArray
00135 NPIProviderIFC::doGetIndicationExportProviders(const ProviderEnvironmentIFCRef& env)
00136 {
00137    //loadNoIdProviders(env);
00138    IndicationExportProviderIFCRefArray rvra;
00139    //for (size_t i = 0; i < m_noidProviders.size(); i++)
00140    //{
00141    // CppProviderBaseIFCRef pProv = m_noidProviders[i];
00142    // if (pProv->isIndicationExportProvider())
00143    // {
00144    //    rvra.append(
00145    //       IndicationExportProviderIFCRef(new
00146    //          CppIndicationExportProviderProxy(
00147    //             pProv.cast_to<CppIndicationExportProviderIFC>())));
00148    // }
00149    //}
00150    return rvra;
00151 }
00153 PolledProviderIFCRefArray
00154 NPIProviderIFC::doGetPolledProviders(const ProviderEnvironmentIFCRef& env)
00155 {
00156    // NPI doesn't support polled providers
00157    PolledProviderIFCRefArray rvra;
00158    return rvra;
00159 }
00161 MethodProviderIFCRef
00162 NPIProviderIFC::doGetMethodProvider(const ProviderEnvironmentIFCRef& env,
00163    const char* provIdString)
00164 {
00165    FTABLERef pProv = getProvider(env, provIdString);
00166    if (pProv)
00167    {
00168       // it's a method provider if the invokeMethod function pointer is not
00169       // NULL
00170       if (pProv->fp_invokeMethod)
00171       {
00172          OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME), Format("NPIProviderIFC found method provider %1",
00173             provIdString));
00174          return MethodProviderIFCRef(
00175             new NPIMethodProviderProxy(pProv));
00176       }
00177       OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), Format("Provider %1 is not a method provider",
00178          provIdString));
00179    }
00180    OW_THROW(NoSuchProviderException, provIdString);
00181 }
00182 #ifndef OW_DISABLE_ASSOCIATION_TRAVERSAL
00183 
00184 AssociatorProviderIFCRef
00185 NPIProviderIFC::doGetAssociatorProvider(const ProviderEnvironmentIFCRef& env,
00186    const char* provIdString)
00187 {
00188    FTABLERef pProv = getProvider(env, provIdString);
00189    if (pProv)
00190    {
00191       // if the associatorNames function pointer is not 0, we know it's an
00192       // associator provider
00193       if (pProv->fp_associatorNames)
00194       {
00195          OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME), Format("NPIProviderIFC found associator provider %1",
00196             provIdString));
00197          return AssociatorProviderIFCRef(new
00198             NPIAssociatorProviderProxy(pProv));
00199       }
00200       OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), Format("Provider %1 is not an associator provider",
00201          provIdString));
00202    }
00203    OW_THROW(NoSuchProviderException, provIdString);
00204 }
00205 #endif
00206 
00207 IndicationProviderIFCRef
00208 NPIProviderIFC::doGetIndicationProvider(const ProviderEnvironmentIFCRef& env,
00209    const char* provIdString)
00210 {
00211    FTABLERef pProv = getProvider(env, provIdString);
00212    if (pProv)
00213    {
00214       // if the indicationNames function pointer is not 0, we know it's an
00215       // indication provider
00216       if (pProv->fp_activateFilter)
00217       {
00218          OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME), Format("NPIProviderIFC found indication provider %1",
00219             provIdString));
00220          return IndicationProviderIFCRef(new
00221             NPIIndicationProviderProxy(pProv));
00222       }
00223       OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), Format("Provider %1 is not an indication provider",
00224          provIdString));
00225    }
00226    OW_THROW(NoSuchProviderException, provIdString);
00227 }
00229 void
00230 NPIProviderIFC::loadNoIdProviders(const ProviderEnvironmentIFCRef& env)
00231 {
00232 
00233    MutexLock ml(m_guard);
00234    if (m_loadDone)
00235    {
00236      return;
00237    }
00238    m_loadDone = true;
00239    const StringArray libPaths = env->getMultiConfigItem(ConfigOpts::NPIPROVIFC_PROV_LOCATION_opt, 
00240       String(OW_DEFAULT_NPIPROVIFC_PROV_LOCATION).tokenize(OW_PATHNAME_SEPARATOR),
00241       OW_PATHNAME_SEPARATOR);
00242    for (size_t i = 0; i < libPaths.size(); ++i)
00243    {
00244       String libPath(libPaths[i]);
00245       SharedLibraryLoaderRef ldr =
00246         SharedLibraryLoader::createSharedLibraryLoader();
00247       if (!ldr)
00248       {
00249         OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), "NPI provider ifc failed to get shared lib loader");
00250         return;
00251       }
00252       StringArray dirEntries;
00253       if (!FileSystem::getDirectoryContents(libPath, dirEntries))
00254       {
00255         OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), Format("NPI provider ifc failed getting contents of "
00256           "directory: %1", libPath));
00257         return;
00258       }
00259       for (size_t i = 0; i < dirEntries.size(); i++)
00260       {
00261         if (!dirEntries[i].endsWith(OW_SHAREDLIB_EXTENSION))
00262         {
00263           continue;
00264         }
00265    #ifdef OW_DARWIN
00266            if (dirEntries[i].indexOf(OW_VERSION) != String::npos)
00267            {
00268                 continue;
00269            }
00270    #endif // OW_DARWIN
00271         String libName = libPath;
00272         libName += OW_FILENAME_SEPARATOR;
00273         libName += dirEntries[i];
00274         SharedLibraryRef theLib = ldr->loadSharedLibrary(libName,
00275             env->getLogger(COMPONENT_NAME));
00276         String guessProvId = dirEntries[i].substring(3, dirEntries[i].length() - (strlen(OW_SHAREDLIB_EXTENSION) + 3));
00277         if (!theLib)
00278         {
00279           OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), Format("NPI provider %1 ifc failed to load"
00280                   " library: %2", guessProvId, libName));
00281           continue;
00282         }
00283 		::FP_INIT_FT createProvider;
00284       String creationFuncName = guessProvId + "_initFunctionTable";
00285       if (!theLib->getFunctionPointer(creationFuncName, createProvider))
00286       {
00287          OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), Format("NPI provider ifc: Libary %1 does not contain"
00288             " %2 function", libName, creationFuncName));
00289          continue;
00290       }
00291       ::FTABLE fTable_ = (*createProvider)();
00292       if (!fTable_.fp_initialize)
00293       {
00294          OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), Format("NPI provider ifc: Libary %1 - %2 returned null"
00295             " initialize function pointer in function table", libName, creationFuncName));
00296          continue;
00297       }
00298          // only initialize polled and indicationexport providers
00299       // since NPI doesn't support indicationexport providers ....
00300       if (!fTable_.fp_activateFilter) continue;
00301       //
00302          // else it must be a polled provider - initialize it
00303       OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME), Format("NPI provider ifc loaded library %1. Calling initialize"
00304          " for provider %2", libName, guessProvId));
00305       ::CIMOMHandle ch = {0}; // CIMOMHandle parameter is meaningless, there is
00306       // nothing the provider can do with it, so we'll just pass in 0
00307       //Reference<NPIEnv> npiHandle(); // TODO: createEnv(...);
00308          // Garbage Collection support
00309       NPIFTABLE fTable;
00310          memcpy(&fTable, &fTable_, sizeof(::FTABLE));
00311          fTable.npicontext = new NPIContext;
00312          fTable.npicontext->scriptName = NULL;
00313       ::NPIHandle _npiHandle = {0, 0, 0, 0, fTable.npicontext};
00314       fTable.fp_initialize(&_npiHandle, ch );   // Let provider initialize itself
00315       // take care of the errorOccurred field - buggy provider or perl script
00316       if (_npiHandle.errorOccurred)
00317       {
00318          OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME), Format("NPI provider ifc loaded library %1. Initialize failed"
00319          " for provider %2", libName, guessProvId));
00320          delete ((NPIContext *)fTable.npicontext);
00321          continue;
00322       }
00323       OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME), Format("NPI provider ifc: provider %1 loaded and initialized",
00324          guessProvId));
00325       //::NPIFTABLE * nf = new ::NPIFTABLE();
00326       //* nf = fTable;
00327          m_noidProviders.append(FTABLERef(theLib, new NPIFTABLE(fTable)));
00328          //m_noidProviders.append(FTABLERef(theLib, nf));
00329       }
00330    }
00331 }
00333 FTABLERef
00334 NPIProviderIFC::getProvider(
00335    const ProviderEnvironmentIFCRef& env, const char* provIdString)
00336 {
00337    MutexLock ml(m_guard);
00338    String provId(provIdString);
00339    ProviderMap::iterator it = m_provs.find(provId);
00340    if (it != m_provs.end())
00341    {
00342       return it->second;
00343    }
00344    const StringArray libPaths = env->getMultiConfigItem(
00345       ConfigOpts::NPIPROVIFC_PROV_LOCATION_opt, 
00346       String(OW_DEFAULT_NPIPROVIFC_PROV_LOCATION).tokenize(OW_PATHNAME_SEPARATOR),
00347       OW_PATHNAME_SEPARATOR);
00348    for (size_t i = 0; i < libPaths.size(); ++i)
00349    {
00350       String libPath(libPaths[i]);
00351       SharedLibraryLoaderRef ldr =
00352          SharedLibraryLoader::createSharedLibraryLoader();
00353       if (!ldr)
00354       {
00355          OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), "NPI: provider ifc failed to get shared lib loader");
00356          return FTABLERef();
00357       }
00358       String libName(libPath);
00359       libName += OW_FILENAME_SEPARATOR;
00360       libName += "lib";
00361       libName += provId;
00362       libName += OW_SHAREDLIB_EXTENSION;
00363       OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME), Format("NPIProviderIFC::getProvider loading library: %1",
00364          libName));
00365 
00366       if (!FileSystem::exists(libName))
00367       {
00368          continue;
00369       }
00370 
00371       SharedLibraryRef theLib = ldr->loadSharedLibrary(libName,
00372          env->getLogger(COMPONENT_NAME));
00373       if (!theLib)
00374       {
00375          OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), Format("NPI provider ifc failed to load library: %1 "
00376             "for provider id %2", libName, provId));
00377          return FTABLERef();
00378       }
00379 		::FP_INIT_FT createProvider;
00380       String creationFuncName = provId + "_initFunctionTable";
00381       if (!theLib->getFunctionPointer(creationFuncName, createProvider))
00382       {
00383          OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), Format("NPI provider ifc: Libary %1 does not contain"
00384             " %2 function", libName, creationFuncName));
00385          return FTABLERef();
00386       }
00387       ::FTABLE fTable_ = (*createProvider)();
00388       //NPIFTABLE fTable = fTable_;
00389       NPIFTABLE fTable;
00390       memcpy(&fTable, &fTable_, sizeof(::FTABLE));
00391       fTable.npicontext = new NPIContext;
00392       fTable.npicontext->scriptName = NULL;
00393       if (!fTable.fp_initialize)
00394       {
00395          OW_LOG_ERROR(env->getLogger(COMPONENT_NAME), Format("NPI provider ifc: Libary %1 - %2 returned null"
00396             " initialize function pointer in function table", libName, creationFuncName));
00397          delete ((NPIContext *)fTable.npicontext);
00398          return FTABLERef();
00399       }
00400       OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME), Format("NPI provider ifc loaded library %1. Calling initialize"
00401          " for provider %2", libName, provId));
00402       ::CIMOMHandle ch = {0}; // CIMOMHandle parameter is meaningless, there is
00403       // nothing the provider can do with it, so we'll just pass in 0
00404       //Reference<NPIEnv> npiHandle(); // TODO: createEnv(...);
00405       ::NPIHandle _npiHandle = { 0, 0, 0, 0, fTable.npicontext};
00406       fTable.fp_initialize(&_npiHandle, ch ); // Let provider initialize itself
00407       // take care of the errorOccurred field
00408       // that might indicate a buggy provider
00409       if (_npiHandle.errorOccurred)
00410       {
00411          OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME), Format("NPI provider ifc loaded library %1. Initialize failed"
00412             " for provider %2", libName, provId));
00413          delete ((NPIContext *)fTable.npicontext);
00414          return FTABLERef();
00415       }
00416       OW_LOG_DEBUG(env->getLogger(COMPONENT_NAME), Format("NPI provider ifc: provider %1 loaded and initialized",
00417          provId));
00418       m_provs[provId] = FTABLERef(theLib, new NPIFTABLE(fTable));
00419 
00420       return m_provs[provId];
00421    }
00422    return FTABLERef();
00423 }
00424 } // end namespace OW_NAMESPACE
00425 
00426 OW_PROVIDERIFCFACTORY(OpenWBEM::NPIProviderIFC, npi)
00427 

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