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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2