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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2