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/XmlParser.h>
36 #include <Pegasus/Common/Tracer.h>
37 #include <Pegasus/Common/CommonUTF.h>
38 #include <Pegasus/Common/MessageLoader.h>
39 #include <Pegasus/Common/AutoPtr.h>
|
40 mike 1.12 #include <Pegasus/Common/SharedPtr.h>
|
41 rohini.deshpande 1.15 #include <Pegasus/IndicationService/IndicationConstants.h>
|
42 kumpf 1.2
43 #include "WsmConstants.h"
44 #include "WsmReader.h"
45 #include "WsmWriter.h"
46 #include "WsmProcessor.h"
47 #include "WsmRequestDecoder.h"
48
49 PEGASUS_NAMESPACE_BEGIN
50
|
51 mike 1.12 static bool _parseInvokeAction(
52 const String& action,
53 String& className,
54 String& methodName)
55 {
56 // Parse the action as though it is a method invocation. If so, set
57 // className and methodName and return true. Else return false. Invoke
58 // actions have the following form:
59 //
60 // http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/<CLASS>/<METHOD>
61
62 // Expect "http://" prefix.
63
64 CString cstr = action.getCString();
65 const char* p = cstr;
66
67 if (strncmp(p, "http://", 7) != 0)
68 return false;
69
70 p += 7;
71
72 mike 1.12 // Find slash that terminates the host name.
73
74 if (!(p = strchr(p, '/')))
75 return false;
76
77 p++;
78
79 // Expect "wbem/wscim/1/cim-schema/2/" sequence.
80
81 if (strncmp(p, "wbem/wscim/1/cim-schema/2/", 26) != 0)
82 return false;
83
84 p += 26;
85
86 // Get classname:
87
88 char* slash = strchr(const_cast<char*>(p), '/');
89
90 if (!slash)
91 return false;
92
93 mike 1.12 *slash = '\0';
94 className = p;
95 *slash = '/';
96 p = slash + 1;
97
98 // Get methodname:
99
100 methodName = p;
101
102 // If we got this far, then action refers to a method.
103 return true;
104 }
105
|
106 kumpf 1.2 WsmRequestDecoder::WsmRequestDecoder(WsmProcessor* wsmProcessor)
|
107 sahana.prabhakar 1.11 : MessageQueue(PEGASUS_QUEUENAME_WSMREQDECODER),
|
108 kumpf 1.2 _wsmProcessor(wsmProcessor),
109 _serverTerminating(false)
110 {
111 }
112
113 WsmRequestDecoder::~WsmRequestDecoder()
114 {
115 }
116
117 void WsmRequestDecoder::sendResponse(
118 Uint32 queueId,
119 Buffer& message,
120 Boolean httpCloseConnect)
121 {
122 MessageQueue* queue = MessageQueue::lookup(queueId);
123
124 if (queue)
125 {
126 AutoPtr<HTTPMessage> httpMessage(new HTTPMessage(message));
127 httpMessage->setCloseConnect(httpCloseConnect);
128 queue->enqueue(httpMessage.release());
129 kumpf 1.2 }
130 }
131
132 void WsmRequestDecoder::sendHttpError(
133 Uint32 queueId,
134 const String& status,
135 const String& cimError,
136 const String& pegasusError,
137 Boolean httpCloseConnect)
138 {
139 Buffer message;
140 message = WsmWriter::formatHttpErrorRspMessage(
141 status,
142 cimError,
143 pegasusError);
144
145 sendResponse(queueId, message, httpCloseConnect);
146 }
147
148 void WsmRequestDecoder::handleEnqueue(Message* message)
149 {
150 kumpf 1.2 PEGASUS_ASSERT(message);
151 PEGASUS_ASSERT(message->getType() == HTTP_MESSAGE);
152
153 handleHTTPMessage((HTTPMessage*)message);
154
155 delete message;
156 }
157
158 void WsmRequestDecoder::handleEnqueue()
159 {
160 Message* message = dequeue();
161 if (message)
162 handleEnqueue(message);
163 }
164
165 //-----------------------------------------------------------------------------
166 //
167 // From the HTTP/1.1 Specification (RFC 2626):
168 //
169 // Both types of message consist of a start-line, zero or more header fields
170 // (also known as "headers"), an empty line (i.e., a line with nothing
171 kumpf 1.2 // preceding the CRLF) indicating the end of the header fields, and possibly
172 // a message-body.
173 //
174 //-----------------------------------------------------------------------------
175 void WsmRequestDecoder::handleHTTPMessage(HTTPMessage* httpMessage)
176 {
177 PEG_METHOD_ENTER(TRC_WSMSERVER, "WsmRequestDecoder::handleHTTPMessage()");
178
179 // Set the Accept-Language into the thread for this service.
180 // This will allow all code in this thread to get
181 // the languages for the messages returned to the client.
182 Thread::setLanguages(httpMessage->acceptLanguages);
183
184 // Save queueId:
185 Uint32 queueId = httpMessage->queueId;
186
187 // Save userName and authType:
188 String userName;
189 String authType;
190 Boolean httpCloseConnect = httpMessage->getCloseConnect();
191
|
192 marek 1.3 PEG_TRACE((TRC_WSMSERVER, Tracer::LEVEL4,
|
193 kumpf 1.2 "WsmRequestDecoder::handleHTTPMessage()- "
194 "httpMessage->getCloseConnect() returned %d",
195 httpCloseConnect));
196
197 userName = httpMessage->authInfo->getAuthenticatedUser();
198 authType = httpMessage->authInfo->getAuthType();
199
200 // Parse the HTTP message:
201 String startLine;
202 Array<HTTPHeader> headers;
203 char* content;
204 Uint32 contentLength;
205
206 httpMessage->parse(startLine, headers, contentLength);
207
208 // Parse the request line:
209 String methodName;
210 String requestUri;
211 String httpVersion;
212 HttpMethod httpMethod = HTTP_METHOD__POST;
213
214 kumpf 1.2 HTTPMessage::parseRequestLine(
215 startLine, methodName, requestUri, httpVersion);
216
217 // Set HTTP method for the request
218 if (methodName == "M-POST")
219 {
220 httpMethod = HTTP_METHOD_M_POST;
221 }
222
223 // Unsupported methods are caught in the HTTPAuthenticatorDelegator
224 PEGASUS_ASSERT(methodName == "M-POST" || methodName == "POST");
225
226 // Mismatch of method and version is caught in HTTPAuthenticatorDelegator
227 PEGASUS_ASSERT(!((httpMethod == HTTP_METHOD_M_POST) &&
228 (httpVersion == "HTTP/1.0")));
229
230 // Process M-POST and POST messages:
231 if (httpVersion == "HTTP/1.1")
232 {
233 // Validate the presence of a "Host" header. The HTTP/1.1
234 // specification says this in section 14.23 regarding the Host
235 kumpf 1.2 // header field:
236 //
237 // All Internet-based HTTP/1.1 servers MUST respond with a 400 (Bad
238 // Request) status code to any HTTP/1.1 request message which lacks
239 // a Host header field.
240 //
241 // Note: The Host header value is not validated.
242
|
243 kumpf 1.8 const char* hostHeader;
|
244 kumpf 1.2 Boolean hostHeaderFound = HTTPMessage::lookupHeader(
245 headers, "Host", hostHeader, false);
246
247 if (!hostHeaderFound)
248 {
249 MessageLoaderParms parms(
250 "Server.WsmRequestDecoder.MISSING_HOST_HEADER",
251 "HTTP request message lacks a Host header field.");
252 sendHttpError(
253 queueId,
254 HTTP_STATUS_BADREQUEST,
255 "",
256 MessageLoader::getMessage(parms),
257 httpCloseConnect);
258 PEG_METHOD_EXIT();
259 return;
260 }
261 }
262
263 // Calculate the beginning of the content from the message size and
264 // the content length.
265 kumpf 1.2 content = (char*) httpMessage->message.getData() +
266 httpMessage->message.size() - contentLength;
267
|
268 mike 1.12 // Lookup HTTP "User-Agent" header. For example:
269 //
270 // User-Agent: Microsoft WinRM Client
271 //
272 // If it contains "WinRM", then omit the XML processing instruction from
273 // the response (first line of XML response). A typical XML processing
274 // instruction looks like this:
275 //
276 // <?xml version="1.0" encoding="utf-8"?>
277 //
278 // The WinRM user agent should never receive this line.
279
280 Boolean omitXMLProcessingInstruction;
281 {
282 String value;
283
284 if (HTTPMessage::lookupHeader(headers, "User-Agent", value, true) &&
285 value.find("WinRM") != Uint32(-1))
286 {
287 omitXMLProcessingInstruction = true;
288 }
289 mike 1.12 else
290 {
291 omitXMLProcessingInstruction = false;
292 }
293 }
294
|
295 kumpf 1.2 // Validate the "Content-Type" header:
|
296 kumpf 1.8 const char* contentType;
|
297 kumpf 1.2 Boolean contentTypeHeaderFound = HTTPMessage::lookupHeader(
298 headers, "Content-Type", contentType, true);
299 String type;
300 String charset;
301
302 if (!contentTypeHeaderFound ||
303 !HTTPMessage::parseContentTypeHeader(contentType, type, charset) ||
304 (!String::equalNoCase(type, "application/soap+xml") &&
305 !String::equalNoCase(type, "text/xml")))
306 {
307 MessageLoaderParms parms(
308 "Server.WsmRequestDecoder.CONTENTTYPE_SYNTAX_ERROR",
309 "HTTP Content-Type header error.");
310 sendHttpError(
311 queueId,
312 HTTP_STATUS_BADREQUEST,
313 "",
314 MessageLoader::getMessage(parms),
315 httpCloseConnect);
316 PEG_METHOD_EXIT();
317 return;
318 kumpf 1.2 }
319
|
320 mike 1.12 if (String::equalNoCase(charset, "utf-16"))
321 {
322 // Reject utf-16 requests.
323 WsmFault fault(
324 WsmFault::wsman_EncodingLimit,
325 "UTF-16 is not supported; Please use UTF-8",
326 ContentLanguageList(),
327 WSMAN_FAULTDETAIL_CHARACTERSET);
328 _wsmProcessor->sendResponse(new WsmFaultResponse(
329 String::EMPTY, queueId, httpMethod, httpCloseConnect,
330 omitXMLProcessingInstruction, fault));
331 PEG_METHOD_EXIT();
332 return;
333 }
334
|
335 kumpf 1.2 if (!String::equalNoCase(charset, "utf-8"))
336 {
337 // DSP0226 R13.1-5: A service shall emit Responses using the same
338 // encoding as the original request. If the service does not support
339 // the requested encoding or cannot determine the encoding, it should
340 // use UTF-8 encoding to return a wsman:EncodingLimit fault with the
341 // following detail code:
342 // http://schemas.dmtf.org/wbem/wsman/1/wsman/faultDetail/CharacterSet
343
344 WsmFault fault(
345 WsmFault::wsman_EncodingLimit,
346 String::EMPTY,
347 ContentLanguageList(),
348 WSMAN_FAULTDETAIL_CHARACTERSET);
349 _wsmProcessor->sendResponse(new WsmFaultResponse(
|
350 mike 1.12 String::EMPTY, queueId, httpMethod, httpCloseConnect,
351 omitXMLProcessingInstruction, fault));
|
352 kumpf 1.2 PEG_METHOD_EXIT();
353 return;
354 }
355
356 // SoapAction header is optional, but if present, it must match
357 // the content of <wsa:Action>
358 String soapAction;
359 HTTPMessage::lookupHeader(headers, "SOAPAction", soapAction, true);
360
361 // Remove the quotes around the SOAPAction value
362 if ((soapAction.size() > 1) &&
363 (soapAction[0] == '\"') &&
364 (soapAction[soapAction.size()-1] == '\"'))
365 {
366 soapAction = soapAction.subString(1, soapAction.size() - 2);
367 }
368
369 // Validating content falls within UTF8
370 // (required to be compliant with section C12 of Unicode 4.0 spec,
371 // chapter 3.)
372 Uint32 count = 0;
373 kumpf 1.2 while (count < contentLength)
374 {
375 if (!(isUTF8((char*) &content[count])))
376 {
377 MessageLoaderParms parms(
378 "Server.WsmRequestDecoder.INVALID_UTF8_CHARACTER",
379 "Invalid UTF-8 character detected.");
380 sendHttpError(
381 queueId,
382 HTTP_STATUS_BADREQUEST,
383 "request-not-valid",
384 MessageLoader::getMessage(parms),
385 httpCloseConnect);
386
387 PEG_METHOD_EXIT();
388 return;
389 }
390 UTF8_NEXT(content, count);
391 }
392
393 handleWsmMessage(
394 kumpf 1.2 queueId,
395 httpMethod,
396 content,
397 contentLength,
398 soapAction,
399 authType,
400 userName,
401 httpMessage->ipAddress,
402 httpMessage->acceptLanguages,
403 httpMessage->contentLanguages,
|
404 mike 1.12 httpCloseConnect,
405 omitXMLProcessingInstruction);
|
406 kumpf 1.2
407 PEG_METHOD_EXIT();
408 }
409
410 void WsmRequestDecoder::handleWsmMessage(
411 Uint32 queueId,
412 HttpMethod httpMethod,
413 char* content,
414 Uint32 contentLength,
415 String& soapAction,
416 const String& authType,
417 const String& userName,
418 const String& ipAddress,
419 const AcceptLanguageList& httpAcceptLanguages,
420 const ContentLanguageList& httpContentLanguages,
|
421 mike 1.12 Boolean httpCloseConnect,
422 Boolean omitXMLProcessingInstruction)
|
423 kumpf 1.2 {
424 PEG_METHOD_ENTER(TRC_WSMSERVER, "WsmRequestDecoder::handleWsmMessage()");
425
|
426 mike 1.12
|
427 kumpf 1.2 // If CIMOM is shutting down, return "Service Unavailable" response
428 if (_serverTerminating)
429 {
430 MessageLoaderParms parms(
431 "Server.WsmRequestDecoder.CIMSERVER_SHUTTING_DOWN",
432 "CIM Server is shutting down.");
433 sendHttpError(
434 queueId,
435 HTTP_STATUS_SERVICEUNAVAILABLE,
436 String::EMPTY,
437 MessageLoader::getMessage(parms),
438 httpCloseConnect);
439 PEG_METHOD_EXIT();
440 return;
441 }
442
443 WsmReader wsmReader(content);
444 XmlEntry entry;
445 AutoPtr<WsmRequest> request;
|
446 rohini.deshpande 1.15 AutoPtr<WsmRequest> createFilterRequest;
447 AutoPtr<WsmRequest> createSubRequest;
448 AutoPtr<WsmRequest> deleteFilterRequest;
449 AutoPtr<WsmRequest> deleteHandlerRequest;
450 // Whether to include the filter request while processing
451 // Subscribe and Unsubscribe requests.
452 Boolean includeFilter=true;
|
453 kumpf 1.2 String wsaMessageId;
|
454 rohini.deshpande 1.15 String wsaAction;
|
455 kumpf 1.2 // Process <?xml ... >
456 try
457 {
458 // These values are currently unused
459 const char* xmlVersion = 0;
460 const char* xmlEncoding = 0;
461
462 // Note: WinRM does not send an XML declaration in its requests.
463 // This return value is ignored.
464 wsmReader.getXmlDeclaration(xmlVersion, xmlEncoding);
465
466 // Decode the SOAP envelope
467
468 wsmReader.expectStartTag(
469 entry, WsmNamespaces::SOAP_ENVELOPE, "Envelope");
470
471 String wsaFrom;
472 String wsaReplyTo;
473 String wsaFaultTo;
474 Uint32 wsmMaxEnvelopeSize = 0;
475 AcceptLanguageList wsmLocale;
476 kumpf 1.2 Boolean wsmRequestEpr = false;
|
477 rohini.deshpande 1.15 String wseIdentifier;
478 WsmEndpointReference epr;
|
479 kumpf 1.4 Boolean wsmRequestItemCount = false;
|
480 kumpf 1.2
481 try
482 {
483 wsmReader.decodeRequestSoapHeaders(
484 wsaMessageId,
485 epr.address,
486 wsaAction,
487 wsaFrom,
488 wsaReplyTo,
489 wsaFaultTo,
490 epr.resourceUri,
491 *epr.selectorSet,
492 wsmMaxEnvelopeSize,
493 wsmLocale,
|
494 kumpf 1.4 wsmRequestEpr,
|
495 rohini.deshpande 1.15 wsmRequestItemCount,
496 wseIdentifier);
|
497 kumpf 1.2 }
498 catch (XmlException&)
499 {
500 // Do not treat this as an InvalidMessageInformationHeader fault.
501 throw;
502 }
503 catch (Exception& e)
504 {
505 throw WsmFault(
506 WsmFault::wsa_InvalidMessageInformationHeader,
507 e.getMessage(),
508 e.getContentLanguages());
509 }
510
|
511 mike 1.12 // If no "Action" header was found, then this might still be a legal
512 // identify request.
513
514 if (wsaAction.size() == 0 && _isIdentifyRequest(wsmReader))
515 {
516 _sendIdentifyResponse(queueId);
517 return;
518 }
519
|
520 kumpf 1.2 // Set the Locale language into the thread for processing this request.
521 Thread::setLanguages(wsmLocale);
522
523 _checkRequiredHeader("wsa:To", epr.address.size());
524 _checkRequiredHeader("wsa:MessageID", wsaMessageId.size());
525 _checkRequiredHeader("wsa:Action", wsaAction.size());
526
527 if (soapAction.size() && (soapAction != wsaAction))
528 {
529 throw WsmFault(
530 WsmFault::wsa_MessageInformationHeaderRequired,
531 MessageLoaderParms(
532 "WsmServer.WsmRequestDecoder.SOAPACTION_HEADER_MISMATCH",
533 "The HTTP SOAPAction header value \"$0\" does not match "
534 "the wsa:Action value \"$1\".",
535 soapAction,
536 wsaAction));
537 }
538
539 // Note: The wsa:To header is not validated. DSP0226 section 5.3
540 // indicates that this header is primarily useful for routing through
541 kumpf 1.2 // intermediaries. The HTTPAuthenticatorDelegator examines the path
542 // specified in the HTTP start line.
543
544 // DSP0226 R5.3-1: The wsa:To header shall be present in all messages,
545 // whether requests, responses, or events. In the absence of other
546 // requirements, it is recommended that the network address for
547 // resources that require authentication be suffixed by the token
548 // sequence /wsman. If /wsman is used, unauthenticated access should
549 // not be allowed.
550 // (1) <wsa:To> http://123.15.166.67/wsman </wsa:To>
551
552 // DSP0226 R5.3-2: In the absence of other requirements, it is
553 // recommended that the network address for resources that do not
554 // require authentication be suffixed by the token sequence
555 // /wsman-anon. If /wsman-anon is used, authenticated access shall
556 // not be required.
557 // (1) <wsa:To> http://123.15.166.67/wsman-anon </wsa:To>
558
559 if (wsaReplyTo != WSM_ADDRESS_ANONYMOUS)
560 {
561 // DSP0226 R5.4.2-2: A conformant service may require that all
562 kumpf 1.2 // responses be delivered over the same connection on which the
563 // request arrives.
564 throw WsmFault(
565 WsmFault::wsman_UnsupportedFeature,
566 MessageLoaderParms(
567 "WsmServer.WsmRequestDecoder.REPLYTO_ADDRESS_NOT_ANONYMOUS",
568 "Responses may only be delivered over the same connection "
569 "on which the request arrives."),
570 WSMAN_FAULTDETAIL_ADDRESSINGMODE);
571 }
572
573 if (wsaFaultTo.size() && (wsaFaultTo != WSM_ADDRESS_ANONYMOUS))
574 {
575 // DSP0226 R5.4.3-3: A conformant service may require that all
576 // faults be delivered to the client over the same transport or
577 // connection on which the request arrives.
578 throw WsmFault(
579 WsmFault::wsman_UnsupportedFeature,
580 MessageLoaderParms(
581 "WsmServer.WsmRequestDecoder.FAULTTO_ADDRESS_NOT_ANONYMOUS",
582 "Responses may only be delivered over the same connection "
583 kumpf 1.2 "on which the request arrives."),
584 WSMAN_FAULTDETAIL_ADDRESSINGMODE);
585 }
586
587 //
588 // Parse the SOAP Body while decoding each action
589 //
590
|
591 mike 1.12 String className;
592 String methodName;
593
|
594 kumpf 1.2 if (wsaAction == WSM_ACTION_GET)
595 {
596 request.reset(_decodeWSTransferGet(
597 wsmReader,
598 wsaMessageId,
599 epr));
600 }
601 else if (wsaAction == WSM_ACTION_PUT)
602 {
603 request.reset(_decodeWSTransferPut(
604 wsmReader,
605 wsaMessageId,
606 epr));
607 }
608 else if (wsaAction == WSM_ACTION_CREATE)
609 {
610 request.reset(_decodeWSTransferCreate(
611 wsmReader,
612 wsaMessageId,
613 epr));
614 }
615 kumpf 1.2 else if (wsaAction == WSM_ACTION_DELETE)
616 {
617 request.reset(_decodeWSTransferDelete(
618 wsmReader,
619 wsaMessageId,
620 epr));
621 }
|
622 kumpf 1.4 else if (wsaAction == WSM_ACTION_ENUMERATE)
623 {
624 request.reset(_decodeWSEnumerationEnumerate(
625 wsmReader,
626 wsaMessageId,
627 epr,
628 wsmRequestItemCount));
629 }
630 else if (wsaAction == WSM_ACTION_PULL)
631 {
632 request.reset(_decodeWSEnumerationPull(
633 wsmReader,
634 wsaMessageId,
635 epr,
636 wsmRequestItemCount));
637 }
638 else if (wsaAction == WSM_ACTION_RELEASE)
639 {
640 request.reset(_decodeWSEnumerationRelease(
641 wsmReader,
642 wsaMessageId,
643 kumpf 1.4 epr));
644 }
|
645 mike 1.12 else if (_parseInvokeAction(wsaAction, className, methodName))
646 {
647 request.reset(_decodeWSInvoke(
648 wsmReader,
649 wsaMessageId,
650 epr,
651 className,
652 methodName));
653 }
|
654 rohini.deshpande 1.15 else if(wsaAction == WSM_ACTION_WSMAN_SUBSCRIBE)
655 {
656 request.reset(_decodeWSSubscriptionRequest(
657 wsmReader,
658 wsaMessageId,
659 epr,
660 createFilterRequest,
661 createSubRequest,
662 includeFilter));
663 }
664 else if(wsaAction == WSM_ACTION_WSMAN_UNSUBSCRIBE)
665 {
666 request.reset(_decodeWSUnsubscribeRequest(
667 wsmReader,
668 wsaMessageId,
669 epr,
670 wseIdentifier,
671 includeFilter,
672 deleteFilterRequest,
673 deleteHandlerRequest));
674 }
675 rohini.deshpande 1.15 else if(wsaAction == WSM_ACTION_SUBSCRIBE_RENEW)
676 {
677 throw WsmFault(
678 WsmFault::wse_UnableToRenew,
679 MessageLoaderParms(
680 "WsmServer.WsmRequestDecoder.UNABLE_TO_RENEW",
681 "The subscription could not be renewed."));
682 }
|
683 kumpf 1.2 else
684 {
685 throw WsmFault(
686 WsmFault::wsa_ActionNotSupported,
687 MessageLoaderParms(
688 "WsmServer.WsmRequestDecoder.ACTION_NOT_SUPPORTED",
689 "The wsa:Action value \"$0\" is not supported.",
690 wsaAction));
691 }
692
693 wsmReader.expectEndTag(WsmNamespaces::SOAP_ENVELOPE, "Envelope");
694
695 request->authType = authType;
696 request->userName = userName;
697 request->ipAddress = ipAddress;
698 request->httpMethod = httpMethod;
699 // Note: The HTTP Accept-Languages header is ignored
700 request->acceptLanguages = wsmLocale;
701 request->contentLanguages = httpContentLanguages;
702 request->httpCloseConnect = httpCloseConnect;
|
703 mike 1.12 request->omitXMLProcessingInstruction = omitXMLProcessingInstruction;
|
704 kumpf 1.2 request->queueId = queueId;
705 request->requestEpr = wsmRequestEpr;
706 request->maxEnvelopeSize = wsmMaxEnvelopeSize;
707 }
708 catch (WsmFault& fault)
709 {
710 _wsmProcessor->sendResponse(new WsmFaultResponse(
|
711 mike 1.12 wsaMessageId, queueId, httpMethod, httpCloseConnect,
712 omitXMLProcessingInstruction, fault));
|
713 kumpf 1.2 PEG_METHOD_EXIT();
714 return;
715 }
716 catch (SoapNotUnderstoodFault& fault)
717 {
718 _wsmProcessor->sendResponse(new SoapFaultResponse(
|
719 mike 1.12 wsaMessageId, queueId, httpMethod, httpCloseConnect,
720 omitXMLProcessingInstruction, fault));
|
721 kumpf 1.2 PEG_METHOD_EXIT();
722 return;
723 }
724 catch (XmlException& e)
725 {
726 WsmFault fault(
727 WsmFault::wsman_SchemaValidationError,
728 e.getMessage(),
729 e.getContentLanguages());
730 _wsmProcessor->sendResponse(new WsmFaultResponse(
|
731 mike 1.12 wsaMessageId, queueId, httpMethod, httpCloseConnect,
732 omitXMLProcessingInstruction, fault));
|
733 kumpf 1.2 PEG_METHOD_EXIT();
734 return;
735 }
|
736 marek 1.16 catch (TooManyElementsException& e)
737 {
738 WsmFault fault(
739 WsmFault::wsman_EncodingLimit,
740 e.getMessage(),
741 e.getContentLanguages(),
|
742 marek 1.17 WSMAN_FAULTDETAIL_OPTION_LIMIT);
|
743 marek 1.16 _wsmProcessor->sendResponse(new WsmFaultResponse(
744 wsaMessageId, queueId, httpMethod, httpCloseConnect,
745 omitXMLProcessingInstruction, fault));
746 PEG_METHOD_EXIT();
747 return;
748 }
|
749 kumpf 1.2 catch (Exception& e)
750 {
751 WsmFault fault(
752 WsmFault::wsman_InternalError,
753 e.getMessage(),
754 e.getContentLanguages());
755 _wsmProcessor->sendResponse(new WsmFaultResponse(
|
756 mike 1.12 wsaMessageId, queueId, httpMethod, httpCloseConnect,
757 omitXMLProcessingInstruction, fault));
|
758 kumpf 1.2 PEG_METHOD_EXIT();
759 return;
760 }
761 catch (const PEGASUS_STD(exception)& e)
762 {
763 WsmFault fault(WsmFault::wsman_InternalError, e.what());
764 _wsmProcessor->sendResponse(new WsmFaultResponse(
|
765 mike 1.12 wsaMessageId, queueId, httpMethod, httpCloseConnect,
766 omitXMLProcessingInstruction, fault));
|
767 kumpf 1.2 PEG_METHOD_EXIT();
768 return;
769 }
770 catch (...)
771 {
772 WsmFault fault(WsmFault::wsman_InternalError);
773 _wsmProcessor->sendResponse(new WsmFaultResponse(
|
774 mike 1.12 wsaMessageId, queueId, httpMethod, httpCloseConnect,
775 omitXMLProcessingInstruction, fault));
|
776 kumpf 1.2 PEG_METHOD_EXIT();
777 return;
778 }
|
779 rohini.deshpande 1.15 if(wsaAction == WSM_ACTION_WSMAN_SUBSCRIBE)
780 {
781 // If a filter has to be created during subscription,
782 // add the filter request.
783 if(includeFilter)
784 {
785 createFilterRequest.get()->copyRequestProperties(request);
786 _wsmProcessor->addReqToSubContext(createFilterRequest.release(),
787 true);
788 }
789 createSubRequest.get()->copyRequestProperties(request);
790 _wsmProcessor->addReqToSubContext(request.get(), true);
791 _wsmProcessor->addReqToSubContext(createSubRequest.release(), true);
792 }
793 else if(wsaAction == WSM_ACTION_WSMAN_UNSUBSCRIBE)
794 {
795 // If the filter has to be deleted during unsubscribe,
796 // add the filter request.
797 if(includeFilter)
798 {
799 deleteFilterRequest.get()->copyRequestProperties(request);
800 rohini.deshpande 1.15 _wsmProcessor->addReqToSubContext(deleteFilterRequest.release(),
801 false);
802 }
803 deleteHandlerRequest.get()->copyRequestProperties(request);
804 _wsmProcessor->addReqToSubContext(deleteHandlerRequest.release(),
805 false);
806 }
|
807 kumpf 1.2 _wsmProcessor->handleRequest(request.release());
808
809 PEG_METHOD_EXIT();
810 }
811
812 void WsmRequestDecoder::_checkRequiredHeader(
813 const char* headerName,
814 Boolean headerSpecified)
815 {
816 if (!headerSpecified)
817 {
818 throw WsmFault(
819 WsmFault::wsa_MessageInformationHeaderRequired,
820 MessageLoaderParms(
821 "WsmServer.WsmRequestDecoder.MISSING_HEADER",
822 "Required SOAP header \"$0\" was not specified.",
823 headerName));
824 }
825 }
826
|
827 kumpf 1.4 void WsmRequestDecoder::_checkNoSelectorsEPR(const WsmEndpointReference& epr)
828 {
|
829 kumpf 1.9 // Make sure that at most __cimnamespace selector is present
830 if (epr.selectorSet->selectors.size())
|
831 kumpf 1.4 {
832 if (epr.selectorSet->selectors.size() > 1 ||
833 epr.selectorSet->selectors[0].type != WsmSelector::VALUE ||
834 epr.selectorSet->selectors[0].name != "__cimnamespace")
835 {
836 throw WsmFault(
837 WsmFault::wsman_InvalidSelectors,
838 MessageLoaderParms(
839 "WsmServer.WsmRequestDecoder.UNEXPECTED_SELECTORS",
|
840 kumpf 1.9 "The operation allows only the __cimnamespace selector to "
|
841 kumpf 1.4 "be present."),
842 WSMAN_FAULTDETAIL_UNEXPECTEDSELECTORS);
843 }
844 }
845 }
846
847 WxfGetRequest* WsmRequestDecoder::_decodeWSTransferGet(
|
848 kumpf 1.2 WsmReader& wsmReader,
849 const String& messageId,
850 const WsmEndpointReference& epr)
851 {
852 _checkRequiredHeader("wsman:ResourceURI", epr.resourceUri.size());
853
854 XmlEntry entry;
855 wsmReader.expectStartOrEmptyTag(
856 entry, WsmNamespaces::SOAP_ENVELOPE, "Body");
857 if (entry.type != XmlEntry::EMPTY_TAG)
858 {
859 wsmReader.expectEndTag(WsmNamespaces::SOAP_ENVELOPE, "Body");
860 }
861
|
862 kumpf 1.4 return new WxfGetRequest(messageId, epr);
|
863 kumpf 1.2 }
864
|
865 kumpf 1.4 WxfPutRequest* WsmRequestDecoder::_decodeWSTransferPut(
|
866 kumpf 1.2 WsmReader& wsmReader,
867 const String& messageId,
868 const WsmEndpointReference& epr)
869 {
870 _checkRequiredHeader("wsman:ResourceURI", epr.resourceUri.size());
871
872 XmlEntry entry;
873 wsmReader.expectStartTag(entry, WsmNamespaces::SOAP_ENVELOPE, "Body");
874
875 // The soap body must contain an XML representation of the updated instance
876 WsmInstance instance;
877 wsmReader.getInstanceElement(instance);
878
879 wsmReader.expectEndTag(WsmNamespaces::SOAP_ENVELOPE, "Body");
880
|
881 kumpf 1.4 return new WxfPutRequest(messageId, epr, instance);
|
882 kumpf 1.2 }
883
|
884 kumpf 1.4 WxfCreateRequest* WsmRequestDecoder::_decodeWSTransferCreate(
|
885 kumpf 1.2 WsmReader& wsmReader,
886 const String& messageId,
887 const WsmEndpointReference& epr)
888 {
889 _checkRequiredHeader("wsman:ResourceURI", epr.resourceUri.size());
|
890 kumpf 1.4 _checkNoSelectorsEPR(epr);
|
891 kumpf 1.2
892 XmlEntry entry;
893 wsmReader.expectStartTag(entry, WsmNamespaces::SOAP_ENVELOPE, "Body");
894
895 // The soap body must contain an XML representation of the new instance
896 WsmInstance instance;
897 wsmReader.getInstanceElement(instance);
898
899 wsmReader.expectEndTag(WsmNamespaces::SOAP_ENVELOPE, "Body");
900
|
901 kumpf 1.4 return new WxfCreateRequest(messageId, epr, instance);
|
902 kumpf 1.2 }
903
|
904 kumpf 1.4 WxfDeleteRequest* WsmRequestDecoder::_decodeWSTransferDelete(
|
905 kumpf 1.2 WsmReader& wsmReader,
906 const String& messageId,
907 const WsmEndpointReference& epr)
908 {
909 _checkRequiredHeader("wsman:ResourceURI", epr.resourceUri.size());
910
911 XmlEntry entry;
912 wsmReader.expectStartOrEmptyTag(
913 entry, WsmNamespaces::SOAP_ENVELOPE, "Body");
914 if (entry.type != XmlEntry::EMPTY_TAG)
915 {
916 wsmReader.expectEndTag(WsmNamespaces::SOAP_ENVELOPE, "Body");
917 }
918
|
919 kumpf 1.4 return new WxfDeleteRequest(messageId, epr);
920 }
921
922 WsenEnumerateRequest* WsmRequestDecoder::_decodeWSEnumerationEnumerate(
923 WsmReader& wsmReader,
924 const String& messageId,
925 const WsmEndpointReference& epr,
926 Boolean requestItemCount)
927 {
|
928 karl 1.13 PEG_METHOD_ENTER(TRC_WSMSERVER,
929 "WsmRequestDecoder::_decodeWSEnumerationEnumerate()");
930
|
931 kumpf 1.4 _checkRequiredHeader("wsman:ResourceURI", epr.resourceUri.size());
932 _checkNoSelectorsEPR(epr);
933
934 String expiration;
935 WsmbPolymorphismMode polymorphismMode = WSMB_PM_UNKNOWN;
936 WsenEnumerationMode enumerationMode = WSEN_EM_UNKNOWN;
937 Boolean optimized = false;
938 Uint32 maxElements = 0;
|
939 karl 1.13 WsmFilter wsmFilter;
|
940 kumpf 1.4
941 XmlEntry entry;
942 wsmReader.expectStartOrEmptyTag(
943 entry, WsmNamespaces::SOAP_ENVELOPE, "Body");
944 if (entry.type != XmlEntry::EMPTY_TAG)
945 {
|
946 kumpf 1.7 wsmReader.decodeEnumerateBody(expiration, polymorphismMode,
|
947 karl 1.13 enumerationMode, optimized, maxElements, wsmFilter);
948
|
949 kumpf 1.4 wsmReader.expectEndTag(WsmNamespaces::SOAP_ENVELOPE, "Body");
950 }
951
952 // If PolymorphismMode header is not specified, set it to default
953 if (polymorphismMode == WSMB_PM_UNKNOWN)
954 {
|
955 kumpf 1.7 // DSP0227, R8.1-4: A service MAY optionally support the
956 // wsmb:PolymorphismMode modifier element with a value of
957 // IncludeSubClassProperties, which returns instances of the base
958 // class and derived classes using the actual classs GED and XSD
|
959 kumpf 1.4 // type. This is the same as not specifying the polymorphism mode.
960 polymorphismMode = WSMB_PM_INCLUDE_SUBCLASS_PROPERTIES;
961 }
962 else
963 {
|
964 kumpf 1.7 // DSP0227, R8.1-6: The service SHOULD also return a
965 // wsmb:PolymorphismModeNotSupported fault for requests using the
966 // all classes ResourceURI if the PolymorphismMode is present and
|
967 kumpf 1.4 // does not equal IncludeSubClassProperties.
|
968 mike 1.12
969 CString tmp(epr.resourceUri.getCString());
970 const char* suffix = WsmUtils::skipHostUri(tmp);
971
972 if (strcmp(suffix, WSM_RESOURCEURI_ALLCLASSES_SUFFIX) == 0 &&
|
973 kumpf 1.4 polymorphismMode != WSMB_PM_INCLUDE_SUBCLASS_PROPERTIES)
974 {
|
975 karl 1.13 PEG_METHOD_EXIT();
|
976 kumpf 1.4 throw WsmFault(
977 WsmFault::wsmb_PolymorphismModeNotSupported,
978 MessageLoaderParms(
979 "WsmServer.WsmReader.ENUMERATE_"
980 "POLYMORPHISM_INCLUDE_SUBCLASS",
981 "\"All classes\" resource URI requires "
982 "IncludeSubClassProperties polymorphism mode."));
983 }
984 }
985
986 // If EnumerationMode header is not specified, set it to default
987 if (enumerationMode == WSEN_EM_UNKNOWN)
988 {
989 enumerationMode = WSEN_EM_OBJECT;
990 }
991
992 // If optimized enumeration is requested but maxElements is not specified,
993 // set it to default value of 1.
994 if (optimized && maxElements == 0)
995 {
996 maxElements = 1;
997 kumpf 1.4 }
998
|
999 karl 1.14 PEG_METHOD_EXIT();
1000
|
1001 kumpf 1.4 return new WsenEnumerateRequest(
|
1002 kumpf 1.7 messageId,
1003 epr,
1004 expiration,
1005 requestItemCount,
1006 optimized,
1007 maxElements,
1008 enumerationMode,
|
1009 mike 1.12 polymorphismMode,
|
1010 karl 1.13 wsmFilter);
|
1011 kumpf 1.4 }
1012
1013 WsenPullRequest* WsmRequestDecoder::_decodeWSEnumerationPull(
1014 WsmReader& wsmReader,
1015 const String& messageId,
1016 const WsmEndpointReference& epr,
1017 Boolean requestItemCount)
1018 {
1019 _checkRequiredHeader("wsman:ResourceURI", epr.resourceUri.size());
1020 _checkNoSelectorsEPR(epr);
1021
|
1022 kumpf 1.10 Uint64 enumerationContext = 0;
|
1023 kumpf 1.4 String maxTime;
1024 Uint32 maxElements = 0;
1025 Uint32 maxCharacters = 0;
1026
1027 XmlEntry entry;
|
1028 kumpf 1.10 wsmReader.expectStartTag(entry, WsmNamespaces::SOAP_ENVELOPE, "Body");
1029 wsmReader.decodePullBody(
1030 enumerationContext, maxTime, maxElements, maxCharacters);
1031 wsmReader.expectEndTag(WsmNamespaces::SOAP_ENVELOPE, "Body");
|
1032 kumpf 1.4
1033 // If maxElements is not specified, set it to default value of 1.
1034 if (maxElements == 0)
1035 {
1036 maxElements = 1;
1037 }
1038
1039 return new WsenPullRequest(
|
1040 kumpf 1.7 messageId,
1041 epr,
|
1042 kumpf 1.4 enumerationContext,
1043 maxTime,
|
1044 kumpf 1.7 requestItemCount,
|
1045 kumpf 1.4 maxElements,
1046 maxCharacters);
1047 }
1048
1049 WsenReleaseRequest* WsmRequestDecoder::_decodeWSEnumerationRelease(
1050 WsmReader& wsmReader,
1051 const String& messageId,
1052 const WsmEndpointReference& epr)
1053 {
1054 _checkRequiredHeader("wsman:ResourceURI", epr.resourceUri.size());
1055 _checkNoSelectorsEPR(epr);
1056
|
1057 kumpf 1.10 Uint64 enumerationContext = 0;
|
1058 kumpf 1.4
1059 XmlEntry entry;
|
1060 kumpf 1.10 wsmReader.expectStartTag(entry, WsmNamespaces::SOAP_ENVELOPE, "Body");
1061 wsmReader.decodeReleaseBody(enumerationContext);
1062 wsmReader.expectEndTag(WsmNamespaces::SOAP_ENVELOPE, "Body");
|
1063 kumpf 1.4
1064 return new WsenReleaseRequest(
|
1065 kumpf 1.7 messageId,
1066 epr,
|
1067 kumpf 1.4 enumerationContext);
|
1068 kumpf 1.2 }
1069
|
1070 mike 1.12 WsmRequest* WsmRequestDecoder::_decodeWSInvoke(
1071 WsmReader& wsmReader,
1072 const String& messageId,
1073 const WsmEndpointReference& epr,
1074 const String& className,
1075 const String& methodName)
1076 {
1077 XmlEntry entry;
1078
1079 //
1080 // Parse the <s:Body> element. Here is an example:
1081 //
1082 // <s:Body>
1083 // <p:Foo_INPUT xmlns:p=
1084 // "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/SomeClass">
1085 // <p:Arg1>
1086 // 1234
1087 // </p:Arg1>
1088 // <p:Arg2>
1089 // Hello!
1090 // </p:Arg2>
1091 mike 1.12 // </p:Foo_INPUT>
1092 // </s:Body>
1093 //
1094
1095 WsmInstance instance;
1096 wsmReader.expectStartTag(entry, WsmNamespaces::SOAP_ENVELOPE, "Body");
1097 wsmReader.decodeInvokeInputBody(className, methodName, instance);
1098 wsmReader.expectEndTag(WsmNamespaces::SOAP_ENVELOPE, "Body");
1099
1100 return new WsInvokeRequest(messageId, epr, className, methodName, instance);
1101 }
1102
|
1103 rohini.deshpande 1.15 WsmRequest* WsmRequestDecoder::_decodeWSUnsubscribeRequest(
1104 WsmReader& wsmReader,
1105 const String& messageId,
1106 WsmEndpointReference& epr,
1107 const String& identifier,
1108 Boolean & includeFilter,
1109 AutoPtr<WsmRequest> &deleteFilterRequest,
1110 AutoPtr<WsmRequest> &deleteHandlerRequest)
1111 {
1112 PEG_METHOD_ENTER(TRC_WSMSERVER,
1113 "WsmRequestDecoder::_decodeWSUnsubscribeRequest()");
1114 _checkRequiredHeader("wse:Identifier", identifier.size());
1115 XmlEntry entry;
1116 wsmReader.expectStartOrEmptyTag(
1117 entry, WsmNamespaces::SOAP_ENVELOPE, "Body");
1118 if (entry.type != XmlEntry::EMPTY_TAG)
1119 {
1120 wsmReader.expectStartOrEmptyTag(
1121 entry, WsmNamespaces::WS_EVENTING, "Unsubscribe");
1122 wsmReader.expectEndTag(WsmNamespaces::SOAP_ENVELOPE, "Body");
1123 }
1124 rohini.deshpande 1.15
1125 WsmEndpointReference filterEPR;
1126 String filterName;
1127 // If existing filter is used in Subscription, do not delete the filter
1128 if(_wsmProcessor->isSubCreatedWithExistingFilter(identifier, filterName))
1129 {
1130 getFilterOrHandlerEPR(filterEPR,
1131 epr.address,
1132 filterName,
1133 PEGASUS_CLASSNAME_INDFILTER.getString());
1134 includeFilter = false;
1135 }
1136 else
1137 {
1138 getFilterOrHandlerEPR(filterEPR,
1139 epr.address,
1140 identifier,
1141 PEGASUS_CLASSNAME_INDFILTER.getString());
1142 }
1143
1144 WsmEndpointReference handlerEPR;
1145 rohini.deshpande 1.15 getFilterOrHandlerEPR(handlerEPR,
1146 epr.address,
1147 identifier, PEGASUS_CLASSNAME_INDHANDLER_WSMAN.getString());
1148
1149 WsmEndpointReference subscriptionEPR;
1150 subscriptionEPR.address = epr.address;
1151 subscriptionEPR.resourceUri = String(WSM_RESOURCEURI_CIMSCHEMAV2) +
1152 "/" + PEGASUS_CLASSNAME_INDSUBSCRIPTION.getString();
1153 subscriptionEPR.selectorSet->selectors.append(WsmSelector
|
1154 dl.meetei 1.18 (String(PEGASUS_WS_CIMNAMESPACE),
|
1155 rohini.deshpande 1.15 PEGASUS_NAMESPACENAME_INTEROP.getString()));
1156 subscriptionEPR.selectorSet->selectors.append(WsmSelector
1157 (PEGASUS_PROPERTYNAME_FILTER.getString(), filterEPR));
1158 subscriptionEPR.selectorSet->selectors.append(WsmSelector
1159 (PEGASUS_PROPERTYNAME_HANDLER.getString(), handlerEPR));
1160 // DSP0227:R10.6-4 :If a service created CIM indication-related instances
1161 // as described in 10.5, then the service shall delete those instances
1162 // when the subscription is canceled for any reason.
1163 if(includeFilter)
1164 {
1165 deleteFilterRequest.reset(new WxfSubDeleteRequest( messageId,
1166 filterEPR,
1167 PEGASUS_CLASSNAME_INDFILTER.getString()));
1168 }
1169 deleteHandlerRequest.reset(new WxfSubDeleteRequest( messageId,
1170 handlerEPR,
1171 PEGASUS_CLASSNAME_INDHANDLER_WSMAN.getString()));
1172 PEG_METHOD_EXIT();
1173 return new WxfSubDeleteRequest(messageId,
1174 subscriptionEPR,
1175 PEGASUS_CLASSNAME_INDSUBSCRIPTION.getString());
1176 rohini.deshpande 1.15 }
1177
1178 WsmRequest* WsmRequestDecoder::_decodeWSSubscriptionRequest(
1179 WsmReader& wsmReader,
1180 const String& messageId,
1181 WsmEndpointReference& epr,
1182 AutoPtr<WsmRequest> &createFilterRequest,
1183 AutoPtr<WsmRequest> &createSubRequest,
1184 Boolean &includeFilter)
1185 {
1186 PEG_METHOD_ENTER(TRC_WSMSERVER,
1187 "WsmRequestDecoder::_decodeWSSubscriptionRequest()");
1188 _checkRequiredHeader("wsman:ResourceURI", epr.resourceUri.size());
1189
1190 String filterName;
1191 String deliveryMode;
1192 String notifyTo;
1193 String subExpiration;
1194 XmlEntry entry;
1195 WsmFilter wsmFilter;
1196 // Remove the "uuid:" from messageId
1197 rohini.deshpande 1.15 String msgId = messageId.subString(PEGASUS_WS_UUID_LENGTH);
1198
1199 wsmReader.expectStartOrEmptyTag(
1200 entry, WsmNamespaces::SOAP_ENVELOPE, "Body");
1201 if (entry.type != XmlEntry::EMPTY_TAG)
1202 {
1203 wsmReader.decodeSubscribeBody(
1204 deliveryMode,
1205 notifyTo,
1206 subExpiration,
1207 wsmFilter);
1208 wsmReader.expectEndTag(WsmNamespaces::SOAP_ENVELOPE, "Body");
1209 }
1210
1211 // DSP0227: 10.2.1.1 - Subscribing to CIM server.
1212 // Resource URI is all classes
1213 if( epr.resourceUri == WSM_RESOURCEURI_ALLCLASSES )
1214 {
1215 if(!wsmFilter.WQLFilter.query.size())
1216 {
1217 MessageLoaderParms parms(
1218 rohini.deshpande 1.15 "WsmServer.WsmRequestDecoder.INVALID_MESSAGE ",
1219 "The request message has unknown or invalid content"
1220 " and cannot be processed. ");
1221 throw WsmFault( WsmFault::wse_InvalidMessage, parms);
1222 }
1223 }
1224 //DSP0227: 10.2.1.3 Subscribing to an existing filter
1225 //Resource URI specifies existing filter
1226 else if ( epr.resourceUri == WSM_RESOURCEURI_INDICATION_FILTER)
1227 {
1228 // DSP0227:R10.2.2-2 - If a service supports filtering using an
1229 // existing filter expression, the service message shall return the
1230 // wsman:InvalidParameter fault if the wse:Subscribe request includes
1231 // a filter expression
1232 if(wsmFilter.WQLFilter.query.size())
1233 {
1234 throw WsmFault(
1235 WsmFault::wsman_InvalidParameter,
1236 MessageLoaderParms(
1237 "WsmServer.WsmRequestDecoder.INVALID_PARAMETER ",
1238 "An operation parameter is not valid."));
1239 rohini.deshpande 1.15 }
1240 else
1241 {
1242 for (Uint32 i = 0; i < epr.selectorSet->selectors.size(); i++)
1243 {
1244 if(String::equalNoCase(epr.selectorSet->selectors[i].name,
1245 "Name"))
1246 {
1247 filterName = epr.selectorSet->selectors[i].value;
1248 includeFilter = false;
1249 break;
1250 }
1251 }
1252 }
1253 }
1254 //DSP0227: 10.2.1.2 Subscribing to an indication class
1255 else
1256 {
1257 CIMName className = WsmToCimRequestMapper::
1258 convertResourceUriToClassName(epr.resourceUri);
1259 if(wsmFilter.filterDialect == WsmFilter::NONE)
1260 rohini.deshpande 1.15 {
1261 //If no filter query is specified, form a filter query.
1262 wsmFilter.filterDialect = WsmFilter::WQL;
1263 String query("SELECT * FROM ");
1264 query.append(className.getString());
1265 wsmFilter.WQLFilter.query = query;
1266 try
1267 {
1268 wsmFilter.WQLFilter.selectStatement.reset(
1269 new WQLSelectStatement);
1270 WQLParser::parse(wsmFilter.WQLFilter.query,
1271 *wsmFilter.WQLFilter.selectStatement.get());
1272 }
1273 catch (ParseError& e)
1274 {
1275 MessageLoaderParms parms(
1276 "WsmServer.WsmRequestDecoder."
1277 "INVALID_FILTER_QUERY_EXPRESSION",
1278 "Invalid filter query expression: \"$0\".",
1279 entry.text);
1280 throw WsmFault(WsmFault::wsen_CannotProcessFilter, parms);
1281 rohini.deshpande 1.15 }
1282 wsmFilter.WQLFilter.queryLanguage = "WQL";
1283 }
1284 else if(wsmFilter.filterDialect == WsmFilter::WQL)
1285 {
1286 // DSP0227 - R8.1-9 : If class name in resource URI does not
1287 // match the class name in the filter query, then throw
1288 // wse:EventSourceUnableToProcess fault.
1289 WQLSelectStatement *st = wsmFilter.WQLFilter.selectStatement.get();
1290 if(className.getString() != st->getClassName().getString())
1291 {
1292 throw WsmFault(
1293 WsmFault::wse_EventSourceUnableToProcess,
1294 MessageLoaderParms(
1295 "WsmServer.WsmRequestDecoder.UNABLE_TO_PROCESS ",
1296 "The event source cannot process the subscription."));
1297 }
1298 }
1299 }
1300 WsmEndpointReference filterEPR;
1301 const String creClassName(PEGASUS_PROPERTYNAME_CREATIONCLASSNAME.
1302 rohini.deshpande 1.15 getString());
1303 const String propertyName(PEGASUS_PROPERTYNAME_NAME.getString());
1304 WsmValue sysNameValue(System::getFullyQualifiedHostName());
1305 WsmProperty sysNameProp("SystemName", sysNameValue);
1306 WsmValue sysCreClassNameValue(System::getSystemCreationClassName ());
1307 WsmProperty sysCreClassNameProp(
1308 "SystemCreationClassName",
1309 sysCreClassNameValue);
1310
1311 //Creating filterInstance and forming createInstace request for filter.
1312 if ( includeFilter == true)
1313 {
1314 WsmInstance filterInstance;
1315 filterInstance.setClassName(PEGASUS_CLASSNAME_INDFILTER.getString());
1316
1317 filterInstance.addProperty(sysCreClassNameProp);
1318 filterInstance.addProperty(sysNameProp);
1319
1320 WsmValue filCreClassNameValue(PEGASUS_CLASSNAME_INDFILTER.getString());
1321 WsmProperty filCreClassNameProp(creClassName, filCreClassNameValue);
1322 filterInstance.addProperty(filCreClassNameProp);
1323 rohini.deshpande 1.15
1324 WsmValue filNameValue(msgId);
1325 WsmProperty filNameProp(propertyName, filNameValue);
1326 filterInstance.addProperty(filNameProp);
1327 filterName = msgId;
1328
1329 WsmValue queryValue(wsmFilter.WQLFilter.query);
1330 WsmProperty queryProp(PEGASUS_PROPERTYNAME_QUERY.getString(),
1331 queryValue);
1332 filterInstance.addProperty(queryProp);
1333
1334 WsmValue queryLangValue(wsmFilter.WQLFilter.queryLanguage);
1335 WsmProperty queryLangProp(PEGASUS_PROPERTYNAME_QUERYLANGUAGE.
1336 getString(),
1337 queryLangValue);
1338 filterInstance.addProperty(queryLangProp);
1339
1340 WsmValue srcNamespaceValue(( const char *)epr.getNamespace().
1341 getCString() );
1342 WsmProperty srcNamespaceProp("SourceNamespaces", srcNamespaceValue);
1343 filterInstance.addProperty(srcNamespaceProp);
1344 rohini.deshpande 1.15 getFilterOrHandlerEPR(filterEPR,
1345 epr.address,
1346 filterName,
1347 PEGASUS_CLASSNAME_INDFILTER.getString());
1348 createFilterRequest.reset(new WxfSubCreateRequest(messageId,
1349 filterEPR,
1350 filterInstance));
1351 }
1352 else
1353 {
1354 getFilterOrHandlerEPR(filterEPR,
1355 epr.address,
1356 filterName,
1357 PEGASUS_CLASSNAME_INDFILTER.getString());
1358 }
1359
1360 //Creating Handler Instance.
1361 WsmInstance handlerInstance;
1362 handlerInstance.setClassName(PEGASUS_CLASSNAME_INDHANDLER_WSMAN.
1363 getString());
1364 handlerInstance.addProperty(sysCreClassNameProp);
1365 rohini.deshpande 1.15 handlerInstance.addProperty(sysNameProp);
1366 WsmValue hanCreClassNameValue(PEGASUS_CLASSNAME_INDHANDLER_WSMAN.
1367 getString());
1368 WsmProperty hanCreClassNameProp(creClassName, hanCreClassNameValue);
1369 handlerInstance.addProperty(hanCreClassNameProp);
1370
1371 WsmValue handlerNameValue(msgId);
1372 WsmProperty handlerNameProp(propertyName,handlerNameValue);
1373 handlerInstance.addProperty(handlerNameProp);
1374
1375 WsmValue deliveryModeValue(deliveryMode);
1376 WsmProperty deliveryModeProp(
1377 PEGASUS_PROPERTYNAME_WSM_DELIVERY_MODE.getString(),
1378 deliveryModeValue);
1379 handlerInstance.addProperty(deliveryModeProp);
1380
1381 WsmValue destValue(notifyTo);
1382 WsmProperty destProp(PEGASUS_PROPERTYNAME_LSTNRDST_DESTINATION.getString(),
1383 destValue);
1384 handlerInstance.addProperty(destProp);
1385
1386 rohini.deshpande 1.15 WsmEndpointReference handlerEPR;
1387 getFilterOrHandlerEPR(handlerEPR,
1388 epr.address,
1389 msgId,
1390 PEGASUS_CLASSNAME_INDHANDLER_WSMAN.getString());
1391
1392 //Creating Subscription Instance.
1393 WsmInstance subscriptionInstance;
1394 subscriptionInstance.setClassName(
1395 PEGASUS_CLASSNAME_INDSUBSCRIPTION.getString());
1396
1397 WsmValue subCreClassNameValue(
1398 PEGASUS_CLASSNAME_INDSUBSCRIPTION.getString());
1399 WsmProperty subCreClassNameProp(creClassName, subCreClassNameValue);
1400
1401 WsmValue subInfoVal(msgId);
1402 WsmProperty subscriptionInfo(_PROPERTY_SUBSCRIPTION_INFO.getString(),
1403 subInfoVal);
1404 subscriptionInstance.addProperty(subscriptionInfo);
1405
1406 WsmValue subFilterValue(filterEPR);
1407 rohini.deshpande 1.15 WsmProperty subFilterProp(PEGASUS_PROPERTYNAME_FILTER.getString(),
1408 subFilterValue);
1409 subscriptionInstance.addProperty(subFilterProp);
1410
1411 WsmValue subHandlerValue(handlerEPR);
1412 WsmProperty subHandlerProp(PEGASUS_PROPERTYNAME_HANDLER.getString(),
1413 subHandlerValue);
1414 subscriptionInstance.addProperty(subHandlerProp);
1415
1416 if(subExpiration.size())
1417 {
1418 WsmValue subDurationval(subExpiration);
1419 WsmProperty subDurationProp(PEGASUS_WS_SUB_DURATION,
1420 subDurationval);
1421 subscriptionInstance.addProperty(subDurationProp);
1422 }
1423
1424 WsmEndpointReference subscriptionEPR;
1425 subscriptionEPR.address = epr.address;
1426 subscriptionEPR.resourceUri = String(WSM_RESOURCEURI_CIMSCHEMAV2) +
1427 "/" + PEGASUS_CLASSNAME_INDSUBSCRIPTION.getString();
1428 rohini.deshpande 1.15 subscriptionEPR.selectorSet->selectors.append(WsmSelector
|
1429 dl.meetei 1.18 (String(PEGASUS_WS_CIMNAMESPACE),
|
1430 rohini.deshpande 1.15 PEGASUS_NAMESPACENAME_INTEROP.getString()));
1431 createSubRequest.reset(new WxfSubCreateRequest(messageId,
1432 subscriptionEPR,
1433 subscriptionInstance));
1434 PEG_METHOD_EXIT();
1435 return(new WxfSubCreateRequest(messageId,
1436 handlerEPR,
1437 handlerInstance));
1438 }
1439
1440 void WsmRequestDecoder::getFilterOrHandlerEPR(
1441 WsmEndpointReference& instanceEPR,
1442 const String address,
1443 const String name,
1444 const String className)
1445 {
1446 instanceEPR.address = address;
1447 instanceEPR.resourceUri = String(WSM_RESOURCEURI_CIMSCHEMAV2)
1448 + "/" + className;
1449 instanceEPR.selectorSet->selectors.append(WsmSelector
|
1450 dl.meetei 1.18 (String(PEGASUS_WS_CIMNAMESPACE),
|
1451 rohini.deshpande 1.15 PEGASUS_NAMESPACENAME_INTEROP.getString()));
1452 instanceEPR.selectorSet->selectors.append(WsmSelector(
1453 "SystemCreationClassName",
1454 System::getSystemCreationClassName()));
1455 instanceEPR.selectorSet->selectors.append(WsmSelector(
1456 "SystemName",
1457 System::getFullyQualifiedHostName()));
1458 instanceEPR.selectorSet->selectors.append(WsmSelector(
1459 PEGASUS_PROPERTYNAME_CREATIONCLASSNAME.getString(),
1460 className));
1461 instanceEPR.selectorSet->selectors.append(WsmSelector(
1462 PEGASUS_PROPERTYNAME_NAME.getString(),
1463 name));
1464 }
1465
|
1466 mike 1.12 bool WsmRequestDecoder::_isIdentifyRequest(WsmReader& wsmReader)
1467 {
1468 // Parse the <s:Body> element. Here is an example:
1469 //
1470 // <s:Body>
1471 // <wsmid:Identify>
1472 // </s:Body>
1473
1474 XmlEntry entry;
1475 wsmReader.setHideEmptyTags(true);
1476 wsmReader.expectStartTag(entry, WsmNamespaces::SOAP_ENVELOPE, "Body");
1477
1478 try
1479 {
1480 // Expect an identify element. Ignore the namespace to be more
1481 // tolerant.
1482 int nsType = wsmReader.expectStartTag(entry, "Identify");
1483 wsmReader.expectEndTag(nsType, "Identify");
1484 }
1485 catch (...)
1486 {
1487 mike 1.12 wsmReader.setHideEmptyTags(false);
1488 return false;
1489 }
1490
1491 wsmReader.expectEndTag(WsmNamespaces::SOAP_ENVELOPE, "Body");
1492 wsmReader.setHideEmptyTags(false);
1493
1494 return true;
1495 }
1496
1497 void WsmRequestDecoder::_sendIdentifyResponse(Uint32 queueId)
1498 {
1499 const char HTTP[] =
1500 "HTTP/1.1 200 OK\r\n"
1501 "Content-Type: application/soap+xml;charset=UTF-8\r\n"
1502 "Content-Length: ";
1503
1504 const char XML[] =
1505 "<s:Envelope xmlns:s=\""
1506 "http://www.w3.org/2003/05/soap-envelope"
1507 "\" xmlns:wsmid=\""
1508 mike 1.12 "http://schemas.dmtf.org/wbem/wsman/identify/1/wsmanidentity.xsd"
1509 "\">"
1510 "<s:Header>"
1511 "</s:Header>"
1512 "<s:Body>"
1513 "<wsmid:IdentifyResponse>"
1514 "<wsmid:ProtocolVersion>"
1515 WSMAN_PROTOCOL_VERSION
1516 "</wsmid:ProtocolVersion>"
1517 "<wsmid:ProductVendor>"
1518 WSMAN_PRODUCT_VENDOR
1519 "</wsmid:ProductVendor>"
1520 "<wsmid:ProductVersion>"
1521 WSMAN_PRODUCT_VERSION
1522 "</wsmid:ProductVersion>"
1523 "</wsmid:IdentifyResponse>"
1524 "</s:Body>"
1525 "</s:Envelope>";
1526
1527 Buffer message;
1528 message.append(HTTP, sizeof(HTTP) - 1);
1529 mike 1.12
1530 char buf[32];
1531 int n = sprintf(buf, "%d\r\n\r\n", int(sizeof(XML) - 1));
1532 message.append(buf, n);
1533
1534 message.append(XML, sizeof(XML) - 1);
1535
1536 sendResponse(queueId, message, false);
1537 }
1538
|
1539 kumpf 1.2 PEGASUS_NAMESPACE_END
|