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