(file) Return to BasicProviderManagerRouter.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / ProviderManagerService

  1 kumpf 1.1 //%2006////////////////////////////////////////////////////////////////////////
  2           //
  3           // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
  4           // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
  5           // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
  6           // IBM Corp.; EMC Corporation, The Open Group.
  7           // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
  8           // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
  9           // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 10           // EMC Corporation; VERITAS Software Corporation; The Open Group.
 11           // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 12           // EMC Corporation; Symantec Corporation; The Open Group.
 13           //
 14           // Permission is hereby granted, free of charge, to any person obtaining a copy
 15           // of this software and associated documentation files (the "Software"), to
 16           // deal in the Software without restriction, including without limitation the
 17           // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 18           // sell copies of the Software, and to permit persons to whom the Software is
 19           // furnished to do so, subject to the following conditions:
 20           // 
 21           // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 22 kumpf 1.1 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 23           // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 24           // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 25           // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 26           // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 27           // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 28           // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 29           //
 30           //==============================================================================
 31           //
 32           //%/////////////////////////////////////////////////////////////////////////////
 33           
 34           #include "BasicProviderManagerRouter.h"
 35           
 36           #include <Pegasus/Common/Config.h>
 37           #include <Pegasus/Common/OperationContextInternal.h>
 38           #include <Pegasus/Common/CIMMessage.h>
 39           #include <Pegasus/Common/Tracer.h>
 40           #include <Pegasus/Common/Logger.h>
 41           #include <Pegasus/Common/FileSystem.h>
 42           #include <Pegasus/Config/ConfigManager.h>
 43 kumpf 1.1 #include <Pegasus/ProviderManagerService/ProviderManagerModule.h>
 44           #include <Pegasus/ProviderManager2/ProviderManager.h>
 45           
 46           // ProviderManager library names.  Should these be defined elsewhere?
 47           #if defined(PEGASUS_OS_OS400)
 48           # define LIBRARY_NAME_DEFAULTPM "QSYS/QYCMPMDE00"
 49           # define LIBRARY_NAME_CMPIPM    "QSYS/QYCMCMPIPM"
 50           # define LIBRARY_NAME_JMPIPM    "QSYS/QYCMJMPIPM"
 51           #else
 52           # define LIBRARY_NAME_CMPIPM    "CMPIProviderManager"
 53           # define LIBRARY_NAME_JMPIPM    "JMPIProviderManager"
 54           #endif
 55           
 56           PEGASUS_NAMESPACE_BEGIN
 57           
 58           class ProviderManagerContainer
 59           {
 60           public:
 61           
 62               ProviderManagerContainer(
 63                   const String& physicalName,
 64 kumpf 1.1         const String& logicalName,
 65                   const String& interfaceName,
 66                   PEGASUS_INDICATION_CALLBACK_T indicationCallback,
 67                   PEGASUS_RESPONSE_CHUNK_CALLBACK_T responseChunkCallback,
 68                   Boolean subscriptionInitComplete)
 69               : _manager(0)
 70               {
 71           #if defined (PEGASUS_OS_VMS)
 72 kumpf 1.3         _physicalName =
 73                       ConfigManager::getInstance()->getCurrentValue("providerDir") +
 74                           String("/") + FileSystem::buildLibraryFileName(physicalName) +
 75                           String(".exe");
 76 kumpf 1.1 #elif defined (PEGASUS_OS_OS400)
 77                   _physicalName = physicalName;
 78           #else
 79                   _physicalName = ConfigManager::getHomedPath(PEGASUS_DEST_LIB_DIR) +
 80                       String("/") + FileSystem::buildLibraryFileName(physicalName);
 81           #endif
 82           
 83                   _logicalName = logicalName;
 84                   _interfaceName = interfaceName;
 85           
 86                   _module.reset(new ProviderManagerModule(_physicalName));
 87                   Boolean moduleLoaded = _module->load();
 88           
 89                   if (moduleLoaded)
 90                   {
 91                       _manager = _module->getProviderManager(_logicalName);
 92                   }
 93                   else
 94                   {
 95                       PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
 96                           "ProviderManagerModule load failed.");
 97 kumpf 1.1         }
 98           
 99                   if (_manager == 0)
100                   {
101                       PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
102                           "Failed to load ProviderManager \"" + _physicalName + "\".");
103           
104                       Logger::put_l(
105                           Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
106                           "ProviderManager.BasicProviderManagerRouter."
107                               "PROVIDERMANAGER_LOAD_FAILED",
108                           "Failed to load the Provider Manager for interface type \"$0\""
109                               " from library \"$1\".",
110                           _interfaceName, _physicalName);
111           
112                       throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED, MessageLoaderParms(
113                           "ProviderManager.BasicProviderManagerRouter."
114                               "PROVIDERMANAGER_LOAD_FAILED",
115                           "Failed to load the Provider Manager for interface type \"$0\""
116                               " from library \"$1\".",
117                           _interfaceName, _physicalName));
118 kumpf 1.1         }
119           
120                   _manager->setIndicationCallback(indicationCallback);
121                   _manager->setResponseChunkCallback(responseChunkCallback);
122           
123                   _manager->setSubscriptionInitComplete (subscriptionInitComplete);
124               }
125           
126               ProviderManagerContainer(
127                   const String& interfaceName,
128                   PEGASUS_INDICATION_CALLBACK_T indicationCallback,
129                   PEGASUS_RESPONSE_CHUNK_CALLBACK_T responseChunkCallback,
130                   Boolean subscriptionInitComplete,
131 kumpf 1.3         ProviderManager* manager)
132                   :
133                   _interfaceName(interfaceName),
134                   _manager(manager),
135                   _module(0)
136 kumpf 1.1     {
137                   _manager->setIndicationCallback(indicationCallback);
138                   _manager->setResponseChunkCallback(responseChunkCallback);
139                   _manager->setSubscriptionInitComplete(subscriptionInitComplete);
140               }
141           
142               ~ProviderManagerContainer()
143               {
144                   delete _manager;
145           
146 kumpf 1.3         if (_module.get())
147                       _module->unload();
148 kumpf 1.1     }
149           
150               ProviderManager* getProviderManager()
151               {
152                   return _manager;
153               }
154           
155               const String& getInterfaceName() const
156               {
157                   return _interfaceName;
158               }
159           
160           
161           private:
162           
163               ProviderManagerContainer();
164               ProviderManagerContainer& operator=(const ProviderManagerContainer&);
165               ProviderManagerContainer(const ProviderManagerContainer&);
166           
167               String _physicalName;
168               String _logicalName;
169 kumpf 1.1     String _interfaceName;
170               ProviderManager* _manager;
171               AutoPtr<ProviderManagerModule> _module;
172           };
173           
174           PEGASUS_INDICATION_CALLBACK_T
175               BasicProviderManagerRouter::_indicationCallback = 0;
176           
177           PEGASUS_RESPONSE_CHUNK_CALLBACK_T
178               BasicProviderManagerRouter::_responseChunkCallback = 0;
179           
180 kumpf 1.3 ProviderManager*
181 kumpf 1.1     (*BasicProviderManagerRouter::_createDefaultProviderManagerCallback)() = 0;
182           
183           BasicProviderManagerRouter::BasicProviderManagerRouter(
184               PEGASUS_INDICATION_CALLBACK_T indicationCallback,
185               PEGASUS_RESPONSE_CHUNK_CALLBACK_T responseChunkCallback,
186               ProviderManager* (*createDefaultProviderManagerCallback)())
187           {
188               PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
189                   "BasicProviderManagerRouter::BasicProviderManagerRouter");
190           
191               _indicationCallback = indicationCallback;
192               _responseChunkCallback = responseChunkCallback;
193               _subscriptionInitComplete = false;
194 kumpf 1.3     _createDefaultProviderManagerCallback =
195                   createDefaultProviderManagerCallback;
196 kumpf 1.1 
197               PEG_METHOD_EXIT();
198           }
199           
200           BasicProviderManagerRouter::~BasicProviderManagerRouter()
201           {
202               PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
203                   "BasicProviderManagerRouter::~BasicProviderManagerRouter");
204               /* Clean up the provider managers */
205               for (Uint32 i = 0, n = _providerManagerTable.size(); i < n; i++)
206               {
207                    ProviderManagerContainer* pmc=_providerManagerTable[i];
208                    delete pmc;
209               }
210               PEG_METHOD_EXIT();
211           }
212           
213           Message* BasicProviderManagerRouter::processMessage(Message * message)
214           {
215               PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
216                   "BasicProviderManagerRouter::processMessage");
217 kumpf 1.1 
218               CIMRequestMessage* request = dynamic_cast<CIMRequestMessage *>(message);
219               PEGASUS_ASSERT(request != 0);
220           
221               Message* response = 0;
222               Boolean remoteNameSpaceRequest=false;
223           
224               //
225               // Retrieve the ProviderManager routing information
226               //
227           
228               CIMInstance providerModule;
229           
230               if ((dynamic_cast<CIMOperationRequestMessage*>(request) != 0) ||
231                   (request->getType() == CIM_EXPORT_INDICATION_REQUEST_MESSAGE) ||
232                   (request->getType() == CIM_INITIALIZE_PROVIDER_REQUEST_MESSAGE))
233               {
234                   // Provider information is in OperationContext
235                   ProviderIdContainer pidc = (ProviderIdContainer)
236                       request->operationContext.get(ProviderIdContainer::NAME);
237                   providerModule = pidc.getModule();
238 kumpf 1.1         remoteNameSpaceRequest=pidc.isRemoteNameSpace();
239               }
240               else if (dynamic_cast<CIMIndicationRequestMessage*>(request) != 0)
241               {
242                   // Provider information is in CIMIndicationRequestMessage
243                   CIMIndicationRequestMessage* indReq =
244                       dynamic_cast<CIMIndicationRequestMessage*>(request);
245 kumpf 1.3         ProviderIdContainer pidc =
246                       indReq->operationContext.get(ProviderIdContainer::NAME);
247 kumpf 1.1         providerModule = pidc.getModule();
248               }
249               else if (request->getType() == CIM_ENABLE_MODULE_REQUEST_MESSAGE)
250               {
251                   // Provider information is in CIMEnableModuleRequestMessage
252                   CIMEnableModuleRequestMessage* emReq =
253                       dynamic_cast<CIMEnableModuleRequestMessage*>(request);
254                   providerModule = emReq->providerModule;
255               }
256               else if (request->getType() == CIM_DISABLE_MODULE_REQUEST_MESSAGE)
257               {
258                   // Provider information is in CIMDisableModuleRequestMessage
259                   CIMDisableModuleRequestMessage* dmReq =
260                       dynamic_cast<CIMDisableModuleRequestMessage*>(request);
261                   providerModule = dmReq->providerModule;
262               }
263               else if ((request->getType() == CIM_STOP_ALL_PROVIDERS_REQUEST_MESSAGE) ||
264                        (request->getType() ==
265                         CIM_SUBSCRIPTION_INIT_COMPLETE_REQUEST_MESSAGE) ||
266                        (request->getType() == CIM_NOTIFY_CONFIG_CHANGE_REQUEST_MESSAGE))
267               {
268 kumpf 1.1         // This operation is not provider-specific
269               }
270               else
271               {
272                   // Error: Unrecognized message type.
273                   PEGASUS_ASSERT(0);
274                   CIMResponseMessage* resp = request->buildResponse();
275                   resp->cimException = PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
276                       "Unknown message type.");
277                   response = resp;
278               }
279           
280               //
281               // Forward the request to the appropriate ProviderManager(s)
282               //
283           
284               if ((request->getType() == CIM_STOP_ALL_PROVIDERS_REQUEST_MESSAGE) ||
285                   (request->getType() ==
286                    CIM_SUBSCRIPTION_INIT_COMPLETE_REQUEST_MESSAGE))
287               {
288                   _subscriptionInitComplete = true;
289 kumpf 1.1 
290                   // Send CIMStopAllProvidersRequestMessage or
291                   // CIMSubscriptionInitCompleteRequestMessage to all ProviderManagers
292                   ReadLock tableLock(_providerManagerTableLock);
293                   for (Uint32 i = 0, n = _providerManagerTable.size(); i < n; i++)
294                   {
295                       ProviderManagerContainer* pmc=_providerManagerTable[i];
296                       Message* resp = pmc->getProviderManager()->processMessage(request);
297                       delete resp;
298                   }
299           
300                   response = request->buildResponse();
301               }
302 kumpf 1.3     else if (request->getType() == CIM_NOTIFY_CONFIG_CHANGE_REQUEST_MESSAGE)
303 kumpf 1.1     {
304                   // Do not need to forward this request to in-process provider
305                   // managers
306                   response = request->buildResponse();
307               }
308               else
309               {
310                   // Retrieve the provider interface type
311                   String interfaceType;
312                   CIMValue itValue = providerModule.getProperty(
313                       providerModule.findProperty("InterfaceType")).getValue();
314                   itValue.get(interfaceType);
315           
316                   ProviderManager* pm = 0;
317                   Boolean gotError = false;
318                   try
319                   {
320                       // Look up the appropriate ProviderManager by InterfaceType
321 kumpf 1.2             pm = _getProviderManager(interfaceType);
322 kumpf 1.1         }
323                   catch (const CIMException& e)
324                   {
325                       CIMResponseMessage* cimResponse = request->buildResponse();
326                       cimResponse->cimException = e;
327                       response = cimResponse;
328                       gotError = true;
329                   }
330           
331                   if (remoteNameSpaceRequest && !pm->supportsRemoteNameSpaces())
332                   {
333                       CIMResponseMessage* resp = request->buildResponse();
334                       resp->cimException = PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
335                           "Remote Namespace operations not supported for interface type "
336                               + interfaceType);
337                       response = resp;
338                       gotError = true;
339                   }
340           
341                   if (!gotError)
342                   {
343 kumpf 1.1             response = pm->processMessage(request);
344                   }
345               }
346           
347               // preserve message key
348               // set HTTP method in response from request
349               // set closeConnect
350              ((CIMResponseMessage *)response)->syncAttributes(request);
351           
352               PEG_METHOD_EXIT();
353               return response;
354           }
355           
356           // ATTN: May need to add interfaceVersion parameter to further constrain lookup
357 kumpf 1.2 ProviderManager* BasicProviderManagerRouter::_getProviderManager(
358 kumpf 1.1     const String& interfaceType)
359           {
360               PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
361 kumpf 1.2         "BasicProviderManagerRouter::_getProviderManager");
362 kumpf 1.1 
363               //
364               // Search for this InterfaceType in the table of loaded ProviderManagers
365               //
366               {
367                   ReadLock tableLock(_providerManagerTableLock);
368           
369 kumpf 1.2         ProviderManager* pm = _lookupProviderManager(interfaceType);
370                   if (pm)
371 kumpf 1.1         {
372 kumpf 1.2             PEG_METHOD_EXIT();
373                       return pm;
374 kumpf 1.1         }
375               }
376           
377               //
378               // Load the ProviderManager for this InterfaceType and add it to the table
379               //
380               {
381                   WriteLock tableLock(_providerManagerTableLock);
382           
383 kumpf 1.2         ProviderManager* pm = _lookupProviderManager(interfaceType);
384                   if (pm)
385                   {
386                       PEG_METHOD_EXIT();
387                       return pm;
388                   }
389           
390 kumpf 1.1         // ATTN: this section is a temporary solution to populate the list of
391                   // enabled provider managers for a given distribution.  It includes
392                   // another temporary solution for converting a generic file name into
393                   // a file name useable by each platform.
394           
395 kumpf 1.3         // The DefaultProviderManager is now statically linked rather than
396                   // dynamically loaded. This code is no longer used but remains for
397                   // reference purposes.
398 kumpf 1.1 
399           #if defined(PEGASUS_ENABLE_DEFAULT_PROVIDER_MANAGER)
400 kumpf 1.3         if (interfaceType == "C++Default" &&
401                       _createDefaultProviderManagerCallback)
402 kumpf 1.1         {
403 kumpf 1.3             pm = (*_createDefaultProviderManagerCallback)();
404 kumpf 1.1             ProviderManagerContainer* pmc = new ProviderManagerContainer(
405                           "C++Default",
406                           _indicationCallback,
407                           _responseChunkCallback,
408                           _subscriptionInitComplete,
409 kumpf 1.3                 pm);
410 kumpf 1.1             _providerManagerTable.append(pmc);
411                       return pmc->getProviderManager();
412                   }
413           #endif
414           
415           #if defined(PEGASUS_ENABLE_CMPI_PROVIDER_MANAGER)
416                   if (interfaceType == "CMPI")
417                   {
418                       ProviderManagerContainer* pmc = new ProviderManagerContainer(
419                           LIBRARY_NAME_CMPIPM,
420                           "CMPI",
421                           "CMPI",
422                           _indicationCallback,
423                           _responseChunkCallback,
424                           _subscriptionInitComplete);
425                       _providerManagerTable.append(pmc);
426                       return pmc->getProviderManager();
427                   }
428           #endif
429           
430           #if defined(PEGASUS_ENABLE_JMPI_PROVIDER_MANAGER)
431 kumpf 1.1         if (  interfaceType == "JMPI"
432                      || interfaceType == "JMPIExperimental"
433                      )
434                   {
435                       ProviderManagerContainer* pmc = new ProviderManagerContainer(
436                           LIBRARY_NAME_JMPIPM,
437                           interfaceType,
438                           interfaceType,
439                           _indicationCallback,
440                           _responseChunkCallback,
441                           _subscriptionInitComplete);
442                       _providerManagerTable.append(pmc);
443                       return pmc->getProviderManager();
444                   }
445           #endif
446                   // END TEMP SECTION
447               }
448           
449               // Error: ProviderManager not found for the specified interface type
450               PEGASUS_ASSERT(0);
451               PEG_METHOD_EXIT();
452 kumpf 1.1     return 0;
453           }
454           
455 kumpf 1.2 // NOTE: The caller must lock _providerManagerTableLock before calling this
456           // method.
457           ProviderManager* BasicProviderManagerRouter::_lookupProviderManager(
458               const String& interfaceType)
459           {
460               PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
461                   "BasicProviderManagerRouter::_lookupProviderManager");
462           
463               //
464               // Search for this InterfaceType in the table of loaded ProviderManagers
465               //
466               for (Uint32 i = 0, n = _providerManagerTable.size(); i < n; i++)
467               {
468                   if (interfaceType == _providerManagerTable[i]->getInterfaceName())
469                   {
470                       ProviderManagerContainer* pmc = _providerManagerTable[i];
471                       PEG_METHOD_EXIT();
472                       return pmc->getProviderManager();
473                   }
474               }
475           
476 kumpf 1.2     // Not found
477               PEG_METHOD_EXIT();
478               return 0;
479           }
480           
481 kumpf 1.1 Boolean BasicProviderManagerRouter::hasActiveProviders()
482           {
483               PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
484                   "BasicProviderManagerRouter::hasActiveProviders");
485           
486               ReadLock tableLock(_providerManagerTableLock);
487 kumpf 1.3     for (Uint32 i = 0, n = _providerManagerTable.size(); i < n; i++)
488 kumpf 1.1     {
489                   ProviderManagerContainer* pmc = _providerManagerTable[i];
490                   if (pmc->getProviderManager()->hasActiveProviders())
491                   {
492                       PEG_METHOD_EXIT();
493                       return true;
494                   }
495               }
496           
497               PEG_METHOD_EXIT();
498               return false;
499           }
500           
501           void BasicProviderManagerRouter::unloadIdleProviders()
502           {
503               PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
504                   "BasicProviderManagerRouter::unloadIdleProviders");
505           
506               //
507               // Save pointers to the ProviderManagerContainers so we don't hold the
508               // _providerManagerTableLock while unloading idle providers
509 kumpf 1.1     //
510               Array<ProviderManagerContainer*> pmcs;
511               {
512                   ReadLock tableLock(_providerManagerTableLock);
513 kumpf 1.3         for (Uint32 i = 0, n = _providerManagerTable.size(); i < n; i++)
514 kumpf 1.1         {
515                       pmcs.append(_providerManagerTable[i]);
516                   }
517               }
518           
519               //
520               // Unload idle providers in each of the active ProviderManagers
521               // _providerManagerTableLock while unloading idle providers
522               //
523               for (Uint32 i = 0; i < pmcs.size(); i++)
524               {
525                   pmcs[i]->getProviderManager()->unloadIdleProviders();
526               }
527           
528               PEG_METHOD_EXIT();
529           }
530           
531           PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2