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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2