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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2