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

  1 a.dunfey 1.73.2.1 //%2006////////////////////////////////////////////////////////////////////////
  2 chip     1.1      //
  3 karl     1.59     // 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 karl     1.15     // IBM Corp.; EMC Corporation, The Open Group.
  7 karl     1.59     // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
  8                   // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
  9 karl     1.63     // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 10                   // EMC Corporation; VERITAS Software Corporation; The Open Group.
 11 a.dunfey 1.73.2.1 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 12                   // EMC Corporation; Symantec Corporation; The Open Group.
 13 chip     1.1      //
 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 karl     1.59     // 
 21 chip     1.1      // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 22                   // 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                   // Author: Chip Vincent (cvincent@us.ibm.com)
 33                   //
 34                   // Modified By: Carol Ann Krug Graves, Hewlett-Packard Company
 35                   //                  (carolann_graves@hp.com)
 36                   //              Mike Day, IBM (mdday@us.ibm.com)
 37                   //              Karl Schopmeyer(k.schopmeyer@opengroup.org) - Fix associators.
 38 chip     1.9      //              Yi Zhou, Hewlett-Packard Company (yi_zhou@hp.com)
 39 schuur   1.19     //              Adrian Schuur, IBM (schuur@de.ibm.com)
 40 a.arora  1.37     //              Amit K Arora (amita@in.ibm.com) for PEP-101
 41 kumpf    1.39     //              Roger Kumpf, Hewlett-Packard Company (roger_kumpf@hp.com)
 42 se.gupta 1.41     //              Seema Gupta (gseema@in.ibm.com for PEP135)
 43 jim.wunderlich 1.69     //              Jim Wunderlich (Jim_Wunderlich@prodigy.net)
 44 aruran.ms      1.71     //              Aruran, IBM (ashanmug@in.ibm.com)for Bug# 3881
 45 chip           1.1      //
 46                         //%/////////////////////////////////////////////////////////////////////////////
 47                         
 48                         #include "ProviderManagerService.h"
 49                         
 50                         #include <Pegasus/Common/Config.h>
 51 kumpf          1.65     #include <Pegasus/Common/PegasusVersion.h>
 52 chip           1.1      #include <Pegasus/Common/Constants.h>
 53                         #include <Pegasus/Common/CIMMessage.h>
 54 kumpf          1.39     #include <Pegasus/Common/Thread.h>
 55 chip           1.1      #include <Pegasus/Common/Tracer.h>
 56                         #include <Pegasus/Common/Logger.h>
 57 a.arora        1.37     #include <Pegasus/Common/AutoPtr.h>
 58 kumpf          1.50     #include <Pegasus/Common/Constants.h>
 59 chip           1.1      
 60 chip           1.6      #include <Pegasus/Config/ConfigManager.h>
 61                         
 62 kumpf          1.39     #include <Pegasus/ProviderManager2/BasicProviderManagerRouter.h>
 63 kumpf          1.51     #include <Pegasus/ProviderManager2/OOPProviderManagerRouter.h>
 64 brian.campbell 1.60     #include <Pegasus/ProviderManager2/OperationResponseHandler.h>
 65 chip           1.17     
 66 chip           1.1      PEGASUS_NAMESPACE_BEGIN
 67                         
 68 chip           1.11     inline Boolean _isSupportedRequestType(const Message * message)
 69                         {
 70                             // ATTN: needs implementation
 71                         
 72                             // for now, assume all requests are valid
 73                         
 74                             return(true);
 75 chip           1.3      }
 76                         
 77                         inline Boolean _isSupportedResponseType(const Message * message)
 78                         {
 79 chip           1.11         // ATTN: needs implementation
 80                         
 81                             // for now, assume all responses are invalid
 82 chip           1.3      
 83 chip           1.11         return(false);
 84 chip           1.3      }
 85                         
 86 schuur         1.19     ProviderManagerService* ProviderManagerService::providerManagerService=NULL;
 87 kumpf          1.39     Uint32 ProviderManagerService::_indicationServiceQueueId = PEG_NOT_FOUND;
 88 schuur         1.19     
 89 chip           1.1      ProviderManagerService::ProviderManagerService(void)
 90                             : MessageQueueService(PEGASUS_QUEUENAME_PROVIDERMANAGER_CPP)
 91                         {
 92 schuur         1.19         providerManagerService=this;
 93 chip           1.1      }
 94                         
 95 schuur         1.25     ProviderManagerService::ProviderManagerService(
 96                                 ProviderRegistrationManager * providerRegistrationManager,
 97                                 CIMRepository * repository)
 98 chip           1.1          : MessageQueueService(PEGASUS_QUEUENAME_PROVIDERMANAGER_CPP)
 99                         {
100 schuur         1.19         providerManagerService=this;
101 schuur         1.25         _repository=repository;
102 dj.gorey       1.31     
103 kumpf          1.38         _providerRegistrationManager = providerRegistrationManager;
104 kumpf          1.44     
105                             _unloadIdleProvidersBusy = 0;
106                         
107 kumpf          1.62         _basicProviderManagerRouter = 0;
108                             _oopProviderManagerRouter = 0;
109                         
110                             // Determine which ProviderManagerRouter(s) to use
111                         
112 kumpf          1.51         ConfigManager* configManager = ConfigManager::getInstance();
113 kumpf          1.62         Boolean forceProviderProcesses = String::equal(
114                                 configManager->getCurrentValue("forceProviderProcesses"), "true");
115                         
116                         #ifdef PEGASUS_DISABLE_PROV_USERCTXT
117                             if (forceProviderProcesses)
118 kumpf          1.51         {
119 a.dunfey       1.73.2.2         _oopProviderManagerRouter = new OOPProviderManagerRouter(
120                                     indicationCallback, responseChunkCallback);
121 kumpf          1.51         }
122                             else
123                             {
124 a.dunfey       1.73.2.2         _basicProviderManagerRouter = new BasicProviderManagerRouter(
125                                     indicationCallback, responseChunkCallback);
126 kumpf          1.62         }
127                         #else
128 a.dunfey       1.73.2.2     _oopProviderManagerRouter = new OOPProviderManagerRouter(
129                                 indicationCallback, responseChunkCallback);
130 kumpf          1.62     
131                             if (!forceProviderProcesses)
132                             {
133 a.dunfey       1.73.2.2         _basicProviderManagerRouter = new BasicProviderManagerRouter(
134                                     indicationCallback, responseChunkCallback);
135 kumpf          1.51         }
136 kumpf          1.62     #endif
137 chip           1.1      }
138                         
139                         ProviderManagerService::~ProviderManagerService(void)
140                         {
141 kumpf          1.62         delete _basicProviderManagerRouter;
142                             delete _oopProviderManagerRouter;
143 schuur         1.19         providerManagerService=NULL;
144 chip           1.1      }
145                         
146                         Boolean ProviderManagerService::messageOK(const Message * message)
147                         {
148                             PEGASUS_ASSERT(message != 0);
149                         
150 chip           1.3          if(_isSupportedRequestType(message))
151 chip           1.1          {
152 chip           1.3              return(MessageQueueService::messageOK(message));
153 chip           1.1          }
154                         
155 chip           1.3          return(false);
156 chip           1.1      }
157                         
158                         void ProviderManagerService::handleEnqueue(void)
159                         {
160                             Message * message = dequeue();
161                         
162                             handleEnqueue(message);
163                         }
164                         
165                         void ProviderManagerService::handleEnqueue(Message * message)
166                         {
167                             PEGASUS_ASSERT(message != 0);
168                         
169                             AsyncLegacyOperationStart * asyncRequest;
170                         
171                             if(message->_async != NULL)
172                             {
173                                 asyncRequest = static_cast<AsyncLegacyOperationStart *>(message->_async);
174                             }
175                             else
176                             {
177 chip           1.1              asyncRequest = new AsyncLegacyOperationStart(
178                                     get_next_xid(),
179                                     0,
180                                     this->getQueueId(),
181                                     message,
182                                     this->getQueueId());
183                             }
184                         
185                             _handle_async_request(asyncRequest);
186                         }
187                         
188                         void ProviderManagerService::_handle_async_request(AsyncRequest * request)
189                         {
190                             PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
191                                 "ProviderManagerService::_handle_async_request");
192                         
193                             PEGASUS_ASSERT((request != 0) && (request->op != 0));
194                         
195                             if(request->getType() == async_messages::ASYNC_LEGACY_OP_START)
196                             {
197                                 request->op->processing();
198 chip           1.1      
199                                 _incomingQueue.enqueue(request->op);
200 konrad.r       1.68             ThreadStatus rtn = PEGASUS_THREAD_OK;
201                         	while (( rtn =_thread_pool->allocate_and_awaken(
202                                              (void *)this, ProviderManagerService::handleCimOperation)) != PEGASUS_THREAD_OK)
203                         	{
204                         	   if (rtn==PEGASUS_THREAD_INSUFFICIENT_RESOURCES)
205                                        pegasus_yield();
206                         	   else
207                         	   {
208                          	       Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
209                                     		"Not enough threads to service provider manager." );
210                          
211                          	       Tracer::trace(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
212                                                 "Could not allocate thread for %s.",
213                                                  getQueueName());
214 aruran.ms      1.71     		   break;
215 konrad.r       1.68     	   }
216                                 }
217 chip           1.1          }
218                             else
219                             {
220                                 // pass all other operations to the default handler
221                                 MessageQueueService::_handle_async_request(request);
222                             }
223                         
224                             PEG_METHOD_EXIT();
225                         
226                             return;
227                         }
228                         
229 kumpf          1.57     // Note: This method should not throw an exception.  It is used as a thread
230                         // entry point, and any exceptions thrown are ignored.
231 kumpf          1.39     PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL
232 kumpf          1.67     ProviderManagerService::handleCimOperation(void* arg) 
233 chip           1.1      {
234 kumpf          1.39         PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
235                                 "ProviderManagerService::handleCimOperation");
236 chip           1.1      
237 kumpf          1.67         PEGASUS_ASSERT(arg != 0);
238 chip           1.8      
239 chip           1.1          // get the service from argument
240 kumpf          1.67         ProviderManagerService* service =
241 kumpf          1.39             reinterpret_cast<ProviderManagerService *>(arg);
242 kumpf          1.67         PEGASUS_ASSERT(service != 0);
243 chip           1.1      
244 kumpf          1.67         try
245 chip           1.1          {
246 kumpf          1.67             if (service->_incomingQueue.size() == 0)
247                                 {
248                                     PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
249                                         "ProviderManagerService::handleCimOperation() called with no "
250                                             "op node in queue");
251 chip           1.1      
252 kumpf          1.67                 PEG_METHOD_EXIT();
253                                     return(PEGASUS_THREAD_RETURN(1));
254                                 }
255 chip           1.1      
256 kumpf          1.67             AsyncOpNode* op = service->_incomingQueue.dequeue();
257 chip           1.1      
258 kumpf          1.67             if ((op == 0) || (op->_request.count() == 0))
259                                 {
260                                     // ATTN: This may dereference a null pointer!
261                                     MessageQueue* queue = MessageQueue::lookup(op->_source_queue);
262 chip           1.1      
263 kumpf          1.67                 PEGASUS_ASSERT(queue != 0);
264 chip           1.1      
265 kumpf          1.67                 PEG_METHOD_EXIT();
266 chip           1.1      
267 kumpf          1.67                 // no request in op node
268                                     return(PEGASUS_THREAD_RETURN(1));
269                                 }
270 chip           1.1      
271 kumpf          1.67             AsyncRequest* request =
272                                     static_cast<AsyncRequest*>(op->_request.next(0));
273 chip           1.1      
274 kumpf          1.67             if ((request == 0) ||
275                                     (request->getType() != async_messages::ASYNC_LEGACY_OP_START))
276                                 {
277                                     // reply with NAK
278                                     PEG_METHOD_EXIT();
279                                     return(PEGASUS_THREAD_RETURN(0));
280                                 }
281 chip           1.1      
282 kumpf          1.39             Message* legacy =
283                                     static_cast<AsyncLegacyOperationStart *>(request)->get_action();
284 chip           1.1      
285 chip           1.8              if(_isSupportedRequestType(legacy))
286 chip           1.1              {
287 a.arora        1.37                 AutoPtr<Message> xmessage(legacy);
288 chip           1.1      
289 chip           1.8                  // Set the client's requested language into this service thread.
290                                     // This will allow functions in this service to return messages
291                                     // in the correct language.
292 kumpf          1.39                 CIMMessage* msg = dynamic_cast<CIMMessage *>(legacy);
293 chip           1.8      
294 kumpf          1.39                 if (msg != 0)
295 chip           1.8                  {
296 a.dunfey       1.73.2.1                 AcceptLanguageList* langs = new AcceptLanguageList(
297 kumpf          1.67                         ((AcceptLanguageListContainer)msg->operationContext.get(
298                                                 AcceptLanguageListContainer::NAME)).getLanguages());
299 chip           1.8                      Thread::setLanguages(langs);
300                                     }
301                                     else
302                                     {
303                                         Thread::clearLanguages();
304                                     }
305 chip           1.1      
306                                     service->handleCimRequest(op, legacy);
307 chip           1.3              }
308 chip           1.8          }
309 konrad.r       1.66         catch (const Exception& e)
310 kumpf          1.67         {
311 konrad.r       1.66             PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
312 kumpf          1.67                 "Unexpected exception in handleCimOperation: " + e.getMessage());
313                             }
314 konrad.r       1.66         catch (...)
315 kumpf          1.67         {
316 konrad.r       1.66             PEG_TRACE_STRING(TRC_DISCARDED_DATA, Tracer::LEVEL2,
317 kumpf          1.67                 "Unexpected exception in handleCimOperation.");
318                             }
319 chip           1.1      
320                             PEG_METHOD_EXIT();
321                         
322                             return(PEGASUS_THREAD_RETURN(0));
323                         }
324                         
325 kumpf          1.39     void ProviderManagerService::handleCimRequest(
326                             AsyncOpNode * op,
327                             Message * message)
328 chip           1.1      {
329 kumpf          1.39         PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
330                                 "ProviderManagerService::handleCimRequest");
331 chip           1.1      
332 kumpf          1.38         CIMRequestMessage * request = dynamic_cast<CIMRequestMessage *>(message);
333                             PEGASUS_ASSERT(request != 0);
334 chip           1.1      
335                             // get request from op node
336                             AsyncRequest * async = static_cast<AsyncRequest *>(op->_request.next(0));
337 kumpf          1.38         PEGASUS_ASSERT(async != 0);
338                         
339                             Message * response = 0;
340 kumpf          1.58         Boolean consumerLookupFailed = false;
341 chip           1.1      
342 kumpf          1.58         if (request->getType() == CIM_EXPORT_INDICATION_REQUEST_MESSAGE)
343                             {
344                                 //
345                                 // Get a ProviderIdContainer for ExportIndicationRequestMessage.
346                                 // Note: This can be removed when the CIMExportRequestDispatcher
347                                 // is updated to add the ProviderIdContainer to the message.
348                                 //
349                                 CIMInstance providerModule;
350                                 CIMInstance provider;
351                                 const CIMExportIndicationRequestMessage* expRequest =
352                                     dynamic_cast<const CIMExportIndicationRequestMessage*>(request);
353                                 if (_providerRegistrationManager->lookupIndicationConsumer(
354                                         expRequest->destinationPath, provider, providerModule))
355                                 {
356                                     request->operationContext.insert(
357                                         ProviderIdContainer(providerModule, provider));
358                                 }
359                                 else
360                                 {
361                                     consumerLookupFailed = true;
362                                 }
363 kumpf          1.58         }
364                         
365                             if (consumerLookupFailed)
366                             {
367                                 CIMResponseMessage* cimResponse = request->buildResponse();
368                                 cimResponse->cimException = PEGASUS_CIM_EXCEPTION(
369                                     CIM_ERR_NOT_SUPPORTED, String::EMPTY);
370                                 response = cimResponse;
371                             }
372                             else if ((dynamic_cast<CIMOperationRequestMessage*>(request) != 0) ||
373 kumpf          1.46             (dynamic_cast<CIMIndicationRequestMessage*>(request) != 0) ||
374 kumpf          1.40             (request->getType() == CIM_EXPORT_INDICATION_REQUEST_MESSAGE) ||
375 kumpf          1.45             (request->getType() == CIM_INITIALIZE_PROVIDER_REQUEST_MESSAGE))
376 kumpf          1.38         {
377 kumpf          1.45             // Handle CIMOperationRequestMessage, CIMExportIndicationRequestMessage,
378 kumpf          1.46             // CIMIndicationRequestMessage, and CIMInitializeProviderRequestMessage.
379                                 // (These should be blocked when the provider module is disabled.)
380 kumpf          1.45     
381 kumpf          1.46             //
382                                 // Get the provider module instance to check for a disabled module
383                                 //
384                                 CIMInstance providerModule;
385 kumpf          1.45     
386 kumpf          1.58             // The provider ID container is added to the OperationContext
387                                 // by the CIMOperationRequestDispatcher for all CIM operation
388                                 // requests to providers, so it does not need to be added again.
389                                 // CIMInitializeProviderRequestMessage also has a provider ID
390                                 // container.
391                                 ProviderIdContainer pidc =
392                                     request->operationContext.get(ProviderIdContainer::NAME);
393                                 providerModule = pidc.getModule();
394 kumpf          1.38     
395 kumpf          1.45             //
396                                 // Check if the target provider is disabled
397                                 //
398                                 Boolean moduleDisabled = false;
399                                 Uint32 pos = providerModule.findProperty(CIMName("OperationalStatus"));
400                                 PEGASUS_ASSERT(pos != PEG_NOT_FOUND);
401                                 Array<Uint16> operationalStatus;
402                                 providerModule.getProperty(pos).getValue().get(operationalStatus);
403                         
404                                 for(Uint32 i = 0; i < operationalStatus.size(); i++)
405                                 {
406 kumpf          1.50                 if ((operationalStatus[i] == CIM_MSE_OPSTATUS_VALUE_STOPPED) ||
407                                         (operationalStatus[i] == CIM_MSE_OPSTATUS_VALUE_STOPPING))
408 kumpf          1.45                 {
409                                         moduleDisabled = true;
410                                         break;
411                                     }
412                                 }
413                         
414                                 if (moduleDisabled)
415                                 {
416                                     //
417                                     // Send a "provider blocked" response
418                                     //
419                                     CIMResponseMessage* cimResponse = request->buildResponse();
420                                     cimResponse->cimException = PEGASUS_CIM_EXCEPTION_L(
421                                         CIM_ERR_ACCESS_DENIED,
422                                         MessageLoaderParms(
423                                             "ProviderManager.ProviderManagerService.PROVIDER_BLOCKED",
424                                             "provider blocked."));
425                                     response = cimResponse;
426 w.white        1.70     
427                                      STAT_COPYDISPATCHER
428 kumpf          1.45             }
429                                 else
430                                 {
431                                     //
432                                     // Forward the request to the appropriate ProviderManagerRouter
433                                     //
434 kumpf          1.62                 response = _processMessage(request);
435 kumpf          1.45             }
436 schuur         1.19         }
437 kumpf          1.38         else if (request->getType() == CIM_ENABLE_MODULE_REQUEST_MESSAGE)
438                             {
439                                 // Handle CIMEnableModuleRequestMessage
440                                 CIMEnableModuleRequestMessage * emReq =
441                                     dynamic_cast<CIMEnableModuleRequestMessage*>(request);
442                         
443                                 CIMInstance providerModule = emReq->providerModule;
444 dj.gorey       1.31     
445 kumpf          1.38             try
446                                 {
447 kumpf          1.39                 // Forward the request to the ProviderManager
448 kumpf          1.62                 response = _processMessage(request);
449 kumpf          1.38     
450                                     // If successful, update provider module status to OK
451                                     // ATTN: Use CIMEnableModuleResponseMessage operationalStatus?
452                                     CIMEnableModuleResponseMessage * emResp =
453                                         dynamic_cast<CIMEnableModuleResponseMessage*>(response);
454                                     if (emResp->cimException.getCode() == CIM_ERR_SUCCESS)
455                                     {
456                                         _updateProviderModuleStatus(
457 kumpf          1.50                         providerModule, CIM_MSE_OPSTATUS_VALUE_STOPPED, 
458                                             CIM_MSE_OPSTATUS_VALUE_OK);
459 kumpf          1.38                 }
460                                 }
461                                 catch (Exception& e)
462                                 {
463                                     // Get the OperationalStatus property from the provider module
464                                     Array<Uint16> operationalStatus;
465                                     CIMValue itValue = emReq->providerModule.getProperty(
466                                         emReq->providerModule.findProperty("OperationalStatus"))
467                                             .getValue();
468                                     itValue.get(operationalStatus);
469                         
470                                     if (response != 0)
471                                     {
472                                         delete response;
473                                     }
474                         
475                                     response = new CIMEnableModuleResponseMessage(
476                                         request->messageId,
477                                         CIMException(CIM_ERR_FAILED, e.getMessage()),
478                                         request->queueIds.copyAndPop(),
479                                         operationalStatus);
480 kumpf          1.38             }
481                             }
482                             else if (request->getType() == CIM_DISABLE_MODULE_REQUEST_MESSAGE)
483                             {
484                                 // Handle CIMDisableModuleRequestMessage
485                                 CIMDisableModuleRequestMessage * dmReq =
486                                     dynamic_cast<CIMDisableModuleRequestMessage*>(request);
487                         
488                                 CIMInstance providerModule = dmReq->providerModule;
489                                 Boolean updateModuleStatus = !dmReq->disableProviderOnly;
490                         
491                                 try
492                                 {
493                                     // Change module status from OK to STOPPING
494                                     if (updateModuleStatus)
495                                     {
496                                         _updateProviderModuleStatus(
497 kumpf          1.50                         providerModule, CIM_MSE_OPSTATUS_VALUE_OK, 
498                                             CIM_MSE_OPSTATUS_VALUE_STOPPING);
499 kumpf          1.38                 }
500                         
501 kumpf          1.39                 // Forward the request to the ProviderManager
502 kumpf          1.62                 response = _processMessage(request);
503 kumpf          1.38     
504                                     // Update provider module status based on success or failure
505                                     if (updateModuleStatus)
506                                     {
507                                         CIMDisableModuleResponseMessage * dmResp =
508                                             dynamic_cast<CIMDisableModuleResponseMessage*>(response);
509                                         if (dmResp->cimException.getCode() != CIM_ERR_SUCCESS)
510                                         {
511                                             // Disable operation failed.  Module not stopped.
512                                             _updateProviderModuleStatus(
513 kumpf          1.50                             providerModule, CIM_MSE_OPSTATUS_VALUE_STOPPING, 
514                                                 CIM_MSE_OPSTATUS_VALUE_OK);
515 kumpf          1.38                     }
516                                         else
517                                         {
518                                             // Disable may or may not have been successful,
519                                             // depending on whether there are outstanding requests.
520                                             // Use last operationalStatus entry.
521                                             _updateProviderModuleStatus(
522 kumpf          1.50                             providerModule, CIM_MSE_OPSTATUS_VALUE_STOPPING,
523 kumpf          1.38                             dmResp->operationalStatus[
524                                                     dmResp->operationalStatus.size()-1]);
525                                         }
526                                     }
527                                 }
528                                 catch (Exception& e)
529                                 {
530                                     // Get the OperationalStatus property from the provider module
531                                     Array<Uint16> operationalStatus;
532                                     CIMValue itValue = dmReq->providerModule.getProperty(
533                                         dmReq->providerModule.findProperty("OperationalStatus"))
534                                             .getValue();
535                                     itValue.get(operationalStatus);
536                         
537                                     if (response != 0)
538                                     {
539                                         delete response;
540                                     }
541                         
542                                     response = new CIMDisableModuleResponseMessage(
543                                         request->messageId,
544 kumpf          1.38                     CIMException(CIM_ERR_FAILED, e.getMessage()),
545                                         request->queueIds.copyAndPop(),
546                                         operationalStatus);
547                                 }
548                             }
549                             else
550                             {
551 kumpf          1.62             response = _processMessage(request);
552 schuur         1.23         }
553 chip           1.13     
554 schuur         1.19         AsyncLegacyOperationResult * async_result =
555                                 new AsyncLegacyOperationResult(
556                                 async->getKey(),
557                                 async->getRouting(),
558                                 op,
559                                 response);
560 chip           1.13     
561 schuur         1.19         _complete_op_node(op, ASYNC_OPSTATE_COMPLETE, 0, 0);
562 chip           1.13     
563 schuur         1.19         PEG_METHOD_EXIT();
564                         }
565 chip           1.13     
566 a.dunfey       1.73.2.2 void ProviderManagerService::responseChunkCallback(
567                             CIMRequestMessage* request,
568                             CIMResponseMessage* response)
569 brian.campbell 1.60     {
570                         	CIMStatusCode code = CIM_ERR_SUCCESS;
571                         	String message;
572                         
573                         	try
574                         	{
575                         		// only incomplete messages are processed because the caller ends up
576                         		// sending the complete() stage
577 a.dunfey       1.73.2.2 		PEGASUS_ASSERT(response->isComplete() == false);
578 brian.campbell 1.60     		
579                         		AsyncLegacyOperationStart *requestAsync = 
580 a.dunfey       1.73.2.2 			dynamic_cast<AsyncLegacyOperationStart *>(request->_async);
581 brian.campbell 1.60     		PEGASUS_ASSERT(requestAsync);
582                         		AsyncOpNode *op = requestAsync->op;
583                         		PEGASUS_ASSERT(op);
584 a.dunfey       1.73.2.2 		PEGASUS_ASSERT(!response->_async);
585                         		response->_async = new AsyncLegacyOperationResult(
586                         			requestAsync->getKey(), requestAsync->getRouting(), op, response);
587 brian.campbell 1.60     		
588                         		// set the destination
589                         		op->_op_dest = op->_callback_response_q;
590                         		
591                         		MessageQueueService *service = 	
592                         			dynamic_cast<MessageQueueService *>(op->_callback_response_q);
593                         
594                         		PEGASUS_ASSERT(service);
595                         
596                         		// the last chunk MUST be sent last, so use execute the callback
597                         		// not all chunks are going through the dispatcher's chunk 
598                         		// resequencer, so this must be a synchronous call here
599                         		// After the call is done, response and asyncResponse are now invalid 
600                         		// as they have been sent and deleted externally
601                         		
602                         		op->_async_callback(op, service, op->_callback_ptr);
603                         	}
604                         
605                         	catch(CIMException &e)
606                         	{
607                         		code = e.getCode();
608 brian.campbell 1.60     		message = e.getMessage();
609                         	}
610                         	catch(Exception &e)
611                         	{
612                         		code = CIM_ERR_FAILED;
613                         		message = e.getMessage();
614                         	}
615                         	catch(...)
616                         	{
617                         		code = CIM_ERR_FAILED;
618                         		message = cimStatusCodeToString(code);
619                         	}
620                         
621                         	if (code !=  CIM_ERR_SUCCESS)
622 a.dunfey       1.73.2.2 		response->cimException = PEGASUS_CIM_EXCEPTION(code, message);
623 brian.campbell 1.60     }
624                         
625 kumpf          1.62     Message* ProviderManagerService::_processMessage(CIMRequestMessage* request)
626                         {
627                             Message* response = 0;
628                         
629                             if ((request->getType() == CIM_STOP_ALL_PROVIDERS_REQUEST_MESSAGE) ||
630 carolann.graves 1.64             (request->getType() == 
631                                      CIM_SUBSCRIPTION_INIT_COMPLETE_REQUEST_MESSAGE) ||
632 kumpf           1.62             (request->getType() == CIM_NOTIFY_CONFIG_CHANGE_REQUEST_MESSAGE))
633                              {
634                                  if (_basicProviderManagerRouter)
635                                  {
636                                      response = _basicProviderManagerRouter->processMessage(request);
637                                  }
638                          
639                                  if (_oopProviderManagerRouter)
640                                  {
641                                      // Note: These responses do not contain interesting data, so just
642                                      // use the last one.
643                                      if (response)
644                                      {
645                                          delete response;
646                                      }
647                          
648                                      response = _oopProviderManagerRouter->processMessage(request);
649                                  }
650                              }
651                              else
652                              {
653 kumpf           1.62             CIMInstance providerModule;
654                          
655                                  if (request->getType() == CIM_ENABLE_MODULE_REQUEST_MESSAGE)
656                                  {
657                                      CIMEnableModuleRequestMessage* emReq =
658                                          dynamic_cast<CIMEnableModuleRequestMessage*>(request);
659                                      providerModule = emReq->providerModule;
660                                  }
661                                  else if (request->getType() == CIM_DISABLE_MODULE_REQUEST_MESSAGE)
662                                  {
663                                      CIMDisableModuleRequestMessage* dmReq =
664                                          dynamic_cast<CIMDisableModuleRequestMessage*>(request);
665                                      providerModule = dmReq->providerModule;
666                                  }
667                                  else
668                                  {
669                                      ProviderIdContainer pidc =
670                                          request->operationContext.get(ProviderIdContainer::NAME);
671                                      providerModule = pidc.getModule();
672                                  }
673                          
674 kumpf           1.62             Uint16 userContext = 0;
675                                  Uint32 pos = providerModule.findProperty(
676                                      PEGASUS_PROPERTYNAME_MODULE_USERCONTEXT);
677                                  if (pos != PEG_NOT_FOUND)
678                                  {
679                                      providerModule.getProperty(pos).getValue().get(userContext);
680                                  }
681                          
682                                  // Forward the request to the appropriate ProviderManagerRouter, based
683                                  // on the CIM Server configuration and the UserContext setting.
684                          
685                                  ConfigManager* configManager = ConfigManager::getInstance();
686                                  Boolean forceProviderProcesses = String::equal(
687                                      configManager->getCurrentValue("forceProviderProcesses"), "true");
688                          
689                                  if (forceProviderProcesses
690                          #ifndef PEGASUS_DISABLE_PROV_USERCTXT
691                                      || (userContext == PG_PROVMODULE_USERCTXT_REQUESTOR)
692                                      || (userContext == PG_PROVMODULE_USERCTXT_DESIGNATED)
693                                      || ((userContext == PG_PROVMODULE_USERCTXT_PRIVILEGED) &&
694                                          !System::isPrivilegedUser(System::getEffectiveUserName()))
695 kumpf           1.62     #endif
696                                     )
697                                  {
698                                      response = _oopProviderManagerRouter->processMessage(request);
699                                  }
700                                  else
701                                  {
702                                      response = _basicProviderManagerRouter->processMessage(request);
703                                  }
704                              }
705                          
706                              return response;
707                          }
708                          
709 kumpf           1.44     void ProviderManagerService::unloadIdleProviders()
710                          {
711                              PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
712                                  "ProviderManagerService::unloadIdleProviders");
713 konrad.r        1.68         ThreadStatus rtn = PEGASUS_THREAD_OK;
714 kumpf           1.44         // Ensure that only one _unloadIdleProvidersHandler thread runs at a time
715                              _unloadIdleProvidersBusy++;
716 mike            1.72         if ((_unloadIdleProvidersBusy.get() == 1) &&
717 konrad.r        1.68             ((rtn = _thread_pool->allocate_and_awaken(
718                                       (void*)this, ProviderManagerService::_unloadIdleProvidersHandler))==PEGASUS_THREAD_OK))
719 kumpf           1.44         {
720                                  // _unloadIdleProvidersBusy is decremented in
721                                  // _unloadIdleProvidersHandler
722                              }
723                              else
724                              {
725                                  // If we fail to allocate a thread, don't retry now.
726                                  _unloadIdleProvidersBusy--;
727                              }
728 konrad.r        1.68         if (rtn != PEGASUS_THREAD_OK) 
729                              {
730                          	Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::TRACE,
731                          		"Not enough threads to unload idle providers.");
732                           
733                          	Tracer::trace(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
734                          		"Could not allocate thread for %s to unload idle providers.", 
735                          		getQueueName());
736                              }
737 kumpf           1.44         PEG_METHOD_EXIT();
738                          }
739                          
740                          PEGASUS_THREAD_RETURN PEGASUS_THREAD_CDECL
741                          ProviderManagerService::_unloadIdleProvidersHandler(void* arg) throw()
742 chip            1.1      {
743 kumpf           1.44         try
744                              {
745                                  PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
746                                      "ProviderManagerService::unloadIdleProvidersHandler");
747                          
748                                  ProviderManagerService* myself =
749                                      reinterpret_cast<ProviderManagerService*>(arg);
750                          
751 kumpf           1.62             if (myself->_basicProviderManagerRouter)
752 kumpf           1.44             {
753 kumpf           1.62                 try
754                                      {
755                                          myself->_basicProviderManagerRouter->unloadIdleProviders();
756                                      }
757                                      catch (...)
758                                      {
759                                          // Ignore errors
760                                          PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
761                                              "Unexpected exception from "
762                                                  "BasicProviderManagerRouter::_unloadIdleProviders");
763                                      }
764 kumpf           1.44             }
765 kumpf           1.62     
766                                  if (myself->_oopProviderManagerRouter)
767 kumpf           1.44             {
768 kumpf           1.62                 try
769                                      {
770                                          myself->_oopProviderManagerRouter->unloadIdleProviders();
771                                      }
772                                      catch (...)
773                                      {
774                                          // Ignore errors
775                                          PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
776                                              "Unexpected exception from "
777                                                  "OOPProviderManagerRouter::_unloadIdleProviders");
778                                      }
779 kumpf           1.44             }
780                          
781                                  myself->_unloadIdleProvidersBusy--;
782                                  PEG_METHOD_EXIT();
783                              }
784                              catch (...)
785                              {
786                                  // Ignore errors
787                                  PEG_TRACE_STRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
788                                      "Unexpected exception in _unloadIdleProvidersHandler");
789                              }
790                          
791                              return(PEGASUS_THREAD_RETURN(0));
792 kumpf           1.38     }
793                          
794                          // Updates the providerModule instance and the ProviderRegistrationManager
795                          void ProviderManagerService::_updateProviderModuleStatus(
796                              CIMInstance& providerModule,
797                              Uint16 fromStatus,
798                              Uint16 toStatus)
799                          {
800                              PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
801                                  "ProviderManagerService::_updateProviderModuleStatus");
802                          
803                              Array<Uint16> operationalStatus;
804                              String providerModuleName;
805                          
806                              Uint32 pos = providerModule.findProperty(CIMName("Name"));
807                              PEGASUS_ASSERT(pos != PEG_NOT_FOUND);
808                              providerModule.getProperty(pos).getValue().get(providerModuleName);
809                          
810                              //
811                              // get operational status
812                              //
813 kumpf           1.38         pos = providerModule.findProperty(CIMName("OperationalStatus"));
814                              PEGASUS_ASSERT(pos != PEG_NOT_FOUND);
815                              CIMProperty operationalStatusProperty = providerModule.getProperty(pos);
816                              CIMValue operationalStatusValue = operationalStatusProperty.getValue();
817                          
818                              if (!operationalStatusValue.isNull())
819                              {
820                                  operationalStatusValue.get(operationalStatus);
821                              }
822                          
823                              //
824                              // update module status
825                              //
826                              for (Uint32 i = operationalStatus.size(); i > 0; i--)
827                              {
828                                  if (operationalStatus[i-1] == fromStatus)
829                                  {
830                                      operationalStatus.remove(i-1);
831                                  }
832                              }
833                          
834 kumpf           1.38         operationalStatus.append(toStatus);
835                          
836                              if (_providerRegistrationManager->setProviderModuleStatus(
837                                      providerModuleName, operationalStatus) == false)
838                              {
839                                  throw PEGASUS_CIM_EXCEPTION_L(
840                                      CIM_ERR_FAILED,
841                                      MessageLoaderParms(
842                                          "ProviderManager.ProviderManagerService."
843                                              "SET_MODULE_STATUS_FAILED",
844                                          "set module status failed."));
845                              }
846                          
847                              operationalStatusProperty.setValue(CIMValue(operationalStatus));
848                          
849                              PEG_METHOD_EXIT();
850 kumpf           1.39     }
851                          
852                          void ProviderManagerService::indicationCallback(
853                              CIMProcessIndicationRequestMessage* request)
854                          {
855 se.gupta        1.52      	try
856                          	{
857                          		AcceptLanguageListContainer cntr = request->operationContext.get(AcceptLanguageListContainer::NAME);
858 david.dillard   1.55     	}catch(const Exception &)
859 se.gupta        1.52     	{
860 a.dunfey        1.73.2.1 		request->operationContext.insert(AcceptLanguageListContainer(AcceptLanguageList()));
861 se.gupta        1.52     	}    
862                          	
863                          	if (_indicationServiceQueueId == PEG_NOT_FOUND)
864 kumpf           1.39         {
865                                  Array<Uint32> serviceIds;
866                          
867                                  providerManagerService->find_services(
868                                      PEGASUS_QUEUENAME_INDICATIONSERVICE, 0, 0, &serviceIds);
869                                  PEGASUS_ASSERT(serviceIds.size() != 0);
870                          
871                                  _indicationServiceQueueId = serviceIds[0];
872                              }
873                          
874                              request->queueIds = QueueIdStack(
875                                  _indicationServiceQueueId, providerManagerService->getQueueId());
876                          
877                              AsyncLegacyOperationStart * asyncRequest =
878                                  new AsyncLegacyOperationStart(
879                                  providerManagerService->get_next_xid(),
880                                  0,
881                                  _indicationServiceQueueId,
882                                  request,
883                                  _indicationServiceQueueId);
884                          
885 kumpf           1.39         providerManagerService->SendForget(asyncRequest);
886 jim.wunderlich  1.69     
887                          
888                          
889                          
890                          #ifdef PEGASUS_INDICATIONS_Q_THRESHOLD
891                          
892                              // See Comments in config.mak asociated with 
893                              //  PEGASUS_INDICATIONS_Q_THRESHOLD
894                              //
895                              // if INDICATIONS_Q_STALL THRESHOLD is gt 0
896                              // then if there are over INDICATIONS_Q_STALL_THRESHOLD
897                              //           indications in the queue 
898                              //      then force this provider to sleep until the queue count
899                              //      is lower than INDICATIONS_Q_RESUME_THRESHOLD
900                          
901                          static Mutex   indicationThresholdReportedLock;
902                          static Boolean indicationThresholdReported = false;
903                          
904                          #define INDICATIONS_Q_STALL_THRESHOLD PEGASUS_INDICATIONS_Q_THRESHOLD
905                          #define INDICATIONS_Q_RESUME_THRESHOLD (int)(PEGASUS_INDICATIONS_Q_THRESHOLD*.90)
906                          #define INDICATIONS_Q_STALL_DURATION 250 // milli-seconds
907 jim.wunderlich  1.69     
908                              MessageQueue * indicationsQueue = MessageQueue::lookup(_indicationServiceQueueId);
909                          
910                              if (((MessageQueueService *)indicationsQueue)->getIncomingCount() > INDICATIONS_Q_STALL_THRESHOLD)
911                                {
912                                  AutoMutex indicationThresholdReportedAutoMutex(indicationThresholdReportedLock);
913                                  if (!indicationThresholdReported)
914                                    {
915                                      indicationThresholdReported = true;
916                                      indicationThresholdReportedAutoMutex.unlock();
917                          
918                                      // make log entry to record que max exceeded 
919                          
920                                      Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::INFORMATION,
921                                         "Indication generation stalled: maximum queue count ($0) exceeded.",
922                                          INDICATIONS_Q_STALL_THRESHOLD);
923                                    }
924                                  else 
925                                    {
926                                      indicationThresholdReportedAutoMutex.unlock();
927                                    }
928 jim.wunderlich  1.69     
929                                  while (((MessageQueueService *)indicationsQueue)->getIncomingCount() > INDICATIONS_Q_RESUME_THRESHOLD)
930                                    {
931                                      pegasus_sleep(INDICATIONS_Q_STALL_DURATION);
932                                    }
933                          
934                                  AutoMutex indicationThresholdReportedAutoMutex1(indicationThresholdReportedLock);
935                                  //        indicationThresholdReportedLock.lock(pegasus_thread_self());
936                                  if(indicationThresholdReported)
937                                    {
938                                      indicationThresholdReported = false;
939                                      indicationThresholdReportedAutoMutex1.unlock();
940                                     
941                                      Logger::put(Logger::STANDARD_LOG, System::CIMSERVER, Logger::INFORMATION,
942                                            "Indication generation resumed: current queue count = $0", 
943                                            ((MessageQueueService *)indicationsQueue)->getIncomingCount() );
944                          
945                                    }
946                                  else
947                                    {
948                                      indicationThresholdReportedAutoMutex1.unlock();
949 jim.wunderlich  1.69               }
950                                }  
951                          #endif /* INDICATIONS_Q_STALL_THRESHOLD */
952                          
953 chip            1.1      }
954                          
955 a.arora         1.37     PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2