1 martin 1.5 //%LICENSE////////////////////////////////////////////////////////////////
|
2 martin 1.6 //
|
3 martin 1.5 // 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.6 //
|
10 martin 1.5 // 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.6 //
|
17 martin 1.5 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
|
19 martin 1.6 //
|
20 martin 1.5 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
21 martin 1.6 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
22 martin 1.5 // 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.6 //
|
28 martin 1.5 //////////////////////////////////////////////////////////////////////////
|
29 kumpf 1.2 //
30 //%////////////////////////////////////////////////////////////////////////////
31
32 #include <cctype>
33 #include <cstdio>
34 #include <Pegasus/Common/Config.h>
35 #include <Pegasus/Common/Tracer.h>
36 #include <Pegasus/Common/MessageLoader.h>
|
37 kumpf 1.3 #include <Pegasus/Common/StringConversion.h>
|
38 kumpf 1.2 #include <Pegasus/Common/AutoPtr.h>
39 #include "WsmConstants.h"
|
40 kumpf 1.8 #include "SoapResponse.h"
|
41 kumpf 1.2 #include "WsmProcessor.h"
42
|
43 kumpf 1.3 PEGASUS_USING_STD;
44
|
45 kumpf 1.2 PEGASUS_NAMESPACE_BEGIN
46
|
47 kumpf 1.3 Uint64 WsmProcessor::_currentEnumContext = 0;
48
|
49 kumpf 1.2 WsmProcessor::WsmProcessor(
|
50 sahana.prabhakar 1.11 MessageQueue* cimOperationProcessorQueue,
|
51 kumpf 1.2 CIMRepository* repository)
|
52 sahana.prabhakar 1.11 : MessageQueue(PEGASUS_QUEUENAME_WSMPROCESSOR),
|
53 kumpf 1.2 _wsmResponseEncoder(),
54 _wsmRequestDecoder(this),
55 _cimOperationProcessorQueue(cimOperationProcessorQueue),
56 _repository(repository),
57 _wsmToCimRequestMapper(repository)
58 {
|
59 karl 1.11.6.1 _initializeSubInfoTable();
|
60 kumpf 1.2 }
61
62 WsmProcessor::~WsmProcessor()
63 {
|
64 kumpf 1.4 // Clean up enumeration responses that have not been pulled or released.
65 for (EnumerationContextTable::Iterator i =
66 _enumerationContextTable.start(); i; i++)
67 {
68 delete i.value().response;
69 }
|
70 kumpf 1.2 }
71
72 void WsmProcessor::handleEnqueue(Message* message)
73 {
74 if (!message)
75 {
76 return;
77 }
78
79 PEGASUS_ASSERT(dynamic_cast<CIMResponseMessage*>(message) != 0);
80 handleResponse(dynamic_cast<CIMResponseMessage*>(message));
81 }
82
83 void WsmProcessor::handleEnqueue()
84 {
85 Message* message = dequeue();
86 handleEnqueue(message);
87 }
88
|
89 karl 1.11.6.1 void WsmProcessor::addReqToSubContext(
90 WsmRequest* wsmRequest,
91 Boolean isCreateReq)
92 {
93 PEG_METHOD_ENTER(TRC_WSMSERVER, "WsmProcessor::addReqToSubContext()");
94 SubscriptionContext *subContext=0;
95 String className;
96 WxfSubCreateRequest *wsmCreateRequest=0;
97 WxfSubDeleteRequest *wsmDeleteRequest=0;
98 if(isCreateReq == true)
99 {
100 wsmCreateRequest = (WxfSubCreateRequest *)wsmRequest;
101 className = wsmCreateRequest->instance.getClassName();
102 }
103 else
104 {
105 wsmDeleteRequest = (WxfSubDeleteRequest *)wsmRequest;
106 className = wsmDeleteRequest->className;
107 }
108
109 AutoMutex lock(_subscriptionContextTableLock);
110 karl 1.11.6.1 // Look up for the Subscription context in the hash table.
111 // If it does not exist, create a new entry.
112 if(_subscriptionContextTable.contains(wsmRequest->messageId))
113 {
114 _subscriptionContextTable.lookupReference(
115 wsmRequest->messageId,
116 subContext);
117 }
118 else
119 {
120 SubscriptionContext subCon(wsmRequest->messageId);
121 _subscriptionContextTable.insert(wsmRequest->messageId, subCon);
122 _subscriptionContextTable.lookupReference(
123 wsmRequest->messageId,
124 subContext);
125 }
126
127 // Fill in the filter, handler and subscription requests
128 if(className == PEGASUS_CLASSNAME_INDFILTER.getString())
129 {
130 if(isCreateReq == true)
131 karl 1.11.6.1 {
132 subContext->filterReq = wsmCreateRequest;
133 }
134 else
135 {
136 subContext->filterDeleteReq = wsmDeleteRequest;
137 }
138 }
139 else if ( className == PEGASUS_CLASSNAME_INDHANDLER_WSMAN.getString())
140 {
141 if (isCreateReq == true)
142 {
143 subContext->handlerReq = wsmCreateRequest;
144 }
145 else
146 {
147 subContext->handlerDeleteReq = wsmDeleteRequest;
148 }
149 }
150 else if ( className == PEGASUS_CLASSNAME_INDSUBSCRIPTION.getString())
151 {
152 karl 1.11.6.1 subContext->subReq = wsmCreateRequest;
153 }
154 PEG_METHOD_EXIT();
155 }
156
157
|
158 kumpf 1.2 void WsmProcessor::handleRequest(WsmRequest* wsmRequest)
159 {
160 PEG_METHOD_ENTER(TRC_WSMSERVER, "WsmProcessor::handleRequest()");
161
162 // Process requests by type. For now, only WS-Transfer operations are
163 // implemented, and they all are handled by forwarding to the CIM Server.
164
165 AutoPtr<WsmRequest> wsmRequestDestroyer(wsmRequest);
166 try
167 {
168 CIMOperationRequestMessage* cimRequest =
169 _wsmToCimRequestMapper.mapToCimRequest(wsmRequest);
170
|
171 kumpf 1.3 // Requests that do not have a CIM representation are mapped to NULL
172 // and are meant to be handled by the WSM processor itself.
173 if (cimRequest)
174 {
175 // Save the request until the response comes back.
176 // Note that the CIM request has its own unique message ID.
177 _requestTable.insert(cimRequest->messageId, wsmRequest);
178
179 cimRequest->queueIds.push(getQueueId());
180 _cimOperationProcessorQueue->enqueue(cimRequest);
|
181 kumpf 1.4
182 wsmRequestDestroyer.release();
|
183 kumpf 1.3 }
184 else
185 {
186 switch (wsmRequest->getType())
187 {
188 case WS_ENUMERATION_PULL:
189 _handlePullRequest((WsenPullRequest*) wsmRequest);
190 break;
191
192 case WS_ENUMERATION_RELEASE:
193 _handleReleaseRequest((WsenReleaseRequest*) wsmRequest);
194 break;
195
196 default:
197 break;
198 }
199 }
|
200 kumpf 1.2 }
201 catch (WsmFault& fault)
202 {
|
203 karl 1.11.6.1 sendResponse(new WsmFaultResponse(wsmRequest, fault),wsmRequest);
|
204 kumpf 1.2 }
205 catch (CIMException& e)
206 {
|
207 karl 1.11.6.1 sendResponse(
208 new WsmFaultResponse(
209 wsmRequest,
210 _cimToWsmResponseMapper.mapCimExceptionToWsmFault(e)),
211 wsmRequest);
|
212 kumpf 1.2 }
213 catch (Exception& e)
214 {
|
215 karl 1.11.6.1 sendResponse(
216 new WsmFaultResponse(
217 wsmRequest,
218 WsmFault(
219 WsmFault::wsman_InternalError,
220 e.getMessage(),
221 e.getContentLanguages())),
222 wsmRequest);
|
223 kumpf 1.2 }
224 catch (PEGASUS_STD(exception)& e)
225 {
|
226 karl 1.11.6.1 sendResponse(
227 new WsmFaultResponse(
228 wsmRequest,
229 WsmFault(WsmFault::wsman_InternalError, e.what())),
230 wsmRequest);
|
231 kumpf 1.2 }
232 catch (...)
233 {
|
234 karl 1.11.6.1 sendResponse(
235 new WsmFaultResponse(
236 wsmRequest,
237 WsmFault(WsmFault::wsman_InternalError)),
238 wsmRequest);
|
239 kumpf 1.2 }
240 // Note this requirement when Enumerate/Pull operations are supported:
241 // DSP0226 R6.3-5: For operations that span multiple message sequences,
242 // the wsman:Locale element is processed in the initial message only.
243 // It should be ignored in subsequent messages because the first
244 // message establishes the required locale. The service may issue a
245 // fault if the wsman:Locale is present in subsequent messages and the
246 // value is different from that used in the initiating request.
247
248 PEG_METHOD_EXIT();
249 }
250
251 void WsmProcessor::handleResponse(CIMResponseMessage* cimResponse)
252 {
253 PEG_METHOD_ENTER(TRC_WSMSERVER, "WsmProcessor::handleResponse()");
254
255 AutoPtr<CIMResponseMessage> cimResponseDestroyer(cimResponse);
256
257 // Lookup the request this response corresponds to
|
258 karl 1.11.6.1 WsmRequest* wsmRequest = 0;
259
260 PEGASUS_FCT_EXECUTE_AND_ASSERT(
261 true,
262 _requestTable.lookup(cimResponse->messageId, wsmRequest));
263
|
264 kumpf 1.2 AutoPtr<WsmRequest> wsmRequestDestroyer(wsmRequest);
|
265 kumpf 1.3 _requestTable.remove(cimResponse->messageId);
|
266 kumpf 1.2
267 try
268 {
|
269 kumpf 1.3 switch (wsmRequest->getType())
270 {
271 case WS_ENUMERATION_ENUMERATE:
272 _handleEnumerateResponse(
273 cimResponse,
274 (WsenEnumerateRequest*) wsmRequest);
275 break;
|
276 karl 1.11.6.1 case WS_SUBSCRIPTION_CREATE:
277 _handleSubscriptionResponse(
278 cimResponse,
279 (WxfSubCreateRequest*) wsmRequest);
280 break;
281 case WS_SUBSCRIPTION_DELETE:
282 _handleSubscriptionDeleteResponse(
283 cimResponse,
284 (WxfSubDeleteRequest*) wsmRequest);
285 break;
|
286 kumpf 1.3 default:
287 _handleDefaultResponse(cimResponse, wsmRequest);
288 break;
289 }
|
290 kumpf 1.2 }
291 catch (WsmFault& fault)
292 {
|
293 karl 1.11.6.1 sendResponse(new WsmFaultResponse(wsmRequest, fault),wsmRequest);
|
294 kumpf 1.2 }
295 catch (CIMException& e)
296 {
|
297 karl 1.11.6.1 sendResponse(
298 new WsmFaultResponse(
299 wsmRequest,
300 _cimToWsmResponseMapper.mapCimExceptionToWsmFault(e)),
301 wsmRequest);
|
302 kumpf 1.2 }
303 catch (Exception& e)
304 {
|
305 karl 1.11.6.1 sendResponse(
306 new WsmFaultResponse(
307 wsmRequest,
308 WsmFault(
309 WsmFault::wsman_InternalError,
310 e.getMessage(),
311 e.getContentLanguages())),
312 wsmRequest);
|
313 kumpf 1.2 }
314 catch (PEGASUS_STD(exception)& e)
315 {
|
316 karl 1.11.6.1 sendResponse(
317 new WsmFaultResponse(
318 wsmRequest,
319 WsmFault(WsmFault::wsman_InternalError, e.what())),
320 wsmRequest);
|
321 kumpf 1.2 }
322 catch (...)
323 {
|
324 karl 1.11.6.1 sendResponse(
325 new WsmFaultResponse(
326 wsmRequest,
327 WsmFault(WsmFault::wsman_InternalError)),
328 wsmRequest);
|
329 kumpf 1.2 }
330
331 PEG_METHOD_EXIT();
332 }
333
|
334 karl 1.11.6.1 void WsmProcessor::sendResponse(
335 WsmResponse* wsmResponse,
336 WsmRequest* wsmReq)
|
337 kumpf 1.2 {
338 PEG_METHOD_ENTER(TRC_WSMSERVER, "WsmProcessor::sendResponse()");
|
339 karl 1.11.6.1 if( wsmReq && wsmReq->getType() == WS_SUBSCRIPTION_CREATE)
340 {
341 SubscriptionContext *subContext = NULL;
342 AutoMutex lock(_subscriptionContextTableLock);
343 _subscriptionContextTable.lookupReference(
344 wsmReq->messageId, subContext);
345 if(wsmReq->getType() == WS_SUBSCRIPTION_CREATE)
346 {
347 Boolean createFilter=false;
348 if(subContext && (subContext->filterReq != NULL))
349 {
350 createFilter = true;
351 }
352 WxfSubCreateRequest *req = (WxfSubCreateRequest *)wsmReq;
353 if (req->instance.getClassName() ==
354 PEGASUS_CLASSNAME_INDHANDLER_WSMAN.getString())
355 {
356 _cleanupFilterHandlerInstances(
357 req->messageId,
358 true,
359 false);
360 karl 1.11.6.1 _cleanupSubContext(wsmReq->messageId,
361 createFilter,
362 false,
363 true);
364
365 }
366 else if (req->instance.getClassName() ==
367 PEGASUS_CLASSNAME_INDSUBSCRIPTION.getString())
368 {
369 _cleanupFilterHandlerInstances(
370 req->messageId,
371 true,
372 true);
373 //Delete the subContext.
374 _cleanupSubContext(wsmReq->messageId);
375 }
376 else if (req->instance.getClassName() ==
377 PEGASUS_CLASSNAME_INDFILTER.getString())
378 {
379 _cleanupSubContext(wsmReq->messageId,
380 false,
381 karl 1.11.6.1 false,
382 true);
383 }
384 }
385 else if (wsmReq->getType() == WS_SUBSCRIPTION_DELETE)
386 {
387 Boolean deleteFilter = false;
388 if(subContext && (subContext->filterDeleteReq != NULL))
389 {
390 deleteFilter = true;
391 }
392 WxfSubDeleteRequest *deleteReq = (WxfSubDeleteRequest *)wsmReq;
393 if(deleteReq->className ==
394 PEGASUS_CLASSNAME_INDSUBSCRIPTION.getString())
395 {
396 _cleanupSubContext(wsmReq->messageId,
397 false,
398 false,
399 false,
400 deleteFilter,
401 true);
402 karl 1.11.6.1 }
403 }
404 }
|
405 kumpf 1.2 _wsmResponseEncoder.enqueue(wsmResponse);
|
406 karl 1.11.6.1
|
407 kumpf 1.2 delete wsmResponse;
408
409 PEG_METHOD_EXIT();
410 }
411
412 Uint32 WsmProcessor::getWsmRequestDecoderQueueId()
413 {
414 return _wsmRequestDecoder.getQueueId();
415 }
416
|
417 kumpf 1.3 void WsmProcessor::_handleEnumerateResponse(
418 CIMResponseMessage* cimResponse,
419 WsenEnumerateRequest* wsmRequest)
420 {
421 if (cimResponse->cimException.getCode() != CIM_ERR_SUCCESS)
422 {
423 _handleDefaultResponse(cimResponse, wsmRequest);
|
424 kumpf 1.8 return;
|
425 kumpf 1.3 }
|
426 kumpf 1.8
427 AutoPtr<SoapResponse> soapResponse;
428
|
429 kumpf 1.3 {
430 AutoMutex lock(_enumerationContextTableLock);
431
432 AutoPtr<WsenEnumerateResponse> wsmResponse(
433 (WsenEnumerateResponse*) _cimToWsmResponseMapper.
434 mapToWsmResponse(wsmRequest, cimResponse));
435
436 // Get the enumeration expiration time
437 CIMDateTime expiration;
438 _getExpirationDatetime(wsmRequest->expiration, expiration);
439
440 // Create a new context
441 Uint64 contextId = _currentEnumContext++;
442 _enumerationContextTable.insert(
443 contextId,
444 EnumerationContext(
445 contextId,
|
446 kumpf 1.10 wsmRequest->userName,
|
447 kumpf 1.3 wsmRequest->enumerationMode,
|
448 kumpf 1.7 expiration,
|
449 kumpf 1.3 wsmRequest->epr,
450 wsmResponse.get()));
451 wsmResponse->setEnumerationContext(contextId);
452
453 // Get the requsted chunk of results
454 AutoPtr<WsenEnumerateResponse> splitResponse(
|
455 kumpf 1.7 _splitEnumerateResponse(wsmRequest, wsmResponse.get(),
|
456 kumpf 1.3 wsmRequest->optimized ? wsmRequest->maxElements : 0));
457 splitResponse->setEnumerationContext(contextId);
458
|
459 kumpf 1.8 // If no items are left in the original response, mark split
|
460 kumpf 1.3 // response as complete
461 if (wsmResponse->getSize() == 0)
462 {
463 splitResponse->setComplete();
464 }
465
|
466 kumpf 1.8 Uint32 numDataItemsEncoded = 0;
467 soapResponse.reset(_wsmResponseEncoder.encodeWsenEnumerateResponse(
468 splitResponse.get(), numDataItemsEncoded));
469
470 if (splitResponse->getSize() > numDataItemsEncoded)
|
471 kumpf 1.3 {
472 // Add unprocessed items back to the context
|
473 kumpf 1.9 splitResponse->remove(0, numDataItemsEncoded);
|
474 kumpf 1.3 wsmResponse->merge(splitResponse.get());
475 }
476
477 // Remove the context if there are no instances left
478 if (wsmResponse->getSize() == 0)
479 {
480 _enumerationContextTable.remove(contextId);
481 }
482 else
483 {
484 // If the context is not removed, the pointer to the response is
485 // now owned by the context
486 wsmResponse.release();
487 }
488 }
|
489 kumpf 1.8
490 _wsmResponseEncoder.sendResponse(soapResponse.get());
|
491 kumpf 1.3 }
492
|
493 karl 1.11.6.1 void WsmProcessor::_handleSubscriptionResponse(
494 CIMResponseMessage* cimResponse,
495 WxfSubCreateRequest* wsmRequest)
496 {
497 PEG_METHOD_ENTER(TRC_WSMSERVER,
498 "WsmProcessor::_handleSubscriptionResponse()");
499 SubscriptionContext *subContext = NULL;
500 AutoMutex lock(_subscriptionContextTableLock);
501 _subscriptionContextTable.lookupReference(
502 wsmRequest->messageId, subContext);
503 if(subContext)
504 {
505 Boolean createFilter = false;
506 if (subContext->filterReq != NULL)
507 createFilter = true;
508 String className = wsmRequest->instance.getClassName();
509 if (className == PEGASUS_CLASSNAME_INDHANDLER_WSMAN.getString())
510 {
511 // If handler response is successful
512 if(cimResponse->cimException.getCode() == CIM_ERR_SUCCESS)
513 {
514 karl 1.11.6.1 subContext->handlerResponse = true;
515 // Proccess filter request if it exists
516 if (createFilter)
517 handleRequest(subContext->filterReq);
518 // Process Subscription request if filter request is NULL,
519 // which means subscription uses existing filter
520 else if (subContext->subReq != NULL)
521 {
522 subContext->filterResponse = true;
523 handleRequest(subContext->subReq);
524 }
525 }
526 else // If unsuccessful, do the cleanup
527 {
528 PEG_TRACE((TRC_WSMSERVER, Tracer::LEVEL2,
529 "Handler creation failed for the request with ID %s ",
530 (const char*)wsmRequest->messageId.getCString()));
531 _subscriptionContextTableLock.unlock();
532 sendResponse(new WsmFaultResponse(
533 wsmRequest,
534 _cimToWsmResponseMapper.mapCimExceptionToWsmFault(
535 karl 1.11.6.1 cimResponse->cimException)));
536 _subscriptionContextTableLock.lock();
537 _cleanupSubContext(wsmRequest->messageId,
538 createFilter,
539 false,
540 true);
541 }
542 }
543 else if (className == PEGASUS_CLASSNAME_INDFILTER.getString())
544 {
545 subContext->filterResponse = true;
546 // If filter response is successful, process the handler
547 if(cimResponse->cimException.getCode() == CIM_ERR_SUCCESS)
548 {
549 if (subContext->subReq != NULL)
550 handleRequest(subContext->subReq);
551 }
552 else // If unsuccessful, do the cleanup
553 {
554 PEG_TRACE((TRC_WSMSERVER, Tracer::LEVEL2,
555 "Filter creation failed for the request with ID %s ",
556 karl 1.11.6.1 (const char*)wsmRequest->messageId.getCString()));
557 // Cleanup handler
558 _cleanupFilterHandlerInstances(
559 wsmRequest->messageId,
560 false,
561 true);
562 _subscriptionContextTableLock.unlock();
563 sendResponse(new WsmFaultResponse(
564 wsmRequest,
565 _cimToWsmResponseMapper.mapCimExceptionToWsmFault(
566 cimResponse->cimException)));
567 _subscriptionContextTableLock.lock();
568 _cleanupSubContext(wsmRequest->messageId,
569 false,
570 false,
571 true);
572
573 }
574 }
575 else if (className == PEGASUS_CLASSNAME_INDSUBSCRIPTION.getString())
576 {
577 karl 1.11.6.1 if ((cimResponse->cimException.getCode() == CIM_ERR_SUCCESS)&&
578 (subContext->filterResponse == true) &&
579 (subContext->handlerResponse == true))
580 {
581 _fillSubscriptionInfoTable(subContext->subReq);
582 _subscriptionContextTableLock.unlock();
583 // Subscription has been created successfully
584 // Send Subscription response
585 AutoPtr<WsmResponse> wsmResponse(
586 _cimToWsmResponseMapper.mapToWsmResponse(
587 wsmRequest,
588 cimResponse));
589 cimResponse->updateThreadLanguages();
590 cimResponse->queueIds.pop();
591 _wsmResponseEncoder.enqueue(wsmResponse.get());
592 }
593 else
594 {
595 // Subscription creation failed, cleanup the filter and handler
596 PEG_TRACE((TRC_WSMSERVER, Tracer::LEVEL2,
597 "Subscription creation failed for the request with ID %s ",
598 karl 1.11.6.1 (const char*)wsmRequest->messageId.getCString()));
599 _cleanupFilterHandlerInstances(
600 wsmRequest->messageId,
601 createFilter,
602 true);
603 _subscriptionContextTableLock.unlock();
604 sendResponse(new WsmFaultResponse(
605 wsmRequest,
606 _cimToWsmResponseMapper.mapCimExceptionToWsmFault(
607 cimResponse->cimException)));
608 }
609 _subscriptionContextTableLock.lock();
610 //Delete the subContext
611 _cleanupSubContext(wsmRequest->messageId);
612 }
613 }
614 // Context entry should usually be found, in case it is not found
615 // log it in the trace
616 else
617 {
618 PEG_TRACE((TRC_WSMSERVER, Tracer::LEVEL2,
619 karl 1.11.6.1 "Subscription context entry for %s not found.",
620 (const char*)wsmRequest->messageId.getCString()));
621 }
622 PEG_METHOD_EXIT();
623 }
624
625 void WsmProcessor::_handleSubscriptionDeleteResponse(
626 CIMResponseMessage* cimResponse,
627 WxfSubDeleteRequest* wsmRequest)
628 {
629 PEG_METHOD_ENTER(TRC_WSMSERVER,
630 "WsmProcessor::_handleSubscriptionDeleteResponse()");
631 String className = wsmRequest->className;
632 if(className == PEGASUS_CLASSNAME_INDSUBSCRIPTION.getString())
633 {
634 SubscriptionContext *subContext = NULL;
635 AutoMutex lock(_subscriptionContextTableLock);
636 _subscriptionContextTable.lookupReference(
637 wsmRequest->messageId,
638 subContext);
639 Boolean deleteFilter = false;
640 karl 1.11.6.1 if(subContext && (subContext->filterDeleteReq != NULL))
641 {
642 deleteFilter = true;
643 }
644 if(cimResponse->cimException.getCode() == CIM_ERR_SUCCESS)
645 {
646 //delete the filter and handler.
647 if(deleteFilter)
648 {
649 handleRequest(subContext->filterDeleteReq);
650 }
651 if(subContext)
652 {
653 handleRequest(subContext->handlerDeleteReq);
654 }
655 //delete the entry from _subscriptionInfoTable if the
656 //subscription is created with the existing filter.
657 for(Uint32 i=0;
658 i<wsmRequest->epr.selectorSet->selectors.size();i++)
659 {
660 if(wsmRequest->epr.selectorSet->selectors[i].name ==
661 karl 1.11.6.1 PEGASUS_PROPERTYNAME_HANDLER.getString())
662 {
663 WsmEndpointReference handlerEpr =
664 wsmRequest->epr.selectorSet->selectors[i].epr;
665 for(Uint32 j=0;
666 j<handlerEpr.selectorSet->selectors.size();j++)
667 {
668 String handlerName;
669 if(handlerEpr.selectorSet->selectors[j].name ==
670 PEGASUS_PROPERTYNAME_NAME.getString())
671 {
672 handlerName =
673 handlerEpr.selectorSet->selectors[j].value;
674 AutoMutex lock(_subscriptionInfoTableLock);
675 if(_subscriptionInfoTable.contains(handlerName))
676 {
677 _subscriptionInfoTable.remove(handlerName);
678 }
679 break;
680 }
681
682 karl 1.11.6.1 }
683 break;
684 }
685 }
686 //Delete the context
687 _cleanupSubContext(wsmRequest->messageId);
688 }
689 else
690 {
691 _cleanupSubContext(wsmRequest->messageId,
692 false,
693 false,
694 false,
695 deleteFilter,
696 true);
697 }
698 _subscriptionContextTableLock.unlock();
699 AutoPtr<WsmResponse> wsmResponse(
700 _cimToWsmResponseMapper.mapToWsmResponse(
701 wsmRequest,
702 cimResponse));
703 karl 1.11.6.1 cimResponse->updateThreadLanguages();
704 cimResponse->queueIds.pop();
705
706 _wsmResponseEncoder.enqueue(wsmResponse.get());
707 _subscriptionContextTableLock.lock();
708 }
709 // Context entry should usually be found, in case it is not found
710 // log it in the trace
711 else
712 {
713 PEG_TRACE((TRC_WSMSERVER, Tracer::LEVEL2,
714 "Subscription context entry for %s not found.",
715 (const char*)wsmRequest->messageId.getCString()));
716 }
717 PEG_METHOD_EXIT();
718 return;
719 }
720
|
721 kumpf 1.3 void WsmProcessor::_handlePullRequest(WsenPullRequest* wsmRequest)
722 {
|
723 kumpf 1.8 AutoPtr<SoapResponse> soapResponse;
|
724 kumpf 1.3
725 {
|
726 kumpf 1.8 AutoMutex lock(_enumerationContextTableLock);
727 EnumerationContext* enumContext;
728
729 if (_enumerationContextTable.lookupReference(
730 wsmRequest->enumerationContext, enumContext))
|
731 kumpf 1.3 {
|
732 kumpf 1.8 // EPRs of the request and the enumeration context must match
733 if (wsmRequest->epr != enumContext->epr)
734 {
735 throw WsmFault(
736 WsmFault::wsa_MessageInformationHeaderRequired,
737 MessageLoaderParms(
738 "WsmServer.WsmProcessor.INVALID_PULL_EPR",
739 "EPR of a Pull request does not match that of "
740 "the enumeration context."));
741 }
742
|
743 kumpf 1.10 // User credentials of the request and the enumeration context must
744 // match.
745 if (wsmRequest->userName != enumContext->userName)
746 {
747 // DSP0226 R8.1-6: The wsen:Pull and wsen:Release operations
748 // are a continuation of the original wsen:Enumerate operation.
749 // The service should enforce the same authentication and
750 // authorization throughout the entire sequence of operations
751 // and should fault any attempt to change credentials during
752 // the sequence.
753
754 throw WsmFault(WsmFault::wsman_AccessDenied);
755 }
756
|
757 kumpf 1.8 AutoPtr<WsenPullResponse> wsmResponse(_splitPullResponse(
758 wsmRequest, enumContext->response, wsmRequest->maxElements));
759 wsmResponse->setEnumerationContext(enumContext->contextId);
760 if (enumContext->response->getSize() == 0)
761 {
762 wsmResponse->setComplete();
763 }
764
765 Uint32 numDataItemsEncoded = 0;
766 soapResponse.reset(_wsmResponseEncoder.encodeWsenPullResponse(
767 wsmResponse.get(), numDataItemsEncoded));
|
768 kumpf 1.3
|
769 kumpf 1.8 if (wsmResponse->getSize() > numDataItemsEncoded)
770 {
771 // Add unprocessed items back to the context
|
772 kumpf 1.9 wsmResponse->remove(0, numDataItemsEncoded);
|
773 kumpf 1.8 enumContext->response->merge(wsmResponse.get());
774 }
|
775 kumpf 1.3
|
776 kumpf 1.8 // Remove the context if there are no instances left
777 if (enumContext->response->getSize() == 0)
778 {
779 delete enumContext->response;
780 _enumerationContextTable.remove(wsmRequest->enumerationContext);
781 }
|
782 kumpf 1.3 }
|
783 kumpf 1.8 else
|
784 kumpf 1.3 {
|
785 kumpf 1.8 throw WsmFault(
786 WsmFault::wsen_InvalidEnumerationContext,
787 MessageLoaderParms(
788 "WsmServer.WsmProcessor.INVALID_ENUMERATION_CONTEXT",
789 "Enumeration context \"$0\" is not valid.",
790 wsmRequest->enumerationContext));
|
791 kumpf 1.3 }
792 }
|
793 kumpf 1.8
794 _wsmResponseEncoder.sendResponse(soapResponse.get());
|
795 kumpf 1.3 }
796
797 void WsmProcessor::_handleReleaseRequest(WsenReleaseRequest* wsmRequest)
798 {
|
799 kumpf 1.8 AutoPtr<WsenReleaseResponse> wsmResponse;
800
|
801 kumpf 1.3 {
|
802 kumpf 1.8 AutoMutex lock(_enumerationContextTableLock);
803
804 EnumerationContext enumContext;
805 if (_enumerationContextTable.lookup(
806 wsmRequest->enumerationContext, enumContext))
807 {
808 // EPRs of the request and the enumeration context must match
809 if (wsmRequest->epr != enumContext.epr)
810 {
811 throw WsmFault(
812 WsmFault::wsa_MessageInformationHeaderRequired,
813 MessageLoaderParms(
814 "WsmServer.WsmProcessor.INVALID_RELEASE_EPR",
815 "EPR of a Release request does not match that of "
816 "the enumeration context."));
817 }
818
|
819 kumpf 1.10 // User credentials of the request and the enumeration context must
820 // match.
821 if (wsmRequest->userName != enumContext.userName)
822 {
823 // DSP0226 R8.1-6: The wsen:Pull and wsen:Release operations
824 // are a continuation of the original wsen:Enumerate operation.
825 // The service should enforce the same authentication and
826 // authorization throughout the entire sequence of operations
827 // and should fault any attempt to change credentials during
828 // the sequence.
829
830 throw WsmFault(WsmFault::wsman_AccessDenied);
831 }
832
|
833 kumpf 1.8 wsmResponse.reset(new WsenReleaseResponse(
834 wsmRequest, enumContext.response->getContentLanguages()));
835
836 delete enumContext.response;
837 _enumerationContextTable.remove(wsmRequest->enumerationContext);
838 }
839 else
|
840 kumpf 1.3 {
841 throw WsmFault(
|
842 kumpf 1.8 WsmFault::wsen_InvalidEnumerationContext,
|
843 kumpf 1.3 MessageLoaderParms(
|
844 kumpf 1.8 "WsmServer.WsmProcessor.INVALID_ENUMERATION_CONTEXT",
845 "Enumeration context \"$0\" is not valid.",
846 wsmRequest->enumerationContext));
|
847 kumpf 1.3 }
|
848 kumpf 1.8 }
|
849 kumpf 1.3
|
850 kumpf 1.8 _wsmResponseEncoder.enqueue(wsmResponse.get());
|
851 kumpf 1.3 }
852
853 void WsmProcessor::_handleDefaultResponse(
854 CIMResponseMessage* cimResponse, WsmRequest* wsmRequest)
855 {
856 AutoPtr<WsmResponse> wsmResponse(
857 _cimToWsmResponseMapper.mapToWsmResponse(wsmRequest, cimResponse));
858
859 cimResponse->updateThreadLanguages();
860 cimResponse->queueIds.pop();
861
862 _wsmResponseEncoder.enqueue(wsmResponse.get());
863 }
864
865 WsenEnumerateResponse* WsmProcessor::_splitEnumerateResponse(
866 WsenEnumerateRequest* request, WsenEnumerateResponse* response, Uint32 num)
867 {
868 WsenEnumerationData splitData;
869 response->getEnumerationData().split(splitData, num);
870
871 return new WsenEnumerateResponse(splitData, response->getItemCount(),
872 kumpf 1.3 request, response->getContentLanguages());
873 }
874
875 WsenPullResponse* WsmProcessor::_splitPullResponse(
876 WsenPullRequest* request, WsenEnumerateResponse* response, Uint32 num)
877 {
878 WsenEnumerationData splitData;
879 response->getEnumerationData().split(splitData, num);
880
|
881 kumpf 1.7 return new WsenPullResponse(splitData, request,
|
882 kumpf 1.3 response->getContentLanguages());
883 }
884
885 void WsmProcessor::_getExpirationDatetime(
886 const String& wsmDT, CIMDateTime& cimDT)
887 {
888 CIMDateTime dt, currentDT;
889
|
890 kumpf 1.7 // Default expiration interval = 10 mins
|
891 kumpf 1.3 // ATTN WSMAN: what should the value be?
892 CIMDateTime maxInterval(0, 0, 10, 0, 0, 6);
893
894 // If expiration is not set, use the dafault.
895 if (wsmDT == String::EMPTY)
896 {
897 dt = maxInterval;
898 }
899 else
900 {
901 try
902 {
903 WsmToCimRequestMapper::convertWsmToCimDatetime(wsmDT, dt);
904 }
905 catch (...)
906 {
907 throw WsmFault(
908 WsmFault::wsen_InvalidExpirationTime,
909 MessageLoaderParms(
910 "WsmServer.WsmToCimRequestMapper.INVALID_EXPIRATION_TIME",
911 "The expiration time \"$0\" is not valid", wsmDT));
912 kumpf 1.3 }
913 }
914
915 currentDT = CIMDateTime::getCurrentDateTime();
916 if (dt.isInterval())
917 {
918 if (dt > maxInterval)
919 {
920 dt = maxInterval;
921 }
922 cimDT = currentDT + dt;
923 }
924 else
925 {
926 if ((dt <= currentDT))
927 {
928 throw WsmFault(
929 WsmFault::wsen_InvalidExpirationTime,
930 MessageLoaderParms(
931 "WsmServer.WsmToCimRequestMapper.INVALID_EXPIRATION_TIME",
932 "The expiration time \"$0\" is not valid", wsmDT));
933 kumpf 1.3 }
934
935 if (dt - currentDT > maxInterval)
936 {
937 cimDT = currentDT + maxInterval;
938 }
939 else
940 {
941 cimDT = dt;
942 }
943 }
944 }
945
946 void WsmProcessor::cleanupExpiredContexts()
947 {
948 CIMDateTime currentDT = CIMDateTime::getCurrentDateTime();
|
949 kumpf 1.4 Array<Uint64> expiredContextIds;
950 Array<WsenEnumerateResponse*> expiredResponses;
|
951 kumpf 1.3
952 AutoMutex lock(_enumerationContextTableLock);
953 for (EnumerationContextTable::Iterator i =
954 _enumerationContextTable.start (); i; i++)
955 {
956 EnumerationContext context = i.value();
957 if (context.expiration < currentDT)
958 {
|
959 kumpf 1.4 expiredContextIds.append(context.contextId);
960 expiredResponses.append(context.response);
|
961 kumpf 1.3 }
962 }
963
|
964 kumpf 1.4 for (Uint32 i = 0; i < expiredContextIds.size(); i++)
|
965 kumpf 1.3 {
|
966 kumpf 1.4 delete expiredResponses[i];
967 _enumerationContextTable.remove(expiredContextIds[i]);
|
968 kumpf 1.3 }
969 }
970
|
971 karl 1.11.6.1 void WsmProcessor::_cleanupFilterHandlerInstances(
972 String messageId,
973 Boolean isfilterCleaup,
974 Boolean isHandlerCleanup)
975 {
976 PEG_METHOD_ENTER(TRC_WSMSERVER,
977 "WsmProcessor::_cleanupFilterHandlerInstances()");
978 SubscriptionContext *subContext = NULL;
979 _subscriptionContextTable.lookupReference(
980 messageId,
981 subContext);
982 AutoPtr<WxfSubDeleteRequest> deleteFilter;
983 if(subContext)
984 {
985 String msgId = messageId.subString(PEGASUS_WS_UUID_LENGTH);
986 if(isfilterCleaup)
987 {
988 //form a deleteInstance Request for filter.
989 WsmEndpointReference filterEPR;
990 _wsmRequestDecoder.getFilterOrHandlerEPR(filterEPR,
991 subContext->subReq->epr.address,
992 karl 1.11.6.1 msgId,
993 PEGASUS_CLASSNAME_INDFILTER.getString());
994 AutoPtr<WxfSubDeleteRequest> deleteFilter(new WxfSubDeleteRequest(
995 messageId,
996 filterEPR,
997 PEGASUS_CLASSNAME_INDFILTER.getString()));
998 handleRequest(deleteFilter.release());
999 }
1000 if(isHandlerCleanup)
1001 {
1002 //Form a deleteInstance request for handler.
1003 WsmEndpointReference handlerEPR;
1004 _wsmRequestDecoder.getFilterOrHandlerEPR(handlerEPR,
1005 subContext->subReq->epr.address,
1006 msgId,
1007 PEGASUS_CLASSNAME_INDHANDLER_WSMAN.getString());
1008 AutoPtr<WxfSubDeleteRequest>deleteHandler(new WxfSubDeleteRequest(
1009 messageId,
1010 handlerEPR,
1011 PEGASUS_CLASSNAME_INDHANDLER_WSMAN.getString()));
1012 handleRequest(deleteHandler.release());
1013 karl 1.11.6.1 }
1014 }
1015 else
1016 {
1017 PEG_TRACE((TRC_WSMSERVER, Tracer::LEVEL2,
1018 "Subscription context entry for %s not found.",
1019 (const char*)messageId.getCString()));
1020 }
1021 PEG_METHOD_EXIT();
1022 }
1023
1024 void WsmProcessor::_cleanupSubContext(String & messageId,
1025 Boolean isFilterCreate,
1026 Boolean isHanlderCreate,
1027 Boolean isSubCreate,
1028 Boolean isFilterDelete,
1029 Boolean isHandlerDelete)
1030 {
1031 SubscriptionContext *subConTxt = 0;
1032 _subscriptionContextTable.lookupReference(messageId,subConTxt);
1033 if(subConTxt)
1034 karl 1.11.6.1 {
1035 if(subConTxt->filterReq && isFilterCreate)
1036 delete subConTxt->filterReq;
1037 if(subConTxt->handlerReq && isHanlderCreate)
1038 delete subConTxt->handlerReq;
1039 if(subConTxt->subReq && isSubCreate)
1040 delete subConTxt->subReq;
1041 if(subConTxt->filterDeleteReq && isFilterDelete)
1042 delete subConTxt->filterDeleteReq;
1043 if(subConTxt->handlerDeleteReq && isHandlerDelete)
1044 delete subConTxt->handlerDeleteReq;
1045
1046 _subscriptionContextTable.remove(messageId);
1047 }
1048 }
1049
1050 void WsmProcessor::_fillSubscriptionInfoTable(WxfSubCreateRequest * subReq)
1051 {
1052
1053 // Filter name is message id without "uuid:"
1054 String msgId = subReq->messageId.subString(PEGASUS_WS_UUID_LENGTH);
1055 karl 1.11.6.1 AutoMutex lock(_subscriptionInfoTableLock);
1056 if(!_subscriptionInfoTable.contains(msgId))
1057 {
1058 String filterName;
1059 WsmEndpointReference filterEPR;
1060 for(Uint32 i=0;i<subReq->instance.getPropertyCount();i++)
1061 {
1062 if((subReq->instance.getProperty(i)).getName() ==
1063 PEGASUS_PROPERTYNAME_FILTER.getString())
1064 {
1065 WsmValue filterPropVal =
1066 subReq->instance.getProperty(i).getValue();
1067 filterPropVal.get(filterEPR);
1068 break;
1069 }
1070 }
1071
1072 for(Uint32 i=0;i<filterEPR.selectorSet->selectors.size();i++)
1073 {
1074 if(filterEPR.selectorSet->selectors[i].name ==
1075 PEGASUS_PROPERTYNAME_NAME.getString())
1076 karl 1.11.6.1 {
1077 filterName = filterEPR.selectorSet->selectors[i].value;
1078 break;
1079 }
1080 }
1081 // If msgId is not equal to filterName, then it is using an
1082 // existing filter.
1083 if( msgId != filterName)
1084 _subscriptionInfoTable.insert(msgId ,filterName);
1085 }
1086 }
1087
1088 Boolean WsmProcessor::isSubCreatedWithExistingFilter(
1089 const String & subId,
1090 String & filterName)
1091 {
1092 AutoMutex lock(_subscriptionInfoTableLock);
1093 if(_subscriptionInfoTable.lookup(subId,filterName))
1094 {
1095 return true;
1096 }
1097 karl 1.11.6.1 else
1098 {
1099 return false;
1100 }
1101 }
1102
1103 void WsmProcessor::_initializeSubInfoTable()
1104 {
1105 if (_repository->nameSpaceExists(PEGASUS_NAMESPACENAME_INTEROP))
1106 {
1107 Array <CIMInstance> subscriptions;
1108 subscriptions = _repository->enumerateInstancesForClass(
1109 CIMNamespaceName(PEGASUS_NAMESPACENAME_INTEROP.getString()),
1110 PEGASUS_CLASSNAME_INDSUBSCRIPTION);
1111 for (Uint32 i = 0; i < subscriptions.size(); i++)
1112 {
1113 CIMObjectPath filterPath;
1114 String subscriptionInfo;
1115 Boolean filterNameUpdated = false;
1116 Boolean subInfoUpdated = false;
1117 String filterName;
1118 karl 1.11.6.1 Boolean isWsmanSub = false;
1119 for(Uint32 j=0; j<subscriptions[i].getPropertyCount(); j++)
1120 {
1121 CIMProperty prop = subscriptions[i].getProperty(j);
1122 if(prop.getName()== PEGASUS_PROPERTYNAME_HANDLER.getString())
1123 {
1124 CIMObjectPath handlePath;
1125 prop.getValue().get(handlePath);
1126 if(handlePath.getClassName() ==
1127 PEGASUS_CLASSNAME_INDHANDLER_WSMAN.getString())
1128 {
1129 isWsmanSub = true;
1130 }
1131
1132 }
1133 else if(prop.getName() == PEGASUS_PROPERTYNAME_FILTER)
1134 {
1135 prop.getValue().get(filterPath);
1136 Array<CIMKeyBinding> filterKeyProp =
1137 filterPath.getKeyBindings();
1138 for(Uint32 k=0 ;k<filterKeyProp.size();k++)
1139 karl 1.11.6.1 {
1140 if(filterKeyProp[k].getName().getString() ==
1141 PEGASUS_PROPERTYNAME_NAME.getString())
1142 {
1143 filterName = filterKeyProp[k].getValue();
1144 filterNameUpdated = true;
1145 }
1146 }
1147 }
1148 else if(prop.getName().getString() == "SubscriptionInfo")
1149 {
1150 prop.getValue().get(subscriptionInfo);
1151 subInfoUpdated = true;
1152 }
1153 }
1154 if(isWsmanSub && filterNameUpdated && subInfoUpdated &&
1155 (filterName != subscriptionInfo))
1156 {
1157 AutoMutex lock(_subscriptionInfoTableLock);
1158 _subscriptionInfoTable.insert(subscriptionInfo, filterName);
1159 }
1160 karl 1.11.6.1 }
1161 }
1162 }
1163
1164
|
1165 kumpf 1.2 PEGASUS_NAMESPACE_END
|