1 martin 1.34 //%LICENSE////////////////////////////////////////////////////////////////
|
2 martin 1.35 //
|
3 martin 1.34 // Licensed to The Open Group (TOG) under one or more contributor license
4 // agreements. Refer to the OpenPegasusNOTICE.txt file distributed with
5 // this work for additional information regarding copyright ownership.
6 // Each contributor licenses this file to you under the OpenPegasus Open
7 // Source License; you may not use this file except in compliance with the
8 // License.
|
9 martin 1.35 //
|
10 martin 1.34 // Permission is hereby granted, free of charge, to any person obtaining a
11 // copy of this software and associated documentation files (the "Software"),
12 // to deal in the Software without restriction, including without limitation
13 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 // and/or sell copies of the Software, and to permit persons to whom the
15 // Software is furnished to do so, subject to the following conditions:
|
16 martin 1.35 //
|
17 martin 1.34 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
|
19 martin 1.35 //
|
20 martin 1.34 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
21 martin 1.35 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
22 martin 1.34 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
27 martin 1.35 //
|
28 martin 1.34 //////////////////////////////////////////////////////////////////////////
|
29 kumpf 1.1 //
30 //%/////////////////////////////////////////////////////////////////////////////
31
32 #include "ProviderManagerService.h"
33
34 #include <Pegasus/Common/Config.h>
35 #include <Pegasus/Common/PegasusVersion.h>
36 #include <Pegasus/Common/Constants.h>
37 #include <Pegasus/Common/CIMMessage.h>
|
38 venkat.puvvada 1.45 #include <Pegasus/Common/CimomMessage.h>
|
39 kumpf 1.1 #include <Pegasus/Common/Thread.h>
40 #include <Pegasus/Common/Tracer.h>
41 #include <Pegasus/Common/Logger.h>
42 #include <Pegasus/Common/AutoPtr.h>
43 #include <Pegasus/Common/Constants.h>
44 #include <Pegasus/Common/StatisticalData.h>
|
45 venkat.puvvada 1.45 #include <Pegasus/Common/StringConversion.h>
46 #include <Pegasus/Common/ModuleController.h>
|
47 kumpf 1.1
48 #include <Pegasus/Config/ConfigManager.h>
49
|
50 s.kodali 1.46 #include <Pegasus/ProviderManagerRouter/BasicProviderManagerRouter.h>
51 #include <Pegasus/ProviderManagerRouter/OOPProviderManagerRouter.h>
|
52 kumpf 1.1
|
53 b.whiteley 1.18 #include <Pegasus/Server/ProviderRegistrationManager/ProviderManagerMap.h>
54
|
55 marek 1.2 #ifdef PEGASUS_ZOS_SECURITY
56 // This include file will not be provided in the OpenGroup CVS for now.
57 // Do NOT try to include it in your compile
58 #include <Pegasus/ProviderManager2/ProviderManagerzOS_inline.h>
59 #endif
60
|
61 kumpf 1.1 PEGASUS_NAMESPACE_BEGIN
62
|
63 venkat.puvvada 1.43 const String PG_PROVMODULE_GROUPNAME_CIMSERVER = "CIMServer";
64
|
65 kumpf 1.1 ProviderManagerService* ProviderManagerService::providerManagerService=NULL;
|
66 kumpf 1.38 Boolean ProviderManagerService::_allProvidersStopped = false;
|
67 kumpf 1.1 Uint32 ProviderManagerService::_indicationServiceQueueId = PEG_NOT_FOUND;
|
68 s.kodali 1.46 ProviderRegistrationManager*
69 ProviderManagerService::_providerRegistrationManager;
|
70 kumpf 1.1
|
71 venkat.puvvada 1.45 /**
72 Hashtable for the failed provider modules. This table maintains the
73 failure count for each provider module.
74 */
75 static HashTable <String, Uint32, EqualFunc <String>,
76 HashFunc <String> > _failedProviderModuleTable;
77
78 static Mutex _failedProviderModuleTableMutex;
79
80 //
81 // This method is called when the provider module is failed and
82 // maxFailedProviderModuleRestarts config value is specified.
83 //
84 void ProviderManagerService::_invokeProviderModuleStartMethod(
85 const CIMObjectPath &ref)
86 {
87 try
88 {
89 ModuleController *controller = ModuleController::getModuleController();
90 PEGASUS_ASSERT(controller);
91
92 venkat.puvvada 1.45 CIMInvokeMethodRequestMessage* request =
93 new CIMInvokeMethodRequestMessage(
94 XmlWriter::getNextMessageId(),
95 PEGASUS_NAMESPACENAME_INTEROP,
96 ref,
97 "Start",
98 Array<CIMParamValue>(),
99 QueueIdStack(controller->getQueueId()));
100
101 request->operationContext.insert(
102 IdentityContainer(String()));
103
104 AsyncModuleOperationStart* moduleControllerRequest =
105 new AsyncModuleOperationStart(
106 0,
107 controller->getQueueId(),
108 PEGASUS_MODULENAME_PROVREGPROVIDER,
109 request);
110 // We are not intersted in the response.
111 controller->SendForget(moduleControllerRequest);
112 }
113 venkat.puvvada 1.45 catch(const Exception &e)
114 {
115 PEG_TRACE((TRC_PROVIDERMANAGER,Tracer::LEVEL1,
116 "Exception caught while invoking PG_ProviderModule.start"
117 " method: %s",
118 (const char*)e.getMessage().getCString()));
119 }
120 catch(...)
121 {
122 PEG_TRACE_CSTRING(TRC_PROVIDERMANAGER,Tracer::LEVEL1,
123 "Unknown exception caught while invoking PG_ProviderModule.start"
124 " method");
125 }
126 }
127
|
128 kumpf 1.1 ProviderManagerService::ProviderManagerService(
129 ProviderRegistrationManager * providerRegistrationManager,
130 CIMRepository * repository,
131 ProviderManager* (*createDefaultProviderManagerCallback)())
132 : MessageQueueService(PEGASUS_QUEUENAME_PROVIDERMANAGER_CPP)
133 {
134 providerManagerService=this;
135 _repository=repository;
136
137 _providerRegistrationManager = providerRegistrationManager;
138
|
139 sahana.prabhakar 1.44 _idleTimeCleanupBusy = 0;
|
140 kumpf 1.1
141 _forceProviderProcesses = ConfigManager::parseBooleanValue(
142 ConfigManager::getInstance()->getCurrentValue(
143 "forceProviderProcesses"));
144
145 _oopProviderManagerRouter = new OOPProviderManagerRouter(
|
146 venkat.puvvada 1.43 indicationCallback,
147 responseChunkCallback,
|
148 s.kodali 1.46 providerModuleGroupFailureCallback,
|
149 sahana.prabhakar 1.44 asyncResponseCallback);
|
150 kumpf 1.1
|
151 venkat.puvvada 1.43 _basicProviderManagerRouter = new BasicProviderManagerRouter(
152 indicationCallback,
153 responseChunkCallback,
154 createDefaultProviderManagerCallback);
|
155 kumpf 1.1 }
156
157 ProviderManagerService::~ProviderManagerService(void)
158 {
159 delete _basicProviderManagerRouter;
160 delete _oopProviderManagerRouter;
161 providerManagerService=NULL;
162 }
163
164 void ProviderManagerService::handleEnqueue(void)
165 {
166 Message * message = dequeue();
167
168 handleEnqueue(message);
169 }
170
|
171 venkat.puvvada 1.49 void ProviderManagerService::_handleIndicationDeliveryResponse(Message *message)
172 {
173 CIMProcessIndicationResponseMessage *response =
174 (CIMProcessIndicationResponseMessage*)message;
175 if (response->oopAgentName.size())
176 {
177 _oopProviderManagerRouter->processMessage(response);
178 }
179 else
180 {
181 IndicationRouter::notify(response);
182 }
183 }
184
|
185 kumpf 1.1 void ProviderManagerService::handleEnqueue(Message * message)
186 {
187 PEGASUS_ASSERT(message != 0);
188
|
189 venkat.puvvada 1.49 if (message->getType() == CIM_PROCESS_INDICATION_RESPONSE_MESSAGE)
190 {
191 _handleIndicationDeliveryResponse(message);
192 return;
193 }
194
|
195 kumpf 1.14 AsyncLegacyOperationStart* asyncRequest =
196 static_cast<AsyncLegacyOperationStart*>(message->get_async());
|
197 kumpf 1.1
|
198 kumpf 1.14 if (asyncRequest == 0)
|
199 kumpf 1.1 {
200 asyncRequest = new AsyncLegacyOperationStart(
201 0,
202 this->getQueueId(),
|
203 venkat.puvvada 1.26 message);
|
204 kumpf 1.1 }
205
206 _handle_async_request(asyncRequest);
207 }
208
209 void ProviderManagerService::_handle_async_request(AsyncRequest * request)
210 {
211 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
212 "ProviderManagerService::_handle_async_request");
213
214 PEGASUS_ASSERT((request != 0) && (request->op != 0));
215
|
216 kumpf 1.10 if (request->getType() == ASYNC_ASYNC_LEGACY_OP_START)
|
217 kumpf 1.1 {
218 _incomingQueue.insert_back(request->op);
219 ThreadStatus rtn = PEGASUS_THREAD_OK;
|
220 kumpf 1.7 while ((rtn = _thread_pool->allocate_and_awaken(
221 (void *)this,
222 ProviderManagerService::handleCimOperation)) !=
223 PEGASUS_THREAD_OK)
|
224 kumpf 1.1 {
|
225 kumpf 1.7 if (rtn == PEGASUS_THREAD_INSUFFICIENT_RESOURCES)
|
226 kumpf 1.1 Threads::yield();
227 else
228 {
|
229 marek 1.19 PEG_TRACE((
230 TRC_PROVIDERMANAGER,
|
231 marek 1.20 Tracer::LEVEL1,
|
232 kumpf 1.1 "Could not allocate thread for %s.",
|
233 marek 1.9 getQueueName()));
|
234 kumpf 1.1 break;
235 }
236 }
237 }
238 else
239 {
240 // pass all other operations to the default handler
241 MessageQueueService::_handle_async_request(request);
242 }
243
244 PEG_METHOD_EXIT();
245
246 return;
247 }
248
249 // Note: This method should not throw an exception. It is used as a thread
250 // entry point, and any exceptions thrown are ignored.
251 ThreadReturnType PEGASUS_THREAD_CDECL
252 ProviderManagerService::handleCimOperation(void* arg)
253 {
254 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
255 kumpf 1.1 "ProviderManagerService::handleCimOperation");
256
257 PEGASUS_ASSERT(arg != 0);
258
259 // get the service from argument
260 ProviderManagerService* service =
261 reinterpret_cast<ProviderManagerService *>(arg);
262 PEGASUS_ASSERT(service != 0);
263
264 try
265 {
266 AsyncOpNode* op = service->_incomingQueue.remove_front();
267 PEGASUS_ASSERT(op != 0);
268
269 AsyncRequest* request =
|
270 kumpf 1.36 static_cast<AsyncRequest*>(op->getRequest());
271 PEGASUS_ASSERT(request != 0);
272 PEGASUS_ASSERT(request->getType() == ASYNC_ASYNC_LEGACY_OP_START);
|
273 kumpf 1.1
274 Message* legacy =
|
275 sahana.prabhakar 1.44 static_cast<AsyncLegacyOperationStart *>(request)->get_action();
276 static_cast<AsyncLegacyOperationStart *>(request)->put_action(legacy);
|
277 kumpf 1.1
|
278 kumpf 1.36 // Set the client's requested language into this service thread.
279 // This will allow functions in this service to return messages
280 // in the correct language.
281 CIMMessage* msg = dynamic_cast<CIMMessage *>(legacy);
282 PEGASUS_ASSERT(msg != 0);
283
284 Thread::setLanguages(
285 ((AcceptLanguageListContainer)msg->operationContext.get(
286 AcceptLanguageListContainer::NAME)).getLanguages());
|
287 kumpf 1.1
|
288 kumpf 1.36 service->handleCimRequest(op, legacy);
|
289 kumpf 1.1 }
290 catch (const Exception& e)
291 {
|
292 thilo.boehm 1.24 PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL1,
293 "Unexpected exception in handleCimOperation: %s",
294 (const char*)e.getMessage().getCString()));
|
295 kumpf 1.1 }
296 catch (...)
297 {
|
298 r.kieninger 1.21 PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1,
|
299 kumpf 1.1 "Unexpected exception in handleCimOperation.");
300 }
301
302 PEG_METHOD_EXIT();
303
|
304 kumpf 1.7 return ThreadReturnType(0);
|
305 kumpf 1.1 }
306
307 void ProviderManagerService::handleCimRequest(
308 AsyncOpNode * op,
309 Message * message)
310 {
311 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
312 "ProviderManagerService::handleCimRequest");
313
314 CIMRequestMessage * request = dynamic_cast<CIMRequestMessage *>(message);
315 PEGASUS_ASSERT(request != 0);
316
|
317 kumpf 1.36 AutoPtr<Message> response;
|
318 kumpf 1.1
|
319 kumpf 1.36 try
|
320 kumpf 1.1 {
|
321 kumpf 1.36 if (request->getType() == CIM_EXPORT_INDICATION_REQUEST_MESSAGE)
|
322 kumpf 1.1 {
|
323 kumpf 1.36 //
324 // Get a ProviderIdContainer for ExportIndicationRequestMessage.
325 // Note: This can be removed when the CIMExportRequestDispatcher
326 // is updated to add the ProviderIdContainer to the message.
327 //
328 CIMInstance providerModule;
329 CIMInstance provider;
330 const CIMExportIndicationRequestMessage* expRequest =
331 dynamic_cast<const CIMExportIndicationRequestMessage*>(request);
332 PEGASUS_ASSERT(expRequest != 0);
333 if (_providerRegistrationManager->lookupIndicationConsumer(
334 expRequest->destinationPath, provider, providerModule))
335 {
336 request->operationContext.insert(
337 ProviderIdContainer(providerModule, provider));
338 response.reset(_processMessage(request));
339 }
340 else
341 {
342 CIMResponseMessage* cimResponse = request->buildResponse();
343 cimResponse->cimException = PEGASUS_CIM_EXCEPTION(
344 kumpf 1.36 CIM_ERR_NOT_SUPPORTED, String::EMPTY);
345 response.reset(cimResponse);
346 }
|
347 kumpf 1.1 }
|
348 kumpf 1.36 else if ((dynamic_cast<CIMOperationRequestMessage*>(request) != 0) ||
349 (dynamic_cast<CIMIndicationRequestMessage*>(request) != 0) ||
350 (request->getType() == CIM_EXPORT_INDICATION_REQUEST_MESSAGE))
|
351 kumpf 1.1 {
|
352 kumpf 1.36 // Handle CIMOperationRequestMessage,
353 // CIMExportIndicationRequestMessage,
354 // and CIMIndicationRequestMessage.
355 // (These should be blocked when the provider module is disabled.)
|
356 kumpf 1.1
|
357 kumpf 1.36 //
358 // Get the provider module instance to check for a disabled module
359 //
360 CIMInstance providerModule;
|
361 kumpf 1.1
|
362 kumpf 1.36 // The provider ID container is added to the OperationContext
363 // by the CIMOperationRequestDispatcher for all CIM operation
364 // requests to providers, so it does not need to be added again.
365 ProviderIdContainer pidc =
366 request->operationContext.get(ProviderIdContainer::NAME);
367 providerModule = pidc.getModule();
|
368 kumpf 1.1
|
369 kumpf 1.36 //
370 // Check if the target provider is disabled
371 //
372 Boolean moduleDisabled = false;
373 Uint32 pos =
374 providerModule.findProperty(CIMName("OperationalStatus"));
375 PEGASUS_ASSERT(pos != PEG_NOT_FOUND);
376 Array<Uint16> operationalStatus;
377 providerModule.getProperty(pos).getValue().get(operationalStatus);
|
378 kumpf 1.1
|
379 kumpf 1.36 for (Uint32 i = 0; i < operationalStatus.size(); i++)
380 {
381 if ((operationalStatus[i] == CIM_MSE_OPSTATUS_VALUE_STOPPED) ||
382 (operationalStatus[i] == CIM_MSE_OPSTATUS_VALUE_STOPPING))
383 {
384 moduleDisabled = true;
385 break;
386 }
387 }
|
388 kumpf 1.1
|
389 kumpf 1.36 if (moduleDisabled)
390 {
391 //
392 // Send a "provider blocked" response
393 //
394 CIMResponseMessage* cimResponse = request->buildResponse();
395 cimResponse->cimException = PEGASUS_CIM_EXCEPTION_L(
396 CIM_ERR_NOT_SUPPORTED,
397 MessageLoaderParms(
398 "ProviderManager.ProviderManagerService."
399 "PROVIDER_BLOCKED",
400 "provider blocked."));
401 response.reset(cimResponse);
402 }
403 else
|
404 kumpf 1.1 {
|
405 kumpf 1.36 //
406 // Forward the request to the appropriate ProviderManagerRouter
407 //
408 response.reset(_processMessage(request));
|
409 kumpf 1.1 }
410 }
|
411 kumpf 1.36 else if (request->getType() == CIM_ENABLE_MODULE_REQUEST_MESSAGE)
|
412 kumpf 1.1 {
|
413 kumpf 1.36 // Handle CIMEnableModuleRequestMessage
414 CIMEnableModuleRequestMessage * emReq =
415 dynamic_cast<CIMEnableModuleRequestMessage*>(request);
|
416 kumpf 1.1
|
417 kumpf 1.36 CIMInstance providerModule = emReq->providerModule;
|
418 kumpf 1.1
419 // Forward the request to the ProviderManager
|
420 kumpf 1.36 response.reset(_processMessage(request));
|
421 kumpf 1.1
422 // If successful, update provider module status to OK
423 // ATTN: Use CIMEnableModuleResponseMessage operationalStatus?
424 CIMEnableModuleResponseMessage * emResp =
|
425 kumpf 1.36 dynamic_cast<CIMEnableModuleResponseMessage*>(response.get());
|
426 sahana.prabhakar 1.44 // If the provider is not loaded then update the provider status in
427 // this thread or else the response thread will call
428 // asyncResponseCallback which will update the provider status.
429 if(!emResp->isAsyncResponsePending)
|
430 kumpf 1.1 {
|
431 sahana.prabhakar 1.44 _updateModuleStatusToEnabled(emResp, providerModule);
|
432 kumpf 1.1 }
433 }
|
434 kumpf 1.36 else if (request->getType() == CIM_DISABLE_MODULE_REQUEST_MESSAGE)
|
435 kumpf 1.1 {
|
436 kumpf 1.36 // Handle CIMDisableModuleRequestMessage
437 CIMDisableModuleRequestMessage * dmReq =
438 dynamic_cast<CIMDisableModuleRequestMessage*>(request);
|
439 kumpf 1.1
|
440 kumpf 1.36 CIMInstance providerModule = dmReq->providerModule;
441 Boolean updateModuleStatus = !dmReq->disableProviderOnly;
|
442 kumpf 1.1
443 //
444 // On issuing a disable request, append Stopping status
445 // Do not remove existing status
446 //
447 if (updateModuleStatus)
448 {
449 Array<Uint16> removeStatus;
450 Array<Uint16> appendStatus;
451 appendStatus.append (CIM_MSE_OPSTATUS_VALUE_STOPPING);
452 _updateProviderModuleStatus(
453 providerModule, removeStatus, appendStatus);
|
454 venkat.puvvada 1.45
455 String providerModuleName;
456 Uint32 pos = providerModule.findProperty(
457 PEGASUS_PROPERTYNAME_NAME);
458 PEGASUS_ASSERT(pos != PEG_NOT_FOUND);
459 providerModule.getProperty(pos).getValue().get(
460 providerModuleName);
461 // Remove from failedProviderModuleTable.
462 AutoMutex mtx(_failedProviderModuleTableMutex);
463 _failedProviderModuleTable.remove(providerModuleName);
|
464 kumpf 1.1 }
465
466 // Forward the request to the ProviderManager
|
467 kumpf 1.36 response.reset(_processMessage(request));
|
468 kumpf 1.1
|
469 sahana.prabhakar 1.44 // If the provider is not initialized then update the status of the
470 // provider in this thread since there will be no response from
471 // any provider.
472 CIMDisableModuleResponseMessage * dmResp =
473 dynamic_cast<CIMDisableModuleResponseMessage*>(response.get());
474 if(!dmResp->isAsyncResponsePending)
|
475 kumpf 1.1 {
|
476 sahana.prabhakar 1.44 if (updateModuleStatus)
|
477 kumpf 1.1 {
|
478 sahana.prabhakar 1.44 _updateModuleStatusToDisabled(dmResp,providerModule);
|
479 kumpf 1.1 }
480 }
481 }
|
482 kumpf 1.36 else
|
483 kumpf 1.1 {
|
484 kumpf 1.36 response.reset(_processMessage(request));
|
485 kumpf 1.1 }
486 }
|
487 kumpf 1.36 catch (Exception& e)
488 {
489 CIMResponseMessage* cimResponse = request->buildResponse();
490 cimResponse->cimException =
491 CIMException(CIM_ERR_FAILED, e.getMessage());
492 response.reset(cimResponse);
493 }
494 catch (PEGASUS_STD(exception)& e)
495 {
496 CIMResponseMessage* cimResponse = request->buildResponse();
497 cimResponse->cimException = CIMException(CIM_ERR_FAILED, e.what());
498 response.reset(cimResponse);
499 }
500 catch (...)
|
501 kumpf 1.1 {
|
502 kumpf 1.36 CIMResponseMessage* cimResponse = request->buildResponse();
503 cimResponse->cimException = CIMException(CIM_ERR_FAILED, String::EMPTY);
504 response.reset(cimResponse);
|
505 kumpf 1.1 }
506
|
507 sahana.prabhakar 1.44 // all responses will be handled by the asyncResponseCallback
508 // Certain requests like disable and enable module will be processed
509 // in this thread if the module is not loaded yet.
510 CIMResponseMessage *cimResponse = dynamic_cast<CIMResponseMessage*>(
511 response.get());
512
513 if(!cimResponse->isAsyncResponsePending)
514 {
|
515 marek 1.50 // constructor of object is putting itself into a linked list
516 // DO NOT remove the new operator
517 new AsyncLegacyOperationResult(
|
518 sahana.prabhakar 1.44 op,
519 response.release());
|
520 kumpf 1.1
|
521 sahana.prabhakar 1.44 _complete_op_node(op);
522 }
|
523 kumpf 1.1
524 PEG_METHOD_EXIT();
525 }
526
527 void ProviderManagerService::responseChunkCallback(
528 CIMRequestMessage* request,
529 CIMResponseMessage* response)
530 {
531 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
532 "ProviderManagerService::responseChunkCallback");
533
534 try
535 {
536 // only incomplete messages are processed because the caller ends up
537 // sending the complete() stage
538 PEGASUS_ASSERT(response->isComplete() == false);
539
540 AsyncLegacyOperationStart *requestAsync =
|
541 kumpf 1.14 dynamic_cast<AsyncLegacyOperationStart *>(request->get_async());
542 request->put_async(requestAsync); // Put it back for the next chunk
|
543 kumpf 1.1 PEGASUS_ASSERT(requestAsync);
544 AsyncOpNode *op = requestAsync->op;
545 PEGASUS_ASSERT(op);
|
546 kumpf 1.14 PEGASUS_ASSERT(!response->get_async());
547 response->put_async(new AsyncLegacyOperationResult(op, response));
|
548 kumpf 1.1
549 // set the destination
550 op->_op_dest = op->_callback_response_q;
551
552 MessageQueueService *service =
553 dynamic_cast<MessageQueueService *>(op->_callback_response_q);
554
555 PEGASUS_ASSERT(service);
556
557 // the last chunk MUST be sent last, so use execute the callback
558 // not all chunks are going through the dispatcher's chunk
559 // resequencer, so this must be a synchronous call here
560 // After the call is done, response and asyncResponse are now invalid
561 // as they have been sent and deleted externally
562
563 op->_async_callback(op, service, op->_callback_ptr);
564 }
|
565 kumpf 1.7 catch (Exception &e)
|
566 kumpf 1.1 {
|
567 thilo.boehm 1.24 PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL1,
568 "Exception in ProviderManagerService::responseChunkCallback: %s"
569 ". Chunk not delivered.",(const char*)e.getMessage().getCString()));
|
570 kumpf 1.1 }
|
571 kumpf 1.7 catch (...)
|
572 kumpf 1.1 {
|
573 r.kieninger 1.21 PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1,
|
574 thilo.boehm 1.24 "Unknown exception in ProviderManagerService::"
575 "responseChunkCallback. Chunk not delivered.");
|
576 kumpf 1.1 }
577
578 PEG_METHOD_EXIT();
579 }
580
|
581 sahana.prabhakar 1.44
582 void ProviderManagerService::asyncResponseCallback(
583 CIMRequestMessage* request,
584 CIMResponseMessage* response)
585 {
586 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
587 "ProviderManagerService::asyncResponseCallback");
588
589 AsyncLegacyOperationStart *requestAsync =
590 dynamic_cast<AsyncLegacyOperationStart *>(request->get_async());
591 request->put_async(requestAsync);
592 PEGASUS_ASSERT(requestAsync);
593
594 AsyncOpNode *op = requestAsync->op;
595 PEGASUS_ASSERT(op);
596
597 try
598 {
599 // Only complete responses for async responses are handled
600 // here.
601 PEGASUS_ASSERT(response->isComplete() == true);
602 sahana.prabhakar 1.44
603 if(request->operationContext.contains(
604 AcceptLanguageListContainer::NAME))
605 {
606 Thread::setLanguages(
607 ((AcceptLanguageListContainer)request->operationContext.get(
608 AcceptLanguageListContainer::NAME)).getLanguages());
609 }
610 else
611 {
612 Thread::setLanguages(AcceptLanguageList());
613 }
614
615 if(request->getType() == CIM_STOP_ALL_PROVIDERS_REQUEST_MESSAGE)
616 {
617 _allProvidersStopped = true;
618 }
619 else if(request->getType() == CIM_ENABLE_MODULE_REQUEST_MESSAGE)
620 {
621 // Handle CIMEnableModuleRequestMessage
622 CIMEnableModuleRequestMessage * emReq =
623 sahana.prabhakar 1.44 dynamic_cast<CIMEnableModuleRequestMessage*>(request);
624
625 CIMInstance providerModule = emReq->providerModule;
626
627 // If successful, update provider module status to OK
628 // ATTN: Use CIMEnableModuleResponseMessage operationalStatus?
629 CIMEnableModuleResponseMessage * emResp =
630 dynamic_cast<CIMEnableModuleResponseMessage*>(response);
631 providerManagerService->_updateModuleStatusToEnabled(
632 emResp,providerModule);
633 }
634 else if (request->getType() == CIM_DISABLE_MODULE_REQUEST_MESSAGE)
635 {
636 // Handle CIMDisableModuleRequestMessage
637 CIMDisableModuleRequestMessage * dmReq =
638 dynamic_cast<CIMDisableModuleRequestMessage*>(request);
639
640 CIMInstance providerModule = dmReq->providerModule;
641 Boolean updateModuleStatus = !dmReq->disableProviderOnly;
642
643 // Update provider module status based on success or failure
644 sahana.prabhakar 1.44 if (updateModuleStatus)
645 {
646 CIMDisableModuleResponseMessage * dmResp =
647 dynamic_cast<CIMDisableModuleResponseMessage*>(
648 response);
649 providerManagerService->_updateModuleStatusToDisabled(
650 dmResp,providerModule);
651 }
652 }
653 }
654 catch (Exception &e)
655 {
656 response->cimException =
657 CIMException(CIM_ERR_FAILED, e.getMessage());
658 }
659 catch (PEGASUS_STD(exception)& e)
660 {
661 response->cimException = CIMException(CIM_ERR_FAILED, e.what());
662 }
663 catch (...)
664 {
665 sahana.prabhakar 1.44 response->cimException = CIMException(CIM_ERR_FAILED, String());
666 }
667
|
668 marek 1.50 // constructor of object is putting itself into a linked list
669 // DO NOT remove the new operator
670 new AsyncLegacyOperationResult(op, response);
|
671 sahana.prabhakar 1.44
672 providerManagerService->_complete_op_node(op);
673
674 PEG_METHOD_EXIT();
675 }
676
|
677 kumpf 1.1 Message* ProviderManagerService::_processMessage(CIMRequestMessage* request)
678 {
679 Message* response = 0;
680
|
681 venkat.puvvada 1.15 // Add CachedClassDefinitionContainer here needed by CMPIProviderManager
|
682 venkat.puvvada 1.28 // to correct mismatches between Embedded Instances/Objects for InvokeMethod
683 // requests.
684 #if defined (PEGASUS_ENABLE_CMPI_PROVIDER_MANAGER)
685 if (request->getType() == CIM_INVOKE_METHOD_REQUEST_MESSAGE)
686 {
|
687 kumpf 1.37 CIMOperationRequestMessage *reqMsg =
|
688 venkat.puvvada 1.28 dynamic_cast<CIMOperationRequestMessage*>(request);
689 PEGASUS_ASSERT(reqMsg);
690 ProviderIdContainer pidc = (ProviderIdContainer)
691 reqMsg->operationContext.get(ProviderIdContainer::NAME);
692 CIMInstance providerModule = pidc.getModule();
693 String interfaceType;
694 CIMValue itValue = providerModule.getProperty(
695 providerModule.findProperty("InterfaceType")).getValue();
696 itValue.get(interfaceType);
697 if (interfaceType == "CMPI")
698 {
|
699 mike 1.33 CIMConstClass cls = _repository->getFullConstClass(
700 reqMsg->nameSpace,
701 reqMsg->className);
|
702 venkat.puvvada 1.28 reqMsg->operationContext.insert(
703 CachedClassDefinitionContainer(cls));
704 }
|
705 venkat.puvvada 1.15 }
|
706 venkat.puvvada 1.28 #endif
|
707 venkat.puvvada 1.15
|
708 kumpf 1.1 if ((request->getType() == CIM_STOP_ALL_PROVIDERS_REQUEST_MESSAGE) ||
709 (request->getType() ==
710 CIM_SUBSCRIPTION_INIT_COMPLETE_REQUEST_MESSAGE) ||
|
711 venkat.puvvada 1.41 (request->getType() ==
712 CIM_INDICATION_SERVICE_DISABLED_REQUEST_MESSAGE) ||
|
713 kumpf 1.1 (request->getType() == CIM_NOTIFY_CONFIG_CHANGE_REQUEST_MESSAGE))
714 {
715 if (_basicProviderManagerRouter)
716 {
717 response = _basicProviderManagerRouter->processMessage(request);
718 }
719
720 if (_oopProviderManagerRouter)
721 {
722 // Note: These responses do not contain interesting data, so just
723 // use the last one.
724 delete response;
725
726 response = _oopProviderManagerRouter->processMessage(request);
727 }
728 }
729 else
730 {
731 CIMInstance providerModule;
|
732 s.kodali 1.47 Uint16 bitness = PG_PROVMODULE_BITNESS_DEFAULT;
|
733 kumpf 1.1
734 if (request->getType() == CIM_ENABLE_MODULE_REQUEST_MESSAGE)
735 {
736 CIMEnableModuleRequestMessage* emReq =
737 dynamic_cast<CIMEnableModuleRequestMessage*>(request);
|
738 kumpf 1.8 PEGASUS_ASSERT(emReq != 0);
|
739 kumpf 1.1 providerModule = emReq->providerModule;
740 }
741 else if (request->getType() == CIM_DISABLE_MODULE_REQUEST_MESSAGE)
742 {
743 CIMDisableModuleRequestMessage* dmReq =
744 dynamic_cast<CIMDisableModuleRequestMessage*>(request);
|
745 kumpf 1.8 PEGASUS_ASSERT(dmReq != 0);
|
746 kumpf 1.1 providerModule = dmReq->providerModule;
747 }
748 else
749 {
750 ProviderIdContainer pidc =
751 request->operationContext.get(ProviderIdContainer::NAME);
752 providerModule = pidc.getModule();
|
753 b.whiteley 1.18
754 String interfaceType;
755 String interfaceVersion;
756 CIMValue itValue = providerModule.getProperty(
757 providerModule.findProperty("InterfaceType")).getValue();
758 CIMValue ivValue = providerModule.getProperty(
759 providerModule.findProperty("InterfaceVersion")).getValue();
760 itValue.get(interfaceType);
761 ivValue.get(interfaceVersion);
762
|
763 s.kodali 1.47 Uint32 idx = providerModule.findProperty(
764 PEGASUS_PROPERTYNAME_MODULE_BITNESS);
765
766 if (idx != PEG_NOT_FOUND)
767 {
768 CIMValue value = providerModule.getProperty(idx).getValue();
769 if (!value.isNull())
770 {
771 value.get(bitness);
772 }
773 }
774
|
775 b.whiteley 1.18 String provMgrPath;
|
776 kumpf 1.22
777 if (!ProviderManagerMap::instance().getProvMgrPathForIfcType(
|
778 s.kodali 1.47 interfaceType, interfaceVersion, bitness, provMgrPath))
|
779 kumpf 1.22 {
780 MessageLoaderParms parms(
781 "ProviderManager.ProviderManagerService."
782 "PROVIDERMANAGER_LOOKUP_FAILED",
783 "Provider interface type \"$0\" version \"$1\" is not "
784 "recognized.",
785 interfaceType,
786 interfaceVersion);
|
787 kumpf 1.23 Logger::put_l(
|
788 kumpf 1.22 Logger::ERROR_LOG, System::CIMSERVER, Logger::SEVERE,
|
789 kumpf 1.23 parms);
|
790 kumpf 1.22
791 CIMResponseMessage* cimResponse = request->buildResponse();
792 cimResponse->cimException = PEGASUS_CIM_EXCEPTION_L(
793 CIM_ERR_FAILED, parms);
794 return cimResponse;
795 }
|
796 b.whiteley 1.18
797 pidc.setProvMgrPath(provMgrPath);
798
799 request->operationContext.set(pidc);
800
|
801 kumpf 1.1 #ifdef PEGASUS_ZOS_SECURITY
802 if (request->getType() != CIM_EXPORT_INDICATION_REQUEST_MESSAGE)
803 {
804 // this is a z/OS only function
805 // the function checks user authorization
806 // based on CIM operation versus provider profile
807 // Input: request and Provider ID Container
808 //Return: failure: a response message for the client
|
809 kumpf 1.7 // success: NULL
|
810 kumpf 1.1 response = checkSAFProviderProfile(request, pidc);
811 if (response != NULL)
812 {
813 return response;
814 }
815 }
816 #endif
817 }
818
819 Uint16 userContext = PEGASUS_DEFAULT_PROV_USERCTXT;
820 Uint32 pos = providerModule.findProperty(
821 PEGASUS_PROPERTYNAME_MODULE_USERCONTEXT);
822 if (pos != PEG_NOT_FOUND)
823 {
824 providerModule.getProperty(pos).getValue().get(userContext);
825 }
826
|
827 venkat.puvvada 1.43 String moduleGroupName;
828 Uint32 idx = providerModule.findProperty(
829 PEGASUS_PROPERTYNAME_MODULE_MODULEGROUPNAME);
830 if (idx != PEG_NOT_FOUND)
831 {
832 providerModule.getProperty(idx).getValue().get(moduleGroupName);
833 }
834
|
835 dave.sudlik 1.6 // Load proxy-provider into CIMServer, in case of remote namespace
836 // requests. (ie through _basicProviderManagerRouter). -V 3913
837 #ifdef PEGASUS_ENABLE_REMOTE_CMPI
838 if ((dynamic_cast<CIMOperationRequestMessage*>(request) != 0) ||
|
839 kumpf 1.16 (request->getType() == CIM_EXPORT_INDICATION_REQUEST_MESSAGE))
|
840 dave.sudlik 1.6 {
841 ProviderIdContainer pidc1 =
842 request->operationContext.get(ProviderIdContainer::NAME);
843 if (pidc1.isRemoteNameSpace() )
844 {
|
845 marek 1.9 PEG_TRACE_CSTRING(TRC_PROVIDERMANAGER, Tracer::LEVEL4,
|
846 dave.sudlik 1.6 "Processing Remote NameSpace request ");
|
847 kumpf 1.7 response = _basicProviderManagerRouter->processMessage(request);
|
848 dave.sudlik 1.6 return response;
849 }
850 }
851 #endif
|
852 kumpf 1.1 // Forward the request to the appropriate ProviderManagerRouter, based
853 // on the CIM Server configuration and the UserContext setting.
854
|
855 venkat.puvvada 1.43 if ( (_forceProviderProcesses &&
|
856 s.kodali 1.47 (moduleGroupName != PG_PROVMODULE_GROUPNAME_CIMSERVER))||
857 bitness == PG_PROVMODULE_BITNESS_32
|
858 r.kieninger 1.13 #if !defined(PEGASUS_DISABLE_PROV_USERCTXT) && !defined(PEGASUS_OS_ZOS)
|
859 kumpf 1.1 || (userContext == PG_PROVMODULE_USERCTXT_REQUESTOR)
860 || (userContext == PG_PROVMODULE_USERCTXT_DESIGNATED)
861 || ((userContext == PG_PROVMODULE_USERCTXT_PRIVILEGED) &&
862 !System::isPrivilegedUser(System::getEffectiveUserName()))
863 #endif
864 )
865 {
866 response = _oopProviderManagerRouter->processMessage(request);
867 }
868 else
869 {
870 response = _basicProviderManagerRouter->processMessage(request);
871 }
872 }
873
874 return response;
875 }
876
|
877 sahana.prabhakar 1.44 void ProviderManagerService::idleTimeCleanup()
|
878 kumpf 1.1 {
879 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
|
880 sahana.prabhakar 1.44 "ProviderManagerService::idleTimeCleanup");
|
881 kumpf 1.3
|
882 sahana.prabhakar 1.44 // Ensure that only one _idleTimeCleanupHandler thread runs at a time
883 _idleTimeCleanupBusy++;
884 if (_idleTimeCleanupBusy.get() != 1)
|
885 kumpf 1.1 {
|
886 sahana.prabhakar 1.44 _idleTimeCleanupBusy--;
|
887 kumpf 1.3 PEG_METHOD_EXIT();
888 return;
|
889 kumpf 1.1 }
|
890 kumpf 1.3
891 //
|
892 sahana.prabhakar 1.44 // Start an idle time cleanup thread.
|
893 kumpf 1.3 //
894
895 if (_thread_pool->allocate_and_awaken((void*)this,
|
896 sahana.prabhakar 1.44 ProviderManagerService::_idleTimeCleanupHandler) !=
|
897 kumpf 1.3 PEGASUS_THREAD_OK)
|
898 kumpf 1.1 {
|
899 marek 1.20 PEG_TRACE((TRC_PROVIDERMANAGER, Tracer::LEVEL1,
|
900 sahana.prabhakar 1.44 "Could not allocate thread for %s to cleanup idle providers \
901 and request.",
|
902 marek 1.9 getQueueName()));
|
903 kumpf 1.3
904 // If we fail to allocate a thread, don't retry now.
|
905 sahana.prabhakar 1.44 _idleTimeCleanupBusy--;
|
906 kumpf 1.3 PEG_METHOD_EXIT();
907 return;
|
908 kumpf 1.1 }
|
909 kumpf 1.3
|
910 sahana.prabhakar 1.44 // Note: _idleTimeCleanupBusy is decremented in
911 // _idleTimeCleanupHandler
|
912 kumpf 1.3
|
913 kumpf 1.1 PEG_METHOD_EXIT();
914 }
915
916 ThreadReturnType PEGASUS_THREAD_CDECL
|
917 sahana.prabhakar 1.44 ProviderManagerService::_idleTimeCleanupHandler(void* arg) throw()
|
918 kumpf 1.1 {
|
919 kumpf 1.3 ProviderManagerService* myself =
920 reinterpret_cast<ProviderManagerService*>(arg);
921
|
922 kumpf 1.1 try
923 {
924 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
|
925 sahana.prabhakar 1.44 "ProviderManagerService::_idleTimeCleanupHandler");
|
926 kumpf 1.1
927 if (myself->_basicProviderManagerRouter)
928 {
929 try
930 {
|
931 sahana.prabhakar 1.44 myself->_basicProviderManagerRouter->idleTimeCleanup();
|
932 kumpf 1.1 }
933 catch (...)
934 {
935 // Ignore errors
|
936 marek 1.9 PEG_TRACE_CSTRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
|
937 kumpf 1.1 "Unexpected exception from "
|
938 sahana.prabhakar 1.44 "BasicProviderManagerRouter::idleTimeCleanup");
|
939 kumpf 1.1 }
940 }
941
942 if (myself->_oopProviderManagerRouter)
943 {
944 try
945 {
|
946 sahana.prabhakar 1.44 myself->_oopProviderManagerRouter->idleTimeCleanup();
|
947 kumpf 1.1 }
948 catch (...)
949 {
950 // Ignore errors
|
951 marek 1.9 PEG_TRACE_CSTRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
|
952 kumpf 1.1 "Unexpected exception from "
|
953 sahana.prabhakar 1.44 "OOPProviderManagerRouter::idleTimeCleanup");
|
954 kumpf 1.1 }
955 }
956
|
957 sahana.prabhakar 1.44 myself->_idleTimeCleanupBusy--;
|
958 kumpf 1.1 PEG_METHOD_EXIT();
959 }
960 catch (...)
961 {
962 // Ignore errors
|
963 marek 1.9 PEG_TRACE_CSTRING(TRC_PROVIDERMANAGER, Tracer::LEVEL2,
|
964 sahana.prabhakar 1.44 "Unexpected exception in _idleTimeCleanupHandler");
|
965 kumpf 1.3
|
966 sahana.prabhakar 1.44 myself->_idleTimeCleanupBusy--;
|
967 kumpf 1.1 }
968
|
969 kumpf 1.7 return ThreadReturnType(0);
|
970 kumpf 1.1 }
971
|
972 sahana.prabhakar 1.44 void ProviderManagerService::_updateModuleStatusToEnabled(
973 CIMEnableModuleResponseMessage *emResp,
974 CIMInstance &providerModule)
975 {
976 if (emResp->cimException.getCode() == CIM_ERR_SUCCESS)
977 {
978 //
979 // On a successful enable, remove Stopped status and
980 // append OK status
981 //
982 Array<Uint16> removeStatus;
983 Array<Uint16> appendStatus;
984 removeStatus.append (CIM_MSE_OPSTATUS_VALUE_STOPPED);
985 appendStatus.append (CIM_MSE_OPSTATUS_VALUE_OK);
986 _updateProviderModuleStatus(
987 providerModule, removeStatus, appendStatus);
|
988 venkat.puvvada 1.48 String moduleName;
989 providerModule.getProperty(
990 providerModule.findProperty("Name")).getValue().get(moduleName);
991 AutoMutex mtx(_failedProviderModuleTableMutex);
992 if (!_failedProviderModuleTable.contains(moduleName))
993 {
994 _providerRegistrationManager->sendPMInstAlert(
995 providerModule,
996 PM_ENABLED);
997 }
|
998 sahana.prabhakar 1.44 }
999 }
1000
1001 void ProviderManagerService::_updateModuleStatusToDisabled(
1002 CIMDisableModuleResponseMessage *dmResp,
1003 CIMInstance &providerModule)
1004 {
1005 // Update provider module status based on success or failure
1006 if (dmResp->cimException.getCode() != CIM_ERR_SUCCESS)
1007 {
1008 //
1009 // On an unsuccessful disable, remove Stopping status
1010 //
1011 Array<Uint16> removeStatus;
1012 Array<Uint16> appendStatus;
1013 removeStatus.append (CIM_MSE_OPSTATUS_VALUE_STOPPING);
1014 _updateProviderModuleStatus(
1015 providerModule, removeStatus, appendStatus);
1016 }
1017 else
1018 {
1019 sahana.prabhakar 1.44 // Disable may or may not have been successful,
1020 // depending on whether there are outstanding requests.
1021 // Remove Stopping status
1022 // Append status, if any, from disable module response
1023 Array<Uint16> removeStatus;
1024 Array<Uint16> appendStatus;
1025 removeStatus.append (CIM_MSE_OPSTATUS_VALUE_STOPPING);
1026 if (dmResp->operationalStatus.size() > 0)
1027 {
1028 //
1029 // On a successful disable, remove an OK or
1030 // a Degraded status, if present
1031 //
1032 if (dmResp->operationalStatus[
1033 dmResp->operationalStatus.size()-1] ==
1034 CIM_MSE_OPSTATUS_VALUE_STOPPED)
1035 {
1036 removeStatus.append (CIM_MSE_OPSTATUS_VALUE_OK);
1037 removeStatus.append
1038 (CIM_MSE_OPSTATUS_VALUE_DEGRADED);
1039 }
1040 sahana.prabhakar 1.44 appendStatus.append (dmResp->operationalStatus[
1041 dmResp->operationalStatus.size()-1]);
1042 }
1043 _updateProviderModuleStatus(
1044 providerModule, removeStatus, appendStatus);
|
1045 venkat.puvvada 1.48 _providerRegistrationManager->sendPMInstAlert(
1046 providerModule,
1047 PM_DISABLED);
|
1048 sahana.prabhakar 1.44 }
1049 }
1050
|
1051 kumpf 1.1 // Updates the providerModule instance and the ProviderRegistrationManager
1052 //
1053 // This method is used to update the provider module status when the module is
1054 // disabled or enabled. If a Degraded status has been set (appended) to the
1055 // OperationalStatus, it is cleared (removed) when the module is disabled or
1056 // enabled.
1057 //
1058 void ProviderManagerService::_updateProviderModuleStatus(
1059 CIMInstance& providerModule,
1060 const Array<Uint16>& removeStatus,
1061 const Array<Uint16>& appendStatus)
1062 {
1063 PEG_METHOD_ENTER(TRC_PROVIDERMANAGER,
1064 "ProviderManagerService::_updateProviderModuleStatus");
1065
1066 Array<Uint16> operationalStatus;
1067 String providerModuleName;
1068
|
1069 marek 1.25 Uint32 pos = providerModule.findProperty(PEGASUS_PROPERTYNAME_NAME);
|
1070 kumpf 1.1 PEGASUS_ASSERT(pos != PEG_NOT_FOUND);
1071 providerModule.getProperty(pos).getValue().get(providerModuleName);
1072
1073 //
1074 // get operational status
1075 //
1076 pos = providerModule.findProperty(CIMName("OperationalStatus"));
1077 PEGASUS_ASSERT(pos != PEG_NOT_FOUND);
1078 CIMProperty operationalStatusProperty = providerModule.getProperty(pos);
1079
1080 if (_providerRegistrationManager->updateProviderModuleStatus(
1081 providerModuleName, removeStatus, appendStatus, operationalStatus) ==
1082 false)
1083 {
1084 throw PEGASUS_CIM_EXCEPTION_L(
1085 CIM_ERR_FAILED,
1086 MessageLoaderParms(
1087 "ProviderManager.ProviderManagerService."
1088 "SET_MODULE_STATUS_FAILED",
|
1089 thilo.boehm 1.51 "Failed to update the provider module status."));
|
1090 kumpf 1.1 }
1091
1092 operationalStatusProperty.setValue(CIMValue(operationalStatus));
1093
1094 PEG_METHOD_EXIT();
1095 }
1096
1097 void ProviderManagerService::indicationCallback(
1098 CIMProcessIndicationRequestMessage* request)
1099 {
|
1100 venkat.puvvada 1.49 IndicationRouter router =
1101 IndicationRouter(request, _indicationDeliveryRoutine);
1102
1103 router.deliverAndWaitForStatus();
1104 }
1105
1106 void ProviderManagerService::_indicationDeliveryRoutine(
1107 CIMProcessIndicationRequestMessage* request)
1108 {
|
1109 kumpf 1.7 if (request->operationContext.contains(AcceptLanguageListContainer::NAME))
|
1110 kumpf 1.1 {
|
1111 kumpf 1.7 AcceptLanguageListContainer cntr =
1112 request->operationContext.get(AcceptLanguageListContainer::NAME);
|
1113 kumpf 1.1 }
1114 else
1115 {
|
1116 kumpf 1.7 request->operationContext.insert(
1117 AcceptLanguageListContainer(AcceptLanguageList()));
|
1118 kumpf 1.1 }
1119
1120 if (_indicationServiceQueueId == PEG_NOT_FOUND)
1121 {
|
1122 venkat.puvvada 1.29 _indicationServiceQueueId = providerManagerService->find_service_qid(
1123 PEGASUS_QUEUENAME_INDICATIONSERVICE);
|
1124 kumpf 1.1 }
1125
1126 request->queueIds = QueueIdStack(
|
1127 venkat.puvvada 1.49 providerManagerService->getQueueId(),
1128 _indicationServiceQueueId);
|
1129 kumpf 1.1
1130 AsyncLegacyOperationStart * asyncRequest =
1131 new AsyncLegacyOperationStart(
1132 0,
1133 _indicationServiceQueueId,
|
1134 venkat.puvvada 1.26 request);
|
1135 kumpf 1.1
1136 providerManagerService->SendForget(asyncRequest);
1137 }
1138
|
1139 s.kodali 1.46 void ProviderManagerService::providerModuleGroupFailureCallback(
1140 const String &groupName,
1141 const String & userName,
1142 Uint16 userContext,
1143 Boolean isGroup)
1144 {
1145 PEG_METHOD_ENTER (TRC_PROVIDERMANAGER,
1146 "ProviderManagerService::providerModuleFailureCallback");
1147
1148 Array<String> moduleNames;
1149
1150 // If this agent is servicing the group of modules, get all related
1151 // provider module names.
1152 if (isGroup)
1153 {
1154 _providerRegistrationManager->getProviderModuleNamesForGroup(
1155 groupName, moduleNames);
1156 }
1157 else
1158 {
1159 moduleNames.append(groupName);
1160 s.kodali 1.46 }
1161
1162 for (Uint32 i = 0, n = moduleNames.size() ; i < n ; ++i)
1163 {
1164 _reconcileProviderModuleFailure(
1165 moduleNames[i],
1166 userName,
1167 userContext);
1168 }
1169
1170 PEG_METHOD_EXIT();
1171 }
1172
1173 void ProviderManagerService::_reconcileProviderModuleFailure(
1174 const String & moduleName,
|
1175 kumpf 1.1 const String & userName,
1176 Uint16 userContext)
1177 {
1178 PEG_METHOD_ENTER (TRC_PROVIDERMANAGER,
|
1179 s.kodali 1.46 "ProviderManagerService::_reconcileProviderModuleFailure");
|
1180 kumpf 1.1
1181 if (userContext == PG_PROVMODULE_USERCTXT_REQUESTOR)
1182 {
|
1183 kumpf 1.23 Logger::put_l(
|
1184 kumpf 1.1 Logger::STANDARD_LOG, System::CIMSERVER, Logger::WARNING,
|
1185 kumpf 1.23 MessageLoaderParms(
|
1186 thilo.boehm 1.51 "ProviderManager.ProviderManagerService."
|
1187 kumpf 1.23 "OOP_PROVIDER_MODULE_USER_CTXT_FAILURE_DETECTED",
1188 "A failure was detected in provider module $0 with "
1189 "user context $1.",
1190 moduleName, userName));
|
1191 kumpf 1.1 }
1192 else // not requestor context
1193 {
|
1194 kumpf 1.23 Logger::put_l(
|
1195 kumpf 1.1 Logger::STANDARD_LOG, System::CIMSERVER, Logger::WARNING,
|
1196 kumpf 1.23 MessageLoaderParms(
|
1197 thilo.boehm 1.51 "ProviderManager.ProviderManagerService."
|
1198 kumpf 1.23 "OOP_PROVIDER_MODULE_FAILURE_DETECTED",
1199 "A failure was detected in provider module $0.",
1200 moduleName));
|
1201 kumpf 1.1 }
|
1202 kumpf 1.7
|
1203 kumpf 1.40 //
1204 // Send Notify Provider Fail request message to Indication Service.
1205 // (After a CIMStopAllProvidersRequestMessage is processed, the
1206 // IndicationService may be destructed, so it cannot be used then.)
1207 //
1208
1209 if (_indicationServiceQueueId == PEG_NOT_FOUND)
|
1210 kumpf 1.1 {
|
1211 kumpf 1.40 MessageQueue* indicationServiceQueue =
1212 lookup(PEGASUS_QUEUENAME_INDICATIONSERVICE);
|
1213 kumpf 1.38
|
1214 kumpf 1.40 if (indicationServiceQueue)
|
1215 kumpf 1.38 {
|
1216 kumpf 1.40 _indicationServiceQueueId = indicationServiceQueue->getQueueId();
|
1217 kumpf 1.38 }
|
1218 kumpf 1.40 }
|
1219 kumpf 1.1
|
1220 kumpf 1.40 if (!_allProvidersStopped && (_indicationServiceQueueId != PEG_NOT_FOUND))
1221 {
|
1222 venkat.puvvada 1.39 //
1223 // Create Notify Provider Fail request message
1224 //
1225 CIMNotifyProviderFailRequestMessage* request =
1226 new CIMNotifyProviderFailRequestMessage(
1227 XmlWriter::getNextMessageId(),
1228 moduleName,
1229 userName,
1230 QueueIdStack());
1231
|
1232 kumpf 1.38 request->queueIds = QueueIdStack(
1233 _indicationServiceQueueId, providerManagerService->getQueueId());
|
1234 kumpf 1.1
|
1235 kumpf 1.38 AsyncLegacyOperationStart asyncRequest(
1236 0,
1237 _indicationServiceQueueId,
1238 request);
|
1239 kumpf 1.1
|
1240 kumpf 1.38 AutoPtr <AsyncReply> asyncReply(
1241 providerManagerService->SendWait(&asyncRequest));
|
1242 kumpf 1.1
|
1243 kumpf 1.38 AutoPtr <CIMNotifyProviderFailResponseMessage> response(
1244 reinterpret_cast<CIMNotifyProviderFailResponseMessage *>(
1245 (dynamic_cast<AsyncLegacyOperationResult *>(
1246 asyncReply.get()))->get_result()));
1247
1248 if (response->cimException.getCode () != CIM_ERR_SUCCESS)
1249 {
1250 PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL2,
1251 "Unexpected exception in providerModuleFailureCallback: %s",
1252 (const char*)response->cimException.getMessage().getCString()));
1253 }
1254 else
|
1255 kumpf 1.1 {
|
1256 venkat.puvvada 1.48 CIMInstance providerModule;
1257 CIMKeyBinding keyBinding(
1258 _PROPERTY_PROVIDERMODULE_NAME,
1259 moduleName,
1260 CIMKeyBinding::STRING);
1261
1262 Array<CIMKeyBinding> kbArray;
1263 kbArray.append(keyBinding);
1264
1265 CIMObjectPath modulePath(
1266 "",
1267 PEGASUS_NAMESPACENAME_INTEROP,
1268 PEGASUS_CLASSNAME_PROVIDERMODULE,
1269 kbArray);
1270
|
1271 kumpf 1.1 //
|
1272 kumpf 1.38 // Successful response
1273 // Examine result to see if any subscriptions were affected
|
1274 kumpf 1.1 //
|
1275 kumpf 1.38 if (response->numSubscriptionsAffected > 0)
|
1276 kumpf 1.1 {
|
1277 kumpf 1.38 //
1278 // Subscriptions were affected
1279 // Update the provider module status to Degraded
1280 //
1281 try
1282 {
|
1283 venkat.puvvada 1.45
1284 Boolean startProviderModule = false;
1285 // Get the maxFailedProviderModuleRestarts value. Note that
1286 // this is a dynamic property.
1287 Uint64 maxFailedProviderModuleRestarts = 0;
1288 Uint32 moduleFailureCount = 1;
1289 String value =
1290 ConfigManager::getInstance()->getCurrentValue(
1291 "maxFailedProviderModuleRestarts");
1292 StringConversion::decimalStringToUint64(value.getCString(),
1293 maxFailedProviderModuleRestarts);
1294
1295 if (maxFailedProviderModuleRestarts)
1296 {
1297 startProviderModule = true;
1298 Uint32 *failedCount;
1299
1300 AutoMutex mtx(_failedProviderModuleTableMutex);
1301 if (_failedProviderModuleTable.lookupReference(
1302 moduleName, failedCount))
1303 {
1304 venkat.puvvada 1.45 if ((moduleFailureCount = ++(*failedCount)) >
1305 maxFailedProviderModuleRestarts)
1306 {
1307 startProviderModule = false;
1308 _failedProviderModuleTable.remove(moduleName);
1309 }
1310 }
1311 else
1312 {
1313 _failedProviderModuleTable.insert(
1314 moduleName, moduleFailureCount);
1315 }
1316 }
1317
|
1318 kumpf 1.38 providerModule =
1319 providerManagerService->_providerRegistrationManager->
1320 getInstance(
1321 modulePath, false, false, CIMPropertyList());
1322
1323 Array<Uint16> removeStatus;
1324 Array<Uint16> appendStatus;
|
1325 venkat.puvvada 1.45
|
1326 kumpf 1.38 removeStatus.append(CIM_MSE_OPSTATUS_VALUE_OK);
|
1327 venkat.puvvada 1.45
1328 // If the provider module needs to be restarted set the
1329 // module OpertionalStatus to the STOPPED and send the
1330 // module start request.
1331 appendStatus.append(startProviderModule ?
1332 CIM_MSE_OPSTATUS_VALUE_STOPPED :
1333 CIM_MSE_OPSTATUS_VALUE_DEGRADED);
1334
|
1335 kumpf 1.38 providerManagerService->_updateProviderModuleStatus(
1336 providerModule, removeStatus, appendStatus);
|
1337 venkat.puvvada 1.45
1338 if (startProviderModule)
1339 {
1340 _invokeProviderModuleStartMethod(modulePath);
|
1341 venkat.puvvada 1.48 _providerRegistrationManager->sendPMInstAlert(
1342 providerModule,
1343 PM_FAILED_RESTARTED);
|
1344 venkat.puvvada 1.45 //
1345 // Log a information message since provider module
1346 // is restarted automatically
1347 //
1348 Logger::put_l(
1349 Logger::STANDARD_LOG,
1350 System::CIMSERVER,
1351 Logger::INFORMATION,
1352 MessageLoaderParms(
1353 "ProviderManager.OOPProviderManagerRouter."
1354 "OOP_PROVIDER_MODULE_RESTARTED_AFTER_FAILURE",
1355 "The indication providers in the module"
1356 " $0 have been restarted with subscriptions"
1357 " enabled after $1 failure(s). After $2"
1358 " such attempts the provider will not be"
1359 " restarted automatically with subscriptions"
1360 " enabled. To ensure these providers continue"
1361 " to service active subscriptions please fix"
1362 " the problem in the provider.",
1363 moduleName,
1364 moduleFailureCount,
1365 venkat.puvvada 1.45 Uint32(maxFailedProviderModuleRestarts)));
1366 }
1367 else
1368 {
|
1369 venkat.puvvada 1.48 _providerRegistrationManager->sendPMInstAlert(
1370 providerModule,
1371 PM_DEGRADED);
|
1372 venkat.puvvada 1.45 //
1373 // Log a warning message since subscriptions
1374 // were affected
1375 //
1376 Logger::put_l(
1377 Logger::STANDARD_LOG,
1378 System::CIMSERVER,
1379 Logger::WARNING,
1380 MessageLoaderParms(
|
1381 thilo.boehm 1.51 "ProviderManager.ProviderManagerService."
|
1382 venkat.puvvada 1.45 "OOP_PROVIDER_MODULE_SUBSCRIPTIONS_AFFECTED",
1383 "The generation of indications by providers"
1384 " in module $0 may be affected. To ensure"
1385 " these providers are serving active "
1386 "subscriptions, disable and then re-enable"
1387 " this module using the cimprovider "
1388 "command.",
1389 moduleName));
1390 }
1391
|
1392 kumpf 1.38 }
1393 catch (const Exception & e)
1394 {
1395 PEG_TRACE((TRC_DISCARDED_DATA, Tracer::LEVEL1,
1396 "Failed to update provider module status: %s",
1397 (const char*)e.getMessage().getCString()));
1398 }
|
1399 kumpf 1.1 }
|
1400 venkat.puvvada 1.48 else
1401 {
1402 providerModule = providerManagerService->
1403 _providerRegistrationManager->getInstance(
1404 modulePath,
1405 false,
1406 false,
1407 CIMPropertyList());
1408 _providerRegistrationManager->sendPMInstAlert(
1409 providerModule,
1410 PM_FAILED);
1411 }
|
1412 kumpf 1.1 }
1413 }
1414
1415 PEG_METHOD_EXIT();
1416 }
1417
1418 PEGASUS_NAMESPACE_END
|