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