(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                   _physicalName = ConfigManager::getInstance()->getCurrentValue("providerDir") +
 73                       String("/") + FileSystem::buildLibraryFileName(physicalName) + String(".exe");
 74           #elif defined (PEGASUS_OS_OS400)
 75                   _physicalName = physicalName;
 76           #else
 77                   _physicalName = ConfigManager::getHomedPath(PEGASUS_DEST_LIB_DIR) +
 78                       String("/") + FileSystem::buildLibraryFileName(physicalName);
 79           #endif
 80           
 81                   _logicalName = logicalName;
 82                   _interfaceName = interfaceName;
 83           
 84                   _module.reset(new ProviderManagerModule(_physicalName));
 85 kumpf 1.1         Boolean moduleLoaded = _module->load();
 86           
 87                   if (moduleLoaded)
 88                   {
 89                       _manager = _module->getProviderManager(_logicalName);
 90                   }
 91                   else
 92                   {
 93                       PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
 94                           "ProviderManagerModule load failed.");
 95                   }
 96           
 97                   if (_manager == 0)
 98                   {
 99                       PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
100                           "Failed to load ProviderManager \"" + _physicalName + "\".");
101           
102                       Logger::put_l(
103                           Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
104                           "ProviderManager.BasicProviderManagerRouter."
105                               "PROVIDERMANAGER_LOAD_FAILED",
106 kumpf 1.1                 "Failed to load the Provider Manager for interface type \"$0\""
107                               " from library \"$1\".",
108                           _interfaceName, _physicalName);
109           
110                       throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED, MessageLoaderParms(
111                           "ProviderManager.BasicProviderManagerRouter."
112                               "PROVIDERMANAGER_LOAD_FAILED",
113                           "Failed to load the Provider Manager for interface type \"$0\""
114                               " from library \"$1\".",
115                           _interfaceName, _physicalName));
116                   }
117           
118                   _manager->setIndicationCallback(indicationCallback);
119                   _manager->setResponseChunkCallback(responseChunkCallback);
120           
121                   _manager->setSubscriptionInitComplete (subscriptionInitComplete);
122               }
123           
124               ProviderManagerContainer(
125                   const String& interfaceName,
126                   PEGASUS_INDICATION_CALLBACK_T indicationCallback,
127 kumpf 1.1         PEGASUS_RESPONSE_CHUNK_CALLBACK_T responseChunkCallback,
128                   Boolean subscriptionInitComplete,
129           	ProviderManager* manager)
130           	: 
131           	_interfaceName(interfaceName),
132           	_manager(manager),
133           	_module(0)
134               {
135                   _manager->setIndicationCallback(indicationCallback);
136                   _manager->setResponseChunkCallback(responseChunkCallback);
137                   _manager->setSubscriptionInitComplete(subscriptionInitComplete);
138               }
139           
140               ~ProviderManagerContainer()
141               {
142                   delete _manager;
143           
144           	if (_module.get())
145           	    _module->unload();
146               }
147           
148 kumpf 1.1     ProviderManager* getProviderManager()
149               {
150                   return _manager;
151               }
152           
153               const String& getInterfaceName() const
154               {
155                   return _interfaceName;
156               }
157           
158           
159           private:
160           
161               ProviderManagerContainer();
162               ProviderManagerContainer& operator=(const ProviderManagerContainer&);
163               ProviderManagerContainer(const ProviderManagerContainer&);
164           
165               String _physicalName;
166               String _logicalName;
167               String _interfaceName;
168               ProviderManager* _manager;
169 kumpf 1.1     AutoPtr<ProviderManagerModule> _module;
170           };
171           
172           PEGASUS_INDICATION_CALLBACK_T
173               BasicProviderManagerRouter::_indicationCallback = 0;
174           
175           PEGASUS_RESPONSE_CHUNK_CALLBACK_T
176               BasicProviderManagerRouter::_responseChunkCallback = 0;
177           
178           ProviderManager* 
179               (*BasicProviderManagerRouter::_createDefaultProviderManagerCallback)() = 0;
180           
181           BasicProviderManagerRouter::BasicProviderManagerRouter(
182               PEGASUS_INDICATION_CALLBACK_T indicationCallback,
183               PEGASUS_RESPONSE_CHUNK_CALLBACK_T responseChunkCallback,
184               ProviderManager* (*createDefaultProviderManagerCallback)())
185           {
186               PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
187                   "BasicProviderManagerRouter::BasicProviderManagerRouter");
188           
189               _indicationCallback = indicationCallback;
190 kumpf 1.1     _responseChunkCallback = responseChunkCallback;
191               _subscriptionInitComplete = false;
192               _createDefaultProviderManagerCallback = 
193           	createDefaultProviderManagerCallback;
194           
195               PEG_METHOD_EXIT();
196           }
197           
198           BasicProviderManagerRouter::~BasicProviderManagerRouter()
199           {
200               PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
201                   "BasicProviderManagerRouter::~BasicProviderManagerRouter");
202               /* Clean up the provider managers */
203               for (Uint32 i = 0, n = _providerManagerTable.size(); i < n; i++)
204               {
205                    ProviderManagerContainer* pmc=_providerManagerTable[i];
206                    delete pmc;
207               }
208               PEG_METHOD_EXIT();
209           }
210           
211 kumpf 1.1 Message* BasicProviderManagerRouter::processMessage(Message * message)
212           {
213               PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
214                   "BasicProviderManagerRouter::processMessage");
215           
216               CIMRequestMessage* request = dynamic_cast<CIMRequestMessage *>(message);
217               PEGASUS_ASSERT(request != 0);
218           
219               Message* response = 0;
220               Boolean remoteNameSpaceRequest=false;
221           
222               //
223               // Retrieve the ProviderManager routing information
224               //
225           
226               CIMInstance providerModule;
227           
228               if ((dynamic_cast<CIMOperationRequestMessage*>(request) != 0) ||
229                   (request->getType() == CIM_EXPORT_INDICATION_REQUEST_MESSAGE) ||
230                   (request->getType() == CIM_INITIALIZE_PROVIDER_REQUEST_MESSAGE))
231               {
232 kumpf 1.1         // Provider information is in OperationContext
233                   ProviderIdContainer pidc = (ProviderIdContainer)
234                       request->operationContext.get(ProviderIdContainer::NAME);
235                   providerModule = pidc.getModule();
236                   remoteNameSpaceRequest=pidc.isRemoteNameSpace();
237               }
238               else if (dynamic_cast<CIMIndicationRequestMessage*>(request) != 0)
239               {
240                   // Provider information is in CIMIndicationRequestMessage
241                   CIMIndicationRequestMessage* indReq =
242                       dynamic_cast<CIMIndicationRequestMessage*>(request);
243                   ProviderIdContainer pidc = indReq->operationContext.get(ProviderIdContainer::NAME);
244                   providerModule = pidc.getModule();
245               }
246               else if (request->getType() == CIM_ENABLE_MODULE_REQUEST_MESSAGE)
247               {
248                   // Provider information is in CIMEnableModuleRequestMessage
249                   CIMEnableModuleRequestMessage* emReq =
250                       dynamic_cast<CIMEnableModuleRequestMessage*>(request);
251                   providerModule = emReq->providerModule;
252               }
253 kumpf 1.1     else if (request->getType() == CIM_DISABLE_MODULE_REQUEST_MESSAGE)
254               {
255                   // Provider information is in CIMDisableModuleRequestMessage
256                   CIMDisableModuleRequestMessage* dmReq =
257                       dynamic_cast<CIMDisableModuleRequestMessage*>(request);
258                   providerModule = dmReq->providerModule;
259               }
260               else if ((request->getType() == CIM_STOP_ALL_PROVIDERS_REQUEST_MESSAGE) ||
261                        (request->getType() ==
262                         CIM_SUBSCRIPTION_INIT_COMPLETE_REQUEST_MESSAGE) ||
263                        (request->getType() == CIM_NOTIFY_CONFIG_CHANGE_REQUEST_MESSAGE))
264               {
265                   // This operation is not provider-specific
266               }
267               else
268               {
269                   // Error: Unrecognized message type.
270                   PEGASUS_ASSERT(0);
271                   CIMResponseMessage* resp = request->buildResponse();
272                   resp->cimException = PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
273                       "Unknown message type.");
274 kumpf 1.1         response = resp;
275               }
276           
277               //
278               // Forward the request to the appropriate ProviderManager(s)
279               //
280           
281               if ((request->getType() == CIM_STOP_ALL_PROVIDERS_REQUEST_MESSAGE) ||
282                   (request->getType() ==
283                    CIM_SUBSCRIPTION_INIT_COMPLETE_REQUEST_MESSAGE))
284               {
285                   _subscriptionInitComplete = true;
286           
287                   // Send CIMStopAllProvidersRequestMessage or
288                   // CIMSubscriptionInitCompleteRequestMessage to all ProviderManagers
289                   ReadLock tableLock(_providerManagerTableLock);
290                   for (Uint32 i = 0, n = _providerManagerTable.size(); i < n; i++)
291                   {
292                       ProviderManagerContainer* pmc=_providerManagerTable[i];
293                       Message* resp = pmc->getProviderManager()->processMessage(request);
294                       delete resp;
295 kumpf 1.1         }
296           
297                   response = request->buildResponse();
298               }
299               else if(request->getType() == CIM_NOTIFY_CONFIG_CHANGE_REQUEST_MESSAGE)
300               {
301                   // Do not need to forward this request to in-process provider
302                   // managers
303                   response = request->buildResponse();
304               }
305               else
306               {
307                   // Retrieve the provider interface type
308                   String interfaceType;
309                   CIMValue itValue = providerModule.getProperty(
310                       providerModule.findProperty("InterfaceType")).getValue();
311                   itValue.get(interfaceType);
312           
313                   ProviderManager* pm = 0;
314                   Boolean gotError = false;
315                   try
316 kumpf 1.1         {
317                       // Look up the appropriate ProviderManager by InterfaceType
318                       pm = _lookupProviderManager(interfaceType);
319                   }
320                   catch (const CIMException& e)
321                   {
322                       CIMResponseMessage* cimResponse = request->buildResponse();
323                       cimResponse->cimException = e;
324                       response = cimResponse;
325                       gotError = true;
326                   }
327           
328                   if (remoteNameSpaceRequest && !pm->supportsRemoteNameSpaces())
329                   {
330                       CIMResponseMessage* resp = request->buildResponse();
331                       resp->cimException = PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED,
332                           "Remote Namespace operations not supported for interface type "
333                               + interfaceType);
334                       response = resp;
335                       gotError = true;
336                   }
337 kumpf 1.1 
338                   if (!gotError)
339                   {
340                       response = pm->processMessage(request);
341                   }
342               }
343           
344               // preserve message key
345               // set HTTP method in response from request
346               // set closeConnect
347              ((CIMResponseMessage *)response)->syncAttributes(request);
348           
349               PEG_METHOD_EXIT();
350               return response;
351           }
352           
353           // ATTN: May need to add interfaceVersion parameter to further constrain lookup
354           ProviderManager* BasicProviderManagerRouter::_lookupProviderManager(
355               const String& interfaceType)
356           {
357               PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
358 kumpf 1.1         "BasicProviderManagerRouter::_lookupProviderManager");
359           
360               //
361               // Search for this InterfaceType in the table of loaded ProviderManagers
362               //
363               {
364                   ReadLock tableLock(_providerManagerTableLock);
365           
366                   // find provider manager for specified provider interface type
367                   for(Uint32 i = 0, n = _providerManagerTable.size(); i < n; i++)
368                   {
369                       if (interfaceType == _providerManagerTable[i]->getInterfaceName())
370                       {
371                           ProviderManagerContainer* pmc=_providerManagerTable[i];
372                           PEG_METHOD_EXIT();
373                           return pmc->getProviderManager();
374                       }
375                   }
376               }
377           
378               //
379 kumpf 1.1     // Load the ProviderManager for this InterfaceType and add it to the table
380               //
381               {
382                   WriteLock tableLock(_providerManagerTableLock);
383           
384                   // ATTN: this section is a temporary solution to populate the list of
385                   // enabled provider managers for a given distribution.  It includes
386                   // another temporary solution for converting a generic file name into
387                   // a file name useable by each platform.
388           
389           	// The DefaultProviderManager is now statically linked rather than
390           	// dynamically loaded. This code is no longer used but remains for
391           	// reference purposes.
392           
393           #if defined(PEGASUS_ENABLE_DEFAULT_PROVIDER_MANAGER)
394           	if (interfaceType == "C++Default" && 
395           	    _createDefaultProviderManagerCallback)
396                   {
397           	    ProviderManager* pm = (*_createDefaultProviderManagerCallback)();
398                       ProviderManagerContainer* pmc = new ProviderManagerContainer(
399                           "C++Default",
400 kumpf 1.1                 _indicationCallback,
401                           _responseChunkCallback,
402                           _subscriptionInitComplete,
403           		pm);
404                       _providerManagerTable.append(pmc);
405                       return pmc->getProviderManager();
406                   }
407           #endif
408           
409           #if defined(PEGASUS_ENABLE_CMPI_PROVIDER_MANAGER)
410                   if (interfaceType == "CMPI")
411                   {
412                       ProviderManagerContainer* pmc = new ProviderManagerContainer(
413                           LIBRARY_NAME_CMPIPM,
414                           "CMPI",
415                           "CMPI",
416                           _indicationCallback,
417                           _responseChunkCallback,
418                           _subscriptionInitComplete);
419                       _providerManagerTable.append(pmc);
420                       return pmc->getProviderManager();
421 kumpf 1.1         }
422           #endif
423           
424           #if defined(PEGASUS_ENABLE_JMPI_PROVIDER_MANAGER)
425                   if (  interfaceType == "JMPI"
426                      || interfaceType == "JMPIExperimental"
427                      )
428                   {
429                       ProviderManagerContainer* pmc = new ProviderManagerContainer(
430                           LIBRARY_NAME_JMPIPM,
431                           interfaceType,
432                           interfaceType,
433                           _indicationCallback,
434                           _responseChunkCallback,
435                           _subscriptionInitComplete);
436                       _providerManagerTable.append(pmc);
437                       return pmc->getProviderManager();
438                   }
439           #endif
440                   // END TEMP SECTION
441               }
442 kumpf 1.1 
443               // Error: ProviderManager not found for the specified interface type
444               PEGASUS_ASSERT(0);
445               PEG_METHOD_EXIT();
446               return 0;
447           }
448           
449           Boolean BasicProviderManagerRouter::hasActiveProviders()
450           {
451               PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
452                   "BasicProviderManagerRouter::hasActiveProviders");
453           
454               ReadLock tableLock(_providerManagerTableLock);
455               for(Uint32 i = 0, n = _providerManagerTable.size(); i < n; i++)
456               {
457                   ProviderManagerContainer* pmc = _providerManagerTable[i];
458                   if (pmc->getProviderManager()->hasActiveProviders())
459                   {
460                       PEG_METHOD_EXIT();
461                       return true;
462                   }
463 kumpf 1.1     }
464           
465               PEG_METHOD_EXIT();
466               return false;
467           }
468           
469           void BasicProviderManagerRouter::unloadIdleProviders()
470           {
471               PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
472                   "BasicProviderManagerRouter::unloadIdleProviders");
473           
474               //
475               // Save pointers to the ProviderManagerContainers so we don't hold the
476               // _providerManagerTableLock while unloading idle providers
477               //
478               Array<ProviderManagerContainer*> pmcs;
479               {
480                   ReadLock tableLock(_providerManagerTableLock);
481                   for(Uint32 i = 0, n = _providerManagerTable.size(); i < n; i++)
482                   {
483                       pmcs.append(_providerManagerTable[i]);
484 kumpf 1.1         }
485               }
486           
487               //
488               // Unload idle providers in each of the active ProviderManagers
489               // _providerManagerTableLock while unloading idle providers
490               //
491               for (Uint32 i = 0; i < pmcs.size(); i++)
492               {
493                   pmcs[i]->getProviderManager()->unloadIdleProviders();
494               }
495           
496               PEG_METHOD_EXIT();
497           }
498           
499           PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2